Backport armor stand movement to 1.16-1.17

This commit is contained in:
fullwall 2023-03-19 23:00:20 +08:00
parent 5a0184c585
commit eac2d33c21
42 changed files with 764 additions and 478 deletions

View File

@ -11,6 +11,8 @@ import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.MobAI;
import net.citizensnpcs.nms.v1_16_R3.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
@ -44,7 +46,8 @@ public class ArmorStandController extends MobEntityController {
} }
} }
public static class EntityArmorStandNPC extends EntityArmorStand implements NPCHolder { public static class EntityArmorStandNPC extends EntityArmorStand implements NPCHolder, ForwardingMobAI {
private MobAI ai;
private final CitizensNPC npc; private final CitizensNPC npc;
public EntityArmorStandNPC(EntityTypes<? extends EntityArmorStand> types, World world) { public EntityArmorStandNPC(EntityTypes<? extends EntityArmorStand> types, World world) {
@ -54,6 +57,9 @@ public class ArmorStandController extends MobEntityController {
public EntityArmorStandNPC(EntityTypes<? extends EntityArmorStand> types, World world, NPC npc) { public EntityArmorStandNPC(EntityTypes<? extends EntityArmorStand> types, World world, NPC npc) {
super(types, world); super(types, world);
this.npc = (CitizensNPC) npc; this.npc = (CitizensNPC) npc;
if (npc != null) {
ai = new BasicMobAI(this);
}
} }
@Override @Override
@ -92,6 +98,11 @@ public class ArmorStandController extends MobEntityController {
return npc == null ? super.d(save) : false; return npc == null ? super.d(save) : false;
} }
@Override
public MobAI getAI() {
return ai;
}
@Override @Override
public CraftEntity getBukkitEntity() { public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) { if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
@ -118,6 +129,7 @@ public class ArmorStandController extends MobEntityController {
super.tick(); super.tick();
if (npc != null) { if (npc != null) {
npc.update(); npc.update();
ai.tickAI();
} }
} }
} }

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -214,7 +214,7 @@ public class CodController extends MobEntityController {
this.moveController = this.oldMoveController; this.moveController = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
} }
super.mobTick(); super.mobTick();

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -217,7 +217,7 @@ public class DolphinController extends MobEntityController {
this.moveController = this.oldMoveController; this.moveController = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
npc.update(); npc.update();
} }

View File

@ -1,11 +1,9 @@
package net.citizensnpcs.nms.v1_16_R3.entity; package net.citizensnpcs.nms.v1_16_R3.entity;
import java.io.IOException; import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.net.Socket; import java.net.Socket;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -16,7 +14,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;
@ -24,7 +21,6 @@ import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPC.NPCUpdate; import net.citizensnpcs.api.npc.NPC.NPCUpdate;
import net.citizensnpcs.api.trait.trait.Inventory; import net.citizensnpcs.api.trait.trait.Inventory;
@ -32,10 +28,9 @@ import net.citizensnpcs.api.util.SpigotUtil;
import net.citizensnpcs.nms.v1_16_R3.network.EmptyNetHandler; import net.citizensnpcs.nms.v1_16_R3.network.EmptyNetHandler;
import net.citizensnpcs.nms.v1_16_R3.network.EmptyNetworkManager; import net.citizensnpcs.nms.v1_16_R3.network.EmptyNetworkManager;
import net.citizensnpcs.nms.v1_16_R3.util.EmptyAdvancementDataPlayer; import net.citizensnpcs.nms.v1_16_R3.util.EmptyAdvancementDataPlayer;
import net.citizensnpcs.nms.v1_16_R3.util.MobAI;
import net.citizensnpcs.nms.v1_16_R3.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerJump;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerNavigation;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerlistTracker; import net.citizensnpcs.nms.v1_16_R3.util.PlayerlistTracker;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
@ -46,10 +41,6 @@ import net.citizensnpcs.trait.SkinTrait;
import net.citizensnpcs.util.EmptySocket; import net.citizensnpcs.util.EmptySocket;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
import net.minecraft.server.v1_16_R3.AttributeBase;
import net.minecraft.server.v1_16_R3.AttributeMapBase;
import net.minecraft.server.v1_16_R3.AttributeModifiable;
import net.minecraft.server.v1_16_R3.AttributeProvider;
import net.minecraft.server.v1_16_R3.AxisAlignedBB; import net.minecraft.server.v1_16_R3.AxisAlignedBB;
import net.minecraft.server.v1_16_R3.BlockPosition; import net.minecraft.server.v1_16_R3.BlockPosition;
import net.minecraft.server.v1_16_R3.ChatComponentText; import net.minecraft.server.v1_16_R3.ChatComponentText;
@ -60,28 +51,22 @@ import net.minecraft.server.v1_16_R3.EntityPlayer;
import net.minecraft.server.v1_16_R3.EnumGamemode; import net.minecraft.server.v1_16_R3.EnumGamemode;
import net.minecraft.server.v1_16_R3.EnumItemSlot; import net.minecraft.server.v1_16_R3.EnumItemSlot;
import net.minecraft.server.v1_16_R3.EnumProtocolDirection; import net.minecraft.server.v1_16_R3.EnumProtocolDirection;
import net.minecraft.server.v1_16_R3.GenericAttributes;
import net.minecraft.server.v1_16_R3.IBlockData; import net.minecraft.server.v1_16_R3.IBlockData;
import net.minecraft.server.v1_16_R3.IChatBaseComponent; import net.minecraft.server.v1_16_R3.IChatBaseComponent;
import net.minecraft.server.v1_16_R3.ItemStack; import net.minecraft.server.v1_16_R3.ItemStack;
import net.minecraft.server.v1_16_R3.MinecraftServer; import net.minecraft.server.v1_16_R3.MinecraftServer;
import net.minecraft.server.v1_16_R3.NavigationAbstract;
import net.minecraft.server.v1_16_R3.NetworkManager; import net.minecraft.server.v1_16_R3.NetworkManager;
import net.minecraft.server.v1_16_R3.Packet; import net.minecraft.server.v1_16_R3.Packet;
import net.minecraft.server.v1_16_R3.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_16_R3.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_16_R3.PathType;
import net.minecraft.server.v1_16_R3.PlayerInteractManager; import net.minecraft.server.v1_16_R3.PlayerInteractManager;
import net.minecraft.server.v1_16_R3.SoundEffect; import net.minecraft.server.v1_16_R3.SoundEffect;
import net.minecraft.server.v1_16_R3.Vec3D; import net.minecraft.server.v1_16_R3.Vec3D;
import net.minecraft.server.v1_16_R3.WorldServer; import net.minecraft.server.v1_16_R3.WorldServer;
public class EntityHumanNPC extends EntityPlayer implements NPCHolder, SkinnableEntity { public class EntityHumanNPC extends EntityPlayer implements NPCHolder, SkinnableEntity, ForwardingMobAI {
private final Map<PathType, Float> bz = Maps.newEnumMap(PathType.class); private MobAI ai;
private PlayerControllerJump controllerJump;
private PlayerControllerMove controllerMove;
private final Map<EnumItemSlot, ItemStack> equipmentCache = Maps.newEnumMap(EnumItemSlot.class); private final Map<EnumItemSlot, ItemStack> equipmentCache = Maps.newEnumMap(EnumItemSlot.class);
private int jumpTicks = 0; private int jumpTicks = 0;
private PlayerNavigation navigation;
private final CitizensNPC npc; private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0); private final Location packetLocationCache = new Location(null, 0, 0, 0);
private PlayerlistTracker playerlistTracker; private PlayerlistTracker playerlistTracker;
@ -92,6 +77,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
super(minecraftServer, world, gameProfile, playerInteractManager); super(minecraftServer, world, gameProfile, playerInteractManager);
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);
playerInteractManager.setGameMode(EnumGamemode.SURVIVAL); playerInteractManager.setGameMode(EnumGamemode.SURVIVAL);
initialise(minecraftServer); initialise(minecraftServer);
@ -115,14 +101,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return super.a(entityplayer); return super.a(entityplayer);
} }
public float a(PathType pathtype) {
return this.bz.containsKey(pathtype) ? this.bz.get(pathtype) : pathtype.a();
}
public void a(PathType pathtype, float f) {
this.bz.put(pathtype, f);
}
@Override @Override
public boolean b(float f, float f1) { public boolean b(float f, float f1) {
if (npc == null || !npc.isFlyable()) { if (npc == null || !npc.isFlyable()) {
@ -131,11 +109,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return false; return false;
} }
public boolean b(PathType pathtype) {
return (pathtype != PathType.DANGER_FIRE && pathtype != PathType.DANGER_CACTUS
&& pathtype != PathType.DANGER_OTHER);
}
@Override @Override
public void collide(net.minecraft.server.v1_16_R3.Entity entity) { public void collide(net.minecraft.server.v1_16_R3.Entity entity) {
// this method is called by both the entities involved - cancelling // this method is called by both the entities involved - cancelling
@ -186,8 +159,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
}, 15); // give enough time for death and smoke animation }, 15); // give enough time for death and smoke animation
} }
@Override @Override
public void g(Vec3D vec3d) { public void g(Vec3D vec3d) {
if (npc == null || !npc.isFlyable()) { if (npc == null || !npc.isFlyable()) {
@ -197,6 +168,11 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
} }
} }
@Override
public MobAI getAI() {
return ai;
}
@Override @Override
public CraftPlayer getBukkitEntity() { public CraftPlayer getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) { if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
@ -205,18 +181,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return super.getBukkitEntity(); return super.getBukkitEntity();
} }
public PlayerControllerJump getControllerJump() {
return controllerJump;
}
public PlayerControllerMove getControllerMove() {
return controllerMove;
}
public NavigationAbstract getNavigation() {
return navigation;
}
@Override @Override
public NPC getNPC() { public NPC getNPC() {
return npc; return npc;
@ -281,30 +245,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
} catch (IOException e) { } catch (IOException e) {
// swallow // swallow
} }
AttributeModifiable range = getAttributeInstance(GenericAttributes.FOLLOW_RANGE);
if (range == null) {
try {
AttributeProvider provider = (AttributeProvider) ATTRIBUTE_MAP.invoke(getAttributeMap());
Map<AttributeBase, AttributeModifiable> all = Maps
.newHashMap((Map<AttributeBase, AttributeModifiable>) ATTRIBUTE_PROVIDER_MAP.invoke(provider));
all.put(GenericAttributes.FOLLOW_RANGE,
new AttributeModifiable(GenericAttributes.FOLLOW_RANGE, new Consumer<AttributeModifiable>() {
@Override
public void accept(AttributeModifiable 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 = getAttributeMap().a(GenericAttributes.FOLLOW_RANGE);
}
range.setValue(Setting.DEFAULT_PATHFINDING_RANGE.asDouble());
controllerJump = new PlayerControllerJump(this);
controllerMove = new PlayerControllerMove(this);
navigation = new PlayerNavigation(this, world);
invulnerableTicks = 0; invulnerableTicks = 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);
@ -330,10 +270,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
: !npc.isProtected(); : !npc.isProtected();
} }
public boolean isNavigating() {
return npc.getNavigator().isNavigating();
}
private void moveOnCurrentHeading() { private void moveOnCurrentHeading() {
if (jumping) { if (jumping) {
if (onGround && jumpTicks == 0) { if (onGround && jumpTicks == 0) {
@ -375,7 +311,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return; return;
} }
entityBaseTick(); entityBaseTick();
boolean navigating = npc.getNavigator().isNavigating() || controllerMove.b(); boolean navigating = npc.getNavigator().isNavigating() || ai.getMoveControl().b();
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))
@ -387,25 +323,18 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
setMot(new Vec3D(0, 0, 0)); setMot(new Vec3D(0, 0, 0));
} }
if (navigating) { if (navigating) {
if (!NMSImpl.isNavigationFinished(navigation)) { if (!NMSImpl.isNavigationFinished(ai.getNavigation())) {
NMSImpl.updateNavigation(navigation); NMSImpl.updateNavigation(ai.getNavigation());
} }
moveOnCurrentHeading(); moveOnCurrentHeading();
} }
updateAI(); ai.getMoveControl().a();
ai.getJumpControl().b();
if (npc.data().get(NPC.Metadata.COLLIDABLE, !npc.isProtected())) { if (npc.data().get(NPC.Metadata.COLLIDABLE, !npc.isProtected())) {
collideNearby(); collideNearby();
} }
} }
public void setMoveDestination(double x, double y, double z, double speed) {
controllerMove.a(x, y, z, speed);
}
public void setShouldJump() {
controllerJump.jump();
}
@Override @Override
public void setSkinFlags(byte flags) { public void setSkinFlags(byte flags) {
// set skin flag byte // set skin flag byte
@ -466,11 +395,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
*/ */
} }
public void updateAI() {
controllerMove.a();
controllerJump.b();
}
private void updatePackets(boolean navigating) { private void updatePackets(boolean navigating) {
if (!npc.isUpdating(NPCUpdate.PACKET)) if (!npc.isUpdating(NPCUpdate.PACKET))
return; return;
@ -497,10 +421,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
NMSImpl.sendPacketsNearby(getBukkitEntity(), current, packets); NMSImpl.sendPacketsNearby(getBukkitEntity(), current, 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 CraftServer cserver; private final CraftServer cserver;
private final CitizensNPC npc; private final CitizensNPC npc;
@ -578,9 +498,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
} }
} }
private static final MethodHandle ATTRIBUTE_MAP = NMS.getGetter(AttributeMapBase.class, "d");
private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getGetter(AttributeProvider.class, "a");
private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeProvider.class, "a");
private static final float EPSILON = 0.003F; private static final float EPSILON = 0.003F;
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0); private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
} }

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -59,7 +59,7 @@ public class MagmaCubeController extends MobEntityController {
if (npc != null) { if (npc != null) {
setSize(3, true); setSize(3, true);
this.oldMoveController = this.moveController; this.oldMoveController = this.moveController;
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
} }
@ -205,7 +205,7 @@ public class MagmaCubeController extends MobEntityController {
this.moveController = this.oldMoveController; this.moveController = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
npc.update(); npc.update();
} }

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -216,7 +216,7 @@ public class PhantomController extends MobEntityController {
this.lookController = this.oldLookController; this.lookController = this.oldLookController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
this.lookController = new ControllerLook(this); this.lookController = new ControllerLook(this);
} }
if (npc.isProtected()) { if (npc.isProtected()) {

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -218,7 +218,7 @@ public class PufferFishController extends MobEntityController {
this.moveController = this.oldMoveController; this.moveController = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
npc.update(); npc.update();
} }

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -206,7 +206,7 @@ public class SalmonController extends MobEntityController {
this.moveController = this.oldMoveController; this.moveController = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
} }
super.mobTick(); super.mobTick();

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -59,7 +59,7 @@ public class SlimeController extends MobEntityController {
if (npc != null) { if (npc != null) {
setSize(3, true); setSize(3, true);
this.oldMoveController = this.moveController; this.oldMoveController = this.moveController;
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
} }
@ -206,7 +206,7 @@ public class SlimeController extends MobEntityController {
this.moveController = this.oldMoveController; this.moveController = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
npc.update(); npc.update();
} }

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -208,7 +208,7 @@ public class TropicalFishController extends MobEntityController {
this.moveController = this.oldMoveController; this.moveController = this.oldMoveController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
} }
} }
super.mobTick(); super.mobTick();

