2021-06-27 00:26:45 -05:00
|
|
|
package net.nuggetmc.ai.bot;
|
2021-06-26 19:43:58 -05:00
|
|
|
|
|
|
|
|
import net.minecraft.server.v1_16_R3.PlayerConnection;
|
2021-07-12 18:20:17 -05:00
|
|
|
import net.nuggetmc.ai.bot.agent.Agent;
|
|
|
|
|
import net.nuggetmc.ai.bot.agent.legacyagent.LegacyAgent;
|
2021-07-23 03:47:11 -05:00
|
|
|
import net.nuggetmc.ai.bot.agent.legacyagent.ai.NeuralNetwork;
|
2021-07-24 23:34:07 -05:00
|
|
|
import net.nuggetmc.ai.bot.event.BotDeathEvent;
|
2021-07-10 23:51:14 -05:00
|
|
|
import net.nuggetmc.ai.utils.MojangAPI;
|
2021-07-21 13:52:21 -05:00
|
|
|
import org.bukkit.*;
|
2021-06-26 19:43:58 -05:00
|
|
|
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
|
2021-06-28 13:18:49 -05:00
|
|
|
import org.bukkit.entity.Player;
|
2021-06-26 19:43:58 -05:00
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
|
import org.bukkit.event.Listener;
|
2021-07-24 23:34:07 -05:00
|
|
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
2021-06-26 19:43:58 -05:00
|
|
|
import org.bukkit.event.player.PlayerJoinEvent;
|
2021-07-24 23:34:07 -05:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
2021-06-28 13:18:49 -05:00
|
|
|
import org.bukkit.util.Vector;
|
2021-06-26 19:43:58 -05:00
|
|
|
|
2021-06-28 15:17:32 -05:00
|
|
|
import java.text.NumberFormat;
|
2021-07-24 23:34:07 -05:00
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.stream.Collectors;
|
2021-06-26 19:43:58 -05:00
|
|
|
|
2021-06-27 00:26:45 -05:00
|
|
|
public class BotManager implements Listener {
|
2021-06-26 19:43:58 -05:00
|
|
|
|
2021-07-12 18:20:17 -05:00
|
|
|
private final Agent agent;
|
2021-07-16 03:41:21 -05:00
|
|
|
private final Set<Bot> bots;
|
2021-06-28 15:17:32 -05:00
|
|
|
private final NumberFormat numberFormat;
|
2021-06-26 19:43:58 -05:00
|
|
|
|
2021-07-21 13:52:21 -05:00
|
|
|
public boolean joinMessages = false;
|
2021-06-26 19:43:58 -05:00
|
|
|
|
2021-07-12 18:20:17 -05:00
|
|
|
public BotManager() {
|
|
|
|
|
this.agent = new LegacyAgent(this);
|
2021-07-16 03:41:21 -05:00
|
|
|
this.bots = new HashSet<>();
|
2021-06-30 02:18:31 -05:00
|
|
|
this.numberFormat = NumberFormat.getInstance(Locale.US);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:26:45 -05:00
|
|
|
public Set<Bot> fetch() {
|
|
|
|
|
return bots;
|
2021-06-26 19:43:58 -05:00
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:26:45 -05:00
|
|
|
public void add(Bot bot) {
|
2021-07-21 13:52:21 -05:00
|
|
|
if (joinMessages) {
|
|
|
|
|
Bukkit.broadcastMessage(ChatColor.YELLOW + bot.getName() + " joined the game");
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:26:45 -05:00
|
|
|
bots.add(bot);
|
2021-06-26 19:43:58 -05:00
|
|
|
}
|
|
|
|
|
|
2021-07-19 17:35:28 -05:00
|
|
|
public Bot getFirst(String name) {
|
|
|
|
|
for (Bot bot : bots) {
|
|
|
|
|
if (name.equals(bot.getName())) {
|
|
|
|
|
return bot;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
public List<String> fetchNames() {
|
|
|
|
|
return bots.stream().map(Bot::getName).collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-12 18:20:17 -05:00
|
|
|
public Agent getAgent() {
|
2021-06-30 02:18:31 -05:00
|
|
|
return agent;
|
2021-06-26 19:43:58 -05:00
|
|
|
}
|
|
|
|
|
|
2021-07-10 23:51:14 -05:00
|
|
|
public void createBots(Player sender, String name, String skinName, int n) {
|
2021-07-23 03:47:11 -05:00
|
|
|
createBots(sender, name, skinName, n, null);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
public void createBots(Player sender, String name, String skinName, int n, NeuralNetwork network) {
|
2021-06-28 13:18:49 -05:00
|
|
|
long timestamp = System.currentTimeMillis();
|
|
|
|
|
|
|
|
|
|
if (n < 1) n = 1;
|
|
|
|
|
|
2021-06-28 15:17:32 -05:00
|
|
|
sender.sendMessage("Creating " + (n == 1 ? "new bot" : ChatColor.RED + numberFormat.format(n) + ChatColor.RESET + " new bots")
|
2021-07-24 23:34:07 -05:00
|
|
|
+ " with name " + ChatColor.GREEN + name.replace("%", ChatColor.LIGHT_PURPLE + "%" + ChatColor.RESET)
|
2021-07-10 23:51:14 -05:00
|
|
|
+ (skinName == null ? "" : ChatColor.RESET + " and skin " + ChatColor.GREEN + skinName)
|
2021-06-28 15:17:32 -05:00
|
|
|
+ ChatColor.RESET + "...");
|
2021-06-28 13:18:49 -05:00
|
|
|
|
2021-07-10 23:51:14 -05:00
|
|
|
skinName = skinName == null ? name : skinName;
|
2021-06-28 13:18:49 -05:00
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
createBots(sender.getLocation(), name, MojangAPI.getSkin(skinName), n, network);
|
|
|
|
|
|
|
|
|
|
sender.sendMessage("Process completed (" + ChatColor.RED + ((System.currentTimeMillis() - timestamp) / 1000D) + "s" + ChatColor.RESET + ").");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Set<Bot> createBots(Location loc, String name, String[] skin, int n, NeuralNetwork network) {
|
|
|
|
|
List<NeuralNetwork> networks = new ArrayList<>();
|
2021-06-28 15:17:32 -05:00
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
networks.add(network);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return createBots(loc, name, skin, networks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Set<Bot> createBots(Location loc, String name, String[] skin, List<NeuralNetwork> networks) {
|
|
|
|
|
Set<Bot> bots = new HashSet<>();
|
|
|
|
|
World world = loc.getWorld();
|
2021-07-10 23:51:14 -05:00
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
int n = networks.size();
|
|
|
|
|
int i = 1;
|
|
|
|
|
|
|
|
|
|
double f = n < 100 ? .004 * n : .4;
|
|
|
|
|
|
|
|
|
|
for (NeuralNetwork network : networks) {
|
2021-07-23 03:47:11 -05:00
|
|
|
Bot bot = Bot.createBot(loc, name.replace("%", String.valueOf(i)), skin);
|
|
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
if (network != null) {
|
|
|
|
|
bot.setNeuralNetwork(network == NeuralNetwork.RANDOM ? NeuralNetwork.generateRandomNetwork() : network);
|
|
|
|
|
bot.setShield(true);
|
|
|
|
|
bot.setDefaultItem(new ItemStack(Material.WOODEN_AXE));
|
|
|
|
|
bot.setRemoveOnDeath(false);
|
2021-07-23 03:47:11 -05:00
|
|
|
}
|
|
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
if (network != null) {
|
|
|
|
|
bot.setVelocity(randomVelocity());
|
|
|
|
|
} else if (i > 1) {
|
|
|
|
|
bot.setVelocity(randomVelocity().multiply(f));
|
2021-07-23 03:47:11 -05:00
|
|
|
}
|
2021-07-24 23:34:07 -05:00
|
|
|
|
|
|
|
|
bots.add(bot);
|
|
|
|
|
i++;
|
2021-06-28 13:18:49 -05:00
|
|
|
}
|
|
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
if (world != null) {
|
|
|
|
|
world.spawnParticle(Particle.CLOUD, loc, 100, 1, 1, 1, 0.5);
|
|
|
|
|
}
|
2021-06-28 13:18:49 -05:00
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
return bots;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Vector randomVelocity() {
|
|
|
|
|
return new Vector(Math.random() - 0.5, 0.5, Math.random() - 0.5).normalize();
|
2021-06-28 13:18:49 -05:00
|
|
|
}
|
|
|
|
|
|
2021-07-12 18:20:17 -05:00
|
|
|
public void remove(Bot bot) {
|
|
|
|
|
bots.remove(bot);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-26 19:43:58 -05:00
|
|
|
public void reset() {
|
2021-07-16 03:41:21 -05:00
|
|
|
bots.forEach(Bot::removeVisually);
|
|
|
|
|
bots.clear(); // Not always necessary, but a good security measure
|
2021-07-19 17:35:28 -05:00
|
|
|
agent.stopAllTasks();
|
2021-07-24 23:34:07 -05:00
|
|
|
|
|
|
|
|
System.gc();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Bot getBot(Player player) { // potentially memory intensive
|
|
|
|
|
Bot bot = null;
|
|
|
|
|
|
|
|
|
|
int id = player.getEntityId();
|
|
|
|
|
|
|
|
|
|
for (Bot b : bots) {
|
|
|
|
|
if (id == b.getId()) {
|
|
|
|
|
bot = b;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bot;
|
2021-06-26 19:43:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@EventHandler
|
|
|
|
|
public void onJoin(PlayerJoinEvent event) {
|
|
|
|
|
PlayerConnection connection = ((CraftPlayer) event.getPlayer()).getHandle().playerConnection;
|
2021-07-19 17:35:28 -05:00
|
|
|
bots.forEach(bot -> bot.render(connection, true));
|
2021-06-26 19:43:58 -05:00
|
|
|
}
|
2021-07-23 17:25:10 -05:00
|
|
|
|
|
|
|
|
@EventHandler
|
2021-07-24 23:34:07 -05:00
|
|
|
public void onDeath(PlayerDeathEvent event) {
|
|
|
|
|
Player player = event.getEntity();
|
|
|
|
|
Bot bot = getBot(player);
|
2021-07-23 17:25:10 -05:00
|
|
|
|
2021-07-24 23:34:07 -05:00
|
|
|
if (bot != null) {
|
|
|
|
|
agent.onBotDeath(new BotDeathEvent(event, bot));
|
|
|
|
|
}
|
2021-07-23 17:25:10 -05:00
|
|
|
}
|
2021-06-26 19:43:58 -05:00
|
|
|
}
|