mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 23:27:59 +01:00
Physics rewrite for better gravity manipulation
This commit is contained in:
parent
298eddb9c2
commit
5b7f298147
41 changed files with 812 additions and 741 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ public class CarryAbility implements Ability<Hit> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Race playerSpecies) {
|
||||
return playerSpecies.canFly();
|
||||
public boolean canUse(Race race) {
|
||||
return race.canFly();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -74,7 +74,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
|
|||
return disc;
|
||||
}).setDisguise(looked);
|
||||
|
||||
iplayer.sendCapabilities(true);
|
||||
iplayer.setDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,8 +42,8 @@ public class ChangelingFeedAbility implements Ability<Hit> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Race playerSpecies) {
|
||||
return playerSpecies == Race.CHANGELING;
|
||||
public boolean canUse(Race race) {
|
||||
return race == Race.CHANGELING;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -33,8 +33,8 @@ public class EarthPonyGrowAbility implements Ability<Pos> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Race playerSpecies) {
|
||||
return playerSpecies == Race.EARTH;
|
||||
public boolean canUse(Race race) {
|
||||
return race == Race.EARTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -64,8 +64,8 @@ public class EarthPonyStompAbility implements Ability<Multi> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Race playerSpecies) {
|
||||
return playerSpecies.canUseEarth();
|
||||
public boolean canUse(Race race) {
|
||||
return race.canUseEarth();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -25,8 +25,8 @@ public class PegasusCloudInteractionAbility implements Ability<Numeric> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Race playerSpecies) {
|
||||
return playerSpecies.canInteractWithClouds();
|
||||
public boolean canUse(Race race) {
|
||||
return race.canInteractWithClouds();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,8 +23,8 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Race playerSpecies) {
|
||||
return playerSpecies.canCast();
|
||||
public boolean canUse(Race race) {
|
||||
return race.canCast();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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<ItemEntityCapabilities> {
|
||||
public interface IItemEntity extends PonyContainer<ItemImpl> {
|
||||
|
||||
int getAge();
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ import com.minelittlepony.unicopia.magic.Caster;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public interface PonyContainer<T extends Ponylike> {
|
||||
public interface PonyContainer<T extends Ponylike<?>> {
|
||||
|
||||
Ponylike create();
|
||||
Ponylike<?> create();
|
||||
|
||||
T get();
|
||||
|
||||
|
@ -28,7 +28,7 @@ public interface PonyContainer<T extends Ponylike> {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <E extends Entity, T extends Ponylike> Optional<PonyContainer<T>> of(Entity entity) {
|
||||
static <E extends Entity, T extends Ponylike<?>> Optional<PonyContainer<T>> of(Entity entity) {
|
||||
if (entity instanceof PonyContainer) {
|
||||
return Optional.of(((PonyContainer<T>)entity));
|
||||
}
|
||||
|
|
|
@ -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<LivingEntity>, Caster<LivingEntity> {
|
||||
public class Creature implements Ponylike<LivingEntity>, Caster<LivingEntity> {
|
||||
|
||||
private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
|
||||
|
||||
|
@ -23,9 +23,11 @@ public class LivingEntityCapabilities implements RaceContainer<LivingEntity>, 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<LivingEntity>, 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<LivingEntity>, 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<LivingEntity>, Ca
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDimensionalTravel(int destinationDimension) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwner(LivingEntity owner) {
|
||||
|
||||
|
@ -111,6 +113,7 @@ public class LivingEntityCapabilities implements RaceContainer<LivingEntity>, Ca
|
|||
if (effect != null) {
|
||||
compound.put("effect", SpellRegistry.instance().serializeEffectToNBT(effect));
|
||||
}
|
||||
physics.toNBT(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -118,5 +121,6 @@ public class LivingEntityCapabilities implements RaceContainer<LivingEntity>, Ca
|
|||
if (compound.contains("effect")) {
|
||||
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect")));
|
||||
}
|
||||
physics.fromNBT(compound);
|
||||
}
|
||||
}
|
|
@ -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<Integer> 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);
|
||||
|
|
|
@ -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<T extends Ponylike<?> & Owned<? extends Entity>> 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,19 +11,21 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.ActionResult;
|
||||
|
||||
public class ItemEntityCapabilities implements RaceContainer<ItemEntity>, Owned<ItemEntity> {
|
||||
public class ItemImpl implements Ponylike<ItemEntity>, Owned<ItemEntity> {
|
||||
private static final TrackedData<Integer> 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<ItemEntity>, 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<ItemEntity>, 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<ItemEntity>, Owned<
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDimensionalTravel(int destinationDimension) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemEntity getOwner() {
|
||||
return owner;
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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<T extends Entity> 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 extends Ponylike> T of(Entity entity) {
|
||||
static <T extends Ponylike<?>> T of(Entity entity) {
|
||||
return PonyContainer.<Entity, T>of(entity)
|
||||
.map(PonyContainer::get)
|
||||
.orElse(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 <T> The type of owner
|
||||
*/
|
||||
public interface RaceContainer<T extends Entity> extends Ponylike {
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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<Integer> PLAYER_RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||
private static final TrackedData<Float> ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
private static final TrackedData<Float> EXERTION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
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 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<SleepFailureReason, Unit> 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 extends MagicEffect> T getEffect(@Nullable Class<T> 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) {
|
||||
}
|
||||
}
|
|
@ -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<AddictiveMagicalItem, Entry> 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<Map.Entry<AddictiveMagicalItem, Entry>> 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;
|
||||
|
|
|
@ -13,6 +13,12 @@ import net.minecraft.util.Identifier;
|
|||
public class PlayerPageStats implements NbtSerialisable, PageOwner {
|
||||
private final Map<Identifier, PageState> pageStates = new HashMap<>();
|
||||
|
||||
private final Pony pony;
|
||||
|
||||
PlayerPageStats(Pony pony) {
|
||||
this.pony = pony;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Identifier, PageState> getPageStates() {
|
||||
return pageStates;
|
||||
|
@ -20,7 +26,7 @@ public class PlayerPageStats implements NbtSerialisable, PageOwner {
|
|||
|
||||
@Override
|
||||
public void sendCapabilities(boolean full) {
|
||||
|
||||
pony.sendCapabilities(full);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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<Pony> 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
|
|
@ -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<PlayerEntity>, RaceContainer<PlayerEntity>, Transmittable {
|
||||
public class Pony implements Caster<PlayerEntity>, Ponylike<PlayerEntity>, Transmittable {
|
||||
|
||||
/**
|
||||
* Gets the player's magical abilities delegate responsible for all spell casting and persisting/updating.
|
||||
*/
|
||||
AbilityDispatcher getAbilities();
|
||||
private static final TrackedData<Integer> RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||
static final TrackedData<Float> ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
static final TrackedData<Float> EXERTION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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<PlayerEntity.SleepFailureReason, Unit> 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<SleepFailureReason, Unit> 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 extends MagicEffect> T getEffect(@Nullable Class<T> 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<Pony>)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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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<Ponylike> {
|
||||
abstract class MixinLivingEntity extends Entity implements PonyContainer<Ponylike<?>> {
|
||||
|
||||
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<Ponylik
|
|||
|
||||
@Inject(method = "tick()V", at = @At("RETURN"))
|
||||
private void afterTick(CallbackInfo info) {
|
||||
get().onUpdate();
|
||||
get().tick();
|
||||
}
|
||||
|
||||
@Inject(method = "<clinit>()V", at = @At("RETURN"), remap = false)
|
||||
private static void clinit(CallbackInfo info) {
|
||||
LivingEntityCapabilities.boostrap();
|
||||
Creature.boostrap();
|
||||
}
|
||||
|
||||
@Inject(method = "writeCustomDataToTag(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("HEAD"))
|
||||
|
@ -75,6 +78,31 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Ponylik
|
|||
}
|
||||
}
|
||||
|
||||
@ModifyConstant(method = "travel(Lnet/minecraft/util/math/Vec3d;)V", constant = {
|
||||
@Constant(doubleValue = 0.08D),
|
||||
@Constant(doubleValue = 0.01D)
|
||||
})
|
||||
private double modifyGravity(double initial) {
|
||||
return get().getPhysics().calcGravity(initial);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockPos getLandingPos() {
|
||||
if (get().getPhysics().isGravityNegative()) {
|
||||
return get().getPhysics().getHeadPosition();
|
||||
}
|
||||
return super.getLandingPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void spawnSprintingParticles() {
|
||||
if (get().getPhysics().isGravityNegative()) {
|
||||
get().getPhysics().spawnSprintingParticles();
|
||||
} else {
|
||||
super.spawnSprintingParticles();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- temporary
|
||||
@SuppressWarnings("deprecation")
|
||||
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
|
||||
|
|
|
@ -10,7 +10,6 @@ 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.player.Pony;
|
||||
import com.minelittlepony.unicopia.entity.player.PlayerImpl;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
|
@ -29,8 +28,8 @@ abstract class MixinPlayerEntity extends LivingEntity implements PonyContainer<P
|
|||
private MixinPlayerEntity() { super(null, null); }
|
||||
|
||||
@Override
|
||||
public Ponylike create() {
|
||||
return new PlayerImpl((PlayerEntity)(Object)this);
|
||||
public Ponylike<?> create() {
|
||||
return new Pony((PlayerEntity)(Object)this);
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "handleFallDamage(FF)Z",
|
||||
|
@ -72,20 +71,20 @@ abstract class MixinPlayerEntity extends LivingEntity implements PonyContainer<P
|
|||
at = @At("RETURN"))
|
||||
private void onSetGameMode(GameMode mode, CallbackInfo info) {
|
||||
get().setSpecies(get().getSpecies());
|
||||
get().sendCapabilities(true);
|
||||
get().setDirty();
|
||||
}
|
||||
|
||||
@Inject(method = "getActiveEyeHeight(Lnet/minecraft/entity/EntityPose;Lnet/minecraft/entity/EntityDimensions;)F",
|
||||
at = @At("RETURN"),
|
||||
cancellable = true)
|
||||
private void onGetActiveEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable<Float> 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<EntityDimensions> info) {
|
||||
info.setReturnValue(get().getGravity().getDimensions().getDimensions(pose, info.getReturnValue()));
|
||||
info.setReturnValue(get().getMotion().getDimensions().getDimensions(pose, info.getReturnValue()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <E extends Entity> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue