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.
* @param caster The caster currently fueling this spell
*/
@Nullable
default Spell prepareForCast(Caster<?> caster, CastingMethod method) {
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));
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

View file

@ -39,8 +39,11 @@ public record CustomisedSpellType<T extends Spell> (
}
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;

View file

@ -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();

View file

@ -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);
}
}