View File

@ -11,7 +11,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_16_R3.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl; import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.nms.v1_16_R3.util.PlayerControllerMove; import net.citizensnpcs.nms.v1_16_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;
@ -196,7 +196,7 @@ public class TurtleController extends MobEntityController {
this.bi = this.oldJumpController; this.bi = this.oldJumpController;
} }
if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) { if (!npc.useMinecraftAI() && this.moveController == this.oldMoveController) {
this.moveController = new PlayerControllerMove(this); this.moveController = new EntityMoveControl(this);
this.bi = new EmptyControllerJump(this); this.bi = new EmptyControllerJump(this);
} }
npc.update(); npc.update();

View File

@ -0,0 +1,27 @@
package net.citizensnpcs.nms.v1_16_R3.util;
import net.minecraft.server.v1_16_R3.ControllerJump;
import net.minecraft.server.v1_16_R3.EntityLiving;
import net.minecraft.server.v1_16_R3.EntitySlime;
import net.minecraft.server.v1_16_R3.EntityTypes;
public class EntityJumpControl extends ControllerJump {
private boolean a;
private final EntityLiving b;
public EntityJumpControl(EntityLiving entityinsentient) {
super(new EntitySlime(EntityTypes.SLIME, entityinsentient.world));
this.b = entityinsentient;
}
@Override
public void b() {
this.b.setJumping(this.a);
this.a = false;
}
@Override
public void jump() {
this.a = true;
}
}

View File

