diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/AI.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/AI.java index bab0830f..cbee5063 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/AI.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/AI.java @@ -175,7 +175,7 @@ public abstract class AI { } Block block = location.getBlock(); - if(block.getType() == Material.AIR) + if(block.getType() == Material.AIR || block.getType() == Material.WATER || block.getType() == Material.LAVA || block.getType() == Material.TNT) block.setType(Material.TNT); } }); @@ -278,6 +278,7 @@ public abstract class AI { FightSystem.getPlugin().getLogger().log(Level.INFO, "Entity not teleported: " + entity.isValid()); GlobalRecorder.getInstance().entityMoves(entity); + navMesh.update(getPosition().toWorld(team)); } }); } @@ -292,6 +293,7 @@ public abstract class AI { private void interact(Block block) { BlockData data = block.getBlockData(); //TODO only 1.14+ compatible at the moment + System.out.println(block + " " + data); if (data instanceof NoteBlock) { NoteBlock noteBlock = (NoteBlock) data; Note note = noteBlock.getNote(); @@ -322,6 +324,7 @@ public abstract class AI { } powerable.setPowered(!isPowered); + System.out.println(powerable); } block.setBlockData(data); if(data instanceof Switch) { @@ -350,7 +353,6 @@ public abstract class AI { private void run() { if(queue.isEmpty()) { try { - navMesh.update(getPosition().toWorld(team)); plan(); } catch (Throwable t) { stop(); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/Action.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/Action.java index d7df800f..e8ba43bf 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/Action.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/Action.java @@ -19,10 +19,13 @@ package de.steamwar.fightsystem.ai; +import de.steamwar.fightsystem.ai.schematic.Cannon; + +import java.util.ArrayList; import java.util.List; public interface Action { - boolean isCompletable(); + Result step(AI ai); enum Result { @@ -32,6 +35,46 @@ public interface Action { ; } + class MultiAction implements Action { + + protected final List actions = new ArrayList<>(); + + @Override + public Result step(AI ai) { + if (!actions.isEmpty()) { + Action.Result result = actions.get(0).step(ai); + if (result == Action.Result.FAILED) { + ai.chat(this + " + " + actions.get(0) + " failed"); + actions.clear(); + return Result.FAILED; + } + if (result == Action.Result.FINISHED) { + ai.chat(this + " + " + actions.get(0) + " finished"); + actions.remove(0); + } + } + return actions.isEmpty() ? Result.FINISHED : Result.ONGOING; + } + } + + class WaitAction implements Action { + + private int delay; + + public WaitAction(int delay) { + this.delay = delay; + } + + @Override + public Result step(AI ai) { + if (--delay > 0) { + return Result.ONGOING; + } else { + return Result.FINISHED; + } + } + } + class MoveAction implements Action { private final WorldCoordinate destination; @@ -47,11 +90,6 @@ public interface Action { this.path = ai.navMesh.pathToNearest(ai.getPosition().toWorld(ai.team), destination); } - @Override - public boolean isCompletable() { - return !path.isEmpty(); - } - @Override public Result step(AI ai) { if (this.path.isEmpty()) return Result.FAILED; @@ -95,15 +133,48 @@ public interface Action { this.destination = destination; } - @Override - public boolean isCompletable() { - return true; - } - @Override public Result step(AI ai) { ai.interact(destination); return Result.FINISHED; } } + + class ReadyAction implements Action { + + @Override + public Result step(AI ai) { + ai.setReady(); + return Result.FINISHED; + } + } + + class PlaceTNTAction implements Action { + + private final LocalCoordinate destination; + + public PlaceTNTAction(LocalCoordinate destination) { + this.destination = destination; + } + + @Override + public Result step(AI ai) { + ai.setTNT(destination); + return Result.FINISHED; + } + } + + class LoadCannon extends MultiAction { + + public LoadCannon(AI ai, Cannon cannon) { + for (LocalCoordinate tntPosition : cannon.getTntPositions()) { + actions.add(new MoveAction(ai, tntPosition.toWorld(ai.team))); + actions.add(new PlaceTNTAction(tntPosition)); + } + + LocalCoordinate trigger = cannon.getTriggerPositions().iterator().next(); + actions.add(new MoveAction(ai, trigger.toWorld(ai.team))); + actions.add(new InteractAction(trigger)); + } + } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/LocalCoordinate.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/LocalCoordinate.java index 334d8afe..87eb180a 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/LocalCoordinate.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/LocalCoordinate.java @@ -50,6 +50,9 @@ public class LocalCoordinate { } public WorldCoordinate toWorld(FightTeam team) { + // TODO: Fix the of by one blue/red + // Team Red is not correct! + // NightTown is team blue unrotated! Region extend = team.getExtendRegion(); if(Fight.getUnrotated() == team) { return new WorldCoordinate( @@ -59,9 +62,9 @@ public class LocalCoordinate { ); } else { return new WorldCoordinate( - extend.getMaxX() - x, + extend.getMaxX() - x - 1, y + team.getSchemRegion().getMinY(), - extend.getMaxZ() - z + extend.getMaxZ() - z - 1 ); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/NavMesh.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/NavMesh.java index b89a30af..db6838dc 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/NavMesh.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/NavMesh.java @@ -306,12 +306,19 @@ public class NavMesh { Pos to = toPos(toCoordinate); if (walkable.containsKey(to)) return path(toPos(fromCoordinate), to); - Pos nearestPos = walkable.values() + Pos closestTo = walkable.values() .stream() - .min(Comparator.comparingDouble(pos -> pos.toWorld().distanceSquared(toCoordinate))) + .filter(pos -> { + double distance = pos.toWorld().distanceSquared(toCoordinate); + return distance < AI.INTERACTION_RANGE * AI.INTERACTION_RANGE && distance > 1.5 * 1.5; + }) + .min(Comparator.comparing(pos -> pos.toWorld().distanceSquared(toCoordinate))) .orElse(null); - if (nearestPos == null) return Collections.emptyList(); - return path(toPos(fromCoordinate), nearestPos); + + if (closestTo == null) { + return Collections.emptyList(); + } + return path(toPos(fromCoordinate), closestTo); } public List path(WorldCoordinate fromCoordinate, WorldCoordinate toCoordinate) { diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/WorldCoordinate.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/WorldCoordinate.java index 4cd7026c..87fc2338 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/WorldCoordinate.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/WorldCoordinate.java @@ -61,6 +61,7 @@ public class WorldCoordinate { } public LocalCoordinate toLocal(FightTeam team) { + // TODO: Fix the of by one blue/red Region extend = team.getExtendRegion(); if (Fight.getUnrotated() == team) { return new LocalCoordinate( @@ -70,9 +71,9 @@ public class WorldCoordinate { ); } else { return new LocalCoordinate( - extend.getMaxX() - x, + extend.getMaxX() - x + 1, y - team.getSchemRegion().getMinY(), - extend.getMaxZ() - z + extend.getMaxZ() - z + 1 ); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/Bridge.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/Bridge.java index 36deb30e..a159c863 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/Bridge.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/Bridge.java @@ -19,8 +19,8 @@ package de.steamwar.fightsystem.ai.schematic; +import de.steamwar.fightsystem.ai.LocalCoordinate; import lombok.Getter; -import org.bukkit.util.Vector; import java.util.HashSet; import java.util.Set; @@ -28,16 +28,16 @@ import java.util.Set; @Getter public class Bridge { - private final Set shieldActivators = new HashSet<>(); - private Vector automaticActivator = null; + private final Set shieldActivators = new HashSet<>(); + private LocalCoordinate automaticActivator = null; private int automaticActivatorTime = 0; - public Bridge addShieldActivator(Vector shieldActivator) { + public Bridge addShieldActivator(LocalCoordinate shieldActivator) { this.shieldActivators.add(shieldActivator); return this; } - public Bridge addAutomaticActivator(Vector automaticActivator, int automaticActivatorTime) { + public Bridge addAutomaticActivator(LocalCoordinate automaticActivator, int automaticActivatorTime) { this.automaticActivator = automaticActivator; this.automaticActivatorTime = automaticActivatorTime; return this; diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/Cannon.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/Cannon.java index 0084c0fc..6d89c02b 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/Cannon.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/Cannon.java @@ -19,8 +19,8 @@ package de.steamwar.fightsystem.ai.schematic; +import de.steamwar.fightsystem.ai.LocalCoordinate; import lombok.Getter; -import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.HashSet; @@ -30,15 +30,15 @@ import java.util.Set; @Getter public class Cannon { - private final List tntPositions = new ArrayList<>(); - private final Set triggerPositions = new HashSet<>(); + private final List tntPositions = new ArrayList<>(); + private final Set triggerPositions = new HashSet<>(); - public Cannon addTnt(Vector tnt) { + public Cannon addTnt(LocalCoordinate tnt) { tntPositions.add(tnt); return this; } - public Cannon addTrigger(Vector trigger) { + public Cannon addTrigger(LocalCoordinate trigger) { triggerPositions.add(trigger); return this; } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/WarMachine.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/WarMachine.java index c27b2ee4..fefe7352 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/WarMachine.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/WarMachine.java @@ -19,9 +19,9 @@ package de.steamwar.fightsystem.ai.schematic; +import de.steamwar.fightsystem.ai.LocalCoordinate; import lombok.Getter; import org.bukkit.util.Consumer; -import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.List; @@ -32,7 +32,7 @@ public class WarMachine { private int schematicId = 0; private Bridge bridge = new Bridge(); private List cannons = new ArrayList<>(); - private List tntChests = new ArrayList<>(); + private List tntChests = new ArrayList<>(); public WarMachine setSchematicId(int schematicId) { this.schematicId = schematicId; @@ -51,7 +51,7 @@ public class WarMachine { return this; } - public WarMachine addTnTChest(Vector chest) { + public WarMachine addTnTChest(LocalCoordinate chest) { tntChests.add(chest); return this; } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/impl/MiniWarGear20.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/impl/MiniWarGear20.java index 62a55725..d0b9089a 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/impl/MiniWarGear20.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/schematic/impl/MiniWarGear20.java @@ -19,6 +19,7 @@ package de.steamwar.fightsystem.ai.schematic.impl; +import de.steamwar.fightsystem.ai.LocalCoordinate; import de.steamwar.fightsystem.ai.schematic.WarMachine; import org.bukkit.util.Vector; @@ -38,27 +39,27 @@ public class MiniWarGear20 { public static final WarMachine DPR_PV1_Reaper = new WarMachine() .setSchematicId(135745) .editBridge(bridge -> { - bridge.addShieldActivator(new Vector(23, 16, 19)); - bridge.addShieldActivator(new Vector(32, 4, 13)); - bridge.addShieldActivator(new Vector(20, 4, 13)); + bridge.addShieldActivator(new LocalCoordinate(22, 15, 18)); + bridge.addShieldActivator(new LocalCoordinate(31, 3, 12)); + bridge.addShieldActivator(new LocalCoordinate(19, 3, 12)); }) .addCannon(cannon -> { - cannon.addTnt(new Vector(30, 2, 22)); - cannon.addTnt(new Vector(30, 2, 23)); - cannon.addTnt(new Vector(30, 2, 24)); - cannon.addTnt(new Vector(31, 2, 23)); - cannon.addTnt(new Vector(31, 2, 24)); - cannon.addTnt(new Vector(30, 3, 25)); - cannon.addTnt(new Vector(31, 3, 25)); - cannon.addTnt(new Vector(30, 3, 26)); - cannon.addTnt(new Vector(31, 3, 26)); - cannon.addTnt(new Vector(30, 4, 25)); - cannon.addTnt(new Vector(31, 4, 25)); - cannon.addTnt(new Vector(30, 4, 26)); - cannon.addTnt(new Vector(31, 4, 26)); - cannon.addTrigger(new Vector(31, 4, 20)); - cannon.addTrigger(new Vector(32, 4, 19)); - cannon.addTrigger(new Vector(32, 4, 21)); + cannon.addTnt(new LocalCoordinate(29, 1, 21)); + cannon.addTnt(new LocalCoordinate(29, 1, 22)); + cannon.addTnt(new LocalCoordinate(29, 1, 23)); + cannon.addTnt(new LocalCoordinate(30, 1, 22)); + cannon.addTnt(new LocalCoordinate(30, 1, 23)); + cannon.addTnt(new LocalCoordinate(29, 2, 24)); + cannon.addTnt(new LocalCoordinate(30, 2, 24)); + cannon.addTnt(new LocalCoordinate(29, 2, 25)); + cannon.addTnt(new LocalCoordinate(30, 2, 25)); + cannon.addTnt(new LocalCoordinate(29, 3, 24)); + cannon.addTnt(new LocalCoordinate(30, 3, 24)); + cannon.addTnt(new LocalCoordinate(29, 3, 25)); + cannon.addTnt(new LocalCoordinate(30, 3, 25)); + cannon.addTrigger(new LocalCoordinate(30, 3, 19)); + cannon.addTrigger(new LocalCoordinate(31, 3, 18)); + cannon.addTrigger(new LocalCoordinate(31, 3, 20)); }) .finish(MiniWarGear20); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/yoyonow/YoyoNowAI.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/yoyonow/YoyoNowAI.java index 68512445..96d075c3 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/yoyonow/YoyoNowAI.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/ai/yoyonow/YoyoNowAI.java @@ -22,14 +22,13 @@ package de.steamwar.fightsystem.ai.yoyonow; import com.sk89q.worldedit.extent.clipboard.Clipboard; import de.steamwar.fightsystem.ai.AI; import de.steamwar.fightsystem.ai.Action; -import de.steamwar.fightsystem.ai.WorldCoordinate; +import de.steamwar.fightsystem.ai.schematic.Cannon; import de.steamwar.fightsystem.ai.schematic.WarMachine; import de.steamwar.fightsystem.ai.schematic.impl.MiniWarGear20; import de.steamwar.fightsystem.fight.FightTeam; +import de.steamwar.fightsystem.states.FightState; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SteamwarUser; -import org.bukkit.Bukkit; -import org.bukkit.World; import java.util.ArrayList; import java.util.List; @@ -37,8 +36,6 @@ import java.util.Random; public class YoyoNowAI extends AI { - private static final World WORLD = Bukkit.getWorlds().get(0); - private WarMachine selectedSchematic; protected YoyoNowAI(FightTeam team) { @@ -54,12 +51,14 @@ public class YoyoNowAI extends AI { @Override public void schematic(Clipboard clipboard) { - setReady(); } - private Random random = new Random(); + private final Random random = new Random(); + private List actions = new ArrayList<>(); + private boolean setupDone = false; + @Override protected void plan() { if (!navMesh.isReady()) return; @@ -67,20 +66,31 @@ public class YoyoNowAI extends AI { if (!actions.isEmpty()) { Action.Result result = actions.get(0).step(this); if (result == Action.Result.FAILED) { + chat(actions.get(0) + " failed"); actions.clear(); return; } if (result == Action.Result.FINISHED) { + chat(actions.get(0) + " finished"); actions.remove(0); - return; } return; } - List walkable = navMesh.walkable(); - WorldCoordinate destination = walkable.get(random.nextInt(walkable.size())); - Action action = new Action.MoveAction(this, destination); - if (!action.isCompletable()) return; - actions.add(action); + if (!setupDone && FightState.getFightState() == FightState.POST_SCHEM_SETUP) { + chat("Setup actions to perform!"); + selectedSchematic.getBridge().getShieldActivators().forEach(localCoordinate -> { + actions.add(new Action.MoveAction(this, localCoordinate.toWorld(getTeam()))); + actions.add(new Action.InteractAction(localCoordinate)); + }); + actions.add(new Action.ReadyAction()); + chat("Actions: " + actions.size()); + setupDone = true; + } + + if (FightState.getFightState() == FightState.RUNNING) { + Cannon cannon = selectedSchematic.getCannons().get(random.nextInt(selectedSchematic.getCannons().size())); + actions.add(new Action.LoadCannon(this, cannon)); + } } }