Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Ursprung
21ee580c0f
Commit
3b6cde085d
@ -144,9 +144,9 @@ public abstract class AI {
|
||||
return translate(pos, true).getBlock().getType();
|
||||
}
|
||||
|
||||
public boolean isPowered(Vector pos) {
|
||||
public BlockData getBlockData(Vector pos) {
|
||||
queue.add(new Action(1));
|
||||
return translate(pos, true).getBlock().isBlockPowered();
|
||||
return translate(pos, true).getBlock().getBlockData();
|
||||
}
|
||||
|
||||
public void setTNT(Vector pos) {
|
||||
@ -219,7 +219,8 @@ public abstract class AI {
|
||||
if(!team.getFightPlayer(entity).canEntern() && !team.getExtendRegion().inRegion(target))
|
||||
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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -19,40 +19,56 @@
|
||||
|
||||
package de.steamwar.fightsystem.ai;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
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.SchematicData;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
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 java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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 List<Vector> setup;
|
||||
private long preRunningStart;
|
||||
private int preRunningStart;
|
||||
private List<TimedVector> timedStart;
|
||||
private List<Cannon> cannons;
|
||||
private Cannon currentCannon;
|
||||
|
||||
public LixfelAI(FightTeam team, String user) {
|
||||
super(team, SteamwarUser.get(user));
|
||||
timerTask = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), () -> currentTime++, 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchematicNode chooseSchematic() {
|
||||
random = new Random();
|
||||
|
||||
List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB());
|
||||
SchematicNode schem = publics.get(random.nextInt(publics.size()));
|
||||
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)));
|
||||
timedStart = new ArrayList<>(Collections.singletonList(new TimedVector(420L, new Vector(21, 15, 24))));
|
||||
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, 27,5,9, 27,6,9, 27,7,9, 27,8,9)
|
||||
));
|
||||
assignWater(clipboard);
|
||||
chooseCannon();
|
||||
|
||||
return schem;
|
||||
@ -81,14 +98,33 @@ public class LixfelAI extends AI {
|
||||
ensureInRange(currentCannon.tnt.keySet().iterator().next());
|
||||
break;
|
||||
case RUNNING:
|
||||
while(currentCannon.shoot())
|
||||
chooseCannon(); //TODO prevent endless loop
|
||||
while(currentCannon.shoot() && chooseCannon() && scanEnemy()) {}
|
||||
break;
|
||||
default:
|
||||
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() {
|
||||
return doWith(setup, this::interact);
|
||||
}
|
||||
@ -100,12 +136,12 @@ public class LixfelAI extends AI {
|
||||
|
||||
private boolean start() {
|
||||
if(preRunningStart == 0)
|
||||
preRunningStart = Config.world.getFullTime();
|
||||
preRunningStart = currentTime;
|
||||
|
||||
if(timedStart.isEmpty())
|
||||
return true;
|
||||
|
||||
long time = Config.world.getFullTime() - preRunningStart;
|
||||
long time = currentTime - preRunningStart;
|
||||
TimedVector vector = timedStart.get(0);
|
||||
if(!ensureInRange(vector.vector))
|
||||
return false;
|
||||
@ -118,8 +154,13 @@ public class LixfelAI extends AI {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void chooseCannon() {
|
||||
currentCannon = cannons.get(random.nextInt(cannons.size()));
|
||||
private boolean chooseCannon() {
|
||||
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) {
|
||||
@ -141,14 +182,19 @@ public class LixfelAI extends AI {
|
||||
if(path.isEmpty())
|
||||
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));
|
||||
return false;
|
||||
}
|
||||
|
||||
private class Cannon {
|
||||
private final List<Vector> water = new ArrayList<>();
|
||||
private final Vector activator;
|
||||
private final Map<Vector, Boolean> tnt = new HashMap<>();
|
||||
private long freeAt;
|
||||
private int freeAt;
|
||||
private int lastCannonCheck = -1;
|
||||
|
||||
public Cannon(Vector activator, int... tntpos) {
|
||||
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() {
|
||||
if(Config.world.getFullTime() < freeAt)
|
||||
if(currentTime < freeAt || water.isEmpty())
|
||||
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()) {
|
||||
if(!entry.getValue()) {
|
||||
if(ensureInRange(entry.getKey())) {
|
||||
@ -179,7 +251,7 @@ public class LixfelAI extends AI {
|
||||
interact(activator);
|
||||
}
|
||||
|
||||
freeAt = Config.world.getFullTime() + 80;
|
||||
freeAt = currentTime + 80;
|
||||
for(Map.Entry<Vector, Boolean> entry : tnt.entrySet())
|
||||
entry.setValue(false);
|
||||
|
||||
|
@ -25,15 +25,12 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.utils.WorldeditWrapper;
|
||||
import de.steamwar.sql.SchematicData;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Banner;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.*;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -75,19 +72,27 @@ public class LixfelPathplanner {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
private static Vector toBukkit(BlockVector3 vector, double height) {
|
||||
return new Vector(vector.getX() + 0.5, vector.getY() + height, vector.getZ() + 0.5);
|
||||
private static Vector toBukkit(BlockVector3 vector, double offset, double height) {
|
||||
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 Map<Vector, Vector[]> neighbours = new HashMap<>();
|
||||
|
||||
public LixfelPathplanner(SchematicNode schem) {
|
||||
try {
|
||||
fillWalkable(new SchematicData(schem).load());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
public LixfelPathplanner(Clipboard clipboard) {
|
||||
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));
|
||||
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() {
|
||||
@ -95,12 +100,6 @@ public class LixfelPathplanner {
|
||||
}
|
||||
|
||||
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();
|
||||
clipboard.getRegion().forEach(vector -> {
|
||||
BlockVector3 below = vector.subtract(0, 1, 0);
|
||||
@ -121,7 +120,7 @@ public class LixfelPathplanner {
|
||||
if(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) {
|
||||
|
@ -19,21 +19,24 @@
|
||||
|
||||
package de.steamwar.fightsystem.ai.chaos;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.ai.AI;
|
||||
import de.steamwar.fightsystem.ai.LixfelPathplanner;
|
||||
import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.sql.SchematicData;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class ChaosAI extends AI {
|
||||
private final LixfelPathplanner pathplanner = new LixfelPathplanner(chooseSchematic());
|
||||
private LixfelPathplanner pathplanner;
|
||||
private State state = State.PRE_PREPARE;
|
||||
private static final Cannon[] cannons = new Cannon[] {
|
||||
Cannon.DS_LEFT,
|
||||
@ -67,7 +70,16 @@ public class ChaosAI extends AI {
|
||||
|
||||
@Override
|
||||
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
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren