From 1fdf88dce7a524799fc1f90289a1ae8456e8d045 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 6 Feb 2024 16:31:49 +0000 Subject: [PATCH] Strip alicorn amulet effects when doing the mind swap spell --- .../unicopia/ability/magic/spell/Spell.java | 1 + .../ability/magic/spell/ThrowableSpell.java | 31 ++++++---- .../spell/effect/CustomisedSpellType.java | 7 ++- .../magic/spell/effect/MindSwapSpell.java | 61 +++++++++++++++---- .../unicopia/item/AlicornAmuletItem.java | 13 ++-- 5 files changed, 80 insertions(+), 33 deletions(-) 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 55a5f3bf..2472b348 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 @@ -81,6 +81,7 @@ public interface Spell extends NbtSerialisable, Affine { * Gets the default form of this spell used to apply to a caster. * @param caster The caster currently fueling this spell */ + @Nullable default Spell prepareForCast(Caster caster, CastingMethod method) { return this; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ThrowableSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ThrowableSpell.java index 49cf0a2e..20c4c9b0 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ThrowableSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ThrowableSpell.java @@ -59,21 +59,26 @@ public final class ThrowableSpell extends AbstractDelegatingSpell { caster.playSound(USounds.SPELL_CAST_SHOOT, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F)); - if (!caster.isClient()) { - MagicProjectileEntity projectile = UEntities.MAGIC_BEAM.create(world); - projectile.setPosition(entity.getX(), entity.getEyeY() - 0.1F, entity.getZ()); - projectile.setOwner(entity); - projectile.setItem(UItems.GEMSTONE.getDefaultStack(spell.getType())); - spell.prepareForCast(caster, CastingMethod.STORED).apply(projectile); - projectile.setVelocity(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, divergance); - projectile.setNoGravity(true); - configureProjectile(projectile, caster); - world.spawnEntity(projectile); - - return Optional.of(projectile); + if (caster.isClient()) { + return Optional.empty(); } - return Optional.empty(); + Spell s = spell.prepareForCast(caster, CastingMethod.STORED); + if (s == null) { + return Optional.empty(); + } + + MagicProjectileEntity projectile = UEntities.MAGIC_BEAM.create(world); + projectile.setPosition(entity.getX(), entity.getEyeY() - 0.1F, entity.getZ()); + projectile.setOwner(entity); + projectile.setItem(UItems.GEMSTONE.getDefaultStack(spell.getType())); + s.apply(projectile); + projectile.setVelocity(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, divergance); + projectile.setNoGravity(true); + configureProjectile(projectile, caster); + world.spawnEntity(projectile); + + return Optional.of(projectile); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java index f3c8991c..4c346401 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java @@ -39,8 +39,11 @@ public record CustomisedSpellType ( } T spell = create(); - if (spell != null && spell.prepareForCast(caster, method).apply(caster)) { - return spell; + if (spell != null) { + Spell s = spell.prepareForCast(caster, method); + if (s != null && s.apply(caster)) { + return spell; + } } return null; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/MindSwapSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/MindSwapSpell.java index edf4ffa4..4b2f9cb0 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/MindSwapSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/MindSwapSpell.java @@ -3,6 +3,8 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; import java.util.Optional; import java.util.UUID; +import org.jetbrains.annotations.Nullable; + import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod; @@ -13,6 +15,8 @@ import com.minelittlepony.unicopia.entity.EntityReference; import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.behaviour.EntitySwap; import com.minelittlepony.unicopia.entity.behaviour.Inventory; +import com.minelittlepony.unicopia.item.AlicornAmuletItem; +import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.ProjectileDelegate; @@ -38,8 +42,12 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti super(type); } + @Nullable @Override public Spell prepareForCast(Caster caster, CastingMethod method) { + if (caster.asEntity() instanceof LivingEntity living && isValidTarget(living)) { + return null; + } return method == CastingMethod.STAFF ? toThrowable() : this; } @@ -50,21 +58,28 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti counterpart.ifPresent(caster.asWorld(), e -> { initialized = false; LivingEntity master = caster.getMaster(); - Caster other = Caster.of(e).get(); + other.getSpellSlot().removeIf(SpellType.MIMIC, true); caster.getSpellSlot().removeIf(getType(), true); - if (master instanceof ServerPlayerEntity sMaster && e instanceof ServerPlayerEntity sE) { - swapPlayerData(sMaster, sE); + if (!isValidTarget(master) || !isValidTarget(e)) { + master.damage(caster.asWorld().getDamageSources().magic(), Float.MAX_VALUE); + master.setHealth(0); + e.damage(caster.asWorld().getDamageSources().magic(), Float.MAX_VALUE); + e.setHealth(0); } else { - EntitySwap.ALL.accept(e, master); - Inventory.swapInventories( - e, myStoredInventory.or(() -> Inventory.of(e)), - master, theirStoredInventory.or(() -> Inventory.of(master)), - a -> {}, - a -> {} - ); + if (master instanceof ServerPlayerEntity sMaster && e instanceof ServerPlayerEntity sE) { + swapPlayerData(sMaster, sE); + } else { + EntitySwap.ALL.accept(e, master); + Inventory.swapInventories( + e, myStoredInventory.or(() -> Inventory.of(e)), + master, theirStoredInventory.or(() -> Inventory.of(master)), + a -> {}, + a -> {} + ); + } } other.playSound(USounds.SPELL_MINDSWAP_UNSWAP, 0.2F); @@ -84,8 +99,20 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti if (!caster.isClient()) { if (!initialized) { counterpart.ifPresent(caster.asWorld(), e -> { + if (!isValidTarget(e)) { + counterpart.set(null); + setDead(); + return; + } + LivingEntity master = caster.getMaster(); + if (!isValidTarget(master)) { + counterpart.set(null); + setDead(); + return; + } + setDisguise(e); Caster other = Caster.of(e).get(); MimicSpell mimic = SpellType.MIMIC.withTraits().apply(other, CastingMethod.INDIRECT); @@ -144,7 +171,9 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti @Override public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) { Caster.of(projectile.getMaster()).ifPresent(master -> { - if (getTypeAndTraits().apply(master, CastingMethod.DIRECT) instanceof HomingSpell homing) { + if (hit.getEntity() instanceof LivingEntity living + && isValidTarget(living) + && getTypeAndTraits().apply(master, CastingMethod.DIRECT) instanceof HomingSpell homing) { homing.setTarget(hit.getEntity()); } }); @@ -152,13 +181,19 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti @Override public boolean setTarget(Entity target) { - if (target instanceof LivingEntity living && Caster.of(target).isPresent()) { + if (target instanceof LivingEntity living) { counterpart.set(living); } return false; } + protected boolean isValidTarget(LivingEntity entity) { + return Caster.of(entity).isPresent() + //&& !UItems.ALICORN_AMULET.isApplicable(entity) + && !UItems.PEARL_NECKLACE.isApplicable(entity); + } + @Override public void toNBT(NbtCompound compound) { super.toNBT(compound); @@ -178,6 +213,8 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti } private static void swapPlayerData(ServerPlayerEntity a, ServerPlayerEntity b) { + AlicornAmuletItem.updateAttributes(Living.living(a), 0); + AlicornAmuletItem.updateAttributes(Living.living(b), 0); final GameMode aMode = a.interactionManager.getGameMode(); final GameMode bMode = b.interactionManager.getGameMode(); diff --git a/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java b/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java index 7a4eb3f3..55d64128 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java @@ -169,8 +169,12 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab wearer.updateVelocity(); } - EFFECT_SCALES.keySet().forEach(attribute -> { - wearer.updateAttributeModifier(EFFECT_UUID, attribute, 0F, EFFECT_FACTORY, false); + updateAttributes(wearer, 0); + } + + public static void updateAttributes(Living wearer, float effectScale) { + EFFECT_SCALES.entrySet().forEach(attribute -> { + wearer.updateAttributeModifier(EFFECT_UUID, attribute.getKey(), attribute.getValue() * effectScale, EFFECT_FACTORY, false); }); } @@ -291,10 +295,7 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab // every 1 second, update modifiers if (fullSecond) { - EFFECT_SCALES.entrySet().forEach(attribute -> { - float seconds = (float)attachedTicks / ItemTracker.SECONDS; - living.updateAttributeModifier(EFFECT_UUID, attribute.getKey(), attribute.getValue() * seconds, EFFECT_FACTORY, false); - }); + updateAttributes(living, (float)attachedTicks / ItemTracker.SECONDS); } }