Moved to gradle & started work on separating API and plugin

This commit is contained in:
Badbird-5907
2022-06-17 00:22:47 -04:00
parent d0bfbb966a
commit b052a04ddb
55 changed files with 273 additions and 233 deletions

View File

@@ -0,0 +1,91 @@
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.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
public interface Terminator {
String getBotName();
GameProfile getGameProfile();
NeuralNetwork getNeuralNetwork();
void setNeuralNetwork(NeuralNetwork neuralNetwork);
boolean hasNeuralNetwork();
Location getLocation();
float getHealth();
float getMaxHealth();
void ignite();
boolean isOnFire();
boolean isFalling();
boolean isBlocking();
void block(int length, int cooldown);
boolean isInWater();
void jump(Vector velocity);
void jump();
void walk(Vector velocity);
void look(BlockFace face);
void attack(Entity target);
void attemptBlockPlace(Location loc, Material type, boolean down);
void punch();
void swim();
void sneak();
void stand();
void addFriction(double factor);
void removeVisually();
int getKills();
void incrementKills();
void setItem(ItemStack item);
void setItem(ItemStack item, EquipmentSlot slot);
void setItemOffhand(ItemStack item);
void setDefaultItem(ItemStack item);
Vector getOffset();
Vector getVelocity();
void setVelocity(Vector velocity);
void addVelocity(Vector velocity);
int getAliveTicks();
boolean tickDelay(int ticks);
}

View File

@@ -0,0 +1,9 @@
package net.nuggetmc.tplus.api.agent.legacyagent.ai;
public enum ActivationType {
TANH,
SIN_X,
SIN_X2,
COS_X,
COS_X2
}

View File

@@ -0,0 +1,53 @@
package net.nuggetmc.tplus.api.agent.legacyagent.ai;
import net.nuggetmc.tplus.api.Terminator;
import net.nuggetmc.tplus.utils.MathUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import java.util.*;
// If this is laggy, try only instantiating this once and update it instead of creating a new instance every tick
public class BotData {
private final Map<BotDataType, Double> values;
private BotData(Terminator bot, LivingEntity target) {
this.values = new HashMap<>();
Location a = bot.getLocation();
Location b = target.getLocation();
float health = bot.getHealth();
values.put(BotDataType.CRITICAL_HEALTH, health >= 5 ? 0 : 5D - health);
values.put(BotDataType.DISTANCE_XZ, Math.sqrt(MathUtils.square(a.getX() - b.getX()) + MathUtils.square(a.getZ() - b.getZ())));
values.put(BotDataType.DISTANCE_Y, b.getY() - a.getY());
values.put(BotDataType.ENEMY_BLOCKING, target instanceof Player && ((Player) target).isBlocking() ? 1D : 0);
}
public static BotData generate(Terminator bot, LivingEntity target) {
return new BotData(bot, target);
}
public Map<BotDataType, Double> getValues() {
return values;
}
public double getValue(BotDataType dataType) {
return values.get(dataType);
}
@Override
public String toString() {
List<String> strings = new ArrayList<>();
values.forEach((type, value) -> strings.add(type.name() + "=" + MathUtils.round2Dec(value)));
Collections.sort(strings);
return "BotData{" + StringUtils.join(strings, ",") + "}";
}
}

View File

@@ -0,0 +1,18 @@
package net.nuggetmc.tplus.api.agent.legacyagent.ai;
public enum BotDataType {
CRITICAL_HEALTH("h"),
DISTANCE_XZ("xz"),
DISTANCE_Y("y"),
ENEMY_BLOCKING("b");
private final String shorthand;
BotDataType(String shorthand) {
this.shorthand = shorthand;
}
public String getShorthand() {
return shorthand;
}
}

View File

@@ -0,0 +1,8 @@
package net.nuggetmc.tplus.api.agent.legacyagent.ai;
public enum BotNode {
BLOCK, // block (can't attack while blocking)
JUMP, // jump
LEFT, // left strafe
RIGHT // right strafe (if L and R are opposite, move forward)
}

View File

