mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Move the code dealing with disguise entities into its own class
This commit is contained in:
parent
e8292e20ec
commit
c7e1cea0c2
6 changed files with 274 additions and 212 deletions
|
@ -5,6 +5,7 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||||
|
import com.minelittlepony.unicopia.entity.behaviour.VirtualEntity;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
import com.minelittlepony.unicopia.util.VecHelper;
|
import com.minelittlepony.unicopia.util.VecHelper;
|
||||||
|
@ -54,6 +55,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
|
||||||
looked = Pony.of((PlayerEntity)looked)
|
looked = Pony.of((PlayerEntity)looked)
|
||||||
.getSpellOrEmpty(DisguiseSpell.class)
|
.getSpellOrEmpty(DisguiseSpell.class)
|
||||||
.map(DisguiseSpell::getDisguise)
|
.map(DisguiseSpell::getDisguise)
|
||||||
|
.map(VirtualEntity::getAppearance)
|
||||||
.orElse(looked);
|
.orElse(looked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package com.minelittlepony.unicopia.ability.magic.spell;
|
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Affinity;
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
|
@ -11,45 +9,24 @@ import com.minelittlepony.unicopia.ability.FlightPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.HeightPredicate;
|
import com.minelittlepony.unicopia.ability.HeightPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.AttachableSpell;
|
import com.minelittlepony.unicopia.ability.magic.AttachableSpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.CasterUtils;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Suppressable;
|
import com.minelittlepony.unicopia.ability.magic.Suppressable;
|
||||||
import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour;
|
import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour;
|
||||||
|
import com.minelittlepony.unicopia.entity.behaviour.VirtualEntity;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
|
|
||||||
import net.minecraft.block.entity.SkullBlockEntity;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.entity.FallingBlockEntity;
|
|
||||||
import net.minecraft.entity.Flutterer;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.boss.dragon.EnderDragonEntity;
|
|
||||||
import net.minecraft.entity.data.TrackedData;
|
import net.minecraft.entity.data.TrackedData;
|
||||||
import net.minecraft.entity.decoration.AbstractDecorationEntity;
|
|
||||||
import net.minecraft.entity.mob.AmbientEntity;
|
|
||||||
import net.minecraft.entity.mob.FlyingEntity;
|
|
||||||
import net.minecraft.entity.mob.MobEntity;
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
import net.minecraft.entity.mob.ShulkerEntity;
|
|
||||||
import net.minecraft.entity.mob.VexEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||||
import net.minecraft.entity.projectile.ShulkerBulletEntity;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
||||||
public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Suppressable, FlightPredicate, HeightPredicate {
|
public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Suppressable, FlightPredicate, HeightPredicate {
|
||||||
|
|
||||||
@Nonnull
|
private final VirtualEntity disguise = new VirtualEntity();
|
||||||
private String entityId = "";
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Entity entity;
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private CompoundTag entityNbt;
|
|
||||||
|
|
||||||
private int suppressionCounter;
|
private int suppressionCounter;
|
||||||
|
|
||||||
|
@ -89,120 +66,23 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
||||||
return suppressionCounter > 0;
|
return suppressionCounter > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entity getDisguise() {
|
public VirtualEntity getDisguise() {
|
||||||
return entity;
|
return disguise;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisguiseSpell setDisguise(@Nullable Entity entity) {
|
public DisguiseSpell setDisguise(@Nullable Entity entity) {
|
||||||
if (entity == this.entity) {
|
if (entity == disguise.getAppearance()) {
|
||||||
entity = null;
|
entity = null;
|
||||||
}
|
}
|
||||||
this.entityNbt = null;
|
|
||||||
this.entityId = "";
|
|
||||||
|
|
||||||
removeDisguise();
|
|
||||||
|
|
||||||
if (entity != null) {
|
|
||||||
entityNbt = encodeEntityToNBT(entity);
|
|
||||||
entityId = entityNbt.getString("id");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
disguise.setAppearance(entity);
|
||||||
setDirty(true);
|
setDirty(true);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removeDisguise() {
|
|
||||||
if (entity != null) {
|
|
||||||
entity.remove();
|
|
||||||
entity = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected CompoundTag encodeEntityToNBT(Entity entity) {
|
|
||||||
CompoundTag entityNbt = new CompoundTag();
|
|
||||||
|
|
||||||
if (entity instanceof PlayerEntity) {
|
|
||||||
GameProfile profile = ((PlayerEntity)entity).getGameProfile();
|
|
||||||
|
|
||||||
entityNbt.putString("id", "player");
|
|
||||||
entityNbt.putUuid("playerId", profile.getId());
|
|
||||||
entityNbt.putString("playerName", profile.getName());
|
|
||||||
|
|
||||||
CompoundTag tag = new CompoundTag();
|
|
||||||
|
|
||||||
entity.saveToTag(tag);
|
|
||||||
|
|
||||||
entityNbt.put("playerNbt", tag);
|
|
||||||
} else {
|
|
||||||
entity.saveToTag(entityNbt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entityNbt;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized void createPlayer(CompoundTag nbt, GameProfile profile, Caster<?> source) {
|
|
||||||
removeDisguise();
|
|
||||||
|
|
||||||
entity = InteractionManager.instance().createPlayer(source.getEntity(), profile);
|
|
||||||
entity.setCustomName(source.getOwner().getName());
|
|
||||||
((PlayerEntity)entity).fromTag(nbt.getCompound("playerNbt"));
|
|
||||||
entity.setUuid(UUID.randomUUID());
|
|
||||||
entity.extinguish();
|
|
||||||
|
|
||||||
onEntityLoaded(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkAndCreateDisguiseEntity(Caster<?> source) {
|
|
||||||
if (entity == null && entityNbt != null) {
|
|
||||||
CompoundTag nbt = entityNbt;
|
|
||||||
entityNbt = null;
|
|
||||||
|
|
||||||
if ("player".equals(entityId)) {
|
|
||||||
createPlayer(nbt, new GameProfile(
|
|
||||||
nbt.getUuid("playerId"),
|
|
||||||
nbt.getString("playerName")
|
|
||||||
), source);
|
|
||||||
new Thread(() -> createPlayer(nbt, SkullBlockEntity.loadProperties(new GameProfile(
|
|
||||||
null,
|
|
||||||
nbt.getString("playerName")
|
|
||||||
)), source)).start();
|
|
||||||
} else {
|
|
||||||
if (source.isClient()) {
|
|
||||||
entity = EntityType.fromTag(nbt).map(type -> type.create(source.getWorld())).orElse(null);
|
|
||||||
if (entity != null) {
|
|
||||||
EntityBehaviour.forEntity(entity).onCreate(entity);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
entity = EntityType.loadEntityWithPassengers(nbt, source.getWorld(), e -> {
|
|
||||||
EntityBehaviour.forEntity(e).onCreate(e);
|
|
||||||
|
|
||||||
return e;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onEntityLoaded(source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onEntityLoaded(Caster<?> source) {
|
|
||||||
source.getEntity().calculateDimensions();
|
|
||||||
|
|
||||||
if (entity == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CasterUtils.toCaster(entity).ifPresent(c -> c.setSpell(null));
|
|
||||||
|
|
||||||
if (source.isClient()) {
|
|
||||||
source.getWorld().spawnEntity(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleProjectileImpact(ProjectileEntity projectile) {
|
public boolean handleProjectileImpact(ProjectileEntity projectile) {
|
||||||
return getDisguise() == projectile;
|
return disguise.getAppearance() == projectile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -219,6 +99,8 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
||||||
public boolean update(Caster<?> source, boolean tick) {
|
public boolean update(Caster<?> source, boolean tick) {
|
||||||
LivingEntity owner = source.getOwner();
|
LivingEntity owner = source.getOwner();
|
||||||
|
|
||||||
|
Entity entity = disguise.getAppearance();
|
||||||
|
|
||||||
if (isSuppressed()) {
|
if (isSuppressed()) {
|
||||||
suppressionCounter--;
|
suppressionCounter--;
|
||||||
|
|
||||||
|
@ -235,7 +117,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAndCreateDisguiseEntity(source);
|
entity = disguise.getOrCreate(source);
|
||||||
|
|
||||||
if (owner == null) {
|
if (owner == null) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -264,7 +146,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
||||||
|
|
||||||
behaviour.copyBaseAttributes(owner, entity);
|
behaviour.copyBaseAttributes(owner, entity);
|
||||||
|
|
||||||
if (tick && !skipsUpdate(entity)) {
|
if (tick && !disguise.skipsUpdate()) {
|
||||||
entity.tick();
|
entity.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +178,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
||||||
@Override
|
@Override
|
||||||
public void setDead() {
|
public void setDead() {
|
||||||
super.setDead();
|
super.setDead();
|
||||||
removeDisguise();
|
disguise.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -314,13 +196,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
||||||
super.toNBT(compound);
|
super.toNBT(compound);
|
||||||
|
|
||||||
compound.putInt("suppressionCounter", suppressionCounter);
|
compound.putInt("suppressionCounter", suppressionCounter);
|
||||||
compound.putString("entityId", entityId);
|
disguise.toNBT(compound);
|
||||||
|
|
||||||
if (entityNbt != null) {
|
|
||||||
compound.put("entity", entityNbt);
|
|
||||||
} else if (entity != null) {
|
|
||||||
compound.put("entity", encodeEntityToNBT(entity));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -328,85 +204,22 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
||||||
super.fromNBT(compound);
|
super.fromNBT(compound);
|
||||||
|
|
||||||
suppressionCounter = compound.getInt("suppressionCounter");
|
suppressionCounter = compound.getInt("suppressionCounter");
|
||||||
|
disguise.fromNBT(compound);
|
||||||
String newId = compound.getString("entityId");
|
|
||||||
|
|
||||||
if (!newId.contentEquals(entityId)) {
|
|
||||||
entityNbt = null;
|
|
||||||
removeDisguise();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compound.contains("entity")) {
|
|
||||||
entityId = newId;
|
|
||||||
|
|
||||||
entityNbt = compound.getCompound("entity");
|
|
||||||
|
|
||||||
compound.getString("entityData");
|
|
||||||
|
|
||||||
if (entity != null) {
|
|
||||||
try {
|
|
||||||
entity.fromTag(entityNbt);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
// Mojang pls
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkCanFly(Pony player) {
|
public boolean checkCanFly(Pony player) {
|
||||||
if (entity == null || !player.getSpecies().canFly()) {
|
return disguise.canFly() && player.getSpecies().canFly();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity instanceof Owned) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Pony iplayer = Pony.of(((Owned<PlayerEntity>)entity).getOwner());
|
|
||||||
|
|
||||||
return iplayer != null && iplayer.getSpecies().canFly();
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity instanceof FlyingEntity
|
|
||||||
|| entity instanceof AmbientEntity
|
|
||||||
|| entity instanceof EnderDragonEntity
|
|
||||||
|| entity instanceof VexEntity
|
|
||||||
|| entity instanceof ShulkerBulletEntity
|
|
||||||
|| entity instanceof Flutterer
|
|
||||||
|| ProjectileUtil.isProjectile(entity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getTargetEyeHeight(Pony player) {
|
public float getTargetEyeHeight(Pony player) {
|
||||||
if (entity != null && !isSuppressed()) {
|
return isSuppressed() ? -1 : disguise.getStandingEyeHeight();
|
||||||
if (entity instanceof FallingBlockEntity) {
|
|
||||||
return 0.5F;
|
|
||||||
}
|
|
||||||
return entity.getStandingEyeHeight();
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getTargetBodyHeight(Pony player) {
|
public float getTargetBodyHeight(Pony player) {
|
||||||
if (entity != null && !isSuppressed()) {
|
return isSuppressed() ? -1 : disguise.getHeight();
|
||||||
if (entity instanceof FallingBlockEntity) {
|
|
||||||
return 0.9F;
|
|
||||||
}
|
|
||||||
return entity.getHeight() - 0.1F;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean skipsUpdate(Entity entity) {
|
|
||||||
return entity instanceof FallingBlockEntity
|
|
||||||
|| entity instanceof AbstractDecorationEntity
|
|
||||||
|| entity instanceof PlayerEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isAttachedEntity(Entity entity) {
|
|
||||||
return entity instanceof ShulkerEntity
|
|
||||||
|| entity instanceof AbstractDecorationEntity
|
|
||||||
|| entity instanceof FallingBlockEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static abstract class PlayerAccess extends PlayerEntity {
|
static abstract class PlayerAccess extends PlayerEntity {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
|
||||||
import com.minelittlepony.unicopia.util.Registries;
|
import com.minelittlepony.unicopia.util.Registries;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
@ -39,8 +38,7 @@ public class EntityBehaviour<T extends Entity> {
|
||||||
to.removed = from.removed;
|
to.removed = from.removed;
|
||||||
to.setOnGround(from.isOnGround());
|
to.setOnGround(from.isOnGround());
|
||||||
|
|
||||||
if (DisguiseSpell.isAttachedEntity(to)) {
|
if (VirtualEntity.isAxisAligned(to)) {
|
||||||
|
|
||||||
double x = Math.floor(from.getX()) + 0.5;
|
double x = Math.floor(from.getX()) + 0.5;
|
||||||
double y = Math.floor(from.getY());
|
double y = Math.floor(from.getY());
|
||||||
double z = Math.floor(from.getZ()) + 0.5;
|
double z = Math.floor(from.getZ()) + 0.5;
|
||||||
|
|
|
@ -0,0 +1,247 @@
|
||||||
|
package com.minelittlepony.unicopia.entity.behaviour;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.InteractionManager;
|
||||||
|
import com.minelittlepony.unicopia.Owned;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.CasterUtils;
|
||||||
|
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.entity.SkullBlockEntity;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.FallingBlockEntity;
|
||||||
|
import net.minecraft.entity.Flutterer;
|
||||||
|
import net.minecraft.entity.boss.dragon.EnderDragonEntity;
|
||||||
|
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.CompoundTag;
|
||||||
|
|
||||||
|
public class VirtualEntity implements NbtSerialisable {
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private String entityId = "";
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Entity entity;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private CompoundTag entityNbt;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Entity getAppearance() {
|
||||||
|
return 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 void remove() {
|
||||||
|
if (entity != null) {
|
||||||
|
entity.remove();
|
||||||
|
entity = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void createPlayer(CompoundTag nbt, GameProfile profile, Caster<?> source) {
|
||||||
|
remove();
|
||||||
|
|
||||||
|
entity = InteractionManager.instance().createPlayer(source.getEntity(), profile);
|
||||||
|
entity.setCustomName(source.getOwner().getName());
|
||||||
|
((PlayerEntity)entity).fromTag(nbt.getCompound("playerNbt"));
|
||||||
|
entity.setUuid(UUID.randomUUID());
|
||||||
|
entity.extinguish();
|
||||||
|
|
||||||
|
onEntityLoaded(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity getOrCreate(Caster<?> source) {
|
||||||
|
if (entity == null && entityNbt != null) {
|
||||||
|
CompoundTag nbt = entityNbt;
|
||||||
|
entityNbt = null;
|
||||||
|
|
||||||
|
if ("player".equals(entityId)) {
|
||||||
|
createPlayer(nbt, new GameProfile(
|
||||||
|
nbt.getUuid("playerId"),
|
||||||
|
nbt.getString("playerName")
|
||||||
|
), source);
|
||||||
|
new Thread(() -> createPlayer(nbt, SkullBlockEntity.loadProperties(new GameProfile(
|
||||||
|
null,
|
||||||
|
nbt.getString("playerName")
|
||||||
|
)), source)).start();
|
||||||
|
} else {
|
||||||
|
if (source.isClient()) {
|
||||||
|
entity = EntityType.fromTag(nbt).map(type -> type.create(source.getWorld())).orElse(null);
|
||||||
|
if (entity != null) {
|
||||||
|
EntityBehaviour.forEntity(entity).onCreate(entity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entity = EntityType.loadEntityWithPassengers(nbt, source.getWorld(), e -> {
|
||||||
|
EntityBehaviour.forEntity(e).onCreate(e);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEntityLoaded(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onEntityLoaded(Caster<?> source) {
|
||||||
|
source.getEntity().calculateDimensions();
|
||||||
|
|
||||||
|
if (entity == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CasterUtils.toCaster(entity).ifPresent(c -> c.setSpell(null));
|
||||||
|
|
||||||
|
if (source.isClient()) {
|
||||||
|
source.getWorld().spawnEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canFly() {
|
||||||
|
if (entity == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity instanceof Owned) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Pony iplayer = Pony.of(((Owned<PlayerEntity>)entity).getOwner());
|
||||||
|
|
||||||
|
return iplayer != null && iplayer.getSpecies().canFly();
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity instanceof FlyingEntity
|
||||||
|
|| entity instanceof AmbientEntity
|
||||||
|
|| entity instanceof EnderDragonEntity
|
||||||
|
|| entity instanceof VexEntity
|
||||||
|
|| entity instanceof ShulkerBulletEntity
|
||||||
|
|| entity instanceof Flutterer
|
||||||
|
|| ProjectileUtil.isProjectile(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getStandingEyeHeight() {
|
||||||
|
if (entity != null) {
|
||||||
|
if (entity instanceof FallingBlockEntity) {
|
||||||
|
return 0.5F;
|
||||||
|
}
|
||||||
|
return entity.getStandingEyeHeight();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHeight() {
|
||||||
|
if (entity != null) {
|
||||||
|
if (entity instanceof FallingBlockEntity) {
|
||||||
|
return 0.9F;
|
||||||
|
}
|
||||||
|
return entity.getHeight() - 0.1F;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(CompoundTag 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(CompoundTag compound) {
|
||||||
|
String newId = compound.getString("entityId");
|
||||||
|
|
||||||
|
if (!newId.contentEquals(entityId)) {
|
||||||
|
entityNbt = null;
|
||||||
|
remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compound.contains("entity")) {
|
||||||
|
entityId = newId;
|
||||||
|
|
||||||
|
entityNbt = compound.getCompound("entity");
|
||||||
|
|
||||||
|
compound.getString("entityData");
|
||||||
|
|
||||||
|
if (entity != null) {
|
||||||
|
try {
|
||||||
|
entity.fromTag(entityNbt);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
// Mojang pls
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAxisAligned(@Nullable Entity entity) {
|
||||||
|
return entity instanceof ShulkerEntity
|
||||||
|
|| entity instanceof AbstractDecorationEntity
|
||||||
|
|| entity instanceof FallingBlockEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompoundTag encodeEntityToNBT(Entity entity) {
|
||||||
|
CompoundTag entityNbt = new CompoundTag();
|
||||||
|
|
||||||
|
if (entity instanceof PlayerEntity) {
|
||||||
|
GameProfile profile = ((PlayerEntity)entity).getGameProfile();
|
||||||
|
|
||||||
|
entityNbt.putString("id", "player");
|
||||||
|
entityNbt.putUuid("playerId", profile.getId());
|
||||||
|
entityNbt.putString("playerName", profile.getName());
|
||||||
|
|
||||||
|
CompoundTag tag = new CompoundTag();
|
||||||
|
|
||||||
|
entity.saveToTag(tag);
|
||||||
|
|
||||||
|
entityNbt.put("playerNbt", tag);
|
||||||
|
} else {
|
||||||
|
entity.saveToTag(entityNbt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entityNbt;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,12 +14,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||||
import com.minelittlepony.unicopia.entity.Creature;
|
import com.minelittlepony.unicopia.entity.Creature;
|
||||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||||
|
import com.minelittlepony.unicopia.entity.behaviour.VirtualEntity;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.entity.Equine;
|
import com.minelittlepony.unicopia.entity.Equine;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.mob.SpiderEntity;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
@ -49,11 +49,13 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<
|
||||||
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
|
||||||
public void onIsClimbing(CallbackInfoReturnable<Boolean> info) {
|
public void onIsClimbing(CallbackInfoReturnable<Boolean> info) {
|
||||||
if (get() instanceof Pony && horizontalCollision) {
|
if (get() instanceof Pony && horizontalCollision) {
|
||||||
DisguiseSpell disguise = ((Pony)get()).getSpell(DisguiseSpell.class, false);
|
((Pony)get()).getSpellOrEmpty(DisguiseSpell.class, false)
|
||||||
if (disguise != null && disguise.getDisguise() instanceof SpiderEntity) {
|
.map(DisguiseSpell::getDisguise)
|
||||||
|
.filter(VirtualEntity::canClimbWalls)
|
||||||
|
.ifPresent(v -> {
|
||||||
climbingPos = Optional.of(getBlockPos());
|
climbingPos = Optional.of(getBlockPos());
|
||||||
info.setReturnValue(true);
|
info.setReturnValue(true);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ abstract class MixinTargetPredicate {
|
||||||
Equine<?> eq = Equine.of(targetEntity);
|
Equine<?> eq = Equine.of(targetEntity);
|
||||||
if (eq instanceof Pony) {
|
if (eq instanceof Pony) {
|
||||||
((Pony)eq).getSpellOrEmpty(DisguiseSpell.class).ifPresent(spell -> {
|
((Pony)eq).getSpellOrEmpty(DisguiseSpell.class).ifPresent(spell -> {
|
||||||
if (spell.getDisguise() == baseEntity) {
|
if (spell.getDisguise().getAppearance() == baseEntity) {
|
||||||
info.setReturnValue(false);
|
info.setReturnValue(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue