Refactoring to allow armor stands to move

This commit is contained in:
fullwall 2023-03-19 21:48:40 +08:00
parent f269019d56
commit 9cff1afb28
20 changed files with 369 additions and 220 deletions

View File

@ -9,6 +9,8 @@ import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.MobAI;
import net.citizensnpcs.nms.v1_19_R3.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
@ -45,7 +47,8 @@ public class ArmorStandController extends MobEntityController {
} }
} }
public static class EntityArmorStandNPC extends ArmorStand implements NPCHolder { public static class EntityArmorStandNPC extends ArmorStand implements NPCHolder, ForwardingMobAI {
private MobAI ai;
private final CitizensNPC npc; private final CitizensNPC npc;
public EntityArmorStandNPC(EntityType<? extends ArmorStand> types, Level level) { public EntityArmorStandNPC(EntityType<? extends ArmorStand> types, Level level) {
@ -55,6 +58,14 @@ public class ArmorStandController extends MobEntityController {
public EntityArmorStandNPC(EntityType<? extends ArmorStand> types, Level level, NPC npc) { public EntityArmorStandNPC(EntityType<? extends ArmorStand> types, Level level, NPC npc) {
super(types, level); super(types, level);
this.npc = (CitizensNPC) npc; this.npc = (CitizensNPC) npc;
if (npc != null) {
ai = new BasicMobAI(this);
}
}
@Override
public MobAI getAI() {
return ai;
} }
@Override @Override
@ -127,6 +138,7 @@ public class ArmorStandController extends MobEntityController {
super.tick(); super.tick();
if (npc != null) { if (npc != null) {
npc.update(); npc.update();
ai.tickAI();
} }
} }

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
@ -126,7 +126,7 @@ public class CodController extends MobEntityController {
this.moveControl = this.oldMoveController; this.moveControl = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
} }
super.customServerAiStep(); super.customServerAiStep();

View File

@ -15,7 +15,6 @@ import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
@ -32,10 +31,9 @@ import net.citizensnpcs.nms.v1_19_R3.network.EmptyNetHandler;
import net.citizensnpcs.nms.v1_19_R3.network.EmptyNetworkManager; import net.citizensnpcs.nms.v1_19_R3.network.EmptyNetworkManager;
import net.citizensnpcs.nms.v1_19_R3.util.EmptyAdvancementDataPlayer; import net.citizensnpcs.nms.v1_19_R3.util.EmptyAdvancementDataPlayer;
import net.citizensnpcs.nms.v1_19_R3.util.EmptyServerStatsCounter; import net.citizensnpcs.nms.v1_19_R3.util.EmptyServerStatsCounter;
import net.citizensnpcs.nms.v1_19_R3.util.MobAI;
import net.citizensnpcs.nms.v1_19_R3.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerControllerJump;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerNavigation;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.npc.skin.SkinPacketTracker; import net.citizensnpcs.npc.skin.SkinPacketTracker;
@ -62,27 +60,17 @@ import net.minecraft.tags.TagKey;
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;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.AttributeMap;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType; import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
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, ForwardingMobAI {
private PlayerControllerJump controllerJump; private MobAI ai;
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 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 boolean setBukkitEntity; private boolean setBukkitEntity;
@ -93,6 +81,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
super(minecraftServer, world, gameProfile); super(minecraftServer, world, gameProfile);
this.npc = (CitizensNPC) npc; this.npc = (CitizensNPC) npc;
if (npc != null) { if (npc != null) {
ai = new BasicMobAI(this);
skinTracker = new SkinPacketTracker(this); skinTracker = new SkinPacketTracker(this);
try { try {
GAMEMODE_SETTING.invoke(gameMode, GameType.SURVIVAL, null); GAMEMODE_SETTING.invoke(gameMode, GameType.SURVIVAL, null);
@ -105,11 +94,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} }
} }
public boolean canCutCorner(BlockPathTypes pathtype) {
return (pathtype != BlockPathTypes.DANGER_FIRE && pathtype != BlockPathTypes.DANGER_POWDER_SNOW
&& pathtype != BlockPathTypes.DANGER_OTHER && pathtype != BlockPathTypes.WALKABLE_DOOR);
}
@Override @Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) { public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) { if (npc == null || !npc.isFlyable()) {
@ -149,7 +133,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return; return;
} }
super.baseTick(); super.baseTick();
boolean navigating = npc.getNavigator().isNavigating() || controllerMove.hasWanted(); boolean navigating = npc.getNavigator().isNavigating() || ai.getMoveControl().hasWanted();
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))
@ -161,12 +145,12 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
setDeltaMovement(Vec3.ZERO); setDeltaMovement(Vec3.ZERO);
} }
if (navigating) { if (navigating) {
if (!navigation.isDone()) { if (!ai.getNavigation().isDone()) {
navigation.tick(); ai.getNavigation().tick();
} }
moveOnCurrentHeading(); moveOnCurrentHeading();
} }
updateAI(); tickAI();
if (isSpectator()) { if (isSpectator()) {
this.noPhysics = true; this.noPhysics = true;
this.onGround = false; this.onGround = false;
@ -187,6 +171,11 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} }
} }
@Override
public MobAI getAI() {
return ai;
}
@Override @Override
public CraftPlayer getBukkitEntity() { public CraftPlayer getBukkitEntity() {
if (npc != null && !setBukkitEntity) { if (npc != null && !setBukkitEntity) {
@ -196,10 +185,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return super.getBukkitEntity(); return super.getBukkitEntity();
} }
public PlayerControllerJump getControllerJump() {
return controllerJump;
}
@Override @Override
protected SoundEvent getDeathSound() { protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND); return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
@ -210,23 +195,11 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND); return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
} }
public PlayerMoveControl getMoveControl() {
return controllerMove;
}
public PathNavigation getNavigation() {
return navigation;
}
@Override @Override
public NPC getNPC() { public NPC getNPC() {
return npc; return npc;
} }
public float getPathfindingMalus(BlockPathTypes pathtype) {
return this.malus.containsKey(pathtype) ? this.malus.get(pathtype) : pathtype.getMalus();
}
@Override @Override
public GameProfile getProfile() { public GameProfile getProfile() {
return super.getGameProfile(); return super.getGameProfile();
@ -288,27 +261,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} catch (IOException e) { } catch (IOException e) {
// swallow // swallow
} }
AttributeInstance range = getAttribute(Attributes.FOLLOW_RANGE);
if (range == null) {
try {
AttributeSupplier provider = (AttributeSupplier) ATTRIBUTE_SUPPLIER.invoke(getAttributes());
Map<Attribute, AttributeInstance> all = Maps
.newHashMap((Map<Attribute, AttributeInstance>) ATTRIBUTE_PROVIDER_MAP.invoke(provider));
all.put(Attributes.FOLLOW_RANGE, new AttributeInstance(Attributes.FOLLOW_RANGE, att -> {
throw new UnsupportedOperationException(
"Tried to change value for default attribute instance FOLLOW_RANGE");
}));
ATTRIBUTE_PROVIDER_MAP_SETTER.invoke(provider, ImmutableMap.copyOf(all));
} catch (Throwable e) {
e.printStackTrace();
}
range = getAttribute(Attributes.FOLLOW_RANGE);
}
getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.3D);
range.setBaseValue(Setting.DEFAULT_PATHFINDING_RANGE.asDouble());
controllerJump = new PlayerControllerJump(this);
controllerMove = new PlayerMoveControl(this);
navigation = new PlayerNavigation(this, level);
this.invulnerableTime = 0; this.invulnerableTime = 0;
NMS.setStepHeight(getBukkitEntity(), 1); // the default (0) breaks step climbing NMS.setStepHeight(getBukkitEntity(), 1); // the default (0) breaks step climbing
setSkinFlags((byte) 0xFF); setSkinFlags((byte) 0xFF);
@ -326,10 +278,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return Util.inBlock(getBukkitEntity()); return Util.inBlock(getBukkitEntity());
} }
public boolean isNavigating() {
return npc.getNavigator().isNavigating();
}
@Override @Override
public boolean isPushable() { public boolean isPushable() {
return npc == null ? super.isPushable() : npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected()); return npc == null ? super.isPushable() : npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
@ -404,18 +352,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
getAdvancements().save(); getAdvancements().save();
} }
public void setMoveDestination(double x, double y, double z, double speed) {
controllerMove.setWantedPosition(x, y, z, speed);
}
public void setPathfindingMalus(BlockPathTypes pathtype, float f) {
malus.put(pathtype, f);
}
public void setShouldJump() {
controllerJump.jump();
}
@Override @Override
public void setSkinFlags(byte flags) { public void setSkinFlags(byte flags) {
getEntityData().set(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION, flags); getEntityData().set(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION, flags);
@ -447,6 +383,12 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
npc.update(); npc.update();
} }
@Override
public void tickAI() {
ai.getMoveControl().tick();
ai.getJumpControl().tick();
}
@Override @Override
public void travel(Vec3 vec3d) { public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) { if (npc == null || !npc.isFlyable()) {
@ -456,11 +398,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} }
} }
public void updateAI() {
controllerMove.tick();
controllerJump.tick();
}
@Override @Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) { public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
Vec3 old = getDeltaMovement().add(0, 0, 0); Vec3 old = getDeltaMovement().add(0, 0, 0);
@ -495,10 +432,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
NMSImpl.sendPacketsNearby(getBukkitEntity(), getBukkitEntity().getLocation(packetLocationCache), packets); NMSImpl.sendPacketsNearby(getBukkitEntity(), getBukkitEntity().getLocation(packetLocationCache), packets);
} }
public void updatePathfindingRange(float pathfindingRange) {
this.navigation.setRange(pathfindingRange);
}
public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity { public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity {
private final CitizensNPC npc; private final CitizensNPC npc;
@ -582,10 +515,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} }
} }
private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getFirstGetter(AttributeSupplier.class, Map.class);
private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeSupplier.class, "a");
private static final MethodHandle ATTRIBUTE_SUPPLIER = NMS.getFirstGetter(AttributeMap.class,
AttributeSupplier.class);
private static final float EPSILON = 0.003F; private static final float EPSILON = 0.003F;
private static final MethodHandle GAMEMODE_SETTING = NMS.getFirstMethodHandle(ServerPlayerGameMode.class, true, private static final MethodHandle GAMEMODE_SETTING = NMS.getFirstMethodHandle(ServerPlayerGameMode.class, true,
GameType.class, GameType.class); GameType.class, GameType.class);

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
@ -60,7 +60,7 @@ public class MagmaCubeController extends MobEntityController {
if (npc != null) { if (npc != null) {
setSize(3, true); setSize(3, true);
this.oldMoveController = this.moveControl; this.oldMoveController = this.moveControl;
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
} }
@ -214,7 +214,7 @@ public class MagmaCubeController extends MobEntityController {
this.moveControl = this.oldMoveController; this.moveControl = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
npc.update(); npc.update();
} }

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
@ -78,7 +78,7 @@ public class PhantomController extends MobEntityController {
this.lookControl = this.oldLookController; this.lookControl = this.oldLookController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
this.lookControl = new LookControl(this); this.lookControl = new LookControl(this);
} }
if (npc.isProtected()) { if (npc.isProtected()) {

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.versioned.PufferFishTrait; import net.citizensnpcs.trait.versioned.PufferFishTrait;
@ -124,7 +124,7 @@ public class PufferFishController extends MobEntityController {
this.moveControl = this.oldMoveController; this.moveControl = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
npc.update(); npc.update();
} }

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
@ -118,7 +118,7 @@ public class SalmonController extends MobEntityController {
this.moveControl = this.oldMoveController; this.moveControl = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
} }
super.customServerAiStep(); super.customServerAiStep();

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
@ -60,7 +60,7 @@ public class SlimeController extends MobEntityController {
if (npc != null) { if (npc != null) {
setSize(3, true); setSize(3, true);
this.oldMoveController = this.moveControl; this.oldMoveController = this.moveControl;
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
} }
@ -215,7 +215,7 @@ public class SlimeController extends MobEntityController {
this.moveControl = this.oldMoveController; this.moveControl = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
npc.update(); npc.update();
} }

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
@ -118,7 +118,7 @@ public class TadpoleController extends MobEntityController {
this.moveControl = this.oldMoveController; this.moveControl = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
} }
super.customServerAiStep(); super.customServerAiStep();

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
@ -120,7 +120,7 @@ public class TropicalFishController extends MobEntityController {
this.moveControl = this.oldMoveController; this.moveControl = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
} }
super.customServerAiStep(); super.customServerAiStep();

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
@ -107,7 +107,7 @@ public class TurtleController extends MobEntityController {
this.jumpControl = this.oldJumpController; this.jumpControl = this.oldJumpController;
} }
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
this.jumpControl = new EmptyControllerJump(this); this.jumpControl = new EmptyControllerJump(this);
} }
npc.update(); npc.update();

