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;
}
}