mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2025-02-16 20:31:30 +01:00
Fix bugs including 1.17.1 player movement, flying yaw and stats incompatibility on 1.17.1
This commit is contained in:
parent
3e1132034e
commit
53e2b50ce8
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user