SteamWar/FightSystem
Archiviert
13
1

Don't load destroyed cannons

Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Lixfel 2023-09-04 19:58:54 +02:00
Ursprung 21ee580c0f
Commit 3b6cde085d
4 geänderte Dateien mit 121 neuen und 37 gelöschten Zeilen
FightSystem_Core/src/de/steamwar/fightsystem/ai

Datei anzeigen

@ -144,9 +144,9 @@ public abstract class AI {
return translate(pos, true).getBlock().getType(); return translate(pos, true).getBlock().getType();
} }
public boolean isPowered(Vector pos) { public BlockData getBlockData(Vector pos) {
queue.add(new Action(1)); queue.add(new Action(1));
return translate(pos, true).getBlock().isBlockPowered(); return translate(pos, true).getBlock().getBlockData();
} }
public void setTNT(Vector pos) { public void setTNT(Vector pos) {
@ -219,7 +219,8 @@ public abstract class AI {
if(!team.getFightPlayer(entity).canEntern() && !team.getExtendRegion().inRegion(target)) if(!team.getFightPlayer(entity).canEntern() && !team.getExtendRegion().inRegion(target))
return; return;
entity.teleport(target, PlayerTeleportEvent.TeleportCause.PLUGIN); if(!entity.teleport(target, PlayerTeleportEvent.TeleportCause.PLUGIN))
FightSystem.getPlugin().getLogger().log(Level.INFO, "Entity not teleported: " + entity.isValid());
} }
}); });
} }

Datei anzeigen

