Consolidate common logic

This commit is contained in:
Sollace 2021-02-14 17:52:56 +02:00
parent 2aae1e6aa0
commit 82393eedef
4 changed files with 123 additions and 142 deletions

View file

@ -3,19 +3,16 @@ package com.minelittlepony.unicopia.entity;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.ability.magic.Affine; 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.Levelled;
import com.minelittlepony.unicopia.ability.magic.Spell; import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.network.EffectSync;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> { public class Creature extends Living<LivingEntity> {
private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND); private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
@ -23,16 +20,10 @@ public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> {
public static void boostrap() {} public static void boostrap() {}
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
private final Physics physics = new EntityPhysics<>(this); private final Physics physics = new EntityPhysics<>(this);
private final LivingEntity entity;
public Creature(LivingEntity entity) { public Creature(LivingEntity entity) {
this.entity = entity; super(entity, EFFECT);
entity.getDataTracker().startTracking(EFFECT, new CompoundTag());
} }
@Override @Override
@ -49,38 +40,6 @@ public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> {
public void setSpecies(Race race) { 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 @Override
public LevelStore getLevel() { public LevelStore getLevel() {
return LEVELS; return LEVELS;

View file

@ -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<T extends LivingEntity> implements Equine<T>, Caster<T> {
protected final T entity;
private final EffectSync effectDelegate;
private boolean prevSneaking;
private boolean prevLanded;
@Nullable
private Runnable landEvent;
protected Living(T entity, TrackedData<CompoundTag> 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);
});
}
}

View file

@ -159,7 +159,7 @@ public class Disguise implements NbtSerialisable {
return entity; 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); EntityBehaviour.forEntity(entity).onImpact(pony, entity, distance, damageMultiplier);
} }

View file

@ -12,21 +12,17 @@ import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.WorldTribeManager; import com.minelittlepony.unicopia.WorldTribeManager;
import com.minelittlepony.unicopia.ability.AbilityDispatcher; 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;
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
import com.minelittlepony.unicopia.ability.magic.spell.ShieldSpell; import com.minelittlepony.unicopia.ability.magic.spell.ShieldSpell;
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.entity.Physics; import com.minelittlepony.unicopia.entity.Physics;
import com.minelittlepony.unicopia.entity.PonyContainer; 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.entity.Trap;
import com.minelittlepony.unicopia.item.toxin.FoodType; import com.minelittlepony.unicopia.item.toxin.FoodType;
import com.minelittlepony.unicopia.item.toxin.Toxicity; import com.minelittlepony.unicopia.item.toxin.Toxicity;
import com.minelittlepony.unicopia.item.toxin.Toxin; import com.minelittlepony.unicopia.item.toxin.Toxin;
import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.EffectSync;
import com.minelittlepony.unicopia.network.MsgOtherPlayerCapabilities; import com.minelittlepony.unicopia.network.MsgOtherPlayerCapabilities;
import com.minelittlepony.unicopia.network.MsgRequestCapabilities; import com.minelittlepony.unicopia.network.MsgRequestCapabilities;
import com.minelittlepony.unicopia.network.Transmittable; import com.minelittlepony.unicopia.network.Transmittable;
@ -40,12 +36,10 @@ import com.mojang.authlib.GameProfile;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.attribute.DefaultAttributeContainer;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket; 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.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmittable, Copieable<Pony> { public class Pony extends Living<PlayerEntity> implements Transmittable, Copieable<Pony> {
private static final TrackedData<Integer> RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER); private static final TrackedData<Integer> RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER);
@ -67,7 +61,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
static final TrackedData<Float> XP = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT); static final TrackedData<Float> XP = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND); private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
private static final TrackedData<CompoundTag> HELD_EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
private final AbilityDispatcher powers = new AbilityDispatcher(this); private final AbilityDispatcher powers = new AbilityDispatcher(this);
private final PlayerPhysics gravity = new PlayerPhysics(this); private final PlayerPhysics gravity = new PlayerPhysics(this);
@ -78,17 +71,11 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
private final List<Tickable> tickers; private final List<Tickable> tickers;
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
private final Interpolator interpolator = new LinearInterpolator(); private final Interpolator interpolator = new LinearInterpolator();
private final PlayerEntity entity;
private boolean dirty; private boolean dirty;
private boolean speciesSet; private boolean speciesSet;
private boolean speciesPersisted; private boolean speciesPersisted;
private boolean prevSneaking;
private boolean prevLanded;
private int ticksHanging; private int ticksHanging;
@ -99,18 +86,13 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
private boolean invisible = false; private boolean invisible = false;
@Nullable
private Runnable landEvent;
public Pony(PlayerEntity player) { public Pony(PlayerEntity player) {
this.entity = player; super(player, EFFECT);
this.mana = new ManaContainer(this); this.mana = new ManaContainer(this);
this.levels = new PlayerLevelStore(this); this.levels = new PlayerLevelStore(this);
this.tickers = Lists.newArrayList(gravity, mana, attributes); this.tickers = Lists.newArrayList(gravity, mana, attributes);
player.getDataTracker().startTracking(RACE, Race.HUMAN.ordinal()); 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) { public static void registerAttributes(DefaultAttributeContainer.Builder builder) {
@ -128,14 +110,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
return Race.fromId(getMaster().getDataTracker().get(RACE)); return Race.fromId(getMaster().getDataTracker().get(RACE));
} }
public boolean sneakingChanged() {
return entity.isSneaking() != prevSneaking;
}
public boolean landedChanged() {
return entity.isOnGround() != prevLanded;
}
@Override @Override
public void setSpecies(Race race) { public void setSpecies(Race race) {
race = race.validate(entity); race = race.validate(entity);
@ -300,36 +274,13 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
ticksHanging = 0; ticksHanging = 0;
} }
if (hasSpell()) { super.tick();
Attached effect = getSpell(Attached.class, true);
if (effect != null) {
if (entity.getEntityWorld().isClient()) {
effect.renderOnPerson(this);
}
if (!effect.updateOnPerson(this)) {
setSpell(null);
}
}
}
tickers.forEach(Tickable::tick); tickers.forEach(Tickable::tick);
if (dirty) { if (dirty) {
sendCapabilities(true); 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<Float> onImpact(float distance, float damageMultiplier) { public Optional<Float> onImpact(float distance, float damageMultiplier) {
@ -357,35 +308,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
return Optional.empty(); 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 @Override
public boolean subtractEnergyCost(double foodSubtract) { public boolean subtractEnergyCost(double foodSubtract) {
if (!entity.isCreative() && !entity.world.isClient) { if (!entity.isCreative() && !entity.world.isClient) {
@ -462,7 +384,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
magicExhaustion = compound.getFloat("magicExhaustion"); magicExhaustion = compound.getFloat("magicExhaustion");
if (compound.contains("effect")) { 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<PlayerEntity>, Equine<PlayerEntity>, Transmi
setDirty(); setDirty();
} }
@Override
public EffectSync getPrimarySpellSlot() {
return effectDelegate;
}
@Override @Override
public void setSpell(@Nullable Spell effect) { public void setSpell(@Nullable Spell effect) {
Caster.super.setSpell(effect); super.setSpell(effect);
setDirty(); setDirty();
} }
@Override
public void setMaster(PlayerEntity owner) {
}
@Override
public PlayerEntity getMaster() {
return entity;
}
public boolean isClientPlayer() { public boolean isClientPlayer() {
return InteractionManager.instance().isClientPlayer(getMaster()); return InteractionManager.instance().isClientPlayer(getMaster());
} }