mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-12-02 17:08:00 +01:00
Move all the logic for hanging and climbing into a separate class and fix bat ponies not automatically cancelling when they move
This commit is contained in:
parent
04cefd8961
commit
884ced25f1
4 changed files with 203 additions and 139 deletions
|
@ -38,13 +38,13 @@ public class BatPonyHangAbility implements Ability<Multi> {
|
||||||
@Override
|
@Override
|
||||||
public Optional<Multi> prepare(Pony player) {
|
public Optional<Multi> prepare(Pony player) {
|
||||||
|
|
||||||
if (player.isHanging()) {
|
if (player.getAcrobatics().isHanging()) {
|
||||||
return Optional.of(new Multi(BlockPos.ZERO, 0));
|
return Optional.of(new Multi(BlockPos.ZERO, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return TraceHelper.findBlock(player.asEntity(), 5, 1)
|
return TraceHelper.findBlock(player.asEntity(), 5, 1)
|
||||||
.map(BlockPos::down)
|
.map(BlockPos::down)
|
||||||
.filter(player::canHangAt)
|
.filter(player.getAcrobatics()::canHangAt)
|
||||||
.map(pos -> new Multi(pos, 1));
|
.map(pos -> new Multi(pos, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,13 +55,13 @@ public class BatPonyHangAbility implements Ability<Multi> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Pony player, Multi data) {
|
public boolean apply(Pony player, Multi data) {
|
||||||
if (data.hitType() == 0 && player.isHanging()) {
|
if (data.hitType() == 0 && player.getAcrobatics().isHanging()) {
|
||||||
player.stopHanging();
|
player.getAcrobatics().stopHanging();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.hitType() == 1 && player.canHangAt(data.pos().pos())) {
|
if (data.hitType() == 1 && player.getAcrobatics().canHangAt(data.pos().pos())) {
|
||||||
player.startHanging(data.pos().pos());
|
player.getAcrobatics().startHanging(data.pos().pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
package com.minelittlepony.unicopia.entity.player;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Race;
|
||||||
|
import com.minelittlepony.unicopia.USounds;
|
||||||
|
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||||
|
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation.Recipient;
|
||||||
|
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
|
||||||
|
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||||
|
import com.minelittlepony.unicopia.util.Tickable;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.SideShapeType;
|
||||||
|
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.nbt.NbtCompound;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class Acrobatics implements Tickable, NbtSerialisable {
|
||||||
|
static final TrackedData<Optional<BlockPos>> HANGING_POSITION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.OPTIONAL_BLOCK_POS);
|
||||||
|
|
||||||
|
private int ticksHanging;
|
||||||
|
|
||||||
|
private Direction attachDirection;
|
||||||
|
double distanceClimbed;
|
||||||
|
|
||||||
|
private final Pony pony;
|
||||||
|
private final PlayerEntity entity;
|
||||||
|
|
||||||
|
public Acrobatics(Pony pony) {
|
||||||
|
this.pony = pony;
|
||||||
|
this.entity = pony.asEntity();
|
||||||
|
|
||||||
|
entity.getDataTracker().startTracking(HANGING_POSITION, Optional.empty());
|
||||||
|
|
||||||
|
pony.addTicker(this::checkDislodge);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
BlockPos climbingPos = entity.getClimbingPos().orElse(null);
|
||||||
|
|
||||||
|
if (!pony.getPhysics().isFlying() && !entity.getAbilities().flying
|
||||||
|
&& climbingPos != null
|
||||||
|
&& pony.getObservedSpecies() == Race.CHANGELING) {
|
||||||
|
Vec3d vel = entity.getVelocity();
|
||||||
|
if (entity.isSneaking()) {
|
||||||
|
entity.setVelocity(vel.x, 0, vel.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
distanceClimbed += Math.abs(pony.getMotion().getClientVelocity().y);
|
||||||
|
BlockPos hangingPos = entity.getBlockPos().up();
|
||||||
|
boolean canhangHere = canHangAt(hangingPos);
|
||||||
|
|
||||||
|
if (distanceClimbed > 1.5) {
|
||||||
|
if (vel.length() > 0.08F && entity.age % (3 + entity.getRandom().nextInt(5)) == 0) {
|
||||||
|
entity.playSound(USounds.ENTITY_PLAYER_CHANGELING_CLIMB,
|
||||||
|
(float)entity.getRandom().nextTriangular(0.5, 0.3),
|
||||||
|
entity.getSoundPitch()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean skipHangCheck = false;
|
||||||
|
Direction newAttachDirection = entity.getHorizontalFacing();
|
||||||
|
if (isFaceClimbable(entity.getWorld(), entity.getBlockPos(), newAttachDirection) && (newAttachDirection != attachDirection)) {
|
||||||
|
attachDirection = newAttachDirection;
|
||||||
|
skipHangCheck = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skipHangCheck && canhangHere) {
|
||||||
|
if (!isHanging()) {
|
||||||
|
startHanging(hangingPos);
|
||||||
|
} else {
|
||||||
|
if (((LivingEntityDuck)entity).isJumping()) {
|
||||||
|
// Jump to let go
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entity.setVelocity(entity.getVelocity().multiply(1, 0, 1));
|
||||||
|
entity.setSneaking(false);
|
||||||
|
}
|
||||||
|
} else if (attachDirection != null) {
|
||||||
|
if (isFaceClimbable(entity.getWorld(), entity.getBlockPos(), attachDirection)) {
|
||||||
|
entity.setBodyYaw(attachDirection.asRotation());
|
||||||
|
entity.prevBodyYaw = attachDirection.asRotation();
|
||||||
|
} else {
|
||||||
|
entity.setVelocity(vel);
|
||||||
|
entity.isClimbing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canhangHere) {
|
||||||
|
pony.setAnimation(Animation.HANG, Recipient.ANYONE);
|
||||||
|
} else if (distanceClimbed > 1.5) {
|
||||||
|
pony.setAnimation(Animation.CLIMB, Recipient.ANYONE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
distanceClimbed = 0;
|
||||||
|
attachDirection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkDislodge() {
|
||||||
|
if (isHanging()) {
|
||||||
|
((LivingEntityDuck)entity).setLeaningPitch(0);
|
||||||
|
if (!pony.isClient() && !canKeepHanging()) {
|
||||||
|
stopHanging();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ticksHanging = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isFaceClimbable(World world, BlockPos pos, Direction direction) {
|
||||||
|
pos = pos.offset(direction);
|
||||||
|
return world.getBlockState(pos).isSideSolid(world, pos, direction, SideShapeType.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<BlockPos> getHangingPosition() {
|
||||||
|
return entity.getDataTracker().get(HANGING_POSITION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHanging() {
|
||||||
|
return getHangingPosition().isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopHanging() {
|
||||||
|
entity.getDataTracker().set(HANGING_POSITION, Optional.empty());
|
||||||
|
entity.calculateDimensions();
|
||||||
|
ticksHanging = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startHanging(BlockPos pos) {
|
||||||
|
entity.getDataTracker().set(HANGING_POSITION, Optional.of(pos));
|
||||||
|
entity.teleport(pos.getX() + 0.5, pos.getY() - 1, pos.getZ() + 0.5);
|
||||||
|
entity.setVelocity(Vec3d.ZERO);
|
||||||
|
entity.setSneaking(false);
|
||||||
|
entity.stopFallFlying();
|
||||||
|
pony.getPhysics().cancelFlight(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canHangAt(BlockPos pos) {
|
||||||
|
if (!pony.asWorld().isAir(pos) || !pony.asWorld().isAir(pos.down())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = pos.up();
|
||||||
|
BlockState state = pony.asWorld().getBlockState(pos);
|
||||||
|
|
||||||
|
return state.isSolidSurface(pony.asWorld(), pos, entity, Direction.DOWN) && entity.getWorld().isAir(entity.getBlockPos().down());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canKeepHanging() {
|
||||||
|
Race race = pony.getObservedSpecies();
|
||||||
|
if (!race.canHang()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ticksHanging++ <= 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return getHangingPosition().filter(hangingPos -> {
|
||||||
|
return (race != Race.BAT || hangingPos.equals(pony.getOrigin().down())) && canHangAt(hangingPos);
|
||||||
|
}).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toNBT(NbtCompound compound) {
|
||||||
|
compound.putInt("ticksHanging", ticksHanging);
|
||||||
|
BLOCK_POS.writeOptional("hangingPosition", compound, getHangingPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromNBT(NbtCompound compound) {
|
||||||
|
ticksHanging = compound.getInt("ticksHanging");
|
||||||
|
pony.asEntity().getDataTracker().set(HANGING_POSITION, NbtSerialisable.BLOCK_POS.readOptional("hangingPosition", compound));
|
||||||
|
}
|
||||||
|
}
|
|
@ -115,7 +115,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
@Override
|
@Override
|
||||||
public float getGravityModifier() {
|
public float getGravityModifier() {
|
||||||
float modifier = getPersistantGravityModifier();
|
float modifier = getPersistantGravityModifier();
|
||||||
if (pony.isHanging() && pony.getObservedSpecies() == Race.BAT) {
|
if (pony.getAcrobatics().isHanging() && pony.getObservedSpecies() == Race.BAT) {
|
||||||
modifier *= -0.05F;
|
modifier *= -0.05F;
|
||||||
}
|
}
|
||||||
return modifier;
|
return modifier;
|
||||||
|
@ -385,7 +385,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
|
|
||||||
entity.setVelocity(velocity.toImmutable());
|
entity.setVelocity(velocity.toImmutable());
|
||||||
|
|
||||||
if (isFlying() && !entity.isFallFlying() && !pony.isHanging() && pony.isClient()) {
|
if (isFlying() && !entity.isFallFlying() && !pony.getAcrobatics().isHanging() && pony.isClient()) {
|
||||||
if (!MineLPDelegate.getInstance().getPlayerPonyRace(entity).isEquine() && getHorizontalMotion() > 0.03) {
|
if (!MineLPDelegate.getInstance().getPlayerPonyRace(entity).isEquine() && getHorizontalMotion() > 0.03) {
|
||||||
float pitch = ((LivingEntityDuck)entity).getLeaningPitch();
|
float pitch = ((LivingEntityDuck)entity).getLeaningPitch();
|
||||||
if (pitch < 1) {
|
if (pitch < 1) {
|
||||||
|
@ -533,7 +533,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
&& pony.getJumpingHeuristic().hasChanged(Heuristic.TWICE);
|
&& pony.getJumpingHeuristic().hasChanged(Heuristic.TWICE);
|
||||||
boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 * getGravitySignum() && entity.fallDistance > 1;
|
boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 * getGravitySignum() && entity.fallDistance > 1;
|
||||||
|
|
||||||
if ((takeOffCondition || fallingTakeOffCondition) && !pony.isHanging() && !isCancelled) {
|
if ((takeOffCondition || fallingTakeOffCondition) && !pony.getAcrobatics().isHanging() && !isCancelled) {
|
||||||
initiateTakeoff(velocity);
|
initiateTakeoff(velocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import java.util.stream.Stream;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation.Recipient;
|
|
||||||
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
|
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
|
||||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.AnimationInstance;
|
import com.minelittlepony.unicopia.client.render.PlayerPoser.AnimationInstance;
|
||||||
import com.minelittlepony.unicopia.*;
|
import com.minelittlepony.unicopia.*;
|
||||||
|
@ -37,8 +36,6 @@ import com.google.common.collect.Streams;
|
||||||
import com.minelittlepony.common.util.animation.Interpolator;
|
import com.minelittlepony.common.util.animation.Interpolator;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.SideShapeType;
|
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.entity.*;
|
import net.minecraft.entity.*;
|
||||||
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
||||||
|
@ -63,7 +60,6 @@ import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.world.GameMode;
|
import net.minecraft.world.GameMode;
|
||||||
import net.minecraft.world.GameRules;
|
import net.minecraft.world.GameRules;
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, UpdateCallback {
|
public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, UpdateCallback {
|
||||||
private static final TrackedData<String> RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.STRING);
|
private static final TrackedData<String> RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.STRING);
|
||||||
|
@ -71,7 +67,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
static final TrackedData<Float> ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
static final TrackedData<Float> ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||||
static final TrackedData<Float> EXHAUSTION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
static final TrackedData<Float> EXHAUSTION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||||
static final TrackedData<Float> EXERTION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
static final TrackedData<Float> EXERTION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||||
static final TrackedData<Optional<BlockPos>> HANGING_POSITION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.OPTIONAL_BLOCK_POS);
|
|
||||||
static final TrackedData<Float> MANA = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
static final TrackedData<Float> MANA = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||||
static final TrackedData<Float> XP = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
static final TrackedData<Float> XP = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||||
static final TrackedData<Float> CHARGE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
static final TrackedData<Float> CHARGE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||||
|
@ -87,6 +82,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
private final PlayerCharmTracker charms = new PlayerCharmTracker(this);
|
private final PlayerCharmTracker charms = new PlayerCharmTracker(this);
|
||||||
private final PlayerCamera camera = new PlayerCamera(this);
|
private final PlayerCamera camera = new PlayerCamera(this);
|
||||||
private final TraitDiscovery discoveries = new TraitDiscovery(this);
|
private final TraitDiscovery discoveries = new TraitDiscovery(this);
|
||||||
|
private final Acrobatics acrobatics = new Acrobatics(this);
|
||||||
|
|
||||||
private final Map<String, Integer> advancementProgress = new HashMap<>();
|
private final Map<String, Integer> advancementProgress = new HashMap<>();
|
||||||
|
|
||||||
|
@ -101,8 +97,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
|
|
||||||
private boolean dirty;
|
private boolean dirty;
|
||||||
|
|
||||||
private int ticksHanging;
|
|
||||||
|
|
||||||
private float magicExhaustion = 0;
|
private float magicExhaustion = 0;
|
||||||
|
|
||||||
private int ticksInvulnerable;
|
private int ticksInvulnerable;
|
||||||
|
@ -111,9 +105,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
private boolean hasShades;
|
private boolean hasShades;
|
||||||
private int ticksSunImmunity = INITIAL_SUN_IMMUNITY;
|
private int ticksSunImmunity = INITIAL_SUN_IMMUNITY;
|
||||||
|
|
||||||
private Direction attachDirection;
|
|
||||||
private double distanceClimbed;
|
|
||||||
|
|
||||||
private AnimationInstance animation = new AnimationInstance(Animation.NONE, Animation.Recipient.ANYONE);
|
private AnimationInstance animation = new AnimationInstance(Animation.NONE, Animation.Recipient.ANYONE);
|
||||||
private int animationMaxDuration;
|
private int animationMaxDuration;
|
||||||
private int animationDuration;
|
private int animationDuration;
|
||||||
|
@ -125,7 +116,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
this.mana = addTicker(new ManaContainer(this));
|
this.mana = addTicker(new ManaContainer(this));
|
||||||
|
|
||||||
player.getDataTracker().startTracking(RACE, Race.DEFAULT_ID);
|
player.getDataTracker().startTracking(RACE, Race.DEFAULT_ID);
|
||||||
player.getDataTracker().startTracking(HANGING_POSITION, Optional.empty());
|
|
||||||
|
|
||||||
addTicker(this::updateAnimations);
|
addTicker(this::updateAnimations);
|
||||||
addTicker(this::updateBatPonyAbilities);
|
addTicker(this::updateBatPonyAbilities);
|
||||||
|
@ -250,6 +240,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
return charms;
|
return charms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Acrobatics getAcrobatics() {
|
||||||
|
return acrobatics;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LevelStore getLevel() {
|
public LevelStore getLevel() {
|
||||||
return levels;
|
return levels;
|
||||||
|
@ -393,67 +387,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
magicExhaustion = ManaConsumptionUtil.burnFood(entity, magicExhaustion);
|
magicExhaustion = ManaConsumptionUtil.burnFood(entity, magicExhaustion);
|
||||||
|
|
||||||
powers.tick();
|
powers.tick();
|
||||||
|
acrobatics.tick();
|
||||||
BlockPos climbingPos = entity.getClimbingPos().orElse(null);
|
|
||||||
|
|
||||||
if (!getPhysics().isFlying() && !entity.getAbilities().flying
|
|
||||||
&& climbingPos != null
|
|
||||||
&& getObservedSpecies() == Race.CHANGELING) {
|
|
||||||
Vec3d vel = entity.getVelocity();
|
|
||||||
if (entity.isSneaking()) {
|
|
||||||
entity.setVelocity(vel.x, 0, vel.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
distanceClimbed += Math.abs(getMotion().getClientVelocity().y);
|
|
||||||
BlockPos hangingPos = entity.getBlockPos().up();
|
|
||||||
boolean canhangHere = canHangAt(hangingPos);
|
|
||||||
|
|
||||||
if (distanceClimbed > 1.5) {
|
|
||||||
if (vel.length() > 0.08F && entity.age % (3 + entity.getRandom().nextInt(5)) == 0) {
|
|
||||||
entity.playSound(USounds.ENTITY_PLAYER_CHANGELING_CLIMB,
|
|
||||||
(float)entity.getRandom().nextTriangular(0.5, 0.3),
|
|
||||||
entity.getSoundPitch()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean skipHangCheck = false;
|
|
||||||
Direction newAttachDirection = entity.getHorizontalFacing();
|
|
||||||
if (isFaceClimbable(entity.getWorld(), entity.getBlockPos(), newAttachDirection) && (newAttachDirection != attachDirection)) {
|
|
||||||
attachDirection = newAttachDirection;
|
|
||||||
skipHangCheck = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!skipHangCheck && canhangHere) {
|
|
||||||
if (!isHanging()) {
|
|
||||||
startHanging(hangingPos);
|
|
||||||
} else {
|
|
||||||
if (((LivingEntityDuck)entity).isJumping()) {
|
|
||||||
// Jump to let go
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
entity.setVelocity(entity.getVelocity().multiply(1, 0, 1));
|
|
||||||
entity.setSneaking(false);
|
|
||||||
}
|
|
||||||
} else if (attachDirection != null) {
|
|
||||||
if (isFaceClimbable(entity.getWorld(), entity.getBlockPos(), attachDirection)) {
|
|
||||||
entity.setBodyYaw(attachDirection.asRotation());
|
|
||||||
entity.prevBodyYaw = attachDirection.asRotation();
|
|
||||||
} else {
|
|
||||||
entity.setVelocity(vel);
|
|
||||||
entity.isClimbing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canhangHere) {
|
|
||||||
setAnimation(Animation.HANG, Recipient.ANYONE);
|
|
||||||
} else if (distanceClimbed > 1.5) {
|
|
||||||
setAnimation(Animation.CLIMB, Recipient.ANYONE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
distanceClimbed = 0;
|
|
||||||
attachDirection = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getObservedSpecies() == Race.KIRIN) {
|
if (getObservedSpecies() == Race.KIRIN) {
|
||||||
var charge = getMagicalReserves().getCharge();
|
var charge = getMagicalReserves().getCharge();
|
||||||
|
@ -488,49 +422,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
return super.beforeUpdate();
|
return super.beforeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFaceClimbable(World world, BlockPos pos, Direction direction) {
|
|
||||||
pos = pos.offset(direction);
|
|
||||||
return world.getBlockState(pos).isSideSolid(world, pos, direction, SideShapeType.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<BlockPos> getHangingPosition() {
|
|
||||||
return entity.getDataTracker().get(HANGING_POSITION);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHanging() {
|
|
||||||
return getHangingPosition().isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopHanging() {
|
|
||||||
entity.getDataTracker().set(HANGING_POSITION, Optional.empty());
|
|
||||||
entity.calculateDimensions();
|
|
||||||
ticksHanging = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startHanging(BlockPos pos) {
|
|
||||||
entity.getDataTracker().set(HANGING_POSITION, Optional.of(pos));
|
|
||||||
entity.teleport(pos.getX() + 0.5, pos.getY() - 1, pos.getZ() + 0.5);
|
|
||||||
entity.setVelocity(Vec3d.ZERO);
|
|
||||||
entity.setSneaking(false);
|
|
||||||
entity.stopFallFlying();
|
|
||||||
getPhysics().cancelFlight(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canHangAt(BlockPos pos) {
|
|
||||||
if (!asWorld().isAir(pos) || !asWorld().isAir(pos.down())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = pos.up();
|
|
||||||
BlockState state = asWorld().getBlockState(pos);
|
|
||||||
|
|
||||||
return state.isSolidSurface(asWorld(), pos, entity, Direction.DOWN) && entity.getWorld().isAir(entity.getBlockPos().down());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<BlockPos> chooseClimbingPos() {
|
public Optional<BlockPos> chooseClimbingPos() {
|
||||||
if (getObservedSpecies() == Race.CHANGELING && getSpellSlot().get(SpellPredicate.IS_DISGUISE, false).isEmpty()) {
|
if (getObservedSpecies() == Race.CHANGELING && getSpellSlot().get(SpellPredicate.IS_DISGUISE, false).isEmpty()) {
|
||||||
if (isFaceClimbable(entity.getWorld(), entity.getBlockPos(), entity.getHorizontalFacing()) || canHangAt(entity.getBlockPos())) {
|
if (acrobatics.isFaceClimbable(entity.getWorld(), entity.getBlockPos(), entity.getHorizontalFacing()) || acrobatics.canHangAt(entity.getBlockPos())) {
|
||||||
return Optional.of(entity.getBlockPos());
|
return Optional.of(entity.getBlockPos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,7 +434,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
|
|
||||||
private void updateAnimations() {
|
private void updateAnimations() {
|
||||||
|
|
||||||
if (distanceClimbed > 0
|
if (acrobatics.distanceClimbed > 0
|
||||||
&& ((animation.isOf(Animation.CLIMB) && entity.isSneaking()) || animation.isOf(Animation.HANG))
|
&& ((animation.isOf(Animation.CLIMB) && entity.isSneaking()) || animation.isOf(Animation.HANG))
|
||||||
&& entity.getClimbingPos().isPresent()
|
&& entity.getClimbingPos().isPresent()
|
||||||
&& entity.getVelocity().length() < 0.08F) {
|
&& entity.getVelocity().length() < 0.08F) {
|
||||||
|
@ -551,7 +446,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
|
|
||||||
if (animationDuration > 0 && --animationDuration <= 0) {
|
if (animationDuration > 0 && --animationDuration <= 0) {
|
||||||
|
|
||||||
if (animation.renderBothArms() && distanceClimbed > 0) {
|
if (animation.renderBothArms() && acrobatics.distanceClimbed > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,17 +459,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
ticksSunImmunity--;
|
ticksSunImmunity--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHanging()) {
|
|
||||||
((LivingEntityDuck)entity).setLeaningPitch(0);
|
|
||||||
if (!getObservedSpecies().canHang() || (ticksHanging++ > 2 && getHangingPosition().filter(this::canHangAt).isEmpty())) {
|
|
||||||
if (!isClient()) {
|
|
||||||
stopHanging();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ticksHanging = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getObservedSpecies() == Race.BAT && !entity.hasPortalCooldown()) {
|
if (getObservedSpecies() == Race.BAT && !entity.hasPortalCooldown()) {
|
||||||
boolean hasShades = TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.FACE).anyMatch(s -> s.isIn(UTags.SHADES));
|
boolean hasShades = TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.FACE).anyMatch(s -> s.isIn(UTags.SHADES));
|
||||||
if (!this.hasShades && hasShades && getObservedSpecies() == Race.BAT) {
|
if (!this.hasShades && hasShades && getObservedSpecies() == Race.BAT) {
|
||||||
|
@ -859,10 +743,9 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
super.toSyncronisedNbt(compound);
|
super.toSyncronisedNbt(compound);
|
||||||
compound.putString("playerSpecies", Race.REGISTRY.getId(getSpecies()).toString());
|
compound.putString("playerSpecies", Race.REGISTRY.getId(getSpecies()).toString());
|
||||||
compound.putFloat("magicExhaustion", magicExhaustion);
|
compound.putFloat("magicExhaustion", magicExhaustion);
|
||||||
compound.putInt("ticksHanging", ticksHanging);
|
|
||||||
BLOCK_POS.writeOptional("hangingPosition", compound, getHangingPosition());
|
|
||||||
compound.putInt("ticksInSun", ticksInSun);
|
compound.putInt("ticksInSun", ticksInSun);
|
||||||
compound.putBoolean("hasShades", hasShades);
|
compound.putBoolean("hasShades", hasShades);
|
||||||
|
compound.put("acrobatics", acrobatics.toNBT());
|
||||||
compound.put("powers", powers.toNBT());
|
compound.put("powers", powers.toNBT());
|
||||||
compound.put("gravity", gravity.toNBT());
|
compound.put("gravity", gravity.toNBT());
|
||||||
compound.put("charms", charms.toNBT());
|
compound.put("charms", charms.toNBT());
|
||||||
|
@ -890,11 +773,9 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
levels.set(compound.getInt("levels"));
|
levels.set(compound.getInt("levels"));
|
||||||
corruption.set(compound.getInt("corruption"));
|
corruption.set(compound.getInt("corruption"));
|
||||||
mana.fromNBT(compound.getCompound("mana"));
|
mana.fromNBT(compound.getCompound("mana"));
|
||||||
|
acrobatics.fromNBT(compound.getCompound("acrobatics"));
|
||||||
magicExhaustion = compound.getFloat("magicExhaustion");
|
magicExhaustion = compound.getFloat("magicExhaustion");
|
||||||
ticksHanging = compound.getInt("ticksHanging");
|
|
||||||
ticksInvulnerable = compound.getInt("ticksInvulnerable");
|
ticksInvulnerable = compound.getInt("ticksInvulnerable");
|
||||||
entity.getDataTracker().set(HANGING_POSITION, NbtSerialisable.BLOCK_POS.readOptional("hangingPosition", compound));
|
|
||||||
ticksInSun = compound.getInt("ticksInSun");
|
ticksInSun = compound.getInt("ticksInSun");
|
||||||
hasShades = compound.getBoolean("hasShades");
|
hasShades = compound.getBoolean("hasShades");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue