From c9abb1a0f8f3edf4b31f72024903bbd8c73b9342 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 4 Mar 2021 23:30:43 +0200 Subject: [PATCH] Link the spell to the entity it spawns --- .../magic/spell/AbstractPlacedSpell.java | 12 +++- .../unicopia/entity/CastSpellEntity.java | 29 ++------- .../unicopia/entity/EntityReference.java | 60 +++++++++++++++++++ .../unicopia/particle/ParticleHandle.java | 8 +-- 4 files changed, 81 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractPlacedSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractPlacedSpell.java index b34206e0..023080cc 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractPlacedSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractPlacedSpell.java @@ -6,9 +6,11 @@ import com.minelittlepony.unicopia.UEntities; import com.minelittlepony.unicopia.ability.magic.Attached; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.entity.CastSpellEntity; +import com.minelittlepony.unicopia.entity.EntityReference; import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect; import com.minelittlepony.unicopia.particle.ParticleHandle; import com.minelittlepony.unicopia.particle.UParticles; + import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Identifier; import net.minecraft.util.math.Vec3d; @@ -20,6 +22,8 @@ public abstract class AbstractPlacedSpell extends AbstractSpell implements Attac private final ParticleHandle particlEffect = new ParticleHandle(); + private final EntityReference castEntity = new EntityReference<>(); + protected AbstractPlacedSpell(SpellType type) { super(type); } @@ -39,13 +43,15 @@ public abstract class AbstractPlacedSpell extends AbstractSpell implements Attac dimension = source.getWorld().getRegistryKey().getValue(); setDirty(true); - if (!source.isClient()) { + if (!source.isClient() && !castEntity.isPresent(source.getWorld())) { CastSpellEntity entity = UEntities.CAST_SPELL.create(source.getWorld()); Vec3d pos = source.getOriginVector(); entity.updatePositionAndAngles(pos.x, pos.y, pos.z, 0, 0); entity.setSpell(this); entity.setMaster(source.getMaster()); entity.world.spawnEntity(entity); + + castEntity.set(entity); } } @@ -75,6 +81,7 @@ public abstract class AbstractPlacedSpell extends AbstractSpell implements Attac if (dimension != null) { compound.putString("dimension", dimension.toString()); } + compound.put("owner", castEntity.toNBT()); } @Override @@ -84,5 +91,8 @@ public abstract class AbstractPlacedSpell extends AbstractSpell implements Attac if (compound.contains("dimension")) { dimension = new Identifier(compound.getString("dimension")); } + if (compound.contains("castEntity")) { + castEntity.fromNBT(compound.getCompound("castEntity")); + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/CastSpellEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/CastSpellEntity.java index fbc16436..363ddffa 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/CastSpellEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/CastSpellEntity.java @@ -21,7 +21,6 @@ import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Packet; -import net.minecraft.server.world.ServerWorld; import net.minecraft.world.World; public class CastSpellEntity extends Entity implements Caster { @@ -36,8 +35,7 @@ public class CastSpellEntity extends Entity implements Caster { private final EntityPhysics physics = new EntityPhysics<>(this, GRAVITY); - private UUID ownerUuid; - private int ownerEntityId; + private final EntityReference owner = new EntityReference<>(); public CastSpellEntity(EntityType type, World world) { super(type, world); @@ -80,10 +78,7 @@ public class CastSpellEntity extends Entity implements Caster { @Override public void setMaster(LivingEntity owner) { - if (owner != null) { - ownerUuid = owner.getUuid(); - ownerEntityId = owner.getEntityId(); - } + this.owner.set(owner); } @Override @@ -98,15 +93,7 @@ public class CastSpellEntity extends Entity implements Caster { @Override public LivingEntity getMaster() { - if (ownerUuid != null && world instanceof ServerWorld) { - return (LivingEntity)((ServerWorld)world).getEntity(ownerUuid); - } - - if (ownerEntityId != 0) { - return (LivingEntity)world.getEntityById(ownerEntityId); - } - - return null; + return owner.get(world); } @Override @@ -131,18 +118,14 @@ public class CastSpellEntity extends Entity implements Caster { @Override protected void writeCustomDataToTag(CompoundTag tag) { - if (ownerUuid != null) { - tag.putUuid("Owner", ownerUuid); - } - tag.putInt("OwnerId", ownerEntityId); + tag.put("owner", owner.toNBT()); } @Override protected void readCustomDataFromTag(CompoundTag tag) { - if (tag.containsUuid("Owner")) { - ownerUuid = tag.getUuid("Owner"); + if (tag.contains("owner")) { + owner.fromNBT(tag.getCompound("owner")); } - ownerEntityId = tag.getInt("OwnerId"); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java new file mode 100644 index 00000000..fa39b8c2 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java @@ -0,0 +1,60 @@ +package com.minelittlepony.unicopia.entity; + +import java.util.UUID; + +import javax.annotation.Nullable; + +import com.minelittlepony.unicopia.util.NbtSerialisable; + +import net.minecraft.entity.Entity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.World; + +public class EntityReference implements NbtSerialisable { + + private UUID uuid; + private int clientId; + + public void set(@Nullable T entity) { + if (entity != null) { + uuid = entity.getUuid(); + clientId = entity.getEntityId(); + } + } + + public boolean isPresent(World world) { + T entity = get(world); + return entity != null && !entity.removed; + } + + @SuppressWarnings("unchecked") + @Nullable + public T get(World world) { + if (uuid != null && world instanceof ServerWorld) { + return (T)((ServerWorld)world).getEntity(uuid); + } + + if (clientId != 0) { + return (T)world.getEntityById(clientId); + } + + return null; + } + + @Override + public void toNBT(CompoundTag tag) { + if (uuid != null) { + tag.putUuid("uuid", uuid); + } + tag.putInt("clientId", clientId); + } + + @Override + public void fromNBT(CompoundTag tag) { + if (tag.containsUuid("uuid")) { + uuid = tag.getUuid("uuid"); + } + clientId = tag.getInt("clientId"); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java b/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java index a86814e3..2390d08f 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java @@ -1,11 +1,11 @@ package com.minelittlepony.unicopia.particle; import java.util.Optional; +import java.util.UUID; import java.util.function.Consumer; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Spell; -import com.minelittlepony.unicopia.ability.magic.spell.SpellType; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -60,13 +60,13 @@ public class ParticleHandle { public static final class Link { private Optional> caster = Optional.empty(); - private SpellType effect; + private UUID effect; private boolean linked; public void attach(Caster caster) { this.linked = true; this.caster = Optional.of(caster); - this.effect = caster.getSpellSlot().get(false).map(Spell::getType).orElse(null); + this.effect = caster.getSpellSlot().get(false).map(Spell::getUuid).orElse(null); } public void detach() { @@ -83,7 +83,7 @@ public class ParticleHandle { return Caster.of(e).orElse(null) == c && c.getSpellSlot().get(false) - .filter(s -> s.getType() == effect) + .filter(s -> s.getUuid().equals(effect)) .isPresent() && e != null && c.getWorld().getEntityById(e.getEntityId()) != null;