View File

@ -0,0 +1,27 @@
package net.citizensnpcs.nms.v1_19_R3.util;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.control.JumpControl;
import net.minecraft.world.entity.monster.Slime;
public class EntityJumpControl extends JumpControl {
private boolean a;
private final LivingEntity b;
public EntityJumpControl(LivingEntity entity) {
super(new Slime(EntityType.SLIME, entity.level));
this.b = entity;
}
@Override
public void jump() {
this.a = true;
}
@Override
public void tick() {
this.b.setJumping(this.a);
this.a = false;
}
}

View File

@ -2,7 +2,6 @@ package net.citizensnpcs.nms.v1_19_R3.util;
import java.util.Random; import java.util.Random;
import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
@ -12,7 +11,7 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.control.MoveControl; 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 EntityMoveControl extends MoveControl {
protected LivingEntity entity; protected LivingEntity entity;
private int jumpTicks; private int jumpTicks;
protected boolean moving; protected boolean moving;
@ -21,7 +20,7 @@ public class PlayerMoveControl extends MoveControl {
protected double ty; protected double ty;
protected double tz; protected double tz;
public PlayerMoveControl(LivingEntity entityinsentient) { public EntityMoveControl(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.entity = entityinsentient; this.entity = entityinsentient;
@ -120,11 +119,7 @@ public class PlayerMoveControl extends MoveControl {
if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 0.4D)) { if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 0.4D)) {
this.jumpTicks = jumpTicks(); this.jumpTicks = jumpTicks();
this.jumpTicks /= 3; this.jumpTicks /= 3;
if (this.entity instanceof EntityHumanNPC) { entity.setJumping(true);
((EntityHumanNPC) this.entity).getControllerJump().jump();
} else {
((Mob) this.entity).getJumpControl().jump();
}
} }
} }
} }

