A long list of fixes for disguises

This commit is contained in:
Sollace 2020-09-24 14:49:02 +02:00
parent 9ba807b3d5
commit f08850e7c2
20 changed files with 275 additions and 79 deletions

View file

@ -52,7 +52,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
if (looked instanceof PlayerEntity) { if (looked instanceof PlayerEntity) {
looked = Pony.of((PlayerEntity)looked) looked = Pony.of((PlayerEntity)looked)
.getSpell(DisguiseSpell.class) .getSpellOrEmpty(DisguiseSpell.class)
.map(DisguiseSpell::getDisguise) .map(DisguiseSpell::getDisguise)
.orElse(looked); .orElse(looked);
} }
@ -64,7 +64,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
player.getEntityWorld().playSound(null, player.getBlockPos(), SoundEvents.ENTITY_PARROT_IMITATE_RAVAGER, SoundCategory.PLAYERS, 1.4F, 0.4F); player.getEntityWorld().playSound(null, player.getBlockPos(), SoundEvents.ENTITY_PARROT_IMITATE_RAVAGER, SoundCategory.PLAYERS, 1.4F, 0.4F);
iplayer.getSpell(DisguiseSpell.class).orElseGet(() -> { iplayer.getSpellOrEmpty(DisguiseSpell.class).orElseGet(() -> {
DisguiseSpell disc = new DisguiseSpell(); DisguiseSpell disc = new DisguiseSpell();
iplayer.setSpell(disc); iplayer.setSpell(disc);

View file

@ -43,7 +43,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
public void apply(Pony player, Hit data) { public void apply(Pony player, Hit data) {
if (player.hasSpell()) { if (player.hasSpell()) {
String current = player.getSpell().getName(); String current = player.getSpell(true).getName();
player.setSpell(Streams.stream(player.getOwner().getItemsHand()) player.setSpell(Streams.stream(player.getOwner().getItemsHand())
.map(SpellRegistry::getKeyFromStack) .map(SpellRegistry::getKeyFromStack)
.filter(i -> i != null && !current.equals(i)) .filter(i -> i != null && !current.equals(i))

View file

@ -43,27 +43,22 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
* Returns null if no such effect exists for this caster. * Returns null if no such effect exists for this caster.
*/ */
@Nullable @Nullable
default <T> T getSpell(@Nullable Class<T> type, boolean update) { default <T extends Spell> T getSpell(@Nullable Class<T> type, boolean update) {
return getPrimarySpellSlot().get(type, update); return getPrimarySpellSlot().get(type, update);
} }
/** /**
* Gets the active effect for this caster updating it if needed. * Gets the active effect for this caster updating it if needed.
*/ */
@Nullable default <T extends Spell> Optional<T> getSpellOrEmpty(Class<T> type, boolean update) {
default Spell getSpell() { return getPrimarySpellSlot().getOrEmpty(type, update);
return getSpell(true);
} }
@SuppressWarnings("unchecked") /**
default <T extends Spell> Optional<T> getSpell(Class<T> type) { * Gets the active effect for this caster updating it if needed.
Spell effect = getSpell(); */
default <T extends Spell> Optional<T> getSpellOrEmpty(Class<T> type) {
if (effect == null || effect.isDead() || !type.isAssignableFrom(effect.getClass())) { return getSpellOrEmpty(type, true);
return Optional.empty();
}
return Optional.of((T)effect);
} }
/** /**

View file

@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.ability.magic;
/** /**
* Magic effects that can be suppressed by other nearby effects. * Magic effects that can be suppressed by other nearby effects.
*/ */
public interface Suppressable { public interface Suppressable extends Spell {
/** /**
* Returns true if this spell is currently still suppressed. * Returns true if this spell is currently still suppressed.

View file

@ -1,7 +1,6 @@
package com.minelittlepony.unicopia.ability.magic.spell; package com.minelittlepony.unicopia.ability.magic.spell;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -16,6 +15,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.CasterUtils; import com.minelittlepony.unicopia.ability.magic.CasterUtils;
import com.minelittlepony.unicopia.ability.magic.Spell; import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.Suppressable; import com.minelittlepony.unicopia.ability.magic.Suppressable;
import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect;
import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.particle.UParticles;
@ -41,7 +41,6 @@ import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.projectile.ShulkerBulletEntity; import net.minecraft.entity.projectile.ShulkerBulletEntity;
import net.minecraft.entity.vehicle.MinecartEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@ -158,6 +157,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
onEntityLoaded(source); onEntityLoaded(source);
} }
@SuppressWarnings("unchecked")
protected void checkAndCreateDisguiseEntity(Caster<?> source) { protected void checkAndCreateDisguiseEntity(Caster<?> source) {
if (entity == null && entityNbt != null) { if (entity == null && entityNbt != null) {
CompoundTag nbt = entityNbt; CompoundTag nbt = entityNbt;
@ -173,11 +173,20 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
nbt.getString("playerName") nbt.getString("playerName")
)), source)).start(); )), source)).start();
} else { } else {
entity = EntityType.loadEntityWithPassengers(nbt, source.getWorld(), e -> { if (source.isClient()) {
e.extinguish(); entity = EntityType.fromTag(nbt).map(type -> type.create(source.getWorld())).orElse(null);
EntityBehaviour.forEntity(entity).ifPresent(behaviour -> {
((EntityBehaviour<Entity>)behaviour).onCreate(entity);
});
} else {
entity = EntityType.loadEntityWithPassengers(nbt, source.getWorld(), e -> {
EntityBehaviour.forEntity(e).ifPresent(behaviour -> {
((EntityBehaviour<Entity>)behaviour).onCreate(e);
});
return e; return e;
}); });
}
} }
onEntityLoaded(source); onEntityLoaded(source);
@ -185,6 +194,8 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
} }
protected void onEntityLoaded(Caster<?> source) { protected void onEntityLoaded(Caster<?> source) {
source.getEntity().calculateDimensions();
if (entity == null) { if (entity == null) {
return; return;
} }
@ -363,9 +374,6 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
} }
entity.noClip = true; entity.noClip = true;
//entity.updateBlocked = true;
//entity.getEntityData().setBoolean("disguise", true);
if (entity instanceof MobEntity) { if (entity instanceof MobEntity) {
((MobEntity)entity).setAiDisabled(true); ((MobEntity)entity).setAiDisabled(true);
@ -380,39 +388,9 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
entity.tick(); entity.tick();
} }
if (entity instanceof ShulkerEntity) { EntityBehaviour.forEntity(entity).ifPresent(b -> {
ShulkerEntity shulker = ((ShulkerEntity)entity); ((EntityBehaviour<Entity>)b).update(source, entity);
});
shulker.yaw = 0;
shulker.prevHeadYaw = 0;
shulker.headYaw = 0;
shulker.prevBodyYaw = 0;
shulker.bodyYaw = 0;
shulker.setAttachedBlock(null);
if (source.isClient() && source instanceof Pony) {
//Pony player = (Pony)source;
float peekAmount = 30;
//if (!owner.isSneaking()) {
//Math.sqrt(Entity.squaredHorizontalLength(owner.getVelocity()));
//peekAmount = (float)MathHelper.clamp(speed * 30, 0, 1);
//}
//peekAmount = player.getInterpolator().interpolate("peek", peekAmount, 5);
shulker.setPeekAmount((int)peekAmount);
}
}
if (entity instanceof MinecartEntity) {
entity.yaw += 90;
entity.pitch = 0;
}
if (source instanceof Pony) { if (source instanceof Pony) {
Pony player = (Pony)source; Pony player = (Pony)source;
@ -487,8 +465,14 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
entityNbt = compound.getCompound("entity"); entityNbt = compound.getCompound("entity");
compound.getString("entityData");
if (entity != null) { if (entity != null) {
entity.fromTag(entityNbt); try {
entity.fromTag(entityNbt);
} catch (Exception ignored) {
// Mojang pls
}
} }
} }
} }

View file

@ -82,7 +82,7 @@ public class DisguiseCommand {
static int reveal(ServerCommandSource source, PlayerEntity player) { static int reveal(ServerCommandSource source, PlayerEntity player) {
Pony iplayer = Pony.of(player); Pony iplayer = Pony.of(player);
iplayer.getSpell(DisguiseSpell.class).ifPresent(disguise -> { iplayer.getSpellOrEmpty(DisguiseSpell.class).ifPresent(disguise -> {
disguise.onDestroyed(iplayer); disguise.onDestroyed(iplayer);
}); });

View file

@ -98,7 +98,7 @@ public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> {
@Override @Override
public void toNBT(CompoundTag compound) { public void toNBT(CompoundTag compound) {
Spell effect = getSpell(); Spell effect = getSpell(true);
if (effect != null) { if (effect != null) {
compound.put("effect", SpellRegistry.toNBT(effect)); compound.put("effect", SpellRegistry.toNBT(effect));

View file

@ -0,0 +1,17 @@
package com.minelittlepony.unicopia.entity.behaviour;
import com.minelittlepony.unicopia.ability.magic.Caster;
import net.minecraft.entity.mob.CreeperEntity;
public class CreeperBehaviour extends EntityBehaviour<CreeperEntity> {
@Override
public void update(Caster<?> source, CreeperEntity entity) {
if (source.getEntity().isSneaking()) {
entity.setFuseSpeed(1);
} else {
entity.setFuseSpeed(-1);
entity.setTarget(null);
entity.getVisibilityCache().clear();
}
}
}

View file

@ -0,0 +1,44 @@
package com.minelittlepony.unicopia.entity.behaviour;
import java.util.Optional;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.util.Registries;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public abstract class EntityBehaviour<T extends Entity> {
private static final Registry<EntityBehaviour<?>> REGISTRY = Registries.createSimple(new Identifier("unicopia", "entity_behaviour"));
public abstract void update(Caster<?> source, T entity);
public void onCreate(T entity) {
entity.extinguish();
}
public static <T extends Entity> void register(Supplier<EntityBehaviour<T>> behaviour, EntityType<?>... types) {
for (EntityType<?> type : types) {
Registry.register(REGISTRY, EntityType.getId(type), behaviour.get());
}
}
public static Optional<EntityBehaviour<?>> forEntity(@Nullable Entity entity) {
if (entity == null) {
return Optional.empty();
}
return REGISTRY.getOrEmpty(EntityType.getId(entity.getType()));
}
static {
register(ShulkerBehaviour::new, EntityType.SHULKER);
register(CreeperBehaviour::new, EntityType.CREEPER);
register(MinecartBehaviour::new, EntityType.CHEST_MINECART, EntityType.COMMAND_BLOCK_MINECART, EntityType.FURNACE_MINECART, EntityType.HOPPER_MINECART, EntityType.MINECART, EntityType.SPAWNER_MINECART, EntityType.TNT_MINECART);
}
}

View file

@ -0,0 +1,38 @@
package com.minelittlepony.unicopia.entity.behaviour;
import com.minelittlepony.unicopia.ability.magic.Caster;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.sound.MovingMinecartSoundInstance;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
public class MinecartBehaviour extends EntityBehaviour<AbstractMinecartEntity> {
@Override
public void onCreate(AbstractMinecartEntity entity) {
super.onCreate(entity);
if (entity.world.isClient) {
MinecraftClient.getInstance().getSoundManager().play(new MovingMinecartSoundInstance(entity));
}
}
@Override
public void update(Caster<?> source, AbstractMinecartEntity entity) {
entity.yaw -= 90;
entity.prevYaw -= 90;
entity.pitch = 0;
entity.prevPitch = 0;
if (source.getEntity() instanceof LivingEntity) {
int hurt = ((LivingEntity)source.getEntity()).hurtTime;
if (hurt > 0) {
entity.setDamageWobbleTicks(hurt);
entity.setDamageWobbleStrength(1);
entity.setDamageWobbleSide(20 + (int)source.getEntity().fallDistance / 10);
}
}
}
}

View file

@ -0,0 +1,47 @@
package com.minelittlepony.unicopia.entity.behaviour;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.mixin.MixinShulkerEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.mob.ShulkerEntity;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.MathHelper;
public class ShulkerBehaviour extends EntityBehaviour<ShulkerEntity> {
@Override
public void update(Caster<?> source, ShulkerEntity shulker) {
shulker.yaw = 0;
shulker.prevBodyYaw = 0;
shulker.bodyYaw = 0;
shulker.setAttachedBlock(null);
if (source instanceof Pony) {
Pony player = (Pony)source;
float peekAmount = 30;
double speed = !source.getEntity().isSneaking() ? 0.29 : 0;
speed += Math.sqrt(Entity.squaredHorizontalLength(source.getEntity().getVelocity())) * 2;
peekAmount = (float)MathHelper.clamp(speed, 0, 1);
peekAmount = ((Pony)source).getInterpolator().interpolate("peek", peekAmount, 5);
MixinShulkerEntity mx = (MixinShulkerEntity)shulker;
mx.setPrevOpenProgress(mx.getOpenProgress());
mx.setOpenProgress(peekAmount);
if (player.sneakingChanged()) {
shulker.setPeekAmount((int)(peekAmount / 0.01F));
} else if (peekAmount > 0.2 && shulker.getPeekAmount() == 0) {
if (shulker.isAlive() && shulker.world.random.nextInt(1000) < shulker.ambientSoundChance++) {
shulker.ambientSoundChance = -shulker.getMinAmbientSoundDelay();
shulker.playSound(SoundEvents.ENTITY_SHULKER_AMBIENT, 1, 1);
}
}
}
}
}

View file

@ -62,7 +62,7 @@ public final class PlayerDimensions {
private float calculateTargetEyeHeight() { private float calculateTargetEyeHeight() {
if (pony.hasSpell()) { if (pony.hasSpell()) {
Spell effect = pony.getSpell(); Spell effect = pony.getSpell(true);
if (!effect.isDead() && effect instanceof HeightPredicate) { if (!effect.isDead() && effect instanceof HeightPredicate) {
float val = ((HeightPredicate)effect).getTargetEyeHeight(pony); float val = ((HeightPredicate)effect).getTargetEyeHeight(pony);
if (val > 0) { if (val > 0) {
@ -80,7 +80,7 @@ public final class PlayerDimensions {
private float calculateTargetBodyHeight() { private float calculateTargetBodyHeight() {
if (pony.hasSpell()) { if (pony.hasSpell()) {
Spell effect = pony.getSpell(); Spell effect = pony.getSpell(true);
if (!effect.isDead() && effect instanceof HeightPredicate) { if (!effect.isDead() && effect instanceof HeightPredicate) {
float val = ((HeightPredicate)effect).getTargetBodyHeight(pony); float val = ((HeightPredicate)effect).getTargetBodyHeight(pony);
if (val > 0) { if (val > 0) {

View file

@ -48,7 +48,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
} }
if (pony.hasSpell()) { if (pony.hasSpell()) {
Spell effect = pony.getSpell(); Spell effect = pony.getSpell(true);
if (!effect.isDead() && effect instanceof FlightPredicate) { if (!effect.isDead() && effect instanceof FlightPredicate) {
return ((FlightPredicate)effect).checkCanFly(pony); return ((FlightPredicate)effect).checkCanFly(pony);
} }

View file

@ -73,6 +73,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
private boolean dirty; private boolean dirty;
private boolean speciesSet; private boolean speciesSet;
private boolean speciesPersisted; private boolean speciesPersisted;
private boolean prevSneaking;
@Nullable @Nullable
private Race clientPreferredRace; private Race clientPreferredRace;
@ -101,6 +102,10 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
return Race.fromId(getOwner().getDataTracker().get(RACE)); return Race.fromId(getOwner().getDataTracker().get(RACE));
} }
public boolean sneakingChanged() {
return entity.isSneaking() != prevSneaking;
}
@Override @Override
public void setSpecies(Race race) { public void setSpecies(Race race) {
race = race.validate(entity); race = race.validate(entity);
@ -245,6 +250,8 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
if (dirty) { if (dirty) {
sendCapabilities(true); sendCapabilities(true);
} }
prevSneaking = entity.isSneaking();
} }
public float onImpact(float distance) { public float onImpact(float distance) {
@ -265,7 +272,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
@Override @Override
public boolean onProjectileImpact(ProjectileEntity projectile) { public boolean onProjectileImpact(ProjectileEntity projectile) {
if (hasSpell()) { if (hasSpell()) {
Spell effect = getSpell(); Spell effect = getSpell(true);
if (!effect.isDead() && effect.handleProjectileImpact(projectile)) { if (!effect.isDead() && effect.handleProjectileImpact(projectile)) {
return true; return true;
} }
@ -323,7 +330,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
compound.put("powers", powers.toNBT()); compound.put("powers", powers.toNBT());
compound.put("gravity", gravity.toNBT()); compound.put("gravity", gravity.toNBT());
Spell effect = getSpell(); Spell effect = getSpell(true);
if (effect != null) { if (effect != null) {
compound.put("effect", SpellRegistry.toNBT(effect)); compound.put("effect", SpellRegistry.toNBT(effect));
@ -346,7 +353,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
@Override @Override
public void copyFrom(Pony oldPlayer) { public void copyFrom(Pony oldPlayer) {
speciesPersisted = oldPlayer.speciesPersisted; speciesPersisted = oldPlayer.speciesPersisted;
setSpell(oldPlayer.getSpell()); setSpell(oldPlayer.getSpell(true));
setSpecies(oldPlayer.getSpecies()); setSpecies(oldPlayer.getSpecies());
setDirty(); setDirty();
} }

View file

@ -0,0 +1,18 @@
package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.entity.mob.ShulkerEntity;
@Mixin(ShulkerEntity.class)
public interface MixinShulkerEntity {
@Accessor
float getOpenProgress();
@Accessor
void setOpenProgress(float value);
@Accessor
float getPrevOpenProgress();
@Accessor
void setPrevOpenProgress(float value);
}

View file

@ -0,0 +1,30 @@
package com.minelittlepony.unicopia.mixin;
import javax.annotation.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.ai.TargetPredicate;
@Mixin(TargetPredicate.class)
abstract class MixinTargetPredicate {
@Inject(method = "test", at = @At("HEAD"), cancellable = true)
public void onTest(@Nullable LivingEntity baseEntity, LivingEntity targetEntity, CallbackInfoReturnable<Boolean> info) {
Equine<?> eq = Equine.of(targetEntity);
if (eq instanceof Pony) {
((Pony)eq).getSpellOrEmpty(DisguiseSpell.class).ifPresent(spell -> {
if (spell.getDisguise() == baseEntity) {
info.setReturnValue(false);
}
});
}
}
}

View file

@ -57,7 +57,7 @@ abstract class MixinEntityRenderDispatcher {
} }
((EntityRenderDispatcher)(Object)this).render(e, x, y, z, yaw, tickDelta, matrices, vertexConsumers, light); ((EntityRenderDispatcher)(Object)this).render(e, x, y, z, e.yaw, tickDelta, matrices, vertexConsumers, light);
} }
} }

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.network; package com.minelittlepony.unicopia.network;
import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
@ -54,8 +56,18 @@ public class EffectSync {
return effect != null; return effect != null;
} }
public <T extends Spell> Optional<T> getOrEmpty(Class<T> type, boolean update) {
T effect = get(type, update);
if (effect == null || effect.isDead()) {
return Optional.empty();
}
return Optional.of(effect);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <E> E get(Class<E> type, boolean update) { public <E extends Spell> E get(Class<E> type, boolean update) {
if (!update) { if (!update) {
if (effect == null || type == null || type.isAssignableFrom(effect.getClass())) { if (effect == null || type == null || type.isAssignableFrom(effect.getClass())) {
return (E)effect; return (E)effect;

View file

@ -111,7 +111,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
@Override @Override
public Affinity getAffinity() { public Affinity getAffinity() {
return hasSpell() ? Affinity.NEUTRAL : getSpell().getAffinity(); return hasSpell() ? Affinity.NEUTRAL : getSpell(true).getAffinity();
} }
@Override @Override
@ -178,14 +178,16 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
lastBlockPos = getBlockPos(); lastBlockPos = getBlockPos();
} }
if (getSpell().isDead()) { Spell spell = getSpell(true);
if (spell.isDead()) {
remove(); remove();
} else { } else {
getSpell().update(this); spell.update(this);
}
if (world.isClient()) { if (world.isClient()) {
getSpell().render(this); spell.render(this);
}
} }
} }
@ -247,7 +249,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
super.writeCustomDataToTag(compound); super.writeCustomDataToTag(compound);
if (hasSpell()) { if (hasSpell()) {
compound.put("effect", SpellRegistry.toNBT(getSpell())); compound.put("effect", SpellRegistry.toNBT(getSpell(true)));
} }
} }
@ -266,7 +268,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
protected void onHitBlock(BlockHitResult hit) { protected void onHitBlock(BlockHitResult hit) {
if (hasSpell()) { if (hasSpell()) {
Spell effect = getSpell(); Spell effect = getSpell(true);
if (effect instanceof ThrowableSpell) { if (effect instanceof ThrowableSpell) {
((ThrowableSpell)effect).onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos())); ((ThrowableSpell)effect).onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos()));

View file

@ -12,7 +12,9 @@
"MixinLivingEntity", "MixinLivingEntity",
"MixinPlayerEntity", "MixinPlayerEntity",
"MixinProjectileEntity", "MixinProjectileEntity",
"MixinServerPlayerEntity" "MixinServerPlayerEntity",
"MixinShulkerEntity",
"MixinTargetPredicate"
], ],
"client": [ "client": [
"client.MixinCamera", "client.MixinCamera",