Rework slow time to use an NBT tag to unblock entity updates when not in a slow time zone, fixes #336 (and related issues with teleporting)
It also simplifies the code and removes the end slow time packet entirely
This commit is contained in:
@@ -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){}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/** <b>[Server -> Client]</b> 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<PacketEndSlowTime.Message, IMessage> {
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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:<br>
|
||||
* 1. Checks if they have the slow time NBT tag<br>
|
||||
* 2. If so, scans the area nearby for players or NPCs with the slow time effect<br>
|
||||
* 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<Entity> 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<EntityLivingBase> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user