Various Changes / Health Preservation to Request Spawn Data

This commit is contained in:
Kam committed 2026-03-04 20:56:06 -05:00
1 parent 12cf4b9a85
commit 8c8815dc45
3 files changed
+31 -40

No files matched your search

@@ -9,7 +9,6 @@ import kamkeel.npcs.network.PacketClient;
import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.enums.EnumPlayerPacket;
import kamkeel.npcs.network.packets.data.npc.UpdateNpcPacket;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -17,16 +16,10 @@ import net.minecraft.nbt.NBTTagCompound;
import noppes.npcs.entity.EntityNPCInterface;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class RequestProperSpawnData extends AbstractPacket {
public static final String packetName = "Player|SpawnData";
private static final int BATCH_LIMIT = 5;
private static final Set<Integer> entitiesToFix = new HashSet<>();
private static long lastBatchAttemptMillis = 0L;
private static final long REQUEST_COOLDOWN_MILLIS = 1000L;
private int entityId;
public RequestProperSpawnData() {}
@@ -37,8 +30,7 @@ public class RequestProperSpawnData extends AbstractPacket {
@SideOnly(Side.CLIENT)
public static void clear() {
entitiesToFix.clear();
lastBatchAttemptMillis = 0L;
// No backlog queue to clear.
}
@Override
@@ -81,40 +73,24 @@ public class RequestProperSpawnData extends AbstractPacket {
if (entityID <= 0)
return;
if (npc.clientFixAttempts++ < 3) {
PacketClient.sendClient(new RequestProperSpawnData(entityID));
} else {
entitiesToFix.add(entityID);
}
long now = System.currentTimeMillis();
if (now - npc.clientFixLastRequestMillis < REQUEST_COOLDOWN_MILLIS)
return;
if (npc.clientFixAttempts >= 3)
return;
npc.clientFixLastRequestMillis = now;
npc.clientFixAttempts++;
PacketClient.sendClient(new RequestProperSpawnData(entityID));
}
@SideOnly(Side.CLIENT)
public static boolean canDoBatchUpdate() {
return System.currentTimeMillis() - lastBatchAttemptMillis >= 5000;
return false;
}
@SideOnly(Side.CLIENT)
public static void handleBacklog() {
Minecraft mc = Minecraft.getMinecraft();
if (mc == null || mc.theWorld == null || mc.thePlayer == null)
return;
if (entitiesToFix.isEmpty())
return;
// Remove entity checks if they're no longer loaded
entitiesToFix.removeIf(value -> !(mc.theWorld.getEntityByID(value) instanceof EntityNPCInterface));
Iterator<Integer> it = entitiesToFix.iterator();
int count = 0;
while (it.hasNext() && count < BATCH_LIMIT) {
PacketClient.sendClient(new RequestProperSpawnData(it.next()));
it.remove();
count++;
}
if (count != 0) {
lastBatchAttemptMillis = System.currentTimeMillis();
}
// No batch backlog. Requests are immediate and throttled in reportMissingData().
}
}
@@ -193,8 +193,6 @@ public class ClientTickHandler {
return;
if (mc.theWorld.getTotalWorldTime() % 20 == 0) { // Update every second
if (RequestProperSpawnData.canDoBatchUpdate())
RequestProperSpawnData.handleBacklog();
updateCompassMarks();
}
}
@@ -236,6 +236,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
// For Client-Side Use Only
public int clientFixAttempts = 0;
public long clientFixLastRequestMillis = 0L;
public EntityNPCInterface(World world) {
super(world);
@@ -483,7 +484,14 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
}
if (wasKilled != isKilled() && wasKilled) {
reset();
if (!worldObj.isRemote) {
reset();
} else {
// Client-side full reset can create health oscillation when spawn data is being repaired.
deathTime = 0;
currentAnimation = EnumAnimation.NONE;
updateHitbox();
}
}
wasKilled = isKilled();
@@ -1838,6 +1846,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
NBTTagCompound compound = new NBTTagCompound();
display.writeToNBT(compound);
compound.setDouble("MaxHealth", stats.maxHealth);
compound.setFloat("CurrentHealth", getHealth());
compound.setTag("Armor", NBTTags.nbtItemStackList(inventory.getArmor()));
compound.setTag("Weapons", NBTTags.nbtItemStackList(inventory.getWeapons()));
compound.setInteger("Speed", ais.getWalkingSpeed());
@@ -1892,6 +1901,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
return;
}
float preservedHealth = getHealth();
stats.maxHealth = compound.getDouble("MaxHealth");
ais.setWalkingSpeed(compound.getInteger("Speed"));
stats.hideKilledBody = compound.getBoolean("DeadBody");
@@ -1916,6 +1926,12 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
ais.bodyOffsetY = compound.getFloat("OffsetY");
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(stats.maxHealth);
if (compound.hasKey("CurrentHealth", Constants.NBT.TAG_FLOAT)) {
setHealth(MathHelper.clamp_float(compound.getFloat("CurrentHealth"), 0.0F, getMaxHealth()));
} else {
// Keep previous client health if packet came from an older sender format.
setHealth(MathHelper.clamp_float(preservedHealth, 0.0F, getMaxHealth()));
}
inventory.setArmor(NBTTags.getItemStackList(compound.getTagList("Armor", 10)));
inventory.setWeapons(NBTTags.getItemStackList(compound.getTagList("Weapons", 10)));
advanced.setRole(compound.getInteger("Role"));
@@ -1990,6 +2006,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
return true;
}
clientFixAttempts = 0;
clientFixLastRequestMillis = 0L;
return false;
}