Strip alicorn amulet effects when doing the mind swap spell

This commit is contained in:
Sollace 2024-02-06 16:31:49 +00:00
parent 2f68d4409a
commit 1fdf88dce7
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
5 changed files with 80 additions and 33 deletions

View file

@ -81,6 +81,7 @@ public interface Spell extends NbtSerialisable, Affine {
* Gets the default form of this spell used to apply to a caster. * Gets the default form of this spell used to apply to a caster.
* @param caster The caster currently fueling this spell * @param caster The caster currently fueling this spell
*/ */
@Nullable
default Spell prepareForCast(Caster<?> caster, CastingMethod method) { default Spell prepareForCast(Caster<?> caster, CastingMethod method) {
return this; return this;
} }

View file

@ -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)); caster.playSound(USounds.SPELL_CAST_SHOOT, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F));
if (!caster.isClient()) { if (caster.isClient()) {
MagicProjectileEntity projectile = UEntities.MAGIC_BEAM.create(world); return Optional.empty();
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);
} }
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 @Override

View file

@ -39,8 +39,11 @@ public record CustomisedSpellType<T extends Spell> (
} }
T spell = create(); T spell = create();
if (spell != null && spell.prepareForCast(caster, method).apply(caster)) { if (spell != null) {
return spell; Spell s = spell.prepareForCast(caster, method);
if (s != null && s.apply(caster)) {
return spell;
}
} }
return null; return null;

View file

@ -3,6 +3,8 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod; 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.Living;
import com.minelittlepony.unicopia.entity.behaviour.EntitySwap; import com.minelittlepony.unicopia.entity.behaviour.EntitySwap;
import com.minelittlepony.unicopia.entity.behaviour.Inventory; 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.MagicProjectileEntity;
import com.minelittlepony.unicopia.projectile.ProjectileDelegate; import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
@ -38,8 +42,12 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
super(type); super(type);
} }
@Nullable
@Override @Override
public Spell prepareForCast(Caster<?> caster, CastingMethod method) { public Spell prepareForCast(Caster<?> caster, CastingMethod method) {
if (caster.asEntity() instanceof LivingEntity living && isValidTarget(living)) {
return null;
}
return method == CastingMethod.STAFF ? toThrowable() : this; return method == CastingMethod.STAFF ? toThrowable() : this;
} }
@ -50,21 +58,28 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
counterpart.ifPresent(caster.asWorld(), e -> { counterpart.ifPresent(caster.asWorld(), e -> {
initialized = false; initialized = false;
LivingEntity master = caster.getMaster(); LivingEntity master = caster.getMaster();
Caster<?> other = Caster.of(e).get(); Caster<?> other = Caster.of(e).get();
other.getSpellSlot().removeIf(SpellType.MIMIC, true); other.getSpellSlot().removeIf(SpellType.MIMIC, true);
caster.getSpellSlot().removeIf(getType(), true); caster.getSpellSlot().removeIf(getType(), true);
if (master instanceof ServerPlayerEntity sMaster && e instanceof ServerPlayerEntity sE) { if (!isValidTarget(master) || !isValidTarget(e)) {
swapPlayerData(sMaster, sE); 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 { } else {
EntitySwap.ALL.accept(e, master); if (master instanceof ServerPlayerEntity sMaster && e instanceof ServerPlayerEntity sE) {
Inventory.swapInventories( swapPlayerData(sMaster, sE);
e, myStoredInventory.or(() -> Inventory.of(e)), } else {
master, theirStoredInventory.or(() -> Inventory.of(master)), EntitySwap.ALL.accept(e, master);
a -> {}, Inventory.swapInventories(
a -> {} e, myStoredInventory.or(() -> Inventory.of(e)),
); master, theirStoredInventory.or(() -> Inventory.of(master)),
a -> {},
a -> {}
);
}
} }
other.playSound(USounds.SPELL_MINDSWAP_UNSWAP, 0.2F); other.playSound(USounds.SPELL_MINDSWAP_UNSWAP, 0.2F);
@ -84,8 +99,20 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
if (!caster.isClient()) { if (!caster.isClient()) {
if (!initialized) { if (!initialized) {
counterpart.ifPresent(caster.asWorld(), e -> { counterpart.ifPresent(caster.asWorld(), e -> {
if (!isValidTarget(e)) {
counterpart.set(null);
setDead();
return;
}
LivingEntity master = caster.getMaster(); LivingEntity master = caster.getMaster();
if (!isValidTarget(master)) {
counterpart.set(null);
setDead();
return;
}
setDisguise(e); setDisguise(e);
Caster<?> other = Caster.of(e).get(); Caster<?> other = Caster.of(e).get();
MimicSpell mimic = SpellType.MIMIC.withTraits().apply(other, CastingMethod.INDIRECT); MimicSpell mimic = SpellType.MIMIC.withTraits().apply(other, CastingMethod.INDIRECT);
@ -144,7 +171,9 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
@Override @Override
public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) { public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) {
Caster.of(projectile.getMaster()).ifPresent(master -> { 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()); homing.setTarget(hit.getEntity());
} }
}); });
@ -152,13 +181,19 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
@Override @Override
public boolean setTarget(Entity target) { public boolean setTarget(Entity target) {
if (target instanceof LivingEntity living && Caster.of(target).isPresent()) { if (target instanceof LivingEntity living) {
counterpart.set(living); counterpart.set(living);
} }
return false; return false;
} }
protected boolean isValidTarget(LivingEntity entity) {
return Caster.of(entity).isPresent()
//&& !UItems.ALICORN_AMULET.isApplicable(entity)
&& !UItems.PEARL_NECKLACE.isApplicable(entity);
}
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound) {
super.toNBT(compound); super.toNBT(compound);
@ -178,6 +213,8 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
} }
private static void swapPlayerData(ServerPlayerEntity a, ServerPlayerEntity b) { 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 aMode = a.interactionManager.getGameMode();
final GameMode bMode = b.interactionManager.getGameMode(); final GameMode bMode = b.interactionManager.getGameMode();

View file

@ -169,8 +169,12 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
wearer.updateVelocity(); wearer.updateVelocity();
} }
EFFECT_SCALES.keySet().forEach(attribute -> { updateAttributes(wearer, 0);
wearer.updateAttributeModifier(EFFECT_UUID, attribute, 0F, EFFECT_FACTORY, false); }
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 // every 1 second, update modifiers
if (fullSecond) { if (fullSecond) {
EFFECT_SCALES.entrySet().forEach(attribute -> { updateAttributes(living, (float)attachedTicks / ItemTracker.SECONDS);
float seconds = (float)attachedTicks / ItemTracker.SECONDS;
living.updateAttributeModifier(EFFECT_UUID, attribute.getKey(), attribute.getValue() * seconds, EFFECT_FACTORY, false);
});
} }
} }