diff --git a/BauSystem_15/build.gradle b/BauSystem_15/build.gradle
index 87ae1928..d0acd9b2 100644
--- a/BauSystem_15/build.gradle
+++ b/BauSystem_15/build.gradle
@@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
-sourceCompatibility = 1.8
-targetCompatibility = 1.8
+sourceCompatibility = 17
+targetCompatibility = 17
sourceSets {
main {
diff --git a/BauSystem_15/src/de/steamwar/bausystem/utils/TickListener15.java b/BauSystem_15/src/de/steamwar/bausystem/utils/TickListener15.java
new file mode 100644
index 00000000..f2b604ac
--- /dev/null
+++ b/BauSystem_15/src/de/steamwar/bausystem/utils/TickListener15.java
@@ -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 .
+ */
+
+package de.steamwar.bausystem.utils;
+
+public class TickListener15 implements TickListener {
+}
diff --git a/BauSystem_18/build.gradle b/BauSystem_18/build.gradle
index 8deb57fd..4ac724e0 100644
--- a/BauSystem_18/build.gradle
+++ b/BauSystem_18/build.gradle
@@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
-sourceCompatibility = 1.8
-targetCompatibility = 1.8
+sourceCompatibility = 17
+targetCompatibility = 17
sourceSets {
main {
diff --git a/BauSystem_19/build.gradle b/BauSystem_19/build.gradle
index fb86e3ac..7973f1b0 100644
--- a/BauSystem_19/build.gradle
+++ b/BauSystem_19/build.gradle
@@ -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'
diff --git a/BauSystem_19/src/de/steamwar/bausystem/utils/TickListener19.java b/BauSystem_19/src/de/steamwar/bausystem/utils/TickListener19.java
new file mode 100644
index 00000000..5191b38b
--- /dev/null
+++ b/BauSystem_19/src/de/steamwar/bausystem/utils/TickListener19.java
@@ -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 .
+ */
+
+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;
+ }
+}
diff --git a/BauSystem_20/build.gradle b/BauSystem_20/build.gradle
index bfb7c724..17121b8d 100644
--- a/BauSystem_20/build.gradle
+++ b/BauSystem_20/build.gradle
@@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
-sourceCompatibility = 1.8
-targetCompatibility = 1.8
+sourceCompatibility = 17
+targetCompatibility = 17
sourceSets {
main {
diff --git a/BauSystem_Linkage/build.gradle b/BauSystem_Linkage/build.gradle
index 2169557f..7b54641a 100644
--- a/BauSystem_Linkage/build.gradle
+++ b/BauSystem_Linkage/build.gradle
@@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
-sourceCompatibility = 1.8
-targetCompatibility = 1.8
+sourceCompatibility = 17
+targetCompatibility = 17
sourceSets {
main {
diff --git a/BauSystem_Linkage/src/de/steamwar/linkage/types/ScoreboardElement_GENERIC.java b/BauSystem_Linkage/src/de/steamwar/linkage/types/ScoreboardElement_GENERIC.java
index 01e29833..ffd6382f 100644
--- a/BauSystem_Linkage/src/de/steamwar/linkage/types/ScoreboardElement_GENERIC.java
+++ b/BauSystem_Linkage/src/de/steamwar/linkage/types/ScoreboardElement_GENERIC.java
@@ -35,6 +35,6 @@ public class ScoreboardElement_GENERIC implements LinkageType {
@Override
public void generateCode(BuildPlan buildPlan, MethodBuilder methodBuilder, String s, TypeElement typeElement) {
buildPlan.addImport("de.steamwar.bausystem.features.world.BauScoreboard");
- methodBuilder.addLine("BauScoreboard.ELEMENTS.add(" + s + ");");
+ methodBuilder.addLine("BauScoreboard.addElement(" + s + ");");
}
}
diff --git a/BauSystem_Main/build.gradle b/BauSystem_Main/build.gradle
index 62d604cf..38432993 100644
--- a/BauSystem_Main/build.gradle
+++ b/BauSystem_Main/build.gradle
@@ -27,8 +27,8 @@ version '1.0'
compileJava.options.encoding = 'UTF-8'
-sourceCompatibility = 1.8
-targetCompatibility = 1.8
+sourceCompatibility = 17
+targetCompatibility = 17
sourceSets {
main {
diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties
index 20b50b0b..98f1ea7a 100644
--- a/BauSystem_Main/src/BauSystem.properties
+++ b/BauSystem_Main/src/BauSystem.properties
@@ -27,6 +27,10 @@ PAGE_LIST=§e Page ({0}/{1}) »»
LIST_PREVIOUS_PAGE=§ePrevious page
LIST_NEXT_PAGE=§eNext page
+# Permissions
+NO_PERMISSION = You are not allowed to use that here
+SPECTATOR = §fSpectator
+
# Scoreboard
SCOREBOARD_TIME = Time
SCOREBOARD_REGION = Region
@@ -40,6 +44,11 @@ SCOREBOARD_TRACE_TICKS = Ticks
SCOREBOARD_TECHHIDER = TechHider§8: §aOn
SCOREBOARD_XRAY = XRay§8: §aOn
+SCOREBOARD_LOCK_TEAM = Bau Lock§8: §eTeam
+SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM = Bau Lock§8: §e(Server) Team
+SCOREBOARD_LOCK_SERVERTEAM = Bau Lock§8: §eServer Team
+SCOREBOARD_LOCK_NOBODY = Bau Lock§8: §cNobody
+
# Flags
FLAG_COLOR = Color
FLAG_TNT = TNT
@@ -116,7 +125,6 @@ BACKUP_HELP_LOAD=§8/§ebackup load §8[§7BackupName§8] §8- §7Load a region
BACKUP_HELP_LIST=§8/§ebackup list §8- §7List all region backups
BACKUP_HELP_GUI=§8/§ebackup gui §8- §7Open the backup GUI
BACKUP_REGION_NO_REGION=§cYou are not inside any region
-BACKUP_NO_PERMS=§You do not have permission to use the backup system
BACKUP_CREATE_SUCCESS=§7Backup created
BACKUP_CREATE_FAILURE=§cBackup failed
BACKUP_CREATE_NO_CHANGE=§7No changes to save
@@ -130,11 +138,6 @@ BACKUP_LORE=§eClick to load
# Bau
BAU_COMMAND_HELP_INFO = §8/§ebau info §8- §7Alias for §8/§ebauinfo
-BAU_COMMAND_HELP_TOGGLEWE = §8/§ebau togglewe §8[§7Player§8] §8- §7Edit the WorldEdit permissions of a player
-BAU_COMMAND_HELP_TOGGLEWORLD = §8/§ebau toggleworld §8[§7Player§8] §8- §7Edit the World permissions of a player
-BAU_UNKNOWN_PLAYER = §cUnknown Player
-BAU_NO_PLAYER = §cThe player is no member of your world!
-BAU_NO_WORLD = §cThis is not your world!
BAU_INFO_ITEM_NAME = §eBau-Management
## This is used in BauInfoBauGuiItem.java
@@ -147,12 +150,7 @@ BAU_INFO_ITEM_LORE_ITEMS = §7Items§8: §e{0}
BAU_INFO_COMMAND_HELP = §8/§ebauinfo §8- §7Information regarding this build server
BAU_INFO_COMMAND_OWNER = §7Owner§8: §e{0}
-BAU_INFO_COMMAND_MEMBER = §7Member §8[§7{0}§8]§8: §e
-BAU_INFO_MEMBER_INFO = §e{0}§8[{1}§8,{2}§8] §8
-BAU_INFO_MEMBER_WE_ALLOW = §aWE
-BAU_INFO_MEMBER_WE_DISALLOW = §cWE
-BAU_INFO_MEMBER_WORLD_ALLOW = §aW
-BAU_INFO_MEMBER_WORLD_DISALLOW = §cW
+BAU_INFO_COMMAND_MEMBER = §7{0} §8[§7{1}§8]§8: §e{2}
BAU_INFO_COMMAND_FLAG = §7{0}§8: §7{1}
BAU_INFO_COMMAND_TPS = §7TPS§8:§e
@@ -211,11 +209,6 @@ HOTBAR_INVENTORY=Standard hotbar
# GUI
GUI_EDITOR_ITEM_NAME=§eGui editor
GUI_NAME=Bau GUI
-GUI_NO_PERMISSION=§cYou do not have enough permissions for this
-GUI_NO_OWNER=§cYou are not the owner of this World
-GUI_NO_WORLD=§cYou do not have permissions to change the World
-GUI_NO_WORLDEDIT=§cYou do not have permissions to use WorldEdit
-GUI_NO_MEMBER=§cYou need to be a member of this World
GUI_ITEM_LORE1=§7Use this item to open the bau gui
GUI_ITEM_LORE2=§7or press swap hands twice.
GUI_EDITOR_TITLE=Bau GUI Editor
@@ -266,7 +259,6 @@ SHIELD_PRINTING_HELP_STEP_7 = §87. §7Apply the shield printing with §8/§eshi
SHIELD_PRINTING_NO_REGION = §cYou are not in a region.
SHIELD_PRINTING_NOT_RUNNING = §cThe shield printing is not running.
-SHIELD_PRINTING_DISALLOWED = §cYou are not allowed to use shield printing here.
SHIELD_PRINTING_BOSSBAR = §fMovements: {0}
SHIELD_PRINTING_BOSSBAR_COPIED = §fMovements: {0} Copied: {1}
@@ -303,7 +295,6 @@ SIMULATOR_CHANGE_HELP = §8/§esimulator change §8-§7 Change your simulator wa
SIMULATOR_DELETE_HELP = §8/§esimulator delete §8[§7name§8] §8-§7 Deletes the simulator
SIMULATOR_START_HELP = §8/§esimulator start §8[§7name§8] §8-§7 Starts the simulator
SIMULATOR_COPY_HELP = §8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Copy the simulator
-SIMULATOR_NO_PERMS = §cYou are not allowed to use the simulator here
SIMULATOR_GUI_ITEM_NAME = §eTNT Simulator
@@ -313,6 +304,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 +320,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
@@ -481,7 +473,6 @@ TPSLIMIT_GUI_ITEM_NAME = §eTPS limiter
TPSLIMIT_GUI_ITEM_LORE = §7Currently: §e{0}
TPSLIMIT_ANVIL_GUI = New TPS limit
TPSLIMIT_CURRENT = §7Current TPS limit§8: §e{0}
-TPSLIMIT_NO_PERMS = §cYou are not allowed to use the TPS-Limiter here
TPSLIMIT_SET = §eSet TPS limit to {0}
TPSLIMIT_FROZEN = §eTPS frozen
@@ -573,7 +564,6 @@ LOADER_PAUSED=§7The Loader is now paused.
LOADER_SMALL_TIME=§cThe wait time is too small
LOADER_NEW_TIME=§7The wait time is now: {0}
LOADER_NEW_LOAD_TIME=§7The action wait time is now: {0}
-LOADER_PERMS=§cYou are not allowed to use the Loader here
LOADER_NOTHING_RECORDED=§cYou have not recorded anything yet!
LOADER_GUI_TITLE=Loader GUI
@@ -693,7 +683,6 @@ OTHER_CLEAR_HELP_PLAYER=§8/§eclear §8[§7Player§8] §8- §7Clears a player i
OTHER_CLEAR_CLEARED=Your inventory was cleared.
OTHER_CLEAR_FROM=Your invetnory was cleared by {0}.
OTHER_CLEAR_TO=The inventory of {0} §7was cleared.
-OTHER_CLEAR_NO_PERMS=§cYou are not allowed to clear other's inventory here.
OTHER_DECLUTTER_HELP=§8/§edeclutter §8- §7Organise your inventory
OTHER_DECLUTTER_DONE=§aYour inventory was organised.
OTHER_GAMEMODE_UNKNOWN=§cUnknown gamemode.
@@ -709,7 +698,6 @@ OTHER_TELEPORT_SELF_2=§cBlocks left to travel: 0; ETA: 0:00
OTHER_TELEPORT_SELF_3=§cA little Movement is important.
OTHER_TELEPORT_SELF_4=§cFor such a distance?
OTHER_TIME_HELP=§8/§etime §8<§7Time 0=Morining§8, §76000=Midday§8, §718000=Midnight§8> - §7Sets the time on the Build
-OTHER_TIME_NO_PERM=§cYou are not allowed to change the time here
OTHER_TIME_INVALID=§cPlease input a time between 0 and 24000
OTHER_TIME_RESULT=§7§oWhooosh
OTHER_TPS_HEAD = §7TPS: 1s 10s 1m 5m 10m
@@ -775,17 +763,6 @@ MATERIAL_FLAMMABLE=§8- §eFlammable block
MATERIAL_BURNABLE=§8- §eBurnable block
MATERIAL_WATERLOGGABLE=§8- §eWaterloggable block
MATERIAL_UNMOVABLE=§8- §eUnmovable block
-# Redstonetester
-RT_HELP=§8/§eredstonetester §8-§7 Gives you the redstone tester
-RT_GIVEN=§7Measure the time between activation of components
-RT_ITEM_NAME=§eRedstonetester
-RT_ITEM_LORE_1=§eLeftclick block §8-§7 Sets the 1. Position
-RT_ITEM_LORE_2=§eRightclick block §8-§7 Sets the 2. Position
-RT_ITEM_LORE_3=§eShift-rightclick in air §8-§7 Reset
-RT_LOC=§8: §e{0} {1} {2}
-RT_INVALID_LOC=§cUnknown Position
-RT_RESULT=§7Difference§8: §e{0}§7 Ticks §8,§7 R-Ticks §e{1}
-RT_ACTIVATE=§7Positions deleted§8.
# Region Items
REGION_ITEM_COLOR=§7Color: §e{0}
REGION_ITEM_COLOR_CHOOSE=Choose color
@@ -811,24 +788,18 @@ REGION_COLOR_HELP_COLOR=§8/§ecolor §8[§7Color§8] §8- §7Sets the color of
REGION_COLOR_HELP_COLOR_TYPE=§8/§ecolor §8[§7Color§8] §8[§7Type§8] §8- §7Sets the color of the region or globally
REGION_COLOR_GLOBAL=§7All regions color set to §e{0}
REGION_COLOR_NO_REGION=§cYou are currently not in any region
-REGION_COLOR_NO_PERMS=§cThis is not your world!
REGION_FIRE_HELP=§8/§efire §8- §7Toggle fire damage
-REGION_FIRE_NO_PERMS=§cYou are not allowed to toggle fire damage here
REGION_FIRE_ENABLED=§cFire damage deactivated in this region
REGION_FIRE_DISABLED=§aFire damage activated in this region
REGION_FREEZE_HELP=§8/§efreeze §8- §7Toggle Freeze
-REGION_FREEZE_NO_PERMS=§cYou are not allowed to freeze this world
REGION_FREEZE_ENABLED=§cRegion frozen
REGION_FREEZE_DISABLED=§aRegion thawed
REGION_ITEMS_HELP=§8/§eitems §8- §7Toggle Items
-REGION_ITEMS_NO_PERMS=§cYou are not allowed to toggle items in this world
REGION_ITEMS_ENABLED=§aItems enabled in this region
-REGION_ITEMS_DISABLED_GLOBAL=§cItems disabled in this world
REGION_ITEMS_DISABLED=§cItems disabled in this region
REGION_PROTECT_HELP=§8/§eprotect §8- §7Protect the region
REGION_PROTECT_DISABLE=§cProtection disabled
REGION_PROTECT_ENABLE=§aProtection enabled
-REGION_PROTECT_NO_PERMS=§cYou are not allowed to protect the floor here
REGION_PROTECT_FALSE_REGION=§cYou are not currently in a (M)WG-region
REGION_REGION_HELP_UNDO=§8/§eregion undo §8- §7undo the last 20 /testblock or /reset
REGION_REGION_HELP_REDO=§8/§eregion redo §8- §7redo the last 20 §8/§7rg undo
@@ -836,8 +807,6 @@ REGION_REGION_HELP_RESTORE=§8/§eregion restore §8- §7Resets the region, with
REGION_REGION_HELP_RESTORE_SCHEMATIC=§8/§eregion restore §8[§7Schematic§8] §8- §7Resets the region, withoout removing your builds
REGION_REGION_HELP_COPYPOINT=§8/§eregion copypoint §8- §7Teleport to the regions copy point
REGION_REGION_HELP_TESTBLOCKPOINT=§8/§eregion testblockpoint §8- §7Teleport to the regions dummy point
-REGION_REGION_HELP_CHANGETYPE_INFO=§8/§eregion changetype §8- §7Returns the region type
-REGION_REGION_HELP_CHANGETYPE=§8/§eregion changetype §8[§7Type§8] §8- §8Sets the region type
REGION_REGION_HELP_CHANGESKIN_INFO=§8/§eregion changeskin §8- §7Returns the region skin
REGION_REGION_HELP_CHANGESKIN=§8/§eregion changeskin §8[§7Skin§8] §8- §8Sets the region skin
REGION_REGION_NOTHING_UNDO=§cNothing left to undo
@@ -853,13 +822,6 @@ REGION_REGION_TP_COPY=§7Teleported to the copy point
REGION_REGION_TP_TEST_BLOCK=§7Teleported to the tesblock
REGION_REGION_TP_UNKNOWN=§cUndefined teleport point
REGION_REGION_NO_REGION=§cYou are not inside any region
-REGION_REGION_NO_PERMS=§cYou are not allowed to change the region
-REGION_REGION_CHANGETYPE_INFO=§7RRegion type is §e{0}
-REGION_REGION_CHANGETYPE_UNKNOWN=§cRegion type is invalid
-REGION_REGION_CHANGETYPE_INVALID=§cRegion type is not allowed here
-REGION_REGION_CHANGETYPE_CHANGE=§7Region type changed to §e{0}
-REGION_REGION_CHANGETYPE_CHANGE_UPDATE=§7Click §e§lHERE §7to change the region type
-REGION_REGION_CHANGETYPE_CHANGE_UPDATE_HOVER=§8/§ereset
REGION_REGION_CHANGESKIN_INFO=§7Region skin is §e{0}
REGION_REGION_CHANGESKIN_INFO_CREATOR=§7Skin created by §e{0}
REGION_REGION_CHANGESKIN_UNKNOWN=§cRegion skin is invalid
@@ -871,7 +833,6 @@ REGION_RESET_HELP_RESET=§8/§ereset §8- §7Resets the region
REGION_RESET_HELP_SCHEMATIC=§8/§ereset §8[§7Schematic§8] §8- §7Resets the region using a schematic
REGION_RESET_RESETED=§7Region reset
REGION_RESET_ERROR=§cError reseting the region
-REGION_RESET_NO_PERMS=§cYou are not allowed to reset the region here
REGION_RESET_NO_REGION=§cYou are currently not in any region
REGION_TB_HELP_RESET=§8/§etestblock §8- §7Reset the dummy
REGION_TB_HELP_RESET_EXTENSION=§8/§etestblock §8[§7ExtensionType§8] §8- §7Reset the dummy
@@ -879,7 +840,6 @@ REGION_TB_HELP_SCHEMATIC=§8/§etestblock §8[§7Schematic§8] §8- §7Reset the
REGION_TB_HELP_SCHEMATIC_EXTENSION=§8/§etestblock §8[§7Schematic§8] §8[§7ExtensionType§8] §8- §7Reset the dummy using a schematic
REGION_TB_DONE=§7Dummy reset
REGION_TB_ERROR=§cError resetting the dummy
-REGION_TB_NO_PERMS=§cYou are not allowed to reset the dummy here
REGION_TB_NO_REGION=§cYou are currently not in any region
REGION_TB_NO_SCHEMSHARING=§cYou currently cannot share schematics until {0}.
REGION_TB_NO_SCHEMRECEIVING=§cThe Owner of this build server cannot receive any schematics until {0}.
@@ -889,11 +849,10 @@ REGION_TNT_ON=§aTNT-Damage activated
REGION_TNT_OFF=§cTNT-Damage deactivated
REGION_TNT_TB=§aTNT-Damage activated outside the building area
REGION_TNT_BUILD=§aTNT-Damage activated outside the testblok area
-REGION_TNT_NO_PERMS=§cYou are not allowed to toggle tnt damage here
REGION_TNT_BUILD_DESTROY=§cAn explosion would have destroyed blocks in the building area
REGION_TNT_TB_DESTROY=§cAn explosion would have destroyed blocks in the testblock area
-AFK_KICK_MESSAGE=§cNothing happened on this server for 5 minutes.
+AFK_KICK_MESSAGE=§cNothing happened on this server for 15 minutes.
AFK_WARNING_MESSAGE=§cThis server will stop in one minute if you remain inactive
SKIN_HELP = §8/§eskin §8[§7Shortform§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Creates the skin schematic. Use 'public' as creator to have no creator, then copy the message to YoyoNow by clicking
@@ -908,7 +867,6 @@ PANZERN_PREPARE1 = §71. Check, if barrels reach until border of armor.
PANZERN_PREPARE2 = §72. Carpet on the floor in walkways helps with armoring.
PANZERN_PREPARE3 = §73. Shieldtechnology should be encased.
PANZERN_PREPARE4 = §74. Standing in the region that is being armored can improve armoring.
-PANZERN_NO_PERM = §cYou are not allowed to use the armoring system here
PANZERN_NO_WORLDEDIT = §cYou have no WorldEdit selcetion
PANZERN_PROGRESS = §e{0} §7Blocks left, §e{1} §7Blocks per second, §e{2} §7block delta
PANZERN_DONE = §aDone
@@ -918,7 +876,6 @@ LAUFBAU_HELP = §8/§elaufbau §8[§7smallest§8|§7blastresistant§8] §8- §7B
LAUFBAU_HELP_SETTINGS = §8/§elaufbau settings §8- §7Opens the settings GUI
LAUFBAU_PREPARE1 = §71. Trace the cannons as often as necessary, in all modes.
LAUFBAU_PREPARE2 = §72. Try to delete all fails from the traces.
-LAUFBAU_NO_PERM = §cYou are not allowed to use the barrel building system here
LAUFBAU_NO_WORLDEDIT = §cYou don't have a WorldEdit selection
LAUFBAU_STATE_FILTERING_TRACES = Filtering traces
LAUFBAU_STATE_PROCESSING_TRACES = Connnecting traces
@@ -1030,7 +987,6 @@ LAUFBAU_TILT_PARTIAL = §8-§7 Tilt partial
# UTILS
SELECT_HELP = §8/§eselect §8[§7RegionsTyp§8] §8- §7Select a region type
SELECT_EXTENSION_HELP = §8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Select a region type with or without extension
-SELECT_NO_PERMS = §cYou are not allowed to use the slection tool here
SELECT_GLOBAL_REGION = §cThe global region cannot be selected
SELECT_NO_TYPE = §cThis region has no {0}
SELECT_NO_EXTENSION = §cThis region has no extension
@@ -1084,7 +1040,6 @@ PISTON_HELP_3 = §7Count is yellow, if too many blocks are present.
PISTON_INFO = §7Moved Blocks {0}{1}§8/§712
# Warp
-WARP_DISALLOWED = §cYou are not allowed to use the warp here
WARP_LOC_X = §7X§8: §e{0}
WARP_LOC_Y = §7Y§8: §e{0}
WARP_LOC_Z = §7Z§8: §e{0}
@@ -1110,12 +1065,9 @@ WARP_HELP_LIST=§8/§ewarp list §8- §7List all warps
# WORLD
STOP_HELP = §8/§estop §8- §7Stops the server
-STOP_NO_PERMS = §cYou do not have the permission to stop the server
STOP_MESSAGE = §eServer is stopping
-WORLD_EDIT_NO_PERMS = §cYou do not have the permission to use WorldEdit
KICKALL_HELP = §8/§ekickall §8- §7Kick all players from the server except the owner
-KICKALL_NO_PERM = §cThis is not your world!
# Techhider
TECHHIDER_HELP = §8/§etechhider §8- §7Toggle Techhider
diff --git a/BauSystem_Main/src/BauSystem_de.properties b/BauSystem_Main/src/BauSystem_de.properties
index af268de5..ca651035 100644
--- a/BauSystem_Main/src/BauSystem_de.properties
+++ b/BauSystem_Main/src/BauSystem_de.properties
@@ -27,6 +27,10 @@ PAGE_LIST=§e Seite ({0}/{1}) »»
LIST_PREVIOUS_PAGE=§eVorherige Seite
LIST_NEXT_PAGE=§eNächste Seite
+# Permission
+NO_PERMISSION = Du darfst dies hier nicht nutzen
+SPECTATOR = §fZuschauer
+
# Scoreboard
SCOREBOARD_TIME = Uhrzeit
SCOREBOARD_REGION = Region
@@ -40,6 +44,11 @@ SCOREBOARD_TRACE_TICKS = Ticks
SCOREBOARD_TECHHIDER = TechHider§8: §aAn
SCOREBOARD_XRAY = XRay§8: §aAn
+SCOREBOARD_LOCK_TEAM = Bau Lock§8: §eTeam
+SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM = Bau Lock§8: §e(Server-) Team
+SCOREBOARD_LOCK_SERVERTEAM = Bau Lock§8: §eServerteam
+SCOREBOARD_LOCK_NOBODY = Bau Lock§8: §cNiemand
+
# Flags
FLAG_COLOR = Color
FLAG_TNT = TNT
@@ -115,7 +124,6 @@ BACKUP_HELP_LOAD=§8/§ebackup load §8[§7BackupName§8] §8- §7 Lade ein Back
BACKUP_HELP_LIST=§8/§ebackup list §8- §7Liste alle Backups der Region auf
BACKUP_HELP_GUI=§8/§ebackup gui §8- §7Öffne die Backups in einer GUI
BACKUP_REGION_NO_REGION=§cDu bist in keiner Region
-BACKUP_NO_PERMS=§cDu darfst hier nicht das Backup System verwenden
BACKUP_CREATE_SUCCESS=§7Das Backup wurde erstellt
BACKUP_CREATE_FAILURE=§cDas Backup erstellen ist schiefgegangen
BACKUP_CREATE_NO_CHANGE=§7Die Region hat keine Veränderung
@@ -129,11 +137,6 @@ BACKUP_LORE=§eKlicken zum Laden
# Bau
BAU_COMMAND_HELP_INFO = §8/§ebau info §8- §7Alias für §8/§ebauinfo
-BAU_COMMAND_HELP_TOGGLEWE = §8/§ebau togglewe §8[§7Player§8] §8- §7Editiere die WorldEdit Rechte eines Spielers
-BAU_COMMAND_HELP_TOGGLEWORLD = §8/§ebau toggleworld §8[§7Player§8] §8- §7Editiere die Welt Rechte eines Spielers
-BAU_UNKNOWN_PLAYER = §cUnbekannter Spieler
-BAU_NO_PLAYER = §cDer Spieler ist kein Mitglied deiner Welt!
-BAU_NO_WORLD = §cDies ist nicht deine Welt!
BAU_INFO_ITEM_NAME = §eBau-Management
## This is used in BauInfoBauGuiItem.java
@@ -146,12 +149,7 @@ BAU_INFO_ITEM_LORE_PROTECT = §7Protect§8: §e{0}
BAU_INFO_COMMAND_HELP = §8/§ebauinfo §8- §7Gibt Informationen über den Bau
BAU_INFO_COMMAND_OWNER = §7Besitzer§8: §e{0}
-BAU_INFO_COMMAND_MEMBER = §7Mitglieder §8[§7{0}§8]§8: §e
-BAU_INFO_MEMBER_INFO = §e{0}§8[{1}§8,{2}§8] §8
-BAU_INFO_MEMBER_WE_ALLOW = §aWE
-BAU_INFO_MEMBER_WE_DISALLOW = §cWE
-BAU_INFO_MEMBER_WORLD_ALLOW = §aW
-BAU_INFO_MEMBER_WORLD_DISALLOW = §cW
+BAU_INFO_COMMAND_MEMBER = §7{0} §8[§7{1}§8]§8: §e{2}
BAU_INFO_COMMAND_FLAG = §7{0}§8: §7{1}
BAU_INFO_COMMAND_TPS = §7TPS§8:§e
@@ -210,11 +208,6 @@ HOTBAR_INVENTORY=Standard Hotbar
# GUI
GUI_EDITOR_ITEM_NAME=§eGui Editor
GUI_NAME=Bau GUI
-GUI_NO_PERMISSION=§cDu hast nicht genug Rechte um dies zu tun
-GUI_NO_OWNER=§cDas ist nicht deine Bauwelt
-GUI_NO_WORLD=§cDu darfst hier die Welt nicht einstellen
-GUI_NO_WORLDEDIT=§cDu darfst hier kein Worldedit benutzen
-GUI_NO_MEMBER=§cDu musst ein Member der Bauwelt sein
GUI_ITEM_LORE1=§7Du kannst dieses Item zum Öffnen der BauGUI nutzen
GUI_ITEM_LORE2=§7oder Doppel F (Swap hands) drücken.
GUI_EDITOR_TITLE=Bau GUI Editor
@@ -258,7 +251,6 @@ SHIELD_PRINTING_HELP_STEP_7 = §87. §7Wende das gedruckte mit §8/§eshieldprin
SHIELD_PRINTING_NO_REGION = §cDu bist in keiner Region.
SHIELD_PRINTING_NOT_RUNNING = §cShield printing ist nicht aktiv.
-SHIELD_PRINTING_DISALLOWED = §cDu darfst Shield printing nicht benutzen.
SHIELD_PRINTING_BOSSBAR = §fBewegungen: {0}
SHIELD_PRINTING_BOSSBAR_COPIED = §fBewegungen: {0} Kopiert: {1}
@@ -295,7 +287,6 @@ SIMULATOR_CHANGE_HELP = §8/§esimulator change §8-§7 Wechsel zu einem anderen
SIMULATOR_DELETE_HELP = §8/§esimulator delete §8[§7name§8] §8-§7 Löscht den Simulator
SIMULATOR_START_HELP = §8/§esimulator start §8[§7name§8] §8-§7 Startet die Simulation
SIMULATOR_COPY_HELP = §8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Kopiert einen Simulator
-SIMULATOR_NO_PERMS = §cDu darfst hier nicht den Simulator nutzen
SIMULATOR_GUI_ITEM_NAME = §eTNT Simulator
@@ -305,6 +296,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 +312,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
@@ -450,7 +442,6 @@ TPSLIMIT_GUI_ITEM_NAME = §eTPS Limiter
TPSLIMIT_GUI_ITEM_LORE = §7Aktuell: §e{0}
TPSLIMIT_ANVIL_GUI = Neues TPS Limit
TPSLIMIT_CURRENT = §7Jetziges TPS limit§8: §e{0}
-TPSLIMIT_NO_PERMS = §cDu darfst hier nicht den TPS-Limiter nutzen
TPSLIMIT_SET = §eTPS limit auf {0} gesetzt.
TPSLIMIT_FROZEN = §eTPS eingefroren.
@@ -542,7 +533,6 @@ LOADER_PAUSED=§7Der Loader ist nun pausiert.
LOADER_SMALL_TIME=§cDie Wartezeit ist zu klein
LOADER_NEW_TIME=§7Die Schusswartezeit ist nun: {0}
LOADER_NEW_LOAD_TIME=§7Die Setzwartezeit ist nun: {0}
-LOADER_PERMS=§cDu darfst hier nicht den Detonator nutzen
LOADER_NOTHING_RECORDED=§cEs wurden keine Elemente aufgenommen!
LOADER_GUI_TITLE=Loader Einstellungen
@@ -661,7 +651,6 @@ OTHER_CLEAR_HELP_PLAYER=§8/§eclear §8[§7Player§8] §8- §7Leere ein Spieler
OTHER_CLEAR_CLEARED=Dein Inventar wurde geleert.
OTHER_CLEAR_FROM=Dein Inventar wurde von {0} §7geleert.
OTHER_CLEAR_TO=Das Inventar von {0} §7wurde geleert.
-OTHER_CLEAR_NO_PERMS=§cDu darfst hier keine fremden Inventare leeren.
OTHER_DECLUTTER_HELP=§8/§edeclutter §8- §7Räume dein Inventar auf
OTHER_DECLUTTER_DONE=§aDein Inventar wurde aufgeräumt.
OTHER_GAMEMODE_UNKNOWN=§cUnbekannter Spielmodus.
@@ -677,7 +666,6 @@ OTHER_TELEPORT_SELF_2=§cNoch zu reisende Blöcke: 0; ETA: 0:00
OTHER_TELEPORT_SELF_3=§cEin wenig bewegung muss ein.
OTHER_TELEPORT_SELF_4=§cFür eine solche Distanz?
OTHER_TIME_HELP=§8/§etime §8<§7Zeit 0=Morgen§8, §76000=Mittag§8, §718000=Mitternacht§8> - §7Setzt die Zeit auf dem Bau
-OTHER_TIME_NO_PERM=§cDu darfst hier nicht die Zeit ändern
OTHER_TIME_INVALID=§cBitte gib eine Zahl zwischen 0 und 24000 an
OTHER_TIME_RESULT=§7§oWhooosh
OTHER_TPS_HEAD = §7TPS: 1s 10s 1m 5m 10m
@@ -739,17 +727,6 @@ MATERIAL_INTERACTABLE=§8- §eInterargierbarer Block
MATERIAL_FLAMMABLE=§8- §eFlammbarer Block
MATERIAL_BURNABLE=§8- §eBrennbarer Block
MATERIAL_WATERLOGGABLE=§8- §eWasserspeicherbarer Block
-# Redstonetester
-RT_HELP=§8/§eredstonetester §8-§7 Gibt den RedstoneTester
-RT_GIVEN=§7Messe die Zeit zwischen der Aktivierung zweier Redstone Komponenten
-RT_ITEM_NAME=§eRedstonetester
-RT_ITEM_LORE_1=§eLinksklick Block §8-§7 Setzt die 1. Position
-RT_ITEM_LORE_2=§eRechtsklick Block §8-§7 Setzt die 2. Position
-RT_ITEM_LORE_3=§eShift-Rechtsklick Luft §8-§7 Zurücksetzten
-RT_LOC=§8: §e{0} {1} {2}
-RT_INVALID_LOC=§cUnbekannte Position
-RT_RESULT=§7Differenz§8: §e{0}§7 Ticks §8,§7 R-Ticks §e{1}
-RT_ACTIVATE=§7Positionen gelöscht§8.
# Region Items
REGION_ITEM_COLOR=§7Color: §e{0}
REGION_ITEM_COLOR_CHOOSE=Farbe Wählen
@@ -775,24 +752,18 @@ REGION_COLOR_HELP_COLOR=§8/§ecolor §8[§7Color§8] §8- §7Setze die Farbe de
REGION_COLOR_HELP_COLOR_TYPE=§8/§ecolor §8[§7Color§8] §8[§7Type§8] §8- §7Setze die Farbe der Region oder Global
REGION_COLOR_GLOBAL=§7Alle Regions farben auf §e{0}§7 gesetzt
REGION_COLOR_NO_REGION=§cDu befindest dich derzeit in keiner Region
-REGION_COLOR_NO_PERMS=§cDies ist nicht deine Welt!
REGION_FIRE_HELP=§8/§efire §8- §7Toggle Feuerschaden
-REGION_FIRE_NO_PERMS=§cDu darfst hier nicht Feuerschaden (de-)aktivieren
REGION_FIRE_ENABLED=§cRegions Feuerschaden deaktiviert
REGION_FIRE_DISABLED=§aRegions Feuerschaden aktiviert
REGION_FREEZE_HELP=§8/§efreeze §8- §7Toggle Freeze
-REGION_FREEZE_NO_PERMS=§cDu darfst diese Welt nicht einfrieren
REGION_FREEZE_ENABLED=§cRegion eingefroren
REGION_FREEZE_DISABLED=§aRegion aufgetaut
REGION_ITEMS_HELP=§8/§eitems §8- §7Toggle Items
-REGION_ITEMS_NO_PERMS=§cDu darfst hier nicht Items (de-)aktivieren
REGION_ITEMS_ENABLED=§aItems aktiviert in dieser Region
REGION_ITEMS_DISABLED=§cItems deaktiviert in dieser Region
-REGION_ITEMS_DISABLED_GLOBAL=§cItems sind auf dem Server deaktiviert.
REGION_PROTECT_HELP=§8/§eprotect §8- §7Schütze die Region
REGION_PROTECT_DISABLE=§cBoden Schutz aufgehoben
REGION_PROTECT_ENABLE=§aBoden geschützt
-REGION_PROTECT_NO_PERMS=§cDu darfst hier nicht den Boden schützen
REGION_PROTECT_FALSE_REGION=§cDu befindest dich derzeit in keiner (M)WG-Region
REGION_REGION_HELP_UNDO=§8/§eregion undo §8- §7Mache die letzten 20 /testblock oder /reset rückgängig
REGION_REGION_HELP_REDO=§8/§eregion redo §8- §7Wiederhole die letzten 20 §8/§7rg undo
@@ -800,8 +771,6 @@ REGION_REGION_HELP_RESTORE=§8/§eregion restore §8- §7Setzte die Region zurü
REGION_REGION_HELP_RESTORE_SCHEMATIC=§8/§eregion restore §8[§7Schematic§8] §8- §7Setzte die Region zurück, ohne das Gebaute zu löschen
REGION_REGION_HELP_COPYPOINT=§8/§eregion copypoint §8- §7Teleportiere dich zum Regions Kopierpunkt
REGION_REGION_HELP_TESTBLOCKPOINT=§8/§eregion testblockpoint §8- §7Teleportiere dich zum Regions Testblockpunkt
-REGION_REGION_HELP_CHANGETYPE_INFO=§8/§eregion changetype §8- §7Gebe den Regions Type aus
-REGION_REGION_HELP_CHANGETYPE=§8/§eregion changetype §8[§7Type§8] §8- §8Setzte den Regions Type
REGION_REGION_HELP_CHANGESKIN_INFO=§8/§eregion changeskin §8- §7Gebe den Regions Skin aus
REGION_REGION_HELP_CHANGESKIN=§8/§eregion changeskin §8[§7Skin§8] §8- §8Setzte den Regions Skin
REGION_REGION_NOTHING_UNDO=§cNichts zum rückgängig machen
@@ -817,13 +786,6 @@ REGION_REGION_TP_COPY=§7Zum Kopierpunkt teleportiert
REGION_REGION_TP_TEST_BLOCK=§7Zum Testblock teleportiert
REGION_REGION_TP_UNKNOWN=§cNicht definierter Teleportierpunkt
REGION_REGION_NO_REGION=§cDu bist in keiner Region
-REGION_REGION_NO_PERMS=§cDu darfst hier nicht die Region verändern
-REGION_REGION_CHANGETYPE_INFO=§7Regions Type ist §e{0}
-REGION_REGION_CHANGETYPE_UNKNOWN=§cRegions Type ist nicht valide
-REGION_REGION_CHANGETYPE_INVALID=§cRegions Type ist nicht erlaubt hier
-REGION_REGION_CHANGETYPE_CHANGE=§7Regions Type ist auf §e{0}§7 geändert
-REGION_REGION_CHANGETYPE_CHANGE_UPDATE=§7Klicke §e§lHIER §7um den Type anzuwenden
-REGION_REGION_CHANGETYPE_CHANGE_UPDATE_HOVER=§8/§ereset
REGION_REGION_CHANGESKIN_INFO=§7Regions Skin ist §e{0}
REGION_REGION_CHANGESKIN_INFO_CREATOR=§7Skin erstellt von §e{0}
REGION_REGION_CHANGESKIN_UNKNOWN=§cRegions Skin ist nicht valide
@@ -835,7 +797,6 @@ REGION_RESET_HELP_RESET=§8/§ereset §8- §7Setzte die Region zurück
REGION_RESET_HELP_SCHEMATIC=§8/§ereset §8[§7Schematic§8] §8- §7Setzte die Region mit einer Schematic zurück
REGION_RESET_RESETED=§7Region zurückgesetzt
REGION_RESET_ERROR=§cFehler beim Zurücksetzen der Region
-REGION_RESET_NO_PERMS=§cDu darfst hier nicht die Region zurücksetzen
REGION_RESET_NO_REGION=§cDu befindest dich derzeit in keiner Region
REGION_TB_HELP_RESET=§8/§etestblock §8- §7Setzte den Testblock zurück
REGION_TB_HELP_RESET_EXTENSION=§8/§etestblock §8[§7ExtensionType§8] §8- §7Setzte den Testblock zurück
@@ -843,7 +804,6 @@ REGION_TB_HELP_SCHEMATIC=§8/§etestblock §8[§7Schematic§8] §8- §7Setzte de
REGION_TB_HELP_SCHEMATIC_EXTENSION=§8/§etestblock §8[§7Schematic§8] §8[§7ExtensionType§8] §8- §7Setzte den Testblock mit einer Schematic zurück
REGION_TB_DONE=§7Testblock zurückgesetzt
REGION_TB_ERROR=§cFehler beim Zurücksetzen des Testblocks
-REGION_TB_NO_PERMS=§cDu darfst hier nicht den Testblock zurücksetzen
REGION_TB_NO_REGION=§cDu befindest dich derzeit in keiner Region
REGION_TB_NO_SCHEMSHARING=§cDu kannst aktuell keine Schematics teilen bis {0}.
REGION_TB_NO_SCHEMRECEIVING=§cDer Besitzer dieses Bauservers kann keine Schematics erhalten bis {0}.
@@ -852,10 +812,9 @@ REGION_TNT_HELP_MODE=§8/§etnt §8[§7Mode§8] §8- §7Setzte das TNT verhalten
REGION_TNT_ON=§aTNT-Schaden aktiviert
REGION_TNT_OFF=§cTNT-Schaden deaktiviert
REGION_TNT_TB=§aTNT-Schaden außerhalb Baurahmen aktiviert
-REGION_TNT_NO_PERMS=§cDu darfst hier nicht TNT-Schaden (de-)aktivieren
REGION_TNT_BUILD_DESTROY=§cEine Explosion hätte Blöcke im Baubereich zerstört
REGION_TNT_TB_DESTROY=§cEine Explosion hätte Blöcke im Testblockbereich zerstört
-AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 5 Minuten nichts passiert.
+AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 15 Minuten nichts passiert.
AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt
SKIN_HELP = §8/§eskin §8[§7Kuerzel§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Erstellt die Skin Schematics. 'public' als Creator nutzen für keinen Creator, danach die nachricht an YoyoNow kopieren (mit Click kopieren)
@@ -870,7 +829,6 @@ PANZERN_PREPARE1 = §71. Gucke nochmal nach, ob Läufe auch bis zur Panzergrenze
PANZERN_PREPARE2 = §72. Teppich in Gänge auf dem Boden vereinfacht das panzern.
PANZERN_PREPARE3 = §73. Schildtechnik sollte explizit eingeschlossen sein.
PANZERN_PREPARE4 = §74. Innerhalb der zu panzernden Region zu stehen, beim Befehlausführen kann das Panzern verbessern.
-PANZERN_NO_PERM = §cDu darfst hier nicht das Panzern System verwenden
PANZERN_NO_WORLDEDIT = §cDu hast keine WorldEdit Selection
PANZERN_PROGRESS = §e{0} §7Blöcke übrig, §e{1} §7Blöcke pro Sekunde, §e{2} §7Block Delta
PANZERN_DONE = §aZuende gepanzert
@@ -880,7 +838,6 @@ LAUFBAU_HELP = §8/§elaufbau §8[§7smallest§8|§7blastresistant§8] §8- §7B
LAUFBAU_HELP_SETTINGS = §8/§elaufbau settings §8- §7Öffnet die Settings GUI
LAUFBAU_PREPARE1 = §71. Trace die Kanonen so oft wie nötig, in allen Modi.
LAUFBAU_PREPARE2 = §72. Versuche alle Fails aus dem Trace zu löschen.
-LAUFBAU_NO_PERM = §cDu darfst hier nicht das Laufbau System verwenden
LAUFBAU_NO_WORLDEDIT = §cDu hast keine WorldEdit Selection
LAUFBAU_STATE_FILTERING_TRACES = Traces filtern
LAUFBAU_STATE_PROCESSING_TRACES = Traces verbinden
@@ -988,7 +945,6 @@ LAUFBAU_TILT_PARTIAL = §8-§7 Neigung teilweise
# UTILS
SELECT_HELP = §8/§eselect §8[§7RegionsTyp§8] §8- §7Wähle einen RegionsTyp aus
SELECT_EXTENSION_HELP = §8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Wähle einen RegionsTyp aus mit oder ohne Extension
-SELECT_NO_PERMS = §cDu darfst hier nicht den Select Befehl verwenden
SELECT_GLOBAL_REGION = §cDie globale Region kannst du nicht auswählen
SELECT_NO_TYPE = §cDiese Region hat keinen {0}
SELECT_NO_EXTENSION = §cDiese Region hat keine Ausfahrmaße
@@ -1040,7 +996,6 @@ PISTON_HELP_3 = §7Die Anzahl ist Gelb, wenn zu viele Blöcke vorhanden sind.
PISTON_INFO = §7Bewegte Blöcke {0}{1}§8/§712
# Warp
-WARP_DISALLOWED = §cDu darfst hier nicht das Warp System nutzen
WARP_LOC_X = §7X§8: §e{0}
WARP_LOC_Y = §7Y§8: §e{0}
WARP_LOC_Z = §7Z§8: §e{0}
@@ -1066,12 +1021,9 @@ WARP_HELP_LIST=§8/§ewarp list §8- §7Liste alle Warp-Punkt auf
# WORLD
STOP_HELP = §8/§estop §8- §7Stoppt den Server
-STOP_NO_PERMS = §cDu hast keine Rechte den Server zu stoppen
STOP_MESSAGE = §eDer Server wird gestoppt
-WORLD_EDIT_NO_PERMS = §cDu darfst hier kein WorldEdit benutzen
KICKALL_HELP = §8/§ekickall §8- §7Kickt alle Spieler vom Server außer den Owner
-KICKALL_NO_PERM = §cDies ist nicht deine Welt!
# Techhider
TECHHIDER_HELP = §8/§etechhider §8- §7Techhider umschalten
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
index 88a46ddc..9707d871 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
@@ -22,16 +22,19 @@ package de.steamwar.bausystem;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils;
-import de.steamwar.bausystem.features.world.RamUsage;
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.command.AbstractValidator;
+import de.steamwar.command.SWCommandUtils;
import de.steamwar.message.Message;
import lombok.Getter;
import org.bukkit.Bukkit;
-import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
@@ -53,12 +56,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();
@@ -79,25 +78,26 @@ public class BauSystem extends JavaPlugin implements Listener {
new Updater(PrototypeLoader.file, PrototypeLoader::load);
new Updater(RegionLoader.file, RegionLoader::load);
- LinkageUtils.link();
- RamUsage.init();
+ SWCommandUtils.addValidator(Player.class, validator(Permission.BUILD));
+ SWCommandUtils.addValidator(CommandSender.class, validator(Permission.BUILD));
+ SWCommandUtils.addValidator("supervisor", validator(Permission.SUPERVISOR));
+ SWCommandUtils.addValidator("owner", validator(Permission.OWNER));
- // This could disable any watchdog stuff. We need to investigate if this is a problem.
- /*
- Thread thread = new Thread(() -> {
- while (true) {
- WatchdogThread.tick();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
+ LinkageUtils.link();
+ TickListener.impl.init();
+ }
+
+ private AbstractValidator validator(Permission permission) {
+ return (commandSender, object, messageSender) -> {
+ if (commandSender instanceof Player) {
+ if (permission.hasPermission((Player) commandSender)) {
+ return true;
}
+ messageSender.send("NO_PERMISSION");
+ return false;
}
- });
- thread.setName("WatchdogThread ticker");
- thread.setDaemon(true);
- thread.start();
- */
+ return true;
+ };
}
@Override
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/Permission.java b/BauSystem_Main/src/de/steamwar/bausystem/Permission.java
index b2f14e4f..0985a62d 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/Permission.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/Permission.java
@@ -20,43 +20,77 @@
package de.steamwar.bausystem;
import de.steamwar.bausystem.config.BauServer;
-import de.steamwar.command.CommandMetaData;
-import de.steamwar.command.TypeValidator;
+import de.steamwar.bausystem.features.world.BauMemberUpdate;
+import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.sql.BauweltMember;
+import de.steamwar.sql.SteamwarUser;
import lombok.AllArgsConstructor;
-import org.bukkit.command.CommandSender;
+import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+import java.util.HashSet;
+import java.util.Set;
import java.util.function.Predicate;
@AllArgsConstructor
public enum Permission {
- WORLD(BauweltMember::isWorld),
- WORLDEDIT(BauweltMember::isWorldEdit),
- MEMBER(bauweltMember -> true),
- OWNER(bauweltMember -> false);
+ OWNER(bauweltMember -> false),
+ SUPERVISOR(bauweltMember -> {
+ return bauweltMember.isSupervisor();
+ }),
+ BUILD(bauweltMember -> {
+ if (isTempOnlySpectator(bauweltMember)) return false;
+ return bauweltMember.isBuild() || SUPERVISOR.permissionPredicate.test(bauweltMember);
+ }),
+ /**
+ * Only used for {@link BauMemberUpdate}
+ */
+ REAL_SPECTATOR(bauweltMember -> {
+ return !bauweltMember.isBuild() && !bauweltMember.isSupervisor();
+ }),
+ /**
+ * Primarily used for {@link de.steamwar.bausystem.linkage.specific.GuiItem}
+ */
+ MEMBER(bauweltMember -> {
+ return true;
+ });
+
+ private static final Set TEMP_ONLY_SPECTATOR = new HashSet<>();
+
+ private static boolean isTempOnlySpectator(BauweltMember bauweltMember) {
+ return TEMP_ONLY_SPECTATOR.contains(bauweltMember.getMemberID());
+ }
+
+ public static boolean isTempOnlySpectator(Player player) {
+ return TEMP_ONLY_SPECTATOR.contains(SteamwarUser.get(player.getUniqueId()).getId());
+ }
+
+ public static void forceOnlySpectator(Player player) {
+ TEMP_ONLY_SPECTATOR.add(SteamwarUser.get(player.getUniqueId()).getId());
+ BauMemberUpdate.baumemberUpdate();
+ }
+
+ /**
+ * Only used by {@link BauMemberUpdate}
+ */
+ public static void removeForceOnlySpectator(Player player) {
+ TEMP_ONLY_SPECTATOR.remove(SteamwarUser.get(player.getUniqueId()).getId());
+ }
private final Predicate permissionPredicate;
- public boolean hasPermission(Player member) {
- if (member.getUniqueId().equals(BauServer.getInstance().getOwner())) {
- return true;
- }
-
- BauweltMember bauMember = BauweltMember.getBauMember(BauServer.getInstance().getOwner(), member.getUniqueId());
- if (bauMember == null) {
- return false;
- }
-
- return permissionPredicate.test(bauMember);
+ public boolean hasPermission(BauweltMember bauweltMember) {
+ if (bauweltMember == null) return false;
+ return permissionPredicate.test(bauweltMember);
}
- public static boolean hasPermission(Player member, Permission permission) {
- return permission.hasPermission(member);
+ public boolean hasPermission(Player member) {
+ if (SteamwarUser.get(member.getUniqueId()).getId() == BauServer.getInstance().getOwnerID()) {
+ return this != REAL_SPECTATOR;
+ }
+ BauweltMember bauweltMember = BauweltMember.getBauMember(BauServer.getInstance().getOwner(), member.getUniqueId());
+ if (bauweltMember == null) return this == REAL_SPECTATOR;
+ return permissionPredicate.test(bauweltMember);
}
}
\ No newline at end of file
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/configplayer/Config.java b/BauSystem_Main/src/de/steamwar/bausystem/configplayer/Config.java
index 2f929687..edce8c58 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/configplayer/Config.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/configplayer/Config.java
@@ -97,7 +97,7 @@ public class Config implements Listener {
public void saveAll() {
playerConfigurations.forEach((uuid, yapionObject) -> {
- String string = yapionObject.toYAPION(new StringOutput()).getResult();
+ String string = yapionObject.toYAPION(new StringOutput()).getResult().replaceAll("\\+", "\\");
UserConfig.updatePlayerConfig(uuid, "bausystem", string);
});
playerConfigurations.clear();
@@ -112,7 +112,7 @@ public class Config implements Listener {
UUID uuid = player.getUniqueId();
if (playerConfigurations.containsKey(uuid)) {
YAPIONObject yapionObject = playerConfigurations.get(uuid);
- String string = yapionObject.toYAPION(new StringOutput()).getResult();
+ String string = yapionObject.toYAPION(new StringOutput()).getResult().replaceAll("\\\\+", "\\\\");
UserConfig.updatePlayerConfig(uuid, "bausystem", string);
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java
index 11cacde1..689be980 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java
@@ -44,7 +44,7 @@ public class AttributeRemoveCommand extends SWCommand {
@Register({"all"})
@Register({"*"})
- public void genericCommand(Player player) {
+ public void genericCommand(@Validator Player player) {
ItemStack itemStack = player.getInventory().getItemInMainHand();
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setLore(new ArrayList<>());
@@ -53,7 +53,7 @@ public class AttributeRemoveCommand extends SWCommand {
}
@Register(description = "ATTRIBUTE_REMOVE_COMMAND_HELP")
- public void genericCommand(Player player, @Mapper("attribute") String attribute) {
+ public void genericCommand(@Validator Player player, @Mapper("attribute") String attribute) {
ItemStack itemStack = player.getInventory().getItemInMainHand();
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesCopyCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesCopyCommand.java
index 01d652b4..808ca339 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesCopyCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesCopyCommand.java
@@ -41,7 +41,7 @@ public class AttributesCopyCommand extends SWCommand {
}
@Register
- public void genericCommand(Player player) {
+ public void genericCommand(@Validator Player player) {
Block block = player.getTargetBlockExact(8, FluidCollisionMode.ALWAYS);
if (block == null) return;
ItemStack mainHand = player.getInventory().getItemInMainHand();
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesPlaceListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesPlaceListener.java
index de4b192a..965d8bad 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesPlaceListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesPlaceListener.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.attributescopy;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -40,6 +41,7 @@ public class AttributesPlaceListener implements Listener {
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ItemStack itemStack = event.getItemInHand();
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) return;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartCommand.java
index 8e2b8c1a..3401267e 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartCommand.java
@@ -32,7 +32,7 @@ public class AutoStartCommand extends SWCommand {
}
@Register(description = "AUTOSTART_COMMAND_HELP")
- public void genericCommand(Player p) {
+ public void genericCommand(@Validator Player p) {
SWUtils.giveItemToPlayer(p, AutostartListener.getWandItem(p));
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartGuiItem.java
index a66e3785..f622d70b 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartGuiItem.java
@@ -50,6 +50,6 @@ public class AutoStartGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.MEMBER;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java
index 7da0fea1..28126ec5 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.autostart;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionUtils;
@@ -29,6 +30,7 @@ import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import lombok.Getter;
+import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.type.Chest;
import org.bukkit.configuration.file.FileConfiguration;
@@ -66,6 +68,7 @@ public class AutostartListener implements Listener {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!ItemUtils.isItem(event.getItem(), "autostart")) {
return;
}
@@ -75,6 +78,12 @@ public class AutostartListener implements Listener {
if (event.getClickedBlock().getBlockData() instanceof Chest) {
return;
}
+ if (event.getClickedBlock().getType() == Material.BEDROCK) {
+ event.getClickedBlock().setType(Material.SLIME_BLOCK);
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ event.getClickedBlock().setType(Material.BEDROCK, false);
+ }, 1);
+ }
activate(event.getPlayer());
}
@@ -83,6 +92,7 @@ public class AutostartListener implements Listener {
if (!(event.getPlayer() instanceof Player)) {
return;
}
+ if(!Permission.BUILD.hasPermission((Player) event.getPlayer())) return;
if (!ItemUtils.isItem(event.getPlayer().getInventory().getItemInMainHand(), "autostart")) {
return;
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/backup/BackupCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/backup/BackupCommand.java
index ba7035dc..b7911275 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/backup/BackupCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/backup/BackupCommand.java
@@ -62,7 +62,7 @@ public class BackupCommand extends SWCommand {
}
@Register(value = "create", description = "BACKUP_HELP_CREATE")
- public void backupCreate(@Validator Player p) {
+ public void backupCreate(@Validator("owner") Player p) {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) {
return;
@@ -79,7 +79,7 @@ public class BackupCommand extends SWCommand {
}
@Register(value = "load", description = "BACKUP_HELP_LOAD")
- public void backupLoad(@Validator Player p, @Mapper("backupName") String backupName) {
+ public void backupLoad(@Validator("owner") Player p, @Mapper("backupName") String backupName) {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) {
return;
@@ -130,7 +130,7 @@ public class BackupCommand extends SWCommand {
}
SWListInv swListInv = new SWListInv<>(p, BauSystem.MESSAGE.parse("BACKUP_INV_NAME", p), swListEntries, (clickType, s) -> {
p.getOpenInventory().close();
- backupLoad(p, s);
+ p.performCommand("backup load " + s);
});
swListInv.open();
}
@@ -140,13 +140,6 @@ public class BackupCommand extends SWCommand {
return SWCommandUtils.createMapper(s -> s, (commandSender, s) -> listBackup((Player) commandSender));
}
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator backupValidator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "BACKUP_NO_PERMS");
- };
- }
-
private List listBackup(Player p) {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/BauCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/BauCommand.java
deleted file mode 100644
index 69ee7af8..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/BauCommand.java
+++ /dev/null
@@ -1,41 +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 .
- */
-
-package de.steamwar.bausystem.features.bau;
-
-import de.steamwar.command.SWCommand;
-import de.steamwar.linkage.Linked;
-import de.steamwar.linkage.LinkedInstance;
-import org.bukkit.entity.Player;
-
-@Linked
-public class BauCommand extends SWCommand {
-
- @LinkedInstance
- public InfoCommand infoCommand;
-
- public BauCommand() {
- super("bau", "b", "gs");
- }
-
- @Register(value = "info", description = "BAU_COMMAND_HELP_INFO")
- public void infoCommand(Player p) {
- infoCommand.sendBauInfo(p);
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/ForceSpectatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/ForceSpectatorCommand.java
new file mode 100644
index 00000000..7bef91df
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/ForceSpectatorCommand.java
@@ -0,0 +1,73 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.bausystem.features.bau;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.command.PreviousArguments;
+import de.steamwar.command.SWCommand;
+import de.steamwar.command.TypeMapper;
+import de.steamwar.linkage.Linked;
+import de.steamwar.techhider.TechHider;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+@Linked
+public class ForceSpectatorCommand extends SWCommand {
+
+ public ForceSpectatorCommand() {
+ super("forcespectator");
+ }
+
+ @Register
+ public void forceSpectator(@Validator("supervisor") Player player, @Mapper("builder") Player other) {
+ Permission.forceOnlySpectator(other);
+ }
+
+ @Mapper("builder")
+ public TypeMapper spectatorMapper() {
+ return new TypeMapper<>() {
+ @Override
+ public Player map(CommandSender commandSender, String[] previousArguments, String s) {
+ Player player = Bukkit.getPlayer(s);
+ if (player == null) {
+ return null;
+ }
+ if (Permission.BUILD.hasPermission(player) && !Permission.SUPERVISOR.hasPermission(player)) {
+ return player;
+ }
+ return null;
+ }
+
+ @Override
+ public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
+ return Bukkit.getOnlinePlayers().stream()
+ .filter(Permission.BUILD::hasPermission)
+ .filter(player -> !Permission.SUPERVISOR.hasPermission(player))
+ .map(Player::getName)
+ .collect(Collectors.toList());
+ }
+ };
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java
index 345dc1b3..2d638888 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java
@@ -1,6 +1,7 @@
package de.steamwar.bausystem.features.bau;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.config.BauServer;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
@@ -12,7 +13,7 @@ import de.steamwar.sql.BauweltMember;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.entity.Player;
-import java.util.List;
+import java.util.*;
@Linked
public class InfoCommand extends SWCommand {
@@ -24,17 +25,8 @@ public class InfoCommand extends SWCommand {
super("bauinfo");
}
- @Register(help = true)
- public void genericHelp(Player p, String... args) {
- BauSystem.MESSAGE.send("BAU_INFO_COMMAND_HELP", p);
- }
-
- @Register
+ @Register(description = "BAU_INFO_COMMAND_HELP")
public void genericCommand(Player p) {
- sendBauInfo(p);
- }
-
- public void sendBauInfo(Player p) {
BauSystem.MESSAGE.send("BAU_INFO_COMMAND_OWNER", p, SteamwarUser.get(bauServer.getOwnerID()).getUserName());
Region region = Region.getRegion(p.getLocation());
for (Flag flag : Flag.getFlags()) {
@@ -47,18 +39,28 @@ public class InfoCommand extends SWCommand {
}
}
- List members = BauweltMember.getMembers(bauServer.getOwnerID());
- StringBuilder membermessage = new StringBuilder();
- membermessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_MEMBER", p, members.size()));
+ if (Permission.BUILD.hasPermission(p)) {
+ List members = BauweltMember.getMembers(bauServer.getOwnerID());
+ Map> memberByPermission = new HashMap<>();
+ members.forEach(member -> {
+ if (Permission.SUPERVISOR.hasPermission(member)) {
+ memberByPermission.computeIfAbsent(Permission.SUPERVISOR, __ -> new ArrayList<>()).add(member);
+ } else if (Permission.BUILD.hasPermission(member)) {
+ memberByPermission.computeIfAbsent(Permission.BUILD, __ -> new ArrayList<>()).add(member);
+ } else {
+ memberByPermission.computeIfAbsent(Permission.MEMBER, __ -> new ArrayList<>()).add(member);
+ }
+ });
- for (BauweltMember member : members) {
- membermessage.append(BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_INFO", p,
- SteamwarUser.get(member.getMemberID()).getUserName(),
- member.isWorldEdit() ? BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_WE_ALLOW", p) : BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_WE_DISALLOW", p),
- member.isWorld() ? BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_WORLD_ALLOW", p) : BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_WORLD_DISALLOW", p)
- ));
+ List supervisor = memberByPermission.getOrDefault(Permission.SUPERVISOR, Collections.emptyList());
+ BauSystem.MESSAGE.send("BAU_INFO_COMMAND_MEMBER", p, "§eSupervisor", supervisor.size(), supervisor.isEmpty() ? "§8" : joining(supervisor));
+
+ List builder = memberByPermission.getOrDefault(Permission.BUILD, Collections.emptyList());
+ BauSystem.MESSAGE.send("BAU_INFO_COMMAND_MEMBER", p, "§6Builder", builder.size(), builder.isEmpty() ? "§8" : joining(builder));
+
+ List spectator = memberByPermission.getOrDefault(Permission.MEMBER, Collections.emptyList());
+ BauSystem.MESSAGE.send("BAU_INFO_COMMAND_MEMBER", p, "§7Spectator", spectator.size(), spectator.isEmpty() ? "§8" : joining(spectator));
}
- p.sendMessage(membermessage.toString());
StringBuilder tpsMessage = new StringBuilder();
tpsMessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_TPS", p));
@@ -69,4 +71,16 @@ public class InfoCommand extends SWCommand {
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES));
p.sendMessage(tpsMessage.toString());
}
+
+ private String joining(List bauweltMembers) {
+ StringBuilder st = new StringBuilder();
+ for (int i = 0; i < bauweltMembers.size(); i++) {
+ if (i != 0) {
+ st.append("§8, ");
+ }
+ st.append("§7");
+ st.append(SteamwarUser.get(bauweltMembers.get(i).getMemberID()).getUserName());
+ }
+ return st.toString();
+ }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandGuiItem.java
index 7772f9c7..dbeae70d 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandGuiItem.java
@@ -48,6 +48,6 @@ public class CountingwandGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.WORLDEDIT;
+ return Permission.MEMBER;
}
}
\ No newline at end of file
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java b/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java
index fd9899f8..0fa990aa 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java
@@ -44,7 +44,6 @@ public class DesignEndStone {
private REntityServer entityServer = new REntityServer();
private List entities = new ArrayList<>();
private Set locations = new HashSet<>();
- private List players = new ArrayList<>();
public DesignEndStone(Region region) {
this.minX = region.getMinPointBuild().getX();
@@ -95,12 +94,10 @@ public class DesignEndStone {
}
public void toggle(Player player) {
- if (players.contains(player)) {
- players.remove(player);
+ if (entityServer.getPlayers().contains(player)) {
entityServer.removePlayer(player);
BauSystem.MESSAGE.sendPrefixless("DESIGN_ENDSTONE_DISABLE", player, ChatMessageType.ACTION_BAR);
} else {
- players.add(player);
entityServer.addPlayer(player);
calc();
BauSystem.MESSAGE.sendPrefixless("DESIGN_ENDSTONE_ENABLE", player, ChatMessageType.ACTION_BAR);
@@ -108,7 +105,7 @@ public class DesignEndStone {
}
public boolean removePlayer(Player player) {
- players.remove(player);
- return players.isEmpty();
+ entityServer.removePlayer(player);
+ return entityServer.getPlayers().isEmpty();
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStoneCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStoneCommand.java
index bafa3206..92934c23 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStoneCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStoneCommand.java
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.design.endstone;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.utils.RegionType;
+import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.Location;
@@ -33,6 +34,7 @@ import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
@Linked
@@ -45,7 +47,7 @@ public class DesignEndStoneCommand extends SWCommand implements Listener {
private Map designEndStoneMap = new HashMap<>();
@Register(description = "DESIGN_ENDSTONE_COMMAND_HELP")
- public void genericCommand(Player player) {
+ public void genericCommand(@Validator Player player) {
Region region = Region.getRegion(player.getLocation());
if (!region.hasType(RegionType.BUILD)) {
BauSystem.MESSAGE.send("DESIGN_ENDSTONE_REGION_ERROR", player);
@@ -56,14 +58,20 @@ public class DesignEndStoneCommand extends SWCommand implements Listener {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
- Region region = Region.getRegion(event.getPlayer().getLocation());
- DesignEndStone designEndStone = designEndStoneMap.get(region);
- if (designEndStone == null) {
- return;
- }
- if (designEndStone.removePlayer(event.getPlayer())) {
- designEndStoneMap.remove(region);
- }
+ disableDesignEndStone(event.getPlayer());
+ }
+
+ @EventHandler
+ public void onBauMemberUpdate(BauMemberUpdateEvent event) {
+ event.getNewSpectator().forEach(this::disableDesignEndStone);
+ }
+
+ private void disableDesignEndStone(Player player) {
+ new HashSet<>(designEndStoneMap.entrySet()).forEach(regionDesignEndStoneEntry -> {
+ if (regionDesignEndStoneEntry.getValue().removePlayer(player)) {
+ designEndStoneMap.remove(regionDesignEndStoneEntry.getKey());
+ }
+ });
}
@EventHandler
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorBauGuiItem.java
index 2207ce45..3f633663 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorBauGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorBauGuiItem.java
@@ -47,6 +47,6 @@ public class DetonatorBauGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.MEMBER;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorCommand.java
index bb71245d..c8d493bd 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorCommand.java
@@ -58,12 +58,12 @@ public class DetonatorCommand extends SWCommand {
}
@Register(value = "wand", description = "DETONATOR_HELP_WAND")
- public void giveWand(Player p) {
+ public void giveWand(@Validator Player p) {
SWUtils.giveItemToPlayer(p, getWAND(p));
}
@Register(value = "click", description = "DETONATOR_HELP_CLICK")
- public void clickDetonator(Player p) {
+ public void clickDetonator(@Validator Player p) {
Detonator.activateDetonator(new ItemStorage(p));
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java
index be8e8ce9..cabe00c6 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.detonator;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
@@ -65,6 +66,7 @@ public class DetonatorListener implements Listener {
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
Player p = event.getPlayer();
if (Detonator.isDetonator(p.getInventory().getItemInMainHand())) {
event.setCancelled(true);
@@ -75,6 +77,7 @@ public class DetonatorListener implements Listener {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!Detonator.isDetonator(event.getItem())) {
return;
}
@@ -89,7 +92,7 @@ public class DetonatorListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onPlayerMove(PlayerMoveEvent event) {
- if (!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) {
+ if (!Permission.BUILD.hasPermission(event.getPlayer()) ||!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) {
if (Detonator.hasActiveDetonatorShow(event.getPlayer())) {
Detonator.hideDetonator(event.getPlayer());
}
@@ -110,6 +113,7 @@ public class DetonatorListener implements Listener {
@EventHandler
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) {
HAS_UPDATED.add(event.getPlayer());
}
@@ -117,6 +121,7 @@ public class DetonatorListener implements Listener {
@EventHandler
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (Detonator.isDetonator(event.getMainHandItem()) || Detonator.isDetonator(event.getOffHandItem())) {
HAS_UPDATED.add(event.getPlayer());
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGUI.java
index 74a915da..3b8dc600 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGUI.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGUI.java
@@ -81,7 +81,7 @@ public class BauGUI {
}
} else {
p.closeInventory();
- BauSystem.MESSAGE.send("GUI_NO_PERMISSION", p);
+ BauSystem.MESSAGE.send("NO_PERMISSION", p);
}
});
});
@@ -108,26 +108,13 @@ public class BauGUI {
if (!permission.hasPermission(p)) {
List lore = meta.getLore();
if (lore == null) {
- lore = Collections.singletonList(BauSystem.MESSAGE.parse(permissionString(permission), p));
+ lore = Collections.singletonList(BauSystem.MESSAGE.parse("NO_PERMISSION", p));
} else {
- lore.add(BauSystem.MESSAGE.parse(permissionString(permission), p));
+ lore.add(BauSystem.MESSAGE.parse("NO_PERMISSION", p));
}
meta.setLore(lore);
}
itemStack.setItemMeta(meta);
return itemStack;
}
-
- private static String permissionString(Permission permission) {
- switch (permission) {
- case OWNER:
- return "GUI_NO_OWNER";
- case WORLD:
- return "GUI_NO_WORLD";
- case WORLDEDIT:
- return "GUI_NO_WORLDEDIT";
- default:
- return "GUI_NO_MEMBER";
- }
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarCommand.java
index 9b52890c..77a13716 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarCommand.java
@@ -35,7 +35,7 @@ public class HotbarCommand extends SWCommand {
}
@Register(value = "load", description = "HOTBAR_HELP_LOAD")
- public void loadHotbar(Player p) {
+ public void loadHotbar(@Validator Player p) {
DefaultHotbar.setHotbar(p);
BauSystem.MESSAGE.send("HOTBAR_LOADED", p);
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarListener.java
index de00331f..8a4c78de 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarListener.java
@@ -19,6 +19,7 @@
package de.steamwar.bausystem.features.hotbar;
+import de.steamwar.bausystem.Permission;
import de.steamwar.linkage.Linked;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -30,6 +31,7 @@ public class HotbarListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerJoin(PlayerJoinEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (allNull(event.getPlayer().getInventory().getContents()) && allNull(event.getPlayer().getInventory().getArmorContents())) {
DefaultHotbar.setHotbar(event.getPlayer());
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/inventoryfiller/InventoryFiller.java b/BauSystem_Main/src/de/steamwar/bausystem/features/inventoryfiller/InventoryFiller.java
index f72d08f2..d69e3410 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/inventoryfiller/InventoryFiller.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/inventoryfiller/InventoryFiller.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.inventoryfiller;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.linkage.Linked;
import net.md_5.bungee.api.ChatMessageType;
@@ -38,6 +39,7 @@ public class InventoryFiller implements Listener {
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
if (!event.getPlayer().isSneaking()) return;
Block block = event.getPlayer().getTargetBlockExact(5);
@@ -59,6 +61,7 @@ public class InventoryFiller implements Listener {
*/
@EventHandler
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
if (!event.getPlayer().isSneaking()) return;
ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand();
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java
index 1340f1c1..9ca7a480 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.killchecker;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Region;
+import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
@@ -54,7 +55,7 @@ public class KillcheckerCommand extends SWCommand implements Listener {
}
@Register(value = "enable", description = "KILLCHECKER_HELP_ENABLE")
- public void genericCommand(Player player, @OptionalValue("-outline") @StaticValue(value = {"-area", "-outline"}, allowISE = true) boolean onlyOutline) {
+ public void genericCommand(@Validator Player player, @OptionalValue("-outline") @StaticValue(value = {"-area", "-outline"}, allowISE = true) boolean onlyOutline) {
Region region = Region.getRegion(player.getLocation());
KillcheckerVisualizer killcheckerVisualizer = visualizers.computeIfAbsent(region, region1 -> new KillcheckerVisualizer(region1, bossBarService));
killcheckerVisualizer.recalc();
@@ -74,16 +75,22 @@ public class KillcheckerCommand extends SWCommand implements Listener {
BauSystem.MESSAGE.send("KILLCHECKER_DISABLE", player);
}
+ @EventHandler
+ public void onBauMemberUpdate(BauMemberUpdateEvent event) {
+ event.getNewSpectator().forEach(this::hide);
+ }
+
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
- Player player = event.getPlayer();
- Set regions = new HashSet<>();
- visualizers.forEach((region, visualizer) -> {
- if (visualizer.disconnect(player)) {
- regions.add(region);
+ hide(event.getPlayer());
+ }
+
+ private void hide(Player player) {
+ new HashSet<>(visualizers.entrySet()).forEach(regionKillcheckerVisualizerEntry -> {
+ if (regionKillcheckerVisualizerEntry.getValue().hide(player)) {
+ visualizers.remove(regionKillcheckerVisualizerEntry.getKey());
}
});
- regions.forEach(visualizers::remove);
}
private void recalc(Block block) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java
index d7c89254..c68ad901 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java
@@ -57,9 +57,6 @@ public class KillcheckerVisualizer {
private final int zArea;
private final int xArea;
- private final Set players = new HashSet<>();
- private final Set areaPlayers = new HashSet<>();
-
private final Region region;
private final BossBarService bossBarService;
@@ -261,7 +258,7 @@ public class KillcheckerVisualizer {
double zPercent = xCount / (double) zArea;
percent = (xPercent + yPercent + zPercent) / 3;
kills = zKills + yKills + xKills;
- players.forEach(this::updateBossBar);
+ outline.getPlayers().forEach(this::updateBossBar);
Set pointSet = new HashSet<>(killCount.keySet());
Set outlinePointsCacheLast = new HashSet<>(outlinePointsCache);
@@ -356,40 +353,21 @@ public class KillcheckerVisualizer {
return new Cuboid(minX, minY, minZ, maxX, maxY, maxZ);
}
- public boolean show(Player player, boolean onlyOutline) {
+ public void show(Player player, boolean onlyOutline) {
outline.addPlayer(player);
if (!onlyOutline) {
inner.addPlayer(player);
- areaPlayers.add(player);
- } else if (areaPlayers.contains(player)) {
+ } else {
inner.removePlayer(player);
- areaPlayers.remove(player);
}
updateBossBar(player);
- return players.add(player);
}
public boolean hide(Player player) {
outline.removePlayer(player);
- if (areaPlayers.contains(player)) {
- inner.removePlayer(player);
- }
- players.remove(player);
- areaPlayers.remove(player);
+ inner.removePlayer(player);
bossBarService.remove(player, region, "killchecker");
- if (players.isEmpty()) {
- outline.close();
- inner.close();
- return true;
- }
- return false;
- }
-
- public boolean disconnect(Player player) {
- players.remove(player);
- areaPlayers.remove(player);
- bossBarService.remove(player, region, "killchecker");
- if (players.isEmpty()) {
+ if (outline.getPlayers().isEmpty() && inner.getPlayers().isEmpty()) {
outline.close();
inner.close();
return true;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java
index 22e0df02..266cd65b 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.loader;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.loader.elements.LoaderElement;
import de.steamwar.bausystem.features.loader.elements.LoaderInteractionElement;
import de.steamwar.bausystem.features.loader.elements.impl.LoaderTNT;
@@ -70,6 +71,7 @@ public class Loader implements Listener {
BauSystem.runTaskTimer(BauSystem.getInstance(), () -> {
if (stage != Stage.RUNNING) return;
+ if(!Permission.BUILD.hasPermission(p)) return;
if (waitTime > 0) {
waitTime--;
return;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java
index b065c3d2..ffe27e64 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java
@@ -21,13 +21,16 @@ package de.steamwar.bausystem.features.loader;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
+import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
@Linked
-public class LoaderCommand extends SWCommand {
+public class LoaderCommand extends SWCommand implements Listener {
public LoaderCommand() {
super("loader");
@@ -102,10 +105,12 @@ public class LoaderCommand extends SWCommand {
loader.setTicksBetweenBlocks(delay);
}
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator loaderValidator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "LOADER_PERMS");
- };
+ @EventHandler
+ public void onBauMemberUpdate(BauMemberUpdateEvent event) {
+ event.getNewSpectator().forEach(player -> {
+ Loader loader = Loader.getLoader(player);
+ if (loader == null) return;
+ loader.stop();
+ });
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java
index ec2153ae..cc3dce23 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java
@@ -43,6 +43,8 @@ import org.bukkit.inventory.EquipmentSlot;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
public class LoaderRecorder implements Listener {
@@ -124,53 +126,10 @@ public class LoaderRecorder implements Listener {
addWaitTime(false);
Block block = event.getClickedBlock();
- Material type = block.getType();
- switch (type) {
- case COMPARATOR:
- loaderElementList.add(new LoaderComparator(block.getLocation()));
- message("LOADER_BUTTON_COMPARATOR");
- break;
- case REPEATER:
- loaderElementList.add(new LoaderRepeater(block.getLocation()));
- message("LOADER_BUTTON_REPEATER");
- break;
- case NOTE_BLOCK:
- loaderElementList.add(new LoaderNoteBlock(block.getLocation()));
- message("LOADER_BUTTON_NOTEBLOCK");
- break;
- case LEVER:
- loaderElementList.add(new LoaderLever(block.getLocation()));
- message("LOADER_BUTTON_SWITCH");
- break;
- case DAYLIGHT_DETECTOR:
- loaderElementList.add(new LoaderDaylightDetector(block.getLocation()));
- message("LOADER_BUTTON_DAYLIGHT_DETECTOR");
- break;
- case LECTERN:
- loaderElementList.add(new LoaderLectern(block.getLocation()));
- message("LOADER_BUTTON_LECTERN");
- break;
- case IRON_TRAPDOOR:
- break;
- default:
- if (type.name().endsWith("_TRAPDOOR")) {
- loaderElementList.add(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_TRAPDOOR", type));
- message("LOADER_BUTTON_TRAPDOOR");
- } else if (type.name().endsWith("_DOOR")) {
- loaderElementList.add(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_DOOR", type));
- message("LOADER_BUTTON_DOOR");
- } else if (type.name().endsWith("FENCE_GATE")) {
- loaderElementList.add(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_FENCEGATE", type));
- message("LOADER_BUTTON_FENCEGATE");
- } else if (type.name().endsWith("STONE_BUTTON")) {
- loaderElementList.add(new LoaderTicks(block.getLocation(), "LOADER_BUTTON_STONE_BUTTON", type, 20));
- message("LOADER_BUTTON_STONE_BUTTON");
- } else if (type.name().endsWith("BUTTON")) {
- loaderElementList.add(new LoaderTicks(block.getLocation(), "LOADER_BUTTON_WOOD_BUTTON", type, 30));
- message("LOADER_BUTTON_WOOD_BUTTON");
- }
- break;
- }
+ getLoaderInteractionElement(block, (loaderInteractionElement, s) -> {
+ loaderElementList.add(loaderInteractionElement);
+ message(s);
+ });
}
private Map blockSet = new HashMap<>();
@@ -226,6 +185,46 @@ public class LoaderRecorder implements Listener {
}
}
+ public static void getLoaderInteractionElement(Block block, BiConsumer, String> consumer) {
+ Material type = block.getType();
+ switch (type) {
+ case COMPARATOR:
+ consumer.accept(new LoaderComparator(block.getLocation()), "LOADER_BUTTON_COMPARATOR");
+ break;
+ case REPEATER:
+ consumer.accept(new LoaderRepeater(block.getLocation()), "LOADER_BUTTON_REPEATER");
+ break;
+ case NOTE_BLOCK:
+ consumer.accept(new LoaderNoteBlock(block.getLocation()), "LOADER_BUTTON_NOTEBLOCK");
+ break;
+ case LEVER:
+ consumer.accept(new LoaderLever(block.getLocation()), "LOADER_BUTTON_SWITCH");
+ break;
+ case DAYLIGHT_DETECTOR:
+ consumer.accept(new LoaderDaylightDetector(block.getLocation()), "LOADER_BUTTON_DAYLIGHT_DETECTOR");
+ break;
+ case LECTERN:
+ consumer.accept(new LoaderLectern(block.getLocation()), "LOADER_BUTTON_LECTERN");
+ break;
+ case IRON_TRAPDOOR:
+ case IRON_DOOR:
+ break;
+ default:
+ if (type.name().endsWith("_TRAPDOOR")) {
+ consumer.accept(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_TRAPDOOR", type), "LOADER_BUTTON_TRAPDOOR");
+ } else if (type.name().endsWith("_DOOR")) {
+ consumer.accept(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_DOOR", type), "LOADER_BUTTON_DOOR");
+ } else if (type.name().endsWith("FENCE_GATE")) {
+ consumer.accept(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_FENCEGATE", type), "LOADER_BUTTON_FENCEGATE");
+ } else if (type.name().endsWith("STONE_BUTTON")) {
+ consumer.accept(new LoaderTicks(block.getLocation(), "LOADER_BUTTON_STONE_BUTTON", type, 20), "LOADER_BUTTON_STONE_BUTTON");
+ } else if (type.name().endsWith("BUTTON")) {
+ consumer.accept(new LoaderTicks(block.getLocation(), "LOADER_BUTTON_WOOD_BUTTON", type, 30), "LOADER_BUTTON_WOOD_BUTTON");
+ }
+ break;
+ }
+ }
+
private void message(String type) {
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("LOADER_MESSAGE_INTERACT", player, BauSystem.MESSAGE.parse(type, player), loaderElementList.size()));
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderScoreboardElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderScoreboardElement.java
index b3e2ba2f..fdcda57a 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderScoreboardElement.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderScoreboardElement.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.loader;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.linkage.Linked;
@@ -40,6 +41,7 @@ public class LoaderScoreboardElement implements ScoreboardElement {
@Override
public String get(Region region, Player p) {
+ if(!Permission.BUILD.hasPermission(p)) return null;
Loader loader = Loader.getLoader(p);
if (loader == null) return null;
if (loader.getStage() == Loader.Stage.RUNNING) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadtimer/LoadtimerCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadtimer/LoadtimerCommand.java
index 42d5175c..503c1b47 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loadtimer/LoadtimerCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadtimer/LoadtimerCommand.java
@@ -32,12 +32,12 @@ public class LoadtimerCommand extends SWCommand {
}
@Register(value = "start", description = "LOADTIMER_HELP_START_1")
- public void start(Player p) {
+ public void start(@Validator Player p) {
start(p, TimerMode.HALF);
}
@Register(value = "start", description = {"LOADTIMER_HELP_START_2", "LOADTIMER_HELP_START_3"})
- public void start(Player p, TimerMode mode) {
+ public void start(@Validator Player p, TimerMode mode) {
Region r = Region.getRegion(p.getLocation());
if (r.isGlobal()) return;
if (!Loadtimer.hasTimer(r))
@@ -45,7 +45,7 @@ public class LoadtimerCommand extends SWCommand {
}
@Register(value = "stop", description = "LOADTIMER_HELP_STOP")
- public void stop(Player p) {
+ public void stop(@Validator Player p) {
Region r = Region.getRegion(p.getLocation());
if (r.isGlobal()) return;
if (Loadtimer.hasTimer(r))
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java
index fd0df724..531eda68 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.observer;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
@@ -46,13 +47,13 @@ public class ObserverTracerCommand extends SWCommand {
}
@Register(value = "delete", description = "OBSERVER_HELP_DELETE")
- public void delete(Player p) {
+ public void delete(@Validator Player p) {
ObserverTracerListener.observerTracerMap.remove(p);
BauSystem.MESSAGE.send("OBSERVER_DELETE", p);
}
@Register(value = "retrace", description = "OBSERVER_HELP_RETRACE")
- public void retrace(Player p) {
+ public void retrace(@Validator Player p) {
if (ObserverTracerListener.observerTracerMap.containsKey(p)) {
BauSystem.MESSAGE.send("OBSERVER_RETRACE_NO_TRACE", p);
return;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java
index b841755b..a2d9c991 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java
@@ -20,6 +20,8 @@
package de.steamwar.bausystem.features.observer;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
@@ -55,6 +57,7 @@ public class ObserverTracerListener implements Listener {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!enabled.contains(event.getPlayer())) {
return;
}
@@ -87,6 +90,11 @@ public class ObserverTracerListener implements Listener {
}
}
+ @EventHandler
+ public void onBauMemberUpdate(BauMemberUpdateEvent event) {
+ event.getNewSpectator().forEach(observerTracerMap::remove);
+ }
+
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
enabled.add(event.getPlayer());
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ColorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ColorCommand.java
index 543d8727..7c60aef2 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ColorCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ColorCommand.java
@@ -85,7 +85,7 @@ public class ColorCommand extends SWCommand {
@ClassValidator(value = Player.class, local = true)
public TypeValidator validator() {
return (commandSender, player, messageSender) -> {
- return !messageSender.send(!bauServer.getOwner().equals(player.getUniqueId()), "REGION_COLOR_NO_PERMS");
+ return !messageSender.send(!bauServer.getOwner().equals(player.getUniqueId()), "NO_PERMISSION");
};
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/FireCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/FireCommand.java
index da5b2665..3a0d4403 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/FireCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/FireCommand.java
@@ -46,10 +46,6 @@ public class FireCommand extends SWCommand {
}
}
- private String getNoPermMessage() {
- return "REGION_FIRE_NO_PERMS";
- }
-
private String getEnableMessage() {
return "REGION_FIRE_ENABLED";
}
@@ -69,11 +65,4 @@ public class FireCommand extends SWCommand {
return false;
}
}
-
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), getNoPermMessage());
- };
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeCommand.java
index 339ea122..d154ce66 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeCommand.java
@@ -46,10 +46,6 @@ public class FreezeCommand extends SWCommand {
}
}
- private String getNoPermMessage() {
- return "REGION_FREEZE_NO_PERMS";
- }
-
private String getEnableMessage(){
return "REGION_FREEZE_ENABLED";
}
@@ -69,11 +65,4 @@ public class FreezeCommand extends SWCommand {
return true;
}
}
-
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), getNoPermMessage());
- };
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ItemsCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ItemsCommand.java
index d1709dc7..8c4452cb 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ItemsCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ItemsCommand.java
@@ -49,10 +49,6 @@ public class ItemsCommand extends SWCommand {
}
}
- private String getNoPermMessage() {
- return "REGION_ITEMS_NO_PERMS";
- }
-
private String getEnableMessage(){
return "REGION_ITEMS_ENABLED";
}
@@ -72,11 +68,4 @@ public class ItemsCommand extends SWCommand {
return true;
}
}
-
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), getNoPermMessage());
- };
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ProtectCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ProtectCommand.java
index 3793d3ec..4fc33cf0 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ProtectCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ProtectCommand.java
@@ -54,13 +54,6 @@ public class ProtectCommand extends SWCommand {
}
}
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "REGION_PROTECT_NO_PERMS");
- };
- }
-
private Region regionCheck(Player player) {
Region region = Region.getRegion(player.getLocation());
if (region.getFloorLevel() == 0) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java
index 5caf0af3..efad26fd 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java
@@ -71,7 +71,7 @@ public class RegionCommand extends SWCommand {
}
@Register(value = "undo", description = "REGION_REGION_HELP_UNDO")
- public void undoCommand(@Validator("WORLD_EDIT") Player p) {
+ public void undoCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) return;
@@ -83,7 +83,7 @@ public class RegionCommand extends SWCommand {
}
@Register(value = "redo", description = "REGION_REGION_HELP_REDO")
- public void redoCommand(@Validator("WORLD_EDIT") Player p) {
+ public void redoCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) {
return;
@@ -97,7 +97,7 @@ public class RegionCommand extends SWCommand {
}
@Register(value = "restore", description = "REGION_REGION_HELP_RESTORE")
- public void genericRestoreCommand(@Validator("WORLD_EDIT") Player p) {
+ public void genericRestoreCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if(checkGlobalRegion(region, p)) return;
@@ -114,7 +114,7 @@ public class RegionCommand extends SWCommand {
}
@Register(value = "restore", description = "REGION_REGION_HELP_RESTORE_SCHEMATIC")
- public void schematicRestoreCommand(@Validator("WORLD_EDIT") Player p, SchematicNode node) {
+ public void schematicRestoreCommand(@Validator Player p, SchematicNode node) {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) return;
@@ -164,36 +164,6 @@ public class RegionCommand extends SWCommand {
BauSystem.MESSAGE.send("REGION_REGION_TP_TEST_BLOCK", p);
}
- @Register(value = "changetype", description = "REGION_REGION_HELP_CHANGETYPE_INFO")
- @Register("type")
- public void changeTypeCommand(Player p) {
- Region region = Region.getRegion(p.getLocation());
- if (checkGlobalRegion(region, p)) {
- return;
- }
- BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_INFO", p, region.getPrototype().getDisplayName());
- }
-
- @Register(value = "changetype", description = "REGION_REGION_HELP_CHANGETYPE")
- @Register("type")
- public void changeTypeCommand(@Validator("WORLD") Player p, @Mapper("regionTypeMapper") String s) {
- Region region = Region.getRegion(p.getLocation());
- if (checkGlobalRegion(region, p)) {
- return;
- }
- Prototype prototype = Prototype.getByDisplayName(s);
- if (prototype == null) {
- BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_UNKNOWN", p);
- } else {
- if (region.setPrototype(prototype)) {
- BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_CHANGE", p, s);
- BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_CHANGE_UPDATE", p, BauSystem.MESSAGE.parse("REGION_REGION_CHANGETYPE_CHANGE_UPDATE_HOVER", p), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/reset"));
- } else {
- BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_INVALID", p);
- }
- }
- }
-
@Register(value = "changeskin", description = "REGION_REGION_HELP_CHANGESKIN_INFO")
@Register("skin")
public void changeSkinCommand(Player p) {
@@ -210,7 +180,7 @@ public class RegionCommand extends SWCommand {
@Register(value = "changeskin", description = "REGION_REGION_HELP_CHANGESKIN")
@Register("skin")
- public void changeSkinCommand(@Validator("WORLD") Player p, @Mapper("skinTypeMapper") String s) {
+ public void changeSkinCommand(@Validator Player p, @Mapper("skinTypeMapper") String s) {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) {
return;
@@ -227,26 +197,6 @@ public class RegionCommand extends SWCommand {
}
}
- @Mapper(value = "regionTypeMapper", local = true)
- private TypeMapper regionTypeMapper() {
- return new TypeMapper() {
- @Override
- public List tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
- Player p = (Player) commandSender;
- Region region = Region.getRegion(p.getLocation());
- if (region.isGlobal()) {
- return Collections.emptyList();
- }
- return region.getPrototypes().stream().map(Prototype::getByName).map(Prototype::getDisplayName).map(c -> c.replace(' ', '_')).collect(Collectors.toList());
- }
-
- @Override
- public String map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
- return s.replace('_', ' ');
- }
- };
- }
-
@Mapper(value = "skinTypeMapper", local = true)
private TypeMapper skinTypeMapper() {
return new TypeMapper() {
@@ -266,18 +216,4 @@ public class RegionCommand extends SWCommand {
}
};
}
-
- @Validator(value = "WORLD", local = true)
- public TypeValidator worldValidator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "REGION_REGION_NO_PERMS");
- };
- }
-
- @Validator(value = "WORLD_EDIT", local = true)
- public TypeValidator worldEditValidator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "REGION_REGION_NO_PERMS");
- };
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java
index 03a22027..680224a7 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java
@@ -97,13 +97,6 @@ public class ResetCommand extends SWCommand {
}
}
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "REGION_RESET_NO_PERMS");
- };
- }
-
private Region regionCheck(Player player) {
Region region = Region.getRegion(player.getLocation());
if (region == GlobalRegion.getInstance()) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java
index af9f3837..27dcbe8f 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java
@@ -157,11 +157,4 @@ public class TNTCommand extends SWCommand {
break;
}
}
-
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "REGION_TNT_NO_PERMS");
- };
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java
index 3572cf71..6b319062 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java
@@ -157,11 +157,6 @@ public class TestblockCommand extends SWCommand {
};
}
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "REGION_TB_NO_PERMS");
- }
-
private Region regionCheck(Player player) {
Region region = Region.getRegion(player.getLocation());
if (!region.hasType(RegionType.TESTBLOCK)) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FireBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FireBauGuiItem.java
index 01714fba..79101ee9 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FireBauGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FireBauGuiItem.java
@@ -57,6 +57,6 @@ public class FireBauGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.WORLD;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FreezeBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FreezeBauGuiItem.java
index 43d1903f..1406638c 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FreezeBauGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FreezeBauGuiItem.java
@@ -57,6 +57,6 @@ public class FreezeBauGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.WORLD;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ProtectBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ProtectBauGuiItem.java
index 652c2fb2..a11e508d 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ProtectBauGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ProtectBauGuiItem.java
@@ -58,6 +58,6 @@ public class ProtectBauGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.WORLDEDIT;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ResetBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ResetBauGuiItem.java
index 79f6537a..e5295b2e 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ResetBauGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ResetBauGuiItem.java
@@ -65,6 +65,6 @@ public class ResetBauGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.WORLDEDIT;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TestblockBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TestblockBauGuiItem.java
index 7b0f25e0..355b5209 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TestblockBauGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TestblockBauGuiItem.java
@@ -64,6 +64,6 @@ public class TestblockBauGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.WORLDEDIT;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TntBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TntBauGuiItem.java
index 673a9295..38f1b04a 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TntBauGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TntBauGuiItem.java
@@ -116,6 +116,6 @@ public class TntBauGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.WORLD;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java
index 9d640d52..0194514f 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java
@@ -31,7 +31,7 @@ public class ScriptCommand extends SWCommand {
}
@Register
- public void genericCommand(Player player) {
+ public void genericCommand(@Validator Player player) {
ScriptGUI.open(player);
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java
index 61b8862d..14f8d983 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java
@@ -19,6 +19,8 @@
package de.steamwar.bausystem.features.script;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
@@ -42,6 +44,8 @@ public class ScriptListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onLeftClick(PlayerInteractEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
+
ItemStack item = event.getItem();
if (item == null || FlatteningWrapper.impl.isNoBook(item) || item.getItemMeta() == null) {
return;
@@ -68,6 +72,13 @@ public class ScriptListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ScriptRunner.updateGlobalScript(event.getPlayer());
}
+
+ @EventHandler
+ public void onBauMemberUpdate(BauMemberUpdateEvent event) {
+ event.getNewSpectator().forEach(ScriptRunner::remove);
+ event.getNewBuilder().forEach(ScriptRunner::updateGlobalScript);
+ }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java
index 77bd991e..da5f1f21 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java
@@ -19,6 +19,7 @@
package de.steamwar.bausystem.features.script.event;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
@@ -41,6 +42,7 @@ public class CommandListener implements Listener {
@EventHandler
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
String[] split = event.getMessage().split(" ");
if (calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).contains(split[0])) {
return;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java
index 89f9667e..c32b0231 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.script.event;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin;
import de.steamwar.bausystem.features.script.lua.libs.StorageLib;
@@ -64,17 +65,20 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfJoin, LuaValue.NIL, event);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerQuit(PlayerQuitEvent event) {
StorageLib.removePlayer(event.getPlayer());
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfLeave, LuaValue.NIL, event);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (LAST_FS.containsKey(event.getPlayer())) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DoubleSwap, LuaValue.NIL, event);
@@ -86,6 +90,7 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onBlockPlace(BlockPlaceEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
LuaTable table = new LuaTable();
table.set("x", event.getBlock().getX());
table.set("y", event.getBlock().getY());
@@ -96,6 +101,7 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onBlockBreak(BlockBreakEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
LuaTable table = new LuaTable();
table.set("x", event.getBlock().getX());
table.set("y", event.getBlock().getY());
@@ -108,6 +114,7 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void onPlayerInteract(PlayerInteractEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (ignore.remove(event.getPlayer())) {
return;
}
@@ -125,6 +132,7 @@ public class EventListener implements Listener {
table.set("blockY", event.getClickedBlock().getY());
table.set("blockZ", event.getClickedBlock().getZ());
table.set("blockFace", event.getBlockFace().name());
+ table.set("blockType", event.getClickedBlock().getType().name());
} else {
table.set("hasBlock", LuaValue.valueOf(false));
}
@@ -144,6 +152,7 @@ public class EventListener implements Listener {
Region tntRegion = Region.getRegion(event.getLocation());
for (Player player : Bukkit.getOnlinePlayers()) {
+ if(!Permission.BUILD.hasPermission(player)) continue;
if (tntRegion.inRegion(player.getLocation(), RegionType.NORMAL, RegionExtensionType.NORMAL)) {
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTSpawn, LuaValue.NIL, event);
}
@@ -165,6 +174,7 @@ public class EventListener implements Listener {
boolean inBuild = event.blockList().stream().anyMatch(block -> tntRegion.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
for (Player player : Bukkit.getOnlinePlayers()) {
+ if(!Permission.BUILD.hasPermission(player)) continue;
if (tntRegion.inRegion(player.getLocation(), RegionType.NORMAL, RegionExtensionType.NORMAL)) {
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTExplode, table, event);
if (inBuild) {
@@ -176,6 +186,7 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerDropItem(PlayerDropItemEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ignore.add(event.getPlayer());
LuaTable table = new LuaTable();
table.set("type", event.getItemDrop().getItemStack().getType().name());
@@ -185,6 +196,7 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onEntityDeath(EntityDeathEvent event) {
for (Player player : Bukkit.getOnlinePlayers()) {
+ if(!Permission.BUILD.hasPermission(player)) continue;
LuaTable table = new LuaTable();
table.set("type", event.getEntityType().name());
ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.EntityDeath, table, event);
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java
index d27a314e..52843f79 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.script.event;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.api.Plain;
@@ -36,6 +37,7 @@ public class HotkeyListener implements PluginMessageListener, Plain {
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
+ if(!Permission.BUILD.hasPermission(player)) return;
if (!channel.equals("sw:hotkeys")) return;
if (message.length < 5) return;
int action = message[4] & 0xFF;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java
index 1e8ec13a..c047531c 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java
@@ -22,15 +22,21 @@ package de.steamwar.bausystem.features.script.lua;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
+import com.sk89q.worldedit.bukkit.BukkitPlayer;
+import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.bausystem.features.script.lua.libs.LuaLib;
import de.steamwar.bausystem.features.world.WorldEditListener;
import de.steamwar.bausystem.utils.WorldEditUtils;
import de.steamwar.inventory.SWAnvilInv;
+import net.md_5.bungee.api.ChatMessageType;
+import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -39,11 +45,10 @@ import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
-import org.luaj.vm2.lib.OneArgFunction;
-import org.luaj.vm2.lib.ThreeArgFunction;
-import org.luaj.vm2.lib.TwoArgFunction;
-import org.luaj.vm2.lib.VarArgFunction;
+import org.luaj.vm2.lib.*;
+import java.lang.reflect.Proxy;
+import java.net.InetSocketAddress;
import java.util.*;
import java.util.logging.Level;
@@ -102,14 +107,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction {
double x = arg1.checkdouble();
double y = arg2.checkdouble();
double z = arg3.checkdouble();
-
- Location loc = new Location(player.getWorld(), x, y, z);
-
- return tableOf(new LuaValue[] {
- valueOf("x"), valueOf(loc.getBlockX()),
- valueOf("y"), valueOf(loc.getBlockY()),
- valueOf("z"), valueOf(loc.getBlockZ())
- });
+ return pos(x, y, z);
}
});
env.set("exec", new VarArgFunction() {
@@ -122,6 +120,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction {
return LuaValue.NIL;
}
+ command = preprocessEvent.getMessage().substring(1);
Bukkit.getLogger().log(Level.INFO, player.getName() + " dispatched command: " + command);
String[] commandSplit = command.split(" ");
if (!commandSplit[0].equals("select") && hasFAWE && WorldEditListener.isWorldEditCommand("/" + commandSplit[0])) {
@@ -166,11 +165,86 @@ public class SteamWarLuaPlugin extends TwoArgFunction {
env.set("rawget", NIL);
env.set("rawlen", NIL);
env.set("rawset", NIL);
- env.set("setmetatable", NIL);
env.set("xpcall", NIL);
return null;
}
+ public static LuaTable pos(double x, double y, double z) {
+ LuaTable position = new LuaTable();
+ position.set("x", x);
+ position.set("y", y);
+ position.set("z", z);
+
+ position.set("add", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue luaValue) {
+ LuaTable table = luaValue.checktable();
+ double dx = table.get("x").checkdouble();
+ double dy = table.get("y").checkdouble();
+ double dz = table.get("z").checkdouble();
+ return pos(x + dx, y + dy, z + dz);
+ }
+ });
+
+ position.set("subtract", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue luaValue) {
+ LuaTable table = luaValue.checktable();
+ double dx = table.get("x").checkdouble();
+ double dy = table.get("y").checkdouble();
+ double dz = table.get("z").checkdouble();
+ return pos(x - dx, y - dy, z - dz);
+ }
+ });
+
+ position.set("addX", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue luaValue) {
+ return pos(x + luaValue.checkdouble(), y, z);
+ }
+ });
+ position.set("subtractX", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue luaValue) {
+ return pos(x - luaValue.checkdouble(), y, z);
+ }
+ });
+ position.set("addY", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue luaValue) {
+ return pos(x, y + luaValue.checkdouble(), z);
+ }
+ });
+ position.set("subtractY", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue luaValue) {
+ return pos(x, y - luaValue.checkdouble(), z);
+ }
+ });
+ position.set("addZ", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue luaValue) {
+ return pos(x, y, z + luaValue.checkdouble());
+ }
+ });
+ position.set("subtractZ", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue luaValue) {
+ return pos(x, y, z - luaValue.checkdouble());
+ }
+ });
+
+ position.set("blockPos", new ZeroArgFunction() {
+ @Override
+ public LuaValue call() {
+ Location location = new Location(Bukkit.getWorlds().get(0), x, y, z);
+ return pos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+ });
+
+ return position;
+ }
+
public static String varArgsToString(Varargs args) {
StringBuilder builder = new StringBuilder();
for (int i = 1; i <= args.narg(); i++) {
@@ -192,7 +266,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction {
class Print extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
- player.sendMessage(varArgsToString(args));
+ player.sendMessage(ChatColor.translateAlternateColorCodes('&', varArgsToString(args)));
return LuaValue.NIL;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/LuaLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/LuaLib.java
index b88ee9d0..a4af0d3a 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/LuaLib.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/LuaLib.java
@@ -19,6 +19,7 @@
package de.steamwar.bausystem.features.script.lua.libs;
+import de.steamwar.bausystem.region.Point;
import lombok.AllArgsConstructor;
import org.bukkit.entity.Player;
import org.luaj.vm2.*;
@@ -69,6 +70,15 @@ public interface LuaLib {
return de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin.varArgsToString(varargs);
}
+ default LuaTable toPos(Point point) {
+ if (point == null) return LuaTable.tableOf();
+ return LuaValue.tableOf(new LuaValue[] {
+ LuaValue.valueOf("x"), LuaValue.valueOf(point.getX()),
+ LuaValue.valueOf("y"), LuaValue.valueOf(point.getY()),
+ LuaValue.valueOf("z"), LuaValue.valueOf(point.getZ())
+ });
+ }
+
default Class extends LuaLib> parent() {
return null;
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/PlayerLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/PlayerLib.java
index 6ce317b3..d8576f81 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/PlayerLib.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/PlayerLib.java
@@ -19,9 +19,11 @@
package de.steamwar.bausystem.features.script.lua.libs;
+import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin;
import de.steamwar.linkage.Linked;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
@@ -43,6 +45,12 @@ public class PlayerLib implements LuaLib {
table.set("chat", new Print(player));
table.set("actionbar", new SendActionbar(player));
+ table.set("pos", getter(() -> {
+ return SteamWarLuaPlugin.pos(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ());
+ }));
+ table.set("blockPos", getter(() -> {
+ return SteamWarLuaPlugin.pos(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ());
+ }));
table.set("x", getterAndSetter("x", () -> player.getLocation().getX(), x -> {
Location location = player.getLocation();
location.setX(x);
@@ -93,7 +101,7 @@ public class PlayerLib implements LuaLib {
@Override
public Varargs invoke(Varargs args) {
- player.sendMessage(varArgsToString(args));
+ player.sendMessage(ChatColor.translateAlternateColorCodes('&', varArgsToString(args)));
return LuaValue.NIL;
}
}
@@ -107,7 +115,7 @@ public class PlayerLib implements LuaLib {
@Override
public Varargs invoke(Varargs args) {
- player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(varArgsToString(args)));
+ player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(ChatColor.translateAlternateColorCodes('&', varArgsToString(args))));
return LuaValue.NIL;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java
index 17c07230..f615dad3 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java
@@ -78,6 +78,17 @@ public class RegionLib implements LuaLib {
Loader loader = Loader.getLoader(player);
table.set("loader", getter(() -> loader == null ? "OFF" : loader.getStage().name()));
+
+ table.set("copyPoint", getter(() -> toPos(region.get().getCopyPoint())));
+ table.set("minPointBuild", getter(() -> toPos(region.get().getMinPointBuild())));
+ table.set("maxPointBuild", getter(() -> toPos(region.get().getMaxPointBuild())));
+ table.set("minPointBuildExtension", getter(() -> toPos(region.get().getMinPointBuildExtension())));
+ table.set("maxPointBuildExtension", getter(() -> toPos(region.get().getMaxPointBuildExtension())));
+ table.set("testblockPoint", getter(() -> toPos(region.get().getTestBlockPoint())));
+ table.set("minPointTestblock", getter(() -> toPos(region.get().getMinPointTestblock())));
+ table.set("maxPointTestblock", getter(() -> toPos(region.get().getMaxPointTestblock())));
+ table.set("minPointTestblockExtension", getter(() -> toPos(region.get().getMinPointTestblockExtension())));
+ table.set("maxPointTestblockExtension", getter(() -> toPos(region.get().getMaxPointTestblockExtension())));
return table;
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ScoreboardLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ScoreboardLib.java
new file mode 100644
index 00000000..af9c67ae
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ScoreboardLib.java
@@ -0,0 +1,75 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2024 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 .
+ */
+
+package de.steamwar.bausystem.features.script.lua.libs;
+
+import de.steamwar.bausystem.features.world.BauScoreboard;
+import de.steamwar.bausystem.utils.ScoreboardElement;
+import de.steamwar.linkage.Linked;
+import org.bukkit.entity.Player;
+import org.luaj.vm2.LuaTable;
+import org.luaj.vm2.LuaValue;
+import org.luaj.vm2.Varargs;
+import org.luaj.vm2.lib.TwoArgFunction;
+import org.luaj.vm2.lib.VarArgFunction;
+
+@Linked
+public class ScoreboardLib implements LuaLib {
+
+ @Override
+ public String name() {
+ return "scoreboard";
+ }
+
+ @Override
+ public LuaTable get(Player player) {
+ LuaTable luaTable = new LuaTable();
+
+ LuaTable groups = new LuaTable();
+ for (ScoreboardElement.ScoreboardGroup group : ScoreboardElement.ScoreboardGroup.values()) {
+ groups.set(group.name(), group.ordinal());
+ }
+ luaTable.set("group", groups);
+
+ luaTable.set("element", new VarArgFunction() {
+ @Override
+ public Varargs invoke(Varargs varargs) {
+ if (varargs.narg() < 2) {
+ return NIL;
+ }
+ String elementKey = varargs.arg(1).checkjstring();
+ ScoreboardElement.ScoreboardGroup elementGroup = ScoreboardElement.ScoreboardGroup.values()[varargs.arg(2).checkint()];
+ int priority = varargs.narg() > 2 ? varargs.arg(2).checkint() : Integer.MAX_VALUE;
+
+ return new VarArgFunction() {
+ @Override
+ public Varargs invoke(Varargs args) {
+ if (args.narg() == 0) {
+ BauScoreboard.setAdditionalElement(player, elementKey, elementGroup, priority, null);
+ } else {
+ BauScoreboard.setAdditionalElement(player, elementKey, elementGroup, priority, args.arg1().checkjstring());
+ }
+ return NIL;
+ }
+ };
+ }
+ });
+ return luaTable;
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ServerLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ServerLib.java
index 80134fba..10a41830 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ServerLib.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ServerLib.java
@@ -20,11 +20,15 @@
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.bausystem.features.loader.Loader;
+import de.steamwar.bausystem.features.loader.LoaderRecorder;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
-import de.steamwar.core.TPSWatcher;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
+import org.bukkit.Bukkit;
import org.bukkit.Material;
+import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
@@ -46,10 +50,14 @@ public class ServerLib implements LuaLib {
public LuaTable get(Player player) {
LuaTable serverLib = LuaValue.tableOf();
serverLib.set("time", getter(() -> new SimpleDateFormat(BauSystem.MESSAGE.parse("TIME", player)).format(Calendar.getInstance().getTime())));
+ serverLib.set("onlinePlayerCount", getter(Bukkit.getOnlinePlayers()::size));
serverLib.set("ticks", getter(TPSUtils.currentTick));
serverLib.set("getBlockAt", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg1) {
+ if (!Permission.SUPERVISOR.hasPermission(player)) {
+ return LuaValue.NIL;
+ }
LuaTable pos = arg1.checktable();
return valueOf(player.getWorld().getBlockAt(pos.get("x").checkint(), pos.get("y").checkint(), pos.get("z").checkint()).getType().name());
}
@@ -57,6 +65,9 @@ public class ServerLib implements LuaLib {
serverLib.set("setBlockAt", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
+ if (!Permission.SUPERVISOR.hasPermission(player)) {
+ return LuaValue.NIL;
+ }
LuaTable pos = arg1.checktable();
LuaString material = arg2.checkstring();
Material mat = SWItem.getMaterial(material.tojstring());
@@ -67,17 +78,19 @@ public class ServerLib implements LuaLib {
return NIL;
}
});
-
- LuaValue tpsLib = LuaValue.tableOf();
- tpsLib.set("oneSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND)));
- tpsLib.set("tenSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS)));
- tpsLib.set("oneMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE)));
- tpsLib.set("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)));
- tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
- tpsLib.set("current", getter(TPSWatcher::getTPS));
- // tpsLib.set("limit", getter(TPSLimitUtils::getCurrentTPSLimit));
-
- serverLib.set("tps", tpsLib);
+ serverLib.set("interactAt", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue arg1) {
+ LuaTable pos = arg1.checktable();
+ Block block = player.getWorld().getBlockAt(pos.get("x").checkint(), pos.get("y").checkint(), pos.get("z").checkint());
+ LoaderRecorder.getLoaderInteractionElement(block, (loaderInteractionElement, s) -> {
+ loaderInteractionElement.execute(aLong -> {
+ // Ignore
+ });
+ });
+ return NIL;
+ }
+ });
return serverLib;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java
index 033c5f98..898b68a7 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java
@@ -19,8 +19,14 @@
package de.steamwar.bausystem.features.script.lua.libs;
+import com.google.gson.*;
import de.steamwar.bausystem.region.Region;
+import de.steamwar.core.Core;
import de.steamwar.linkage.Linked;
+import de.steamwar.linkage.api.Disable;
+import de.steamwar.linkage.api.Enable;
+import de.steamwar.sql.SteamwarUser;
+import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
@@ -29,15 +35,173 @@ import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
@Linked
-public class StorageLib implements LuaLib {
+public class StorageLib implements LuaLib, Enable, Disable {
+
+ private final Gson gson = new Gson();
+ private final File storageDirectory = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "script_storage");
private static final HashMap GLOBAL_STORAGE = new HashMap<>();
- private static final HashMap> PLAYER_STORAGE = new HashMap<>();
+ private static final HashMap> PLAYER_STORAGE = new HashMap<>();
private static final HashMap> REGION_STORAGE = new HashMap<>();
+ @Override
+ public void enable() {
+ if (Core.getVersion() <= 15) return;
+ if (!storageDirectory.exists()) storageDirectory.mkdirs();
+
+ try {
+ JsonObject jsonObject = JsonParser.parseReader(new FileReader(new File(storageDirectory, "global.json"))).getAsJsonObject();
+ jsonObject.keySet().forEach(key -> {
+ GLOBAL_STORAGE.put(key, fromJson(jsonObject.get(key)));
+ });
+ } catch (Exception e) {}
+
+ File regionStorageDirectory = new File(storageDirectory, "region");
+ regionStorageDirectory.mkdirs();
+ for (File regionStorage : regionStorageDirectory.listFiles()) {
+ try {
+ JsonObject jsonObject = JsonParser.parseReader(new FileReader(regionStorage)).getAsJsonObject();
+ HashMap map = new HashMap<>();
+ jsonObject.keySet().forEach(key -> {
+ map.put(key, fromJson(jsonObject.get(key)));
+ });
+ Region region = Region.getREGION_MAP().get(regionStorage.getName().substring(0, regionStorage.getName().length() - ".json".length()));
+ REGION_STORAGE.put(region, map);
+ } catch (Exception e) {}
+ }
+
+ File playerStorageDirectory = new File(storageDirectory, "player");
+ playerStorageDirectory.mkdirs();
+ for (File playerStorage : playerStorageDirectory.listFiles()) {
+ try {
+ JsonObject jsonObject = JsonParser.parseReader(new FileReader(playerStorage)).getAsJsonObject();
+ HashMap map = new HashMap<>();
+ jsonObject.keySet().forEach(key -> {
+ map.put(key, fromJson(jsonObject.get(key)));
+ });
+ SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(playerStorage.getName().substring(0, playerStorage.getName().length() - ".json".length())));
+ PLAYER_STORAGE.put(steamwarUser.getUUID(), map);
+ } catch (Exception e) {}
+ }
+ }
+
+ private LuaValue fromJson(JsonElement jsonElement) {
+ if (jsonElement.isJsonNull()) {
+ return LuaValue.NIL;
+ }
+ if (jsonElement.isJsonPrimitive()) {
+ JsonPrimitive jsonPrimitive = jsonElement.getAsJsonPrimitive();
+ if (jsonPrimitive.isBoolean()) {
+ return LuaValue.valueOf(jsonPrimitive.getAsBoolean());
+ }
+ if (jsonPrimitive.isNumber()) {
+ try {
+ return LuaValue.valueOf(jsonPrimitive.getAsInt());
+ } catch (NumberFormatException e) {}
+ try {
+ return LuaValue.valueOf(jsonPrimitive.getAsDouble());
+ } catch (NumberFormatException e) {}
+ }
+ if (jsonPrimitive.isString()) {
+ return LuaValue.valueOf(jsonPrimitive.getAsString());
+ }
+ return null;
+ }
+ if (jsonElement.isJsonObject()) {
+ JsonObject jsonObject = jsonElement.getAsJsonObject();
+ LuaTable luaTable = new LuaTable();
+ jsonObject.keySet().forEach(string -> {
+ LuaValue value = fromJson(jsonObject.get(string));
+ if (value == null) return;
+ luaTable.set(string, value);
+ });
+ return luaTable;
+ }
+ return null;
+ }
+
+ @Override
+ public void disable() {
+ if (Core.getVersion() <= 15) return;
+ if (!storageDirectory.exists()) storageDirectory.mkdirs();
+ try {
+ FileWriter fileWriter = new FileWriter(new File(storageDirectory, "global.json"));
+ gson.toJson(toJson(GLOBAL_STORAGE), fileWriter);
+ fileWriter.close();
+ } catch (IOException e) {}
+
+ File regionStorageDirectory = new File(storageDirectory, "region");
+ regionStorageDirectory.mkdirs();
+ for (Map.Entry> entry : REGION_STORAGE.entrySet()) {
+ try {
+ FileWriter fileWriter = new FileWriter(new File(regionStorageDirectory, entry.getKey().getName() + ".json"));
+ gson.toJson(toJson(entry.getValue()), fileWriter);
+ fileWriter.close();
+ } catch (IOException e) {}
+ }
+
+ File playerStorageDirectory = new File(storageDirectory, "player");
+ playerStorageDirectory.mkdirs();
+ for (Map.Entry> entry : PLAYER_STORAGE.entrySet()) {
+ try {
+ FileWriter fileWriter = new FileWriter(new File(playerStorageDirectory, SteamwarUser.get(entry.getKey()).getId() + ".json"));
+ gson.toJson(toJson(entry.getValue()), fileWriter);
+ fileWriter.close();
+ } catch (IOException e) {}
+ }
+ }
+
+ private JsonObject toJson(HashMap valueMap) {
+ JsonObject jsonObject = new JsonObject();
+ valueMap.forEach((string, luaValue) -> {
+ JsonElement value = toJson(luaValue);
+ if (value == null) return;
+ jsonObject.add(string, value);
+ });
+ return jsonObject;
+ }
+
+ private JsonElement toJson(LuaValue luaValue) {
+ if (luaValue.isnil()) {
+ return JsonNull.INSTANCE;
+ }
+ try {
+ return new JsonPrimitive(luaValue.checkboolean());
+ } catch (Exception e) {}
+ try {
+ return new JsonPrimitive(luaValue.checkint());
+ } catch (Exception e) {}
+ try {
+ return new JsonPrimitive(luaValue.checkdouble());
+ } catch (Exception e) {}
+
+ if (luaValue.isstring()) {
+ return new JsonPrimitive(luaValue.tojstring());
+ }
+ if (luaValue.istable()) {
+ LuaTable luaTable = luaValue.checktable();
+ JsonObject jsonObject = new JsonObject();
+ for (LuaValue key : luaTable.keys()) {
+ JsonElement value = toJson(luaTable.get(key));
+ if (value == null) continue;
+ try {
+ jsonObject.add(key.checkjstring(), value);
+ } catch (Exception e) {}
+ }
+ return jsonObject;
+ }
+ return null;
+ }
+
@Override
public String name() {
return "storage";
@@ -92,7 +256,7 @@ public class StorageLib implements LuaLib {
storageLib.set("global", global);
LuaTable playerStorage = new LuaTable();
- HashMap playerStorageMap = PLAYER_STORAGE.computeIfAbsent(player, k -> new HashMap<>());
+ HashMap playerStorageMap = PLAYER_STORAGE.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>());
playerStorage.set("get", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
@@ -137,34 +301,38 @@ public class StorageLib implements LuaLib {
storageLib.set("player", playerStorage);
LuaTable regionStorage = new LuaTable();
- HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
regionStorage.set("get", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
+ HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
return regionStorageMap.getOrDefault(arg.checkjstring(), NIL);
}
});
regionStorage.set("set", new TwoArgFunction() {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
+ HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
return regionStorageMap.put(arg1.checkjstring(), arg2);
}
});
regionStorage.set("has", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
+ HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
return valueOf(regionStorageMap.containsKey(arg.checkjstring()));
}
});
regionStorage.set("remove", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
+ HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
return regionStorageMap.remove(arg.checkjstring());
}
});
regionStorage.set("accessor", new OneArgFunction() {
@Override
public LuaValue call(LuaValue arg) {
+ HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>());
String key = arg.checkjstring();
return new VarArgFunction() {
@Override
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java
new file mode 100644
index 00000000..3b0b430d
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java
@@ -0,0 +1,53 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2024 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 .
+ */
+
+package de.steamwar.bausystem.features.script.lua.libs;
+
+import de.steamwar.bausystem.features.tpslimit.TPSSystem;
+import de.steamwar.core.TPSWatcher;
+import de.steamwar.linkage.Linked;
+import org.bukkit.entity.Player;
+import org.luaj.vm2.LuaTable;
+
+@Linked
+public class TpsLib implements LuaLib {
+
+ @Override
+ public Class extends LuaLib> parent() {
+ return ServerLib.class;
+ }
+
+ @Override
+ public String name() {
+ return "tps";
+ }
+
+ @Override
+ public LuaTable get(Player player) {
+ LuaTable tpsLib = new LuaTable();
+ tpsLib.set("oneSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND)));
+ tpsLib.set("tenSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS)));
+ tpsLib.set("oneMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE)));
+ tpsLib.set("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)));
+ tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
+ tpsLib.set("current", getter(TPSWatcher::getTPS));
+ tpsLib.set("limit", getter(TPSSystem.getInstance()::getCurrentTPSLimit));
+ return tpsLib;
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java
index 197300d0..1aa4149a 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java
@@ -20,8 +20,10 @@
package de.steamwar.bausystem.features.shieldprinting;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.shieldprinting.impl.*;
import de.steamwar.bausystem.region.Region;
+import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import de.steamwar.inventory.SWItem;
@@ -43,6 +45,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockCanBuildEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
@@ -259,18 +262,14 @@ public class ShieldPrinting implements Listener {
}
@EventHandler
- public void onPlayerInteract(PlayerInteractEvent event) {
- if (event.getClickedBlock() == null) return;
- if (event.getItem() == null) return;
- if (Region.getRegion(event.getClickedBlock().getLocation()) != region) return;
- Vector vector = event.getClickedBlock().getLocation().toVector();
- if (!shieldMap.containsKey(vector)) return;
- event.getClickedBlock().setType(Material.AIR);
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ updateBossbar(event.getPlayer());
}
@EventHandler
- public void onPlayerJoin(PlayerJoinEvent event) {
- updateBossbar(event.getPlayer());
+ public void onBauMemberUpdate(BauMemberUpdateEvent event) {
+ event.getNewSpectator().forEach(player -> BossBarService.instance.remove(player, region, "shieldprinting"));
+ event.getNewBuilder().forEach(this::updateBossbar);
}
private void updateBossbars() {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java
index d1b60349..5bb60219 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java
@@ -26,9 +26,7 @@ import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerInteractEvent;
import java.util.HashMap;
import java.util.Map;
@@ -108,8 +106,8 @@ public class ShieldPrintingCommand extends SWCommand implements Listener {
@ClassValidator(value = Player.class, local = true)
public TypeValidator validator() {
return (commandSender, player, messageSender) -> {
- if (!Permission.hasPermission(player, Permission.WORLD)) {
- messageSender.send("SHIELD_PRINTING_DISALLOWED", player);
+ if (!Permission.BUILD.hasPermission(player)) {
+ messageSender.send("NO_PERMISSION", player);
return false;
}
Region region = Region.getRegion(player.getLocation());
@@ -120,20 +118,4 @@ public class ShieldPrintingCommand extends SWCommand implements Listener {
return true;
};
}
-
- @EventHandler
- public void onPlayerInteract(PlayerInteractEvent event) {
- if (event.getClickedBlock() == null) {
- return;
- }
- Region region = Region.getRegion(event.getClickedBlock().getLocation());
- if (region.isGlobal()) {
- return;
- }
- ShieldPrinting shieldPrinting = SHIELD_PRINTING_MAP.get(region);
- if (shieldPrinting == null) {
- return;
- }
- shieldPrinting.onPlayerInteract(event);
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/OrderUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/OrderUtils.java
deleted file mode 100644
index 2c377cea..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/OrderUtils.java
+++ /dev/null
@@ -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 .
- */
-
-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 activationOrder = new ArrayList<>();
-
- private final Map 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 orderList(Material material, Player player) {
- List 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);
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorBauGuiItem.java
index baae7add..d03dc55c 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorBauGuiItem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorBauGuiItem.java
@@ -1,20 +1,20 @@
/*
- * This file is a part of the SteamWar software.
+ * This file is a part of the SteamWar software.
*
- * Copyright (C) 2021 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package de.steamwar.bausystem.features.simulator;
@@ -55,6 +55,6 @@ public class SimulatorBauGuiItem extends BauGuiItem {
@Override
public Permission permission() {
- return Permission.WORLD;
+ return Permission.BUILD;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java
index 640d0360..06af3e68 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java
@@ -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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
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 allSimulators() {
- return new TypeMapper() {
+ @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 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
@@ -129,11 +102,4 @@ public class SimulatorCommand extends SWCommand {
}
};
}
-
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "SIMULATOR_NO_PERMS");
- };
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java
index e8fc1bac..a7664158 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java
@@ -1,107 +1,248 @@
/*
- * 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
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.Permission;
+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.observer.ObserverElement;
+import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase;
+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.BauMemberUpdateEvent;
+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.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+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 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 cursorType = Collections.synchronizedMap(new HashMap<>());
+ private Map cursors = Collections.synchronizedMap(new HashMap<>());
+ private final Set calculating = new HashSet<>();
- if (cursor != null)
- cursor.close();
-
- tntSimulator.show(player);
-
- if (result == null)
- return;
-
- if (result.getHitEntity() != null) {
- List 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 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) {
+ if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ calcCursor(event.getPlayer());
+ }, 0);
+ }
+
+ @EventHandler
+ public void onPlayerDropItem(PlayerDropItemEvent event) {
+ if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
+ calcCursor(event.getPlayer());
+ }
+
+ @EventHandler
+ public void onPlayerItemHeld(PlayerItemHeldEvent event) {
+ if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ calcCursor(event.getPlayer());
+ }, 1);
+ }
+
+ @EventHandler
+ public void onBauMemberUpdate(BauMemberUpdateEvent event) {
+ event.getChanged().forEach(this::calcCursor);
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ cursorType.remove(event.getPlayer());
+ cursors.remove(event.getPlayer());
+ synchronized (calculating) {
+ calculating.remove(event.getPlayer());
+ }
+ }
+
+ private static final Map 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 void calcCursor(Player player) {
+ synchronized (calculating) {
+ if (calculating.contains(player)) return;
+ calculating.add(player);
+ }
+ if (!Permission.BUILD.hasPermission(player) || (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand()))) {
+ if (removeCursor(player) || SimulatorWatcher.show(null, player)) {
+ SWUtils.sendToActionbar(player, "");
+ }
+ synchronized (calculating) {
+ calculating.remove(player);
+ }
+ return;
+ }
+ Simulator simulator = SimulatorStorage.getSimulator(player);
+ SimulatorWatcher.show(simulator, player);
+
+ List 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");
+ }
+ synchronized (calculating) {
+ calculating.remove(player);
+ }
+ return;
+ }
+
+ showCursor(player, rayTraceResult, simulator != null);
+ synchronized (calculating) {
+ calculating.remove(player);
+ }
+ }
+
+ 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 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 getPosFree(Player player, RayTraceUtils.RRayTraceResult result) {
Vector pos = result.getHitPosition();
BlockFace face = result.getHitBlockFace();
@@ -140,4 +281,177 @@ public class SimulatorCursor {
return pos;
}
+
+ private static Vector getPosBlockAligned(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::getPosFree, "TNT", vector -> new TNTElement(vector).add(new TNTPhase())),
+ REDSTONE_BLOCK(Material.REDSTONE_BLOCK, SimulatorCursor::getPosBlockAligned, "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())),
+ OBSERVER(Material.OBSERVER, SimulatorCursor::getPosBlockAligned, "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())),
+ ;
+
+ private Material material;
+ private BiFunction position;
+ private String name;
+ private Function> elementFunction;
+
+ public CursorType switchType() {
+ if (this == TNT) {
+ return REDSTONE_BLOCK;
+ }
+ if (this == REDSTONE_BLOCK) {
+ return OBSERVER;
+ }
+ return TNT;
+ }
+ }
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
+ 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> 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 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);
+ }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorStorage.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorStorage.java
index a549e0a2..b3fbcba8 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorStorage.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorStorage.java
@@ -1,124 +1,172 @@
/*
- * 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
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 simulatorMap = new HashMap<>();
private static NamespacedKey simulatorSelection = SWUtils.getNamespaceKey("simulator_selection");
- private static Map tntSimulators = new HashMap<>();
-
- public static void createNewSimulator(String name) {
- tntSimulators.put(name, new TNTSimulator());
- }
-
- public static Set 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 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();
+
+ File[] files = simulatorsDir.listFiles();
+ if (files == null) return;
+ for (File file : files) {
+ try {
+ List simulators = simFormatSimulatorLoader.load(file)
+ .orElse(null);
+ if (simulators != null) {
+ simulators.forEach(simulator -> {
+ simulatorMap.put(simulator.getName(), simulator);
+ });
+ continue;
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+
+ try {
+ List 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 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 simulatorPageGui = new SimulatorPageGui(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 +178,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 entry : tntSimulators.entrySet()) {
- try {
- entry.getValue().toYAPION().toFile(new File(simulatorsDir, entry.getKey() + ".simulator"));
- } catch (Exception e) {
- e.printStackTrace();
- }
+ public static List 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;
}
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorWatcher.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorWatcher.java
new file mode 100644
index 00000000..d5f98986
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorWatcher.java
@@ -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 .
+ */
+
+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 entityServers = new HashMap<>();
+ private Map> 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>> 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 getEntitiesOfSimulator(Simulator simulator) {
+ REntityServer entityServer = entityServers.get(simulator);
+ if (entityServer == null) {
+ return Collections.emptyList();
+ }
+ return entityServer.getEntities();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java
deleted file mode 100644
index ef00d521..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java
+++ /dev/null
@@ -1,279 +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 .
- */
-
-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.Recorder;
-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 de.steamwar.linkage.LinkedInstance;
-import lombok.Getter;
-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 players = new HashSet<>();
- private REntityServer entityServer = new REntityServer();
-
- private Material material = Material.TNT;
-
- private List tntElementList = new ArrayList<>();
-
- @LinkedInstance
- public Recorder traceRecorder;
-
- private Region autoTraceRegion;
-
- 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 getEntities() {
- return tntElementList.stream().flatMap(element -> element.getEntities().stream()).collect(Collectors.toList());
- }
-
- public List getEntity(REntity entity) {
- List 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 elements = getEntity(result.getHitEntity());
- if (elements.isEmpty()) return;
-
- if (elements.size() == 1) {
- TNTElementGUI.open(player, (TNTElement) elements.get(0), null);
- } else {
- List tntGroups = tntElementList.stream().filter(TNTGroup.class::isInstance).map(TNTGroup.class::cast).collect(Collectors.toList());
- List 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 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>>> 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()) {
- traceRecorder.startRecording(region);
- autoTraceRegion = region;
- }
-
- AtomicInteger maxTick = new AtomicInteger(0);
- Map>>> toSpawn = new HashMap<>();
- result.forEach((integer, integerSetMap) -> {
- List>>> 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()) {
- traceRecorder.stopRecording(autoTraceRegion);
- autoTraceRegion = null;
- bukkitTask.cancel();
- }
- currentTick.incrementAndGet();
-
- List>> 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);
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java
deleted file mode 100644
index a3862c9f..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java
+++ /dev/null
@@ -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 .
- */
-
-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 oldItemFunction, Function 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;
- }
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java
new file mode 100644
index 00000000..91b7a8e1
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java
@@ -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 .
+ */
+
+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 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 tickStart, BiConsumer tickEnd) {
+ groups.forEach(simulatorGroup -> {
+ simulatorGroup.toSimulatorActions(tickStart, tickEnd);
+ });
+ }
+
+ public Simulator add(SimulatorGroup group) {
+ groups.add(group);
+ return this;
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java
new file mode 100644
index 00000000..de0d2b69
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java
@@ -0,0 +1,35 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.bausystem.features.simulator.data;
+
+import org.bukkit.Material;
+import org.bukkit.util.Vector;
+
+public abstract class SimulatorBlockAlignedElement extends SimulatorElement {
+
+ protected SimulatorBlockAlignedElement(Material material, Vector position) {
+ super(material, position);
+ }
+
+ @Override
+ public final boolean canBeInGroup(SimulatorGroup simulatorGroup) {
+ return simulatorGroup.getElements().stream().allMatch(SimulatorBlockAlignedElement.class::isInstance);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorElement.java
new file mode 100644
index 00000000..119143db
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorElement.java
@@ -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 .
+ */
+
+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 {
+ protected Material material;
+ protected final Vector position;
+ protected boolean disabled = false;
+ protected final List phases = new ArrayList<>();
+
+ protected SimulatorElement(Material material, Vector position) {
+ this.material = material;
+ this.position = position;
+ }
+
+ public SimulatorElement 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 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 tickStart, BiConsumer 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) {}
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorGroup.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorGroup.java
new file mode 100644
index 00000000..8031dd1c
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorGroup.java
@@ -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 .
+ */
+
+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> 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 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 tickStart, BiConsumer tickEnd) {
+ if (disabled) return;
+ elements.forEach(simulatorElement -> {
+ simulatorElement.toSimulatorActions(tickStart, tickEnd);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorPhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorPhase.java
new file mode 100644
index 00000000..b226d124
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorPhase.java
@@ -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 .
+ */
+
+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 tickStart, BiConsumer tickEnd);
+ public void saveExtra(YAPIONObject phaseObject) {}
+ public void loadExtra(YAPIONObject phaseObject) {}
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java
new file mode 100644
index 00000000..7fdff328
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java
@@ -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 .
+ */
+
+package de.steamwar.bausystem.features.simulator.data.observer;
+
+import de.steamwar.bausystem.features.simulator.data.Simulator;
+import de.steamwar.bausystem.features.simulator.data.SimulatorBlockAlignedElement;
+import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
+import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
+import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
+import de.steamwar.bausystem.features.simulator.gui.SimulatorObserverGui;
+import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockState;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiConsumer;
+
+public final class ObserverElement extends SimulatorBlockAlignedElement {
+
+ public ObserverElement(Vector position) {
+ super(Material.OBSERVER, position);
+ }
+
+ @Override
+ public String getName(Player player) {
+ return "Observer";
+ }
+
+ @Override
+ public Material getWorldMaterial() {
+ return Material.OBSERVER;
+ }
+
+ @Override
+ public Material getWorldDisabledMaterial() {
+ return Material.GRAY_STAINED_GLASS;
+ }
+
+ public void toSimulatorActions(BiConsumer tickStart, BiConsumer tickEnd) {
+ if (disabled) return;
+ phases.forEach(phase -> {
+ phase.toSimulatorActions(position.clone(), tickStart, tickEnd);
+ });
+
+ int end = phases.stream().mapToInt(SimulatorPhase::getTickOffset).max().orElse(0) + 4;
+ AtomicReference blockState = new AtomicReference<>();
+ tickStart.accept(0, new SimulatorAction(-100, 1) {
+ @Override
+ public void accept(World world) {
+ Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
+ blockState.set(block.getState());
+ block.setType(Material.OBSERVER, false);
+ }
+ });
+ tickEnd.accept(end, new SimulatorAction(0, 1) {
+ @Override
+ public void accept(World world) {
+ BlockState oldState = blockState.get();
+ if (oldState != null) {
+ oldState.update(true, true);
+ } else {
+ Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
+ block.setType(Material.AIR);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back) {
+ new SimulatorObserverGui(player, simulator, group, this, back).open();
+ }
+
+ @Override
+ public String getType() {
+ return "Observer";
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java
new file mode 100644
index 00000000..e3707c3e
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java
@@ -0,0 +1,81 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.bausystem.features.simulator.data.observer;
+
+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.Material;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.block.BlockState;
+import org.bukkit.block.data.type.Observer;
+import org.bukkit.util.Vector;
+import yapion.hierarchy.types.YAPIONObject;
+
+import java.util.function.BiConsumer;
+
+@NoArgsConstructor
+public final class ObserverPhase extends SimulatorPhase {
+
+ @Getter
+ @Setter
+ private BlockFace orientation = BlockFace.UP;
+
+ public ObserverPhase(int tickOffset) {
+ this.tickOffset = tickOffset;
+ }
+
+ {
+ this.lifetime = 0;
+ }
+
+ @Override
+ public void toSimulatorActions(Vector position, BiConsumer tickStart, BiConsumer tickEnd) {
+ Observer observer = (Observer) Material.OBSERVER.createBlockData();
+ observer.setFacing(orientation.getOppositeFace());
+ observer.setPowered(true);
+
+ tickStart.accept(tickOffset, new SimulatorAction(order, 1) {
+ @Override
+ public void accept(World world) {
+ Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
+ Block updateBlock = block.getRelative(orientation);
+ BlockState state = updateBlock.getState();
+ updateBlock.setType(Material.SPONGE, true);
+ block.setBlockData(observer, true);
+ state.update(true, true);
+ }
+ });
+ }
+
+ @Override
+ public void saveExtra(YAPIONObject phaseObject) {
+ phaseObject.add("orientation", orientation.name());
+ }
+
+ @Override
+ public void loadExtra(YAPIONObject phaseObject) {
+ orientation = BlockFace.valueOf(phaseObject.getPlainValue("orientation"));
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java
new file mode 100644
index 00000000..3b949609
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java
@@ -0,0 +1,66 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.bausystem.features.simulator.data.redstone;
+
+import de.steamwar.bausystem.features.simulator.data.Simulator;
+import de.steamwar.bausystem.features.simulator.data.SimulatorBlockAlignedElement;
+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 SimulatorBlockAlignedElement {
+
+ 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 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";
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstonePhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstonePhase.java
new file mode 100644
index 00000000..614be659
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstonePhase.java
@@ -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 .
+ */
+
+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 tickStart, BiConsumer tickEnd) {
+ AtomicReference 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);
+ }
+ });
+ tickStart.accept(tickOffset + lifetime, new SimulatorAction(ORDER_LIMIT + 1, 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);
+ }
+ }
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTElement.java
new file mode 100644
index 00000000..29e90d83
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTElement.java
@@ -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 .
+ */
+
+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 {
+
+ 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";
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java
new file mode 100644
index 00000000..4c03ac9b
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java
@@ -0,0 +1,97 @@
+/*
+ * 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 .
+ */
+
+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 de.steamwar.bausystem.region.Region;
+import de.steamwar.bausystem.region.flags.Flag;
+import de.steamwar.bausystem.region.flags.flagvalues.FreezeMode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.bukkit.Location;
+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 tickStart, BiConsumer tickEnd) {
+ tickStart.accept(tickOffset, new SimulatorAction(order, count) {
+ @Override
+ public void accept(World world) {
+ Location location = position.toLocation(world);
+ if (Region.getRegion(location).get(Flag.FREEZE) == FreezeMode.ACTIVE) return;
+ TNTPrimed tnt = world.spawn(location, 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");
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorAction.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorAction.java
new file mode 100644
index 00000000..c6c9f1da
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorAction.java
@@ -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 .
+ */
+
+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 {
+ private int order;
+
+ @Setter
+ private int count;
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java
new file mode 100644
index 00000000..893161f4
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java
@@ -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 .
+ */
+
+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 currentlyRunning = new HashSet<>();
+ private static Map>> tickStartActions = new HashMap<>();
+ private static Map> 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> actionsToRun = tickStartActions.remove(currentTick);
+ if (actionsToRun == null) return;
+
+ List 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 actionsToRun = tickEndActions.remove(currentTick);
+ if (actionsToRun == null) return;
+ runActions(actionsToRun);
+ }
+
+ private void runActions(List 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);
+ }
+ }
+ }
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/ItemUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/ItemUtils.java
deleted file mode 100644
index 8a4bceb5..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/ItemUtils.java
+++ /dev/null
@@ -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 .
- */
-
-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;
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupChooserGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupChooserGui.java
new file mode 100644
index 00000000..10396677
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupChooserGui.java
@@ -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 .
+ */
+
+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 {
+
+ 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);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupGui.java
new file mode 100644
index 00000000..c3b8ee1a
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupGui.java
@@ -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 .
+ */
+
+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> {
+
+ 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 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);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupSettingsGui.java
new file mode 100644
index 00000000..e9439ce9
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupSettingsGui.java
@@ -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 .
+ */
+
+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);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGui.java
new file mode 100644
index 00000000..e35f0eaa
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGui.java
@@ -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 .
+ */
+
+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 {
+
+ 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);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java
new file mode 100644
index 00000000..84f1e682
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java
@@ -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 .
+ */
+
+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 {
+
+ private static final List MATERIALS = Arrays.stream(Material.values())
+ .filter(material -> !material.isAir())
+ .filter(material -> !material.isLegacy())
+ .filter(Material::isItem)
+ .collect(Collectors.toList());
+
+ private final Supplier currentMaterial;
+ private Material material;
+ private final Consumer change;
+ private final SimulatorBaseGui back;
+
+ public SimulatorMaterialGui(Player player, Simulator simulator, Supplier currentMaterial, Consumer 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);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java
new file mode 100644
index 00000000..42669387
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java
@@ -0,0 +1,188 @@
+/*
+ * 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 .
+ */
+
+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.observer.ObserverElement;
+import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase;
+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.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+public class SimulatorObserverGui extends SimulatorScrollGui {
+
+ private final SimulatorGroup parent;
+ private final ObserverElement observer;
+ private final SimulatorBaseGui back;
+
+ public SimulatorObserverGui(Player player, Simulator simulator, SimulatorGroup parent, ObserverElement observer, SimulatorBaseGui back) {
+ super(player, simulator, 6 * 9, observer.getPhases());
+ this.parent = parent;
+ this.observer = observer;
+ this.back = back;
+ }
+
+ @Override
+ public String baseTitle() {
+ return "Observer";
+ }
+
+ @Override
+ public void headerAndFooter() {
+ if (observer.getPhases().isEmpty()) {
+ back.open();
+ SimulatorWatcher.update(simulator);
+ return;
+ }
+
+ observer.sort();
+
+ // Back Arrow
+ inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
+ if (parent.getElements().contains(observer)) {
+ back.open();
+ } else {
+ SimulatorGroup newParent = observer.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 -> {
+ observer.getPhases().clear();
+ SimulatorWatcher.update(simulator);
+ }));
+
+ // Material Chooser
+ inventory.setItem(4, observer.toItem(player, clickType -> {
+ new SimulatorMaterialGui(player, simulator, observer::getMaterial, observer::setMaterial, this).open();
+ }));
+
+ // Settings
+ inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> {
+ new SimulatorObserverSettingsGui(player, simulator, observer, this).open();
+ }));
+
+ // Enable/Disable
+ inventory.setItem(48, new SWItem(observer.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, observer.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> {
+ observer.setDisabled(!observer.isDisabled());
+ SimulatorWatcher.update(simulator);
+ }));
+
+ // Group chooser
+ inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> {
+ new SimulatorGroupChooserGui(player, simulator, observer, observer.getGroup(simulator), this).open();
+ }));
+ }
+
+ @Override
+ public SWItem[] column(ObserverPhase observerPhase, int index) {
+ int min;
+ if (index > 0) {
+ min = data.get(index - 1).getTickOffset() + 4;
+ } else {
+ min = 0;
+ }
+
+ int max;
+ if (index < data.size() - 1) {
+ max = data.get(index + 1).getTickOffset() - 4;
+ } else {
+ max = Integer.MAX_VALUE - 4;
+ }
+
+ List lore = new ArrayList<>();
+ lore.add("§7Time§8:§e " + observerPhase.getTickOffset());
+ lore.add("§7Order§8:§e " + observerPhase.getOrder());
+ lore.add("");
+ lore.add("§7Orientation§8:§e " + observerPhase.getOrientation().name());
+ lore.add("");
+ lore.add("§7Click§8:§e Edit");
+ lore.add("§7Middle-Click§8:§e Remove");
+ SWItem observer = new SWItem(Material.OBSERVER, "§eObserver", lore, false, clickType -> {
+ if (clickType == ClickType.MIDDLE) {
+ this.observer.getPhases().remove(observerPhase);
+ SimulatorWatcher.update(simulator);
+ } else {
+ new SimulatorObserverPhaseSettingsGui(player, simulator, this.observer, observerPhase, this).open();
+ }
+ });
+ observer.getItemStack().setAmount(Math.min(Math.max(observerPhase.getTickOffset(), 1), 64));
+
+ Supplier getter = observerPhase::getTickOffset;
+ Consumer setter = observerPhase::setTickOffset;
+ 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);
+ }),
+ observer,
+ 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 SimulatorObserverPhaseSettingsGui(player, simulator, this.observer, observerPhase, 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.QUARTZ, "§eObserver§8:§a New Phase", clickType -> {
+ addNewPhase(false);
+ }),
+ new SWItem(SWItem.getDye(8), "§7", clickType -> {
+ }),
+ };
+ }
+
+ private void addNewPhase(boolean shift) {
+ ObserverPhase lastElement = observer.getPhases().get(observer.getPhases().size() - 1);
+ ObserverPhase newPhase = new ObserverPhase(lastElement.getTickOffset() + 4);
+ if (shift) newPhase.setTickOffset(newPhase.getTickOffset() + 5);
+ scroll += 2;
+ observer.add(newPhase);
+ SimulatorWatcher.update(simulator);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java
new file mode 100644
index 00000000..f7925c34
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java
@@ -0,0 +1,172 @@
+/*
+ * 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 .
+ */
+
+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.observer.ObserverElement;
+import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase;
+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.block.BlockFace;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+
+public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui {
+
+ private final ObserverElement observerElement;
+ private final ObserverPhase observer;
+ private final SimulatorBaseGui back;
+
+ public SimulatorObserverPhaseSettingsGui(Player player, Simulator simulator, ObserverElement observerElement, ObserverPhase observer, SimulatorBaseGui back) {
+ super(player, simulator, 5 * 9);
+ this.observerElement = observerElement;
+ this.observer = observer;
+ this.back = back;
+ }
+
+ @Override
+ public String title() {
+ return "Observer";
+ }
+
+ @Override
+ public void populate() {
+ if (!observerElement.getPhases().contains(observer)) {
+ back.open();
+ return;
+ }
+
+ // Back Arrow
+ inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
+ back.open();
+ }));
+
+ // Material Chooser
+ inventory.setItem(4, observerElement.toItem(player, clickType -> {
+ new SimulatorMaterialGui(player, simulator, observerElement::getMaterial, observerElement::setMaterial, this).open();
+ }));
+
+ // Delete
+ inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> {
+ observerElement.getPhases().remove(observer);
+ back.open();
+ SimulatorWatcher.update(simulator);
+ }));
+
+ int index = observerElement.getPhases().indexOf(observer);
+ int min;
+ if (index > 0) {
+ ObserverPhase previous = observerElement.getPhases().get(index - 1);
+ min = previous.getTickOffset() + 4;
+ } else {
+ min = 0;
+ }
+
+ int max;
+ if (index < observerElement.getPhases().size() - 1) {
+ ObserverPhase next = observerElement.getPhases().get(index + 1);
+ max = next.getTickOffset() - 4;
+ } else {
+ max = Integer.MAX_VALUE - 4;
+ }
+
+ //Tick Offset
+ int offset = observer.getTickOffset();
+ inventory.setItem(10, SWItem.getDye(offset < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
+ observer.setTickOffset(Math.min(max, 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;
+ observer.setTickOffset(Math.min(Math.max(integer, min), max));
+ 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 -> {
+ observer.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
+ SimulatorWatcher.update(simulator);
+ });
+
+ //Order
+ int order = observer.getOrder();
+ inventory.setItem(13, SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
+ observer.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;
+ observer.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 -> {
+ observer.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
+ SimulatorWatcher.update(simulator);
+ });
+
+ // Update orientation
+ inventory.setItem(25, new SWItem(Material.SUNFLOWER, "§7", clickType -> {
+ }));
+ inventory.setItem(15, new SWItem(observer.getOrientation() == BlockFace.UP ? Material.LIME_CONCRETE : Material.GRAY_CONCRETE, "§eUp", clickType -> {
+ observer.setOrientation(BlockFace.UP);
+ SimulatorWatcher.update(simulator);
+ }));
+ inventory.setItem(33, new SWItem(observer.getOrientation() == BlockFace.DOWN ? Material.RED_CONCRETE : Material.GRAY_CONCRETE, "§eDown", clickType -> {
+ observer.setOrientation(BlockFace.DOWN);
+ SimulatorWatcher.update(simulator);
+ }));
+ inventory.setItem(16, new SWItem(observer.getOrientation() == BlockFace.NORTH ? Material.LIME_WOOL : Material.GRAY_WOOL, "§eNorth", clickType -> {
+ observer.setOrientation(BlockFace.NORTH);
+ SimulatorWatcher.update(simulator);
+ }));
+ inventory.setItem(34, new SWItem(observer.getOrientation() == BlockFace.SOUTH ? Material.RED_WOOL : Material.GRAY_WOOL, "§eSouth", clickType -> {
+ observer.setOrientation(BlockFace.SOUTH);
+ SimulatorWatcher.update(simulator);
+ }));
+ inventory.setItem(24, new SWItem(observer.getOrientation() == BlockFace.EAST ? Material.LIME_STAINED_GLASS : Material.GRAY_STAINED_GLASS, "§eEast", clickType -> {
+ observer.setOrientation(BlockFace.EAST);
+ SimulatorWatcher.update(simulator);
+ }));
+ inventory.setItem(26, new SWItem(observer.getOrientation() == BlockFace.WEST ? Material.RED_STAINED_GLASS : Material.GRAY_STAINED_GLASS, "§eWest", clickType -> {
+ observer.setOrientation(BlockFace.WEST);
+ SimulatorWatcher.update(simulator);
+ }));
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java
new file mode 100644
index 00000000..8084c7b1
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java
@@ -0,0 +1,142 @@
+/*
+ * 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 .
+ */
+
+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.observer.ObserverElement;
+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 SimulatorObserverSettingsGui extends SimulatorBaseGui {
+
+ private final ObserverElement observer;
+ private final SimulatorBaseGui back;
+
+ public SimulatorObserverSettingsGui(Player player, Simulator simulator, ObserverElement observer, SimulatorBaseGui back) {
+ super(player, simulator, 5 * 9);
+ this.observer = observer;
+ this.back = back;
+ }
+
+ @Override
+ public String title() {
+ return "Observer";
+ }
+
+ @Override
+ public void populate() {
+ if (observer.getPhases().isEmpty()) {
+ back.open();
+ return;
+ }
+
+ // Back Arrow
+ inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
+ back.open();
+ }));
+
+ // Material Chooser
+ inventory.setItem(4, observer.toItem(player, clickType -> {
+ new SimulatorMaterialGui(player, simulator, observer::getMaterial, observer::setMaterial, this).open();
+ }));
+
+ // Base Tick
+ int baseTicks = observer.getBaseTick();
+ inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
+ observer.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;
+ observer.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) {
+ observer.changeBaseTicks(-baseTicks);
+ } else {
+ observer.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 -> {
+ observer.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
+ SimulatorWatcher.update(simulator);
+ });
+ inventory.setItem(24, new SWItem(Material.PAPER, "§eX§8:§7 " + observer.getPosition().getBlockX(), clickType -> {
+ new SimulatorAnvilGui<>(player, "X", observer.getPosition().getBlockX() + "", Integer::parseInt, i -> {
+ observer.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 -> {
+ observer.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 -> {
+ observer.move(0, clickType.isShiftClick() ? 5 : 1, 0);
+ SimulatorWatcher.update(simulator);
+ });
+ inventory.setItem(25, new SWItem(Material.PAPER, "§eY§8:§7 " + observer.getPosition().getBlockY(), clickType -> {
+ new SimulatorAnvilGui<>(player, "Y", observer.getPosition().getBlockY() + "", Integer::parseInt, i -> {
+ observer.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 -> {
+ observer.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 -> {
+ observer.move(0, 0, clickType.isShiftClick() ? 5 : 1);
+ SimulatorWatcher.update(simulator);
+ });
+ inventory.setItem(26, new SWItem(Material.PAPER, "§eZ§8:§7 " + observer.getPosition().getBlockZ(), clickType -> {
+ new SimulatorAnvilGui<>(player, "Z", observer.getPosition().getBlockZ() + "", Integer::parseInt, i -> {
+ observer.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 -> {
+ observer.move(0, 0, clickType.isShiftClick() ? -5 : -1);
+ SimulatorWatcher.update(simulator);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java
new file mode 100644
index 00000000..2e288895
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java
@@ -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 .
+ */
+
+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 {
+
+ 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(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> {
+ new SimulatorRedstoneSettingsGui(player, simulator, redstone, this).open();
+ }));
+
+ // Enable/Disable
+ inventory.setItem(48, new SWItem(redstone.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, redstone.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> {
+ redstone.setDisabled(!redstone.isDisabled());
+ SimulatorWatcher.update(simulator);
+ }));
+
+ // Group chooser
+ inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> {
+ new SimulatorGroupChooserGui(player, simulator, redstone, redstone.getGroup(simulator), this).open();
+ }));
+ }
+
+ @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 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 getter = redstoneSubPhase.place ? redstoneSubPhase.phase::getTickOffset : redstoneSubPhase.phase::getLifetime;
+ Consumer 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 {
+ 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());
+ }
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstonePhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstonePhaseSettingsGui.java
new file mode 100644
index 00000000..27901b09
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstonePhaseSettingsGui.java
@@ -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 .
+ */
+
+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);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneSettingsGui.java
new file mode 100644
index 00000000..184d73a1
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneSettingsGui.java
@@ -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 .
+ */
+
+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);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSelectionGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSelectionGUI.java
deleted file mode 100644
index 2ca90d2a..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSelectionGUI.java
+++ /dev/null
@@ -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 .
- */
-
-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> 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 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();
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSettingsGui.java
new file mode 100644
index 00000000..ccb00412
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSettingsGui.java
@@ -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 .
+ */
+
+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);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java
new file mode 100644
index 00000000..a9c178ce
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java
@@ -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 .
+ */
+
+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 {
+
+ 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(tnt.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, tnt.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> {
+ tnt.setDisabled(!tnt.isDisabled());
+ SimulatorWatcher.update(simulator);
+ }));
+ 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(Material.LEAD, "§eJoin Group", clickType -> {
+ new SimulatorGroupChooserGui(player, simulator, tnt, tnt.getGroup(simulator), this).open();
+ }));
+ }
+
+ @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);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTPhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTPhaseSettingsGui.java
new file mode 100644
index 00000000..9bfc4fe5
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTPhaseSettingsGui.java
@@ -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 .
+ */
+
+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 < 1) 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);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTSettingsGui.java
new file mode 100644
index 00000000..1dcf005c
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTSettingsGui.java
@@ -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 .
+ */
+
+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 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);
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTElementGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTElementGUI.java
deleted file mode 100644
index 93181f90..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTElementGUI.java
+++ /dev/null
@@ -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 .
- */
-
-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 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 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 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 plusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_FIVE_SHIFT", player));
- List minusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_FIVE_SHIFT", player));
- List 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 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();
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTGroupEditGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTGroupEditGUI.java
deleted file mode 100644
index 9c4aa70a..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTGroupEditGUI.java
+++ /dev/null
@@ -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 .
- */
-
-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 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 plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player));
- List minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player));
- List 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 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 plusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_FIVE_SHIFT", player));
- List minusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_FIVE_SHIFT", player));
- List 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 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();
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTSimulatorGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTSimulatorGui.java
deleted file mode 100644
index e813580a..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTSimulatorGui.java
+++ /dev/null
@@ -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 .
- */
-
-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> simulatorElements, Runnable back) {
- List> 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 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 elements = simulatorElements.get();
- inv.setItem(elements.isEmpty() ? 49 : 50, swItem);
- if (currentTntGroup != null) {
- Runnable editObserver = () -> {
- List 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 plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player));
- List minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player));
- List 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));
- }
- }
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java
new file mode 100644
index 00000000..380dc618
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java
@@ -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 .
+ */
+
+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 {
+
+ private SWAnvilInv anvilInv;
+
+ public SimulatorAnvilGui(Player player, String title, String defaultText, Function mapper, Function 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 setItem(Material material) {
+ anvilInv.setItem(material);
+ return this;
+ }
+
+ public void open() {
+ anvilInv.open();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java
new file mode 100644
index 00000000..41f95a88
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java
@@ -0,0 +1,100 @@
+/*
+ * 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 .
+ */
+
+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();
+ if (player.getOpenInventory().getTopInventory() == inv) {
+ inventory.open();
+ SimulatorWatcher.watch(player, simulator, this::open);
+ }
+ 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);
+ });
+
+ SimulatorWatcher.watch(player, simulator, this::open);
+ populate();
+ inventory.open();
+ }
+
+ 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();
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorPageGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorPageGui.java
new file mode 100644
index 00000000..e3c3ccbd
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorPageGui.java
@@ -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 .
+ */
+
+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 extends SimulatorBaseGui {
+
+ protected int page = 0;
+ protected List data;
+
+ protected SimulatorPageGui(Player player, Simulator simulator, int size, List 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);
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorScrollGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorScrollGui.java
new file mode 100644
index 00000000..a4cfbb5d
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorScrollGui.java
@@ -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 .
+ */
+
+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 extends SimulatorBaseGui {
+ protected int scroll = 0;
+ protected final List data;
+
+ protected SimulatorScrollGui(Player player, Simulator simulator, int size, List 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();
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangeMaterial.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangeMaterial.java
deleted file mode 100644
index 5c6750fc..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangeMaterial.java
+++ /dev/null
@@ -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 .
- */
-
-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 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> 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 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();
- }
- }));
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangePosition.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangePosition.java
deleted file mode 100644
index 16f1090c..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangePosition.java
+++ /dev/null
@@ -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 .
- */
-
-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> toChangeVector, Runnable back) {
- String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player);
- String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player);
- List plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player));
- List minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player));
- List 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 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();
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/Disabled.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/Disabled.java
deleted file mode 100644
index a6798165..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/Disabled.java
+++ /dev/null
@@ -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 .
- */
-
-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();
- }));
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java
new file mode 100644
index 00000000..218c89a4
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java
@@ -0,0 +1,135 @@
+/*
+ * 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 .
+ */
+
+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.observer.ObserverElement;
+import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase;
+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> 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 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;
+ case "Observer":
+ element = new ObserverElement(position);
+ phaseConstructor = ObserverPhase::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 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);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorFormatSimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorFormatSimulatorLoader.java
new file mode 100644
index 00000000..a386f86d
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorFormatSimulatorLoader.java
@@ -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 .
+ */
+
+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> 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;
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorLoader.java
new file mode 100644
index 00000000..4c9e3f92
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorLoader.java
@@ -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 .
+ */
+
+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> load(File file);
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorSaver.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorSaver.java
new file mode 100644
index 00000000..48ccfd7a
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorSaver.java
@@ -0,0 +1,84 @@
+/*
+ * 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 .
+ */
+
+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) {
+ if (!directory.exists()) {
+ directory.mkdirs();
+ }
+
+ 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
+ }
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/YAPIONFormatSimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/YAPIONFormatSimulatorLoader.java
new file mode 100644
index 00000000..0c715443
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/YAPIONFormatSimulatorLoader.java
@@ -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 .
+ */
+
+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> 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 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);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/SimulatorElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/SimulatorElement.java
deleted file mode 100644
index 181e3389..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/SimulatorElement.java
+++ /dev/null
@@ -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 .
- */
-
-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> observer = new HashMap<>();
- Map closeObserver = new HashMap<>();
-
- YAPIONObject toYAPION();
- List getEntities();
- void getEntity(List elements, REntity entity);
-
- Vector getPosition();
- void setPosition(Vector position);
-
- void remove(TNTElement tntElement);
-
- SWItem menu(Player p);
- boolean locations(Map>>> 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 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);
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java
deleted file mode 100644
index 666c3359..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java
+++ /dev/null
@@ -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 .
- */
-
-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 getEntities() {
- if (disabled) return new ArrayList<>();
- return Arrays.asList(entity);
- }
-
- @Override
- public void getEntity(List 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 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>>> 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));
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java
deleted file mode 100644
index f3327578..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java
+++ /dev/null
@@ -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 .
- */
-
-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 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 getEntities() {
- if (disabled) new ArrayList<>();
- return elements.stream().flatMap(tntElement -> tntElement.getEntities().stream()).collect(Collectors.toList());
- }
-
- @Override
- public void getEntity(List 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 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>>> 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);
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java
index 86585417..daff9d87 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java
@@ -78,11 +78,4 @@ public class LaufbauCommand extends SWCommand {
public void laufbauSettings(@Validator Player player) {
new LaufbauSettings(player);
}
-
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "LAUFBAU_NO_PERM");
- };
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/PanzernCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/PanzernCommand.java
index 3bb2379e..cca7a266 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/PanzernCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/PanzernCommand.java
@@ -91,13 +91,6 @@ public class PanzernCommand extends SWCommand {
}.runTaskTimer(BauSystem.getInstance(), 1, 1);
}
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "PANZERN_NO_PERM");
- };
- }
-
@Mapper(value = "block", local = true)
private TypeMapper blockMapper() {
Set strings = new HashSet<>();
@@ -130,7 +123,7 @@ public class PanzernCommand extends SWCommand {
if (!material.isBlock()) {
continue;
}
- if (material.name().contains("STAIRS") || material.name().contains("SLAB")) {
+ if (material.name().contains("STAIRS") || material.name().contains("SLAB") || material.name().contains("GLASS")) {
strings.add(material.name().toLowerCase());
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java
index 07748a98..de40c6c7 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.smartplace;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
@@ -39,7 +40,10 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.inventory.ItemStack;
+import java.io.OutputStream;
+import java.io.PrintStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -67,11 +71,13 @@ public class SmartPlaceListener implements Plain, Listener {
}
}
CONTAINERS.add(Material.GRINDSTONE);
+ CONTAINERS.remove(Material.COMPARATOR);
state.update(true, false);
IGNORED.add(Material.TNT);
IGNORED.add(Material.REDSTONE_ORE);
IGNORED.add(SWItem.getMaterial("BEEHIVE"));
+ IGNORED.add(SWItem.getMaterial("SEA_PICKLE"));
IGNORED.remove(Material.STONE);
IGNORED.remove(Material.BARRIER);
}
@@ -89,32 +95,42 @@ public class SmartPlaceListener implements Plain, Listener {
public SmartPlaceListener() {
TinyProtocol.instance.addFilter(useItem, (player, packet) -> {
+ if(!Permission.BUILD.hasPermission(player)) return packet;
if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return packet;
Block block = player.getTargetBlockExact(6);
- boolean shouldSneak = !(block != null && (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) && !CONTAINERS.contains(block.getType()) && !IGNORED.contains(block.getType()));
+ boolean shouldSneak = false;
+ if (block != null) {
+ if (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) {
+ shouldSneak = true;
+ }
+ if (CONTAINERS.contains(block.getType())) {
+ ItemStack itemStack = player.getInventory().getItemInMainHand();
+ if (itemStack.getType() == Material.TNT) {
+ if (block.getType() == Material.CHEST || block.getType() == Material.BARREL || block.getType().name().endsWith("SHULKER_BOX")) {
+ shouldSneak = false;
+ }
+ }
+ } else {
+ shouldSneak = false;
+ }
+ if (IGNORED.contains(block.getType())) {
+ shouldSneak = false;
+ }
+ }
boolean sneaking = player.isSneaking();
- run(player, packet, true, sneaking, shouldSneak);
- return null;
- });
- }
-
- private void run(Player player, Object packet, boolean first, boolean sneaking, boolean shouldSneak) {
- Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
if (sneaking) SMART_PLACING.add(player);
player.setSneaking(shouldSneak || sneaking);
- packetExecutor.invoke(playerConnection.get(getHandle.invoke(player)), packet);
- SMART_PLACING.remove(player);
- player.setSneaking(sneaking);
-
- if (!WAS_EXECUTED.contains(player) && first) {
- run(player, packet, false, sneaking, shouldSneak);
- }
- WAS_EXECUTED.remove(player);
- }, first ? 0 : 1);
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ SMART_PLACING.remove(player);
+ player.setSneaking(sneaking);
+ }, 0);
+ return packet;
+ });
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
WAS_EXECUTED.add(event.getPlayer());
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
@@ -133,6 +149,7 @@ public class SmartPlaceListener implements Plain, Listener {
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
if (!SMART_PLACING.contains(event.getPlayer())) {
if (CONTAINERS.contains(event.getBlockAgainst().getType())) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java
index b6c6975e..38725cf0 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java
@@ -20,16 +20,22 @@
package de.steamwar.bausystem.features.techhider;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.bausystem.features.world.SpectatorListener;
import de.steamwar.bausystem.features.xray.XrayCommand;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.utils.ScoreboardElement;
+import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand;
+import de.steamwar.command.TypeMapper;
import de.steamwar.core.CraftbukkitWrapper;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import de.steamwar.techhider.TechHider;
import net.md_5.bungee.api.ChatMessageType;
+import org.bukkit.Bukkit;
import org.bukkit.Material;
+import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@@ -55,7 +61,7 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE
public XrayCommand xrayCommand;
@Register(description = "TECHHIDER_HELP")
- public void toggleHider(Player player) {
+ public void toggleHider(@Validator Player player) {
Region region = Region.getRegion(player.getLocation());
if (region.isGlobal()) {
BauSystem.MESSAGE.send("TECHHIDER_GLOBAL", player);
@@ -79,7 +85,7 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE
Set hiddenBlocks = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlocks")));
Set hiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities")));
- TechHider current = new TechHider((p, cX, cY) -> {
+ TechHider current = new TechHider((TechHider.LocationEvaluator) (p, cX, cY) -> {
if (rg.buildChunkOutside(cX, cY)) return true;
return !hidden.get(rg).contains(p);
}, Material.valueOf(obfuscateWith.toUpperCase()), hiddenBlocks.stream().map(String::toUpperCase).map(Material::valueOf).collect(Collectors.toSet()), hiddenBlockEntities);
@@ -104,6 +110,33 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE
});
}
+ @Register
+ public void toggleHider(@Validator("supervisor") Player player, @Mapper("spectator") Player other) {
+ SpectatorListener.toggleNoTechHider(other);
+ }
+
+ @Mapper("spectator")
+ public TypeMapper spectatorMapper() {
+ return new TypeMapper<>() {
+ @Override
+ public Player map(CommandSender commandSender, String[] previousArguments, String s) {
+ Player player = Bukkit.getPlayer(s);
+ if (player != null && Permission.REAL_SPECTATOR.hasPermission(player)) {
+ return player;
+ }
+ return null;
+ }
+
+ @Override
+ public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
+ return Bukkit.getOnlinePlayers().stream()
+ .filter(Permission.REAL_SPECTATOR::hasPermission)
+ .map(Player::getName)
+ .collect(Collectors.toList());
+ }
+ };
+ }
+
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
hidden.values().forEach(set -> set.remove(event.getPlayer()));
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounter.java b/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounter.java
index cf34f6f1..8b0796b8 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounter.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounter.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.testblock.blockcounter;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.region.Region;
import lombok.experimental.UtilityClass;
@@ -49,6 +50,8 @@ public class BlockCounter {
}
public String getMessage(Player player, int count, int tntCount, long tick, long lastTick) {
+ if(!Permission.BUILD.hasPermission(player)) return null;
+
double countPerTNT = (double) count / tntCount;
double countPerTick = (double) count / Math.max((lastTick - tick), 1);
if (isActive(player)) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java
index 43eb40da..6de8d252 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java
@@ -26,6 +26,7 @@ import de.steamwar.bausystem.linkage.specific.BauGuiItem;
import de.steamwar.bausystem.region.GlobalRegion;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.utils.ScoreboardElement;
+import de.steamwar.bausystem.utils.TickEndEvent;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import de.steamwar.command.AbstractSWCommand;
@@ -37,22 +38,20 @@ import de.steamwar.core.TPSWatcher;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
-import de.steamwar.linkage.api.Plain;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.boss.BarColor;
import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
-import org.bukkit.scheduler.BukkitRunnable;
-import org.bukkit.scheduler.BukkitTask;
import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicInteger;
@Linked
-public class TPSSystem implements Plain {
+public class TPSSystem implements Listener {
@Getter
private double currentTPSLimit = 20;
@@ -65,6 +64,8 @@ public class TPSSystem implements Plain {
}
public TPSSystem() {
+ instance = this;
+
if (TPSFreezeUtils.isCanFreeze()) {
new TPSFreezeCommand();
new TickFreezeCommand();
@@ -83,16 +84,11 @@ public class TPSSystem implements Plain {
new TickDefaultCommand();
new TPSBaseCommand();
new TickBaseCommand();
-
- instance = this;
}
- private BukkitTask stepper = null;
-
private void setTPS(double tps) {
- if (stepper != null) {
- stepper.cancel();
- stepper = null;
+ if (currentlyStepping) {
+ currentlyStepping = false;
Bukkit.getOnlinePlayers().forEach(player -> {
BossBarService.instance.remove(player, GlobalRegion.getInstance(), "TickStep");
});
@@ -120,37 +116,34 @@ public class TPSSystem implements Plain {
});
}
- private void setSkip(int steps, double tpsLimitToUse) {
- double currentLimit = tpsLimitToUse == 20 ? 0 : currentTPSLimit;
- setTPS(tpsLimitToUse);
- stepper = new BukkitRunnable() {
- AtomicInteger stepsLeft = new AtomicInteger(steps);
+ private boolean currentlyStepping = false;
+ private double currentLimit;
+ private int stepsTotal;
+ private int stepsLeft;
- @Override
- public void run() {
- if (steps > 1) {
- Bukkit.getOnlinePlayers().forEach(player -> {
- BauSystemBossbar bossbar = BossBarService.instance.get(player, GlobalRegion.getInstance(), "TickStep");
- bossbar.setColor(BarColor.YELLOW);
- bossbar.setTitle(BauSystem.MESSAGE.parse("TICK_BOSSBAR", player, (steps - stepsLeft.get()), steps));
- bossbar.setProgress((steps - stepsLeft.get()) / (double) steps);
- });
- }
- if (stepsLeft.decrementAndGet() < 0) {
- setTPS(currentLimit);
- }
- }
- }.runTaskTimer(BauSystem.getInstance(), 1, 1);
+ private void setSkip(int steps, double tpsLimitToUse) {
+ currentLimit = tpsLimitToUse == 20 ? 0 : currentTPSLimit;
+ setTPS(tpsLimitToUse);
+ stepsLeft = steps;
+ stepsTotal = steps;
+ currentlyStepping = true;
}
- public TypeValidator player() {
- return (commandSender, player, messageSender) -> {
- if (!Permission.hasPermission(player, Permission.WORLD)) {
- messageSender.send("TPSLIMIT_NO_PERMS");
- return false;
- }
- return true;
- };
+ @EventHandler
+ public void onTickEnd(TickEndEvent event) {
+ if (!currentlyStepping) return;
+ if (stepsTotal > 1) {
+ Bukkit.getOnlinePlayers().forEach(player -> {
+ BauSystemBossbar bossbar = BossBarService.instance.get(player, GlobalRegion.getInstance(), "TickStep");
+ bossbar.setColor(BarColor.YELLOW);
+ bossbar.setTitle(BauSystem.MESSAGE.parse("TICK_BOSSBAR", player, (stepsTotal - stepsLeft), stepsTotal));
+ bossbar.setProgress((stepsTotal - stepsLeft) / (double) stepsTotal);
+ });
+ }
+ stepsLeft--;
+ if (stepsLeft <= 0) {
+ setTPS(currentLimit);
+ }
}
private class TPSBaseCommand extends SWCommand {
@@ -160,11 +153,6 @@ public class TPSSystem implements Plain {
setMessage(BauSystem.MESSAGE);
addDefaultHelpMessage("TPSLIMIT_HELP");
}
-
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator player() {
- return TPSSystem.this.player();
- }
}
@AbstractSWCommand.PartOf(TPSBaseCommand.class)
@@ -230,11 +218,6 @@ public class TPSSystem implements Plain {
super("tick");
setMessage(BauSystem.MESSAGE);
}
-
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator player() {
- return TPSSystem.this.player();
- }
}
@AbstractSWCommand.PartOf(TickBaseCommand.class)
@@ -341,7 +324,7 @@ public class TPSSystem implements Plain {
@Override
public String get(Region region, Player p) {
- if (TPSSystem.getInstance().stepper != null) {
+ if (TPSSystem.getInstance() != null && TPSSystem.getInstance().currentlyStepping) {
long time = System.currentTimeMillis() % 1000;
if (time < 250) {
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: §7•••";
@@ -403,7 +386,7 @@ public class TPSSystem implements Plain {
@Override
public Permission permission() {
- return Permission.WORLD;
+ return Permission.BUILD;
}
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java
index ab213c83..9a93977e 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java
@@ -1,9 +1,17 @@
package de.steamwar.bausystem.features.util;
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.bukkit.BukkitAdapter;
+import com.sk89q.worldedit.event.platform.CommandEvent;
+import com.sk89q.worldedit.extension.platform.Actor;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.script.ScriptCommand;
import de.steamwar.bausystem.features.script.ScriptRunner;
+import de.steamwar.bausystem.features.world.WorldEditListener;
+import de.steamwar.bausystem.utils.WorldEditUtils;
import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
@@ -20,14 +28,18 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
+import org.luaj.vm2.LuaValue;
import java.lang.reflect.Field;
import java.util.*;
+import java.util.logging.Level;
import java.util.stream.Collectors;
@Linked
public class BindCommand extends SWCommand implements Listener {
+ private static final boolean hasFAWE = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null;
+
@Linked
public static class UnBindCommand extends SWCommand {
@@ -62,7 +74,7 @@ public class BindCommand extends SWCommand implements Listener {
}
@Register(description = "OTHER_BIND_HELP")
- public void bind(Player player, @Mapper("command") @ErrorMessage("OTHER_BIND_ERROR") String... command) {
+ public void bind(@Validator Player player, @Mapper("command") @ErrorMessage("OTHER_BIND_ERROR") String... command) {
bindInternal(player, command);
}
@@ -91,6 +103,7 @@ public class BindCommand extends SWCommand implements Listener {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (!event.hasItem()) return;
+ if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ItemStack itemStack = event.getItem();
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
@@ -104,10 +117,22 @@ public class BindCommand extends SWCommand implements Listener {
event.setCancelled(true);
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
- PlayerCommandPreprocessEvent playerCommandPreprocessEvent = new PlayerCommandPreprocessEvent(event.getPlayer(), "/" + command);
- Bukkit.getPluginManager().callEvent(playerCommandPreprocessEvent);
- if (playerCommandPreprocessEvent.isCancelled()) return;
- Bukkit.getServer().dispatchCommand(event.getPlayer(), command);
+ PlayerCommandPreprocessEvent preprocessEvent = new PlayerCommandPreprocessEvent(event.getPlayer(), "/" + command);
+ Bukkit.getPluginManager().callEvent(preprocessEvent);
+ if (preprocessEvent.isCancelled()) return;
+
+ String processedCommand = preprocessEvent.getMessage().substring(1);
+ Bukkit.getLogger().log(Level.INFO, event.getPlayer().getName() + " dispatched command: " + processedCommand);
+ String[] commandSplit = processedCommand.split(" ");
+ if (!commandSplit[0].equals("select") && hasFAWE && WorldEditListener.isWorldEditCommand("/" + commandSplit[0])) {
+ EditSession editSession = WorldEditUtils.getEditSession(event.getPlayer());
+ Actor actor = BukkitAdapter.adapt(event.getPlayer());
+ WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().handleCommandOnCurrentThread(new CommandEvent(actor, processedCommand, editSession));
+ editSession.flushSession();
+ WorldEditUtils.addToPlayer(event.getPlayer(), editSession);
+ } else {
+ Bukkit.getServer().dispatchCommand(event.getPlayer(), processedCommand);
+ }
}, 1);
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BookReplaceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BookReplaceCommand.java
index 290223a2..c534e38d 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BookReplaceCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BookReplaceCommand.java
@@ -17,7 +17,7 @@ public class BookReplaceCommand extends SWCommand {
}
@Register("color")
- public void color(Player player) {
+ public void color(@Validator Player player) {
ItemStack itemStack = player.getInventory().getItemInMainHand();
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta instanceof BookMeta) {
@@ -29,7 +29,7 @@ public class BookReplaceCommand extends SWCommand {
}
@Register("uncolor")
- public void uncolor(Player player) {
+ public void uncolor(@Validator Player player) {
ItemStack itemStack = player.getInventory().getItemInMainHand();
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta instanceof BookMeta) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/ClearCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/ClearCommand.java
index 3e8899d6..1df08e5d 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/ClearCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/ClearCommand.java
@@ -48,13 +48,6 @@ public class ClearCommand extends SWCommand {
BauSystem.MESSAGE.send("OTHER_CLEAR_TO", p, target.getName());
}
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator validator() {
- return (commandSender, player, messageSender) -> {
- return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "OTHER_CLEAR_NO_PERMS");
- };
- }
-
private void clear(Player player) {
player.getInventory().clear();
player.getInventory().setHelmet(new ItemStack(Material.AIR));
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/DebugStickCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/DebugStickCommand.java
index e2de740f..5b87464c 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/DebugStickCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/DebugStickCommand.java
@@ -34,7 +34,7 @@ public class DebugStickCommand extends SWCommand {
}
@Register(description = "DEBUG_STICK_COMMAND_HELP")
- public void genericCommand(Player p) {
+ public void genericCommand(@Validator Player p) {
SWUtils.giveItemToPlayer(p, new ItemStack(Material.DEBUG_STICK));
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/KillAllCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/KillAllCommand.java
index 49654a05..e08b40c0 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/KillAllCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/KillAllCommand.java
@@ -45,12 +45,12 @@ public class KillAllCommand extends SWCommand {
}
@Register(description = "OTHER_KILLALL_HELP_SELF")
- public void genericCommand(Player player) {
+ public void genericCommand(@Validator Player player) {
genericCommand(player, RegionSelectionType.LOCAL);
}
@Register(description = "OTHER_KILLALL_HELP_ALL")
- public void genericCommand(Player player, RegionSelectionType regionSelectionType) {
+ public void genericCommand(@Validator Player player, RegionSelectionType regionSelectionType) {
Region region = Region.getRegion(player.getLocation());
AtomicLong count = new AtomicLong(0);
if (regionSelectionType == RegionSelectionType.GLOBAL || GlobalRegion.getInstance() == region) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java
index 6f7a92c7..7893b8c4 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.util;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.SWUtils;
+import de.steamwar.bausystem.features.world.WorldEditListener;
import de.steamwar.bausystem.shared.EnumDisplay;
import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand;
@@ -51,6 +52,7 @@ public class MaterialCommand extends SWCommand implements Listener {
public MaterialCommand() {
super("material", "baumaterial");
+ WorldEditListener.addCommandExclusion("material");
}
private Map searchMap = new HashMap<>();
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java
index ba5d5000..867ad83d 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java
@@ -24,6 +24,7 @@ import com.comphenix.tinyprotocol.TinyProtocol;
import com.mojang.authlib.GameProfile;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
+import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.command.SWCommand;
import de.steamwar.core.ProtocolWrapper;
@@ -97,7 +98,7 @@ public class NoClipCommand extends SWCommand implements Listener {
}
@Register(help = true)
- public void genericCommand(Player player, String... args) {
+ public void genericCommand(@Validator Player player) {
if (NOCLIPS.contains(player)) {
NOCLIPS.remove(player);
player.setGameMode(GameMode.CREATIVE);
@@ -116,6 +117,16 @@ public class NoClipCommand extends SWCommand implements Listener {
}
}
+ @EventHandler
+ public void onBauMemberUpdate(BauMemberUpdateEvent event) {
+ event.getNewSpectator().forEach(player -> {
+ if (NOCLIPS.contains(player)) {
+ NOCLIPS.remove(player);
+ player.setGameMode(GameMode.CREATIVE);
+ }
+ });
+ }
+
@EventHandler(ignoreCancelled = true)
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
if (NOCLIPS.contains(event.getPlayer())) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java
index 0f1cfe5e..de9ea34a 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.util;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
import de.steamwar.linkage.Linked;
@@ -49,6 +50,7 @@ public class PistonCalculator implements Listener {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
+ if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
if (!event.hasItem() || event.getItem().getType() != Material.SLIME_BALL) return;
if (event.getClickedBlock() == null) return;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculatorCommand.java
index 8aef617f..71fefaa4 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculatorCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculatorCommand.java
@@ -32,7 +32,7 @@ public class PistonCalculatorCommand extends SWCommand {
}
@Register
- public void help(Player player) {
+ public void help(@Validator Player player) {
BauSystem.MESSAGE.send("PISTON_HELP_1", player);
BauSystem.MESSAGE.send("PISTON_HELP_2", player);
BauSystem.MESSAGE.send("PISTON_HELP_3", player);
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/SelectCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/SelectCommand.java
index bd8566ea..e9c2c09a 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/SelectCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/SelectCommand.java
@@ -45,13 +45,6 @@ public class SelectCommand extends SWCommand {
baurahmenCommand(p, RegionType.TESTBLOCK, regionExtensionType);
}
- @ClassValidator(value = Player.class, local = true)
- public TypeValidator