View File

@ -7,17 +7,17 @@ import java.util.stream.Stream;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import net.citizensnpcs.Settings; import net.citizensnpcs.Settings;
import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i; import net.minecraft.core.Vec3i;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.monster.Slime;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.PathNavigationRegion; import net.minecraft.world.level.PathNavigationRegion;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
@ -29,7 +29,7 @@ import net.minecraft.world.level.pathfinder.Path;
import net.minecraft.world.level.pathfinder.PathFinder; import net.minecraft.world.level.pathfinder.PathFinder;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
public class PlayerNavigation extends PathNavigation { public class EntityNavigation extends PathNavigation {
private boolean avoidSun; private boolean avoidSun;
private final AttributeInstance followRange; private final AttributeInstance followRange;
protected boolean hasDelayedRecomputation; protected boolean hasDelayedRecomputation;
@ -37,13 +37,13 @@ public class PlayerNavigation extends PathNavigation {
protected int lastStuckCheck; protected int lastStuckCheck;
protected Vec3 lastStuckCheckPos = Vec3.ZERO; protected Vec3 lastStuckCheckPos = Vec3.ZERO;
protected long lastTimeoutCheck; protected long lastTimeoutCheck;
protected final Level level;
protected float maxDistanceToWaypoint = 0.5F; protected float maxDistanceToWaypoint = 0.5F;
private float maxVisitedNodesMultiplier = 1.0F; private float maxVisitedNodesMultiplier = 1.0F;
private final EntityHumanNPC mob; private final LivingEntity mob;
protected PlayerNodeEvaluator nodeEvaluator; private final MobAI mvmt;
protected EntityNodeEvaluator nodeEvaluator;
protected Path path; protected Path path;
private final PlayerPathfinder pathFinder; private final EntityPathfinder pathFinder;
private int reachRange; private int reachRange;
protected double speedModifier; protected double speedModifier;
private BlockPos targetPos; private BlockPos targetPos;
@ -53,17 +53,23 @@ public class PlayerNavigation extends PathNavigation {
protected double timeoutLimit; protected double timeoutLimit;
protected long timeoutTimer; protected long timeoutTimer;
public PlayerNavigation(EntityHumanNPC entityinsentient, Level world) { public EntityNavigation(LivingEntity entityinsentient, Level world) {
super(getDummyInsentient(entityinsentient, world), world); super(new Slime(EntityType.SLIME, world), world);
this.mob = entityinsentient; this.mob = entityinsentient;
this.level = world; this.mvmt = MobAI.from(entityinsentient);
this.followRange = entityinsentient.getAttribute(Attributes.FOLLOW_RANGE); this.followRange = entityinsentient.getAttribute(Attributes.FOLLOW_RANGE);
this.nodeEvaluator = new PlayerNodeEvaluator(); this.nodeEvaluator = new EntityNodeEvaluator();
this.nodeEvaluator.setCanPassDoors(true); this.nodeEvaluator.setCanPassDoors(true);
this.pathFinder = new PlayerPathfinder(this.nodeEvaluator, Settings.Setting.MAXIMUM_VISITED_NODES.asInt()); this.pathFinder = new EntityPathfinder(this.nodeEvaluator, Settings.Setting.MAXIMUM_VISITED_NODES.asInt());
this.setRange(24); this.setRange(24);
} }
@Override
public boolean canCutCorner(BlockPathTypes pathtype) {
return (pathtype != BlockPathTypes.DANGER_FIRE && pathtype != BlockPathTypes.DANGER_POWDER_SNOW
&& pathtype != BlockPathTypes.DANGER_OTHER && pathtype != BlockPathTypes.WALKABLE_DOOR);
}
@Override @Override
public boolean canFloat() { public boolean canFloat() {
return this.nodeEvaluator.canFloat(); return this.nodeEvaluator.canFloat();
@ -148,7 +154,7 @@ public class PlayerNavigation extends PathNavigation {
} }
return true; return true;
} }
private boolean canWalkOn(int var0, int var1, int var2, int var3, int var4, int var5, Vec3 var6, double var7, private boolean canWalkOn(int var0, int var1, int var2, int var3, int var4, int var5, Vec3 var6, double var7,
double var9) { double var9) {
int var11 = var0 - var3 / 2; int var11 = var0 - var3 / 2;
@ -287,7 +293,7 @@ public class PlayerNavigation extends PathNavigation {
double var4 = Math.abs(this.mob.getY() - blockPos.getY()); double var4 = Math.abs(this.mob.getY() - blockPos.getY());
double var6 = Math.abs(this.mob.getZ() - (blockPos.getZ() + 0.5D)); double var6 = Math.abs(this.mob.getZ() - (blockPos.getZ() + 0.5D));
boolean var8 = (var2 < this.maxDistanceToWaypoint && var6 < this.maxDistanceToWaypoint && var4 < 1.0D); boolean var8 = (var2 < this.maxDistanceToWaypoint && var6 < this.maxDistanceToWaypoint && var4 < 1.0D);
if (var8 || (this.mob.canCutCorner((this.path.getNextNode()).type) && shouldTargetNextNodeInDirection(var0))) if (var8 || (canCutCorner((this.path.getNextNode()).type) && shouldTargetNextNodeInDirection(var0)))
this.path.advance(); this.path.advance();
doStuckDetection(var0); doStuckDetection(var0);
} }
@ -538,7 +544,7 @@ public class PlayerNavigation extends PathNavigation {
if (isDone()) if (isDone())
return; return;
Vec3 var0 = this.path.getNextEntityPos(this.mob); Vec3 var0 = this.path.getNextEntityPos(this.mob);
this.mob.getMoveControl().setWantedPosition(var0.x, this.getGroundY(var0), var0.z, this.speedModifier); mvmt.getMoveControl().setWantedPosition(var0.x, this.getGroundY(var0), var0.z, this.speedModifier);
} }
private void timeoutPath() { private void timeoutPath() {
@ -563,9 +569,4 @@ public class PlayerNavigation extends PathNavigation {
} }
} }
} }
private static Mob getDummyInsentient(EntityHumanNPC from, Level world) {
return new Mob(EntityType.VILLAGER, world) {
};
}
} }

