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
public float getTargetEyeHeight(Pony player) {
return isSuppressed() ? -1 : disguise.getStandingEyeHeight();
public Optional<Float> getTargetEyeHeight(Pony player) {
return isSuppressed() ? Optional.empty() : disguise.getStandingEyeHeight();
}
@Override

View file

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

View file

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

View file

@ -134,13 +134,16 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
}
private void cancelFlight() {
boolean wasFlying = isFlyingEither;
entity.getAbilities().flying = false;
isFlyingEither = false;
isFlyingSurvival = false;
strafe = 0;
thrustScale = 0;
if (wasFlying) {
entity.calculateDimensions();
pony.sendCapabilities(true);
}
}
private double getHorizontalMotion() {
@ -184,6 +187,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
boolean creative = entity.getAbilities().creativeMode || entity.isSpectator();
boolean startedFlyingCreative = !creative && isFlyingEither != entity.getAbilities().flying;
if (!creative) {
if (entity.world.isClient && entity.isOnGround()) {
cancelFlight();
@ -206,6 +211,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
cancelFlight();
}
}
if (isGravityNegative()) {
@ -222,6 +229,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
isFlyingSurvival = entity.getAbilities().flying && !creative;
isFlyingEither = isFlyingSurvival || (creative && entity.getAbilities().flying);
if (startedFlyingCreative) {
entity.calculateDimensions();
}
if (type.canFly()) {
if (isFlying()) {
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;
strafe = 1;
ticksToGlide = 20;
if (!SpellType.DISGUISE.isOn(pony)) {
entity.playSound(type.getWingFlapSound(), 0.25F, 1);
}
} else {
strafe *= 0.28;
}
@ -407,6 +420,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
entity.getAbilities().flying = true;
isFlyingEither = true;
isFlyingSurvival = true;
entity.calculateDimensions();
if (!isGravityNegative()) {
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",
at = @At("RETURN"),
cancellable = true)
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;",
at = @At("RETURN"),
cancellable = true)
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",