@ -2,7 +2,6 @@ package net.citizensnpcs.nms.v1_16_R3.util;
import java.util.Random; import java.util.Random;
import net.citizensnpcs.nms.v1_16_R3.entity.EntityHumanNPC;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_16_R3.AttributeModifiable; import net.minecraft.server.v1_16_R3.AttributeModifiable;
import net.minecraft.server.v1_16_R3.ControllerMove; import net.minecraft.server.v1_16_R3.ControllerMove;
@ -13,8 +12,9 @@ import net.minecraft.server.v1_16_R3.EntityTypes;
import net.minecraft.server.v1_16_R3.GenericAttributes; import net.minecraft.server.v1_16_R3.GenericAttributes;
import net.minecraft.server.v1_16_R3.MathHelper; import net.minecraft.server.v1_16_R3.MathHelper;
public class PlayerControllerMove extends ControllerMove { public class EntityMoveControl extends ControllerMove {
protected EntityLiving a; protected EntityLiving a;
private final MobAI ai;
protected double b; protected double b;
protected double c; protected double c;
protected double d; protected double d;
@ -22,10 +22,11 @@ public class PlayerControllerMove extends ControllerMove {
protected boolean f; protected boolean f;
private int h; private int h;
public PlayerControllerMove(EntityLiving entityinsentient) { public EntityMoveControl(EntityLiving entityinsentient) {
super(entityinsentient instanceof EntityInsentient ? (EntityInsentient) entityinsentient super(entityinsentient instanceof EntityInsentient ? (EntityInsentient) entityinsentient
: new EntitySlime(EntityTypes.SLIME, entityinsentient.world)); : new EntitySlime(EntityTypes.SLIME, entityinsentient.world));
this.a = entityinsentient; this.a = entityinsentient;
this.ai = MobAI.from(entityinsentient);
this.b = entityinsentient.locX(); this.b = entityinsentient.locX();
this.c = entityinsentient.locY(); this.c = entityinsentient.locY();
this.d = entityinsentient.locZ(); this.d = entityinsentient.locZ();
@ -56,11 +57,7 @@ public class PlayerControllerMove extends ControllerMove {
if (shouldSlimeJump() || (d2 >= NMS.getStepHeight(a.getBukkitEntity()) && (d0 * d0 + d1 * d1) < 1.0D)) { if (shouldSlimeJump() || (d2 >= NMS.getStepHeight(a.getBukkitEntity()) && (d0 * d0 + d1 * d1) < 1.0D)) {
this.h = cg(); this.h = cg();
this.h /= 3; this.h /= 3;
if (this.a instanceof EntityHumanNPC) { ai.getJumpControl().jump();
((EntityHumanNPC) this.a).getControllerJump().jump();
} else {
((EntityInsentient) this.a).getControllerJump().jump();
}
} }
} }
} }

View File

@ -8,7 +8,6 @@ import java.util.stream.Stream;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.nms.v1_16_R3.entity.EntityHumanNPC;
import net.minecraft.server.v1_16_R3.AttributeModifiable; import net.minecraft.server.v1_16_R3.AttributeModifiable;
import net.minecraft.server.v1_16_R3.BaseBlockPosition; import net.minecraft.server.v1_16_R3.BaseBlockPosition;
import net.minecraft.server.v1_16_R3.Block; import net.minecraft.server.v1_16_R3.Block;
@ -17,6 +16,7 @@ import net.minecraft.server.v1_16_R3.Blocks;
import net.minecraft.server.v1_16_R3.ChunkCache; import net.minecraft.server.v1_16_R3.ChunkCache;
import net.minecraft.server.v1_16_R3.Entity; import net.minecraft.server.v1_16_R3.Entity;
import net.minecraft.server.v1_16_R3.EntityInsentient; import net.minecraft.server.v1_16_R3.EntityInsentient;
import net.minecraft.server.v1_16_R3.EntityLiving;
import net.minecraft.server.v1_16_R3.EntityTypes; import net.minecraft.server.v1_16_R3.EntityTypes;
import net.minecraft.server.v1_16_R3.GenericAttributes; import net.minecraft.server.v1_16_R3.GenericAttributes;
import net.minecraft.server.v1_16_R3.IBlockData; import net.minecraft.server.v1_16_R3.IBlockData;
@ -33,9 +33,8 @@ import net.minecraft.server.v1_16_R3.SystemUtils;
import net.minecraft.server.v1_16_R3.Vec3D; import net.minecraft.server.v1_16_R3.Vec3D;
import net.minecraft.server.v1_16_R3.World; import net.minecraft.server.v1_16_R3.World;
public class PlayerNavigation extends NavigationAbstract { public class EntityNavigation extends NavigationAbstract {
protected final EntityHumanNPC a; protected final EntityLiving a;
protected final World b;
protected PathEntity c; protected PathEntity c;
protected double d; protected double d;
protected int e; protected int e;
@ -48,26 +47,27 @@ public class PlayerNavigation extends NavigationAbstract {
protected double k; protected double k;
protected float l = 0.5F; protected float l = 0.5F;
protected boolean m; protected boolean m;
private final MobAI mvmt;
protected long n; protected long n;
protected PlayerPathfinderNormal o; protected EntityPathfinderNormal o;
private BlockPosition p; private BlockPosition p;
private boolean pp; private boolean pp;
private int q; private int q;
private float r = 1.0F; private float r = 1.0F;
private final PlayerPathfinder s; private final EntityPathfinder s;
private boolean t; private boolean t;
public PlayerNavigation(EntityHumanNPC entityinsentient, World world) { public EntityNavigation(EntityLiving entityinsentient, World world) {
super(getDummyInsentient(entityinsentient, world), world); super(getDummyInsentient(entityinsentient, world), world);
this.g = Vec3D.ORIGIN; this.g = Vec3D.ORIGIN;
this.l = 0.5F; this.l = 0.5F;
this.r = 1.0F; this.r = 1.0F;
this.mvmt = MobAI.from(entityinsentient);
this.a = entityinsentient; this.a = entityinsentient;
this.b = world;
this.followRange = entityinsentient.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); this.followRange = entityinsentient.getAttributeInstance(GenericAttributes.FOLLOW_RANGE);
this.o = new PlayerPathfinderNormal(); this.o = new EntityPathfinderNormal();
this.o.a(true); this.o.a(true);
this.s = new PlayerPathfinder(this.o, Setting.MAXIMUM_VISITED_NODES.asInt()); this.s = new EntityPathfinder(this.o, Setting.MAXIMUM_VISITED_NODES.asInt());
this.setRange(24); this.setRange(24);
// this.b.C().a(this); // this.b.C().a(this);
} }
@ -154,7 +154,7 @@ public class PlayerNavigation extends NavigationAbstract {
if (!a(var19)) if (!a(var19))
return false; return false;
var19 = this.o.a(this.b, var13, var1, var14, this.a, var3, var4, var5, true, true); var19 = this.o.a(this.b, var13, var1, var14, this.a, var3, var4, var5, true, true);
float var20 = this.a.a(var19); float var20 = mvmt.getPathfindingMalus(var19);
if (var20 < 0.0F || var20 >= 8.0F) if (var20 < 0.0F || var20 >= 8.0F)
return false; return false;
if (var19 == PathType.DAMAGE_FIRE || var19 == PathType.DANGER_FIRE if (var19 == PathType.DAMAGE_FIRE || var19 == PathType.DANGER_FIRE
@ -332,6 +332,11 @@ public class PlayerNavigation extends NavigationAbstract {
return true; return true;
} }
public boolean b(PathType pathtype) {
return (pathtype != PathType.DANGER_FIRE && pathtype != PathType.DANGER_CACTUS
&& pathtype != PathType.DANGER_OTHER);
}
private boolean b(Vec3D var0) { private boolean b(Vec3D var0) {
if (this.c.f() + 1 >= this.c.e()) if (this.c.f() + 1 >= this.c.e())
return false; return false;
@ -364,8 +369,8 @@ public class PlayerNavigation extends NavigationAbstract {
return; return;
Vec3D var0 = this.c.a(this.a); Vec3D var0 = this.c.a(this.a);
BlockPosition var1 = new BlockPosition(var0); BlockPosition var1 = new BlockPosition(var0);
this.a.getControllerMove().a(var0.x, mvmt.getMoveControl().a(var0.x, this.b.getType(var1.down()).isAir() ? var0.y : PathfinderNormal.a(this.b, var1),
this.b.getType(var1.down()).isAir() ? var0.y : PathfinderNormal.a(this.b, var1), var0.z, this.d); var0.z, this.d);
} }
public void c(boolean var0) { public void c(boolean var0) {
@ -450,7 +455,7 @@ public class PlayerNavigation extends NavigationAbstract {
boolean b2 = Math.abs(this.a.locX() - (var1.getX() + 0.5D)) < this.l boolean b2 = Math.abs(this.a.locX() - (var1.getX() + 0.5D)) < this.l
&& Math.abs(this.a.locZ() - (var1.getZ() + 0.5D)) < this.l && Math.abs(this.a.locZ() - (var1.getZ() + 0.5D)) < this.l
&& Math.abs(this.a.locY() - var1.getY()) < 1.0D; // old-style calc && Math.abs(this.a.locY() - var1.getY()) < 1.0D; // old-style calc
if (var8 || b2 || (this.a.b((this.c.h()).l) && b(var0))) if (var8 || b2 || (b((this.c.h()).l) && b(var0)))
this.c.a(); this.c.a();
a(var0); a(var0);
} }
@ -528,7 +533,7 @@ public class PlayerNavigation extends NavigationAbstract {
return var0; return var0;
} }
private static EntityInsentient getDummyInsentient(EntityHumanNPC from, World world) { private static EntityInsentient getDummyInsentient(EntityLiving from, World world) {
return new EntityInsentient(EntityTypes.VILLAGER, world) { return new EntityInsentient(EntityTypes.VILLAGER, world) {
}; };
} }

View File

@ -14,29 +14,30 @@ 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_16_R3.entity.EntityHumanNPC;
import net.minecraft.server.v1_16_R3.BlockPosition; import net.minecraft.server.v1_16_R3.BlockPosition;
import net.minecraft.server.v1_16_R3.ChunkCache; import net.minecraft.server.v1_16_R3.ChunkCache;
import net.minecraft.server.v1_16_R3.EntityInsentient; import net.minecraft.server.v1_16_R3.EntityInsentient;
import net.minecraft.server.v1_16_R3.EntityLiving;
import net.minecraft.server.v1_16_R3.Path; import net.minecraft.server.v1_16_R3.Path;
import net.minecraft.server.v1_16_R3.PathDestination; import net.minecraft.server.v1_16_R3.PathDestination;
import net.minecraft.server.v1_16_R3.PathEntity; import net.minecraft.server.v1_16_R3.PathEntity;
import net.minecraft.server.v1_16_R3.PathPoint; import net.minecraft.server.v1_16_R3.PathPoint;
import net.minecraft.server.v1_16_R3.Pathfinder; import net.minecraft.server.v1_16_R3.Pathfinder;
public class PlayerPathfinder extends Pathfinder { public class EntityPathfinder extends Pathfinder {
private final PathPoint[] a = new PathPoint[32]; private final PathPoint[] a = new PathPoint[32];
private final int b; private final int b;
private final PlayerPathfinderNormal c; private final EntityPathfinderNormal c;
private final Path d = new Path(); private final Path d = new Path();
public PlayerPathfinder(PlayerPathfinderNormal var0, int var1) { public EntityPathfinder(EntityPathfinderNormal var0, int var1) {
super(var0, var1); super(var0, var1);
this.c = var0; this.c = var0;
this.b = var1; this.b = var1;
} }
public PathEntity a(ChunkCache var0, EntityHumanNPC var1, Set<BlockPosition> var2, float var3, int var4, @Override
public PathEntity a(ChunkCache var0, EntityInsentient var1, Set<BlockPosition> var2, float var3, int var4,
float var5) { float var5) {
this.d.a(); this.d.a();
this.c.a(var0, var1); this.c.a(var0, var1);
@ -49,9 +50,7 @@ public class PlayerPathfinder extends Pathfinder {
return var8; return var8;
} }
@Override public PathEntity a(ChunkCache var0, EntityLiving var1, Set<BlockPosition> var2, float var3, int var4, float var5) {
public PathEntity a(ChunkCache var0, EntityInsentient var1, Set<BlockPosition> var2, float var3, int var4,
float var5) {
this.d.a(); this.d.a();
this.c.a(var0, var1); this.c.a(var0, var1);
PathPoint var6 = this.c.b(); PathPoint var6 = this.c.b();

View File

@ -3,16 +3,16 @@ package net.citizensnpcs.nms.v1_16_R3.util;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.citizensnpcs.nms.v1_16_R3.entity.EntityHumanNPC;
import net.minecraft.server.v1_16_R3.BlockPosition; import net.minecraft.server.v1_16_R3.BlockPosition;
import net.minecraft.server.v1_16_R3.ChunkCache; import net.minecraft.server.v1_16_R3.ChunkCache;
import net.minecraft.server.v1_16_R3.EntityLiving;
import net.minecraft.server.v1_16_R3.MathHelper; import net.minecraft.server.v1_16_R3.MathHelper;
import net.minecraft.server.v1_16_R3.PathPoint; import net.minecraft.server.v1_16_R3.PathPoint;
import net.minecraft.server.v1_16_R3.PathfinderAbstract; import net.minecraft.server.v1_16_R3.PathfinderAbstract;
public abstract class PlayerPathfinderAbstract extends PathfinderAbstract { public abstract class EntityPathfinderAbstract extends PathfinderAbstract {
protected ChunkCache a; protected ChunkCache a;
protected EntityHumanNPC b; protected EntityLiving b;
protected final Int2ObjectMap<PathPoint> c = new Int2ObjectOpenHashMap(); protected final Int2ObjectMap<PathPoint> c = new Int2ObjectOpenHashMap();
protected int d; protected int d;
protected int e; protected int e;
@ -20,11 +20,13 @@ public abstract class PlayerPathfinderAbstract extends PathfinderAbstract {
protected boolean g; protected boolean g;
protected boolean h; protected boolean h;
protected boolean i; protected boolean i;
protected MobAI mvmt;
@Override @Override
public void a() { public void a() {
this.a = null; this.a = null;
this.b = null; this.b = null;
mvmt = null;
} }
@Override @Override
@ -37,7 +39,8 @@ public abstract class PlayerPathfinderAbstract extends PathfinderAbstract {
this.g = var0; this.g = var0;
} }
public void a(ChunkCache var0, EntityHumanNPC var1) { public void a(ChunkCache var0, EntityLiving var1) {
this.mvmt = MobAI.from(var1);
this.a = var0; this.a = var0;
this.b = var1; this.b = var1;
this.c.clear(); this.c.clear();

View File

@ -7,7 +7,6 @@ import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.longs.Long2ObjectOpenHa
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2BooleanMap; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2BooleanMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
import net.citizensnpcs.nms.v1_16_R3.entity.EntityHumanNPC;
import net.minecraft.server.v1_16_R3.AxisAlignedBB; import net.minecraft.server.v1_16_R3.AxisAlignedBB;
import net.minecraft.server.v1_16_R3.Block; import net.minecraft.server.v1_16_R3.Block;
import net.minecraft.server.v1_16_R3.BlockCampfire; import net.minecraft.server.v1_16_R3.BlockCampfire;
@ -19,6 +18,7 @@ import net.minecraft.server.v1_16_R3.BlockPosition;
import net.minecraft.server.v1_16_R3.Blocks; import net.minecraft.server.v1_16_R3.Blocks;
import net.minecraft.server.v1_16_R3.ChunkCache; import net.minecraft.server.v1_16_R3.ChunkCache;
import net.minecraft.server.v1_16_R3.EntityInsentient; import net.minecraft.server.v1_16_R3.EntityInsentient;
import net.minecraft.server.v1_16_R3.EntityLiving;
import net.minecraft.server.v1_16_R3.EnumDirection; import net.minecraft.server.v1_16_R3.EnumDirection;
import net.minecraft.server.v1_16_R3.Fluid; import net.minecraft.server.v1_16_R3.Fluid;
import net.minecraft.server.v1_16_R3.FluidTypes; import net.minecraft.server.v1_16_R3.FluidTypes;
@ -35,14 +35,14 @@ import net.minecraft.server.v1_16_R3.TagsFluid;
import net.minecraft.server.v1_16_R3.Vec3D; import net.minecraft.server.v1_16_R3.Vec3D;
import net.minecraft.server.v1_16_R3.VoxelShape; import net.minecraft.server.v1_16_R3.VoxelShape;
public class PlayerPathfinderNormal extends PlayerPathfinderAbstract { public class EntityPathfinderNormal extends EntityPathfinderAbstract {
protected float j; protected float j;
private final Long2ObjectMap<PathType> k = new Long2ObjectOpenHashMap(); private final Long2ObjectMap<PathType> k = new Long2ObjectOpenHashMap();
private final Object2BooleanMap<AxisAlignedBB> l = new Object2BooleanOpenHashMap(); private final Object2BooleanMap<AxisAlignedBB> l = new Object2BooleanOpenHashMap();
@Override @Override
public void a() { public void a() {
this.b.a(PathType.WATER, this.j); this.mvmt.setPathfindingMalus(PathType.WATER, this.j);
this.k.clear(); this.k.clear();
this.l.clear(); this.l.clear();
super.a(); super.a();
@ -53,15 +53,15 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
} }
@Override @Override
public void a(ChunkCache var0, EntityHumanNPC var1) { public void a(ChunkCache var0, EntityInsentient var1) {
super.a(var0, var1); super.a(var0, var1);
this.j = var1.a(PathType.WATER); this.j = var1.a(PathType.WATER);
} }
@Override @Override
public void a(ChunkCache var0, EntityInsentient var1) { public void a(ChunkCache var0, EntityLiving var1) {
super.a(var0, var1); super.a(var0, var1);
this.j = var1.a(PathType.WATER); this.j = mvmt.getPathfindingMalus(PathType.WATER);
} }
@Override @Override
@ -69,11 +69,11 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
return new PathDestination(a(MathHelper.floor(var0), MathHelper.floor(var2), MathHelper.floor(var4))); return new PathDestination(a(MathHelper.floor(var0), MathHelper.floor(var2), MathHelper.floor(var4)));
} }
private PathType a(EntityHumanNPC var0, BlockPosition var1) { private PathType a(EntityLiving var0, BlockPosition var1) {
return a(var0, var1.getX(), var1.getY(), var1.getZ()); return a(var0, var1.getX(), var1.getY(), var1.getZ());
} }
private PathType a(EntityHumanNPC var0, int var1, int var2, int var3) { private PathType a(EntityLiving var0, int var1, int var2, int var3) {
return this.k.computeIfAbsent(BlockPosition.a(var1, var2, var3), (var4) -> { return this.k.computeIfAbsent(BlockPosition.a(var1, var2, var3), (var4) -> {
return this.a(this.a, var1, var2, var3, var0, this.d, this.e, this.f, this.d(), this.c()); return this.a(this.a, var1, var2, var3, var0, this.d, this.e, this.f, this.d(), this.c());
}); });
@ -97,28 +97,6 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
return a(var0, new BlockPosition.MutableBlockPosition(var1, var2, var3)); return a(var0, new BlockPosition.MutableBlockPosition(var1, var2, var3));
} }
public PathType a(IBlockAccess var0, int var1, int var2, int var3, EntityHumanNPC var4, int var5, int var6,
int var7, boolean var8, boolean var9) {
EnumSet<PathType> var10 = EnumSet.noneOf(PathType.class);
PathType var11 = PathType.BLOCKED;
BlockPosition var12 = var4.getChunkCoordinates();
var11 = a(var0, var1, var2, var3, var5, var6, var7, var8, var9, var10, var11, var12);
if (var10.contains(PathType.FENCE))
return PathType.FENCE;
if (var10.contains(PathType.UNPASSABLE_RAIL))
return PathType.UNPASSABLE_RAIL;
PathType var13 = PathType.BLOCKED;
for (PathType var15 : var10) {
if (var4.a(var15) < 0.0F)
return var15;
if (var4.a(var15) >= var4.a(var13))
var13 = var15;
}
if (var11 == PathType.OPEN && var4.a(var13) == 0.0F && var5 <= 1)
return PathType.OPEN;
return var13;
}
@Override @Override
public PathType a(IBlockAccess var0, int var1, int var2, int var3, EntityInsentient var4, int var5, int var6, public PathType a(IBlockAccess var0, int var1, int var2, int var3, EntityInsentient var4, int var5, int var6,
int var7, boolean var8, boolean var9) { int var7, boolean var8, boolean var9) {
@ -132,12 +110,34 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
return PathType.UNPASSABLE_RAIL; return PathType.UNPASSABLE_RAIL;
PathType var13 = PathType.BLOCKED; PathType var13 = PathType.BLOCKED;
for (PathType var15 : var10) { for (PathType var15 : var10) {
if (var4.a(var15) < 0.0F) if (mvmt.getPathfindingMalus(var15) < 0.0F)
return var15; return var15;
if (var4.a(var15) >= var4.a(var13)) if (mvmt.getPathfindingMalus(var15) >= mvmt.getPathfindingMalus(var13))
var13 = var15; var13 = var15;
} }
if (var11 == PathType.OPEN && var4.a(var13) == 0.0F && var5 <= 1) if (var11 == PathType.OPEN && mvmt.getPathfindingMalus(var13) == 0.0F && var5 <= 1)
return PathType.OPEN;
return var13;
}
public PathType a(IBlockAccess var0, int var1, int var2, int var3, EntityLiving var4, int var5, int var6, int var7,
boolean var8, boolean var9) {
EnumSet<PathType> var10 = EnumSet.noneOf(PathType.class);
PathType var11 = PathType.BLOCKED;
BlockPosition var12 = var4.getChunkCoordinates();
var11 = a(var0, var1, var2, var3, var5, var6, var7, var8, var9, var10, var11, var12);
if (var10.contains(PathType.FENCE))
return PathType.FENCE;
if (var10.contains(PathType.UNPASSABLE_RAIL))
return PathType.UNPASSABLE_RAIL;
PathType var13 = PathType.BLOCKED;
for (PathType var15 : var10) {
if (mvmt.getPathfindingMalus(var15) < 0.0F)
return var15;
if (mvmt.getPathfindingMalus(var15) >= mvmt.getPathfindingMalus(var13))
var13 = var15;
}
if (var11 == PathType.OPEN && mvmt.getPathfindingMalus(var13) == 0.0F && var5 <= 1)
return PathType.OPEN; return PathType.OPEN;
return var13; return var13;
} }
@ -168,7 +168,7 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
if (var10 - var4 > 1.125D) if (var10 - var4 > 1.125D)
return null; return null;
PathType var12 = a(this.b, var0, var1, var2); PathType var12 = a(this.b, var0, var1, var2);
float var13 = this.b.a(var12); float var13 = this.mvmt.getPathfindingMalus(var12);
double var14 = this.b.getWidth() / 2.0D; double var14 = this.b.getWidth() / 2.0D;
if (var13 >= 0.0F) { if (var13 >= 0.0F) {
var8 = a(var0, var1, var2); var8 = a(var0, var1, var2);
@ -201,7 +201,7 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
if (var12 == PathType.WATER) { if (var12 == PathType.WATER) {
var8 = a(var0, var1, var2); var8 = a(var0, var1, var2);
var8.l = var12; var8.l = var12;
var8.k = Math.max(var8.k, this.b.a(var12)); var8.k = Math.max(var8.k, mvmt.getPathfindingMalus(var12));
continue; continue;
} }
return var8; return var8;
@ -225,7 +225,7 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
return var18; return var18;
} }
var12 = a(this.b, var0, var1, var2); var12 = a(this.b, var0, var1, var2);
var13 = this.b.a(var12); var13 = mvmt.getPathfindingMalus(var12);
if (var12 != PathType.OPEN && var13 >= 0.0F) { if (var12 != PathType.OPEN && var13 >= 0.0F) {
var8 = a(var0, var1, var2); var8 = a(var0, var1, var2);
var8.l = var12; var8.l = var12;
@ -284,7 +284,7 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
int var3 = 0; int var3 = 0;
PathType var4 = a(this.b, var1.a, var1.b + 1, var1.c); PathType var4 = a(this.b, var1.a, var1.b + 1, var1.c);
PathType var5 = a(this.b, var1.a, var1.b, var1.c); PathType var5 = a(this.b, var1.a, var1.b, var1.c);
if (this.b.a(var4) >= 0.0F && var5 != PathType.STICKY_HONEY) if (mvmt.getPathfindingMalus(var4) >= 0.0F && var5 != PathType.STICKY_HONEY)
var3 = MathHelper.d(Math.max(1.0F, this.b.G)); var3 = MathHelper.d(Math.max(1.0F, this.b.G));
double var6 = aa(this.a, new BlockPosition(var1.a, var1.b, var1.c)); double var6 = aa(this.a, new BlockPosition(var1.a, var1.b, var1.c));
PathPoint var8 = a(var1.a, var1.b, var1.c + 1, var3, var6, EnumDirection.SOUTH, var5); PathPoint var8 = a(var1.a, var1.b, var1.c + 1, var3, var6, EnumDirection.SOUTH, var5);
@ -343,7 +343,7 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
} }
BlockPosition var3 = this.b.getChunkCoordinates(); BlockPosition var3 = this.b.getChunkCoordinates();
PathType var4 = a(this.b, var3.getX(), var0, var3.getZ()); PathType var4 = a(this.b, var3.getX(), var0, var3.getZ());
if (this.b.a(var4) < 0.0F) { if (mvmt.getPathfindingMalus(var4) < 0.0F) {
AxisAlignedBB axisAlignedBB = this.b.getBoundingBox(); AxisAlignedBB axisAlignedBB = this.b.getBoundingBox();
if (b(var1.c(axisAlignedBB.minX, var0, axisAlignedBB.minZ)) if (b(var1.c(axisAlignedBB.minX, var0, axisAlignedBB.minZ))
|| b(var1.c(axisAlignedBB.minX, var0, axisAlignedBB.maxZ)) || b(var1.c(axisAlignedBB.minX, var0, axisAlignedBB.maxZ))
@ -351,19 +351,19 @@ public class PlayerPathfinderNormal extends PlayerPathfinderAbstract {
|| b(var1.c(axisAlignedBB.maxX, var0, axisAlignedBB.maxZ))) { || b(var1.c(axisAlignedBB.maxX, var0, axisAlignedBB.maxZ))) {
PathPoint var6 = a(var1); PathPoint var6 = a(var1);
var6.l = a(this.b, var6.a()); var6.l = a(this.b, var6.a());
var6.k = this.b.a(var6.l); var6.k = mvmt.getPathfindingMalus(var6.l);
return var6; return var6;
} }
} }
PathPoint var5 = a(var3.getX(), var0, var3.getZ()); PathPoint var5 = a(var3.getX(), var0, var3.getZ());
var5.l = a(this.b, var5.a()); var5.l = a(this.b, var5.a());
var5.k = this.b.a(var5.l); var5.k = mvmt.getPathfindingMalus(var5.l);
return var5; return var5;
} }
private boolean b(BlockPosition var0) { private boolean b(BlockPosition var0) {
PathType var1 = a(this.b, var0); PathType var1 = a(this.b, var0);
return (this.b.a(var1) >= 0.0F); return (mvmt.getPathfindingMalus(var1) >= 0.0F);
} }
public static PathType a(IBlockAccess var0, BlockPosition.MutableBlockPosition var1) { public static PathType a(IBlockAccess var0, BlockPosition.MutableBlockPosition var1) {

View File

@ -0,0 +1,177 @@
package net.citizensnpcs.nms.v1_16_R3.util;
import java.util.Map;
import com.google.common.collect.Maps;
import net.citizensnpcs.Settings.Setting;
import net.minecraft.server.v1_16_R3.ControllerJump;
import net.minecraft.server.v1_16_R3.ControllerMove;
import net.minecraft.server.v1_16_R3.Entity;
import net.minecraft.server.v1_16_R3.EntityInsentient;
import net.minecraft.server.v1_16_R3.EntityLiving;
import net.minecraft.server.v1_16_R3.GenericAttributes;
import net.minecraft.server.v1_16_R3.NavigationAbstract;
import net.minecraft.server.v1_16_R3.PathType;
public interface MobAI {
org.bukkit.entity.Entity getBukkitEntity();
ControllerJump getJumpControl();
Map<PathType, Float> getMalus();
ControllerMove getMoveControl();
NavigationAbstract getNavigation();
default float getPathfindingMalus(PathType var1) {
Map<PathType, Float> malus = getMalus();
return malus.containsKey(var1) ? malus.get(var1) : var1.a();
}
default void setPathfindingMalus(PathType water, float oldWaterCost) {
getMalus().put(water, oldWaterCost);
}
default void tickAI() {
getJumpControl().b();
getMoveControl().a();
NavigationAbstract navigation = getNavigation();
if (!NMSImpl.isNavigationFinished(navigation)) {
NMSImpl.updateNavigation(navigation);
}
}
default void updatePathfindingRange(float range) {
((EntityLiving) NMSImpl.getHandle(getBukkitEntity())).getAttributeInstance(GenericAttributes.FOLLOW_RANGE)
.setValue(range);
}
public static class BasicMobAI implements MobAI {
private final EntityJumpControl controllerJump;
private final EntityMoveControl controllerMove;
private final EntityLiving entity;
private final Map<PathType, Float> malus;
private final EntityNavigation navigation;
public BasicMobAI(EntityLiving entity) {
this.entity = entity;
NMSImpl.setAttribute(entity, GenericAttributes.FOLLOW_RANGE, Setting.DEFAULT_PATHFINDING_RANGE.asDouble());
entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.3D);
controllerJump = new EntityJumpControl(entity);
controllerMove = new EntityMoveControl(entity);
navigation = new EntityNavigation(entity, entity.world);
malus = Maps.newEnumMap(PathType.class);
}
@Override
public org.bukkit.entity.Entity getBukkitEntity() {
return entity.getBukkitEntity();
}
@Override
public ControllerJump getJumpControl() {
return controllerJump;
}
@Override
public Map<PathType, Float> getMalus() {
return malus;
}
@Override
public ControllerMove getMoveControl() {
return controllerMove;
}
@Override
public NavigationAbstract getNavigation() {
return navigation;
}
}
public static interface ForwardingMobAI extends MobAI {
MobAI getAI();
@Override
default org.bukkit.entity.Entity getBukkitEntity() {
return getAI().getBukkitEntity();
}
@Override
default ControllerJump getJumpControl() {
return getAI().getJumpControl();
}
@Override
default Map<PathType, Float> getMalus() {
return getAI().getMalus();
}
@Override
default ControllerMove getMoveControl() {
return getAI().getMoveControl();
}
@Override
default NavigationAbstract getNavigation() {
return getAI().getNavigation();
}
}
public static MobAI from(Entity handle) {
if (handle instanceof EntityInsentient) {
EntityInsentient mob = (EntityInsentient) handle;
return new MobAI() {
@Override
public org.bukkit.entity.Entity getBukkitEntity() {
return mob.getBukkitEntity();
}
@Override
public ControllerJump getJumpControl() {
return mob.getControllerJump();
}
@Override
public Map<PathType, Float> getMalus() {
return null;
}
@Override
public ControllerMove getMoveControl() {
return mob.getControllerMove();
}
@Override
public NavigationAbstract getNavigation() {
return mob.getNavigation();
}
@Override
public float getPathfindingMalus(PathType var1) {
return mob.a(var1);
}
@Override
public void setPathfindingMalus(PathType water, float oldWaterCost) {
mob.a(water, oldWaterCost);
}
@Override
public void tickAI() {
mob.getEntitySenses().a();
NMSImpl.updateNavigation(mob.getNavigation());
mob.getControllerMove().a();
mob.getControllerLook().a();
mob.getControllerJump().b();
}
};
} else if (handle instanceof MobAI) {
return (MobAI) handle;
}
return null;
}
}

View File

@ -57,6 +57,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;
@ -238,7 +239,10 @@ import net.citizensnpcs.util.NMSBridge;
import net.citizensnpcs.util.PlayerAnimation; import net.citizensnpcs.util.PlayerAnimation;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
import net.minecraft.server.v1_16_R3.AdvancementDataPlayer; import net.minecraft.server.v1_16_R3.AdvancementDataPlayer;
import net.minecraft.server.v1_16_R3.AttributeBase;
import net.minecraft.server.v1_16_R3.AttributeMapBase;
import net.minecraft.server.v1_16_R3.AttributeModifiable; import net.minecraft.server.v1_16_R3.AttributeModifiable;
import net.minecraft.server.v1_16_R3.AttributeProvider;
import net.minecraft.server.v1_16_R3.AxisAlignedBB; import net.minecraft.server.v1_16_R3.AxisAlignedBB;
import net.minecraft.server.v1_16_R3.BehaviorController; import net.minecraft.server.v1_16_R3.BehaviorController;
import net.minecraft.server.v1_16_R3.Block; import net.minecraft.server.v1_16_R3.Block;
@ -414,14 +418,15 @@ 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 EntityInsentient) { MobAI ai = MobAI.from(handle);
if (ai.getMoveControl() instanceof EntityMoveControl) {
((EntityMoveControl) ai.getMoveControl()).f = false;
} else {
try { try {
MOVE_CONTROLLER_MOVING.invoke(((EntityInsentient) handle).getControllerMove(), null); MOVE_CONTROLLER_MOVING.invoke(ai.getMoveControl(), null);
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).getControllerMove().f = false;
} }
} }
@ -548,7 +553,7 @@ public class NMSImpl implements NMSBridge {
public Location getDestination(org.bukkit.entity.Entity entity) { public Location getDestination(org.bukkit.entity.Entity entity) {
Entity handle = getHandle(entity); Entity handle = getHandle(entity);
ControllerMove controller = handle instanceof EntityInsentient ? ((EntityInsentient) handle).getControllerMove() ControllerMove controller = handle instanceof EntityInsentient ? ((EntityInsentient) handle).getControllerMove()
: handle instanceof EntityHumanNPC ? ((EntityHumanNPC) handle).getControllerMove() : null; : handle instanceof MobAI ? ((MobAI) handle).getMoveControl() : null;
if (controller == null || !controller.b()) { if (controller == null || !controller.b()) {
return null; return null;
} }
@ -709,11 +714,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 NavigationAbstract navigation = NMSImpl.getNavigation(entity); final NavigationAbstract navigation = NMSImpl.getNavigation(entity);
final float oldWater = raw instanceof EntityPlayer ? ((EntityHumanNPC) raw).a(PathType.WATER) final float oldWater = raw instanceof EntityPlayer ? ((MobAI) raw).getPathfindingMalus(PathType.WATER)
: ((EntityInsentient) raw).a(PathType.WATER); : ((EntityInsentient) raw).a(PathType.WATER);
if (params.avoidWater() && oldWater >= 0) { if (params.avoidWater() && oldWater >= 0) {
if (raw instanceof EntityPlayer) { if (raw instanceof MobAI) {
((EntityHumanNPC) raw).a(PathType.WATER, oldWater + 1F); ((MobAI) raw).setPathfindingMalus(PathType.WATER, oldWater + 1F);
} else { } else {
((EntityInsentient) raw).a(PathType.WATER, oldWater + 1F); ((EntityInsentient) raw).a(PathType.WATER, oldWater + 1F);
} }
@ -750,8 +755,8 @@ public class NMSImpl implements NMSBridge {
Util.sendBlockChanges(blocks, null); Util.sendBlockChanges(blocks, null);
} }
if (oldWater >= 0) { if (oldWater >= 0) {
if (raw instanceof EntityPlayer) { if (raw instanceof MobAI) {
((EntityHumanNPC) raw).a(PathType.WATER, oldWater); ((MobAI) raw).setPathfindingMalus(PathType.WATER, oldWater);
} else { } else {
((EntityInsentient) raw).a(PathType.WATER, oldWater); ((EntityInsentient) raw).a(PathType.WATER, oldWater);
} }
@ -993,7 +998,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 EntityInsentient) && !(handle instanceof EntityHumanNPC))) { || (!(handle instanceof EntityInsentient) && !(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();
@ -1027,8 +1032,8 @@ public class NMSImpl implements NMSBridge {
while (((EntityLiving) handle).aC < -180F) { while (((EntityLiving) handle).aC < -180F) {
((EntityLiving) handle).aC += 360F; ((EntityLiving) handle).aC += 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);
} }
} }
@ -1036,7 +1041,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 EntityInsentient) && !(handle instanceof EntityHumanNPC))) { || (!(handle instanceof EntityInsentient) && !(handle instanceof MobAI))) {
if (to instanceof LivingEntity) { if (to instanceof LivingEntity) {
look(from, ((LivingEntity) to).getEyeLocation(), false, true); look(from, ((LivingEntity) to).getEyeLocation(), false, true);
} else { } else {
@ -1051,8 +1056,8 @@ public class NMSImpl implements NMSBridge {
while (((EntityLiving) handle).aC < -180F) { while (((EntityLiving) handle).aC < -180F) {
((EntityLiving) handle).aC += 360F; ((EntityLiving) handle).aC += 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);
} }
} }
@ -1304,8 +1309,8 @@ public class NMSImpl implements NMSBridge {
return; return;
if (handle instanceof EntityInsentient) { if (handle instanceof EntityInsentient) {
((EntityInsentient) handle).getControllerMove().a(x, y, z, speed); ((EntityInsentient) handle).getControllerMove().a(x, y, z, speed);
} else if (handle instanceof EntityHumanNPC) { } else if (handle instanceof MobAI) {
((EntityHumanNPC) handle).setMoveDestination(x, y, z, speed); ((MobAI) handle).getMoveControl().a(x, y, z, speed);
} }
} }
@ -1431,8 +1436,8 @@ public class NMSImpl implements NMSBridge {
if (handle instanceof EntityInsentient) { if (handle instanceof EntityInsentient) {
ControllerJump controller = ((EntityInsentient) handle).getControllerJump(); ControllerJump controller = ((EntityInsentient) handle).getControllerJump();
controller.jump(); controller.jump();
} else if (handle instanceof EntityHumanNPC) { } else if (handle instanceof MobAI) {
((EntityHumanNPC) handle).setShouldJump(); ((MobAI) handle).getJumpControl().jump();
} }
} }
@ -1642,10 +1647,8 @@ public class NMSImpl implements NMSBridge {
if (!npc.isSpawned() || !npc.getEntity().getType().isAlive()) if (!npc.isSpawned() || !npc.getEntity().getType().isAlive())
return; return;
EntityLiving en = NMSImpl.getHandle((LivingEntity) npc.getEntity()); EntityLiving en = NMSImpl.getHandle((LivingEntity) npc.getEntity());
if (!(en instanceof EntityInsentient)) { if (en instanceof MobAI) {
if (en instanceof EntityHumanNPC) { ((MobAI) en).updatePathfindingRange(pathfindingRange);
((EntityHumanNPC) en).updatePathfindingRange(pathfindingRange);
}
return; return;
} }
if (NAVIGATION_S == null) if (NAVIGATION_S == null)
@ -2005,7 +2008,7 @@ public class NMSImpl implements NMSBridge {
public static NavigationAbstract getNavigation(org.bukkit.entity.Entity entity) { public static NavigationAbstract getNavigation(org.bukkit.entity.Entity entity) {
Entity handle = getHandle(entity); Entity handle = getHandle(entity);
return handle instanceof EntityInsentient ? ((EntityInsentient) handle).getNavigation() return handle instanceof EntityInsentient ? ((EntityInsentient) handle).getNavigation()
: handle instanceof EntityHumanNPC ? ((EntityHumanNPC) handle).getNavigation() : null; : handle instanceof MobAI ? ((MobAI) handle).getNavigation() : null;
} }
public static DataWatcherObject<Integer> getRabbitTypeField() { public static DataWatcherObject<Integer> getRabbitTypeField() {
@ -2153,6 +2156,30 @@ public class NMSImpl implements NMSBridge {
} }
} }
public static void setAttribute(EntityLiving entity, AttributeBase attribute, double value) {
AttributeModifiable range = entity.getAttributeInstance(attribute);
if (range == null) {
try {
AttributeProvider provider = (AttributeProvider) ATTRIBUTE_MAP.invoke(entity.getAttributeMap());
Map<AttributeBase, AttributeModifiable> all = Maps
.newHashMap((Map<AttributeBase, AttributeModifiable>) ATTRIBUTE_PROVIDER_MAP.invoke(provider));
all.put(GenericAttributes.FOLLOW_RANGE,
new AttributeModifiable(GenericAttributes.FOLLOW_RANGE, new Consumer<AttributeModifiable>() {
@Override
public void accept(AttributeModifiable 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 = entity.getAttributeMap().a(attribute);
}
range.setValue(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);
@ -2218,8 +2245,8 @@ public class NMSImpl implements NMSBridge {
handle.getControllerMove().a(); handle.getControllerMove().a();
handle.getControllerLook().a(); handle.getControllerLook().a();
handle.getControllerJump().b(); handle.getControllerJump().b();
} else if (entity instanceof EntityHumanNPC) { } else if (entity instanceof MobAI) {
((EntityHumanNPC) entity).updateAI(); ((MobAI) entity).tickAI();
} }
} }
@ -2249,6 +2276,12 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle ADVANCEMENT_PLAYER_FIELD = NMS.getFinalSetter(EntityPlayer.class, private static final MethodHandle ADVANCEMENT_PLAYER_FIELD = NMS.getFinalSetter(EntityPlayer.class,
"advancementDataPlayer"); "advancementDataPlayer");
private static final MethodHandle ATTRIBUTE_MAP = NMS.getGetter(AttributeMapBase.class, "d");
private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getGetter(AttributeProvider.class, "a");
private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeProvider.class, "a");
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_16_R3.util;
import net.citizensnpcs.nms.v1_16_R3.entity.EntityHumanNPC;
public class PlayerControllerJump {
private boolean a;
private final EntityHumanNPC b;
public PlayerControllerJump(EntityHumanNPC entityinsentient) {
this.b = entityinsentient;
}
public void b() {
this.b.setJumping(this.a);
this.a = false;
}
public void jump() {
this.a = true;
}
}

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_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.MobAI;
import net.citizensnpcs.nms.v1_17_R1.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
@ -43,7 +45,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) {
@ -53,6 +56,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 (ai != null) {
ai = new BasicMobAI(this);
}
}
@Override
public MobAI getAI() {
return ai;
} }
@Override @Override
@ -118,6 +129,7 @@ public class ArmorStandController extends MobEntityController {
super.tick(); super.tick();
if (npc != null) { if (npc != null) {
npc.update(); npc.update();
ai.tickAI();
} }
} }

View File

@ -12,7 +12,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -223,7 +223,7 @@ public class AxolotlController 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_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -124,7 +124,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

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -206,7 +206,7 @@ public class DolphinController 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

@ -5,7 +5,6 @@ import java.lang.invoke.MethodHandle;
import java.net.Socket; import java.net.Socket;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -16,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;
@ -24,7 +22,6 @@ import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPC.NPCUpdate; import net.citizensnpcs.api.npc.NPC.NPCUpdate;
import net.citizensnpcs.api.trait.trait.Inventory; import net.citizensnpcs.api.trait.trait.Inventory;
@ -33,10 +30,9 @@ import net.citizensnpcs.nms.v1_17_R1.network.EmptyNetHandler;
import net.citizensnpcs.nms.v1_17_R1.network.EmptyNetworkManager; import net.citizensnpcs.nms.v1_17_R1.network.EmptyNetworkManager;
import net.citizensnpcs.nms.v1_17_R1.util.EmptyAdvancementDataPlayer; import net.citizensnpcs.nms.v1_17_R1.util.EmptyAdvancementDataPlayer;
import net.citizensnpcs.nms.v1_17_R1.util.EmptyServerStatsCounter; import net.citizensnpcs.nms.v1_17_R1.util.EmptyServerStatsCounter;
import net.citizensnpcs.nms.v1_17_R1.util.MobAI;
import net.citizensnpcs.nms.v1_17_R1.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerControllerJump;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerNavigation;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerlistTracker; import net.citizensnpcs.nms.v1_17_R1.util.PlayerlistTracker;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
@ -62,26 +58,16 @@ import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.EquipmentSlot;
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.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 PlayerlistTracker playerlistTracker; private PlayerlistTracker playerlistTracker;
@ -93,6 +79,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
this.npc = (CitizensNPC) npc; this.npc = (CitizensNPC) npc;
if (npc != null) { if (npc != null) {
skinTracker = new SkinPacketTracker(this); skinTracker = new SkinPacketTracker(this);
ai = new BasicMobAI(this);
try { try {
GAMEMODE_SETTING.invoke(gameMode, GameType.SURVIVAL, null); GAMEMODE_SETTING.invoke(gameMode, GameType.SURVIVAL, null);
} catch (Throwable e) { } catch (Throwable e) {
@ -112,11 +99,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return super.broadcastToPlayer(entityplayer); return super.broadcastToPlayer(entityplayer);
} }
public boolean canCutCorner(BlockPathTypes pathtype) {
return (pathtype != BlockPathTypes.DANGER_FIRE && pathtype != BlockPathTypes.DANGER_CACTUS
&& 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,8 +131,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
}, 15); // give enough time for death and smoke animation }, 15); // give enough time for death and smoke animation
} }
@Override @Override
public void doTick() { public void doTick() {
if (npc == null) { if (npc == null) {
@ -158,7 +138,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))
@ -170,12 +150,13 @@ 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(); ai.getJumpControl().tick();
ai.getMoveControl().tick();
if (isSpectator()) { if (isSpectator()) {
this.noPhysics = true; this.noPhysics = true;
this.onGround = false; this.onGround = false;
@ -204,6 +185,11 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return super.getAddEntityPacket(); return super.getAddEntityPacket();
} }
@Override
public MobAI getAI() {
return ai;
}
@Override @Override
public CraftPlayer getBukkitEntity() { public CraftPlayer getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) { if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
@ -212,10 +198,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);
@ -226,23 +208,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();
@ -304,31 +274,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, new Consumer<AttributeInstance>() {
@Override
public void accept(AttributeInstance 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);
@ -346,10 +291,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() return npc == null ? super.isPushable()
@ -416,18 +357,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) {
this.malus.put(pathtype, f);
}
public void setShouldJump() {
controllerJump.jump();
}
@Override @Override
public void setSkinFlags(byte flags) { public void setSkinFlags(byte flags) {
this.getEntityData().set(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION, flags); this.getEntityData().set(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION, flags);
@ -472,11 +401,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} }
} }
public void updateAI() {
controllerMove.tick();
controllerJump.b();
}
private void updatePackets(boolean navigating) { private void updatePackets(boolean navigating) {
if (!npc.isUpdating(NPCUpdate.PACKET)) if (!npc.isUpdating(NPCUpdate.PACKET))
return; return;
@ -502,10 +426,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
NMSImpl.sendPacketsNearby(getBukkitEntity(), current, packets); NMSImpl.sendPacketsNearby(getBukkitEntity(), current, 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 CraftServer cserver; private final CraftServer cserver;
private final CitizensNPC npc; private final CitizensNPC npc;
@ -583,12 +503,9 @@ 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);
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0); private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
} }

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -58,7 +58,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);
} }
} }
@ -205,7 +205,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_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -76,7 +76,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_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -122,7 +122,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_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -116,7 +116,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_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -58,7 +58,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);
} }
} }
@ -206,7 +206,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_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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 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_17_R1.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_17_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_17_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl; import net.citizensnpcs.nms.v1_17_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_17_R1.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_17_R1.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;
@ -105,7 +105,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_17_R1.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 entityinsentient) {
super(new Slime(EntityType.SLIME, entityinsentient.level));
this.b = entityinsentient;
}
@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_17_R1.util;
import java.util.Random; import java.util.Random;
import net.citizensnpcs.nms.v1_17_R1.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;
@ -13,7 +12,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;
@ -22,7 +21,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;
@ -122,11 +121,7 @@ public class PlayerMoveControl extends MoveControl {
if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 1.0D)) { if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 1.0D)) {
this.jumpTicks = jumpTicks(); this.jumpTicks = jumpTicks();
this.jumpTicks /= 3; this.jumpTicks /= 3;
if (this.entity instanceof EntityHumanNPC) { entity.setJumping(true);
((EntityHumanNPC) this.entity).getControllerJump().jump();
} else {
((Mob) this.entity).getJumpControl().jump();
}
} }
} }
} }

