diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/ArmorStandController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/ArmorStandController.java index e8a0077b1..b8c422948 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/ArmorStandController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/ArmorStandController.java @@ -9,6 +9,8 @@ import org.bukkit.util.Vector; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; +import net.citizensnpcs.nms.v1_19_R3.util.MobAI; +import net.citizensnpcs.nms.v1_19_R3.util.MobAI.ForwardingMobAI; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.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 types, Level level) { @@ -55,6 +58,14 @@ public class ArmorStandController extends MobEntityController { public EntityArmorStandNPC(EntityType 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(); } } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/CodController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/CodController.java index be47de44f..f2d545338 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/CodController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/CodController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; @@ -126,7 +126,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(); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EntityHumanNPC.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EntityHumanNPC.java index 6892fc4fd..312f048cd 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EntityHumanNPC.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EntityHumanNPC.java @@ -15,7 +15,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; @@ -32,10 +31,9 @@ import net.citizensnpcs.nms.v1_19_R3.network.EmptyNetHandler; import net.citizensnpcs.nms.v1_19_R3.network.EmptyNetworkManager; import net.citizensnpcs.nms.v1_19_R3.util.EmptyAdvancementDataPlayer; import net.citizensnpcs.nms.v1_19_R3.util.EmptyServerStatsCounter; +import net.citizensnpcs.nms.v1_19_R3.util.MobAI; +import net.citizensnpcs.nms.v1_19_R3.util.MobAI.ForwardingMobAI; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerControllerJump; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerNavigation; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.skin.SkinPacketTracker; @@ -62,27 +60,17 @@ import net.minecraft.tags.TagKey; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.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.material.Fluid; -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 equipmentCache = Maps.newEnumMap(EquipmentSlot.class); private int jumpTicks = 0; - private final Map malus = Maps.newEnumMap(BlockPathTypes.class); - private PlayerNavigation navigation; private final CitizensNPC npc; private final Location packetLocationCache = new Location(null, 0, 0, 0); private boolean setBukkitEntity; @@ -93,6 +81,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable super(minecraftServer, world, gameProfile); this.npc = (CitizensNPC) npc; if (npc != null) { + ai = new BasicMobAI(this); skinTracker = new SkinPacketTracker(this); try { GAMEMODE_SETTING.invoke(gameMode, GameType.SURVIVAL, null); @@ -105,11 +94,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable } } - public boolean canCutCorner(BlockPathTypes pathtype) { - return (pathtype != BlockPathTypes.DANGER_FIRE && pathtype != BlockPathTypes.DANGER_POWDER_SNOW - && pathtype != BlockPathTypes.DANGER_OTHER && pathtype != BlockPathTypes.WALKABLE_DOOR); - } - @Override public boolean causeFallDamage(float f, float f1, DamageSource damagesource) { if (npc == null || !npc.isFlyable()) { @@ -149,7 +133,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)) @@ -161,12 +145,12 @@ 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(); + tickAI(); if (isSpectator()) { this.noPhysics = true; this.onGround = false; @@ -187,6 +171,11 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable } } + @Override + public MobAI getAI() { + return ai; + } + @Override public CraftPlayer getBukkitEntity() { if (npc != null && !setBukkitEntity) { @@ -196,10 +185,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); @@ -210,23 +195,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(); @@ -288,27 +261,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 all = Maps - .newHashMap((Map) ATTRIBUTE_PROVIDER_MAP.invoke(provider)); - all.put(Attributes.FOLLOW_RANGE, new AttributeInstance(Attributes.FOLLOW_RANGE, att -> { - throw new UnsupportedOperationException( - "Tried to change value for default attribute instance FOLLOW_RANGE"); - })); - ATTRIBUTE_PROVIDER_MAP_SETTER.invoke(provider, ImmutableMap.copyOf(all)); - } catch (Throwable e) { - e.printStackTrace(); - } - range = getAttribute(Attributes.FOLLOW_RANGE); - } - getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.3D); - range.setBaseValue(Setting.DEFAULT_PATHFINDING_RANGE.asDouble()); - controllerJump = new PlayerControllerJump(this); - controllerMove = new PlayerMoveControl(this); - navigation = new PlayerNavigation(this, level); this.invulnerableTime = 0; NMS.setStepHeight(getBukkitEntity(), 1); // the default (0) breaks step climbing setSkinFlags((byte) 0xFF); @@ -326,10 +278,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable return Util.inBlock(getBukkitEntity()); } - public boolean isNavigating() { - return npc.getNavigator().isNavigating(); - } - @Override public boolean isPushable() { return npc == null ? super.isPushable() : npc.data(). get(NPC.Metadata.COLLIDABLE, !npc.isProtected()); @@ -404,18 +352,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) { - malus.put(pathtype, f); - } - - public void setShouldJump() { - controllerJump.jump(); - } - @Override public void setSkinFlags(byte flags) { getEntityData().set(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION, flags); @@ -447,6 +383,12 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable npc.update(); } + @Override + public void tickAI() { + ai.getMoveControl().tick(); + ai.getJumpControl().tick(); + } + @Override public void travel(Vec3 vec3d) { if (npc == null || !npc.isFlyable()) { @@ -456,11 +398,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable } } - public void updateAI() { - controllerMove.tick(); - controllerJump.tick(); - } - @Override public boolean updateFluidHeightAndDoFluidPushing(TagKey tagkey, double d0) { Vec3 old = getDeltaMovement().add(0, 0, 0); @@ -495,10 +432,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable NMSImpl.sendPacketsNearby(getBukkitEntity(), getBukkitEntity().getLocation(packetLocationCache), packets); } - public void updatePathfindingRange(float pathfindingRange) { - this.navigation.setRange(pathfindingRange); - } - public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity { private final CitizensNPC npc; @@ -582,10 +515,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable } } - private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getFirstGetter(AttributeSupplier.class, Map.class); - private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeSupplier.class, "a"); - private static final MethodHandle ATTRIBUTE_SUPPLIER = NMS.getFirstGetter(AttributeMap.class, - AttributeSupplier.class); private static final float EPSILON = 0.003F; private static final MethodHandle GAMEMODE_SETTING = NMS.getFirstMethodHandle(ServerPlayerGameMode.class, true, GameType.class, GameType.class); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/MagmaCubeController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/MagmaCubeController.java index 36811c106..51c843dd1 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/MagmaCubeController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/MagmaCubeController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; @@ -60,7 +60,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); } } @@ -214,7 +214,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(); } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/PhantomController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/PhantomController.java index 5c4a7e14c..9ba973aed 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/PhantomController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/PhantomController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; @@ -78,7 +78,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()) { diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/PufferFishController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/PufferFishController.java index 22ac5b168..e699da2c2 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/PufferFishController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/PufferFishController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.trait.versioned.PufferFishTrait; @@ -124,7 +124,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(); } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/SalmonController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/SalmonController.java index 20362fbe3..67b683404 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/SalmonController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/SalmonController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; @@ -118,7 +118,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(); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/SlimeController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/SlimeController.java index afa193f59..66b1814e2 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/SlimeController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/SlimeController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; @@ -60,7 +60,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); } } @@ -215,7 +215,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(); } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TadpoleController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TadpoleController.java index 995359bdd..a30ddbdef 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TadpoleController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TadpoleController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; @@ -118,7 +118,7 @@ public class TadpoleController 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(); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TropicalFishController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TropicalFishController.java index 6ca120e67..cf608ded8 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TropicalFishController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TropicalFishController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; @@ -120,7 +120,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(); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TurtleController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TurtleController.java index d24062e96..62f1fc4c2 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TurtleController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/TurtleController.java @@ -10,7 +10,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.util.ForwardingNPCHolder; import net.citizensnpcs.nms.v1_19_R3.util.NMSBoundingBox; import net.citizensnpcs.nms.v1_19_R3.util.NMSImpl; -import net.citizensnpcs.nms.v1_19_R3.util.PlayerMoveControl; +import net.citizensnpcs.nms.v1_19_R3.util.EntityMoveControl; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; @@ -107,7 +107,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(); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityJumpControl.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityJumpControl.java new file mode 100644 index 000000000..98a9e495d --- /dev/null +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityJumpControl.java @@ -0,0 +1,27 @@ +package net.citizensnpcs.nms.v1_19_R3.util; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.control.JumpControl; +import net.minecraft.world.entity.monster.Slime; + +public class EntityJumpControl extends JumpControl { + private boolean a; + private final LivingEntity b; + + public EntityJumpControl(LivingEntity entity) { + super(new Slime(EntityType.SLIME, entity.level)); + this.b = entity; + } + + @Override + public void jump() { + this.a = true; + } + + @Override + public void tick() { + this.b.setJumping(this.a); + this.a = false; + } +} diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerMoveControl.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityMoveControl.java similarity index 89% rename from v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerMoveControl.java rename to v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityMoveControl.java index 7686f9148..b83ec2d34 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerMoveControl.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityMoveControl.java @@ -2,7 +2,6 @@ package net.citizensnpcs.nms.v1_19_R3.util; import java.util.Random; -import net.citizensnpcs.nms.v1_19_R3.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); } } } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNavigation.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNavigation.java similarity index 94% rename from v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNavigation.java rename to v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNavigation.java index c15869108..288f3705e 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNavigation.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNavigation.java @@ -7,17 +7,17 @@ import java.util.stream.Stream; import com.google.common.collect.ImmutableSet; import net.citizensnpcs.Settings; -import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; 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.Mob; +import net.minecraft.world.entity.LivingEntity; 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; @@ -29,7 +29,7 @@ import net.minecraft.world.level.pathfinder.Path; import net.minecraft.world.level.pathfinder.PathFinder; 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; @@ -37,13 +37,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; - private final EntityHumanNPC mob; - protected PlayerNodeEvaluator nodeEvaluator; + private 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; @@ -53,17 +53,23 @@ 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); } + @Override + public boolean canCutCorner(BlockPathTypes pathtype) { + return (pathtype != BlockPathTypes.DANGER_FIRE && pathtype != BlockPathTypes.DANGER_POWDER_SNOW + && pathtype != BlockPathTypes.DANGER_OTHER && pathtype != BlockPathTypes.WALKABLE_DOOR); + } + @Override public boolean canFloat() { return this.nodeEvaluator.canFloat(); @@ -148,7 +154,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 +293,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); } @@ -538,7 +544,7 @@ public class PlayerNavigation extends PathNavigation { if (isDone()) return; Vec3 var0 = this.path.getNextEntityPos(this.mob); - this.mob.getMoveControl().setWantedPosition(var0.x, this.getGroundY(var0), var0.z, this.speedModifier); + mvmt.getMoveControl().setWantedPosition(var0.x, this.getGroundY(var0), var0.z, this.speedModifier); } private void timeoutPath() { @@ -563,9 +569,4 @@ public class PlayerNavigation extends PathNavigation { } } } - - private static Mob getDummyInsentient(EntityHumanNPC from, Level world) { - return new Mob(EntityType.VILLAGER, world) { - }; - } } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNodeEvaluator.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNodeEvaluator.java similarity index 95% rename from v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNodeEvaluator.java rename to v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNodeEvaluator.java index f443d90e9..88078c689 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNodeEvaluator.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNodeEvaluator.java @@ -7,13 +7,13 @@ 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_19_R3.entity.EntityHumanNPC; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; 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; @@ -36,7 +36,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 Object2BooleanMap collisionCache = new Object2BooleanOpenHashMap(); protected float oldWaterCost; private final Long2ObjectMap pathTypesByPosCache = new Long2ObjectOpenHashMap(); @@ -60,12 +60,12 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { protected boolean canStartAt(BlockPos var0) { BlockPathTypes var1 = this.getBlockPathType(this.mob, var0); - return var1 != BlockPathTypes.OPEN && this.mob.getPathfindingMalus(var1) >= 0.0F; + return var1 != BlockPathTypes.OPEN && this.mvmt.getPathfindingMalus(var1) >= 0.0F; } @Override public void done() { - this.mob.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost); + this.mvmt.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost); this.pathTypesByPosCache.clear(); this.collisionCache.clear(); super.done(); @@ -98,7 +98,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { return null; } else { BlockPathTypes var12 = this.getCachedBlockType(this.mob, var0, var1, var2); - float var13 = this.mob.getPathfindingMalus(var12); + float var13 = this.mvmt.getPathfindingMalus(var12); double var14 = this.mob.getBbWidth() / 2.0; if (var13 >= 0.0F) { var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12, var13); @@ -147,7 +147,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { } var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12, - this.mob.getPathfindingMalus(var12)); + this.mvmt.getPathfindingMalus(var12)); } } @@ -166,7 +166,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { } var12 = this.getCachedBlockType(this.mob, var0, var1, var2); - var13 = this.mob.getPathfindingMalus(var12); + var13 = this.mvmt.getPathfindingMalus(var12); if (var12 != BlockPathTypes.OPEN && var13 >= 0.0F) { var8 = this.getNodeAndUpdateCostToMax(var0, var1, var2, var12, var13); break; @@ -202,7 +202,7 @@ 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) { + public BlockPathTypes getBlockPathType(BlockGetter var0, int var1, int var2, int var3, LivingEntity var4) { EnumSet var5 = EnumSet.noneOf(BlockPathTypes.class); BlockPathTypes var6 = BlockPathTypes.BLOCKED; var6 = this.getBlockPathTypes(var0, var1, var2, var3, var5, var6, var4.blockPosition()); @@ -216,16 +216,16 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { while (var9.hasNext()) { BlockPathTypes varr9 = (BlockPathTypes) var9.next(); - if (var4.getPathfindingMalus(varr9) < 0.0F) { + if (mvmt.getPathfindingMalus(varr9) < 0.0F) { return varr9; } - if (var4.getPathfindingMalus(varr9) >= var4.getPathfindingMalus(var7)) { + if (mvmt.getPathfindingMalus(varr9) >= mvmt.getPathfindingMalus(var7)) { var7 = varr9; } } - if (var6 == BlockPathTypes.OPEN && var4.getPathfindingMalus(var7) == 0.0F && this.entityWidth <= 1) { + if (var6 == BlockPathTypes.OPEN && mvmt.getPathfindingMalus(var7) == 0.0F && this.entityWidth <= 1) { return BlockPathTypes.OPEN; } else { return var7; @@ -265,7 +265,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { } } - protected BlockPathTypes getBlockPathType(EntityHumanNPC var0, BlockPos var1) { + protected BlockPathTypes getBlockPathType(LivingEntity var0, BlockPos var1) { return this.getCachedBlockType(var0, var1.getX(), var1.getY(), var1.getZ()); } @@ -291,7 +291,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { return var5; } - protected BlockPathTypes getCachedBlockType(EntityHumanNPC var0, int var1, int var2, int var3) { + protected BlockPathTypes getCachedBlockType(LivingEntity var0, int var1, int var2, int var3) { return (BlockPathTypes) this.pathTypesByPosCache.computeIfAbsent(BlockPos.asLong(var1, var2, var3), (var4) -> { return this.getBlockPathType(this.level, var1, var2, var3, var0); }); @@ -318,7 +318,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { int var3 = 0; BlockPathTypes var4 = this.getCachedBlockType(this.mob, var1.x, var1.y + 1, var1.z); BlockPathTypes var5 = this.getCachedBlockType(this.mob, var1.x, var1.y, var1.z); - 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())); } @@ -429,7 +429,7 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { protected Node getStartNode(BlockPos var0) { Node var1 = this.getNode(var0); var1.type = this.getBlockPathType(this.mob, var1.asBlockPos()); - var1.costMalus = this.mob.getPathfindingMalus(var1.type); + var1.costMalus = this.mvmt.getPathfindingMalus(var1.type); return var1; } @@ -470,9 +470,9 @@ public class PlayerNodeEvaluator extends PlayerNodeEvaluatorBase { } @Override - public void prepare(PathNavigationRegion var0, EntityHumanNPC var1) { + public void prepare(PathNavigationRegion var0, LivingEntity var1) { super.prepare(var0, var1); - this.oldWaterCost = var1.getPathfindingMalus(BlockPathTypes.WATER); + this.oldWaterCost = mvmt.getPathfindingMalus(BlockPathTypes.WATER); } @Override diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNodeEvaluatorBase.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNodeEvaluatorBase.java similarity index 90% rename from v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNodeEvaluatorBase.java rename to v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNodeEvaluatorBase.java index 57c02eebc..8a2c87ae1 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerNodeEvaluatorBase.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityNodeEvaluatorBase.java @@ -2,15 +2,15 @@ package net.citizensnpcs.nms.v1_19_R3.util; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import net.citizensnpcs.nms.v1_19_R3.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 boolean canFloat; protected boolean canOpenDoors; protected boolean canPassDoors; @@ -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; protected final Int2ObjectMap nodes = new Int2ObjectOpenHashMap(); @Override @@ -46,6 +47,7 @@ public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator { public void done() { this.level = null; this.mob = null; + this.mvmt = null; } @Override @@ -65,8 +67,9 @@ public abstract class PlayerNodeEvaluatorBase extends NodeEvaluator { return new net.minecraft.world.level.pathfinder.Target(var0); } - public void prepare(PathNavigationRegion var0, EntityHumanNPC var1) { + public void prepare(PathNavigationRegion var0, LivingEntity var1) { this.mob = var1; + this.mvmt = MobAI.from(var1); this.level = var0; this.nodes.clear(); this.entityWidth = Mth.floor(var1.getBbWidth() + 1.0F); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerPathfinder.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityPathfinder.java similarity index 94% rename from v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerPathfinder.java rename to v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityPathfinder.java index 8898b0f2c..3287164c1 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerPathfinder.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/EntityPathfinder.java @@ -13,9 +13,9 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import net.citizensnpcs.Settings.Setting; -import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC; import net.minecraft.core.BlockPos; import net.minecraft.util.profiling.ProfilerFiller; +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; @@ -24,20 +24,20 @@ 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(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 var2, float var3, int var4, + public Path findPath(PathNavigationRegion var0, LivingEntity var1, Set var2, float var3, int var4, float var5) { this.openSet.clear(); this.nodeEvaluator.prepare(var0, var1); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/MobAI.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/MobAI.java new file mode 100644 index 000000000..1f065257a --- /dev/null +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/MobAI.java @@ -0,0 +1,176 @@ +package net.citizensnpcs.nms.v1_19_R3.util; + +import java.util.Map; + +import com.google.common.collect.Maps; + +import net.citizensnpcs.Settings.Setting; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.JumpControl; +import net.minecraft.world.entity.ai.control.MoveControl; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.level.pathfinder.BlockPathTypes; + +public interface MobAI { + org.bukkit.entity.Entity getBukkitEntity(); + + JumpControl getJumpControl(); + + Map getMalus(); + + MoveControl getMoveControl(); + + PathNavigation getNavigation(); + + default float getPathfindingMalus(BlockPathTypes var1) { + Map 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 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 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 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 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; + } +} diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java index 0c9fdd7e7..63e121b40 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java @@ -55,6 +55,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; @@ -118,7 +119,6 @@ import net.citizensnpcs.nms.v1_19_R3.entity.DrownedController; import net.citizensnpcs.nms.v1_19_R3.entity.EnderDragonController; import net.citizensnpcs.nms.v1_19_R3.entity.EndermanController; import net.citizensnpcs.nms.v1_19_R3.entity.EndermiteController; -import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC; import net.citizensnpcs.nms.v1_19_R3.entity.EvokerController; import net.citizensnpcs.nms.v1_19_R3.entity.FoxController; import net.citizensnpcs.nms.v1_19_R3.entity.FrogController; @@ -301,7 +301,10 @@ import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.Pose; import net.minecraft.world.entity.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; @@ -457,14 +460,16 @@ 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); + MoveControl control = ai != null ? ai.getMoveControl() : null; + if (control instanceof EntityMoveControl) { + ((EntityMoveControl) control).moving = false; + } else { try { - MOVE_CONTROLLER_OPERATION.invoke(((Mob) handle).getMoveControl(), null); + MOVE_CONTROLLER_OPERATION.invoke(control, null); } catch (Throwable t) { t.printStackTrace(); } - } else if (handle instanceof EntityHumanNPC) { - ((EntityHumanNPC) handle).getMoveControl().moving = false; } } @@ -587,8 +592,8 @@ public class NMSImpl implements NMSBridge { @Override 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; + MobAI ai = MobAI.from(handle); + MoveControl controller = ai != null ? ai.getMoveControl() : null; if (controller == null || !controller.hasWanted()) { return null; } @@ -732,12 +737,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); } @@ -774,8 +778,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); } @@ -1039,7 +1043,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(); @@ -1074,8 +1078,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); } } @@ -1083,7 +1087,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 { @@ -1098,8 +1102,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); } } @@ -1436,10 +1440,9 @@ public class NMSImpl implements NMSBridge { Entity handle = NMSImpl.getHandle(entity); if (handle == null) 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); + MobAI ai = MobAI.from(handle); + if (ai != null) { + ai.getMoveControl().setWantedPosition(x, y, z, speed); } } @@ -1564,8 +1567,8 @@ public class NMSImpl implements NMSBridge { if (handle instanceof Mob) { JumpControl controller = ((Mob) handle).getJumpControl(); controller.jump(); - } else if (handle instanceof EntityHumanNPC) { - ((EntityHumanNPC) handle).setShouldJump(); + } else { + ((LivingEntity) handle).setJumping(true); } } @@ -1779,10 +1782,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) @@ -2145,12 +2146,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(); @@ -2290,6 +2291,26 @@ public class NMSImpl implements NMSBridge { } } + public static void setAttribute(LivingEntity entity, Attribute attribute, double value) { + AttributeInstance attr = entity.getAttribute(attribute); + if (attr == null) { + try { + AttributeSupplier provider = (AttributeSupplier) ATTRIBUTE_SUPPLIER.invoke(entity.getAttributes()); + Map all = Maps + .newHashMap((Map) 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); @@ -2395,8 +2416,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(); } } @@ -2422,6 +2443,12 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFirstFinalSetter(ServerPlayer.class, PlayerAdvancements.class); + + private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getFirstGetter(AttributeSupplier.class, Map.class); + + private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeSupplier.class, "a"); + private static final MethodHandle ATTRIBUTE_SUPPLIER = NMS.getFirstGetter(AttributeMap.class, + AttributeSupplier.class); private static final Set 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, diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerControllerJump.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerControllerJump.java deleted file mode 100644 index fa9446da0..000000000 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/PlayerControllerJump.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.citizensnpcs.nms.v1_19_R3.util; - -import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC; - -public class PlayerControllerJump { - private boolean a; - private final EntityHumanNPC b; - - public PlayerControllerJump(EntityHumanNPC entityinsentient) { - this.b = entityinsentient; - } - - public void jump() { - this.a = true; - } - - public void tick() { - this.b.setJumping(this.a); - this.a = false; - } -}