@@ -0,0 +1,94 @@
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 org.apache.commons.lang.StringUtils;
import java.util.*;
public class NeuralNetwork {
// thinking about making an enum called BotNode, and have a map here, .check(Node.L) or fetch
// also randomize activation point between 0 and 0.5
// randomize the blocking length and cooldown
// also the XZ offset randomizers!! (or maybe just turn them off entirely, that works too)
// b, j, l, r, ox, oz, av, bl, bc, dlr
private final Map<BotNode, NodeConnections> nodes;
private final boolean dynamicLR;
public static final NeuralNetwork RANDOM = new NeuralNetwork(new HashMap<>());
private NeuralNetwork(Map<BotNode, Map<BotDataType, Double>> profile) {
this.nodes = new HashMap<>();
this.dynamicLR = true;
if (profile == null) {
Arrays.stream(BotNode.values()).forEach(n -> this.nodes.put(n, new NodeConnections()));
} else {
profile.forEach((nodeType, map) -> nodes.put(nodeType, new NodeConnections(map)));
}
}
public static NeuralNetwork createNetworkFromProfile(Map<BotNode, Map<BotDataType, Double>> profile) {
return new NeuralNetwork(profile);
}
public static NeuralNetwork generateRandomNetwork() {
return new NeuralNetwork(null);
}
public NodeConnections fetch(BotNode node) {
return nodes.get(node);
}
public boolean check(BotNode node) {
return nodes.get(node).check();
}
public double value(BotNode node) {
return nodes.get(node).value();
}
public void feed(BotData data) {
nodes.values().forEach(n -> n.test(data));
}
public Map<BotNode, NodeConnections> nodes() {
return nodes;
}
public boolean dynamicLR() {
return dynamicLR;
}
public Map<BotNode, Map<BotDataType, Double>> values() {
Map<BotNode, Map<BotDataType, Double>> output = new HashMap<>();
nodes.forEach((nodeType, node) -> output.put(nodeType, node.getValues()));
return output;
}
public String output() {
List<String> strings = new ArrayList<>();
nodes.forEach((type, node) -> strings.add(type.name().toLowerCase() + "=" + (node.check() ? ChatUtils.ON + "1" : ChatUtils.OFF + "0") + ChatColor.RESET));
Collections.sort(strings);
return "[" + StringUtils.join(strings, ", ") + "]";
}
@Override
public String toString() {
List<String> strings = new ArrayList<>();
nodes.forEach((nodeType, node) -> {
List<String> values = new ArrayList<>();
values.add("name=\"" + nodeType.name().toLowerCase() + "\"");
node.getValues().forEach((dataType, value) -> values.add(dataType.getShorthand() + "=" + MathUtils.round2Dec(value)));
strings.add("{" + StringUtils.join(values, ",") + "}");
});
return "NeuralNetwork{nodes:[" + StringUtils.join(strings, ",") + "]}";
}
}

View File

@@ -0,0 +1,69 @@
package net.nuggetmc.tplus.api.agent.legacyagent.ai;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
public class NodeConnections {
/*
* more node ideas
* how much the bot is to the left or right of target (not horizontal distance)
* bot velocity?
* if the player is temporarily invincible (has damage ticks > 0)
*/
private final Map<BotDataType, Double> connections;
private boolean active;
private double value;
public NodeConnections() {
this.connections = new HashMap<>();
Arrays.stream(BotDataType.values()).forEach(type -> connections.put(type, generateValue()));
}
public NodeConnections(Map<BotDataType, Double> values) {
this.connections = values;
}
private double generateValue() {
return ThreadLocalRandom.current().nextDouble(-10, 10);
}
public boolean check() {
return active;
}
public double value() {
return value;
}
public Map<BotDataType, Double> getValues() {
return connections;
}
public double getValue(BotDataType dataType) {
return connections.get(dataType);
}
/*
* maybe a sinusoidal activation function?
* maybe generate a random activation function?
* definitely something less.. broad
*/
public void test(BotData data) {
this.activationFunction(data);
this.active = this.value >= 0.5;
}
/*
* try sin, sin x^2, cos, cos x^2
*/
private void activationFunction(BotData data) {
this.value = Math.tanh(data.getValues().entrySet().stream().mapToDouble(entry -> connections.get(entry.getKey()) * entry.getValue()).sum());
}
}