From ca8cf8371ae4a4fc8beeb23a613a280fb9c45a54 Mon Sep 17 00:00:00 2001
From: Sollace <sollacea@gmail.com>
Date: Tue, 7 Nov 2023 18:20:04 +0000
Subject: [PATCH] Changelings can now untransform by using their ability on
 something they've already transformed into

---
 .../unicopia/ability/ChangelingDisguiseAbility.java | 13 +++++++++----
 .../unicopia/entity/behaviour/Disguise.java         |  4 ++++
 .../unicopia/entity/behaviour/EntityAppearance.java |  4 ++++
 .../unicopia/entity/behaviour/EntityBehaviour.java  |  4 ++++
 .../entity/behaviour/FallingBlockBehaviour.java     |  5 +++++
 .../unicopia/entity/behaviour/PlayerBehaviour.java  |  7 ++++++-
 6 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java
index 33a67ac0..6f3e2c60 100644
--- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java
+++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java
@@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.ability.data.Hit;
 import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell;
 import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
 import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
+import com.minelittlepony.unicopia.entity.behaviour.Disguise;
 import com.minelittlepony.unicopia.entity.player.Pony;
 import com.minelittlepony.unicopia.mixin.MixinFallingBlockEntity;
 import com.minelittlepony.unicopia.particle.UParticles;
@@ -50,9 +51,13 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
 
         player.getEntityWorld().playSound(null, player.getBlockPos(), USounds.ENTITY_PLAYER_CHANGELING_TRANSFORM, SoundCategory.PLAYERS, 1.4F, 0.4F);
 
-        iplayer.getSpellSlot().get(SpellType.CHANGELING_DISGUISE, true)
-            .orElseGet(() -> SpellType.CHANGELING_DISGUISE.withTraits().apply(iplayer, CastingMethod.INNATE))
-            .setDisguise(looked);
+        Disguise currentDisguise = iplayer.getSpellSlot().get(SpellType.CHANGELING_DISGUISE, true)
+            .orElseGet(() -> SpellType.CHANGELING_DISGUISE.withTraits().apply(iplayer, CastingMethod.INNATE));
+
+        if (currentDisguise.isOf(looked)) {
+            looked = null;
+        }
+        currentDisguise.setDisguise(looked);
 
         if (!player.isCreative()) {
             iplayer.getMagicalReserves().getMana().multiply(0.1F);
@@ -65,7 +70,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
 
     @Override
     public void warmUp(Pony player, AbilitySlot slot) {
-        player.getMagicalReserves().getEnergy().add(20);
+        player.getMagicalReserves().getEnergy().add(2F);
         player.spawnParticles(UParticles.CHANGELING_MAGIC, 5);
     }
 
diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java
index 56ecd0eb..272cde97 100644
--- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java
+++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java
@@ -46,6 +46,10 @@ public interface Disguise extends FlightType.Provider, PlayerDimensions.Provider
         return getAppearance().flatMap(d -> d.getTargetDimensions(player));
     }
 
+    default boolean isOf(@Nullable Entity entity) {
+        return getDisguise().isOf(entity);
+    }
+
     default Disguise setDisguise(@Nullable Entity entity) {
         if (entity == getDisguise().getAppearance()) {
             entity = null;
diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java
index edad3ecb..15c8fee6 100644
--- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java
+++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java
@@ -109,6 +109,10 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
         return entity != null;
     }
 
+    public boolean isOf(@Nullable Entity entity) {
+        return isPresent() && entity != null && EntityBehaviour.forEntity(this.entity).isEqual(this.entity, entity);
+    }
+
     public NbtCompound getOrCreateTag() {
         if (tag == null) {
             tag = new NbtCompound();
diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java
index 189ee33d..b37e06df 100644
--- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java
+++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java
@@ -74,6 +74,10 @@ public class EntityBehaviour<T extends Entity> {
         entity.remove(RemovalReason.KILLED);
     }
 
+    public boolean isEqual(T a, Entity b) {
+        return a.getType() == b.getType();
+    }
+
     public Optional<Double> getCameraDistance(Entity entity, Pony player) {
         if (entity == null) {
             return Optional.empty();
diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java
index bc3fafd2..b9d440a4 100644
--- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java
+++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java
@@ -53,6 +53,11 @@ public class FallingBlockBehaviour extends EntityBehaviour<FallingBlockEntity> {
         }
     }
 
+    @Override
+    public boolean isEqual(FallingBlockEntity a, Entity b) {
+        return b instanceof FallingBlockEntity f && f.getBlockState() == a.getBlockState();
+    }
+
     private FallingBlockEntity configure(FallingBlockEntity entity, Block block) {
         if (block instanceof MixinFallingBlock) {
             ((MixinFallingBlock)block).invokeConfigureFallingBlockEntity(entity);
diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/PlayerBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/PlayerBehaviour.java
index 612153bc..489248e6 100644
--- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/PlayerBehaviour.java
+++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/PlayerBehaviour.java
@@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.entity.Living;
 import com.minelittlepony.unicopia.entity.duck.*;
 import com.minelittlepony.unicopia.entity.player.Pony;
 
+import net.minecraft.entity.Entity;
 import net.minecraft.entity.player.PlayerEntity;
 
 public class PlayerBehaviour extends EntityBehaviour<PlayerEntity> {
@@ -29,8 +30,12 @@ public class PlayerBehaviour extends EntityBehaviour<PlayerEntity> {
             entity.setSwimming(source.asEntity().isSwimming());
         }
         if (source.asEntity() instanceof LivingEntityDuck duck) {
-            // TODO: CopyAngles
             duck.copyLeaningAnglesFrom(((LivingEntityDuck)entity));
         }
     }
+
+    @Override
+    public boolean isEqual(PlayerEntity a, Entity b) {
+        return b instanceof PlayerEntity p && p.getUuid().equals(b.getUuid());
+    }
 }