From 8a093a8a8bc2f58bc28430d643f87145f77d711c Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 23 May 2024 12:53:11 +0100 Subject: [PATCH] Sync all spells onto the ether --- .../magic/spell/AbstractDelegatingSpell.java | 5 + .../magic/spell/AbstractDisguiseSpell.java | 5 +- .../ability/magic/spell/PlaceableSpell.java | 40 ++++--- .../magic/spell/PlacementControlSpell.java | 102 ++++++++---------- .../unicopia/ability/magic/spell/Spell.java | 4 + .../magic/spell/effect/AbstractSpell.java | 10 +- .../spell/effect/AreaProtectionSpell.java | 5 - .../magic/spell/effect/BubbleSpell.java | 1 + .../magic/spell/effect/DisplacementSpell.java | 1 + .../magic/spell/effect/HydrophobicSpell.java | 7 +- .../magic/spell/effect/LightSpell.java | 1 + .../magic/spell/effect/NecromancySpell.java | 1 + .../magic/spell/effect/PortalSpell.java | 24 ++--- .../magic/spell/effect/ShieldSpell.java | 3 + .../client/gui/DismissSpellScreen.java | 7 +- .../unicopia/server/world/Ether.java | 49 ++++++++- 16 files changed, 154 insertions(+), 111 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java index 5ad87443..79ed5954 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java @@ -6,6 +6,8 @@ import java.util.stream.Stream; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType; +import com.minelittlepony.unicopia.server.world.Ether; + import net.minecraft.nbt.NbtCompound; public abstract class AbstractDelegatingSpell implements Spell { @@ -101,6 +103,9 @@ public abstract class AbstractDelegatingSpell implements Spell { } protected void onDestroyed(Caster caster) { + if (!caster.isClient()) { + Ether.get(caster.asWorld()).remove(this, caster); + } if (delegate.get() instanceof Spell s) { s.destroy(caster); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java index 14a35e99..41e7c996 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java @@ -28,10 +28,11 @@ public abstract class AbstractDisguiseSpell extends AbstractSpell implements Dis @Override protected void onDestroyed(Caster caster) { + super.onDestroyed(caster); caster.asEntity().calculateDimensions(); caster.asEntity().setInvisible(false); - if (caster instanceof Pony) { - ((Pony) caster).setInvisible(false); + if (caster instanceof Pony pony) { + pony.setInvisible(false); } disguise.remove(); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java index 83c56ddf..548e66ea 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java @@ -51,16 +51,6 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS } } - @Override - public boolean apply(Caster caster) { - boolean result = super.apply(caster); - if (result && !caster.isClient()) { - Ether.get(caster.asWorld()).getOrCreate(this, caster); - } - setDirty(); - return result; - } - public float getAge(float tickDelta) { return MathHelper.lerp(tickDelta, prevAge, age); } @@ -91,9 +81,16 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS @Override public boolean tick(Caster source, Situation situation) { - if (!source.isClient() && !checkConnection(source)) { - setDead(); - return false; + if (!source.isClient()) { + if (!checkConnection(source)) { + setDead(); + return true; + } + + var entry = Ether.get(source.asWorld()).get(this, source); + if (entry != null && entry.hasChanged()) { + setOrientation(source, entry.getPitch(), entry.getYaw()); + } } prevAge = age; @@ -115,14 +112,6 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS deathTicks--; } - @Override - protected void onDestroyed(Caster source) { - if (!source.isClient()) { - Ether.get(source.asWorld()).remove(this, source); - } - super.onDestroyed(source); - } - @Override public void setOrientation(Caster caster, float pitch, float yaw) { this.pitch = -pitch - 90; @@ -131,6 +120,15 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS entity.updatePositionAndAngles(entity.getX(), entity.getY(), entity.getZ(), this.yaw, this.pitch); entity.setYaw(this.yaw); entity.setPitch(this.pitch); + + if (!caster.isClient()) { + var entry = Ether.get(caster.asWorld()).get(this, caster); + if (entry != null) { + entry.setPitch(pitch); + entry.setYaw(yaw); + } + } + setDirty(); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlacementControlSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlacementControlSpell.java index d54b3e8f..6103890b 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlacementControlSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlacementControlSpell.java @@ -5,11 +5,9 @@ import java.util.UUID; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.SpellPredicate; +import com.minelittlepony.unicopia.ability.magic.spell.effect.AbstractSpell; import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; -import com.minelittlepony.unicopia.entity.EntityReference; -import com.minelittlepony.unicopia.entity.EntityReference.EntityValues; import com.minelittlepony.unicopia.entity.mob.CastSpellEntity; import com.minelittlepony.unicopia.entity.mob.UEntities; import com.minelittlepony.unicopia.server.world.Ether; @@ -23,15 +21,18 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class PlacementControlSpell extends AbstractDelegatingSpell implements OrientedSpell { +public class PlacementControlSpell extends AbstractSpell implements OrientedSpell { @Nullable private UUID placedSpellId; - private final EntityReference castEntity = new EntityReference<>(); + @Nullable + private UUID placedEntityId; private Optional> dimension = Optional.empty(); private Optional position = Optional.empty(); private Optional orientation = Optional.empty(); + private SpellReference delegate = new SpellReference<>(); + public PlacementControlSpell(CustomisedSpellType type) { super(type); } @@ -41,6 +42,11 @@ public class PlacementControlSpell extends AbstractDelegatingSpell implements Or this.delegate.set(delegate); } + @Nullable + public Spell getDelegate() { + return delegate.get(); + } + public Optional getPosition() { return position; } @@ -56,107 +62,91 @@ public class PlacementControlSpell extends AbstractDelegatingSpell implements Or @Override public void setOrientation(Caster caster, float pitch, float yaw) { this.orientation = Optional.of(new Vec3d(pitch, yaw, 0)); - castEntity.ifPresent(caster.asWorld(), entity -> { - entity.getSpellSlot().stream(SpellPredicate.IS_ORIENTED).forEach(spell -> { - if (!getTypeAndTraits().type().test(spell)) { - spell.setOrientation(caster, pitch, yaw); + setDirty(); + if (!caster.isClient() && placedEntityId != null) { + getWorld(caster).ifPresent(world -> { + var entry = Ether.get(world).get(SpellType.PLACED_SPELL, placedEntityId, placedSpellId); + if (entry != null) { + entry.setPitch(pitch); + entry.setYaw(yaw); } }); - }); - setDirty(); + } } @Override public boolean apply(Caster caster) { boolean result = super.apply(caster); if (result) { - if (!caster.isClient()) { - Ether.get(caster.asWorld()).getOrCreate(this, caster); - } if (dimension.isEmpty()) { setDimension(caster.asWorld().getRegistryKey()); } if (position.isEmpty()) { setPosition(caster.asEntity().getPos()); } + + PlaceableSpell copy = new PlaceableSpell(caster, this, delegate.get()); + + Vec3d pos = position.orElse(caster.asEntity().getPos()); + Vec3d rot = orientation.orElse(Vec3d.ZERO); + + CastSpellEntity entity = UEntities.CAST_SPELL.create(caster.asWorld()); + entity.setCaster(caster); + entity.updatePositionAndAngles(pos.x, pos.y, pos.z, (float)rot.y, (float)rot.x); + entity.setYaw((float)rot.y); + entity.setPitch((float)rot.x); + copy.apply(entity); + entity.getWorld().spawnEntity(entity); + + placedSpellId = copy.getUuid(); + placedEntityId = entity.getUuid(); + setDirty(); } return result; } @Override public boolean tick(Caster source, Situation situation) { - if (!source.isClient()) { - Ether.get(source.asWorld()).getOrCreate(this, source); - castEntity.getTarget().ifPresentOrElse(target -> { - if (!checkConnection(source, target)) { - setDead(); - } - }, () -> spawnPlacedEntity(source)); + if (!source.isClient() && !checkConnection(source)) { + setDead(); } return !isDead(); } - private void spawnPlacedEntity(Caster source) { - PlaceableSpell copy = new PlaceableSpell(source, this, getDelegate()); - - Vec3d pos = position.orElse(source.asEntity().getPos()); - Vec3d rot = orientation.orElse(Vec3d.ZERO); - - CastSpellEntity entity = UEntities.CAST_SPELL.create(source.asWorld()); - entity.setCaster(source); - entity.updatePositionAndAngles(pos.x, pos.y, pos.z, (float)rot.y, (float)rot.x); - entity.setYaw((float)rot.y); - entity.setPitch((float)rot.x); - copy.apply(entity); - entity.getWorld().spawnEntity(entity); - - placedSpellId = copy.getUuid(); - castEntity.set(entity); - setDirty(); - } - - private boolean checkConnection(Caster source, EntityValues target) { - return getWorld(source) - .map(Ether::get) - .map(ether -> ether.get(SpellType.PLACED_SPELL, target, placedSpellId)) - .isPresent(); + private boolean checkConnection(Caster source) { + return getWorld(source).map(world -> Ether.get(world).get(SpellType.PLACED_SPELL, placedEntityId, placedSpellId)).isPresent(); } private Optional getWorld(Caster source) { return dimension.map(source.asWorld().getServer()::getWorld); } - @Override - protected void onDestroyed(Caster source) { - if (!source.isClient()) { - Ether.get(source.asWorld()).remove(this, source); - } - super.onDestroyed(source); - } - @Override public void toNBT(NbtCompound compound) { super.toNBT(compound); + compound.put("spell", delegate.toNBT()); position.ifPresent(pos -> compound.put("position", NbtSerialisable.writeVector(pos))); orientation.ifPresent(o -> compound.put("orientation", NbtSerialisable.writeVector(o))); dimension.ifPresent(d -> compound.putString("dimension", d.getValue().toString())); if (placedSpellId != null) { compound.putUuid("placedSpellId", placedSpellId); } - compound.put("castEntity", castEntity.toNBT()); - + if (placedEntityId != null) { + compound.putUuid("placedEntityId", placedEntityId); + } } @Override public void fromNBT(NbtCompound compound) { super.fromNBT(compound); + delegate.fromNBT(compound.getCompound("spell")); placedSpellId = compound.containsUuid("placedSpellId") ? compound.getUuid("placedSpellId") : null; + placedEntityId = compound.containsUuid("placedEntityId") ? compound.getUuid("placedEntityId") : null; position = compound.contains("position") ? Optional.of(NbtSerialisable.readVector(compound.getList("position", NbtElement.FLOAT_TYPE))) : Optional.empty(); orientation = compound.contains("orientation") ? Optional.of(NbtSerialisable.readVector(compound.getList("orientation", NbtElement.FLOAT_TYPE))) : Optional.empty(); if (compound.contains("dimension", NbtElement.STRING_TYPE)) { dimension = Optional.ofNullable(Identifier.tryParse(compound.getString("dimension"))).map(id -> RegistryKey.of(RegistryKeys.WORLD, id)); } - castEntity.fromNBT(compound.getCompound("castEntity")); } public interface PlacementDelegate { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Spell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Spell.java index 8ede5a8b..d087ed0c 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Spell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Spell.java @@ -13,6 +13,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.server.world.Ether; import com.minelittlepony.unicopia.util.NbtSerialisable; import net.minecraft.nbt.NbtCompound; @@ -81,6 +82,9 @@ public interface Spell extends NbtSerialisable, Affine { */ default boolean apply(Caster caster) { caster.getSpellSlot().put(this); + if (!caster.isClient()) { + Ether.get(caster.asWorld()).getOrCreate(this, caster); + } return true; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AbstractSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AbstractSpell.java index ada82e85..f7cef06d 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AbstractSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AbstractSpell.java @@ -5,6 +5,7 @@ import java.util.UUID; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.server.world.Ether; import net.minecraft.nbt.NbtCompound; @@ -78,9 +79,6 @@ public abstract class AbstractSpell implements Spell { this.hidden = hidden; } - protected void onDestroyed(Caster caster) { - } - @Override public void tickDying(Caster caster) { dead = true; @@ -96,6 +94,12 @@ public abstract class AbstractSpell implements Spell { onDestroyed(caster); } + protected void onDestroyed(Caster caster) { + if (!caster.isClient()) { + Ether.get(caster.asWorld()).remove(this, caster); + } + } + @Override public void toNBT(NbtCompound compound) { compound.putBoolean("dying", dying); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AreaProtectionSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AreaProtectionSpell.java index 920c5bd5..5ae9df44 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AreaProtectionSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AreaProtectionSpell.java @@ -54,11 +54,6 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell { return !isDead(); } - @Override - protected void onDestroyed(Caster caster) { - Ether.get(caster.asWorld()).remove(this, caster); - } - /** * Calculates the maximum radius of the shield. aka The area of effect. */ diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/BubbleSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/BubbleSpell.java index 2cc4dd51..c35227af 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/BubbleSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/BubbleSpell.java @@ -139,6 +139,7 @@ public class BubbleSpell extends AbstractSpell implements TimedSpell, @Override protected void onDestroyed(Caster source) { + super.onDestroyed(source); if (source.asEntity() instanceof LivingEntity l) { MODIFIERS.forEach((attribute, modifier) -> { if (l.getAttributes().hasAttribute(attribute)) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DisplacementSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DisplacementSpell.java index a58b77de..b787778b 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DisplacementSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DisplacementSpell.java @@ -90,6 +90,7 @@ public class DisplacementSpell extends AbstractSpell implements HomingSpell, Pro @Override protected void onDestroyed(Caster caster) { + super.onDestroyed(caster); caster.getOriginatingCaster().asEntity().setGlowing(false); target.ifPresent(caster.asWorld(), e -> e.setGlowing(false)); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java index ce21955f..434d6ad7 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java @@ -92,8 +92,7 @@ public class HydrophobicSpell extends AbstractSpell { } double range = getRange(source); - var entry = Ether.get(source.asWorld()).getOrCreate(this, source); - entry.radius = (float)range; + Ether.get(source.asWorld()).getOrCreate(this, source).setRadius((float)range); source.spawnParticles(new Sphere(true, range), 10, pos -> { BlockPos bp = BlockPos.ofFloored(pos); @@ -116,7 +115,7 @@ public class HydrophobicSpell extends AbstractSpell { @Override protected void onDestroyed(Caster caster) { - Ether.get(caster.asWorld()).remove(this, caster); + super.onDestroyed(caster); storedFluidPositions.removeIf(entry -> { if (caster.canModifyAt(entry.pos())) { entry.restore(caster.asWorld()); @@ -175,7 +174,7 @@ public class HydrophobicSpell extends AbstractSpell { } public boolean blocksFlow(Ether.Entry entry, Vec3d center, BlockPos pos, FluidState fluid) { - return fluid.isIn(affectedFluid) && pos.isWithinDistance(center, (double)entry.radius + 1); + return fluid.isIn(affectedFluid) && pos.isWithinDistance(center, (double)entry.getRadius() + 1); } public static boolean blocksFluidFlow(BlockView world, BlockPos pos, FluidState state) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/LightSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/LightSpell.java index 8bd9c813..9688b7f7 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/LightSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/LightSpell.java @@ -91,6 +91,7 @@ public class LightSpell extends AbstractSpell implements TimedSpell, ProjectileD @Override protected void onDestroyed(Caster caster) { + super.onDestroyed(caster); if (caster.isClient()) { return; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/NecromancySpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/NecromancySpell.java index dbf79bab..910fddd3 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/NecromancySpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/NecromancySpell.java @@ -153,6 +153,7 @@ public class NecromancySpell extends AbstractAreaEffectSpell implements Projecti @Override protected void onDestroyed(Caster caster) { + super.onDestroyed(caster); if (caster.isClient()) { return; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java index fff35722..944f1365 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java @@ -121,11 +121,9 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell. ); } - Ether ether = Ether.get(source.asWorld()); - var entry = ether.getOrCreate(this, source); - entry.pitch = pitch; - entry.yaw = yaw; - ether.markDirty(); + var entry = Ether.get(source.asWorld()).getOrCreate(this, source); + entry.setPitch(pitch); + entry.setYaw(yaw); } return !isDead(); @@ -133,13 +131,9 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell. private void tickWithTargetLink(Caster source, Ether.Entry destination) { - if (!MathHelper.approximatelyEquals(targetPortalPitch, destination.pitch)) { - targetPortalPitch = destination.pitch; - setDirty(); - } - if (!MathHelper.approximatelyEquals(targetPortalYaw, destination.yaw)) { - targetPortalYaw = destination.yaw; - setDirty(); + if (destination.hasChanged()) { + targetPortalPitch = destination.getPitch(); + targetPortalYaw = destination.getYaw(); } destination.entity.getTarget().ifPresent(target -> { @@ -221,8 +215,10 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell. @Override protected void onDestroyed(Caster caster) { - Ether.get(caster.asWorld()).remove(getType(), caster); - getDestination(caster).ifPresent(Ether.Entry::release); + super.onDestroyed(caster); + if (!caster.isClient()) { + getDestination(caster).ifPresent(Ether.Entry::release); + } } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java index da5e5dc2..541f1033 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java @@ -19,6 +19,7 @@ import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.projectile.ProjectileUtil; +import com.minelittlepony.unicopia.server.world.Ether; import com.minelittlepony.unicopia.util.ColorHelper; import com.minelittlepony.unicopia.util.Lerp; import com.minelittlepony.unicopia.util.shape.Sphere; @@ -115,6 +116,8 @@ public class ShieldSpell extends AbstractSpell { if (source.isClient()) { generateParticles(source); + } else { + Ether.get(source.asWorld()).getOrCreate(this, source).setRadius(radius.getValue()); } if (situation == Situation.PROJECTILE) { diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java b/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java index 85a5bd85..9ff61ac3 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java @@ -136,7 +136,9 @@ public class DismissSpellScreen extends GameGui { } private Spell getActualSpell() { - return spell instanceof AbstractDelegatingSpell s && s.getDelegate() instanceof Spell p ? p : spell; + return spell instanceof AbstractDelegatingSpell s && s.getDelegate() instanceof Spell p ? p + : spell instanceof PlacementControlSpell s && s.getDelegate() instanceof Spell p ? p + : spell; } @Override @@ -161,11 +163,10 @@ public class DismissSpellScreen extends GameGui { MatrixStack matrices = context.getMatrices(); var type = actualSpell.getTypeAndTraits(); - var affinity = actualSpell.getAffinity(); copy.set(mouseX - width * 0.5F - x * 0.5F, mouseY - height * 0.5F - y * 0.5F, 0, 0); - DrawableUtil.drawLine(matrices, 0, 0, (int)x, (int)y, affinity.getColor().getColorValue()); + DrawableUtil.drawLine(matrices, 0, 0, (int)x, (int)y, actualSpell.getAffinity().getColor().getColorValue()); DrawableUtil.renderItemIcon(context, actualSpell.isDead() ? UItems.BOTCHED_GEM.getDefaultStack() : type.getDefaultStack(), x - 8 - copy.x * 0.2F, y - 8 - copy.y * 0.2F, diff --git a/src/main/java/com/minelittlepony/unicopia/server/world/Ether.java b/src/main/java/com/minelittlepony/unicopia/server/world/Ether.java index f0982276..13707da6 100644 --- a/src/main/java/com/minelittlepony/unicopia/server/world/Ether.java +++ b/src/main/java/com/minelittlepony/unicopia/server/world/Ether.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.server.world; import java.lang.ref.WeakReference; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiPredicate; import java.util.function.Predicate; @@ -15,6 +16,7 @@ import com.minelittlepony.unicopia.entity.EntityReference; import com.minelittlepony.unicopia.util.NbtSerialisable; import net.minecraft.nbt.*; import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.PersistentState; import net.minecraft.world.World; @@ -168,9 +170,10 @@ public class Ether extends PersistentState { private boolean removed; private boolean taken; - public float pitch; - public float yaw; - public float radius; + private float pitch; + private final AtomicBoolean changed = new AtomicBoolean(true); + private float yaw; + private float radius; private Entry(NbtElement nbt) { this.entity = new EntityReference<>(); @@ -184,6 +187,46 @@ public class Ether extends PersistentState { spellId = spell.getUuid(); } + public boolean hasChanged() { + return changed.getAndSet(false); + } + + public float getPitch() { + return pitch; + } + + public void setPitch(float pitch) { + if (!MathHelper.approximatelyEquals(this.pitch, pitch)) { + this.pitch = pitch; + changed.set(true); + } + markDirty(); + } + + public float getYaw() { + return yaw; + } + + public void setYaw(float yaw) { + if (!MathHelper.approximatelyEquals(this.yaw, yaw)) { + this.yaw = yaw; + changed.set(true); + } + markDirty(); + } + + public float getRadius() { + return radius; + } + + public void setRadius(float radius) { + if (!MathHelper.approximatelyEquals(this.radius, radius)) { + this.radius = radius; + changed.set(true); + } + markDirty(); + } + boolean isAlive() { return !isDead(); }