@ -19,40 +19,56 @@
package de.steamwar.fightsystem.ai; package de.steamwar.fightsystem.ai;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.FightState;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;
public class LixfelAI extends AI { public class LixfelAI extends AI {
private Random random; private static final Random random = new Random();
private final BukkitTask timerTask;
private int currentTime;
private LixfelPathplanner pathplanner; private LixfelPathplanner pathplanner;
private List<Vector> setup; private List<Vector> setup;
private long preRunningStart; private int preRunningStart;
private List<TimedVector> timedStart; private List<TimedVector> timedStart;
private List<Cannon> cannons; private List<Cannon> cannons;
private Cannon currentCannon; private Cannon currentCannon;
public LixfelAI(FightTeam team, String user) { public LixfelAI(FightTeam team, String user) {
super(team, SteamwarUser.get(user)); super(team, SteamwarUser.get(user));
timerTask = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), () -> currentTime++, 1, 1);
} }
@Override @Override
public SchematicNode chooseSchematic() { public SchematicNode chooseSchematic() {
random = new Random();
List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB()); List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB());
SchematicNode schem = publics.get(random.nextInt(publics.size())); SchematicNode schem = publics.get(random.nextInt(publics.size()));
schem = publics.stream().filter(s -> s.getName().equals("TheUnderground")).findAny().orElse(schem); schem = publics.stream().filter(s -> s.getName().equals("TheUnderground")).findAny().orElse(schem);
Clipboard clipboard;
try {
clipboard = new SchematicData(schem).load();
} catch (IOException e) {
throw new IllegalStateException(e);
}
pathplanner = new LixfelPathplanner(schem); pathplanner = new LixfelPathplanner(clipboard);
setup = new ArrayList<>(Collections.singletonList(new Vector(25, 15, 25))); setup = new ArrayList<>(Collections.singletonList(new Vector(25, 15, 25)));
timedStart = new ArrayList<>(Collections.singletonList(new TimedVector(420L, new Vector(21, 15, 24)))); timedStart = new ArrayList<>(Collections.singletonList(new TimedVector(420L, new Vector(21, 15, 24))));
cannons = new ArrayList<>(Arrays.asList( cannons = new ArrayList<>(Arrays.asList(
@ -64,6 +80,7 @@ public class LixfelAI extends AI {
new Cannon(null, 23,5,9, 23,6,9, 23,7,9, 23,8,9), new Cannon(null, 23,5,9, 23,6,9, 23,7,9, 23,8,9),
new Cannon(null, 27,5,9, 27,6,9, 27,7,9, 27,8,9) new Cannon(null, 27,5,9, 27,6,9, 27,7,9, 27,8,9)
)); ));
assignWater(clipboard);
chooseCannon(); chooseCannon();
return schem; return schem;
@ -81,14 +98,33 @@ public class LixfelAI extends AI {
ensureInRange(currentCannon.tnt.keySet().iterator().next()); ensureInRange(currentCannon.tnt.keySet().iterator().next());
break; break;
case RUNNING: case RUNNING:
while(currentCannon.shoot()) while(currentCannon.shoot() && chooseCannon() && scanEnemy()) {}
chooseCannon(); //TODO prevent endless loop
break; break;
default: default:
break; break;
} }
} }
@Override
public void stop() {
if(!timerTask.isCancelled())
timerTask.cancel();
super.stop();
}
private void assignWater(Clipboard clipboard) {
List<Vector> waterSources = new ArrayList<>();
clipboard.getRegion().forEach(block -> {
if(clipboard.getBlock(block).getBlockType().getMaterial().isLiquid())
waterSources.add(pathplanner.clipboardToSchem(block));
});
for(Vector water : waterSources) {
cannons.stream().min(Comparator.comparingDouble(c -> c.waterDistance(water))).ifPresent(cannon -> cannon.addWater(water));
}
}
private boolean prepareSchem() { private boolean prepareSchem() {
return doWith(setup, this::interact); return doWith(setup, this::interact);
} }
@ -100,12 +136,12 @@ public class LixfelAI extends AI {
private boolean start() { private boolean start() {
if(preRunningStart == 0) if(preRunningStart == 0)
preRunningStart = Config.world.getFullTime(); preRunningStart = currentTime;
if(timedStart.isEmpty()) if(timedStart.isEmpty())
return true; return true;
long time = Config.world.getFullTime() - preRunningStart; long time = currentTime - preRunningStart;
TimedVector vector = timedStart.get(0); TimedVector vector = timedStart.get(0);
if(!ensureInRange(vector.vector)) if(!ensureInRange(vector.vector))
return false; return false;
@ -118,8 +154,13 @@ public class LixfelAI extends AI {
return false; return false;
} }
private void chooseCannon() { private boolean chooseCannon() {
currentCannon = cannons.get(random.nextInt(cannons.size())); List<Cannon> availableCannons = cannons.stream().filter(Cannon::available).collect(Collectors.toList());
if(availableCannons.isEmpty())
return false;
currentCannon = availableCannons.get(random.nextInt(availableCannons.size()));
return true;
} }
private boolean doWith(List<Vector> targets, Consumer<Vector> method) { private boolean doWith(List<Vector> targets, Consumer<Vector> method) {
@ -141,14 +182,19 @@ public class LixfelAI extends AI {
if(path.isEmpty()) if(path.isEmpty())
path.add(new Vector(0, 1, 0).add(position)); path.add(new Vector(0, 1, 0).add(position));
for(Vector v : path)
Config.world.spawnParticle(Particle.VILLAGER_HAPPY, translate(v, false), 1);
move(path.get(0)); move(path.get(0));
return false; return false;
} }
private class Cannon { private class Cannon {
private final List<Vector> water = new ArrayList<>();
private final Vector activator; private final Vector activator;
private final Map<Vector, Boolean> tnt = new HashMap<>(); private final Map<Vector, Boolean> tnt = new HashMap<>();
private long freeAt; private int freeAt;
private int lastCannonCheck = -1;
public Cannon(Vector activator, int... tntpos) { public Cannon(Vector activator, int... tntpos) {
this.activator = activator; this.activator = activator;
@ -158,10 +204,36 @@ public class LixfelAI extends AI {
} }
} }
public void addWater(Vector vector) {
water.add(vector);
}
public double waterDistance(Vector vector) {
return tnt.keySet().stream().mapToDouble(t -> {
double distance = t.distance(vector);
if(t.getY() < vector.getY())
distance += 10.0; //It is unlikely that TNT is loaded from below into the cannon
return distance;
}).min().orElse(Double.MAX_VALUE);
}
public boolean available() {
return currentTime >= freeAt && !water.isEmpty();
}
public boolean shoot() { public boolean shoot() {
if(Config.world.getFullTime() < freeAt) if(currentTime < freeAt || water.isEmpty())
return true; return true;
if(lastCannonCheck < freeAt) {
Vector w = water.get(random.nextInt(water.size()));
if(getBlock(w) == Material.WATER)
lastCannonCheck = freeAt;
else
water.remove(w);
return false;
}
for(Map.Entry<Vector, Boolean> entry : tnt.entrySet()) { for(Map.Entry<Vector, Boolean> entry : tnt.entrySet()) {
if(!entry.getValue()) { if(!entry.getValue()) {
if(ensureInRange(entry.getKey())) { if(ensureInRange(entry.getKey())) {
@ -179,7 +251,7 @@ public class LixfelAI extends AI {
interact(activator); interact(activator);
} }
freeAt = Config.world.getFullTime() + 80; freeAt = currentTime + 80;
for(Map.Entry<Vector, Boolean> entry : tnt.entrySet()) for(Map.Entry<Vector, Boolean> entry : tnt.entrySet())
entry.setValue(false); entry.setValue(false);

Datei anzeigen

@ -25,15 +25,12 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.utils.WorldeditWrapper; import de.steamwar.fightsystem.utils.WorldeditWrapper;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Banner; import org.bukkit.block.Banner;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.*; import org.bukkit.block.data.type.*;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -75,19 +72,27 @@ public class LixfelPathplanner {
return 0.0; return 0.0;
} }
private static Vector toBukkit(BlockVector3 vector, double height) { private static Vector toBukkit(BlockVector3 vector, double offset, double height) {
return new Vector(vector.getX() + 0.5, vector.getY() + height, vector.getZ() + 0.5); return new Vector(vector.getX() + offset, vector.getY() + height, vector.getZ() + offset);
} }
private final Vector clipboardToSchem;
private final BlockVector3 diff;
private final List<Vector> walkable = new ArrayList<>(); private final List<Vector> walkable = new ArrayList<>();
private final Map<Vector, Vector[]> neighbours = new HashMap<>(); private final Map<Vector, Vector[]> neighbours = new HashMap<>();
public LixfelPathplanner(SchematicNode schem) { public LixfelPathplanner(Clipboard clipboard) {
try { clipboardToSchem = new Vector(Config.BluePasteRegion.getSizeX(), Config.BluePasteRegion.getSizeY(), Config.BluePasteRegion.getSizeZ())
fillWalkable(new SchematicData(schem).load()); .subtract(WorldeditWrapper.impl.getDimensions(clipboard))
} catch (IOException e) { .multiply(0.5)
throw new IllegalStateException(e); .add(new Vector(Config.PreperationArea, 0, Config.PreperationArea));
diff = clipboard.getRegion().getMinimumPoint().subtract(clipboardToSchem.getBlockX(), clipboardToSchem.getBlockY(), clipboardToSchem.getBlockZ());
fillWalkable(clipboard);
} }
public Vector clipboardToSchem(BlockVector3 vector) {
return toBukkit(vector.subtract(diff), 0.0, 0.0);
} }
public List<Vector> getWalkable() { public List<Vector> getWalkable() {
@ -95,12 +100,6 @@ public class LixfelPathplanner {
} }
private void fillWalkable(Clipboard clipboard) { private void fillWalkable(Clipboard clipboard) {
Vector clipboardToSchem = new Vector(Config.BluePasteRegion.getSizeX(), Config.BluePasteRegion.getSizeY(), Config.BluePasteRegion.getSizeZ())
.subtract(WorldeditWrapper.impl.getDimensions(clipboard))
.multiply(0.5)
.add(new Vector(Config.PreperationArea, 0, Config.PreperationArea));
BlockVector3 diff = clipboard.getRegion().getMinimumPoint().subtract(clipboardToSchem.getBlockX(), clipboardToSchem.getBlockY(), clipboardToSchem.getBlockZ());
Region region = clipboard.getRegion(); Region region = clipboard.getRegion();
clipboard.getRegion().forEach(vector -> { clipboard.getRegion().forEach(vector -> {
BlockVector3 below = vector.subtract(0, 1, 0); BlockVector3 below = vector.subtract(0, 1, 0);
@ -121,7 +120,7 @@ public class LixfelPathplanner {
if(height < 0.0) if(height < 0.0)
height = 0.0; height = 0.0;
walkable.add(toBukkit(vector.subtract(diff), height)); walkable.add(toBukkit(vector.subtract(diff), 0.5, height));
}); });
for(Vector vector : walkable) { for(Vector vector : walkable) {

Datei anzeigen

@ -19,21 +19,24 @@
package de.steamwar.fightsystem.ai.chaos; package de.steamwar.fightsystem.ai.chaos;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.ai.AI; import de.steamwar.fightsystem.ai.AI;
import de.steamwar.fightsystem.ai.LixfelPathplanner; import de.steamwar.fightsystem.ai.LixfelPathplanner;
import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.FightState;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.io.IOException;
import java.util.*; import java.util.*;
public class ChaosAI extends AI { public class ChaosAI extends AI {
private final LixfelPathplanner pathplanner = new LixfelPathplanner(chooseSchematic()); private LixfelPathplanner pathplanner;
private State state = State.PRE_PREPARE; private State state = State.PRE_PREPARE;
private static final Cannon[] cannons = new Cannon[] { private static final Cannon[] cannons = new Cannon[] {
Cannon.DS_LEFT, Cannon.DS_LEFT,
@ -67,7 +70,16 @@ public class ChaosAI extends AI {
@Override @Override
public SchematicNode chooseSchematic() { public SchematicNode chooseSchematic() {
return SchematicNode.getSchematicNode(111476); SchematicNode schem = SchematicNode.getSchematicNode(111476);
Clipboard clipboard;
try {
clipboard = new SchematicData(schem).load();
} catch (IOException e) {
throw new IllegalStateException(e);
}
pathplanner = new LixfelPathplanner(clipboard);
return schem;
} }
@Override @Override