View File

@ -7,13 +7,13 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.tags.FluidTags; import net.minecraft.tags.FluidTags;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.PathNavigationRegion; import net.minecraft.world.level.PathNavigationRegion;
@ -36,7 +36,7 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { public class EntityNodeEvaluator extends EntityNodeEvaluatorBase {
private final Object2BooleanMap collisionCache = new Object2BooleanOpenHashMap(); private final Object2BooleanMap collisionCache = new Object2BooleanOpenHashMap();
protected float oldWaterCost; protected float oldWaterCost;
private final Long2ObjectMap pathTypesByPosCache = new Long2ObjectOpenHashMap(); private final Long2ObjectMap pathTypesByPosCache = new Long2ObjectOpenHashMap();
@ -60,12 +60,12 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
protected boolean canStartAt(BlockPos var0) { protected boolean canStartAt(BlockPos var0) {
BlockPathTypes var1 = this.getBlockPathType(this.mob, var0); BlockPathTypes var1 = this.getBlockPathType(this.mob, var0);
return var1 != BlockPathTypes.OPEN && this.mob.getPathfindingMalus(var1) >= 0.0F; return var1 != BlockPathTypes.OPEN && this.mvmt.getPathfindingMalus(var1) >= 0.0F;
} }
@Override @Override
public void done() { public void done() {
this.mob.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost); this.mvmt.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost);
this.pathTypesByPosCache.clear(); this.pathTypesByPosCache.clear();
this.collisionCache.clear(); this.collisionCache.clear();
super.done(); super.done();
@ -98,7 +98,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return null; return null;
} else { } else {
BlockPathTypes var12 = this.getCachedBlockType(this.mob, var0, var1, var2); BlockPathTypes var12 = this.getCachedBlockType(this.mob, var0, var1, var2);
float var13 = this.mob.getPathfindingMalus(var12); float var13 = this.mvmt.getPathfindingMalus(var12);
double var14 = this.mob.getBbWidth() / 2.0; double var14 = this.mob.getBbWidth() / 2.0;
if (var13 >= 0.0F) { if (var13 >= 0.0F) {
var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12, var13); var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12, var13);
@ -147,7 +147,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
} }
var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12, var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12,
this.mob.getPathfindingMalus(var12)); this.mvmt.getPathfindingMalus(var12));
} }
} }
@ -166,7 +166,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
} }
var12 = this.getCachedBlockType(this.mob, var0, var1, var2); var12 = this.getCachedBlockType(this.mob, var0, var1, var2);
var13 = this.mob.getPathfindingMalus(var12); var13 = this.mvmt.getPathfindingMalus(var12);
if (var12 != BlockPathTypes.OPEN && var13 >= 0.0F) { if (var12 != BlockPathTypes.OPEN && var13 >= 0.0F) {
var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12, var13); var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12, var13);
break; break;
@ -202,7 +202,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return getBlockPathTypeStatic(var0, new BlockPos.MutableBlockPos(var1, var2, var3)); return getBlockPathTypeStatic(var0, new BlockPos.MutableBlockPos(var1, var2, var3));
} }
public BlockPathTypes getBlockPathType(BlockGetter var0, int var1, int var2, int var3, EntityHumanNPC var4) { public BlockPathTypes getBlockPathType(BlockGetter var0, int var1, int var2, int var3, LivingEntity var4) {
EnumSet var5 = EnumSet.noneOf(BlockPathTypes.class); EnumSet var5 = EnumSet.noneOf(BlockPathTypes.class);
BlockPathTypes var6 = BlockPathTypes.BLOCKED; BlockPathTypes var6 = BlockPathTypes.BLOCKED;
var6 = this.getBlockPathTypes(var0, var1, var2, var3, var5, var6, var4.blockPosition()); var6 = this.getBlockPathTypes(var0, var1, var2, var3, var5, var6, var4.blockPosition());
@ -216,16 +216,16 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
while (var9.hasNext()) { while (var9.hasNext()) {
BlockPathTypes varr9 = (BlockPathTypes) var9.next(); BlockPathTypes varr9 = (BlockPathTypes) var9.next();
if (var4.getPathfindingMalus(varr9) < 0.0F) { if (mvmt.getPathfindingMalus(varr9) < 0.0F) {
return varr9; return varr9;
} }
if (var4.getPathfindingMalus(varr9) >= var4.getPathfindingMalus(var7)) { if (mvmt.getPathfindingMalus(varr9) >= mvmt.getPathfindingMalus(var7)) {
var7 = varr9; var7 = varr9;
} }
} }
if (var6 == BlockPathTypes.OPEN && var4.getPathfindingMalus(var7) == 0.0F && this.entityWidth <= 1) { if (var6 == BlockPathTypes.OPEN && mvmt.getPathfindingMalus(var7) == 0.0F && this.entityWidth <= 1) {
return BlockPathTypes.OPEN; return BlockPathTypes.OPEN;
} else { } else {
return var7; return var7;
@ -265,7 +265,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
} }
} }
protected BlockPathTypes getBlockPathType(EntityHumanNPC var0, BlockPos var1) { protected BlockPathTypes getBlockPathType(LivingEntity var0, BlockPos var1) {
return this.getCachedBlockType(var0, var1.getX(), var1.getY(), var1.getZ()); return this.getCachedBlockType(var0, var1.getX(), var1.getY(), var1.getZ());
} }
@ -291,7 +291,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return var5; return var5;
} }
protected BlockPathTypes getCachedBlockType(EntityHumanNPC var0, int var1, int var2, int var3) { protected BlockPathTypes getCachedBlockType(LivingEntity var0, int var1, int var2, int var3) {
return (BlockPathTypes) this.pathTypesByPosCache.computeIfAbsent(BlockPos.asLong(var1, var2, var3), (var4) -> { return (BlockPathTypes) this.pathTypesByPosCache.computeIfAbsent(BlockPos.asLong(var1, var2, var3), (var4) -> {
return this.getBlockPathType(this.level, var1, var2, var3, var0); return this.getBlockPathType(this.level, var1, var2, var3, var0);
}); });
@ -318,7 +318,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
int var3 = 0; int var3 = 0;
BlockPathTypes var4 = this.getCachedBlockType(this.mob, var1.x, var1.y + 1, var1.z); BlockPathTypes var4 = this.getCachedBlockType(this.mob, var1.x, var1.y + 1, var1.z);
BlockPathTypes var5 = this.getCachedBlockType(this.mob, var1.x, var1.y, var1.z); BlockPathTypes var5 = this.getCachedBlockType(this.mob, var1.x, var1.y, var1.z);
if (this.mob.getPathfindingMalus(var4) >= 0.0F && var5 != BlockPathTypes.STICKY_HONEY) { if (this.mvmt.getPathfindingMalus(var4) >= 0.0F && var5 != BlockPathTypes.STICKY_HONEY) {
var3 = Mth.floor(Math.max(1.0F, this.mob.maxUpStep())); var3 = Mth.floor(Math.max(1.0F, this.mob.maxUpStep()));
} }
@ -429,7 +429,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
protected Node getStartNode(BlockPos var0) { protected Node getStartNode(BlockPos var0) {
Node var1 = this.getNode(var0); Node var1 = this.getNode(var0);
var1.type = this.getBlockPathType(this.mob, var1.asBlockPos()); var1.type = this.getBlockPathType(this.mob, var1.asBlockPos());
var1.costMalus = this.mob.getPathfindingMalus(var1.type); var1.costMalus = this.mvmt.getPathfindingMalus(var1.type);
return var1; return var1;
} }
@ -470,9 +470,9 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
} }
@Override @Override
public void prepare(PathNavigationRegion var0, EntityHumanNPC var1) { public void prepare(PathNavigationRegion var0, LivingEntity var1) {
super.prepare(var0, var1); super.prepare(var0, var1);
this.oldWaterCost = var1.getPathfindingMalus(BlockPathTypes.WATER); this.oldWaterCost = mvmt.getPathfindingMalus(BlockPathTypes.WATER);
} }
@Override @Override

