refactored almost everything into the API module, and left NMS stuff in plugin module, and performance improvements
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
package net.nuggetmc.tplus.api;
|
||||
|
||||
public interface AIManager {
|
||||
void clearSession();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package net.nuggetmc.tplus.api;
|
||||
|
||||
import net.nuggetmc.tplus.api.agent.Agent;
|
||||
import net.nuggetmc.tplus.api.agent.legacyagent.ai.NeuralNetwork;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface BotManager {
|
||||
Set<Terminator> fetch();
|
||||
|
||||
Agent getAgent();
|
||||
|
||||
void add(Terminator bot);
|
||||
|
||||
Terminator getFirst(String name);
|
||||
|
||||
List<String> fetchNames();
|
||||
|
||||
void createBots(Player sender, String name, String skinName, int n);
|
||||
|
||||
void createBots(Player sender, String name, String skinName, int n, NeuralNetwork network);
|
||||
|
||||
Set<Terminator> createBots(Location loc, String name, String[] skin, List<NeuralNetwork> networks);
|
||||
|
||||
Set<Terminator> createBots(Location loc, String name, String[] skin, int n, NeuralNetwork network);
|
||||
|
||||
void remove(Terminator bot);
|
||||
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Get a bot from a Player object
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
* @deprecated Use {@link #getBot(UUID)} instead as this may no longer work
|
||||
*/
|
||||
@Deprecated
|
||||
Terminator getBot(Player player);
|
||||
|
||||
Terminator getBot(UUID uuid);
|
||||
|
||||
Terminator getBot(int entityId);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.nuggetmc.tplus.api;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
/**
|
||||
* This class serves as a bridge between the API and internal code that interacts with NMS.
|
||||
*/
|
||||
public interface InternalBridge {
|
||||
void sendBlockDestructionPacket(short entityId, int x, int y, int z, int progress);
|
||||
|
||||
Sound breakBlockSound(Block block);
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
package net.nuggetmc.tplus.api;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.nuggetmc.tplus.api.agent.legacyagent.ai.NeuralNetwork;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
@@ -15,8 +15,12 @@ public interface Terminator {
|
||||
|
||||
String getBotName();
|
||||
|
||||
int getId();
|
||||
|
||||
GameProfile getGameProfile();
|
||||
|
||||
LivingEntity getBukkitEntity();
|
||||
|
||||
NeuralNetwork getNeuralNetwork();
|
||||
|
||||
void setNeuralNetwork(NeuralNetwork neuralNetwork);
|
||||
@@ -25,6 +29,8 @@ public interface Terminator {
|
||||
|
||||
Location getLocation();
|
||||
|
||||
boolean isAlive();
|
||||
|
||||
float getHealth();
|
||||
|
||||
float getMaxHealth();
|
||||
@@ -41,6 +47,10 @@ public interface Terminator {
|
||||
|
||||
boolean isInWater();
|
||||
|
||||
boolean isOnGround();
|
||||
|
||||
void setXRot(float pitch);
|
||||
|
||||
void jump(Vector velocity);
|
||||
|
||||
void jump();
|
||||
@@ -49,6 +59,8 @@ public interface Terminator {
|
||||
|
||||
void look(BlockFace face);
|
||||
|
||||
void faceLocation(Location location);
|
||||
|
||||
void attack(Entity target);
|
||||
|
||||
void attemptBlockPlace(Location loc, Material type, boolean down);
|
||||
@@ -88,4 +100,8 @@ public interface Terminator {
|
||||
int getAliveTicks();
|
||||
|
||||
boolean tickDelay(int ticks);
|
||||
|
||||
void renderBot(Object packetListener, boolean login);
|
||||
|
||||
void setOnFirePackets(boolean onFire);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.nuggetmc.tplus.api;
|
||||
|
||||
public class TerminatorPlusAPI {
|
||||
private static InternalBridge internalBridge;
|
||||
private static BotManager botManager;
|
||||
|
||||
public static InternalBridge getInternalBridge() {
|
||||
return internalBridge;
|
||||
}
|
||||
|
||||
public static void setInternalBridge(InternalBridge internalBridge) {
|
||||
TerminatorPlusAPI.internalBridge = internalBridge;
|
||||
}
|
||||
|
||||
public static BotManager getBotManager() {
|
||||
return botManager;
|
||||
}
|
||||
|
||||
public static void setBotManager(BotManager botManager) {
|
||||
TerminatorPlusAPI.botManager = botManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package net.nuggetmc.tplus.api.agent;
|
||||
|
||||
import net.nuggetmc.tplus.api.BotManager;
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import net.nuggetmc.tplus.api.event.BotDamageByPlayerEvent;
|
||||
import net.nuggetmc.tplus.api.event.BotDeathEvent;
|
||||
import net.nuggetmc.tplus.api.event.BotFallDamageEvent;
|
||||
import net.nuggetmc.tplus.api.event.BotKilledByPlayerEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class Agent {
|
||||
|
||||
protected final Plugin plugin;
|
||||
protected final BotManager manager;
|
||||
protected final BukkitScheduler scheduler;
|
||||
protected final Set<BukkitRunnable> taskList;
|
||||
protected final Random random;
|
||||
|
||||
protected boolean enabled;
|
||||
protected int taskID;
|
||||
|
||||
protected boolean drops;
|
||||
|
||||
public Agent(BotManager manager, Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.manager = manager;
|
||||
this.scheduler = Bukkit.getScheduler();
|
||||
this.taskList = new HashSet<>();
|
||||
this.random = new Random();
|
||||
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean b) {
|
||||
enabled = b;
|
||||
|
||||
if (b) {
|
||||
taskID = scheduler.scheduleSyncRepeatingTask(plugin, this::tick, 0, 1);
|
||||
} else {
|
||||
scheduler.cancelTask(taskID);
|
||||
stopAllTasks();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopAllTasks() {
|
||||
if (!taskList.isEmpty()) {
|
||||
taskList.stream().filter(t -> !t.isCancelled()).forEach(BukkitRunnable::cancel);
|
||||
taskList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDrops(boolean enabled) {
|
||||
this.drops = enabled;
|
||||
}
|
||||
|
||||
protected abstract void tick();
|
||||
|
||||
public void onFallDamage(BotFallDamageEvent event) {
|
||||
}
|
||||
|
||||
public void onPlayerDamage(BotDamageByPlayerEvent event) {
|
||||
}
|
||||
|
||||
public void onBotDeath(BotDeathEvent event) {
|
||||
}
|
||||
|
||||
public void onBotKilledByPlayer(BotKilledByPlayerEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
scheduler.runTaskAsynchronously(plugin, () -> {
|
||||
Terminator bot = manager.getBot(player);
|
||||
|
||||
if (bot != null) {
|
||||
bot.incrementKills();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package net.nuggetmc.tplus.api.agent.botagent;
|
||||
|
||||
import net.nuggetmc.tplus.api.BotManager;
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import net.nuggetmc.tplus.api.agent.Agent;
|
||||
import net.nuggetmc.tplus.api.utils.MathUtils;
|
||||
import net.nuggetmc.tplus.api.utils.PlayerUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* New bot agent!!!!!
|
||||
* this will replace legacyagent eventually
|
||||
* - basically this one will actually have A* pathfinding, whereas the legacy one only straightlines
|
||||
*/
|
||||
|
||||
public class BotAgent extends Agent {
|
||||
|
||||
private int count;
|
||||
|
||||
public BotAgent(BotManager manager, Plugin plugin) {
|
||||
super(manager, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tick() {
|
||||
Set<Terminator> bots = manager.fetch();
|
||||
count = bots.size();
|
||||
bots.forEach(this::tickBot);
|
||||
}
|
||||
|
||||
// This is where the code starts to get spicy
|
||||
private void tickBot(Terminator bot) {
|
||||
if (!bot.isAlive()) return;
|
||||
|
||||
Location loc = bot.getLocation();
|
||||
|
||||
// if bot.hasHoldState() return; << This will be to check if a bot is mining or something similar where it can't move
|
||||
|
||||
Player player = nearestPlayer(loc);
|
||||
if (player == null) return;
|
||||
|
||||
Location target = player.getLocation();
|
||||
|
||||
if (count > 1) target.add(bot.getOffset());
|
||||
|
||||
// Make the XZ offsets stored in the bot object (so they don't form a straight line),
|
||||
// and make it so when mining and stuff, the offset is not taken into account
|
||||
|
||||
// if checkVertical(bot) { break block action add; return; }
|
||||
|
||||
BotSituation situation = new BotSituation(bot, target);
|
||||
|
||||
// based on the situation, the bot can perform different actions
|
||||
// there can be priorities assigned
|
||||
|
||||
// for building up, bot.setAction(BotAction.TOWER) or bot.startBuildingUp()
|
||||
|
||||
VerticalDisplacement disp = situation.getVerticalDisplacement();
|
||||
|
||||
// Later on maybe do bot.setAction(Action.MOVE) and what not instead of hardcoding it here
|
||||
|
||||
// bot.setSneaking(false);
|
||||
move(bot, player, loc, target);
|
||||
/*if (disp == VerticalDisplacement.ABOVE) {
|
||||
if (bot.isOnGround()) { // checks this twice, again during .jump()
|
||||
bot.sneak();
|
||||
bot.look(BlockFace.DOWN);
|
||||
bot.jump();
|
||||
// bot.setSneaking(true);
|
||||
|
||||
// delay -> block place underneath and .setSneaking(false) << check possibilities of cancelling (add a cancel system)
|
||||
// catch exceptions for slabs
|
||||
scheduler.runTaskLater(plugin, () -> {
|
||||
if (bot.isAlive()) {
|
||||
bot.setItem(new ItemStack(Material.COBBLESTONE));
|
||||
bot.attemptBlockPlace(loc, Material.COBBLESTONE);
|
||||
}
|
||||
}, 6);
|
||||
|
||||
} // maybe they will be in water or something, do not make them just do nothing here
|
||||
} else {
|
||||
move(bot, player, loc, target);
|
||||
}*/
|
||||
|
||||
if (bot.tickDelay(3)) attack(bot, player, loc);
|
||||
}
|
||||
|
||||
private void attack(Terminator bot, Player player, Location loc) {
|
||||
if (PlayerUtils.isInvincible(player.getGameMode()) || player.getNoDamageTicks() >= 5 || loc.distance(player.getLocation()) >= 4)
|
||||
return;
|
||||
|
||||
bot.attack(player);
|
||||
}
|
||||
|
||||
private void move(Terminator bot, Player player, Location loc, Location target) {
|
||||
Vector vel = target.toVector().subtract(loc.toVector()).normalize();
|
||||
|
||||
if (bot.tickDelay(5)) bot.faceLocation(player.getLocation());
|
||||
if (!bot.isOnGround()) return; // calling this a second time later on
|
||||
|
||||
bot.stand(); // eventually create a memory system so packets do not have to be sent every tick
|
||||
bot.setItem(null); // method to check item in main hand, bot.getItemInHand()
|
||||
|
||||
try {
|
||||
vel.add(bot.getVelocity());
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (MathUtils.isNotFinite(vel)) {
|
||||
MathUtils.clean(vel);
|
||||
}
|
||||
}
|
||||
|
||||
if (vel.length() > 1) vel.normalize();
|
||||
|
||||
if (loc.distance(target) <= 5) {
|
||||
vel.multiply(0.3);
|
||||
} else {
|
||||
vel.multiply(0.4);
|
||||
}
|
||||
|
||||
vel.setY(0.4);
|
||||
|
||||
bot.jump(vel);
|
||||
}
|
||||
|
||||
private Player nearestPlayer(Location loc) {
|
||||
Player result = null;
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (PlayerUtils.isInvincible(player.getGameMode()) || loc.getWorld() != player.getWorld()) continue;
|
||||
|
||||
if (result == null || loc.distance(player.getLocation()) < loc.distance(result.getLocation())) {
|
||||
result = player;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.nuggetmc.tplus.api.agent.botagent;
|
||||
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class BotSituation {
|
||||
|
||||
private final VerticalDisplacement disp;
|
||||
|
||||
/*
|
||||
* aboveGround
|
||||
*/
|
||||
|
||||
public BotSituation(Terminator bot, Location target) {
|
||||
Location loc = bot.getLocation();
|
||||
|
||||
this.disp = VerticalDisplacement.fetch(loc.getBlockY(), target.getBlockY());
|
||||
}
|
||||
|
||||
public VerticalDisplacement getVerticalDisplacement() {
|
||||
return disp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.nuggetmc.tplus.api.agent.botagent;
|
||||
|
||||
public enum VerticalDisplacement {
|
||||
AT,
|
||||
ABOVE,
|
||||
BELOW;
|
||||
|
||||
public static VerticalDisplacement fetch(int botY, int targetY) {
|
||||
int diff = botY - targetY;
|
||||
|
||||
if (diff >= 2) return BELOW;
|
||||
if (diff <= -2) return ABOVE;
|
||||
|
||||
return AT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum EnumTargetGoal {
|
||||
NEAREST_VULNERABLE_PLAYER("Locate the nearest real player that is in either Survival or Adventure mode."),
|
||||
NEAREST_PLAYER("Locate the nearest real online player, despite the gamemode."),
|
||||
NEAREST_HOSTILE("Locate the nearest hostile entity."),
|
||||
NEAREST_MOB("Locate the nearest mob."),
|
||||
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."),
|
||||
NONE("No target goal.");
|
||||
|
||||
private static final Map<String, EnumTargetGoal> VALUES = new HashMap<String, EnumTargetGoal>() {
|
||||
{
|
||||
this.put("none", NONE);
|
||||
this.put("nearestvulnerableplayer", NEAREST_VULNERABLE_PLAYER);
|
||||
this.put("nearestplayer", NEAREST_PLAYER);
|
||||
this.put("nearesthostile", NEAREST_HOSTILE);
|
||||
this.put("nearestmob", NEAREST_MOB);
|
||||
this.put("nearestbot", NEAREST_BOT);
|
||||
this.put("nearestbotdiffer", NEAREST_BOT_DIFFER);
|
||||
this.put("nearestbotdifferalpha", NEAREST_BOT_DIFFER_ALPHA);
|
||||
}
|
||||
};
|
||||
|
||||
private final String description;
|
||||
|
||||
EnumTargetGoal(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public static EnumTargetGoal from(String name) {
|
||||
return VALUES.get(name);
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,195 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent;
|
||||
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class LegacyBlockCheck {
|
||||
|
||||
private final Plugin plugin;
|
||||
private final LegacyAgent agent;
|
||||
|
||||
public LegacyBlockCheck(LegacyAgent agent, Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.agent = agent;
|
||||
}
|
||||
|
||||
private void placeFinal(Terminator bot, LivingEntity player, Location loc) {
|
||||
if (loc.getBlock().getType() != Material.COBBLESTONE) {
|
||||
for (Player all : Bukkit.getOnlinePlayers())
|
||||
all.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1);
|
||||
bot.setItem(new ItemStack(Material.COBBLESTONE));
|
||||
loc.getBlock().setType(Material.COBBLESTONE);
|
||||
|
||||
Block under = loc.clone().add(0, -1, 0).getBlock();
|
||||
if (under.getType() == Material.LAVA) {
|
||||
under.setType(Material.COBBLESTONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void placeBlock(Terminator bot, LivingEntity player, Block block) {
|
||||
|
||||
Location loc = block.getLocation();
|
||||
|
||||
Block under = loc.clone().add(0, -1, 0).getBlock();
|
||||
|
||||
if (LegacyMats.SPAWN.contains(under.getType())) {
|
||||
placeFinal(bot, player, loc.clone().add(0, -1, 0));
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
placeFinal(bot, player, block.getLocation());
|
||||
}, 2);
|
||||
}
|
||||
|
||||
Set<Block> face = new HashSet<>(Arrays.asList(loc.clone().add(1, 0, 0).getBlock(),
|
||||
loc.clone().add(-1, 0, 0).getBlock(),
|
||||
loc.clone().add(0, 0, 1).getBlock(),
|
||||
loc.clone().add(0, 0, -1).getBlock()));
|
||||
|
||||
boolean a = false;
|
||||
for (Block side : face) {
|
||||
if (!LegacyMats.SPAWN.contains(side.getType())) {
|
||||
a = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (a) {
|
||||
placeFinal(bot, player, block.getLocation());
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Block> edge = new HashSet<>(Arrays.asList(loc.clone().add(1, -1, 0).getBlock(),
|
||||
loc.clone().add(-1, -1, 0).getBlock(),
|
||||
loc.clone().add(0, -1, 1).getBlock(),
|
||||
loc.clone().add(0, -1, -1).getBlock()));
|
||||
|
||||
boolean b = false;
|
||||
for (Block side : edge) {
|
||||
if (!LegacyMats.SPAWN.contains(side.getType())) {
|
||||
b = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (b && LegacyMats.SPAWN.contains(under.getType())) {
|
||||
placeFinal(bot, player, loc.clone().add(0, -1, 0));
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
placeFinal(bot, player, block.getLocation());
|
||||
}, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
Block c1 = loc.clone().add(1, -1, 1).getBlock();
|
||||
Block c2 = loc.clone().add(1, -1, -1).getBlock();
|
||||
Block c3 = loc.clone().add(-1, -1, 1).getBlock();
|
||||
Block c4 = loc.clone().add(-1, -1, -1).getBlock();
|
||||
|
||||
boolean t = false;
|
||||
|
||||
if (!LegacyMats.SPAWN.contains(c1.getType()) || !LegacyMats.SPAWN.contains(c2.getType())) {
|
||||
|
||||
Block b1 = loc.clone().add(1, -1, 0).getBlock();
|
||||
if (LegacyMats.SPAWN.contains(b1.getType())) {
|
||||
placeFinal(bot, player, b1.getLocation());
|
||||
}
|
||||
|
||||
t = true;
|
||||
|
||||
} else if (!LegacyMats.SPAWN.contains(c3.getType()) || !LegacyMats.SPAWN.contains(c4.getType())) {
|
||||
|
||||
Block b1 = loc.clone().add(-1, -1, 0).getBlock();
|
||||
if (LegacyMats.SPAWN.contains(b1.getType())) {
|
||||
placeFinal(bot, player, b1.getLocation());
|
||||
}
|
||||
|
||||
t = true;
|
||||
}
|
||||
|
||||
if (t) {
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
Block b2 = loc.clone().add(0, -1, 0).getBlock();
|
||||
if (LegacyMats.SPAWN.contains(b2.getType())) {
|
||||
for (Player all : Bukkit.getOnlinePlayers())
|
||||
all.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1);
|
||||
placeFinal(bot, player, b2.getLocation());
|
||||
}
|
||||
}, 1);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
for (Player all : Bukkit.getOnlinePlayers())
|
||||
all.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1);
|
||||
placeFinal(bot, player, block.getLocation());
|
||||
}, 3);
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player all : Bukkit.getOnlinePlayers())
|
||||
all.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1);
|
||||
placeFinal(bot, player, block.getLocation());
|
||||
}
|
||||
|
||||
public void clutch(Terminator bot, LivingEntity target) {
|
||||
Location botLoc = bot.getLocation();
|
||||
|
||||
Material type = botLoc.clone().add(0, -1, 0).getBlock().getType();
|
||||
Material type2 = botLoc.clone().add(0, -2, 0).getBlock().getType();
|
||||
|
||||
if (!(LegacyMats.SPAWN.contains(type) && LegacyMats.SPAWN.contains(type2))) return;
|
||||
|
||||
if (target.getLocation().getBlockY() >= botLoc.getBlockY()) {
|
||||
Location loc = botLoc.clone().add(0, -1, 0);
|
||||
|
||||
Set<Block> face = new HashSet<>(Arrays.asList(
|
||||
loc.clone().add(1, 0, 0).getBlock(),
|
||||
loc.clone().add(-1, 0, 0).getBlock(),
|
||||
loc.clone().add(0, 0, 1).getBlock(),
|
||||
loc.clone().add(0, 0, -1).getBlock()
|
||||
));
|
||||
|
||||
Location at = null;
|
||||
for (Block side : face) {
|
||||
if (!LegacyMats.SPAWN.contains(side.getType())) {
|
||||
at = side.getLocation();
|
||||
}
|
||||
}
|
||||
|
||||
if (at != null) {
|
||||
agent.slow.add(bot);
|
||||
agent.noFace.add(bot);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
bot.stand();
|
||||
agent.slow.remove(bot);
|
||||
}, 12);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
agent.noFace.remove(bot);
|
||||
}, 15);
|
||||
|
||||
Location faceLoc = at.clone().add(0, -1.5, 0);
|
||||
|
||||
bot.faceLocation(faceLoc);
|
||||
bot.look(BlockFace.DOWN);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
bot.faceLocation(faceLoc);
|
||||
}, 1);
|
||||
|
||||
bot.punch();
|
||||
bot.sneak();
|
||||
for (Player all : Bukkit.getOnlinePlayers())
|
||||
all.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1);
|
||||
bot.setItem(new ItemStack(Material.COBBLESTONE));
|
||||
loc.getBlock().setType(Material.COBBLESTONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class LegacyItems {
|
||||
public static final Material SHOVEL = Material.IRON_SHOVEL;
|
||||
public static final Material AXE = Material.IRON_AXE;
|
||||
public static final Material PICKAXE = Material.IRON_PICKAXE;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public enum LegacyLevel {
|
||||
ABOVE,
|
||||
BELOW,
|
||||
AT,
|
||||
AT_D,
|
||||
NORTH,
|
||||
SOUTH,
|
||||
EAST,
|
||||
WEST,
|
||||
NORTH_D,
|
||||
SOUTH_D,
|
||||
EAST_D,
|
||||
WEST_D;
|
||||
|
||||
private static final Set<LegacyLevel> SIDE = new HashSet<>(Arrays.asList(
|
||||
NORTH,
|
||||
SOUTH,
|
||||
EAST,
|
||||
WEST,
|
||||
NORTH_D,
|
||||
SOUTH_D,
|
||||
EAST_D,
|
||||
WEST_D
|
||||
));
|
||||
|
||||
public boolean isSide() {
|
||||
return SIDE.contains(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class LegacyMats {
|
||||
|
||||
public static final Set<Material> AIR = new HashSet<>(Arrays.asList(
|
||||
Material.WATER,
|
||||
Material.OAK_TRAPDOOR,
|
||||
Material.FIRE,
|
||||
Material.LAVA,
|
||||
Material.SNOW,
|
||||
Material.CAVE_AIR,
|
||||
Material.VINE,
|
||||
Material.FERN,
|
||||
Material.LARGE_FERN,
|
||||
Material.GRASS,
|
||||
Material.TALL_GRASS,
|
||||
Material.SEAGRASS,
|
||||
Material.TALL_SEAGRASS,
|
||||
Material.KELP,
|
||||
Material.KELP_PLANT,
|
||||
Material.SUNFLOWER,
|
||||
Material.AIR,
|
||||
Material.VOID_AIR,
|
||||
Material.FIRE,
|
||||
Material.SOUL_FIRE
|
||||
));
|
||||
|
||||
public static final Set<Material> NO_CRACK = new HashSet<>(Arrays.asList(
|
||||
Material.WATER,
|
||||
Material.FIRE,
|
||||
Material.LAVA,
|
||||
Material.CAVE_AIR,
|
||||
Material.SOUL_FIRE
|
||||
));
|
||||
|
||||
public static final Set<Material> SHOVEL = new HashSet<>(Arrays.asList(
|
||||
Material.DIRT,
|
||||
Material.GRAVEL,
|
||||
Material.SAND,
|
||||
Material.SNOW
|
||||
));
|
||||
|
||||
public static final Set<Material> AXE = new HashSet<>(Arrays.asList(
|
||||
Material.OAK_PLANKS, Material.OAK_DOOR, Material.OAK_FENCE, Material.OAK_FENCE_GATE, Material.OAK_LOG, Material.OAK_PLANKS,
|
||||
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_PLANKS,
|
||||
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_PLANKS,
|
||||
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_PLANKS,
|
||||
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_PLANKS,
|
||||
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_PLANKS,
|
||||
Material.SPRUCE_SIGN, Material.SPRUCE_SLAB, Material.SPRUCE_STAIRS, Material.SPRUCE_TRAPDOOR, Material.SPRUCE_WALL_SIGN, Material.SPRUCE_WOOD,
|
||||
Material.CRIMSON_PLANKS, Material.CRIMSON_DOOR, Material.CRIMSON_FENCE, Material.CRIMSON_FENCE_GATE, Material.CRIMSON_PLANKS,
|
||||
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_PLANKS,
|
||||
Material.WARPED_SIGN, Material.WARPED_SLAB, Material.WARPED_STAIRS, Material.WARPED_TRAPDOOR, Material.WARPED_WALL_SIGN
|
||||
));
|
||||
|
||||
public static final Set<Material> BREAK = new HashSet<>(Arrays.asList(
|
||||
Material.AIR,
|
||||
Material.WATER,
|
||||
Material.LAVA,
|
||||
Material.TALL_GRASS,
|
||||
Material.SNOW,
|
||||
Material.DIRT_PATH,
|
||||
Material.CAVE_AIR,
|
||||
Material.VINE,
|
||||
Material.FERN,
|
||||
Material.LARGE_FERN,
|
||||
Material.SUGAR_CANE,
|
||||
Material.TWISTING_VINES,
|
||||
Material.WEEPING_VINES,
|
||||
Material.SEAGRASS,
|
||||
Material.TALL_SEAGRASS,
|
||||
Material.KELP,
|
||||
Material.KELP_PLANT,
|
||||
Material.SUNFLOWER,
|
||||
Material.FIRE,
|
||||
Material.SOUL_FIRE
|
||||
));
|
||||
|
||||
public static final Set<Material> WATER = new HashSet<>(Arrays.asList(
|
||||
Material.WATER,
|
||||
Material.SEAGRASS,
|
||||
Material.TALL_SEAGRASS,
|
||||
Material.KELP,
|
||||
Material.KELP_PLANT
|
||||
));
|
||||
|
||||
public static final Set<Material> SPAWN = new HashSet<>(Arrays.asList(
|
||||
Material.AIR,
|
||||
Material.TALL_GRASS,
|
||||
Material.SNOW,
|
||||
Material.CAVE_AIR,
|
||||
Material.VINE,
|
||||
Material.FERN,
|
||||
Material.LARGE_FERN,
|
||||
Material.SUGAR_CANE,
|
||||
Material.TWISTING_VINES,
|
||||
Material.WEEPING_VINES,
|
||||
Material.SEAGRASS,
|
||||
Material.TALL_SEAGRASS,
|
||||
Material.KELP,
|
||||
Material.KELP_PLANT,
|
||||
Material.SUNFLOWER,
|
||||
Material.FIRE,
|
||||
Material.SOUL_FIRE
|
||||
));
|
||||
|
||||
public static final Set<Material> FALL = new HashSet<>(Arrays.asList(
|
||||
Material.AIR,
|
||||
Material.TALL_GRASS,
|
||||
Material.SNOW,
|
||||
Material.CAVE_AIR,
|
||||
Material.VINE,
|
||||
Material.FERN,
|
||||
Material.LARGE_FERN,
|
||||
Material.SUGAR_CANE,
|
||||
Material.TWISTING_VINES,
|
||||
Material.WEEPING_VINES,
|
||||
Material.SEAGRASS,
|
||||
Material.TALL_SEAGRASS,
|
||||
Material.KELP,
|
||||
Material.KELP_PLANT,
|
||||
Material.SUNFLOWER,
|
||||
Material.WATER
|
||||
));
|
||||
|
||||
public static final Set<Material> FENCE = new HashSet<>(Arrays.asList(
|
||||
Material.OAK_FENCE,
|
||||
Material.ACACIA_FENCE,
|
||||
Material.BIRCH_FENCE,
|
||||
Material.CRIMSON_FENCE,
|
||||
Material.DARK_OAK_FENCE,
|
||||
Material.JUNGLE_FENCE,
|
||||
Material.NETHER_BRICK_FENCE,
|
||||
Material.SPRUCE_FENCE,
|
||||
Material.WARPED_FENCE,
|
||||
Material.COBBLESTONE_WALL,
|
||||
Material.ANDESITE_WALL,
|
||||
Material.BLACKSTONE_WALL,
|
||||
Material.BRICK_WALL,
|
||||
Material.GRANITE_WALL,
|
||||
Material.DIORITE_WALL,
|
||||
Material.SANDSTONE_WALL,
|
||||
Material.RED_SANDSTONE_WALL,
|
||||
Material.RED_NETHER_BRICK_WALL,
|
||||
Material.IRON_BARS,
|
||||
Material.COBWEB
|
||||
));
|
||||
|
||||
public static final Set<Material> LEAVES = new HashSet<>(Arrays.asList(
|
||||
Material.BIRCH_LEAVES,
|
||||
Material.DARK_OAK_LEAVES,
|
||||
Material.JUNGLE_LEAVES,
|
||||
Material.OAK_LEAVES,
|
||||
Material.SPRUCE_LEAVES
|
||||
));
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
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;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class LegacyUtils {
|
||||
|
||||
public static boolean checkFreeSpace(Location a, Location b) {
|
||||
Vector v = b.toVector().subtract(a.toVector());
|
||||
|
||||
int n = 32;
|
||||
double m = 1 / (double) n;
|
||||
|
||||
double j = Math.floor(v.length() * n);
|
||||
v.multiply(m / v.length());
|
||||
|
||||
org.bukkit.World world = a.getWorld();
|
||||
if (world == null) return false;
|
||||
|
||||
for (int i = 0; i <= j; i++) {
|
||||
Block block = world.getBlockAt((a.toVector().add(v.clone().multiply(i))).toLocation(world));
|
||||
|
||||
if (!LegacyMats.AIR.contains(block.getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Sound breakBlockSound(Block block) {
|
||||
return TerminatorPlusAPI.getInternalBridge().breakBlockSound(block);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class LegacyWorldManager {
|
||||
|
||||
/*
|
||||
* This is where the respawning queue will be managed
|
||||
*/
|
||||
|
||||
public static boolean aboveGround(Location loc) {
|
||||
int y = 1;
|
||||
|
||||
while (y < 25) {
|
||||
if (loc.clone().add(0, y, 0).getBlock().getType() != Material.AIR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
y++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent.ai;
|
||||
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import net.nuggetmc.tplus.utils.MathUtils;
|
||||
import net.nuggetmc.tplus.api.utils.MathUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent.ai;
|
||||
|
||||
import net.nuggetmc.tplus.api.AIManager;
|
||||
import net.nuggetmc.tplus.api.BotManager;
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import net.nuggetmc.tplus.api.agent.legacyagent.EnumTargetGoal;
|
||||
import net.nuggetmc.tplus.api.agent.legacyagent.LegacyAgent;
|
||||
import net.nuggetmc.tplus.api.utils.ChatUtils;
|
||||
import net.nuggetmc.tplus.api.utils.MathUtils;
|
||||
import net.nuggetmc.tplus.api.utils.MojangAPI;
|
||||
import net.nuggetmc.tplus.api.utils.PlayerUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
public class IntelligenceAgent {
|
||||
|
||||
/*
|
||||
* export all agent data to the plugin folder as separate folder things
|
||||
* commands /ai stop and /ai pause
|
||||
* if a session with name already exists keep adding underscores
|
||||
* /ai conclude or /ai finish
|
||||
* default anchor location, /ai relocateanchor
|
||||
*/
|
||||
|
||||
private final Plugin plugin;
|
||||
private final BotManager manager;
|
||||
private final AIManager aiManager;
|
||||
private final BukkitScheduler scheduler;
|
||||
|
||||
private LegacyAgent agent;
|
||||
private Thread thread;
|
||||
private boolean active;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String botName;
|
||||
private final String botSkin;
|
||||
private final int cutoff;
|
||||
|
||||
private final Map<String, Terminator> bots;
|
||||
|
||||
private int populationSize;
|
||||
private int generation;
|
||||
|
||||
private Player primary;
|
||||
|
||||
private final Set<CommandSender> users;
|
||||
private final Map<Integer, Set<Map<BotNode, Map<BotDataType, Double>>>> genProfiles;
|
||||
|
||||
public IntelligenceAgent(AIManager aiManager, int populationSize, String name, String skin, Plugin plugin, BotManager manager) {
|
||||
this.plugin = plugin;
|
||||
this.manager = manager;
|
||||
this.aiManager = aiManager;
|
||||
this.scheduler = Bukkit.getScheduler();
|
||||
this.name = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(Calendar.getInstance().getTime());
|
||||
this.botName = name;
|
||||
this.botSkin = skin;
|
||||
this.bots = new HashMap<>();
|
||||
this.users = new HashSet<>(Collections.singletonList(Bukkit.getConsoleSender()));
|
||||
this.cutoff = 5;
|
||||
this.genProfiles = new HashMap<>();
|
||||
this.populationSize = populationSize;
|
||||
this.active = true;
|
||||
|
||||
scheduler.runTaskAsynchronously(plugin, () -> {
|
||||
thread = Thread.currentThread();
|
||||
|
||||
try {
|
||||
task();
|
||||
} catch (Exception e) {
|
||||
print(e);
|
||||
print("The thread has been interrupted.");
|
||||
print("The session will now close.");
|
||||
close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void task() throws InterruptedException {
|
||||
setup();
|
||||
sleep(1000);
|
||||
|
||||
while (active) {
|
||||
runGeneration();
|
||||
}
|
||||
|
||||
sleep(5000);
|
||||
close();
|
||||
}
|
||||
|
||||
private void runGeneration() throws InterruptedException {
|
||||
generation++;
|
||||
|
||||
print("Starting generation " + ChatColor.RED + generation + ChatColor.RESET + "...");
|
||||
|
||||
sleep(2000);
|
||||
|
||||
String skinName = botSkin == null ? this.botName : botSkin;
|
||||
|
||||
print("Fetching skin data for " + ChatColor.GREEN + skinName + ChatColor.RESET + "...");
|
||||
|
||||
String[] skinData = MojangAPI.getSkin(skinName);
|
||||
|
||||
String botName = this.botName.endsWith("%") ? this.botName : this.botName + "%";
|
||||
|
||||
print("Creating " + (populationSize == 1 ? "new bot" : ChatColor.RED + NumberFormat.getInstance(Locale.US).format(populationSize) + ChatColor.RESET + " new bots")
|
||||
+ " with name " + ChatColor.GREEN + botName.replace("%", ChatColor.LIGHT_PURPLE + "%" + ChatColor.RESET)
|
||||
+ (botSkin == null ? "" : ChatColor.RESET + " and skin " + ChatColor.GREEN + botSkin)
|
||||
+ ChatColor.RESET + "...");
|
||||
|
||||
Set<Map<BotNode, Map<BotDataType, Double>>> loadedProfiles = genProfiles.get(generation);
|
||||
Location loc = PlayerUtils.findAbove(primary.getLocation(), 20);
|
||||
|
||||
scheduler.runTask(plugin, () -> {
|
||||
Set<Terminator> bots;
|
||||
|
||||
if (loadedProfiles == null) {
|
||||
bots = manager.createBots(loc, botName, skinData, populationSize, NeuralNetwork.RANDOM);
|
||||
} else {
|
||||
List<NeuralNetwork> networks = new ArrayList<>();
|
||||
loadedProfiles.forEach(profile -> networks.add(NeuralNetwork.createNetworkFromProfile(profile)));
|
||||
|
||||
if (populationSize != networks.size()) {
|
||||
print("An exception has occured.");
|
||||
print("The stored population size differs from the size of the stored networks.");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
bots = manager.createBots(loc, botName, skinData, networks);
|
||||
}
|
||||
|
||||
bots.forEach(bot -> {
|
||||
String name = bot.getBotName();
|
||||
|
||||
while (this.bots.containsKey(name)) {
|
||||
name += "_";
|
||||
}
|
||||
|
||||
this.bots.put(name, bot);
|
||||
});
|
||||
});
|
||||
|
||||
while (bots.size() != populationSize) {
|
||||
sleep(1000);
|
||||
}
|
||||
|
||||
sleep(2000);
|
||||
print("The bots will now attack each other.");
|
||||
|
||||
agent.setTargetType(EnumTargetGoal.NEAREST_BOT);
|
||||
|
||||
while (aliveCount() > 1) {
|
||||
sleep(1000);
|
||||
}
|
||||
|
||||
print("Generation " + ChatColor.RED + generation + ChatColor.RESET + " has ended.");
|
||||
|
||||
HashMap<Terminator, Integer> values = new HashMap<>();
|
||||
|
||||
for (Terminator bot : bots.values()) {
|
||||
values.put(bot, bot.getAliveTicks());
|
||||
}
|
||||
|
||||
List<Map.Entry<Terminator, Integer>> sorted = MathUtils.sortByValue(values);
|
||||
Set<Terminator> winners = new HashSet<>();
|
||||
|
||||
int i = 1;
|
||||
|
||||
for (Map.Entry<Terminator, Integer> entry : sorted) {
|
||||
Terminator bot = entry.getKey();
|
||||
boolean check = i <= cutoff;
|
||||
if (check) {
|
||||
print(ChatColor.GRAY + "[" + ChatColor.YELLOW + "#" + i + ChatColor.GRAY + "] " + ChatColor.GREEN + bot.getBotName()
|
||||
+ ChatUtils.BULLET_FORMATTED + ChatColor.RED + bot.getKills() + " kills");
|
||||
winners.add(bot);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
sleep(3000);
|
||||
|
||||
Map<BotNode, Map<BotDataType, List<Double>>> lists = new HashMap<>();
|
||||
|
||||
winners.forEach(bot -> {
|
||||
Map<BotNode, Map<BotDataType, Double>> data = bot.getNeuralNetwork().values();
|
||||
|
||||
data.forEach((nodeType, node) -> {
|
||||
if (!lists.containsKey(nodeType)) {
|
||||
lists.put(nodeType, new HashMap<>());
|
||||
}
|
||||
|
||||
Map<BotDataType, List<Double>> nodeValues = lists.get(nodeType);
|
||||
|
||||
node.forEach((dataType, value) -> {
|
||||
if (!nodeValues.containsKey(dataType)) {
|
||||
nodeValues.put(dataType, new ArrayList<>());
|
||||
}
|
||||
|
||||
nodeValues.get(dataType).add(value);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Set<Map<BotNode, Map<BotDataType, Double>>> profiles = new HashSet<>();
|
||||
|
||||
double mutationSize = Math.pow(Math.E, 2); //MathUtils.getMutationSize(generation);
|
||||
|
||||
for (int j = 0; j < populationSize; j++) {
|
||||
Map<BotNode, Map<BotDataType, Double>> profile = new HashMap<>();
|
||||
|
||||
lists.forEach((nodeType, map) -> {
|
||||
Map<BotDataType, Double> points = new HashMap<>();
|
||||
|
||||
map.forEach((dataType, dataPoints) -> {
|
||||
double value = ((int) (10 * MathUtils.generateConnectionValue(dataPoints, mutationSize))) / 10D;
|
||||
|
||||
points.put(dataType, value);
|
||||
});
|
||||
|
||||
profile.put(nodeType, points);
|
||||
});
|
||||
|
||||
profiles.add(profile);
|
||||
}
|
||||
|
||||
genProfiles.put(generation + 1, profiles);
|
||||
|
||||
sleep(2000);
|
||||
|
||||
clearBots();
|
||||
|
||||
agent.setTargetType(EnumTargetGoal.NONE);
|
||||
}
|
||||
|
||||
private int aliveCount() {
|
||||
return (int) bots.values().stream().filter(Terminator::isAlive).count();
|
||||
}
|
||||
|
||||
private void close() {
|
||||
aiManager.clearSession();
|
||||
stop(); // safety call
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (this.active) {
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
if (!thread.isInterrupted()) {
|
||||
this.thread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private void sleep(long millis) throws InterruptedException {
|
||||
Thread.sleep(millis);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void addUser(CommandSender sender) {
|
||||
if (users.contains(sender)) return;
|
||||
|
||||
users.add(sender);
|
||||
print(sender.getName() + " has been added to the userlist.");
|
||||
|
||||
if (primary == null && sender instanceof Player) {
|
||||
setPrimary((Player) sender);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrimary(Player player) {
|
||||
this.primary = player;
|
||||
print(player.getName() + " has been set as the primary user.");
|
||||
}
|
||||
|
||||
private void print(Object... objects) {
|
||||
String message = ChatColor.DARK_GREEN + "[REINFORCEMENT] " + ChatColor.RESET + String.join(" ", Arrays.stream(objects).map(String::valueOf).toArray(String[]::new));
|
||||
users.forEach(u -> u.sendMessage(message));
|
||||
// log -> ChatColor.stripColor(message);
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
clearBots();
|
||||
|
||||
if (populationSize < cutoff) {
|
||||
populationSize = cutoff;
|
||||
print("The input value for the population size is lower than the cutoff (" + ChatColor.RED + cutoff + ChatColor.RESET + ")!"
|
||||
+ " The new population size is " + ChatColor.RED + populationSize + ChatColor.RESET + ".");
|
||||
}
|
||||
|
||||
if (!(manager.getAgent() instanceof LegacyAgent)) {
|
||||
print("The AI manager currently only supports " + ChatColor.AQUA + "LegacyAgent" + ChatColor.RESET + ".");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
agent = (LegacyAgent) manager.getAgent();
|
||||
agent.setTargetType(EnumTargetGoal.NONE);
|
||||
|
||||
print("The bot target goal has been set to " + ChatColor.YELLOW + EnumTargetGoal.NONE.name() + ChatColor.RESET + ".");
|
||||
print("Disabling target offsets...");
|
||||
|
||||
agent.offsets = false;
|
||||
|
||||
print("Disabling bot drops...");
|
||||
|
||||
agent.setDrops(false);
|
||||
|
||||
print(ChatColor.GREEN + "Setup is now complete.");
|
||||
}
|
||||
|
||||
private void clearBots() {
|
||||
if (!bots.isEmpty()) {
|
||||
print("Removing all cached bots...");
|
||||
|
||||
bots.values().forEach(Terminator::removeVisually);
|
||||
bots.clear();
|
||||
}
|
||||
|
||||
/*print("Removing all current bots...");
|
||||
|
||||
int size = manager.fetch().size();
|
||||
manager.reset();
|
||||
|
||||
String formatted = NumberFormat.getNumberInstance(Locale.US).format(size);
|
||||
print("Removed " + ChatColor.RED + formatted + ChatColor.RESET + " entit" + (size == 1 ? "y" : "ies") + ".");
|
||||
|
||||
bots.clear();*/
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent.ai;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.nuggetmc.tplus.utils.MathUtils;
|
||||
import net.nuggetmc.tplus.utils.ChatUtils;
|
||||
import net.nuggetmc.tplus.api.utils.ChatUtils;
|
||||
import net.nuggetmc.tplus.api.utils.MathUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.nuggetmc.tplus.api.event;
|
||||
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class BotDamageByPlayerEvent {
|
||||
|
||||
private final Terminator bot;
|
||||
private final Player player;
|
||||
|
||||
private float damage;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public BotDamageByPlayerEvent(Terminator bot, Player player, float damage) {
|
||||
this.bot = bot;
|
||||
this.player = player;
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
public Terminator getBot() {
|
||||
return bot;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public float getDamage() {
|
||||
return damage;
|
||||
}
|
||||
|
||||
public void setDamage(float damage) {
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.nuggetmc.tplus.api.event;
|
||||
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
|
||||
public class BotDeathEvent extends EntityDeathEvent {
|
||||
|
||||
private final Terminator bot;
|
||||
|
||||
public BotDeathEvent(EntityDeathEvent event, Terminator bot) {
|
||||
super(event.getEntity(), event.getDrops(), event.getDroppedExp());
|
||||
this.bot = bot;
|
||||
}
|
||||
|
||||
public Terminator getBot() {
|
||||
return bot;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.nuggetmc.tplus.api.event;
|
||||
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
|
||||
public class BotFallDamageEvent {
|
||||
|
||||
private final Terminator bot;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public BotFallDamageEvent(Terminator bot) {
|
||||
this.bot = bot;
|
||||
}
|
||||
|
||||
public Terminator getBot() {
|
||||
return bot;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.nuggetmc.tplus.api.event;
|
||||
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class BotKilledByPlayerEvent {
|
||||
|
||||
// eventually also call this event for deaths from other damage causes within combat time
|
||||
// (like hitting the ground too hard)
|
||||
|
||||
private final Terminator bot;
|
||||
private final Player player;
|
||||
|
||||
public BotKilledByPlayerEvent(Terminator bot, Player player) {
|
||||
this.bot = bot;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public Terminator getBot() {
|
||||
return bot;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BotUtils {
|
||||
|
||||
public static final Set<Material> NO_FALL = new HashSet<>(Arrays.asList(
|
||||
Material.WATER,
|
||||
Material.LAVA,
|
||||
Material.TWISTING_VINES,
|
||||
Material.VINE
|
||||
));
|
||||
|
||||
public static UUID randomSteveUUID() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
if (uuid.hashCode() % 2 == 0) {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
return randomSteveUUID();
|
||||
}
|
||||
|
||||
public static boolean solidAt(Location loc) { // not perfect, still cuts corners of fences
|
||||
Block block = loc.getBlock();
|
||||
BoundingBox box = block.getBoundingBox();
|
||||
Vector position = loc.toVector();
|
||||
|
||||
double x = position.getX();
|
||||
double y = position.getY();
|
||||
double z = position.getZ();
|
||||
|
||||
double minX = box.getMinX();
|
||||
double minY = box.getMinY();
|
||||
double minZ = box.getMinZ();
|
||||
|
||||
double maxX = box.getMaxX();
|
||||
double maxY = box.getMaxY();
|
||||
double maxZ = box.getMaxZ();
|
||||
|
||||
return x > minX && x < maxX && y > minY && y < maxY && z > minZ && z < maxZ;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.nuggetmc.tplus.utils;
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CustomGameProfile extends GameProfile {
|
||||
|
||||
public CustomGameProfile(UUID uuid, String name, String[] skin) {
|
||||
super(uuid, name);
|
||||
|
||||
setSkin(skin);
|
||||
}
|
||||
|
||||
public CustomGameProfile(UUID uuid, String name, String skinName) {
|
||||
super(uuid, name);
|
||||
|
||||
setSkin(skinName);
|
||||
}
|
||||
|
||||
public void setSkin(String skinName) {
|
||||
setSkin(MojangAPI.getSkin(skinName));
|
||||
}
|
||||
|
||||
public void setSkin(String[] skin) {
|
||||
if (skin != null) {
|
||||
getProperties().put("textures", new Property("textures", skin[0], skin[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.permissions.ServerOperator;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DebugLogUtils {
|
||||
public static final String PREFIX = ChatColor.YELLOW + "[DEBUG] " + ChatColor.RESET;
|
||||
|
||||
public static void log(Object... objects) {
|
||||
String[] values = fromStringArray(objects);
|
||||
String message = PREFIX + String.join(" ", values);
|
||||
|
||||
Bukkit.getConsoleSender().sendMessage(message);
|
||||
Bukkit.getOnlinePlayers().stream().filter(ServerOperator::isOp).forEach(p -> p.sendMessage(message));
|
||||
}
|
||||
|
||||
public static String[] fromStringArray(Object[] objects) {
|
||||
return Arrays.stream(objects).map(String::valueOf).toArray(String[]::new);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ItemUtils {
|
||||
|
||||
public static double getLegacyAttackDamage(ItemStack item) {
|
||||
switch (item.getType()) {
|
||||
default:
|
||||
return 0.25;
|
||||
|
||||
case WOODEN_SHOVEL:
|
||||
case GOLDEN_SHOVEL:
|
||||
case WOODEN_HOE:
|
||||
case GOLDEN_HOE:
|
||||
case STONE_HOE:
|
||||
case IRON_HOE:
|
||||
case DIAMOND_HOE:
|
||||
case NETHERITE_HOE:
|
||||
return 1;
|
||||
|
||||
case WOODEN_PICKAXE:
|
||||
case GOLDEN_PICKAXE:
|
||||
case STONE_SHOVEL:
|
||||
return 2;
|
||||
|
||||
case WOODEN_AXE:
|
||||
case GOLDEN_AXE:
|
||||
case STONE_PICKAXE:
|
||||
case IRON_SHOVEL:
|
||||
return 3;
|
||||
|
||||
case WOODEN_SWORD:
|
||||
case GOLDEN_SWORD:
|
||||
case STONE_AXE:
|
||||
case IRON_PICKAXE:
|
||||
case DIAMOND_SHOVEL:
|
||||
return 4;
|
||||
|
||||
case STONE_SWORD:
|
||||
case IRON_AXE:
|
||||
case DIAMOND_PICKAXE:
|
||||
case NETHERITE_SHOVEL:
|
||||
return 5;
|
||||
|
||||
case IRON_SWORD:
|
||||
case DIAMOND_AXE:
|
||||
case NETHERITE_PICKAXE:
|
||||
return 6;
|
||||
|
||||
case DIAMOND_SWORD:
|
||||
case NETHERITE_AXE:
|
||||
return 7;
|
||||
|
||||
case NETHERITE_SWORD:
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.nuggetmc.tplus.utils;
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
@@ -0,0 +1,41 @@
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MojangAPI {
|
||||
|
||||
private static final boolean CACHE_ENABLED = false;
|
||||
|
||||
private static final Map<String, String[]> CACHE = new HashMap<>();
|
||||
|
||||
public static String[] getSkin(String name) {
|
||||
if (CACHE_ENABLED && CACHE.containsKey(name)) {
|
||||
return CACHE.get(name);
|
||||
}
|
||||
|
||||
String[] values = pullFromAPI(name);
|
||||
CACHE.put(name, values);
|
||||
return values;
|
||||
}
|
||||
|
||||
// CATCHING NULL ILLEGALSTATEEXCEPTION BAD!!!! eventually fix from the getAsJsonObject thingy
|
||||
public static String[] pullFromAPI(String name) {
|
||||
try {
|
||||
String uuid = new JsonParser().parse(new InputStreamReader(new URL("https://api.mojang.com/users/profiles/minecraft/" + name)
|
||||
.openStream())).getAsJsonObject().get("id").getAsString();
|
||||
JsonObject property = new JsonParser()
|
||||
.parse(new InputStreamReader(new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false")
|
||||
.openStream())).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject();
|
||||
return new String[] {property.get("value").getAsString(), property.get("signature").getAsString()};
|
||||
} catch (IOException | IllegalStateException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class PlayerUtils {
|
||||
|
||||
private static final Set<String> USERNAME_CACHE = new HashSet<>();
|
||||
|
||||
public static boolean isInvincible(GameMode mode) {
|
||||
return mode != GameMode.SURVIVAL && mode != GameMode.ADVENTURE && mode != null;
|
||||
}
|
||||
|
||||
public static String randomName() {
|
||||
if (USERNAME_CACHE.isEmpty()) {
|
||||
fillUsernameCache();
|
||||
}
|
||||
|
||||
return MathUtils.getRandomSetElement(USERNAME_CACHE);
|
||||
}
|
||||
|
||||
public static void fillUsernameCache() {
|
||||
String file = Bukkit.getServer().getWorldContainer().getAbsolutePath();
|
||||
file = file.substring(0, file.length() - 1) + "usercache.json";
|
||||
|
||||
JSONParser parser = new JSONParser();
|
||||
|
||||
try {
|
||||
JSONArray array = (JSONArray) parser.parse(new FileReader(file));
|
||||
|
||||
for (Object obj : array) {
|
||||
JSONObject jsonOBJ = (JSONObject) obj;
|
||||
String username = (String) jsonOBJ.get("name");
|
||||
|
||||
USERNAME_CACHE.add(username);
|
||||
}
|
||||
} catch (IOException | ParseException e) {
|
||||
DebugLogUtils.log("Failed to fetch from the usercache.");
|
||||
}
|
||||
}
|
||||
|
||||
public static Location findAbove(Location loc, int amount) {
|
||||
boolean check = false;
|
||||
|
||||
for (int i = 0; i <= amount; i++) {
|
||||
if (loc.clone().add(0, i, 0).getBlock().getType().isSolid()) {
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check) {
|
||||
return loc;
|
||||
} else {
|
||||
return loc.clone().add(0, amount, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static Location findBottom(Location loc) {
|
||||
loc.setY(loc.getBlockY());
|
||||
|
||||
for (int i = 0; i < 255; i++) {
|
||||
Location check = loc.clone().add(0, -i, 0);
|
||||
|
||||
if (check.getY() <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (check.getBlock().getType().isSolid()) {
|
||||
return check.add(0, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.nuggetmc.tplus.api.utils;
|
||||
|
||||
public class Singularity {
|
||||
|
||||
private Object value;
|
||||
|
||||
public Singularity(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Singularity() {
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean hasValue() {
|
||||
return value != null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user