Backport armor stand movement to 1.18.2

This commit is contained in:
fullwall 2023-03-19 22:03:45 +08:00
parent 9cff1afb28
commit 5a0184c585
19 changed files with 369 additions and 224 deletions

View File

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

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_18_R2.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;
@ -125,7 +125,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

@ -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;
@ -17,7 +16,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;
@ -25,7 +23,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;
@ -34,10 +31,9 @@ import net.citizensnpcs.nms.v1_18_R2.network.EmptyNetHandler;
import net.citizensnpcs.nms.v1_18_R2.network.EmptyNetworkManager; import net.citizensnpcs.nms.v1_18_R2.network.EmptyNetworkManager;
import net.citizensnpcs.nms.v1_18_R2.util.EmptyAdvancementDataPlayer; import net.citizensnpcs.nms.v1_18_R2.util.EmptyAdvancementDataPlayer;
import net.citizensnpcs.nms.v1_18_R2.util.EmptyServerStatsCounter; import net.citizensnpcs.nms.v1_18_R2.util.EmptyServerStatsCounter;
import net.citizensnpcs.nms.v1_18_R2.util.MobAI;
import net.citizensnpcs.nms.v1_18_R2.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerControllerJump;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerNavigation;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerlistTracker; import net.citizensnpcs.nms.v1_18_R2.util.PlayerlistTracker;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
@ -63,26 +59,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;
@ -94,6 +80,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) {
@ -113,11 +100,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()) {
@ -150,8 +132,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) {
@ -159,7 +139,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))
@ -171,12 +151,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;
@ -205,6 +186,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)) {
@ -213,10 +199,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);
@ -227,23 +209,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();
@ -305,31 +275,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);
@ -415,18 +360,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);
@ -471,11 +404,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} }
} }
public void updateAI() {
controllerMove.tick();
controllerJump.tick();
}
private void updatePackets(boolean navigating) { private void updatePackets(boolean navigating) {
if (!npc.isUpdating(NPCUpdate.PACKET)) if (!npc.isUpdating(NPCUpdate.PACKET))
return; return;
@ -501,10 +429,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;
@ -590,12 +514,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_18_R2.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_18_R2.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.moveControl; this.oldMoveController = this.moveControl;
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
} }
@ -213,7 +213,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_18_R2.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_18_R2.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;
@ -77,7 +77,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_18_R2.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_18_R2.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;
@ -123,7 +123,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_18_R2.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_18_R2.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;
@ -117,7 +117,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_18_R2.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_18_R2.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.moveControl; this.oldMoveController = this.moveControl;
this.moveControl = new PlayerMoveControl(this); this.moveControl = new EntityMoveControl(this);
} }
} }
@ -214,7 +214,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_18_R2.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_18_R2.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;
@ -119,7 +119,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_18_R2.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_18_R2.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_18_R2.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl; import net.citizensnpcs.nms.v1_18_R2.util.NMSImpl;
import net.citizensnpcs.nms.v1_18_R2.util.PlayerMoveControl; import net.citizensnpcs.nms.v1_18_R2.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;
@ -106,7 +106,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_18_R2.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_18_R2.util;
import java.util.Random; import java.util.Random;
import net.citizensnpcs.nms.v1_18_R2.entity.EntityHumanNPC;
import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.NMS;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
@ -12,7 +11,7 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.control.MoveControl; import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.monster.Slime; import net.minecraft.world.entity.monster.Slime;
public class PlayerMoveControl extends MoveControl { public class EntityMoveControl extends MoveControl {
protected LivingEntity entity; protected LivingEntity entity;
private int jumpTicks; private int jumpTicks;
protected boolean moving; protected boolean moving;
@ -21,7 +20,7 @@ public class PlayerMoveControl extends MoveControl {
protected double ty; protected double ty;
protected double tz; protected double tz;
public PlayerMoveControl(LivingEntity entityinsentient) { public EntityMoveControl(LivingEntity entityinsentient) {
super(entityinsentient instanceof Mob ? (Mob) entityinsentient super(entityinsentient instanceof Mob ? (Mob) entityinsentient
: new Slime(EntityType.SLIME, entityinsentient.level)); : new Slime(EntityType.SLIME, entityinsentient.level));
this.entity = entityinsentient; this.entity = entityinsentient;
@ -120,11 +119,7 @@ public class PlayerMoveControl extends MoveControl {
if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 0.4D)) { if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 0.4D)) {
this.jumpTicks = jumpTicks(); this.jumpTicks = jumpTicks();
this.jumpTicks /= 3; this.jumpTicks /= 3;
if (this.entity instanceof EntityHumanNPC) { entity.setJumping(true);
((EntityHumanNPC) this.entity).getControllerJump().jump();
} else {
((Mob) this.entity).getJumpControl().jump();
}
} }
} }
} }

View File

