diff --git a/src/main/java/net/nuggetmc/ai/bot/Bot.java b/src/main/java/net/nuggetmc/ai/bot/Bot.java index f601e63..6641231 100644 --- a/src/main/java/net/nuggetmc/ai/bot/Bot.java +++ b/src/main/java/net/nuggetmc/ai/bot/Bot.java @@ -1,20 +1,28 @@ package net.nuggetmc.ai.bot; import com.mojang.authlib.GameProfile; +import com.mojang.datafixers.util.Pair; import net.minecraft.server.v1_16_R3.*; import net.nuggetmc.ai.PlayerAI; import net.nuggetmc.ai.utils.MathUtils; +import net.nuggetmc.ai.utils.MojangAPI; import net.nuggetmc.ai.utils.SteveUUID; -import org.bukkit.Bukkit; -import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.SoundCategory; import org.bukkit.World; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.v1_16_R3.CraftServer; import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; import org.bukkit.craftbukkit.v1_16_R3.entity.CraftEntity; import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.util.Vector; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.UUID; @@ -38,7 +46,7 @@ public class Bot extends EntityPlayer { datawatcher.set(new DataWatcherObject<>(16, DataWatcherRegistry.a), (byte) 0xFF); } - public static Bot createBot(Location loc, String name, String skin) { + public static Bot createBot(Location loc, String name, String[] skin) { MinecraftServer nmsServer = ((CraftServer) Bukkit.getServer()).getServer(); WorldServer nmsWorld = ((CraftWorld) Objects.requireNonNull(loc.getWorld())).getHandle(); @@ -61,25 +69,41 @@ public class Bot extends EntityPlayer { return bot; } + public Vector prevVel = new Vector(0, 0, 0); + public int velCount; + + public static Bot createBot(Location loc, String name, String skinName) { + return createBot(loc, name, MojangAPI.getSkin(skinName)); + } + private void renderAll() { - for (Player player : Bukkit.getOnlinePlayers()) { - PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection; - render(connection, false); + Packet[] packets = getRenderPackets(); + Bukkit.getOnlinePlayers().forEach(p -> render(((CraftPlayer) p).getHandle().playerConnection, packets, false)); + } + + public void render(PlayerConnection connection, Packet[] packets, boolean login) { + connection.sendPacket(packets[0]); + connection.sendPacket(packets[1]); + connection.sendPacket(packets[2]); + + if (login) { + Bukkit.getScheduler().runTaskLater(PlayerAI.getInstance(), () -> connection.sendPacket(packets[3]), 10); + } else { + connection.sendPacket(packets[3]); } } public void render(PlayerConnection connection, boolean login) { - connection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, this)); - connection.sendPacket(new PacketPlayOutNamedEntitySpawn(this)); - connection.sendPacket(new PacketPlayOutEntityMetadata(this.getId(), this.getDataWatcher(), true)); + render(connection, getRenderPackets(), login); + } - PacketPlayOutEntityHeadRotation rotationPacket = new PacketPlayOutEntityHeadRotation(this, (byte) ((this.yaw * 256f) / 360f)); - - if (login) { - Bukkit.getScheduler().runTaskLater(PlayerAI.getInstance(), () -> connection.sendPacket(rotationPacket), 10); - } else { - connection.sendPacket(rotationPacket); - } + private Packet[] getRenderPackets() { + return new Packet[] { + new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, this), + new PacketPlayOutNamedEntitySpawn(this), + new PacketPlayOutEntityMetadata(this.getId(), this.getDataWatcher(), true), + new PacketPlayOutEntityHeadRotation(this, (byte) ((this.yaw * 256f) / 360f)) + }; } public Vector getOffset() { @@ -119,8 +143,8 @@ public class Bot extends EntityPlayer { if (kbTicks > 0) --kbTicks; if (jumpTicks > 0) --jumpTicks; - if (isOnGround()) { - groundTicks++; + if (checkGround()) { + if (groundTicks < 5) groundTicks++; } else { groundTicks = 0; } @@ -157,7 +181,7 @@ public class Bot extends EntityPlayer { y = velocity.getY(); } - velocity.setY(velocity.getY() - 0.1); + velocity.setY(Math.max(velocity.getY() - 0.1, -3.5)); this.move(EnumMoveType.SELF, new Vec3D(velocity.getX(), y, velocity.getZ())); } @@ -183,8 +207,8 @@ public class Bot extends EntityPlayer { swingHand(EnumHand.MAIN_HAND); } - @Override - public boolean isOnGround() { + public boolean checkGround() { + double k = 0.01; double vy = velocity.getY(); if (vy > 0) { @@ -195,13 +219,13 @@ public class Bot extends EntityPlayer { AxisAlignedBB box = getBoundingBox(); double[] xVals = new double[] { - box.minX, - box.maxX + box.minX + k, + box.maxX - k }; double[] zVals = new double[] { - box.minZ, - box.maxZ + box.minZ + k, + box.maxZ - k }; for (double x : xVals) { @@ -215,14 +239,19 @@ public class Bot extends EntityPlayer { return false; } + @Override + public boolean isOnGround() { + return groundTicks != 0; + } + public void addFriction() { double frictionMin = 0.01; double x = velocity.getX(); double z = velocity.getZ(); - velocity.setX(x < frictionMin ? 0 : x * 0.5); - velocity.setZ(z < frictionMin ? 0 : z * 0.5); + velocity.setX(Math.abs(x) < frictionMin ? 0 : x * 0.5); + velocity.setZ(Math.abs(z) < frictionMin ? 0 : z * 0.5); } public void despawn() { @@ -290,14 +319,11 @@ public class Bot extends EntityPlayer { } private void kb(Location loc1, Location loc2) { - double f = 4; double kbUp = 0.3; - Vector diff = loc1.toVector().subtract(loc2.toVector()).setY(0).normalize().multiply(f).setY(kbUp); - Vector vel = velocity.clone().add(diff).multiply(0.3 / f); + Vector vel = loc1.toVector().subtract(loc2.toVector()).setY(0).normalize().multiply(0.3); - if (vel.length() > 1) vel.normalize(); - if (groundTicks != 0) vel.multiply(0.8).setY(0.4); + if (isOnGround()) vel.multiply(0.8).setY(0.4); else if (vel.getY() > kbUp) vel.setY(kbUp); velocity = vel; @@ -309,17 +335,73 @@ public class Bot extends EntityPlayer { } public void faceLocation(Location loc) { - CraftPlayer botPlayer = getBukkitEntity(); - Vector dir = loc.toVector().subtract(botPlayer.getLocation().toVector()); + look(loc.toVector().subtract(getLocation().toVector()), false); + } - float[] vals = MathUtils.fetchYawPitch(dir); + public void look(BlockFace face) { + look(face.getDirection(), face == BlockFace.DOWN || face == BlockFace.UP); + } - setYawPitch(vals[0], vals[1]); + private void look(Vector dir, boolean keepYaw) { + float yaw, pitch; - for (Player player : Bukkit.getOnlinePlayers()) { - PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection; - connection.sendPacket(new PacketPlayOutEntityHeadRotation(botPlayer.getHandle(), (byte) (vals[0] * 256 / 360f))); + if (keepYaw) { + yaw = this.yaw; + pitch = MathUtils.fetchPitch(dir); + } else { + float[] vals = MathUtils.fetchYawPitch(dir); + yaw = vals[0]; + pitch = vals[1]; } + + setYawPitch(yaw, pitch); + + PacketPlayOutEntityHeadRotation packet = new PacketPlayOutEntityHeadRotation(getBukkitEntity().getHandle(), (byte) (yaw * 256 / 360f)); + Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().playerConnection.sendPacket(packet)); + } + + public void attemptBlockPlace(Location loc, Material type) { + setItem(new org.bukkit.inventory.ItemStack(Material.COBBLESTONE)); + punch(); + + Block block = loc.getBlock(); + World world = loc.getWorld(); + + if (!block.getType().isSolid()) { + block.setType(type); + if (world != null) world.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1); + } + } + + public void setItem(org.bukkit.inventory.ItemStack item) { + if (item == null) item = new org.bukkit.inventory.ItemStack(Material.AIR); + + CraftPlayer player = getBukkitEntity(); + player.getInventory().setItemInMainHand(item); + + List> equipment = new ArrayList<>(); + equipment.add(new Pair<>(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(item))); + + PacketPlayOutEntityEquipment packet = new PacketPlayOutEntityEquipment(player.getEntityId(), equipment); + Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().playerConnection.sendPacket(packet)); + } + + public void swim() { + registerPose(EntityPose.SWIMMING); + } + + public void sneak() { + registerPose(EntityPose.CROUCHING); + } + + public void stand() { + registerPose(EntityPose.STANDING); + } + + private void registerPose(EntityPose pose) { + datawatcher.set(DataWatcherRegistry.s.a(6), pose); + PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(getId(), datawatcher, false); + Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().playerConnection.sendPacket(packet)); } @Override diff --git a/src/main/java/net/nuggetmc/ai/bot/BotManager.java b/src/main/java/net/nuggetmc/ai/bot/BotManager.java index 8556aed..7ca28a1 100644 --- a/src/main/java/net/nuggetmc/ai/bot/BotManager.java +++ b/src/main/java/net/nuggetmc/ai/bot/BotManager.java @@ -3,6 +3,7 @@ package net.nuggetmc.ai.bot; import net.minecraft.server.v1_16_R3.PlayerConnection; import net.nuggetmc.ai.PlayerAI; import net.nuggetmc.ai.bot.agent.BotAgent; +import net.nuggetmc.ai.utils.MojangAPI; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Particle; @@ -45,7 +46,7 @@ public class BotManager implements Listener { return agent; } - public void createBots(Player sender, String name, String skin, int n) { + public void createBots(Player sender, String name, String skinName, int n) { long timestamp = System.currentTimeMillis(); if (n < 1) n = 1; @@ -54,17 +55,19 @@ public class BotManager implements Listener { Location loc = sender.getLocation(); if (name.length() > 16) name = name.substring(0, 16); - if (skin != null && skin.length() > 16) skin = skin.substring(0, 16); + if (skinName != null && skinName.length() > 16) skinName = skinName.substring(0, 16); sender.sendMessage("Creating " + (n == 1 ? "new bot" : ChatColor.RED + numberFormat.format(n) + ChatColor.RESET + " new bots") + " with name " + ChatColor.GREEN + name - + (skin == null ? "" : ChatColor.RESET + " and skin " + ChatColor.GREEN + skin) + + (skinName == null ? "" : ChatColor.RESET + " and skin " + ChatColor.GREEN + skinName) + ChatColor.RESET + "..."); - skin = skin == null ? name : skin; + skinName = skinName == null ? name : skinName; double f = n < 100 ? .004 * n : .4; + String[] skin = MojangAPI.getSkin(skinName); + for (int i = 0; i < n; i++) { Bot bot = Bot.createBot(loc, name, skin); if (i > 0) bot.setVelocity(new Vector(Math.random() - 0.5, 0.5, Math.random() - 0.5).normalize().multiply(f)); @@ -76,19 +79,13 @@ public class BotManager implements Listener { } public void reset() { - for (Bot bot : bots) { - bot.remove(); - } - + bots.forEach(Bot::remove); bots.clear(); } @EventHandler public void onJoin(PlayerJoinEvent event) { PlayerConnection connection = ((CraftPlayer) event.getPlayer()).getHandle().playerConnection; - - for (Bot bot : bots) { - bot.render(connection, true); - } + bots.forEach(b -> b.render(connection, true)); } } diff --git a/src/main/java/net/nuggetmc/ai/bot/CustomGameProfile.java b/src/main/java/net/nuggetmc/ai/bot/CustomGameProfile.java index e77b9d7..40e90eb 100644 --- a/src/main/java/net/nuggetmc/ai/bot/CustomGameProfile.java +++ b/src/main/java/net/nuggetmc/ai/bot/CustomGameProfile.java @@ -8,17 +8,25 @@ import java.util.UUID; public class CustomGameProfile extends GameProfile { - public CustomGameProfile(UUID uuid, String name, String skin) { + public CustomGameProfile(UUID uuid, String name, String[] skin) { super(uuid, name); setSkin(skin); } - public void setSkin(String skin) { - String[] vals = MojangAPI.getSkin(skin); + public CustomGameProfile(UUID uuid, String name, String skinName) { + super(uuid, name); - if (vals != null) { - getProperties().put("textures", new Property("textures", vals[0], vals[1])); + setSkin(skinName); + } + + public void setSkin(String skinName) { + setSkin(MojangAPI.getSkin(skinName)); + } + + public void setSkin(String[] skin) { + if (skin != null) { + getProperties().put("textures", new Property("textures", skin[0], skin[1])); } } } diff --git a/src/main/java/net/nuggetmc/ai/bot/agent/BotAgent.java b/src/main/java/net/nuggetmc/ai/bot/agent/BotAgent.java index b4b201b..e73f146 100644 --- a/src/main/java/net/nuggetmc/ai/bot/agent/BotAgent.java +++ b/src/main/java/net/nuggetmc/ai/bot/agent/BotAgent.java @@ -15,15 +15,12 @@ import java.util.Set; public class BotAgent { - private PlayerAI plugin; - private BotManager manager; - + private final PlayerAI plugin; + private final BotManager manager; private final BukkitScheduler scheduler; private boolean enabled; - private int taskID; - private int count; public BotAgent(BotManager manager) { @@ -54,6 +51,7 @@ public class BotAgent { bots.forEach(this::tickBot); } + // This is where the code starts to get spicy private void tickBot(Bot bot) { Location loc = bot.getLocation(); @@ -71,17 +69,45 @@ public class BotAgent { // if checkVertical(bot) { break block action add; return; } - // BotSituation situation = BotSituation.create(bot); + BotSituation situation = new BotSituation(bot, target); // based on the situation, the bot can perform different actions // there can be priorities assigned - if (bot.tickDelay(3)) attack(bot, player, loc); + // for building up, bot.setAction(BotAction.TOWER) or bot.startBuildingUp() + + VerticalDisplacement disp = situation.getVerticalDisplacement(); + + // Later on maybe do bot.setAction(Action.MOVE) and what not instead of hardcoding it here + + // bot.setSneaking(false); move(bot, player, loc, target); + /*if (disp == VerticalDisplacement.ABOVE) { + if (bot.isOnGround()) { // checks this twice, again during .jump() + bot.sneak(); + bot.look(BlockFace.DOWN); + bot.jump(); + // bot.setSneaking(true); + + // delay -> block place underneath and .setSneaking(false) << check possibilities of cancelling (add a cancel system) + // catch exceptions for slabs + scheduler.runTaskLater(plugin, () -> { + if (bot.isAlive()) { + bot.setItem(new ItemStack(Material.COBBLESTONE)); + bot.attemptBlockPlace(loc, Material.COBBLESTONE); + } + }, 6); + + } // maybe they will be in water or something, do not make them just do nothing here + } else { + move(bot, player, loc, target); + }*/ + + if (bot.tickDelay(3)) attack(bot, player, loc); } private void attack(Bot bot, Player player, Location loc) { - if (player.getNoDamageTicks() >= 5 || loc.distance(player.getLocation()) >= 4) return; + if (!PlayerUtils.isVulnerableGameMode(player.getGameMode()) || player.getNoDamageTicks() >= 5 || loc.distance(player.getLocation()) >= 4) return; bot.attack(player); } @@ -90,9 +116,12 @@ public class BotAgent { Vector vel = target.toVector().subtract(loc.toVector()).normalize(); if (bot.tickDelay(5)) bot.faceLocation(player.getLocation()); + if (!bot.isOnGround()) return; // calling this a second time later on + + bot.stand(); // eventually create a memory system so packets do not have to be sent every tick + bot.setItem(null); // method to check item in main hand, bot.getItemInHand() try { - vel.checkFinite(); vel.add(bot.velocity); } catch (IllegalArgumentException e) { if (!MathUtils.isFinite(vel)) { diff --git a/src/main/java/net/nuggetmc/ai/bot/agent/BotSituation.java b/src/main/java/net/nuggetmc/ai/bot/agent/BotSituation.java new file mode 100644 index 0000000..6115df6 --- /dev/null +++ b/src/main/java/net/nuggetmc/ai/bot/agent/BotSituation.java @@ -0,0 +1,23 @@ +package net.nuggetmc.ai.bot.agent; + +import net.nuggetmc.ai.bot.Bot; +import org.bukkit.Location; + +public class BotSituation { + + private final VerticalDisplacement disp; + + /* + * aboveGround + */ + + public BotSituation(Bot bot, Location target) { + Location loc = bot.getLocation(); + + this.disp = VerticalDisplacement.fetch(loc.getBlockY(), target.getBlockY()); + } + + public VerticalDisplacement getVerticalDisplacement() { + return disp; + } +} diff --git a/src/main/java/net/nuggetmc/ai/bot/agent/VerticalDisplacement.java b/src/main/java/net/nuggetmc/ai/bot/agent/VerticalDisplacement.java new file mode 100644 index 0000000..2d2d9b6 --- /dev/null +++ b/src/main/java/net/nuggetmc/ai/bot/agent/VerticalDisplacement.java @@ -0,0 +1,16 @@ +package net.nuggetmc.ai.bot.agent; + +public enum VerticalDisplacement { + AT, + ABOVE, + BELOW; + + public static VerticalDisplacement fetch(int botY, int targetY) { + int diff = botY - targetY; + + if (diff >= 2) return BELOW; + if (diff <= -2) return ABOVE; + + return AT; + } +} diff --git a/src/main/java/net/nuggetmc/ai/command/CommandHandler.java b/src/main/java/net/nuggetmc/ai/command/CommandHandler.java index aadec93..4f0fd14 100644 --- a/src/main/java/net/nuggetmc/ai/command/CommandHandler.java +++ b/src/main/java/net/nuggetmc/ai/command/CommandHandler.java @@ -5,7 +5,7 @@ import com.jonahseguin.drink.annotation.Command; import com.jonahseguin.drink.command.DrinkCommandService; import com.jonahseguin.drink.utils.ChatUtils; import net.nuggetmc.ai.PlayerAI; -import net.nuggetmc.ai.command.commands.PlayerAICommand; +import net.nuggetmc.ai.command.commands.MainCommand; import org.bukkit.ChatColor; import java.lang.reflect.Method; @@ -22,11 +22,11 @@ public class CommandHandler { public CommandHandler(PlayerAI plugin) { drink = (DrinkCommandService) Drink.get(plugin); - drink.register(new PlayerAICommand(this), "playerai.manage", "bot", "playerai", "pai", "ai", "npc"); + drink.register(new MainCommand(this), "playerai.manage", "bot", "playerai", "pai", "ai", "npc"); drink.registerCommands(); help = new HashMap<>(); - setHelps(PlayerAICommand.class); + setHelps(MainCommand.class); } @SafeVarargs diff --git a/src/main/java/net/nuggetmc/ai/command/commands/PlayerAICommand.java b/src/main/java/net/nuggetmc/ai/command/commands/MainCommand.java similarity index 95% rename from src/main/java/net/nuggetmc/ai/command/commands/PlayerAICommand.java rename to src/main/java/net/nuggetmc/ai/command/commands/MainCommand.java index 16bba85..7843219 100644 --- a/src/main/java/net/nuggetmc/ai/command/commands/PlayerAICommand.java +++ b/src/main/java/net/nuggetmc/ai/command/commands/MainCommand.java @@ -14,12 +14,12 @@ import org.bukkit.entity.Player; import java.text.NumberFormat; import java.util.Locale; -public class PlayerAICommand extends CommandInstance { +public class MainCommand extends CommandInstance { private PlayerAI plugin; private BotManager manager; - public PlayerAICommand(CommandHandler commandHandler) { + public MainCommand(CommandHandler commandHandler) { super(commandHandler); this.plugin = PlayerAI.getInstance(); diff --git a/src/main/java/net/nuggetmc/ai/utils/Debugger.java b/src/main/java/net/nuggetmc/ai/utils/Debugger.java index 2bf6c7c..1d4669e 100644 --- a/src/main/java/net/nuggetmc/ai/utils/Debugger.java +++ b/src/main/java/net/nuggetmc/ai/utils/Debugger.java @@ -3,6 +3,7 @@ package net.nuggetmc.ai.utils; import net.nuggetmc.ai.PlayerAI; import net.nuggetmc.ai.bot.Bot; import net.nuggetmc.ai.bot.agent.BotAgent; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.World; @@ -10,6 +11,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.bukkit.permissions.ServerOperator; import java.beans.Statement; import java.util.ArrayList; @@ -27,9 +29,17 @@ public class Debugger { this.sender = sender; } + public static void log(Object... objects) { + String[] values = formStringArray(objects); + Bukkit.getOnlinePlayers().stream().filter(ServerOperator::isOp).forEach(p -> p.sendMessage(PREFIX + String.join(" ", values))); + } + + private static String[] formStringArray(Object[] objects) { + return Arrays.stream(objects).map(Object::toString).toArray(String[]::new); + } + private void print(Object... objects) { - String[] values = Arrays.stream(objects).map(Object::toString).toArray(String[]::new); - sender.sendMessage(PREFIX + String.join(" ", values)); + sender.sendMessage(PREFIX + String.join(" ", formStringArray(objects))); } public void execute(String cmd) { @@ -40,7 +50,7 @@ public class Debugger { String name = cmd.substring(0, pts[0]); String content = cmd.substring(pts[0] + 1, pts[1]); - Statement statement = new Statement(this, name, new Object[]{content}); + Statement statement = new Statement(this, name, content.isEmpty() ? null : new Object[]{content}); print("Running the expression \"" + ChatColor.AQUA + cmd + ChatColor.RESET + "\"..."); statement.execute(); } @@ -65,6 +75,20 @@ public class Debugger { return list.toArray(); } + public void trackYVel() { + if (!(sender instanceof Player)) return; + + Player player = (Player) sender; + + Bukkit.getScheduler().scheduleSyncRepeatingTask(PlayerAI.getInstance(), () -> { + print(player.getVelocity().getY()); + }, 0, 1); + } + + public void t() { + Bukkit.dispatchCommand(sender, "bot debug t(" + !PlayerUtils.getAllTargetable() + ")"); + } + public void t(String content) { Object[] obj = buildObjects(content); @@ -83,7 +107,7 @@ public class Debugger { } } - public void hideNametags(String content) { // this works for some reason + public void hideNametags() { // this works for some reason Set bots = PlayerAI.getInstance().getManager().fetch(); for (Bot bot : bots) { @@ -106,7 +130,7 @@ public class Debugger { } } - public void sit(String content) { + public void sit() { Set bots = PlayerAI.getInstance().getManager().fetch(); for (Bot bot : bots) { @@ -130,7 +154,7 @@ public class Debugger { } } - public void look(String content) { + public void look() { if (!(sender instanceof Player)) { print("Unspecified player."); return; @@ -152,7 +176,7 @@ public class Debugger { Arrays.stream(buildObjects(content)).forEach(this::print); } - public void toggleAgent(String content) { + public void toggleAgent() { BotAgent agent = PlayerAI.getInstance().getManager().getAgent(); boolean b = agent.isEnabled(); diff --git a/src/main/java/net/nuggetmc/ai/utils/MathUtils.java b/src/main/java/net/nuggetmc/ai/utils/MathUtils.java index f2ee5ce..aff233a 100644 --- a/src/main/java/net/nuggetmc/ai/utils/MathUtils.java +++ b/src/main/java/net/nuggetmc/ai/utils/MathUtils.java @@ -28,6 +28,26 @@ public class MathUtils { return out; } + public static float fetchPitch(Vector dir) { + double x = dir.getX(); + double z = dir.getZ(); + + float result; + + if (x == 0.0D && z == 0.0D) { + result = (float) (dir.getY() > 0.0D ? -90 : 90); + } + + else { + double x2 = NumberConversions.square(x); + double z2 = NumberConversions.square(z); + double xz = Math.sqrt(x2 + z2); + result = (float) Math.toDegrees(Math.atan(-dir.getY() / xz)); + } + + return result; + } + public static Vector circleOffset(double r) { double rad = 2 * Math.random() * Math.PI; diff --git a/src/main/java/net/nuggetmc/ai/utils/PlayerUtils.java b/src/main/java/net/nuggetmc/ai/utils/PlayerUtils.java index a0785ff..4805d6e 100644 --- a/src/main/java/net/nuggetmc/ai/utils/PlayerUtils.java +++ b/src/main/java/net/nuggetmc/ai/utils/PlayerUtils.java @@ -7,7 +7,11 @@ public class PlayerUtils { public static boolean allTargetable; public static boolean isTargetable(GameMode mode) { - return allTargetable || mode == GameMode.SURVIVAL || mode == GameMode.ADVENTURE; + return allTargetable || isVulnerableGameMode(mode); + } + + public static boolean isVulnerableGameMode(GameMode mode) { + return mode == GameMode.SURVIVAL || mode == GameMode.ADVENTURE; } public static void setAllTargetable(boolean b) {