Fixed player walking speed changes due to heavy items

This commit is contained in:
Sollace 2019-01-31 19:17:11 +02:00
parent 37265afbfa
commit 0ec870cd9f
2 changed files with 75 additions and 3 deletions

View file

@ -28,6 +28,8 @@ class PlayerAttributes {
private double loadStrength = 0;
private final WalkSpeed walker = new WalkSpeed();
public void applyAttributes(EntityPlayer entity, Race race) {
loadStrength = 0;
@ -38,9 +40,7 @@ class PlayerAttributes {
loadStrength += InventoryOfHolding.decodeStackWeight(item);
}
if (entity.world.isRemote) {
entity.capabilities.setPlayerWalkSpeed(0.1F - (float)(loadStrength / 100000));
}
walker.setPlayerWalkSpeed(entity.capabilities, 0.1F - (float)(loadStrength / 100000));
applyAttribute(entity, SharedMonsterAttributes.ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth());
applyAttribute(entity, SharedMonsterAttributes.KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth());

View file

@ -0,0 +1,72 @@
package com.minelittlepony.unicopia.player;
import java.lang.reflect.Field;
import com.minelittlepony.unicopia.forgebullshit.FUF;
import net.minecraft.entity.player.PlayerCapabilities;
import net.minecraft.nbt.NBTTagCompound;;
/**
* Workaround for setting the player's walking speed.
*/
@FUF(reason = "`setPlayerWalkSpeed(v)` is marked as client-only. Waiting on mixins...")
class WalkSpeed {
private static boolean regularMethodCheck = true;
private static boolean reflexiveMethodCheck = true;
private static Field walkSpeed;
public void setPlayerWalkSpeed(PlayerCapabilities capabilities, float speed) {
if (capabilities.getWalkSpeed() == speed) {
return;
}
if (!setNormally(capabilities, speed)) {
if (!setReflexively(capabilities, speed)) {
setTheMostSlow(capabilities, speed);
}
}
}
private boolean setNormally(PlayerCapabilities capabilities, float speed) {
if (regularMethodCheck) {
try {
capabilities.setPlayerWalkSpeed(speed);
} catch (Throwable t) {
regularMethodCheck = false;
}
}
return regularMethodCheck;
}
private boolean setReflexively(PlayerCapabilities capabilities, float speed) {
if (reflexiveMethodCheck) {
try {
if (walkSpeed == null) {
Field[] f = PlayerCapabilities.class.getDeclaredFields();
walkSpeed = f[f.length - 1];
walkSpeed.setAccessible(true);
}
walkSpeed.set(capabilities, speed);
} catch (Throwable t) {
reflexiveMethodCheck = false;
}
}
return reflexiveMethodCheck;
}
private void setTheMostSlow(PlayerCapabilities capabilities, float speed) {
NBTTagCompound comp = new NBTTagCompound();
capabilities.writeCapabilitiesToNBT(comp);
comp.getCompoundTag("capabilities").setFloat("walkSpeed", speed);
capabilities.readCapabilitiesFromNBT(comp);
}
}