diff --git a/BauSystem_Linkage/src/de/steamwar/linkage/types/SmartPlaceBehaviour_GENERIC.java b/BauSystem_Linkage/src/de/steamwar/linkage/types/SmartPlaceBehaviour_GENERIC.java
deleted file mode 100644
index 0f50ac45..00000000
--- a/BauSystem_Linkage/src/de/steamwar/linkage/types/SmartPlaceBehaviour_GENERIC.java
+++ /dev/null
@@ -1,40 +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.linkage.types;
-
-import de.steamwar.linkage.LinkageType;
-import de.steamwar.linkage.plan.BuildPlan;
-import de.steamwar.linkage.plan.MethodBuilder;
-
-import javax.lang.model.element.TypeElement;
-
-public class SmartPlaceBehaviour_GENERIC implements LinkageType {
-
- @Override
- public String method() {
- return "linkSmartPlace";
- }
-
- @Override
- public void generateCode(BuildPlan buildPlan, MethodBuilder methodBuilder, String s, TypeElement typeElement) {
- buildPlan.addImport("de.steamwar.bausystem.features.smartplace.SmartPlaceListener");
- methodBuilder.addLine("SmartPlaceListener.add(" + s + ");");
- }
-}
diff --git a/BauSystem_Main/build.gradle b/BauSystem_Main/build.gradle
index 744e575c..62d604cf 100644
--- a/BauSystem_Main/build.gradle
+++ b/BauSystem_Main/build.gradle
@@ -54,12 +54,11 @@ dependencies {
implementation project(":BauSystem_Linkage")
annotationProcessor project(":BauSystem_Linkage")
- compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT'
+ compileOnly 'org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT'
compileOnly 'com.mojang:authlib:1.5.25'
compileOnly 'io.netty:netty-all:4.1.68.Final'
- compileOnly swdep('Spigot-1.19')
- // compileOnly swdep('WorldEdit-1.15')
+ compileOnly swdep('Spigot-1.20')
compileOnly swdep('SpigotCore')
annotationProcessor swdep('SpigotCore')
diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties
index 57f92a6e..045e4872 100644
--- a/BauSystem_Main/src/BauSystem.properties
+++ b/BauSystem_Main/src/BauSystem.properties
@@ -60,6 +60,7 @@ FLAG_PROTECT_INACTIVE = §coff
FLAG_TNT_ALLOW = §aon
FLAG_TNT_DENY = §coff
FLAG_TNT_ONLY_TB = §7no §ebuild area
+FLAG_TNT_ONLY_BUILD = §7no §etestblock area
FLAG_ITEMS_ACTIVE = §aon
FLAG_ITEMS_INACTIVE = §coff
@@ -105,9 +106,8 @@ AUTOSTART_ITEM_LORE = §eRight Click Block §8- §7Start Timer
AUTOSTART_MESSAGE_NO_REGION = §cYou are not inside any region
AUTOSTART_MESSAGE_RESET = §eAutostartTimer restarted
AUTOSTART_MESSAGE_START = §eAutostartTimer started
-AUTOSTART_MESSAGE_RESULT1 = §eTime §7until §eexplosion §7at enemy§8:§e {0}
-AUTOSTART_MESSAGE_DATE_PATTERN=mm:ss SSSS
-AUTOSTART_MESSAGE_RESULT2 = §eTime difference in game-ticks §7until {0} seconds§8:§e {1}
+AUTOSTART_MESSAGE_RESULT1 = §eTime §7until §eexplosion §7at enemy§8:§e {0}§7 game ticks
+AUTOSTART_MESSAGE_RESULT2 = §7Time difference in §egame-ticks §7until {0} seconds§8:§e {1}
AUTOSTART_MESSAGE_RESULT3 = §7positive, if too few, negative if too many
# Backup
@@ -140,22 +140,21 @@ BAU_INFO_ITEM_NAME = §eBau-Management
## This is used in BauInfoBauGuiItem.java
BAU_INFO_ITEM_LORE_TNT = §7TNT§8: §e{0}
BAU_INFO_ITEM_LORE_FREEZE = §7Freeze§8: §e{0}
-BAU_INFO_ITEM_LORE_DAMAGE=
BAU_INFO_ITEM_LORE_FIRE = §7Fire§8: §e{0}
BAU_INFO_ITEM_LORE_COLOR = §7Color§8: §e{0}
BAU_INFO_ITEM_LORE_PROTECT = §7Protect§8: §e{0}
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: §e{0}
-BAU_INFO_COMMAND_MEMBER = §7Member: §e
+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_FLAG = §e{0} §8: §7{1}
-BAU_INFO_COMMAND_TPS = TPS:§e
+BAU_INFO_COMMAND_FLAG = §7{0}§8: §7{1}
+BAU_INFO_COMMAND_TPS = §7TPS§8:§e
# Countingwand
COUNTINGWAND_COMMAND_HELP = §8/§ecountingwand §8- §7Receive a CountingWand
@@ -168,10 +167,10 @@ COUNTINGWAND_MESSAGE_VOLUME = §e{0}
COUNTINGWAND_MESSAGE_DIMENSION = §e{0}§8, §e{1}§8, §e{2}
# Design Endstone
-DESIGN_ENDSTONE_COMMAND_HELP = §8/§edesign endstone §8- §7Show where Endstone is
+DESIGN_ENDSTONE_COMMAND_HELP = §8/§edesignendstone §8- §7Highlight endstone in design
DESIGN_ENDSTONE_REGION_ERROR = §cThis region has no build area
-DESIGN_ENDSTONE_ENABLE = §aEndstone is activated
-DESIGN_ENDSTONE_DISABLE = §cEndstone is deactivated
+DESIGN_ENDSTONE_ENABLE = §aEndstone is highlighted
+DESIGN_ENDSTONE_DISABLE = §cEndstone is no longer hightlighted
# Detonator
DETONATOR_LOC_REMOVE = §e{0} removed
@@ -202,7 +201,7 @@ DETONATOR_INVALID_POINT=§cOne point could not be activated
DETONATOR_INVALID_POINTS=§c{0} points could not be activated
DETONATOR_INVALID_BLOCK=§eThe block could not be addded
# Hotbar
-HOTBAR_HELP_GENERIC=§7Saves a hotbar. While joining a bau with an empty inventory this hotbar will be used
+HOTBAR_HELP_GENERIC=§7Saves a hotbar. While joining a bau with an empty inventory this hotbar will be used.
HOTBAR_HELP_SAVE=§8/§ehotbar save §8-§7 Saves your current hotbar
HOTBAR_HELP_LOAD=§8/§ehotbar load §8-§7 Loads the saved hotbar
HOTBAR_HELP_SHOW=§8/§ehotbar show §8-§7 Displays the saved hotbar
@@ -490,14 +489,19 @@ TRACE_IDLE_AUTO_EXPLODE=§eauto §8(§7explode§8)
TRACE_IDLE_AUTO_IGNITE=§eauto §8(§7ignite§8)
TRACE_MESSAGE_AUTO_IDLE_EXPLODE = §aAuto-Tracer explode started
TRACE_MESSAGE_AUTO_IDLE_IGNITE = §aAuto-Tracer ignite started
+TRACE_MESSAGE_AUTO_DELETE_INVALID = §cAuto delete cannot be used currently
+TRACE_MESSAGE_AUTO_DELETE_ALWAYS = §7Last Shot will §ealways §7be deleted
+TRACE_MESSAGE_AUTO_DELETE_NEVER = §7Last Shot will §enever §7be deleted
+TRACE_MESSAGE_AUTO_DELETE_NO_BUILD_DESTROY = §7Last Shot will be deleted if §eno build §7block was destroyed
+TRACE_MESSAGE_AUTO_DELETE_BUILD_DESTROY = §7Last Shot will be deleted if §ea build §7block was destroyed
+TRACE_MESSAGE_AUTO_DELETE_NO_TESTBLOCK_DESTROY = §7Last Shot will be deleted if §eno testblock §7block was destroyed
+TRACE_MESSAGE_AUTO_DELETE_TESTBLOCK_DESTROY = §7Last Shot will be deleted if §ea testlblock §7block was destroyed
TRACE_MESSAGE_START = §aTNT-Tracer started
TRACE_MESSAGE_SINGLE = §aSingle-Tracer started
TRACE_MESSAGE_STOP = §cTNT-Tracer stopped
TRACE_MESSAGE_DELETE = §cAll TNT-positions deleted
TRACE_MESSAGE_SHOW = §aAll TNT-positions shown
TRACE_MESSAGE_HIDE = §cAll TNT-positions hidden
-TRACE_MESSAGE_ISOLATE = §aTNT-positions isolated
-TRACE_MESSAGE_UNISOLATE = §cTNT-positions hidden
TRACE_MESSAGE_CLICK_ISOLATE = §eClick to §aisolate§8/§cunisolate
TRACE_MESSAGE_DISALLOWED = §cYou are not allowed to use the TNT-Tracer here
@@ -505,15 +509,10 @@ TRACE_COMMAND_HELP_START = §8/§etrace start §8- §7Starts recording of all TN
TRACE_COMMAND_HELP_SINGLE = §8/§etrace single §8- §7Starts a single recording of all TNT-positions
TRACE_COMMAND_HELP_STOP = §8/§etrace stop §8- §7Stops the TNT-Tracer
TRACE_COMMAND_HELP_AUTO = §8/§etrace toggleauto §8- §7Automatic start of recording
+TRACE_COMMAND_HELP_AUTO_REMOVE = §8/§etrace autoremove §8<§eParameter§8> §8- §7Remove last Trace Record automatically
TRACE_COMMAND_HELP_SHOW = §8/§etrace show §8<§eParameter§8> - §7Shows all TNT-positions
TRACE_COMMAND_HELP_HIDE = §8/§etrace hide §8- §7Hides all TNT-positions
TRACE_COMMAND_HELP_DELETE = §8/§etrace delete §8- §7Deletes all TNT-positions
-TRACE_COMMAND_HELP_GUI = §8/§etrace gui §8- §7Shows the Trace GUI
-TRACE_COMMAND_HELP_REPLAY = §8/§etrace replay §8[§7tick§8] §8- §7Replays your recording
-TRACE_COMMAND_HELP_REPLAY_DISABLE = §8/§etrace replay disable §8- §7Stops the replay
-TRACE_COMMAND_HELP_REPLAY_NEXT = §8/§etrace replay next §8[§7step§8] §8- §7Jump one§8/§7step tick forward
-TRACE_COMMAND_HELP_REPLAY_PREVIOUS = §8/§etrace replay previous §8[§7step§8] §8- §7Jump one§8/§7step tick back
-TRACE_COMMAND_HELP_REPLAY_LOOP = §8/§etrace replay loop §8<§7start§8> §8<§7end§8> §8[§7speed§8] §8- §7Loop the replay
TRACE_GUI_ITEM_NAME = §eTracer
TRACE_GUI_ITEM_LORE = §7Status§8: {0}
@@ -525,19 +524,6 @@ TRACE_GUI_AUTO_TRACE_INACTIVE = §eacitvate Auto-Tracer
TRACE_GUI_AUTO_TRACE_ACTIVE = §edeactivate Auto-Tracer
TRACE_GUI_DELETE = §eDelete trace
-TRACE_GUI_TITLE = Trace GUI
-TRACE_GUI_ITEM_BACK = §eBack
-TRACE_GUI_ITEM = §eTrace §8- §e{0} §7TNT
-TRACE_GUI_CLEAR = §eDelete traces
-TRACE_GUI_RECORD_ITEM = §eTNT §8- §e{0} §7Positions
-TRACE_GUI_RECORD_CLEAR = §eDelete TNT
-TRACE_GUI_POSITION_ITEM = §ePosition
-TRACE_GUI_POSITION_X = §7X§8: §e{0}
-TRACE_GUI_POSITION_Y = §7Y§8: §e{0}
-TRACE_GUI_POSITION_Z = §7Z§8: §e{0}
-TRACE_GUI_POSITION_SOURCE = §7Source§8: §e{0}
-TRACE_GUI_POSITION_EXPLODED = §7Exploded§8: §e{0}
-
# Loader
LOADER_SETUP = §eSetup
LOADER_RUNNING = §aRunning
@@ -545,6 +531,7 @@ LOADER_PAUSE = §7Pause
LOADER_END = §8Finished
LOADER_MESSAGE_INTERACT=§e{0} added {1}
+LOADER_MESSAGE_UNINTERACT=§eRemoved Element
LOADER_BUTTON_TNT=TNT
LOADER_BUTTON_SWITCH=Lever
LOADER_BUTTON_WOOD_BUTTON=Wooden Button
@@ -567,36 +554,45 @@ LOADER_HELP_START=§8/§eloader start §8- §7Playback of previously recorded ac
LOADER_HELP_PAUSE=§8/§7loader pause §8- §7Pauses Loader
LOADER_HELP_GUI=§8/§7loader gui §8- §7Shows Loader gui
LOADER_HELP_STOP=§8/§eloader stop §8- §7Stops recording/playback
+LOADER_HELP_WAIT=§8/§7loader wait §8[§7Ticks§8] - §7Sets wait time between shots
+LOADER_HELP_SPEED=§8/§7loader speed §8[§7Ticks§8] - §7Sets wait time between actions
LOADER_NO_LOADER=§cYou have no Laoder. Create one with /loader setup
LOADER_NEW=§7Load your cannon and fire it once, to initialise the loader.
LOADER_HOW_TO_START=§7Then, execute /§eloader start§7 to start the Loader
LOADER_ACTIVE=§7The Loader is now active.
LOADER_STOP=§7The Loader has been stopped.
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
-LOADER_GUI_SHOW_INTERACTIONS=§eShow only Interactions
-LOADER_GUI_SHOW_WAITS=§eShow only Waits
-LOADER_GUI_SHOW_WAITS_SET_BETWEEN_TNT=§7Wait Time between TNT
+LOADER_GUI_SHOW_ALL=Show all
+LOADER_GUI_SHOW_INTERACTIONS=Show only Interactions
+LOADER_GUI_SHOW_WAITS=Show only Waits
+LOADER_GUI_SHOW_WAITS_BETWEEN_TNT=Show only Waits between TNT
+LOADER_GUI_SHOW_TNT=Show TNT
LOADER_GUI_SHOW_WAITS_SET_ALL=§7Wait Time all
LOADER_GUI_SHOW_WAITS_TITLE=§7Wait Time
LOADER_GUI_SETTINGS_TITLE=Settings
+LOADER_GUI_COPY_TITLE=Copy amount
LOADER_GUI_SETTINGS_BACK=§8Back
+LOADER_GUI_SETTINGS_COPY=§7Copy
LOADER_GUI_SETTINGS_DELETE=§cDelete
LOADER_GUI_WAIT_TITLE=Settings
LOADER_GUI_WAIT_BACK=§8Back
-LOADER_GUI_CLICK_TO_EDIT=§7Klicke zum editieren
+LOADER_GUI_CLICK_TO_EDIT=§7Click to edit
LOADER_GUI_ITEM_NAME=§7{0}§8: §e{1}
LOADER_SETTING_NAME=§7{0}
-LOADER_SETTING_MODES=§7Modi§8: §e{0}
-LOADER_SETTING_POWER=§7Redstone Stärke§8: §e{0}
+LOADER_SETTING_MODES=§7Modes§8: §e{0}
+LOADER_SETTING_POWER=§7Power§8: §e{0}
LOADER_SETTING_TICKS=§7Ticks§8: §e{0}
LOADER_SETTING_REPEATER=§7Repeater§8: §e{0}
-LOADER_SETTING_WAIT=§7Wartezeit§8: §e{0} Tick(s)
-LOADER_SETTING_WAIT_NAME=Wartezeit
+LOADER_SETTING_WAIT=§7Wait§8: §e{0} Tick(s)
+LOADER_SETTING_WAIT_NAME=Wait
LOADER_SETTING_TICKS_NAME=Ticks
LOADER_SETTING_TICKS_REMOVE_ONE=§c-1
LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT=§7Shift§8: §c-5
@@ -607,18 +603,21 @@ LOADER_SETTING_TNT_X=§7X§8: §e{0}
LOADER_SETTING_TNT_Y=§7Y§8: §e{0}
LOADER_SETTING_TNT_Z=§7Z§8: §e{0}
LOADER_INTERACTION_NOOP=NOOP
-LOADER_INTERACTION_INTERACT=Interagiere
-LOADER_INTERACTION_POWERED=Aktiviert
-LOADER_INTERACTION_UNPOWERED=Deaktiviert
-LOADER_INTERACTION_PAGE_PREV=Vorherige Seite
-LOADER_INTERACTION_PAGE_NEXT=Nächste Seite
-LOADER_INTERACTION_PAGE=Seite {0}
-LOADER_INTERACTION_ACTIVE=Aktiviert
-LOADER_INTERACTION_INACTIVE=Deaktiviert
-LOADER_INTERACTION_WAIT_FOR=Darauf warten
-LOADER_INTERACTION_NO_WAIT_FOR=Nicht darauf warten
-LOADER_INTERACTION_OPEN=Geöffnet
-LOADER_INTERACTION_CLOSED=Geschlossen
+LOADER_INTERACTION_PLACE=Place
+LOADER_INTERACTION_INTERACT=Interact
+LOADER_INTERACTION_POWERED=Powered
+LOADER_INTERACTION_UNPOWERED=Unpowered
+LOADER_INTERACTION_PAGE_PREV=Previous Page
+LOADER_INTERACTION_PAGE_NEXT=Next Page
+LOADER_INTERACTION_PAGE=Page {0}
+LOADER_INTERACTION_ACTIVE=Active
+LOADER_INTERACTION_INACTIVE=Inactive
+LOADER_INTERACTION_WAIT_FOR=Wait for
+LOADER_INTERACTION_NO_WAIT_FOR=No wait for
+LOADER_INTERACTION_OPEN=Open
+LOADER_INTERACTION_CLOSED=Closed
+LOADER_INTERACTION_COMPARE=Compare
+LOADER_INTERACTION_SUBTRACT=Subtract
# Loadtimer
LOADTIMER_HELP_OVERVIEW=§7Compete with your friends loading your cannon and get information about the cannon
@@ -709,6 +708,12 @@ OTHER_TPS_HEAD = §7TPS: 1s 10s 1m 5m 10m
OTHER_TPS_MESSAGE = §7 §e{0}§7 §e{1}§7 §e{2}§7 §e{3}§7 §e{4}
OTHER_TPS_SINGLE = §8TPS: §e{0}
OTHER_WORLDSPAWN_HELP=§8/§eworldspawn §8-§e Teleport to the spawn
+OTHER_BIND_HELP=§8/§ebind §8[§7Command§8] §8-§e Bind a command on item interaction
+OTHER_BIND_ERROR=§cInvalid or unknown command
+OTHER_BIND_UNBINDABLE=§cCould not bind command
+OTHER_BIND_LORE=§eCommand§8:§7 {0}
+OTHER_BIND_MESSAGE_BIND=§7Bound command §e{0} §7to item
+OTHER_BIND_MESSAGE_UNBIND=§7Unbound command
# DebugStick
DEBUG_STICK_COMMAND_HELP=§8/§edebugstick §8-§7 receive a debugstick
DEBUG_STICK_NAME=§eDebugstick
@@ -786,10 +791,12 @@ REGION_ITEM_RESET=§eReset
REGION_ITEM_TESTBLOCK=§eDummy
REGION_ITEM_TNT_OFF=§7TNT: §eDeactivated
REGION_ITEM_TNT_ONLY_TB=§7TNT: §eonly dummy
+REGION_ITEM_TNT_ONLY_BUILD=§7TNT: §eonly build
REGION_ITEM_TNT_ON=§7TNT: §eActivated
REGION_ITEM_SELECTOR_TITLE=Tnt Mode
REGION_ITEM_SELECTOR_ON=§eActivate
REGION_ITEM_SELECTOR_ONLY_TB=§eonly dummy
+REGION_ITEM_SELECTOR_ONLY_BUILD=§eonly build
REGION_ITEM_SELECTOR_OFF=§eDeactivate
#Region
REGION_COLOR_HELP_COLOR=§8/§ecolor §8[§7Color§8] §8- §7Sets the color of the region
@@ -873,8 +880,10 @@ REGION_TNT_HELP_MODE=§8/§etnt §8[§7Mode§8] §8- §7Set TNT behaviour to a g
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=§cAn explosion would have destroyed blocks in the building area
+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_WARNING_MESSAGE=§cThis server will stop in one minute if you remain inactive
diff --git a/BauSystem_Main/src/BauSystem_de.properties b/BauSystem_Main/src/BauSystem_de.properties
index b7496d63..368721b8 100644
--- a/BauSystem_Main/src/BauSystem_de.properties
+++ b/BauSystem_Main/src/BauSystem_de.properties
@@ -60,6 +60,7 @@ FLAG_PROTECT_INACTIVE = §caus
FLAG_TNT_ALLOW = §aan
FLAG_TNT_DENY = §caus
FLAG_TNT_ONLY_TB = §7Kein §eBaurahmen
+FLAG_TNT_ONLY_BUILD = §7Kein §eTestblock
FLAG_ITEMS_ACTIVE = §aan
FLAG_ITEMS_INACTIVE = §caus
@@ -104,8 +105,8 @@ AUTOSTART_ITEM_LORE = §eRechtsklick Block §8- §7Starte den Timer
AUTOSTART_MESSAGE_NO_REGION = §cDu befindest dich derzeit in keiner Region
AUTOSTART_MESSAGE_RESET = §eDer AutostartTimer wurde zurückgesetzt
AUTOSTART_MESSAGE_START = §eAutostartTimer gestartet
-AUTOSTART_MESSAGE_RESULT1 = §eZeit §7bis zur §eExplosion §7am Gegner§8:§e {0}
-AUTOSTART_MESSAGE_RESULT2 = §eZeitdifferenz in ticks §7bis {0} Sekunden§8:§e {1}
+AUTOSTART_MESSAGE_RESULT1 = §eZeit §7bis zur §eExplosion §7am Gegner§8:§e {0}§7 in game ticks
+AUTOSTART_MESSAGE_RESULT2 = §7Zeitdifferenz in §egame ticks §7bis {0} Sekunden§8:§e {1}
AUTOSTART_MESSAGE_RESULT3 = §7Positiv, wenn zu wenig, negativ wenn zu viel
# Backup
@@ -144,15 +145,15 @@ BAU_INFO_ITEM_LORE_COLOR = §7Farbe§8: §e{0}
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: §e{0}
-BAU_INFO_COMMAND_MEMBER = §7Mitglieder: §e
+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_FLAG = §e{0} §8: §7{1}
-BAU_INFO_COMMAND_TPS = TPS:§e
+BAU_INFO_COMMAND_FLAG = §7{0}§8: §7{1}
+BAU_INFO_COMMAND_TPS = §7TPS§8:§e
# Countingwand
COUNTINGWAND_COMMAND_HELP = §8/§ecountingwand §8- §7Gibt dir ein CountingWand
@@ -165,10 +166,10 @@ COUNTINGWAND_MESSAGE_VOLUME = §e{0}
COUNTINGWAND_MESSAGE_DIMENSION = §e{0}§8, §e{1}§8, §e{2}
# Design Endstone
-DESIGN_ENDSTONE_COMMAND_HELP = §8/§edesign endstone §8- §7Zeige wo Endstone ist
+DESIGN_ENDSTONE_COMMAND_HELP = §8/§edesign endstone §8- §7Zeige End Stone im Design
DESIGN_ENDSTONE_REGION_ERROR = §cDiese Region hat keinen Baubereich
-DESIGN_ENDSTONE_ENABLE = §aEndstone ist aktiviert
-DESIGN_ENDSTONE_DISABLE = §cEndstone ist deaktiviert
+DESIGN_ENDSTONE_ENABLE = §aEndstone im Design ist angezeigt
+DESIGN_ENDSTONE_DISABLE = §cEndstone im Design ist versteckt
# Detonator
DETONATOR_LOC_REMOVE = §e{0} entfernt
@@ -457,14 +458,19 @@ TRACE_IDLE_AUTO_EXPLODE=§eauto §8(§7explode§8)
TRACE_IDLE_AUTO_IGNITE=§eauto §8(§7ignite§8)
TRACE_MESSAGE_AUTO_IDLE_EXPLODE = §aAuto-Tracer explode gestartet
TRACE_MESSAGE_AUTO_IDLE_IGNITE = §aAuto-Tracer ignite gestartet
+TRACE_MESSAGE_AUTO_DELETE_INVALID = §cAuto delete kann aktuell nicht genutzt werden
+TRACE_MESSAGE_AUTO_DELETE_ALWAYS = §7Der letzte Schuss wird §eimmer§7 gelöscht
+TRACE_MESSAGE_AUTO_DELETE_NEVER = §7Der letzte Schuss wird §enie§7 gelöscht
+TRACE_MESSAGE_AUTO_DELETE_NO_BUILD_DESTROY = §7Der letzte Schuss wird gelöscht, wenn §ekein§7 Block aus dem §eBaubereich§7 zerstört wurde
+TRACE_MESSAGE_AUTO_DELETE_BUILD_DESTROY = §7Der letzte Schuss wird gelöscht, wenn §eein§7 Block aus dem §eBaubereich§7 zerstört wurde
+TRACE_MESSAGE_AUTO_DELETE_NO_TESTBLOCK_DESTROY = §7Der letzte Schuss wird gelöscht, wenn §ekein§7 Block aus dem §eTestblock§7 zerstört wurde
+TRACE_MESSAGE_AUTO_DELETE_TESTBLOCK_DESTROY = §7Der letzte Schuss wird gelöscht, wenn §eein§7 Block aus dem §eTestblock§7 zerstört wurde
TRACE_MESSAGE_START = §aTNT-Tracer gestartet
TRACE_MESSAGE_SINGLE = §aSingle-Tracer gestartet
TRACE_MESSAGE_STOP = §cTNT-Tracer gestoppt
TRACE_MESSAGE_DELETE = §cAlle TNT-Positionen gelöscht
TRACE_MESSAGE_SHOW = §aAlle TNT-Positionen angezeigt
TRACE_MESSAGE_HIDE = §cAlle TNT-Positionen ausgeblendet
-TRACE_MESSAGE_ISOLATE = §aTNT-Positionen isoliert
-TRACE_MESSAGE_UNISOLATE = §cTNT-Positionen ausgeblendet
TRACE_MESSAGE_CLICK_ISOLATE = §eKlicken zum §aisolieren§8/§causblenden
TRACE_MESSAGE_DISALLOWED = §cDu darfst hier nicht den TNT-Tracer nutzen
@@ -472,15 +478,10 @@ TRACE_COMMAND_HELP_START = §8/§etrace start §8- §7Startet die Aufnahme aller
TRACE_COMMAND_HELP_SINGLE = §8/§etrace single §8- §7Startet eine einzelne Aufnahme aller TNT-Positionen
TRACE_COMMAND_HELP_STOP = §8/§etrace stop §8- §7Stoppt den TNT-Tracer
TRACE_COMMAND_HELP_AUTO = §8/§etrace toggleauto §8- §7Automatischer Aufnahmenstart
+TRACE_COMMAND_HELP_AUTO_REMOVE = §8/§etrace autoremove §8<§eParameter§8> §8- §7Löscht den letzten Trace automatisch
TRACE_COMMAND_HELP_SHOW = §8/§etrace show §8<§eParameter§8> - §7Zeigt alle TNT-Positionen
TRACE_COMMAND_HELP_HIDE = §8/§etrace hide §8- §7Versteckt alle TNT-Positionen
TRACE_COMMAND_HELP_DELETE = §8/§etrace delete §8- §7Löscht alle TNT-Positionen
-TRACE_COMMAND_HELP_GUI = §8/§etrace gui §8- §7Zeigt die Trace Oberfläche an
-TRACE_COMMAND_HELP_REPLAY = §8/§etrace replay §8[§7Tick§8] §8- §7Replayes die Aufnahme
-TRACE_COMMAND_HELP_REPLAY_DISABLE = §8/§etrace replay disable §8- §7Stoppt das Replay
-TRACE_COMMAND_HELP_REPLAY_NEXT = §8/§etrace replay next §8[§7Step§8] §8- §7Springe einen§8/§7step Tick vor
-TRACE_COMMAND_HELP_REPLAY_PREVIOUS = §8/§etrace replay previous §8[§7Step§8] §8- §7Springe einen§8/§7step Tick zurück
-TRACE_COMMAND_HELP_REPLAY_LOOP = §8/§etrace replay loop §8<§7start§8> §8<§7end§8> §8[§7speed§8] §8- §7Spielt die Aufnahme in einer Schleife ab
TRACE_GUI_ITEM_NAME = §eTracer
TRACE_GUI_ITEM_LORE = §7Status§8: {0}
@@ -492,19 +493,6 @@ TRACE_GUI_AUTO_TRACE_INACTIVE = §eAuto-Tracer Aktivieren
TRACE_GUI_AUTO_TRACE_ACTIVE = §eAuto-Tracer Deaktivieren
TRACE_GUI_DELETE = §eTrace Löschen
-TRACE_GUI_TITLE = Trace GUI
-TRACE_GUI_ITEM_BACK = §eBack
-TRACE_GUI_ITEM = §eTrace §8- §e{0} §7TNT
-TRACE_GUI_CLEAR = §eTraces löschen
-TRACE_GUI_RECORD_ITEM = §eTNT §8- §e{0} §7Positionen
-TRACE_GUI_RECORD_CLEAR = §eTNT löschen
-TRACE_GUI_POSITION_ITEM = §ePosition
-TRACE_GUI_POSITION_X = §7X§8: §e{0}
-TRACE_GUI_POSITION_Y = §7Y§8: §e{0}
-TRACE_GUI_POSITION_Z = §7Z§8: §e{0}
-TRACE_GUI_POSITION_SOURCE = §7Ursprung§8: §e{0}
-TRACE_GUI_POSITION_EXPLODED = §7Explodiert§8: §e{0}
-
# Loader
LOADER_SETUP = §eEinrichtung
LOADER_RUNNING = §aLaufend
@@ -534,36 +522,45 @@ LOADER_HELP_START=§8/§eloader start §8- §7Spielt die zuvor aufgenommenen Akt
LOADER_HELP_PAUSE=§8/§7loader pause §8- §7Pausiert das Abspielen
LOADER_HELP_GUI=§8/§7loader settings §8- §7Zeigt die Einstellungen an
LOADER_HELP_STOP=§8/§eloader stop §8- §7Stoppt die Aufnahme bzw. das Abspielen
+LOADER_HELP_WAIT=§8/§7loader wait §8[§7Ticks§8] - §7Setzt die Wartezeit zwischen Schüssen
+LOADER_HELP_SPEED=§8/§7loader speed §8[§7Ticks§8] - §7Setzt die Wartezeit zwischen Aktionen
LOADER_NO_LOADER=§cDu hast noch keinen Loader. Erstelle dir einen mit /loader setup
LOADER_NEW=§7Belade und feuer einmal die Kanone ab, um den Loader zu initialisieren.
LOADER_HOW_TO_START=§7Führe dann /§eloader start§7 um den Loader zu starten
LOADER_ACTIVE=§7Der Loader ist nun aktiviert.
LOADER_STOP=§7Der Loader ist nun gestoppt.
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
-LOADER_GUI_SHOW_INTERACTIONS=§eZeige Interaktionen
-LOADER_GUI_SHOW_WAITS=§eZeige Wartezeiten
-LOADER_GUI_SHOW_WAITS_SET_BETWEEN_TNT=§7Wait Time zwischen TNT
+LOADER_GUI_SHOW_ALL=Zeige alles
+LOADER_GUI_SHOW_INTERACTIONS=Zeige Interaktionen
+LOADER_GUI_SHOW_WAITS=Zeige Wartezeiten
+LOADER_GUI_SHOW_WAITS_BETWEEN_TNT=Zeige Wartezeiten zwischen TNT
+LOADER_GUI_SHOW_TNT=Zeige TNT
LOADER_GUI_SHOW_WAITS_SET_ALL=§7Wait Time alle
LOADER_GUI_SHOW_WAITS_TITLE=§7Wartezeit
LOADER_GUI_SETTINGS_TITLE=Einstellungen
+LOADER_GUI_COPY_TITLE=Anzahl Kopien
LOADER_GUI_SETTINGS_BACK=§8Zurück
+LOADER_GUI_SETTINGS_COPY=§7Kopieren
LOADER_GUI_SETTINGS_DELETE=§cLöschen
LOADER_GUI_WAIT_TITLE=Wartezeit
LOADER_GUI_WAIT_BACK=§8Zurück
-LOADER_GUI_CLICK_TO_EDIT=§7Click to edit
+LOADER_GUI_CLICK_TO_EDIT=§7Klicke zum editieren
LOADER_GUI_ITEM_NAME=§7{0}§8: §e{1}
LOADER_SETTING_NAME=§7{0}
-LOADER_SETTING_MODES=§7Modes§8: §e{0}
-LOADER_SETTING_POWER=§7Power§8: §e{0}
+LOADER_SETTING_MODES=§7Modi§8: §e{0}
+LOADER_SETTING_POWER=§7Redstone Stärke§8: §e{0}
LOADER_SETTING_TICKS=§7Ticks§8: §e{0}
LOADER_SETTING_REPEATER=§7Repeater§8: §e{0}
-LOADER_SETTING_WAIT=§7Wait§8: §e{0} Tick(s)
-LOADER_SETTING_WAIT_NAME=Wait
+LOADER_SETTING_WAIT=§7Wartezeit§8: §e{0} Tick(s)
+LOADER_SETTING_WAIT_NAME=Wartezeit
LOADER_SETTING_TICKS_NAME=Ticks
LOADER_SETTING_TICKS_REMOVE_ONE=§c-1
LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT=§7Shift§8: §c-5
@@ -574,18 +571,21 @@ LOADER_SETTING_TNT_X=§7X§8: §e{0}
LOADER_SETTING_TNT_Y=§7Y§8: §e{0}
LOADER_SETTING_TNT_Z=§7Z§8: §e{0}
LOADER_INTERACTION_NOOP=NOOP
-LOADER_INTERACTION_INTERACT=Interact
-LOADER_INTERACTION_POWERED=Powered
-LOADER_INTERACTION_UNPOWERED=Unpowered
-LOADER_INTERACTION_PAGE_PREV=Previous Page
-LOADER_INTERACTION_PAGE_NEXT=Next Page
-LOADER_INTERACTION_PAGE=Page {0}
-LOADER_INTERACTION_ACTIVE=Active
-LOADER_INTERACTION_INACTIVE=Inactive
-LOADER_INTERACTION_WAIT_FOR=Wait for
-LOADER_INTERACTION_NO_WAIT_FOR=No wait for
-LOADER_INTERACTION_OPEN=Open
-LOADER_INTERACTION_CLOSED=Closed
+LOADER_INTERACTION_PLACE=Platzieren
+LOADER_INTERACTION_INTERACT=Interagiere
+LOADER_INTERACTION_POWERED=Aktiviert
+LOADER_INTERACTION_UNPOWERED=Deaktiviert
+LOADER_INTERACTION_PAGE_PREV=Vorherige Seite
+LOADER_INTERACTION_PAGE_NEXT=Nächste Seite
+LOADER_INTERACTION_PAGE=Seite {0}
+LOADER_INTERACTION_ACTIVE=Aktiviert
+LOADER_INTERACTION_INACTIVE=Deaktiviert
+LOADER_INTERACTION_WAIT_FOR=Darauf warten
+LOADER_INTERACTION_NO_WAIT_FOR=Nicht darauf warten
+LOADER_INTERACTION_OPEN=Geöffnet
+LOADER_INTERACTION_CLOSED=Geschlossen
+LOADER_INTERACTION_COMPARE=Vergleichen
+LOADER_INTERACTION_SUBTRACT=Subtrahieren
# Loadtimer
LOADTIMER_HELP_OVERVIEW=§7Messe dich und deine Freunde beim Beladen einer Kanone und bekomme informationen über die Kanone
@@ -674,6 +674,11 @@ OTHER_TIME_RESULT=§7§oWhooosh
OTHER_TPS_HEAD = §7TPS: 1s 10s 1m 5m 10m
OTHER_TPS_MESSAGE = §7 §e{0}§7 §e{1}§7 §e{2}§7 §e{3}§7 §e{4}
OTHER_TPS_SINGLE = §8TPS: §e{0}
+OTHER_BIND_HELP=§8/§ebind §8[§7Command§8] §8-§e Binde ein Befehl auf Item Interaktion
+OTHER_BIND_ERROR=§cFalscher oder unbekannter Befehl
+OTHER_BIND_UNBINDABLE=§cBefehl konnte nicht gebunden werden
+OTHER_BIND_MESSAGE_BIND=§7Befehl §e{0} §7ans Item gebunden
+OTHER_BIND_MESSAGE_UNBIND=§7Befehl entbunden
# DebugStick
DEBUG_STICK_COMMAND_HELP=§8/§edebugstick §8-§7 Erhalte einen DebugStick
DEBUG_STICK_NAME=§eDebugstick
@@ -749,10 +754,12 @@ REGION_ITEM_RESET=§eReset
REGION_ITEM_TESTBLOCK=§eTestblock
REGION_ITEM_TNT_OFF=§7TNT: §eAusgeschaltet
REGION_ITEM_TNT_ONLY_TB=§7TNT: §enur Testblock
+REGION_ITEM_TNT_ONLY_BUILD=§7TNT: §enur Baubereich
REGION_ITEM_TNT_ON=§7TNT: §eEingeschaltet
REGION_ITEM_SELECTOR_TITLE=Tnt Modus
REGION_ITEM_SELECTOR_ON=§eEinschalten
REGION_ITEM_SELECTOR_ONLY_TB=§enur Testblock
+REGION_ITEM_SELECTOR_ONLY_BUILD=§enur Baubereich
REGION_ITEM_SELECTOR_OFF=§eAusschalten
#Region
REGION_COLOR_HELP_COLOR=§8/§ecolor §8[§7Color§8] §8- §7Setze die Farbe der Region
@@ -837,7 +844,8 @@ 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=§cEine Explosion hätte Blöcke im Baubereich zerstört
+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_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt
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 4f1bdd92..11cacde1 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java
@@ -73,7 +73,7 @@ public class AttributeRemoveCommand extends SWCommand {
BauSystem.MESSAGE.send("ATTRIBUTE_REMOVE_NOT_FOUND", player);
return;
}
- lore.removeIf(s -> s.equals("§8-§7 " + attribute));
+ lore.removeIf(s -> s.startsWith("§8-§7 " + attribute + "§8:"));
if (lore.size() == 1) {
itemStack.setItemMeta(null);
} else {
@@ -99,15 +99,13 @@ public class AttributeRemoveCommand extends SWCommand {
return lore.stream()
.skip(1)
.map(s1 -> s1.substring(6))
- .map(s1 -> s1.replace('§', '&'))
- .map(s1 -> s1.replace(' ', '_'))
+ .map(s1 -> s1.substring(0, s1.indexOf("§8:")))
.collect(Collectors.toList());
}
@Override
public String map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
- return s.replace('_', ' ')
- .replace('&', '§');
+ return s;
}
};
}
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 66f53359..232962a1 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java
@@ -30,10 +30,12 @@ import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import lombok.Getter;
import org.bukkit.Material;
+import org.bukkit.block.data.type.Chest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
@@ -70,9 +72,28 @@ public class AutostartListener implements Listener {
if (event.getClickedBlock() == null) {
return;
}
+ if (event.getClickedBlock().getBlockData() instanceof Chest) {
+ return;
+ }
activate(event.getPlayer());
}
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event) {
+ if (!(event.getPlayer() instanceof Player)) {
+ return;
+ }
+ if (!ItemUtils.isItem(event.getPlayer().getInventory().getItemInMainHand(), "autostart")) {
+ return;
+ }
+ if (event.getInventory().getLocation() == null) {
+ return;
+ }
+ if (event.getInventory().getLocation().getBlock().getBlockData() instanceof Chest) {
+ activate((Player) event.getPlayer());
+ }
+ }
+
public void activate(Player player) {
Region region = Region.getRegion(player.getLocation());
if (region.isGlobal()) {
@@ -102,9 +123,7 @@ public class AutostartListener implements Listener {
if (!region.hasType(RegionType.TESTBLOCK)) return;
if (!region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return;
long tickDiff = TPSUtils.currentRealTick.get() - regionStartTime.remove(region);
- RegionUtils.message(region, player -> {
- return BauSystem.MESSAGE.parse("AUTOSTART_MESSAGE_RESULT1", player, new SimpleDateFormat(BauSystem.MESSAGE.parse("AUTOSTART_MESSAGE_DATE_PATTERN", player)).format(new Date(tickDiff * 50)));
- });
+ RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT1", tickDiff);
RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT2", 30, (600 - tickDiff));
RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT3");
});
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 b3de2a11..53acafeb 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java
@@ -52,7 +52,7 @@ 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));
+ membermessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_MEMBER", p, members.size()));
for (BauweltMember member : members) {
membermessage.append(BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_INFO", p,
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/CannonDetector.java b/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/CannonDetector.java
index 09893fd5..3ab4fe70 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/CannonDetector.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/CannonDetector.java
@@ -28,28 +28,29 @@ import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.util.Vector;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.stream.Collectors;
@Linked
public class CannonDetector implements Listener {
private Map velocities = new HashMap<>();
+ private Map> propulsionOfProjectile = new HashMap<>();
- @EventHandler
+ @EventHandler(priority = EventPriority.LOW)
public void onEntityExplode(EntityExplodeEvent event) {
if (!(event.getEntity() instanceof TNTPrimed)) {
return;
}
TNTPrimed tnt = (TNTPrimed) event.getEntity();
+ propulsionOfProjectile.remove(tnt);
+
DepthManager.update(tnt, event.blockList());
List tnts = Bukkit.getWorlds().get(0).getEntitiesByClass(TNTPrimed.class)
@@ -66,6 +67,7 @@ public class CannonDetector implements Listener {
boolean isEmpty = velocities.isEmpty();
tnts.forEach(tntPrimed -> {
velocities.put(tntPrimed, tntPrimed.getVelocity().clone());
+ propulsionOfProjectile.computeIfAbsent(tntPrimed, __ -> new HashSet<>()).add(tnt.getUniqueId());
});
if (!isEmpty) {
@@ -75,7 +77,10 @@ public class CannonDetector implements Listener {
BauSystem.runTaskLater(BauSystem.getInstance(), () -> {
Map> grouped = new HashMap<>();
velocities.forEach((tntPrimed, vector) -> {
- grouped.computeIfAbsent(new CannonKey(round(tntPrimed.getLocation().toVector()), round(vector)), ignored -> new ArrayList<>()).add(tntPrimed);
+ boolean xBiggest = Math.abs(vector.getX()) > Math.abs(vector.getZ());
+ boolean zBiggest = Math.abs(vector.getZ()) > Math.abs(vector.getX());
+ Vector vec = new Vector(xBiggest ? Math.signum(vector.getX()) : 0, Math.round(vector.getY() * 100), zBiggest ? Math.signum(vector.getZ()) : 0);
+ grouped.computeIfAbsent(new CannonKey(propulsionOfProjectile.get(tntPrimed), vec), ignored -> new ArrayList<>()).add(tntPrimed);
});
grouped.forEach((cannonKey, tntPrimeds) -> {
if (tntPrimeds.size() <= 5) return;
@@ -88,12 +93,4 @@ public class CannonDetector implements Listener {
velocities.clear();
}, 1);
}
-
- private Vector round(Vector vector) {
- vector.multiply(10000);
- vector.setX(Math.round(vector.getX()));
- vector.setY(Math.round(vector.getY()));
- vector.setZ(Math.round(vector.getZ()));
- return vector;
- }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/CannonKey.java b/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/CannonKey.java
index 73270eab..c260e8a9 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/CannonKey.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/CannonKey.java
@@ -22,12 +22,16 @@ package de.steamwar.bausystem.features.cannon;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
+import org.bukkit.entity.TNTPrimed;
import org.bukkit.util.Vector;
+import java.util.Set;
+import java.util.UUID;
+
@AllArgsConstructor
@EqualsAndHashCode
@Getter
public final class CannonKey {
- private Vector locationVector;
+ private Set propulsions;
private Vector velocityVector;
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java b/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java
index 506b6e93..a13d6250 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java
@@ -51,7 +51,6 @@ public class Depth {
List blocksList = blocks.stream()
.filter(block -> region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION))
.collect(Collectors.toList());
- if (blocksList.isEmpty()) return;
tntCount++;
for (Block block : blocksList) {
internalUpdate(block);
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 b2c83c7e..fd9899f8 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
@@ -55,7 +55,7 @@ public class DesignEndStone {
this.maxZ = region.getMaxPointBuild().getZ();
}
- private void calc() {
+ public void calc() {
entities.forEach(REntity::die);
entities.clear();
locations.clear();
@@ -98,12 +98,17 @@ public class DesignEndStone {
if (players.contains(player)) {
players.remove(player);
entityServer.removePlayer(player);
- BauSystem.MESSAGE.send("DESIGN_ENDSTONE_DISABLE", player, ChatMessageType.ACTION_BAR);
+ BauSystem.MESSAGE.sendPrefixless("DESIGN_ENDSTONE_DISABLE", player, ChatMessageType.ACTION_BAR);
} else {
players.add(player);
entityServer.addPlayer(player);
calc();
- BauSystem.MESSAGE.send("DESIGN_ENDSTONE_ENABLE", player, ChatMessageType.ACTION_BAR);
+ BauSystem.MESSAGE.sendPrefixless("DESIGN_ENDSTONE_ENABLE", player, ChatMessageType.ACTION_BAR);
}
}
+
+ public boolean removePlayer(Player player) {
+ players.remove(player);
+ return players.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 56b2d419..bafa3206 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
@@ -24,13 +24,19 @@ import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.command.SWCommand;
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.block.BlockBreakEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
@Linked
-public class DesignEndStoneCommand extends SWCommand {
+public class DesignEndStoneCommand extends SWCommand implements Listener {
public DesignEndStoneCommand() {
super("designendstone");
@@ -47,4 +53,37 @@ public class DesignEndStoneCommand extends SWCommand {
}
designEndStoneMap.computeIfAbsent(region, DesignEndStone::new).toggle(player);
}
+
+ @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);
+ }
+ }
+
+ @EventHandler
+ public void onBlockPlace(BlockPlaceEvent event) {
+ update(event.getBlock().getLocation());
+ }
+
+ @EventHandler
+ public void onBlockBreak(BlockBreakEvent event) {
+ BauSystem.runTaskLater(BauSystem.getInstance(), () -> {
+ update(event.getBlock().getLocation());
+ }, 1);
+ }
+
+ private void update(Location location) {
+ Region region = Region.getRegion(location);
+ DesignEndStone designEndStone = designEndStoneMap.get(region);
+ if (designEndStone == null) {
+ return;
+ }
+ designEndStone.calc();
+ }
}
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 6d4b8af2..d7c89254 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java
@@ -48,7 +48,7 @@ public class KillcheckerVisualizer {
private static final Material[] MATERIALS = new Material[] {Material.YELLOW_STAINED_GLASS, Material.ORANGE_STAINED_GLASS, Material.RED_STAINED_GLASS, Material.PURPLE_STAINED_GLASS, Material.BLACK_STAINED_GLASS};
private static final World WORLD = Bukkit.getWorlds().get(0);
- private static final double SURROUND = 4;
+ private static final double SURROUND = 4.5;
private final Point minPoint;
private final Point maxPoint;
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 8cea017b..22e0df02 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java
@@ -35,9 +35,11 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
public class Loader implements Listener {
@@ -72,18 +74,19 @@ public class Loader implements Listener {
waitTime--;
return;
}
+ if (currentElement >= elements.size()) {
+ currentElement = 0;
+ }
while (currentElement < elements.size()) {
LoaderElement element = elements.get(currentElement);
currentElement++;
element.execute(delay -> waitTime = delay);
if (waitTime > 0) {
- break;
+ if (element instanceof LoaderTNT) currentElement--;
+ return;
}
}
- if (currentElement >= elements.size()) {
- currentElement = 0;
- }
}, 0, 1);
}
@@ -121,27 +124,67 @@ public class Loader implements Listener {
LOADER_MAP.remove(p);
}
+ public boolean setTicksBetweenShots(int delay) {
+ if (elements.size() == 0) return false;
+ LoaderElement loaderElement = elements.get(elements.size() - 1);
+ if (loaderElement instanceof LoaderWait) {
+ ((LoaderWait) loaderElement).setDelay(delay);
+ return true;
+ }
+ return false;
+ }
+
+ public void setTicksBetweenBlocks(int delay) {
+ for (int i = 0; i < elements.size() - 1; i++) {
+ LoaderElement loaderElement = elements.get(i);
+ if (loaderElement instanceof LoaderWait) {
+ ((LoaderWait) loaderElement).setDelay(delay);
+ }
+ }
+ }
+
public void gui(SettingsSorting settingsSorting) {
List> list = new ArrayList<>();
+ AtomicBoolean allWait = new AtomicBoolean(true);
Runnable updateRunnable = () -> {
list.clear();
- for (LoaderElement element : elements) {
- if (settingsSorting != null) {
- if (settingsSorting == SettingsSorting.WAIT && !(element instanceof LoaderWait)) {
- continue;
- }
- if (settingsSorting == SettingsSorting.INTERACTIONS && (element instanceof LoaderWait || element instanceof LoaderTNT)) {
- continue;
- }
+ for (int i = 0; i < elements.size(); i++) {
+ LoaderElement previous = i > 0 ? elements.get(i - 1) : null;
+ LoaderElement current = elements.get(i);
+ LoaderElement next = i < elements.size() - 1 ? elements.get(i + 1) : null;
+
+ if (!settingsSorting.shouldShow(previous, current, next)) {
+ continue;
}
- SWItem item = element.menu(p);
- if (element instanceof LoaderInteractionElement>) {
- LoaderInteractionElement> interactionElement = (LoaderInteractionElement>) element;
- item.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_MODES", p, interactionElement.size()), "§8", BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", p)));
+
+ if ((!(current instanceof LoaderWait))) {
+ allWait.set(false);
+ }
+
+ SWItem item = current.menu(p);
+ if (current instanceof LoaderInteractionElement>) {
+ LoaderInteractionElement> interactionElement = (LoaderInteractionElement>) current;
+ List lore = new ArrayList<>();
+ if (item.getItemMeta() != null && item.getItemMeta().getLore() != null) {
+ lore.addAll(item.getItemMeta().getLore());
+ lore.add("§8");
+ }
+ lore.add(BauSystem.MESSAGE.parse("LOADER_SETTING_MODES", p, interactionElement.size()));
+ lore.add(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", p));
+ item.setLore(lore);
} else {
- item.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", p)));
+ List lore = new ArrayList<>();
+ if (item.getItemMeta() != null && item.getItemMeta().getLore() != null) {
+ lore.addAll(item.getItemMeta().getLore());
+ lore.add("§8");
+ }
+ lore.add(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", p));
+ item.setLore(lore);
}
- list.add(new SWListInv.SWListEntry<>(item, element));
+ list.add(new SWListInv.SWListEntry<>(item, current));
+ }
+ if (list.isEmpty()) {
+ allWait.set(false);
}
};
updateRunnable.run();
@@ -152,65 +195,51 @@ public class Loader implements Listener {
swListInv.open();
}));
- SWItem onlyInteractionsElements = new SWItem(Material.REPEATER, BauSystem.MESSAGE.parse("LOADER_GUI_SHOW_INTERACTIONS", p), clickType -> {
- gui(settingsSorting == SettingsSorting.INTERACTIONS ? null : SettingsSorting.INTERACTIONS);
+ SWItem settingItem = new SWItem(settingsSorting.getMaterial(), "§e" + BauSystem.MESSAGE.parse(settingsSorting.getName(), p), clickType -> {
+ if (clickType == ClickType.LEFT) {
+ int index = settingsSorting.ordinal() + 1;
+ if (index >= SettingsSorting.LENGTH) {
+ index = 0;
+ }
+ gui(SettingsSorting.values()[index]);
+ } else if (clickType == ClickType.RIGHT) {
+ int index = settingsSorting.ordinal() - 1;
+ if (index < 0) {
+ index = SettingsSorting.LENGTH - 1;
+ }
+ gui(SettingsSorting.values()[index]);
+ }
});
- if (settingsSorting == SettingsSorting.INTERACTIONS) onlyInteractionsElements.setEnchanted(true);
- swListInv.setItem(47, onlyInteractionsElements);
-
- SWItem onlyWaitElements = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("LOADER_GUI_SHOW_WAITS", p), clickType -> {
- gui(settingsSorting == SettingsSorting.WAIT ? null : SettingsSorting.WAIT);
- });
- if (settingsSorting == SettingsSorting.WAIT) onlyWaitElements.setEnchanted(true);
- swListInv.setItem(48, onlyWaitElements);
-
- if (settingsSorting == SettingsSorting.WAIT) {
- SWItem waitBetweenTNT = new SWItem(Material.TNT, BauSystem.MESSAGE.parse("LOADER_GUI_SHOW_WAITS_SET_BETWEEN_TNT", p), clickType -> {
- SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("LOADER_GUI_SHOW_WAITS_TITLE", p), "");
- swAnvilInv.setCallback(s -> {
- try {
- long delay = Long.parseLong(s);
- if (delay < 0) delay = 0;
- for (int i = 1; i < elements.size() - 1; i++) {
- if (!(elements.get(i - 1) instanceof LoaderTNT)) continue;
- if (!(elements.get(i + 1) instanceof LoaderTNT)) continue;
- if (!(elements.get(i) instanceof LoaderWait)) continue;
- ((LoaderWait) elements.get(i)).setDelay(delay);
- }
- } catch (NumberFormatException ignored) {
- }
- gui(settingsSorting);
- });
- updateRunnable.run();
- swAnvilInv.open();
- });
- swListInv.setItem(50, waitBetweenTNT);
-
- SWItem waitTime = new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("LOADER_GUI_SHOW_WAITS_SET_ALL", p), clickType -> {
- SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("LOADER_GUI_SHOW_WAITS_TITLE", p), "");
- swAnvilInv.setCallback(s -> {
- try {
- long delay = Long.parseLong(s);
- if (delay < 0) delay = 0;
- long finalDelay = delay;
- elements.stream()
- .filter(LoaderWait.class::isInstance)
- .map(LoaderWait.class::cast)
- .forEach(loaderWait -> loaderWait.setDelay(finalDelay));
- } catch (NumberFormatException ignored) {
- }
- gui(settingsSorting);
- });
- updateRunnable.run();
- swAnvilInv.open();
- });
- swListInv.setItem(51, waitTime);
- } else {
- SWItem empty = new SWItem(Material.STRUCTURE_VOID, "§7", clickType -> {});
- swListInv.setItem(50, empty);
- swListInv.setItem(51, empty);
+ List strings = new ArrayList<>();
+ for (SettingsSorting setting : SettingsSorting.values()) {
+ if (setting == settingsSorting) {
+ strings.add("§e> §7" + BauSystem.MESSAGE.parse(setting.getName(), p));
+ } else {
+ strings.add("§8> §7" + BauSystem.MESSAGE.parse(setting.getName(), p));
+ }
}
+ settingItem.setLore(strings);
+ swListInv.setItem(48, settingItem);
+ if (allWait.get()) {
+ SWItem setWait = new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("LOADER_GUI_SHOW_WAITS_SET_ALL", p), clickType -> {
+ SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("LOADER_GUI_SHOW_WAITS_TITLE", p), "");
+ swAnvilInv.setCallback(s -> {
+ try {
+ long delay = Math.max(Long.parseLong(s), 0);
+ list.forEach(loaderElementSWListEntry -> {
+ ((LoaderWait) loaderElementSWListEntry.getObject()).setDelay(delay);
+ });
+ } catch (NumberFormatException ignored) {
+ }
+ gui(settingsSorting);
+ });
+ swAnvilInv.open();
+ });
+ swListInv.setItem(50, setWait);
+ } else {
+ swListInv.setItem(50, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§8"));
+ }
swListInv.open();
}
@@ -221,12 +250,97 @@ public class Loader implements Listener {
}
public String getProgress() {
- return (currentElement + 1) + "§8/§7" + elements.size();
+ return Math.max(currentElement, 1) + "§8/§7" + elements.size();
}
public enum SettingsSorting {
- WAIT,
- INTERACTIONS,
+ ALL {
+ @Override
+ public Material getMaterial() {
+ return Material.STRUCTURE_VOID;
+ }
+
+ @Override
+ public String getName() {
+ return "LOADER_GUI_SHOW_ALL";
+ }
+
+ @Override
+ public boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next) {
+ return true;
+ }
+ },
+ WAIT {
+ @Override
+ public Material getMaterial() {
+ return Material.CLOCK;
+ }
+
+ @Override
+ public String getName() {
+ return "LOADER_GUI_SHOW_WAITS";
+ }
+
+ @Override
+ public boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next) {
+ return current instanceof LoaderWait;
+ }
+ },
+ WAIT_BETWEEN_TNT {
+ @Override
+ public Material getMaterial() {
+ return Material.REDSTONE_BLOCK;
+ }
+
+ @Override
+ public String getName() {
+ return "LOADER_GUI_SHOW_WAITS_BETWEEN_TNT";
+ }
+
+ @Override
+ public boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next) {
+ return previous instanceof LoaderTNT && current instanceof LoaderWait && next instanceof LoaderTNT;
+ }
+ },
+ INTERACTIONS {
+ @Override
+ public Material getMaterial() {
+ return Material.REPEATER;
+ }
+
+ @Override
+ public String getName() {
+ return "LOADER_GUI_SHOW_INTERACTIONS";
+ }
+
+ @Override
+ public boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next) {
+ return current instanceof LoaderInteractionElement && !(current instanceof LoaderTNT);
+ }
+ },
+ TNT {
+ @Override
+ public Material getMaterial() {
+ return Material.TNT;
+ }
+
+ @Override
+ public String getName() {
+ return "LOADER_GUI_SHOW_TNT";
+ }
+
+ @Override
+ public boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next) {
+ return current instanceof LoaderTNT;
+ }
+ },
+ ;
+
+ public static int LENGTH = SettingsSorting.values().length;
+
+ public abstract Material getMaterial();
+ public abstract String getName();
+ public abstract boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next);
}
@AllArgsConstructor
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 ee03be16..b065c3d2 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java
@@ -80,7 +80,26 @@ public class LoaderCommand extends SWCommand {
public void guiLoader(@Validator Player player) {
Loader loader = Loader.getLoader(player);
if (loaderNullCheck(loader, player)) return;
- loader.gui(null);
+ loader.gui(Loader.SettingsSorting.ALL);
+ }
+
+ @Register(value = "wait", description = "LOADER_HELP_WAIT")
+ public void shotDelayLoader(@Validator Player p, @Min(intValue = 1) @ErrorMessage("LOADER_SMALL_TIME") int delay) {
+ Loader loader = Loader.getLoader(p);
+ if (loaderNullCheck(loader, p)) return;
+ if (loader.setTicksBetweenShots(delay)) {
+ BauSystem.MESSAGE.send("LOADER_NEW_TIME", p, delay);
+ } else {
+ BauSystem.MESSAGE.send("LOADER_SMALL_TIME", p);
+ }
+ }
+
+ @Register(value = "speed", description = "LOADER_HELP_SPEED")
+ public void speedLoader(@Validator Player p, @Min(intValue = 0) @ErrorMessage("LOADER_SMALL_TIME") int delay) {
+ Loader loader = Loader.getLoader(p);
+ if (loaderNullCheck(loader, p)) return;
+ BauSystem.MESSAGE.send("LOADER_NEW_LOAD_TIME", p, delay);
+ loader.setTicksBetweenBlocks(delay);
}
@ClassValidator(value = Player.class, local = true)
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 a0734231..ec2153ae 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.loader;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.loader.elements.LoaderElement;
+import de.steamwar.bausystem.features.loader.elements.LoaderInteractionElement;
import de.steamwar.bausystem.features.loader.elements.impl.*;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import org.bukkit.Bukkit;
@@ -33,6 +34,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
+import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
@@ -70,7 +72,7 @@ public class LoaderRecorder implements Listener {
return;
}
long diff = TPSUtils.currentRealTick.get() - lastInteraction;
- if (last && diff > 160) diff = 160;
+ if (last) diff = 120;
lastInteraction = TPSUtils.currentRealTick.get();
loaderElementList.add(new LoaderWait(diff));
}
@@ -86,7 +88,34 @@ public class LoaderRecorder implements Listener {
}
@EventHandler
- public void onPlayerInteractEntity(PlayerInteractEvent event) {
+ public void onBlockBreak(BlockBreakEvent event) {
+ if (event.getPlayer() != player) return;
+
+ boolean removedOne = false;
+ for (int i = 0; i < loaderElementList.size(); i++) {
+ LoaderElement element = loaderElementList.get(i);
+ if (!(element instanceof LoaderInteractionElement)) continue;
+ LoaderInteractionElement interactionElement = (LoaderInteractionElement) element;
+ if (interactionElement.getLocation().equals(event.getBlock().getLocation())) {
+ loaderElementList.remove(i);
+ if (i > 0) {
+ loaderElementList.remove(i - 1);
+ }
+ removedOne = true;
+ break;
+ }
+ }
+
+ if (removedOne) {
+ if (event.getBlock().getType() != Material.TNT) {
+ event.setCancelled(true);
+ }
+ SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("LOADER_MESSAGE_UNINTERACT", player));
+ }
+ }
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getPlayer() != player) return;
if (player.isSneaking()) return;
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) return;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/ElementSettings.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/ElementSettings.java
deleted file mode 100644
index 25b839ff..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/ElementSettings.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.loader.elements;
-
-import de.steamwar.bausystem.BauSystem;
-import de.steamwar.inventory.SWItem;
-import org.bukkit.entity.Player;
-
-import java.util.function.Consumer;
-
-public interface ElementSettings {
- SWItem menu(Player player);
- void execute(Consumer delay);
- void click(Player player, Runnable backAction, Runnable deleteAction);
-
- default void playerInteract() {}
- void noop();
-
- default String translateItemName(String name, String mode, Player player, Object... args) {
- return BauSystem.MESSAGE.parse("LOADER_GUI_ITEM_NAME", player, BauSystem.MESSAGE.parse(name, player), BauSystem.MESSAGE.parse(mode, player, args));
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/LoaderInteractionElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/LoaderInteractionElement.java
index cc00c662..67539fd8 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/LoaderInteractionElement.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/LoaderInteractionElement.java
@@ -21,62 +21,93 @@ package de.steamwar.bausystem.features.loader.elements;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.inventory.SWAnvilInv;
+import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
+import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.block.data.FaceAttachable;
+import org.bukkit.block.data.*;
+import org.bukkit.block.data.type.Door;
import org.bukkit.block.data.type.Switch;
import org.bukkit.entity.Player;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
-public abstract class LoaderInteractionElement implements LoaderElement {
+public abstract class LoaderInteractionElement & LoaderSettingsEnum> implements LoaderElement {
+ @Getter
protected final Location location;
protected int currentShot = 0;
+ protected T defaultSetting;
+ protected T newSetting;
+ protected T[] allSettings;
protected List elements = new ArrayList<>();
+ protected List extraPower = new ArrayList<>();
+ protected List extraTicks = new ArrayList<>();
+ protected int settingsGuiSize = 0;
- protected LoaderInteractionElement(Location location) {
+ protected LoaderInteractionElement(Location location, T defaultSetting, T newSetting, T[] allSettings) {
this.location = location;
- T element = createNewElement();
- element.playerInteract();
- elements.add(element);
+ this.defaultSetting = defaultSetting;
+ this.newSetting = newSetting;
+ this.allSettings = allSettings;
+
+ elements.add(defaultSetting);
+ extraPower.add(0);
+ extraTicks.add(0L);
+
+ for (T element : allSettings) {
+ settingsGuiSize = Math.max(element.getPos(), settingsGuiSize);
+ }
+ while (settingsGuiSize % 9 != 0) settingsGuiSize++;
+ settingsGuiSize += 9;
}
@Override
public void execute(Consumer delay) {
if (currentShot >= elements.size()) currentShot = 0;
- elements.get(currentShot).execute(delay);
+ if (checkBlockInWorld()) {
+ BlockData blockData = location.getBlock().getBlockData();
+ elements.get(currentShot).execute(location, blockData, this, extraPower.get(currentShot), extraTicks.get(currentShot), delay);
+ }
currentShot++;
if (currentShot >= elements.size()) currentShot = 0;
}
@Override
public void click(Player player, Runnable backAction) {
- List> entries = new ArrayList<>();
+ List> entries = new ArrayList<>();
Runnable updateRunnable = () -> {
entries.clear();
- for (T element : elements) {
- entries.add(new SWListInv.SWListEntry<>(element.menu(player), element));
+ for (int i = 0; i < elements.size(); i++) {
+ SWItem swItem = elements.get(i).menu(player, this, extraPower.get(i), extraTicks.get(i));
+ swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
+ entries.add(new SWListInv.SWListEntry<>(swItem, i));
}
};
updateRunnable.run();
- SWListInv listInv = new SWListInv<>(player, "Interaction Settings", false, entries, (clickType, entry) -> {});
+ SWListInv listInv = new SWListInv<>(player, "Interaction Settings", false, entries, (clickType, entry) -> {});
listInv.setCallback((clickType, entry) -> {
- entry.click(player, () -> {
+ openIndividualSettingsMenu(player, entry, () -> {
updateRunnable.run();
listInv.open();
}, () -> {
- if (elements.size() == 1) return;
- elements.remove(entry);
+ elements.remove((int) entry);
+ extraPower.remove((int) entry);
+ extraTicks.remove((int) entry);
+ if (elements.isEmpty()) {
+ elements.add(newSetting);
+ extraPower.add(0);
+ extraTicks.add(1L);
+ }
click(player, backAction);
});
});
@@ -84,69 +115,190 @@ public abstract class LoaderInteractionElement implem
backAction.run();
}));
listInv.setItem(50, new SWItem(Material.GHAST_SPAWN_EGG, "§7Insert another Setting", clickType -> {
- T element = createNewElement();
- elements.add(element);
- element.click(player, () -> {
+ elements.add(defaultSetting);
+ extraPower.add(0);
+ extraTicks.add(1L);
+ openIndividualSettingsMenu(player, elements.size() - 1, () -> {
updateRunnable.run();
listInv.open();
}, () -> {
- if (elements.size() == 1) return;
- elements.remove(element);
+ elements.remove(elements.size() - 1);
+ extraPower.remove(extraPower.size() - 1);
+ extraTicks.remove(extraTicks.size() - 1);
+ if (elements.isEmpty()) {
+ elements.add(newSetting);
+ extraPower.add(0);
+ extraTicks.add(1L);
+ }
click(player, backAction);
});
}));
- listInv.setItem(51, new SWItem(Material.STRUCTURE_VOID, "§7Insert NOOP's", clickType -> {
- SWAnvilInv anvilInv = new SWAnvilInv(player, "§7NOOP Count", "1");
- anvilInv.setCallback(s -> {
- try {
- int count = Integer.parseInt(s);
- for (int i = 0; i < count; i++) {
- T element = createNewElement();
- element.noop();
- elements.add(element);
- }
- updateRunnable.run();
- listInv.open();
- } catch (NumberFormatException e) {
- player.sendMessage("§cInvalid Number");
- }
- });
- anvilInv.open();
- }));
listInv.open();
}
+ private void openIndividualSettingsMenu(Player player, int index, Runnable back, Runnable delete) {
+ T currentElement = elements.get(index);
+ int guiSize = settingsGuiSize;
+ int powerStart = guiSize - 9;
+ if (currentElement.hasPower(this)) {
+ guiSize += 18;
+ }
+ int ticksStart = guiSize - 9;
+ if (currentElement.hasTicks(this)) {
+ guiSize += 9;
+ }
+
+ SWInventory swInventory = new SWInventory(player, guiSize, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
+ for (int i = guiSize - 9; i < guiSize; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", clickType -> {}));
+ swInventory.setItem(guiSize - 9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> back.run());
+ swInventory.setItem(guiSize - 5, new SWItem(Material.WOODEN_AXE, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_COPY", player)).getItemStack(), clickType -> {
+ SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_GUI_COPY_TITLE", player), "1");
+ swAnvilInv.setCallback(s -> {
+ try {
+ int count = Integer.parseInt(s);
+ if (count < 1) count = 1;
+ if (count > 65536) count = 65536;
+
+ int power = extraPower.get(index);
+ long ticks = extraTicks.get(index);
+ for (int i = 0; i < count; i++) {
+ elements.add(currentElement);
+ extraPower.add(power);
+ extraTicks.add(ticks);
+ }
+
+ if (count == 1) {
+ openIndividualSettingsMenu(player, elements.size() - 1, back, delete);
+ } else {
+ back.run();
+ }
+ } catch (NumberFormatException e) {
+ back.run();
+ }
+ });
+ swAnvilInv.open();
+ });
+ swInventory.setItem(guiSize - 1, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> delete.run());
+
+ for (T element : allSettings) {
+ SWItem item = element.menu(player, this, extraPower.get(index), extraTicks.get(index));
+ if (element == currentElement) {
+ item.setEnchanted(true);
+ }
+
+ swInventory.setItem(element.getPos(), item.getItemStack(), clickType -> {
+ elements.set(index, element);
+ openIndividualSettingsMenu(player, index, back, delete);
+ });
+ }
+
+ if (currentElement.hasPower(this)) {
+ for (int power = 0; power < 16; power++) {
+ int finalPowerPosition = power;
+ if (power >= 9) finalPowerPosition++;
+ SWItem powerItem = new SWItem(Material.REDSTONE, BauSystem.MESSAGE.parse("LOADER_SETTING_POWER", player, power), Arrays.asList(), false, clickType -> {});
+ powerItem.getItemStack().setAmount(Math.max(power, 1));
+ if (extraPower.get(index) == power) powerItem.setEnchanted(true);
+
+ int finalPower = power;
+ swInventory.setItem(finalPowerPosition + powerStart, powerItem.getItemStack(), clickType -> {
+ extraPower.set(index, finalPower);
+ openIndividualSettingsMenu(player, index, back, delete);
+ });
+ }
+ }
+
+ if (currentElement.hasTicks(this)) {
+ swInventory.setItem(ticksStart + 3, new SWItem(SWItem.getDye(1), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
+ long ticks = extraTicks.get(index);
+ ticks -= clickType.isShiftClick() ? 5 : 1;
+ if (ticks < 1) ticks = 1;
+ extraTicks.set(index, ticks);
+ openIndividualSettingsMenu(player, index, back, delete);
+ });
+
+ SWItem ticksItem = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS", player, extraTicks.get(index)), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)), false, clickType -> {});
+ ticksItem.getItemStack().setAmount((int) Math.min(extraTicks.get(index), 64));
+ swInventory.setItem(ticksStart + 4, ticksItem.getItemStack(), clickType -> {
+ SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_NAME", player), extraTicks.get(index) + "");
+ swAnvilInv.setCallback(s -> {
+ try {
+ long ticks = Long.parseLong(s);
+ if (ticks < 1) ticks = 1;
+ extraTicks.set(index, ticks);
+ } catch (NumberFormatException ignored) {
+ }
+ openIndividualSettingsMenu(player, index, back, delete);
+ });
+ swAnvilInv.open();
+ });
+
+ swInventory.setItem(ticksStart + 5, new SWItem(SWItem.getDye(10), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
+ long ticks = extraTicks.get(index);
+ ticks += clickType.isShiftClick() ? 5 : 1;
+ extraTicks.set(index, ticks);
+ openIndividualSettingsMenu(player, index, back, delete);
+ });
+ }
+
+ swInventory.open();
+ }
+
protected void update(BlockData blockData) {
- Material material = blockData.getMaterial();
Block block = location.getBlock();
- if (blockData instanceof Switch) {
+ if (blockData instanceof Door) {
+ Door door = (Door) blockData;
+ block.setBlockData(door);
+ if (door.getHalf() == Bisected.Half.BOTTOM) {
+ updateBlock(block.getRelative(BlockFace.UP), door.isOpen() ? 15 : 0);
+ } else {
+ updateBlock(block.getRelative(BlockFace.DOWN), door.isOpen() ? 15 : 0);
+ }
+ } else if (blockData instanceof Switch) {
Switch sw = (Switch) blockData;
updateBlock(block, sw);
FaceAttachable.AttachedFace face = sw.getAttachedFace();
if (face == FaceAttachable.AttachedFace.FLOOR) {
- updateBlock(block.getRelative(BlockFace.DOWN));
+ updateBlock(block.getRelative(BlockFace.DOWN), sw.isPowered() ? 15 : 0);
} else if (face == FaceAttachable.AttachedFace.CEILING) {
- updateBlock(block.getRelative(BlockFace.UP));
+ updateBlock(block.getRelative(BlockFace.UP), sw.isPowered() ? 15 : 0);
} else {
- updateBlock(block.getRelative(sw.getFacing().getOppositeFace()));
+ updateBlock(block.getRelative(sw.getFacing().getOppositeFace()), sw.isPowered() ? 15 : 0);
}
- } else if (material == Material.TRIPWIRE) {
+ } else if (blockData instanceof Powerable) {
+ updateBlock(block, blockData);
+ updateBlock(block.getRelative(BlockFace.DOWN), ((Powerable) blockData).isPowered() ? 15 : 0);
+ } else if (blockData instanceof AnaloguePowerable) {
+ updateBlock(block, blockData);
+ updateBlock(block.getRelative(BlockFace.DOWN), ((AnaloguePowerable) blockData).getPower());
+ } else {
updateBlock(block, blockData);
- } else if (material.name().endsWith("_PLATE")) {
- updateBlock(block.getRelative(BlockFace.DOWN));
}
}
- protected void updateBlock(Block block) {
- updateBlock(block, block.getBlockData());
+ private void updateBlock(Block block, int powered) {
+ BlockData data = block.getBlockData();
+ if (data instanceof Door) {
+ Door door = (Door) data;
+ door.setOpen(powered > 0);
+ block.setBlockData(door);
+ return;
+ } else if (data instanceof Powerable) {
+ Powerable powerable = (Powerable) data;
+ powerable.setPowered(powered > 0);
+ } else if (data instanceof AnaloguePowerable) {
+ AnaloguePowerable analoguePowerable = (AnaloguePowerable) data;
+ analoguePowerable.setPower(powered);
+ }
+ updateBlock(block, data);
}
- protected void updateBlock(Block block, BlockData data) {
- block.setType(Material.BARRIER, true);
- block.setBlockData(data, true);
+ private void updateBlock(Block block, BlockData data) {
+ block.setType(Material.BARRIER);
+ block.setBlockData(data);
}
- public abstract T createNewElement();
+ public abstract boolean checkBlockInWorld();
protected final String translateItemName(String name, Player player) {
return BauSystem.MESSAGE.parse("LOADER_SETTING_NAME", player, BauSystem.MESSAGE.parse(name, player));
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/LoaderSettingsEnum.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/LoaderSettingsEnum.java
new file mode 100644
index 00000000..f1e628d0
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/LoaderSettingsEnum.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.loader.elements;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+import java.util.function.Consumer;
+
+public interface LoaderSettingsEnum, E extends Enum & LoaderSettingsEnum> {
+ int getPos();
+ SWItem menu(Player player, P parent, int power, long ticks);
+ default boolean hasPower(P parent) {
+ return false;
+ }
+ default boolean hasTicks(P parent) {
+ return false;
+ }
+
+ void execute(Location location, T blockData, P parent, int power, long ticks, Consumer delay);
+
+ default String translateItemName(String name, String mode, Player player, Object... args) {
+ return BauSystem.MESSAGE.parse("LOADER_GUI_ITEM_NAME", player, BauSystem.MESSAGE.parse(name, player), BauSystem.MESSAGE.parse(mode, player, args));
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/impl/LoaderComparator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/impl/LoaderComparator.java
index 9e446448..fa7a032e 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/impl/LoaderComparator.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/impl/LoaderComparator.java
@@ -19,10 +19,8 @@
package de.steamwar.bausystem.features.loader.elements.impl;
-import de.steamwar.bausystem.BauSystem;
-import de.steamwar.bausystem.features.loader.elements.ElementSettings;
import de.steamwar.bausystem.features.loader.elements.LoaderInteractionElement;
-import de.steamwar.inventory.SWInventory;
+import de.steamwar.bausystem.features.loader.elements.LoaderSettingsEnum;
import de.steamwar.inventory.SWItem;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -30,101 +28,83 @@ import org.bukkit.block.data.type.Comparator;
import org.bukkit.entity.Player;
import java.util.Arrays;
-import java.util.Collections;
import java.util.function.Consumer;
-public class LoaderComparator extends LoaderInteractionElement {
+public class LoaderComparator extends LoaderInteractionElement {
public LoaderComparator(Location location) {
- super(location);
+ super(location, ComparatorSettingsEnum.INTERACT, ComparatorSettingsEnum.NOOP, ComparatorSettingsEnum.values());
}
- public class ComparatorSettings implements ElementSettings {
-
- private boolean interact = false;
- private Comparator.Mode mode = Comparator.Mode.COMPARE;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, interact, mode);
- }
-
- private SWItem menu(Player player, boolean interact, Comparator.Mode mode) {
- SWItem swItem;
- if (interact) {
- swItem = new SWItem(Material.STICK, "§7Comparator§8: §eInteract");
- } else if (mode == null) {
- swItem = new SWItem(Material.STRUCTURE_VOID, "§7Comparator§8: §eNOOP");
- } else {
- swItem = new SWItem(Material.COMPARATOR, "§7Comparator§8: §e" + mode.name());
+ public enum ComparatorSettingsEnum implements LoaderSettingsEnum {
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
}
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
- @Override
- public void execute(Consumer delay) {
- if (location.getBlock().getType() != Material.COMPARATOR) return;
- Comparator comparator = (Comparator) location.getBlock().getBlockData();
- if (interact) {
- comparator.setMode(comparator.getMode() == Comparator.Mode.COMPARE ? Comparator.Mode.SUBTRACT : Comparator.Mode.COMPARE);
- } else if (mode == null) {
- return;
- } else {
- comparator.setMode(mode);
+ @Override
+ public SWItem menu(Player player, LoaderComparator parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_COMPARATOR", "LOADER_INTERACTION_NOOP", player));
}
- location.getBlock().setBlockData(comparator, true);
- }
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, 18, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(17, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
-
- swInventory.setItem(2, item(player, false, null).getItemStack(), clickType -> {
- interact = false;
- mode = null;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(3, item(player, true, null).getItemStack(), clickType -> {
- interact = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(5, item(player, false, Comparator.Mode.COMPARE).getItemStack(), clickType -> {
- interact = false;
- mode = Comparator.Mode.COMPARE;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(6, item(player, false, Comparator.Mode.SUBTRACT).getItemStack(), clickType -> {
- interact = false;
- mode = Comparator.Mode.SUBTRACT;
- click(player, backAction, deleteAction);
- });
-
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean interact, Comparator.Mode mode) {
- SWItem swItem = menu(player, interact, mode);
- if (swItem.getItemStack().equals(menu(player, this.interact, this.mode).getItemStack())) {
- swItem.setEnchanted(true);
+ @Override
+ public void execute(Location location, Comparator blockData, LoaderComparator parent, int power, long ticks, Consumer delay) {
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
+ },
- @Override
- public void playerInteract() {
- interact = true;
- mode = null;
- }
+ INTERACT {
+ @Override
+ public int getPos() {
+ return 3;
+ }
- @Override
- public void noop() {
- interact = false;
- mode = null;
+ @Override
+ public SWItem menu(Player player, LoaderComparator parent, int power, long ticks) {
+ return new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_COMPARATOR", "LOADER_INTERACTION_INTERACT", player));
+ }
+
+ @Override
+ public void execute(Location location, Comparator blockData, LoaderComparator parent, int power, long ticks, Consumer delay) {
+ blockData.setMode(blockData.getMode() == Comparator.Mode.COMPARE ? Comparator.Mode.SUBTRACT : Comparator.Mode.COMPARE);
+ parent.update(blockData);
+ }
+ },
+
+ COMPARE {
+ @Override
+ public int getPos() {
+ return 5;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderComparator parent, int power, long ticks) {
+ return new SWItem(Material.COMPARATOR, translateItemName("LOADER_BUTTON_COMPARATOR", "LOADER_INTERACTION_COMPARE", player));
+ }
+
+ @Override
+ public void execute(Location location, Comparator blockData, LoaderComparator parent, int power, long ticks, Consumer delay) {
+ blockData.setMode(Comparator.Mode.COMPARE);
+ parent.update(blockData);
+ }
+ },
+
+ SUBTRACT {
+ @Override
+ public int getPos() {
+ return 6;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderComparator parent, int power, long ticks) {
+ return new SWItem(Material.COMPARATOR, translateItemName("LOADER_BUTTON_COMPARATOR", "LOADER_INTERACTION_SUBTRACT", player));
+ }
+
+ @Override
+ public void execute(Location location, Comparator blockData, LoaderComparator parent, int power, long ticks, Consumer delay) {
+ blockData.setMode(Comparator.Mode.SUBTRACT);
+ parent.update(blockData);
+ }
}
}
@@ -136,7 +116,7 @@ public class LoaderComparator extends LoaderInteractionElement {
+public class LoaderDaylightDetector extends LoaderInteractionElement {
public LoaderDaylightDetector(Location location) {
- super(location);
+ super(location, DaylightSettingsEnum.INTERACT, DaylightSettingsEnum.NOOP, DaylightSettingsEnum.values());
}
- public class DaylightDetectorSettings implements ElementSettings {
-
- private boolean noop = false;
- private boolean interact = false;
- private boolean inverted = true;
- private int power = 0;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, noop, interact, inverted);
- }
-
- private SWItem menu(Player player, boolean noop, boolean interact, boolean powered) {
- SWItem swItem;
- if (noop) {
- swItem = new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_DAYLIGHT_DETECTOR", "LOADER_INTERACTION_NOOP", player));
- } else if (interact) {
- swItem = new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_DAYLIGHT_DETECTOR", "LOADER_INTERACTION_INTERACT", player));
- } else {
- swItem = new SWItem(Material.DAYLIGHT_DETECTOR, translateItemName("LOADER_BUTTON_DAYLIGHT_DETECTOR", powered ? "LOADER_INTERACTION_POWERED": "LOADER_INTERACTION_UNPOWERED", player));
- }
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
-
- @Override
- public void execute(Consumer delay) {
- if (location.getBlock().getType() != Material.DAYLIGHT_DETECTOR) return;
- DaylightDetector daylightDetector = (DaylightDetector) location.getBlock().getBlockData();
- if (noop) {
- return;
- } else if (interact) {
- daylightDetector.setInverted(!daylightDetector.isInverted());
- } else {
- daylightDetector.setInverted(inverted);
- }
- daylightDetector.setPower(daylightDetector.isInverted() ? 15 - power : power);
- location.getBlock().setBlockData(daylightDetector);
- updateBlock(location.getBlock().getRelative(0, -1, 0));
- }
-
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, 36, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = 27; i < 35; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(27, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(35, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
-
- swInventory.setItem(2, item(player, true, false, false).getItemStack(), clickType -> {
- noop = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(3, item(player, false, true, false).getItemStack(), clickType -> {
- noop = false;
- interact = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(5, item(player, false, false, false).getItemStack(), clickType -> {
- noop = false;
- interact = false;
- inverted = false;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(6, item(player, false, false, true).getItemStack(), clickType -> {
- noop = false;
- interact = false;
- inverted = true;
- click(player, backAction, deleteAction);
- });
-
- for (int i = 0; i < 16; i++) {
- int finalI = i;
- int finalI2 = i;
- if (i >= 9) finalI2++;
- swInventory.setItem(finalI2 + 9, item(player, finalI).getItemStack(), clickType -> {
- power = finalI;
- click(player, backAction, deleteAction);
- });
+ public enum DaylightSettingsEnum implements LoaderSettingsEnum {
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
}
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean noop, boolean interact, boolean inverted) {
- SWItem swItem = menu(player, noop, interact, inverted);
- if (swItem.getItemStack().equals(menu(player, this.noop, this.interact, this.inverted).getItemStack())) {
- swItem.setEnchanted(true);
+ @Override
+ public SWItem menu(Player player, LoaderDaylightDetector parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_DAYLIGHT_DETECTOR", "LOADER_INTERACTION_NOOP", player));
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
- private SWItem item(Player player, int power) {
- SWItem swItem = new SWItem(power == 0 ? Material.GUNPOWDER : Material.REDSTONE, BauSystem.MESSAGE.parse("LOADER_SETTING_POWER", player, power));
- swItem.getItemStack().setAmount(power == 0 ? 1 : power);
- if (!this.noop && this.power == power) swItem.setEnchanted(true);
- return swItem;
- }
+ @Override
+ public void execute(Location location, DaylightDetector blockData, LoaderDaylightDetector parent, int power, long ticks, Consumer delay) {
+ }
+ },
- @Override
- public void playerInteract() {
- noop = false;
- interact = true;
- inverted = false;
- }
+ INTERACT {
+ @Override
+ public int getPos() {
+ return 3;
+ }
- @Override
- public void noop() {
- noop = true;
- interact = false;
- inverted = false;
+ @Override
+ public SWItem menu(Player player, LoaderDaylightDetector parent, int power, long ticks) {
+ return new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_DAYLIGHT_DETECTOR", "LOADER_INTERACTION_INTERACT", player));
+ }
+
+ @Override
+ public void execute(Location location, DaylightDetector blockData, LoaderDaylightDetector parent, int power, long ticks, Consumer delay) {
+ blockData.setInverted(!blockData.isInverted());
+ blockData.setPower(15 - blockData.getPower());
+ parent.update(blockData);
+ }
+ },
+
+ DAY_MODE {
+ @Override
+ public int getPos() {
+ return 5;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderDaylightDetector parent, int power, long ticks) {
+ return new SWItem(Material.DAYLIGHT_DETECTOR, translateItemName("LOADER_BUTTON_DAYLIGHT_DETECTOR", "LOADER_INTERACTION_UNPOWERED", player));
+ }
+
+ @Override
+ public void execute(Location location, DaylightDetector blockData, LoaderDaylightDetector parent, int power, long ticks, Consumer delay) {
+ if (blockData.isInverted()) {
+ blockData.setInverted(false);
+ blockData.setPower(15 - blockData.getPower());
+ parent.update(blockData);
+ }
+ }
+ },
+
+ NIGHT_MODE {
+ @Override
+ public int getPos() {
+ return 6;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderDaylightDetector parent, int power, long ticks) {
+ return new SWItem(Material.DAYLIGHT_DETECTOR, translateItemName("LOADER_BUTTON_DAYLIGHT_DETECTOR", "LOADER_INTERACTION_POWERED", player));
+ }
+
+ @Override
+ public void execute(Location location, DaylightDetector blockData, LoaderDaylightDetector parent, int power, long ticks, Consumer delay) {
+ if (!blockData.isInverted()) {
+ blockData.setInverted(true);
+ blockData.setPower(15 - blockData.getPower());
+ parent.update(blockData);
+ }
+ }
}
}
@@ -159,7 +120,7 @@ public class LoaderDaylightDetector extends LoaderInteractionElement {
+public class LoaderLectern extends LoaderInteractionElement {
public LoaderLectern(Location location) {
- super(location);
+ super(location, LecternSettingsEnum.NEXT_PAGE, LecternSettingsEnum.NOOP, LecternSettingsEnum.values());
}
- public class LecternSettings implements ElementSettings {
-
- private boolean noop = true;
- private LecternAction action = LecternAction.PAGE_NEXT;
- private int page = 0;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, noop, action, page);
- }
-
- private SWItem menu(Player player, boolean noop, LecternAction action, int page) {
- SWItem swItem;
- if (noop) {
- swItem = new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_NOOP", player));
- } else if (action == LecternAction.PAGE_PREV) {
- swItem = new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE_PREV", player));
- } else if (action == LecternAction.PAGE_NEXT) {
- swItem = new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE_NEXT", player));
- } else {
- swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, page));
- swItem.getItemStack().setAmount(page);
- }
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
-
- @Override
- public void execute(Consumer delay) {
- if (location.getBlock().getType() != Material.LECTERN) return;
- Lectern lectern = (Lectern) location.getBlock().getState();
- if (!((org.bukkit.block.data.type.Lectern) lectern.getBlockData()).hasBook()) return;
- int pages = ((BookMeta) lectern.getInventory().getItem(0).getItemMeta()).getPages().size();
- if (noop) {
- return;
- } else if (action == LecternAction.PAGE_PREV) {
- int page = lectern.getPage();
- if (page > 1) lectern.setPage(page - 1);
- } else if (action == LecternAction.PAGE_NEXT) {
- int page = lectern.getPage();
- if (page < pages) lectern.setPage(page + 1);
- } else if (action == LecternAction.PAGE_SET) {
- if (page <= pages) lectern.setPage(page);
- }
- lectern.update(false, true);
- }
-
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, 36, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = 27; i < 35; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(27, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(35, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
-
- swInventory.setItem(2, item(player, true, LecternAction.PAGE_SET, 0).getItemStack(), clickType -> {
- noop = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(5, item(player, false, LecternAction.PAGE_PREV, 0).getItemStack(), clickType -> {
- noop = false;
- action = LecternAction.PAGE_PREV;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(6, item(player, false, LecternAction.PAGE_NEXT, 0).getItemStack(), clickType -> {
- noop = false;
- action = LecternAction.PAGE_NEXT;
- click(player, backAction, deleteAction);
- });
-
- for (int i = 0; i < 15; i++) {
- int finalI = i;
- int finalI2 = i;
- if (i >= 9) finalI2++;
- if (i >= 12) finalI2++;
- swInventory.setItem(finalI2 + 9, item(player, false, LecternAction.PAGE_SET, finalI + 1).getItemStack(), clickType -> {
- noop = false;
- action = LecternAction.PAGE_SET;
- page = finalI + 1;
- click(player, backAction, deleteAction);
- });
+ public enum LecternSettingsEnum implements LoaderSettingsEnum {
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
}
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean noop, LecternAction action, int page) {
- SWItem swItem = menu(player, noop, action, page);
- if (swItem.getItemStack().equals(menu(player, this.noop, this.action, this.page).getItemStack())) {
- swItem.setEnchanted(true);
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_NOOP", player));
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
- @Override
- public void noop() {
- noop = true;
- }
- }
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ }
+ },
- public enum LecternAction {
- PAGE_NEXT,
- PAGE_PREV,
- PAGE_SET
+ PREVIOUS_PAGE {
+ @Override
+ public int getPos() {
+ return 5;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ return new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE_PREV", player));
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ if (lectern.getPage() > 0) {
+ lectern.setPage(lectern.getPage() - 1);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ NEXT_PAGE {
+ @Override
+ public int getPos() {
+ return 6;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ return new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE_NEXT", player));
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (lectern.getPage() < pages) {
+ lectern.setPage(lectern.getPage() + 1);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_1 {
+ @Override
+ public int getPos() {
+ return 9;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 1));
+ swItem.getItemStack().setAmount(1);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (1 <= pages) {
+ lectern.setPage(1);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_2 {
+ @Override
+ public int getPos() {
+ return 10;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 2));
+ swItem.getItemStack().setAmount(2);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (2 <= pages) {
+ lectern.setPage(2);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_3 {
+ @Override
+ public int getPos() {
+ return 11;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 3));
+ swItem.getItemStack().setAmount(3);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (3 <= pages) {
+ lectern.setPage(3);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_4 {
+ @Override
+ public int getPos() {
+ return 12;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 4));
+ swItem.getItemStack().setAmount(4);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (4 <= pages) {
+ lectern.setPage(4);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_5 {
+ @Override
+ public int getPos() {
+ return 13;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 5));
+ swItem.getItemStack().setAmount(5);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (5 <= pages) {
+ lectern.setPage(5);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_6 {
+ @Override
+ public int getPos() {
+ return 14;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 6));
+ swItem.getItemStack().setAmount(6);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (6 <= pages) {
+ lectern.setPage(6);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_7 {
+ @Override
+ public int getPos() {
+ return 15;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 7));
+ swItem.getItemStack().setAmount(7);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (7 <= pages) {
+ lectern.setPage(7);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_8 {
+ @Override
+ public int getPos() {
+ return 16;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 8));
+ swItem.getItemStack().setAmount(8);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (8 <= pages) {
+ lectern.setPage(8);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_9 {
+ @Override
+ public int getPos() {
+ return 17;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 9));
+ swItem.getItemStack().setAmount(9);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (9 <= pages) {
+ lectern.setPage(9);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_10 {
+ @Override
+ public int getPos() {
+ return 19;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 10));
+ swItem.getItemStack().setAmount(10);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (10 <= pages) {
+ lectern.setPage(10);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_11 {
+ @Override
+ public int getPos() {
+ return 20;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 11));
+ swItem.getItemStack().setAmount(11);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (11 <= pages) {
+ lectern.setPage(11);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_12 {
+ @Override
+ public int getPos() {
+ return 21;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 12));
+ swItem.getItemStack().setAmount(12);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (12 <= pages) {
+ lectern.setPage(12);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_13 {
+ @Override
+ public int getPos() {
+ return 23;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 13));
+ swItem.getItemStack().setAmount(13);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (13 <= pages) {
+ lectern.setPage(13);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_14 {
+ @Override
+ public int getPos() {
+ return 24;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 14));
+ swItem.getItemStack().setAmount(14);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (14 <= pages) {
+ lectern.setPage(14);
+ parent.update(blockData);
+ }
+ }
+ },
+
+ PAGE_15 {
+ @Override
+ public int getPos() {
+ return 25;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLectern parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.LECTERN, translateItemName("LOADER_BUTTON_LECTERN", "LOADER_INTERACTION_PAGE", player, 15));
+ swItem.getItemStack().setAmount(15);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, org.bukkit.block.data.type.Lectern blockData, LoaderLectern parent, int power, long ticks, Consumer delay) {
+ if (!blockData.hasBook()) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ ItemStack itemStack = lectern.getInventory().getItem(0);
+ if (itemStack == null) return;
+ int pages = ((BookMeta) itemStack.getItemMeta()).getPages().size();
+ if (15 <= pages) {
+ lectern.setPage(15);
+ parent.update(blockData);
+ }
+ }
+ }
}
@Override
@@ -153,7 +514,7 @@ public class LoaderLectern extends LoaderInteractionElement {
+public class LoaderLever extends LoaderInteractionElement {
public LoaderLever(Location location) {
- super(location);
+ super(location, LeverSettingsEnum.INTERACT, LeverSettingsEnum.NOOP, LeverSettingsEnum.values());
}
- public class LeverSettings implements ElementSettings {
+ public enum LeverSettingsEnum implements LoaderSettingsEnum {
- private boolean noop = false;
- private boolean interact = true;
- private boolean power = false;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, noop, interact, power);
- }
-
- private SWItem menu(Player player, boolean noop, boolean interact, boolean power) {
- SWItem swItem;
- if (noop) {
- swItem = new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_SWITCH", "LOADER_INTERACTION_NOOP", player));
- } else if (interact) {
- swItem = new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_SWITCH", "LOADER_INTERACTION_INTERACT", player));
- } else {
- swItem = new SWItem(Material.LEVER, translateItemName("LOADER_BUTTON_SWITCH", power ? "LOADER_INTERACTION_ACTIVE" : "LOADER_INTERACTION_INACTIVE", player));
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
}
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
- @Override
- public void execute(Consumer delay) {
- if (location.getBlock().getType() != Material.LEVER) return;
- if (noop) return;
-
- Switch lever = (Switch) location.getBlock().getBlockData();
- if (interact) {
- lever.setPowered(!lever.isPowered());
- } else {
- lever.setPowered(power);
+ @Override
+ public SWItem menu(Player player, LoaderLever parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_SWITCH", "LOADER_INTERACTION_NOOP", player));
}
- location.getBlock().setBlockData(lever, true);
- }
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, 18, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(17, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
-
- swInventory.setItem(2, item(player, true, false, false).getItemStack(), clickType -> {
- noop = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(3, item(player, false, true, false).getItemStack(), clickType -> {
- noop = false;
- interact = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(5, item(player, false, false, false).getItemStack(), clickType -> {
- noop = false;
- interact = false;
- power = false;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(6, item(player, false, false, true).getItemStack(), clickType -> {
- noop = false;
- interact = false;
- power = true;
- click(player, backAction, deleteAction);
- });
-
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean noop, boolean interact, boolean power) {
- SWItem swItem = menu(player, noop, interact, power);
- if (swItem.getItemStack().equals(menu(player, this.noop, this.interact, this.power).getItemStack())) {
- swItem.setEnchanted(true);
+ @Override
+ public void execute(Location location, Switch blockData, LoaderLever parent, int power, long ticks, Consumer delay) {
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
+ },
- @Override
- public void noop() {
- noop = true;
+ INTERACT {
+ @Override
+ public int getPos() {
+ return 3;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLever parent, int power, long ticks) {
+ return new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_SWITCH", "LOADER_INTERACTION_INTERACT", player));
+ }
+
+ @Override
+ public void execute(Location location, Switch blockData, LoaderLever parent, int power, long ticks, Consumer delay) {
+ blockData.setPowered(!blockData.isPowered());
+ parent.update(blockData);
+ }
+ },
+
+ POWER_OFF {
+ @Override
+ public int getPos() {
+ return 5;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLever parent, int power, long ticks) {
+ return new SWItem(Material.LEVER, translateItemName("LOADER_BUTTON_SWITCH", "LOADER_INTERACTION_INACTIVE", player));
+ }
+
+ @Override
+ public void execute(Location location, Switch blockData, LoaderLever parent, int power, long ticks, Consumer delay) {
+ blockData.setPowered(false);
+ parent.update(blockData);
+ }
+ },
+
+ POWER_ON {
+ @Override
+ public int getPos() {
+ return 6;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderLever parent, int power, long ticks) {
+ return new SWItem(Material.LEVER, translateItemName("LOADER_BUTTON_SWITCH", "LOADER_INTERACTION_ACTIVE", player));
+ }
+
+ @Override
+ public void execute(Location location, Switch blockData, LoaderLever parent, int power, long ticks, Consumer delay) {
+ blockData.setPowered(true);
+ }
}
}
@@ -130,7 +113,7 @@ public class LoaderLever extends LoaderInteractionElement {
+public class LoaderMovement extends LoaderInteractionElement {
private String name;
private Material material;
private boolean analogue;
public LoaderMovement(Location location, String name, Material material) {
- super(location);
+ super(location, MovementSettingsEnum.NO_WAIT_FOR, MovementSettingsEnum.NOOP, MovementSettingsEnum.values());
this.name = name;
this.material = material;
this.analogue = location.getBlock().getBlockData() instanceof AnaloguePowerable;
@@ -52,167 +47,108 @@ public class LoaderMovement extends LoaderInteractionElement {
- private boolean noop = false;
- private boolean waitFor = false;
- private int power = 15;
- private long ticks = 1;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, noop, waitFor);
- }
-
- private SWItem menu(Player player, boolean noop, boolean waitFor) {
- SWItem swItem;
- if (noop) {
- swItem = new SWItem(Material.STRUCTURE_VOID, translateItemName(name, "LOADER_INTERACTION_NOOP", player));
- } else if (waitFor) {
- swItem = new SWItem(material, translateItemName(name, "LOADER_INTERACTION_WAIT_FOR", player));
- swItem.getItemStack().setAmount((int) Math.min(ticks, 64));
- } else {
- swItem = new SWItem(material, translateItemName(name, "LOADER_INTERACTION_NO_WAIT_FOR", player));
- swItem.getItemStack().setAmount((int) Math.min(ticks, 64));
- swItem.setEnchanted(true);
- }
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
-
- @Override
- public void execute(Consumer delay) {
- if (!(material == Material.STRING && location.getBlock().getType() == Material.TRIPWIRE) && location.getBlock().getType() != material) return;
- if (noop) return;
-
- BlockData blockData = location.getBlock().getBlockData();
- if (blockData instanceof AnaloguePowerable) {
- AnaloguePowerable analoguePowerable = (AnaloguePowerable) location.getBlock().getBlockData();
- analoguePowerable.setPower(power);
- location.getBlock().setBlockData(analoguePowerable, true);
- update(analoguePowerable);
- } else if (blockData instanceof Powerable) {
- Powerable powerable = (Powerable) location.getBlock().getBlockData();
- if (ticks < 0) {
- powerable.setPowered(power > 0);
- } else {
- powerable.setPowered(true);
- }
- location.getBlock().setBlockData(powerable, true);
- update(powerable);
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
}
- if (ticks >= 0) {
- if (waitFor) {
- delay.accept(ticks);
+ @Override
+ public SWItem menu(Player player, LoaderMovement parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName(parent.name, "LOADER_INTERACTION_NOOP", player));
+ }
+
+ @Override
+ public void execute(Location location, BlockData blockData, LoaderMovement parent, int power, long ticks, Consumer delay) {
+ }
+ },
+
+ NO_WAIT_FOR {
+ @Override
+ public int getPos() {
+ return 5;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderMovement parent, int power, long ticks) {
+ SWItem swItem = new SWItem(parent.material, translateItemName(parent.name, "LOADER_INTERACTION_WAIT_FOR", player));
+ swItem.getItemStack().setAmount((int) Math.min(ticks, 64));
+ return swItem;
+ }
+
+ @Override
+ public boolean hasPower(LoaderMovement parent) {
+ return parent.analogue;
+ }
+
+ @Override
+ public boolean hasTicks(LoaderMovement parent) {
+ return true;
+ }
+
+ @Override
+ public void execute(Location location, BlockData blockData, LoaderMovement parent, int power, long ticks, Consumer delay) {
+ if (blockData instanceof AnaloguePowerable) {
+ AnaloguePowerable analoguePowerable = (AnaloguePowerable) location.getBlock().getBlockData();
+ analoguePowerable.setPower(power);
+ parent.update(analoguePowerable);
+ } else if (blockData instanceof Powerable) {
+ Powerable powerable = (Powerable) location.getBlock().getBlockData();
+ if (ticks < 0) {
+ powerable.setPowered(power > 0);
+ } else {
+ powerable.setPowered(true);
+ }
+ parent.update(powerable);
}
+
BauSystem.runTaskLater(BauSystem.getInstance(), () -> {
if (blockData instanceof AnaloguePowerable) {
AnaloguePowerable analoguePowerable = (AnaloguePowerable) blockData;
analoguePowerable.setPower(0);
- location.getBlock().setBlockData(analoguePowerable, true);
- update(analoguePowerable);
+ parent.update(analoguePowerable);
} else {
Powerable powerable = (Powerable) blockData;
powerable.setPowered(false);
- location.getBlock().setBlockData(powerable, true);
- update(powerable);
+ parent.update(powerable);
}
}, ticks);
}
- }
+ },
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, analogue ? 45 : 27, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = analogue ? 36 : 18; i < (analogue ? 44 : 26); i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(analogue ? 36 : 18, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(analogue ? 44 : 26, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
-
- swInventory.setItem(2, item(player, true, false).getItemStack(), clickType -> {
- noop = true;
- click(player, backAction, deleteAction);
- });
- if (ticks >= 0) {
- swInventory.setItem(5, item(player, false, false).getItemStack(), clickType -> {
- noop = false;
- waitFor = false;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(6, item(player, false, true).getItemStack(), clickType -> {
- noop = false;
- waitFor = true;
- click(player, backAction, deleteAction);
- });
+ WAIT_FOR {
+ @Override
+ public int getPos() {
+ return 6;
}
- swInventory.setItem(12, new SWItem(SWItem.getDye(1), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
- ticks -= clickType.isShiftClick() ? 5 : 1;
- if (ticks < 1) ticks = 1;
- swInventory.setItem(13, item(player));
- });
- swInventory.setItem(13, item(player).getItemStack(), clickType -> {
- SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_NAME", player), ticks + "");
- swAnvilInv.setCallback(s -> {
- try {
- ticks = Long.parseLong(s);
- if (ticks < 1) ticks = 1;
- } catch (NumberFormatException ignored) {
- }
- click(player, backAction, deleteAction);
- });
- swAnvilInv.open();
- });
- swInventory.setItem(14, new SWItem(SWItem.getDye(10), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
- ticks += clickType.isShiftClick() ? 5 : 1;
- swInventory.setItem(13, item(player));
- });
-
- if (analogue) {
- for (int i = 0; i < 16; i++) {
- int finalI = i;
- int finalI2 = i;
- if (i >= 9) finalI2++;
- swInventory.setItem(finalI2 + 18, item(player, finalI).getItemStack(), clickType -> {
- power = finalI;
- click(player, backAction, deleteAction);
- });
- }
+ @Override
+ public SWItem menu(Player player, LoaderMovement parent, int power, long ticks) {
+ SWItem swItem = new SWItem(parent.material, translateItemName(parent.name, "LOADER_INTERACTION_NO_WAIT_FOR", player));
+ swItem.getItemStack().setAmount((int) Math.min(ticks, 64));
+ return swItem;
}
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean noop, boolean waitFor) {
- SWItem swItem = menu(player, noop, waitFor);
- if (swItem.getItemStack().equals(menu(player, this.noop, this.waitFor).getItemStack())) {
- swItem.setEnchanted(true);
+ @Override
+ public boolean hasPower(LoaderMovement parent) {
+ return parent.analogue;
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
- private SWItem item(Player player, int power) {
- SWItem swItem = new SWItem(power == 0 ? Material.GUNPOWDER : Material.REDSTONE, BauSystem.MESSAGE.parse("LOADER_SETTING_POWER", player, power));
- swItem.getItemStack().setAmount(power == 0 ? 1 : power);
- if (!this.noop && this.power == power) swItem.setEnchanted(true);
- return swItem;
- }
+ @Override
+ public boolean hasTicks(LoaderMovement parent) {
+ return true;
+ }
- private SWItem item(Player player) {
- SWItem swItem = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS", player, ticks));
- swItem.getItemStack().setAmount((int) Math.min(ticks, 64));
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
-
- @Override
- public void noop() {
- noop = true;
- waitFor = false;
+ @Override
+ public void execute(Location location, BlockData blockData, LoaderMovement parent, int power, long ticks, Consumer delay) {
+ NO_WAIT_FOR.execute(location, blockData, parent, power, ticks, delay);
+ delay.accept(ticks);
+ }
}
}
@@ -222,7 +158,8 @@ public class LoaderMovement extends LoaderInteractionElement {
+public class LoaderNoteBlock extends LoaderInteractionElement {
public LoaderNoteBlock(Location location) {
- super(location);
+ super(location, NoteBlockSettingsEnum.INTERACT, NoteBlockSettingsEnum.NOOP, NoteBlockSettingsEnum.values());
}
- public class NoteBlockSettings implements ElementSettings {
+ public enum NoteBlockSettingsEnum implements LoaderSettingsEnum {
- private boolean interact = true;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, interact);
- }
-
- private SWItem menu(Player player, boolean interact) {
- SWItem swItem;
- if (interact) {
- swItem = new SWItem(Material.NOTE_BLOCK, translateItemName("LOADER_BUTTON_NOTEBLOCK", "LOADER_INTERACTION_INTERACT", player));
- } else {
- swItem = new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_NOTEBLOCK", "LOADER_INTERACTION_NOOP", player));
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
}
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
- @Override
- public void execute(Consumer delay) {
- if (location.getBlock().getType() != Material.NOTE_BLOCK) return;
- NoteBlock noteBlock = (NoteBlock) location.getBlock().getBlockData();
- if (interact) {
- if (noteBlock.getInstrument() == Instrument.BANJO) noteBlock.setInstrument(Instrument.BIT);
- else noteBlock.setInstrument(Instrument.BANJO);
- } else {
- return;
+ @Override
+ public SWItem menu(Player player, LoaderNoteBlock parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_NOTEBLOCK", "LOADER_INTERACTION_NOOP", player));
}
- location.getBlock().setBlockData(noteBlock);
- }
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, 18, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(17, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
+ @Override
+ public void execute(Location location, NoteBlock blockData, LoaderNoteBlock parent, int power, long ticks, Consumer delay) {
- swInventory.setItem(2, item(player, false).getItemStack(), clickType -> {
- interact = false;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(3, item(player, true).getItemStack(), clickType -> {
- interact = true;
- click(player, backAction, deleteAction);
- });
-
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean interact) {
- SWItem swItem = menu(player, interact);
- if (swItem.getItemStack().equals(menu(player, this.interact).getItemStack())) {
- swItem.setEnchanted(true);
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
+ },
- @Override
- public void noop() {
- interact = false;
+ INTERACT {
+ @Override
+ public int getPos() {
+ return 3;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderNoteBlock parent, int power, long ticks) {
+ return new SWItem(Material.NOTE_BLOCK, translateItemName("LOADER_BUTTON_NOTEBLOCK", "LOADER_INTERACTION_INTERACT", player));
+ }
+
+ @Override
+ public void execute(Location location, NoteBlock blockData, LoaderNoteBlock parent, int power, long ticks, Consumer delay) {
+ if (blockData.getInstrument() == Instrument.BANJO) blockData.setInstrument(Instrument.BIT);
+ else blockData.setInstrument(Instrument.BANJO);
+ parent.update(blockData);
+ }
}
}
@@ -113,7 +81,7 @@ public class LoaderNoteBlock extends LoaderInteractionElement {
+public class LoaderOpenable extends LoaderInteractionElement {
private String name;
private Material material;
public LoaderOpenable(Location location, String name, Material material) {
- super(location);
+ super(location, OpenableSettingsEnum.INTERACT, OpenableSettingsEnum.NOOP, OpenableSettingsEnum.values());
this.name = name;
this.material = material;
}
- public class TrapdoorSettings implements ElementSettings {
+ public enum OpenableSettingsEnum implements LoaderSettingsEnum {
- private boolean noop = false;
- private boolean interact = true;
- private boolean open = false;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, noop, interact, open);
- }
-
- private SWItem menu(Player player, boolean noop, boolean interact, boolean powered) {
- SWItem swItem;
- if (noop) {
- swItem = new SWItem(Material.STRUCTURE_VOID, translateItemName(name, "LOADER_INTERACTION_NOOP", player));
- } else if (interact) {
- swItem = new SWItem(Material.STICK, translateItemName(name, "LOADER_INTERACTION_INTERACT", player));
- } else {
- swItem = new SWItem(material, translateItemName(name, open ? "LOADER_INTERACTION_OPEN" : "LOADER_INTERACTION_CLOSED", player));
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
}
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
- @Override
- public void execute(Consumer delay) {
- if (location.getBlock().getType() != material) return;
- Openable openable = (Openable) location.getBlock().getBlockData();
- if (noop) {
- return;
- } else if (interact) {
- openable.setOpen(!openable.isOpen());
- } else {
- openable.setOpen(open);
+ @Override
+ public SWItem menu(Player player, LoaderOpenable parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName(parent.name, "LOADER_INTERACTION_NOOP", player));
}
- location.getBlock().setBlockData(openable);
- }
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, 18, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(17, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
-
- swInventory.setItem(2, item(player, true, false, false).getItemStack(), clickType -> {
- noop = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(3, item(player, false, true, false).getItemStack(), clickType -> {
- noop = false;
- interact = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(5, item(player, false, false, false).getItemStack(), clickType -> {
- noop = false;
- interact = false;
- open = false;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(6, item(player, false, false, true).getItemStack(), clickType -> {
- noop = false;
- interact = false;
- open = true;
- click(player, backAction, deleteAction);
- });
-
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean noop, boolean interact, boolean open) {
- SWItem swItem = menu(player, noop, interact, open);
- if (swItem.getItemStack().equals(menu(player, this.noop, this.interact, this.open).getItemStack())) {
- swItem.setEnchanted(true);
+ @Override
+ public void execute(Location location, Openable blockData, LoaderOpenable parent, int power, long ticks, Consumer delay) {
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
+ },
- @Override
- public void noop() {
- noop = true;
+ INTERACT {
+ @Override
+ public int getPos() {
+ return 3;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderOpenable parent, int power, long ticks) {
+ return new SWItem(Material.STICK, translateItemName(parent.name, "LOADER_INTERACTION_INTERACT", player));
+ }
+
+ @Override
+ public void execute(Location location, Openable blockData, LoaderOpenable parent, int power, long ticks, Consumer delay) {
+ blockData.setOpen(!blockData.isOpen());
+ parent.update(blockData);
+ }
+ },
+
+ CLOSED {
+ @Override
+ public int getPos() {
+ return 5;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderOpenable parent, int power, long ticks) {
+ return new SWItem(parent.material, translateItemName(parent.name, "LOADER_INTERACTION_CLOSED", player));
+ }
+
+ @Override
+ public void execute(Location location, Openable blockData, LoaderOpenable parent, int power, long ticks, Consumer delay) {
+ blockData.setOpen(false);
+ parent.update(blockData);
+ }
+ },
+
+ OPEN {
+ @Override
+ public int getPos() {
+ return 6;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderOpenable parent, int power, long ticks) {
+ return new SWItem(parent.material, translateItemName(parent.name, "LOADER_INTERACTION_OPEN", player));
+ }
+
+ @Override
+ public void execute(Location location, Openable blockData, LoaderOpenable parent, int power, long ticks, Consumer delay) {
+ blockData.setOpen(true);
+ parent.update(blockData);
+ }
}
}
@@ -135,7 +119,7 @@ public class LoaderOpenable extends LoaderInteractionElement {
+public class LoaderRepeater extends LoaderInteractionElement {
public LoaderRepeater(Location location) {
- super(location);
+ super(location, RepeaterSettingsEnum.INTERACT, RepeaterSettingsEnum.NOOP, RepeaterSettingsEnum.values());
}
- public class RepeaterSettings implements ElementSettings {
+ public enum RepeaterSettingsEnum implements LoaderSettingsEnum {
- private boolean interact = false;
- private int delay = 1;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, interact, delay);
- }
-
- private SWItem menu(Player player, boolean interact, int delay) {
- SWItem swItem;
- if (interact) {
- swItem = new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_REPEATER", "LOADER_INTERACTION_INTERACT", player));
- } else if (delay == 0) {
- swItem = new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_REPEATER", "LOADER_INTERACTION_NOOP", player));
- } else {
- swItem = new SWItem(Material.REPEATER, BauSystem.MESSAGE.parse("LOADER_SETTING_REPEATER", player, delay));
- swItem.getItemStack().setAmount(delay);
+ NOOP {
+ @Override
+ public int getPos() {
+ return 1;
}
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
- @Override
- public void execute(Consumer __) {
- if (location.getBlock().getType() != Material.REPEATER) return;
- Repeater repeater = (Repeater) location.getBlock().getBlockData();
- if (interact) {
- int delay = repeater.getDelay();
- delay++;
- if (delay > 4) delay = 1;
- repeater.setDelay(delay);
- } else if (delay == 0) {
- return;
- } else {
- repeater.setDelay(delay);
+ @Override
+ public SWItem menu(Player player, LoaderRepeater parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_REPEATER", "LOADER_INTERACTION_NOOP", player));
}
- location.getBlock().setBlockData(repeater, true);
- }
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, 18, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(17, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
+ @Override
+ public void execute(Location location, Repeater blockData, LoaderRepeater parent, int power, long ticks, Consumer delay) {
- swInventory.setItem(1, item(player, false, 0).getItemStack(), clickType -> {
- interact = false;
- delay = 0;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(2, item(player, true, -1).getItemStack(), clickType -> {
- interact = true;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(4, item(player, false, 1).getItemStack(), clickType -> {
- interact = false;
- delay = 1;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(5, item(player, false, 2).getItemStack(), clickType -> {
- interact = false;
- delay = 2;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(6, item(player, false, 3).getItemStack(), clickType -> {
- interact = false;
- delay = 3;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(7, item(player, false, 4).getItemStack(), clickType -> {
- interact = false;
- delay = 4;
- click(player, backAction, deleteAction);
- });
-
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean interact, int delay) {
- SWItem swItem = menu(player, interact, delay);
- if (swItem.getItemStack().equals(menu(player, this.interact, this.delay).getItemStack())) {
- swItem.setEnchanted(true);
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
+ },
- @Override
- public void playerInteract() {
- interact = true;
- delay = 0;
- }
+ INTERACT {
+ @Override
+ public int getPos() {
+ return 2;
+ }
- @Override
- public void noop() {
- interact = false;
- delay = 0;
+ @Override
+ public SWItem menu(Player player, LoaderRepeater parent, int power, long ticks) {
+ return new SWItem(Material.STICK, translateItemName("LOADER_BUTTON_REPEATER", "LOADER_INTERACTION_INTERACT", player));
+ }
+
+ @Override
+ public void execute(Location location, Repeater blockData, LoaderRepeater parent, int power, long ticks, Consumer delay) {
+ int repeaterDelay = blockData.getDelay();
+ repeaterDelay++;
+ if (repeaterDelay > 4) repeaterDelay = 1;
+ blockData.setDelay(repeaterDelay);
+ parent.update(blockData);
+ }
+ },
+
+ DELAY_1 {
+ @Override
+ public int getPos() {
+ return 4;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderRepeater parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.REPEATER, BauSystem.MESSAGE.parse("LOADER_SETTING_REPEATER", player, 1));
+ swItem.getItemStack().setAmount(1);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, Repeater blockData, LoaderRepeater parent, int power, long ticks, Consumer delay) {
+ blockData.setDelay(1);
+ parent.update(blockData);
+ }
+ },
+
+ DELAY_2 {
+ @Override
+ public int getPos() {
+ return 5;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderRepeater parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.REPEATER, BauSystem.MESSAGE.parse("LOADER_SETTING_REPEATER", player, 2));
+ swItem.getItemStack().setAmount(2);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, Repeater blockData, LoaderRepeater parent, int power, long ticks, Consumer delay) {
+ blockData.setDelay(2);
+ parent.update(blockData);
+ }
+ },
+
+ DELAY_3 {
+ @Override
+ public int getPos() {
+ return 6;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderRepeater parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.REPEATER, BauSystem.MESSAGE.parse("LOADER_SETTING_REPEATER", player, 3));
+ swItem.getItemStack().setAmount(3);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, Repeater blockData, LoaderRepeater parent, int power, long ticks, Consumer delay) {
+ blockData.setDelay(3);
+ parent.update(blockData);
+ }
+ },
+
+ DELAY_4 {
+ @Override
+ public int getPos() {
+ return 7;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderRepeater parent, int power, long ticks) {
+ SWItem swItem = new SWItem(Material.REPEATER, BauSystem.MESSAGE.parse("LOADER_SETTING_REPEATER", player, 4));
+ swItem.getItemStack().setAmount(4);
+ return swItem;
+ }
+
+ @Override
+ public void execute(Location location, Repeater blockData, LoaderRepeater parent, int power, long ticks, Consumer delay) {
+ blockData.setDelay(4);
+ parent.update(blockData);
+ }
}
}
@@ -148,7 +163,7 @@ public class LoaderRepeater extends LoaderInteractionElement {
public LoaderTNT(Location location) {
- this.location = location;
+ super(location, TNTSettingsEnum.PLACE, TNTSettingsEnum.NOOP, TNTSettingsEnum.values());
+ }
+
+ public enum TNTSettingsEnum implements LoaderSettingsEnum {
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderTNT parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName("LOADER_BUTTON_TNT", "LOADER_INTERACTION_NOOP", player));
+ }
+
+ @Override
+ public void execute(Location location, BlockData blockData, LoaderTNT parent, int power, long ticks, Consumer delay) {
+ }
+ },
+
+ PLACE {
+ @Override
+ public int getPos() {
+ return 3;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderTNT parent, int power, long ticks) {
+ return new SWItem(Material.TNT, translateItemName("LOADER_BUTTON_TNT", "LOADER_INTERACTION_PLACE", player));
+ }
+
+ @Override
+ public void execute(Location location, BlockData blockData, LoaderTNT parent, int power, long ticks, Consumer delay) {
+ location.getBlock().setType(Material.TNT);
+ }
+ }
}
@Override
@@ -54,10 +88,11 @@ public class LoaderTNT implements LoaderElement {
return;
}
- block.setType(Material.TNT, true);
+ super.execute(delay);
}
@Override
- public void click(Player player, Runnable backAction) {
+ public boolean checkBlockInWorld() {
+ return true;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/impl/LoaderTicks.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/impl/LoaderTicks.java
index 2beafc06..32e65f61 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/impl/LoaderTicks.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/elements/impl/LoaderTicks.java
@@ -20,120 +20,87 @@
package de.steamwar.bausystem.features.loader.elements.impl;
import de.steamwar.bausystem.BauSystem;
-import de.steamwar.bausystem.features.loader.elements.ElementSettings;
import de.steamwar.bausystem.features.loader.elements.LoaderInteractionElement;
-import de.steamwar.inventory.SWInventory;
+import de.steamwar.bausystem.features.loader.elements.LoaderSettingsEnum;
import de.steamwar.inventory.SWItem;
-import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.data.Powerable;
import org.bukkit.entity.Player;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.function.Consumer;
-public class LoaderTicks extends LoaderInteractionElement {
+public class LoaderTicks extends LoaderInteractionElement {
private String name;
private Material material;
private int ticks;
public LoaderTicks(Location location, String name, Material material, int ticks) {
- super(location);
+ super(location, TicksSettingsEnum.NO_WAIT_FOR, TicksSettingsEnum.NOOP, TicksSettingsEnum.values());
this.name = name;
this.material = material;
this.ticks = ticks;
}
- public class TicksSettings implements ElementSettings {
+ public enum TicksSettingsEnum implements LoaderSettingsEnum {
- private boolean noop = false;
- private boolean waitFor = false;
-
- @Override
- public SWItem menu(Player player) {
- return menu(player, noop, waitFor);
- }
-
- private SWItem menu(Player player, boolean noop, boolean waitFor) {
- SWItem swItem;
- if (noop) {
- swItem = new SWItem(Material.STRUCTURE_VOID, translateItemName(name, "LOADER_INTERACTION_NOOP", player));
- } else if (waitFor) {
- swItem = new SWItem(material, translateItemName(name, "LOADER_INTERACTION_WAIT_FOR", player, ticks));
- } else {
- swItem = new SWItem(material, translateItemName(name, "LOADER_INTERACTION_NO_WAIT_FOR", player, ticks));
- swItem.setEnchanted(true);
- }
- swItem.setLore(Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)));
- return swItem;
- }
-
- @Override
- public void execute(Consumer delay) {
- if (location.getBlock().getType() != material) {
- return;
- }
- if (noop) {
- return;
+ NOOP {
+ @Override
+ public int getPos() {
+ return 2;
}
- Powerable powerable = (Powerable) location.getBlock().getBlockData();
- powerable.setPowered(true);
- location.getBlock().setBlockData(powerable, true);
- update(powerable);
-
- if (waitFor) {
- delay.accept((long) ticks);
- }
- BauSystem.runTaskLater(BauSystem.getInstance(), () -> {
- powerable.setPowered(false);
- location.getBlock().setBlockData(powerable, true);
- update(powerable);
- }, ticks);
- }
-
- @Override
- public void click(Player player, Runnable backAction, Runnable deleteAction) {
- SWInventory swInventory = new SWInventory(player, 18, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
- for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
- swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).getItemStack(), clickType -> backAction.run());
- swInventory.setItem(17, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_DELETE", player)).getItemStack(), clickType -> deleteAction.run());
-
- swInventory.setItem(2, item(player, true, false).getItemStack(), clickType -> {
- noop = true;
- click(player, backAction, deleteAction);
- });
- if (ticks >= 0) {
- swInventory.setItem(5, item(player, false, false).getItemStack(), clickType -> {
- noop = false;
- waitFor = false;
- click(player, backAction, deleteAction);
- });
- swInventory.setItem(6, item(player, false, true).getItemStack(), clickType -> {
- noop = false;
- waitFor = true;
- click(player, backAction, deleteAction);
- });
+ @Override
+ public SWItem menu(Player player, LoaderTicks parent, int power, long ticks) {
+ return new SWItem(Material.STRUCTURE_VOID, translateItemName(parent.name, "LOADER_INTERACTION_NOOP", player));
}
- swInventory.open();
- }
-
- private SWItem item(Player player, boolean noop, boolean waitFor) {
- SWItem swItem = menu(player, noop, waitFor);
- if (swItem.getItemStack().equals(menu(player, this.noop, this.waitFor).getItemStack())) {
- swItem.setEnchanted(true);
+ @Override
+ public void execute(Location location, Powerable blockData, LoaderTicks parent, int power, long ticks, Consumer delay) {
}
- swItem.setLore(Collections.emptyList());
- return swItem;
- }
+ },
- @Override
- public void noop() {
- noop = true;
+ NO_WAIT_FOR {
+ @Override
+ public int getPos() {
+ return 5;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderTicks parent, int power, long ticks) {
+ return new SWItem(parent.material, translateItemName(parent.name, "LOADER_INTERACTION_NO_WAIT_FOR", player, ticks));
+ }
+
+ @Override
+ public void execute(Location location, Powerable blockData, LoaderTicks parent, int power, long ticks, Consumer delay) {
+ Powerable powerable = (Powerable) location.getBlock().getBlockData();
+ powerable.setPowered(true);
+ parent.update(powerable);
+
+ BauSystem.runTaskLater(BauSystem.getInstance(), () -> {
+ powerable.setPowered(false);
+ parent.update(powerable);
+ }, parent.ticks);
+ }
+ },
+
+ WAIT_FOR {
+ @Override
+ public int getPos() {
+ return 6;
+ }
+
+ @Override
+ public SWItem menu(Player player, LoaderTicks parent, int power, long ticks) {
+ return new SWItem(parent.material, translateItemName(parent.name, "LOADER_INTERACTION_WAIT_FOR", player, ticks));
+ }
+
+ @Override
+ public void execute(Location location, Powerable blockData, LoaderTicks parent, int power, long ticks, Consumer delay) {
+ NO_WAIT_FOR.execute(location, blockData, parent, power, ticks, delay);
+ delay.accept((long) parent.ticks);
+ }
}
}
@@ -143,7 +110,7 @@ public class LoaderTicks extends LoaderInteractionElement.
- */
-
-package de.steamwar.bausystem.features.redstonetester;
-
-import de.steamwar.bausystem.BauSystem;
-import de.steamwar.bausystem.Permission;
-import de.steamwar.bausystem.linkage.specific.BauGuiItem;
-import de.steamwar.inventory.SWItem;
-import de.steamwar.linkage.Linked;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
-import org.bukkit.inventory.ItemStack;
-
-import java.util.Arrays;
-
-@Linked
-public class RedstoneTesterGuiItem extends BauGuiItem {
-
- public RedstoneTesterGuiItem() {
- super(23);
- }
-
- @Override
- public ItemStack getItem(Player player) {
- return new SWItem(Material.REPEATER,
- BauSystem.MESSAGE.parse("RT_ITEM_NAME", player),
- Arrays.asList(BauSystem.MESSAGE.parse("RT_ITEM_LORE_1", player),
- BauSystem.MESSAGE.parse("RT_ITEM_LORE_2", player),
- BauSystem.MESSAGE.parse("RT_ITEM_LORE_3", player))
- , false, null).getItemStack();
- }
-
- @Override
- public boolean click(ClickType click, Player p) {
- p.closeInventory();
- p.performCommand("redstonetester");
- return false;
- }
-
- @Override
- public Permission permission() {
- return Permission.MEMBER;
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RedstonetesterCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RedstonetesterCommand.java
deleted file mode 100644
index 0e1c7b63..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RedstonetesterCommand.java
+++ /dev/null
@@ -1,40 +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.redstonetester;
-
-import de.steamwar.bausystem.BauSystem;
-import de.steamwar.bausystem.SWUtils;
-import de.steamwar.command.SWCommand;
-import de.steamwar.linkage.Linked;
-import org.bukkit.entity.Player;
-
-@Linked
-public class RedstonetesterCommand extends SWCommand {
-
- public RedstonetesterCommand() {
- super("redstonetester", "rt");
- }
-
- @Register(description = "RT_HELP")
- public void genericCommand(Player p) {
- BauSystem.MESSAGE.send("RT_GIVEN", p);
- SWUtils.giveItemToPlayer(p, RedstonetesterUtils.getWand(p));
- }
-}
\ No newline at end of file
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RedstonetesterUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RedstonetesterUtils.java
deleted file mode 100644
index a70b143b..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RedstonetesterUtils.java
+++ /dev/null
@@ -1,108 +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.redstonetester;
-
-import de.steamwar.bausystem.BauSystem;
-import de.steamwar.bausystem.features.tpslimit.TPSUtils;
-import de.steamwar.bausystem.utils.ItemUtils;
-import de.steamwar.inventory.SWItem;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.experimental.UtilityClass;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.block.data.Powerable;
-import org.bukkit.block.data.type.Piston;
-import org.bukkit.block.data.type.RedstoneWire;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-@UtilityClass
-public class RedstonetesterUtils {
-
- public static ItemStack getWand(Player player) {
- ItemStack i = new SWItem(Material.BLAZE_ROD,
- BauSystem.MESSAGE.parse("RT_ITEM_NAME", player),
- Arrays.asList(BauSystem.MESSAGE.parse("RT_ITEM_LORE_1", player),
- BauSystem.MESSAGE.parse("RT_ITEM_LORE_2", player),
- BauSystem.MESSAGE.parse("RT_ITEM_LORE_3", player)),
- false, null).getItemStack();
- ItemUtils.setItem(i, "redstonetester");
- return i;
- }
-
- @Getter
- private final Map playerMap = new HashMap<>();
-
- public void sendLocation(Player player, String prefix, Location location) {
- BauSystem.MESSAGE.send("RT_LOC", player, location.getBlockX(), location.getBlockY(), location.getBlockZ());
- }
-
- @SuppressWarnings("BooleanMethodIsAlwaysInverted")
- public boolean validBlock(Player player, BlockData block) {
- if (block instanceof Powerable) return true;
- if (block instanceof Piston) return true;
- if (block instanceof RedstoneWire) return true;
- BauSystem.MESSAGE.send("RT_INVALID_LOC", player);
- return false;
- }
-
- @Getter
- @Setter
- public static class RedstoneTester {
-
- private final Player player;
- private Location loc1 = null;
- private Location loc2 = null;
-
- private long lastTick = 0;
- private Long tick = null;
-
- public RedstoneTester(Player player) {
- this.player = player;
- }
-
- public void activate(Location location) {
- if (loc1 == null || loc2 == null) {
- tick = null;
- return;
- }
- if (TPSUtils.currentRealTick.get() - lastTick > 100) {
- tick = null;
- }
- if (loc1.equals(location)) {
- lastTick = TPSUtils.currentRealTick.get();
- if (tick == null) {
- tick = TPSUtils.currentRealTick.get();
- }
- return;
- }
- if (tick != null && loc2.equals(location)) {
- BauSystem.MESSAGE.send("RT_RESULT", player, (TPSUtils.currentRealTick.get() - tick), ((TPSUtils.currentRealTick.get() - tick) / 2.0));
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RestonetesterListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RestonetesterListener.java
deleted file mode 100644
index 2ab015b9..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/redstonetester/RestonetesterListener.java
+++ /dev/null
@@ -1,94 +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.redstonetester;
-
-import de.steamwar.bausystem.BauSystem;
-import de.steamwar.bausystem.utils.ItemUtils;
-import de.steamwar.linkage.Linked;
-import org.bukkit.block.Block;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.block.BlockDispenseEvent;
-import org.bukkit.event.block.BlockPistonExtendEvent;
-import org.bukkit.event.block.BlockPistonRetractEvent;
-import org.bukkit.event.block.BlockRedstoneEvent;
-import org.bukkit.event.player.PlayerInteractEvent;
-import org.bukkit.event.player.PlayerQuitEvent;
-
-import java.util.Objects;
-
-@Linked
-public class RestonetesterListener implements Listener {
-
- @EventHandler
- public void onPlayerInteract(PlayerInteractEvent event) {
- if (!ItemUtils.isItem(event.getItem(), "redstonetester")) return;
- Player player = event.getPlayer();
- Block block = event.getClickedBlock();
- event.setCancelled(true);
-
- switch (event.getAction()) {
- case RIGHT_CLICK_AIR:
- if (player.isSneaking()) {
- RedstonetesterUtils.getPlayerMap().remove(event.getPlayer());
- BauSystem.MESSAGE.send("RT_ACTIVATE", player);
- }
- break;
- case LEFT_CLICK_BLOCK:
- if (!RedstonetesterUtils.validBlock(event.getPlayer(), Objects.requireNonNull(block).getBlockData())) return;
- RedstonetesterUtils.getPlayerMap().computeIfAbsent(event.getPlayer(), RedstonetesterUtils.RedstoneTester::new).setLoc1(block.getLocation());
- RedstonetesterUtils.sendLocation(event.getPlayer(), "POS1", block.getLocation());
- break;
- case RIGHT_CLICK_BLOCK:
- if (!RedstonetesterUtils.validBlock(event.getPlayer(), Objects.requireNonNull(block).getBlockData())) return;
- RedstonetesterUtils.getPlayerMap().computeIfAbsent(event.getPlayer(), RedstonetesterUtils.RedstoneTester::new).setLoc2(block.getLocation());
- RedstonetesterUtils.sendLocation(event.getPlayer(), "POS2", block.getLocation());
- break;
- default:
- break;
- }
- }
-
- @EventHandler
- public void onPlayerQuit(PlayerQuitEvent event) {
- RedstonetesterUtils.getPlayerMap().remove(event.getPlayer());
- }
-
- @EventHandler
- public void onPistonExtend(BlockPistonExtendEvent e) {
- RedstonetesterUtils.getPlayerMap().forEach((player, redstoneTester) -> redstoneTester.activate(e.getBlock().getLocation()));
- }
-
- @EventHandler
- public void onPistonRetract(BlockPistonRetractEvent e) {
- RedstonetesterUtils.getPlayerMap().forEach((player, redstoneTester) -> redstoneTester.activate(e.getBlock().getLocation()));
- }
-
- @EventHandler
- public void onRedstoneEvent(BlockRedstoneEvent e) {
- RedstonetesterUtils.getPlayerMap().forEach((player, redstoneTester) -> redstoneTester.activate(e.getBlock().getLocation()));
- }
-
- @EventHandler
- public void onBlockDispense(BlockDispenseEvent e) {
- RedstonetesterUtils.getPlayerMap().forEach((player, redstoneTester) -> redstoneTester.activate(e.getBlock().getLocation()));
- }
-}
\ No newline at end of file
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 f8d6fd40..af9f3837 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java
@@ -74,6 +74,9 @@ public class TNTCommand extends SWCommand {
case ONLY_TB:
requestedMessage = getTestblockEnableMessage();
break;
+ case ONLY_BUILD:
+ requestedMessage = getBuildEnableMessage();
+ break;
}
tntToggle(region, tntMode, requestedMessage);
}
@@ -89,6 +92,7 @@ public class TNTCommand extends SWCommand {
Map tntModeMap = new HashMap<>(tntModeMapReduced);
tntModeMap.put("testblock", TNTMode.ONLY_TB);
tntModeMap.put("tb", TNTMode.ONLY_TB);
+ tntModeMap.put("build", TNTMode.ONLY_BUILD);
return new TypeMapper() {
@Override
@@ -125,6 +129,10 @@ public class TNTCommand extends SWCommand {
return "REGION_TNT_TB";
}
+ private String getBuildEnableMessage() {
+ return "REGION_TNT_BUILD";
+ }
+
private void tntToggle(Region region, TNTMode requestedMode, String requestedMessage) {
if (requestedMode != null && region.hasType(RegionType.TESTBLOCK) && region.hasType(RegionType.BUILD)) {
region.set(Flag.TNT, requestedMode);
@@ -134,6 +142,7 @@ public class TNTCommand extends SWCommand {
switch (region.getPlain(Flag.TNT, TNTMode.class)) {
case ALLOW:
case ONLY_TB:
+ case ONLY_BUILD:
region.set(Flag.TNT, TNTMode.DENY);
RegionUtils.actionBar(region, getDisableMessage());
break;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTListener.java
index d65a8750..a8d34de5 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTListener.java
@@ -28,12 +28,8 @@ import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.linkage.Linked;
-import de.steamwar.linkage.LinkedInstance;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
-import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -47,22 +43,29 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class TNTListener implements Listener, ScoreboardElement {
private void explode(List blockList) {
- AtomicBoolean inBuild = new AtomicBoolean();
blockList.removeIf(block -> {
Region region = Region.getRegion(block.getLocation());
TNTMode value = region.getPlain(Flag.TNT);
if (value == TNTMode.ALLOW) {
return false;
- }
- if (region.hasType(RegionType.BUILD) && region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.NORMAL)) {
- RegionUtils.actionBar(region, "REGION_TNT_BUILD");
- inBuild.set(true);
- return true;
- }
- if (region.hasType(RegionType.BUILD) && region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION)) {
- RegionUtils.actionBar(region, "REGION_TNT_BUILD");
- inBuild.set(true);
- return true;
+ } else if (value == TNTMode.ONLY_TB) {
+ if (region.hasType(RegionType.BUILD) && region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.NORMAL)) {
+ RegionUtils.actionBar(region, "REGION_TNT_BUILD_DESTROY");
+ return true;
+ }
+ if (region.hasType(RegionType.BUILD) && region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION)) {
+ RegionUtils.actionBar(region, "REGION_TNT_BUILD_DESTROY");
+ return true;
+ }
+ } else if (value == TNTMode.ONLY_BUILD) {
+ if (region.hasType(RegionType.TESTBLOCK) && region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.NORMAL)) {
+ RegionUtils.actionBar(region, "REGION_TNT_TB_DESTROY");
+ return true;
+ }
+ if (region.hasType(RegionType.TESTBLOCK) && region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) {
+ RegionUtils.actionBar(region, "REGION_TNT_TB_DESTROY");
+ return true;
+ }
}
return value == TNTMode.DENY;
});
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 132e7cac..3572cf71 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java
@@ -159,7 +159,7 @@ public class TestblockCommand extends SWCommand {
@ClassValidator(value = Player.class, local = true)
public TypeValidator validator() {
- return (commandSender, player, messageSender) -> !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "REGION_TB_NO_PERMS");
+ return (commandSender, player, messageSender) -> !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "REGION_TB_NO_PERMS");
}
private Region regionCheck(Player player) {
@@ -192,44 +192,12 @@ public class TestblockCommand extends SWCommand {
};
}
- public static class TestblockParameter {
- private boolean water = false;
- private boolean tnt = false;
- private boolean extension = false;
- private boolean onlyColor = false;
-
- private boolean ignoreAir = false;
-
- public void enableWater() {
- this.water = true;
- }
-
- public void enableTNT() {
- this.tnt = true;
- }
-
- public void enableExtension() {
- this.extension = true;
- }
-
- public void enableOnlyColor() {
- this.onlyColor = true;
- }
-
- public void enableIgnoreAir() {
- this.ignoreAir = true;
- }
- }
-
public enum TestblockParameterType {
- EXTENSION(TestblockParameter::enableExtension, Arrays.asList("-e", "-extension")),
- TNT(TestblockParameter::enableTNT, Arrays.asList("-t", "-tnt")),
- WATER(TestblockParameter::enableWater, Arrays.asList("-w", "-water")),
- IGNORE_AIR(TestblockParameter::enableIgnoreAir, Arrays.asList("-ig", "-ignore_air")),
- ONLY_COLOR(TestblockParameter::enableOnlyColor, Arrays.asList("-o", "-color", "-only_color"));
-
- @Getter
- private final Consumer testblockParameterConsumer;
+ EXTENSION(Arrays.asList("-e", "-extension")),
+ TNT(Arrays.asList("-t", "-tnt")),
+ WATER(Arrays.asList("-w", "-water")),
+ IGNORE_AIR(Arrays.asList("-ig", "-ignore_air")),
+ ONLY_COLOR(Arrays.asList("-o", "-color", "-only_color"));
@Getter
private List tabCompletes;
@@ -238,8 +206,7 @@ public class TestblockCommand extends SWCommand {
private final Supplier removed;
private AtomicReference cached = new AtomicReference<>();
- TestblockParameterType(Consumer testblockParameterConsumer, List tabCompletes, String... removed) {
- this.testblockParameterConsumer = testblockParameterConsumer;
+ TestblockParameterType(List tabCompletes, String... removed) {
this.tabCompletes = tabCompletes;
this.removed = () -> {
if (cached.get() == null) {
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 f4626cce..673a9295 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
@@ -25,6 +25,7 @@ import de.steamwar.bausystem.linkage.specific.BauGuiItem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.flagvalues.TNTMode;
+import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
@@ -47,6 +48,8 @@ public class TntBauGuiItem extends BauGuiItem {
return new SWItem(Material.MINECART, BauSystem.MESSAGE.parse("REGION_ITEM_TNT_OFF", player)).getItemStack();
case ONLY_TB:
return new SWItem(Material.TNT_MINECART, BauSystem.MESSAGE.parse("REGION_ITEM_TNT_ONLY_TB", player)).getItemStack();
+ case ONLY_BUILD:
+ return new SWItem(Material.OBSIDIAN, BauSystem.MESSAGE.parse("REGION_ITEM_TNT_ONLY_BUILD", player)).getItemStack();
default:
return new SWItem(Material.TNT, BauSystem.MESSAGE.parse("REGION_ITEM_TNT_ON", player)).getItemStack();
}
@@ -60,8 +63,10 @@ public class TntBauGuiItem extends BauGuiItem {
updateTntMode(TNTMode.ALLOW, p);
break;
case ALLOW:
- updateTntMode(TNTMode.ONLY_TB, p);
- break;
+ if (Region.getRegion(p.getLocation()).hasType(RegionType.BUILD) && Region.getRegion(p.getLocation()).hasType(RegionType.TESTBLOCK)) {
+ updateTntMode(TNTMode.ONLY_TB, p);
+ break;
+ }
default:
updateTntMode(TNTMode.DENY, p);
}
@@ -72,11 +77,15 @@ public class TntBauGuiItem extends BauGuiItem {
updateTntMode(TNTMode.ALLOW, p);
p.closeInventory();
}));
- if (!Region.getRegion(p.getLocation()).isGlobal()) {
- selector.setItem(4, new SWItem(Material.TNT_MINECART, BauSystem.MESSAGE.parse("REGION_ITEM_SELECTOR_ONLY_TB", p), clickType -> {
+ if (Region.getRegion(p.getLocation()).hasType(RegionType.BUILD) && Region.getRegion(p.getLocation()).hasType(RegionType.TESTBLOCK)) {
+ selector.setItem(3, new SWItem(Material.TNT_MINECART, BauSystem.MESSAGE.parse("REGION_ITEM_SELECTOR_ONLY_TB", p), clickType -> {
updateTntMode(TNTMode.ONLY_TB, p);
p.closeInventory();
}));
+ selector.setItem(5, new SWItem(Material.OBSIDIAN, BauSystem.MESSAGE.parse("REGION_ITEM_SELECTOR_ONLY_BUILD", p), clickType -> {
+ updateTntMode(TNTMode.ONLY_BUILD, p);
+ p.closeInventory();
+ }));
}
selector.setItem(7, new SWItem(Material.MINECART, BauSystem.MESSAGE.parse("REGION_ITEM_SELECTOR_OFF", p), clickType -> {
updateTntMode(TNTMode.DENY, p);
@@ -92,6 +101,9 @@ public class TntBauGuiItem extends BauGuiItem {
case ONLY_TB:
p.performCommand("tnt tb");
break;
+ case ONLY_BUILD:
+ p.performCommand("tnt build");
+ break;
case ALLOW:
p.performCommand("tnt on");
break;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java
index 85cc8586..7ee93eb3 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java
@@ -48,6 +48,10 @@ public class ScriptRunner {
private static final Map>> HOTKEY_MAP = new HashMap<>();
private static final Map> COMMAND_MAP = new HashMap<>();
+ public Set getCommandsOfPlayer(Player player) {
+ return COMMAND_MAP.getOrDefault(player, new HashMap<>()).keySet();
+ }
+
public static void runScript(String script, Player player) {
Globals globals = SteamWarPlatform.createClickGlobals(player);
catchScript("SCRIPT_ERROR_CLICK", player, () -> globals.load(script).call());
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 3f0a60b6..89f9667e 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
@@ -57,8 +57,9 @@ public class EventListener implements Listener {
static {
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
- LAST_FS.entrySet().removeIf(entry -> TPSUtils.currentTick.get() - entry.getValue() > 4);
- }, 2, 2);
+ long millis = System.currentTimeMillis();
+ LAST_FS.entrySet().removeIf(entry -> millis - entry.getValue() > 200);
+ }, 1, 1);
}
@EventHandler(priority = EventPriority.MONITOR)
@@ -75,9 +76,11 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
if (LAST_FS.containsKey(event.getPlayer())) {
- ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DoubleSwap, LuaValue.NIL, event);
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DoubleSwap, LuaValue.NIL, event);
+ }, 1);
} else {
- LAST_FS.put(event.getPlayer(), TPSUtils.currentTick.get());
+ LAST_FS.put(event.getPlayer(), System.currentTimeMillis());
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/BossbarLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/BossbarLib.java
new file mode 100644
index 00000000..adbb334e
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/BossbarLib.java
@@ -0,0 +1,130 @@
+/*
+ * 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.script.lua.libs;
+
+import de.steamwar.linkage.Linked;
+import org.bukkit.Bukkit;
+import org.bukkit.boss.BarColor;
+import org.bukkit.boss.BarFlag;
+import org.bukkit.boss.BarStyle;
+import org.bukkit.boss.BossBar;
+import org.bukkit.entity.Player;
+import org.luaj.vm2.LuaError;
+import org.luaj.vm2.LuaTable;
+import org.luaj.vm2.LuaValue;
+import org.luaj.vm2.lib.OneArgFunction;
+import org.luaj.vm2.lib.ThreeArgFunction;
+import org.luaj.vm2.lib.ZeroArgFunction;
+
+@Linked
+public class BossbarLib implements LuaLib {
+ @Override
+ public String name() {
+ return "bossbar";
+ }
+
+ @Override
+ public LuaTable get(Player player) {
+ LuaTable table = new LuaTable();
+
+ table.set("create", new ThreeArgFunction() {
+
+ @Override
+ public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
+ String title = arg1.checkjstring();
+ BarStyle style;
+ BarColor color;
+ try {
+ color = BarColor.valueOf(arg2.checkjstring());
+ style = BarStyle.valueOf(arg3.checkjstring());
+ } catch (IllegalArgumentException e) {
+ throw new LuaError("Invalid color or style");
+ }
+ BossBar bossBar = Bukkit.createBossBar(title, color, style);
+ bossBar.addPlayer(player);
+
+ LuaTable bbTable = new LuaTable();
+
+ bbTable.set("title", getterAndSetter("title", bossBar::getTitle, bossBar::setTitle));
+ bbTable.set("style", getterAndSetter("style", () -> bossBar.getStyle().name(), s -> {
+ try {
+ bossBar.setStyle(BarStyle.valueOf(s));
+ } catch (IllegalArgumentException e) {
+ throw new LuaError("Invalid style");
+ }
+ }));
+ bbTable.set("color", getterAndSetter("color", () -> bossBar.getColor().name(), s -> {
+ try {
+ bossBar.setColor(BarColor.valueOf(s));
+ } catch (IllegalArgumentException e) {
+ throw new LuaError("Invalid color");
+ }
+ }));
+ bbTable.set("progress", getterAndSetter("progress", bossBar::getProgress, bossBar::setProgress));
+ bbTable.set("visible", getterAndSetter("visible", bossBar::isVisible, bossBar::setVisible));
+ bbTable.set("hasFlag", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue arg) {
+ try {
+ return LuaValue.valueOf(bossBar.hasFlag(BarFlag.valueOf(arg.checkjstring())));
+ } catch (IllegalArgumentException e) {
+ throw new LuaError("Invalid flag");
+ }
+ }
+ });
+
+ bbTable.set("addFlag", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue arg) {
+ try {
+ bossBar.addFlag(BarFlag.valueOf(arg.checkjstring()));
+ return LuaValue.TRUE;
+ } catch (IllegalArgumentException e) {
+ throw new LuaError("Invalid flag");
+ }
+ }
+ });
+
+ bbTable.set("removeFlag", new OneArgFunction() {
+ @Override
+ public LuaValue call(LuaValue arg) {
+ try {
+ bossBar.removeFlag(BarFlag.valueOf(arg.checkjstring()));
+ return LuaValue.TRUE;
+ } catch (IllegalArgumentException e) {
+ throw new LuaError("Invalid flag");
+ }
+ }
+ });
+ bbTable.set("destroy", new ZeroArgFunction() {
+ @Override
+ public LuaValue call() {
+ bossBar.removeAll();
+ return LuaValue.NIL;
+ }
+ });
+
+ return bbTable;
+ }
+ });
+
+ return table;
+ }
+}
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 0f3104cf..f6c35f9f 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
@@ -23,6 +23,7 @@ import de.steamwar.bausystem.features.loader.Loader;
import de.steamwar.bausystem.features.tracer.record.ActiveTracer;
import de.steamwar.bausystem.features.tracer.record.AutoTraceRecorder;
import de.steamwar.bausystem.features.tracer.record.Recorder;
+import de.steamwar.bausystem.region.GlobalRegion;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.flagvalues.FireMode;
@@ -49,12 +50,20 @@ public class RegionLib implements LuaLib {
LuaTable table = LuaValue.tableOf();
table.set("name", getter(() -> region.get().getName()));
- table.set("type", getter(() -> region.get().getPrototype().getName()));
+ table.set("type", getter(() -> {
+ Region region1 = region.get();
+ if (region1 instanceof GlobalRegion) {
+ return "global";
+ } else {
+ return region1.getPrototype().getName();
+ }
+ }));
LuaValue tntLib = LuaValue.tableOf();
tntLib.set("mode", getter(() -> region.get().getPlain(Flag.TNT, TNTMode.class).name()));
tntLib.set("enabled", getter(() -> region.get().getPlain(Flag.TNT, TNTMode.class) != TNTMode.DENY));
tntLib.set("onlyTb", getter(() -> region.get().getPlain(Flag.TNT, TNTMode.class) == TNTMode.ONLY_TB));
+ tntLib.set("onlyBuild", getter(() -> region.get().getPlain(Flag.TNT, TNTMode.class) == TNTMode.ONLY_BUILD));
table.set("tnt", tntLib);
@@ -86,7 +95,7 @@ public class RegionLib implements LuaLib {
}
});
- table.set("list", getter(() -> LuaValue.listOf(Region.getREGION_MAP().values().stream().map(region -> create(() -> region, player)).toArray(LuaValue[]::new))));
+ table.set("list", getter(() -> LuaValue.listOf(Region.getREGION_MAP().values().stream().map(region -> create(() -> region, player)).toArray(LuaTable[]::new))));
return table;
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceBehaviour.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceBehaviour.java
deleted file mode 100644
index 19ca8d0d..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceBehaviour.java
+++ /dev/null
@@ -1,45 +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.smartplace;
-
-import org.bukkit.event.block.BlockPlaceEvent;
-import org.bukkit.event.player.PlayerInteractEvent;
-
-public interface SmartPlaceBehaviour {
-
- enum SmartPlaceResult {
- APPLIED,
- IGNORED
- }
-
- enum SmartPlaceType {
- PLACE,
- INTERACT_DIRECT, // Before checking if block is interacteable
- INTERACT_INDIRECT, // After checking if block is interacteable
- }
-
- SmartPlaceType getType();
- default SmartPlaceResult place(BlockPlaceEvent event) {
- return SmartPlaceResult.IGNORED;
- }
- default SmartPlaceResult interact(PlayerInteractEvent event) {
- return SmartPlaceResult.IGNORED;
- }
-}
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 a5ac0456..75f60d53 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java
@@ -20,82 +20,84 @@
package de.steamwar.bausystem.features.smartplace;
import de.steamwar.bausystem.configplayer.Config;
-import de.steamwar.bausystem.linkage.LinkageUtils;
+import de.steamwar.bausystem.utils.PlaceItemUtils;
import de.steamwar.linkage.Linked;
+import org.bukkit.Bukkit;
import org.bukkit.GameMode;
+import org.bukkit.Material;
+import org.bukkit.SoundGroup;
+import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
-import org.bukkit.block.data.Directional;
-import org.bukkit.block.data.Rotatable;
+import org.bukkit.block.data.type.Repeater;
+import org.bukkit.block.data.type.Sign;
+import org.bukkit.block.data.type.Switch;
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.block.BlockPlaceEvent;
+import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerInteractEvent;
-import java.util.ArrayList;
-import java.util.List;
-
@Linked
public class SmartPlaceListener implements Listener {
- private static List smartPlaceBehaviours = new ArrayList<>();
-
- public static void add(SmartPlaceBehaviour smartPlaceBehaviour) {
- smartPlaceBehaviours.add(smartPlaceBehaviour);
- }
-
- @EventHandler
- public void onBlockPlace(BlockPlaceEvent event) {
- if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
- if (smartPlaceBehaviours.isEmpty()) LinkageUtils.linkSmartPlace();
- SmartPlaceBehaviour.SmartPlaceResult smartPlaceResult = SmartPlaceBehaviour.SmartPlaceResult.IGNORED;
- for (SmartPlaceBehaviour smartPlaceBehaviour : smartPlaceBehaviours) {
- if (smartPlaceBehaviour.getType() == SmartPlaceBehaviour.SmartPlaceType.PLACE) {
- smartPlaceResult = smartPlaceBehaviour.place(event);
- }
- if (smartPlaceResult == SmartPlaceBehaviour.SmartPlaceResult.APPLIED) {
- break;
- }
- }
- }
-
- @EventHandler
+ @EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerInteract(PlayerInteractEvent event) {
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
- if (smartPlaceBehaviours.isEmpty()) LinkageUtils.linkSmartPlace();
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return;
- for (SmartPlaceBehaviour smartPlaceBehaviour : smartPlaceBehaviours) {
- SmartPlaceBehaviour.SmartPlaceResult smartPlaceResult = SmartPlaceBehaviour.SmartPlaceResult.IGNORED;
- if (smartPlaceBehaviour.getType() == SmartPlaceBehaviour.SmartPlaceType.INTERACT_DIRECT) {
- smartPlaceResult = smartPlaceBehaviour.interact(event);
- }
- if (smartPlaceResult == SmartPlaceBehaviour.SmartPlaceResult.APPLIED) {
+ boolean shouldRotate = event.getPlayer().isSneaking();
+ Material blockType = event.getClickedBlock().getType();
+ switch (blockType) {
+ case REPEATER:
+ if (shouldRotate && (event.getItem() == null || event.getItem().getType() == Material.REPEATER)) {
+ Repeater repeater = (Repeater) event.getClickedBlock().getBlockData();
+ int i = repeater.getDelay() - 1;
+ if (i <= 0) i += 4;
+ repeater.setDelay(i);
+ event.getClickedBlock().setBlockData(repeater);
+ event.setCancelled(true);
+ }
+ return;
+ }
+ BlockData blockData = event.getClickedBlock().getBlockData();
+ if (blockData instanceof Switch) {
+ if (!shouldRotate && (event.getItem() == null || event.getItem().getType() == event.getClickedBlock().getType())) {
return;
}
+ shouldRotate = false;
}
- if (!event.getClickedBlock().getType().isInteractable()) return;
- if (event.getItem() == null) return;
- if (!event.getMaterial().isBlock()) return;
- try {
- BlockData blockData = event.getItem().getType().createBlockData();
- if (!(blockData instanceof Directional) && !(blockData instanceof Rotatable)) {
- return;
+ PlaceItemUtils.PlaceItemResult result = PlaceItemUtils.placeItem(event.getPlayer(), event.getItem(), event.getClickedBlock(), event.getBlockFace(), event.getHand(), true, true, shouldRotate, false);
+ if (result.isSuccess()) {
+ event.setCancelled(true);
+ Block block = event.getClickedBlock().getRelative(event.getBlockFace());
+ SoundGroup soundGroup = block.getBlockData().getSoundGroup();
+ Bukkit.getOnlinePlayers().forEach(player -> {
+ if (!(event.getClickedBlock().getBlockData() instanceof Sign) && player == event.getPlayer()) {
+ return;
+ }
+ player.playSound(block.getLocation(), soundGroup.getPlaceSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
+ });
+ if (result.wasForced()) {
+ event.getPlayer().playSound(block.getLocation(), soundGroup.getPlaceSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
}
- } catch (Exception e) {
- return;
}
+ // Fix Double sound for original player
+ }
- for (SmartPlaceBehaviour smartPlaceBehaviour : smartPlaceBehaviours) {
- SmartPlaceBehaviour.SmartPlaceResult smartPlaceResult = SmartPlaceBehaviour.SmartPlaceResult.IGNORED;
- if (smartPlaceBehaviour.getType() == SmartPlaceBehaviour.SmartPlaceType.INTERACT_INDIRECT) {
- smartPlaceResult = smartPlaceBehaviour.interact(event);
- }
- if (smartPlaceResult == SmartPlaceBehaviour.SmartPlaceResult.APPLIED) {
- return;
- }
- }
+ @EventHandler
+ public void onBlockBreak(BlockBreakEvent event) {
+ if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
+ if (!event.getPlayer().isSneaking()) return;
+ event.setCancelled(true);
+ event.getBlock().setType(Material.AIR, false);
+
+ SoundGroup soundGroup = event.getBlock().getBlockData().getSoundGroup();
+ Bukkit.getOnlinePlayers().forEach(player -> {
+ if (player == event.getPlayer()) return;
+ player.playSound(event.getBlock().getLocation(), soundGroup.getBreakSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
+ });
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockPlaceBehaviour.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockPlaceBehaviour.java
deleted file mode 100644
index bfe5accd..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockPlaceBehaviour.java
+++ /dev/null
@@ -1,63 +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.smartplace.behaviour;
-
-import de.steamwar.bausystem.features.smartplace.SmartPlaceBehaviour;
-import de.steamwar.linkage.Linked;
-import org.bukkit.block.Block;
-import org.bukkit.block.BlockFace;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.block.data.Directional;
-import org.bukkit.block.data.Rotatable;
-import org.bukkit.event.block.BlockPlaceEvent;
-
-@Linked
-public class BlockPlaceBehaviour implements SmartPlaceBehaviour {
-
- @Override
- public SmartPlaceType getType() {
- return SmartPlaceType.PLACE;
- }
-
- @Override
- public SmartPlaceResult place(BlockPlaceEvent event) {
- if (!event.getPlayer().isSneaking()) {
- return SmartPlaceResult.IGNORED;
- }
-
- SmartPlaceResult smartPlaceResult = SmartPlaceResult.IGNORED;
- Block block = event.getBlockPlaced();
- BlockData blockData = block.getBlockData();
- if (blockData instanceof Directional) {
- Directional directional = (Directional) blockData;
- BlockFace blockFace = directional.getFacing().getOppositeFace();
- if (directional.getFaces().contains(blockFace)) {
- directional.setFacing(blockFace);
- }
- smartPlaceResult = SmartPlaceResult.APPLIED;
- } else if (blockData instanceof Rotatable) {
- Rotatable rotatable = (Rotatable) blockData;
- rotatable.setRotation(rotatable.getRotation().getOppositeFace());
- smartPlaceResult = SmartPlaceResult.APPLIED;
- }
- block.setBlockData(blockData);
- return smartPlaceResult;
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockRotatingBehaviour.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockRotatingBehaviour.java
deleted file mode 100644
index fc266d0e..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockRotatingBehaviour.java
+++ /dev/null
@@ -1,84 +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.smartplace.behaviour;
-
-import de.steamwar.bausystem.features.smartplace.SmartPlaceBehaviour;
-import de.steamwar.linkage.Linked;
-import org.bukkit.Material;
-import org.bukkit.World;
-import org.bukkit.block.Block;
-import org.bukkit.block.BlockFace;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.block.data.Directional;
-import org.bukkit.block.data.Rotatable;
-import org.bukkit.event.Event;
-import org.bukkit.event.player.PlayerInteractEvent;
-import org.bukkit.inventory.InventoryHolder;
-
-@Linked
-public class BlockRotatingBehaviour implements SmartPlaceBehaviour {
-
- @Override
- public SmartPlaceType getType() {
- return SmartPlaceType.INTERACT_INDIRECT;
- }
-
- @Override
- public SmartPlaceResult interact(PlayerInteractEvent event) {
- if (!(event.getClickedBlock().getState() instanceof InventoryHolder)) {
- return SmartPlaceResult.IGNORED;
- }
-
- BlockData blockData = event.getMaterial().createBlockData();
- if (!(blockData instanceof Directional) && !(blockData instanceof Rotatable)) {
- return SmartPlaceResult.IGNORED;
- }
-
- event.setUseInteractedBlock(Event.Result.DENY);
- World world = event.getPlayer().getWorld();
- Block block = world.getBlockAt(event.getClickedBlock().getX() + event.getBlockFace().getModX(), event.getClickedBlock().getY() + event.getBlockFace().getModY(), event.getClickedBlock().getZ() + event.getBlockFace().getModZ());
- if (!block.getType().isAir()) {
- return SmartPlaceResult.IGNORED;
- }
- block.setType(event.getMaterial());
- blockData = event.getItem().getType().createBlockData();
- BlockFace blockFace = event.getBlockFace();
- if ((blockFace == BlockFace.UP || blockFace == BlockFace.DOWN) && blockData instanceof Directional) {
- blockFace = event.getPlayer().getFacing().getOppositeFace();
- }
- if (block.getType() == Material.HOPPER || block.getType() == Material.OBSERVER) {
- blockFace = blockFace.getOppositeFace();
- }
- if (blockData instanceof Directional) {
- Directional directional = (Directional) blockData;
- if (directional.getFaces().contains(blockFace)) {
- directional.setFacing(blockFace);
- }
- } else if (blockData instanceof Rotatable) {
- try {
- ((Rotatable) blockData).setRotation(blockFace);
- } catch (Exception e) {
- // Ignore
- }
- }
- block.setBlockData(blockData);
- return SmartPlaceResult.APPLIED;
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/ReverseRepeaterBehaviour.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/ReverseRepeaterBehaviour.java
deleted file mode 100644
index 13242417..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/ReverseRepeaterBehaviour.java
+++ /dev/null
@@ -1,54 +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.smartplace.behaviour;
-
-import de.steamwar.bausystem.features.smartplace.SmartPlaceBehaviour;
-import de.steamwar.linkage.Linked;
-import org.bukkit.Material;
-import org.bukkit.block.data.type.Repeater;
-import org.bukkit.event.player.PlayerInteractEvent;
-
-@Linked
-public class ReverseRepeaterBehaviour implements SmartPlaceBehaviour {
-
- @Override
- public SmartPlaceType getType() {
- return SmartPlaceType.INTERACT_DIRECT;
- }
-
- @Override
- public SmartPlaceResult interact(PlayerInteractEvent event) {
- if (event.getPlayer().isSneaking()) {
- if (event.getClickedBlock().getType() == Material.REPEATER) {
- if (event.getItem() != null && event.getMaterial() != Material.REPEATER) {
- return SmartPlaceResult.APPLIED;
- }
- Repeater repeater = (Repeater) event.getClickedBlock().getBlockData();
- int i = repeater.getDelay() - 1;
- if (i <= 0) i += 4;
- repeater.setDelay(i);
- event.getClickedBlock().setBlockData(repeater);
- event.setCancelled(true);
- }
- return SmartPlaceResult.APPLIED;
- }
- return SmartPlaceResult.IGNORED;
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java
index be47e4bc..1af2b710 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.tracer;
import de.steamwar.bausystem.features.tracer.show.Record;
import de.steamwar.bausystem.shared.Position;
import lombok.Getter;
+import lombok.Setter;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.util.Vector;
@@ -30,16 +31,21 @@ public class TNTPosition extends Position {
private final Record.TNTRecord record;
private final int fuseTicks;
+ private final long timeTicks;
private final Vector previousLocation;
private final Vector velocity;
private final Vector updateVelocity;
private final boolean source;
private final boolean exploded;
- public TNTPosition(Record.TNTRecord record, TNTPrimed entity, Vector previousLocation, Vector velocity, Vector updateVelocity, boolean source, boolean exploded) {
+ @Setter
+ private boolean microMotion;
+
+ public TNTPosition(Record.TNTRecord record, TNTPrimed entity, long timeTicks, Vector previousLocation, Vector velocity, Vector updateVelocity, boolean source, boolean exploded) {
super(entity.getLocation().toVector());
this.record = record;
this.fuseTicks = entity.getFuseTicks();
+ this.timeTicks = timeTicks;
this.previousLocation = previousLocation;
this.velocity = velocity;
this.updateVelocity = updateVelocity;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java
index f18147f3..0ffe04de 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java
@@ -21,9 +21,7 @@ package de.steamwar.bausystem.features.tracer;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
-import de.steamwar.bausystem.features.tracer.gui.TraceGui;
import de.steamwar.bausystem.features.tracer.record.*;
-import de.steamwar.bausystem.features.tracer.show.Record;
import de.steamwar.bausystem.features.tracer.show.*;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.shared.ShowMode;
@@ -91,11 +89,84 @@ public class TraceCommand extends SWCommand {
}
}
+ @Register(value = {"autoremove"}, description = "TRACE_COMMAND_HELP_AUTO_REMOVE")
+ @Register(value = {"autodelete"})
+ public void setAutoDeleteMode(@Validator Player p, @StaticValue({"-always", "-never", "-no_build_destroy", "-build_destroy", "-no_testblock_destroy", "-testblock_destroy"}) String destroyMode) {
+ Region region = Region.getRegion(p.getLocation());
+ TraceRecorder recorder = this.recorder.get(region);
+ if (!(recorder instanceof AutoTraceRecorder) || recorder instanceof SingleTraceRecorder) {
+ BauSystem.MESSAGE.send("TRACE_MESSAGE_AUTO_DELETE_INVALID", p);
+ return;
+ }
+ AutoTraceRecorder autoTraceRecorder = (AutoTraceRecorder) recorder;
+ switch (destroyMode) {
+ case "-always":
+ autoTraceRecorder.setTraceRecordAutoDeletion(TraceRecordAutoDeletion.ALWAYS);
+ break;
+ case "-never":
+ autoTraceRecorder.setTraceRecordAutoDeletion(TraceRecordAutoDeletion.NEVER);
+ break;
+ case "-no_build_destroy":
+ autoTraceRecorder.setTraceRecordAutoDeletion(TraceRecordAutoDeletion.NO_BUILD_DESTROY);
+ break;
+ case "-build_destroy":
+ autoTraceRecorder.setTraceRecordAutoDeletion(TraceRecordAutoDeletion.BUILD_DESTROY);
+ break;
+ case "-no_testblock_destroy":
+ autoTraceRecorder.setTraceRecordAutoDeletion(TraceRecordAutoDeletion.NO_TESTBLOCK_DESTROY);
+ break;
+ case "-testblock_destroy":
+ autoTraceRecorder.setTraceRecordAutoDeletion(TraceRecordAutoDeletion.TESTBLOCK_DESTROY);
+ break;
+ default:
+ return;
+ }
+ BauSystem.MESSAGE.send("TRACE_MESSAGE_AUTO_DELETE_" + autoTraceRecorder.getTraceRecordAutoDeletion().name(), p);
+ }
+
+ @Register(value = {"show"})
+ public void showAtCommand(@Validator Player p, @OptionalValue("time") @StaticValue({"time", "fuse"}) String type, @StaticValue("at") String __, @Min(intValue = 0) int at) {
+ showFromToCommand(p, type, __, at, __, at);
+ }
+
+ @Register(value = {"show"})
+ public void showFromCommand(@Validator Player p, @OptionalValue("time") @StaticValue({"time", "fuse"}) String type, @StaticValue("from") String __, @Min(intValue = 0) int from) {
+ if (from == 0) {
+ TraceShowManager.setShowFilter(p, null);
+ return;
+ }
+ showFromToCommand(p, type, __, from, __, Integer.MAX_VALUE);
+ }
+
+ @Register(value = {"show"})
+ public void showFromToCommand(@Validator Player p, @OptionalValue("time") @StaticValue({"time", "fuse"}) String type, @StaticValue("from") String __, @Min(intValue = 0) int from, @StaticValue("to") String ___, @Min(intValue = 0) int to) {
+ TraceShowManager.setShowFilter(p, tntPosition -> {
+ switch (type) {
+ case "time":
+ return tntPosition.getTimeTicks() >= from && tntPosition.getTimeTicks() <= to;
+ case "fuse":
+ return tntPosition.getFuseTicks() >= from && tntPosition.getFuseTicks() <= to;
+ default:
+ return true;
+ }
+ });
+ }
+
+ // /trace show at 0
+ // /trace show raw -auto at 0
@Register(value = {"show"}, description = "TRACE_COMMAND_HELP_SHOW")
public void showCommand(@Validator Player p, @OptionalValue("entity") ShowModeType showModeType, ShowModeParameterType... showModeParameterTypes) {
+ Region region = Region.getRegion(p.getLocation());
ShowModeParameter showModeParameter = new ShowModeParameter();
+ if (region.getWaterLevel() != 0) { // Enable Water by default for regions with WaterLevel e.g. WarShip
+ showModeParameter.enableWater();
+ }
for (ShowModeParameterType showModeParameterType : showModeParameterTypes) {
- showModeParameterType.getShowModeParameterConsumer().accept(showModeParameter);
+ if (showModeParameterType == ShowModeParameterType.WATER && region.getWaterLevel() != 0) {
+ showModeParameter.disableWater();
+ } else {
+ showModeParameterType.getShowModeParameterConsumer().accept(showModeParameter);
+ }
}
TraceShowManager.show(p, showModeType.showModeBiFunction.apply(p, showModeParameter));
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW", p);
@@ -104,9 +175,6 @@ public class TraceCommand extends SWCommand {
@Register(value = {"hide"}, description = "TRACE_COMMAND_HELP_HIDE")
public void hideCommand(@Validator Player p) {
TraceShowManager.hide(p);
- Region region = Region.getRegion(p.getLocation());
- StoredRecords.hideIsolated(region, p);
- StoredRecords.removeReplayTime(region, p);
BauSystem.MESSAGE.send("TRACE_MESSAGE_HIDE", p);
}
@@ -115,97 +183,9 @@ public class TraceCommand extends SWCommand {
public void deleteCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
StoredRecords.clear(region);
- StoredRecords.hideIsolated(region);
- StoredRecords.removeReplayTime(region);
BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE", p);
}
- @Register(value = {"gui"}, description = "TRACE_COMMAND_HELP_GUI")
- public void guiCommand(@Validator Player p) {
- TraceGui.openGui(p);
- }
-
- @Register(value = "isolate", noTabComplete = true)
- public void isolate(Player p, String s) {
- try {
- UUID uuid = UUID.fromString(s);
- Record.TNTRecord tntRecord = StoredRecords.getRecord(uuid);
- StoredRecords.toggleIsolate(p, tntRecord);
- } catch (Exception e) {
- // Ignore
- }
- }
-
- @Register(value = "replay", description = "TRACE_COMMAND_HELP_REPLAY")
- public void replay(@Validator Player p, @OptionalValue("0") int replayTick) {
- Region region = Region.getRegion(p.getLocation());
- if (replayTick < 0) replayTick = 0;
- StoredRecords.setReplayTime(region, p, replayTick);
- }
-
- @Register(value = {"replay", "disable"}, description = "TRACE_COMMAND_HELP_REPLAY_DISABLE")
- public void replayDisable(@Validator Player p) {
- Region region = Region.getRegion(p.getLocation());
- StoredRecords.removeReplayTime(region, p);
- }
-
- @Register(value = {"replay", "next"}, description = "TRACE_COMMAND_HELP_REPLAY_NEXT")
- public void replayNext(@Validator Player p, @OptionalValue("1") int step) {
- Region region = Region.getRegion(p.getLocation());
- int replayTick = StoredRecords.getReplayTime(region, p);
- StoredRecords.setReplayTime(region, p, replayTick + step);
- }
-
- @Register(value = {"replay", "previous"}, description = "TRACE_COMMAND_HELP_REPLAY_PREVIOUS")
- public void replayPrevious(@Validator Player p, @OptionalValue("1") int step) {
- Region region = Region.getRegion(p.getLocation());
- int replayTick = StoredRecords.getReplayTime(region, p) - step;
- if (replayTick < 0) replayTick = 0;
- StoredRecords.setReplayTime(region, p, replayTick);
- }
-
- @Register(value = {"replay", "loop"}, description = "TRACE_COMMAND_HELP_REPLAY_LOOP")
- public void replayLoop(@Validator Player p, int start, int end, @OptionalValue("0") int speed) {
- Region region = Region.getRegion(p.getLocation());
-
- if (start < 0) start = 0;
- if (end < 0) end = 0;
-
- int initial = StoredRecords.getReplayTime(region, p);
- if (!(Math.min(start, end) < initial && Math.max(start, end) > initial)) {
- initial = start;
- }
- int finalInitial = initial;
-
- int finalStart = start;
- int finalEnd = end;
- Supplier supplier = new Supplier() {
- int temp = speed;
- int current = finalInitial;
-
- @Override
- public Integer get() {
- if (temp-- > 0) {
- return current;
- }
- temp = speed;
- if (finalEnd > finalStart) {
- current++;
- if (current > finalEnd) {
- current = finalStart;
- }
- } else {
- current--;
- if (current < finalEnd) {
- current = finalStart;
- }
- }
- return current;
- }
- };
- StoredRecords.setReplayLoop(region, p, supplier);
- }
-
@AllArgsConstructor
private enum ShowModeType {
ENTITY((player, showModeParameter) -> new EntityShowMode(player, showModeParameter, 10)),
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/gui/TraceGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/gui/TraceGui.java
deleted file mode 100644
index fc4500af..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/gui/TraceGui.java
+++ /dev/null
@@ -1,108 +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.tracer.gui;
-
-import de.steamwar.bausystem.BauSystem;
-import de.steamwar.bausystem.features.tracer.TNTPosition;
-import de.steamwar.bausystem.features.tracer.show.Record;
-import de.steamwar.bausystem.features.tracer.show.StoredRecords;
-import de.steamwar.bausystem.features.tracer.show.TraceShowManager;
-import de.steamwar.bausystem.region.Region;
-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 TraceGui {
-
- public static void openGui(Player player) {
- Region region = Region.getRegion(player.getLocation());
- List> recordList = new ArrayList<>();
- StoredRecords.getRecords(region).forEach(record -> {
- if (record.getTnt().isEmpty()) {
- return;
- }
- SWItem swItem = new SWItem(Material.TNT, BauSystem.MESSAGE.parse("TRACE_GUI_ITEM", player, record.size()));
- recordList.add(new SWListInv.SWListEntry<>(swItem, record));
- });
- SWListInv recordSWListInv = new SWListInv<>(player, BauSystem.MESSAGE.parse("TRACE_GUI_TITLE", player), false, recordList, (clickType, record) -> {
- openRecordGui(player, record);
- });
- recordSWListInv.setItem(49, new SWItem(Material.BUCKET, BauSystem.MESSAGE.parse("TRACE_GUI_CLEAR", player), clickType -> {
- StoredRecords.clear(region);
- player.getOpenInventory().close();
- }));
- recordSWListInv.open();
- }
-
- public static void openRecordGui(Player player, Record record) {
- Region region = Region.getRegion(player.getLocation());
- List> recordList = new ArrayList<>();
- record.getTnt().forEach(tntRecord -> {
- SWItem swItem = new SWItem(Material.TNT_MINECART, BauSystem.MESSAGE.parse("TRACE_GUI_RECORD_ITEM", player, tntRecord.getPositions().size()), new ArrayList<>(), StoredRecords.isIsolated(player, tntRecord), clickType -> {
- });
- recordList.add(new SWListInv.SWListEntry<>(swItem, tntRecord));
- });
- SWListInv tntRecordSWListInv = new SWListInv<>(player, BauSystem.MESSAGE.parse("TRACE_GUI_TITLE", player), false, recordList, (clickType, tntRecord) -> {
- if (clickType.isShiftClick()) {
- StoredRecords.toggleIsolate(player, tntRecord);
- openRecordGui(player, record);
- } else {
- openTntGui(player, record, tntRecord);
- }
- });
- tntRecordSWListInv.setItem(48, new SWItem(Material.BUCKET, BauSystem.MESSAGE.parse("TRACE_GUI_RECORD_CLEAR", player), clickType -> {
- StoredRecords.remove(region, record);
- TraceShowManager.reshow(region);
- openGui(player);
- }));
- tntRecordSWListInv.setItem(50, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("TRACE_GUI_ITEM_BACK", player), clickType -> {
- openGui(player);
- }));
- tntRecordSWListInv.open();
- }
-
- public static void openTntGui(Player player, Record record, Record.TNTRecord tntRecord) {
- List> positionList = new ArrayList<>();
- tntRecord.getPositions().forEach(tntPosition -> {
- SWItem swItem = new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("TRACE_GUI_POSITION_ITEM", player));
- swItem.setLore(Arrays.asList(
- BauSystem.MESSAGE.parse("TRACE_GUI_POSITION_X", player, tntPosition.getLocation().getX()),
- BauSystem.MESSAGE.parse("TRACE_GUI_POSITION_Y", player, tntPosition.getLocation().getY()),
- BauSystem.MESSAGE.parse("TRACE_GUI_POSITION_Z", player, tntPosition.getLocation().getZ()),
- BauSystem.MESSAGE.parse("TRACE_GUI_POSITION_SOURCE", player, tntPosition.isSource()),
- BauSystem.MESSAGE.parse("TRACE_GUI_POSITION_EXPLODED", player, tntPosition.isExploded())
- ));
- positionList.add(new SWListInv.SWListEntry<>(swItem, tntPosition));
- });
- SWListInv tntPositionSWListInv = new SWListInv<>(player, BauSystem.MESSAGE.parse("TRACE_GUI_TITLE", player), false, positionList, (clickType, tntPosition) -> {
- });
- tntPositionSWListInv.setItem(49, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("TRACE_GUI_ITEM_BACK", player), clickType -> {
- openRecordGui(player, record);
- }));
- tntPositionSWListInv.open();
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoTraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoTraceRecorder.java
index f0eeab8c..ab326abc 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoTraceRecorder.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoTraceRecorder.java
@@ -22,6 +22,11 @@ package de.steamwar.bausystem.features.tracer.record;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.features.tracer.show.Record;
+import de.steamwar.bausystem.features.tracer.show.StoredRecords;
+import de.steamwar.bausystem.features.tracer.show.TraceShowManager;
+import de.steamwar.bausystem.region.Region;
+import lombok.Getter;
+import lombok.Setter;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
@@ -37,10 +42,17 @@ public abstract class AutoTraceRecorder implements TraceRecorder {
private final Map recordMap = new HashMap<>();
private Record record;
+
+ private Region region;
private Supplier recordSupplier;
+ @Setter
+ @Getter
+ private TraceRecordAutoDeletion traceRecordAutoDeletion = TraceRecordAutoDeletion.NEVER;
+ private Record lastRecord;
+
private Record.TNTRecord getRecord(TNTPrimed tntPrimed) {
- return recordMap.computeIfAbsent(tntPrimed, __ -> record.spawn(TPSUtils.currentRealTick.get() - startTime));
+ return recordMap.computeIfAbsent(tntPrimed, __ -> record.spawn());
}
protected abstract String getInactivityMessage();
@@ -58,6 +70,10 @@ public abstract class AutoTraceRecorder implements TraceRecorder {
}
private void startRecording() {
+ if (lastRecord != null && traceRecordAutoDeletion.test(lastRecord)) {
+ StoredRecords.remove(region, lastRecord);
+ TraceShowManager.reshow(region);
+ }
lastExplosion = 0;
startTime = TPSUtils.currentRealTick.get();
record = recordSupplier.get();
@@ -65,7 +81,8 @@ public abstract class AutoTraceRecorder implements TraceRecorder {
}
@Override
- public void recordSupplier(Supplier recordSupplier) {
+ public void init(Region region, Supplier recordSupplier) {
+ this.region = region;
this.recordSupplier = recordSupplier;
}
@@ -93,13 +110,14 @@ public abstract class AutoTraceRecorder implements TraceRecorder {
}
@Override
- public final void explode(TNTPrimed tntPrimed, boolean inBuildRegion) {
+ public final void explode(TNTPrimed tntPrimed, boolean inBuildRegion, boolean inTestblockRegion) {
if (!recording && shouldStartRecording(StartType.EXPLODE)) {
startRecording();
}
if (recording) {
Record.TNTRecord tntRecord = getRecord(tntPrimed);
if (inBuildRegion) tntRecord.setInBuildArea(true);
+ if (inTestblockRegion) tntRecord.setInTestblockArea(true);
tntRecord.explode(tntPrimed);
}
lastExplosion = 0;
@@ -111,6 +129,7 @@ public abstract class AutoTraceRecorder implements TraceRecorder {
if (recording && lastExplosion > 80) {
recording = false;
recordMap.clear();
+ lastRecord = record;
record = null;
stoppedRecording();
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java
index 7dd12060..1bd04377 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java
@@ -26,7 +26,6 @@ import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.linkage.Linked;
-import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
@@ -65,7 +64,7 @@ public class Recorder implements Listener {
}
@Override
- public void explode(TNTPrimed tntPrimed, boolean b) {
+ public void explode(TNTPrimed tntPrimed, boolean inBuildArea, boolean inTestblockRegion) {
}
@Override
@@ -80,12 +79,6 @@ public class Recorder implements Listener {
}
private static final DisabledTracerRecorder DISABLED = new DisabledTracerRecorder();
- static Recorder instance;
-
- {
- instance = this;
- }
-
private Map regionTraceRecorderMap = new HashMap<>();
private Map tntTraceRecorderMap = new HashMap<>();
@@ -99,13 +92,13 @@ public class Recorder implements Listener {
public void set(Region region, TraceRecorder traceRecorder) {
regionTraceRecorderMap.put(region, traceRecorder);
- traceRecorder.recordSupplier(() -> {
+ traceRecorder.init(region, () -> {
Record record = new Record(region);
StoredRecords.add(region, record);
return record;
});
- tntTraceRecorderMap.forEach((tntPrimed, region1) -> {
- if (region1 == region) {
+ tntTraceRecorderMap.forEach((tntPrimed, rg) -> {
+ if (rg == region) {
traceRecorder.spawn(tntPrimed);
}
});
@@ -155,7 +148,8 @@ public class Recorder implements Listener {
TraceRecorder traceRecorder = get((TNTPrimed) entity);
Region region = tntTraceRecorderMap.get((TNTPrimed) entity);
boolean inBuildRegion = event.blockList().stream().anyMatch(block -> region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
- traceRecorder.explode((TNTPrimed) entity, inBuildRegion);
+ boolean inTestblockRegion = event.blockList().stream().anyMatch(block -> region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION));
+ traceRecorder.explode((TNTPrimed) entity, inBuildRegion, inTestblockRegion);
tntTraceRecorderMap.remove(entity);
tick();
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SimpleTraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SimpleTraceRecorder.java
index 1077f59a..875d25b5 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SimpleTraceRecorder.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SimpleTraceRecorder.java
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.tracer.record;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.features.tracer.show.Record;
+import de.steamwar.bausystem.region.Region;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
@@ -41,7 +42,7 @@ public class SimpleTraceRecorder implements TraceRecorder, ActiveTracer {
}
@Override
- public void recordSupplier(Supplier recordSupplier) {
+ public void init(Region region, Supplier recordSupplier) {
record = recordSupplier.get();
}
@@ -51,7 +52,7 @@ public class SimpleTraceRecorder implements TraceRecorder, ActiveTracer {
}
private Record.TNTRecord getRecord(TNTPrimed tntPrimed) {
- return recordMap.computeIfAbsent(tntPrimed, __ -> record.spawn(TPSUtils.currentRealTick.get() - startTime));
+ return recordMap.computeIfAbsent(tntPrimed, __ -> record.spawn());
}
@Override
@@ -65,9 +66,10 @@ public class SimpleTraceRecorder implements TraceRecorder, ActiveTracer {
}
@Override
- public void explode(TNTPrimed tntPrimed, boolean inBuildRegion) {
+ public void explode(TNTPrimed tntPrimed, boolean inBuildRegion, boolean inTestblockRegion) {
Record.TNTRecord tntRecord = getRecord(tntPrimed);
if (inBuildRegion) tntRecord.setInBuildArea(true);
+ if (inTestblockRegion) tntRecord.setInTestblockArea(true);
tntRecord.explode(tntPrimed);
recordMap.remove(tntPrimed);
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecordAutoDeletion.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecordAutoDeletion.java
new file mode 100644
index 00000000..a99eff0e
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecordAutoDeletion.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.tracer.record;
+
+import de.steamwar.bausystem.features.tracer.show.Record;
+
+public enum TraceRecordAutoDeletion {
+
+ ALWAYS {
+ @Override
+ public boolean test(Record record) {
+ return true;
+ }
+ },
+ NEVER {
+ @Override
+ public boolean test(Record record) {
+ return false;
+ }
+ },
+ NO_BUILD_DESTROY {
+ @Override
+ public boolean test(Record record) {
+ return record.getTnt().stream().noneMatch(Record.TNTRecord::isInBuildArea);
+ }
+ },
+ BUILD_DESTROY {
+ @Override
+ public boolean test(Record record) {
+ return record.getTnt().stream().anyMatch(Record.TNTRecord::isInBuildArea);
+ }
+ },
+ NO_TESTBLOCK_DESTROY {
+ @Override
+ public boolean test(Record record) {
+ return record.getTnt().stream().noneMatch(Record.TNTRecord::isInTestblockArea);
+ }
+ },
+ TESTBLOCK_DESTROY {
+ @Override
+ public boolean test(Record record) {
+ return record.getTnt().stream().anyMatch(Record.TNTRecord::isInTestblockArea);
+ }
+ },
+ ;
+
+ public abstract boolean test(Record record);
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecorder.java
index bb2a1325..c667f4e0 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecorder.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecorder.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.tracer.record;
import de.steamwar.bausystem.features.tracer.show.Record;
+import de.steamwar.bausystem.region.Region;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
@@ -28,13 +29,13 @@ import java.util.function.Supplier;
public interface TraceRecorder {
String scoreboard(Player player);
- default void recordSupplier(Supplier recordSupplier) {
+ default void init(Region region, Supplier recordSupplier) {
}
default void postClear() {
}
void spawn(TNTPrimed tntPrimed);
void tick(TNTPrimed tntPrimed);
- void explode(TNTPrimed tntPrimed, boolean inBuildRegion);
+ void explode(TNTPrimed tntPrimed, boolean inBuildRegion, boolean inTestblockRegion);
default void tick() {
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityShowMode.java
index 0828ce73..dfa05ac4 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityShowMode.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityShowMode.java
@@ -84,15 +84,22 @@ public class EntityShowMode implements ShowMode {
return;
}
+ if (showModeParameter.isTestblockDestroyOnly() && !position.getRecord().isInTestblockArea()) {
+ return;
+ }
+
if (showModeParameter.isMicroMotion() && !position.getRecord().isHasMicroMotion()) {
return;
}
+ boolean exploded = position.getRecord().getPositions().stream().anyMatch(TNTPosition::isExploded);
+ boolean hideWater = !showModeParameter.isWater() && exploded && checkWater(position.getLocation());
+
if (showModeParameter.isExplodeOnly()) {
if (position.isExploded()) {
generatePositions(position, false, false);
}
- if (!showModeParameter.isSourceOnly()) {
+ if (!showModeParameter.isSourceOnly() && !showModeParameter.isMicroMotionLocation() && !hideWater) {
return;
}
}
@@ -101,11 +108,22 @@ public class EntityShowMode implements ShowMode {
if (position.isSource()) {
generatePositions(position, false, false);
}
- return;
+ if (!showModeParameter.isMicroMotionLocation() && !hideWater) {
+ return;
+ }
}
- boolean exploded = position.getRecord().getPositions().stream().anyMatch(TNTPosition::isExploded);
- if (!showModeParameter.isWater() && exploded && checkWater(position.getLocation())) {
+ if (showModeParameter.isMicroMotionLocation()) {
+ if (position.isMicroMotion()) {
+ generatePositions(position, false, false);
+ }
+ if (!hideWater) {
+ return;
+ }
+ }
+
+
+ if (hideWater) {
if (position.isExploded()) {
for (TNTPosition pos : position.getRecord().getPositions()) {
generatePositions(pos, showModeParameter.isInterpolateY(), showModeParameter.isInterpolateXZ(), (positionType, vector) -> {
@@ -201,12 +219,10 @@ public class EntityShowMode implements ShowMode {
entity = createEntity(position, positionType);
}
count++;
- if (showModeParameter.isTicks()) {
+ if (showModeParameter.isFuse()) {
entity.setDisplayName(fuseTicks + "");
} else if (showModeParameter.isCount()) {
entity.setDisplayName(new HashSet<>(records).size() + "");
- } else if (showModeParameter.isTicksSinceStart()) {
- entity.setDisplayName((80 - fuseTicks) + tntPosition.getRecord().getOffset() + "");
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java
index 8314b640..fce2d789 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java
@@ -19,6 +19,7 @@
package de.steamwar.bausystem.features.tracer.show;
+import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.features.tracer.TNTPosition;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.shared.ShowMode;
@@ -38,6 +39,7 @@ public class Record {
@Getter
private final List tnt = new ArrayList<>();
private final Region region;
+ private final long startTicks = TPSUtils.currentTick.get();
public int size() {
return tnt.size();
@@ -47,8 +49,8 @@ public class Record {
tnt.forEach(tntRecord -> tntRecord.getPositions().forEach(traceShowMode::show));
}
- public TNTRecord spawn(long offset) {
- TNTRecord record = new TNTRecord(this, offset, region);
+ public TNTRecord spawn() {
+ TNTRecord record = new TNTRecord(this, region);
tnt.add(record);
return record;
}
@@ -57,18 +59,21 @@ public class Record {
tnt.clear();
}
- private void checkMicroMotion() {
+ private void checkMicroMotion(Vector explosionPosition) {
for (TNTRecord tntRecord : tnt) {
List positions = tntRecord.positions;
if (positions.isEmpty()) continue;
TNTPosition position = positions.get(positions.size() - 1);
+ if (position.isExploded()) continue;
+ if (position.getLocation().distanceSquared(explosionPosition) > 64) continue;
Vector velocity = position.getVelocity();
- if (velocity.getY() == 0 && (velocity.getX() != 0 || velocity.getZ() != 0) && (Math.abs(velocity.getX()) < 0.001 || Math.abs(velocity.getZ()) < 0.001)) {
+ if (velocity.getY() == 0 && ((velocity.getX() != 0 && Math.abs(velocity.getX()) < 0.001) || (velocity.getZ() != 0 && Math.abs(velocity.getZ()) < 0.001))) {
if (!tntRecord.hasMicroMotion) {
positions.forEach(tntPosition -> TraceShowManager.show(region, tntPosition));
}
tntRecord.hasMicroMotion = true;
+ position.setMicroMotion(true);
}
}
}
@@ -80,9 +85,6 @@ public class Record {
private Record record;
- @Getter
- private final long offset;
-
@Getter
private final Region region;
@@ -93,12 +95,15 @@ public class Record {
@Setter
private boolean inBuildArea = false;
+ @Getter
+ @Setter
+ private boolean inTestblockArea = false;
+
@Getter
private boolean hasMicroMotion = false;
- public TNTRecord(Record record, long offset, Region region) {
+ public TNTRecord(Record record, Region region) {
this.record = record;
- this.offset = offset;
this.region = region;
}
@@ -112,17 +117,17 @@ public class Record {
public void explode(TNTPrimed tntPrimed) {
add(tntPrimed, false, true);
- record.checkMicroMotion();
+ record.checkMicroMotion(tntPrimed.getLocation().toVector());
}
private void add(TNTPrimed tntPrimed, boolean source, boolean exploded) {
TNTPosition position;
if (positions.isEmpty()) {
- position = new TNTPosition(this, tntPrimed, null, tntPrimed.getVelocity(), null, source, exploded);
+ position = new TNTPosition(this, tntPrimed, TPSUtils.currentTick.get() - record.startTicks, null, tntPrimed.getVelocity(), null, source, exploded);
} else {
TNTPosition tntPosition = positions.get(positions.size() - 1);
Vector lastVelocity = tntPrimed.getLocation().toVector().clone().subtract(tntPosition.getLocation());
- position = new TNTPosition(this, tntPrimed, positions.get(positions.size() - 1).getLocation(), tntPrimed.getVelocity(), lastVelocity, source, exploded);
+ position = new TNTPosition(this, tntPrimed, TPSUtils.currentTick.get() - record.startTicks, positions.get(positions.size() - 1).getLocation(), tntPrimed.getVelocity(), lastVelocity, source, exploded);
}
positions.add(position);
TraceShowManager.show(region, position);
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameter.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameter.java
index 802c1eba..1da942eb 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameter.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameter.java
@@ -28,15 +28,20 @@ public class ShowModeParameter {
private boolean interpolateXZ = false;
private boolean sourceOnly = false;
private boolean explodeOnly = false;
- private boolean ticks = false;
+ private boolean fuse = false;
private boolean count = false;
private boolean buildDestroyOnly = false;
- private boolean ticksSinceStart = false;
+ private boolean testblockDestroyOnly = false;
private boolean microMotion = false;
+ private boolean microMotionLocation = false;
public void enableWater() {
this.water = true;
}
+
+ public void disableWater() {
+ this.water = false;
+ }
public void enableInterpolateY() {
this.interpolateY = true;
@@ -54,8 +59,8 @@ public class ShowModeParameter {
this.explodeOnly = true;
}
- public void enableTicks() {
- this.ticks = true;
+ public void enableFuse() {
+ this.fuse = true;
}
public void enableCount() {
@@ -66,11 +71,15 @@ public class ShowModeParameter {
this.buildDestroyOnly = true;
}
- public void enableTicksSinceStart() {
- this.ticksSinceStart = true;
+ public void enableTestblockDestroyOnly() {
+ this.testblockDestroyOnly = true;
}
public void enableMicroMotion() {
this.microMotion = true;
}
+
+ public void enableMicroMotionLocation() {
+ this.microMotionLocation = true;
+ }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameterType.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameterType.java
index a4f83958..51e1e9a5 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameterType.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameterType.java
@@ -36,13 +36,14 @@ public enum ShowModeParameterType {
showModeParameter.enableInterpolateY();
showModeParameter.enableInterpolateXZ();
}, Arrays.asList("-advanced", "-a"), "INTERPOLATE_Y", "INTERPOLATE_XZ"),
- SOURCE(ShowModeParameter::enableSourceOnly, Arrays.asList("-source", "-sourceonly", "-ignite"), "TICKS", "ADVANCED", "INTERPOLATE_Y", "INTERPOLATE_XZ", "WATER"),
- EXPLODE(ShowModeParameter::enableExplodeOnly, Arrays.asList("-explode", "-explodeonly"), "TICKS", "ADVANCED", "INTERPOLATE_Y", "INTERPOLATE_XZ", "WATER"),
- TICKS(ShowModeParameter::enableTicks, Arrays.asList("-ticks", "-t"), "EXPLODE", "SOURCE", "COUNT", "TICKS_SINCE_START"),
- COUNT(ShowModeParameter::enableCount, Arrays.asList("-count", "-c"), "TICKS", "TICKS_SINCE_START"),
- BUILD_DESTROY_ONLY(ShowModeParameter::enableBuildDestroyOnly, Arrays.asList("-builddestroy", "-builddestoryonly"), "WATER"),
- TICKS_SINCE_START(ShowModeParameter::enableTicksSinceStart, Arrays.asList("-tickssincestart", "-tss"), "TICKS", "COUNT"),
+ SOURCE(ShowModeParameter::enableSourceOnly, Arrays.asList("-source", "-sourceonly", "-ignite"), "FUSE", "ADVANCED", "INTERPOLATE_Y", "INTERPOLATE_XZ", "WATER"),
+ EXPLODE(ShowModeParameter::enableExplodeOnly, Arrays.asList("-explode", "-explodeonly"), "FUSE", "ADVANCED", "INTERPOLATE_Y", "INTERPOLATE_XZ", "WATER"),
+ FUSE(ShowModeParameter::enableFuse, Arrays.asList("-fuse", "-f"), "EXPLODE", "SOURCE", "COUNT"),
+ COUNT(ShowModeParameter::enableCount, Arrays.asList("-count", "-c"), "FUSE"),
+ BUILD_DESTROY_ONLY(ShowModeParameter::enableBuildDestroyOnly, Arrays.asList("-builddestroy", "-builddestoryonly"), "WATER", "TESTBLOCK_DESTROY_ONLY"),
+ TESTBLOCK_DESTROY_ONLY(ShowModeParameter::enableTestblockDestroyOnly, Arrays.asList("-testblockdestroy", "-testblockdestroyonly"), "WATER", "BUILD_DESTROY_ONLY"),
MICROMOTION(ShowModeParameter::enableMicroMotion, Arrays.asList("-micromotion", "-micro", "-m")),
+ MICROMOTION_LOCATION(ShowModeParameter::enableMicroMotionLocation, Arrays.asList("-micromotionloc", "-microloc", "-mloc", "-micromotionlocation", "-microlocation", "-mlocation")),
;
@Getter
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java
index 993e4fdd..91bc2272 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java
@@ -19,46 +19,21 @@
package de.steamwar.bausystem.features.tracer.show;
-import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tracer.TNTPosition;
import de.steamwar.bausystem.features.tracer.record.Recorder;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.shared.ShowMode;
import lombok.experimental.UtilityClass;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
import java.util.*;
import java.util.function.Predicate;
-import java.util.function.Supplier;
import java.util.stream.Collectors;
@UtilityClass
public class StoredRecords {
- private static final Map>> isolatedTNT = new HashMap<>();
- private static final Map> replayTime = new HashMap<>();
- private static final Map>> replayLoops = new HashMap<>();
private static final Map> records = new HashMap<>();
- static {
- BauSystem.runTaskTimer(BauSystem.getInstance(), () -> {
- replayLoops.forEach((region, playerSupplierMap) -> {
- playerSupplierMap.forEach((player, integerSupplier) -> {
- int tick = integerSupplier.get();
- replayTime.computeIfAbsent(region, __ -> new HashMap<>()).put(player, tick);
- TraceShowManager.reshow(region, player);
- });
- });
- }, 1, 1);
- }
-
- static void cleanup(Player player) {
- isolatedTNT.forEach((region, playerListMap) -> playerListMap.remove(player));
- replayTime.forEach((region, playerIntegerMap) -> playerIntegerMap.remove(player));
- replayLoops.forEach((region, playerIntegerMap) -> playerIntegerMap.remove(player));
- }
-
public static void add(Region region, Record record) {
records.computeIfAbsent(region, k -> new ArrayList<>()).add(record);
}
@@ -83,117 +58,13 @@ public class StoredRecords {
return records.getOrDefault(region, Collections.emptyList());
}
- public Record.TNTRecord getRecord(UUID id) {
- return records.values().stream()
- .flatMap(Collection::stream)
- .map(Record::getTnt)
- .flatMap(Collection::stream)
- .filter(tntRecord -> tntRecord.getId().equals(id))
- .findFirst()
- .orElse(null);
- }
-
- public static boolean isIsolated(Player p, Record.TNTRecord tntRecord) {
- return isolatedTNT.values()
- .stream()
- .filter(map -> map.containsKey(p))
- .anyMatch(map -> map.get(p).contains(tntRecord));
- }
-
- public static void toggleIsolate(Player p, Record.TNTRecord tntRecord) {
- List tntRecords = isolatedTNT.computeIfAbsent(tntRecord.getRegion(), k -> new HashMap<>())
- .computeIfAbsent(p, k -> new ArrayList<>());
- if (tntRecords.contains(tntRecord)) {
- tntRecords.remove(tntRecord);
- if (tntRecords.isEmpty()) {
- isolatedTNT.get(tntRecord.getRegion()).remove(p);
- if (isolatedTNT.get(tntRecord.getRegion()).isEmpty()) {
- isolatedTNT.remove(tntRecord.getRegion());
- }
- }
- } else {
- tntRecords.add(tntRecord);
- }
- TraceShowManager.reshow(tntRecord.getRegion(), p);
- }
-
- public static void hideIsolated(Region region) {
- isolatedTNT.remove(region);
- }
-
- public static void hideIsolated(Region region, Player player) {
- Map> regionalIsolatedTNT = isolatedTNT.get(region);
- if (regionalIsolatedTNT == null) {
- return;
- }
- regionalIsolatedTNT.remove(player);
- }
-
- public static int getReplayTime(Region region, Player player) {
- return replayTime.computeIfAbsent(region, k -> new HashMap<>()).getOrDefault(player, -1);
- }
-
- public static void removeReplayTime(Region region) {
- replayTime.remove(region);
- replayLoops.remove(region);
- }
-
- public static void removeReplayTime(Region region, Player player) {
- Map regionalReplayTime = replayTime.get(region);
- if (regionalReplayTime != null) {
- regionalReplayTime.remove(player);
- }
- Map> regionalReplayLoops = replayLoops.get(region);
- if (regionalReplayLoops != null) {
- regionalReplayLoops.remove(player);
- }
- }
-
- public static void setReplayTime(Region region, Player player, int time) {
- if (time < 0) {
- removeReplayTime(region, player);
- return;
- }
- replayTime.computeIfAbsent(region, k -> new HashMap<>()).put(player, time);
- TraceShowManager.reshow(region, player);
-
- Map> regionalReplayLoops = replayLoops.get(region);
- if (regionalReplayLoops != null) {
- regionalReplayLoops.remove(player);
- }
- }
-
- public static void setReplayLoop(Region region, Player player, Supplier loop) {
- replayLoops.computeIfAbsent(region, k -> new HashMap<>()).put(player, loop);
- }
-
- static Predicate replayTimeFilter(Region region, Player player) {
- Predicate replayTimeFilter = tntPosition -> true;
- if (replayTime.containsKey(region) && replayTime.get(region).containsKey(player)) {
- int time = replayTime.get(region).get(player);
- replayTimeFilter = tntPosition -> (80 - tntPosition.getFuseTicks()) + tntPosition.getRecord().getOffset() == time;
- }
- return replayTimeFilter;
- }
-
- static void show(Region region, Player player, ShowMode traceShowMode) {
- Predicate replayTimeFilter = replayTimeFilter(region, player);
- if (isolatedTNT.containsKey(region) && isolatedTNT.get(region).containsKey(player)) {
- isolatedTNT.get(region).get(player).forEach(record -> {
- record.getPositions()
- .stream()
- .filter(replayTimeFilter)
+ static void show(Region region, Predicate traceShowFilter, ShowMode traceShowMode) {
+ records.getOrDefault(region, new ArrayList<>()).forEach(record -> {
+ record.getTnt().forEach(tntRecord -> {
+ tntRecord.getPositions().stream()
+ .filter(traceShowFilter)
.forEach(traceShowMode::show);
});
- } else {
- records.getOrDefault(region, new ArrayList<>()).forEach(record -> {
- record.getTnt().forEach(tntRecord -> {
- tntRecord.getPositions()
- .stream()
- .filter(replayTimeFilter)
- .forEach(traceShowMode::show);
- });
- });
- }
+ });
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java
index 5cebaa1c..e3745391 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java
@@ -23,17 +23,13 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tracer.TNTPosition;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.shared.ShowMode;
-import de.steamwar.entity.REntity;
import org.bukkit.Bukkit;
-import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
@@ -42,40 +38,36 @@ public class TraceShowManager implements Listener {
}
private static final Map>> showModes = new HashMap<>();
+ private static final Map>> showFilters = new HashMap<>();
public static void show(Player player, ShowMode traceShowMode) {
- hide(player);
-
Region region = Region.getRegion(player.getLocation());
+ _hide(region, player, true);
+
Map> regionalShowModes = showModes.computeIfAbsent(region, __ -> new HashMap<>());
regionalShowModes.put(player, traceShowMode);
- StoredRecords.show(region, player, traceShowMode);
+ StoredRecords.show(region, getShowFilter(player, region), traceShowMode);
}
public static void hide(Player player) {
Region region = Region.getRegion(player.getLocation());
- Map> regionalShowModes = showModes.get(region);
- if (regionalShowModes == null) {
- return;
- }
- ShowMode showMode = regionalShowModes.remove(player);
- if (showMode == null) {
- return;
- }
- showMode.hide();
+ _hide(region, player, true);
+
+ showFilters.getOrDefault(region, new HashMap<>()).remove(player);
}
- public static void reshow(Region region, Player p) {
- Map> regionalShowModes = showModes.get(region);
- if (regionalShowModes == null) {
- return;
+ public static void setShowFilter(Player player, Predicate showFilter) {
+ Region region = Region.getRegion(player.getLocation());
+ Map> regionShowFilters = showFilters.computeIfAbsent(region, __ -> new HashMap<>());
+ if (showFilter == null) {
+ regionShowFilters.remove(player);
+ } else {
+ regionShowFilters.put(player, showFilter);
}
- ShowMode showMode = regionalShowModes.get(p);
- if (showMode == null) {
- return;
- }
- showMode.hide();
- StoredRecords.show(region, p, showMode);
+
+ _hide(region, player, false);
+ ShowMode showMode = showModes.computeIfAbsent(region, __ -> new HashMap<>()).computeIfAbsent(player, __ -> new EntityShowMode(player, new ShowModeParameter(), 10));
+ StoredRecords.show(region, getShowFilter(player, region), showMode);
}
public static void reshow(Region region) {
@@ -85,10 +77,31 @@ public class TraceShowManager implements Listener {
}
for (Map.Entry> entry : regionalShowModes.entrySet()) {
entry.getValue().hide();
- StoredRecords.show(region, entry.getKey(), entry.getValue());
+ StoredRecords.show(region, getShowFilter(entry.getKey(), region), entry.getValue());
}
}
+ private static void _hide(Region region, Player player, boolean remove) {
+ Map> regionalShowModes = showModes.get(region);
+ if (regionalShowModes == null) {
+ return;
+ }
+ ShowMode showMode;
+ if (remove) {
+ showMode = regionalShowModes.remove(player);
+ } else {
+ showMode = regionalShowModes.get(player);
+ }
+ if (showMode == null) {
+ return;
+ }
+ showMode.hide();
+ }
+
+ private static Predicate getShowFilter(Player player, Region region) {
+ return showFilters.getOrDefault(region, new HashMap<>()).getOrDefault(player, tntPosition -> true);
+ }
+
/* Only to be called by record */
static void show(Region region, TNTPosition tnt) {
Map> regionalShowModes = showModes.get(region);
@@ -96,8 +109,9 @@ public class TraceShowManager implements Listener {
return;
}
regionalShowModes.forEach((player, tntPositionShowMode) -> {
- Predicate replayTimeFilter = StoredRecords.replayTimeFilter(region, player);
- if (replayTimeFilter.test(tnt)) tntPositionShowMode.show(tnt);
+ if (getShowFilter(player, region).test(tnt)) {
+ tntPositionShowMode.show(tnt);
+ }
});
}
@@ -121,6 +135,8 @@ public class TraceShowManager implements Listener {
ShowMode showMode = playerShowModeMap.remove(event.getPlayer());
if (showMode != null) showMode.hide();
});
- StoredRecords.cleanup(event.getPlayer());
+ showFilters.forEach((region, playerPredicateMap) -> {
+ playerPredicateMap.remove(event.getPlayer());
+ });
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java
new file mode 100644
index 00000000..ab213c83
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java
@@ -0,0 +1,147 @@
+package de.steamwar.bausystem.features.util;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.SWUtils;
+import de.steamwar.bausystem.features.script.ScriptCommand;
+import de.steamwar.bausystem.features.script.ScriptRunner;
+import de.steamwar.command.PreviousArguments;
+import de.steamwar.command.SWCommand;
+import de.steamwar.command.TypeMapper;
+import de.steamwar.linkage.Linked;
+import org.bukkit.Bukkit;
+import org.bukkit.NamespacedKey;
+import org.bukkit.command.CommandMap;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataType;
+
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Linked
+public class BindCommand extends SWCommand implements Listener {
+
+ @Linked
+ public static class UnBindCommand extends SWCommand {
+
+ public UnBindCommand() {
+ super("unbind");
+ }
+
+ @Register
+ public void generic(Player player) {
+ bindInternal(player);
+ }
+ }
+
+ private static final CommandMap commandMap;
+
+ static {
+ Field knownCommandsField;
+ try {
+ knownCommandsField = Bukkit.getServer().getClass().getDeclaredField("commandMap");
+ knownCommandsField.setAccessible(true);
+ commandMap = (CommandMap)knownCommandsField.get(Bukkit.getServer());
+ } catch (IllegalAccessException | NoSuchFieldException var2) {
+ Bukkit.shutdown();
+ throw new SecurityException("Oh shit. Commands cannot be registered.", var2);
+ }
+ }
+
+ private static final NamespacedKey KEY = SWUtils.getNamespaceKey("command");
+
+ public BindCommand() {
+ super("bind");
+ }
+
+ @Register(description = "OTHER_BIND_HELP")
+ public void bind(Player player, @Mapper("command") @ErrorMessage("OTHER_BIND_ERROR") String... command) {
+ bindInternal(player, command);
+ }
+
+ private static void bindInternal(Player player, String... command) {
+ ItemStack item = player.getInventory().getItemInMainHand();
+ ItemMeta meta = item.getItemMeta();
+ if (meta == null) {
+ BauSystem.MESSAGE.send("OTHER_BIND_UNBINDABLE", player);
+ return;
+ }
+
+ if (command.length != 0) {
+ String commandText = String.join(" ", command);
+ meta.getPersistentDataContainer().set(KEY, PersistentDataType.STRING, commandText);
+ meta.setDisplayName(BauSystem.MESSAGE.parse("OTHER_BIND_LORE", player, commandText));
+ BauSystem.MESSAGE.send("OTHER_BIND_MESSAGE_BIND", player, commandText);
+ } else {
+ meta.getPersistentDataContainer().remove(KEY);
+ meta.setDisplayName(null);
+ BauSystem.MESSAGE.send("OTHER_BIND_MESSAGE_UNBIND", player);
+ }
+ item.setItemMeta(meta);
+ player.getInventory().setItemInMainHand(item);
+ }
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ if (!event.hasItem()) return;
+ ItemStack itemStack = event.getItem();
+ ItemMeta meta = itemStack.getItemMeta();
+ if (meta == null) {
+ return;
+ }
+
+ String command = meta.getPersistentDataContainer().get(KEY, PersistentDataType.STRING);
+ if (command == null) {
+ return;
+ }
+
+ 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);
+ }, 1);
+ }
+
+ @Mapper(value = "command", local = true)
+ public TypeMapper getCommandMapper() {
+ return new TypeMapper() {
+ @Override
+ public String map(CommandSender sender, PreviousArguments previousArguments, String s) {
+ return s;
+ }
+
+ @Override
+ public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
+ if (previousArguments.mappedArgs.length == 0) return null;
+ Object[] args = (Object[]) previousArguments.mappedArgs[previousArguments.mappedArgs.length - 1];
+ List tabCompletes;
+ if (args.length == 0) {
+ tabCompletes = commandMap.tabComplete(sender, "");
+ } else {
+ tabCompletes = commandMap.tabComplete(sender, Arrays.stream(args).map(Objects::toString).collect(Collectors.joining(" ")) + " ");
+ }
+ if (tabCompletes == null) return null;
+ if (args.length == 0) {
+ tabCompletes = tabCompletes.stream()
+ .map(t -> t.substring(1))
+ .filter(t -> !t.equals("bind"))
+ .collect(Collectors.toList());
+ tabCompletes.addAll(ScriptRunner.getCommandsOfPlayer((Player) sender));
+ return tabCompletes.stream()
+ .filter(t -> !t.contains(":"))
+ .collect(Collectors.toList());
+ }
+ return tabCompletes;
+ }
+ };
+ }
+}
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 e7efd6dd..6f7a92c7 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.util;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.shared.EnumDisplay;
import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand;
@@ -39,6 +40,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.function.BiConsumer;
@@ -185,6 +187,9 @@ public class MaterialCommand extends SWCommand implements Listener {
}
});
SWListInv materialSWListInv = new SWListInv<>(p, BauSystem.MESSAGE.parse("MATERIAL_INV_NAME", p, swListEntries.size(), MaterialLazyInit.materialData.size()), false, swListEntries, (clickType, material) -> {
+ if (material.isItem()) {
+ SWUtils.giveItemToPlayer(p, new ItemStack(material, 1));
+ }
});
materialSWListInv.setItem(49, new SWItem(Material.NAME_TAG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH", p), clickType -> {
searchGUI(p);
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 281b159f..15f0a005 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java
@@ -20,11 +20,15 @@
package de.steamwar.bausystem.features.util;
import de.steamwar.bausystem.BauSystem;
+import de.steamwar.entity.REntityServer;
+import de.steamwar.entity.RFallingBlockEntity;
import de.steamwar.linkage.Linked;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import net.md_5.bungee.api.ChatMessageType;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
@@ -37,10 +41,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@Linked
@@ -59,6 +60,7 @@ public class PistonCalculator implements Listener {
boolean pulling = blockType == Material.STICKY_PISTON && (clickedBlock.getRelative(piston.getFacing()).getType() == Material.AIR || piston.isExtended());
CalculationResult result = calc(clickedBlock, piston.getFacing(), (pulling ? piston.getFacing().getOppositeFace() : piston.getFacing()));
+ result.entityServer.addPlayer(event.getPlayer());
BauSystem.MESSAGE.sendPrefixless("PISTON_INFO", event.getPlayer(), ChatMessageType.ACTION_BAR, result.unmovable ? "§c" : (result.tooMany ? "§e" : "§a"), result.amount);
}
@@ -66,7 +68,7 @@ public class PistonCalculator implements Listener {
private CalculationResult calc(Block origin, BlockFace facing, BlockFace direction) {
Set blockSet = new HashSet<>();
- AtomicBoolean unmovable = new AtomicBoolean();
+ Set unmovable = new HashSet<>();
Block calcOrigin = origin;
if (facing != direction) calcOrigin = origin.getRelative(facing, 3);
@@ -95,21 +97,30 @@ public class PistonCalculator implements Listener {
blockSet.remove(origin);
if (facing != direction) blockSet.remove(origin.getRelative(facing, 1));
- return new CalculationResult(blockSet.size(), blockSet.size() > 12, unmovable.get());
+
+ REntityServer entityServer = new REntityServer();
+ for (Location loc : unmovable) {
+ RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(entityServer, loc.clone().add(0.5, 0, 0.5), Material.RED_STAINED_GLASS);
+ rFallingBlockEntity.setGlowing(true);
+ rFallingBlockEntity.setNoGravity(true);
+ rFallingBlockEntity.setInvisible(true);
+ }
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), entityServer::close, 20);
+ return new CalculationResult(blockSet.size(), blockSet.size() > 12, !unmovable.isEmpty(), entityServer);
}
- private void calcDirection(Block origin, Block blockOrigin, Block calcOrigin, Block ignore, BlockFace facing, BlockFace direction, Set blockSet, List toCalc, AtomicBoolean unmovable) {
- for (int i = 1; i < 13; i++) {
+ private void calcDirection(Block origin, Block blockOrigin, Block calcOrigin, Block ignore, BlockFace facing, BlockFace direction, Set blockSet, List toCalc, Set unmovable) {
+ for (int i = 1; i < 24; i++) {
Block block = calcOrigin.getRelative(direction, i);
if (block.equals(ignore)) return;
if (block.getPistonMoveReaction() == PistonMoveReaction.BREAK) return;
if (!isPiston(block) && (block.getPistonMoveReaction() == PistonMoveReaction.BLOCK || block.getPistonMoveReaction() == PistonMoveReaction.IGNORE || block.getState() instanceof TileState)) {
- unmovable.set(true);
+ unmovable.add(block.getLocation());
return;
}
if (block.getType().isAir()) return;
if (facing == direction && block.equals(blockOrigin)) {
- unmovable.set(true);
+ unmovable.add(block.getLocation());
return;
}
if (facing != direction && (block.equals(origin) || block.getRelative(facing.getOppositeFace()).equals(origin))) return;
@@ -127,10 +138,10 @@ public class PistonCalculator implements Listener {
@AllArgsConstructor
@Getter
- @ToString
private static class CalculationResult {
private int amount;
private boolean tooMany;
private boolean unmovable;
+ private REntityServer entityServer;
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditFrom20.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditFrom20.java
new file mode 100644
index 00000000..7956a3ef
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditFrom20.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.world;
+
+import com.comphenix.tinyprotocol.Reflection;
+import com.comphenix.tinyprotocol.TinyProtocol;
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.utils.PlaceItemUtils;
+import de.steamwar.linkage.Linked;
+import de.steamwar.linkage.MinVersion;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.block.Sign;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.block.data.Directional;
+import org.bukkit.block.data.Rotatable;
+import org.bukkit.block.sign.Side;
+import org.bukkit.block.sign.SignSide;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.util.Vector;
+
+@Linked
+@MinVersion(20)
+public class SignEditFrom20 implements Listener {
+
+ private static final Class> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
+ private static final Class> craftBlock = Reflection.getClass("{obc}.block.CraftBlock");
+ private static final Class> craftWorld = Reflection.getClass("{obc}.CraftWorld");
+ private static final Class> generatorAccess = Reflection.getClass("{nms.world.level}.GeneratorAccess");
+ private static final Reflection.MethodInvoker getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
+ private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
+ private static final Reflection.MethodInvoker at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
+
+ private static final Class> openSign = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutOpenSignEditor");
+ private static final Reflection.FieldAccessor> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
+ private static final Reflection.FieldAccessor> sideFieldAccessor = Reflection.getField(openSign, boolean.class, 0);
+
+ private static final Class> updateSign = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUpdateSign");
+ private static final Reflection.FieldAccessor> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
+ private static final Reflection.FieldAccessor stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
+
+ @EventHandler
+ public void editSign(PlayerInteractEvent event) {
+ if (event.getClickedBlock() == null || !event.getClickedBlock().getType().name().contains("SIGN")) return;
+ if (event.getAction() == Action.RIGHT_CLICK_BLOCK && !event.getPlayer().isSneaking()) {
+ PlaceItemUtils.placeItem(event.getPlayer(), event.getItem(), event.getClickedBlock(), event.getBlockFace(), event.getHand(), false, true, false, true);
+ event.setCancelled(true);
+ }
+ if (!event.getPlayer().isSneaking()) return;
+
+ if (event.getAction() == Action.RIGHT_CLICK_BLOCK && (event.getItem() == null || event.getItem().getType() == Material.AIR) || event.getAction() == Action.LEFT_CLICK_BLOCK) {
+ event.setCancelled(true);
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ edit(event.getPlayer(), event.getClickedBlock());
+ }, 1);
+ }
+ }
+
+ private void edit(Player player, Block block) {
+ Sign sign = (Sign) block.getState();
+ Side side = signSide(player, block);
+ SignSide signSide = sign.getSide(side);
+ String[] lines = signSide.getLines();
+ for (int i = 0; i < lines.length; i++) {
+ signSide.setLine(i, lines[i].replace('§', '&'));
+ }
+ sign.update(true);
+
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ Object openSignObject = Reflection.newInstance(openSign);
+ blockPositionFieldAccessor.set(openSignObject, getPosition.invoke(block));
+ sideFieldAccessor.set(openSignObject, side == Side.FRONT);
+ TinyProtocol.instance.sendPacket(player, openSignObject);
+ }, 1);
+
+ }
+
+ private Side signSide(Player entity, Block sign) {
+ Vector vector = entity.getEyeLocation().toVector().subtract(sign.getLocation().add(0.5, 0.5, 0.5).toVector());
+ BlockData blockData = sign.getBlockData();
+
+ BlockFace blockFace = BlockFace.NORTH;
+ if (blockData instanceof Directional) {
+ blockFace = ((Directional) blockData).getFacing();
+ } else if (blockData instanceof Rotatable) {
+ blockFace = ((Rotatable) blockData).getRotation();
+ }
+
+ Vector signDirection = new Vector(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ());
+ return vector.dot(signDirection) > 0 ? Side.FRONT : Side.BACK;
+ }
+
+ {
+ TinyProtocol.instance.addFilter(updateSign, (player, o) -> {
+ Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
+ String[] lines = stringFieldAccessor.get(o);
+
+ Block signLoc = (Block) at.invoke(null, getWorldHandle.invoke(player.getWorld()), getBlockPositionFieldAccessor.get(o));
+ if (!signLoc.getType().name().contains("SIGN"))
+ return;
+
+ Sign sign = ((Sign) signLoc.getState());
+ SignSide signSide = sign.getSide(signSide(player, signLoc));
+ for (int i = 0; i < lines.length; i++) {
+ signSide.setLine(i, ChatColor.translateAlternateColorCodes('&', lines[i]));
+ }
+ sign.update(true);
+ });
+ return o;
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEdit.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditUntil19.java
similarity index 97%
rename from BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEdit.java
rename to BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditUntil19.java
index 2f8e154e..19184032 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEdit.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditUntil19.java
@@ -23,6 +23,7 @@ import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.linkage.Linked;
+import de.steamwar.linkage.MaxVersion;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -35,7 +36,8 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
@Linked
-public class SignEdit implements Listener {
+@MaxVersion(19)
+public class SignEditUntil19 implements Listener {
private static final Class> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
private static final Class> craftBlock = Reflection.getClass("{obc}.block.CraftBlock");
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java
index 1a9387c6..ff466080 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java
@@ -131,6 +131,7 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
+ if (!event.hasItem() || event.getItem().getType().isAir()) return;
Region region = Region.getRegion(event.getPlayer().getLocation());
if (!(hidden.containsKey(region) && hidden.get(region).contains(event.getPlayer()))) {
return;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/region/Region.java b/BauSystem_Main/src/de/steamwar/bausystem/region/Region.java
index dd234713..c6f8b5c7 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/region/Region.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/region/Region.java
@@ -445,22 +445,18 @@ public class Region {
pasteBuilder.pastePoint(minPointBuild.add(prototype.getBuild().getSizeX() / 2, 0, prototype.getBuild().getSizeZ() / 2));
break;
case TESTBLOCK:
- Point pastePoint = minPointTestblock.add(prototype.getTestblock().getSizeX() / 2, 0, 0);
- if (!pasteBuilder.getClipboardProvider().is(PasteBuilder.SchematicProvider.class)) {
- pastePoint = pastePoint.add(0, 0, prototype.getTestblock().getSizeZ() / 2);
- } else {
- int dz = Math.abs(pasteBuilder.getClipboard().getOrigin().getZ() - pasteBuilder.getClipboard().getMinimumPoint().getZ());
- if (dz < 2 || dz > prototype.getTestblock().getSizeZ()) {
- pastePoint = pastePoint.add(0, 0, prototype.getTestblock().getSizeZ() / 2);
- } else if (pasteBuilder.getClipboard().getDimensions().getZ() != prototype.getTestblock().getSizeZ()) {
- pastePoint = pastePoint.add(0, 0, pasteBuilder.getClipboard().getDimensions().getZ() / 2 - (pasteBuilder.getClipboard().getOrigin().getZ() - pasteBuilder.getClipboard().getMinimumPoint().getZ()) - 1);
- } else {
- pastePoint = pastePoint.add(0, 0, prototype.getTestblock().getSizeZ() / 2);
- }
+ Point pastePoint = minPointTestblock.add(prototype.getTestblock().getSizeX() / 2, 0, prototype.getTestblock().getSizeZ() / 2);
+ if (pasteBuilder.getClipboardProvider().is(PasteBuilder.SchematicProvider.class)) {
SchematicType schematicType = pasteBuilder.getClipboardProvider().as(PasteBuilder.SchematicProvider.class).getSchematic().getSchemtype();
if (schematicType.getKuerzel().equalsIgnoreCase("wg")) {
pastePoint = pastePoint.add(0, 0, 1);
}
+ if (schematicType.getKuerzel().equalsIgnoreCase("ws")) {
+ pastePoint = pastePoint.add(-1, 0, 1);
+ }
+ if (schematicType.getKuerzel().equalsIgnoreCase("as")) {
+ pastePoint = pastePoint.add(-1, 0, 1);
+ }
}
pasteBuilder.pastePoint(pastePoint);
break;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/region/flags/flagvalues/TNTMode.java b/BauSystem_Main/src/de/steamwar/bausystem/region/flags/flagvalues/TNTMode.java
index f6f2706d..9b05d6b5 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/region/flags/flagvalues/TNTMode.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/region/flags/flagvalues/TNTMode.java
@@ -29,7 +29,8 @@ public enum TNTMode implements Flag.Value {
ALLOW("FLAG_TNT_ALLOW"),
DENY("FLAG_TNT_DENY"),
- ONLY_TB("FLAG_TNT_ONLY_TB");
+ ONLY_TB("FLAG_TNT_ONLY_TB"),
+ ONLY_BUILD("FLAG_TNT_ONLY_BUILD");
private static TNTMode[] values;
private final String chatValue;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/PasteBuilder.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/PasteBuilder.java
index 3dddc008..b0479f90 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/utils/PasteBuilder.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/PasteBuilder.java
@@ -183,7 +183,10 @@ public class PasteBuilder {
clipboard.setBlock(blockVector3, air);
return;
}
- clipboard.setBlock(blockVector3, waterloggedRemover.applyBlock(blockVector3));
+ baseBlock = waterloggedRemover.applyBlock(blockVector3);
+ if (baseBlock != air) {
+ clipboard.setBlock(blockVector3, baseBlock);
+ }
});
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/PlaceItemUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/PlaceItemUtils.java
new file mode 100644
index 00000000..2f83c416
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/PlaceItemUtils.java
@@ -0,0 +1,552 @@
+/*
+ * 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.comphenix.tinyprotocol.Reflection;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.experimental.UtilityClass;
+import org.bukkit.*;
+import org.bukkit.block.*;
+import org.bukkit.block.data.*;
+import org.bukkit.block.data.type.Hopper;
+import org.bukkit.block.data.type.Observer;
+import org.bukkit.block.data.type.*;
+import org.bukkit.entity.Player;
+import org.bukkit.event.block.BlockCanBuildEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.*;
+import org.bukkit.util.RayTraceResult;
+import org.bukkit.util.Vector;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+
+@UtilityClass
+public class PlaceItemUtils {
+
+ // https://github.com/Articdive/ArticData/blob/1.20.1/1_20_1_tags/1_20_1_block_tags.json
+ // #minecraft:replaceable
+ private static final Set replaceables;
+
+ static {
+ replaceables = new HashSet<>(Arrays.asList(
+ "minecraft:air",
+ "minecraft:water",
+ "minecraft:lava",
+ "minecraft:grass",
+ "minecraft:fern",
+ "minecraft:dead_bush",
+ "minecraft:seagrass",
+ "minecraft:tall_seagrass",
+ "minecraft:fire",
+ "minecraft:soul_fire",
+ "minecraft:snow",
+ "minecraft:vine",
+ "minecraft:glow_lichen",
+ "minecraft:light",
+ "minecraft:tall_grass",
+ "minecraft:large_fern",
+ "minecraft:structure_void",
+ "minecraft:void_air",
+ "minecraft:cave_air",
+ "minecraft:bubble_column",
+ "minecraft:warped_roots",
+ "minecraft:nether_sprouts",
+ "minecraft:crimson_roots",
+ "minecraft:hanging_roots"))
+ .stream()
+ .map(s -> s.substring(10))
+ .map(String::toUpperCase)
+ .collect(Collectors.toSet());
+ }
+
+ private static final Map ITEM_MATERIAL_TO_BLOCK_MATERIAL = new HashMap<>();
+ private static final Map BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL = new HashMap<>();
+
+ static {
+ for (Material material : Material.values()) {
+ if (!material.isBlock()) continue;
+ if (material.isLegacy()) continue;
+ BlockData blockData = material.createBlockData();
+ Material placementMaterial = blockData.getPlacementMaterial();
+ if (material == placementMaterial) continue;
+ if (placementMaterial == Material.AIR) continue;
+ if (placementMaterial.isItem() && !placementMaterial.isBlock()) {
+ ITEM_MATERIAL_TO_BLOCK_MATERIAL.put(placementMaterial, material);
+ }
+ if (material.name().contains("WALL")) {
+ BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(placementMaterial, material);
+ }
+ }
+ }
+
+ private static final Class> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
+ private static final Reflection.ConstructorInvoker blockPositionConstructor = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
+ private static final Class> craftBlock = Reflection.getClass("{obc}.block.CraftBlockState");
+ private static final Class> craftWorld = Reflection.getClass("{obc}.CraftWorld");
+ private static final Reflection.FieldAccessor> positionAccessor = Reflection.getField(craftBlock, blockPosition, 0);
+ private static final Reflection.FieldAccessor> worldAccessor = Reflection.getField(craftBlock, craftWorld, 0);
+
+ /**
+ * Attempt to place an {@link ItemStack} the {@link Player} is holding against a {@link Block} inside the World.
+ * This can be easily used inside the {@link org.bukkit.event.player.PlayerInteractEvent} to mimik placing a
+ * block without any minecraft related GUI's etc. executing.
+ *
+ * @param player the Player placing the block
+ * @param itemStack the ItemStack to be placed
+ * @param against the Block at which the player aims (does not need to be in range of the player)
+ * @param againstSide the BlockFace the player aims
+ * @param hand the Hand the player is using
+ * @param force allow illegal states to be created by placing the block
+ * @param applyPhysics apply physics while placing the block
+ * @param rotateAway rotate everything in the opposite direction, so a block facing the Player will face away, and the other way round
+ * @param playSound enables sound of placing
+ */
+ public PlaceItemResult placeItem(Player player, ItemStack itemStack, Block against, BlockFace againstSide, EquipmentSlot hand, boolean force, boolean applyPhysics, boolean rotateAway, boolean playSound) {
+ // If the ItemStack is null or air we cannot place it
+ if (itemStack == null) return PlaceItemResult.NO_ITEM_HELD;
+ if (itemStack.getType().isAir()) return PlaceItemResult.NO_ITEM_HELD;
+
+ // This Block should be replaced by the new Block
+ Block block = against.getRelative(againstSide);
+
+ // We cannot place any Item that is not also a Block, this is checked by testing for the ItemMeta
+ ItemMeta itemMeta = itemStack.getItemMeta();
+ if (!(itemMeta instanceof BlockDataMeta)) {
+ return PlaceItemResult.NO_BLOCK_ITEM_HELD;
+ }
+
+ BlockDataMeta blockDataMeta = (BlockDataMeta) itemMeta;
+
+ // Converting the Item Material to a Block Material
+ // e.g. Material.REDSTONE -> Material.REDSTONE_WIRE
+ Material typeToPlace = ITEM_MATERIAL_TO_BLOCK_MATERIAL.getOrDefault(itemStack.getType(), itemStack.getType());
+
+ BlockData blockData = null;
+ AtomicBoolean usedForcePlace = new AtomicBoolean();
+ if (againstSide == BlockFace.NORTH || againstSide == BlockFace.SOUTH || againstSide == BlockFace.EAST || againstSide == BlockFace.WEST) {
+ // Try Wall Placement first
+ blockData = toBlockData(player, blockDataMeta, BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.getOrDefault(typeToPlace, typeToPlace));
+ if (blockData != null && !canPlace(block, blockData, force, usedForcePlace)) {
+ // Check if default Rotation from input could be valid
+ BlockFace rotation = getRotation(blockData);
+ setRotation(blockData, againstSide);
+ if (!canPlace(block, blockData, force, usedForcePlace)) {
+ setRotation(blockData, rotation);
+ }
+ }
+ }
+
+ // Try default Placement
+ if (blockData == null || !canPlace(block, blockData, force, usedForcePlace)) {
+ blockData = toBlockData(player, blockDataMeta, typeToPlace);
+ }
+
+ if (blockData != null && !canPlace(block, blockData, force, usedForcePlace)) {
+ if (blockData instanceof FaceAttachable) {
+ // FaceAttachable Blocks should be placed on the Ceiling/Floor if possible
+ // This applies mainly to Lever and Buttons
+ FaceAttachable faceAttachable = (FaceAttachable) blockData;
+ boolean topFirst = isHitHalfTop(player);
+ faceAttachable.setAttachedFace(topFirst ? FaceAttachable.AttachedFace.CEILING : FaceAttachable.AttachedFace.FLOOR);
+ if (!canPlace(block, blockData, force, usedForcePlace)) {
+ faceAttachable.setAttachedFace(topFirst ? FaceAttachable.AttachedFace.FLOOR : FaceAttachable.AttachedFace.CEILING);
+ }
+ if (!canPlace(block, blockData, force, usedForcePlace)) {
+ return PlaceItemResult.NO_VALID_PLACEMENT;
+ }
+ }
+ }
+
+ if (blockData == null) return PlaceItemResult.NO_BLOCK_ITEM_HELD;
+
+ // Placing a Block inside of Water should set it to Waterlogged
+ if (blockData instanceof Waterlogged) {
+ ((Waterlogged) blockData).setWaterlogged(block.getType() == Material.WATER);
+ }
+
+ if (blockData instanceof Slab) {
+ // Slabs can be set at Top or Bottom
+ ((Slab) blockData).setType(isHitHalfTop(player) ? Slab.Type.TOP : Slab.Type.BOTTOM);
+ } else if (blockData instanceof Stairs) {
+ // Stairs can be set at Top or Bottom
+ ((Stairs) blockData).setHalf(isHitHalfTop(player) ? Bisected.Half.TOP : Bisected.Half.BOTTOM);
+ } else if (blockData instanceof TrapDoor) {
+ // TrapDoors can be set at Top or Bottom
+ ((TrapDoor) blockData).setHalf(isHitHalfTop(player) ? Bisected.Half.TOP : Bisected.Half.BOTTOM);
+ } else if (blockData instanceof Chain) {
+ // Chains are always rotated against the block you place against
+ Orientable orientable = (Orientable) blockData;
+ switch (againstSide) {
+ case EAST:
+ case WEST:
+ orientable.setAxis(Axis.X);
+ break;
+ case UP:
+ case DOWN:
+ orientable.setAxis(Axis.Y);
+ break;
+ case NORTH:
+ case SOUTH:
+ orientable.setAxis(Axis.Z);
+ break;
+ }
+ } else if (blockData instanceof Hopper && (againstSide == BlockFace.UP || againstSide == BlockFace.DOWN)) {
+ // Placing at the Top or Bottom of a Block result in a downwards facing Hopper
+ ((Hopper) blockData).setFacing(BlockFace.DOWN);
+ } else if (blockData instanceof Directional && (blockData.getMaterial().name().endsWith("_HEAD") || blockData.getMaterial().name().endsWith("_SKULL")) && againstSide != BlockFace.DOWN && againstSide != BlockFace.UP) {
+ // Skulls and Heads are always rotated towards you if not in Wall variant
+ ((Directional) blockData).setFacing(againstSide);
+ } else if (blockData instanceof LightningRod) {
+ // Lightning Rod is always rotated against the block you place against
+ ((Directional) blockData).setFacing(againstSide);
+ }
+ if (force && blockData instanceof FaceAttachable) {
+ // Forcing to Place a FaceAttachable against the Block you specified. Needs the force flag to be set
+ FaceAttachable faceAttachable = (FaceAttachable) blockData;
+ if (blockData instanceof Switch && againstSide == BlockFace.DOWN) {
+ faceAttachable.setAttachedFace(FaceAttachable.AttachedFace.CEILING);
+ } else if (againstSide == BlockFace.UP) {
+ faceAttachable.setAttachedFace(FaceAttachable.AttachedFace.FLOOR);
+ } else if (blockData instanceof Directional) {
+ ((Directional) blockData).setFacing(againstSide);
+ }
+ if (blockData instanceof Switch) {
+ // Levers and Buttons are always Rotated the other way
+ Switch switchType = (Switch) blockData;
+ switch (switchType.getAttachedFace()) {
+ case FLOOR:
+ case CEILING:
+ switchType.setFacing(switchType.getFacing().getOppositeFace());
+ break;
+ }
+ }
+ }
+ if (force && blockData instanceof Directional && !(blockData instanceof FaceAttachable) && BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.containsValue(blockData.getMaterial())) {
+ Directional directional = (Directional) blockData;
+ if (directional.getFaces().contains(againstSide)) {
+ directional.setFacing(againstSide);
+ }
+ }
+ if (force && blockData instanceof Rotatable && !(blockData instanceof FaceAttachable)) {
+ Rotatable rotatable = (Rotatable) blockData;
+ if (againstSide != BlockFace.UP && againstSide != BlockFace.DOWN) {
+ rotatable.setRotation(againstSide);
+ }
+ }
+
+ if (blockData instanceof RedstoneWire) {
+ // Redstone Wire is connected to every Side by default
+ RedstoneWire redstoneWire = (RedstoneWire) blockData;
+ redstoneWire.setFace(BlockFace.NORTH, RedstoneWire.Connection.SIDE);
+ redstoneWire.setFace(BlockFace.SOUTH, RedstoneWire.Connection.SIDE);
+ redstoneWire.setFace(BlockFace.EAST, RedstoneWire.Connection.SIDE);
+ redstoneWire.setFace(BlockFace.WEST, RedstoneWire.Connection.SIDE);
+ }
+
+ if (rotateAway) {
+ // Rotate the other way if rotateAway is set to true
+ BlockFace blockFace = getRotation(blockData);
+ if (blockFace != null) {
+ blockFace = blockFace.getOppositeFace();
+ if (blockData instanceof Hopper && (blockFace == BlockFace.UP || blockFace == BlockFace.DOWN)) {
+ ((Hopper) blockData).setFacing(BlockFace.DOWN);
+ } else {
+ setRotation(blockData, blockFace);
+ }
+ }
+ }
+
+ // Check if the Block can be build
+ BlockCanBuildEvent blockCanBuildEvent = new BlockCanBuildEvent(against, player, blockData, canPlace(block, blockData, force, usedForcePlace));
+ Bukkit.getPluginManager().callEvent(blockCanBuildEvent);
+ if (!blockCanBuildEvent.isBuildable()) return PlaceItemResult.NO_BUILD;
+
+ BlockState oldState = block.getState();
+
+ // Retrieve the BlockState of the ItemStack if present
+ BlockState blockState = null;
+ if (itemMeta instanceof BlockStateMeta) {
+ blockState = ((BlockStateMeta) itemMeta).getBlockState();
+ }
+
+ if (blockState == null) {
+ // If no BlockState is present use the BlockState of the Block you want to edit
+ blockState = block.getState();
+ } else {
+ // If a BlockState is present set the Position and World to the Block you want to place
+ Location blockLocation = block.getLocation();
+ positionAccessor.set(blockState, blockPositionConstructor.invoke(blockLocation.getBlockX(), blockLocation.getBlockY(), blockLocation.getBlockZ()));
+ worldAccessor.set(blockState, blockLocation.getWorld());
+ }
+
+ if (blockData.getMaterial().isSolid()) {
+ for (Player p : Bukkit.getOnlinePlayers()) {
+ Location min = p.getLocation().add(-0.3, 0, -0.3);
+ Location max = p.getLocation().add(0.3, p.isSneaking() ? 1.5 : 1.8, 0.3);
+
+ Location blockmin = block.getLocation();
+ Location blockmax = block.getLocation().add(1.0, 1.0, 1.0);
+ if (
+ !(max.getX() <= blockmin.getX() || min.getX() >= blockmax.getX() ||
+ max.getY() <= blockmin.getY() || min.getY() >= blockmax.getY() ||
+ max.getZ() <= blockmin.getZ() || min.getZ() >= blockmax.getZ())
+ ) {
+ return PlaceItemResult.NO_PLACE_INSIDE_PLAYER;
+ }
+ }
+ }
+
+ // Set the generated BlockData to the BlockState and update the world without physics
+ blockState.setBlockData(blockData);
+ blockState.update(true, false);
+
+ // Check if the Block is allowed to be placed
+ BlockPlaceEvent blockPlaceEvent = new BlockPlaceEvent(block, oldState, against, itemStack, player, true, hand);
+ Bukkit.getPluginManager().callEvent(blockCanBuildEvent);
+ if (blockPlaceEvent.isCancelled() || !blockPlaceEvent.canBuild()) {
+ // Reset world
+ oldState.update(true, false);
+ return PlaceItemResult.NO_PLACE;
+ }
+
+ if (hasSecondBlock(blockData)) {
+ // Place tht second block of a Door or Tallgrass.
+ Bisected bisected = (Bisected) blockData;
+ Block blockAbove = block.getRelative(0, 1, 0);
+ bisected.setHalf(Bisected.Half.TOP);
+ if (canPlace(blockAbove, blockData, force, usedForcePlace)) {
+ if (blockData instanceof Waterlogged) {
+ ((Waterlogged) blockData).setWaterlogged(blockAbove.getType() == Material.WATER);
+ }
+ blockAbove.setBlockData(blockData, applyPhysics);
+ } else {
+ // If the second Block couldn't be placed remove the first Block as well
+ oldState.update(true, false);
+ return PlaceItemResult.NO_DOUBLE_HIGH_BLOCK_SPACE;
+ }
+ }
+ if (applyPhysics) {
+ // Apply Physics by placing the old State without Physics and setting the new with physics
+ oldState.update(true, false);
+ blockState.update(true, true);
+ }
+
+ if (itemMeta instanceof BannerMeta) {
+ // Apply Banner Patterns to now placed Block in World
+ BannerMeta bannerMeta = (BannerMeta) itemMeta;
+ Banner banner = (Banner) block.getState();
+ banner.setPatterns(bannerMeta.getPatterns());
+ banner.update(true, false);
+ } else if (itemMeta instanceof SkullMeta) {
+ // Apply Skull Data to now placed Block in World
+ SkullMeta skullMeta = (SkullMeta) itemMeta;
+ Skull skull = (Skull) block.getState();
+ skull.setOwnerProfile(skullMeta.getOwnerProfile());
+ skull.setOwningPlayer(skullMeta.getOwningPlayer());
+ skull.update(true, false);
+ }
+
+ if (playSound) {
+ // Play the corresponding sound of placing the now placed Block
+ SoundGroup soundGroup = blockData.getSoundGroup();
+ block.getWorld().playSound(block.getLocation(), soundGroup.getPlaceSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
+ }
+ return usedForcePlace.get() ? PlaceItemResult.SUCCESS_FORCE : PlaceItemResult.SUCCESS;
+ }
+
+ public BlockFace[] axis = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
+ public BlockFace[] radial = { BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST };
+
+ public BlockFace yawToFace(float yaw) {
+ return radial[Math.round(yaw / 45f) & 0x7];
+ }
+
+ public BlockFace yawToFaceAxis(float yaw) {
+ return axis[Math.round(yaw / 90f) & 0x3];
+ }
+
+ public BlockFace toFace(Set faces, float pitch, float yaw) {
+ if (faces.contains(BlockFace.UP) && pitch >= 45.0) {
+ return BlockFace.UP;
+ }
+ if (faces.contains(BlockFace.DOWN) && pitch <= -45.0) {
+ return BlockFace.DOWN;
+ }
+ return yawToFaceAxis(yaw);
+ }
+
+ public BlockData toBlockData(Player player, BlockDataMeta blockDataMeta, Material material) {
+ BlockData blockData;
+ try {
+ blockData = blockDataMeta.getBlockData(material);
+ } catch (NullPointerException e) {
+ // Some items have a BlockDataMeta but they cannot be converted to one like ItemFrame, those will be ignored
+ return null;
+ }
+
+ if (blockData instanceof Stairs || blockData instanceof Observer || blockData instanceof Hopper || blockData instanceof Door) {
+ // Stairs, Observer, Hopper and Doors are placed the opposite way
+ Directional directional = (Directional) blockData;
+ BlockFace face = toFace(directional.getFaces(), player.getLocation().getPitch(), player.getLocation().getYaw());
+ directional.setFacing(face.getOppositeFace());
+ } else if (blockData instanceof Orientable) {
+ // Orientable only have 3 Axis: X, Y, Z
+ Orientable orientable = (Orientable) blockData;
+ Set faces = new HashSet<>();
+ Set axisSet = orientable.getAxes();
+ if (axisSet.contains(Axis.X)) {
+ faces.add(BlockFace.EAST);
+ faces.add(BlockFace.WEST);
+ }
+ if (axisSet.contains(Axis.Y)) {
+ faces.add(BlockFace.UP);
+ faces.add(BlockFace.DOWN);
+ }
+ if (axisSet.contains(Axis.Z)) {
+ faces.add(BlockFace.NORTH);
+ faces.add(BlockFace.SOUTH);
+ }
+ BlockFace face = toFace(faces, player.getLocation().getPitch(), player.getLocation().getYaw());
+ switch (face) {
+ case EAST:
+ case WEST:
+ orientable.setAxis(Axis.X);
+ break;
+ case UP:
+ case DOWN:
+ orientable.setAxis(Axis.Y);
+ break;
+ case NORTH:
+ case SOUTH:
+ orientable.setAxis(Axis.Z);
+ break;
+ }
+ } else if (blockData instanceof Rotatable) {
+ Rotatable rotatable = (Rotatable) blockData;
+ BlockFace blockeFace = yawToFace(player.getLocation().getYaw());
+ if (blockData.getMaterial().name().endsWith("_HEAD") || blockData.getMaterial().name().endsWith("_SKULL")) {
+ // Wall Heads and Wall Skulls are placed the opposite way
+ rotatable.setRotation(blockeFace.getOppositeFace());
+ } else {
+ rotatable.setRotation(blockeFace);
+ }
+ } else if (blockData instanceof Directional) {
+ Directional directional = (Directional) blockData;
+ directional.setFacing(toFace(directional.getFaces(), player.getLocation().getPitch(), player.getLocation().getYaw()));
+ } else if (blockData instanceof Rail) {
+ Rail rail = (Rail) blockData;
+ BlockFace face = yawToFaceAxis(player.getLocation().getYaw());
+ // Rails are only represented by 2 States, North_South or East_West the remaining States will be ignored here
+ rail.setShape(face == BlockFace.NORTH || face == BlockFace.SOUTH ? Rail.Shape.NORTH_SOUTH : Rail.Shape.EAST_WEST);
+ }
+
+ return blockData;
+ }
+
+ private BlockFace getRotation(BlockData blockData) {
+ if (blockData instanceof Rotatable) {
+ return ((Rotatable) blockData).getRotation();
+ } else if (blockData instanceof Directional) {
+ return ((Directional) blockData).getFacing();
+ } else if (blockData instanceof Rail) {
+ Rail rail = (Rail) blockData;
+ switch (rail.getShape()) {
+ case NORTH_SOUTH:
+ return BlockFace.NORTH;
+ case EAST_WEST:
+ return BlockFace.EAST;
+ }
+ }
+ return null;
+ }
+
+ private void setRotation(BlockData blockData, BlockFace rotation) {
+ if (blockData instanceof Rotatable) {
+ ((Rotatable) blockData).setRotation(rotation);
+ } else if (blockData instanceof Directional) {
+ ((Directional) blockData).setFacing(rotation);
+ } else if (blockData instanceof Rail) {
+ Rail rail = (Rail) blockData;
+ switch (rotation) {
+ case NORTH:
+ case SOUTH:
+ rail.setShape(Rail.Shape.NORTH_SOUTH);
+ break;
+ case EAST:
+ case WEST:
+ rail.setShape(Rail.Shape.EAST_WEST);
+ break;
+ }
+ }
+ }
+
+ private boolean isHitHalfTop(Player player) {
+ RayTraceResult rayTraceResult = player.rayTraceBlocks(6, FluidCollisionMode.NEVER);
+ if (rayTraceResult != null) {
+ Vector vector = rayTraceResult.getHitPosition();
+ return (vector.getY() - vector.getBlockY()) > 0.5;
+ }
+ return false;
+ }
+
+ private boolean hasSecondBlock(BlockData blockData) {
+ if (!(blockData instanceof Bisected)) {
+ return false;
+ }
+ if (blockData instanceof Door) {
+ return true;
+ }
+ return blockData.getClass().getName().contains("Tall");
+ }
+
+ private boolean canPlace(Block block, BlockData blockData, boolean force, AtomicBoolean usedForcePlace) {
+ if (!block.canPlace(blockData)) {
+ if (force) usedForcePlace.set(true);
+ return force;
+ }
+ return replaceables.contains(block.getType().name());
+ }
+
+ @AllArgsConstructor
+ @Getter
+ public enum PlaceItemResult {
+ NO_ITEM_HELD(false),
+ NO_BLOCK_ITEM_HELD(false),
+ NO_VALID_PLACEMENT(false),
+ NO_BUILD(false),
+ NO_PLACE(false),
+ NO_DOUBLE_HIGH_BLOCK_SPACE(false),
+ NO_PLACE_INSIDE_PLAYER(false),
+ SUCCESS(true),
+ SUCCESS_FORCE(true),
+ ;
+
+ private final boolean success;
+
+ public boolean wasForced() {
+ return this == SUCCESS_FORCE;
+ }
+ }
+}
diff --git a/SCRIPT.md b/SCRIPT.md
index bd4edd7c..ae9cb181 100644
--- a/SCRIPT.md
+++ b/SCRIPT.md
@@ -144,11 +144,12 @@ Es gibt folgende weitere Module:
Das `tnt`-Modul stellt Funktionen zur Verfügung, die den TNT-Modus in der Region des Spielers betreffen.
Es gibt folgende Funktionen:
-| Name | Signature | Beschreibung |
-|-----------|--------------------|-------------------------------------------------------------------------------------|
-| `mode` | mode(): String | Gibt den Aktuellen TNT-Modus zurück, die werte sind: `ALLOW`, `DENY` oder `ONLY_TB` |
-| `enabled` | enabled(): Boolean | Gibt zurück, ob der TNT-Modus in der Region des Spielers aktiviert ist oder nicht |
-| `onlyTb` | onlyTb(): Boolean | Gibt zurück, ob der TNT-Modus auf Only-Tb ist |
+| Name | Signature | Beschreibung |
+|-------------|----------------------|-------------------------------------------------------------------------------------|
+| `mode` | mode(): String | Gibt den Aktuellen TNT-Modus zurück, die werte sind: `ALLOW`, `DENY` oder `ONLY_TB` |
+| `enabled` | enabled(): Boolean | Gibt zurück, ob der TNT-Modus in der Region des Spielers aktiviert ist oder nicht |
+| `onlyTb` | onlyTb(): Boolean | Gibt zurück, ob der TNT-Modus auf Only-Tb ist |
+| `onlyBuild` | onlyBuild(): Boolean | Gibt zurück, ob der TNT-Modus auf Only-Build ist |
#### trace
diff --git a/sw.def.lua b/sw.def.lua
index d1570fd8..d56a134e 100644
--- a/sw.def.lua
+++ b/sw.def.lua
@@ -167,6 +167,9 @@ function tnt.enabled() return nil end
---@return boolean
function tnt.onlyTb() return nil end
+---@return boolean
+function tnt.onlyBuild() return nil end
+
---@class trace
local trace = {}
@@ -341,3 +344,54 @@ function command(command, handler) end
---@param handler fun(pressed: boolean): void
---@return void
function hotkey(trigger, handler) end
+
+---@class bossbar
+bossbar = {}
+
+---@alias BossBarColor 'PINK' | 'BLUE' | 'RED' | 'GREEN' | 'YELLOW' | 'PURPLE' | 'WHITE'
+---@alias BossBarStyle 'SEGMENTED_6' | 'SEGMENTED_10' | 'SEGMENTED_12' | 'SEGMENTED_20' | 'SOLID'
+---@alias BossBarFlag 'DARKEN_SKY' | 'PLAY_BOSS_MUSIC' | 'CREATE_FOG'
+
+---@class BossBar
+local BossBar = {}
+
+---@param title string
+---@param color BossBarColor
+---@param style BossBarStyle
+---@return BossBar
+function bossbar.create(title, color, style) return nil end
+
+---@return string
+---@overload fun(title: string): void
+function BossBar.title() end
+
+---@return BossBarColor
+---@overload fun(color: BossBarColor): void
+function BossBar.color() end
+
+---@return BossBarStyle
+---@overload fun(style: BossBarStyle): void
+function BossBar.style() end
+
+---@return number
+---@overload fun(progress: number): void
+function BossBar.progress() end
+
+---@return boolean
+---@overload fun(visible: boolean): void
+function BossBar.visible() end
+
+---@return boolean
+---@param flag BossBarFlag
+function BossBar.hasFlag(flag) return nil end
+
+---@return void
+---@param flag BossBarFlag
+function BossBar.addFlag(flag) end
+
+---@return boolean
+---@param flag BossBarFlag
+function BossBar.removeFlag(flag) return nil end
+
+---@return void
+function BossBar.destroy() end