Distance the disguises system from the magic system and make it possible to have different diguise spells

This commit is contained in:
Sollace 2021-12-22 16:43:06 +02:00
parent e3bd201f0a
commit f10dcb59ec
38 changed files with 731 additions and 683 deletions

View file

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

View file

@ -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<T extends Spell> extends Predicate<Spell> {
SpellPredicate<ProjectileSpell> HAS_PROJECTILE_EVENTS = s -> s instanceof ProjectileSpell;
SpellPredicate<AbstractDisguiseSpell> IS_DISGUISE = s -> s instanceof AbstractDisguiseSpell;
default boolean isOn(Caster<?> caster) {
return caster.getSpellSlot().get(this, false).isPresent();
}

View file

@ -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.
* <p>
*/
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<EntityAppearance> getAppearance() {
return Optional.ofNullable(disguise);
}
}

View file

@ -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.
* <p>
* 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<EntityAppearance> getAppearance() {
return isSuppressed() ? Optional.empty() : super.getAppearance();
}
}

View file

@ -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.
* <p>
* 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<Entity> 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<LivingEntity>)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<Disguise> getAppearance() {
return isSuppressed() ? Optional.empty() : Optional.ofNullable(disguise);
}
@Override
public Optional<Float> getTargetEyeHeight(Pony player) {
return getAppearance().flatMap(d -> d.getTargetEyeHeight(player));
}
@Override
public Optional<EntityDimensions> 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<Byte> getModelBitFlag() {
return PLAYER_MODEL_PARTS;
}
}
}

View file

@ -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<T extends Spell> implements Affine, SpellPredicate<
public static final SpellType<PlaceableSpell> PLACED_SPELL = register("placed", Affinity.NEUTRAL, 0, false, PlaceableSpell::new);
public static final SpellType<ThrowableSpell> THROWN_SPELL = register("thrown", Affinity.NEUTRAL, 0, false, ThrowableSpell::new);
public static final SpellType<DisguiseSpell> DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new);
public static final SpellType<AbstractDisguiseSpell> CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, ChangelingDisguiseSpell::new);
public static final SpellType<JoustingSpell> RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new);
public static final SpellType<IceSpell> FROST = register("frost", Affinity.GOOD, 0xBDBDF9, true, IceSpell::new);

View file

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

View file

@ -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) {

View file

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

View file

@ -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<T extends LivingEntity> implements Equine<T>, 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);
});
}

View file

@ -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<AxolotlEntity> {
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;
}

View file

@ -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<BeeEntity> {
@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<BeeEntity> {
}
@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 {

View file

@ -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<BlazeEntity> {
@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<BlazeEntity> {
}
@Override
public void update(Pony player, BlazeEntity entity, DisguiseSpell spell) {
public void update(Pony player, BlazeEntity entity, Disguise spell) {
NbtCompound tag = spell.getDisguise().getOrCreateTag();

View file

@ -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<ChickenEntity> {
}
@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) {

View file

@ -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<CreeperEntity> {
@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);

View file

@ -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<Float> 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<Entity> attachments = new ArrayList<>();
private Optional<EntityDimensions> 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<Entity> 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);
}
default Optional<EntityAppearance> getAppearance() {
return Optional.ofNullable(getDisguise());
}
@Override
public FlightType getFlightType() {
if (!isPresent()) {
return FlightType.UNSET;
default FlightType getFlightType() {
return getAppearance().map(EntityAppearance::getFlightType).orElse(FlightType.UNSET);
}
@Override
default Optional<Float> getTargetEyeHeight(Pony player) {
return getAppearance().flatMap(d -> d.getTargetEyeHeight(player));
}
@Override
default Optional<EntityDimensions> getTargetDimensions(Pony player) {
return getAppearance().flatMap(d -> d.getTargetDimensions(player));
}
default Disguise setDisguise(@Nullable Entity entity) {
if (entity == getDisguise().getAppearance()) {
entity = null;
}
getDisguise().setAppearance(entity);
setDirty();
return this;
}
@SuppressWarnings("unchecked")
default boolean update(Caster<?> source, boolean tick) {
LivingEntity owner = source.getMaster();
Entity entity = getDisguise().getOrCreate(source);
if (owner == null) {
return true;
}
if (entity == null) {
return FlightType.NONE;
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<Entity> 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) {
@SuppressWarnings("unchecked")
Pony iplayer = Pony.of(((Owned<PlayerEntity>)entity).getMaster());
return iplayer == null ? FlightType.NONE : iplayer.getSpecies().getFlightType();
((Owned<LivingEntity>)entity).setMaster(player.getMaster());
}
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<Float> 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<Double> getDistance(Pony player) {
return EntityBehaviour.forEntity(entity).getCameraDistance(entity, player);
}
@Override
public Optional<EntityDimensions> 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<VoxelShape> output) {
getCollissionShapes(getAppearance(), context, output);
getAttachments().forEach(e -> getCollissionShapes(e, context, output));
}
private static void getCollissionShapes(@Nullable Entity entity, ShapeContext context, Consumer<VoxelShape> 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())
);
entity.getDataTracker().set(PlayerAccess.getModelBitFlag(), owner.getDataTracker().get(PlayerAccess.getModelBitFlag()));
}
}
public static List<VoxelShape> getColissonShapes(@Nullable Entity entity, WorldAccess world, Box box) {
List<VoxelShape> shapes = new ArrayList<>();
ShapeContext ctx = entity == null ? ShapeContext.absent() : ShapeContext.of(entity);
VoxelShape entityShape = VoxelShapes.cuboid(box.expand(1.0E-6D));
return !isDead() && !source.getMaster().isDead();
}
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);
}
});
});
return false;
});
return shapes;
static abstract class PlayerAccess extends PlayerEntity {
public PlayerAccess() { super(null, null, 0, null); }
static TrackedData<Byte> getModelBitFlag() {
return PLAYER_MODEL_PARTS;
}
}
}