View File

@ -7,13 +7,13 @@ import java.util.stream.Stream;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.nms.v1_17_R1.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.LivingEntity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
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;
@ -31,7 +31,7 @@ import net.minecraft.world.level.pathfinder.PathFinder;
import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; import net.minecraft.world.level.pathfinder.WalkNodeEvaluator;
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;
@ -39,13 +39,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;
protected final EntityHumanNPC mob; protected 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;
@ -55,17 +55,22 @@ 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(getDummyInsentient(entityinsentient, 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, Setting.MAXIMUM_VISITED_NODES.asInt()); this.pathFinder = new EntityPathfinder(this.nodeEvaluator, Setting.MAXIMUM_VISITED_NODES.asInt());
this.setRange(24); this.setRange(24);
} }
public boolean canCutCorner(BlockPathTypes pathtype) {
return (pathtype != BlockPathTypes.DANGER_FIRE && pathtype != BlockPathTypes.DANGER_CACTUS
&& pathtype != BlockPathTypes.DANGER_OTHER && pathtype != BlockPathTypes.WALKABLE_DOOR);
}
@Override @Override
public boolean canFloat() { public boolean canFloat() {
return this.nodeEvaluator.canFloat(); return this.nodeEvaluator.canFloat();
@ -165,7 +170,7 @@ public class PlayerNavigation extends PathNavigation {
return false; return false;
var19 = this.nodeEvaluator.getBlockPathType(this.level, var13, var1, var14, this.mob, var3, var4, var19 = this.nodeEvaluator.getBlockPathType(this.level, var13, var1, var14, this.mob, var3, var4,
var5, true, true); var5, true, true);
float var20 = this.mob.getPathfindingMalus(var19); float var20 = this.mvmt.getPathfindingMalus(var19);
if (var20 < 0.0F || var20 >= 8.0F) if (var20 < 0.0F || var20 >= 8.0F)
return false; return false;
if (var19 == BlockPathTypes.DAMAGE_FIRE || var19 == BlockPathTypes.DANGER_FIRE if (var19 == BlockPathTypes.DAMAGE_FIRE || var19 == BlockPathTypes.DANGER_FIRE
@ -287,7 +292,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);
} }
@ -529,7 +534,7 @@ public class PlayerNavigation extends PathNavigation {
return; return;
Vec3 var0 = this.path.getNextEntityPos(this.mob); Vec3 var0 = this.path.getNextEntityPos(this.mob);
BlockPos var1 = new BlockPos(var0); BlockPos var1 = new BlockPos(var0);
this.mob.getMoveControl().setWantedPosition(var0.x, this.level.getBlockState(var1.down()).isAir() ? var0.y this.mvmt.getMoveControl().setWantedPosition(var0.x, this.level.getBlockState(var1.down()).isAir() ? var0.y
: WalkNodeEvaluator.getFloorLevel(this.level, var1), var0.z, this.speedModifier); : WalkNodeEvaluator.getFloorLevel(this.level, var1), var0.z, this.speedModifier);
} }
@ -554,7 +559,7 @@ public class PlayerNavigation extends PathNavigation {
} }
} }
private static Mob getDummyInsentient(EntityHumanNPC from, Level world) { private static Mob getDummyInsentient(LivingEntity from, Level world) {
return new Mob(EntityType.VILLAGER, world) { return new Mob(EntityType.VILLAGER, world) {
}; };
} }

