forked from SteamWar/SteamWar
Optimize SimulatorStabGenerator
This commit is contained in:
+1
@@ -60,6 +60,7 @@ public final class TNTPhase extends SimulatorPhase {
|
||||
|
||||
@Override
|
||||
public void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd) {
|
||||
if (count <= 0) return;
|
||||
tickStart.accept(tickOffset, new SimulatorAction(order, count) {
|
||||
@Override
|
||||
public void accept(World world) {
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum Direction {
|
||||
X(Vector::getBlockX),
|
||||
Y(Vector::getBlockY),
|
||||
Z(Vector::getBlockZ);
|
||||
|
||||
public final Function<Vector, Integer> component;
|
||||
}
|
||||
+7
-350
@@ -19,370 +19,27 @@
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.bausystem.features.tracer.TNTPoint;
|
||||
import de.steamwar.bausystem.features.tracer.Trace;
|
||||
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||
import de.steamwar.bausystem.region.Point;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.region.flags.flagvalues.ColorMode;
|
||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||
import de.steamwar.bausystem.region.utils.RegionType;
|
||||
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
public class SimulatorStabGenerator {
|
||||
|
||||
public class SimulatorStabGenerator implements Listener {
|
||||
|
||||
// Lupfstichs sind noch nicht perfekt
|
||||
// Schwenkstichs sidn noch nicht perfekt
|
||||
|
||||
private static final int MAX_RECORDINGS = 5;
|
||||
private static final Level LEVEL = Level.INFO;
|
||||
private static final int TNT_INCREASE = 10;
|
||||
private static final int MIN_BLOCK_TO_COUNT_AS_DEPTH = 20;
|
||||
|
||||
private final Map<Integer, Set<Location>> destroyedBlocksPerSlice = new HashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
if (direction == null) return;
|
||||
if (Region.getRegion(event.getEntity().getLocation()) == region) {
|
||||
event.blockList().forEach(block -> {
|
||||
if (!region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return;
|
||||
int component = direction.component.apply(block.getLocation().toVector());
|
||||
destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>())
|
||||
.add(block.getLocation());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private final Region region;
|
||||
private final Simulator simulator;
|
||||
private final TNTElement tntElement;
|
||||
private final List<TNTPhase> phases;
|
||||
private final int depthLimit;
|
||||
|
||||
private Clipboard clipboard;
|
||||
private boolean cancel = false;
|
||||
|
||||
private Direction direction = null;
|
||||
private final StabData stabData;
|
||||
|
||||
public SimulatorStabGenerator(Region region, Simulator simulator, TNTElement tntElement, int depthLimit) {
|
||||
this.region = region;
|
||||
this.simulator = simulator;
|
||||
this.tntElement = tntElement;
|
||||
this.phases = tntElement.getPhases();
|
||||
this.depthLimit = depthLimit;
|
||||
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
TNTPhase tntPhase = simulator.getGroups().stream()
|
||||
.filter(simulatorGroup -> !simulatorGroup.isDisabled())
|
||||
.map(SimulatorGroup::getElements)
|
||||
.flatMap(List::stream)
|
||||
.filter(TNTElement.class::isInstance)
|
||||
.map(TNTElement.class::cast)
|
||||
.filter(tntElement -> !tntElement.isDisabled())
|
||||
.filter(tntElement -> this.tntElement != tntElement)
|
||||
.map(tntElement -> tntElement.getPhases().stream().max(Comparator.comparingInt(TNTPhase::getTickOffset)))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.filter(phase -> phase != phases.get(0))
|
||||
.max(Comparator.comparingInt(TNTPhase::getTickOffset))
|
||||
.orElse(null);
|
||||
if (tntPhase == null) {
|
||||
throw new SecurityException("");
|
||||
}
|
||||
|
||||
TNTPhase phase = phases.get(0);
|
||||
phases.clear();
|
||||
phases.add(phase);
|
||||
phase.setCount(1);
|
||||
phase.setTickOffset(tntPhase.getTickOffset());
|
||||
phase.setOrder(100);
|
||||
|
||||
TraceRecorder.instance.stopRecording(region);
|
||||
if (TraceRecorder.instance.isAutoTraceEnabledInRegion(region)) {
|
||||
TraceRecorder.instance.removeAutoTraceRegion(region);
|
||||
}
|
||||
clipboard = FlatteningWrapper.impl.copy(region.getMinPointTestblockExtension(), region.getMaxPointTestblockExtension(), region.getTestBlockPoint());
|
||||
|
||||
getDirection();
|
||||
}
|
||||
|
||||
private BlockVector3 toBlockVector3(Point point) {
|
||||
return BlockVector3.at(point.getX(), point.getY(), point.getZ());
|
||||
}
|
||||
|
||||
private void getDirection() {
|
||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
|
||||
e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(toBlockVector3(region.getMinPointTestblockExtension()), toBlockVector3(region.getMaxPointTestblockExtension())), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
||||
}
|
||||
|
||||
showBossbar(false);
|
||||
|
||||
Trace trace = TraceRecorder.instance.startRecording(region);
|
||||
SimulatorExecutor.run(simulator, () -> {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
TraceRecorder.instance.stopRecording(region);
|
||||
calculateDirection(trace);
|
||||
}, 20);
|
||||
});
|
||||
}
|
||||
|
||||
private void calculateDirection(Trace trace) {
|
||||
long tickSinceStart = -1;
|
||||
List<TNTPoint> points = null;
|
||||
for (List<TNTPoint> current : trace.getHistories()) {
|
||||
long ticks = current.get(0).getTicksSinceStart();
|
||||
if (points == null || ticks > tickSinceStart) {
|
||||
tickSinceStart = ticks;
|
||||
points = current;
|
||||
} else if (ticks == tickSinceStart && points.get(0).getTntId() < current.get(0).getTntId()) {
|
||||
points = current;
|
||||
}
|
||||
}
|
||||
TraceManager.instance.remove(trace);
|
||||
if (points == null) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
TNTPoint current = points.getLast();
|
||||
Vector velocity = current.getVelocity();
|
||||
if (velocity.getX() < 0) velocity.setX(-velocity.getX());
|
||||
if (velocity.getY() < 0) velocity.setY(-velocity.getY());
|
||||
if (velocity.getZ() < 0) velocity.setZ(-velocity.getZ());
|
||||
if (velocity.getX() > velocity.getY() && velocity.getX() > velocity.getZ()) {
|
||||
direction = Direction.X;
|
||||
} else if (velocity.getY() > velocity.getX() && velocity.getY() > velocity.getZ()) {
|
||||
direction = Direction.Y;
|
||||
} else if (velocity.getZ() > velocity.getX() && velocity.getZ() > velocity.getY()) {
|
||||
direction = Direction.Z;
|
||||
} else {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getLogger().log(LEVEL, "Direction: {0}", direction);
|
||||
phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT);
|
||||
phases.getFirst().setCount(TNT_INCREASE);
|
||||
destroyedBlocksPerSlice.clear();
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
|
||||
getStab();
|
||||
}, 20);
|
||||
}
|
||||
|
||||
private void getStab() {
|
||||
try {
|
||||
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(clipboard);
|
||||
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider)
|
||||
.color(region.getPlain(Flag.COLOR, ColorMode.class).getColor());
|
||||
region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION);
|
||||
} catch (SecurityException e) {
|
||||
stop();
|
||||
throw e;
|
||||
}
|
||||
if (cancel) return;
|
||||
|
||||
showBossbar(false);
|
||||
|
||||
SimulatorExecutor.run(simulator, () -> {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::calculateStep, 20);
|
||||
});
|
||||
}
|
||||
|
||||
private int recordings = 0;
|
||||
private List<Integer> currentDepths = new ArrayList<>();
|
||||
private int lastDepth = 0;
|
||||
private int currentDepth = 0;
|
||||
|
||||
private void calculateStep() {
|
||||
List<Map.Entry<Integer, Set<Location>>> locations = destroyedBlocksPerSlice.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(Map.Entry::getKey))
|
||||
.collect(Collectors.toList());
|
||||
int depth = 0;
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
if (i == 0 || i == locations.size() - 1) {
|
||||
if (locations.get(i).getValue().size() > MIN_BLOCK_TO_COUNT_AS_DEPTH) {
|
||||
depth++;
|
||||
}
|
||||
} else {
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
if (depth > 0) {
|
||||
Bukkit.getLogger().log(LEVEL, "{0} {1} {2}", new Object[]{depth, destroyedBlocksPerSlice.size(), destroyedBlocksPerSlice.values().stream().map(Set::size).collect(Collectors.toList())});
|
||||
currentDepths.add(depth);
|
||||
}
|
||||
destroyedBlocksPerSlice.clear();
|
||||
|
||||
int maxDepth = currentDepths.stream().max(Integer::compareTo).orElse(0);
|
||||
currentDepth = maxDepth;
|
||||
|
||||
int countWithoutLast = 0;
|
||||
for (int i = 0; i < phases.size() - 1; i++) {
|
||||
countWithoutLast += phases.get(i).getCount();
|
||||
}
|
||||
|
||||
TNTPhase lastPhase = phases.getLast();
|
||||
boolean moreTNTNeeded = maxDepth - countWithoutLast >= lastPhase.getCount() - 5;
|
||||
if (!currentDepths.isEmpty() && moreTNTNeeded) {
|
||||
Bukkit.getLogger().log(LEVEL, "Increasing tnt count by {0}", TNT_INCREASE);
|
||||
lastPhase.setCount(lastPhase.getCount() + TNT_INCREASE);
|
||||
recordings = 0;
|
||||
currentDepths.clear();
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20);
|
||||
return;
|
||||
}
|
||||
|
||||
if (recordings++ < MAX_RECORDINGS) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20);
|
||||
return;
|
||||
}
|
||||
|
||||
recordings = 0;
|
||||
if (currentDepths.isEmpty()) {
|
||||
Bukkit.getLogger().log(LEVEL, "No dimension - Increasing tickOffset to: {0}", phases.getFirst().getTickOffset() + 1);
|
||||
phases.getFirst().setTickOffset(phases.getFirst().getTickOffset() + 1);
|
||||
phases.getFirst().setOrder(0);
|
||||
if (phases.getFirst().getTickOffset() > 80) {
|
||||
stop();
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
currentDepths.clear();
|
||||
|
||||
Bukkit.getLogger().log(LEVEL, "No more TNT needed on phase adjusting - {0} new depth; {1} current count", new Object[]{maxDepth - countWithoutLast, lastPhase.getCount()});
|
||||
lastPhase.setCount(maxDepth - countWithoutLast);
|
||||
if (lastPhase.getCount() <= 0) {
|
||||
Bukkit.getLogger().log(LEVEL, "Count was 0 or negative - removing last phase");
|
||||
phases.removeLast();
|
||||
}
|
||||
|
||||
if (maxDepth > depthLimit) {
|
||||
Bukkit.getLogger().log(LEVEL, "Depth is greater than {0} - finished", depthLimit);
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
if (maxDepth <= lastDepth) {
|
||||
Bukkit.getLogger().log(LEVEL, "Depth is equal to last depth recorded {0} - finished", maxDepth);
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
lastDepth = maxDepth;
|
||||
|
||||
Bukkit.getLogger().log(LEVEL, "Adding new phase in next tick");
|
||||
TNTPhase nextPhase = new TNTPhase();
|
||||
nextPhase.setCount(TNT_INCREASE);
|
||||
nextPhase.setTickOffset(lastPhase.getTickOffset() + 1);
|
||||
nextPhase.setXJump(lastPhase.isXJump());
|
||||
nextPhase.setYJump(lastPhase.isYJump());
|
||||
nextPhase.setZJump(lastPhase.isZJump());
|
||||
phases.add(nextPhase);
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private enum Direction {
|
||||
X(Vector::getBlockX),
|
||||
Y(Vector::getBlockY),
|
||||
Z(Vector::getBlockZ);
|
||||
|
||||
private final Function<Vector, Integer> component;
|
||||
}
|
||||
|
||||
private void showBossbar(boolean finished) {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BauSystemBossbar bossbar = BossBarService.instance.get(player, region, "simulator_stab_generator");
|
||||
bossbar.setColor(BarColor.GREEN);
|
||||
bossbar.setStyle(BarStyle.SEGMENTED_10);
|
||||
bossbar.setProgress(Math.min(currentDepth / (double) depthLimit, 1.0));
|
||||
StringBuilder st = new StringBuilder();
|
||||
|
||||
if (finished) {
|
||||
st.append("§eFinished ").append(currentDepth).append("§8/§7").append(depthLimit);
|
||||
} else if (direction == null) {
|
||||
st.append("§eCalculating Stab Direction");
|
||||
} else {
|
||||
st.append("§7Direction§7 §e" + direction);
|
||||
st.append(" §e").append(currentDepth).append("§8/§7").append(depthLimit);
|
||||
if (recordings > 0) {
|
||||
st.append(" §7Retries§8:§e ").append(recordings).append("§8/§7").append(MAX_RECORDINGS);
|
||||
}
|
||||
}
|
||||
|
||||
bossbar.setTitle(st.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void stop() {
|
||||
simulator.setStabGenerator(null);
|
||||
SimulatorWatcher.update(simulator);
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
showBossbar(true);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(4000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BossBarService.instance.remove(player, region, "simulator_stab_generator");
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
stabData = new StabData(region, simulator, tntElement, tntElement.getPhases(), depthLimit);
|
||||
new StabSetup(stabData);
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
cancel = true;
|
||||
simulator.setStabGenerator(null);
|
||||
stabData.cancel = true;
|
||||
stabData.simulator.setStabGenerator(null);
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BossBarService.instance.remove(player, region, "simulator_stab_generator");
|
||||
BossBarService.instance.remove(player, stabData.region, "simulator_stab_generator");
|
||||
}
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
}
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class StabData {
|
||||
|
||||
protected static final int MAX_RECORDINGS = 5;
|
||||
protected static final int MAX_TICK_DIFFERENCE = 3;
|
||||
protected static final Level LEVEL = Level.INFO;
|
||||
protected static final int TNT_INCREASE = 10;
|
||||
protected static final int MIN_BLOCK_TO_COUNT_AS_DEPTH = 20;
|
||||
|
||||
protected final Region region;
|
||||
protected final Simulator simulator;
|
||||
protected final TNTElement tntElement;
|
||||
protected final List<TNTPhase> phases;
|
||||
protected final int depthLimit;
|
||||
|
||||
protected Clipboard clipboard;
|
||||
protected boolean cancel = false;
|
||||
|
||||
protected Direction direction = null;
|
||||
protected int currentDepth = 0;
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
||||
import de.steamwar.bausystem.features.tracer.TNTPoint;
|
||||
import de.steamwar.bausystem.features.tracer.Trace;
|
||||
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class StabDirection extends StabStep {
|
||||
|
||||
public StabDirection(StabData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
|
||||
e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(data.region.getMinPointTestblockExtension().toBlockVector3(), data.region.getMaxPointTestblockExtension().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
||||
}
|
||||
|
||||
Trace trace = TraceRecorder.instance.startRecording(data.region);
|
||||
runSimulator(() -> {
|
||||
TraceRecorder.instance.stopRecording(data.region);
|
||||
calculateDirection(trace);
|
||||
});
|
||||
}
|
||||
|
||||
private void calculateDirection(Trace trace) {
|
||||
long tickSinceStart = -1;
|
||||
List<TNTPoint> points = null;
|
||||
for (List<TNTPoint> current : trace.getHistories()) {
|
||||
long ticks = current.get(0).getTicksSinceStart();
|
||||
if (points == null || ticks > tickSinceStart) {
|
||||
tickSinceStart = ticks;
|
||||
points = current;
|
||||
} else if (ticks == tickSinceStart && points.get(0).getTntId() < current.get(0).getTntId()) {
|
||||
points = current;
|
||||
}
|
||||
}
|
||||
TraceManager.instance.remove(trace);
|
||||
if (points == null) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
TNTPoint current = points.getLast();
|
||||
Vector velocity = current.getVelocity();
|
||||
if (velocity.getX() < 0) velocity.setX(-velocity.getX());
|
||||
if (velocity.getY() < 0) velocity.setY(-velocity.getY());
|
||||
if (velocity.getZ() < 0) velocity.setZ(-velocity.getZ());
|
||||
if (velocity.getX() > velocity.getY() && velocity.getX() > velocity.getZ()) {
|
||||
data.direction = Direction.X;
|
||||
} else if (velocity.getY() > velocity.getX() && velocity.getY() > velocity.getZ()) {
|
||||
data.direction = Direction.Y;
|
||||
} else if (velocity.getZ() > velocity.getX() && velocity.getZ() > velocity.getY()) {
|
||||
data.direction = Direction.Z;
|
||||
} else {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Direction: {0}", data.direction);
|
||||
data.phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT);
|
||||
data.phases.getFirst().setCount(StabData.TNT_INCREASE);
|
||||
new StabGenerator(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
|
||||
bossbar.setProgress(0);
|
||||
bossbar.setTitle("§eCalculating Stab Direction");
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.features.tracer.Trace;
|
||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.region.flags.flagvalues.ColorMode;
|
||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||
import de.steamwar.bausystem.region.utils.RegionType;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
|
||||
public class StabFinalizer extends StabStep {
|
||||
|
||||
public StabFinalizer(StabData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
try {
|
||||
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
|
||||
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider)
|
||||
.color(data.region.getPlain(Flag.COLOR, ColorMode.class).getColor());
|
||||
data.region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION);
|
||||
} catch (SecurityException e) {
|
||||
stop();
|
||||
throw e;
|
||||
}
|
||||
|
||||
TraceRecorder.instance.startRecording(data.region);
|
||||
runSimulator(() -> {
|
||||
TraceRecorder.instance.stopRecording(data.region);
|
||||
stop();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bossbar(BauSystemBossbar bossbar, boolean stopped) {
|
||||
bossbar.setProgress(Math.min(data.currentDepth / (double) data.depthLimit, 1.0));
|
||||
bossbar.setTitle("§e" + data.currentDepth + "§8/§7" + data.depthLimit);
|
||||
}
|
||||
}
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.region.flags.flagvalues.ColorMode;
|
||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||
import de.steamwar.bausystem.region.utils.RegionType;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.bausystem.features.simulator.execute.Direction.Y;
|
||||
|
||||
public class StabGenerator extends StabStep implements Listener {
|
||||
|
||||
private int recordings = 0;
|
||||
private List<Integer> currentDepths = new ArrayList<>();
|
||||
private int lastDepth = 0;
|
||||
|
||||
private int retries = 0;
|
||||
|
||||
private final Map<Integer, Set<Location>> destroyedBlocksPerSlice = new HashMap<>();
|
||||
|
||||
private Set<Integer> gabStart = new HashSet<>();
|
||||
private Set<TNTPhase> failedAtLeastOnce = new HashSet<>();
|
||||
|
||||
@EventHandler
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
if (Region.getRegion(event.getEntity().getLocation()) == data.region) {
|
||||
event.blockList().forEach(block -> {
|
||||
if (!data.region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return;
|
||||
int component = data.direction.component.apply(block.getLocation().toVector());
|
||||
destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>())
|
||||
.add(block.getLocation());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public StabGenerator(StabData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
try {
|
||||
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
|
||||
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider)
|
||||
.color(data.region.getPlain(Flag.COLOR, ColorMode.class).getColor());
|
||||
data.region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION);
|
||||
} catch (SecurityException e) {
|
||||
stop();
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (data.cancel) {
|
||||
HandlerList.unregisterAll(this);
|
||||
return;
|
||||
}
|
||||
|
||||
runSimulator(this::calculateStab);
|
||||
}
|
||||
|
||||
private void calculateStab() {
|
||||
TNTPhase lastPhase = data.phases.getLast();
|
||||
|
||||
List<Map.Entry<Integer, Set<Location>>> locations = destroyedBlocksPerSlice.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(Map.Entry::getKey))
|
||||
.collect(Collectors.toList());
|
||||
int depth = 0;
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
if (data.direction != Y && i > 0 && Math.abs(locations.get(i - 1).getKey() - locations.get(i).getKey()) > 3) {
|
||||
if (gabStart.add(locations.get(i).getKey())) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Increasing tnt count by {0} because of gap", StabData.TNT_INCREASE);
|
||||
lastPhase.setCount(lastPhase.getCount() + StabData.TNT_INCREASE);
|
||||
recordings = 0;
|
||||
currentDepths.clear();
|
||||
|
||||
run();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (i == 0 || i == locations.size() - 1) {
|
||||
if (locations.get(i).getValue().size() > StabData.MIN_BLOCK_TO_COUNT_AS_DEPTH) {
|
||||
depth++;
|
||||
}
|
||||
} else {
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
if (depth > 0) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "{0} {1} {2}", new Object[]{depth, destroyedBlocksPerSlice.size(), destroyedBlocksPerSlice.values().stream().map(Set::size).collect(Collectors.toList())});
|
||||
destroyedBlocksPerSlice.clear();
|
||||
currentDepths.add(depth);
|
||||
} else {
|
||||
destroyedBlocksPerSlice.clear();
|
||||
lastPhase.setTickOffset(lastPhase.getTickOffset() + 1);
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "No dimension - Increasing tickOffset to: {0}", lastPhase.getTickOffset());
|
||||
lastPhase.setOrder(0);
|
||||
if (lastPhase.getTickOffset() > 80) {
|
||||
stop();
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int minDepth = currentDepths.stream().min(Integer::compareTo).orElse(0);
|
||||
int maxDepth = currentDepths.stream().max(Integer::compareTo).orElse(0);
|
||||
data.currentDepth = maxDepth;
|
||||
|
||||
int countWithoutLast = 0;
|
||||
for (int i = 0; i < data.phases.size() - 1; i++) {
|
||||
countWithoutLast += data.phases.get(i).getCount();
|
||||
}
|
||||
countWithoutLast -= gabStart.size();
|
||||
|
||||
boolean moreTNTNeeded = maxDepth - countWithoutLast >= lastPhase.getCount() - 5;
|
||||
if (moreTNTNeeded) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Increasing tnt count by {0}", StabData.TNT_INCREASE);
|
||||
lastPhase.setCount(lastPhase.getCount() + StabData.TNT_INCREASE);
|
||||
recordings = 0;
|
||||
currentDepths.clear();
|
||||
|
||||
run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (recordings++ < StabData.MAX_RECORDINGS) {
|
||||
run();
|
||||
return;
|
||||
}
|
||||
|
||||
recordings = 0;
|
||||
currentDepths.clear();
|
||||
|
||||
if (maxDepth - minDepth > lastPhase.getCount()) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Stab failed at least once. Adding one tnt to {0}", minDepth - 3);
|
||||
int current = 0;
|
||||
TNTPhase last = null;
|
||||
for (TNTPhase phase : data.phases) {
|
||||
if (current < minDepth - 3) {
|
||||
current += phase.getCount();
|
||||
last = phase;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (failedAtLeastOnce.add(last)) {
|
||||
last = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (last != null) {
|
||||
last.setCount(last.getCount() + 1);
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Added to phase {0} now has {1} tnt", new Object[]{data.phases.indexOf(last), last.getCount()});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (last != null) {
|
||||
run();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "No more TNT needed on phase adjusting - {0} new count; {1} current count", new Object[]{maxDepth - countWithoutLast, lastPhase.getCount()});
|
||||
lastPhase.setCount(maxDepth - countWithoutLast);
|
||||
if (lastPhase.getCount() <= 0) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Count was 0 or negative - removing last phase");
|
||||
data.phases.removeLast();
|
||||
}
|
||||
|
||||
if (maxDepth > data.depthLimit) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Depth is greater than {0} - finished", data.depthLimit);
|
||||
new StabFinalizer(data);
|
||||
return;
|
||||
}
|
||||
if (maxDepth <= lastDepth) {
|
||||
if (lastPhase.getCount() <= 0) {
|
||||
retries++;
|
||||
}
|
||||
if (lastPhase.getCount() > 0 || retries > StabData.MAX_TICK_DIFFERENCE) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Depth is equal to last depth recorded {0} - finished", maxDepth);
|
||||
new StabFinalizer(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
lastDepth = maxDepth;
|
||||
|
||||
newPhase(data, lastPhase);
|
||||
run();
|
||||
}
|
||||
|
||||
public static void newPhase(StabData data, TNTPhase lastPhase) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Adding new phase in next tick");
|
||||
TNTPhase nextPhase = new TNTPhase();
|
||||
nextPhase.setCount(StabData.TNT_INCREASE);
|
||||
nextPhase.setTickOffset(lastPhase.getTickOffset() + 1);
|
||||
nextPhase.setXJump(lastPhase.isXJump());
|
||||
nextPhase.setYJump(lastPhase.isYJump());
|
||||
nextPhase.setZJump(lastPhase.isZJump());
|
||||
data.phases.add(nextPhase);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
|
||||
bossbar.setProgress(Math.min(data.currentDepth / (double) data.depthLimit, 1.0));
|
||||
if (finished) {
|
||||
bossbar.setTitle("§e" + data.currentDepth + "§8/§7" + data.depthLimit);
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder st = new StringBuilder();
|
||||
st.append("§7Direction §e").append(data.direction);
|
||||
st.append(" §e").append(data.currentDepth).append("§8/§7").append(data.depthLimit);
|
||||
if (recordings > 0) {
|
||||
st.append(" §7Retries§8:§e ").append(recordings).append("§8/§7").append(StabData.MAX_RECORDINGS);
|
||||
}
|
||||
bossbar.setTitle(st.toString());
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class StabSetup extends StabStep {
|
||||
|
||||
public StabSetup(StabData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
TNTPhase tntPhase = data.simulator.getGroups().stream()
|
||||
.filter(simulatorGroup -> !simulatorGroup.isDisabled())
|
||||
.map(SimulatorGroup::getElements)
|
||||
.flatMap(List::stream)
|
||||
.filter(TNTElement.class::isInstance)
|
||||
.map(TNTElement.class::cast)
|
||||
.filter(tntElement -> !tntElement.isDisabled())
|
||||
.filter(tntElement -> data.tntElement != tntElement)
|
||||
.map(tntElement -> tntElement.getPhases().stream().max(Comparator.comparingInt(TNTPhase::getTickOffset)))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.peek(phase -> {
|
||||
if (phase.getOrder() > TNTPhase.ORDER_LIMIT) {
|
||||
phase.setOrder(TNTPhase.ORDER_LIMIT);
|
||||
}
|
||||
})
|
||||
.filter(phase -> phase != data.phases.get(0))
|
||||
.max(Comparator.comparingInt(TNTPhase::getTickOffset))
|
||||
.orElse(null);
|
||||
if (tntPhase == null) {
|
||||
throw new SecurityException("");
|
||||
}
|
||||
|
||||
TNTPhase phase = data.phases.get(0);
|
||||
data.phases.clear();
|
||||
data.phases.add(phase);
|
||||
phase.setCount(1);
|
||||
phase.setTickOffset(tntPhase.getTickOffset());
|
||||
phase.setOrder(100);
|
||||
|
||||
TraceRecorder.instance.stopRecording(data.region);
|
||||
if (TraceRecorder.instance.isAutoTraceEnabledInRegion(data.region)) {
|
||||
TraceRecorder.instance.removeAutoTraceRegion(data.region);
|
||||
}
|
||||
data.clipboard = FlatteningWrapper.impl.copy(data.region.getMinPointTestblockExtension(), data.region.getMaxPointTestblockExtension(), data.region.getTestBlockPoint());
|
||||
|
||||
new StabDirection(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
|
||||
bossbar.setProgress(0);
|
||||
bossbar.setTitle("§eSetting up Simulator");
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public abstract class StabStep {
|
||||
|
||||
protected final StabData data;
|
||||
|
||||
protected StabStep(StabData data) {
|
||||
this.data = data;
|
||||
run();
|
||||
}
|
||||
|
||||
protected final void run() {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BauSystemBossbar bossbar = BossBarService.instance.get(player, data.region, "simulator_stab_generator");
|
||||
bossbar.setColor(BarColor.GREEN);
|
||||
bossbar.setStyle(BarStyle.SEGMENTED_10);
|
||||
bossbar(bossbar, false);
|
||||
}
|
||||
}, 1);
|
||||
|
||||
if (this instanceof Listener) {
|
||||
Bukkit.getPluginManager().registerEvents((Listener) this, BauSystem.getInstance());
|
||||
}
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::start, 20);
|
||||
}
|
||||
|
||||
protected abstract void start();
|
||||
|
||||
protected final void runSimulator(Runnable onFinish) {
|
||||
SimulatorExecutor.run(data.simulator, () -> {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
if (this instanceof Listener) {
|
||||
HandlerList.unregisterAll((Listener) this);
|
||||
}
|
||||
onFinish.run();
|
||||
}, 20);
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void bossbar(BauSystemBossbar bossbar, boolean stopped);
|
||||
|
||||
protected final void stop() {
|
||||
data.simulator.setStabGenerator(null);
|
||||
SimulatorWatcher.update(data.simulator);
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BauSystemBossbar bossbar = BossBarService.instance.get(player, data.region, "simulator_stab_generator");
|
||||
bossbar.setColor(BarColor.GREEN);
|
||||
bossbar.setStyle(BarStyle.SEGMENTED_10);
|
||||
bossbar(bossbar, true);
|
||||
}
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(4000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BossBarService.instance.remove(player, data.region, "simulator_stab_generator");
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -73,4 +73,8 @@ public class Point {
|
||||
public Location toLocation(Player player, double dx, double dy, double dz) {
|
||||
return new Location(player.getWorld(), x + dx, y + dy, z + dz, player.getLocation().getYaw(), player.getLocation().getPitch());
|
||||
}
|
||||
|
||||
public BlockVector3 toBlockVector3() {
|
||||
return BlockVector3.at(this.x, this.y, this.z);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user