diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java b/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java index 9d14b0d39..45583ea4c 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java @@ -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); diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/FlyingAStarNavigationStrategy.java b/main/src/main/java/net/citizensnpcs/npc/ai/FlyingAStarNavigationStrategy.java index ba59eb5c1..abd8ddc96 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/FlyingAStarNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/FlyingAStarNavigationStrategy.java @@ -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); diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index 3cedb51b1..81d3ab91d 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -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(); } diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/entity/EntityHumanNPC.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/entity/EntityHumanNPC.java index 0a16c6835..be81e6c22 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/entity/EntityHumanNPC.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/entity/EntityHumanNPC.java @@ -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 bz = Maps.newEnumMap(BlockPathTypes.class); private PlayerControllerJump controllerJump; private PlayerLookControl controllerLook; private PlayerMoveControl controllerMove; private final Map equipmentCache = Maps.newEnumMap(EquipmentSlot.class); private int jumpTicks = 0; + private final Map 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() { diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/EmptyServerStatsCounter.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/EmptyServerStatsCounter.java new file mode 100644 index 000000000..72343fc81 --- /dev/null +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/EmptyServerStatsCounter.java @@ -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> getDirty() { + return Collections.EMPTY_SET; + } + + private Optional> getStat(StatType 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 ResourceLocation getKey(Stat statistic) { + return statistic.getType().getRegistry().getKey(statistic.getValue()); + } +} diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java index aec02d8f0..d17a6ab67 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java @@ -1920,7 +1920,7 @@ public class NMSImpl implements NMSBridge { } try { RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor) NMS - .getFirstGetter(Rabbit.class, EntityDataAccessor.class).invoke(); + .getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke(); } catch (Throwable e) { e.printStackTrace(); } diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerMoveControl.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerMoveControl.java index 8d80a5fc4..42cf06d4d 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerMoveControl.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerMoveControl.java @@ -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(); } } }