From f10dcb59ec6f07fd74ebc4c55894b9d50170ea1c Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 22 Dec 2021 16:43:06 +0200 Subject: [PATCH] Distance the disguises system from the magic system and make it possible to have different diguise spells --- .../ability/ChangelingDisguiseAbility.java | 15 +- .../ability/magic/SpellPredicate.java | 3 + .../magic/spell/AbstractDisguiseSpell.java | 76 ++++ .../magic/spell/ChangelingDisguiseSpell.java | 98 ++++ .../ability/magic/spell/DisguiseSpell.java | 232 ---------- .../ability/magic/spell/effect/SpellType.java | 5 +- .../unicopia/client/gui/UHud.java | 8 +- .../client/render/WorldRenderDelegate.java | 10 +- .../unicopia/command/DisguiseCommand.java | 8 +- .../unicopia/entity/Living.java | 4 +- .../entity/behaviour/AxolotlBehaviour.java | 3 +- .../entity/behaviour/BeeBehaviour.java | 5 +- .../entity/behaviour/BlazeBehaviour.java | 5 +- .../entity/behaviour/ChickenBehaviour.java | 3 +- .../entity/behaviour/CreeperBehaviour.java | 3 +- .../unicopia/entity/behaviour/Disguise.java | 430 ++++-------------- .../entity/behaviour/EndermanBehaviour.java | 3 +- .../entity/behaviour/EntityAppearance.java | 399 ++++++++++++++++ .../entity/behaviour/EntityBehaviour.java | 9 +- .../behaviour/FallingBlockBehaviour.java | 7 +- .../entity/behaviour/GhastBehaviour.java | 3 +- .../entity/behaviour/HoppingBehaviour.java | 3 +- .../entity/behaviour/MinecartBehaviour.java | 5 +- .../entity/behaviour/MobBehaviour.java | 3 +- .../entity/behaviour/PlayerBehaviour.java | 3 +- .../behaviour/RangedAttackBehaviour.java | 3 +- .../entity/behaviour/SheepBehaviour.java | 3 +- .../entity/behaviour/ShulkerBehaviour.java | 5 +- .../entity/behaviour/SilverfishBehaviour.java | 3 +- .../SpellcastingIllagerBehaviour.java | 5 +- .../entity/behaviour/SteedBehaviour.java | 3 +- .../entity/behaviour/TraderBehaviour.java | 3 +- .../behaviour/WaterCreatureBehaviour.java | 3 +- .../unicopia/entity/player/PlayerCamera.java | 8 +- .../unicopia/entity/player/PlayerPhysics.java | 9 +- .../unicopia/mixin/MixinLivingEntity.java | 18 +- .../unicopia/mixin/MixinTargetPredicate.java | 4 +- .../unicopia/mixin/MixinWorld.java | 4 +- 38 files changed, 731 insertions(+), 683 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java create mode 100644 src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ChangelingDisguiseSpell.java delete mode 100644 src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java index b8c27e45..0b443adc 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java @@ -4,10 +4,11 @@ package com.minelittlepony.unicopia.ability; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.ability.data.Hit; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; +import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; -import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.util.RayTraceHelper; @@ -46,9 +47,9 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility { Entity looked = trace.getEntity().map(e -> { return e instanceof PlayerEntity ? Pony.of((PlayerEntity)e) .getSpellSlot() - .get(SpellType.DISGUISE, true) - .map(DisguiseSpell::getDisguise) - .map(Disguise::getAppearance) + .get(SpellPredicate.IS_DISGUISE, true) + .map(AbstractDisguiseSpell::getDisguise) + .map(EntityAppearance::getAppearance) .orElse(e) : e; }).orElseGet(() -> trace.getBlockPos().map(pos -> { if (!iplayer.getWorld().isAir(pos)) { @@ -59,8 +60,8 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility { player.getEntityWorld().playSound(null, player.getBlockPos(), SoundEvents.ENTITY_PARROT_IMITATE_RAVAGER, SoundCategory.PLAYERS, 1.4F, 0.4F); - iplayer.getSpellSlot().get(SpellType.DISGUISE, true) - .orElseGet(() -> SpellType.DISGUISE.apply(iplayer, SpellTraits.EMPTY)) + iplayer.getSpellSlot().get(SpellType.CHANGELING_DISGUISE, true) + .orElseGet(() -> SpellType.CHANGELING_DISGUISE.apply(iplayer, SpellTraits.EMPTY)) .setDisguise(looked); if (!player.isCreative()) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellPredicate.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellPredicate.java index cf1e58cf..9c0be101 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellPredicate.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellPredicate.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.ability.magic; import java.util.function.Predicate; +import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell; import com.minelittlepony.unicopia.ability.magic.spell.Spell; @@ -10,6 +11,8 @@ public interface SpellPredicate extends Predicate { SpellPredicate HAS_PROJECTILE_EVENTS = s -> s instanceof ProjectileSpell; + SpellPredicate IS_DISGUISE = s -> s instanceof AbstractDisguiseSpell; + default boolean isOn(Caster caster) { return caster.getSpellSlot().get(this, false).isPresent(); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java new file mode 100644 index 00000000..e6e03455 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java @@ -0,0 +1,76 @@ +package com.minelittlepony.unicopia.ability.magic.spell; + +import java.util.Optional; + +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.spell.effect.AbstractSpell; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.projectile.ProjectileImpactListener; + +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.nbt.NbtCompound; + +/** + * Shapeshifts the player. + *

+ */ +public abstract class AbstractDisguiseSpell extends AbstractSpell implements Disguise, ProjectileImpactListener { + + private final EntityAppearance disguise = new EntityAppearance(); + + public AbstractDisguiseSpell(SpellType type, SpellTraits traits) { + super(type, traits); + } + + @Override + public void onDestroyed(Caster caster) { + caster.getEntity().calculateDimensions(); + caster.getEntity().setInvisible(false); + if (caster instanceof Pony) { + ((Pony) caster).setInvisible(false); + } + disguise.remove(); + } + + @Override + public EntityAppearance getDisguise() { + return disguise; + } + + @Override + public boolean onProjectileImpact(ProjectileEntity projectile) { + return disguise.getAppearance() == projectile; + } + + @Override + public boolean tick(Caster source, Situation situation) { + return situation == Situation.BODY && update(source, true); + } + + @Override + public void setDead() { + super.setDead(); + disguise.remove(); + } + + @Override + public void toNBT(NbtCompound compound) { + super.toNBT(compound); + disguise.toNBT(compound); + } + + @Override + public void fromNBT(NbtCompound compound) { + super.fromNBT(compound); + disguise.fromNBT(compound); + } + + @Override + public Optional getAppearance() { + return Optional.ofNullable(disguise); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ChangelingDisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ChangelingDisguiseSpell.java new file mode 100644 index 00000000..192d9412 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ChangelingDisguiseSpell.java @@ -0,0 +1,98 @@ +package com.minelittlepony.unicopia.ability.magic.spell; + +import java.util.Optional; + +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.Suppressable; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.particle.MagicParticleEffect; +import com.minelittlepony.unicopia.particle.UParticles; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.nbt.NbtCompound; + +/** + * Shapeshifts the player. + *

+ * Internal. Used by the changeling ability. + */ +public class ChangelingDisguiseSpell extends AbstractDisguiseSpell implements Suppressable { + + private int suppressionCounter; + + public ChangelingDisguiseSpell(SpellType type, SpellTraits traits) { + super(type, traits); + } + + @Override + public boolean isVulnerable(Caster otherSource, Spell other) { + return suppressionCounter <= otherSource.getLevel().get(); + } + + @Override + public void onSuppressed(Caster otherSource, float time) { + time /= getTraits().getOrDefault(Trait.STRENGTH, 1); + suppressionCounter = (int)(100 * time); + setDirty(); + } + + @Override + public boolean isSuppressed() { + return suppressionCounter > 0; + } + + @Override + public boolean update(Caster source, boolean tick) { + if (source.isClient()) { + if (isSuppressed()) { + source.spawnParticles(MagicParticleEffect.UNICORN, 5); + source.spawnParticles(UParticles.CHANGELING_MAGIC, 5); + } else if (source.getWorld().random.nextInt(30) == 0) { + source.spawnParticles(UParticles.CHANGELING_MAGIC, 2); + } + } + + LivingEntity owner = source.getMaster(); + + Entity entity = getDisguise().getAppearance(); + + if (isSuppressed()) { + suppressionCounter--; + + owner.setInvisible(false); + if (source instanceof Pony) { + ((Pony)source).setInvisible(false); + } + + if (entity != null) { + entity.setInvisible(true); + entity.setPos(entity.getX(), Integer.MIN_VALUE, entity.getY()); + } + + return true; + } + + return super.update(source, tick); + } + + @Override + public void toNBT(NbtCompound compound) { + super.toNBT(compound); + compound.putInt("suppressionCounter", suppressionCounter); + } + + @Override + public void fromNBT(NbtCompound compound) { + super.fromNBT(compound); + suppressionCounter = compound.getInt("suppressionCounter"); + } + + @Override + public Optional getAppearance() { + return isSuppressed() ? Optional.empty() : super.getAppearance(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java deleted file mode 100644 index 7b864297..00000000 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java +++ /dev/null @@ -1,232 +0,0 @@ -package com.minelittlepony.unicopia.ability.magic.spell; - -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import com.minelittlepony.unicopia.FlightType; -import com.minelittlepony.unicopia.Owned; -import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.Suppressable; -import com.minelittlepony.unicopia.ability.magic.spell.effect.AbstractSpell; -import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; -import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; -import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; -import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour; -import com.minelittlepony.unicopia.entity.behaviour.Disguise; -import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.entity.player.PlayerDimensions; -import com.minelittlepony.unicopia.particle.MagicParticleEffect; -import com.minelittlepony.unicopia.particle.UParticles; -import com.minelittlepony.unicopia.projectile.ProjectileImpactListener; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityDimensions; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.data.TrackedData; -import net.minecraft.entity.mob.MobEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.projectile.ProjectileEntity; -import net.minecraft.nbt.NbtCompound; - -/** - * Shapeshifts the player. - *

- * Internal. Used by the changeling ability. - */ -public class DisguiseSpell extends AbstractSpell implements Suppressable, FlightType.Provider, PlayerDimensions.Provider, ProjectileImpactListener { - - private final Disguise disguise = new Disguise(); - - private int suppressionCounter; - - public DisguiseSpell(SpellType type, SpellTraits traits) { - super(type, traits); - } - - @Override - public boolean isVulnerable(Caster otherSource, Spell other) { - return suppressionCounter <= otherSource.getLevel().get(); - } - - @Override - public void onDestroyed(Caster caster) { - caster.getEntity().calculateDimensions(); - caster.getEntity().setInvisible(false); - if (caster instanceof Pony) { - ((Pony) caster).setInvisible(false); - } - disguise.remove(); - } - - @Override - public void onSuppressed(Caster otherSource, float time) { - time /= getTraits().getOrDefault(Trait.STRENGTH, 1); - suppressionCounter = (int)(100 * time); - setDirty(); - } - - @Override - public boolean isSuppressed() { - return suppressionCounter > 0; - } - - public Disguise getDisguise() { - return disguise; - } - - public DisguiseSpell setDisguise(@Nullable Entity entity) { - if (entity == disguise.getAppearance()) { - entity = null; - } - - disguise.setAppearance(entity); - setDirty(); - return this; - } - - @Override - public boolean onProjectileImpact(ProjectileEntity projectile) { - return disguise.getAppearance() == projectile; - } - - @Override - public boolean tick(Caster source, Situation situation) { - if (situation == Situation.BODY) { - return update(source, true); - } - return false; - } - - @SuppressWarnings("unchecked") - public boolean update(Caster source, boolean tick) { - if (source.isClient()) { - if (isSuppressed()) { - source.spawnParticles(MagicParticleEffect.UNICORN, 5); - source.spawnParticles(UParticles.CHANGELING_MAGIC, 5); - } else if (source.getWorld().random.nextInt(30) == 0) { - source.spawnParticles(UParticles.CHANGELING_MAGIC, 2); - } - } - - LivingEntity owner = source.getMaster(); - - Entity entity = disguise.getAppearance(); - - if (isSuppressed()) { - suppressionCounter--; - - owner.setInvisible(false); - if (source instanceof Pony) { - ((Pony)source).setInvisible(false); - } - - if (entity != null) { - entity.setInvisible(true); - entity.setPos(entity.getX(), Integer.MIN_VALUE, entity.getY()); - } - - return true; - } - - entity = disguise.getOrCreate(source); - - if (owner == null) { - return true; - } - - if (entity == null) { - owner.setInvisible(false); - if (source instanceof Pony) { - ((Pony) source).setInvisible(false); - } - - owner.calculateDimensions(); - return false; - } - - entity.noClip = true; - - if (entity instanceof MobEntity) { - ((MobEntity)entity).setAiDisabled(true); - } - - entity.setInvisible(false); - entity.setNoGravity(true); - - EntityBehaviour behaviour = EntityBehaviour.forEntity(entity); - - behaviour.copyBaseAttributes(owner, entity); - - if (tick && !disguise.skipsUpdate()) { - entity.tick(); - } - - behaviour.update(source, entity, this); - - if (source instanceof Pony) { - Pony player = (Pony)source; - - source.getMaster().setInvisible(true); - player.setInvisible(true); - - if (entity instanceof Owned) { - ((Owned)entity).setMaster(player.getMaster()); - } - - if (entity instanceof PlayerEntity) { - entity.getDataTracker().set(PlayerAccess.getModelBitFlag(), owner.getDataTracker().get(PlayerAccess.getModelBitFlag())); - } - } - - return !isDead() && !source.getMaster().isDead(); - } - - @Override - public void setDead() { - super.setDead(); - disguise.remove(); - } - - @Override - public void toNBT(NbtCompound compound) { - super.toNBT(compound); - - compound.putInt("suppressionCounter", suppressionCounter); - disguise.toNBT(compound); - } - - @Override - public void fromNBT(NbtCompound compound) { - super.fromNBT(compound); - - suppressionCounter = compound.getInt("suppressionCounter"); - disguise.fromNBT(compound); - } - - @Override - public FlightType getFlightType() { - return getAppearance().map(Disguise::getFlightType).orElse(FlightType.UNSET); - } - - public Optional getAppearance() { - return isSuppressed() ? Optional.empty() : Optional.ofNullable(disguise); - } - - @Override - public Optional getTargetEyeHeight(Pony player) { - return getAppearance().flatMap(d -> d.getTargetEyeHeight(player)); - } - - @Override - public Optional getTargetDimensions(Pony player) { - return getAppearance().flatMap(d -> d.getTargetDimensions(player)); - } - - static abstract class PlayerAccess extends PlayerEntity { - public PlayerAccess() { super(null, null, 0, null); } - static TrackedData getModelBitFlag() { - return PLAYER_MODEL_PARTS; - } - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java index af750fb8..2b8c3bc2 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java @@ -13,7 +13,8 @@ import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.CompoundSpell; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; +import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; +import com.minelittlepony.unicopia.ability.magic.spell.ChangelingDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.JoustingSpell; import com.minelittlepony.unicopia.ability.magic.spell.PlaceableSpell; import com.minelittlepony.unicopia.ability.magic.spell.Spell; @@ -40,7 +41,7 @@ public final class SpellType implements Affine, SpellPredicate< public static final SpellType PLACED_SPELL = register("placed", Affinity.NEUTRAL, 0, false, PlaceableSpell::new); public static final SpellType THROWN_SPELL = register("thrown", Affinity.NEUTRAL, 0, false, ThrowableSpell::new); - public static final SpellType DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new); + public static final SpellType CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, ChangelingDisguiseSpell::new); public static final SpellType RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new); public static final SpellType FROST = register("frost", Affinity.GOOD, 0xBDBDF9, true, IceSpell::new); diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java index 8682d8fe..2de55c3a 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java @@ -9,11 +9,11 @@ import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.AbilityDispatcher; import com.minelittlepony.unicopia.ability.AbilitySlot; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; +import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.client.KeyBindingsHandler; import com.minelittlepony.unicopia.client.sound.LoopingSoundInstance; -import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect; import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.player.Pony; @@ -111,8 +111,8 @@ public class UHud extends DrawableHelper { matrices.pop(); if (pony.getSpecies() == Race.CHANGELING && !client.player.isSneaking()) { - pony.getSpellSlot().get(SpellType.DISGUISE, false).map(DisguiseSpell::getDisguise) - .map(Disguise::getAppearance) + pony.getSpellSlot().get(SpellType.CHANGELING_DISGUISE, false).map(AbstractDisguiseSpell::getDisguise) + .map(EntityAppearance::getAppearance) .ifPresent(appearance -> { float baseHeight = 20; diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java index bee52af5..80e78e96 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java @@ -3,11 +3,11 @@ package com.minelittlepony.unicopia.client.render; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.entity.ItemImpl; import com.minelittlepony.unicopia.entity.Living; -import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.behaviour.FallingBlockBehaviour; import com.minelittlepony.unicopia.entity.player.Pony; @@ -93,10 +93,10 @@ public class WorldRenderDelegate { int fireTicks = pony.getMaster().doesRenderOnFire() ? 1 : 0; - return ((Caster)pony).getSpellSlot().get(SpellType.DISGUISE, true).map(effect -> { + return ((Caster)pony).getSpellSlot().get(SpellPredicate.IS_DISGUISE, true).map(effect -> { effect.update(pony, false); - Disguise ve = effect.getDisguise(); + EntityAppearance ve = effect.getDisguise(); Entity e = ve.getAppearance(); if (e != null) { @@ -127,7 +127,7 @@ public class WorldRenderDelegate { } } - public void renderDisguise(EntityRenderDispatcher dispatcher, Disguise ve, Entity e, + public void renderDisguise(EntityRenderDispatcher dispatcher, EntityAppearance ve, Entity e, double x, double y, double z, int fireTicks, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) { diff --git a/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java b/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java index 0cbec6aa..135daf28 100644 --- a/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java +++ b/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java @@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.command; import java.util.function.Function; import com.minelittlepony.unicopia.InteractionManager; -import com.minelittlepony.unicopia.ability.magic.spell.Spell; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.entity.player.Pony; @@ -83,8 +83,8 @@ public class DisguiseCommand { } Pony iplayer = Pony.of(player); - iplayer.getSpellSlot().get(SpellType.DISGUISE, true) - .orElseGet(() -> SpellType.DISGUISE.apply(iplayer, SpellTraits.EMPTY)) + iplayer.getSpellSlot().get(SpellType.CHANGELING_DISGUISE, true) + .orElseGet(() -> SpellType.CHANGELING_DISGUISE.apply(iplayer, SpellTraits.EMPTY)) .setDisguise(entity); if (source.getEntity() == player) { @@ -112,7 +112,7 @@ public class DisguiseCommand { static int reveal(ServerCommandSource source, PlayerEntity player) { Pony iplayer = Pony.of(player); - iplayer.getSpellSlot().get(SpellType.DISGUISE, true).ifPresent(Spell::setDead); + iplayer.getSpellSlot().removeIf(SpellPredicate.IS_DISGUISE, true); if (source.getEntity() == player) { source.sendFeedback(new TranslatableText("commands.disguise.removed.self"), true); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index a8278005..1453cabb 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -7,8 +7,8 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.SpellContainer; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.Situation; -import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.network.datasync.EffectSync; import com.minelittlepony.unicopia.projectile.ProjectileImpactListener; @@ -161,7 +161,7 @@ public abstract class Living implements Equine, Caste } protected void handleFall(float distance, float damageMultiplier, DamageSource cause) { - getSpellSlot().get(SpellType.DISGUISE, false).ifPresent(spell -> { + getSpellSlot().get(SpellPredicate.IS_DISGUISE, false).ifPresent(spell -> { spell.getDisguise().onImpact(this, distance, damageMultiplier, cause); }); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/AxolotlBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/AxolotlBehaviour.java index 270a4312..2abe50a6 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/AxolotlBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/AxolotlBehaviour.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import net.minecraft.entity.passive.AxolotlEntity; import net.minecraft.util.math.Vec3f; @@ -9,7 +8,7 @@ import net.minecraft.util.math.Vec3f; public class AxolotlBehaviour extends EntityBehaviour { private static final float toRad = 0.017453292F; @Override - public void update(Caster source, AxolotlEntity entity, DisguiseSpell spell) { + public void update(Caster source, AxolotlEntity entity, Disguise spell) { if (entity.getModelAngles().isEmpty()) { return; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/BeeBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/BeeBehaviour.java index 880d9eb5..7d054758 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/BeeBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/BeeBehaviour.java @@ -2,13 +2,12 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import net.minecraft.entity.passive.BeeEntity; public class BeeBehaviour extends EntityBehaviour { @Override - public BeeEntity onCreate(BeeEntity entity, Disguise context, boolean replaceOld) { + public BeeEntity onCreate(BeeEntity entity, EntityAppearance context, boolean replaceOld) { super.onCreate(entity, context, replaceOld); if (replaceOld && entity.world.isClient) { InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_BEE); @@ -17,7 +16,7 @@ public class BeeBehaviour extends EntityBehaviour { } @Override - public void update(Caster source, BeeEntity entity, DisguiseSpell spell) { + public void update(Caster source, BeeEntity entity, Disguise spell) { if (source.getMaster().isSneaking()) { entity.setAngerTime(10); } else { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/BlazeBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/BlazeBehaviour.java index 76e5c296..95786ecf 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/BlazeBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/BlazeBehaviour.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.mixin.MixinBlazeEntity; @@ -15,7 +14,7 @@ import net.minecraft.world.WorldEvents; public class BlazeBehaviour extends EntityBehaviour { @Override - public void update(Caster source, BlazeEntity entity, DisguiseSpell spell) { + public void update(Caster source, BlazeEntity entity, Disguise spell) { super.update(source, entity, spell); Entity src = source.getEntity(); @@ -32,7 +31,7 @@ public class BlazeBehaviour extends EntityBehaviour { } @Override - public void update(Pony player, BlazeEntity entity, DisguiseSpell spell) { + public void update(Pony player, BlazeEntity entity, Disguise spell) { NbtCompound tag = spell.getDisguise().getOrCreateTag(); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ChickenBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ChickenBehaviour.java index f8962a87..f484b762 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ChickenBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ChickenBehaviour.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.Entity; @@ -21,7 +20,7 @@ public class ChickenBehaviour extends EntityBehaviour { } @Override - public void update(Caster source, ChickenEntity entity, DisguiseSpell spell) { + public void update(Caster source, ChickenEntity entity, Disguise spell) { entity.eggLayTime = Integer.MAX_VALUE; if (source instanceof Pony) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/CreeperBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/CreeperBehaviour.java index df3793fd..5901b3bf 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/CreeperBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/CreeperBehaviour.java @@ -1,14 +1,13 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import net.minecraft.entity.mob.CreeperEntity; import net.minecraft.util.math.MathHelper; public class CreeperBehaviour extends EntityBehaviour { @Override - public void update(Caster source, CreeperEntity entity, DisguiseSpell spell) { + public void update(Caster source, CreeperEntity entity, Disguise spell) { int fuseCountDown = spell.getDisguise().getOrCreateTag().getInt("fuseCountdown"); boolean trigger = isSneakingOnGround(source); 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 5808c5ab..d87686ac 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java @@ -1,399 +1,121 @@ package com.minelittlepony.unicopia.entity.behaviour; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; import java.util.Optional; -import java.util.UUID; -import java.util.function.Consumer; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.FlightType; -import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; -import com.minelittlepony.unicopia.entity.player.PlayerAttributes; import com.minelittlepony.unicopia.entity.player.PlayerDimensions; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.projectile.ProjectileUtil; -import com.minelittlepony.unicopia.util.NbtSerialisable; -import com.mojang.authlib.GameProfile; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.SkullBlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityDimensions; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.FallingBlockEntity; -import net.minecraft.entity.Flutterer; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.boss.dragon.EnderDragonEntity; -import net.minecraft.entity.damage.DamageSource; -import net.minecraft.entity.decoration.AbstractDecorationEntity; -import net.minecraft.entity.mob.AmbientEntity; -import net.minecraft.entity.mob.FlyingEntity; -import net.minecraft.entity.mob.ShulkerEntity; -import net.minecraft.entity.mob.SpiderEntity; -import net.minecraft.entity.mob.VexEntity; +import net.minecraft.entity.data.TrackedData; +import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.projectile.ShulkerBulletEntity; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.util.function.BooleanBiFunction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; -import net.minecraft.world.WorldAccess; -public class Disguise implements NbtSerialisable, PlayerDimensions.Provider, FlightType.Provider { - private static final Optional BLOCK_HEIGHT = Optional.of(0.5F); +public interface Disguise extends FlightType.Provider, PlayerDimensions.Provider { - @NotNull - private String entityId = ""; + EntityAppearance getDisguise(); - @Nullable - private Entity entity; + void setDirty(); - @Nullable - private BlockEntity blockEntity; + boolean isDead(); - private List attachments = new ArrayList<>(); - - private Optional dimensions = Optional.empty(); - - /** - * Tag that allows behaviours to store data between ticks. - * This is not serialized, so should only be used for server-side data. - */ - @Nullable - private NbtCompound tag; - - @Nullable - private NbtCompound entityNbt; - - @Nullable - public Entity getAppearance() { - return entity; + default Optional getAppearance() { + return Optional.ofNullable(getDisguise()); } - @Nullable - public BlockEntity getBlockEntity() { - return blockEntity; + @Override + default FlightType getFlightType() { + return getAppearance().map(EntityAppearance::getFlightType).orElse(FlightType.UNSET); } - public List getAttachments() { - return attachments; + @Override + default Optional getTargetEyeHeight(Pony player) { + return getAppearance().flatMap(d -> d.getTargetEyeHeight(player)); } - public void addBlockEntity(BlockEntity blockEntity) { - this.blockEntity = blockEntity; + @Override + default Optional getTargetDimensions(Pony player) { + return getAppearance().flatMap(d -> d.getTargetDimensions(player)); } - public void attachExtraEntity(Entity entity) { - attachments.add(entity); - } - - public void setAppearance(@Nullable Entity entity) { - remove(); - - entityNbt = entity == null ? null : encodeEntityToNBT(entity); - entityId = entityNbt == null ? "" : entityNbt.getString("id"); - } - - public boolean isPresent() { - return entity != null; - } - - public NbtCompound getOrCreateTag() { - if (tag == null) { - tag = new NbtCompound(); - } - return tag; - } - - public boolean hasTag() { - return tag != null; - } - - public void remove() { - attachments.clear(); - if (entity != null) { - EntityBehaviour.forEntity(entity).onDestroy(entity); + default Disguise setDisguise(@Nullable Entity entity) { + if (entity == getDisguise().getAppearance()) { entity = null; } - if (blockEntity != null) { - blockEntity.markRemoved(); - blockEntity = null; - } + + getDisguise().setAppearance(entity); + setDirty(); + return this; } - private synchronized void createPlayer(NbtCompound nbt, GameProfile profile, Caster source) { - remove(); + @SuppressWarnings("unchecked") + default boolean update(Caster source, boolean tick) { - entity = InteractionManager.instance().createPlayer(source.getEntity(), profile); - entity.setCustomName(source.getMaster().getName()); - ((PlayerEntity)entity).readNbt(nbt.getCompound("playerNbt")); - entity.setUuid(UUID.randomUUID()); - entity.extinguish(); + LivingEntity owner = source.getMaster(); - onEntityLoaded(source); - } + Entity entity = getDisguise().getOrCreate(source); - public Entity getOrCreate(Caster source) { - if (entity == null && entityNbt != null) { - NbtCompound nbt = entityNbt; - entity = null; - entityNbt = null; - attachments.clear(); - - if ("player".equals(entityId)) { - createPlayer(nbt, new GameProfile( - nbt.containsUuid("playerId") ? nbt.getUuid("playerId") : UUID.randomUUID(), - nbt.getString("playerName") - ), source); - - SkullBlockEntity.loadProperties(new GameProfile( - nbt.containsUuid("playerId") ? nbt.getUuid("playerId") : null, - nbt.getString("playerName") - ), p -> createPlayer(nbt, p, source)); - } else { - if (source.isClient()) { - entity = EntityType.fromNbt(nbt).map(type -> type.create(source.getWorld())).orElse(null); - if (entity != null) { - try { - entity.readNbt(nbt); - } catch (Exception ignored) { - // Mojang pls - } - entity = EntityBehaviour.forEntity(entity).onCreate(entity, this, true); - } - } else { - entity = EntityType.loadEntityWithPassengers(nbt, source.getWorld(), e -> { - return EntityBehaviour.forEntity(e).onCreate(e, this, true); - }); - } - - onEntityLoaded(source); - } - } - - return entity; - } - - public void onImpact(Caster pony, float distance, float damageMultiplier, DamageSource cause) { - EntityBehaviour.forEntity(entity).onImpact(pony, entity, distance, damageMultiplier, cause); - } - - private void onEntityLoaded(Caster source) { - source.getEntity().calculateDimensions(); - - if (entity == null) { - return; - } - - Caster.of(entity).ifPresent(c -> c.getSpellSlot().clear()); - - if (entity instanceof LivingEntity) { - ((LivingEntity) entity).getAttributeInstance(PlayerAttributes.ENTITY_GRAVTY_MODIFIER).clearModifiers(); - } - - if (source.isClient()) { - source.getWorld().spawnEntity(entity); - } - } - - @Override - public FlightType getFlightType() { - if (!isPresent()) { - return FlightType.UNSET; + if (owner == null) { + return true; } if (entity == null) { - return FlightType.NONE; - } - - if (entity instanceof Owned) { - @SuppressWarnings("unchecked") - Pony iplayer = Pony.of(((Owned)entity).getMaster()); - - return iplayer == null ? FlightType.NONE : iplayer.getSpecies().getFlightType(); - } - - if (entity instanceof FlyingEntity - || entity instanceof AmbientEntity - || entity instanceof EnderDragonEntity - || entity instanceof VexEntity - || entity instanceof ShulkerBulletEntity - || entity instanceof Flutterer - || ProjectileUtil.isFlyingProjectile(entity)) { - return FlightType.INSECTOID; - } - - return FlightType.NONE; - } - - @Override - public Optional getTargetEyeHeight(Pony player) { - if (entity != null) { - if (entity instanceof FallingBlockEntity) { - return BLOCK_HEIGHT; + owner.setInvisible(false); + if (source instanceof Pony) { + ((Pony) source).setInvisible(false); } - return Optional.of(entity.getStandingEyeHeight()); - } - return Optional.empty(); - } - public float getHeight() { - if (entity != null) { - if (entity instanceof FallingBlockEntity) { - return 0.9F; - } - return entity.getHeight() - 0.1F; - } - return -1; - } - - public Optional getDistance(Pony player) { - return EntityBehaviour.forEntity(entity).getCameraDistance(entity, player); - } - - @Override - public Optional getTargetDimensions(Pony player) { - return dimensions = EntityBehaviour.forEntity(entity).getDimensions(entity, dimensions); - } - - public boolean skipsUpdate() { - return entity instanceof FallingBlockEntity - || entity instanceof AbstractDecorationEntity - || entity instanceof PlayerEntity; - } - - public boolean isAxisAligned() { - return isAxisAligned(entity); - } - - public boolean canClimbWalls() { - return entity instanceof SpiderEntity; - } - - @Override - public void toNBT(NbtCompound compound) { - compound.putString("entityId", entityId); - - if (entityNbt != null) { - compound.put("entity", entityNbt); - } else if (entity != null) { - compound.put("entity", encodeEntityToNBT(entity)); - } - } - - @Override - public void fromNBT(NbtCompound compound) { - String newId = compound.getString("entityId"); - - String newPlayerName = null; - if (compound.contains("entity") && compound.getCompound("entity").contains("playerName")) { - newPlayerName = compound.getCompound("entity").getString("playerName"); - } - - String oldPlayerName = entity != null && entity instanceof PlayerEntity ? ((PlayerEntity)entity).getGameProfile().getName() : null; - - if (!Objects.equals(newId, entityId) || !Objects.equals(newPlayerName, oldPlayerName)) { - entityNbt = null; - remove(); - } - - if (compound.contains("entity")) { - entityId = newId; - - entityNbt = compound.getCompound("entity"); - - compound.getString("entityData"); - - if (entity != null) { - try { - entity.readNbt(entityNbt); - } catch (Exception ignored) { - // Mojang pls - } - - attachments.clear(); - entity = EntityBehaviour.forEntity(entity).onCreate(entity, this, false); - } - } - } - - public static boolean isAxisAligned(@Nullable Entity entity) { - return entity instanceof ShulkerEntity - || entity instanceof AbstractDecorationEntity - || entity instanceof FallingBlockEntity; - } - - private static NbtCompound encodeEntityToNBT(Entity entity) { - NbtCompound entityNbt = new NbtCompound(); - - if (entity instanceof PlayerEntity) { - GameProfile profile = ((PlayerEntity)entity).getGameProfile(); - - entityNbt.putString("id", "player"); - if (profile.getId() != null) { - entityNbt.putUuid("playerId", profile.getId()); - } - entityNbt.putString("playerName", profile.getName()); - - NbtCompound tag = new NbtCompound(); - - entity.writeNbt(tag); - - entityNbt.put("playerNbt", tag); - } else { - entity.saveSelfNbt(entityNbt); - } - - return entityNbt; - } - - void getCollissionShapes(ShapeContext context, Consumer output) { - getCollissionShapes(getAppearance(), context, output); - getAttachments().forEach(e -> getCollissionShapes(e, context, output)); - } - - private static void getCollissionShapes(@Nullable Entity entity, ShapeContext context, Consumer output) { - if (entity == null) { - return; - } - - if (entity.isCollidable()) { - output.accept(VoxelShapes.cuboid(entity.getBoundingBox())); - } else if (entity instanceof FallingBlockEntity) { - BlockPos pos = entity.getBlockPos(); - output.accept(((FallingBlockEntity) entity).getBlockState() - .getCollisionShape(entity.world, entity.getBlockPos(), context) - .offset(pos.getX(), pos.getY(), pos.getZ()) - ); - } - } - - public static List getColissonShapes(@Nullable Entity entity, WorldAccess world, Box box) { - List shapes = new ArrayList<>(); - ShapeContext ctx = entity == null ? ShapeContext.absent() : ShapeContext.of(entity); - VoxelShape entityShape = VoxelShapes.cuboid(box.expand(1.0E-6D)); - - world.getOtherEntities(entity, box.expand(0.5), e -> { - Caster.of(e).flatMap(c -> c.getSpellSlot().get(SpellType.DISGUISE, false)).ifPresent(p -> { - p.getDisguise().getCollissionShapes(ctx, shape -> { - if (!shape.isEmpty() && VoxelShapes.matchesAnywhere(shape, entityShape, BooleanBiFunction.AND)) { - shapes.add(shape); - } - }); - }); + owner.calculateDimensions(); return false; - }); + } - return shapes; + entity.noClip = true; + + if (entity instanceof MobEntity) { + ((MobEntity)entity).setAiDisabled(true); + } + + entity.setInvisible(false); + entity.setNoGravity(true); + + EntityBehaviour behaviour = EntityBehaviour.forEntity(entity); + + behaviour.copyBaseAttributes(owner, entity); + + if (tick && !getDisguise().skipsUpdate()) { + entity.tick(); + } + + behaviour.update(source, entity, this); + + if (source instanceof Pony) { + Pony player = (Pony)source; + + source.getMaster().setInvisible(true); + player.setInvisible(true); + + if (entity instanceof Owned) { + ((Owned)entity).setMaster(player.getMaster()); + } + + if (entity instanceof PlayerEntity) { + entity.getDataTracker().set(PlayerAccess.getModelBitFlag(), owner.getDataTracker().get(PlayerAccess.getModelBitFlag())); + } + } + + return !isDead() && !source.getMaster().isDead(); + } + + static abstract class PlayerAccess extends PlayerEntity { + public PlayerAccess() { super(null, null, 0, null); } + static TrackedData getModelBitFlag() { + return PLAYER_MODEL_PARTS; + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EndermanBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EndermanBehaviour.java index 0b7d6786..159bf793 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EndermanBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EndermanBehaviour.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import net.minecraft.entity.mob.EndermanEntity; import net.minecraft.item.BlockItem; @@ -10,7 +9,7 @@ import net.minecraft.util.Hand; public class EndermanBehaviour extends EntityBehaviour { @Override - public void update(Caster source, EndermanEntity entity, DisguiseSpell spell) { + public void update(Caster source, EndermanEntity entity, Disguise spell) { if (source.getMaster().isSneaking() || source.getMaster().isSprinting()) { entity.setTarget(entity); } else { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java new file mode 100644 index 00000000..edee5a6d --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java @@ -0,0 +1,399 @@ +package com.minelittlepony.unicopia.entity.behaviour; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Consumer; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.FlightType; +import com.minelittlepony.unicopia.InteractionManager; +import com.minelittlepony.unicopia.Owned; +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; +import com.minelittlepony.unicopia.entity.player.PlayerAttributes; +import com.minelittlepony.unicopia.entity.player.PlayerDimensions; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.projectile.ProjectileUtil; +import com.minelittlepony.unicopia.util.NbtSerialisable; +import com.mojang.authlib.GameProfile; + +import net.minecraft.block.ShapeContext; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.SkullBlockEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.FallingBlockEntity; +import net.minecraft.entity.Flutterer; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.boss.dragon.EnderDragonEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.decoration.AbstractDecorationEntity; +import net.minecraft.entity.mob.AmbientEntity; +import net.minecraft.entity.mob.FlyingEntity; +import net.minecraft.entity.mob.ShulkerEntity; +import net.minecraft.entity.mob.SpiderEntity; +import net.minecraft.entity.mob.VexEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ShulkerBulletEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.function.BooleanBiFunction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.WorldAccess; + +public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provider, FlightType.Provider { + private static final Optional BLOCK_HEIGHT = Optional.of(0.5F); + + @NotNull + private String entityId = ""; + + @Nullable + private Entity entity; + + @Nullable + private BlockEntity blockEntity; + + private List attachments = new ArrayList<>(); + + private Optional dimensions = Optional.empty(); + + /** + * Tag that allows behaviours to store data between ticks. + * This is not serialized, so should only be used for server-side data. + */ + @Nullable + private NbtCompound tag; + + @Nullable + private NbtCompound entityNbt; + + @Nullable + public Entity getAppearance() { + return entity; + } + + @Nullable + public BlockEntity getBlockEntity() { + return blockEntity; + } + + public List getAttachments() { + return attachments; + } + + public void addBlockEntity(BlockEntity blockEntity) { + this.blockEntity = blockEntity; + } + + public void attachExtraEntity(Entity entity) { + attachments.add(entity); + } + + public void setAppearance(@Nullable Entity entity) { + remove(); + + entityNbt = entity == null ? null : encodeEntityToNBT(entity); + entityId = entityNbt == null ? "" : entityNbt.getString("id"); + } + + public boolean isPresent() { + return entity != null; + } + + public NbtCompound getOrCreateTag() { + if (tag == null) { + tag = new NbtCompound(); + } + return tag; + } + + public boolean hasTag() { + return tag != null; + } + + public void remove() { + attachments.clear(); + if (entity != null) { + EntityBehaviour.forEntity(entity).onDestroy(entity); + entity = null; + } + if (blockEntity != null) { + blockEntity.markRemoved(); + blockEntity = null; + } + } + + private synchronized void createPlayer(NbtCompound nbt, GameProfile profile, Caster source) { + remove(); + + entity = InteractionManager.instance().createPlayer(source.getEntity(), profile); + entity.setCustomName(source.getMaster().getName()); + ((PlayerEntity)entity).readNbt(nbt.getCompound("playerNbt")); + entity.setUuid(UUID.randomUUID()); + entity.extinguish(); + + onEntityLoaded(source); + } + + public Entity getOrCreate(Caster source) { + if (entity == null && entityNbt != null) { + NbtCompound nbt = entityNbt; + entity = null; + entityNbt = null; + attachments.clear(); + + if ("player".equals(entityId)) { + createPlayer(nbt, new GameProfile( + nbt.containsUuid("playerId") ? nbt.getUuid("playerId") : UUID.randomUUID(), + nbt.getString("playerName") + ), source); + + SkullBlockEntity.loadProperties(new GameProfile( + nbt.containsUuid("playerId") ? nbt.getUuid("playerId") : null, + nbt.getString("playerName") + ), p -> createPlayer(nbt, p, source)); + } else { + if (source.isClient()) { + entity = EntityType.fromNbt(nbt).map(type -> type.create(source.getWorld())).orElse(null); + if (entity != null) { + try { + entity.readNbt(nbt); + } catch (Exception ignored) { + // Mojang pls + } + entity = EntityBehaviour.forEntity(entity).onCreate(entity, this, true); + } + } else { + entity = EntityType.loadEntityWithPassengers(nbt, source.getWorld(), e -> { + return EntityBehaviour.forEntity(e).onCreate(e, this, true); + }); + } + + onEntityLoaded(source); + } + } + + return entity; + } + + public void onImpact(Caster pony, float distance, float damageMultiplier, DamageSource cause) { + EntityBehaviour.forEntity(entity).onImpact(pony, entity, distance, damageMultiplier, cause); + } + + private void onEntityLoaded(Caster source) { + source.getEntity().calculateDimensions(); + + if (entity == null) { + return; + } + + Caster.of(entity).ifPresent(c -> c.getSpellSlot().clear()); + + if (entity instanceof LivingEntity) { + ((LivingEntity) entity).getAttributeInstance(PlayerAttributes.ENTITY_GRAVTY_MODIFIER).clearModifiers(); + } + + if (source.isClient()) { + source.getWorld().spawnEntity(entity); + } + } + + @Override + public FlightType getFlightType() { + if (!isPresent()) { + return FlightType.UNSET; + } + + if (entity == null) { + return FlightType.NONE; + } + + if (entity instanceof Owned) { + @SuppressWarnings("unchecked") + Pony iplayer = Pony.of(((Owned)entity).getMaster()); + + return iplayer == null ? FlightType.NONE : iplayer.getSpecies().getFlightType(); + } + + if (entity instanceof FlyingEntity + || entity instanceof AmbientEntity + || entity instanceof EnderDragonEntity + || entity instanceof VexEntity + || entity instanceof ShulkerBulletEntity + || entity instanceof Flutterer + || ProjectileUtil.isFlyingProjectile(entity)) { + return FlightType.INSECTOID; + } + + return FlightType.NONE; + } + + @Override + public Optional getTargetEyeHeight(Pony player) { + if (entity != null) { + if (entity instanceof FallingBlockEntity) { + return BLOCK_HEIGHT; + } + return Optional.of(entity.getStandingEyeHeight()); + } + return Optional.empty(); + } + + public float getHeight() { + if (entity != null) { + if (entity instanceof FallingBlockEntity) { + return 0.9F; + } + return entity.getHeight() - 0.1F; + } + return -1; + } + + public Optional getDistance(Pony player) { + return EntityBehaviour.forEntity(entity).getCameraDistance(entity, player); + } + + @Override + public Optional getTargetDimensions(Pony player) { + return dimensions = EntityBehaviour.forEntity(entity).getDimensions(entity, dimensions); + } + + public boolean skipsUpdate() { + return entity instanceof FallingBlockEntity + || entity instanceof AbstractDecorationEntity + || entity instanceof PlayerEntity; + } + + public boolean isAxisAligned() { + return isAxisAligned(entity); + } + + public boolean canClimbWalls() { + return entity instanceof SpiderEntity; + } + + @Override + public void toNBT(NbtCompound compound) { + compound.putString("entityId", entityId); + + if (entityNbt != null) { + compound.put("entity", entityNbt); + } else if (entity != null) { + compound.put("entity", encodeEntityToNBT(entity)); + } + } + + @Override + public void fromNBT(NbtCompound compound) { + String newId = compound.getString("entityId"); + + String newPlayerName = null; + if (compound.contains("entity") && compound.getCompound("entity").contains("playerName")) { + newPlayerName = compound.getCompound("entity").getString("playerName"); + } + + String oldPlayerName = entity != null && entity instanceof PlayerEntity ? ((PlayerEntity)entity).getGameProfile().getName() : null; + + if (!Objects.equals(newId, entityId) || !Objects.equals(newPlayerName, oldPlayerName)) { + entityNbt = null; + remove(); + } + + if (compound.contains("entity")) { + entityId = newId; + + entityNbt = compound.getCompound("entity"); + + compound.getString("entityData"); + + if (entity != null) { + try { + entity.readNbt(entityNbt); + } catch (Exception ignored) { + // Mojang pls + } + + attachments.clear(); + entity = EntityBehaviour.forEntity(entity).onCreate(entity, this, false); + } + } + } + + public static boolean isAxisAligned(@Nullable Entity entity) { + return entity instanceof ShulkerEntity + || entity instanceof AbstractDecorationEntity + || entity instanceof FallingBlockEntity; + } + + private static NbtCompound encodeEntityToNBT(Entity entity) { + NbtCompound entityNbt = new NbtCompound(); + + if (entity instanceof PlayerEntity) { + GameProfile profile = ((PlayerEntity)entity).getGameProfile(); + + entityNbt.putString("id", "player"); + if (profile.getId() != null) { + entityNbt.putUuid("playerId", profile.getId()); + } + entityNbt.putString("playerName", profile.getName()); + + NbtCompound tag = new NbtCompound(); + + entity.writeNbt(tag); + + entityNbt.put("playerNbt", tag); + } else { + entity.saveSelfNbt(entityNbt); + } + + return entityNbt; + } + + void getCollissionShapes(ShapeContext context, Consumer output) { + getCollissionShapes(getAppearance(), context, output); + getAttachments().forEach(e -> getCollissionShapes(e, context, output)); + } + + private static void getCollissionShapes(@Nullable Entity entity, ShapeContext context, Consumer output) { + if (entity == null) { + return; + } + + if (entity.isCollidable()) { + output.accept(VoxelShapes.cuboid(entity.getBoundingBox())); + } else if (entity instanceof FallingBlockEntity) { + BlockPos pos = entity.getBlockPos(); + output.accept(((FallingBlockEntity) entity).getBlockState() + .getCollisionShape(entity.world, entity.getBlockPos(), context) + .offset(pos.getX(), pos.getY(), pos.getZ()) + ); + } + } + + public static List getColissonShapes(@Nullable Entity entity, WorldAccess world, Box box) { + List shapes = new ArrayList<>(); + ShapeContext ctx = entity == null ? ShapeContext.absent() : ShapeContext.of(entity); + VoxelShape entityShape = VoxelShapes.cuboid(box.expand(1.0E-6D)); + + world.getOtherEntities(entity, box.expand(0.5), e -> { + Caster.of(e).flatMap(c -> c.getSpellSlot().get(SpellPredicate.IS_DISGUISE, false)).ifPresent(p -> { + p.getDisguise().getCollissionShapes(ctx, shape -> { + if (!shape.isEmpty() && VoxelShapes.matchesAnywhere(shape, entityShape, BooleanBiFunction.AND)) { + shapes.add(shape); + } + }); + }); + return false; + }); + + return shapes; + } +} 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 3536bc5e..834577a7 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java @@ -6,7 +6,6 @@ import java.util.function.Supplier; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.ItemWielder; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.mixin.MixinEntity; @@ -45,13 +44,13 @@ public class EntityBehaviour { *
* We use this to add entity-specific behaviours. */ - public void update(Caster source, T entity, DisguiseSpell spell) { + public void update(Caster source, T entity, Disguise spell) { if (source instanceof Pony) { update((Pony)source, entity, spell); } } - protected void update(Pony pony, T entity, DisguiseSpell spell) { + protected void update(Pony pony, T entity, Disguise spell) { } @@ -59,7 +58,7 @@ public class EntityBehaviour { } - public T onCreate(T entity, Disguise context, boolean wasNew) { + public T onCreate(T entity, EntityAppearance context, boolean wasNew) { entity.extinguish(); return entity; } @@ -120,7 +119,7 @@ public class EntityBehaviour { to.horizontalCollision = from.horizontalCollision; } - if (Disguise.isAxisAligned(to)) { + if (EntityAppearance.isAxisAligned(to)) { double x = positionOffset.x + Math.floor(from.getX()) + 0.5; double y = positionOffset.y + Math.floor(from.getY()); double z = positionOffset.z + Math.floor(from.getZ()) + 0.5; 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 0246c7b3..ba396c80 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.Optional; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.mixin.MixinFallingBlock; import com.minelittlepony.unicopia.util.Tickable; @@ -62,7 +61,7 @@ public class FallingBlockBehaviour extends EntityBehaviour { } @Override - public FallingBlockEntity onCreate(FallingBlockEntity entity, Disguise context, boolean replaceOld) { + public FallingBlockEntity onCreate(FallingBlockEntity entity, EntityAppearance context, boolean replaceOld) { super.onCreate(entity, context, replaceOld); BlockState state = entity.getBlockState(); @@ -85,7 +84,7 @@ public class FallingBlockBehaviour extends EntityBehaviour { } @Override - public void update(Caster source, FallingBlockEntity entity, DisguiseSpell spell) { + public void update(Caster source, FallingBlockEntity entity, Disguise spell) { BlockState state = entity.getBlockState(); if (state.contains(Properties.WATERLOGGED)) { @@ -98,7 +97,7 @@ public class FallingBlockBehaviour extends EntityBehaviour { } } - Disguise disguise = spell.getDisguise(); + EntityAppearance disguise = spell.getDisguise(); List attachments = disguise.getAttachments(); if (attachments.size() > 0) { copyBaseAttributes(source.getMaster(), attachments.get(0), UP); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/GhastBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/GhastBehaviour.java index f0f1b2d2..e92d4d0e 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/GhastBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/GhastBehaviour.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.entity.behaviour; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.mob.GhastEntity; @@ -10,7 +9,7 @@ import net.minecraft.util.math.Vec3d; public class GhastBehaviour extends MobBehaviour { @Override - public void update(Pony player, GhastEntity entity, DisguiseSpell spell) { + public void update(Pony player, GhastEntity entity, Disguise spell) { if (player.sneakingChanged()) { boolean sneaking = player.getMaster().isSneaking(); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/HoppingBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/HoppingBehaviour.java index 550ceddd..26c9ed0a 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/HoppingBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/HoppingBehaviour.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.entity.behaviour; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.LivingEntity; @@ -8,7 +7,7 @@ import net.minecraft.entity.passive.RabbitEntity; public class HoppingBehaviour extends EntityBehaviour { @Override - public void update(Pony player, LivingEntity entity, DisguiseSpell spell) { + public void update(Pony player, LivingEntity entity, Disguise spell) { if (player.getEntity().isOnGround()) { if (player.getEntity().getVelocity().horizontalLengthSquared() > 0.01) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MinecartBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MinecartBehaviour.java index b000892d..48e1fead 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MinecartBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MinecartBehaviour.java @@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.vehicle.AbstractMinecartEntity; @@ -10,7 +9,7 @@ import net.minecraft.entity.vehicle.AbstractMinecartEntity; public class MinecartBehaviour extends EntityBehaviour { @Override - public AbstractMinecartEntity onCreate(AbstractMinecartEntity entity, Disguise context, boolean replaceOld) { + public AbstractMinecartEntity onCreate(AbstractMinecartEntity entity, EntityAppearance context, boolean replaceOld) { super.onCreate(entity, context, replaceOld); if (replaceOld && entity.world.isClient) { InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_MINECART); @@ -19,7 +18,7 @@ public class MinecartBehaviour extends EntityBehaviour { } @Override - public void update(Caster source, AbstractMinecartEntity entity, DisguiseSpell spell) { + public void update(Caster source, AbstractMinecartEntity entity, Disguise spell) { entity.setYaw(entity.getYaw() - 90); entity.prevYaw -= 90; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java index 1bc769cb..7cb297f1 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.entity.behaviour; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.util.RayTraceHelper; @@ -18,7 +17,7 @@ public class MobBehaviour extends EntityBehaviour { } @Override - public void update(Pony player, T entity, DisguiseSpell spell) { + public void update(Pony player, T entity, Disguise spell) { if (player.sneakingChanged() && isSneakingOnGround(player)) { LivingEntity target = findTarget(player, entity); entity.tryAttack(target); 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 964cdf79..9de9eb71 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/PlayerBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/PlayerBehaviour.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.CapeHolder; import com.minelittlepony.unicopia.entity.Leaner; import com.minelittlepony.unicopia.entity.player.Pony; @@ -10,7 +9,7 @@ import net.minecraft.entity.player.PlayerEntity; public class PlayerBehaviour extends EntityBehaviour { @Override - public void update(Caster source, PlayerEntity entity, DisguiseSpell spell) { + public void update(Caster source, PlayerEntity entity, Disguise spell) { if (source instanceof Pony) { PlayerEntity pFrom = ((Pony)source).getMaster(); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/RangedAttackBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/RangedAttackBehaviour.java index 38bbc0ee..e0cd3c80 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/RangedAttackBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/RangedAttackBehaviour.java @@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import java.util.function.BiFunction; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.Entity; @@ -24,7 +23,7 @@ public class RangedAttackBehaviour extends E } @Override - public void update(Pony player, T entity, DisguiseSpell spell) { + public void update(Pony player, T entity, Disguise spell) { if (player.sneakingChanged() && isSneakingOnGround(player)) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SheepBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SheepBehaviour.java index b402fb21..8c3058c7 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SheepBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SheepBehaviour.java @@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import java.util.Random; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.mixin.MixinSheepEntity; @@ -19,7 +18,7 @@ import net.minecraft.world.WorldEvents; public class SheepBehaviour extends EntityBehaviour { @Override - public void update(Pony player, SheepEntity entity, DisguiseSpell spell) { + public void update(Pony player, SheepEntity entity, Disguise spell) { if (player.sneakingChanged()) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ShulkerBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ShulkerBehaviour.java index 0ec861db..c0e14f7f 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ShulkerBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ShulkerBehaviour.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.mixin.MixinShulkerEntity; @@ -15,7 +14,7 @@ import net.minecraft.util.math.Vec3d; public class ShulkerBehaviour extends EntityBehaviour { @Override - public void update(Caster source, ShulkerEntity shulker, DisguiseSpell spell) { + public void update(Caster source, ShulkerEntity shulker, Disguise spell) { shulker.setYaw(0); shulker.prevBodyYaw = 0; shulker.bodyYaw = 0; @@ -38,7 +37,7 @@ public class ShulkerBehaviour extends EntityBehaviour { } @Override - protected void update(Pony player, ShulkerEntity shulker, DisguiseSpell spell) { + protected void update(Pony player, ShulkerEntity shulker, Disguise spell) { float peekAmount = 30; double speed = !player.getEntity().isSneaking() ? 0.29 : 0; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SilverfishBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SilverfishBehaviour.java index 0d5fe705..eb5c4a06 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SilverfishBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SilverfishBehaviour.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.entity.behaviour; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.block.state.StateMaps; import com.minelittlepony.unicopia.entity.player.Pony; @@ -12,7 +11,7 @@ import net.minecraft.world.WorldEvents; public class SilverfishBehaviour extends EntityBehaviour { @Override - public void update(Pony player, SilverfishEntity entity, DisguiseSpell spell) { + public void update(Pony player, SilverfishEntity entity, Disguise spell) { if (!player.isClient() && player.sneakingChanged() && player.getMaster().isSneaking()) { BlockPos pos = entity.getBlockPos().down(); BlockState state = entity.world.getBlockState(pos); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SpellcastingIllagerBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SpellcastingIllagerBehaviour.java index ec4c71d5..b3acfc67 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SpellcastingIllagerBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/SpellcastingIllagerBehaviour.java @@ -1,13 +1,12 @@ package com.minelittlepony.unicopia.entity.behaviour; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.mob.SpellcastingIllagerEntity; public class SpellcastingIllagerBehaviour extends EntityBehaviour { @Override - public void update(Pony player, SpellcastingIllagerEntity entity, DisguiseSpell s) { + public void update(Pony player, SpellcastingIllagerEntity entity, Disguise s) { if (player.sneakingChanged()) { SpellCastAccess.setSpell(player, entity, s); } @@ -16,7 +15,7 @@ public class SpellcastingIllagerBehaviour extends EntityBehaviour extends EntityBehaviour { @Override - public void update(Pony player, T entity, DisguiseSpell spell) { + public void update(Pony player, T entity, Disguise spell) { HorseBaseEntity horse = ((HorseBaseEntity)entity); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/TraderBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/TraderBehaviour.java index 789e9194..46af39a9 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/TraderBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/TraderBehaviour.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.entity.behaviour; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.passive.MerchantEntity; @@ -8,7 +7,7 @@ import net.minecraft.sound.SoundEvents; public class TraderBehaviour extends EntityBehaviour { @Override - public void update(Pony pony, MerchantEntity entity, DisguiseSpell spell) { + public void update(Pony pony, MerchantEntity entity, Disguise spell) { if (pony.sneakingChanged() && pony.getMaster().isSneaking()) { entity.setHeadRollingTimeLeft(40); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/WaterCreatureBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/WaterCreatureBehaviour.java index 784c35b2..63408f6a 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/WaterCreatureBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/WaterCreatureBehaviour.java @@ -1,14 +1,13 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.mob.WaterCreatureEntity; public class WaterCreatureBehaviour extends EntityBehaviour { @Override - public void update(Caster source, WaterCreatureEntity entity, DisguiseSpell spell) { + public void update(Caster source, WaterCreatureEntity entity, Disguise spell) { if (source.getEntity().isInsideWaterOrBubbleColumn()) { source.getEntity().setAir(source.getEntity().getAir() - 1); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java index 233e572e..9825b8ba 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java @@ -3,8 +3,8 @@ package com.minelittlepony.unicopia.entity.player; import java.util.Optional; import com.minelittlepony.common.util.animation.MotionCompositor; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; -import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; +import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import net.minecraft.util.math.Vec3d; @@ -48,8 +48,8 @@ public class PlayerCamera extends MotionCompositor { public Optional calculateDistance(double distance) { return player.getSpellSlot() - .get(SpellType.DISGUISE, false) - .map(DisguiseSpell::getDisguise) + .get(SpellPredicate.IS_DISGUISE, false) + .map(AbstractDisguiseSpell::getDisguise) .flatMap(d -> d.getDistance(player)) .map(d -> distance * d); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 200cd960..f62274d7 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.FlightType; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.entity.Creature; @@ -258,7 +259,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab prevStrafe = strafing; strafe = 1; ticksToGlide = MAX_TICKS_TO_GLIDE; - if (!SpellType.DISGUISE.isOn(pony)) { + if (!SpellPredicate.IS_DISGUISE.isOn(pony)) { entity.playSound(type.getWingFlapSound(), 0.25F, 1); } } else { @@ -334,7 +335,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab ticksToGlide = MAX_TICKS_TO_GLIDE; } - if (!SpellType.DISGUISE.isOn(pony)) { + if (!SpellPredicate.IS_DISGUISE.isOn(pony)) { if (ticksInAir % GLIDING_SOUND_INTERVAL == 1 && pony.isClient()) { InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_GLIDING); } @@ -343,7 +344,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab velocity.y -= 0.02 * getGravitySignum(); velocity.x *= 0.9896; velocity.z *= 0.9896; - } else if (type == FlightType.INSECTOID && !SpellType.DISGUISE.isOn(pony)) { + } else if (type == FlightType.INSECTOID && !SpellPredicate.IS_DISGUISE.isOn(pony)) { if (entity.world.isClient && !soundPlaying) { soundPlaying = true; InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_CHANGELING_BUZZ); @@ -496,7 +497,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab if (thrustScale <= 0.000001F & flapping) { flapping = false; - if (!SpellType.DISGUISE.isOn(pony)) { + if (!SpellPredicate.IS_DISGUISE.isOn(pony)) { entity.playSound(getFlightType().getWingFlapSound(), 0.5F, 1); } thrustScale = 1; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java index 54d72ebc..0f20bc60 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java @@ -13,11 +13,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; -import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; +import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.entity.Creature; import com.minelittlepony.unicopia.entity.PonyContainer; -import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.entity.ItemWielder; @@ -91,9 +91,9 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer info) { if (get() instanceof Pony && horizontalCollision) { - ((Pony)get()).getSpellSlot().get(SpellType.DISGUISE, false) - .map(DisguiseSpell::getDisguise) - .filter(Disguise::canClimbWalls) + ((Pony)get()).getSpellSlot().get(SpellPredicate.IS_DISGUISE, false) + .map(AbstractDisguiseSpell::getDisguise) + .filter(EntityAppearance::canClimbWalls) .ifPresent(v -> { climbingPos = Optional.of(getBlockPos()); info.setReturnValue(true); @@ -104,9 +104,9 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer info) { Caster.of(this) - .flatMap(c -> c.getSpellSlot().get(SpellType.DISGUISE, false)) - .map(DisguiseSpell::getDisguise) - .map(Disguise::getAppearance) + .flatMap(c -> c.getSpellSlot().get(SpellPredicate.IS_DISGUISE, false)) + .map(AbstractDisguiseSpell::getDisguise) + .map(EntityAppearance::getAppearance) .filter(Entity::isPushable) .ifPresent(v -> { info.setReturnValue(false); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinTargetPredicate.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinTargetPredicate.java index 9b77c98b..34610cb0 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinTargetPredicate.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinTargetPredicate.java @@ -7,7 +7,7 @@ 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.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.entity.player.Pony; @@ -20,7 +20,7 @@ abstract class MixinTargetPredicate { public void onTest(@Nullable LivingEntity baseEntity, LivingEntity targetEntity, CallbackInfoReturnable info) { Equine eq = Equine.of(targetEntity).orElse(null); if (eq instanceof Pony) { - ((Pony)eq).getSpellSlot().get(SpellType.DISGUISE, true).ifPresent(spell -> { + ((Pony)eq).getSpellSlot().get(SpellPredicate.IS_DISGUISE, true).ifPresent(spell -> { if (spell.getDisguise().getAppearance() == baseEntity) { info.setReturnValue(false); } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java index ec9fbf49..7f8264b5 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java @@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.BlockDestructionManager; import com.minelittlepony.unicopia.entity.RotatedView; -import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; @@ -50,7 +50,7 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source @Override public List getEntityCollisions(@Nullable Entity entity, Box box) { if (box.getAverageSideLength() >= 1.0E-7D) { - List shapes = Disguise.getColissonShapes(entity, this, box); + List shapes = EntityAppearance.getColissonShapes(entity, this, box); if (!shapes.isEmpty()) { return Stream.concat(shapes.stream(), WorldAccess.super.getEntityCollisions(entity, box).stream()).toList(); }