diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 0e7059f..e65dea3 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -9,23 +9,20 @@ jobs: os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 - - name: Make gradlew executable - run: chmod +x ./gradlew - - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/actions/setup-gradle@v4 - name: Execute Gradle build run: ./gradlew build - name: Upload a Build Artifact - uses: actions/upload-artifact@v2.2.4 + uses: actions/upload-artifact@v4 if: success() with: name: TerminatorPlus diff --git a/TerminatorPlus-API/build.gradle.kts b/TerminatorPlus-API/build.gradle.kts index d6a703f..6754434 100644 --- a/TerminatorPlus-API/build.gradle.kts +++ b/TerminatorPlus-API/build.gradle.kts @@ -17,6 +17,6 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.19.3-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") compileOnly("com.mojang:authlib:3.2.38") } diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/InternalBridge.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/InternalBridge.java index 54c6f58..639ff90 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/InternalBridge.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/InternalBridge.java @@ -1,6 +1,5 @@ package net.nuggetmc.tplus.api; -import org.bukkit.Sound; import org.bukkit.block.Block; /** @@ -8,6 +7,4 @@ import org.bukkit.block.Block; */ public interface InternalBridge { void sendBlockDestructionPacket(short entityId, Block block, int progress); - - Sound breakBlockSound(Block block); } diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/CustomListMode.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/CustomListMode.java new file mode 100644 index 0000000..e8f7d2f --- /dev/null +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/CustomListMode.java @@ -0,0 +1,28 @@ +package net.nuggetmc.tplus.api.agent.legacyagent; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public enum CustomListMode { + HOSTILE, + RAIDER, + MOB, + CUSTOM; + + public static boolean isValid(String name) { + return from(name) != null; + } + + public static CustomListMode from(String name) { + for (CustomListMode mode : values()) { + if (mode.name().equalsIgnoreCase(name)) { + return mode; + } + } + return null; + } + + public static String listModes() { + return Arrays.stream(values()).map(e -> e.name().toLowerCase()).collect(Collectors.joining("|")); + } +} diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/EnumTargetGoal.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/EnumTargetGoal.java index 02eb72f..61f86eb 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/EnumTargetGoal.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/EnumTargetGoal.java @@ -12,6 +12,7 @@ public enum EnumTargetGoal { NEAREST_BOT("Locate the nearest bot."), NEAREST_BOT_DIFFER("Locate the nearest bot with a different username."), NEAREST_BOT_DIFFER_ALPHA("Locate the nearest bot with a different username after filtering out non-alpha characters."), + CUSTOM_LIST("Locate only the mob types specified in the custom list of mobs"), PLAYER("Target a single player. Defaults to NEAREST_VULNERABLE_PLAYER if no player found."), NONE("No target goal."); @@ -26,6 +27,7 @@ public enum EnumTargetGoal { this.put("nearestbot", NEAREST_BOT); this.put("nearestbotdiffer", NEAREST_BOT_DIFFER); this.put("nearestbotdifferalpha", NEAREST_BOT_DIFFER_ALPHA); + this.put("customlist", CUSTOM_LIST); this.put("player", PLAYER); } }; diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyAgent.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyAgent.java index 15794ab..687f646 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyAgent.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyAgent.java @@ -57,6 +57,9 @@ public class LegacyAgent extends Agent { private double regionWeightY; private double regionWeightZ; + public static final Set CUSTOM_MOB_LIST = new HashSet<>(); + public static CustomListMode customListMode = CustomListMode.CUSTOM; + public LegacyAgent(BotManager manager, Plugin plugin) { super(manager, plugin); @@ -1017,18 +1020,21 @@ public class LegacyAgent extends Agent { } private void preBreak(Terminator bot, LivingEntity player, Block block, LegacyLevel level) { - Material item; - Material type = block.getType(); + List materials = List.of(LegacyItems.PICKAXE, LegacyItems.AXE, LegacyItems.SHOVEL); + ItemStack optimal = new ItemStack(Material.AIR); + float optimalSpeed = 1; - if (LegacyMats.SHOVEL.contains(type)) { - item = LegacyItems.SHOVEL; - } else if (LegacyMats.AXE.contains(type)) { - item = LegacyItems.AXE; - } else { - item = LegacyItems.PICKAXE; + for (Material mat : materials) { + ItemStack tool = new ItemStack(mat); + float destroySpeed = block.getDestroySpeed(tool); + + if (destroySpeed > optimalSpeed) { + optimal = tool; + optimalSpeed = destroySpeed; + } } - bot.setItem(new ItemStack(item)); + bot.setItem(optimal); if (level.isSideDown() || level.isSideDown2()) { bot.setBotPitch(69); @@ -1456,17 +1462,18 @@ public class LegacyAgent extends Agent { case NEAREST_HOSTILE: { for (LivingEntity entity : bot.getBukkitEntity().getWorld().getLivingEntities()) { - if (entity instanceof Monster && validateCloserEntity(entity, loc, result)) { + if ((entity instanceof Monster || (customListMode == CustomListMode.HOSTILE && CUSTOM_MOB_LIST.contains(entity.getType()))) && validateCloserEntity(entity, loc, result)) { result = entity; } } break; } - + case NEAREST_RAIDER: { for (LivingEntity entity : bot.getBukkitEntity().getWorld().getLivingEntities()) { - if ((entity instanceof Raider || (entity instanceof Vex vex && vex.getSummoner() instanceof Raider)) && validateCloserEntity(entity, loc, result)) { + boolean raider = entity instanceof Raider || (entity instanceof Vex vex && vex.getSummoner() instanceof Raider); + if ((raider || (customListMode == CustomListMode.RAIDER && CUSTOM_MOB_LIST.contains(entity.getType()))) && validateCloserEntity(entity, loc, result)) { result = entity; } } @@ -1476,7 +1483,7 @@ public class LegacyAgent extends Agent { case NEAREST_MOB: { for (LivingEntity entity : bot.getBukkitEntity().getWorld().getLivingEntities()) { - if (entity instanceof Mob && validateCloserEntity(entity, loc, result)) { + if ((entity instanceof Mob || (customListMode == CustomListMode.MOB && CUSTOM_MOB_LIST.contains(entity.getType()))) && validateCloserEntity(entity, loc, result)) { result = entity; } } @@ -1526,15 +1533,29 @@ public class LegacyAgent extends Agent { } } } + + break; } - case PLAYER: { //Target a single player. Defaults to NEAREST_VULNERABLE_PLAYER if no player found. + + case CUSTOM_LIST: { + for (LivingEntity entity : bot.getBukkitEntity().getWorld().getLivingEntities()) { + if (customListMode == CustomListMode.CUSTOM && CUSTOM_MOB_LIST.contains(entity.getType()) && validateCloserEntity(entity, loc, result)) { + result = entity; + } + } + + break; + } + + case PLAYER: { if (bot.getTargetPlayer() != null) { Player player = Bukkit.getPlayer(bot.getTargetPlayer()); if (player != null && !botsInPlayerList.contains(player) && validateCloserEntity(player, loc, null)) { - return player; + result = player; } } - return locateTarget(bot, loc, EnumTargetGoal.NEAREST_VULNERABLE_PLAYER); + + break; } } TerminatorLocateTargetEvent event = new TerminatorLocateTargetEvent(bot, result); @@ -1544,26 +1565,26 @@ public class LegacyAgent extends Agent { } private boolean validateCloserEntity(LivingEntity entity, Location loc, LivingEntity result) { - double regionDistEntity = getWeightedRegionDist(entity.getLocation()); - if (regionDistEntity == Double.MAX_VALUE) - return false; - double regionDistResult = result == null ? 0 : getWeightedRegionDist(result.getLocation()); - return loc.getWorld() == entity.getWorld() && !entity.isDead() - && (result == null || (loc.distanceSquared(entity.getLocation()) + regionDistEntity) < (loc.distanceSquared(result.getLocation())) + regionDistResult); + double regionDistEntity = getWeightedRegionDist(entity.getLocation()); + if (regionDistEntity == Double.MAX_VALUE) + return false; + double regionDistResult = result == null ? 0 : getWeightedRegionDist(result.getLocation()); + return loc.getWorld() == entity.getWorld() && !entity.isDead() + && (result == null || (loc.distanceSquared(entity.getLocation()) + regionDistEntity) < (loc.distanceSquared(result.getLocation())) + regionDistResult); } - + private double getWeightedRegionDist(Location loc) { - if (region == null) - return 0; - double diffX = Math.max(0, Math.abs(region.getCenterX() - loc.getX()) - region.getWidthX() * 0.5); - double diffY = Math.max(0, Math.abs(region.getCenterY() - loc.getY()) - region.getHeight() * 0.5); - double diffZ = Math.max(0, Math.abs(region.getCenterZ() - loc.getZ()) - region.getWidthZ() * 0.5); - if (regionWeightX == 0 && regionWeightY == 0 && regionWeightZ == 0) - if (diffX > 0 || diffY > 0 || diffZ > 0) - return Double.MAX_VALUE; - return diffX * diffX * regionWeightX + diffY * diffY * regionWeightY + diffZ * diffZ * regionWeightZ; + if (region == null) + return 0; + double diffX = Math.max(0, Math.abs(region.getCenterX() - loc.getX()) - region.getWidthX() * 0.5); + double diffY = Math.max(0, Math.abs(region.getCenterY() - loc.getY()) - region.getHeight() * 0.5); + double diffZ = Math.max(0, Math.abs(region.getCenterZ() - loc.getZ()) - region.getWidthZ() * 0.5); + if (regionWeightX == 0 && regionWeightY == 0 && regionWeightZ == 0) + if (diffX > 0 || diffY > 0 || diffZ > 0) + return Double.MAX_VALUE; + return diffX * diffX * regionWeightX + diffY * diffY * regionWeightY + diffZ * diffZ * regionWeightZ; } - + @Override public void stopAllTasks() { super.stopAllTasks(); diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyBlockCheck.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyBlockCheck.java index 3fffacc..3b61e59 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyBlockCheck.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyBlockCheck.java @@ -176,7 +176,7 @@ public class LegacyBlockCheck { // Blocks before must all be pass-through Material type = below.getBlock().getType(); - if (type.isSolid() || LegacyMats.canStandOn(type)) + if (LegacyMats.isSolid(type) || LegacyMats.canStandOn(type)) return false; below = below.clone(); } @@ -192,7 +192,7 @@ public class LegacyBlockCheck { Block next = itr.next().getBlock(); boolean placeable = nether ? LegacyMats.canPlaceTwistingVines(next) : LegacyMats.canPlaceWater(next, Optional.absent()); - if (placeable || (!next.getType().isSolid() && !LegacyMats.canStandOn(next.getType()))) + if (placeable || (!LegacyMats.isSolid(next.getType()) && !LegacyMats.canStandOn(next.getType()))) itr.remove(); } diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyMats.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyMats.java index fe37af8..d6bd82e 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyMats.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyMats.java @@ -31,7 +31,7 @@ public class LegacyMats { Material.VINE, Material.FERN, Material.LARGE_FERN, - Material.GRASS, + Material.SHORT_GRASS, Material.TALL_GRASS, Material.SEAGRASS, Material.TALL_SEAGRASS, @@ -54,46 +54,6 @@ public class LegacyMats { Material.SOUL_FIRE )); - public static final Set SHOVEL = new HashSet<>(concatTypes(Lists.newArrayList( - Material.CLAY, - Material.DIRT, - Material.GRASS_BLOCK, - Material.COARSE_DIRT, - Material.PODZOL, - Material.MYCELIUM, - Material.GRAVEL, - Material.MUD, - Material.MUDDY_MANGROVE_ROOTS, - Material.SAND, - Material.RED_SAND, - Material.SOUL_SAND, - Material.SOUL_SOIL, - Material.SNOW, - Material.SNOW_BLOCK - ), Arrays.asList(), Arrays.asList(), m -> m.name().endsWith("_CONCRETE_POWDER"))); - - public static final Set AXE = new HashSet<>(Arrays.asList( - Material.OAK_PLANKS, Material.OAK_DOOR, Material.OAK_FENCE, Material.OAK_FENCE_GATE, Material.OAK_LOG, - Material.OAK_SIGN, Material.OAK_SLAB, Material.OAK_STAIRS, Material.OAK_TRAPDOOR, Material.OAK_WALL_SIGN, Material.OAK_WOOD, - Material.DARK_OAK_PLANKS, Material.DARK_OAK_DOOR, Material.DARK_OAK_FENCE, Material.DARK_OAK_FENCE_GATE, Material.DARK_OAK_LOG, - Material.DARK_OAK_SIGN, Material.DARK_OAK_SLAB, Material.DARK_OAK_STAIRS, Material.DARK_OAK_TRAPDOOR, Material.DARK_OAK_WALL_SIGN, Material.DARK_OAK_WOOD, - Material.ACACIA_PLANKS, Material.ACACIA_DOOR, Material.ACACIA_FENCE, Material.ACACIA_FENCE_GATE, Material.ACACIA_LOG, - Material.ACACIA_SIGN, Material.ACACIA_SLAB, Material.ACACIA_STAIRS, Material.ACACIA_TRAPDOOR, Material.ACACIA_WALL_SIGN, Material.ACACIA_WOOD, - Material.BIRCH_PLANKS, Material.BIRCH_DOOR, Material.BIRCH_FENCE, Material.BIRCH_FENCE_GATE, Material.BIRCH_LOG, - Material.BIRCH_SIGN, Material.BIRCH_SLAB, Material.BIRCH_STAIRS, Material.BIRCH_TRAPDOOR, Material.BIRCH_WALL_SIGN, Material.BIRCH_WOOD, - Material.JUNGLE_PLANKS, Material.JUNGLE_DOOR, Material.JUNGLE_FENCE, Material.JUNGLE_FENCE_GATE, Material.JUNGLE_LOG, - Material.JUNGLE_SIGN, Material.JUNGLE_SLAB, Material.JUNGLE_STAIRS, Material.JUNGLE_TRAPDOOR, Material.JUNGLE_WALL_SIGN, Material.JUNGLE_WOOD, - Material.SPRUCE_PLANKS, Material.SPRUCE_DOOR, Material.SPRUCE_FENCE, Material.SPRUCE_FENCE_GATE, Material.SPRUCE_LOG, - Material.SPRUCE_SIGN, Material.SPRUCE_SLAB, Material.SPRUCE_STAIRS, Material.SPRUCE_TRAPDOOR, Material.SPRUCE_WALL_SIGN, Material.SPRUCE_WOOD, - Material.MANGROVE_PLANKS, Material.MANGROVE_DOOR, Material.MANGROVE_FENCE, Material.MANGROVE_FENCE_GATE, Material.MANGROVE_LOG, - Material.MANGROVE_SIGN, Material.MANGROVE_SLAB, Material.MANGROVE_STAIRS, Material.MANGROVE_TRAPDOOR, Material.MANGROVE_WALL_SIGN, Material.MANGROVE_WOOD, - Material.CRIMSON_PLANKS, Material.CRIMSON_DOOR, Material.CRIMSON_FENCE, Material.CRIMSON_FENCE_GATE, Material.CRIMSON_STEM, - Material.CRIMSON_SIGN, Material.CRIMSON_SLAB, Material.CRIMSON_STAIRS, Material.CRIMSON_TRAPDOOR, Material.CRIMSON_WALL_SIGN, - Material.WARPED_PLANKS, Material.WARPED_DOOR, Material.WARPED_FENCE, Material.WARPED_FENCE_GATE, Material.WARPED_STEM, - Material.WARPED_SIGN, Material.WARPED_SLAB, Material.WARPED_STAIRS, Material.WARPED_TRAPDOOR, Material.WARPED_WALL_SIGN, - Material.CHEST, Material.TRAPPED_CHEST - )); - public static final Set BREAK = new HashSet<>(Arrays.asList( Material.AIR, Material.WATER, @@ -112,6 +72,8 @@ public class LegacyMats { Material.KELP, Material.KELP_PLANT, Material.SUNFLOWER, + Material.TORCHFLOWER, + Material.PITCHER_PLANT, Material.FIRE, Material.SOUL_FIRE )); @@ -207,7 +169,7 @@ public class LegacyMats { public static final Set INSTANT_BREAK = new HashSet<>(concatTypes(Lists.newArrayList( Material.TALL_GRASS, - Material.GRASS, + Material.SHORT_GRASS, Material.FERN, Material.LARGE_FERN, Material.KELP_PLANT, @@ -319,7 +281,7 @@ public class LegacyMats { } public static boolean canPlaceWater(Block block, Optional entityYPos) { - if (block.getType().isSolid()) { + if (isSolid(block.getType())) { if (block.getType() == Material.CHAIN && ((Chain)block.getBlockData()).getAxis() == Axis.Y && !((Chain)block.getBlockData()).isWaterlogged()) return false; @@ -381,7 +343,7 @@ public class LegacyMats { } public static boolean canPlaceTwistingVines(Block block) { - if (block.getType().isSolid()) { + if (isSolid(block.getType())) { if (block.getType().data == Leaves.class) return false; if (block.getType().name().endsWith("_CORAL_FAN") || block.getType().name().endsWith("_CORAL") @@ -515,4 +477,13 @@ public class LegacyMats { return false; } } + + /** + * This set stores solid materials that are added by mods. + */ + public static final Set SOLID_MATERIALS = new HashSet<>(); + + public static boolean isSolid(Material mat) { + return mat.isSolid() || SOLID_MATERIALS.contains(mat); + } } diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyUtils.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyUtils.java index d7c00b7..bddb858 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyUtils.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyUtils.java @@ -1,6 +1,5 @@ package net.nuggetmc.tplus.api.agent.legacyagent; -import net.nuggetmc.tplus.api.TerminatorPlusAPI; import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.block.Block; @@ -32,6 +31,6 @@ public class LegacyUtils { } public static Sound breakBlockSound(Block block) { - return TerminatorPlusAPI.getInternalBridge().breakBlockSound(block); + return block.getBlockData().getSoundGroup().getBreakSound(); } } diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/event/BotFallDamageEvent.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/event/BotFallDamageEvent.java index a294fdf..233a275 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/event/BotFallDamageEvent.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/event/BotFallDamageEvent.java @@ -21,9 +21,9 @@ public class BotFallDamageEvent { public Terminator getBot() { return bot; } - + public List getStandingOn() { - return standingOn; + return standingOn; } public boolean isCancelled() { diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/utils/BotUtils.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/utils/BotUtils.java index 85cfce6..e9ce524 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/utils/BotUtils.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/utils/BotUtils.java @@ -34,12 +34,12 @@ public class BotUtils { return randomSteveUUID(); } - + public static boolean overlaps(BoundingBox playerBox, BoundingBox blockBox) { - return playerBox.overlaps(blockBox); + return playerBox.overlaps(blockBox); } - + public static double getHorizSqDist(Location blockLoc, Location pLoc) { - return NumberConversions.square(blockLoc.getX() + 0.5 - pLoc.getX()) + NumberConversions.square(blockLoc.getZ() + 0.5 - pLoc.getZ()); + return NumberConversions.square(blockLoc.getX() + 0.5 - pLoc.getX()) + NumberConversions.square(blockLoc.getZ() + 0.5 - pLoc.getZ()); } } diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/utils/PlayerUtils.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/utils/PlayerUtils.java index 909bdd9..1b5fc7a 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/utils/PlayerUtils.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/utils/PlayerUtils.java @@ -8,6 +8,8 @@ import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; +import net.nuggetmc.tplus.api.agent.legacyagent.LegacyMats; + import java.io.FileReader; import java.io.IOException; import java.util.HashSet; @@ -53,7 +55,7 @@ public class PlayerUtils { boolean check = false; for (int i = 0; i <= amount; i++) { - if (loc.clone().add(0, i, 0).getBlock().getType().isSolid()) { + if (LegacyMats.isSolid(loc.clone().add(0, i, 0).getBlock().getType())) { check = true; break; } @@ -76,7 +78,7 @@ public class PlayerUtils { break; } - if (check.getBlock().getType().isSolid()) { + if (LegacyMats.isSolid(check.getBlock().getType())) { return check.add(0, 1, 0); } } diff --git a/TerminatorPlus-Plugin/build.gradle.kts b/TerminatorPlus-Plugin/build.gradle.kts index 7399105..bf01938 100644 --- a/TerminatorPlus-Plugin/build.gradle.kts +++ b/TerminatorPlus-Plugin/build.gradle.kts @@ -17,12 +17,6 @@ dependencies { //add the TerminatorPlus-API module implementation(project(":TerminatorPlus-API")) - - // paperweightDevBundle("com.example.paperfork", "1.19-R0.1-SNAPSHOT") - - // You will need to manually specify the full dependency if using the groovy gradle dsl - // (paperDevBundle and paperweightDevBundle functions do not work in groovy) - // paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.19-R0.1-SNAPSHOT") } tasks { diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/TerminatorPlus.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/TerminatorPlus.java index 3570bd7..042754c 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/TerminatorPlus.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/TerminatorPlus.java @@ -52,13 +52,9 @@ public class TerminatorPlus extends JavaPlugin { instance = this; version = getDescription().getVersion(); - String version = Bukkit.getVersion(); - correctVersion = version.contains(REQUIRED_VERSION); - if (version.contains("MC:")) { // git-ABX-123 (MC: ABCD) - version = version.substring(version.indexOf("MC:") + 3, version.indexOf(")")).trim(); - } - mcVersion = version; - getLogger().info("Running on version: " + version + ", required version: " + REQUIRED_VERSION + ", correct version: " + correctVersion); + mcVersion = Bukkit.getServer().getMinecraftVersion(); + correctVersion = mcVersion.equals(REQUIRED_VERSION); + getLogger().info("Running on version: " + mcVersion + ", required version: " + REQUIRED_VERSION + ", correct version: " + correctVersion); // Create Instances this.manager = new BotManagerImpl(); @@ -74,7 +70,7 @@ public class TerminatorPlus extends JavaPlugin { for (int i = 0; i < 20; i++) { // Kids are stupid so we need to make sure they see this getLogger().severe("----------------------------------------"); getLogger().severe("TerminatorPlus is not compatible with your server version!"); - getLogger().severe("You are running on version: " + version + ", required version: " + REQUIRED_VERSION); + getLogger().severe("You are running on version: " + mcVersion + ", required version: " + REQUIRED_VERSION); getLogger().severe("Either download the correct version of TerminatorPlus or update your server. (https://papermc.io/downloads)"); getLogger().severe("----------------------------------------"); } diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/Bot.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/Bot.java index aec6633..51771b2 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/Bot.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/Bot.java @@ -117,12 +117,15 @@ public class Bot extends ServerPlayer implements Terminator { bot.setPos(loc.getX(), loc.getY(), loc.getZ()); bot.setRot(loc.getYaw(), loc.getPitch()); bot.getBukkitEntity().setNoDamageTicks(0); - Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send( - new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, bot))); - if (addPlayerList) + if (addPlayerList) { + Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send( + ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(bot)))); nmsWorld.addNewPlayer(bot); - else + } else { + Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send( + new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, bot))); nmsWorld.addFreshEntity(bot); + } bot.renderAll(); TerminatorPlus.getInstance().getManager().add(bot); @@ -544,7 +547,7 @@ public class Bot extends ServerPlayer implements Terminator { Location loc = new Location(world, x, position().y - 0.01, z); Block block = world.getBlockAt(loc); - if ((block.getType().isSolid() || LegacyMats.canStandOn(block.getType())) && BotUtils.overlaps(playerBox, block.getBoundingBox())) { + if ((LegacyMats.isSolid(block.getType()) || LegacyMats.canStandOn(block.getType())) && BotUtils.overlaps(playerBox, block.getBoundingBox())) { if (!locations.contains(block.getLocation())) { standingOn.add(block); locations.add(block.getLocation()); @@ -563,7 +566,7 @@ public class Bot extends ServerPlayer implements Terminator { blockBox.getMinY() + 1.5, blockBox.getMaxZ()); if ((LegacyMats.FENCE.contains(block.getType()) || LegacyMats.GATES.contains(block.getType())) - && block.getType().isSolid() && BotUtils.overlaps(playerBox, modifiedBox)) { + && LegacyMats.isSolid(block.getType()) && BotUtils.overlaps(playerBox, modifiedBox)) { if (!locations.contains(block.getLocation())) { standingOn.add(block); locations.add(block.getLocation()); @@ -815,7 +818,7 @@ public class Bot extends ServerPlayer implements Terminator { Block block = loc.getBlock(); World world = loc.getWorld(); - if (!block.getType().isSolid()) { + if (!LegacyMats.isSolid(block.getType())) { block.setType(type); if (world != null) world.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1); } @@ -882,6 +885,7 @@ public class Bot extends ServerPlayer implements Terminator { @Override public void doTick() { + detectEquipmentUpdatesPublic(); baseTick(); } diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bridge/InternalBridgeImpl.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bridge/InternalBridgeImpl.java index 5d03de0..133a781 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bridge/InternalBridgeImpl.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bridge/InternalBridgeImpl.java @@ -2,13 +2,8 @@ package net.nuggetmc.tplus.bridge; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; import net.nuggetmc.tplus.api.InternalBridge; -import org.bukkit.Sound; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; import org.bukkit.entity.Player; @@ -20,19 +15,4 @@ public class InternalBridgeImpl implements InternalBridge { ((CraftPlayer) all).getHandle().connection.send(crack); } } - - @Override - public Sound breakBlockSound(Block block) { - try { - Level nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); - BlockState blockState = nmsWorld.getBlockState(new BlockPos(block.getX(), block.getY(), block.getZ())); - net.minecraft.world.level.block.Block nmsBlock = blockState.getBlock(); - - SoundType soundEffectType = nmsBlock.getSoundType(blockState); - - return Sound.valueOf(soundEffectType.getBreakSound().getLocation().getPath().replace(".", "_").toUpperCase()); - } catch (Exception e) { // potentially unsafe, just fallback to stone break sound - return Sound.BLOCK_STONE_BREAK; - } - } } diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/CommandHandler.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/CommandHandler.java index 0a7bb3d..7bc1d2c 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/CommandHandler.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/CommandHandler.java @@ -8,6 +8,7 @@ import net.nuggetmc.tplus.command.annotation.Command; import net.nuggetmc.tplus.command.annotation.Require; import net.nuggetmc.tplus.command.commands.AICommand; import net.nuggetmc.tplus.command.commands.BotCommand; +import net.nuggetmc.tplus.command.commands.BotEnvironmentCommand; import net.nuggetmc.tplus.command.commands.MainCommand; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -43,7 +44,8 @@ public class CommandHandler { registerCommands( new MainCommand(this, "terminatorplus", "The TerminatorPlus main command.", "tplus"), new BotCommand(this, "bot", "The root command for bot management.", "npc"), - new AICommand(this, "ai", "The root command for bot AI training.") + new AICommand(this, "ai", "The root command for bot AI training."), + new BotEnvironmentCommand(this, "botenvironment", "Do /botenvironment help for more information.", "botenv") ); } diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/CommandInstance.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/CommandInstance.java index 216dbeb..3a98937 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/CommandInstance.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/CommandInstance.java @@ -235,17 +235,25 @@ public abstract class CommandInstance extends BukkitCommand { @SuppressWarnings("unchecked") public List tabComplete(@Nonnull CommandSender sender, @Nonnull String label, @Nonnull String[] args) { if (args.length == 1) { - return methods.keySet().stream().filter(c -> !c.isEmpty()).collect(Collectors.toList()); + List result = methods.keySet().stream().filter(c -> !c.isEmpty() && c.contains(args[0])).collect(Collectors.toList()); + if (result.isEmpty()) { + // Add aliases also + methods.forEach((s, m) -> result.addAll(m.getAliases())); + return result.stream().filter(c -> c.contains(args[0])).collect(Collectors.toList()); + } + return result; } if (args.length > 1) { CommandMethod commandMethod = methods.get(args[0]); + if (commandMethod == null) + commandMethod = methods.values().stream().filter(m -> m.getAliases().contains(args[0])).findFirst().orElse(null); if (commandMethod == null) return new ArrayList<>(); Method autofiller = commandMethod.getAutofiller(); if (autofiller != null) { try { - return (List) autofiller.invoke(commandMethod.getHandler(), sender, args); + return ((List) autofiller.invoke(commandMethod.getHandler(), sender, args)).stream().filter(c -> c.contains(args[args.length - 1])).collect(Collectors.toList()); } catch (InvocationTargetException | IllegalAccessException e) { e.printStackTrace(); } diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/AICommand.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/AICommand.java index afd26a4..1554c41 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/AICommand.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/AICommand.java @@ -188,10 +188,6 @@ public class AICommand extends CommandInstance implements AIManager { @Autofill public List infoAutofill(CommandSender sender, String[] args) { - if (args.length == 2) { - return manager.fetchNames(); - } else { - return null; - } + return args.length == 2 ? manager.fetchNames() : new ArrayList<>(); } } diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotCommand.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotCommand.java index 1e362ea..e3ec80b 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotCommand.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotCommand.java @@ -146,6 +146,13 @@ public class BotCommand extends CommandInstance { } private void armorTierSetup() { + armorTiers.put("none", new ItemStack[]{ + new ItemStack(Material.AIR), + new ItemStack(Material.AIR), + new ItemStack(Material.AIR), + new ItemStack(Material.AIR), + }); + armorTiers.put("leather", new ItemStack[]{ new ItemStack(Material.LEATHER_BOOTS), new ItemStack(Material.LEATHER_LEGGINGS), @@ -223,7 +230,7 @@ public class BotCommand extends CommandInstance { @Autofill public List armorAutofill(CommandSender sender, String[] args) { - return args.length == 2 ? new ArrayList<>(armorTiers.keySet()) : null; + return args.length == 2 ? new ArrayList<>(armorTiers.keySet()) : new ArrayList<>(); } @Command( @@ -280,7 +287,7 @@ public class BotCommand extends CommandInstance { @Autofill public List infoAutofill(CommandSender sender, String[] args) { - return args.length == 2 ? manager.fetchNames() : null; + return args.length == 2 ? manager.fetchNames() : new ArrayList<>(); } @Command( @@ -520,12 +527,18 @@ public class BotCommand extends CommandInstance { @Command( name = "debug", desc = "Debug plugin code.", - visible = false + visible = false, + autofill = "debugAutofill" ) public void debug(CommandSender sender, @Arg("expression") String expression) { new Debugger(sender).execute(expression); } + @Autofill + public List debugAutofill(CommandSender sender, String[] args) { + return args.length == 2 ? new ArrayList<>(Debugger.AUTOFILL_METHODS) : new ArrayList<>(); + } + private double parseDoubleOrRelative(String pos, Location loc, int type) { if (loc == null || pos.length() == 0 || pos.charAt(0) != '~') return Double.parseDouble(pos); diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotEnvironmentCommand.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotEnvironmentCommand.java new file mode 100644 index 0000000..3e538ea --- /dev/null +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotEnvironmentCommand.java @@ -0,0 +1,323 @@ +package net.nuggetmc.tplus.command.commands; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import net.nuggetmc.tplus.api.agent.legacyagent.CustomListMode; +import net.nuggetmc.tplus.api.agent.legacyagent.LegacyAgent; +import net.nuggetmc.tplus.api.agent.legacyagent.LegacyMats; +import net.nuggetmc.tplus.api.utils.ChatUtils; +import net.nuggetmc.tplus.command.CommandHandler; +import net.nuggetmc.tplus.command.CommandInstance; +import net.nuggetmc.tplus.command.annotation.Arg; +import net.nuggetmc.tplus.command.annotation.Autofill; +import net.nuggetmc.tplus.command.annotation.Command; + +public class BotEnvironmentCommand extends CommandInstance { + + public BotEnvironmentCommand(CommandHandler handler, String name, String description, String... aliases) { + super(handler, name, description, aliases); + } + + @Command + public void root(CommandSender sender, List args) { + commandHandler.sendRootInfo(this, sender); + } + + @Command( + name = "help", + desc = "Help for /botenvironment.", + autofill = "autofill" + ) + public void help(CommandSender sender, List args) { + if (args.size() > 0 && args.get(0).equals("blocks")) { + sender.sendMessage(ChatUtils.LINE); + sender.sendMessage("If you are running this plugin on a hybrid server, keep in mind that blocks added by mods are not considered solid."); + sender.sendMessage("You must manually add solid blocks added by mods with " + ChatColor.YELLOW + "/botenvironment addSolid " + ChatColor.RESET + "."); + sender.sendMessage(ChatUtils.LINE); + } else if (args.size() > 0 && args.get(0).equals("mobs")) { + sender.sendMessage(ChatUtils.LINE); + sender.sendMessage("The custom mob list is a user-defined list of mobs."); + sender.sendMessage("Use " + ChatColor.YELLOW + "/botenvironment addCustomMob " + ChatColor.RESET + " to add mob types to the list."); + sender.sendMessage("The list can be used in the CUSTOM_LIST targeting option, and can also be appended to the hostile, raider, or mob targeting options."); + sender.sendMessage("When appending, the mobs predefined as well as the mobs in the custom list will be considered."); + sender.sendMessage("Use " + ChatColor.YELLOW + "/botenvironment mobListType" + ChatColor.RESET + " to change the behavior of the custom mob list."); + sender.sendMessage(ChatUtils.LINE); + } else { + sender.sendMessage("Do " + ChatColor.YELLOW + "/botenvironment help blocks " + ChatColor.RESET + "for more information on adding solid blocks."); + sender.sendMessage("Do " + ChatColor.YELLOW + "/botenvironment help mobs " + ChatColor.RESET + "for more information on creating a custom mob list."); + } + } + + @Command( + name = "getMaterial", + desc = "Prints out the current material at the specified location.", + aliases = {"getmat", "getMat", "getmaterial"} + ) + public void getMaterial(Player sender, @Arg("x") String x, @Arg("y") String y, @Arg("z") String z) { + Location loc = sender.getLocation().clone(); + try { + loc.setX(parseDoubleOrRelative(x, loc, 0)); + loc.setY(parseDoubleOrRelative(y, loc, 1)); + loc.setZ(parseDoubleOrRelative(z, loc, 2)); + } catch (NumberFormatException e) { + sender.sendMessage("A valid location must be provided!"); + return; + } + if (!isLocationLoaded(loc)) { + sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is not loaded.", + loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + return; + } + Material mat = loc.getBlock().getType(); + sender.sendMessage(String.format("Material at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + ": " + ChatColor.GREEN + "%s" + ChatColor.RESET, + loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), mat.name())); + } + + @Command( + name = "addSolid", + desc = "Adds a material to the list of solid materials.", + aliases = {"addsolid"}, + autofill = "autofill" + ) + public void addSolid(CommandSender sender, List args) { + Material mat; + if (args.size() == 1) + mat = Material.getMaterial(args.get(0)); + else if (args.size() == 3) { + if (!(sender instanceof Player)) { + sender.sendMessage("You must be a player to specify coordinates!"); + return; + } + Location loc = ((Player)sender).getLocation().clone(); + try { + loc.setX(parseDoubleOrRelative(args.get(0), loc, 0)); + loc.setY(parseDoubleOrRelative(args.get(1), loc, 1)); + loc.setZ(parseDoubleOrRelative(args.get(2), loc, 2)); + } catch (NumberFormatException e) { + sender.sendMessage("A valid location must be provided! " + ChatColor.YELLOW + "/bot addSolid " + ChatColor.RESET); + return; + } + if (!isLocationLoaded(loc)) { + sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is not loaded.", + loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + return; + } + mat = loc.getBlock().getType(); + } else { + sender.sendMessage("Invalid syntax!"); + sender.sendMessage("To specify a material: " + ChatColor.YELLOW + "/bot addSolid " + ChatColor.RESET); + sender.sendMessage("To specify a location containing a material: " + ChatColor.YELLOW + "/bot addSolid " + ChatColor.RESET); + return; + } + if (mat == null) { + sender.sendMessage("The material you specified does not exist!"); + return; + } + if (LegacyMats.SOLID_MATERIALS.add(mat)) + sender.sendMessage("Successfully added " + ChatColor.BLUE + mat.name() + ChatColor.RESET + " to the list."); + else + sender.sendMessage(ChatColor.BLUE + mat.name() + ChatColor.RESET + " already exists in the list!"); + } + + @Command( + name = "removeSolid", + desc = "Removes a material from the list of solid materials.", + aliases = {"removesolid"}, + autofill = "autofill" + ) + public void removeSolid(CommandSender sender, List args) { + Material mat; + if (args.size() == 1) + mat = Material.getMaterial(args.get(0)); + else if (args.size() == 3) { + if (!(sender instanceof Player)) { + sender.sendMessage("You must be a player to specify coordinates!"); + return; + } + Location loc = ((Player)sender).getLocation().clone(); + try { + loc.setX(parseDoubleOrRelative(args.get(0), loc, 0)); + loc.setY(parseDoubleOrRelative(args.get(1), loc, 1)); + loc.setZ(parseDoubleOrRelative(args.get(2), loc, 2)); + } catch (NumberFormatException e) { + sender.sendMessage("A valid location must be provided! " + ChatColor.YELLOW + "/bot removeSolid " + ChatColor.RESET); + return; + } + if (!isLocationLoaded(loc)) { + sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is not loaded.", + loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + return; + } + mat = loc.getBlock().getType(); + } else { + sender.sendMessage("Invalid syntax!"); + sender.sendMessage("To specify a material: " + ChatColor.YELLOW + "/bot removeSolid " + ChatColor.RESET); + sender.sendMessage("To specify a location containing a material: " + ChatColor.YELLOW + "/bot removeSolid " + ChatColor.RESET); + return; + } + if (mat == null) { + sender.sendMessage("The material you specified does not exist!"); + return; + } + if (LegacyMats.SOLID_MATERIALS.remove(mat)) + sender.sendMessage("Successfully removed " + ChatColor.BLUE + mat.name() + ChatColor.RESET + " from the list."); + else + sender.sendMessage(ChatColor.BLUE + mat.name() + ChatColor.RESET + " does not exist in the list!"); + } + + @Command( + name = "listSolids", + desc = "Displays the list of solid materials manually added.", + aliases = {"listsolids"} + ) + public void listSolids(CommandSender sender) { + sender.sendMessage(ChatUtils.LINE); + for (Material mat : LegacyMats.SOLID_MATERIALS) + sender.sendMessage(ChatColor.GREEN + mat.name() + ChatColor.RESET); + sender.sendMessage("Total items: " + ChatColor.BLUE + LegacyMats.SOLID_MATERIALS.size() + ChatColor.RESET); + sender.sendMessage(ChatUtils.LINE); + } + + @Command( + name = "clearSolids", + desc = "Clears the list of solid materials manually added.", + aliases = {"clearsolids"} + ) + public void clearSolids(CommandSender sender) { + int size = LegacyMats.SOLID_MATERIALS.size(); + LegacyMats.SOLID_MATERIALS.clear(); + sender.sendMessage("Removed all " + ChatColor.BLUE + size + ChatColor.RESET + " item(s) from the list."); + } + + @Command( + name = "addCustomMob", + desc = "Adds a mob to the custom list.", + aliases = {"addcustommob"}, + autofill = "autofill" + ) + public void addCustomMob(CommandSender sender, @Arg("mobName") String mobName) { + EntityType type = EntityType.fromName(mobName); + if (type == null) { + sender.sendMessage("The entity type you specified does not exist!"); + return; + } + if (LegacyAgent.CUSTOM_MOB_LIST.add(type)) + sender.sendMessage("Successfully added " + ChatColor.BLUE + type.name() + ChatColor.RESET + " to the list."); + else + sender.sendMessage(ChatColor.BLUE + type.name() + ChatColor.RESET + " already exists in the list!"); + } + + @Command( + name = "removeCustomMob", + desc = "Removes a mob from the custom list.", + aliases = {"removecustommob"}, + autofill = "autofill" + ) + public void removeCustomMob(CommandSender sender, @Arg("mobName") String mobName) { + EntityType type = EntityType.fromName(mobName); + if (type == null) { + sender.sendMessage("The entity type you specified does not exist!"); + return; + } + if (LegacyAgent.CUSTOM_MOB_LIST.remove(type)) + sender.sendMessage("Successfully removed " + ChatColor.BLUE + type.name() + ChatColor.RESET + " from the list."); + else + sender.sendMessage(ChatColor.BLUE + type.name() + ChatColor.RESET + " does not exist in the list!"); + } + + @Command( + name = "listCustomMobs", + desc = "Displays the custom list of mobs.", + aliases = {"listcustommobs"} + ) + public void listCustomMobs(CommandSender sender) { + sender.sendMessage(ChatUtils.LINE); + for (EntityType type : LegacyAgent.CUSTOM_MOB_LIST) + sender.sendMessage(ChatColor.GREEN + type.name() + ChatColor.RESET); + sender.sendMessage("Total items: " + ChatColor.BLUE + LegacyAgent.CUSTOM_MOB_LIST.size() + ChatColor.RESET); + sender.sendMessage(ChatUtils.LINE); + } + + @Command( + name = "clearCustomMobs", + desc = "Clears the custom list of mobs.", + aliases = {"clearcustommobs"} + ) + public void clearCustomMobs(CommandSender sender) { + int size = LegacyAgent.CUSTOM_MOB_LIST.size(); + LegacyAgent.CUSTOM_MOB_LIST.clear(); + sender.sendMessage("Removed all " + ChatColor.BLUE + size + ChatColor.RESET + " item(s) from the list."); + } + + @Command( + name = "mobListType", + desc = "Changes the behavior of the custom mob list.", + aliases = {"moblisttype"}, + autofill = "autofill" + ) + public void mobListType(CommandSender sender, List args) { + if (args.isEmpty()) { + sender.sendMessage("The custom mob list type is " + ChatColor.BLUE + LegacyAgent.customListMode + ChatColor.RESET + "."); + } else if (args.size() > 0 && CustomListMode.isValid(args.get(0))) { + LegacyAgent.customListMode = CustomListMode.from(args.get(0)); + sender.sendMessage( + "Successfully set the custom mob list type to " + ChatColor.BLUE + args.get(0) + ChatColor.RESET + "."); + } else + sender.sendMessage("Usage: " + ChatColor.YELLOW + "/botenvironment mobListType (" + CustomListMode.listModes() + ")" + ChatColor.RESET); + } + + @Autofill + public List autofill(CommandSender sender, String[] args) { + List output = new ArrayList<>(); + if (args.length == 2) { + if (args[0].equals("help")) { + output.add("blocks"); + output.add("mobs"); + } else if (matches(args[0], "addSolid") || matches(args[0], "removeSolid")) { + for (Material mat : Material.values()) + if (!mat.isLegacy()) + output.add(mat.name()); + } else if (matches(args[0], "addCustomMob") || matches(args[0], "removeCustomMob")) { + for (EntityType type : EntityType.values()) + if (type != EntityType.UNKNOWN) + output.add(type.name()); + } else if (matches(args[0], "mobListType")) { + for (CustomListMode mode : CustomListMode.values()) + output.add(mode.name().toLowerCase(Locale.ENGLISH)); + } + } + return output; + } + + private boolean matches(String input, String check) { + return input.equals(check) || input.equals(check.toLowerCase(Locale.ENGLISH)); + } + + private double parseDoubleOrRelative(String pos, Location loc, int type) { + if (loc == null || pos.length() == 0 || pos.charAt(0) != '~') + return Double.parseDouble(pos); + double relative = pos.length() == 1 ? 0 : Double.parseDouble(pos.substring(1)); + switch (type) { + case 0: + return relative + Math.round(loc.getX() * 1000) / 1000D; + case 1: + return relative + Math.round(loc.getY() * 1000) / 1000D; + case 2: + return relative + Math.round(loc.getZ() * 1000) / 1000D; + default: + return 0; + } + } + + private boolean isLocationLoaded(Location loc) { + return loc.getWorld().isChunkLoaded(Location.locToBlock(loc.getX()) >> 4, Location.locToBlock(loc.getZ()) >> 4); + } +} diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/utils/Debugger.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/utils/Debugger.java index 2466e30..83695d6 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/utils/Debugger.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/utils/Debugger.java @@ -16,6 +16,7 @@ import net.nuggetmc.tplus.command.commands.AICommand; import org.bukkit.*; import org.bukkit.command.CommandSender; import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -23,12 +24,30 @@ import org.bukkit.permissions.ServerOperator; import org.bukkit.util.Vector; import java.beans.Statement; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; import java.util.*; import java.util.stream.Collectors; public class Debugger { private final CommandSender sender; + public static final Set AUTOFILL_METHODS = new HashSet<>(); + + static { + for (Method method : Debugger.class.getDeclaredMethods()) { + if (!method.getName().equals("print") && !method.getName().equals("execute") && !method.getName().equals("buildObjects") + && !method.getName().startsWith("lambda$")) { + String autofill = method.getName() + "("; + for (Parameter par : method.getParameters()) { + autofill += par.getType().getSimpleName() + ","; + } + autofill = method.getParameters().length > 0 ? autofill.substring(0, autofill.length() - 1) : autofill; + autofill += ")"; + AUTOFILL_METHODS.add(autofill); + } + } + } public Debugger(CommandSender sender) { this.sender = sender; @@ -241,6 +260,18 @@ public class Debugger { TerminatorPlus.getInstance().getManager().fetch().forEach(bot -> bot.setShield(true)); } + public void totem() { + TerminatorPlus.getInstance().getManager().fetch().forEach(bot -> bot.setItemOffhand(new ItemStack(Material.TOTEM_OF_UNDYING))); + } + + public void clearMainHand() { + TerminatorPlus.getInstance().getManager().fetch().forEach(bot -> bot.setItem(new ItemStack(Material.AIR))); + } + + public void clearOffHand() { + TerminatorPlus.getInstance().getManager().fetch().forEach(bot -> bot.setItemOffhand(new ItemStack(Material.AIR))); + } + public void offsets(boolean b) { Agent agent = TerminatorPlus.getInstance().getManager().getAgent(); if (!(agent instanceof LegacyAgent)) { @@ -447,4 +478,20 @@ public class Debugger { print("The Bot Agent is now " + (b ? ChatColor.RED + "DISABLED" : ChatColor.GREEN + "ENABLED") + ChatColor.RESET + "."); } + + public void printSurroundingMobs(double dist) { + if (!(sender instanceof Player)) { + print("You must be a player to call this."); + return; + } + + Player player = (Player) sender; + double distSq = Math.pow(dist, 2); + for (Entity en : player.getWorld().getEntities()) { + Location loc = en.getLocation(); + if (loc.distanceSquared(player.getLocation()) < distSq) + print(String.format("Entity at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + ": Type " + ChatColor.GREEN + "%s" + ChatColor.RESET, + loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), en.getType().toString())); + } + } } diff --git a/gradlew b/gradlew old mode 100644 new mode 100755