Fix bugs including 1.17.1 player movement, flying yaw and stats incompatibility on 1.17.1

This commit is contained in:
fullwall 2021-07-10 00:47:05 +08:00
parent 3e1132034e
commit 53e2b50ce8
7 changed files with 131 additions and 36 deletions

View File

@ -175,8 +175,8 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
|| (dY >= 0.2 && MinecraftBlockExaminer.isLiquidOrInLiquid(in))) { || (dY >= 0.2 && MinecraftBlockExaminer.isLiquidOrInLiquid(in))) {
dir.add(new Vector(0, 0.75, 0)); dir.add(new Vector(0, 0.75, 0));
} }
Util.faceLocation(npc.getEntity(), destVector.toLocation(npc.getEntity().getWorld()));
npc.getEntity().setVelocity(dir); npc.getEntity().setVelocity(dir);
Util.faceLocation(npc.getEntity(), destVector.toLocation(npc.getEntity().getWorld()));
} }
params.run(); params.run();
plan.run(npc); plan.run(npc);

View File

@ -28,6 +28,7 @@ import net.citizensnpcs.api.astar.pathfinder.VectorNode;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.PlayerAnimation;
import net.citizensnpcs.util.Util;
public class FlyingAStarNavigationStrategy extends AbstractPathStrategy { public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
private int iterations; private int iterations;
@ -153,9 +154,10 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
} }
} }
double d0 = vector.getX() + 0.5D - current.getX(); Vector centeredDest = new Vector(vector.getX() + 0.5D, vector.getY() + 0.1D, vector.getZ() + 0.5D);
double d1 = vector.getY() + 0.1D - current.getY(); double d0 = centeredDest.getX() - current.getX();
double d2 = vector.getZ() + 0.5D - current.getZ(); double d1 = centeredDest.getY() - current.getY();
double d2 = centeredDest.getZ() - current.getZ();
Vector velocity = npc.getEntity().getVelocity(); Vector velocity = npc.getEntity().getVelocity();
double motX = velocity.getX(), motY = velocity.getY(), motZ = velocity.getZ(); double motX = velocity.getX(), motY = velocity.getY(), motZ = velocity.getZ();
@ -166,7 +168,7 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
velocity.setX(motX).setY(motY).setZ(motZ).multiply(parameters.speed()); velocity.setX(motX).setY(motY).setZ(motZ).multiply(parameters.speed());
npc.getEntity().setVelocity(velocity); npc.getEntity().setVelocity(velocity);
float targetYaw = (float) (Math.atan2(motZ, motX) * 180.0D / Math.PI) - 90.0F; float targetYaw = (float) (Math.toDegrees(Math.atan2(motZ, motX))) - 90.0F;
float normalisedTargetYaw = (targetYaw - current.getYaw()) % 360; float normalisedTargetYaw = (targetYaw - current.getYaw()) % 360;
if (normalisedTargetYaw >= 180.0F) { if (normalisedTargetYaw >= 180.0F) {
normalisedTargetYaw -= 360.0F; normalisedTargetYaw -= 360.0F;
@ -177,7 +179,7 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
if (npc.getEntity().getType() != EntityType.ENDER_DRAGON) { if (npc.getEntity().getType() != EntityType.ENDER_DRAGON) {
NMS.setVerticalMovement(npc.getEntity(), 0.5); NMS.setVerticalMovement(npc.getEntity(), 0.5);
NMS.setHeadYaw(npc.getEntity(), current.getYaw() + normalisedTargetYaw); Util.faceLocation(npc.getEntity(), centeredDest.toLocation(npc.getEntity().getWorld()));
} }
parameters.run(); parameters.run();
plan.run(npc); plan.run(npc);

View File

@ -164,9 +164,11 @@ public class NMS {
return null; return null;
} }
private static Field getFirstFieldMatchingType(Class<?> clazz, Class<?> type) { private static Field getFirstFieldMatchingType(Class<?> clazz, Class<?> type, boolean allowStatic) {
Field found = null; Field found = null;
for (Field field : clazz.getDeclaredFields()) { for (Field field : clazz.getDeclaredFields()) {
if (allowStatic ^ Modifier.isStatic(field.getModifiers()))
continue;
if (field.getType() == type) { if (field.getType() == type) {
found = field; found = field;
break; break;
@ -180,7 +182,7 @@ public class NMS {
public static MethodHandle getFirstGetter(Class<?> clazz, Class<?> type) { public static MethodHandle getFirstGetter(Class<?> clazz, Class<?> type) {
try { try {
Field found = getFirstFieldMatchingType(clazz, type); Field found = getFirstFieldMatchingType(clazz, type, false);
if (found == null) if (found == null)
return null; return null;
return LOOKUP.unreflectGetter(found); return LOOKUP.unreflectGetter(found);
@ -223,7 +225,7 @@ public class NMS {
public static MethodHandle getFirstSetter(Class<?> clazz, Class<?> type) { public static MethodHandle getFirstSetter(Class<?> clazz, Class<?> type) {
try { try {
Field found = getFirstFieldMatchingType(clazz, type); Field found = getFirstFieldMatchingType(clazz, type, false);
if (found == null) if (found == null)
return null; return null;
return LOOKUP.unreflectSetter(found); return LOOKUP.unreflectSetter(found);
@ -233,6 +235,18 @@ public class NMS {
return null; return null;
} }
public static MethodHandle getFirstStaticGetter(Class<?> clazz, Class<?> type) {
try {
Field found = getFirstFieldMatchingType(clazz, type, true);
if (found == null)
return null;
return LOOKUP.unreflectGetter(found);
} catch (Exception e) {
Messaging.logTr(Messages.ERROR_GETTING_FIELD, type, e.getLocalizedMessage());
}
return null;
}
public static GameProfileRepository getGameProfileRepository() { public static GameProfileRepository getGameProfileRepository() {
return BRIDGE.getGameProfileRepository(); return BRIDGE.getGameProfileRepository();
} }

View File

@ -31,6 +31,7 @@ import net.citizensnpcs.nms.v1_17_R1.network.EmptyNetHandler;
import net.citizensnpcs.nms.v1_17_R1.network.EmptyNetworkManager; import net.citizensnpcs.nms.v1_17_R1.network.EmptyNetworkManager;
import net.citizensnpcs.nms.v1_17_R1.network.EmptySocket; import net.citizensnpcs.nms.v1_17_R1.network.EmptySocket;
import net.citizensnpcs.nms.v1_17_R1.util.EmptyAdvancementDataPlayer; import net.citizensnpcs.nms.v1_17_R1.util.EmptyAdvancementDataPlayer;
import net.citizensnpcs.nms.v1_17_R1.util.EmptyServerStatsCounter;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerControllerJump; import net.citizensnpcs.nms.v1_17_R1.util.PlayerControllerJump;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerLookControl; import net.citizensnpcs.nms.v1_17_R1.util.PlayerLookControl;
@ -55,6 +56,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.ServerPlayerGameMode; import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.EquipmentSlot;
@ -72,17 +74,18 @@ import net.minecraft.world.level.pathfinder.BlockPathTypes;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity { public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity {
private final Map<BlockPathTypes, Float> bz = Maps.newEnumMap(BlockPathTypes.class);
private PlayerControllerJump controllerJump; private PlayerControllerJump controllerJump;
private PlayerLookControl controllerLook; private PlayerLookControl controllerLook;
private PlayerMoveControl controllerMove; private PlayerMoveControl controllerMove;
private final Map<EquipmentSlot, ItemStack> equipmentCache = Maps.newEnumMap(EquipmentSlot.class); private final Map<EquipmentSlot, ItemStack> equipmentCache = Maps.newEnumMap(EquipmentSlot.class);
private int jumpTicks = 0; private int jumpTicks = 0;
private final Map<BlockPathTypes, Float> malus = Maps.newEnumMap(BlockPathTypes.class);
private PlayerNavigation navigation; private PlayerNavigation navigation;
private final CitizensNPC npc; private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0); private final Location packetLocationCache = new Location(null, 0, 0, 0);
private PlayerlistTracker playerlistTracker; private PlayerlistTracker playerlistTracker;
private final SkinPacketTracker skinTracker; private final SkinPacketTracker skinTracker;
private EmptyServerStatsCounter statsCache;
private int updateCounter = 0; private int updateCounter = 0;
public EntityHumanNPC(MinecraftServer minecraftServer, ServerLevel world, GameProfile gameProfile, NPC npc) { public EntityHumanNPC(MinecraftServer minecraftServer, ServerLevel world, GameProfile gameProfile, NPC npc) {
@ -166,17 +169,19 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
super.doTick(); super.doTick();
return; return;
} }
super.tick(); super.baseTick();
boolean navigating = npc.getNavigator().isNavigating(); boolean navigating = npc.getNavigator().isNavigating();
if (!navigating && getBukkitEntity() != null if (!navigating && getBukkitEntity() != null
&& (!npc.hasTrait(Gravity.class) || npc.getOrAddTrait(Gravity.class).hasGravity()) && (!npc.hasTrait(Gravity.class) || npc.getOrAddTrait(Gravity.class).hasGravity())
&& Util.isLoaded(getBukkitEntity().getLocation(LOADED_LOCATION))) { && Util.isLoaded(getBukkitEntity().getLocation(LOADED_LOCATION))) {
travel(new Vec3(0, 0, 0)); travel(Vec3.ZERO);
} }
Vec3 mot = getDeltaMovement(); Vec3 mot = getDeltaMovement();
if (Math.abs(mot.x) < EPSILON && Math.abs(mot.y) < EPSILON && Math.abs(mot.z) < EPSILON) { if (Math.abs(mot.x) < EPSILON && Math.abs(mot.y) < EPSILON && Math.abs(mot.z) < EPSILON) {
setDeltaMovement(new Vec3(0, 0, 0)); setDeltaMovement(Vec3.ZERO);
} }
if (navigating) { if (navigating) {
if (!NMSImpl.isNavigationFinished(navigation)) { if (!NMSImpl.isNavigationFinished(navigation)) {
NMSImpl.updateNavigation(navigation); NMSImpl.updateNavigation(navigation);
@ -194,8 +199,9 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
this.hurtTime--; this.hurtTime--;
if (this.invulnerableTime > 0) if (this.invulnerableTime > 0)
this.invulnerableTime--; this.invulnerableTime--;
if (isDeadOrDying()) if (isDeadOrDying()) {
tickDeath(); tickDeath();
}
if (this.lastHurtByPlayerTime > 0) { if (this.lastHurtByPlayerTime > 0) {
this.lastHurtByPlayerTime--; this.lastHurtByPlayerTime--;
} else { } else {
@ -250,7 +256,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} }
public float getPathfindingMalus(BlockPathTypes pathtype) { public float getPathfindingMalus(BlockPathTypes pathtype) {
return this.bz.containsKey(pathtype) ? this.bz.get(pathtype) : pathtype.getMalus(); return this.malus.containsKey(pathtype) ? this.malus.get(pathtype) : pathtype.getMalus();
} }
@Override @Override
@ -272,6 +278,11 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return skinTracker; return skinTracker;
} }
@Override
public ServerStatsCounter getStats() {
return this.statsCache == null ? statsCache = new EmptyServerStatsCounter() : statsCache;
}
@Override @Override
public Component getTabListDisplayName() { public Component getTabListDisplayName() {
if (Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean()) { if (Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean()) {
@ -419,7 +430,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} }
public void setPathfindingMalus(BlockPathTypes pathtype, float f) { public void setPathfindingMalus(BlockPathTypes pathtype, float f) {
this.bz.put(pathtype, f); this.malus.put(pathtype, f);
} }
public void setShouldJump() { public void setShouldJump() {

View File

@ -0,0 +1,66 @@
package net.citizensnpcs.nms.v1_17_R1.util;
import java.util.Collections;
import java.util.Set;
import com.google.common.base.Optional;
import com.google.gson.JsonObject;
import com.mojang.datafixers.DataFixer;
import net.citizensnpcs.api.CitizensAPI;
import net.minecraft.SharedConstants;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.stats.Stat;
import net.minecraft.stats.StatType;
import net.minecraft.world.entity.player.Player;
public class EmptyServerStatsCounter extends ServerStatsCounter {
public EmptyServerStatsCounter() {
super(null, CitizensAPI.getDataFolder());
}
private Set<Stat<?>> getDirty() {
return Collections.EMPTY_SET;
}
private <T> Optional<Stat<T>> getStat(StatType<T> statisticwrapper, String s) {
return Optional.absent();
}
@Override
public void markAllDirty() {
}
@Override
public void parseLocal(DataFixer datafixer, String s) {
}
@Override
public void save() {
}
@Override
public void sendStats(ServerPlayer entityplayer) {
}
@Override
public void setValue(Player entityhuman, Stat<?> statistic, int i) {
}
@Override
protected String toJson() {
return "{\"stats\":{},\"DataVersion\":" + Integer.valueOf(SharedConstants.getCurrentVersion().getWorldVersion())
+ "}";
}
private static CompoundTag fromJson(JsonObject jsonobject) {
return new CompoundTag();
}
private static <T> ResourceLocation getKey(Stat<T> statistic) {
return statistic.getType().getRegistry().getKey(statistic.getValue());
}
}

View File

@ -1920,7 +1920,7 @@ public class NMSImpl implements NMSBridge {
} }
try { try {
RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor<Integer>) NMS RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor<Integer>) NMS
.getFirstGetter(Rabbit.class, EntityDataAccessor.class).invoke(); .getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke();
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -14,8 +14,9 @@ import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.monster.Slime; import net.minecraft.world.entity.monster.Slime;
public class PlayerMoveControl extends MoveControl { public class PlayerMoveControl extends MoveControl {
protected LivingEntity a; protected LivingEntity entity;
private int jumpTicks; private int jumpTicks;
private int keepMovingTicks;
protected boolean moving; protected boolean moving;
protected double speed; protected double speed;
protected double tx; protected double tx;
@ -25,7 +26,7 @@ public class PlayerMoveControl extends MoveControl {
public PlayerMoveControl(LivingEntity entityinsentient) { public PlayerMoveControl(LivingEntity entityinsentient) {
super(entityinsentient instanceof Mob ? (Mob) entityinsentient super(entityinsentient instanceof Mob ? (Mob) entityinsentient
: new Slime(EntityType.SLIME, entityinsentient.level)); : new Slime(EntityType.SLIME, entityinsentient.level));
this.a = entityinsentient; this.entity = entityinsentient;
this.tx = entityinsentient.getX(); this.tx = entityinsentient.getX();
this.ty = entityinsentient.getY(); this.ty = entityinsentient.getY();
this.tz = entityinsentient.getZ(); this.tz = entityinsentient.getZ();
@ -90,10 +91,11 @@ public class PlayerMoveControl extends MoveControl {
this.tz = d2; this.tz = d2;
this.speed = d3; this.speed = d3;
this.moving = true; this.moving = true;
this.keepMovingTicks = 1;
} }
private boolean shouldJump() { private boolean shouldJump() {
if (!(this.a instanceof Slime)) { if (!(this.entity instanceof Slime)) {
return false; return false;
} }
if (this.jumpTicks-- <= 0) { if (this.jumpTicks-- <= 0) {
@ -104,32 +106,32 @@ public class PlayerMoveControl extends MoveControl {
@Override @Override
public void tick() { public void tick() {
this.a.zza = 0; this.entity.zza = 0;
if (this.moving) { if (this.moving) {
this.moving = false; this.moving = false;
double dX = this.tx - this.a.getX(); double dX = this.tx - this.entity.getX();
double dZ = this.tz - this.a.getZ(); double dZ = this.tz - this.entity.getZ();
double dY = this.ty - this.a.getY(); double dY = this.ty - this.entity.getY();
double dXZ = dY * dY + dZ * dZ; double dXZ = dX * dX + dZ * dZ;
if (dY * dY < 1.0 && dXZ < 0.005) { if (dY * dY < 1.0 && dXZ < 0.005) {
this.a.zza = 0.0F; this.entity.zza = 0.0F;
return; return;
} }
float f = (float) (Mth.atan2(dZ, dX) * 57.2957763671875D) - 90.0F; float f = (float) (Mth.atan2(dZ, dX) * 57.2957763671875D) - 90.0F;
this.a.setYRot(rotlerp(this.a.getYRot(), f, 90.0F)); this.entity.setYRot(rotlerp(this.entity.getYRot(), f, 90.0F));
NMS.setHeadYaw(a.getBukkitEntity(), this.a.getYRot()); NMS.setHeadYaw(entity.getBukkitEntity(), this.entity.getYRot());
AttributeInstance speed = this.a.getAttribute(Attributes.MOVEMENT_SPEED); AttributeInstance speed = this.entity.getAttribute(Attributes.MOVEMENT_SPEED);
speed.setBaseValue(0.3D * this.speed); speed.setBaseValue(0.3D * this.speed);
float movement = (float) (this.speed * speed.getValue()); float movement = (float) (this.speed * speed.getValue());
this.a.setSpeed(movement); this.entity.setSpeed(movement);
this.a.zza = movement; this.entity.zza = movement;
if (shouldJump() || (dY >= NMS.getStepHeight(a.getBukkitEntity()) && dXZ < 1.0D)) { if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 1.0D)) {
this.jumpTicks = jumpTicks(); this.jumpTicks = jumpTicks();
this.jumpTicks /= 3; this.jumpTicks /= 3;
if (this.a instanceof EntityHumanNPC) { if (this.entity instanceof EntityHumanNPC) {
((EntityHumanNPC) this.a).getControllerJump().jump(); ((EntityHumanNPC) this.entity).getControllerJump().jump();
} else { } else {
((Mob) this.a).getJumpControl().jump(); ((Mob) this.entity).getJumpControl().jump();
} }
} }
} }