View File

@ -2,15 +2,15 @@ package net.citizensnpcs.nms.v1_19_R3.util;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.PathNavigationRegion; import net.minecraft.world.level.PathNavigationRegion;
import net.minecraft.world.level.pathfinder.Node; import net.minecraft.world.level.pathfinder.Node;
import net.minecraft.world.level.pathfinder.NodeEvaluator; import net.minecraft.world.level.pathfinder.NodeEvaluator;
public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator { public abstract class EntityNodeEvaluatorBase extends NodeEvaluator {
protected boolean canFloat; protected boolean canFloat;
protected boolean canOpenDoors; protected boolean canOpenDoors;
protected boolean canPassDoors; protected boolean canPassDoors;
@ -19,7 +19,8 @@ public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator {
protected int entityHeight; protected int entityHeight;
protected int entityWidth; protected int entityWidth;
protected PathNavigationRegion level; protected PathNavigationRegion level;
protected EntityHumanNPC mob; protected LivingEntity mob;
protected MobAI mvmt;
protected final Int2ObjectMap<Node> nodes = new Int2ObjectOpenHashMap<Node>(); protected final Int2ObjectMap<Node> nodes = new Int2ObjectOpenHashMap<Node>();
@Override @Override
@ -46,6 +47,7 @@ public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator {
public void done() { public void done() {
this.level = null; this.level = null;
this.mob = null; this.mob = null;
this.mvmt = null;
} }
@Override @Override
@ -65,8 +67,9 @@ public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator {
return new net.minecraft.world.level.pathfinder.Target(var0); return new net.minecraft.world.level.pathfinder.Target(var0);
} }
public void prepare(PathNavigationRegion var0, EntityHumanNPC var1) { public void prepare(PathNavigationRegion var0, LivingEntity var1) {
this.mob = var1; this.mob = var1;
this.mvmt = MobAI.from(var1);
this.level = var0; this.level = var0;
this.nodes.clear(); this.nodes.clear();
this.entityWidth = Mth.floor(var1.getBbWidth() + 1.0F); this.entityWidth = Mth.floor(var1.getBbWidth() + 1.0F);

View File

@ -13,9 +13,9 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.PathNavigationRegion; import net.minecraft.world.level.PathNavigationRegion;
import net.minecraft.world.level.pathfinder.BinaryHeap; import net.minecraft.world.level.pathfinder.BinaryHeap;
@ -24,20 +24,20 @@ import net.minecraft.world.level.pathfinder.Path;
import net.minecraft.world.level.pathfinder.PathFinder; import net.minecraft.world.level.pathfinder.PathFinder;
import net.minecraft.world.level.pathfinder.Target; import net.minecraft.world.level.pathfinder.Target;
public class PlayerPathfinder extends PathFinder { public class EntityPathfinder extends PathFinder {
private final int maxVisitedNodes; private final int maxVisitedNodes;
private final Node[] neighbors = new Node[32]; private final Node[] neighbors = new Node[32];
private final PlayerNodeEvaluator nodeEvaluator; private final EntityNodeEvaluator nodeEvaluator;
private final BinaryHeap openSet; private final BinaryHeap openSet;
public PlayerPathfinder(PlayerNodeEvaluator var0, int var1) { public EntityPathfinder(EntityNodeEvaluator var0, int var1) {
super(var0, var1); super(var0, var1);
this.openSet = new BinaryHeap(); this.openSet = new BinaryHeap();
this.nodeEvaluator = var0; this.nodeEvaluator = var0;
this.maxVisitedNodes = var1; this.maxVisitedNodes = var1;
} }
public Path findPath(PathNavigationRegion var0, EntityHumanNPC var1, Set<BlockPos> var2, float var3, int var4, public Path findPath(PathNavigationRegion var0, LivingEntity var1, Set<BlockPos> var2, float var3, int var4,
float var5) { float var5) {
this.openSet.clear(); this.openSet.clear();
this.nodeEvaluator.prepare(var0, var1); this.nodeEvaluator.prepare(var0, var1);

View File

@ -0,0 +1,176 @@
package net.citizensnpcs.nms.v1_19_R3.util;
import java.util.Map;
import com.google.common.collect.Maps;
import net.citizensnpcs.Settings.Setting;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.control.JumpControl;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
public interface MobAI {
org.bukkit.entity.Entity getBukkitEntity();
JumpControl getJumpControl();
Map<BlockPathTypes, Float> getMalus();
MoveControl getMoveControl();
PathNavigation getNavigation();
default float getPathfindingMalus(BlockPathTypes var1) {
Map<BlockPathTypes, Float> malus = getMalus();
return malus.containsKey(var1) ? malus.get(var1) : var1.getMalus();
}
default void setPathfindingMalus(BlockPathTypes water, float oldWaterCost) {
getMalus().put(water, oldWaterCost);
}
default void tickAI() {
getJumpControl().tick();
getMoveControl().tick();
PathNavigation nav = getNavigation();
if (!nav.isDone()) {
nav.tick();
}
}
default void updatePathfindingRange(float range) {
((LivingEntity) NMSImpl.getHandle(getBukkitEntity())).getAttribute(Attributes.FOLLOW_RANGE).setBaseValue(range);
}
public static class BasicMobAI implements MobAI {
private final EntityJumpControl controllerJump;
private final EntityMoveControl controllerMove;
private final LivingEntity entity;
private final Map<BlockPathTypes, Float> malus;
private final EntityNavigation navigation;
public BasicMobAI(LivingEntity entity) {
this.entity = entity;
NMSImpl.setAttribute(entity, Attributes.FOLLOW_RANGE, Setting.DEFAULT_PATHFINDING_RANGE.asDouble());
entity.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.3D);
controllerJump = new EntityJumpControl(entity);
controllerMove = new EntityMoveControl(entity);
navigation = new EntityNavigation(entity, entity.level);
malus = Maps.newEnumMap(BlockPathTypes.class);
}
@Override
public org.bukkit.entity.Entity getBukkitEntity() {
return entity.getBukkitEntity();
}
@Override
public JumpControl getJumpControl() {
return controllerJump;
}
@Override
public Map<BlockPathTypes, Float> getMalus() {
return malus;
}
@Override
public MoveControl getMoveControl() {
return controllerMove;
}
@Override
public PathNavigation getNavigation() {
return navigation;
}
}
public static interface ForwardingMobAI extends MobAI {
MobAI getAI();
@Override
default org.bukkit.entity.Entity getBukkitEntity() {
return getAI().getBukkitEntity();
}
@Override
default JumpControl getJumpControl() {
return getAI().getJumpControl();
}
@Override
default Map<BlockPathTypes, Float> getMalus() {
return getAI().getMalus();
}
@Override
default MoveControl getMoveControl() {
return getAI().getMoveControl();
}
@Override
default PathNavigation getNavigation() {
return getAI().getNavigation();
}
}
public static MobAI from(Entity handle) {
if (handle instanceof Mob) {
Mob mob = (Mob) handle;
return new MobAI() {
@Override
public org.bukkit.entity.Entity getBukkitEntity() {
return mob.getBukkitEntity();
}
@Override
public JumpControl getJumpControl() {
return mob.getJumpControl();
}
@Override
public Map<BlockPathTypes, Float> getMalus() {
return null;
}
@Override
public MoveControl getMoveControl() {
return mob.getMoveControl();
}
@Override
public PathNavigation getNavigation() {
return mob.getNavigation();
}
@Override
public float getPathfindingMalus(BlockPathTypes var1) {
return mob.getPathfindingMalus(var1);
}
@Override
public void setPathfindingMalus(BlockPathTypes water, float oldWaterCost) {
mob.setPathfindingMalus(water, oldWaterCost);
}
@Override
public void tickAI() {
mob.getSensing().tick();
mob.getNavigation().tick();
mob.getMoveControl().tick();
mob.getLookControl().tick();
mob.getJumpControl().tick();
}
};
} else if (handle instanceof MobAI) {
return (MobAI) handle;
}
return null;
}
}

View File

@ -55,6 +55,7 @@ import org.bukkit.util.Vector;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
@ -118,7 +119,6 @@ import net.citizensnpcs.nms.v1_19_R3.entity.DrownedController;
import net.citizensnpcs.nms.v1_19_R3.entity.EnderDragonController; import net.citizensnpcs.nms.v1_19_R3.entity.EnderDragonController;
import net.citizensnpcs.nms.v1_19_R3.entity.EndermanController; import net.citizensnpcs.nms.v1_19_R3.entity.EndermanController;
import net.citizensnpcs.nms.v1_19_R3.entity.EndermiteController; import net.citizensnpcs.nms.v1_19_R3.entity.EndermiteController;
import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC;
import net.citizensnpcs.nms.v1_19_R3.entity.EvokerController; import net.citizensnpcs.nms.v1_19_R3.entity.EvokerController;
import net.citizensnpcs.nms.v1_19_R3.entity.FoxController; import net.citizensnpcs.nms.v1_19_R3.entity.FoxController;
import net.citizensnpcs.nms.v1_19_R3.entity.FrogController; import net.citizensnpcs.nms.v1_19_R3.entity.FrogController;
@ -301,7 +301,10 @@ import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.Pose; import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.TamableAnimal; import net.minecraft.world.entity.TamableAnimal;
import net.minecraft.world.entity.ai.Brain; import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.AttributeMap;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.control.FlyingMoveControl; import net.minecraft.world.entity.ai.control.FlyingMoveControl;
import net.minecraft.world.entity.ai.control.JumpControl; import net.minecraft.world.entity.ai.control.JumpControl;
@ -457,14 +460,16 @@ public class NMSImpl implements NMSBridge {
@Override @Override
public void cancelMoveDestination(org.bukkit.entity.Entity entity) { public void cancelMoveDestination(org.bukkit.entity.Entity entity) {
Entity handle = getHandle(entity); Entity handle = getHandle(entity);
if (handle instanceof Mob) { MobAI ai = MobAI.from(handle);
MoveControl control = ai != null ? ai.getMoveControl() : null;
if (control instanceof EntityMoveControl) {
((EntityMoveControl) control).moving = false;
} else {
try { try {
MOVE_CONTROLLER_OPERATION.invoke(((Mob) handle).getMoveControl(), null); MOVE_CONTROLLER_OPERATION.invoke(control, null);
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).getMoveControl().moving = false;
} }
} }
@ -587,8 +592,8 @@ public class NMSImpl implements NMSBridge {
@Override @Override
public Location getDestination(org.bukkit.entity.Entity entity) { public Location getDestination(org.bukkit.entity.Entity entity) {
Entity handle = getHandle(entity); Entity handle = getHandle(entity);
MoveControl controller = handle instanceof Mob ? ((Mob) handle).getMoveControl() MobAI ai = MobAI.from(handle);
: handle instanceof EntityHumanNPC ? ((EntityHumanNPC) handle).getMoveControl() : null; MoveControl controller = ai != null ? ai.getMoveControl() : null;
if (controller == null || !controller.hasWanted()) { if (controller == null || !controller.hasWanted()) {
return null; return null;
} }
@ -732,12 +737,11 @@ public class NMSImpl implements NMSBridge {
// navigation won't execute, and calling entity.move doesn't // navigation won't execute, and calling entity.move doesn't
// entirely fix the problem. // entirely fix the problem.
final PathNavigation navigation = NMSImpl.getNavigation(entity); final PathNavigation navigation = NMSImpl.getNavigation(entity);
final float oldWater = raw instanceof ServerPlayer final float oldWater = raw instanceof MobAI ? ((MobAI) raw).getPathfindingMalus(BlockPathTypes.WATER)
? ((EntityHumanNPC) raw).getPathfindingMalus(BlockPathTypes.WATER)
: ((Mob) raw).getPathfindingMalus(BlockPathTypes.WATER); : ((Mob) raw).getPathfindingMalus(BlockPathTypes.WATER);
if (params.avoidWater() && oldWater >= 0) { if (params.avoidWater() && oldWater >= 0) {
if (raw instanceof ServerPlayer) { if (raw instanceof MobAI) {
((EntityHumanNPC) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F); ((MobAI) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F);
} else { } else {
((Mob) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F); ((Mob) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F);
} }
@ -774,8 +778,8 @@ public class NMSImpl implements NMSBridge {
Util.sendBlockChanges(blocks, null); Util.sendBlockChanges(blocks, null);
} }
if (oldWater >= 0) { if (oldWater >= 0) {
if (raw instanceof ServerPlayer) { if (raw instanceof MobAI) {
((EntityHumanNPC) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater); ((MobAI) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater);
} else { } else {
((Mob) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater); ((Mob) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater);
} }
@ -1039,7 +1043,7 @@ public class NMSImpl implements NMSBridge {
public void look(org.bukkit.entity.Entity entity, Location to, boolean headOnly, boolean immediate) { public void look(org.bukkit.entity.Entity entity, Location to, boolean headOnly, boolean immediate) {
Entity handle = NMSImpl.getHandle(entity); Entity handle = NMSImpl.getHandle(entity);
if (immediate || headOnly || BAD_CONTROLLER_LOOK.contains(handle.getBukkitEntity().getType()) if (immediate || headOnly || BAD_CONTROLLER_LOOK.contains(handle.getBukkitEntity().getType())
|| (!(handle instanceof Mob) && !(handle instanceof EntityHumanNPC))) { || (!(handle instanceof Mob) && !(handle instanceof MobAI))) {
Location fromLocation = entity.getLocation(FROM_LOCATION); Location fromLocation = entity.getLocation(FROM_LOCATION);
double xDiff, yDiff, zDiff; double xDiff, yDiff, zDiff;
xDiff = to.getX() - fromLocation.getX(); xDiff = to.getX() - fromLocation.getX();
@ -1074,8 +1078,8 @@ public class NMSImpl implements NMSBridge {
while (((LivingEntity) handle).yHeadRot < -180F) { while (((LivingEntity) handle).yHeadRot < -180F) {
((LivingEntity) handle).yHeadRot += 360F; ((LivingEntity) handle).yHeadRot += 360F;
} }
} else if (handle instanceof EntityHumanNPC) { } else if (handle instanceof NPCHolder) {
((EntityHumanNPC) handle).getNPC().getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToFace(to); ((NPCHolder) handle).getNPC().getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToFace(to);
} }
} }
@ -1083,7 +1087,7 @@ public class NMSImpl implements NMSBridge {
public void look(org.bukkit.entity.Entity from, org.bukkit.entity.Entity to) { public void look(org.bukkit.entity.Entity from, org.bukkit.entity.Entity to) {
Entity handle = NMSImpl.getHandle(from), target = NMSImpl.getHandle(to); Entity handle = NMSImpl.getHandle(from), target = NMSImpl.getHandle(to);
if (BAD_CONTROLLER_LOOK.contains(handle.getBukkitEntity().getType()) if (BAD_CONTROLLER_LOOK.contains(handle.getBukkitEntity().getType())
|| (!(handle instanceof Mob) && !(handle instanceof EntityHumanNPC))) { || (!(handle instanceof Mob) && !(handle instanceof MobAI))) {
if (to instanceof org.bukkit.entity.LivingEntity) { if (to instanceof org.bukkit.entity.LivingEntity) {
look(from, ((org.bukkit.entity.LivingEntity) to).getEyeLocation(), false, true); look(from, ((org.bukkit.entity.LivingEntity) to).getEyeLocation(), false, true);
} else { } else {
@ -1098,8 +1102,8 @@ public class NMSImpl implements NMSBridge {
while (((LivingEntity) handle).yHeadRot < -180F) { while (((LivingEntity) handle).yHeadRot < -180F) {
((LivingEntity) handle).yHeadRot += 360F; ((LivingEntity) handle).yHeadRot += 360F;
} }
} else if (handle instanceof EntityHumanNPC) { } else if (handle instanceof NPCHolder) {
((EntityHumanNPC) handle).getNPC().getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToFace(to); ((NPCHolder) handle).getNPC().getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToFace(to);
} }
} }
@ -1436,10 +1440,9 @@ public class NMSImpl implements NMSBridge {
Entity handle = NMSImpl.getHandle(entity); Entity handle = NMSImpl.getHandle(entity);
if (handle == null) if (handle == null)
return; return;
if (handle instanceof Mob) { MobAI ai = MobAI.from(handle);
((Mob) handle).getMoveControl().setWantedPosition(x, y, z, speed); if (ai != null) {
} else if (handle instanceof EntityHumanNPC) { ai.getMoveControl().setWantedPosition(x, y, z, speed);
((EntityHumanNPC) handle).setMoveDestination(x, y, z, speed);
} }
} }
@ -1564,8 +1567,8 @@ public class NMSImpl implements NMSBridge {
if (handle instanceof Mob) { if (handle instanceof Mob) {
JumpControl controller = ((Mob) handle).getJumpControl(); JumpControl controller = ((Mob) handle).getJumpControl();
controller.jump(); controller.jump();
} else if (handle instanceof EntityHumanNPC) { } else {
((EntityHumanNPC) handle).setShouldJump(); ((LivingEntity) handle).setJumping(true);
} }
} }
@ -1779,10 +1782,8 @@ public class NMSImpl implements NMSBridge {
if (!npc.isSpawned() || !npc.getEntity().getType().isAlive()) if (!npc.isSpawned() || !npc.getEntity().getType().isAlive())
return; return;
LivingEntity en = NMSImpl.getHandle((org.bukkit.entity.LivingEntity) npc.getEntity()); LivingEntity en = NMSImpl.getHandle((org.bukkit.entity.LivingEntity) npc.getEntity());
if (!(en instanceof Mob)) { if (en instanceof MobAI) {
if (en instanceof EntityHumanNPC) { ((MobAI) en).updatePathfindingRange(pathfindingRange);
((EntityHumanNPC) en).updatePathfindingRange(pathfindingRange);
}
return; return;
} }
if (NAVIGATION_PATHFINDER == null) if (NAVIGATION_PATHFINDER == null)
@ -2145,12 +2146,12 @@ public class NMSImpl implements NMSBridge {
public static PathNavigation getNavigation(org.bukkit.entity.Entity entity) { public static PathNavigation getNavigation(org.bukkit.entity.Entity entity) {
Entity handle = getHandle(entity); Entity handle = getHandle(entity);
return handle instanceof Mob ? ((Mob) handle).getNavigation() return handle instanceof Mob ? ((Mob) handle).getNavigation()
: handle instanceof EntityHumanNPC ? ((EntityHumanNPC) handle).getNavigation() : null; : handle instanceof MobAI ? ((MobAI) handle).getNavigation() : null;
} }
private static Path getPathEntity(PathNavigation nav) { private static Path getPathEntity(PathNavigation nav) {
try { try {
return nav instanceof PlayerNavigation ? ((PlayerNavigation) nav).getPathEntity() return nav instanceof EntityNavigation ? ((EntityNavigation) nav).getPathEntity()
: (Path) NAVIGATION_PATH.invoke(nav); : (Path) NAVIGATION_PATH.invoke(nav);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@ -2290,6 +2291,26 @@ public class NMSImpl implements NMSBridge {
} }
} }
public static void setAttribute(LivingEntity entity, Attribute attribute, double value) {
AttributeInstance attr = entity.getAttribute(attribute);
if (attr == null) {
try {
AttributeSupplier provider = (AttributeSupplier) ATTRIBUTE_SUPPLIER.invoke(entity.getAttributes());
Map<Attribute, AttributeInstance> all = Maps
.newHashMap((Map<Attribute, AttributeInstance>) ATTRIBUTE_PROVIDER_MAP.invoke(provider));
all.put(attribute, new AttributeInstance(attribute, att -> {
throw new UnsupportedOperationException(
"Tried to change value for default attribute instance FOLLOW_RANGE");
}));
ATTRIBUTE_PROVIDER_MAP_SETTER.invoke(provider, ImmutableMap.copyOf(all));
} catch (Throwable e) {
e.printStackTrace();
}
attr = entity.getAttribute(attribute);
}
attr.setBaseValue(value);
}
public static void setBukkitEntity(Entity entity, CraftEntity bukkitEntity) { public static void setBukkitEntity(Entity entity, CraftEntity bukkitEntity) {
try { try {
BUKKITENTITY_FIELD_SETTER.invoke(entity, bukkitEntity); BUKKITENTITY_FIELD_SETTER.invoke(entity, bukkitEntity);
@ -2395,8 +2416,8 @@ public class NMSImpl implements NMSBridge {
handle.getMoveControl().tick(); handle.getMoveControl().tick();
handle.getLookControl().tick(); handle.getLookControl().tick();
handle.getJumpControl().tick(); handle.getJumpControl().tick();
} else if (entity instanceof EntityHumanNPC) { } else if (entity instanceof MobAI) {
((EntityHumanNPC) entity).updateAI(); ((MobAI) entity).tickAI();
} }
} }
@ -2422,6 +2443,12 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFirstFinalSetter(ServerPlayer.class, private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFirstFinalSetter(ServerPlayer.class,
PlayerAdvancements.class); PlayerAdvancements.class);
private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getFirstGetter(AttributeSupplier.class, Map.class);
private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeSupplier.class, "a");
private static final MethodHandle ATTRIBUTE_SUPPLIER = NMS.getFirstGetter(AttributeMap.class,
AttributeSupplier.class);
private static final Set<EntityType> BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.BEE, private static final Set<EntityType> BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.BEE,
EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT,
EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST, EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST,

View File

@ -1,21 +0,0 @@
package net.citizensnpcs.nms.v1_19_R3.util;
import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC;
public class PlayerControllerJump {
private boolean a;
private final EntityHumanNPC b;
public PlayerControllerJump(EntityHumanNPC entityinsentient) {
this.b = entityinsentient;
}
public void jump() {
this.a = true;
}
public void tick() {
this.b.setJumping(this.a);
this.a = false;
}
}