@ -14,10 +14,12 @@ 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;
import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.monster.Slime;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.PathNavigationRegion; import net.minecraft.world.level.PathNavigationRegion;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
@ -30,7 +32,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;
@ -38,13 +40,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;
@ -54,17 +56,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(new Slime(EntityType.SLIME, world), world);
this.mob = entityinsentient; this.mob = entityinsentient;
this.level = world; this.mvmt = MobAI.from(entityinsentient);
this.followRange = entityinsentient.getAttribute(Attributes.FOLLOW_RANGE); this.followRange = entityinsentient.getAttribute(Attributes.FOLLOW_RANGE);
this.nodeEvaluator = new PlayerNodeEvaluator(); this.nodeEvaluator = new EntityNodeEvaluator();
this.nodeEvaluator.setCanPassDoors(true); this.nodeEvaluator.setCanPassDoors(true);
this.pathFinder = new PlayerPathfinder(this.nodeEvaluator, Settings.Setting.MAXIMUM_VISITED_NODES.asInt()); this.pathFinder = new EntityPathfinder(this.nodeEvaluator, Settings.Setting.MAXIMUM_VISITED_NODES.asInt());
this.setRange(24); this.setRange(24);
} }
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();
@ -149,7 +156,7 @@ public class PlayerNavigation extends PathNavigation {
} }
return true; return true;
} }
private boolean canWalkOn(int var0, int var1, int var2, int var3, int var4, int var5, Vec3 var6, double var7, private boolean canWalkOn(int var0, int var1, int var2, int var3, int var4, int var5, Vec3 var6, double var7,
double var9) { double var9) {
int var11 = var0 - var3 / 2; int var11 = var0 - var3 / 2;
@ -287,7 +294,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);
} }
@ -527,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.below()).isAir() ? var0.y mvmt.getMoveControl().setWantedPosition(var0.x, this.level.getBlockState(var1.below()).isAir() ? var0.y
: WalkNodeEvaluator.getFloorLevel(this.level, var1), var0.z, this.speedModifier); : WalkNodeEvaluator.getFloorLevel(this.level, var1), var0.z, this.speedModifier);
} }

View File

@ -6,12 +6,12 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
import net.citizensnpcs.nms.v1_18_R2.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;
@ -33,7 +33,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;
@ -53,7 +53,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();
@ -83,7 +83,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);
@ -120,7 +120,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;
@ -144,7 +144,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;
@ -173,8 +173,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();
@ -185,12 +185,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;
} }
@ -218,12 +218,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();
@ -234,12 +234,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;
} }
@ -263,7 +263,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()));
@ -290,7 +290,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);
@ -349,7 +349,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))
@ -357,13 +357,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;
} }
@ -373,7 +373,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

@ -2,15 +2,15 @@ package net.citizensnpcs.nms.v1_18_R2.util;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.citizensnpcs.nms.v1_18_R2.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<Node>(); protected final Int2ObjectMap<Node> c = new Int2ObjectOpenHashMap<Node>();
protected boolean canFloat; protected boolean canFloat;
protected boolean canOpenDoors; protected boolean canOpenDoors;
@ -19,7 +19,8 @@ public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator {
protected int entityHeight; protected int entityHeight;
protected int entityWidth; protected int entityWidth;
protected PathNavigationRegion level; protected PathNavigationRegion level;
protected EntityHumanNPC mob; protected LivingEntity mob;
protected MobAI mvmt;
@Override @Override
public boolean canFloat() { public boolean canFloat() {
@ -52,9 +53,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

@ -13,10 +13,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_18_R2.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;
@ -25,27 +25,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_18_R2.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;
@ -279,10 +280,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;
@ -433,14 +436,17 @@ 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 == null)
return;
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;
} }
} }
@ -564,7 +570,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;
} }
@ -708,12 +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 PathNavigation navigation = NMSImpl.getNavigation(entity); final PathNavigation navigation = NMSImpl.getNavigation(entity);
final float oldWater = raw instanceof ServerPlayer final float oldWater = raw instanceof MobAI ? ((MobAI) raw).getPathfindingMalus(BlockPathTypes.WATER)
? ((EntityHumanNPC) raw).getPathfindingMalus(BlockPathTypes.WATER)
: ((Mob) raw).getPathfindingMalus(BlockPathTypes.WATER); : ((Mob) raw).getPathfindingMalus(BlockPathTypes.WATER);
if (params.avoidWater() && oldWater >= 0) { if (params.avoidWater() && oldWater >= 0) {
if (raw instanceof ServerPlayer) { if (raw instanceof MobAI) {
((EntityHumanNPC) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F); ((MobAI) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F);
} else { } else {
((Mob) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F); ((Mob) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F);
} }
@ -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 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);
} }
@ -1000,7 +1005,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();
@ -1035,8 +1040,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);
} }
} }
@ -1044,7 +1049,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 {
@ -1059,8 +1064,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);
} }
} }
@ -1305,8 +1310,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);
} }
} }
@ -1428,12 +1433,8 @@ 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(); ai.getJumpControl().jump();
controller.jump();
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).setShouldJump();
}
} }
@Override @Override
@ -1639,10 +1640,8 @@ public class NMSImpl implements NMSBridge {
if (!npc.isSpawned() || !npc.getEntity().getType().isAlive()) if (!npc.isSpawned() || !npc.getEntity().getType().isAlive())
return; return;
LivingEntity en = NMSImpl.getHandle((org.bukkit.entity.LivingEntity) npc.getEntity()); LivingEntity en = NMSImpl.getHandle((org.bukkit.entity.LivingEntity) npc.getEntity());
if (!(en instanceof Mob)) { if (en instanceof MobAI) {
if (en instanceof EntityHumanNPC) { ((MobAI) en).updatePathfindingRange(pathfindingRange);
((EntityHumanNPC) en).updatePathfindingRange(pathfindingRange);
}
return; return;
} }
if (NAVIGATION_PATHFINDER == null) if (NAVIGATION_PATHFINDER == null)
@ -2009,12 +2008,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();
@ -2154,6 +2153,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);
@ -2259,8 +2278,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();
} }
} }
@ -2285,6 +2304,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_18_R2.util;
import net.citizensnpcs.nms.v1_18_R2.entity.EntityHumanNPC;
public class PlayerControllerJump {
private boolean a;
private final EntityHumanNPC b;
public PlayerControllerJump(EntityHumanNPC entityinsentient) {
this.b = entityinsentient;
}
public void jump() {
this.a = true;
}
public void tick() {
this.b.setJumping(this.a);
this.a = false;
}
}