View File

@ -7,12 +7,12 @@ import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.longs.Long2ObjectOpenHa
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2BooleanMap; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2BooleanMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
import net.citizensnpcs.nms.v1_17_R1.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.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;
@ -34,7 +34,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 Long2ObjectMap<BlockPathTypes> l = new Long2ObjectOpenHashMap<BlockPathTypes>(); private final Long2ObjectMap<BlockPathTypes> l = new Long2ObjectOpenHashMap<BlockPathTypes>();
private final Object2BooleanMap<AABB> m = new Object2BooleanOpenHashMap<AABB>(); private final Object2BooleanMap<AABB> m = new Object2BooleanOpenHashMap<AABB>();
protected float oldWaterCost; protected float oldWaterCost;
@ -54,7 +54,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
@Override @Override
public void done() { public void done() {
this.mob.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost); this.mvmt.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost);
this.l.clear(); this.l.clear();
this.m.clear(); this.m.clear();
super.done(); super.done();
@ -84,7 +84,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
if (var10 - var4 > 1.125D) if (var10 - var4 > 1.125D)
return null; return null;
BlockPathTypes var12 = getCachedBlockType(this.mob, var0, var1, var2); BlockPathTypes var12 = getCachedBlockType(this.mob, var0, var1, var2);
float var13 = this.mob.getPathfindingMalus(var12); float var13 = this.mvmt.getPathfindingMalus(var12);
double var14 = this.mob.getBbWidth() / 2.0D; double var14 = this.mob.getBbWidth() / 2.0D;
if (var13 >= 0.0F) { if (var13 >= 0.0F) {
var8 = getNode(var0, var1, var2); var8 = getNode(var0, var1, var2);
@ -121,7 +121,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
if (var12 == BlockPathTypes.WATER) { if (var12 == BlockPathTypes.WATER) {
var8 = getNode(var0, var1, var2); var8 = getNode(var0, var1, var2);
var8.type = var12; var8.type = var12;
var8.costMalus = Math.max(var8.costMalus, this.mob.getPathfindingMalus(var12)); var8.costMalus = Math.max(var8.costMalus, this.mvmt.getPathfindingMalus(var12));
continue; continue;
} }
return var8; return var8;
@ -145,7 +145,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return var18; return var18;
} }
var12 = getCachedBlockType(this.mob, var0, var1, var2); var12 = 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 = getNode(var0, var1, var2); var8 = getNode(var0, var1, var2);
var8.type = var12; var8.type = var12;
@ -174,8 +174,8 @@ 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, int var5,
int var5, int var6, int var7, boolean var8, boolean var9) { int var6, int var7, boolean var8, boolean var9) {
EnumSet<BlockPathTypes> var10 = EnumSet.noneOf(BlockPathTypes.class); EnumSet<BlockPathTypes> var10 = EnumSet.noneOf(BlockPathTypes.class);
BlockPathTypes var11 = BlockPathTypes.BLOCKED; BlockPathTypes var11 = BlockPathTypes.BLOCKED;
BlockPos var12 = var4.blockPosition(); BlockPos var12 = var4.blockPosition();
@ -186,12 +186,12 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return BlockPathTypes.UNPASSABLE_RAIL; return BlockPathTypes.UNPASSABLE_RAIL;
BlockPathTypes var13 = BlockPathTypes.BLOCKED; BlockPathTypes var13 = BlockPathTypes.BLOCKED;
for (BlockPathTypes var15 : var10) { for (BlockPathTypes var15 : var10) {
if (var4.getPathfindingMalus(var15) < 0.0F) if (mvmt.getPathfindingMalus(var15) < 0.0F)
return var15; return var15;
if (var4.getPathfindingMalus(var15) >= var4.getPathfindingMalus(var13)) if (mvmt.getPathfindingMalus(var15) >= mvmt.getPathfindingMalus(var13))
var13 = var15; var13 = var15;
} }
if (var11 == BlockPathTypes.OPEN && var4.getPathfindingMalus(var13) == 0.0F && var5 <= 1) if (var11 == BlockPathTypes.OPEN && mvmt.getPathfindingMalus(var13) == 0.0F && var5 <= 1)
return BlockPathTypes.OPEN; return BlockPathTypes.OPEN;
return var13; return var13;
} }
@ -219,12 +219,12 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return var13; return var13;
} }
private BlockPathTypes getBlockPathType(EntityHumanNPC var0, BlockPos var1) { private BlockPathTypes getBlockPathType(LivingEntity var0, BlockPos var1) {
return getCachedBlockType(var0, var1.getX(), var1.getY(), var1.getZ()); return getCachedBlockType(var0, var1.getX(), var1.getY(), var1.getZ());
} }
public BlockPathTypes getBlockPathTypee(BlockGetter var0, int var1, int var2, int var3, EntityHumanNPC var4, public BlockPathTypes getBlockPathTypee(BlockGetter var0, int var1, int var2, int var3, LivingEntity var4, int var5,
int var5, int var6, int var7, boolean var8, boolean var9) { int var6, int var7, boolean var8, boolean var9) {
EnumSet<BlockPathTypes> var10 = EnumSet.noneOf(BlockPathTypes.class); EnumSet<BlockPathTypes> var10 = EnumSet.noneOf(BlockPathTypes.class);
BlockPathTypes var11 = BlockPathTypes.BLOCKED; BlockPathTypes var11 = BlockPathTypes.BLOCKED;
BlockPos var12 = var4.blockPosition(); BlockPos var12 = var4.blockPosition();
@ -235,12 +235,12 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return BlockPathTypes.UNPASSABLE_RAIL; return BlockPathTypes.UNPASSABLE_RAIL;
BlockPathTypes var13 = BlockPathTypes.BLOCKED; BlockPathTypes var13 = BlockPathTypes.BLOCKED;
for (BlockPathTypes var15 : var10) { for (BlockPathTypes var15 : var10) {
if (var4.getPathfindingMalus(var15) < 0.0F) if (mvmt.getPathfindingMalus(var15) < 0.0F)
return var15; return var15;
if (var4.getPathfindingMalus(var15) >= var4.getPathfindingMalus(var13)) if (mvmt.getPathfindingMalus(var15) >= mvmt.getPathfindingMalus(var13))
var13 = var15; var13 = var15;
} }
if (var11 == BlockPathTypes.OPEN && var4.getPathfindingMalus(var13) == 0.0F && var5 <= 1) if (var11 == BlockPathTypes.OPEN && mvmt.getPathfindingMalus(var13) == 0.0F && var5 <= 1)
return BlockPathTypes.OPEN; return BlockPathTypes.OPEN;
return var13; return var13;
} }
@ -264,7 +264,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return var10; return var10;
} }
protected BlockPathTypes getCachedBlockType(EntityHumanNPC var0, int var1, int var2, int var3) { protected BlockPathTypes getCachedBlockType(LivingEntity var0, int var1, int var2, int var3) {
return this.l.computeIfAbsent(BlockPos.asLong(var1, var2, var3), return this.l.computeIfAbsent(BlockPos.asLong(var1, var2, var3),
var4 -> getBlockPathType(this.level, var1, var2, var3, var0, this.entityWidth, this.entityHeight, var4 -> getBlockPathType(this.level, var1, var2, var3, var0, this.entityWidth, this.entityHeight,
this.entityDepth, canOpenDoors(), canPassDoors())); this.entityDepth, canOpenDoors(), canPassDoors()));
@ -291,7 +291,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
int var3 = 0; int var3 = 0;
BlockPathTypes var4 = getCachedBlockType(this.mob, var1.x, var1.y + 1, var1.z); BlockPathTypes var4 = getCachedBlockType(this.mob, var1.x, var1.y + 1, var1.z);
BlockPathTypes var5 = getCachedBlockType(this.mob, var1.x, var1.y, var1.z); BlockPathTypes var5 = 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));
double var6 = getFloorLevel(new BlockPos(var1.x, var1.y, var1.z)); double var6 = getFloorLevel(new BlockPos(var1.x, var1.y, var1.z));
Node var8 = findAcceptedNode(var1.x, var1.y, var1.z + 1, var3, var6, Direction.SOUTH, var5); Node var8 = findAcceptedNode(var1.x, var1.y, var1.z + 1, var3, var6, Direction.SOUTH, var5);
@ -350,7 +350,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
} }
BlockPos var3 = this.mob.blockPosition(); BlockPos var3 = this.mob.blockPosition();
BlockPathTypes var4 = getCachedBlockType(this.mob, var3.getX(), var0, var3.getZ()); BlockPathTypes var4 = getCachedBlockType(this.mob, var3.getX(), var0, var3.getZ());
if (this.mob.getPathfindingMalus(var4) < 0.0F) { if (this.mvmt.getPathfindingMalus(var4) < 0.0F) {
AABB aABB = this.mob.getBoundingBox(); AABB aABB = this.mob.getBoundingBox();
if (hasPositiveMalus(var1.set(aABB.minX, var0, aABB.minZ)) if (hasPositiveMalus(var1.set(aABB.minX, var0, aABB.minZ))
|| hasPositiveMalus(var1.set(aABB.minX, var0, aABB.maxZ)) || hasPositiveMalus(var1.set(aABB.minX, var0, aABB.maxZ))
@ -358,13 +358,13 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
|| hasPositiveMalus(var1.set(aABB.maxX, var0, aABB.maxZ))) { || hasPositiveMalus(var1.set(aABB.maxX, var0, aABB.maxZ))) {
Node var6 = getNode(var1); Node var6 = getNode(var1);
var6.type = getBlockPathType(this.mob, var6.asBlockPos()); var6.type = getBlockPathType(this.mob, var6.asBlockPos());
var6.costMalus = this.mob.getPathfindingMalus(var6.type); var6.costMalus = this.mvmt.getPathfindingMalus(var6.type);
return var6; return var6;
} }
} }
Node var5 = getNode(var3.getX(), var0, var3.getZ()); Node var5 = getNode(var3.getX(), var0, var3.getZ());
var5.type = getBlockPathType(this.mob, var5.asBlockPos()); var5.type = getBlockPathType(this.mob, var5.asBlockPos());
var5.costMalus = this.mob.getPathfindingMalus(var5.type); var5.costMalus = this.mvmt.getPathfindingMalus(var5.type);
return var5; return var5;
} }
@ -374,7 +374,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
private boolean hasPositiveMalus(BlockPos var0) { private boolean hasPositiveMalus(BlockPos var0) {
BlockPathTypes var1 = getBlockPathType(this.mob, var0); BlockPathTypes var1 = getBlockPathType(this.mob, var0);
return (this.mob.getPathfindingMalus(var1) >= 0.0F); return (this.mvmt.getPathfindingMalus(var1) >= 0.0F);
} }
protected boolean isAmphibious() { protected boolean isAmphibious() {

View File

@ -3,15 +3,15 @@ package net.citizensnpcs.nms.v1_17_R1.util;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.citizensnpcs.nms.v1_17_R1.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 final Int2ObjectMap<Node> c = new Int2ObjectOpenHashMap(); protected final Int2ObjectMap<Node> c = new Int2ObjectOpenHashMap();
protected boolean canFloat; protected boolean canFloat;
protected boolean canOpenDoors; protected boolean canOpenDoors;
@ -20,7 +20,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;
@Override @Override
public boolean canFloat() { public boolean canFloat() {
@ -41,6 +42,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
@ -53,9 +55,10 @@ public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator {
return this.c.computeIfAbsent(Node.createHash(var0, var1, var2), var3 -> new Node(var0, var1, var2)); return this.c.computeIfAbsent(Node.createHash(var0, var1, var2), var3 -> new Node(var0, var1, var2));
} }
public void prepare(PathNavigationRegion var0, EntityHumanNPC var1) { public void prepare(PathNavigationRegion var0, LivingEntity var1) {
this.level = var0; this.level = var0;
this.mob = var1; this.mob = var1;
this.mvmt = MobAI.from(var1);
this.c.clear(); this.c.clear();
this.entityWidth = Mth.floor(var1.getBbWidth() + 1.0F); this.entityWidth = Mth.floor(var1.getBbWidth() + 1.0F);
this.entityHeight = Mth.floor(var1.getBbHeight() + 1.0F); this.entityHeight = Mth.floor(var1.getBbHeight() + 1.0F);

View File

@ -14,10 +14,10 @@ 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_17_R1.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.util.profiling.metrics.MetricCategory; import net.minecraft.util.profiling.metrics.MetricCategory;
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;
@ -26,27 +26,27 @@ 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() { public EntityPathfinder() {
super(null, Setting.MAXIMUM_VISITED_NODES.asInt()); super(null, Setting.MAXIMUM_VISITED_NODES.asInt());
this.nodeEvaluator = new PlayerNodeEvaluator(); this.nodeEvaluator = new EntityNodeEvaluator();
this.openSet = new BinaryHeap(); this.openSet = new BinaryHeap();
this.maxVisitedNodes = Setting.MAXIMUM_VISITED_NODES.asInt(); this.maxVisitedNodes = Setting.MAXIMUM_VISITED_NODES.asInt();
} }
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_17_R1.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

@ -54,6 +54,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;
@ -278,10 +279,12 @@ 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.MoveControl; import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.ai.goal.GoalSelector; import net.minecraft.world.entity.ai.goal.GoalSelector;
import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation;
@ -429,14 +432,15 @@ 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);
if (ai.getMoveControl() instanceof EntityMoveControl) {
((EntityMoveControl) ai.getMoveControl()).moving = false;
} else {
try { try {
MOVE_CONTROLLER_MOVING.invoke(((Mob) handle).getMoveControl(), null); MOVE_CONTROLLER_MOVING.invoke(ai.getMoveControl(), null);
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).getMoveControl().moving = false;
} }
} }
@ -560,7 +564,7 @@ public class NMSImpl implements NMSBridge {
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() MoveControl controller = handle instanceof Mob ? ((Mob) handle).getMoveControl()
: handle instanceof EntityHumanNPC ? ((EntityHumanNPC) handle).getMoveControl() : null; : handle instanceof MobAI ? ((MobAI) handle).getMoveControl() : null;
if (controller == null || !controller.hasWanted()) { if (controller == null || !controller.hasWanted()) {
return null; return null;
} }
@ -702,12 +706,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 ServerPlayer) {
((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);
} }
@ -744,8 +747,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);
} }
@ -995,7 +998,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();
@ -1029,8 +1032,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);
} }
} }
@ -1038,7 +1041,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 {
@ -1053,8 +1056,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);
} }
} }
@ -1299,8 +1302,8 @@ public class NMSImpl implements NMSBridge {
return; return;
if (handle instanceof Mob) { if (handle instanceof Mob) {
((Mob) handle).getMoveControl().setWantedPosition(x, y, z, speed); ((Mob) handle).getMoveControl().setWantedPosition(x, y, z, speed);
} else if (handle instanceof EntityHumanNPC) { } else if (handle instanceof MobAI) {
((EntityHumanNPC) handle).setMoveDestination(x, y, z, speed); ((MobAI) handle).getMoveControl().setWantedPosition(x, y, z, speed);
} }
} }
@ -1422,11 +1425,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);
JumpControl controller = ((Mob) handle).getJumpControl(); if (ai != null) {
controller.jump(); ai.getJumpControl().jump();
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).setShouldJump();
} }
} }
@ -1633,10 +1634,9 @@ 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 EntityHumanNPC) { if (en instanceof MobAI) {
((EntityHumanNPC) en).updatePathfindingRange(pathfindingRange); ((MobAI) en).updatePathfindingRange(pathfindingRange);
}
return; return;
} }
if (NAVIGATION_PATHFINDER == null) if (NAVIGATION_PATHFINDER == null)
@ -2003,12 +2003,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();
@ -2148,6 +2148,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);
@ -2218,8 +2238,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();
} }
} }
@ -2244,6 +2264,13 @@ public class NMSImpl implements NMSBridge {
} }
private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFinalSetter(ServerPlayer.class, "cr"); private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFinalSetter(ServerPlayer.class, "cr");
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_17_R1.util;
import net.citizensnpcs.nms.v1_17_R1.entity.EntityHumanNPC;
public class PlayerControllerJump {
private boolean a;
private final EntityHumanNPC b;
public PlayerControllerJump(EntityHumanNPC entityinsentient) {
this.b = entityinsentient;
}
public void b() {
this.b.setJumping(this.a);
this.a = false;
}
public void jump() {
this.a = true;
}
}

View File

@ -292,10 +292,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());