Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Ursprung
21ee580c0f
Commit
3b6cde085d
FightSystem_Core/src/de/steamwar/fightsystem/ai
@ -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());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren