Merge pull request 'QOL' (#203) from QOL into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #203
Dieser Commit ist enthalten in:
Commit
cf569d6e76
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 + ");");
|
||||
}
|
||||
}
|
@ -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')
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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");
|
||||
});
|
||||
|
@ -52,7 +52,7 @@ public class InfoCommand extends SWCommand {
|
||||
|
||||
List<BauweltMember> 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,
|
||||
|
@ -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<TNTPrimed, Vector> velocities = new HashMap<>();
|
||||
private Map<TNTPrimed, Set<UUID>> 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<TNTPrimed> 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<CannonKey, List<TNTPrimed>> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<UUID> propulsions;
|
||||
private Vector velocityVector;
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ public class Depth {
|
||||
List<Block> 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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<SWListInv.SWListEntry<LoaderElement>> 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<String> 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<String> 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<String> 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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Long> 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));
|
||||
}
|
||||
}
|
@ -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<T extends ElementSettings> implements LoaderElement {
|
||||
public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSettingsEnum> implements LoaderElement {
|
||||
|
||||
@Getter
|
||||
protected final Location location;
|
||||
protected int currentShot = 0;
|
||||
protected T defaultSetting;
|
||||
protected T newSetting;
|
||||
protected T[] allSettings;
|
||||
protected List<T> elements = new ArrayList<>();
|
||||
protected List<Integer> extraPower = new ArrayList<>();
|
||||
protected List<Long> 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<Long> 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<SWListInv.SWListEntry<T>> entries = new ArrayList<>();
|
||||
List<SWListInv.SWListEntry<Integer>> 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<T> listInv = new SWListInv<>(player, "Interaction Settings", false, entries, (clickType, entry) -> {});
|
||||
SWListInv<Integer> 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<T extends ElementSettings> 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));
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.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<T, P extends LoaderInteractionElement<E>, E extends Enum<E> & LoaderSettingsEnum<T, P, E>> {
|
||||
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<Long> 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));
|
||||
}
|
||||
}
|
@ -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<LoaderComparator.ComparatorSettings> {
|
||||
public class LoaderComparator extends LoaderInteractionElement<LoaderComparator.ComparatorSettingsEnum> {
|
||||
|
||||
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<Comparator, LoaderComparator, ComparatorSettingsEnum> {
|
||||
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<Long> 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<Long> 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<Long> 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<Long> 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<Long> delay) {
|
||||
blockData.setMode(Comparator.Mode.SUBTRACT);
|
||||
parent.update(blockData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +116,7 @@ public class LoaderComparator extends LoaderInteractionElement<LoaderComparator.
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComparatorSettings createNewElement() {
|
||||
return new ComparatorSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
return location.getBlock().getType() == Material.COMPARATOR;
|
||||
}
|
||||
}
|
||||
|
@ -19,137 +19,98 @@
|
||||
|
||||
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;
|
||||
import org.bukkit.block.data.type.DaylightDetector;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LoaderDaylightDetector extends LoaderInteractionElement<LoaderDaylightDetector.DaylightDetectorSettings> {
|
||||
public class LoaderDaylightDetector extends LoaderInteractionElement<LoaderDaylightDetector.DaylightSettingsEnum> {
|
||||
|
||||
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<Long> 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<DaylightDetector, LoaderDaylightDetector, DaylightSettingsEnum> {
|
||||
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<Long> 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<Long> 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<Long> 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<Long> delay) {
|
||||
if (!blockData.isInverted()) {
|
||||
blockData.setInverted(true);
|
||||
blockData.setPower(15 - blockData.getPower());
|
||||
parent.update(blockData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +120,7 @@ public class LoaderDaylightDetector extends LoaderInteractionElement<LoaderDayli
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaylightDetectorSettings createNewElement() {
|
||||
return new DaylightDetectorSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
return location.getBlock().getType() == Material.DAYLIGHT_DETECTOR;
|
||||
}
|
||||
}
|
||||
|
@ -19,132 +19,493 @@
|
||||
|
||||
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;
|
||||
import org.bukkit.block.Lectern;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BookMeta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LoaderLectern extends LoaderInteractionElement<LoaderLectern.LecternSettings> {
|
||||
public class LoaderLectern extends LoaderInteractionElement<LoaderLectern.LecternSettingsEnum> {
|
||||
|
||||
|
||||
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<Long> 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<org.bukkit.block.data.type.Lectern, LoaderLectern, LecternSettingsEnum> {
|
||||
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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<LoaderLectern.Lecter
|
||||
}
|
||||
|
||||
@Override
|
||||
public LecternSettings createNewElement() {
|
||||
return new LecternSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
return location.getBlock().getType() == Material.LECTERN;
|
||||
}
|
||||
}
|
||||
|
@ -19,108 +19,91 @@
|
||||
|
||||
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;
|
||||
import org.bukkit.block.data.type.Switch;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LoaderLever extends LoaderInteractionElement<LoaderLever.LeverSettings> {
|
||||
public class LoaderLever extends LoaderInteractionElement<LoaderLever.LeverSettingsEnum> {
|
||||
|
||||
public LoaderLever(Location location) {
|
||||
super(location);
|
||||
super(location, LeverSettingsEnum.INTERACT, LeverSettingsEnum.NOOP, LeverSettingsEnum.values());
|
||||
}
|
||||
|
||||
public class LeverSettings implements ElementSettings {
|
||||
public enum LeverSettingsEnum implements LoaderSettingsEnum<Switch, LoaderLever, LeverSettingsEnum> {
|
||||
|
||||
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<Long> 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<Long> 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<Long> 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<Long> 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<Long> delay) {
|
||||
blockData.setPowered(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +113,7 @@ public class LoaderLever extends LoaderInteractionElement<LoaderLever.LeverSetti
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeverSettings createNewElement() {
|
||||
return new LeverSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
return location.getBlock().getType() == Material.LEVER;
|
||||
}
|
||||
}
|
||||
|
@ -20,12 +20,9 @@
|
||||
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.SWAnvilInv;
|
||||
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.AnaloguePowerable;
|
||||
@ -33,18 +30,16 @@ import org.bukkit.block.data.BlockData;
|
||||
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 LoaderMovement extends LoaderInteractionElement<LoaderMovement.MovementSettings> {
|
||||
public class LoaderMovement extends LoaderInteractionElement<LoaderMovement.MovementSettingsEnum> {
|
||||
|
||||
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<LoaderMovement.Move
|
||||
|
||||
public void setInitialTicks(long ticks) {
|
||||
if (ticks < 1) ticks = 1;
|
||||
elements.get(currentShot).ticks = ticks;
|
||||
extraTicks.set(currentShot, ticks);
|
||||
}
|
||||
|
||||
public class MovementSettings implements ElementSettings {
|
||||
public enum MovementSettingsEnum implements LoaderSettingsEnum<BlockData, LoaderMovement, MovementSettingsEnum> {
|
||||
|
||||
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<Long> 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<Long> 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<Long> 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<Long> delay) {
|
||||
NO_WAIT_FOR.execute(location, blockData, parent, power, ticks, delay);
|
||||
delay.accept(ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,7 +158,8 @@ public class LoaderMovement extends LoaderInteractionElement<LoaderMovement.Move
|
||||
}
|
||||
|
||||
@Override
|
||||
public MovementSettings createNewElement() {
|
||||
return new MovementSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
if (material == Material.STRING && location.getBlock().getType() == Material.TRIPWIRE) return true;
|
||||
return location.getBlock().getType() == material;
|
||||
}
|
||||
}
|
||||
|
@ -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.Instrument;
|
||||
import org.bukkit.Location;
|
||||
@ -30,80 +28,50 @@ import org.bukkit.Material;
|
||||
import org.bukkit.block.data.type.NoteBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LoaderNoteBlock extends LoaderInteractionElement<LoaderNoteBlock.NoteBlockSettings> {
|
||||
public class LoaderNoteBlock extends LoaderInteractionElement<LoaderNoteBlock.NoteBlockSettingsEnum> {
|
||||
|
||||
public LoaderNoteBlock(Location location) {
|
||||
super(location);
|
||||
super(location, NoteBlockSettingsEnum.INTERACT, NoteBlockSettingsEnum.NOOP, NoteBlockSettingsEnum.values());
|
||||
}
|
||||
|
||||
public class NoteBlockSettings implements ElementSettings {
|
||||
public enum NoteBlockSettingsEnum implements LoaderSettingsEnum<NoteBlock, LoaderNoteBlock, NoteBlockSettingsEnum> {
|
||||
|
||||
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<Long> 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<Long> 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<Long> 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<LoaderNoteBlock.No
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteBlockSettings createNewElement() {
|
||||
return new NoteBlockSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
return location.getBlock().getType() == Material.NOTE_BLOCK;
|
||||
}
|
||||
}
|
||||
|
@ -19,113 +19,97 @@
|
||||
|
||||
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;
|
||||
import org.bukkit.block.data.Openable;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LoaderOpenable extends LoaderInteractionElement<LoaderOpenable.TrapdoorSettings> {
|
||||
public class LoaderOpenable extends LoaderInteractionElement<LoaderOpenable.OpenableSettingsEnum> {
|
||||
|
||||
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<Openable, LoaderOpenable, OpenableSettingsEnum> {
|
||||
|
||||
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<Long> 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<Long> 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<Long> 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<Long> 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<Long> delay) {
|
||||
blockData.setOpen(true);
|
||||
parent.update(blockData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,7 +119,7 @@ public class LoaderOpenable extends LoaderInteractionElement<LoaderOpenable.Trap
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrapdoorSettings createNewElement() {
|
||||
return new TrapdoorSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
return location.getBlock().getType() == material;
|
||||
}
|
||||
}
|
||||
|
@ -20,125 +20,140 @@
|
||||
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;
|
||||
import org.bukkit.block.data.type.Repeater;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LoaderRepeater extends LoaderInteractionElement<LoaderRepeater.RepeaterSettings> {
|
||||
public class LoaderRepeater extends LoaderInteractionElement<LoaderRepeater.RepeaterSettingsEnum> {
|
||||
|
||||
public LoaderRepeater(Location location) {
|
||||
super(location);
|
||||
super(location, RepeaterSettingsEnum.INTERACT, RepeaterSettingsEnum.NOOP, RepeaterSettingsEnum.values());
|
||||
}
|
||||
|
||||
public class RepeaterSettings implements ElementSettings {
|
||||
public enum RepeaterSettingsEnum implements LoaderSettingsEnum<Repeater, LoaderRepeater, RepeaterSettingsEnum> {
|
||||
|
||||
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<Long> __) {
|
||||
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<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> delay) {
|
||||
blockData.setDelay(4);
|
||||
parent.update(blockData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +163,7 @@ public class LoaderRepeater extends LoaderInteractionElement<LoaderRepeater.Repe
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepeaterSettings createNewElement() {
|
||||
return new RepeaterSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
return location.getBlock().getType() == Material.REPEATER;
|
||||
}
|
||||
}
|
||||
|
@ -20,23 +20,57 @@
|
||||
package de.steamwar.bausystem.features.loader.elements.impl;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.loader.elements.LoaderElement;
|
||||
import de.steamwar.bausystem.features.loader.elements.LoaderInteractionElement;
|
||||
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.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LoaderTNT implements LoaderElement {
|
||||
|
||||
private Location location;
|
||||
public class LoaderTNT extends LoaderInteractionElement<LoaderTNT.TNTSettingsEnum> {
|
||||
|
||||
public LoaderTNT(Location location) {
|
||||
this.location = location;
|
||||
super(location, TNTSettingsEnum.PLACE, TNTSettingsEnum.NOOP, TNTSettingsEnum.values());
|
||||
}
|
||||
|
||||
public enum TNTSettingsEnum implements LoaderSettingsEnum<BlockData, LoaderTNT, TNTSettingsEnum> {
|
||||
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<Long> 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<Long> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<LoaderTicks.TicksSettings> {
|
||||
public class LoaderTicks extends LoaderInteractionElement<LoaderTicks.TicksSettingsEnum> {
|
||||
|
||||
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<Powerable, LoaderTicks, TicksSettingsEnum> {
|
||||
|
||||
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<Long> 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<Long> 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<Long> 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<Long> 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<LoaderTicks.TicksSetti
|
||||
}
|
||||
|
||||
@Override
|
||||
public TicksSettings createNewElement() {
|
||||
return new TicksSettings();
|
||||
public boolean checkBlockInWorld() {
|
||||
return location.getBlock().getType() == material;
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.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;
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Player, RedstoneTester> 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
@ -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<String, TNTMode> 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<TNTMode>() {
|
||||
@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;
|
||||
|
@ -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<Block> 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;
|
||||
});
|
||||
|
@ -159,7 +159,7 @@ public class TestblockCommand extends SWCommand {
|
||||
|
||||
@ClassValidator(value = Player.class, local = true)
|
||||
public TypeValidator<Player> 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<TestblockParameter> 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<String> tabCompletes;
|
||||
@ -238,8 +206,7 @@ public class TestblockCommand extends SWCommand {
|
||||
private final Supplier<TestblockParameterType[]> removed;
|
||||
private AtomicReference<TestblockParameterType[]> cached = new AtomicReference<>();
|
||||
|
||||
TestblockParameterType(Consumer<TestblockParameter> testblockParameterConsumer, List<String> tabCompletes, String... removed) {
|
||||
this.testblockParameterConsumer = testblockParameterConsumer;
|
||||
TestblockParameterType(List<String> tabCompletes, String... removed) {
|
||||
this.tabCompletes = tabCompletes;
|
||||
this.removed = () -> {
|
||||
if (cached.get() == null) {
|
||||
|
@ -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;
|
||||
|
@ -48,6 +48,10 @@ public class ScriptRunner {
|
||||
private static final Map<Player, Map<Hotkey, List<LuaFunction>>> HOTKEY_MAP = new HashMap<>();
|
||||
private static final Map<Player, Map<String, CommandRegister>> COMMAND_MAP = new HashMap<>();
|
||||
|
||||
public Set<String> 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());
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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<SmartPlaceBehaviour> 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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<Integer> supplier = new Supplier<Integer>() {
|
||||
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)),
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<SWListInv.SWListEntry<Record>> 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<Record> 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<SWListInv.SWListEntry<Record.TNTRecord>> 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<Record.TNTRecord> 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<SWListInv.SWListEntry<TNTPosition>> 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<TNTPosition> 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();
|
||||
}
|
||||
}
|
@ -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<TNTPrimed, Record.TNTRecord> recordMap = new HashMap<>();
|
||||
private Record record;
|
||||
|
||||
private Region region;
|
||||
private Supplier<Record> 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<Record> recordSupplier) {
|
||||
public void init(Region region, Supplier<Record> 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();
|
||||
}
|
||||
|
@ -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<Region, TraceRecorder> regionTraceRecorderMap = new HashMap<>();
|
||||
private Map<TNTPrimed, Region> 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();
|
||||
}
|
||||
|
@ -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<Record> recordSupplier) {
|
||||
public void init(Region region, Supplier<Record> 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);
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.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);
|
||||
}
|
@ -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<Record> recordSupplier) {
|
||||
default void init(Region region, Supplier<Record> 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() {
|
||||
}
|
||||
|
||||
|
@ -84,15 +84,22 @@ public class EntityShowMode implements ShowMode<TNTPosition> {
|
||||
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<TNTPosition> {
|
||||
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<TNTPosition> {
|
||||
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() + "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<TNTRecord> 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<TNTPosition> 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);
|
||||
|
@ -28,16 +28,21 @@ 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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<Region, Map<Player, List<Record.TNTRecord>>> isolatedTNT = new HashMap<>();
|
||||
private static final Map<Region, Map<Player, Integer>> replayTime = new HashMap<>();
|
||||
private static final Map<Region, Map<Player, Supplier<Integer>>> replayLoops = new HashMap<>();
|
||||
private static final Map<Region, List<Record>> 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<Record.TNTRecord> 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<Player, List<Record.TNTRecord>> 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<Player, Integer> regionalReplayTime = replayTime.get(region);
|
||||
if (regionalReplayTime != null) {
|
||||
regionalReplayTime.remove(player);
|
||||
}
|
||||
Map<Player, Supplier<Integer>> 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<Player, Supplier<Integer>> regionalReplayLoops = replayLoops.get(region);
|
||||
if (regionalReplayLoops != null) {
|
||||
regionalReplayLoops.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setReplayLoop(Region region, Player player, Supplier<Integer> loop) {
|
||||
replayLoops.computeIfAbsent(region, k -> new HashMap<>()).put(player, loop);
|
||||
}
|
||||
|
||||
static Predicate<TNTPosition> replayTimeFilter(Region region, Player player) {
|
||||
Predicate<TNTPosition> 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<TNTPosition> traceShowMode) {
|
||||
Predicate<TNTPosition> 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<TNTPosition> traceShowFilter, ShowMode<TNTPosition> 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);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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<Region, Map<Player, ShowMode<TNTPosition>>> showModes = new HashMap<>();
|
||||
private static final Map<Region, Map<Player, Predicate<TNTPosition>>> showFilters = new HashMap<>();
|
||||
|
||||
public static void show(Player player, ShowMode<TNTPosition> traceShowMode) {
|
||||
hide(player);
|
||||
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
_hide(region, player, true);
|
||||
|
||||
Map<Player, ShowMode<TNTPosition>> 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<Player, ShowMode<TNTPosition>> regionalShowModes = showModes.get(region);
|
||||
if (regionalShowModes == null) {
|
||||
return;
|
||||
}
|
||||
ShowMode<TNTPosition> 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<Player, ShowMode<TNTPosition>> regionalShowModes = showModes.get(region);
|
||||
if (regionalShowModes == null) {
|
||||
return;
|
||||
public static void setShowFilter(Player player, Predicate<TNTPosition> showFilter) {
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
Map<Player, Predicate<TNTPosition>> regionShowFilters = showFilters.computeIfAbsent(region, __ -> new HashMap<>());
|
||||
if (showFilter == null) {
|
||||
regionShowFilters.remove(player);
|
||||
} else {
|
||||
regionShowFilters.put(player, showFilter);
|
||||
}
|
||||
ShowMode<TNTPosition> showMode = regionalShowModes.get(p);
|
||||
if (showMode == null) {
|
||||
return;
|
||||
}
|
||||
showMode.hide();
|
||||
StoredRecords.show(region, p, showMode);
|
||||
|
||||
_hide(region, player, false);
|
||||
ShowMode<TNTPosition> 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<Player, ShowMode<TNTPosition>> 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<Player, ShowMode<TNTPosition>> regionalShowModes = showModes.get(region);
|
||||
if (regionalShowModes == null) {
|
||||
return;
|
||||
}
|
||||
ShowMode<TNTPosition> showMode;
|
||||
if (remove) {
|
||||
showMode = regionalShowModes.remove(player);
|
||||
} else {
|
||||
showMode = regionalShowModes.get(player);
|
||||
}
|
||||
if (showMode == null) {
|
||||
return;
|
||||
}
|
||||
showMode.hide();
|
||||
}
|
||||
|
||||
private static Predicate<TNTPosition> 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<Player, ShowMode<TNTPosition>> regionalShowModes = showModes.get(region);
|
||||
@ -96,8 +109,9 @@ public class TraceShowManager implements Listener {
|
||||
return;
|
||||
}
|
||||
regionalShowModes.forEach((player, tntPositionShowMode) -> {
|
||||
Predicate<TNTPosition> 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<TNTPosition> showMode = playerShowModeMap.remove(event.getPlayer());
|
||||
if (showMode != null) showMode.hide();
|
||||
});
|
||||
StoredRecords.cleanup(event.getPlayer());
|
||||
showFilters.forEach((region, playerPredicateMap) -> {
|
||||
playerPredicateMap.remove(event.getPlayer());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
147
BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java
Normale Datei
147
BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java
Normale Datei
@ -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<String> getCommandMapper() {
|
||||
return new TypeMapper<String>() {
|
||||
@Override
|
||||
public String map(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||
if (previousArguments.mappedArgs.length == 0) return null;
|
||||
Object[] args = (Object[]) previousArguments.mappedArgs[previousArguments.mappedArgs.length - 1];
|
||||
List<String> 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -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<Material> 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);
|
||||
|
@ -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<Block> blockSet = new HashSet<>();
|
||||
AtomicBoolean unmovable = new AtomicBoolean();
|
||||
Set<Location> 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<Block> blockSet, List<Block> 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<Block> blockSet, List<Block> toCalc, Set<Location> 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;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.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<String[]> 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;
|
||||
});
|
||||
}
|
||||
}
|
@ -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");
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -29,7 +29,8 @@ public enum TNTMode implements Flag.Value<TNTMode> {
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
552
BauSystem_Main/src/de/steamwar/bausystem/utils/PlaceItemUtils.java
Normale Datei
552
BauSystem_Main/src/de/steamwar/bausystem/utils/PlaceItemUtils.java
Normale Datei
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<String> 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<Material, Material> ITEM_MATERIAL_TO_BLOCK_MATERIAL = new HashMap<>();
|
||||
private static final Map<Material, Material> 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<BlockFace> 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<BlockFace> faces = new HashSet<>();
|
||||
Set<Axis> 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;
|
||||
}
|
||||
}
|
||||
}
|
11
SCRIPT.md
11
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
|
||||
|
54
sw.def.lua
54
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
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren