diff --git a/src/main/java/electroblob/wizardry/CommonProxy.java b/src/main/java/electroblob/wizardry/CommonProxy.java index 74682ce4..d01c6a9b 100644 --- a/src/main/java/electroblob/wizardry/CommonProxy.java +++ b/src/main/java/electroblob/wizardry/CommonProxy.java @@ -140,8 +140,6 @@ public class CommonProxy { public void handleAdvancementSyncPacket(PacketSyncAdvancements.Message message){} - public void handleEndSlowTimePacket(PacketEndSlowTime.Message message){} - public void handleResurrectionPacket(PacketResurrection.Message message){} public void handlePossessionPacket(PacketPossession.Message message){} diff --git a/src/main/java/electroblob/wizardry/client/ClientProxy.java b/src/main/java/electroblob/wizardry/client/ClientProxy.java index 4307ec73..40b7b180 100644 --- a/src/main/java/electroblob/wizardry/client/ClientProxy.java +++ b/src/main/java/electroblob/wizardry/client/ClientProxy.java @@ -575,13 +575,6 @@ public class ClientProxy extends CommonProxy { GuiWizardHandbook.updateUnlockStatus(message.showToasts, message.completedAdvancements); } - @Override - public void handleEndSlowTimePacket(PacketEndSlowTime.Message message){ - Entity entity = Minecraft.getMinecraft().world.getEntityByID(message.hostID); - if(entity instanceof EntityLivingBase) PotionSlowTime.unblockNearbyEntities((EntityLivingBase)entity); - else Wizardry.logger.warn("Received a PacketEndSlowTime, but the entity ID did not match any living entity"); - } - @Override public void handleResurrectionPacket(PacketResurrection.Message message){ Entity entity = Minecraft.getMinecraft().world.getEntityByID(message.playerID); diff --git a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java index 7b25b636..74dbedb1 100644 --- a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java +++ b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java @@ -9,6 +9,7 @@ import electroblob.wizardry.data.WizardData; import electroblob.wizardry.item.ISpellCastingItem; import electroblob.wizardry.item.ItemArtefact; import electroblob.wizardry.item.ItemSpectralBow; +import electroblob.wizardry.potion.PotionSlowTime; import electroblob.wizardry.registry.Spells; import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.registry.WizardryPotions; @@ -153,6 +154,7 @@ public final class WizardryClientEventHandler { } SpellEmitterData.update(world); + PotionSlowTime.cleanUpEntities(world); } } diff --git a/src/main/java/electroblob/wizardry/packet/PacketEndSlowTime.java b/src/main/java/electroblob/wizardry/packet/PacketEndSlowTime.java deleted file mode 100644 index e4d276f8..00000000 --- a/src/main/java/electroblob/wizardry/packet/PacketEndSlowTime.java +++ /dev/null @@ -1,47 +0,0 @@ -package electroblob.wizardry.packet; - -import electroblob.wizardry.Wizardry; -import io.netty.buffer.ByteBuf; -import net.minecraft.entity.Entity; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; - -/** [Server -> Client] This packet is sent when the slow time potion effect expires or is removed from an - * entity to unblock all nearby entities' updates. */ -public class PacketEndSlowTime implements IMessageHandler { - - @Override - public IMessage onMessage(Message message, MessageContext ctx){ - - // Just to make sure that the side is correct - if(ctx.side.isClient()){ - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleEndSlowTimePacket(message)); - } - - return null; - } - - public static class Message implements IMessage { - - public int hostID; - - // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) - public Message(){ - } - - public Message(Entity host){ - this.hostID = host.getEntityId(); - } - - @Override - public void fromBytes(ByteBuf buf){ - this.hostID = buf.readInt(); - } - - @Override - public void toBytes(ByteBuf buf){ - buf.writeInt(hostID); - } - } -} diff --git a/src/main/java/electroblob/wizardry/packet/WizardryPacketHandler.java b/src/main/java/electroblob/wizardry/packet/WizardryPacketHandler.java index 41d12d0d..045205bf 100644 --- a/src/main/java/electroblob/wizardry/packet/WizardryPacketHandler.java +++ b/src/main/java/electroblob/wizardry/packet/WizardryPacketHandler.java @@ -26,7 +26,6 @@ public class WizardryPacketHandler { registerMessage(PacketSpellProperties.class, PacketSpellProperties.Message.class); registerMessage(PacketSyncAdvancements.class, PacketSyncAdvancements.Message.class); registerMessage(PacketRequestAdvancementSync.class, PacketRequestAdvancementSync.Message.class); - registerMessage(PacketEndSlowTime.class, PacketEndSlowTime.Message.class); registerMessage(PacketResurrection.class, PacketResurrection.Message.class); registerMessage(PacketCastSpellAtPos.class, PacketCastSpellAtPos.Message.class); registerMessage(PacketEmitterData.class, PacketEmitterData.Message.class); diff --git a/src/main/java/electroblob/wizardry/potion/PotionSlowTime.java b/src/main/java/electroblob/wizardry/potion/PotionSlowTime.java index b6e1f51d..e849de0c 100644 --- a/src/main/java/electroblob/wizardry/potion/PotionSlowTime.java +++ b/src/main/java/electroblob/wizardry/potion/PotionSlowTime.java @@ -2,8 +2,6 @@ package electroblob.wizardry.potion; import electroblob.wizardry.Wizardry; import electroblob.wizardry.item.ItemArtefact; -import electroblob.wizardry.packet.PacketEndSlowTime; -import electroblob.wizardry.packet.WizardryPacketHandler; import electroblob.wizardry.registry.Spells; import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.registry.WizardryPotions; @@ -17,11 +15,15 @@ import net.minecraft.entity.IProjectile; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.living.PotionEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import java.util.ArrayList; import java.util.List; @Mod.EventBusSubscriber @@ -29,6 +31,8 @@ public class PotionSlowTime extends PotionMagicEffect implements ISyncedPotion { // FIXME: Minecarts with entities in them (and, I suspect, any other ridden entities) go crazy when time-slowed + public static final String NBT_KEY = "time_slowed"; + public PotionSlowTime(boolean isBadEffect, int liquidColour){ super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icon_slow_time.png")); this.setPotionName("potion." + Wizardry.MODID + ":slow_time"); @@ -61,6 +65,8 @@ public class PotionSlowTime extends PotionMagicEffect implements ISyncedPotion { for(Entity entity : targetsInRange){ + entity.getEntityData().setBoolean(NBT_KEY, true); + // If time is stopped, block all updates; otherwise block all updates except every [interval] ticks entity.updateBlocked = stopTime || host.ticksExisted % interval != 0; @@ -130,6 +136,29 @@ public class PotionSlowTime extends PotionMagicEffect implements ISyncedPotion { } + /** + * Goes through every entity in the given world and does the following:
+ * 1. Checks if they have the slow time NBT tag
+ * 2. If so, scans the area nearby for players or NPCs with the slow time effect
+ * 3. If none are found, removes the slow time NBT tag and unblocks the entity's updates + */ + public static void cleanUpEntities(World world){ + // Had trouble with accessing loadedTileEntityList from tick events causing random CMEs so I'm making a + // copy of this too just in case + List loadedEntityList = new ArrayList<>(world.loadedEntityList); + + for(Entity entity : loadedEntityList){ + if(entity.getEntityData().getBoolean(NBT_KEY)){ + // Currently only players can cast slow time, but you could apply the effect to NPCs with commands + List nearby = WizardryUtilities.getEntitiesWithinRadius(getEffectRadius(), entity.posX, entity.posY, entity.posZ, entity.world, EntityLivingBase.class); + if(nearby.stream().noneMatch(e -> e.isPotionActive(WizardryPotions.slow_time))){ + entity.getEntityData().removeTag(NBT_KEY); + entity.updateBlocked = false; + } + } + } + } + @SubscribeEvent public static void onLivingUpdateEvent(LivingUpdateEvent event){ @@ -150,23 +179,16 @@ public class PotionSlowTime extends PotionMagicEffect implements ISyncedPotion { } @SubscribeEvent - public static void onPotionExpiryEvent(PotionEvent.PotionExpiryEvent event){ - if(event.getPotionEffect() != null && event.getPotionEffect().getPotion() == WizardryPotions.slow_time){ - unblockNearbyEntities(event.getEntityLiving()); - if(!event.getEntity().world.isRemote){ - WizardryPacketHandler.net.sendToDimension(new PacketEndSlowTime.Message(event.getEntityLiving()), event.getEntity().dimension); - } - } + public static void tick(TickEvent.WorldTickEvent event){ + if(!event.world.isRemote && event.phase == TickEvent.Phase.END) cleanUpEntities(event.world); } + // We still need this as well as tick events because the player hasn't moved anywhere, they just logged out + // In fact, it won't really matter since the tick event fixes it on login anyway, but if the mod is uninstalled or + // something else weird happens... @SubscribeEvent - public static void onPotionRemoveEvent(PotionEvent.PotionRemoveEvent event){ - if(event.getPotionEffect() != null && event.getPotionEffect().getPotion() == WizardryPotions.slow_time){ - unblockNearbyEntities(event.getEntityLiving()); - if(!event.getEntity().world.isRemote){ - WizardryPacketHandler.net.sendToDimension(new PacketEndSlowTime.Message(event.getEntityLiving()), event.getEntity().dimension); - } - } + public static void onPlayerLoggedOutEvent(PlayerEvent.PlayerLoggedOutEvent event){ + if(event.player.updateBlocked) event.player.updateBlocked = false; } }