diff --git a/src/main/java/kamkeel/npcs/network/packets/data/RequestProperSpawnData.java b/src/main/java/kamkeel/npcs/network/packets/data/RequestProperSpawnData.java index e747bf62c..fce6c13fa 100644 --- a/src/main/java/kamkeel/npcs/network/packets/data/RequestProperSpawnData.java +++ b/src/main/java/kamkeel/npcs/network/packets/data/RequestProperSpawnData.java @@ -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 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 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(). } } diff --git a/src/main/java/noppes/npcs/client/ClientTickHandler.java b/src/main/java/noppes/npcs/client/ClientTickHandler.java index c0b501c4d..1f6e1bf34 100644 --- a/src/main/java/noppes/npcs/client/ClientTickHandler.java +++ b/src/main/java/noppes/npcs/client/ClientTickHandler.java @@ -193,8 +193,6 @@ public class ClientTickHandler { return; if (mc.theWorld.getTotalWorldTime() % 20 == 0) { // Update every second - if (RequestProperSpawnData.canDoBatchUpdate()) - RequestProperSpawnData.handleBacklog(); updateCompassMarks(); } } diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 6045317d8..3eed36105 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -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; }