Rewrite player dimensions calculations to avoid messing with dimensions when we don't have to (should improve compatibility)

This commit is contained in:
Sollace 2021-08-23 23:09:13 +02:00
parent 6fbcce7c22
commit 95231f181f
5 changed files with 48 additions and 73 deletions

View file

@ -202,8 +202,8 @@ public class DisguiseSpell extends AbstractSpell implements Attached, Suppressab
} }
@Override @Override
public float getTargetEyeHeight(Pony player) { public Optional<Float> getTargetEyeHeight(Pony player) {
return isSuppressed() ? -1 : disguise.getStandingEyeHeight(); return isSuppressed() ? Optional.empty() : disguise.getStandingEyeHeight();
} }
@Override @Override

View file

@ -50,6 +50,7 @@ import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
public class Disguise implements NbtSerialisable { public class Disguise implements NbtSerialisable {
private static final Optional<Float> BLOCK_HEIGHT = Optional.of(0.5F);
@NotNull @NotNull
private String entityId = ""; private String entityId = "";
@ -230,14 +231,14 @@ public class Disguise implements NbtSerialisable {
return FlightType.NONE; return FlightType.NONE;
} }
public float getStandingEyeHeight() { public Optional<Float> getStandingEyeHeight() {
if (entity != null) { if (entity != null) {
if (entity instanceof FallingBlockEntity) { if (entity instanceof FallingBlockEntity) {
return 0.5F; return BLOCK_HEIGHT;
} }
return entity.getStandingEyeHeight(); return Optional.of(entity.getStandingEyeHeight());
} }
return -1; return Optional.empty();
} }
public float getHeight() { public float getHeight() {

View file

@ -2,20 +2,12 @@ package com.minelittlepony.unicopia.entity.player;
import java.util.Optional; import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.Unicopia;
import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityDimensions;
public final class PlayerDimensions { public final class PlayerDimensions {
private static final float FLYING_HEIGHT = 0.6F;
private float defaultEyeHeight; private static final Optional<EntityDimensions> FLYING_DIMENSIONS = Optional.of(EntityDimensions.changing(FLYING_HEIGHT, FLYING_HEIGHT));
private static final Optional<Float> FLYING_EYE_HEIGHT = Optional.of(FLYING_HEIGHT * 0.6F);
@Nullable
private EntityDimensions defaultDimensions;
@Nullable
private EntityDimensions flyingDimensions;
private final PlayerPhysics physics; private final PlayerPhysics physics;
@ -26,48 +18,28 @@ public final class PlayerDimensions {
this.physics = gravity; this.physics = gravity;
} }
public float calculateActiveEyeHeight(EntityDimensions dimensions, float original) { public Optional<Float> calculateActiveEyeHeight(EntityDimensions dimensions) {
defaultEyeHeight = original; return getPredicate()
.flatMap(e -> e.getTargetEyeHeight(pony))
float height = calculateTargetEyeHeight(); .filter(h -> h > 0)
.or(() -> physics.isFlyingSurvival ? FLYING_EYE_HEIGHT : Optional.empty())
.map(h -> {
if (physics.isGravityNegative()) { if (physics.isGravityNegative()) {
if (pony.getMaster().isSneaking()) { if (pony.getMaster().isSneaking()) {
height += 0.2F; h += 0.2F;
} }
height = dimensions.height - height; return dimensions.height - h;
}
return h;
});
} }
return height; public Optional<EntityDimensions> calculateDimensions() {
} return getPredicate()
public EntityDimensions calculateDimensions(EntityDimensions dimensions) {
if (defaultDimensions == null || dimensions.height != defaultDimensions.height || dimensions.width != defaultDimensions.width) {
defaultDimensions = dimensions;
flyingDimensions = dimensions;//EntityDimensions.changing(dimensions.width, dimensions.height / 2);
}
dimensions = getPredicate()
.flatMap(e -> e.getTargetDimensions(pony)) .flatMap(e -> e.getTargetDimensions(pony))
.orElseGet(() -> physics.isFlyingSurvival ? flyingDimensions : defaultDimensions); .or(() -> physics.isFlyingSurvival ? FLYING_DIMENSIONS : Optional.empty())
.filter(d -> d.height > 0 && d.width > 0);
if (dimensions.height < 0 || dimensions.width < 0) {
Unicopia.LOGGER.warn("Dim out was negative! Restoring original");
return defaultDimensions;
}
return dimensions;
}
private float calculateTargetEyeHeight() {
float height = getPredicate().map(e -> e.getTargetEyeHeight(pony)).orElse(-1F);
if (height > 0) {
return height;
}
return defaultEyeHeight;
} }
Optional<Provider> getPredicate() { Optional<Provider> getPredicate() {
@ -77,7 +49,7 @@ public final class PlayerDimensions {
} }
public interface Provider { public interface Provider {
float getTargetEyeHeight(Pony player); Optional<Float> getTargetEyeHeight(Pony player);
Optional<EntityDimensions> getTargetDimensions(Pony player); Optional<EntityDimensions> getTargetDimensions(Pony player);
} }

View file

@ -134,13 +134,16 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
} }
private void cancelFlight() { private void cancelFlight() {
boolean wasFlying = isFlyingEither;
entity.getAbilities().flying = false; entity.getAbilities().flying = false;
isFlyingEither = false; isFlyingEither = false;
isFlyingSurvival = false; isFlyingSurvival = false;
strafe = 0; strafe = 0;
thrustScale = 0; thrustScale = 0;
if (wasFlying) {
entity.calculateDimensions(); entity.calculateDimensions();
pony.sendCapabilities(true); }
} }
private double getHorizontalMotion() { private double getHorizontalMotion() {
@ -184,6 +187,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
boolean creative = entity.getAbilities().creativeMode || entity.isSpectator(); boolean creative = entity.getAbilities().creativeMode || entity.isSpectator();
boolean startedFlyingCreative = !creative && isFlyingEither != entity.getAbilities().flying;
if (!creative) { if (!creative) {
if (entity.world.isClient && entity.isOnGround()) { if (entity.world.isClient && entity.isOnGround()) {
cancelFlight(); cancelFlight();
@ -206,6 +211,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
cancelFlight(); cancelFlight();
} }
} }
if (isGravityNegative()) { if (isGravityNegative()) {
@ -222,6 +229,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
isFlyingSurvival = entity.getAbilities().flying && !creative; isFlyingSurvival = entity.getAbilities().flying && !creative;
isFlyingEither = isFlyingSurvival || (creative && entity.getAbilities().flying); isFlyingEither = isFlyingSurvival || (creative && entity.getAbilities().flying);
if (startedFlyingCreative) {
entity.calculateDimensions();
}
if (type.canFly()) { if (type.canFly()) {
if (isFlying()) { if (isFlying()) {
if (pony.getSpecies() == Race.BAT && entity.verticalCollision && pony.canHangAt(pony.getOrigin().up(2))) { if (pony.getSpecies() == Race.BAT && entity.verticalCollision && pony.canHangAt(pony.getOrigin().up(2))) {
@ -242,7 +253,9 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
prevStrafe = strafing; prevStrafe = strafing;
strafe = 1; strafe = 1;
ticksToGlide = 20; ticksToGlide = 20;
if (!SpellType.DISGUISE.isOn(pony)) {
entity.playSound(type.getWingFlapSound(), 0.25F, 1); entity.playSound(type.getWingFlapSound(), 0.25F, 1);
}
} else { } else {
strafe *= 0.28; strafe *= 0.28;
} }
@ -407,6 +420,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
entity.getAbilities().flying = true; entity.getAbilities().flying = true;
isFlyingEither = true; isFlyingEither = true;
isFlyingSurvival = true; isFlyingSurvival = true;
entity.calculateDimensions();
if (!isGravityNegative()) { if (!isGravityNegative()) {
velocity.y += horMotion + 0.3; velocity.y += horMotion + 0.3;

View file

@ -86,30 +86,18 @@ abstract class MixinPlayerEntity extends LivingEntity implements PonyContainer<P
}); });
} }
/*
* TODO: Mojang plz.
* Moved to ClientPlayerInteractionManager#setGameMode, ClientPlayerInteractionManager#setGameModes, ClientPlayerInteractionManager#copyAbilities
* ServerPlayerInteractionManager#setGameMode
@Inject(method = "setGameMode(Lnet/minecraft/world/GameMode;)V",
at = @At("RETURN"))
private void onSetGameMode(GameMode mode, CallbackInfo info) {
get().setSpecies(get().getSpecies());
get().setDirty();
}
*/
@Inject(method = "getActiveEyeHeight(Lnet/minecraft/entity/EntityPose;Lnet/minecraft/entity/EntityDimensions;)F", @Inject(method = "getActiveEyeHeight(Lnet/minecraft/entity/EntityPose;Lnet/minecraft/entity/EntityDimensions;)F",
at = @At("RETURN"), at = @At("RETURN"),
cancellable = true) cancellable = true)
private void onGetActiveEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable<Float> info) { private void onGetActiveEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable<Float> info) {
info.setReturnValue(get().getMotion().getDimensions().calculateActiveEyeHeight(dimensions, info.getReturnValue())); get().getMotion().getDimensions().calculateActiveEyeHeight(dimensions).ifPresent(info::setReturnValue);
} }
@Inject(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;", @Inject(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;",
at = @At("RETURN"), at = @At("RETURN"),
cancellable = true) cancellable = true)
private void onGetDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> info) { private void onGetDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> info) {
info.setReturnValue(get().getMotion().getDimensions().calculateDimensions(info.getReturnValue())); get().getMotion().getDimensions().calculateDimensions().ifPresent(info::setReturnValue);
} }
@Inject(method = "getBlockBreakingSpeed(Lnet/minecraft/block/BlockState;)F", @Inject(method = "getBlockBreakingSpeed(Lnet/minecraft/block/BlockState;)F",