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.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.NMSImpl;
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;
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) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
ai = new BasicMobAI(this);
}
}
@Override
public MobAI getAI() {
return ai;
}
@Override
@ -127,6 +138,7 @@ public class ArmorStandController extends MobEntityController {
super.tick();
if (npc != null) {
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.NMSBoundingBox;
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.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
@ -125,7 +125,7 @@ public class CodController extends MobEntityController {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this);
this.moveControl = new EntityMoveControl(this);
}
}
super.customServerAiStep();

View File

@ -5,7 +5,6 @@ import java.lang.invoke.MethodHandle;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -17,7 +16,6 @@ import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;
@ -25,7 +23,6 @@ import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPC.NPCUpdate;
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.util.EmptyAdvancementDataPlayer;
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.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.npc.CitizensNPC;
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.entity.Entity;
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.level.GameType;
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.Vec3;
public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity {
private PlayerControllerJump controllerJump;
private PlayerMoveControl controllerMove;
public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity, ForwardingMobAI {
private MobAI ai;
private final Map<EquipmentSlot, ItemStack> equipmentCache = Maps.newEnumMap(EquipmentSlot.class);
private int jumpTicks = 0;
private final Map<BlockPathTypes, Float> malus = Maps.newEnumMap(BlockPathTypes.class);
private PlayerNavigation navigation;
private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0);
private PlayerlistTracker playerlistTracker;
@ -94,6 +80,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
this.npc = (CitizensNPC) npc;
if (npc != null) {
skinTracker = new SkinPacketTracker(this);
ai = new BasicMobAI(this);
try {
GAMEMODE_SETTING.invoke(gameMode, GameType.SURVIVAL, null);
} catch (Throwable e) {
@ -113,11 +100,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
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
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
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
}
@Override
public void doTick() {
if (npc == null) {
@ -159,7 +139,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return;
}
super.baseTick();
boolean navigating = npc.getNavigator().isNavigating() || controllerMove.hasWanted();
boolean navigating = npc.getNavigator().isNavigating() || ai.getMoveControl().hasWanted();
if (!navigating && getBukkitEntity() != null
&& (!npc.hasTrait(Gravity.class) || npc.getOrAddTrait(Gravity.class).hasGravity())
&& Util.isLoaded(getBukkitEntity().getLocation(LOADED_LOCATION))
@ -171,12 +151,13 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
setDeltaMovement(Vec3.ZERO);
}
if (navigating) {
if (!navigation.isDone()) {
navigation.tick();
if (!ai.getNavigation().isDone()) {
ai.getNavigation().tick();
}
moveOnCurrentHeading();
}
updateAI();
ai.getJumpControl().tick();
ai.getMoveControl().tick();
if (isSpectator()) {
this.noPhysics = true;
this.onGround = false;
@ -205,6 +186,11 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return super.getAddEntityPacket();
}
@Override
public MobAI getAI() {
return ai;
}
@Override
public CraftPlayer getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
@ -213,10 +199,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return super.getBukkitEntity();
}
public PlayerControllerJump getControllerJump() {
return controllerJump;
}
@Override
protected SoundEvent getDeathSound() {
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);
}
public PlayerMoveControl getMoveControl() {
return controllerMove;
}
public PathNavigation getNavigation() {
return navigation;
}
@Override
public NPC getNPC() {
return npc;
}
public float getPathfindingMalus(BlockPathTypes pathtype) {
return this.malus.containsKey(pathtype) ? this.malus.get(pathtype) : pathtype.getMalus();
}
@Override
public GameProfile getProfile() {
return super.getGameProfile();
@ -305,31 +275,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
} catch (IOException e) {
// 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;
NMS.setStepHeight(getBukkitEntity(), 1); // the default (0) breaks step climbing
setSkinFlags((byte) 0xFF);
@ -415,18 +360,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
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
public void setSkinFlags(byte 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) {
if (!npc.isUpdating(NPCUpdate.PACKET))
return;
@ -501,10 +429,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
NMSImpl.sendPacketsNearby(getBukkitEntity(), current, packets);
}
public void updatePathfindingRange(float pathfindingRange) {
this.navigation.setRange(pathfindingRange);
}
public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity {
private final CraftServer cserver;
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 MethodHandle GAMEMODE_SETTING = NMS.getFirstMethodHandle(ServerPlayerGameMode.class, true,
GameType.class, GameType.class);
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.NMSBoundingBox;
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.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
@ -59,7 +59,7 @@ public class MagmaCubeController extends MobEntityController {
if (npc != null) {
setSize(3, true);
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;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this);
this.moveControl = new EntityMoveControl(this);
}
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.NMSBoundingBox;
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.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
@ -77,7 +77,7 @@ public class PhantomController extends MobEntityController {
this.lookControl = this.oldLookController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this);
this.moveControl = new EntityMoveControl(this);
this.lookControl = new LookControl(this);
}
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.NMSBoundingBox;
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.ai.NPCHolder;
import net.citizensnpcs.trait.versioned.PufferFishTrait;
@ -123,7 +123,7 @@ public class PufferFishController extends MobEntityController {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this);
this.moveControl = new EntityMoveControl(this);
}
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.NMSBoundingBox;
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.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
@ -117,7 +117,7 @@ public class SalmonController extends MobEntityController {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this);
this.moveControl = new EntityMoveControl(this);
}
}
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.NMSBoundingBox;
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.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
@ -59,7 +59,7 @@ public class SlimeController extends MobEntityController {
if (npc != null) {
setSize(3, true);
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;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this);
this.moveControl = new EntityMoveControl(this);
}
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.NMSBoundingBox;
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.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
@ -119,7 +119,7 @@ public class TropicalFishController extends MobEntityController {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this);
this.moveControl = new EntityMoveControl(this);
}
}
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.NMSBoundingBox;
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.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
@ -106,7 +106,7 @@ public class TurtleController extends MobEntityController {
this.jumpControl = this.oldJumpController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new PlayerMoveControl(this);
this.moveControl = new EntityMoveControl(this);
this.jumpControl = new EmptyControllerJump(this);
}
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 net.citizensnpcs.nms.v1_18_R2.entity.EntityHumanNPC;
import net.citizensnpcs.util.NMS;
import net.minecraft.util.Mth;
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.monster.Slime;
public class PlayerMoveControl extends MoveControl {
public class EntityMoveControl extends MoveControl {
protected LivingEntity entity;
private int jumpTicks;
protected boolean moving;
@ -21,7 +20,7 @@ public class PlayerMoveControl extends MoveControl {
protected double ty;
protected double tz;
public PlayerMoveControl(LivingEntity entityinsentient) {
public EntityMoveControl(LivingEntity entityinsentient) {
super(entityinsentient instanceof Mob ? (Mob) entityinsentient
: new Slime(EntityType.SLIME, entityinsentient.level));
this.entity = entityinsentient;
@ -120,11 +119,7 @@ public class PlayerMoveControl extends MoveControl {
if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 0.4D)) {
this.jumpTicks = jumpTicks();
this.jumpTicks /= 3;
if (this.entity instanceof EntityHumanNPC) {
((EntityHumanNPC) this.entity).getControllerJump().jump();
} else {
((Mob) this.entity).getJumpControl().jump();
}
entity.setJumping(true);
}
}
}

View File

@ -14,10 +14,12 @@ import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.Attributes;
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.PathNavigationRegion;
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.phys.Vec3;
public class PlayerNavigation extends PathNavigation {
public class EntityNavigation extends PathNavigation {
private boolean avoidSun;
private final AttributeInstance followRange;
protected boolean hasDelayedRecomputation;
@ -38,13 +40,13 @@ public class PlayerNavigation extends PathNavigation {
protected int lastStuckCheck;
protected Vec3 lastStuckCheckPos = Vec3.ZERO;
protected long lastTimeoutCheck;
protected final Level level;
protected float maxDistanceToWaypoint = 0.5F;
private float maxVisitedNodesMultiplier = 1.0F;
protected final EntityHumanNPC mob;
protected PlayerNodeEvaluator nodeEvaluator;
protected final LivingEntity mob;
private final MobAI mvmt;
protected EntityNodeEvaluator nodeEvaluator;
protected Path path;
private final PlayerPathfinder pathFinder;
private final EntityPathfinder pathFinder;
private int reachRange;
protected double speedModifier;
private BlockPos targetPos;
@ -54,17 +56,22 @@ public class PlayerNavigation extends PathNavigation {
protected double timeoutLimit;
protected long timeoutTimer;
public PlayerNavigation(EntityHumanNPC entityinsentient, Level world) {
super(getDummyInsentient(entityinsentient, world), world);
public EntityNavigation(LivingEntity entityinsentient, Level world) {
super(new Slime(EntityType.SLIME, world), world);
this.mob = entityinsentient;
this.level = world;
this.mvmt = MobAI.from(entityinsentient);
this.followRange = entityinsentient.getAttribute(Attributes.FOLLOW_RANGE);
this.nodeEvaluator = new PlayerNodeEvaluator();
this.nodeEvaluator = new EntityNodeEvaluator();
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);
}
public boolean canCutCorner(BlockPathTypes pathtype) {
return (pathtype != BlockPathTypes.DANGER_FIRE && pathtype != BlockPathTypes.DANGER_CACTUS
&& pathtype != BlockPathTypes.DANGER_OTHER && pathtype != BlockPathTypes.WALKABLE_DOOR);
}
@Override
public boolean canFloat() {
return this.nodeEvaluator.canFloat();
@ -149,7 +156,7 @@ public class PlayerNavigation extends PathNavigation {
}
return true;
}
private boolean canWalkOn(int var0, int var1, int var2, int var3, int var4, int var5, Vec3 var6, double var7,
double var9) {
int var11 = var0 - var3 / 2;
@ -287,7 +294,7 @@ public class PlayerNavigation extends PathNavigation {
double var4 = Math.abs(this.mob.getY() - blockPos.getY());
double var6 = Math.abs(this.mob.getZ() - (blockPos.getZ() + 0.5D));
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();
doStuckDetection(var0);
}
@ -527,7 +534,7 @@ public class PlayerNavigation extends PathNavigation {
return;
Vec3 var0 = this.path.getNextEntityPos(this.mob);
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);
}

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.objects.Object2BooleanMap;
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.Direction;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.BlockGetter;
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.shapes.VoxelShape;
public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
public class EntityNodeEvaluator extends EntityNodeEvaluatorBase {
private final Long2ObjectMap<BlockPathTypes> l = new Long2ObjectOpenHashMap<BlockPathTypes>();
private final Object2BooleanMap<AABB> m = new Object2BooleanOpenHashMap<AABB>();
protected float oldWaterCost;
@ -53,7 +53,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
@Override
public void done() {
this.mob.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost);
this.mvmt.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost);
this.l.clear();
this.m.clear();
super.done();
@ -83,7 +83,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
if (var10 - var4 > 1.125D)
return null;
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;
if (var13 >= 0.0F) {
var8 = getNode(var0, var1, var2);
@ -120,7 +120,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
if (var12 == BlockPathTypes.WATER) {
var8 = getNode(var0, var1, var2);
var8.type = var12;
var8.costMalus = Math.max(var8.costMalus, this.mob.getPathfindingMalus(var12));
var8.costMalus = Math.max(var8.costMalus, this.mvmt.getPathfindingMalus(var12));
continue;
}
return var8;
@ -144,7 +144,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return var18;
}
var12 = getCachedBlockType(this.mob, var0, var1, var2);
var13 = this.mob.getPathfindingMalus(var12);
var13 = this.mvmt.getPathfindingMalus(var12);
if (var12 != BlockPathTypes.OPEN && var13 >= 0.0F) {
var8 = getNode(var0, var1, var2);
var8.type = var12;
@ -173,8 +173,8 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return getBlockPathTypeStatic(var0, new BlockPos.MutableBlockPos(var1, var2, var3));
}
public BlockPathTypes getBlockPathType(BlockGetter var0, int var1, int var2, int var3, EntityHumanNPC var4,
int var5, int var6, int var7, boolean var8, boolean var9) {
public BlockPathTypes getBlockPathType(BlockGetter var0, int var1, int var2, int var3, LivingEntity var4, int var5,
int var6, int var7, boolean var8, boolean var9) {
EnumSet<BlockPathTypes> var10 = EnumSet.noneOf(BlockPathTypes.class);
BlockPathTypes var11 = BlockPathTypes.BLOCKED;
BlockPos var12 = var4.blockPosition();
@ -185,12 +185,12 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return BlockPathTypes.UNPASSABLE_RAIL;
BlockPathTypes var13 = BlockPathTypes.BLOCKED;
for (BlockPathTypes var15 : var10) {
if (var4.getPathfindingMalus(var15) < 0.0F)
if (mvmt.getPathfindingMalus(var15) < 0.0F)
return var15;
if (var4.getPathfindingMalus(var15) >= var4.getPathfindingMalus(var13))
if (mvmt.getPathfindingMalus(var15) >= mvmt.getPathfindingMalus(var13))
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 var13;
}
@ -218,12 +218,12 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
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());
}
public BlockPathTypes getBlockPathTypee(BlockGetter var0, int var1, int var2, int var3, EntityHumanNPC var4,
int var5, int var6, int var7, boolean var8, boolean var9) {
public BlockPathTypes getBlockPathTypee(BlockGetter var0, int var1, int var2, int var3, LivingEntity var4, int var5,
int var6, int var7, boolean var8, boolean var9) {
EnumSet<BlockPathTypes> var10 = EnumSet.noneOf(BlockPathTypes.class);
BlockPathTypes var11 = BlockPathTypes.BLOCKED;
BlockPos var12 = var4.blockPosition();
@ -234,12 +234,12 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
return BlockPathTypes.UNPASSABLE_RAIL;
BlockPathTypes var13 = BlockPathTypes.BLOCKED;
for (BlockPathTypes var15 : var10) {
if (var4.getPathfindingMalus(var15) < 0.0F)
if (mvmt.getPathfindingMalus(var15) < 0.0F)
return var15;
if (var4.getPathfindingMalus(var15) >= var4.getPathfindingMalus(var13))
if (mvmt.getPathfindingMalus(var15) >= mvmt.getPathfindingMalus(var13))
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 var13;
}
@ -263,7 +263,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
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),
var4 -> getBlockPathType(this.level, var1, var2, var3, var0, this.entityWidth, this.entityHeight,
this.entityDepth, canOpenDoors(), canPassDoors()));
@ -290,7 +290,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
int var3 = 0;
BlockPathTypes var4 = getCachedBlockType(this.mob, var1.x, var1.y + 1, 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));
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);
@ -349,7 +349,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
}
BlockPos var3 = this.mob.blockPosition();
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();
if (hasPositiveMalus(var1.set(aABB.minX, var0, aABB.minZ))
|| 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))) {
Node var6 = getNode(var1);
var6.type = getBlockPathType(this.mob, var6.asBlockPos());
var6.costMalus = this.mob.getPathfindingMalus(var6.type);
var6.costMalus = this.mvmt.getPathfindingMalus(var6.type);
return var6;
}
}
Node var5 = getNode(var3.getX(), var0, var3.getZ());
var5.type = getBlockPathType(this.mob, var5.asBlockPos());
var5.costMalus = this.mob.getPathfindingMalus(var5.type);
var5.costMalus = this.mvmt.getPathfindingMalus(var5.type);
return var5;
}
@ -373,7 +373,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase {
private boolean hasPositiveMalus(BlockPos var0) {
BlockPathTypes var1 = getBlockPathType(this.mob, var0);
return (this.mob.getPathfindingMalus(var1) >= 0.0F);
return (this.mvmt.getPathfindingMalus(var1) >= 0.0F);
}
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.Int2ObjectOpenHashMap;
import net.citizensnpcs.nms.v1_18_R2.entity.EntityHumanNPC;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.PathNavigationRegion;
import net.minecraft.world.level.pathfinder.Node;
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 boolean canFloat;
protected boolean canOpenDoors;
@ -19,7 +19,8 @@ public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator {
protected int entityHeight;
protected int entityWidth;
protected PathNavigationRegion level;
protected EntityHumanNPC mob;
protected LivingEntity mob;
protected MobAI mvmt;
@Override
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));
}
public void prepare(PathNavigationRegion var0, EntityHumanNPC var1) {
public void prepare(PathNavigationRegion var0, LivingEntity var1) {
this.level = var0;
this.mob = var1;
this.mvmt = MobAI.from(var1);
this.c.clear();
this.entityWidth = Mth.floor(var1.getBbWidth() + 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 net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.nms.v1_18_R2.entity.EntityHumanNPC;
import net.minecraft.core.BlockPos;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.util.profiling.metrics.MetricCategory;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.PathNavigationRegion;
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.Target;
public class PlayerPathfinder extends PathFinder {
public class EntityPathfinder extends PathFinder {
private final int maxVisitedNodes;
private final Node[] neighbors = new Node[32];
private final PlayerNodeEvaluator nodeEvaluator;
private final EntityNodeEvaluator nodeEvaluator;
private final BinaryHeap openSet;
public PlayerPathfinder() {
public EntityPathfinder() {
super(null, Setting.MAXIMUM_VISITED_NODES.asInt());
this.nodeEvaluator = new PlayerNodeEvaluator();
this.nodeEvaluator = new EntityNodeEvaluator();
this.openSet = new BinaryHeap();
this.maxVisitedNodes = Setting.MAXIMUM_VISITED_NODES.asInt();
}
public PlayerPathfinder(PlayerNodeEvaluator var0, int var1) {
public EntityPathfinder(EntityNodeEvaluator var0, int var1) {
super(var0, var1);
this.openSet = new BinaryHeap();
this.nodeEvaluator = var0;
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) {
this.openSet.clear();
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.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
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.TamableAnimal;
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.AttributeMap;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
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.goal.GoalSelector;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
@ -433,14 +436,17 @@ public class NMSImpl implements NMSBridge {
@Override
public void cancelMoveDestination(org.bukkit.entity.Entity 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 {
MOVE_CONTROLLER_MOVING.invoke(((Mob) handle).getMoveControl(), null);
MOVE_CONTROLLER_MOVING.invoke(ai.getMoveControl(), null);
} catch (Throwable t) {
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) {
Entity handle = getHandle(entity);
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()) {
return null;
}
@ -708,12 +714,11 @@ public class NMSImpl implements NMSBridge {
// navigation won't execute, and calling entity.move doesn't
// entirely fix the problem.
final PathNavigation navigation = NMSImpl.getNavigation(entity);
final float oldWater = raw instanceof ServerPlayer
? ((EntityHumanNPC) raw).getPathfindingMalus(BlockPathTypes.WATER)
final float oldWater = raw instanceof MobAI ? ((MobAI) raw).getPathfindingMalus(BlockPathTypes.WATER)
: ((Mob) raw).getPathfindingMalus(BlockPathTypes.WATER);
if (params.avoidWater() && oldWater >= 0) {
if (raw instanceof ServerPlayer) {
((EntityHumanNPC) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F);
if (raw instanceof MobAI) {
((MobAI) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F);
} else {
((Mob) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater + 1F);
}
@ -750,8 +755,8 @@ public class NMSImpl implements NMSBridge {
Util.sendBlockChanges(blocks, null);
}
if (oldWater >= 0) {
if (raw instanceof ServerPlayer) {
((EntityHumanNPC) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater);
if (raw instanceof MobAI) {
((MobAI) raw).setPathfindingMalus(BlockPathTypes.WATER, oldWater);
} else {
((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) {
Entity handle = NMSImpl.getHandle(entity);
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);
double xDiff, yDiff, zDiff;
xDiff = to.getX() - fromLocation.getX();
@ -1035,8 +1040,8 @@ public class NMSImpl implements NMSBridge {
while (((LivingEntity) handle).yHeadRot < -180F) {
((LivingEntity) handle).yHeadRot += 360F;
}
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).getNPC().getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToFace(to);
} else if (handle instanceof NPCHolder) {
((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) {
Entity handle = NMSImpl.getHandle(from), target = NMSImpl.getHandle(to);
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) {
look(from, ((org.bukkit.entity.LivingEntity) to).getEyeLocation(), false, true);
} else {
@ -1059,8 +1064,8 @@ public class NMSImpl implements NMSBridge {
while (((LivingEntity) handle).yHeadRot < -180F) {
((LivingEntity) handle).yHeadRot += 360F;
}
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).getNPC().getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToFace(to);
} else if (handle instanceof NPCHolder) {
((NPCHolder) handle).getNPC().getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToFace(to);
}
}
@ -1305,8 +1310,8 @@ public class NMSImpl implements NMSBridge {
return;
if (handle instanceof Mob) {
((Mob) handle).getMoveControl().setWantedPosition(x, y, z, speed);
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).setMoveDestination(x, y, z, speed);
} else if (handle instanceof MobAI) {
((MobAI) handle).getMoveControl().setWantedPosition(x, y, z, speed);
}
}
@ -1428,12 +1433,8 @@ public class NMSImpl implements NMSBridge {
Entity handle = NMSImpl.getHandle(entity);
if (handle == null)
return;
if (handle instanceof Mob) {
JumpControl controller = ((Mob) handle).getJumpControl();
controller.jump();
} else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).setShouldJump();
}
MobAI ai = MobAI.from(handle);
ai.getJumpControl().jump();
}
@Override
@ -1639,10 +1640,8 @@ public class NMSImpl implements NMSBridge {
if (!npc.isSpawned() || !npc.getEntity().getType().isAlive())
return;
LivingEntity en = NMSImpl.getHandle((org.bukkit.entity.LivingEntity) npc.getEntity());
if (!(en instanceof Mob)) {
if (en instanceof EntityHumanNPC) {
((EntityHumanNPC) en).updatePathfindingRange(pathfindingRange);
}
if (en instanceof MobAI) {
((MobAI) en).updatePathfindingRange(pathfindingRange);
return;
}
if (NAVIGATION_PATHFINDER == null)
@ -2009,12 +2008,12 @@ public class NMSImpl implements NMSBridge {
public static PathNavigation getNavigation(org.bukkit.entity.Entity entity) {
Entity handle = getHandle(entity);
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) {
try {
return nav instanceof PlayerNavigation ? ((PlayerNavigation) nav).getPathEntity()
return nav instanceof EntityNavigation ? ((EntityNavigation) nav).getPathEntity()
: (Path) NAVIGATION_PATH.invoke(nav);
} catch (Throwable e) {
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) {
try {
BUKKITENTITY_FIELD_SETTER.invoke(entity, bukkitEntity);
@ -2259,8 +2278,8 @@ public class NMSImpl implements NMSBridge {
handle.getMoveControl().tick();
handle.getLookControl().tick();
handle.getJumpControl().tick();
} else if (entity instanceof EntityHumanNPC) {
((EntityHumanNPC) entity).updateAI();
} else if (entity instanceof MobAI) {
((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 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,
EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT,
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;
}
}