diff --git a/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java b/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java index 1378ebab..a4850446 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java @@ -8,7 +8,6 @@ import javax.annotation.Nullable; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.ability.data.Hit; -import com.minelittlepony.unicopia.entity.Updatable; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.network.MsgPlayerAbility; import com.minelittlepony.unicopia.network.Channel; @@ -16,8 +15,9 @@ import com.minelittlepony.unicopia.util.NbtSerialisable; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Identifier; +import net.minecraft.util.Tickable; -public class AbilityDispatcher implements Updatable, NbtSerialisable { +public class AbilityDispatcher implements Tickable, NbtSerialisable { private final Pony player; @@ -88,7 +88,7 @@ public class AbilityDispatcher implements Updatable, NbtSerialisable { } @Override - public void onUpdate() { + public void tick() { getActiveAbility().ifPresent(this::activate); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/CarryAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/CarryAbility.java index 88f6cdfc..38d0d0cc 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/CarryAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/CarryAbility.java @@ -28,8 +28,8 @@ public class CarryAbility implements Ability { } @Override - public boolean canUse(Race playerSpecies) { - return playerSpecies.canFly(); + public boolean canUse(Race race) { + return race.canFly(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java index 72a6b370..94a9fc15 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java @@ -74,7 +74,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility { return disc; }).setDisguise(looked); - iplayer.sendCapabilities(true); + iplayer.setDirty(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java index 1fe9a1de..9a9eae22 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java @@ -42,8 +42,8 @@ public class ChangelingFeedAbility implements Ability { } @Override - public boolean canUse(Race playerSpecies) { - return playerSpecies == Race.CHANGELING; + public boolean canUse(Race race) { + return race == Race.CHANGELING; } @Nullable diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java index 1ce03159..0ac5997c 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java @@ -33,8 +33,8 @@ public class EarthPonyGrowAbility implements Ability { } @Override - public boolean canUse(Race playerSpecies) { - return playerSpecies == Race.EARTH; + public boolean canUse(Race race) { + return race == Race.EARTH; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java index 54640ed5..71572f6e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java @@ -64,8 +64,8 @@ public class EarthPonyStompAbility implements Ability { } @Override - public boolean canUse(Race playerSpecies) { - return playerSpecies.canUseEarth(); + public boolean canUse(Race race) { + return race.canUseEarth(); } @Nullable diff --git a/src/main/java/com/minelittlepony/unicopia/ability/PegasusCloudInteractionAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/PegasusCloudInteractionAbility.java index cd785ff0..14565897 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/PegasusCloudInteractionAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/PegasusCloudInteractionAbility.java @@ -25,8 +25,8 @@ public class PegasusCloudInteractionAbility implements Ability { } @Override - public boolean canUse(Race playerSpecies) { - return playerSpecies.canInteractWithClouds(); + public boolean canUse(Race race) { + return race.canInteractWithClouds(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index 5e734089..3bc87193 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -23,8 +23,8 @@ public class UnicornCastingAbility implements Ability { } @Override - public boolean canUse(Race playerSpecies) { - return playerSpecies.canCast(); + public boolean canUse(Race race) { + return race.canCast(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java new file mode 100644 index 00000000..9d98d8f0 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java @@ -0,0 +1,67 @@ +package com.minelittlepony.unicopia.client.render; + +import com.minelittlepony.unicopia.entity.player.Pony; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.util.math.Vector3f; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; + +public class WorldRenderDelegate { + + public static final WorldRenderDelegate INSTANCE = new WorldRenderDelegate(); + + public void beforeEntityRender(Pony pony, MatrixStack matrices, double x, double y, double z) { + if (pony.getPhysics().isGravityNegative()) { + matrices.push(); + + Entity entity = pony.getOwner(); + + matrices.translate(x, y, z); + matrices.translate(0, entity.getHeight(), 0); + matrices.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(180)); + matrices.translate(-x, -y, -z); + + flipAngles(entity); + } + } + + public void afterEntityRender(Pony pony, MatrixStack matrices) { + if (pony.getPhysics().isGravityNegative()) { + matrices.pop(); + + flipAngles(pony.getOwner()); + + } + } + + private void flipAngles(Entity entity) { + if (MinecraftClient.getInstance().options.perspective > 0) { + entity.prevYaw *= -1; + entity.yaw *= -1; + + if (entity instanceof LivingEntity) { + LivingEntity living = (LivingEntity)entity; + + living.bodyYaw = -living.bodyYaw; + living.prevBodyYaw = -living.prevBodyYaw; + living.headYaw = -living.headYaw; + living.prevHeadYaw = -living.prevHeadYaw; + } + } + entity.prevPitch *= -1; + entity.pitch *= -1; + } + + public void applyWorldTransform(MatrixStack matrices, float tickDelta) { + PlayerEntity player = MinecraftClient.getInstance().player; + + if (player != null && MinecraftClient.getInstance().cameraEntity == player) { + float roll = Pony.of(player).getCamera().calculateRoll(); + + matrices.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(roll)); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/command/GravityCommand.java b/src/main/java/com/minelittlepony/unicopia/command/GravityCommand.java index e27db4fe..71d10d07 100644 --- a/src/main/java/com/minelittlepony/unicopia/command/GravityCommand.java +++ b/src/main/java/com/minelittlepony/unicopia/command/GravityCommand.java @@ -39,7 +39,7 @@ class GravityCommand { Pony iplayer = Pony.of(player); - float gravity = iplayer.getGravity().getGravitationConstant(); + float gravity = iplayer.getPhysics().getGravityModifier(); if (source.getPlayer() != player) { translationKey += ".other"; @@ -54,8 +54,8 @@ class GravityCommand { Pony iplayer = Pony.of(player); - iplayer.getGravity().setGraviationConstant(gravity); - iplayer.sendCapabilities(true); + iplayer.getPhysics().setGravityModifier(gravity); + iplayer.setDirty(); if (isSelf) { player.sendMessage(new TranslatableText(translationKey, gravity)); diff --git a/src/main/java/com/minelittlepony/unicopia/command/SpeciesCommand.java b/src/main/java/com/minelittlepony/unicopia/command/SpeciesCommand.java index 4391b37a..5d392ea7 100644 --- a/src/main/java/com/minelittlepony/unicopia/command/SpeciesCommand.java +++ b/src/main/java/com/minelittlepony/unicopia/command/SpeciesCommand.java @@ -49,7 +49,7 @@ class SpeciesCommand { if (race.isPermitted(player)) { Pony pony = Pony.of(player); pony.setSpecies(race); - pony.sendCapabilities(false); + pony.setDirty(); Text formattedName = new TranslatableText(race.name().toLowerCase()); diff --git a/src/main/java/com/minelittlepony/unicopia/ducks/IItemEntity.java b/src/main/java/com/minelittlepony/unicopia/ducks/IItemEntity.java index 10f234f0..94bbaefa 100644 --- a/src/main/java/com/minelittlepony/unicopia/ducks/IItemEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/ducks/IItemEntity.java @@ -1,8 +1,8 @@ package com.minelittlepony.unicopia.ducks; -import com.minelittlepony.unicopia.entity.ItemEntityCapabilities; +import com.minelittlepony.unicopia.entity.ItemImpl; -public interface IItemEntity extends PonyContainer { +public interface IItemEntity extends PonyContainer { int getAge(); diff --git a/src/main/java/com/minelittlepony/unicopia/ducks/PonyContainer.java b/src/main/java/com/minelittlepony/unicopia/ducks/PonyContainer.java index a6599583..9d68338e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ducks/PonyContainer.java +++ b/src/main/java/com/minelittlepony/unicopia/ducks/PonyContainer.java @@ -10,9 +10,9 @@ import com.minelittlepony.unicopia.magic.Caster; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; -public interface PonyContainer { +public interface PonyContainer> { - Ponylike create(); + Ponylike create(); T get(); @@ -28,7 +28,7 @@ public interface PonyContainer { } @SuppressWarnings("unchecked") - static Optional> of(Entity entity) { + static > Optional> of(Entity entity) { if (entity instanceof PonyContainer) { return Optional.of(((PonyContainer)entity)); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/LivingEntityCapabilities.java b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java similarity index 89% rename from src/main/java/com/minelittlepony/unicopia/entity/LivingEntityCapabilities.java rename to src/main/java/com/minelittlepony/unicopia/entity/Creature.java index 4538ccc9..32cbdc53 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/LivingEntityCapabilities.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java @@ -15,7 +15,7 @@ import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.nbt.CompoundTag; -public class LivingEntityCapabilities implements RaceContainer, Caster { +public class Creature implements Ponylike, Caster { private static final TrackedData EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND); @@ -23,9 +23,11 @@ public class LivingEntityCapabilities implements RaceContainer, Ca private final EffectSync effectDelegate = new EffectSync(this, EFFECT); + private final Physics physics = new EntityPhysics<>(this); + private final LivingEntity entity; - public LivingEntityCapabilities(LivingEntity entity) { + public Creature(LivingEntity entity) { this.entity = entity; entity.getDataTracker().startTracking(EFFECT, new CompoundTag()); @@ -36,6 +38,11 @@ public class LivingEntityCapabilities implements RaceContainer, Ca return Race.HUMAN; } + @Override + public Physics getPhysics() { + return physics; + } + @Override public void setSpecies(Race race) { } @@ -56,7 +63,7 @@ public class LivingEntityCapabilities implements RaceContainer, Ca } @Override - public void onUpdate() { + public void tick() { if (hasEffect()) { AttachedMagicEffect effect = getEffect(AttachedMagicEffect.class, true); @@ -72,11 +79,6 @@ public class LivingEntityCapabilities implements RaceContainer, Ca } } - @Override - public void onDimensionalTravel(int destinationDimension) { - - } - @Override public void setOwner(LivingEntity owner) { @@ -111,6 +113,7 @@ public class LivingEntityCapabilities implements RaceContainer, Ca if (effect != null) { compound.put("effect", SpellRegistry.instance().serializeEffectToNBT(effect)); } + physics.toNBT(compound); } @Override @@ -118,5 +121,6 @@ public class LivingEntityCapabilities implements RaceContainer, Ca if (compound.contains("effect")) { setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect"))); } + physics.fromNBT(compound); } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/CuccoonEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/CuccoonEntity.java index 52410e4a..2f329555 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/CuccoonEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/CuccoonEntity.java @@ -40,7 +40,7 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameRules; import net.minecraft.world.World; -public class CuccoonEntity extends LivingEntity implements IMagicals, InAnimate { +public class CuccoonEntity extends LivingEntity implements IMagicals, InAnimate, Trap { private static final TrackedData STRUGGLE_COUNT = DataTracker.registerData(CuccoonEntity.class, TrackedDataHandlerRegistry.INTEGER); @@ -206,6 +206,7 @@ public class CuccoonEntity extends LivingEntity implements IMagicals, InAnimate return true; } + @Override public boolean attemptDismount(Entity captive) { if (captive.isSneaking() != captiveLastSneakState) { setStruggleCount(getStruggleCount() + 1); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java new file mode 100644 index 00000000..cb42fc1f --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java @@ -0,0 +1,101 @@ +package com.minelittlepony.unicopia.entity; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.FenceGateBlock; +import net.minecraft.entity.Entity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.particle.BlockStateParticleEffect; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.tag.BlockTags; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public class EntityPhysics & Owned> implements Physics { + + private float gravity = 1; + + protected final T pony; + + public EntityPhysics(T pony) { + this.pony = pony; + } + + @Override + public boolean isFlying() { + return false; + } + + @Override + public double calcGravity(double worldConstant) { + return worldConstant * gravity; + } + + @Override + public BlockPos getHeadPosition() { + + pony.getOwner().onGround = false; + + int i = MathHelper.floor(pony.getOwner().getX()); + int j = MathHelper.floor(pony.getOwner().getY() + pony.getOwner().getHeight() + 0.20000000298023224D); + int k = MathHelper.floor(pony.getOwner().getZ()); + + BlockPos blockPos = new BlockPos(i, j, k); + + if (pony.getOwner().world.getBlockState(blockPos).isAir()) { + BlockPos blockPos2 = blockPos.down(); + BlockState blockState = pony.getOwner().world.getBlockState(blockPos2); + Block block = blockState.getBlock(); + if (block.matches(BlockTags.FENCES) || block.matches(BlockTags.WALLS) || block instanceof FenceGateBlock) { + pony.getOwner().onGround = true; + return blockPos2; + } + } else { + pony.getOwner().onGround = true; + } + + return blockPos; + } + + @Override + public void spawnSprintingParticles() { + Entity entity = pony.getOwner(); + BlockState state = entity.world.getBlockState(getHeadPosition()); + if (state.getRenderType() != BlockRenderType.INVISIBLE) { + Vec3d vel = entity.getVelocity(); + entity.world.addParticle(new BlockStateParticleEffect(ParticleTypes.BLOCK, state), + entity.getX() + (entity.world.random.nextFloat() - 0.5D) * entity.getWidth(), + entity.getY() + entity.getHeight() - 0.1D, + entity.getZ() + (entity.world.random.nextFloat() - 0.5D) * entity.getWidth(), + vel.x * -4, -1.5D, vel.z * -4); + } + } + + @Override + public void setGravityModifier(float constant) { + gravity = constant; + } + + @Override + public float getGravityModifier() { + return gravity; + } + + @Override + public void toNBT(CompoundTag compound) { + if (gravity != 0) { + compound.putFloat("gravity", gravity); + } + } + + @Override + public void fromNBT(CompoundTag compound) { + if (compound.contains("gravity")) { + gravity = compound.getFloat("gravity"); + } else { + gravity = 0; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ItemEntityCapabilities.java b/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java similarity index 86% rename from src/main/java/com/minelittlepony/unicopia/entity/ItemEntityCapabilities.java rename to src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java index 3a19923c..de35af6a 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/ItemEntityCapabilities.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java @@ -11,19 +11,21 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.ActionResult; -public class ItemEntityCapabilities implements RaceContainer, Owned { +public class ItemImpl implements Ponylike, Owned { private static final TrackedData ITEM_RACE = DataTracker.registerData(ItemEntity.class, TrackedDataHandlerRegistry.INTEGER); private final ItemEntity owner; private Race serverRace; - public ItemEntityCapabilities(ItemEntity owner) { + private final Physics physics = new EntityPhysics<>(this); + + public ItemImpl(ItemEntity owner) { this.owner = owner; owner.getDataTracker().startTracking(ITEM_RACE, Race.HUMAN.ordinal()); } @Override - public void onUpdate() { + public void tick() { } @Override @@ -47,6 +49,11 @@ public class ItemEntityCapabilities implements RaceContainer, Owned< return false; } + @Override + public Physics getPhysics() { + return physics; + } + @Override public Race getSpecies() { return Race.fromId(getOwner().getDataTracker().get(ITEM_RACE)); @@ -60,12 +67,14 @@ public class ItemEntityCapabilities implements RaceContainer, Owned< @Override public void toNBT(CompoundTag compound) { compound.putString("owner_species", getSpecies().name()); + physics.toNBT(compound); } @Override public void fromNBT(CompoundTag compound) { setSpecies(Race.fromName(compound.getString("owner_species"))); + physics.fromNBT(compound); } @Override @@ -73,11 +82,6 @@ public class ItemEntityCapabilities implements RaceContainer, Owned< } - @Override - public void onDimensionalTravel(int destinationDimension) { - - } - @Override public ItemEntity getOwner() { return owner; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Physics.java b/src/main/java/com/minelittlepony/unicopia/entity/Physics.java new file mode 100644 index 00000000..f3b4f703 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/Physics.java @@ -0,0 +1,28 @@ +package com.minelittlepony.unicopia.entity; + +import com.minelittlepony.unicopia.util.NbtSerialisable; + +import net.minecraft.util.math.BlockPos; + +public interface Physics extends NbtSerialisable { + + double calcGravity(double worldConstant); + + float getGravityModifier(); + + void setGravityModifier(float constant); + + boolean isFlying(); + + BlockPos getHeadPosition(); + + void spawnSprintingParticles(); + + default boolean isGravityNegative() { + return getGravityModifier() < 0; + } + + default int getGravitySignum() { + return (int)Math.signum(getGravityModifier()); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Ponylike.java b/src/main/java/com/minelittlepony/unicopia/entity/Ponylike.java index adcfa9e2..39a077c3 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Ponylike.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Ponylike.java @@ -8,13 +8,14 @@ import com.minelittlepony.unicopia.util.NbtSerialisable; import net.minecraft.entity.Entity; import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.util.Tickable; -public interface Ponylike extends NbtSerialisable, Updatable { +public interface Ponylike extends NbtSerialisable, Tickable { Race getSpecies(); - void setSpecies(Race race); + Physics getPhysics(); - void onDimensionalTravel(int destinationDimension); + void setSpecies(Race race); /** * Returns true if this player is fully invisible. @@ -54,7 +55,7 @@ public interface Ponylike extends NbtSerialisable, Updatable { } @Nullable - static T of(Entity entity) { + static > T of(Entity entity) { return PonyContainer.of(entity) .map(PonyContainer::get) .orElse(null); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/RaceContainer.java b/src/main/java/com/minelittlepony/unicopia/entity/RaceContainer.java deleted file mode 100644 index 458a07b0..00000000 --- a/src/main/java/com/minelittlepony/unicopia/entity/RaceContainer.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.minelittlepony.unicopia.entity; - -import net.minecraft.entity.Entity; - -/** - * Generic container for an entity that has a race. - * - * @param The type of owner - */ -public interface RaceContainer extends Ponylike { - -} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Updatable.java b/src/main/java/com/minelittlepony/unicopia/entity/Updatable.java deleted file mode 100644 index 3876559d..00000000 --- a/src/main/java/com/minelittlepony/unicopia/entity/Updatable.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.minelittlepony.unicopia.entity; - -/** - * Interface for objects that receive regular updates. - */ -@FunctionalInterface -public interface Updatable { - /** - * Called to update the internal logic. - */ - void onUpdate(); -} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/ManaContainer.java b/src/main/java/com/minelittlepony/unicopia/entity/player/ManaContainer.java new file mode 100644 index 00000000..088a5675 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/ManaContainer.java @@ -0,0 +1,32 @@ +package com.minelittlepony.unicopia.entity.player; + +public class ManaContainer implements MagicReserves { + private final Pony pony; + + public ManaContainer(Pony pony) { + this.pony = pony; + pony.getOwner().getDataTracker().startTracking(Pony.ENERGY, 0F); + pony.getOwner().getDataTracker().startTracking(Pony.EXERTION, 0F); + } + + @Override + public float getExertion() { + return pony.getOwner().getDataTracker().get(Pony.EXERTION); + } + + @Override + public void setExertion(float exertion) { + pony.getOwner().getDataTracker().set(Pony.EXERTION, Math.max(0, exertion)); + } + + @Override + public float getEnergy() { + return pony.getOwner().getDataTracker().get(Pony.ENERGY); + } + + @Override + public void setEnergy(float energy) { + pony.getOwner().getDataTracker().set(Pony.ENERGY, Math.max(0, energy)); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/FlightControl.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Motion.java similarity index 66% rename from src/main/java/com/minelittlepony/unicopia/entity/FlightControl.java rename to src/main/java/com/minelittlepony/unicopia/entity/player/Motion.java index be113d13..d56af216 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/FlightControl.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Motion.java @@ -1,9 +1,9 @@ -package com.minelittlepony.unicopia.entity; +package com.minelittlepony.unicopia.entity.player; /** * Interface for controlling flight. */ -public interface FlightControl { +public interface Motion { /** * True is we're currently flying. */ @@ -14,4 +14,6 @@ public interface FlightControl { float getFlightDuration(); boolean isExperienceCritical(); + + PlayerDimensions getDimensions(); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java index 858c1219..ecc78856 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java @@ -18,19 +18,19 @@ public class PlayerCamera extends MotionCompositor { double roll = baseRoll; - if (player.getFlight().isFlying()) { + if (player.getMotion().isFlying()) { Vec3d vel = player.getOwner().getVelocity(); roll -= super.calculateRoll(player.getOwner(), vel.x, vel.y, vel.z); } - if (player.getGravity().getGravitationConstant() < 0) { - roll = -roll; - roll += 180; + if (player.getPhysics().isGravityNegative()) { + roll = -roll; + roll += 180; } if (player.getEntity().age > 10) { - roll = player.getInterpolator().interpolate("roll", (float)roll, 250); + roll = player.getInterpolator().interpolate("roll", (float)roll, 50); } return (float)roll; @@ -45,7 +45,7 @@ public class PlayerCamera extends MotionCompositor { } public double calculateFieldOfView(double fov) { - fov += player.getMagicalReserves().getExertion() / 5; + fov += player.getMagicalReserves().getExertion() / 5F; fov += getEnergyAddition(); return fov; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensionsDelegate.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensions.java similarity index 76% rename from src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensionsDelegate.java rename to src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensions.java index fddf0fee..c045b525 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensionsDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensions.java @@ -6,7 +6,7 @@ import com.minelittlepony.unicopia.magic.MagicEffect; import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityPose; -public final class PlayerDimensionsDelegate { +public final class PlayerDimensions { private float defaultEyeHeight; private float defaultBodyHeight; @@ -14,10 +14,13 @@ public final class PlayerDimensionsDelegate { private float lastTargetEyeHeight; private float lastTargetBodyHeight; - private final GravityDelegate gravity; + private final PlayerPhysics physics; - public PlayerDimensionsDelegate(GravityDelegate gravity) { - this.gravity = gravity; + private final Pony pony; + + public PlayerDimensions(Pony pony, PlayerPhysics gravity) { + this.pony = pony; + this.physics = gravity; } public float getActiveEyeHeight(float original) { @@ -46,11 +49,11 @@ public final class PlayerDimensionsDelegate { private float calculateTargetEyeHeightWithGravity(float targetBodyHeight) { float height = calculateTargetEyeHeight(); - if (gravity.getGravitationConstant() < 0 && gravity.player.getOwner().isSneaking()) { + if (physics.isGravityNegative() && pony.getOwner().isSneaking()) { height += 0.2F; } - if (gravity.getGravitationConstant() < 0) { + if (physics.isGravityNegative()) { height = targetBodyHeight - height; } @@ -58,17 +61,17 @@ public final class PlayerDimensionsDelegate { } private float calculateTargetEyeHeight() { - if (gravity.player.hasEffect()) { - MagicEffect effect = gravity.player.getEffect(); + if (pony.hasEffect()) { + MagicEffect effect = pony.getEffect(); if (!effect.isDead() && effect instanceof HeightPredicate) { - float val = ((HeightPredicate)effect).getTargetEyeHeight(gravity.player); + float val = ((HeightPredicate)effect).getTargetEyeHeight(pony); if (val > 0) { return val; } } } - if (gravity.isFlying && gravity.isRainboom()) { + if (physics.isFlying && physics.isRainboom()) { return 0.5F; } @@ -76,17 +79,17 @@ public final class PlayerDimensionsDelegate { } private float calculateTargetBodyHeight() { - if (gravity.player.hasEffect()) { - MagicEffect effect = gravity.player.getEffect(); + if (pony.hasEffect()) { + MagicEffect effect = pony.getEffect(); if (!effect.isDead() && effect instanceof HeightPredicate) { - float val = ((HeightPredicate)effect).getTargetBodyHeight(gravity.player); + float val = ((HeightPredicate)effect).getTargetBodyHeight(pony); if (val > 0) { return val; } } } - if (gravity.isFlying && gravity.isRainboom()) { + if (physics.isFlying && physics.isRainboom()) { return defaultBodyHeight / 2; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerImpl.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerImpl.java deleted file mode 100644 index 024efd19..00000000 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerImpl.java +++ /dev/null @@ -1,443 +0,0 @@ -package com.minelittlepony.unicopia.entity.player; - -import javax.annotation.Nullable; - -import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.UTags; -import com.minelittlepony.unicopia.ability.AbilityDispatcher; -import com.minelittlepony.unicopia.enchanting.PageOwner; -import com.minelittlepony.unicopia.entity.FlightControl; -import com.minelittlepony.unicopia.entity.Trap; -import com.minelittlepony.unicopia.magic.Affinity; -import com.minelittlepony.unicopia.magic.AttachedMagicEffect; -import com.minelittlepony.unicopia.magic.HeldMagicEffect; -import com.minelittlepony.unicopia.magic.MagicEffect; -import com.minelittlepony.unicopia.magic.MagicalItem; -import com.minelittlepony.unicopia.magic.spell.SpellRegistry; -import com.minelittlepony.unicopia.network.Channel; -import com.minelittlepony.unicopia.network.EffectSync; -import com.minelittlepony.unicopia.network.MsgPlayerCapabilities; -import com.minelittlepony.unicopia.toxin.Toxicity; -import com.minelittlepony.unicopia.toxin.Toxin; -import com.minelittlepony.util.BasicEasingInterpolator; -import com.minelittlepony.util.IInterpolator; -import com.mojang.datafixers.util.Either; - -import net.minecraft.client.network.packet.EntityPassengersSetS2CPacket; -import net.minecraft.entity.Entity; -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.player.PlayerEntity.SleepFailureReason; -import net.minecraft.entity.projectile.ProjectileEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.TranslatableText; -import net.minecraft.util.Hand; -import net.minecraft.util.Unit; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; - -public class PlayerImpl implements Pony, MagicReserves { - - private static final TrackedData PLAYER_RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER); - private static final TrackedData ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT); - private static final TrackedData EXERTION = 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 PlayerPageStats pageStates = new PlayerPageStats(); - - private final AbilityDispatcher powers = new AbilityDispatcher(this); - - private final GravityDelegate gravity = new GravityDelegate(this); - - private final PlayerAttributes attributes = new PlayerAttributes(); - - private final PlayerCamera view = new PlayerCamera(this); - - private final PlayerInventory inventory = new PlayerInventory(this); - - private final EffectSync effectDelegate = new EffectSync(this, EFFECT); - private final EffectSync heldEffectDelegate = new EffectSync(this, HELD_EFFECT); - - private final IInterpolator interpolator = new BasicEasingInterpolator(); - - private float nextStepDistance = 1; - - private final PlayerEntity entity; - - private boolean dirty = false; - - private boolean invisible = false; - - public PlayerImpl(PlayerEntity player) { - this.entity = player; - - player.getDataTracker().startTracking(PLAYER_RACE, Race.EARTH.ordinal()); - player.getDataTracker().startTracking(EXERTION, 0F); - player.getDataTracker().startTracking(ENERGY, 0F); - player.getDataTracker().startTracking(EFFECT, new CompoundTag()); - player.getDataTracker().startTracking(HELD_EFFECT, new CompoundTag()); - - player.getAttributes().register(PlayerAttributes.EXTENDED_REACH_DISTANCE); - } - - @Override - public Race getSpecies() { - if (getOwner() == null) { - return Race.HUMAN; - } - - return Race.fromId(getOwner().getDataTracker().get(PLAYER_RACE)); - } - - @Override - public void setSpecies(Race race) { - race = race.validate(entity); - - entity.getDataTracker().set(PLAYER_RACE, race.ordinal()); - - gravity.updateFlightStat(entity, entity.abilities.flying); - entity.sendAbilitiesUpdate(); - } - - @Override - public MagicReserves getMagicalReserves() { - return this; - } - - @Override - public float getExertion() { - return getOwner().getDataTracker().get(EXERTION); - } - - @Override - public void setExertion(float exertion) { - entity.getDataTracker().set(EXERTION, Math.max(0, exertion)); - } - - @Override - public float getEnergy() { - return entity.getDataTracker().get(ENERGY); - } - - @Override - public void setEnergy(float energy) { - entity.getDataTracker().set(ENERGY, Math.max(0, energy)); - } - - @Override - public boolean isInvisible() { - return invisible && hasEffect(); - } - - @Override - public void setInvisible(boolean invisible) { - this.invisible = invisible; - } - - @Nullable - public HeldMagicEffect getHeldEffect(ItemStack stack) { - - if (!getSpecies().canCast()) { - heldEffectDelegate.set(null); - - return null; - } - - HeldMagicEffect heldEffect = heldEffectDelegate.get(HeldMagicEffect.class, true); - - if (heldEffect == null || !heldEffect.getName().equals(SpellRegistry.getKeyFromStack(stack))) { - heldEffect = SpellRegistry.instance().getHeldFrom(stack); - heldEffectDelegate.set(heldEffect); - } - - return heldEffect; - } - - @Override - public Affinity getAffinity() { - return Affinity.NEUTRAL; - } - - @Override - public void sendCapabilities(boolean full) { - dirty = false; - - if (entity instanceof ServerPlayerEntity) { - System.out.println("Sending capabilities for player"); - Channel.BROADCAST_CAPABILITIES.send(new MsgPlayerCapabilities(full, this)); - } - } - - @Override - public void onDimensionalTravel(int destinationDimension) { - if (!getWorld().isClient()) { - dirty = true; - } - } - - @Override - public AbilityDispatcher getAbilities() { - return powers; - } - - @Override - public PageOwner getPages() { - return pageStates; - } - - @Override - public GravityDelegate getGravity() { - return gravity; - } - - @Override - public float getExtendedReach() { - return (float)entity.getAttributeInstance(PlayerAttributes.EXTENDED_REACH_DISTANCE).getValue(); - } - - @Override - public FlightControl getFlight() { - return gravity; - } - - @Override - public PlayerCamera getCamera() { - return view; - } - - @Override - public IInterpolator getInterpolator() { - return interpolator; - } - - @Override - public boolean beforeUpdate() { - if (entity.world.isClient()) { - if (entity.hasVehicle() && entity.isSneaking()) { - - Entity ridee = entity.getVehicle(); - - if (ridee instanceof Trap) { - if (((Trap)ridee).attemptDismount(entity)) { - entity.stopRiding(); - } else { - entity.setSneaking(false); - } - } else { - entity.stopRiding(); - - if (ridee instanceof ServerPlayerEntity) { - ((ServerPlayerEntity)ridee).networkHandler.sendPacket(new EntityPassengersSetS2CPacket(ridee)); - } - } - } - } - - powers.onUpdate(); - inventory.onUpdate(); - - return false; - } - - @Override - public void onUpdate() { - gravity.onUpdate(); - - if (hasEffect()) { - AttachedMagicEffect effect = getEffect(AttachedMagicEffect.class, true); - - if (effect != null) { - if (entity.getEntityWorld().isClient()) { - effect.renderOnPerson(this); - } - - if (!effect.updateOnPerson(this)) { - setEffect(null); - } - } - } - - ItemStack stack = entity.getStackInHand(Hand.MAIN_HAND); - - HeldMagicEffect effect = getHeldEffect(stack); - - if (effect != null) { - Affinity affinity = stack.getItem() instanceof MagicalItem ? ((MagicalItem)stack.getItem()).getAffinity(stack) : Affinity.NEUTRAL; - - effect.updateInHand(this, affinity); - } - - addExertion(-1); - addEnergy(-1); - - attributes.applyAttributes(entity, getSpecies()); - - if (dirty) { - sendCapabilities(true); - } - } - - @Override - public float onImpact(float distance) { - if (getSpecies().canFly()) { - distance = Math.max(0, distance - 5); - } - return distance; - } - - @Override - public void onJump() { - if (gravity.getGravitationConstant() < 0) { - Vec3d velocity = entity.getVelocity(); - entity.setVelocity(velocity.x, velocity.y * -1, velocity.z); - } - } - - @Override - public boolean onProjectileImpact(ProjectileEntity projectile) { - if (hasEffect()) { - MagicEffect effect = getEffect(); - if (!effect.isDead() && effect.handleProjectileImpact(projectile)) { - return true; - } - } - - return false; - } - - @Override - public boolean subtractEnergyCost(double foodSubtract) { - if (!entity.abilities.creativeMode) { - int food = (int)(entity.getHungerManager().getFoodLevel() - foodSubtract); - - if (food < 0) { - entity.getHungerManager().add(-entity.getHungerManager().getFoodLevel(), 0); - entity.damage(DamageSource.MAGIC, -food/2); - } else { - entity.getHungerManager().add((int)-foodSubtract, 0); - } - } - - return entity.getHealth() > 0; - } - - @Override - public boolean stepOnCloud() { - if (entity.fallDistance > 1 || entity.distanceTraveled > nextStepDistance) { - nextStepDistance = entity.distanceTraveled + 2; - entity.fallDistance = 0; - - return true; - } - - return false; - } - - @Override - public Either trySleep(BlockPos pos) { - - if (getInventory().matches(UTags.CURSED_ARTEFACTS)) { - if (!isClient()) { - entity.addChatMessage(new TranslatableText("tile.bed.youAreAMonster"), true); - } - return Either.left(SleepFailureReason.OTHER_PROBLEM); - } - - if (findAllSpellsInRange(10).anyMatch(c -> c instanceof Pony && ((Pony)c).getInventory().matches(UTags.CURSED_ARTEFACTS))) { - return Either.left(SleepFailureReason.NOT_SAFE); - } - - return Either.right(Unit.INSTANCE); - } - - @Override - public PlayerInventory getInventory() { - return inventory; - } - - @Override - public void onEat(ItemStack stack) { - if (getSpecies() == Race.CHANGELING) { - Toxin.POISON.afflict(getOwner(), Toxicity.SAFE, stack); - } - } - - @Override - public void toNBT(CompoundTag compound) { - compound.putString("playerSpecies", getSpecies().name()); - - compound.put("powers", powers.toNBT()); - compound.put("gravity", gravity.toNBT()); - - MagicEffect effect = getEffect(); - - if (effect != null) { - compound.put("effect", SpellRegistry.instance().serializeEffectToNBT(effect)); - } - - pageStates.toNBT(compound); - } - - @Override - public void fromNBT(CompoundTag compound) { - setSpecies(Race.fromName(compound.getString("playerSpecies"))); - - powers.fromNBT(compound.getCompound("powers")); - gravity.fromNBT(compound.getCompound("gravity")); - - if (compound.contains("effect")) { - effectDelegate.set(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect"))); - } - - pageStates.fromNBT(compound); - } - - @Override - public void copyFrom(Pony oldPlayer) { - setEffect(oldPlayer.getEffect()); - setSpecies(oldPlayer.getSpecies()); - sendCapabilities(true); - } - - @Override - public void setEffect(@Nullable MagicEffect effect) { - effectDelegate.set(effect); - - sendCapabilities(true); - } - - @Override - public boolean hasEffect() { - return effectDelegate.has(); - } - - @Nullable - @Override - public T getEffect(@Nullable Class type, boolean update) { - return effectDelegate.get(type, update); - } - - @Override - public void setOwner(PlayerEntity owner) { - } - - @Override - public PlayerEntity getOwner() { - return entity; - } - - @Override - public int getCurrentLevel() { - return 0; - } - - @Override - public void setCurrentLevel(int level) { - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerInventory.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerInventory.java index 630f2f9a..702ad1a4 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerInventory.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerInventory.java @@ -4,7 +4,6 @@ import java.util.Iterator; import java.util.Map; import com.google.common.collect.Maps; -import com.minelittlepony.unicopia.entity.Updatable; import com.minelittlepony.unicopia.item.MagicGemItem; import com.minelittlepony.unicopia.magic.AddictiveMagicalItem; import com.minelittlepony.unicopia.magic.MagicalItem; @@ -16,9 +15,10 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.tag.Tag; import net.minecraft.util.Identifier; +import net.minecraft.util.Tickable; import net.minecraft.util.registry.Registry; -public class PlayerInventory implements Updatable, NbtSerialisable { +public class PlayerInventory implements Tickable, NbtSerialisable { private final Map dependencies = Maps.newHashMap(); private final Pony player; @@ -66,7 +66,7 @@ public class PlayerInventory implements Updatable, NbtSerialisable { } @Override - public synchronized void onUpdate() { + public synchronized void tick() { Iterator> iterator = dependencies.entrySet().iterator(); @@ -75,7 +75,7 @@ public class PlayerInventory implements Updatable, NbtSerialisable { Entry item = entry.getValue(); - item.onUpdate(); + item.tick(); if (item.needfulness <= 0.001) { iterator.remove(); @@ -132,7 +132,7 @@ public class PlayerInventory implements Updatable, NbtSerialisable { }); } - class Entry implements Updatable, NbtSerialisable { + class Entry implements Tickable, NbtSerialisable { int ticksAttached = 0; float needfulness = 1; @@ -152,7 +152,7 @@ public class PlayerInventory implements Updatable, NbtSerialisable { } @Override - public void onUpdate() { + public void tick() { if (isWearing(item)) { ticksAttached ++; needfulness *= 0.9F; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPageStats.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPageStats.java index b7a75bb8..edf56e86 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPageStats.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPageStats.java @@ -13,6 +13,12 @@ import net.minecraft.util.Identifier; public class PlayerPageStats implements NbtSerialisable, PageOwner { private final Map pageStates = new HashMap<>(); + private final Pony pony; + + PlayerPageStats(Pony pony) { + this.pony = pony; + } + @Override public Map getPageStates() { return pageStates; @@ -20,7 +26,7 @@ public class PlayerPageStats implements NbtSerialisable, PageOwner { @Override public void sendCapabilities(boolean full) { - + pony.sendCapabilities(full); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/GravityDelegate.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java similarity index 74% rename from src/main/java/com/minelittlepony/unicopia/entity/player/GravityDelegate.java rename to src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 2adc5020..9455e632 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/GravityDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -5,8 +5,7 @@ import java.util.Random; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.FlightPredicate; -import com.minelittlepony.unicopia.entity.FlightControl; -import com.minelittlepony.unicopia.entity.Updatable; +import com.minelittlepony.unicopia.entity.EntityPhysics; import com.minelittlepony.unicopia.magic.MagicEffect; import com.minelittlepony.unicopia.particles.MagicParticleEffect; import com.minelittlepony.unicopia.util.NbtSerialisable; @@ -18,13 +17,12 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Tickable; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -public class GravityDelegate implements Updatable, FlightControl, NbtSerialisable, FlightPredicate { - - final Pony player; +public class PlayerPhysics extends EntityPhysics implements Tickable, Motion, NbtSerialisable { private static final float MAXIMUM_FLIGHT_EXPERIENCE = 1500; @@ -37,73 +35,63 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl private double lastTickPosX = 0; private double lastTickPosZ = 0; - private float gravity = 0; + private final PlayerDimensions dimensions; - private final PlayerDimensionsDelegate dimensions; - - public GravityDelegate(Pony player) { - this.player = player; - this.dimensions = new PlayerDimensionsDelegate(this); + public PlayerPhysics(Pony pony) { + super(pony); + dimensions = new PlayerDimensions(pony, this); } - @Override - public boolean checkCanFly(Pony player) { - if (player.getOwner().abilities.creativeMode) { + private boolean checkCanFly() { + if (pony.getOwner().abilities.creativeMode) { return true; } - if (player.hasEffect()) { - MagicEffect effect = player.getEffect(); + if (pony.hasEffect()) { + MagicEffect effect = pony.getEffect(); if (!effect.isDead() && effect instanceof FlightPredicate) { - return ((FlightPredicate)effect).checkCanFly(player); + return ((FlightPredicate)effect).checkCanFly(pony); } } - return player.getSpecies().canFly(); + return pony.getSpecies().canFly(); } protected boolean isRainboom() { - return Math.sqrt(getHorizontalMotion(player.getOwner())) > 0.4F; + return Math.sqrt(getHorizontalMotion(pony.getOwner())) > 0.4F; } - public PlayerDimensionsDelegate getDimensions() { + @Override + public PlayerDimensions getDimensions() { return dimensions; } - public void setGraviationConstant(float constant) { - gravity = constant; - } - - public float getGravitationConstant() { - return gravity; - } - @Override public boolean isExperienceCritical() { return isRainbooming || flightExperience > MAXIMUM_FLIGHT_EXPERIENCE * 0.8; } @Override - public void onUpdate() { - PlayerEntity entity = player.getOwner(); + public void tick() { + PlayerEntity entity = pony.getOwner(); MutableVector velocity = new MutableVector(entity.getVelocity()); - if (isExperienceCritical() && player.isClient()) { - Random rnd = player.getWorld().random; + if (isExperienceCritical() && pony.isClient()) { + Random rnd = pony.getWorld().random; for (int i = 0; i < 360 + getHorizontalMotion(entity); i += 10) { - Vec3d pos = player.getOriginVector().add( + Vec3d pos = pony.getOriginVector().add( rnd.nextGaussian() * entity.getWidth(), rnd.nextGaussian() * entity.getHeight()/2, rnd.nextGaussian() * entity.getWidth() ); - player.addParticle(MagicParticleEffect.UNICORN, pos, velocity.toImmutable()); + pony.addParticle(MagicParticleEffect.UNICORN, pos, velocity.toImmutable()); } } - entity.abilities.allowFlying = checkCanFly(player); + entity.abilities.allowFlying = checkCanFly(); if (!entity.abilities.creativeMode) { entity.abilities.flying |= entity.abilities.allowFlying && isFlying && !entity.onGround && !entity.isTouchingWater(); @@ -111,26 +99,6 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl isFlying = entity.abilities.flying && !entity.abilities.creativeMode; - if (gravity != 0) { - if (!entity.abilities.flying) { - velocity.y += 0.038; - velocity.y -= gravity; - } - - if (gravity < 0) { - entity.onGround = !entity.world.isAir(new BlockPos(entity.getX(), entity.getY() + entity.getHeight() + 0.5F, entity.getZ())); - - if (entity.onGround) { - entity.abilities.flying = false; - isFlying = false; - } - } - } - - if (dimensions.update()) { - player.getOwner().calculateDimensions(); - } - if (!entity.abilities.creativeMode && !entity.isFallFlying()) { if (isFlying && !entity.hasVehicle()) { @@ -140,7 +108,7 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl entity.fallDistance = 0; - if (player.getSpecies() != Race.CHANGELING && entity.world.random.nextInt(100) == 0) { + if (pony.getSpecies() != Race.CHANGELING && entity.world.random.nextInt(100) == 0) { float exhaustion = (0.3F * ticksNextLevel) / 70; if (entity.isSprinting()) { exhaustion *= 3.11F; @@ -163,8 +131,8 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl if (isExperienceCritical()) { - if (player.getMagicalReserves().getEnergy() <= 0.25F) { - player.getMagicalReserves().addEnergy(2); + if (pony.getMagicalReserves().getEnergy() <= 0.25F) { + pony.getMagicalReserves().addEnergy(2); } if (isRainbooming || (entity.isSneaking() && isRainboom())) { @@ -209,6 +177,15 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl } } + if (pony.getPhysics().isGravityNegative()) { + entity.onGround = !entity.world.isAir(new BlockPos(entity.getX(), entity.getY() + entity.getHeight() + 0.5F, entity.getZ())); + + if (entity.onGround) { + entity.abilities.flying = false; + isFlying = false; + } + } + lastTickPosX = entity.getX(); lastTickPosZ = entity.getZ(); @@ -216,21 +193,20 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl } public SoundEvent getWingSound() { - return player.getSpecies() == Race.CHANGELING ? USounds.CHANGELING_BUZZ : USounds.WING_FLAP; + return pony.getSpecies() == Race.CHANGELING ? USounds.CHANGELING_BUZZ : USounds.WING_FLAP; } protected void moveFlying(Entity player, MutableVector velocity) { float forward = 0.000015F * flightExperience * (float)Math.sqrt(getHorizontalMotion(player)); - int factor = gravity < 0 ? -1 : 1; boolean sneak = !player.isSneaking(); // vertical drop due to gravity if (sneak) { - velocity.y -= (0.005F - getHorizontalMotion(player) / 100) * factor; + velocity.y -= (0.005F - getHorizontalMotion(player) / 100) * getGravitySignum(); } else { forward += 0.005F; - velocity.y -= 0.0001F * factor; + velocity.y -= 0.0001F * getGravitySignum(); } velocity.x += - forward * MathHelper.sin(player.yaw * 0.017453292F); @@ -264,7 +240,6 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl forward = 4; } - //player.knockBack(player, forward, 1, 1); velocity.x += - forward * MathHelper.sin((player.yaw + glance) * 0.017453292F); velocity.z += forward * MathHelper.cos((player.yaw + glance) * 0.017453292F); } @@ -289,8 +264,10 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl flightExperience = Math.max(0, flightExperience + factor * maximumGain / gainSteps); } - public void updateFlightStat(PlayerEntity entity, boolean flying) { - entity.abilities.allowFlying = checkCanFly(Pony.of(entity)); + public void updateFlightStat(boolean flying) { + PlayerEntity entity = pony.getOwner(); + + entity.abilities.allowFlying = checkCanFly(); if (entity.abilities.allowFlying) { entity.abilities.flying |= flying; @@ -308,28 +285,22 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl @Override public void toNBT(CompoundTag compound) { + super.toNBT(compound); compound.putInt("flightDuration", ticksNextLevel); compound.putFloat("flightExperience", flightExperience); compound.putBoolean("isFlying", isFlying); compound.putBoolean("isRainbooming", isRainbooming); - - if (gravity != 0) { - compound.putFloat("gravity", gravity); - } } @Override public void fromNBT(CompoundTag compound) { + super.fromNBT(compound); ticksNextLevel = compound.getInt("flightDuration"); flightExperience = compound.getFloat("flightExperience"); isFlying = compound.getBoolean("isFlying"); isRainbooming = compound.getBoolean("isRainbooming"); - if (compound.contains("gravity")) { - gravity = compound.getFloat("gravity"); - } else { - gravity = 0; - } + pony.getOwner().calculateDimensions(); } @Override 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 2a07008a..405d4886 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -3,111 +3,422 @@ package com.minelittlepony.unicopia.entity.player; import javax.annotation.Nullable; import com.minelittlepony.unicopia.InteractionManager; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.ability.AbilityDispatcher; import com.minelittlepony.unicopia.ducks.PonyContainer; import com.minelittlepony.unicopia.enchanting.PageOwner; -import com.minelittlepony.unicopia.entity.FlightControl; -import com.minelittlepony.unicopia.entity.RaceContainer; +import com.minelittlepony.unicopia.entity.Physics; +import com.minelittlepony.unicopia.entity.Ponylike; +import com.minelittlepony.unicopia.entity.Trap; +import com.minelittlepony.unicopia.magic.Affinity; +import com.minelittlepony.unicopia.magic.AttachedMagicEffect; import com.minelittlepony.unicopia.magic.Caster; +import com.minelittlepony.unicopia.magic.HeldMagicEffect; +import com.minelittlepony.unicopia.magic.MagicEffect; +import com.minelittlepony.unicopia.magic.MagicalItem; +import com.minelittlepony.unicopia.magic.spell.SpellRegistry; +import com.minelittlepony.unicopia.network.Channel; +import com.minelittlepony.unicopia.network.EffectSync; +import com.minelittlepony.unicopia.network.MsgPlayerCapabilities; import com.minelittlepony.unicopia.network.Transmittable; +import com.minelittlepony.unicopia.toxin.Toxicity; +import com.minelittlepony.unicopia.toxin.Toxin; +import com.minelittlepony.util.BasicEasingInterpolator; import com.minelittlepony.util.IInterpolator; import com.mojang.authlib.GameProfile; import com.mojang.datafixers.util.Either; +import net.minecraft.client.network.packet.EntityPassengersSetS2CPacket; +import net.minecraft.entity.Entity; +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.player.PlayerEntity.SleepFailureReason; +import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Hand; import net.minecraft.util.Unit; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; -/** - * The player. - * - * This is the core of unicopia. - */ -public interface Pony extends Caster, RaceContainer, Transmittable { +public class Pony implements Caster, Ponylike, Transmittable { - /** - * Gets the player's magical abilities delegate responsible for all spell casting and persisting/updating. - */ - AbilityDispatcher getAbilities(); + private static final TrackedData RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER); + static final TrackedData ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT); + static final TrackedData EXERTION = 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); - /** - * Gets the gravity delegate responsible for updating flight states - */ - GravityDelegate getGravity(); + private final PlayerPageStats pageStates = new PlayerPageStats(this); + private final AbilityDispatcher powers = new AbilityDispatcher(this); + private final PlayerPhysics gravity = new PlayerPhysics(this); + private final PlayerAttributes attributes = new PlayerAttributes(); + private final PlayerCamera camera = new PlayerCamera(this); + private final PlayerInventory inventory = new PlayerInventory(this); + private final MagicReserves mana; - /** - * Gets the flight delegate. - */ - FlightControl getFlight(); + private final EffectSync effectDelegate = new EffectSync(this, EFFECT); + private final EffectSync heldEffectDelegate = new EffectSync(this, HELD_EFFECT); - /** - * Gets the player's viewport. - */ - PlayerCamera getCamera(); + private final IInterpolator interpolator = new BasicEasingInterpolator(); - MagicReserves getMagicalReserves(); + private float nextStepDistance = 1; - /** - * Gets the inventory delegate for this player. - */ - PlayerInventory getInventory(); + private final PlayerEntity entity; - /** - * Gets an animation interpolator. - */ - IInterpolator getInterpolator(); + private boolean dirty = false; - PageOwner getPages(); + private boolean invisible = false; - /** - */ - float getExtendedReach(); + public Pony(PlayerEntity player) { + this.entity = player; + this.mana = new ManaContainer(this); - void copyFrom(Pony oldPlayer); + player.getDataTracker().startTracking(RACE, Race.EARTH.ordinal()); + player.getDataTracker().startTracking(EFFECT, new CompoundTag()); + player.getDataTracker().startTracking(HELD_EFFECT, new CompoundTag()); - /** - * Called when the player steps on clouds. - */ - boolean stepOnCloud(); + player.getAttributes().register(PlayerAttributes.EXTENDED_REACH_DISTANCE); + } - /** - * Called when this player falls. - */ - float onImpact(float distance); + @Override + public Race getSpecies() { + if (getOwner() == null) { + return Race.HUMAN; + } - /** - * Called whenever the player eats something. - */ - void onEat(ItemStack food); + return Race.fromId(getOwner().getDataTracker().get(RACE)); + } - /** - * Attempts to sleep in a bed. - * - * @param pos The position of the bed - * - * @return The sleep result. - */ - Either trySleep(BlockPos pos); + @Override + public void setSpecies(Race race) { + race = race.validate(entity); - /** - * Returns true if this player is the use. - */ - default boolean isClientPlayer() { + entity.getDataTracker().set(RACE, race.ordinal()); + + gravity.updateFlightStat(entity.abilities.flying); + entity.sendAbilitiesUpdate(); + } + + public MagicReserves getMagicalReserves() { + return mana; + } + + @Override + public boolean isInvisible() { + return invisible && hasEffect(); + } + + @Override + public void setInvisible(boolean invisible) { + this.invisible = invisible; + } + + @Nullable + public HeldMagicEffect getHeldEffect(ItemStack stack) { + + if (!getSpecies().canCast()) { + heldEffectDelegate.set(null); + return null; + } + + HeldMagicEffect heldEffect = heldEffectDelegate.get(HeldMagicEffect.class, true); + + if (heldEffect == null || !heldEffect.getName().equals(SpellRegistry.getKeyFromStack(stack))) { + heldEffect = SpellRegistry.instance().getHeldFrom(stack); + heldEffectDelegate.set(heldEffect); + } + + return heldEffect; + } + + @Override + public Affinity getAffinity() { + return Affinity.NEUTRAL; + } + + public void setDirty() { + dirty = true; + } + + @Override + public void sendCapabilities(boolean full) { + dirty = false; + + if (entity instanceof ServerPlayerEntity) { + System.out.println("Sending capabilities for player"); + Channel.BROADCAST_CAPABILITIES.send(new MsgPlayerCapabilities(full, this)); + } + } + + public AbilityDispatcher getAbilities() { + return powers; + } + + public PageOwner getPages() { + return pageStates; + } + + @Override + public Physics getPhysics() { + return gravity; + } + + public float getExtendedReach() { + return (float)entity.getAttributeInstance(PlayerAttributes.EXTENDED_REACH_DISTANCE).getValue(); + } + + public Motion getMotion() { + return gravity; + } + + public PlayerCamera getCamera() { + return camera; + } + + public IInterpolator getInterpolator() { + return interpolator; + } + + @Override + public boolean beforeUpdate() { + if (entity.world.isClient()) { + if (entity.hasVehicle() && entity.isSneaking()) { + + Entity ridee = entity.getVehicle(); + + if (ridee instanceof Trap) { + if (((Trap)ridee).attemptDismount(entity)) { + entity.stopRiding(); + } else { + entity.setSneaking(false); + } + } else { + entity.stopRiding(); + + if (ridee instanceof ServerPlayerEntity) { + ((ServerPlayerEntity)ridee).networkHandler.sendPacket(new EntityPassengersSetS2CPacket(ridee)); + } + } + } + } + + powers.tick(); + inventory.tick(); + + return false; + } + + @Override + public void tick() { + gravity.tick(); + + if (hasEffect()) { + AttachedMagicEffect effect = getEffect(AttachedMagicEffect.class, true); + + if (effect != null) { + if (entity.getEntityWorld().isClient()) { + effect.renderOnPerson(this); + } + + if (!effect.updateOnPerson(this)) { + setEffect(null); + } + } + } + + ItemStack stack = entity.getStackInHand(Hand.MAIN_HAND); + + HeldMagicEffect effect = getHeldEffect(stack); + + if (effect != null) { + Affinity affinity = stack.getItem() instanceof MagicalItem ? ((MagicalItem)stack.getItem()).getAffinity(stack) : Affinity.NEUTRAL; + + effect.updateInHand(this, affinity); + } + + mana.addExertion(-1); + mana.addEnergy(-1); + + attributes.applyAttributes(entity, getSpecies()); + + if (dirty) { + sendCapabilities(true); + } + } + + public float onImpact(float distance) { + if (getSpecies().canFly()) { + distance = Math.max(0, distance - 5); + } + return distance; + } + + @Override + public void onJump() { + if (gravity.isGravityNegative()) { + Vec3d velocity = entity.getVelocity(); + entity.setVelocity(velocity.x, velocity.y * -1, velocity.z); + } + } + + @Override + public boolean onProjectileImpact(ProjectileEntity projectile) { + if (hasEffect()) { + MagicEffect effect = getEffect(); + if (!effect.isDead() && effect.handleProjectileImpact(projectile)) { + return true; + } + } + + return false; + } + + @Override + public boolean subtractEnergyCost(double foodSubtract) { + if (!entity.abilities.creativeMode) { + int food = (int)(entity.getHungerManager().getFoodLevel() - foodSubtract); + + if (food < 0) { + entity.getHungerManager().add(-entity.getHungerManager().getFoodLevel(), 0); + entity.damage(DamageSource.MAGIC, -food/2); + } else { + entity.getHungerManager().add((int)-foodSubtract, 0); + } + } + + return entity.getHealth() > 0; + } + + public boolean stepOnCloud() { + if (entity.fallDistance > 1 || entity.distanceTraveled > nextStepDistance) { + nextStepDistance = entity.distanceTraveled + 2; + entity.fallDistance = 0; + + return true; + } + + return false; + } + + public Either trySleep(BlockPos pos) { + + if (getInventory().matches(UTags.CURSED_ARTEFACTS)) { + if (!isClient()) { + entity.addChatMessage(new TranslatableText("tile.bed.youAreAMonster"), true); + } + return Either.left(SleepFailureReason.OTHER_PROBLEM); + } + + if (findAllSpellsInRange(10).anyMatch(c -> c instanceof Pony && ((Pony)c).getInventory().matches(UTags.CURSED_ARTEFACTS))) { + return Either.left(SleepFailureReason.NOT_SAFE); + } + + return Either.right(Unit.INSTANCE); + } + + public PlayerInventory getInventory() { + return inventory; + } + + public void onEat(ItemStack stack) { + if (getSpecies() == Race.CHANGELING) { + Toxin.POISON.afflict(getOwner(), Toxicity.SAFE, stack); + } + } + + @Override + public void toNBT(CompoundTag compound) { + compound.putString("playerSpecies", getSpecies().name()); + + compound.put("powers", powers.toNBT()); + compound.put("gravity", gravity.toNBT()); + + MagicEffect effect = getEffect(); + + if (effect != null) { + compound.put("effect", SpellRegistry.instance().serializeEffectToNBT(effect)); + } + + pageStates.toNBT(compound); + } + + @Override + public void fromNBT(CompoundTag compound) { + setSpecies(Race.fromName(compound.getString("playerSpecies"))); + + powers.fromNBT(compound.getCompound("powers")); + gravity.fromNBT(compound.getCompound("gravity")); + + if (compound.contains("effect")) { + effectDelegate.set(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect"))); + } + + pageStates.fromNBT(compound); + } + + public void copyFrom(Pony oldPlayer) { + setEffect(oldPlayer.getEffect()); + setSpecies(oldPlayer.getSpecies()); + setDirty(); + } + + @Override + public void setEffect(@Nullable MagicEffect effect) { + effectDelegate.set(effect); + setDirty(); + } + + @Override + public boolean hasEffect() { + return effectDelegate.has(); + } + + @Nullable + @Override + public T getEffect(@Nullable Class type, boolean update) { + return effectDelegate.get(type, update); + } + + @Override + public void setOwner(PlayerEntity owner) { + } + + @Override + public PlayerEntity getOwner() { + return entity; + } + + @Override + public int getCurrentLevel() { + return 0; + } + + @Override + public void setCurrentLevel(int level) { + } + + public boolean isClientPlayer() { return InteractionManager.instance().isClientPlayer(getOwner()); } @SuppressWarnings("unchecked") @Nullable - static Pony of(@Nullable PlayerEntity player) { + public static Pony of(@Nullable PlayerEntity player) { return player == null ? null : ((PonyContainer)player).get(); } - static boolean equal(GameProfile one, GameProfile two) { + public static boolean equal(GameProfile one, GameProfile two) { return one == two || (one != null && two != null && one.getId().equals(two.getId())); } - static boolean equal(PlayerEntity one, PlayerEntity two) { + public static boolean equal(PlayerEntity one, PlayerEntity two) { return one == two || (one != null && two != null && equal(one.getGameProfile(), two.getGameProfile())); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java b/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java index 9c41527a..60c0bc46 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java @@ -8,7 +8,7 @@ import javax.annotation.Nullable; import com.google.common.collect.Multimap; import com.minelittlepony.unicopia.AwaitTickQueue; import com.minelittlepony.unicopia.ducks.IItemEntity; -import com.minelittlepony.unicopia.entity.ItemEntityCapabilities; +import com.minelittlepony.unicopia.entity.ItemImpl; import com.minelittlepony.unicopia.entity.player.MagicReserves; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.magic.Affinity; @@ -48,7 +48,7 @@ import net.minecraft.world.LocalDifficulty; import net.minecraft.world.World; import net.minecraft.world.explosion.Explosion.DestructionType; -public class AlicornAmuletItem extends ArmorItem implements AddictiveMagicalItem, ItemEntityCapabilities.TickableItem { +public class AlicornAmuletItem extends ArmorItem implements AddictiveMagicalItem, ItemImpl.TickableItem { private static final UUID[] MODIFIERS = new UUID[] { UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), diff --git a/src/main/java/com/minelittlepony/unicopia/item/AppleItem.java b/src/main/java/com/minelittlepony/unicopia/item/AppleItem.java index a1fcb5fb..4af47fb1 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/AppleItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/AppleItem.java @@ -4,7 +4,7 @@ import java.util.List; import javax.annotation.Nullable; import com.minelittlepony.unicopia.ducks.IItemEntity; -import com.minelittlepony.unicopia.entity.ItemEntityCapabilities; +import com.minelittlepony.unicopia.entity.ItemImpl; import com.minelittlepony.unicopia.toxin.Toxicity; import net.minecraft.client.item.TooltipContext; import net.minecraft.entity.EntityType; @@ -17,7 +17,7 @@ import net.minecraft.util.ActionResult; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -public class AppleItem extends Item implements ItemEntityCapabilities.TickableItem { +public class AppleItem extends Item implements ItemImpl.TickableItem { public AppleItem(Settings settings) { super(settings); diff --git a/src/main/java/com/minelittlepony/unicopia/magic/Useable.java b/src/main/java/com/minelittlepony/unicopia/magic/Useable.java index 1bf50219..0cac5823 100644 --- a/src/main/java/com/minelittlepony/unicopia/magic/Useable.java +++ b/src/main/java/com/minelittlepony/unicopia/magic/Useable.java @@ -19,7 +19,7 @@ public interface Useable { * * @param stack The current itemstack * @param affinity The affinity of the casting artifact - * @param player The player + * @param pony The player * @param world The player's world * @param pos The location clicked * @param side The side of the block clicked diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemEntity.java index 7b51d191..381d47c4 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemEntity.java @@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minelittlepony.unicopia.ducks.IItemEntity; -import com.minelittlepony.unicopia.entity.ItemEntityCapabilities; +import com.minelittlepony.unicopia.entity.ItemImpl; import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; @@ -16,17 +16,17 @@ import net.minecraft.nbt.CompoundTag; @Mixin(ItemEntity.class) abstract class MixinItemEntity extends Entity implements IItemEntity { - private ItemEntityCapabilities caster; + private ItemImpl caster; private MixinItemEntity() { super(null, null); } @Override - public ItemEntityCapabilities create() { - return new ItemEntityCapabilities((ItemEntity)(Object)this); + public ItemImpl create() { + return new ItemImpl((ItemEntity)(Object)this); } @Override - public ItemEntityCapabilities get() { + public ItemImpl get() { if (caster == null) { caster = create(); } @@ -42,7 +42,7 @@ abstract class MixinItemEntity extends Entity implements IItemEntity { @Inject(method = "tick()V", at = @At("RETURN")) private void afterTick(CallbackInfo info) { - get().onUpdate(); + get().tick(); } @Inject(method = "writeCustomDataToTag(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("HEAD")) diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java index faaf536a..31f4002f 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java @@ -2,32 +2,35 @@ package com.minelittlepony.unicopia.mixin; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyConstant; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.ducks.PonyContainer; import com.minelittlepony.unicopia.entity.Ponylike; -import com.minelittlepony.unicopia.entity.LivingEntityCapabilities; +import com.minelittlepony.unicopia.entity.Creature; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.math.BlockPos; @Mixin(LivingEntity.class) -abstract class MixinLivingEntity extends Entity implements PonyContainer { +abstract class MixinLivingEntity extends Entity implements PonyContainer> { - private Ponylike caster; + private Ponylike caster; private MixinLivingEntity() { super(null, null); } @Override - public Ponylike create() { - return new LivingEntityCapabilities((LivingEntity)(Object)this); + public Ponylike create() { + return new Creature((LivingEntity)(Object)this); } @Override - public Ponylike get() { + public Ponylike get() { if (caster == null) { caster = create(); } @@ -55,12 +58,12 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer create() { + return new Pony((PlayerEntity)(Object)this); } @ModifyVariable(method = "handleFallDamage(FF)Z", @@ -72,20 +71,20 @@ abstract class MixinPlayerEntity extends LivingEntity implements PonyContainer

info) { - info.setReturnValue(get().getGravity().getDimensions().getActiveEyeHeight(info.getReturnValue())); + info.setReturnValue(get().getMotion().getDimensions().getActiveEyeHeight(info.getReturnValue())); } @Inject(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;", at = @At("RETURN"), cancellable = true) public void onGetDimensions(EntityPose pose, CallbackInfoReturnable info) { - info.setReturnValue(get().getGravity().getDimensions().getDimensions(pose, info.getReturnValue())); + info.setReturnValue(get().getMotion().getDimensions().getDimensions(pose, info.getReturnValue())); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinCamera.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinCamera.java index fac17978..142ef481 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinCamera.java @@ -2,15 +2,11 @@ package com.minelittlepony.unicopia.mixin.client; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.At.Shift; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Camera; -import net.minecraft.client.util.math.Vector3f; import net.minecraft.entity.player.PlayerEntity; @Mixin(Camera.class) @@ -42,18 +38,4 @@ abstract class MixinCamera { return pitch; } - - @Inject(method = "setRotation(FF)V", - at = @At(value = "INVOKE", - target = "Lnet/minecraft/util/math/Quaternion;set(FFFF)V", - shift = Shift.AFTER) - ) - private void onSetRotation(float yaw, float pitch, CallbackInfo info) { - PlayerEntity player = MinecraftClient.getInstance().player; - - if (player != null && MinecraftClient.getInstance().cameraEntity == player) { - float roll = Pony.of(player).getCamera().calculateRoll(); - ((Camera)(Object)this).getRotation().hamiltonProduct(Vector3f.POSITIVE_Z.getDegreesQuaternion(roll)); - } - } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinEntityRenderDispatcher.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinEntityRenderDispatcher.java index b4aaa500..3a3f29f2 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinEntityRenderDispatcher.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinEntityRenderDispatcher.java @@ -5,6 +5,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.minelittlepony.unicopia.client.render.WorldRenderDelegate; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.magic.spell.DisguiseSpell; @@ -31,13 +32,7 @@ abstract class MixinEntityRenderDispatcher { Pony pony = Pony.of((PlayerEntity)entity); - if (pony.getGravity().getGravitationConstant() < 0) { - matrices.push(); - matrices.translate(0, entity.getDimensions(entity.getPose()).height, 0); - matrices.scale(1, -1, 1); - entity.prevPitch *= -1; - entity.pitch *= -1; - } + WorldRenderDelegate.INSTANCE.beforeEntityRender(pony, matrices, x, y, z); DisguiseSpell effect = pony.getEffect(DisguiseSpell.class, true); @@ -64,19 +59,13 @@ abstract class MixinEntityRenderDispatcher { } } - @Inject(method = RENDER, at = @At("HEAD")) + @Inject(method = RENDER, at = @At("RETURN")) private void afterRender(E entity, double x, double y, double z, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) { if (!(entity instanceof PlayerEntity)) { return; } - Pony pony = Pony.of((PlayerEntity)entity); - - if (pony.getGravity().getGravitationConstant() < 0) { - matrices.pop(); - entity.prevPitch *= -1; - entity.pitch *= -1; - } + WorldRenderDelegate.INSTANCE.afterEntityRender(Pony.of((PlayerEntity)entity), matrices); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinGameRenderer.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinGameRenderer.java index be097250..23ccb742 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinGameRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinGameRenderer.java @@ -3,13 +3,16 @@ package com.minelittlepony.unicopia.mixin.client; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import com.minelittlepony.unicopia.client.render.WorldRenderDelegate; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Camera; import net.minecraft.client.render.GameRenderer; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.resource.SynchronousResourceReloadListener; @Mixin(GameRenderer.class) @@ -22,4 +25,10 @@ abstract class MixinGameRenderer implements AutoCloseable, SynchronousResourceRe .getCamera() .calculateFieldOfView(info.getReturnValue())); } + + @Inject(method = "renderWorld(FLLnet/minecraft/client/util/math/MatrixStack;)V", + at = @At("HEAD")) + public void onRenderWorld(float tickDelta, long limitTime, MatrixStack matrices, CallbackInfo info) { + WorldRenderDelegate.INSTANCE.applyWorldTransform(matrices, tickDelta); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java index 2fce6597..1d35bc4a 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java @@ -17,7 +17,7 @@ abstract class MixinKeyboardInput extends Input { private void onTick(boolean strafe, CallbackInfo info) { Pony player = Pony.of(MinecraftClient.getInstance().player); - if (player.getGravity().getGravitationConstant() < 0) { + if (player.getPhysics().isGravityNegative()) { boolean tmp = pressingLeft; pressingLeft = pressingRight; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinMouse.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinMouse.java index 4a095957..6bcdf6ec 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinMouse.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinMouse.java @@ -21,7 +21,7 @@ abstract class MixinMouse { @Inject(method = "updateMouse()V", at = @At("HEAD")) private void onUpdateMouse(CallbackInfo info) { Pony player = Pony.of(MinecraftClient.getInstance().player); - if (player != null&& player.getGravity().getGravitationConstant() < 0) { + if (player != null&& player.getPhysics().isGravityNegative()) { cursorDeltaX = -cursorDeltaX; cursorDeltaY = -cursorDeltaY; }