diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Creature.java b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java index f1108824..db076d6b 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Creature.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java @@ -3,19 +3,16 @@ package com.minelittlepony.unicopia.entity; import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.ability.magic.Affine; -import com.minelittlepony.unicopia.ability.magic.Attached; -import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Levelled; import com.minelittlepony.unicopia.ability.magic.Spell; import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry; -import com.minelittlepony.unicopia.network.EffectSync; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.nbt.CompoundTag; -public class Creature implements Equine, Caster { +public class Creature extends Living { private static final TrackedData EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND); @@ -23,16 +20,10 @@ public class Creature implements Equine, Caster { public static void boostrap() {} - private final EffectSync effectDelegate = new EffectSync(this, EFFECT); - private final Physics physics = new EntityPhysics<>(this); - private final LivingEntity entity; - public Creature(LivingEntity entity) { - this.entity = entity; - - entity.getDataTracker().startTracking(EFFECT, new CompoundTag()); + super(entity, EFFECT); } @Override @@ -49,38 +40,6 @@ public class Creature implements Equine, Caster { public void setSpecies(Race race) { } - @Override - public EffectSync getPrimarySpellSlot() { - return effectDelegate; - } - - @Override - public void tick() { - if (hasSpell()) { - Attached effect = getSpell(Attached.class, true); - - if (effect != null) { - if (entity.getEntityWorld().isClient()) { - effect.renderOnPerson(this); - } - - if (!effect.updateOnPerson(this)) { - setSpell(null); - } - } - } - } - - @Override - public void setMaster(LivingEntity owner) { - - } - - @Override - public LivingEntity getMaster() { - return entity; - } - @Override public LevelStore getLevel() { return LEVELS; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java new file mode 100644 index 00000000..c01c1491 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -0,0 +1,114 @@ +package com.minelittlepony.unicopia.entity; + +import javax.annotation.Nullable; + +import com.minelittlepony.unicopia.ability.magic.Attached; +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.Spell; +import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; +import com.minelittlepony.unicopia.network.EffectSync; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.data.TrackedData; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.nbt.CompoundTag; + +public abstract class Living implements Equine, Caster { + + protected final T entity; + + private final EffectSync effectDelegate; + + private boolean prevSneaking; + private boolean prevLanded; + + @Nullable + private Runnable landEvent; + + protected Living(T entity, TrackedData effect) { + this.entity = entity; + this.effectDelegate = new EffectSync(this, effect); + + entity.getDataTracker().startTracking(effect, new CompoundTag()); + } + + public void waitForFall(Runnable action) { + landEvent = action; + } + + public boolean sneakingChanged() { + return entity.isSneaking() != prevSneaking; + } + + public boolean landedChanged() { + return entity.isOnGround() != prevLanded; + } + + @Override + public EffectSync getPrimarySpellSlot() { + return effectDelegate; + } + + @Override + public void setMaster(T owner) { + } + + @Override + public T getMaster() { + return entity; + } + + @Override + public void tick() { + if (hasSpell()) { + Attached effect = getSpell(Attached.class, true); + + if (effect != null) { + if (entity.getEntityWorld().isClient()) { + effect.renderOnPerson(this); + } + + if (!effect.updateOnPerson(this)) { + setSpell(null); + } + } + } + + prevSneaking = entity.isSneaking(); + prevLanded = entity.isOnGround(); + + if (getPhysics().isGravityNegative() && entity.getY() > entity.world.getHeight() + 64) { + entity.damage(DamageSource.OUT_OF_WORLD, 4.0F); + } + } + + @Override + public void onJump() { + if (getPhysics().isGravityNegative()) { + entity.setVelocity(entity.getVelocity().multiply(1, -1, 1)); + } + } + + @Override + public boolean onProjectileImpact(ProjectileEntity projectile) { + if (hasSpell()) { + Spell effect = getSpell(true); + if (!effect.isDead() && effect.handleProjectileImpact(projectile)) { + return true; + } + } + + return false; + } + + protected void handleFall(float distance, float damageMultiplier) { + if (landEvent != null) { + landEvent.run(); + landEvent = null; + } + getSpellOrEmpty(DisguiseSpell.class, false).ifPresent(spell -> { + spell.getDisguise().onImpact(this, distance, damageMultiplier); + }); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java index 6ed3a705..bf751cc0 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java @@ -159,7 +159,7 @@ public class Disguise implements NbtSerialisable { return entity; } - public void onImpact(Pony pony, float distance, float damageMultiplier) { + public void onImpact(Caster pony, float distance, float damageMultiplier) { EntityBehaviour.forEntity(entity).onImpact(pony, entity, distance, damageMultiplier); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index a01da91b..0e7f8e53 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -12,21 +12,17 @@ import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.WorldTribeManager; import com.minelittlepony.unicopia.ability.AbilityDispatcher; -import com.minelittlepony.unicopia.ability.magic.Attached; -import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Spell; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.ShieldSpell; import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.entity.Physics; import com.minelittlepony.unicopia.entity.PonyContainer; -import com.minelittlepony.unicopia.entity.Equine; +import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.Trap; import com.minelittlepony.unicopia.item.toxin.FoodType; import com.minelittlepony.unicopia.item.toxin.Toxicity; import com.minelittlepony.unicopia.item.toxin.Toxin; import com.minelittlepony.unicopia.network.Channel; -import com.minelittlepony.unicopia.network.EffectSync; import com.minelittlepony.unicopia.network.MsgOtherPlayerCapabilities; import com.minelittlepony.unicopia.network.MsgRequestCapabilities; import com.minelittlepony.unicopia.network.Transmittable; @@ -40,12 +36,10 @@ import com.mojang.authlib.GameProfile; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.attribute.DefaultAttributeContainer; -import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket; @@ -57,7 +51,7 @@ import net.minecraft.util.Tickable; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -public class Pony implements Caster, Equine, Transmittable, Copieable { +public class Pony extends Living implements Transmittable, Copieable { private static final TrackedData RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER); @@ -67,7 +61,6 @@ public class Pony implements Caster, Equine, Transmi static final TrackedData XP = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT); private static final TrackedData EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND); - private static final TrackedData HELD_EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND); private final AbilityDispatcher powers = new AbilityDispatcher(this); private final PlayerPhysics gravity = new PlayerPhysics(this); @@ -78,17 +71,11 @@ public class Pony implements Caster, Equine, Transmi private final List tickers; - private final EffectSync effectDelegate = new EffectSync(this, EFFECT); - private final Interpolator interpolator = new LinearInterpolator(); - private final PlayerEntity entity; - private boolean dirty; private boolean speciesSet; private boolean speciesPersisted; - private boolean prevSneaking; - private boolean prevLanded; private int ticksHanging; @@ -99,18 +86,13 @@ public class Pony implements Caster, Equine, Transmi private boolean invisible = false; - @Nullable - private Runnable landEvent; - public Pony(PlayerEntity player) { - this.entity = player; + super(player, EFFECT); this.mana = new ManaContainer(this); this.levels = new PlayerLevelStore(this); this.tickers = Lists.newArrayList(gravity, mana, attributes); player.getDataTracker().startTracking(RACE, Race.HUMAN.ordinal()); - player.getDataTracker().startTracking(EFFECT, new CompoundTag()); - player.getDataTracker().startTracking(HELD_EFFECT, new CompoundTag()); } public static void registerAttributes(DefaultAttributeContainer.Builder builder) { @@ -128,14 +110,6 @@ public class Pony implements Caster, Equine, Transmi return Race.fromId(getMaster().getDataTracker().get(RACE)); } - public boolean sneakingChanged() { - return entity.isSneaking() != prevSneaking; - } - - public boolean landedChanged() { - return entity.isOnGround() != prevLanded; - } - @Override public void setSpecies(Race race) { race = race.validate(entity); @@ -300,36 +274,13 @@ public class Pony implements Caster, Equine, Transmi ticksHanging = 0; } - if (hasSpell()) { - Attached effect = getSpell(Attached.class, true); - - if (effect != null) { - if (entity.getEntityWorld().isClient()) { - effect.renderOnPerson(this); - } - - if (!effect.updateOnPerson(this)) { - setSpell(null); - } - } - } + super.tick(); tickers.forEach(Tickable::tick); if (dirty) { sendCapabilities(true); } - - prevSneaking = entity.isSneaking(); - prevLanded = entity.isOnGround(); - - if (gravity.isGravityNegative() && entity.getY() > entity.world.getHeight() + 64) { - entity.damage(DamageSource.OUT_OF_WORLD, 4.0F); - } - } - - public void waitForFall(Runnable action) { - landEvent = action; } public Optional onImpact(float distance, float damageMultiplier) { @@ -357,35 +308,6 @@ public class Pony implements Caster, Equine, Transmi return Optional.empty(); } - private void handleFall(float distance, float damageMultiplier) { - if (landEvent != null) { - landEvent.run(); - landEvent = null; - } - getSpellOrEmpty(DisguiseSpell.class, false).ifPresent(spell -> { - spell.getDisguise().onImpact(this, distance, damageMultiplier); - }); - } - - @Override - public void onJump() { - if (gravity.isGravityNegative()) { - entity.setVelocity(entity.getVelocity().multiply(1, -1, 1)); - } - } - - @Override - public boolean onProjectileImpact(ProjectileEntity projectile) { - if (hasSpell()) { - Spell effect = getSpell(true); - if (!effect.isDead() && effect.handleProjectileImpact(projectile)) { - return true; - } - } - - return false; - } - @Override public boolean subtractEnergyCost(double foodSubtract) { if (!entity.isCreative() && !entity.world.isClient) { @@ -462,7 +384,7 @@ public class Pony implements Caster, Equine, Transmi magicExhaustion = compound.getFloat("magicExhaustion"); if (compound.contains("effect")) { - effectDelegate.set(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect"))); + getPrimarySpellSlot().set(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect"))); } } @@ -476,26 +398,12 @@ public class Pony implements Caster, Equine, Transmi setDirty(); } - @Override - public EffectSync getPrimarySpellSlot() { - return effectDelegate; - } - @Override public void setSpell(@Nullable Spell effect) { - Caster.super.setSpell(effect); + super.setSpell(effect); setDirty(); } - @Override - public void setMaster(PlayerEntity owner) { - } - - @Override - public PlayerEntity getMaster() { - return entity; - } - public boolean isClientPlayer() { return InteractionManager.instance().isClientPlayer(getMaster()); }