View file

@ -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<EndermanEntity> {
@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 {

View file

@ -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<Float> BLOCK_HEIGHT = Optional.of(0.5F);
@NotNull
private String entityId = "";
@Nullable
private Entity entity;
@Nullable
private BlockEntity blockEntity;
private List<Entity> attachments = new ArrayList<>();
private Optional<EntityDimensions> 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<Entity> 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<PlayerEntity>)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<Float> 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<Double> getDistance(Pony player) {
return EntityBehaviour.forEntity(entity).getCameraDistance(entity, player);
}
@Override
public Optional<EntityDimensions> 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<VoxelShape> output) {
getCollissionShapes(getAppearance(), context, output);
getAttachments().forEach(e -> getCollissionShapes(e, context, output));
}
private static void getCollissionShapes(@Nullable Entity entity, ShapeContext context, Consumer<VoxelShape> 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<VoxelShape> getColissonShapes(@Nullable Entity entity, WorldAccess world, Box box) {
List<VoxelShape> 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;
}
}

View file

@ -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<T extends Entity> {
* <br>
* 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<T extends Entity> {
}
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<T extends Entity> {
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;

View file

@ -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<FallingBlockEntity> {
}
@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<FallingBlockEntity> {
}
@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<FallingBlockEntity> {
}
}
Disguise disguise = spell.getDisguise();
EntityAppearance disguise = spell.getDisguise();
List<Entity> attachments = disguise.getAttachments();
if (attachments.size() > 0) {
copyBaseAttributes(source.getMaster(), attachments.get(0), UP);

View file

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

View file

@ -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<LivingEntity> {
@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) {

View file

@ -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<AbstractMinecartEntity> {
@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<AbstractMinecartEntity> {
}
@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;

View file

@ -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<T extends MobEntity> extends EntityBehaviour<T> {
}
@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);

View file

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

View file

@ -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<T extends Entity & RangedAttackMob> 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)) {

View file

@ -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<SheepEntity> {
@Override
public void update(Pony player, SheepEntity entity, DisguiseSpell spell) {
public void update(Pony player, SheepEntity entity, Disguise spell) {
if (player.sneakingChanged()) {

View file

@ -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<ShulkerEntity> {
@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<ShulkerEntity> {
}
@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;

View file

@ -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<SilverfishEntity> {
@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);

View file

@ -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<SpellcastingIllagerEntity> {
@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<SpellcastingIl
private static abstract class SpellCastAccess extends SpellcastingIllagerEntity {
SpellCastAccess() {super(null, null);}
static void setSpell(Pony player, SpellcastingIllagerEntity entity, DisguiseSpell s) {
static void setSpell(Pony player, SpellcastingIllagerEntity entity, Disguise s) {
if (player.getMaster().isSneaking()) {
SpellcastingIllagerEntity.Spell[] spells = SpellcastingIllagerEntity.Spell.values();
SpellcastingIllagerEntity.Spell spell = spells[entity.world.random.nextInt(spells.length - 1) + 1];

View file

@ -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.JumpingMount;
@ -10,7 +9,7 @@ import net.minecraft.entity.passive.HorseBaseEntity;
public class SteedBehaviour<T extends LivingEntity & JumpingMount> extends EntityBehaviour<T> {
@Override
public void update(Pony player, T entity, DisguiseSpell spell) {
public void update(Pony player, T entity, Disguise spell) {
HorseBaseEntity horse = ((HorseBaseEntity)entity);

View file

@ -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<MerchantEntity> {
@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);

View file

@ -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<WaterCreatureEntity> {
@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);

View file

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

View file

@ -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<PlayerEntity> 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<PlayerEntity> 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<PlayerEntity> 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<PlayerEntity> 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;

View file

@ -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<Equine<
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
public void onIsClimbing(CallbackInfoReturnable<Boolean> 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<Equine<
@Inject(method = "isPushable()Z", at = @At("HEAD"), cancellable = true)
private void onIsPushable(CallbackInfoReturnable<Boolean> 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);

View file

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

View file

@ -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<VoxelShape> getEntityCollisions(@Nullable Entity entity, Box box) {
if (box.getAverageSideLength() >= 1.0E-7D) {
List<VoxelShape> shapes = Disguise.getColissonShapes(entity, this, box);
List<VoxelShape> shapes = EntityAppearance.getColissonShapes(entity, this, box);
if (!shapes.isEmpty()) {
return Stream.concat(shapes.stream(), WorldAccess.super.getEntityCollisions(entity, box).stream()).toList();
}