SimRework2.0 #216

Zusammengeführt
YoyoNow hat 49 Commits von SimRework2.0 nach master 2023-12-16 12:30:57 +01:00 zusammengeführt
67 geänderte Dateien mit 4229 neuen und 2636 gelöschten Zeilen

Datei anzeigen

@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
sourceSets {
main {

Datei anzeigen

@ -0,0 +1,23 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils;
public class TickListener15 implements TickListener {
}

Datei anzeigen

@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
sourceSets {
main {

Datei anzeigen

@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
sourceSets {
main {
@ -51,6 +51,7 @@ dependencies {
implementation project(":BauSystem_Main")
compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT'
compileOnly 'io.papermc.paper:paper-api:1.19.2-R0.1-SNAPSHOT'
compileOnly 'it.unimi.dsi:fastutil:8.5.6'
compileOnly 'com.mojang:datafixerupper:4.0.26'
compileOnly 'io.netty:netty-all:4.1.68.Final'

Datei anzeigen

@ -0,0 +1,51 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils;
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
import com.destroystokyo.paper.event.server.ServerTickStartEvent;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class TickListener19 implements TickListener, Listener {
private boolean tickStartRan = false;
public TickListener19() {
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
}
@EventHandler
public void onServerTickStart(ServerTickStartEvent event) {
if (TPSFreezeUtils.isFrozen()) return;
Bukkit.getPluginManager().callEvent(new TickStartEvent());
tickStartRan = true;
}
@EventHandler
public void onServerTickEnd(ServerTickEndEvent event) {
if (!tickStartRan) return;
Bukkit.getPluginManager().callEvent(new TickEndEvent());
tickStartRan = false;
}
}

Datei anzeigen

@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
sourceSets {
main {

Datei anzeigen

@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
sourceSets {
main {

Datei anzeigen

@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
sourceSets {
main {

Datei anzeigen

@ -313,6 +313,7 @@ SIMULATOR_GUI_CREATE_SIM = §eCreate simulator
SIMULATOR_GUI_CREATE_SIM_GUI = Create simulator
SIMULATOR_NAME_ALREADY_EXISTS = §cSimulator already exists
SIMULATOR_NAME_INVALID = §cInvalid name
SIMULATOR_ERROR_COPY = §cCopy failed
SIMULATOR_NOT_EXISTS = §cSimulator does not exist
SIMULATOR_CREATE = §aSimulator created
SIMULATOR_EDIT_LOCATION = §7Edit position
@ -328,7 +329,7 @@ SIMULATOR_WAND_LORE_1 = §eRight click §8- §7Adds a position
SIMULATOR_WAND_LORE_2 = §eSneaking §8- §7Free movement
SIMULATOR_WAND_LORE_3 = §eLeft click §8- §7Start the simulation
SIMULATOR_WAND_LORE_4 = §eRight click in air §8- §7Opens the gui
SIMULATOR_WAND_LORE_5 = §eOffhand §8- §7Simulator preview
SIMULATOR_WAND_LORE_5 = §eDouble Sneak §8- §7Swap between TNT and Redstone Block
SIMULATOR_REGION_FROZEN = §cSimulator cannot be used inside frozen regions

Datei anzeigen

@ -305,6 +305,7 @@ SIMULATOR_GUI_CREATE_SIM = §eSimulator erstellen
SIMULATOR_GUI_CREATE_SIM_GUI = Simulator erstellen
SIMULATOR_NAME_ALREADY_EXISTS = §cSimulator existiert bereits
SIMULATOR_NAME_INVALID = §cUngültiger Name
SIMULATOR_ERROR_COPY = §cFehler beim kopieren
SIMULATOR_NOT_EXISTS = §cSimulator existiert nicht
SIMULATOR_CREATE = §aSimulator erstellt
SIMULATOR_EDIT_LOCATION = §7Editiere Positionen
@ -320,7 +321,7 @@ SIMULATOR_WAND_LORE_1 = §eRechtsklick §8- §7Füge eine Position hinzu
SIMULATOR_WAND_LORE_2 = §eSneaken §8- §7Freie Bewegung
SIMULATOR_WAND_LORE_3 = §eLinksklick §8- §7Starte die Simulation
SIMULATOR_WAND_LORE_4 = §eRechtsklick Luft §8- §7Öffne die GUI
SIMULATOR_WAND_LORE_5 = §eOffhand §8- §7Simulator Vorschau
SIMULATOR_WAND_LORE_5 = §eDoppel Shift §8- §7Wechsel zwischen TNT und Redstone Block
SIMULATOR_REGION_FROZEN = §cSimulator kann nicht in eingefrorenen Regionen genutzt werden

Datei anzeigen

@ -27,11 +27,11 @@ import de.steamwar.bausystem.linkage.LinkageUtils;
import de.steamwar.bausystem.region.loader.PrototypeLoader;
import de.steamwar.bausystem.region.loader.RegionLoader;
import de.steamwar.bausystem.region.loader.Updater;
import de.steamwar.bausystem.utils.TickListener;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.message.Message;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
@ -53,12 +53,8 @@ public class BauSystem extends JavaPlugin implements Listener {
@Getter
private static BauSystem instance;
private World world;
@Override
public void onEnable() {
world = Bukkit.getWorlds().get(0);
// LOGGER
fixLogging();
@ -81,6 +77,7 @@ public class BauSystem extends JavaPlugin implements Listener {
LinkageUtils.link();
RamUsage.init();
TickListener.impl.init();
// This could disable any watchdog stuff. We need to investigate if this is a problem.
/*

Datei anzeigen

@ -1,92 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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;
import de.steamwar.bausystem.BauSystem;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@UtilityClass
public class OrderUtils {
private final List<Material> activationOrder = new ArrayList<>();
private final Map<Material, String> nameMap = new HashMap<>();
static {
add(Material.REPEATER, "SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_REPEATER");
add(Material.OBSERVER, "SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_OBSERVER");
add(Material.COMPARATOR, "SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_COMPARATOR");
}
public Material next(Material material) {
int index = activationOrder.indexOf(material);
if (index == -1) {
return activationOrder.get(0);
}
if (index + 1 >= activationOrder.size()) {
return activationOrder.get(0);
}
return activationOrder.get(index + 1);
}
public Material previous(Material material) {
int index = activationOrder.indexOf(material);
if (index == -1) {
return activationOrder.get(0);
}
if (index - 1 < 0) {
return activationOrder.get(activationOrder.size() - 1);
}
return activationOrder.get(index - 1);
}
public List<String> orderList(Material material, Player player) {
List<String> lore = new ArrayList<>();
for (Material m : activationOrder) {
String element = BauSystem.MESSAGE.parse(name(m), player);
if (m == material) {
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ACTIVE", player, element));
} else {
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_INACTIVE", player, element));
}
}
return lore;
}
public int order(Material material) {
return activationOrder.indexOf(material);
}
public String name(Material material) {
return nameMap.getOrDefault(material, "SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_UNKNOWN");
}
private void add(Material material, String name) {
activationOrder.add(material);
nameMap.put(material, name);
}
}

Datei anzeigen

@ -1,60 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 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;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.linkage.specific.BauGuiItem;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@Linked
public class SimulatorBauGuiItem extends BauGuiItem {
public SimulatorBauGuiItem() {
super(20);
}
@Override
public ItemStack getItem(Player player) {
ItemStack itemStack = new SWItem(Material.BLAZE_ROD, BauSystem.MESSAGE.parse("SIMULATOR_GUI_ITEM_NAME", player)).getItemStack();
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setCustomModelData(1);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
@Override
public boolean click(ClickType click, Player p) {
p.closeInventory();
p.performCommand("sim");
return false;
}
@Override
public Permission permission() {
return Permission.WORLD;
}
}

Datei anzeigen

@ -1,20 +1,20 @@
/*
* This file is a part of the SteamWar software.
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
* 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 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.
* 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/>.
* 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;
@ -22,105 +22,78 @@ package de.steamwar.bausystem.features.simulator;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI;
import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor;
import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.command.TypeValidator;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import de.steamwar.linkage.MinVersion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
@Linked
@MinVersion(19)
public class SimulatorCommand extends SWCommand {
@LinkedInstance
public SimulatorCursor simulatorCursor;
public SimulatorCommand() {
super("simulator", "sim");
super("sim", "simulator");
}
@Register(description = "SIMULATOR_HELP")
public void genericCommand(@Validator Player p) {
SimulatorCursor.hide(p, null);
SWUtils.giveItemToPlayer(p, SimulatorStorage.getWand(p));
simulatorCursor.calcCursor(p);
}
@Register(value = "change", description = "SIMULATOR_CHANGE_HELP")
public void change(@Validator Player p) {
ItemStack itemStack = p.getInventory().getItemInMainHand();
if (!ItemUtils.isItem(itemStack, "simulator")) {
if (!SimulatorCursor.isSimulatorItem(p.getInventory().getItemInMainHand()) && !SimulatorCursor.isSimulatorItem(p.getInventory().getItemInOffHand())) {
BauSystem.MESSAGE.send("SIMULATOR_NO_SIM_IN_HAND", p);
return;
}
SimulatorSelectionGUI.open(p, itemStack);
}
@Register(value = "create", description = "SIMULATOR_CREATE_HELP")
public void create(@Validator Player p, String name) {
createSimulator(p, name);
}
public static boolean createSimulator(Player p, String name) {
if (SimulatorStorage.getSimulatorNames().contains(name)) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", p);
return false;
}
if (!name.matches("[a-zA-Z_0-9-]+")) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", p);
return false;
}
SimulatorStorage.createNewSimulator(name);
BauSystem.MESSAGE.send("SIMULATOR_CREATE", p);
return true;
}
@Register(value = "delete", description = "SIMULATOR_DELETE_HELP")
public void delete(@Validator Player p, @Mapper("simulators") String name) {
if (!SimulatorStorage.getSimulatorNames().contains(name)) {
BauSystem.MESSAGE.send("SIMULATOR_NOT_EXISTS", p);
return;
}
SimulatorStorage.delete(name);
BauSystem.MESSAGE.send("SIMULATOR_DELETED", p);
}
@Register(value = "start", description = "SIMULATOR_START_HELP")
public void start(@Validator Player p, @Mapper("simulators") String name) {
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(name);
if (tntSimulator == null) {
BauSystem.MESSAGE.send("SIMULATOR_NOT_EXISTS", p);
return;
}
tntSimulator.start(p);
SimulatorStorage.openSimulatorSelector(p);
}
@Register(value = "copy", description = "SIMULATOR_COPY_HELP")
public void copy(@Validator Player p, @Mapper("simulators") String toCopy, String name) {
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(toCopy);
if (tntSimulator == null) {
BauSystem.MESSAGE.send("SIMULATOR_NOT_EXISTS", p);
return;
}
public void copy(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator, String name) {
if (SimulatorStorage.getSimulator(name) != null) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", p);
return;
}
SimulatorStorage.copySimulator(tntSimulator, name);
if (!name.matches("[a-zA-Z_0-9-]+")) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", p);
return;
}
if (!SimulatorStorage.copy(simulator, name)) {
BauSystem.MESSAGE.send("SIMULATOR_ERROR_COPY", p);
}
}
@Mapper("simulators")
public TypeMapper<String> allSimulators() {
return new TypeMapper<String>() {
@Register(value = "delete", description = "SIMULATOR_DELETE_HELP")
public void delete(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator) {
SimulatorStorage.delete(simulator);
BauSystem.MESSAGE.send("SIMULATOR_DELETED", p);
}
@Register(value = "start", description = "SIMULATOR_START_HELP")
public void start(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator) {
SimulatorExecutor.run(simulator);
}
@ClassMapper(value = Simulator.class, local = true)
public TypeMapper<Simulator> allSimulators() {
return new TypeMapper<>() {
@Override
public String map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
if (SimulatorStorage.getSimulatorNames().contains(s)) {
return s;
} else {
return null;
}
public Simulator map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
return SimulatorStorage.getSimulator(s);
}
@Override

Datei anzeigen

@ -1,107 +1,222 @@
/*
* This file is a part of the SteamWar software.
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
* 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 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.
* 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/>.
* 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;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor;
import de.steamwar.bausystem.features.simulator.gui.SimulatorGroupGui;
import de.steamwar.bausystem.features.simulator.gui.SimulatorGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.bausystem.utils.RayTraceUtils;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
import lombok.experimental.UtilityClass;
import net.md_5.bungee.api.ChatMessageType;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
@UtilityClass
public class SimulatorCursor {
@Linked
@MinVersion(19)
public class SimulatorCursor implements Listener {
private static final World WORLD = Bukkit.getWorlds().get(0);
private Map<Player, REntityServer> rEntityServerMap = new HashMap<>();
private final World WORLD = Bukkit.getWorlds().get(0);
private Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
private Class<?> look = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInLook");
private Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
public void show(Player player, TNTSimulator tntSimulator, RayTraceUtils.RRayTraceResult result) {
REntityServer cursor = rEntityServerMap.get(player);
private Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
private Map<Player, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
if (cursor != null)
cursor.close();
tntSimulator.show(player);
if (result == null)
return;
if (result.getHitEntity() != null) {
List<SimulatorElement> elements = tntSimulator.getEntity(result.getHitEntity());
cursor = new REntityServer();
RFallingBlockEntity entity = new RFallingBlockEntity(cursor, (elements.isEmpty() ? getPos(player, result) : elements.get(0).getPosition()).toLocation(WORLD), Material.TNT);
entity.setNoGravity(true);
entity.setGlowing(true);
cursor.addPlayer(player);
rEntityServerMap.put(player, cursor);
BauSystem.MESSAGE.sendPrefixless("SIMULATOR_POSITION_EDIT", player, ChatMessageType.ACTION_BAR);
return;
}
if (SimulatorStorage.getSimulator(player.getInventory().getItemInOffHand()) != null && result.getHitPosition().distanceSquared(player.getLocation().toVector()) < 25) {
return;
}
cursor = new REntityServer();
RFallingBlockEntity entity = new RFallingBlockEntity(cursor, getPos(player, result).toLocation(WORLD), Material.TNT);
entity.setNoGravity(true);
cursor.addPlayer(player);
rEntityServerMap.put(player, cursor);
BauSystem.MESSAGE.sendPrefixless("SIMULATOR_POSITION_ADD", player, ChatMessageType.ACTION_BAR);
public static boolean isSimulatorItem(ItemStack itemStack) {
return ItemUtils.isItem(itemStack, "simulator");
}
public void hide(Player player) {
REntityServer cursor = rEntityServerMap.get(player);
if (cursor == null) return;
public SimulatorCursor() {
BiFunction<Player, Object, Object> function = (player, object) -> {
calcCursor(player);
return object;
};
TinyProtocol.instance.addFilter(position, function);
TinyProtocol.instance.addFilter(look, function);
TinyProtocol.instance.addFilter(positionLook, function);
}
cursor.close();
SimulatorStorage.getSimulatorNames().forEach(s -> {
SimulatorStorage.getSimulator(s).hide(player);
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
calcCursor(event.getPlayer());
}, 0);
}
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
calcCursor(event.getPlayer());
}
@EventHandler
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
calcCursor(event.getPlayer());
}, 1);
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
cursorType.remove(event.getPlayer());
cursors.remove(event.getPlayer());
}
private static final Map<Player, Long> LAST_SNEAKS = new HashMap<>();
static {
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
long millis = System.currentTimeMillis();
LAST_SNEAKS.entrySet().removeIf(entry -> millis - entry.getValue() > 200);
}, 1, 1);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
if (!event.isSneaking()) return;
Player player = event.getPlayer();
if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) {
return;
}
if (LAST_SNEAKS.containsKey(player)) {
cursorType.put(player, cursorType.getOrDefault(player, CursorType.TNT).switchType());
calcCursor(player);
} else {
LAST_SNEAKS.put(player, System.currentTimeMillis());
}
}
public synchronized void calcCursor(Player player) {
if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) {
if (removeCursor(player) || SimulatorWatcher.show(null, player)) {
SWUtils.sendToActionbar(player, "");
}
return;
}
Simulator simulator = SimulatorStorage.getSimulator(player);
SimulatorWatcher.show(simulator, player);
List<REntity> entities = SimulatorWatcher.getEntitiesOfSimulator(simulator);
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), entities);
if (rayTraceResult == null) {
removeCursor(player);
if (simulator == null) {
SWUtils.sendToActionbar(player, "§eSelect Simulator");
} else {
SWUtils.sendToActionbar(player, "§eOpen Simulator");
}
return;
}
showCursor(player, rayTraceResult, simulator != null);
}
private synchronized boolean removeCursor(Player player) {
REntityServer entityServer = cursors.get(player);
boolean hadCursor = entityServer != null && !entityServer.getEntities().isEmpty();
if (entityServer != null) {
entityServer.getEntities().forEach(REntity::die);
}
return hadCursor;
}
private synchronized void showCursor(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, boolean hasSimulatorSelected) {
REntityServer entityServer = cursors.computeIfAbsent(player, __ -> {
REntityServer rEntityServer = new REntityServer();
rEntityServer.addPlayer(player);
return rEntityServer;
});
}
public void hide(Player player, TNTSimulator tntSimulator) {
REntityServer cursor = rEntityServerMap.get(player);
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
REntity hitEntity = rayTraceResult.getHitEntity();
Location location = hitEntity != null ? new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(WORLD) :
type.position.apply(player, rayTraceResult).toLocation(WORLD);
if (cursor != null)
cursor.close();
if (tntSimulator != null) {
tntSimulator.hide(player);
Material material = hitEntity != null ? Material.GLASS : type.getMaterial();
List<RFallingBlockEntity> entities = entityServer.getEntitiesByType(RFallingBlockEntity.class);
entities.removeIf(rFallingBlockEntity -> {
if (rFallingBlockEntity.getMaterial() != material) {
rFallingBlockEntity.die();
return true;
}
rFallingBlockEntity.move(location);
return false;
});
if (entities.isEmpty()) {
RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(entityServer, location, material);
rFallingBlockEntity.setNoGravity(true);
if (material == Material.GLASS) {
rFallingBlockEntity.setGlowing(true);
}
}
if (hasSimulatorSelected) {
if (hitEntity != null) {
SWUtils.sendToActionbar(player, "§eEdit Position");
} else {
SWUtils.sendToActionbar(player, "§eAdd new " + type.name);
}
} else {
SWUtils.sendToActionbar(player, "§eCreate new Simulator");
}
rEntityServerMap.remove(player);
}
public static Vector getPos(Player player, RayTraceUtils.RRayTraceResult result) {
public static Vector getPosTNT(Player player, RayTraceUtils.RRayTraceResult result) {
Vector pos = result.getHitPosition();
BlockFace face = result.getHitBlockFace();
@ -140,4 +255,172 @@ public class SimulatorCursor {
return pos;
}
private static Vector getPosRedstoneBlock(Player player, RayTraceUtils.RRayTraceResult result) {
Vector pos = result.getHitPosition();
BlockFace face = result.getHitBlockFace();
if (face != null) {
switch (face) {
case DOWN:
pos.setY(pos.getY() - 0.98);
break;
case EAST:
pos.setX(pos.getX() + 0.49);
break;
case WEST:
pos.setX(pos.getX() - 0.49);
break;
case NORTH:
pos.setZ(pos.getZ() - 0.49);
break;
case SOUTH:
pos.setZ(pos.getZ() + 0.49);
break;
default:
break;
}
}
pos.setX(pos.getBlockX() + 0.5);
if (pos.getY() - pos.getBlockY() != 0 && face == BlockFace.UP) {
pos.setY(pos.getBlockY() + 1.0);
} else {
pos.setY(pos.getBlockY());
}
pos.setZ(pos.getBlockZ() + 0.5);
return pos;
}
@Getter
@AllArgsConstructor
public enum CursorType {
TNT(Material.TNT, SimulatorCursor::getPosTNT, "TNT", vector -> new TNTElement(vector).add(new TNTPhase())),
REDSTONE_BLOCK(Material.REDSTONE_BLOCK, SimulatorCursor::getPosRedstoneBlock, "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())),
;
private Material material;
private BiFunction<Player, RayTraceUtils.RRayTraceResult, Vector> position;
private String name;
private Function<Vector, SimulatorElement<?>> elementFunction;
public CursorType switchType() {
if (this == TNT) {
return REDSTONE_BLOCK;
}
return TNT;
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (!ItemUtils.isItem(event.getItem(), "simulator")) {
return;
}
event.setCancelled(true);
Player player = event.getPlayer();
Simulator simulator = SimulatorStorage.getSimulator(player);
if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) {
if (simulator == null) {
return;
}
SimulatorExecutor.run(simulator);
return;
}
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_AIR) {
return;
}
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), SimulatorWatcher.getEntitiesOfSimulator(simulator));
if (simulator == null) {
if (rayTraceResult == null) {
SimulatorStorage.openSimulatorSelector(player);
} else {
SWAnvilInv anvilInv = new SWAnvilInv(player, "Name");
anvilInv.setCallback(s -> {
Simulator sim = SimulatorStorage.getSimulator(s);
if (sim != null) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", player);
return;
}
if (!s.matches("[a-zA-Z_0-9-]+")) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", player);
return;
}
sim = new Simulator(s);
SimulatorStorage.addSimulator(s, sim);
createElement(player, rayTraceResult, sim);
SimulatorStorage.setSimulator(player, sim);
});
anvilInv.open();
}
return;
}
if (rayTraceResult == null) {
new SimulatorGui(player, simulator).open();
return;
}
if (rayTraceResult.getHitEntity() != null) {
REntity hitEntity = rayTraceResult.getHitEntity();
Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ());
List<SimulatorElement<?>> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> {
return element.getWorldPos().distanceSquared(vector) < (1 / 16.0) * (1 / 16.0);
}).collect(Collectors.toList());
switch (elements.size()) {
case 0:
return;
case 1:
// Open single element present in Simulator
SimulatorElement<?> element = elements.get(0);
SimulatorGroup group1 = element.getGroup(simulator);
SimulatorBaseGui back = new SimulatorGui(player, simulator);
if (group1.getElements().size() > 1) {
back = new SimulatorGroupGui(player, simulator, group1, back);
}
element.open(player, simulator, group1, back);
break;
default:
List<SimulatorGroup> parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList());
if (parents.size() == 1) {
// Open multi element present in Simulator in existing group
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
new SimulatorGroupGui(player, simulator, parents.get(0), simulatorGui).open();
} else {
// Open multi element present in Simulator in implicit group
SimulatorGroup group2 = new SimulatorGroup();
group2.setMaterial(null);
group2.getElements().addAll(elements);
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
new SimulatorGroupGui(player, simulator, group2, simulatorGui).open();
}
break;
}
return;
}
// Add new Element to current simulator
createElement(player, rayTraceResult, simulator);
}
private void createElement(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, Simulator simulator) {
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
Vector vector = type.position.apply(player, rayTraceResult);
if (type == CursorType.REDSTONE_BLOCK) {
vector.subtract(new Vector(0.5, 0, 0.5));
}
SimulatorElement<?> element = type.elementFunction.apply(vector);
SimulatorGroup group = new SimulatorGroup().add(element);
simulator.getGroups().add(group);
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
element.open(player, simulator, group, simulatorGui);
SimulatorWatcher.update(simulator);
calcCursor(player);
}
}

Datei anzeigen

@ -1,124 +1,170 @@
/*
* This file is a part of the SteamWar software.
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
* 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 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.
* 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/>.
* 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;
import com.google.common.io.Files;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.simulator.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui;
import de.steamwar.bausystem.features.simulator.storage.SimFormatSimulatorLoader;
import de.steamwar.bausystem.features.simulator.storage.SimulatorFormatSimulatorLoader;
import de.steamwar.bausystem.features.simulator.storage.SimulatorSaver;
import de.steamwar.bausystem.features.simulator.storage.YAPIONFormatSimulatorLoader;
import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.api.Disable;
import de.steamwar.linkage.MinVersion;
import de.steamwar.linkage.api.Enable;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import yapion.exceptions.YAPIONException;
import yapion.hierarchy.types.YAPIONArray;
import yapion.hierarchy.types.YAPIONObject;
import yapion.parser.YAPIONParser;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.*;
@Linked
public class SimulatorStorage implements Enable, Disable {
public static final World WORLD = Bukkit.getWorlds().get(0);
private static final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators");
@MinVersion(19)
public class SimulatorStorage implements Enable {
public static final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators");
private static Map<String, Simulator> simulatorMap = new HashMap<>();
private static NamespacedKey simulatorSelection = SWUtils.getNamespaceKey("simulator_selection");
private static Map<String, TNTSimulator> tntSimulators = new HashMap<>();
public static void createNewSimulator(String name) {
tntSimulators.put(name, new TNTSimulator());
}
public static Set<String> getSimulatorNames() {
return tntSimulators.keySet();
}
public static TNTSimulator getSimulator(String name) {
return tntSimulators.get(name);
}
public static TNTSimulator getSimulator(Player player) {
TNTSimulator current = getSimulator(player.getInventory().getItemInMainHand());
if (current != null) return current;
public static Simulator getSimulator(Player player) {
Simulator simulator = getSimulator(player.getInventory().getItemInMainHand());
if (simulator != null) return simulator;
return getSimulator(player.getInventory().getItemInOffHand());
}
public static TNTSimulator getSimulator(ItemStack itemStack) {
if (itemStack == null) {
return null;
}
if (!ItemUtils.isItem(itemStack, "simulator")) {
public static Simulator getSimulator(ItemStack itemStack) {
if (!SimulatorCursor.isSimulatorItem(itemStack)) {
return null;
}
String selection = ItemUtils.getTag(itemStack, simulatorSelection);
if (selection == null) {
return null;
}
return tntSimulators.get(selection);
return simulatorMap.get(selection);
}
public static void setSimulator(Player player, ItemStack itemStack, TNTSimulator simulator) {
for (Map.Entry<String, TNTSimulator> entry : tntSimulators.entrySet()) {
if (entry.getValue() == simulator) {
ItemUtils.setTag(itemStack, simulatorSelection, entry.getKey());
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setDisplayName(BauSystem.MESSAGE.parse("SIMULATOR_WAND_NAME_SELECTED", player, entry.getKey()));
itemStack.setItemMeta(itemMeta);
return;
public static Simulator getSimulator(String name) {
return simulatorMap.get(name);
}
public static void addSimulator(String name, Simulator simulator) {
simulatorMap.putIfAbsent(name, simulator);
}
@Override
public void enable() {
SimFormatSimulatorLoader simFormatSimulatorLoader = new SimFormatSimulatorLoader();
SimulatorFormatSimulatorLoader simulatorFormatSimulatorLoader = new SimulatorFormatSimulatorLoader();
YAPIONFormatSimulatorLoader yapionFormatSimulatorLoader = new YAPIONFormatSimulatorLoader();
for (File file : simulatorsDir.listFiles()) {
try {
List<Simulator> simulators = simFormatSimulatorLoader.load(file)
.orElse(null);
if (simulators != null) {
simulators.forEach(simulator -> {
simulatorMap.put(simulator.getName(), simulator);
});
continue;
}
} catch (Exception e) {
// Ignore
}
try {
List<Simulator> simulators = simulatorFormatSimulatorLoader.load(file)
.orElse(null);
if (simulators != null) {
simulators.forEach(simulator -> {
simulatorMap.put(simulator.getName(), simulator);
SimulatorSaver.saveSimulator(simulatorsDir, simulator);
});
continue;
}
} catch (Exception e) {
// Ignore
}
try {
List<Simulator> simulators = yapionFormatSimulatorLoader.load(file)
.orElse(null);
if (simulators != null) {
simulators.forEach(simulator -> {
simulatorMap.put(simulator.getName(), simulator);
SimulatorSaver.saveSimulator(simulatorsDir, simulator);
});
}
} catch (Exception e) {
// Ignore
}
}
}
public static void delete(String name) {
TNTSimulator tntSimulator = tntSimulators.remove(name);
if (tntSimulator != null) {
tntSimulator.close();
}
new File(simulatorsDir, name + ".simulator").delete();
}
public static void openSimulatorSelector(Player player) {
SimulatorPageGui<Simulator> simulatorPageGui = new SimulatorPageGui<Simulator>(player, null, 6 * 9, new ArrayList<>(simulatorMap.values())) {
@Override
public String baseTitle() {
return "Simulators";
}
public static void copySimulator(TNTSimulator tntSimulator, String name) {
tntSimulators.put(name, new TNTSimulator(tntSimulator.toYAPION()));
}
@Override
public void headerAndFooter() {
inventory.setItem(49, new SWItem(Material.NAME_TAG, "§eCreate", clickType -> {
SWAnvilInv anvilInv = new SWAnvilInv(player, "Name");
anvilInv.setCallback(s -> {
Simulator sim = SimulatorStorage.getSimulator(s);
if (sim != null) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", player);
return;
}
if (!s.matches("[a-zA-Z_0-9-]+")) {
BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", player);
return;
}
sim = new Simulator(s);
SimulatorStorage.addSimulator(s, sim);
SimulatorStorage.setSimulator(player, sim);
});
anvilInv.open();
}));
}
public static void removeSimulator(ItemStack itemStack) {
if (!ItemUtils.isItem(itemStack, "simulator")) {
return;
}
ItemUtils.setTag(itemStack, simulatorSelection, null);
@Override
public SWItem convert(Simulator simulator) {
return simulator.toItem(player, clickType -> {
setSimulator(player, simulator);
player.closeInventory();
});
}
};
simulatorPageGui.open();
}
public static ItemStack getWand(Player p) {
@ -130,68 +176,48 @@ public class SimulatorStorage implements Enable, Disable {
return itemStack;
}
@Override
public void enable() {
if (!simulatorsDir.exists()) {
simulatorsDir.mkdir();
public static void setSimulator(Player player, Simulator simulator) {
ItemStack mainHand = player.getInventory().getItemInMainHand();
ItemStack offHand = player.getInventory().getItemInOffHand();
ItemStack itemStack;
if (SimulatorCursor.isSimulatorItem(mainHand)) {
itemStack = mainHand;
} else if (SimulatorCursor.isSimulatorItem(offHand)) {
itemStack = offHand;
} else {
itemStack = null;
}
File[] files = simulatorsDir.listFiles();
if (files == null) return;
for (File file : files) {
YAPIONObject yapionObject;
try {
yapionObject = YAPIONParser.parse(file);
} catch (YAPIONException | IOException e) {
continue;
}
if (file.getName().endsWith(".yapion")) {
String name = file.getName().substring(0, file.getName().length() - 7);
try {
SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(name));
convert(file, steamwarUser);
} catch (Exception e) {
file.delete();
}
} else {
String name = file.getName().substring(0, file.getName().length() - ".simulator".length());
tntSimulators.put(name, new TNTSimulator(yapionObject));
}
}
}
private static void convert(File file, SteamwarUser steamwarUser) {
YAPIONObject yapionObject;
try {
yapionObject = YAPIONParser.parse(file);
} catch (YAPIONException | IOException e) {
if (itemStack == null) {
return;
}
try {
file.delete();
} catch (Exception e) {
e.printStackTrace();
}
for (String s : yapionObject.getKeys()) {
String newName = steamwarUser.getUserName() + (s.isEmpty() ? "" : "_" + s);
YAPIONArray content = yapionObject.getArray(s);
if (content.isEmpty()) continue;
TNTSimulator tntSimulator = new TNTSimulator();
for (YAPIONObject element : content.streamObject().collect(Collectors.toList())) {
tntSimulator.getTntElementList().add(new TNTElement(element, null, tntSimulator.getEntityServer()));
}
tntSimulators.put(newName, tntSimulator);
}
ItemUtils.setTag(itemStack, simulatorSelection, simulator.getName());
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setDisplayName(BauSystem.MESSAGE.parse("SIMULATOR_WAND_NAME_SELECTED", player, simulator.getName()));
itemStack.setItemMeta(itemMeta);
}
@Override
public void disable() {
for (Map.Entry<String, TNTSimulator> entry : tntSimulators.entrySet()) {
try {
entry.getValue().toYAPION().toFile(new File(simulatorsDir, entry.getKey() + ".simulator"));
} catch (Exception e) {
e.printStackTrace();
}
public static List<String> getSimulatorNames() {
return new ArrayList<>(simulatorMap.keySet());
}
public static void delete(Simulator simulator) {
simulatorMap.remove(simulator.getName());
new File(simulatorsDir, simulator.getName() + ".sim").delete();
}
public static boolean copy(Simulator simulator, String name) {
try {
File file = new File(simulatorsDir, name + ".sim");
Files.copy(new File(simulatorsDir, simulator.getName() + ".sim"), file);
new SimFormatSimulatorLoader().load(file).ifPresent(simulators -> {
simulators.forEach(sim -> {
simulatorMap.put(sim.getName(), sim);
});
});
return true;
} catch (IOException e) {
return false;
}
}
}

Datei anzeigen

@ -0,0 +1,129 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.storage.SimulatorSaver;
import de.steamwar.bausystem.shared.Pair;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@UtilityClass
public class SimulatorWatcher {
private final World WORLD = Bukkit.getWorlds().get(0);
private Map<Simulator, REntityServer> entityServers = new HashMap<>();
private Map<Player, Pair<Simulator, Runnable>> watchers = new HashMap<>();
public void watch(Player player, Simulator simulator, Runnable watcher) {
if (simulator == null || watcher == null) {
watchers.remove(player);
} else {
watchers.put(player, new Pair<>(simulator, watcher));
}
}
public synchronized void update(Simulator simulator) {
REntityServer rEntityServer = entityServers.get(simulator);
if (rEntityServer != null) {
rEntityServer.getEntities().forEach(REntity::die);
createSim(rEntityServer, simulator);
}
new ArrayList<>(watchers.values()).forEach(simulatorRunnablePair -> {
if (simulatorRunnablePair.getKey() == simulator) {
simulatorRunnablePair.getValue().run();
}
});
SimulatorSaver.saveSimulator(SimulatorStorage.simulatorsDir, simulator);
}
@Linked
@MinVersion(19)
public static class QuitListener implements Listener {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
watchers.remove(event.getPlayer());
show(null, event.getPlayer());
}
}
private REntityServer createSim(REntityServer server, Simulator simulator) {
if (simulator == null) {
return null;
}
Map<Vector, Set<Class<?>>> positionCache = new HashMap<>();
simulator.getGroups().stream().map(group -> group.getElements().stream().map(element -> new Pair<>(group, element)).collect(Collectors.toList())).flatMap(List::stream).forEach(pair -> {
SimulatorGroup group = pair.getKey();
SimulatorElement<?> element = pair.getValue();
boolean wasNotPresent = positionCache.computeIfAbsent(element.getPosition(), __ -> new HashSet<>())
.add(element.getClass());
if (!wasNotPresent) return;
Material material = group.isDisabled() || element.isDisabled() ? element.getWorldDisabledMaterial() : element.getWorldMaterial();
Location location = element.getWorldPos().toLocation(WORLD);
RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(server, location, material);
rFallingBlockEntity.setNoGravity(true);
});
return server;
}
public synchronized boolean show(Simulator sim, Player player) {
AtomicBoolean removed = new AtomicBoolean();
entityServers.forEach((simulator, rEntityServer) -> {
if (rEntityServer == null) return;
if (rEntityServer.getPlayers().contains(player) && sim != simulator) {
rEntityServer.removePlayer(player);
removed.set(true);
}
});
if (sim == null) return removed.get();
entityServers.computeIfAbsent(sim, __ -> createSim(new REntityServer(), sim)).addPlayer(player);
return removed.get();
}
synchronized List<REntity> getEntitiesOfSimulator(Simulator simulator) {
REntityServer entityServer = entityServers.get(simulator);
if (entityServer == null) {
return Collections.emptyList();
}
return entityServer.getEntities();
}
}

Datei anzeigen

@ -1,270 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.features.simulator.gui.TNTElementGUI;
import de.steamwar.bausystem.features.simulator.gui.TNTSimulatorGui;
import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement;
import de.steamwar.bausystem.features.simulator.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.tnt.TNTGroup;
import de.steamwar.bausystem.features.tracer.record.Recorder;
import de.steamwar.bausystem.features.tracer.record.SingleTraceRecorder;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.shared.Pair;
import de.steamwar.bausystem.utils.RayTraceUtils;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import yapion.hierarchy.types.YAPIONArray;
import yapion.hierarchy.types.YAPIONObject;
import yapion.hierarchy.types.YAPIONType;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Getter
public class TNTSimulator {
private Set<Player> players = new HashSet<>();
private REntityServer entityServer = new REntityServer();
private Material material = Material.TNT;
private List<SimulatorElement> tntElementList = new ArrayList<>();
public TNTSimulator() {
}
public TNTSimulator(YAPIONObject yapionObject) {
material = Material.valueOf(yapionObject.getStringOrDefault("material", Material.TNT.name()));
YAPIONArray yapionArray = yapionObject.getArrayOrDefault("tntElements", new YAPIONArray());
for (YAPIONObject element : yapionArray.streamObject().collect(Collectors.toList())) {
if (element.containsKey("elements", YAPIONType.ARRAY)) {
tntElementList.add(new TNTGroup(element, entityServer));
} else {
tntElementList.add(new TNTElement(element, null, entityServer));
}
}
}
public YAPIONObject toYAPION() {
YAPIONObject yapionObject = new YAPIONObject();
yapionObject.add("material", material.name());
YAPIONArray yapionArray = new YAPIONArray();
for (SimulatorElement element : tntElementList) {
yapionArray.add(element.toYAPION());
}
yapionObject.add("tntElements", yapionArray);
return yapionObject;
}
public void close() {
entityServer.close();
}
public void show(Player player) {
if (!players.contains(player)) {
entityServer.addPlayer(player);
players.add(player);
}
}
public void hide(Player player) {
if (players.contains(player)) {
entityServer.removePlayer(player);
players.remove(player);
}
}
void _hide(Player player) {
players.remove(player);
}
public List<REntity> getEntities() {
return tntElementList.stream().flatMap(element -> element.getEntities().stream()).collect(Collectors.toList());
}
public List<SimulatorElement> getEntity(REntity entity) {
List<SimulatorElement> tntSpawns = new ArrayList<>();
for (SimulatorElement spawn : tntElementList) {
spawn.getEntity(tntSpawns, entity);
}
return tntSpawns;
}
public void clear() {
new ArrayList<>(tntElementList).forEach(this::remove);
}
public void remove(SimulatorElement element) {
if (element instanceof TNTElement) {
TNTElement tntElement = (TNTElement) element;
if (tntElement.hasParent()) {
tntElement.getParent().remove(tntElement);
if (tntElement.getParent().getElements().isEmpty()) {
remove(tntElement.getParent());
}
} else {
element.remove(tntElement);
}
} else if (element instanceof TNTGroup) {
TNTGroup tntGroup = (TNTGroup) element;
tntGroup.getElements().forEach(tntElement -> {
tntElement.remove(tntElement);
});
tntGroup.getElements().clear();
}
element.close();
tntElementList.remove(element);
}
public void change() {
tntElementList.forEach(simulatorElement -> {
simulatorElement.change();
if (simulatorElement instanceof TNTGroup) {
((TNTGroup) simulatorElement).getElements().forEach(SimulatorElement::change);
}
});
}
public void edit(Player player, RayTraceUtils.RRayTraceResult result) {
if (result == null) {
TNTSimulatorGui.open(player, this, null, this::getTntElementList, null);
return;
}
SimulatorCursor.show(player, this, result);
if (result.getHitEntity() != null) {
List<SimulatorElement> elements = getEntity(result.getHitEntity());
if (elements.isEmpty()) return;
if (elements.size() == 1) {
TNTElementGUI.open(player, (TNTElement) elements.get(0), null);
} else {
List<TNTGroup> tntGroups = tntElementList.stream().filter(TNTGroup.class::isInstance).map(TNTGroup.class::cast).collect(Collectors.toList());
List<SimulatorElement> newElementList = new ArrayList<>();
for (TNTGroup tntGroup : tntGroups) {
if (new HashSet<>(elements).containsAll(tntGroup.getElements())) {
newElementList.add(tntGroup);
elements.removeAll(tntGroup.getElements());
}
}
newElementList.addAll(elements);
if (newElementList.size() == 1) {
SimulatorElement element = newElementList.get(0);
if (element instanceof TNTGroup) {
TNTGroup tntGroup = (TNTGroup) element;
TNTSimulatorGui.open(player, null, tntGroup, () -> {
List<SimulatorElement> elementList = new ArrayList<>();
elementList.addAll(tntGroup.getElements());
return elementList;
}, null);
} else {
TNTElementGUI.open(player, (TNTElement) elements.get(0), null);
}
} else {
TNTSimulatorGui.open(player, null, null, () -> newElementList, null);
}
}
return;
}
if (SimulatorStorage.getSimulator(player.getInventory().getItemInOffHand()) != null && result.getHitPosition().distanceSquared(player.getLocation().toVector()) < 25) {
return;
}
TNTElement tntElement = new TNTElement(SimulatorCursor.getPos(player, result), null, entityServer);
tntElementList.add(tntElement);
TNTElementGUI.open(player, tntElement, null);
}
public void start(Player p) {
Region region = Region.getRegion(p.getLocation());
Map<Integer, Map<Integer, Set<Pair<Runnable, Integer>>>> result = new HashMap<>();
boolean regionFrozen = false;
for (SimulatorElement element : tntElementList) {
regionFrozen |= element.locations(result, region, p.getLocation());
}
if (regionFrozen) {
BauSystem.MESSAGE.send("SIMULATOR_REGION_FROZEN", p);
return;
}
AtomicBoolean needsAutoTrace = new AtomicBoolean();
players.forEach(player -> {
boolean simulatorAutoTrace = Config.getInstance().get(player).getPlainValueOrDefault("simulatorAutoTrace", false);
if (simulatorAutoTrace) {
needsAutoTrace.set(true);
player.performCommand("trace show");
}
});
if (needsAutoTrace.get()) {
Recorder.INSTANCE.set(region, new SingleTraceRecorder(region));
}
AtomicInteger maxTick = new AtomicInteger(0);
Map<Integer, List<List<Pair<Runnable, Integer>>>> toSpawn = new HashMap<>();
result.forEach((integer, integerSetMap) -> {
List<Pair<Integer, Set<Pair<Runnable, Integer>>>> internal = new ArrayList<>();
integerSetMap.forEach((integer1, pairs) -> {
internal.add(new Pair<>(integer1, pairs));
});
internal.sort(Comparator.comparingInt(Pair::getKey));
toSpawn.put(integer, internal.stream().map(Pair::getValue).map(ArrayList::new).peek(Collections::shuffle).collect(Collectors.toList()));
if (maxTick.get() < integer) {
maxTick.set(integer);
}
});
AtomicInteger currentTick = new AtomicInteger(0);
BauSystem.runTaskTimer(BauSystem.getInstance(), bukkitTask -> {
int tick = currentTick.get();
if (tick > maxTick.get()) bukkitTask.cancel();
currentTick.incrementAndGet();
List<List<Pair<Runnable, Integer>>> toSpawnInTick = toSpawn.get(tick);
if (toSpawnInTick == null) return;
toSpawnInTick.forEach(pairs -> {
AtomicBoolean hasSomeLeft = new AtomicBoolean(true);
while(hasSomeLeft.get()) {
hasSomeLeft.set(false);
pairs.forEach(pair -> {
if (pair.getValue() > 0) {
hasSomeLeft.set(true);
pair.getKey().run();
pair.setValue(pair.getValue() - 1);
}
});
}
});
}, 1, 1);
}
}

Datei anzeigen

@ -1,130 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI;
import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.bausystem.utils.RayTraceUtils;
import de.steamwar.linkage.Linked;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import java.util.function.Function;
@Linked
public class TNTSimulatorListener implements Listener {
private boolean permissionCheck(Player player) {
if (!Permission.hasPermission(player, Permission.WORLD)) {
BauSystem.MESSAGE.send("SIMULATOR_NO_PERMS", player);
return false;
}
return true;
}
static RayTraceUtils.RRayTraceResult trace(Player player, Location to, TNTSimulator simulator) {
return RayTraceUtils.traceREntity(player, to, simulator.getEntities());
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent e) {
if (ItemUtils.isItem(e.getPlayer().getInventory().getItemInMainHand(), "simulator")) {
simulatorShowHide(e.getPlayer(), i -> null, PlayerInventory::getItemInMainHand, e.getTo());
} else {
SimulatorCursor.hide(e.getPlayer());
}
}
@EventHandler
public void onPlayerItemHeld(PlayerItemHeldEvent e) {
simulatorShowHide(e.getPlayer(), i -> i.getItem(e.getPreviousSlot()), i -> i.getItem(e.getNewSlot()), e.getPlayer().getLocation());
}
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent e) {
simulatorShowHide(e.getPlayer(), i -> e.getItemDrop().getItemStack(), i -> null, e.getPlayer().getLocation());
}
private TNTSimulator simulatorShowHide(Player player, Function<PlayerInventory, ItemStack> oldItemFunction, Function<PlayerInventory, ItemStack> newItemFunction, Location location) {
TNTSimulator oldSimulator = SimulatorStorage.getSimulator(oldItemFunction.apply(player.getInventory()));
SimulatorCursor.hide(player, oldSimulator);
TNTSimulator simulator = SimulatorStorage.getSimulator(newItemFunction.apply(player.getInventory()));
if (simulator == null) return null;
SimulatorCursor.show(player, simulator, trace(player, location, simulator));
return simulator;
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
if (ItemUtils.isItem(e.getPlayer().getInventory().getItemInMainHand(), "simulator")) {
simulatorShowHide(e.getPlayer(), i -> null, PlayerInventory::getItemInMainHand, e.getPlayer().getLocation());
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
SimulatorCursor.hide(event.getPlayer(), null);
SimulatorStorage.getSimulatorNames().forEach(s -> {
SimulatorStorage.getSimulator(s)._hide(event.getPlayer());
});
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (!ItemUtils.isItem(event.getItem(), "simulator")) {
return;
}
event.setCancelled(true);
if (!permissionCheck(event.getPlayer())) {
return;
}
TNTSimulator simulator = SimulatorStorage.getSimulator(event.getItem());
switch (event.getAction()) {
case LEFT_CLICK_BLOCK:
case LEFT_CLICK_AIR:
if (simulator == null) {
return;
}
simulator.start(event.getPlayer());
break;
case RIGHT_CLICK_BLOCK:
case RIGHT_CLICK_AIR:
if (simulator == null) {
SimulatorSelectionGUI.open(event.getPlayer(), event.getItem());
} else {
simulator.edit(event.getPlayer(), trace(event.getPlayer(), event.getPlayer().getLocation(), simulator));
}
break;
default:
break;
}
}
}

Datei anzeigen

@ -0,0 +1,65 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.data;
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
import de.steamwar.inventory.InvCallback;
import de.steamwar.inventory.SWItem;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
@Getter
@Setter
@RequiredArgsConstructor
public final class Simulator {
private Material material = Material.BARREL;
private final String name;
private boolean autoTrace = false;
private final List<SimulatorGroup> groups = new ArrayList<>();
public void move(int x, int y, int z) {
groups.forEach(simulatorGroup -> {
simulatorGroup.move(x, y, z);
});
}
public SWItem toItem(Player player, InvCallback invCallback) {
return new SWItem(material, "§e" + name, invCallback);
}
public void toSimulatorActions(BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd) {
groups.forEach(simulatorGroup -> {
simulatorGroup.toSimulatorActions(tickStart, tickEnd);
});
}
public Simulator add(SimulatorGroup group) {
groups.add(group);
return this;
}
}

Datei anzeigen

@ -0,0 +1,126 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.data;
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.inventory.InvCallback;
import de.steamwar.inventory.SWItem;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import yapion.hierarchy.types.YAPIONObject;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
@Getter
@Setter
public abstract class SimulatorElement<T extends SimulatorPhase> {
protected Material material;
protected final Vector position;
protected boolean disabled = false;
protected final List<T> phases = new ArrayList<>();
protected SimulatorElement(Material material, Vector position) {
this.material = material;
this.position = position;
}
public SimulatorElement<T> add(T setting) {
phases.add(setting);
return this;
}
public void sort() {
phases.sort(Comparator.comparingInt(SimulatorPhase::getTickOffset));
}
public abstract String getName(Player player);
public int getBaseTick() {
return phases.stream()
.mapToInt(value -> value.tickOffset)
.min()
.orElse(0);
}
public void changeBaseTicks(int tick) {
phases.forEach(t -> {
t.tickOffset += tick;
});
}
public void move(double x, double y, double z) {
position.setX(position.getX() + x);
position.setY(position.getY() + y);
position.setZ(position.getZ() + z);
}
public abstract Material getWorldMaterial();
public abstract Material getWorldDisabledMaterial();
public abstract boolean canBeInGroup(SimulatorGroup simulatorGroup);
public Vector getWorldPos() {
return position;
}
public SWItem toItem(Player player, InvCallback invCallback) {
List<String> lore = new ArrayList<>();
lore.add("§7Phase count§8:§e " + phases.size());
lore.add("§7Tick§8:§e " + getBaseTick());
lore.add("");
lore.add("§7X§8:§e " + position.getX());
lore.add("§7Y§8:§e " + position.getY());
lore.add("§7Z§8:§e " + position.getZ());
if (disabled) {
lore.add("");
lore.add("§cDisabled");
}
return new SWItem(material, "§e" + getName(player), lore, disabled, invCallback);
}
public void toSimulatorActions(BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd) {
if (disabled) return;
phases.forEach(phase -> {
phase.toSimulatorActions(position.clone(), tickStart, tickEnd);
});
}
public abstract void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back);
public SimulatorGroup getGroup(Simulator simulator) {
return simulator.getGroups().stream()
.filter(simulatorGroup -> simulatorGroup.getElements().contains(this))
.findFirst()
.orElse(null);
}
public abstract String getType();
public void saveExtra(YAPIONObject elementObject) {}
public void loadExtra(YAPIONObject elementObject) {}
}

Datei anzeigen

@ -0,0 +1,93 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.data;
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
import de.steamwar.inventory.InvCallback;
import de.steamwar.inventory.SWItem;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiConsumer;
@Getter
@Setter
public final class SimulatorGroup {
private Material material = Material.CHEST;
private boolean disabled = false;
private final List<SimulatorElement<?>> elements = new ArrayList<>();
public SimulatorGroup add(SimulatorElement<?> element) {
if (!elements.contains(element)) {
elements.add(element);
}
return this;
}
public void sort() {
elements.sort(Comparator.comparingInt(SimulatorElement::getBaseTick));
}
public int getBaseTick() {
return elements.stream()
.mapToInt(SimulatorElement::getBaseTick)
.min()
.orElse(0);
}
public void changeBaseTicks(int tick) {
elements.forEach(simulatorElement -> {
simulatorElement.changeBaseTicks(tick);
});
}
public void move(double x, double y, double z) {
elements.forEach(simulatorElement -> {
simulatorElement.move(x, y, z);
});
}
public SWItem toItem(Player player, InvCallback groupCallback, InvCallback itemCallback) {
if (elements.size() == 1) {
return elements.get(0).toItem(player, itemCallback);
} else {
List<String> lore = new ArrayList<>();
lore.add("§7Element count§8:§e " + elements.size());
lore.add("§7Tick§8:§e " + getBaseTick());
if (disabled) {
lore.add("");
lore.add("§cDisabled");
}
return new SWItem(material != null ? material : Material.ENDER_CHEST, "§eGroup", lore, disabled, groupCallback);
}
}
public void toSimulatorActions(BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd) {
if (disabled) return;
elements.forEach(simulatorElement -> {
simulatorElement.toSimulatorActions(tickStart, tickEnd);
});
}
}

Datei anzeigen

@ -0,0 +1,44 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.data;
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.util.Vector;
import yapion.hierarchy.types.YAPIONObject;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
@Getter
@Setter
public abstract class SimulatorPhase {
public static final int ORDER_LIMIT = 30;
protected int tickOffset = 0;
protected int lifetime = 80;
protected int order = 0;
public abstract void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd);
public void saveExtra(YAPIONObject phaseObject) {}
public void loadExtra(YAPIONObject phaseObject) {}
}

Datei anzeigen

@ -0,0 +1,71 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.data.redstone;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.gui.SimulatorRedstoneGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public final class RedstoneElement extends SimulatorElement<RedstonePhase> {
public RedstoneElement(Vector position) {
super(Material.REDSTONE_BLOCK, position);
}
@Override
public String getName(Player player) {
return "Redstone";
}
@Override
public Material getWorldMaterial() {
return Material.REDSTONE_BLOCK;
}
@Override
public Material getWorldDisabledMaterial() {
return Material.WHITE_STAINED_GLASS;
}
@Override
public boolean canBeInGroup(SimulatorGroup simulatorGroup) {
return simulatorGroup.getElements().stream().allMatch(RedstoneElement.class::isInstance);
}
@Override
public Vector getWorldPos() {
return position.clone().add(new Vector(0.5, 0, 0.5));
}
@Override
public void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back) {
new SimulatorRedstoneGui(player, simulator, group, this, back).open();
}
@Override
public String getType() {
return "Redstone";
}
}

Datei anzeigen

@ -0,0 +1,70 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.data.redstone;
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
import lombok.NoArgsConstructor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.util.Vector;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
@NoArgsConstructor
public final class RedstonePhase extends SimulatorPhase {
public RedstonePhase(int tickOffset) {
this.tickOffset = tickOffset;
}
{
this.lifetime = 1;
}
@Override
public void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd) {
AtomicReference<BlockState> blockState = new AtomicReference<>();
tickStart.accept(tickOffset, new SimulatorAction(order, 1) {
@Override
public void accept(World world) {
Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
blockState.set(block.getState());
block.setType(Material.REDSTONE_BLOCK);
}
});
tickEnd.accept(tickOffset + lifetime, new SimulatorAction(0, 1) {
@Override
public void accept(World world) {
BlockState state = blockState.get();
if (state != null) {
state.update(true, true);
} else {
Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
block.setType(Material.AIR);
}
}
});
}
}

Datei anzeigen

@ -0,0 +1,105 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.data.tnt;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.gui.SimulatorTNTGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.inventory.InvCallback;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public final class TNTElement extends SimulatorElement<TNTPhase> {
public TNTElement(Vector position) {
super(Material.TNT, position);
}
@Override
public String getName(Player player) {
return "TNT";
}
public void move(double x, double y, double z) {
position.setX(position.getX() + x);
position.setY(position.getY() + y);
position.setZ(position.getZ() + z);
}
public void align(Vector offset) {
if (offset.getX() != 0) {
if (position.getX() - (int) position.getX() == 0.49) {
position.setX(position.getX() + 0.02);
}
if (position.getX() - (int) position.getX() == -0.49) {
position.setX(position.getX() - 0.02);
}
position.setX(position.getBlockX() + offset.getX());
}
if (offset.getZ() != 0) {
if (position.getZ() - (int) position.getZ() == 0.49) {
position.setZ(position.getZ() + 0.02);
}
if (position.getZ() - (int) position.getZ() == -0.49) {
position.setZ(position.getZ() - 0.02);
}
position.setZ(position.getBlockZ() + offset.getZ());
}
}
@Override
public SWItem toItem(Player player, InvCallback invCallback) {
long sum = phases.stream().mapToInt(TNTPhase::getCount).sum();
SWItem swItem = super.toItem(player, invCallback);
swItem.getItemStack().setAmount((int) Math.min(64, Math.max(1, sum)));
swItem.setName("§e" + getName(player) + "§8:§7 " + sum);
return swItem;
}
@Override
public Material getWorldMaterial() {
return Material.TNT;
}
@Override
public Material getWorldDisabledMaterial() {
return Material.RED_STAINED_GLASS;
}
@Override
public boolean canBeInGroup(SimulatorGroup simulatorGroup) {
return simulatorGroup.getElements().stream().allMatch(TNTElement.class::isInstance);
}
@Override
public void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back) {
new SimulatorTNTGui(player, simulator, this, group, back).open();
}
@Override
public String getType() {
return "TNT";
}
}

Datei anzeigen

@ -0,0 +1,91 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.data.tnt;
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.bukkit.World;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.util.Vector;
import yapion.hierarchy.types.YAPIONObject;
import java.util.function.BiConsumer;
@Getter
@Setter
@NoArgsConstructor
public final class TNTPhase extends SimulatorPhase {
private int count = 1;
private boolean xJump = false;
private boolean yJump = false;
private boolean zJump = false;
public TNTPhase(int tickOffset) {
this.tickOffset = tickOffset;
}
public boolean hasJump() {
return xJump || yJump || zJump;
}
public void setJump(boolean jump) {
xJump = jump;
yJump = jump;
zJump = jump;
}
@Override
public void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd) {
tickStart.accept(tickOffset, new SimulatorAction(order, count) {
@Override
public void accept(World world) {
TNTPrimed tnt = world.spawn(position.toLocation(world), TNTPrimed.class);
if (!xJump) tnt.setVelocity(tnt.getVelocity().setX(0));
if (!yJump) tnt.setVelocity(tnt.getVelocity().setY(0));
if (!zJump) tnt.setVelocity(tnt.getVelocity().setZ(0));
tnt.setFuseTicks(lifetime);
}
});
tickEnd.accept(tickOffset + lifetime, new SimulatorAction(0, 1) {
@Override
public void accept(World world) {
}
});
}
@Override
public void saveExtra(YAPIONObject phaseObject) {
phaseObject.add("count", count);
phaseObject.add("xJump", xJump);
phaseObject.add("yJump", yJump);
phaseObject.add("zJump", zJump);
}
@Override
public void loadExtra(YAPIONObject phaseObject) {
count = phaseObject.getPlainValue("count");
xJump = phaseObject.getPlainValue("xJump");
yJump = phaseObject.getPlainValue("yJump");
zJump = phaseObject.getPlainValue("zJump");
}
}

Datei anzeigen

@ -0,0 +1,36 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.World;
import java.util.function.Consumer;
@Getter
@AllArgsConstructor
public abstract class SimulatorAction implements Consumer<World> {
private int order;
@Setter
private int count;
}

Datei anzeigen

@ -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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.features.tracer.record.Recorder;
import de.steamwar.bausystem.features.tracer.record.SingleTraceRecorder;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.utils.TickEndEvent;
import de.steamwar.bausystem.utils.TickStartEvent;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
@Linked
@MinVersion(19)
public class SimulatorExecutor implements Listener {
private static final World WORLD = Bukkit.getWorlds().get(0);
private static Set<Simulator> currentlyRunning = new HashSet<>();
private static Map<Long, Map<Integer, List<SimulatorAction>>> tickStartActions = new HashMap<>();
private static Map<Long, List<SimulatorAction>> tickEndActions = new HashMap<>();
public static boolean run(Simulator simulator) {
if (currentlyRunning.contains(simulator)) return false;
currentlyRunning.add(simulator);
long currentTick = TPSUtils.currentRealTick.get();
AtomicLong lastTick = new AtomicLong();
simulator.toSimulatorActions((tickOffset, simulatorAction) -> {
lastTick.set(Math.max(lastTick.get(), tickOffset));
tickStartActions.computeIfAbsent(currentTick + tickOffset, __ -> new HashMap<>())
.computeIfAbsent(simulatorAction.getOrder(), __ -> new ArrayList<>())
.add(simulatorAction);
}, (tickOffset, simulatorAction) -> {
lastTick.set(Math.max(lastTick.get(), tickOffset));
tickEndActions.computeIfAbsent(currentTick + tickOffset, __ -> new ArrayList<>())
.add(simulatorAction);
});
tickEndActions.computeIfAbsent(currentTick + lastTick.get() + 4, __ -> new ArrayList<>())
.add(new SimulatorAction(0, 1) {
@Override
public void accept(World world) {
currentlyRunning.remove(simulator);
}
});
if (simulator.isAutoTrace()) {
simulator.getGroups()
.stream()
.map(SimulatorGroup::getElements)
.flatMap(List::stream)
.map(SimulatorElement::getPosition)
.map(pos -> pos.toLocation(WORLD))
.map(Region::getRegion)
.distinct()
.forEach(region -> {
if (Recorder.INSTANCE.isDisabled(region)) {
Recorder.INSTANCE.set(region, new SingleTraceRecorder(region));
}
});
}
return true;
}
@EventHandler
public void onTickStart(TickStartEvent event) {
long currentTick = TPSUtils.currentRealTick.get();
Map<Integer, List<SimulatorAction>> actionsToRun = tickStartActions.remove(currentTick);
if (actionsToRun == null) return;
List<Integer> keys = new ArrayList<>(actionsToRun.keySet());
keys.sort(null);
for (int actionKey : keys) {
runActions(actionsToRun.get(actionKey));
}
}
@EventHandler
public void onTickEnd(TickEndEvent event) {
long currentTick = TPSUtils.currentRealTick.get() - 1;
List<SimulatorAction> actionsToRun = tickEndActions.remove(currentTick);
if (actionsToRun == null) return;
runActions(actionsToRun);
}
private void runActions(List<SimulatorAction> actionsToRun) {
while (!actionsToRun.isEmpty()) {
Collections.shuffle(actionsToRun);
for (int i = actionsToRun.size() - 1 ; i >= 0; i--) {
SimulatorAction action = actionsToRun.get(i);
action.accept(WORLD);
action.setCount(action.getCount() - 1);
if (action.getCount() == 0) {
actionsToRun.remove(i);
}
}
}
}
}

Datei anzeigen

@ -1,39 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.gui;
import de.steamwar.inventory.SWItem;
import lombok.experimental.UtilityClass;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import java.util.UUID;
@UtilityClass
public class ItemUtils {
public static SWItem unique(SWItem swItem) {
ItemMeta itemMeta = swItem.getItemMeta();
itemMeta.getPersistentDataContainer().set(NamespacedKey.minecraft(UUID.randomUUID().toString()), PersistentDataType.INTEGER, 0);
swItem.setItemMeta(itemMeta);
return swItem;
}
}

Datei anzeigen

@ -0,0 +1,90 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui;
import de.steamwar.inventory.InvCallback;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.stream.Collectors;
public class SimulatorGroupChooserGui extends SimulatorPageGui<SimulatorGroup> {
private final SimulatorElement<?> subject;
private final SimulatorGroup parent;
private final SimulatorBaseGui back;
public SimulatorGroupChooserGui(Player player, Simulator simulator, SimulatorElement<?> subject, SimulatorGroup parent, SimulatorBaseGui back) {
super(player, simulator, 6 * 9, simulator.getGroups().stream().filter(e -> e != parent).filter(e -> subject.canBeInGroup(e)).collect(Collectors.toList()));
this.subject = subject;
this.parent = parent;
this.back = back;
}
@Override
public void headerAndFooter() {
inventory.setItem(4, new SWItem(simulator.getMaterial(), "§e" + simulator.getName(), clickType -> {
}));
if (parent.getElements().size() != 1) {
inventory.setItem(49, new SWItem(Material.BARRIER, "§cRemove from Group", clickType -> {
SimulatorGroup newParent = new SimulatorGroup();
newParent.add(subject);
simulator.getGroups().add(newParent);
parent.getElements().remove(subject);
back.open();
SimulatorWatcher.update(simulator);
if (parent.getElements().size() == 1) {
parent.setDisabled(false);
parent.setMaterial(Material.BARREL);
}
}));
}
inventory.addCloseCallback(clickType -> {
back.open();
});
}
@Override
public String baseTitle() {
return "Choose Group";
}
@Override
public SWItem convert(SimulatorGroup simulatorGroup) {
InvCallback invCallback = clickType -> {
simulatorGroup.add(subject);
parent.getElements().remove(subject);
if (parent.getElements().size() == 1) {
parent.setDisabled(false);
parent.setMaterial(Material.BARREL);
}
back.open();
SimulatorWatcher.update(simulator);
};
return simulatorGroup.toItem(player, invCallback, invCallback);
}
}

Datei anzeigen

@ -0,0 +1,108 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.stream.Collectors;
public class SimulatorGroupGui extends SimulatorPageGui<SimulatorElement<?>> {
private SimulatorGroup simulatorGroup;
private final SimulatorBaseGui back;
public SimulatorGroupGui(Player player, Simulator simulator, SimulatorGroup simulatorGroup, SimulatorBaseGui back) {
super(player, simulator, 6 * 9, simulatorGroup.getElements());
this.simulatorGroup = simulatorGroup;
this.back = back;
}
@Override
public String baseTitle() {
return "Group";
}
@Override
public void headerAndFooter() {
if (simulatorGroup.getMaterial() == null) {
List<SimulatorGroup> parents = data.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList());
if (parents.size() == 1) {
simulatorGroup = parents.get(0);
data = simulatorGroup.getElements();
}
}
if (simulatorGroup.getElements().removeIf(element -> element.getPhases().isEmpty())) {
SimulatorWatcher.update(simulator);
}
if (simulatorGroup.getElements().size() < 2) {
back.open();
return;
}
simulatorGroup.sort();
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
back.open();
}));
inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> {
simulatorGroup.getElements().clear();
SimulatorWatcher.update(simulator);
}));
inventory.setItem(4, simulatorGroup.toItem(player, clickType -> {
if (simulatorGroup.getMaterial() == null) return;
new SimulatorMaterialGui(player, simulator, simulatorGroup::getMaterial, simulatorGroup::setMaterial, this).open();
}, clickType -> {
}));
inventory.setItem(48, new SWItem(Material.REPEATER, "§eSettings", clickType -> {
new SimulatorGroupSettingsGui(player, simulator, simulatorGroup, this).open();
}));
boolean disabled = simulatorGroup.getMaterial() == null ? simulatorGroup.getElements().stream().allMatch(SimulatorElement::isDisabled) : simulatorGroup.isDisabled();
inventory.setItem(50, new SWItem(disabled ? Material.ENDER_PEARL : Material.ENDER_EYE, simulatorGroup.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> {
if (simulatorGroup.getMaterial() == null) {
simulatorGroup.getElements().forEach(simulatorElement -> {
simulatorElement.setDisabled(!disabled);
});
} else {
simulatorGroup.setDisabled(!disabled);
}
SimulatorWatcher.update(simulator);
}));
}
@Override
public SWItem convert(SimulatorElement<?> element) {
return element.toItem(player, clickType -> {
element.open(player, simulator, simulatorGroup, this);
});
}
}

Datei anzeigen

@ -0,0 +1,173 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
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.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.Arrays;
public class SimulatorGroupSettingsGui extends SimulatorBaseGui {
private final SimulatorGroup simulatorGroup;
private final SimulatorBaseGui back;
public SimulatorGroupSettingsGui(Player player, Simulator simulator, SimulatorGroup simulatorGroup, SimulatorBaseGui back) {
super(player, simulator, 5 * 9);
this.simulatorGroup = simulatorGroup;
this.back = back;
}
@Override
public String title() {
return "Group";
}
@Override
public void populate() {
if (simulatorGroup.getElements().size() < 2) {
back.open();
return;
}
// Back Arrow
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
back.open();
}));
// Material Chooser
inventory.setItem(4, simulatorGroup.toItem(player, clickType -> {
if (simulatorGroup.getMaterial() == null) return;
new SimulatorMaterialGui(player, simulator, simulatorGroup::getMaterial, simulatorGroup::setMaterial, this).open();
}, clickType -> {
}));
// Base Tick
int baseTicks = simulatorGroup.getBaseTick();
inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
simulatorGroup.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
SimulatorWatcher.update(simulator);
});
SWItem baseTick = new SWItem(Material.REPEATER, "§eTicks§8:§7 " + baseTicks, clickType -> {
new SimulatorAnvilGui<>(player, "Ticks", baseTicks + "", Integer::parseInt, integer -> {
if (integer < 0) return false;
simulatorGroup.changeBaseTicks(integer - baseTicks);
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(Material.REPEATER).open();
});
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
inventory.setItem(18, baseTick);
inventory.setItem(27, SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
simulatorGroup.changeBaseTicks(-baseTicks);
} else {
simulatorGroup.changeBaseTicks(clickType.isShiftClick() ? -5 : -1);
}
SimulatorWatcher.update(simulator);
});
boolean allTNT = simulatorGroup.getElements().stream().allMatch(TNTElement.class::isInstance);
if (allTNT) {
// Subpixel Alignment
inventory.setItem(21, new SWItem(Material.SUNFLOWER, "§7Align§8: §eCenter", clickType -> {
simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> {
tnt.align(new Vector(0.5, 0, 0.5));
});
SimulatorWatcher.update(simulator);
}));
// Z
inventory.setItem(20, new SWItem(Material.OAK_BUTTON, "§7Align§8: §eNegativ Z", clickType -> {
simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> {
tnt.align(new Vector(0, 0, 0.49));
});
SimulatorWatcher.update(simulator);
}));
inventory.setItem(22, new SWItem(Material.OAK_BUTTON, "§7Align§8: §ePositiv Z", clickType -> {
simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> {
tnt.align(new Vector(0, 0, 0.51));
});
SimulatorWatcher.update(simulator);
}));
// X
inventory.setItem(12, new SWItem(Material.STONE_BUTTON, "§7Align§8: §eNegativ X", clickType -> {
simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> {
tnt.align(new Vector(0.49, 0, 0));
});
SimulatorWatcher.update(simulator);
}));
inventory.setItem(30, new SWItem(Material.STONE_BUTTON, "§7Align§8: §ePositiv X", clickType -> {
simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> {
tnt.align(new Vector(0.51, 0, 0));
});
SimulatorWatcher.update(simulator);
}));
}
//Pos X
inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
simulatorGroup.move(clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1, 0, 0);
SimulatorWatcher.update(simulator);
});
inventory.setItem(24, new SWItem(Material.PAPER, "§eX", clickType -> {
}));
inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
simulatorGroup.move(clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1, 0, 0);
SimulatorWatcher.update(simulator);
});
//Pos Y
inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
simulatorGroup.move(0, clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1, 0);
SimulatorWatcher.update(simulator);
});
inventory.setItem(25, new SWItem(Material.PAPER, "§eY", clickType -> {
}));
inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
simulatorGroup.move(0, clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1, 0);
SimulatorWatcher.update(simulator);
});
//Pos Z
inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
simulatorGroup.move(0, 0, clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1);
SimulatorWatcher.update(simulator);
});
inventory.setItem(26, new SWItem(Material.PAPER, "§eZ", clickType -> {
}));
inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
simulatorGroup.move(0, 0, clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1);
SimulatorWatcher.update(simulator);
});
}
}

Datei anzeigen

@ -0,0 +1,65 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
public class SimulatorGui extends SimulatorPageGui<SimulatorGroup> {
public SimulatorGui(Player player, Simulator simulator) {
super(player, simulator, 6 * 9, simulator.getGroups());
}
@Override
public String baseTitle() {
return "Simulator - " + simulator.getName();
}
@Override
public void headerAndFooter() {
if (simulator.getGroups().removeIf(element -> element.getElements().isEmpty() || element.getElements().stream().allMatch(simulatorElement -> simulatorElement.getPhases().isEmpty()))) {
SimulatorWatcher.update(simulator);
}
inventory.setItem(4, simulator.toItem(player, clickType -> {
new SimulatorMaterialGui(player, simulator, simulator::getMaterial, simulator::setMaterial, this).open();
}));
inventory.setItem(49, new SWItem(Material.REPEATER, "§eSettings", clickType -> {
new SimulatorSettingsGui(player, simulator, this).open();
}));
}
@Override
public SWItem convert(SimulatorGroup simulatorGroup) {
return simulatorGroup.toItem(player, clickType -> {
new SimulatorGroupGui(player, simulator, simulatorGroup, this).open();
}, clickType -> {
SimulatorElement<?> element = simulatorGroup.getElements().get(0);
element.open(player, simulator, simulatorGroup, this);
});
}
}

Datei anzeigen

@ -0,0 +1,78 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class SimulatorMaterialGui extends SimulatorPageGui<Material> {
private static final List<Material> MATERIALS = Arrays.stream(Material.values())
.filter(material -> !material.isAir())
.filter(material -> !material.isLegacy())
.filter(Material::isItem)
.collect(Collectors.toList());
private final Supplier<Material> currentMaterial;
private Material material;
private final Consumer<Material> change;
private final SimulatorBaseGui back;
public SimulatorMaterialGui(Player player, Simulator simulator, Supplier<Material> currentMaterial, Consumer<Material> change, SimulatorBaseGui back) {
super(player, simulator, 6 * 9, MATERIALS);
this.currentMaterial = currentMaterial;
this.change = change;
this.back = back;
}
@Override
public String baseTitle() {
return "Material";
}
@Override
public void headerAndFooter() {
material = currentMaterial.get();
inventory.setItem(4, new SWItem(material, "§eMaterial", clickType -> {
}));
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
back.open();
}));
}
@Override
public SWItem convert(Material material) {
return new SWItem(material, "§eNew Material", Arrays.asList(material == this.material ? "§eSelected" : "§eClick to select"), material == this.material, clickType -> {
change.accept(material);
SimulatorWatcher.update(simulator);
});
}
}

Datei anzeigen

@ -0,0 +1,232 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
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.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui;
import de.steamwar.inventory.SWItem;
import lombok.AllArgsConstructor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class SimulatorRedstoneGui extends SimulatorScrollGui<SimulatorRedstoneGui.RedstoneSubPhase> {
private final SimulatorGroup parent;
private final RedstoneElement redstone;
private final SimulatorBaseGui back;
public SimulatorRedstoneGui(Player player, Simulator simulator, SimulatorGroup parent, RedstoneElement redstone, SimulatorBaseGui back) {
super(player, simulator, 6 * 9, new ArrayList<>());
this.parent = parent;
this.redstone = redstone;
this.back = back;
}
@Override
public String baseTitle() {
return "Redstone";
}
@Override
public void headerAndFooter() {
if (redstone.getPhases().isEmpty()) {
back.open();
SimulatorWatcher.update(simulator);
return;
}
data.clear();
redstone.getPhases().forEach(redstonePhase -> {
data.add(new RedstoneSubPhase(true, redstonePhase));
data.add(new RedstoneSubPhase(false, redstonePhase));
});
data.sort(null);
// Back Arrow
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
if (parent.getElements().contains(redstone)) {
back.open();
} else {
SimulatorGroup newParent = redstone.getGroup(simulator);
if (newParent == null) {
player.closeInventory();
return;
}
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
if (newParent.getElements().size() == 1) {
simulatorGui.open();
} else {
new SimulatorGroupGui(player, simulator, newParent, simulatorGui).open();
}
}
}));
inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> {
redstone.getPhases().clear();
SimulatorWatcher.update(simulator);
}));
// Material Chooser
inventory.setItem(4, redstone.toItem(player, clickType -> {
new SimulatorMaterialGui(player, simulator, redstone::getMaterial, redstone::setMaterial, this).open();
}));
// Settings
inventory.setItem(48, new SWItem(Material.REPEATER, "§eSettings", clickType -> {
new SimulatorRedstoneSettingsGui(player, simulator, redstone, this).open();
}));
// Group chooser
inventory.setItem(49, new SWItem(Material.LEAD, "§eJoin Group", clickType -> {
new SimulatorGroupChooserGui(player, simulator, redstone, redstone.getGroup(simulator), this).open();
}));
// Enable/Disable
inventory.setItem(50, new SWItem(redstone.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, redstone.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> {
redstone.setDisabled(!redstone.isDisabled());
SimulatorWatcher.update(simulator);
}));
}
@Override
public SWItem[] column(RedstoneSubPhase redstoneSubPhase, int index) {
int min;
if (index % 2 == 0 && index > 0) {
RedstoneSubPhase subPhase = data.get(index - 1);
min = subPhase.phase.getTickOffset() + subPhase.phase.getLifetime() + 1;
} else {
min = 0;
}
int max;
if (index % 2 == 0 && index < data.size() - 2) {
RedstoneSubPhase subPhase = data.get(index + 2);
max = subPhase.phase.getTickOffset() - redstoneSubPhase.phase.getLifetime() - 1;
} else if (index % 2 != 0 && index < data.size() - 1) {
RedstoneSubPhase subPhase = data.get(index + 1);
max = subPhase.phase.getTickOffset() - redstoneSubPhase.phase.getTickOffset() - 1;
} else {
max = Integer.MAX_VALUE - 5;
}
List<String> lore = new ArrayList<>();
int time = redstoneSubPhase.phase.getTickOffset() + (redstoneSubPhase.place ? 0 : redstoneSubPhase.phase.getLifetime());
if (redstoneSubPhase.place) {
lore.add("§7Time§8:§e " + time);
lore.add("§7Order§8:§e " + redstoneSubPhase.phase.getOrder());
} else {
lore.add("§7Time§8:§e " + time);
lore.add("§7Activation Time§8:§e " + redstoneSubPhase.phase.getLifetime());
}
lore.add("");
lore.add("§7Click§8:§e Edit");
lore.add("§7Middle-Click§8:§e Remove");
SWItem redstone = new SWItem(redstoneSubPhase.place ? Material.REDSTONE_BLOCK : Material.STONE, redstoneSubPhase.place ? "§eActivate" : "§eDeactivate", lore, false, clickType -> {
if (clickType == ClickType.MIDDLE) {
this.redstone.getPhases().remove(redstoneSubPhase.phase);
SimulatorWatcher.update(simulator);
} else {
new SimulatorRedstonePhaseSettingsGui(player, simulator, this.redstone, redstoneSubPhase.phase, this).open();
}
});
redstone.getItemStack().setAmount(Math.max(1, Math.min(time, 64)));
Supplier<Integer> getter = redstoneSubPhase.place ? redstoneSubPhase.phase::getTickOffset : redstoneSubPhase.phase::getLifetime;
Consumer<Integer> setter = redstoneSubPhase.place ? redstoneSubPhase.phase::setTickOffset : redstoneSubPhase.phase::setLifetime;
return new SWItem[] {
new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
}),
redstone,
new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
}),
new SWItem(Material.ANVIL, "§eEdit Activation", clickType -> {
new SimulatorRedstonePhaseSettingsGui(player, simulator, this.redstone, redstoneSubPhase.phase, this).open();
}),
};
}
@Override
public SWItem[] lastColumn() {
return new SWItem[]{
new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
addNewPhase(clickType.isShiftClick());
}),
new SWItem(Material.REDSTONE, "§eRedstone§8:§a New Phase", clickType -> {
addNewPhase(false);
}),
new SWItem(SWItem.getDye(8), "§7", clickType -> {
}),
};
}
private void addNewPhase(boolean shift) {
RedstonePhase lastElement = redstone.getPhases().get(redstone.getPhases().size() - 1);
RedstonePhase newPhase = new RedstonePhase(lastElement.getTickOffset() + lastElement.getLifetime() + 1);
if (shift) newPhase.setTickOffset(newPhase.getTickOffset() + 5);
scroll += 2;
redstone.add(newPhase);
SimulatorWatcher.update(simulator);
}
@AllArgsConstructor
public static class RedstoneSubPhase implements Comparable<RedstoneSubPhase> {
private boolean place;
private RedstonePhase phase;
@Override
public int compareTo(RedstoneSubPhase o) {
int thisTick = phase.getTickOffset() + (place ? 0 : phase.getLifetime());
int otherTick = o.phase.getTickOffset() + (o.place ? 0 : o.phase.getLifetime());
int compare = Integer.compare(thisTick, otherTick);
if (compare != 0) {
return compare;
}
if (place && !o.place) {
return -1;
}
if (!place && o.place) {
return 1;
}
if (!place) {
return 0;
}
return Integer.compare(phase.getOrder(), o.phase.getOrder());
}
}
}

Datei anzeigen

@ -0,0 +1,168 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.core.Core;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.Arrays;
public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
private final RedstoneElement redstoneElement;
private final RedstonePhase redstone;
private final SimulatorBaseGui back;
public SimulatorRedstonePhaseSettingsGui(Player player, Simulator simulator, RedstoneElement redstoneElement, RedstonePhase redstone, SimulatorBaseGui back) {
super(player, simulator, 5 * 9);
this.redstoneElement = redstoneElement;
this.redstone = redstone;
this.back = back;
}
@Override
public String title() {
return "Redstone";
}
@Override
public void populate() {
if (!redstoneElement.getPhases().contains(redstone)) {
back.open();
return;
}
// Back Arrow
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
back.open();
}));
// Material Chooser
inventory.setItem(4, redstoneElement.toItem(player, clickType -> {
new SimulatorMaterialGui(player, simulator, redstoneElement::getMaterial, redstoneElement::setMaterial, this).open();
}));
// Delete
inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> {
redstoneElement.getPhases().remove(redstone);
back.open();
SimulatorWatcher.update(simulator);
}));
int index = redstoneElement.getPhases().indexOf(redstone);
int min;
if (index > 0) {
RedstonePhase previous = redstoneElement.getPhases().get(index - 1);
min = previous.getTickOffset() + previous.getLifetime() + 1;
} else {
min = 0;
}
int maxLifetime;
int maxOffset;
if (index < redstoneElement.getPhases().size() - 1) {
RedstonePhase next = redstoneElement.getPhases().get(index + 1);
maxLifetime = next.getTickOffset() - redstone.getTickOffset() - 1;
maxOffset = next.getTickOffset() - redstone.getLifetime() - 1;
} else {
maxLifetime = Integer.MAX_VALUE - 5;
maxOffset = Integer.MAX_VALUE - 5;
}
//Tick Offset
int offset = redstone.getTickOffset();
inventory.setItem(10, SWItem.getDye(offset < maxOffset ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
redstone.setTickOffset(Math.min(maxOffset, offset + (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
SWItem offsetItem = new SWItem(Material.REPEATER, "§eStart at§8:§7 " + offset, clickType -> {
new SimulatorAnvilGui<>(player, "Start at", offset + "", Integer::parseInt, integer -> {
if (integer < 0) return false;
redstone.setTickOffset(Math.min(Math.max(integer, min), maxOffset));
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(Material.REPEATER).open();
});
offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64)));
inventory.setItem(19, offsetItem);
inventory.setItem(28, SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
redstone.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
//Lifetime
int lifetime = redstone.getLifetime();
inventory.setItem(11, SWItem.getDye(lifetime < maxLifetime ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
redstone.setLifetime(Math.min(maxLifetime, lifetime + (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
SWItem lifetimeItem = new SWItem(Material.CLOCK, "§eActivation Time§8:§7 " + lifetime, clickType -> {
new SimulatorAnvilGui<>(player, "Activation Time", lifetime + "", Integer::parseInt, integer -> {
if (integer < 0) return false;
redstone.setLifetime(Math.min(integer, maxLifetime));
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(Material.CLOCK).open();
});
lifetimeItem.getItemStack().setAmount(Math.max(1, Math.min(lifetime, 64)));
inventory.setItem(20, lifetimeItem);
inventory.setItem(29, SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
redstone.setLifetime(Math.max(0, lifetime - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
//Order
int order = redstone.getOrder();
inventory.setItem(13, SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
redstone.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
Material negativeNumbers = Material.getMaterial(Core.getVersion() >= 19 ? "RECOVERY_COMPASS" : "FIREWORK_STAR");
SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : negativeNumbers, "§eActivation Order§8:§7 " + order, clickType -> {
new SimulatorAnvilGui<>(player, "Activation Order", order + "", Integer::parseInt, integer -> {
if (integer < -SimulatorPhase.ORDER_LIMIT) return false;
if (integer > SimulatorPhase.ORDER_LIMIT) return false;
redstone.setOrder(integer);
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(order >= 0 ? Material.COMPASS : negativeNumbers).open();
});
orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30)));
inventory.setItem(22, orderItem);
inventory.setItem(31, SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
redstone.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
}
}

Datei anzeigen

@ -0,0 +1,141 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.Arrays;
public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui {
private final RedstoneElement redstone;
private final SimulatorBaseGui back;
public SimulatorRedstoneSettingsGui(Player player, Simulator simulator, RedstoneElement redstone, SimulatorBaseGui back) {
super(player, simulator, 5 * 9);
this.redstone = redstone;
this.back = back;
}
@Override
public String title() {
return "Redstone";
}
@Override
public void populate() {
if (redstone.getPhases().isEmpty()) {
back.open();
return;
}
// Back Arrow
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
back.open();
}));
// Material Chooser
inventory.setItem(4, redstone.toItem(player, clickType -> {
new SimulatorMaterialGui(player, simulator, redstone::getMaterial, redstone::setMaterial, this).open();
}));
// Base Tick
int baseTicks = redstone.getBaseTick();
inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
redstone.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
SimulatorWatcher.update(simulator);
});
SWItem baseTick = new SWItem(Material.REPEATER, "§eTicks§8:§7 " + baseTicks, clickType -> {
new SimulatorAnvilGui<>(player, "Ticks", baseTicks + "", Integer::parseInt, integer -> {
if (integer < 0) return false;
redstone.changeBaseTicks(integer - baseTicks);
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(Material.REPEATER).open();
});
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
inventory.setItem(18, baseTick);
inventory.setItem(27, SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
redstone.changeBaseTicks(-baseTicks);
} else {
redstone.changeBaseTicks(clickType.isShiftClick() ? -5 : -1);
}
SimulatorWatcher.update(simulator);
});
//Pos X
inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
redstone.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
SimulatorWatcher.update(simulator);
});
inventory.setItem(24, new SWItem(Material.PAPER, "§eX§8:§7 " + redstone.getPosition().getBlockX(), clickType -> {
new SimulatorAnvilGui<>(player, "X", redstone.getPosition().getBlockX() + "", Integer::parseInt, i -> {
redstone.getPosition().setX(i);
SimulatorWatcher.update(simulator);
return true;
}, this).open();
}));
inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
redstone.move(clickType.isShiftClick() ? -5 : -1, 0, 0);
SimulatorWatcher.update(simulator);
});
//Pos Y
inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
redstone.move(0, clickType.isShiftClick() ? 5 : 1, 0);
SimulatorWatcher.update(simulator);
});
inventory.setItem(25, new SWItem(Material.PAPER, "§eY§8:§7 " + redstone.getPosition().getBlockY(), clickType -> {
new SimulatorAnvilGui<>(player, "Y", redstone.getPosition().getBlockY() + "", Integer::parseInt, i -> {
redstone.getPosition().setY(i);
SimulatorWatcher.update(simulator);
return true;
}, this).open();
}));
inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
redstone.move(0, clickType.isShiftClick() ? -5 : -1, 0);
SimulatorWatcher.update(simulator);
});
//Pos Z
inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
redstone.move(0, 0, clickType.isShiftClick() ? 5 : 1);
SimulatorWatcher.update(simulator);
});
inventory.setItem(26, new SWItem(Material.PAPER, "§eZ§8:§7 " + redstone.getPosition().getBlockZ(), clickType -> {
new SimulatorAnvilGui<>(player, "Z", redstone.getPosition().getBlockZ() + "", Integer::parseInt, i -> {
redstone.getPosition().setZ(i);
SimulatorWatcher.update(simulator);
return true;
}, this).open();
}));
inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
redstone.move(0, 0, clickType.isShiftClick() ? -5 : -1);
SimulatorWatcher.update(simulator);
});
}
}

Datei anzeigen

@ -1,79 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.gui;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.SimulatorCommand;
import de.steamwar.bausystem.features.simulator.SimulatorStorage;
import de.steamwar.bausystem.features.simulator.TNTSimulator;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
@UtilityClass
public class SimulatorSelectionGUI {
public void open(Player player, ItemStack hand) {
List<SWListInv.SWListEntry<TNTSimulator>> swListEntryList = new ArrayList<>();
for (String name : SimulatorStorage.getSimulatorNames()) {
TNTSimulator simulator = SimulatorStorage.getSimulator(name);
SWItem swItem = new SWItem(simulator.getMaterial(), "§f" + name, new ArrayList<>(), false, null);
swListEntryList.add(new SWListInv.SWListEntry<>(swItem, simulator));
}
SWListInv<TNTSimulator> inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SIMULATOR_GUI_SELECT_SIM", player), false, swListEntryList, (clickType, tntSimulator) -> {
TNTSimulator current = SimulatorStorage.getSimulator(hand);
if (current != null) {
current.hide(player);
}
SimulatorStorage.setSimulator(player, hand, tntSimulator);
player.getInventory().setItemInMainHand(hand);
player.closeInventory();
});
inv.setItem(49, new SWItem(Material.NAME_TAG, BauSystem.MESSAGE.parse("SIMULATOR_GUI_CREATE_SIM", player), clickType -> {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("SIMULATOR_GUI_CREATE_SIM_GUI", player), "");
swAnvilInv.setItem(Material.PAPER);
swAnvilInv.setCallback(s -> {
player.closeInventory();
if (SimulatorCommand.createSimulator(player, s)) {
TNTSimulator current = SimulatorStorage.getSimulator(hand);
if (current != null) {
current.hide(player);
}
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(s);
SimulatorStorage.setSimulator(player, hand, tntSimulator);
player.getInventory().setItemInMainHand(hand);
}
});
swAnvilInv.open();
}));
inv.open();
}
}

Datei anzeigen

@ -0,0 +1,99 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.Arrays;
public class SimulatorSettingsGui extends SimulatorBaseGui {
private final SimulatorBaseGui back;
public SimulatorSettingsGui(Player player, Simulator simulator, SimulatorBaseGui back) {
super(player, simulator, 5 * 9);
this.back = back;
}
@Override
public String title() {
return simulator.getName() + " Settings";
}
@Override
public void populate() {
// Back Arrow
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
back.open();
}));
// Material Chooser
inventory.setItem(4, simulator.toItem(player, clickType -> {
new SimulatorMaterialGui(player, simulator, simulator::getMaterial, simulator::setMaterial, this).open();
}));
//AutoTrace
inventory.setItem(20, new SWItem(simulator.isAutoTrace() ? Material.CHAIN_COMMAND_BLOCK : Material.COMMAND_BLOCK, "§eAutoTrace§8: " + (simulator.isAutoTrace() ? "§aOn" : "§cOff"), clickType -> {
simulator.setAutoTrace(!simulator.isAutoTrace());
SimulatorWatcher.update(simulator);
}));
//Pos X
inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
simulator.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
SimulatorWatcher.update(simulator);
});
inventory.setItem(24, new SWItem(Material.PAPER, "§eX", clickType -> {
}));
inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
simulator.move(clickType.isShiftClick() ? -5 : -1, 0, 0);
SimulatorWatcher.update(simulator);
});
//Pos Y
inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
simulator.move(0, clickType.isShiftClick() ? 5 : 1, 0);
SimulatorWatcher.update(simulator);
});
inventory.setItem(25, new SWItem(Material.PAPER, "§eY", clickType -> {
}));
inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
simulator.move(0, clickType.isShiftClick() ? -5 : -1, 0);
SimulatorWatcher.update(simulator);
});
//Pos Z
inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
simulator.move(0, 0, clickType.isShiftClick() ? 5 : 1);
SimulatorWatcher.update(simulator);
});
inventory.setItem(26, new SWItem(Material.PAPER, "§eZ", clickType -> {
}));
inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
simulator.move(0, 0, clickType.isShiftClick() ? -5 : -1);
SimulatorWatcher.update(simulator);
});
}
}

Datei anzeigen

@ -0,0 +1,162 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
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.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import java.util.Arrays;
public class SimulatorTNTGui extends SimulatorScrollGui<TNTPhase> {
private TNTElement tnt;
private SimulatorGroup parent;
private SimulatorBaseGui back;
public SimulatorTNTGui(Player player, Simulator simulator, TNTElement tnt, SimulatorGroup parent, SimulatorBaseGui back) {
super(player, simulator, 6 * 9, tnt.getPhases());
this.tnt = tnt;
this.parent = parent;
this.back = back;
}
@Override
public String baseTitle() {
return "TNT";
}
@Override
public void headerAndFooter() {
if (tnt.getPhases().isEmpty()) {
back.open();
SimulatorWatcher.update(simulator);
return;
}
tnt.sort();
// Back Arrow
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
if (parent.getElements().contains(tnt)) {
back.open();
} else {
SimulatorGroup newParent = tnt.getGroup(simulator);
if (newParent == null) {
player.closeInventory();
return;
}
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
if (newParent.getElements().size() == 1) {
simulatorGui.open();
} else {
new SimulatorGroupGui(player, simulator, newParent, simulatorGui).open();
}
}
}));
inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> {
tnt.getPhases().clear();
SimulatorWatcher.update(simulator);
}));
// Material Chooser
inventory.setItem(4, tnt.toItem(player, clickType -> {
new SimulatorMaterialGui(player, simulator, tnt::getMaterial, tnt::setMaterial, this).open();
}));
inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> {
new SimulatorTNTSettingsGui(player, simulator, tnt, this).open();
}));
inventory.setItem(48, new SWItem(Material.LEAD, "§eJoin Group", clickType -> {
new SimulatorGroupChooserGui(player, simulator, tnt, tnt.getGroup(simulator), this).open();
}));
inventory.setItem(50, new SWItem(Material.CHEST, parent.getElements().size() == 1 ? "§eMake Group" : "§eAdd another TNT to Group", clickType -> {
TNTElement tntElement = new TNTElement(tnt.getPosition().clone());
tntElement.add(new TNTPhase());
parent.add(tntElement);
new SimulatorGroupGui(player, simulator, parent, new SimulatorGui(player, simulator)).open();
SimulatorWatcher.update(simulator);
}));
inventory.setItem(51, new SWItem(tnt.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, tnt.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> {
tnt.setDisabled(!tnt.isDisabled());
SimulatorWatcher.update(simulator);
}));
}
@Override
public SWItem[] column(TNTPhase tntSetting, int index) {
SWItem tnt = new SWItem(Material.TNT, "§eTNT§8:§7 " + tntSetting.getCount(), Arrays.asList("§7Tick§8: §e" + tntSetting.getTickOffset(), "§7Fuse§8:§e " + tntSetting.getLifetime(), "", "§7Order§8:§e " + tntSetting.getOrder(), "", "§7X-Jump§8: " + (tntSetting.isXJump() ? "§aOn" : "§cOff"), "§7Y-Jump§8: " + (tntSetting.isYJump() ? "§aOn" : "§cOff"), "§7Z-Jump§8: " + (tntSetting.isZJump() ? "§aOn" : "§cOff"), "", "§7Click§8:§e Edit", "§7Middle-Click§8:§e Remove"), false, clickType -> {
if (clickType == ClickType.MIDDLE) {
this.tnt.getPhases().remove(tntSetting);
SimulatorWatcher.update(simulator);
} else {
new SimulatorTNTPhaseSettingsGui(player, simulator, this.tnt, tntSetting, this).open();
}
});
tnt.getItemStack().setAmount(Math.min(tntSetting.getCount(), 64));
return new SWItem[]{
new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
tntSetting.setCount(tntSetting.getCount() + (clickType.isShiftClick() ? 5 : 1));
SimulatorWatcher.update(simulator);
}),
tnt,
new SWItem(SWItem.getDye(tntSetting.getCount() > 1 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
tntSetting.setCount(Math.max(1, tntSetting.getCount() - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
}),
new SWItem(Material.ANVIL, "§eEdit Phase", clickType -> {
new SimulatorTNTPhaseSettingsGui(player, simulator, this.tnt, tntSetting, this).open();
}),
};
}
@Override
public SWItem[] lastColumn() {
return new SWItem[]{
new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
addNewPhase(clickType.isShiftClick());
}),
new SWItem(Material.GUNPOWDER, "§eTNT§8:§a New Phase", clickType -> {
addNewPhase(false);
}),
new SWItem(SWItem.getDye(8), "§7", clickType -> {
}),
};
}
private void addNewPhase(boolean shift) {
TNTPhase lastElement = tnt.getPhases().get(tnt.getPhases().size() - 1);
TNTPhase newPhase = new TNTPhase(lastElement.getTickOffset() + 1);
if (shift) newPhase.setCount(newPhase.getCount() + 5);
scroll++;
tnt.add(newPhase);
SimulatorWatcher.update(simulator);
}
}

Datei anzeigen

@ -0,0 +1,196 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
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.simulator.gui.base.SimulatorAnvilGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.core.Core;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.Arrays;
public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
private final TNTElement tntElement;
private final TNTPhase tnt;
private final SimulatorBaseGui back;
public SimulatorTNTPhaseSettingsGui(Player player, Simulator simulator, TNTElement tntElement, TNTPhase tnt, SimulatorBaseGui back) {
super(player, simulator, 5 * 9);
this.tntElement = tntElement;
this.tnt = tnt;
this.back = back;
}
@Override
public String title() {
return "TNT";
}
@Override
public void populate() {
if (!tntElement.getPhases().contains(tnt)) {
back.open();
return;
}
// Back Arrow
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
back.open();
}));
// Material Chooser
inventory.setItem(4, tntElement.toItem(player, clickType -> {
new SimulatorMaterialGui(player, simulator, tntElement::getMaterial, tntElement::setMaterial, this).open();
}));
//Delete
inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> {
tntElement.getPhases().remove(tnt);
back.open();
SimulatorWatcher.update(simulator);
}));
//Count
int count = tnt.getCount();
inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
tnt.setCount(count + (clickType.isShiftClick() ? 5 : 1));
SimulatorWatcher.update(simulator);
});
SWItem countItem = new SWItem(Material.TNT, "§eCount§8:§7 " + count, clickType -> {
new SimulatorAnvilGui<>(player, "Count", count + "", Integer::parseInt, integer -> {
if (integer < 0) return false;
tnt.setCount(integer);
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(Material.TNT).open();
});
countItem.getItemStack().setAmount(Math.max(1, Math.min(count, 64)));
inventory.setItem(18, countItem);
inventory.setItem(27, SWItem.getDye(count > 1 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
tnt.setCount(Math.max(1, count - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
//Tick Offset
int offset = tnt.getTickOffset();
inventory.setItem(10, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
tnt.setTickOffset(offset + (clickType.isShiftClick() ? 5 : 1));
SimulatorWatcher.update(simulator);
});
SWItem offsetItem = new SWItem(Material.REPEATER, "§eStart at§8:§7 " + offset, clickType -> {
new SimulatorAnvilGui<>(player, "Start at", offset + "", Integer::parseInt, integer -> {
if (integer < 0) return false;
tnt.setTickOffset(integer);
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(Material.REPEATER).open();
});
offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64)));
inventory.setItem(19, offsetItem);
inventory.setItem(28, SWItem.getDye(offset > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
tnt.setTickOffset(Math.max(0, offset - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
//Lifetime
int lifetime = tnt.getLifetime();
inventory.setItem(11, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
tnt.setLifetime(lifetime + (clickType.isShiftClick() ? 5 : 1));
SimulatorWatcher.update(simulator);
});
SWItem lifetimeItem = new SWItem(Material.CLOCK, "§eLifetime§8:§7 " + lifetime, clickType -> {
new SimulatorAnvilGui<>(player, "Lifetime", lifetime + "", Integer::parseInt, integer -> {
if (integer < 1) return false;
tnt.setLifetime(integer);
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(Material.CLOCK).open();
});
lifetimeItem.getItemStack().setAmount(Math.max(1, Math.min(lifetime, 64)));
inventory.setItem(20, lifetimeItem);
inventory.setItem(29, SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
tnt.setLifetime(Math.max(1, lifetime - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
//Order
int order = tnt.getOrder();
inventory.setItem(13, SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
tnt.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
Material negativeNumbers = Material.getMaterial(Core.getVersion() >= 19 ? "RECOVERY_COMPASS" : "FIREWORK_STAR");
SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : negativeNumbers, "§eCalculation Order§8:§7 " + order, clickType -> {
new SimulatorAnvilGui<>(player, "Calculation Order", order + "", Integer::parseInt, integer -> {
if (integer < -SimulatorPhase.ORDER_LIMIT) return false;
if (integer > SimulatorPhase.ORDER_LIMIT) return false;
tnt.setOrder(integer);
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(order >= 0 ? Material.COMPASS : negativeNumbers).open();
});
orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30)));
inventory.setItem(22, orderItem);
inventory.setItem(31, SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
tnt.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
SimulatorWatcher.update(simulator);
});
//Jump
SWItem jumpX = new SWItem(tnt.isXJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump X§8: " + (tnt.isZJump() ? "§aon" : "§coff"), clickType -> {
tnt.setXJump(!tnt.isXJump());
SimulatorWatcher.update(simulator);
});
inventory.setItem(33, jumpX);
SWItem jumpY = new SWItem(tnt.isYJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump Y§8: " + (tnt.isYJump() ? "§aon" : "§coff"), clickType -> {
tnt.setYJump(!tnt.isYJump());
SimulatorWatcher.update(simulator);
});
inventory.setItem(16, jumpY);
SWItem jumpZ = new SWItem(tnt.isZJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump Z§8: " + (tnt.isZJump() ? "§aon" : "§coff"), clickType -> {
tnt.setZJump(!tnt.isZJump());
SimulatorWatcher.update(simulator);
});
inventory.setItem(35, jumpZ);
SWItem jumpAll = new SWItem(Material.TNT, "§7TNT §eJump §8: " + (tnt.hasJump() ? "§aon" : "§coff"), clickType -> {
tnt.setJump(!tnt.hasJump());
SimulatorWatcher.update(simulator);
});
inventory.setItem(25, jumpAll);
}
}

Datei anzeigen

@ -0,0 +1,179 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SimulatorTNTSettingsGui extends SimulatorBaseGui {
private final TNTElement tnt;
private final SimulatorBaseGui back;
public SimulatorTNTSettingsGui(Player player, Simulator simulator, TNTElement tnt, SimulatorBaseGui back) {
super(player, simulator, 5 * 9);
this.tnt = tnt;
this.back = back;
}
@Override
public String title() {
return "TNT";
}
@Override
public void populate() {
if (tnt.getPhases().isEmpty()) {
back.open();
return;
}
// Back Arrow
inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
back.open();
}));
// Material Chooser
List<String> lore = new ArrayList<>();
lore.add("§7Phase count§8:§e " + tnt.getPhases().size());
lore.add("§7Tick§8:§e " + tnt.getBaseTick());
if (tnt.isDisabled()) {
lore.add("");
lore.add("§cDisabled");
}
inventory.setItem(4, tnt.toItem(player, clickType -> {
new SimulatorMaterialGui(player, simulator, tnt::getMaterial, tnt::setMaterial, this).open();
}));
// Base Tick
int baseTicks = tnt.getBaseTick();
inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
tnt.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
SimulatorWatcher.update(simulator);
});
SWItem baseTick = new SWItem(Material.REPEATER, "§eTicks§8:§7 " + baseTicks, clickType -> {
new SimulatorAnvilGui<>(player, "Ticks", baseTicks + "", Integer::parseInt, integer -> {
if (integer < 0) return false;
tnt.changeBaseTicks(integer - baseTicks);
SimulatorWatcher.update(simulator);
return true;
}, this).setItem(Material.REPEATER).open();
});
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
inventory.setItem(18, baseTick);
inventory.setItem(27, SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
tnt.changeBaseTicks(-baseTicks);
} else {
tnt.changeBaseTicks(clickType.isShiftClick() ? -5 : -1);
}
SimulatorWatcher.update(simulator);
});
// Subpixel Alignment
inventory.setItem(21, new SWItem(Material.SUNFLOWER, "§7Align§8: §eCenter", clickType -> {
tnt.align(new Vector(0.5, 0, 0.5));
SimulatorWatcher.update(simulator);
}));
// Z
inventory.setItem(20, new SWItem(Material.OAK_BUTTON, "§7Align§8: §eNegativ Z", clickType -> {
tnt.align(new Vector(0, 0, 0.49));
SimulatorWatcher.update(simulator);
}));
inventory.setItem(22, new SWItem(Material.OAK_BUTTON, "§7Align§8: §ePositiv Z", clickType -> {
tnt.align(new Vector(0, 0, 0.51));
SimulatorWatcher.update(simulator);
}));
// X
inventory.setItem(12, new SWItem(Material.STONE_BUTTON, "§7Align§8: §eNegativ X", clickType -> {
tnt.align(new Vector(0.49, 0, 0));
SimulatorWatcher.update(simulator);
}));
inventory.setItem(30, new SWItem(Material.STONE_BUTTON, "§7Align§8: §ePositiv X", clickType -> {
tnt.align(new Vector(0.51, 0, 0));
SimulatorWatcher.update(simulator);
}));
// Pos X
inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
tnt.move(clickType.isShiftClick() ? 0.0625 : 1, 0, 0);
SimulatorWatcher.update(simulator);
});
inventory.setItem(24, new SWItem(Material.PAPER, "§eX§8:§7 " + tnt.getPosition().getX(), clickType -> {
new SimulatorAnvilGui<>(player, "X", tnt.getPosition().getX() + "", Double::parseDouble, d -> {
tnt.getPosition().setX(d);
SimulatorWatcher.update(simulator);
return true;
}, this).open();
}));
inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
tnt.move(clickType.isShiftClick() ? -0.0625 : -1, 0, 0);
SimulatorWatcher.update(simulator);
});
// Pos Y
inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
tnt.move(0, clickType.isShiftClick() ? 0.0625 : 1, 0);
SimulatorWatcher.update(simulator);
});
inventory.setItem(25, new SWItem(Material.PAPER, "§eY§8:§7 " + tnt.getPosition().getY(), clickType -> {
new SimulatorAnvilGui<>(player, "Y", tnt.getPosition().getY() + "", Double::parseDouble, d -> {
tnt.getPosition().setY(d);
SimulatorWatcher.update(simulator);
return true;
}, this).open();
}));
inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
tnt.move(0, clickType.isShiftClick() ? -0.0625 : -1, 0);
SimulatorWatcher.update(simulator);
});
// Pos Z
inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
tnt.move(0, 0, clickType.isShiftClick() ? 0.0625 : 1);
SimulatorWatcher.update(simulator);
});
inventory.setItem(26, new SWItem(Material.PAPER, "§eZ§8:§7 " + tnt.getPosition().getZ(), clickType -> {
new SimulatorAnvilGui<>(player, "Z", tnt.getPosition().getZ() + "", Double::parseDouble, d -> {
tnt.getPosition().setZ(d);
SimulatorWatcher.update(simulator);
return true;
}, this).open();
}));
inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
tnt.move(0, 0, clickType.isShiftClick() ? -0.0625 : -1);
SimulatorWatcher.update(simulator);
});
}
}

Datei anzeigen

@ -1,390 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.gui;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.OrderUtils;
import de.steamwar.bausystem.features.simulator.SimulatorStorage;
import de.steamwar.bausystem.features.simulator.TNTSimulator;
import de.steamwar.bausystem.features.simulator.gui.components.ChangeMaterial;
import de.steamwar.bausystem.features.simulator.gui.components.ChangePosition;
import de.steamwar.bausystem.features.simulator.gui.components.Disabled;
import de.steamwar.bausystem.features.simulator.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.tnt.TNTGroup;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.util.Consumer;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static de.steamwar.bausystem.features.simulator.gui.ItemUtils.unique;
@UtilityClass
public class TNTElementGUI {
private SWInventory open(Player player, String name) {
SWInventory inv = new SWInventory(player, 45, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_GUI_NAME", player, name));
SWItem gray = new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§f", clickType -> {});
for (int i = 0; i < 9; i++) {
inv.setItem(i, gray);
inv.setItem(i + 36, gray);
}
return inv;
}
public void open(Player player, TNTElement tntElement, Runnable back) {
SWInventory inv = open(player, "");
if (back != null) {
inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run()));
}
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player);
Runnable editObserver = () -> {
List<String> locationLore = new ArrayList<>();
locationLore.add("");
locationLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_X", player, tntElement.getPosition().getX()));
locationLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Y", player, tntElement.getPosition().getY()));
locationLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Z", player, tntElement.getPosition().getZ()));
inv.setItem(20, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_LOCATION", player), locationLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
editLocation(player, tntElement, () -> open(player, tntElement, back));
}));
List<String> propertiesLore = new ArrayList<>();
propertiesLore.add("");
propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_COUNT", player, tntElement.getCount()));
propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK", player, tntElement.getTickOffset()));
propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_FUSE", player, tntElement.getFuseTicks()));
propertiesLore.add("");
propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_X", player, active(player, tntElement.isXVelocity())));
propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_Y", player, active(player, tntElement.isYVelocity())));
propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_Z", player, active(player, tntElement.isZVelocity())));
inv.setItem(22, new SWItem(Material.TNT, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_PROPERTIES", player), propertiesLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
editProperties(player, tntElement, () -> open(player, tntElement, back));
}));
List<String> otherLore = new ArrayList<>();
otherLore.add("");
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ACTIVATED_WITH", player, BauSystem.MESSAGE.parse(OrderUtils.name(tntElement.getOrder()), player)));
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_NAME_LORE", player, tntElement.getMaterial().name()));
if (tntElement.isDisabled()) {
otherLore.add("");
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_DISABLED", player));
}
inv.setItem(24, new SWItem(Material.ANVIL, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_OTHER", player), otherLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
editOther(player, tntElement, () -> open(player, tntElement, back));
}));
// Delete tnt
inv.setItem(44, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_REMOVE_TNT", player), clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntSimulator.remove(tntElement);
player.closeInventory();
}));
};
editObserver.run();
tntElement.register(editObserver, player::closeInventory);
inv.addCloseRunnable(() -> {
tntElement.unregister(editObserver);
});
inv.open();
}
private void editLocation(Player player, TNTElement tntElement, Runnable back) {
SWInventory inv = open(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_EDIT_LOCATION", player));
if (back != null) {
inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run()));
}
Runnable editObserver = () -> {
ChangePosition.show(inv, player, tntElement, vectorUnaryOperator -> {
if (tntElement.getParent() == null) {
tntElement.setPosition(vectorUnaryOperator.apply(tntElement.getPosition()));
} else {
tntElement.setPosition(vectorUnaryOperator.apply(tntElement.getPosition()).subtract(tntElement.getParent().getPosition()));
}
}, () -> editLocation(player, tntElement, back));
// Alignment
inv.setItem(23, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_NEGATIVE_Z", player), clickType -> { // Z negative
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0, 0, 0.49));
tntElement.change();
}));
inv.setItem(25, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_POSITIVE_Z", player), clickType -> { // Z positive
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0, 0, 0.51));
tntElement.change();
}));
inv.setItem(15, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_POSITIVE_X", player), clickType -> { // X positive
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0.51, 0, 0));
tntElement.change();
}));
inv.setItem(33, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_NEGATIVE_X", player), clickType -> { // X negative
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0.49, 0, 0));
tntElement.change();
}));
inv.setItem(24, new SWItem(Material.SUNFLOWER, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_CENTER", player), clickType -> { // CENTER
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0.5, 0, 0.5));
tntElement.change();
}));
};
editObserver.run();
tntElement.register(editObserver, player::closeInventory);
inv.addCloseRunnable(() -> {
tntElement.unregister(editObserver);
});
inv.open();
}
private void editProperties(Player player, TNTElement tntElement, Runnable back) {
SWInventory inv = open(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_EDIT_PROPERTIES", player));
if (back != null) {
inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run()));
}
String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player);
String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player);
List<String> plusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_FIVE_SHIFT", player));
List<String> minusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_FIVE_SHIFT", player));
List<String> lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player));
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player);
Runnable editObserver = () -> {
// Change Count of spawned TNT
inv.setItem(10, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOneFiveShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setCount(tntElement.getCount() + ((clickType.isShiftClick()) ? 5 : 1));
tntElement.change();
})));
SWItem countItem = new SWItem(Material.TNT, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_COUNT", player, tntElement.getCount()), lore, false, clickType -> changeCount(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_COUNT_ANVIL_GUI_NAME", player), tntElement.getCount(), c -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setCount(c);
tntElement.change();
editProperties(player, tntElement, back);
}, () -> editProperties(player, tntElement, back)));
countItem.getItemStack().setAmount(tntElement.getCount());
inv.setItem(19, countItem);
inv.setItem(28, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOneFiveShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setCount(tntElement.getCount() - ((clickType.isShiftClick()) ? 5 : 1));
tntElement.change();
})));
// Change TickOffset
inv.setItem(11, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOneFiveShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setTickOffset(tntElement.getOwnTickOffset() + (clickType.isShiftClick() ? 5 : 1));
tntElement.change();
})));
SWItem tickItem = new SWItem(SWItem.getMaterial("DIODE"), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK", player, tntElement.getTickOffset()), lore, false, clickType -> changeCount(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK_ANVIL_GUI_NAME", player), tntElement.getTickOffset(), tick -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setTickOffset(tick - tntElement.getParentTickOffset());
tntElement.change();
editProperties(player, tntElement, back);
}, () -> editProperties(player, tntElement, back)));
tickItem.getItemStack().setAmount(Math.max(tntElement.getTickOffset(), 1));
inv.setItem(20, tickItem);
inv.setItem(29, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOneFiveShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setTickOffset(tntElement.getOwnTickOffset() - (clickType.isShiftClick() ? 5 : 1));
tntElement.change();
})));
// Change FuseTicks
inv.setItem(12, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOneFiveShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setFuseTicks(tntElement.getFuseTicks() + (clickType.isShiftClick() ? 5 : 1));
tntElement.change();
})));
SWItem fuseTickItem = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_FUSE", player, tntElement.getFuseTicks()), lore, false, clickType -> changeCount(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_FUSE_ANVIL_GUI_NAME", player), tntElement.getFuseTicks(), tick -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setFuseTicks(tick);
tntElement.change();
editProperties(player, tntElement, back);
}, () -> editProperties(player, tntElement, back)));
fuseTickItem.getItemStack().setAmount(Math.max(tntElement.getFuseTicks(), 1));
inv.setItem(21, fuseTickItem);
inv.setItem(30, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOneFiveShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setFuseTicks(tntElement.getFuseTicks() - (clickType.isShiftClick() ? 5 : 1));
tntElement.change();
})));
// Velocity Settings
inv.setItem(24, Material.TNT, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_NAME", player), clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
if (tntElement.isXVelocity() || tntElement.isYVelocity() || tntElement.isZVelocity()) {
tntElement.setXVelocity(false);
tntElement.setYVelocity(false);
tntElement.setZVelocity(false);
} else {
tntElement.setXVelocity(true);
tntElement.setYVelocity(true);
tntElement.setZVelocity(true);
}
tntElement.change();
});
inv.setItem(32, new SWItem(getWool(tntElement.isXVelocity()), getColor(tntElement.isXVelocity()), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_X", player, active(player, tntElement.isXVelocity())), clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setXVelocity(!tntElement.isXVelocity());
tntElement.change();
}));
inv.setItem(15, new SWItem(getWool(tntElement.isYVelocity()), getColor(tntElement.isYVelocity()), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_Y", player, active(player, tntElement.isYVelocity())), clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setYVelocity(!tntElement.isYVelocity());
tntElement.change();
}));
inv.setItem(34, new SWItem(getWool(tntElement.isZVelocity()), getColor(tntElement.isZVelocity()), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_Z", player, active(player, tntElement.isZVelocity())), clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.setZVelocity(!tntElement.isZVelocity());
tntElement.change();
}));
};
editObserver.run();
tntElement.register(editObserver, player::closeInventory);
inv.addCloseRunnable(() -> {
tntElement.unregister(editObserver);
});
inv.open();
}
private void editOther(Player player, TNTElement tntElement, Runnable back) {
SWInventory inv = open(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_EDIT_OTHER", player));
if (back != null) {
inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run()));
}
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player);
Runnable editObserver = () -> {
inv.setItem(19, new SWItem(tntElement.getOrder(), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ACTIVATED_NAME", player), OrderUtils.orderList(tntElement.getOrder(), player), false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
if (clickType.isShiftClick()) {
tntElement.setOrder(OrderUtils.previous(tntElement.getOrder()));
} else {
tntElement.setOrder(OrderUtils.next(tntElement.getOrder()));
}
tntElement.change();
}));
ChangeMaterial.show(inv, player, 21, tntElement, Material.BARREL, () -> editOther(player, tntElement, back));
Disabled.show(inv, player, 22, tntSimulator, tntElement);
if (!tntElement.hasParent()) {
inv.setItem(24, new SWItem(Material.TNT, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ADD_IGNITION_PHASE", player), Arrays.asList(), false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
// Create TNTGroup
tntSimulator.getTntElementList().remove(tntElement);
Vector vector = tntElement.getOwnPosition().clone();
int tickOffset = tntElement.getOwnTickOffset();
TNTGroup tntGroup = new TNTGroup(vector);
tntGroup.setTickOffset(tickOffset);
tntGroup.add(tntElement);
tntElement.setTickOffset(0);
tntElement.setPosition(new Vector(0, 0, 0));
tntSimulator.getTntElementList().add(tntGroup);
// Add new TNT
TNTElement newElement = new TNTElement(new Vector(0, 0, 0), tntGroup, tntSimulator.getEntityServer());
newElement.setTickOffset(1);
tntGroup.add(newElement);
tntElement.change();
open(player, newElement, () -> TNTSimulatorGui.open(player, null, tntGroup, () -> new ArrayList<>(tntGroup.getElements()), () -> {
TNTSimulatorGui.open(player, tntSimulator, null, () -> new ArrayList<>(tntSimulator.getTntElementList()), null);
}));
}));
} else {
inv.setItem(24, new SWItem());
}
inv.setItem(25, new SWItem(Material.DISPENSER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ADD_TNT", player), clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
Vector vector = tntElement.getOwnPosition().clone();
TNTElement newElement = new TNTElement(vector, null, tntSimulator.getEntityServer());
if (tntElement.hasParent()) {
newElement.setTickOffset(tntElement.getOwnTickOffset() + 1);
tntElement.getParent().add(newElement);
open(player, newElement, () -> TNTSimulatorGui.open(player, null, tntElement.getParent(), () -> new ArrayList<>(tntElement.getParent().getElements()), () -> {
TNTSimulatorGui.open(player, tntSimulator, null, () -> new ArrayList<>(tntSimulator.getTntElementList()), null);
}));
} else {
tntSimulator.getTntElementList().add(newElement);
open(player, newElement, () -> TNTSimulatorGui.open(player, tntSimulator, null, tntSimulator::getTntElementList, null));
}
}));
// Delete tnt
inv.setItem(44, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_REMOVE_TNT", player), clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntSimulator.remove(tntElement);
player.closeInventory();
}));
};
editObserver.run();
tntElement.register(editObserver, player::closeInventory);
inv.addCloseRunnable(() -> {
tntElement.unregister(editObserver);
});
inv.open();
}
private String active(Player p, boolean active) {
return active ? BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_ON", p) : BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_OFF", p);
}
private Material getWool(boolean b) {
return b ? Material.LIME_WOOL : Material.RED_WOOL;
}
private byte getColor(boolean b) {
return (byte) (b ? 10 : 1);
}
private void changeCount(Player player, String name, int defaultValue, Consumer<Integer> result, Runnable failure) {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, name, defaultValue + "");
swAnvilInv.setItem(Material.PAPER);
swAnvilInv.setCallback(s -> {
try {
result.accept(Integer.parseInt(s));
} catch (NumberFormatException e) {
failure.run();
}
});
swAnvilInv.open();
}
}

Datei anzeigen

@ -1,198 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.gui;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.SimulatorStorage;
import de.steamwar.bausystem.features.simulator.TNTSimulator;
import de.steamwar.bausystem.features.simulator.gui.components.ChangeMaterial;
import de.steamwar.bausystem.features.simulator.gui.components.ChangePosition;
import de.steamwar.bausystem.features.simulator.gui.components.Disabled;
import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement;
import de.steamwar.bausystem.features.simulator.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.tnt.TNTGroup;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.util.Consumer;
import org.bukkit.util.Vector;
import java.util.Arrays;
import java.util.List;
import java.util.function.UnaryOperator;
import static de.steamwar.bausystem.features.simulator.gui.ItemUtils.unique;
@UtilityClass
public class TNTGroupEditGUI {
private static final Vector X_VECTOR = new Vector(0.0625, 0, 0);
private static final Vector Y_VECTOR = new Vector(0, 0.0625, 0);
private static final Vector Z_VECTOR = new Vector(0, 0, 0.0625);
private static final Vector FX_VECTOR = new Vector(1, 0, 0);
private static final Vector FY_VECTOR = new Vector(0, 1, 0);
private static final Vector FZ_VECTOR = new Vector(0, 0, 1);
public void open(Player player, TNTSimulator tntSimulator, List<SimulatorElement> simulatorElements, Runnable back) {
SWInventory inv = new SWInventory(player, 45, BauSystem.MESSAGE.parse("SIMULATOR_MOVE_ALL_GUI_NAME", player));
SWItem gray = new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§f", clickType -> {});
for (int i = 0; i < 9; i++) {
inv.setItem(i, gray);
inv.setItem(i + 36, gray);
}
if (back != null) {
inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run()));
}
String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player);
String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player);
List<String> plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player));
List<String> minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player));
List<String> lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player));
Vector vector = simulatorElements.get(0).getPosition();
// X Position
inv.setItem(12, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(simulatorElements, clickType.isShiftClick() ? X_VECTOR : FX_VECTOR);
tntSimulator.change();
})));
inv.setItem(21, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_X", player, vector.getX()), lore, false, clickType -> {}));
inv.setItem(30, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(simulatorElements, (clickType.isShiftClick() ? X_VECTOR : FX_VECTOR).clone().multiply(-1));
tntSimulator.change();
})));
// Y Position
inv.setItem(13, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(simulatorElements, clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR);
tntSimulator.change();
})));
inv.setItem(22, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Y", player, vector.getY()), lore, false, clickType -> {}));
inv.setItem(31, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(simulatorElements, (clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR).clone().multiply(-1));
tntSimulator.change();
})));
// Z Position
inv.setItem(14, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(simulatorElements, clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR);
tntSimulator.change();
})));
inv.setItem(23, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Z", player, vector.getZ()), lore, false, clickType -> {}));
inv.setItem(32, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(simulatorElements, (clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR).clone().multiply(-1));
})));
inv.open();
}
public void moveAll(List<SimulatorElement> simulatorElements, Vector vector) {
for (SimulatorElement element : simulatorElements) {
if (element instanceof TNTGroup) {
TNTGroup group = (TNTGroup) element;
group.setPosition(group.getPosition().add(vector));
} else if (element instanceof TNTElement) {
TNTElement tntElement = (TNTElement) element;
tntElement.setPosition(tntElement.getOwnPosition().add(vector));
}
}
}
public void open(Player player, TNTGroup tntGroup, Runnable back) {
SWInventory inv = new SWInventory(player, 45, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_GROUP_MENU", player));
SWItem gray = new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§f", clickType -> {});
for (int i = 0; i < 9; i++) {
inv.setItem(i, gray);
inv.setItem(i + 36, gray);
}
if (back != null) {
inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run()));
}
String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player);
String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player);
List<String> plusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_FIVE_SHIFT", player));
List<String> minusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_FIVE_SHIFT", player));
List<String> lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player));
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player);
Runnable editObserver = () -> {
ChangePosition.show(inv, player, tntGroup, vectorUnaryOperator -> {
tntGroup.setPosition(vectorUnaryOperator.apply(tntGroup.getPosition()));
}, () -> open(player, tntGroup, back));
ChangeMaterial.show(inv, player, 14, tntGroup, Material.BARREL, () -> open(player, tntGroup, back));
Disabled.show(inv, player, 32, tntSimulator, tntGroup);
// Change TickOffset
inv.setItem(16, new SWItem(SWItem.getDye(10), plusOneName, plusOneFiveShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntGroup.setTickOffset(tntGroup.getTickOffset() + (clickType.isShiftClick() ? 5 : 1));
tntGroup.change();
}));
SWItem tickItem = new SWItem(SWItem.getMaterial("DIODE"), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK", player, tntGroup.getTickOffset()), lore, false, clickType -> changeCount(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK_ANVIL_GUI_NAME", player), tntGroup.getTickOffset(), tick -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntGroup.setTickOffset(tick);
tntGroup.change();
open(player, tntGroup, back);
}, () -> open(player, tntGroup, back)));
tickItem.getItemStack().setAmount(Math.max(tntGroup.getTickOffset(), 1));
inv.setItem(25, tickItem);
inv.setItem(34, new SWItem(SWItem.getDye(1), minusOneName, minusOneFiveShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
tntGroup.setTickOffset(tntGroup.getTickOffset() - (clickType.isShiftClick() ? 5 : 1));
tntGroup.change();
}));
};
editObserver.run();
tntGroup.register(editObserver, player::closeInventory);
inv.addCloseRunnable(() -> {
tntGroup.unregister(editObserver);
});
inv.open();
}
private void changeCount(Player player, String name, int defaultValue, Consumer<Integer> result, Runnable failure) {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, name, defaultValue + "");
swAnvilInv.setItem(Material.PAPER);
swAnvilInv.setCallback(s -> {
try {
result.accept(Integer.parseInt(s));
} catch (NumberFormatException e) {
failure.run();
}
});
swAnvilInv.open();
}
}

Datei anzeigen

@ -1,216 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.gui;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.features.simulator.SimulatorStorage;
import de.steamwar.bausystem.features.simulator.TNTSimulator;
import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement;
import de.steamwar.bausystem.features.simulator.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.tnt.TNTGroup;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Supplier;
import static de.steamwar.bausystem.features.simulator.gui.ItemUtils.unique;
@UtilityClass
public class TNTSimulatorGui {
private static final Vector X_VECTOR = new Vector(0.0625, 0, 0);
private static final Vector Y_VECTOR = new Vector(0, 0.0625, 0);
private static final Vector Z_VECTOR = new Vector(0, 0, 0.0625);
private static final Vector FX_VECTOR = new Vector(1, 0, 0);
private static final Vector FY_VECTOR = new Vector(0, 1, 0);
private static final Vector FZ_VECTOR = new Vector(0, 0, 1);
public void open(Player player, TNTSimulator currentTntSimulator, TNTGroup currentTntGroup, Supplier<List<SimulatorElement>> simulatorElements, Runnable back) {
List<SWListInv.SWListEntry<SimulatorElement>> swListEntryList = new ArrayList<>();
int totalTNTCount = 0;
for (SimulatorElement element : simulatorElements.get()) {
swListEntryList.add(new SWListInv.SWListEntry<>(element.menu(player), element));
totalTNTCount += element.tntCount();
}
swListEntryList.sort(Comparator.comparing(o -> o.getObject().tick()));
SWListInv<SimulatorElement> inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SIMULATOR_GUI_NAME", player), false, swListEntryList, (clickType, simulatorElement) -> {
if (simulatorElement instanceof TNTGroup) {
TNTGroup tntGroup = (TNTGroup) simulatorElement;
open(player, null, tntGroup, () -> new ArrayList<>(tntGroup.getElements()), () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back));
} else {
TNTElementGUI.open(player, (TNTElement) simulatorElement, () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back));
}
});
if (back != null) {
inv.setItem(47, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run()));
}
SWItem swItem = new SWItem(Material.TNT_MINECART, BauSystem.MESSAGE.parse("SIMULATOR_GUI_TOTAL_TNT", player, totalTNTCount), clickType -> {
});
swItem.getItemStack().setAmount(totalTNTCount);
List<SimulatorElement> elements = simulatorElements.get();
inv.setItem(elements.isEmpty() ? 49 : 50, swItem);
if (currentTntGroup != null) {
Runnable editObserver = () -> {
List<String> otherLore = new ArrayList<>();
otherLore.add("");
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_X", player, currentTntGroup.getPosition().getX()));
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Y", player, currentTntGroup.getPosition().getY()));
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Z", player, currentTntGroup.getPosition().getZ()));
otherLore.add("");
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_NAME_LORE", player, currentTntGroup.getMaterial().name()));
otherLore.add("");
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK", player, currentTntGroup.getTickOffset()));
if (currentTntGroup.isDisabled()) {
otherLore.add("");
otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_DISABLED", player));
}
inv.setItem(48, new SWItem(Material.ANVIL, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_GROUP", player), otherLore, false, clickType -> {
TNTGroupEditGUI.open(player, currentTntGroup, () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back));
}));
};
editObserver.run();
currentTntGroup.register(editObserver, player::closeInventory);
inv.addCloseRunnable(() -> {
currentTntGroup.unregister(editObserver);
});
} else {
if (!elements.isEmpty()) {
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player);
inv.setItem(48, new SWItem(Material.ANVIL, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_GROUP", player), new ArrayList<>(), false, clickType -> {
TNTGroupEditGUI.open(player, tntSimulator, elements, () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back));
}));
}
}
if (currentTntSimulator != null) {
if (totalTNTCount > 0) {
inv.setItem(48, new SWItem(Material.MAGENTA_GLAZED_TERRACOTTA, BauSystem.MESSAGE.parse("SIMULATOR_GUI_MOVE_ALL", player), clickType -> {
moveAll(player, currentTntSimulator, () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back));
}));
}
boolean simulatorAutoTrace = Config.getInstance().get(player).getPlainValueOrDefault("simulatorAutoTrace", false);
inv.setItem(47, new SWItem(simulatorAutoTrace ? Material.CHAIN_COMMAND_BLOCK : Material.COMMAND_BLOCK, BauSystem.MESSAGE.parse("SIMULATOR_GUI_AUTO_TRACE", player, simulatorAutoTrace), clickType -> {
Config.getInstance().get(player).put("simulatorAutoTrace", !simulatorAutoTrace);
open(player, currentTntSimulator, currentTntGroup, simulatorElements, back);
}));
}
if (currentTntSimulator != null || currentTntGroup != null) {
inv.setItem(51, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("SIMULATOR_GUI_DELETE", player), clickType -> {
if (currentTntSimulator != null) {
currentTntSimulator.getTntElementList().forEach(SimulatorElement::close);
currentTntSimulator.clear();
player.closeInventory();
} else {
TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player);
tntSimulator.remove(currentTntGroup);
}
}));
}
inv.open();
}
public void moveAll(Player player, TNTSimulator tntSimulator, Runnable back) {
SWInventory inv = new SWInventory(player, 45, BauSystem.MESSAGE.parse("SIMULATOR_MOVE_ALL_GUI_NAME", player));
SWItem gray = new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§f", clickType -> {});
for (int i = 0; i < 9; i++) {
inv.setItem(i, gray);
inv.setItem(i + 36, gray);
}
if (back != null) {
inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run()));
}
String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player);
String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player);
List<String> plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player));
List<String> minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player));
List<String> lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player));
// X Position
inv.setItem(12, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(tntSimulator, clickType.isShiftClick() ? X_VECTOR : FX_VECTOR);
tntSimulator.change();
})));
inv.setItem(21, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_POSITION_X", player), lore, false, clickType -> {}));
inv.setItem(30, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(tntSimulator, (clickType.isShiftClick() ? X_VECTOR : FX_VECTOR).clone().multiply(-1));
tntSimulator.change();
})));
// Y Position
inv.setItem(13, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(tntSimulator, clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR);
tntSimulator.change();
})));
inv.setItem(22, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_POSITION_Y", player), lore, false, clickType -> {}));
inv.setItem(31, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(tntSimulator, (clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR).clone().multiply(-1));
tntSimulator.change();
})));
// Z Position
inv.setItem(14, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(tntSimulator, clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR);
tntSimulator.change();
})));
inv.setItem(23, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_POSITION_Z", player), lore, false, clickType -> {}));
inv.setItem(32, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
moveAll(tntSimulator, (clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR).clone().multiply(-1));
tntSimulator.change();
})));
inv.open();
}
public void moveAll(TNTSimulator tntSimulator, Vector vector) {
for (SimulatorElement element : tntSimulator.getTntElementList()) {
if (element instanceof TNTGroup) {
TNTGroup group = (TNTGroup) element;
group.setPosition(group.getPosition().add(vector));
} else if (element instanceof TNTElement) {
TNTElement tntElement = (TNTElement) element;
tntElement.setPosition(tntElement.getOwnPosition().add(vector));
}
}
}
}

Datei anzeigen

@ -0,0 +1,78 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui.base;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.inventory.SWAnvilInv;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
public class SimulatorAnvilGui<T extends Number> {
private SWAnvilInv anvilInv;
public SimulatorAnvilGui(Player player, String title, String defaultText, Function<String, T> mapper, Function<T, Boolean> value, SimulatorBaseGui back) {
if (defaultText == null) {
anvilInv = new SWAnvilInv(player, title);
} else {
anvilInv = new SWAnvilInv(player, title + ": " + defaultText);
}
AtomicBoolean error = new AtomicBoolean();
anvilInv.addCloseCallback(() -> {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
if (error.get()) {
anvilInv.open();
} else {
back.open();
}
error.set(false);
}, 0);
});
anvilInv.setCallback(s -> {
T t;
try {
t = mapper.apply(s);
} catch (NumberFormatException e) {
error.set(true);
return;
}
try {
if (!value.apply(t)) {
error.set(true);
}
} catch (Exception e) {
// Ignore
}
});
}
public SimulatorAnvilGui<T> setItem(Material material) {
anvilInv.setItem(material);
return this;
}
public void open() {
anvilInv.open();
}
}

Datei anzeigen

@ -0,0 +1,96 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui.base;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.core.Core;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
public abstract class SimulatorBaseGui {
protected final Player player;
protected final Simulator simulator;
private Inventory inv;
protected SWInventory inventory;
protected final int size;
protected SimulatorBaseGui(Player player, Simulator simulator, int size) {
this.player = player;
this.simulator = simulator;
this.size = size;
}
public final void open() {
String newTitle = title();
String originalTitle = player.getOpenInventory().getTitle();
if (inv != null && (Core.getVersion() > 19 || newTitle.equals(originalTitle))) {
// TODO: Flickering is better but not gone!
for (int i = 9; i < size - 9; i++) {
inv.setItem(i, null);
}
setup();
if (player.getOpenInventory().getTopInventory() != inv) {
inventory.open();
SimulatorWatcher.watch(player, simulator, this::open);
}
if (Core.getVersion() > 19) {
player.getOpenInventory().setTitle(title());
}
populate();
return;
}
player.getOpenInventory().close();
inventory = new SWInventory(player, () -> {
inv = Bukkit.createInventory(null, size, title());
return inv;
});
setup();
inventory.addCloseCallback(clickType -> {
SimulatorWatcher.watch(player, null, null);
});
inventory.open();
SimulatorWatcher.watch(player, simulator, this::open);
populate();
}
private void setup() {
for (int i = 0; i < 9; i++) {
inventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§8", clickType -> {
}));
inventory.setItem(size - 9 + i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§8", clickType -> {
}));
}
}
public abstract String title();
public abstract void populate();
}

Datei anzeigen

@ -0,0 +1,83 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui.base;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.core.Core;
import de.steamwar.inventory.SWItem;
import org.bukkit.entity.Player;
import java.util.List;
public abstract class SimulatorPageGui<T> extends SimulatorBaseGui {
protected int page = 0;
protected List<T> data;
protected SimulatorPageGui(Player player, Simulator simulator, int size, List<T> data) {
super(player, simulator, size);
this.data = data;
}
public final int maxPage() {
return data.size() / (size - 18);
}
@Override
public final String title() {
return baseTitle() + " " + (page + 1) + "/" + (maxPage() + 1);
}
@Override
public final void populate() {
headerAndFooter();
page = Math.min(page, maxPage());
inventory.setItem(size - 9, SWItem.getDye(page > 0 ? 10 : 8), page > 0 ? (byte) 10 : (byte) 8, Core.MESSAGE.parse(page > 0 ? "SWLISINV_PREVIOUS_PAGE_ACTIVE" : "SWLISINV_PREVIOUS_PAGE_INACTIVE", player), clickType -> {
if (page > 0) {
page--;
open();
}
});
boolean hasNext = page < maxPage() - (data.size() % (size - 18) == 0 ? 1 : 0);
inventory.setItem(size - 1, SWItem.getDye(hasNext ? 10 : 8), hasNext ? (byte) 10 : (byte) 8, Core.MESSAGE.parse(hasNext ? "SWLISINV_NEXT_PAGE_ACTIVE" : "SWLISINV_NEXT_PAGE_INACTIVE", player), clickType -> {
if (hasNext) {
page++;
open();
}
});
int minElement = page * (size - 18);
int maxElement = Math.min(data.size(), (page + 1) * (size - 18));
int index = 9;
for (int i = minElement; i < maxElement; i++) {
T element = data.get(i);
inventory.setItem(index++, convert(element));
}
}
public abstract String baseTitle();
public void headerAndFooter() {
}
public abstract SWItem convert(T t);
}

Datei anzeigen

@ -0,0 +1,94 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.gui.base;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.core.Core;
import de.steamwar.inventory.SWItem;
import org.bukkit.entity.Player;
import java.util.List;
public abstract class SimulatorScrollGui<T> extends SimulatorBaseGui {
protected int scroll = 0;
protected final List<T> data;
protected SimulatorScrollGui(Player player, Simulator simulator, int size, List<T> data) {
super(player, simulator, size);
this.data = data;
}
private int maxScroll() {
return Math.max(0, Math.min(scroll, data.size() - 9 + 1));
}
@Override
public final String title() {
return baseTitle() + " " + maxScroll() + "/" + Math.max((data.size() - 9 + 1), 0);
}
@Override
public final void populate() {
headerAndFooter();
scroll = maxScroll();
inventory.setItem(size - 9, SWItem.getDye(scroll > 0 ? 10 : 8), scroll > 0 ? (byte) 10 : (byte) 8, Core.MESSAGE.parse(scroll > 0 ? "SWLISINV_PREVIOUS_PAGE_ACTIVE" : "SWLISINV_PREVIOUS_PAGE_INACTIVE", player), clickType -> {
if (scroll > 0) {
scroll = Math.max(0, scroll - 9);
open();
}
});
boolean hasNext = (data.size() + 1) - scroll > 9;
inventory.setItem(size - 1, SWItem.getDye(hasNext ? 10 : 8), hasNext ? (byte) 10 : (byte) 8, Core.MESSAGE.parse(hasNext ? "SWLISINV_NEXT_PAGE_ACTIVE" : "SWLISINV_NEXT_PAGE_INACTIVE", player), clickType -> {
if (hasNext) {
scroll = Math.min(scroll + 9, data.size() + 1 - 9);
open();
}
});
for (int i = 0; i < 9; i++) {
if (scroll + i < data.size()) {
T element = data.get(scroll + i);
SWItem[] column = column(element, scroll + i);
populateColumn(column, i);
} else {
SWItem[] column = lastColumn();
populateColumn(column, i);
break;
}
}
}
public abstract String baseTitle();
public void headerAndFooter() {
}
public void populateColumn(SWItem[] column, int index) {
for (int j = 0; j < column.length; j++) {
inventory.setItem(index + j * 9 + 9, column[j]);
}
}
public abstract SWItem[] column(T t, int index);
public abstract SWItem[] lastColumn();
}

Datei anzeigen

@ -1,66 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.gui.components;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@UtilityClass
public class ChangeMaterial {
private static final List<Material> MATERIALS = new ArrayList<>();
static {
Arrays.stream(Material.values())
.filter(Material::isItem)
.filter(material -> !material.isLegacy())
.forEach(MATERIALS::add);
}
public void show(SWInventory inv, Player player, int position, SimulatorElement simulatorElement, Material defaultMaterial, Runnable back) {
inv.setItem(position, new SWItem(simulatorElement.getMaterial(), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_MATERIAL", player), Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_MATERIAL_LORE_1", player, simulatorElement.getMaterial().name().toLowerCase()), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_MATERIAL_LORE_2", player), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_MATERIAL_LORE_3", player)), false, clickType -> {
if (clickType.isLeftClick()) {
List<SWListInv.SWListEntry<Material>> swListEntries = new ArrayList<>();
MATERIALS.forEach(current -> {
swListEntries.add(new SWListInv.SWListEntry<>(new SWItem(current, BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_NAME", player, current.name().toLowerCase()), Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_CLICK", player)), false, ignored -> {
}), current));
});
SWListInv<Material> swListInv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_GUI_NAME", player), false, swListEntries, (invClickType, material) -> {
simulatorElement.setMaterial(material);
simulatorElement.change();
back.run();
});
swListInv.open();
} else {
simulatorElement.setMaterial(defaultMaterial);
simulatorElement.change();
}
}));
}
}

Datei anzeigen

@ -1,163 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.gui.components;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.TNTSimulator;
import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.util.Consumer;
import org.bukkit.util.Vector;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import static de.steamwar.bausystem.features.simulator.gui.ItemUtils.unique;
@UtilityClass
public class ChangePosition {
private static final Vector X_VECTOR = new Vector(0.0625, 0, 0);
private static final Vector Y_VECTOR = new Vector(0, 0.0625, 0);
private static final Vector Z_VECTOR = new Vector(0, 0, 0.0625);
private static final Vector FX_VECTOR = new Vector(1, 0, 0);
private static final Vector FY_VECTOR = new Vector(0, 1, 0);
private static final Vector FZ_VECTOR = new Vector(0, 0, 1);
public void show(SWInventory inv, Player player, SimulatorElement simulatorElement, Consumer<UnaryOperator<Vector>> toChangeVector, Runnable back) {
String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player);
String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player);
List<String> plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player));
List<String> minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player));
List<String> lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player));
// X Position
inv.setItem(10, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
toChangeVector.accept(vector -> {
vector.add(clickType.isShiftClick() ? X_VECTOR : FX_VECTOR);
return vector;
});
simulatorElement.change();
})));
inv.setItem(19, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_X", player, simulatorElement.getPosition().getX()), lore, false, clickType -> {
changePosition(player, simulatorElement.getPosition().getX(), x -> {
toChangeVector.accept(vector -> {
vector.setX(clamp(x));
return vector;
});
simulatorElement.change();
back.run();
}, back);
}));
inv.setItem(28, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
toChangeVector.accept(vector -> {
vector.subtract(clickType.isShiftClick() ? X_VECTOR : FX_VECTOR);
return vector;
});
simulatorElement.change();
})));
// Y Position
inv.setItem(11, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
toChangeVector.accept(vector -> {
vector.add(clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR);
return vector;
});
simulatorElement.change();
})));
inv.setItem(20, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Y", player, simulatorElement.getPosition().getY()), lore, false, clickType -> {
changePosition(player, simulatorElement.getPosition().getY(), y -> {
toChangeVector.accept(vector -> {
vector.setY(clamp(y));
return vector;
});
simulatorElement.change();
back.run();
}, back);
}));
inv.setItem(29, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
toChangeVector.accept(vector -> {
vector.subtract(clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR);
return vector;
});
simulatorElement.change();
})));
// Z Position
inv.setItem(12, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
toChangeVector.accept(vector -> {
vector.add(clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR);
return vector;
});
simulatorElement.change();
})));
inv.setItem(21, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Z", player, simulatorElement.getPosition().getZ()), lore, false, clickType -> {
changePosition(player, simulatorElement.getPosition().getZ(), z -> {
toChangeVector.accept(vector -> {
vector.setZ(clamp(z));
return vector;
});
simulatorElement.change();
back.run();
}, back);
}));
inv.setItem(30, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> {
if (clickType == ClickType.DOUBLE_CLICK) return;
toChangeVector.accept(vector -> {
vector.subtract(clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR);
return vector;
});
simulatorElement.change();
})));
}
private double clamp(double d) {
return (int) (d * 10000) * 0.0001;
}
private void changePosition(Player player, double defaultValue, Consumer<Double> result, Runnable failure) {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_ANVIL_GUI_NAME", player), defaultValue + "");
swAnvilInv.setItem(Material.PAPER);
swAnvilInv.setCallback(s -> {
try {
result.accept(Double.parseDouble(s.replace(',', '.')));
} catch (NumberFormatException e) {
failure.run();
}
});
swAnvilInv.open();
}
}

Datei anzeigen

@ -1,42 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.gui.components;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.TNTSimulator;
import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
@UtilityClass
public class Disabled {
public void show(SWInventory inv, Player player, int position, TNTSimulator tntSimulator, SimulatorElement simulatorElement) {
inv.setItem(position, new SWItem(simulatorElement.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, BauSystem.MESSAGE.parse(simulatorElement.isDisabled() ? "SIMULATOR_TNT_SPAWN_DISABLED" : "SIMULATOR_TNT_SPAWN_ENABLED", player), new ArrayList<>(), !simulatorElement.isDisabled(), clickType -> {
simulatorElement.setDisabled(!simulatorElement.isDisabled());
simulatorElement.change();
}));
}
}

Datei anzeigen

@ -0,0 +1,129 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.storage;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import org.bukkit.Material;
import org.bukkit.util.Vector;
import yapion.exceptions.YAPIONException;
import yapion.hierarchy.types.YAPIONArray;
import yapion.hierarchy.types.YAPIONObject;
import yapion.parser.YAPIONParser;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
public class SimFormatSimulatorLoader implements SimulatorLoader {
@Override
public Optional<List<Simulator>> load(File file) {
if (!file.getName().endsWith(".sim")) {
return Optional.empty();
}
YAPIONObject yapionObject;
try {
yapionObject = YAPIONParser.parse(file);
} catch (YAPIONException | IOException e) {
return Optional.empty();
}
String name = file.getName().substring(0, file.getName().length() - ".sim".length());
Simulator simulator = new Simulator(name);
loadSimulator(yapionObject, simulator);
return Optional.of(Collections.singletonList(simulator));
}
private void loadSimulator(YAPIONObject simulatorObject, Simulator simulator) {
simulator.setMaterial(Material.valueOf(simulatorObject.getPlainValue("material")));
simulator.setAutoTrace(simulatorObject.getPlainValue("autoTrace"));
YAPIONArray groups = simulatorObject.getArray("groups");
groups.streamObject().forEach(groupObject -> {
SimulatorGroup simulatorGroup = new SimulatorGroup();
loadGroup(groupObject, simulatorGroup);
simulator.add(simulatorGroup);
});
}
private void loadGroup(YAPIONObject groupObject, SimulatorGroup group) {
group.setMaterial(Material.valueOf(groupObject.getPlainValue("material")));
group.setDisabled(groupObject.getPlainValue("disabled"));
YAPIONArray elements = groupObject.getArray("elements");
elements.streamObject().forEach(elementObject -> {
SimulatorElement<?> element;
Supplier<SimulatorPhase> phaseConstructor;
Vector position = new Vector(elementObject.getDouble("x"), elementObject.getDouble("y"), elementObject.getDouble("z"));
String type = elementObject.getPlainValue("type");
switch (type) {
case "TNT":
element = new TNTElement(position);
phaseConstructor = TNTPhase::new;
break;
case "Redstone":
element = new RedstoneElement(position);
phaseConstructor = RedstonePhase::new;
break;
default:
element = null;
phaseConstructor = null;
break;
}
if (element == null) {
return;
}
loadElement(elementObject, element, phaseConstructor);
group.add(element);
});
}
private void loadElement(YAPIONObject elementObject, SimulatorElement<?> element, Supplier<SimulatorPhase> phaseConstructor) {
element.setMaterial(Material.valueOf(elementObject.getPlainValue("material")));
element.setDisabled(elementObject.getPlainValue("disabled"));
element.loadExtra(elementObject);
YAPIONArray phases = elementObject.getArray("phases");
phases.streamObject().forEach(phaseObject -> {
SimulatorPhase phase = phaseConstructor.get();
loadPhase(phaseObject, phase);
((SimulatorElement) element).add(phase);
});
}
private void loadPhase(YAPIONObject phaseObject, SimulatorPhase phase) {
phase.setTickOffset(phaseObject.getPlainValue("tickOffset"));
phase.setLifetime(phaseObject.getPlainValue("lifetime"));
phase.setOrder(phaseObject.getPlainValue("order"));
phase.loadExtra(phaseObject);
}
}

Datei anzeigen

@ -0,0 +1,136 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.storage;
import de.steamwar.bausystem.features.simulator.data.Simulator;
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 org.bukkit.Material;
import org.bukkit.util.Vector;
import yapion.exceptions.YAPIONException;
import yapion.hierarchy.types.YAPIONArray;
import yapion.hierarchy.types.YAPIONObject;
import yapion.parser.YAPIONParser;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class SimulatorFormatSimulatorLoader implements SimulatorLoader {
@Override
public Optional<List<Simulator>> load(File file) {
if (!file.getName().endsWith(".simulator")) {
return Optional.empty();
}
YAPIONObject yapionObject;
try {
yapionObject = YAPIONParser.parse(file);
} catch (YAPIONException | IOException e) {
return Optional.empty();
}
String name = file.getName().substring(0, file.getName().length() - ".simulator".length());
Simulator simulator = new Simulator(name);
simulator.setMaterial(Material.valueOf(yapionObject.getStringOrDefault("material", "BARREL")));
YAPIONArray tntElements = yapionObject.getArrayOrDefault("tntElements", new YAPIONArray());
for (YAPIONObject element : tntElements.streamObject().collect(Collectors.toList())) {
if (element.containsKey("elements")) {
simulator.add(loadGroup(element));
} else {
simulator.add(loadElement(element));
}
}
file.delete();
return Optional.of(Collections.singletonList(simulator));
}
private SimulatorGroup loadGroup(YAPIONObject element) {
double x = element.getDoubleOrDefault("x", 0);
double y = element.getDoubleOrDefault("y", 0);
double z = element.getDoubleOrDefault("z", 0);
int tickOffset = element.getIntOrDefault("tickOffset", 0);
SimulatorGroup simulatorGroup = new SimulatorGroup();
simulatorGroup.setDisabled(element.getBooleanOrDefault("disabled", false));
YAPIONArray elements = element.getArrayOrDefault("elements", new YAPIONArray());
for (YAPIONObject e : elements.streamObject().collect(Collectors.toList())) {
simulatorGroup.add(loadElement(e, x, y, z, tickOffset));
}
return simulatorGroup;
}
private TNTElement loadElement(YAPIONObject element, double dx, double dy, double dz, int dTickOffset) {
TNTElement tntElement = new TNTElement(new Vector(element.getDouble("x") + dx, element.getDouble("y") + dy, element.getDouble("z") + dz));
tntElement.setDisabled(element.getBooleanOrDefault("disabled", false));
tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT")));
TNTPhase tntPhase = loadPhase(element);
tntPhase.setTickOffset(tntPhase.getTickOffset() + dTickOffset);
tntElement.add(tntPhase);
return tntElement;
}
private SimulatorGroup loadElement(YAPIONObject element) {
SimulatorGroup simulatorGroup = new SimulatorGroup();
TNTElement tntElement = new TNTElement(new Vector(element.getDouble("x"), element.getDouble("y"), element.getDouble("z")));
tntElement.setDisabled(element.getBooleanOrDefault("disabled", false));
tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT")));
simulatorGroup.add(tntElement);
tntElement.add(loadPhase(element));
return simulatorGroup;
}
private TNTPhase loadPhase(YAPIONObject element) {
TNTPhase tntPhase = new TNTPhase();
tntPhase.setLifetime(element.getIntOrDefault("fuseTicks", 80));
tntPhase.setCount(element.getIntOrDefault("count", 1));
tntPhase.setTickOffset(element.getIntOrDefault("tickOffset", 0));
tntPhase.setXJump(element.getBooleanOrDefault("xVelocity", false));
tntPhase.setYJump(element.getBooleanOrDefault("yVelocity", false));
tntPhase.setZJump(element.getBooleanOrDefault("zVelocity", false));
switch (element.getStringOrDefault("order", "REPEATER")) {
case "REPEATER":
tntPhase.setOrder(0);
break;
case "OBSERVER":
tntPhase.setOrder(1);
break;
case "COMPARATOR":
tntPhase.setOrder(2);
break;
}
return tntPhase;
}
}

Datei anzeigen

@ -0,0 +1,31 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.storage;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import java.io.File;
import java.util.List;
import java.util.Optional;
public interface SimulatorLoader {
Optional<List<Simulator>> load(File file);
}

Datei anzeigen

@ -0,0 +1,80 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.storage;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import lombok.experimental.UtilityClass;
import yapion.hierarchy.output.FileOutput;
import yapion.hierarchy.types.YAPIONArray;
import yapion.hierarchy.types.YAPIONObject;
import java.io.File;
import java.io.IOException;
@UtilityClass
public class SimulatorSaver {
public void saveSimulator(File directory, Simulator simulator) {
YAPIONObject simulatorObject = new YAPIONObject();
simulatorObject.add("material", simulator.getMaterial().name());
simulatorObject.add("autoTrace", simulator.isAutoTrace());
YAPIONArray groups = new YAPIONArray();
simulator.getGroups().forEach(group -> {
YAPIONObject groupObject = new YAPIONObject();
groupObject.add("material", group.getMaterial().name());
groupObject.add("disabled", group.isDisabled());
YAPIONArray elements = new YAPIONArray();
group.getElements().forEach(element -> {
YAPIONObject elementObject = new YAPIONObject();
elementObject.add("type", element.getType());
elementObject.add("material", element.getMaterial().name());
elementObject.add("disabled", element.isDisabled());
elementObject.add("x", element.getPosition().getX());
elementObject.add("y", element.getPosition().getY());
elementObject.add("z", element.getPosition().getZ());
element.saveExtra(elementObject);
YAPIONArray phases = new YAPIONArray();
element.getPhases().forEach(phase -> {
YAPIONObject phaseObject = new YAPIONObject();
phaseObject.add("tickOffset", phase.getTickOffset());
phaseObject.add("lifetime", phase.getLifetime());
phaseObject.add("order", phase.getOrder());
phase.saveExtra(phaseObject);
phases.add(phaseObject);
});
elementObject.add("phases", phases);
elements.add(elementObject);
});
groupObject.add("elements", elements);
groups.add(groupObject);
});
simulatorObject.add("groups", groups);
File file = new File(directory, simulator.getName() + ".sim");
try {
simulatorObject.toJSONLossy(new FileOutput(file)).close();
} catch (IOException e) {
// Ignore
}
}
}

Datei anzeigen

@ -0,0 +1,90 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.storage;
import de.steamwar.bausystem.features.simulator.data.Simulator;
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.sql.SteamwarUser;
import org.bukkit.Material;
import org.bukkit.util.Vector;
import yapion.exceptions.YAPIONException;
import yapion.hierarchy.types.YAPIONArray;
import yapion.hierarchy.types.YAPIONObject;
import yapion.parser.YAPIONParser;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class YAPIONFormatSimulatorLoader implements SimulatorLoader {
@Override
public Optional<List<Simulator>> load(File file) {
if (!file.getName().endsWith(".yapion")) {
return Optional.empty();
}
YAPIONObject yapionObject;
try {
yapionObject = YAPIONParser.parse(file);
} catch (YAPIONException | IOException e) {
return Optional.empty();
}
String name = file.getName().substring(0, file.getName().length() - 7);
SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(name));
List<Simulator> simulators = new ArrayList<>();
for (String s : yapionObject.getKeys()) {
String newName = steamwarUser.getUserName() + (s.isEmpty() ? "" : "_" + s);
YAPIONArray content = yapionObject.getArray(s);
if (content.isEmpty()) continue;
Simulator simulator = new Simulator(newName);
for (YAPIONObject element : content.streamObject().collect(Collectors.toList())) {
SimulatorGroup simulatorGroup = new SimulatorGroup();
simulator.add(simulatorGroup);
TNTElement tntElement = new TNTElement(new Vector(element.getDouble("positionX"), element.getDouble("positionY"), element.getDouble("positionZ")));
tntElement.setDisabled(element.getBooleanOrDefault("disabled", false)); // IDK if this existed back then?
tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT")));
simulatorGroup.add(tntElement);
TNTPhase tntPhase = new TNTPhase();
tntPhase.setLifetime(element.getIntOrDefault("fuseTicks", 80));
tntPhase.setCount(element.getIntOrDefault("count", 1));
tntPhase.setTickOffset(element.getIntOrDefault("tickOffset", 0));
tntPhase.setXJump(element.getBooleanOrDefault("xVelocity", false));
tntPhase.setYJump(element.getBooleanOrDefault("yVelocity", false));
tntPhase.setZJump(element.getBooleanOrDefault("zVelocity", false));
tntPhase.setOrder(element.getBooleanOrDefault("comparator", false) ? 2 : 0);
tntElement.add(tntPhase);
}
simulators.add(simulator);
}
file.delete();
return Optional.of(simulators);
}
}

Datei anzeigen

@ -1,90 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.tnt;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.shared.Pair;
import de.steamwar.entity.REntity;
import de.steamwar.inventory.SWItem;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import yapion.hierarchy.types.YAPIONObject;
import java.util.*;
public interface SimulatorElement {
Map<SimulatorElement, Set<Runnable>> observer = new HashMap<>();
Map<Runnable, Runnable> closeObserver = new HashMap<>();
YAPIONObject toYAPION();
List<REntity> getEntities();
void getEntity(List<SimulatorElement> elements, REntity entity);
Vector getPosition();
void setPosition(Vector position);
void remove(TNTElement tntElement);
SWItem menu(Player p);
boolean locations(Map<Integer, Map<Integer, Set<Pair<Runnable, Integer>>>> result, Region region, Location location); // Ticks to subtick order to spawning runnable to count of activations
int tntCount();
int tick();
// Observer
default void change() {
observer.getOrDefault(this, new HashSet<>()).forEach(Runnable::run);
if (this instanceof TNTGroup) {
((TNTGroup) this).getElements().forEach(SimulatorElement::change);
}
}
default void register(Runnable observer, Runnable close) {
SimulatorElement.observer.computeIfAbsent(this, k -> new HashSet<>()).add(observer);
SimulatorElement.closeObserver.put(observer, close);
}
default void unregister(Runnable observer) {
SimulatorElement.observer.computeIfPresent(this, (k, v) -> {
v.remove(observer);
return v.isEmpty() ? null : v;
});
SimulatorElement.closeObserver.remove(observer);
}
default void close() {
Set<Runnable> allRunnables = observer.remove(this);
if (allRunnables == null) return;
allRunnables.forEach(runnable -> {
Runnable closeRunnable = closeObserver.remove(runnable);
if (closeRunnable == null) return;
closeRunnable.run();
});
if (this instanceof TNTGroup) {
((TNTGroup) this).getElements().forEach(SimulatorElement::close);
}
}
// API
Material getMaterial();
void setMaterial(Material material);
boolean isDisabled();
void setDisabled(boolean disabled);
}

Datei anzeigen

@ -1,318 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.tnt;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.OrderUtils;
import de.steamwar.bausystem.features.simulator.SimulatorStorage;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.flagvalues.FreezeMode;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.bausystem.shared.Pair;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
import de.steamwar.inventory.SWItem;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.util.Vector;
import yapion.hierarchy.types.YAPIONObject;
import java.util.*;
@Getter
public class TNTElement implements SimulatorElement {
private static final World WORLD = Bukkit.getWorlds().get(0);
private final REntityServer entityServer;
private RFallingBlockEntity entity;
TNTGroup tntGroup = null;
private final Vector position;
private int fuseTicks = 80;
private int count = 1;
private int tickOffset = 0;
@Setter
private boolean xVelocity = false;
@Setter
private boolean yVelocity = false;
@Setter
private boolean zVelocity = false;
private Material order = Material.REPEATER;
private Material material = Material.TNT;
private boolean disabled = false;
public TNTElement(Vector position, TNTGroup tntGroup, REntityServer entityServer) {
this.entityServer = entityServer;
this.tntGroup = tntGroup;
this.position = position;
initEntity();
}
public TNTElement(YAPIONObject yapionObject, TNTGroup tntGroup, REntityServer entityServer) {
this.entityServer = entityServer;
this.tntGroup = tntGroup;
this.position = new Vector(yapionObject.getDoubleOrDefault("x", yapionObject.getDoubleOrDefault("positionX", 0)), yapionObject.getDoubleOrDefault("y", yapionObject.getDoubleOrDefault("positionY", 0)), yapionObject.getDoubleOrDefault("z", yapionObject.getDoubleOrDefault("positionZ", 0)));
this.disabled = yapionObject.getBooleanOrDefault("disabled", false);
this.fuseTicks = yapionObject.getIntOrDefault("fuseTicks", 80);
this.count = yapionObject.getIntOrDefault("count", 1);
this.tickOffset = yapionObject.getIntOrDefault("tickOffset", 0);
this.xVelocity = yapionObject.getBooleanOrDefault("xVelocity", false);
this.yVelocity = yapionObject.getBooleanOrDefault("yVelocity", false);
this.zVelocity = yapionObject.getBooleanOrDefault("zVelocity", false);
this.order = Material.valueOf(yapionObject.getStringOrDefault("order", yapionObject.getBooleanOrDefault("comparator", false) ? Material.COMPARATOR.name() : Material.REPEATER.name()));
this.material = Material.valueOf(yapionObject.getStringOrDefault("material", Material.TNT.name()));
initEntity();
}
private void initEntity() {
this.entity = new RFallingBlockEntity(entityServer, getPosition().toLocation(WORLD), Material.TNT);
this.entity.setNoGravity(true);
_updatePosition();
}
@Override
public YAPIONObject toYAPION() {
YAPIONObject yapionObject = new YAPIONObject();
yapionObject.add("x", position.getX());
yapionObject.add("y", position.getY());
yapionObject.add("z", position.getZ());
yapionObject.add("fuseTicks", fuseTicks);
yapionObject.add("count", count);
yapionObject.add("tickOffset", tickOffset);
yapionObject.add("xVelocity", xVelocity);
yapionObject.add("yVelocity", yVelocity);
yapionObject.add("zVelocity", zVelocity);
yapionObject.add("order", order.name());
yapionObject.add("material", material.name());
yapionObject.add("disabled", disabled);
return yapionObject;
}
@Override
public List<REntity> getEntities() {
if (disabled) return new ArrayList<>();
return Arrays.asList(entity);
}
@Override
public void getEntity(List<SimulatorElement> elements, REntity entity) {
if (disabled) return;
if (this.entity.getEntityId() == entity.getEntityId() || getPosition().distanceSquared(new Vector(entity.getX(), entity.getY(), entity.getZ())) < 0.01) {
elements.add(this);
}
}
@Override
public Vector getPosition() {
if (tntGroup != null) {
return tntGroup.getPosition().clone().add(position);
}
return position.clone();
}
@Override
public void setPosition(Vector position) {
this.position.setX(position.getX());
this.position.setY(position.getY());
this.position.setZ(position.getZ());
_updatePosition();
}
void _updatePosition() {
if (disabled || (getParent() != null && getParent().isDisabled())) {
entity.move(-200000, 0, -200000, 0F, 0F, (byte) 0);
} else {
Vector position = getPosition();
entity.move(position.getX(), position.getY(), position.getZ(), 0F, 0F, (byte) 0);
}
}
public int getTickOffset() {
if (tntGroup != null) {
return tntGroup.getTickOffset() + tickOffset;
}
return tickOffset;
}
@Override
public void remove(TNTElement tntElement) {
entity.die();
}
@Override
public SWItem menu(Player p) {
List<String> lore = new ArrayList<>();
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_1", p, count));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_2", p, getTickOffset()));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_3", p, getFuseTicks()));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_4", p));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_5", p, getPosition().getX()));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_6", p, getPosition().getY()));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_7", p, getPosition().getZ()));
if (disabled) {
lore.add("");
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_DISABLED", p));
}
SWItem swItem = new SWItem(material, BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_NAME", p), lore, disabled, null);
if (!disabled) swItem.getItemStack().setAmount(Math.max(tntCount(), 1));
return swItem;
}
@Override
public boolean locations(Map<Integer, Map<Integer, Set<Pair<Runnable, Integer>>>> result, Region region, Location radius) {
if (disabled) return false;
Location location = getPosition().toLocation(SimulatorStorage.WORLD);
if (region.isGlobal() && location.distanceSquared(radius) > 10000) {
return false;
}
if (!region.inRegion(location, RegionType.NORMAL, RegionExtensionType.NORMAL)) {
return false;
}
Region thisRegion = Region.getRegion(location);
if (thisRegion.getFlagStorage().get(Flag.FREEZE) == FreezeMode.ACTIVE) {
return true;
}
result.computeIfAbsent(getTickOffset(), ignore -> new HashMap<>())
.computeIfAbsent(OrderUtils.order(order), ignore -> new HashSet<>())
.add(new Pair<>(() -> {
SimulatorStorage.WORLD.spawn(location, TNTPrimed.class, tntPrimed -> {
tntPrimed.setFuseTicks(fuseTicks);
if (!xVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setX(0));
if (!yVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setY(0));
if (!zVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setZ(0));
});
}, count));
return false;
}
@Override
public int tntCount() {
return disabled ? 0 : count;
}
@Override
public int tick() {
return getTickOffset();
}
public void setCount(int count) {
if (count < 0) count = 0;
if (count > 400) count = 400;
this.count = count;
}
public int getOwnTickOffset() {
return tickOffset;
}
public int getParentTickOffset() {
if (tntGroup != null) {
return tntGroup.getTickOffset();
}
return 0;
}
public void setTickOffset(int tickOffset) {
if (getTickOffset() - this.tickOffset + tickOffset < 0) {
this.tickOffset = -this.getParentTickOffset();
return;
}
if (getTickOffset() - this.tickOffset + tickOffset > 400) {
this.tickOffset = 400 - this.getParentTickOffset();
return;
}
this.tickOffset = tickOffset;
}
public void setFuseTicks(int fuseTicks) {
if (fuseTicks < 0) fuseTicks = 0;
if (fuseTicks > 160) fuseTicks = 160;
this.fuseTicks = fuseTicks;
}
public Vector getOwnPosition() {
return position.clone();
}
public void setOrder(Material material) {
this.order = material;
}
public void setMaterial(Material material) {
this.material = material;
}
public boolean hasParent() {
return tntGroup != null;
}
public TNTGroup getParent() {
return tntGroup;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
_updatePosition();
}
public void align(Vector offset) {
Vector vector = getPosition();
Vector parentVector = new Vector(0, 0, 0);
if (tntGroup != null) {
parentVector = tntGroup.getPosition();
}
if (offset.getX() != 0) {
if (vector.getX() - (int) vector.getX() == 0.49) {
vector.setX(vector.getX() + 0.02);
}
if (vector.getX() - (int) vector.getX() == -0.49) {
vector.setX(vector.getX() - 0.02);
}
vector.setX(vector.getBlockX() + offset.getX());
}
if (offset.getZ() != 0) {
if (vector.getZ() - (int) vector.getZ() == 0.49) {
vector.setZ(vector.getZ() + 0.02);
}
if (vector.getZ() - (int) vector.getZ() == -0.49) {
vector.setZ(vector.getZ() - 0.02);
}
vector.setZ(vector.getBlockZ() + offset.getZ());
}
setPosition(vector.subtract(parentVector));
}
}

Datei anzeigen

@ -1,186 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.tnt;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.shared.Pair;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.inventory.SWItem;
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import yapion.hierarchy.types.YAPIONArray;
import yapion.hierarchy.types.YAPIONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Getter
public class TNTGroup implements SimulatorElement {
private final Vector position;
private int tickOffset = 0;
private Material material = Material.BARREL;
private boolean disabled = false;
private List<TNTElement> elements = new ArrayList<>();
public TNTGroup(Vector position) {
this.position = position;
}
public TNTGroup(YAPIONObject yapionObject, REntityServer entityServer) {
this.position = new Vector(yapionObject.getDoubleOrDefault("x", 0), yapionObject.getDoubleOrDefault("y", 0), yapionObject.getDoubleOrDefault("z", 0));
this.tickOffset = yapionObject.getIntOrDefault("tickOffset", 0);
this.material = Material.getMaterial(yapionObject.getStringOrDefault("material", "BARREL"));
this.disabled = yapionObject.getBooleanOrDefault("disabled", false);
YAPIONArray elements = yapionObject.getArrayOrDefault("elements", new YAPIONArray());
for (YAPIONObject element : elements.streamObject().collect(Collectors.toList())) {
TNTElement tntElement = new TNTElement(element, this, entityServer);
this.elements.add(tntElement);
tntElement._updatePosition();
}
}
@Override
public YAPIONObject toYAPION() {
YAPIONObject yapionObject = new YAPIONObject();
yapionObject.add("x", position.getX());
yapionObject.add("y", position.getY());
yapionObject.add("z", position.getZ());
yapionObject.add("tickOffset", tickOffset);
yapionObject.add("material", material.name());
yapionObject.add("disabled", disabled);
YAPIONArray yapionArray = new YAPIONArray();
for (TNTElement element : elements) {
yapionArray.add(element.toYAPION());
}
yapionObject.add("elements", yapionArray);
return yapionObject;
}
public void add(TNTElement tntElement) {
tntElement.tntGroup = this;
elements.add(tntElement);
}
@Override
public List<REntity> getEntities() {
if (disabled) new ArrayList<>();
return elements.stream().flatMap(tntElement -> tntElement.getEntities().stream()).collect(Collectors.toList());
}
@Override
public void getEntity(List<SimulatorElement> elements, REntity entity) {
if (disabled) return;
for (TNTElement tntElement : this.elements) {
tntElement.getEntity(elements, entity);
}
}
@Override
public Vector getPosition() {
return position.clone();
}
@Override
public void setPosition(Vector position) {
this.position.setX(position.getX());
this.position.setY(position.getY());
this.position.setZ(position.getZ());
elements.forEach(TNTElement::_updatePosition);
}
@Override
public void remove(TNTElement tntElement) {
if (elements.remove(tntElement)) {
tntElement.remove(tntElement);
}
}
@Override
public SWItem menu(Player p) {
List<String> lore = new ArrayList<>();
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_1", p, elements.size()));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_2", p, tickOffset));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_3", p));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_4", p, position.getX()));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_5", p, position.getY()));
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_6", p, position.getZ()));
if (disabled) {
lore.add("");
lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_DISABLED", p));
}
SWItem swItem = new SWItem(material, BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_NAME", p), lore, disabled, null);
if (!disabled) swItem.getItemStack().setAmount(Math.max(tntCount(), 1));
return swItem;
}
@Override
public boolean locations(Map<Integer, Map<Integer, Set<Pair<Runnable, Integer>>>> result, Region region, Location location) {
if (disabled) return false;
for (TNTElement element : elements) {
if (element.locations(result, region, location)) {
return true;
}
}
return false;
}
@Override
public int tntCount() {
if (disabled) return 0;
return elements.stream().mapToInt(TNTElement::tntCount).sum();
}
@Override
public int tick() {
return getTickOffset();
}
public void setTickOffset(int tickOffset) {
if (tickOffset < 0) tickOffset = 0;
if (tickOffset > 400) tickOffset = 400;
for (TNTElement tntElement : elements) {
if (tntElement.getTickOffset() - this.tickOffset + tickOffset < 0) {
tickOffset = Math.max(tickOffset, -tntElement.getOwnTickOffset());
}
if (tntElement.getTickOffset() - this.tickOffset + tickOffset > 400) {
tickOffset = Math.min(tickOffset, 400 - tntElement.getOwnTickOffset());
}
}
this.tickOffset = tickOffset;
}
public void setMaterial(Material material) {
this.material = material;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
elements.forEach(TNTElement::_updatePosition);
}
}

Datei anzeigen

@ -86,6 +86,10 @@ public class Recorder implements Listener {
return get(tntTraceRecorderMap.computeIfAbsent(tntPrimed, e -> Region.getRegion(e.getLocation())));
}
public boolean isDisabled(Region region) {
return !regionTraceRecorderMap.containsKey(region);
}
public TraceRecorder get(Region region) {
return regionTraceRecorderMap.getOrDefault(region, DISABLED);
}

Datei anzeigen

@ -36,7 +36,7 @@ public class SingleTraceRecorder extends AutoTraceRecorder {
@Override
protected boolean shouldStartRecording(StartType startType) {
return startType == StartType.EXPLODE;
return startType == StartType.IGNITE;
}
@Override

Datei anzeigen

@ -0,0 +1,36 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class TickEndEvent extends Event {
private static final HandlerList handlers = new HandlerList();
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

Datei anzeigen

@ -0,0 +1,31 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.core.VersionDependent;
public interface TickListener {
TickListener impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
default void init() {
}
}

Datei anzeigen

@ -0,0 +1,36 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class TickStartEvent extends Event {
private static final HandlerList handlers = new HandlerList();
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

Datei anzeigen

@ -37,8 +37,8 @@ version ''
compileJava.options.encoding = 'UTF-8'
compileJava.options.compilerArgs << '-parameter'
sourceCompatibility = 11
targetCompatibility = 11
sourceCompatibility = 17
targetCompatibility = 17
mainClassName = ''
@ -61,6 +61,10 @@ allprojects {
maven {
url = uri('https://libraries.minecraft.net')
}
maven {
url = uri("https://repo.papermc.io/repository/maven-public/")
}
}
}