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

@ -137,7 +137,7 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
Location currLoc = npc.getEntity().getLocation(NPC_LOCATION);
Vector destVector = new Vector(vector.getX() + 0.5, vector.getY(), vector.getZ() + 0.5);
/* Proper door movement - gets stuck on corners at times
Block block = currLoc.getWorld().getBlockAt(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
if (MinecraftBlockExaminer.isDoor(block.getType())) {
Door door = (Door) block.getState().getData();
@ -175,8 +175,8 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
|| (dY >= 0.2 && MinecraftBlockExaminer.isLiquidOrInLiquid(in))) {
dir.add(new Vector(0, 0.75, 0));
}
Util.faceLocation(npc.getEntity(), destVector.toLocation(npc.getEntity().getWorld()));
npc.getEntity().setVelocity(dir);
Util.faceLocation(npc.getEntity(), destVector.toLocation(npc.getEntity().getWorld()));
}
params.run();
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.util.NMS;
import net.citizensnpcs.util.PlayerAnimation;
import net.citizensnpcs.util.Util;
public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
private int iterations;
@ -153,9 +154,10 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
}
}
double d0 = vector.getX() + 0.5D - current.getX();
double d1 = vector.getY() + 0.1D - current.getY();
double d2 = vector.getZ() + 0.5D - current.getZ();
Vector centeredDest = new Vector(vector.getX() + 0.5D, vector.getY() + 0.1D, vector.getZ() + 0.5D);
double d0 = centeredDest.getX() - current.getX();
double d1 = centeredDest.getY() - current.getY();
double d2 = centeredDest.getZ() - current.getZ();
Vector velocity = npc.getEntity().getVelocity();
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());
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;
if (normalisedTargetYaw >= 180.0F) {
normalisedTargetYaw -= 360.0F;
@ -177,7 +179,7 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
if (npc.getEntity().getType() != EntityType.ENDER_DRAGON) {
NMS.setVerticalMovement(npc.getEntity(), 0.5);
NMS.setHeadYaw(npc.getEntity(), current.getYaw() + normalisedTargetYaw);
Util.faceLocation(npc.getEntity(), centeredDest.toLocation(npc.getEntity().getWorld()));
}
parameters.run();
plan.run(npc);

View File

@ -164,9 +164,11 @@ public class NMS {
return null;
}
private static Field getFirstFieldMatchingType(Class<?> clazz, Class<?> type) {
private static Field getFirstFieldMatchingType(Class<?> clazz, Class<?> type, boolean allowStatic) {
Field found = null;
for (Field field : clazz.getDeclaredFields()) {
if (allowStatic ^ Modifier.isStatic(field.getModifiers()))
continue;
if (field.getType() == type) {
found = field;
break;
@ -180,7 +182,7 @@ public class NMS {
public static MethodHandle getFirstGetter(Class<?> clazz, Class<?> type) {
try {
Field found = getFirstFieldMatchingType(clazz, type);
Field found = getFirstFieldMatchingType(clazz, type, false);
if (found == null)
return null;
return LOOKUP.unreflectGetter(found);
@ -223,7 +225,7 @@ public class NMS {
public static MethodHandle getFirstSetter(Class<?> clazz, Class<?> type) {
try {
Field found = getFirstFieldMatchingType(clazz, type);
Field found = getFirstFieldMatchingType(clazz, type, false);
if (found == null)
return null;
return LOOKUP.unreflectSetter(found);
@ -233,6 +235,18 @@ public class NMS {
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() {
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.EmptySocket;
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.PlayerControllerJump;
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.ServerPlayer;
import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
@ -72,17 +74,18 @@ import net.minecraft.world.level.pathfinder.BlockPathTypes;
import net.minecraft.world.phys.Vec3;
public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity {
private final Map<BlockPathTypes, Float> bz = Maps.newEnumMap(BlockPathTypes.class);
private PlayerControllerJump controllerJump;
private PlayerLookControl controllerLook;
private PlayerMoveControl controllerMove;
private final Map<EquipmentSlot, ItemStack> equipmentCache = Maps.newEnumMap(EquipmentSlot.class);
private int jumpTicks = 0;
private final Map<BlockPathTypes, Float> malus = Maps.newEnumMap(BlockPathTypes.class);
private PlayerNavigation navigation;
private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0);
private PlayerlistTracker playerlistTracker;
private final SkinPacketTracker skinTracker;
private EmptyServerStatsCounter statsCache;
private int updateCounter = 0;
public EntityHumanNPC(MinecraftServer minecraftServer, ServerLevel world, GameProfile gameProfile, NPC npc) {
@ -166,17 +169,19 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
super.doTick();
return;
}
super.tick();
super.baseTick();
boolean navigating = npc.getNavigator().isNavigating();
if (!navigating && getBukkitEntity() != null
&& (!npc.hasTrait(Gravity.class) || npc.getOrAddTrait(Gravity.class).hasGravity())
&& Util.isLoaded(getBukkitEntity().getLocation(LOADED_LOCATION))) {
travel(new Vec3(0, 0, 0));
travel(Vec3.ZERO);
}
Vec3 mot = getDeltaMovement();
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 (!NMSImpl.isNavigationFinished(navigation)) {
NMSImpl.updateNavigation(navigation);
@ -194,8 +199,9 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
this.hurtTime--;
if (this.invulnerableTime > 0)
this.invulnerableTime--;
if (isDeadOrDying())
if (isDeadOrDying()) {
tickDeath();
}
if (this.lastHurtByPlayerTime > 0) {
this.lastHurtByPlayerTime--;
} else {
@ -250,7 +256,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
}
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
@ -272,6 +278,11 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return skinTracker;
}
@Override
public ServerStatsCounter getStats() {
return this.statsCache == null ? statsCache = new EmptyServerStatsCounter() : statsCache;
}
@Override
public Component getTabListDisplayName() {
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) {
this.bz.put(pathtype, f);
this.malus.put(pathtype, f);
}
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 {
RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor<Integer>) NMS
.getFirstGetter(Rabbit.class, EntityDataAccessor.class).invoke();
.getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke();
} catch (Throwable e) {
e.printStackTrace();
}

View File

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