diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
index ff07546..09500a9 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
@@ -21,6 +21,7 @@ package de.steamwar.fightsystem;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.core.Core;
+import de.steamwar.fightsystem.ai.LixfelAI;
import de.steamwar.fightsystem.commands.*;
import de.steamwar.fightsystem.countdown.*;
import de.steamwar.fightsystem.event.HellsBells;
@@ -105,7 +106,7 @@ public class FightSystem extends JavaPlugin {
techHider = new TechHiderWrapper();
new FightWorld();
new FightUI();
- new FightStatistics();
+ //new FightStatistics();
new BungeeFightInfo();
new WinconditionAllDead();
@@ -163,6 +164,8 @@ public class FightSystem extends JavaPlugin {
}else if(Config.mode == ArenaMode.PREPARE) {
Fight.getUnrotated().setSchem(SchematicNode.getSchematicNode(Config.PrepareSchemID));
}
+
+ new LixfelAI(Fight.getBlueTeam());
}
@Override
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/ai/AI.java b/FightSystem_Core/src/de/steamwar/fightsystem/ai/AI.java
new file mode 100644
index 0000000..33aafdc
--- /dev/null
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/ai/AI.java
@@ -0,0 +1,127 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.fightsystem.ai;
+
+import com.comphenix.tinyprotocol.Reflection;
+import de.steamwar.fightsystem.Config;
+import de.steamwar.fightsystem.FightSystem;
+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.Material;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Villager;
+import org.bukkit.scheduler.BukkitTask;
+import org.bukkit.util.Vector;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+public abstract class AI {
+
+ private static final Map ais = new HashMap<>();
+
+ public static AI getAI(UUID uuid) {
+ return ais.get(uuid);
+ }
+
+ private final FightTeam team;
+ private final LivingEntity entity;
+ private final BukkitTask task;
+ private int cooldown;
+
+ private static final Reflection.MethodInvoker getHandle = Reflection.getMethod("{obc}.entity.CraftEntity", "getHandle");
+ private static final Reflection.FieldAccessor entityUUID = Reflection.getField("{nms.world.entity}.Entity", UUID.class, 0);
+ protected AI(FightTeam team, SteamwarUser user) {
+ this.team = team;
+
+ entity = Config.world.spawn(Config.SpecSpawn, Villager.class, entity -> entityUUID.set(getHandle.invoke(entity), user.getUUID()));
+ entity.setCustomName(user.getUserName());
+ entity.setAI(false);
+
+ task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::run, 1, 1);
+ ais.put(user.getUUID(), this);
+ team.addMember(entity);
+ }
+
+ public abstract SchematicNode chooseSchematic();
+
+ public boolean acceptJoinRequest(Player player, FightTeam team) {
+ return true;
+ }
+
+ protected abstract void plan();
+
+ public void cleanup() {
+ ais.remove(entity.getUniqueId());
+ task.cancel();
+ }
+
+ public LivingEntity getEntity() {
+ return entity;
+ }
+
+ protected void setReady() {
+ if(FightState.getFightState() != FightState.POST_SCHEM_SETUP)
+ return;
+
+ if(team.getLeader().getEntity() != entity)
+ return;
+
+ team.setReady(true);
+ }
+
+ protected Material getBlock(Vector pos) {
+ //TODO position translation
+ cooldown++;
+ return pos.toLocation(Config.world).getBlock().getType();
+ }
+
+ protected void setTNT(Vector pos) {
+ //TODO position translation
+ //TODO Check position
+ //TODO Check AIR is there
+ cooldown++;
+ pos.toLocation(Config.world).getBlock().setType(Material.TNT);
+ }
+
+ protected void move(Vector pos) {
+ //TODO position translation
+ //TODO Check position
+ //TODO falling check
+ //TODO pathfinding
+ cooldown += 5;
+ entity.teleport(pos.toLocation(Config.world));
+ }
+
+ private void run() {
+ if(cooldown > 0)
+ cooldown--;
+
+ if(cooldown > 0)
+ return;
+
+ plan();
+ }
+}
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/ai/AIPlayer.java b/FightSystem_Core/src/de/steamwar/fightsystem/ai/LixfelAI.java
similarity index 54%
rename from FightSystem_Core/src/de/steamwar/fightsystem/ai/AIPlayer.java
rename to FightSystem_Core/src/de/steamwar/fightsystem/ai/LixfelAI.java
index 1730174..fcc834b 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/ai/AIPlayer.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/ai/LixfelAI.java
@@ -19,27 +19,28 @@
package de.steamwar.fightsystem.ai;
-import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.fightsystem.Config;
+import de.steamwar.fightsystem.fight.FightTeam;
+import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Villager;
-import java.util.UUID;
+import java.util.List;
+import java.util.Random;
-public class AIPlayer {
- private static final Reflection.MethodInvoker getHandle = Reflection.getMethod("{obc}.entity.CraftEntity", "getHandle");
- private static final Reflection.FieldAccessor entityUUID = Reflection.getField("{nms.world.entity}.Entity", UUID.class, 0);
-
- private final LivingEntity player;
-
- public AIPlayer(SteamwarUser user) {
- player = Config.world.spawn(Config.SpecSpawn, Villager.class, entity -> entityUUID.set(getHandle.invoke(entity), user.getUUID()));
- player.setCustomName(user.getUserName());
- player.setAI(false);
+public class LixfelAI extends AI {
+ public LixfelAI(FightTeam team) {
+ super(team, SteamwarUser.get("public"));
}
- public LivingEntity getEntity() {
- return player;
+ @Override
+ public SchematicNode chooseSchematic() {
+ List publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB());
+ return publics.get(new Random().nextInt(publics.size()));
+ }
+
+ @Override
+ protected void plan() {
+ setReady();
+ getEntity().setAI(true);
}
}
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java
index ec89b25..41735a7 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java
@@ -20,6 +20,7 @@
package de.steamwar.fightsystem.fight;
import de.steamwar.fightsystem.Config;
+import de.steamwar.fightsystem.ai.AI;
import de.steamwar.fightsystem.countdown.EnternCountdown;
import de.steamwar.sql.PersonalKit;
import de.steamwar.sql.SteamwarUser;
@@ -62,6 +63,7 @@ public class FightPlayer {
public void setOut() {
isOut = true;
stopEnternCountdown();
+ ifAI(AI::cleanup);
}
public void startEnternCountdown() {
@@ -83,6 +85,11 @@ public class FightPlayer {
return entity;
}
+ public void ifAI(Consumer function) {
+ if(!(entity instanceof Player))
+ function.accept(AI.getAI(uuid));
+ }
+
public void ifPlayer(Consumer function) {
if(entity instanceof Player)
function.accept((Player) entity);
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java
index 1184916..03726d3 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java
@@ -372,6 +372,8 @@ public class FightTeam {
if(FightState.getFightState() == FightState.PRE_LEADER_SETUP && !Fight.getOpposite(this).isLeaderless()){
FightState.setFightState(FightState.PRE_SCHEM_SETUP);
}
+
+ leader.ifAI(ai -> setSchem(ai.chooseSchematic()));
}
public Collection getPlayers() {
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/JoinRequest.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/JoinRequest.java
index 9bdfe27..4f80744 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/JoinRequest.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/JoinRequest.java
@@ -63,6 +63,8 @@ public class JoinRequest {
this.player = player;
this.team = team;
this.waitOnApproval = new HashSet<>(FightState.ingame() ? Fight.teams() : Collections.singleton(team));
+
+ activeRequests.put(player, this);
for(FightTeam t : waitOnApproval) {
FightPlayer leader = t.getLeader();
if(leader == null)
@@ -72,9 +74,12 @@ public class JoinRequest {
continue;
leader.ifPlayer(leaderPlayer -> FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_NOTIFICATION", leaderPlayer, "REQUESTS", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/requests"), player.getName(), team.getColoredName()));
+ leader.ifAI(ai -> {
+ if(ai.acceptJoinRequest(player, team))
+ accept(t);
+ });
}
- activeRequests.put(player, this);
FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_CONFIRMATION", player, ChatMessageType.ACTION_BAR);
}
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/NormalJoin.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/NormalJoin.java
index 931f0b7..371ae75 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/NormalJoin.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/NormalJoin.java
@@ -20,14 +20,10 @@
package de.steamwar.fightsystem.listener;
import de.steamwar.fightsystem.ArenaMode;
-import de.steamwar.fightsystem.FightSystem;
-import de.steamwar.fightsystem.ai.AIPlayer;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentListener;
-import de.steamwar.sql.SteamwarUser;
-import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -47,15 +43,7 @@ public class NormalJoin implements Listener {
FightTeam team = Fight.teams().stream().filter(t -> player.getUniqueId().equals(t.getDesignatedLeader())).findAny( // Player is designated leader of a team
).orElse(Fight.teams().stream().filter(t -> t.canbeLeader(player)).findAny().orElse(null)); // Else search empty team
- if(team != null) {
+ if(team != null)
team.addMember(player);
- FightTeam aiTeam = Fight.getOpposite(team);
- AIPlayer aiPlayer = new AIPlayer(SteamwarUser.get(0));
- aiTeam.addMember(aiPlayer.getEntity());
- Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
- FightState.setFightState(FightState.POST_SCHEM_SETUP);
- aiTeam.setReady(true);
- }, 1);
- }
}
}