diff --git a/.gitignore b/.gitignore index 36e1257e..7f1c1b0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ -# Package Files +# Build files *.jar +**/bin +**/build # Gradle .gradle @@ -10,6 +12,10 @@ steamwar.properties # IntelliJ IDEA .idea *.iml +plugin.yml # Other -lib \ No newline at end of file +lib + +#linkage +LinkageUtils.java \ No newline at end of file diff --git a/BauSystem_15/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator15.java b/BauSystem_15/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator15.java deleted file mode 100644 index 36c53f40..00000000 --- a/BauSystem_15/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator15.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -import net.minecraft.server.v1_15_R1.EntityTNTPrimed; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; -import org.bukkit.entity.TNTPrimed; - -import java.util.stream.Stream; - -public class TNTPrimedIterator15 implements TNTPrimedIterator { - - private static final CraftWorld WORLD = (CraftWorld) Bukkit.getWorlds().get(0); - - @Override - public Stream iterator() { - return WORLD.getHandle().entitiesById.values().stream() - .filter(EntityTNTPrimed.class::isInstance) - .map(entity -> (TNTPrimed) entity.getBukkitEntity()); - } -} diff --git a/BauSystem_18/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator18.java b/BauSystem_18/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator18.java deleted file mode 100644 index 0df69fb9..00000000 --- a/BauSystem_18/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator18.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -import com.comphenix.tinyprotocol.Reflection; -import net.minecraft.server.level.WorldServer; -import net.minecraft.world.level.entity.LevelEntityGetter; -import org.bukkit.Bukkit; -import org.bukkit.entity.TNTPrimed; - -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -public class TNTPrimedIterator18 implements TNTPrimedIterator { - - private static final Reflection.MethodInvoker getWorld = Reflection.getMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle"); - private static final Reflection.MethodInvoker getWorldEntities = Reflection.getTypedMethod(WorldServer.class, null, LevelEntityGetter.class); - private static final Reflection.MethodInvoker getIterable = Reflection.getTypedMethod(LevelEntityGetter.class, null, Iterable.class); - private static final Reflection.MethodInvoker getBukkitEntity = Reflection.getTypedMethod(Reflection.getClass("{nms.world.entity}.Entity"), "getBukkitEntity", null); - - @Override - public Stream iterator() { - return StreamSupport.stream(((Iterable) getIterable.invoke(getWorldEntities.invoke(getWorld.invoke(Bukkit.getWorlds().get(0))))).spliterator(), false) - .map(getBukkitEntity::invoke) - .filter(TNTPrimed.class::isInstance) - .map(TNTPrimed.class::cast); - } -} - diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index 887439f7..0911d917 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -16,109 +16,90 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - -PREFIX = §eBau§8System§8» -TIME = HH:mm:ss +PREFIX=§eBau§8System§8» +TIME=HH:mm:ss DATE=........ COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===--- ONLY_SCHEMS=§cFolders are unselectable - PAGE_LIST=§e Page ({0}/{1}) »» LIST_PREVIOUS_PAGE=§ePrevious page LIST_NEXT_PAGE=§eNext page - # Permissions -NO_PERMISSION = You are not allowed to use that here -SPECTATOR = §fSpectator - +NO_PERMISSION=You are not allowed to use that here +SPECTATOR=§fSpectator # Scoreboard -SCOREBOARD_TIME = Time -SCOREBOARD_REGION = Region -SCOREBOARD_TRACE = Trace -SCOREBOARD_LOADER = Loader -SCOREBOARD_TPS = TPS -SCOREBOARD_TPS_FROZEN = §eFrozen - -SCOREBOARD_TRACE_TICKS = Ticks - -SCOREBOARD_TECHHIDER = TechHider§8: §aOn -SCOREBOARD_XRAY = XRay§8: §aOn - -SCOREBOARD_LOCK_TEAM = Bau Lock§8: §eTeam -SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM = Bau Lock§8: §e(Server) Team -SCOREBOARD_LOCK_SERVERTEAM = Bau Lock§8: §eServer Team -SCOREBOARD_LOCK_NOBODY = Bau Lock§8: §cNobody - +SCOREBOARD_TIME=Time +SCOREBOARD_REGION=Region +SCOREBOARD_TRACE=Trace +SCOREBOARD_LOADER=Loader +SCOREBOARD_TPS=TPS +SCOREBOARD_TPS_FROZEN=§eFrozen +SCOREBOARD_TRACE_TICKS=Ticks +SCOREBOARD_TECHHIDER=TechHider§8: §aOn +SCOREBOARD_XRAY=XRay§8: §aOn +SCOREBOARD_LOCK_TEAM=Bau Lock§8: §eTeam +SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM=Bau Lock§8: §e(Server) Team +SCOREBOARD_LOCK_SERVERTEAM=Bau Lock§8: §eServer Team +SCOREBOARD_LOCK_NOBODY=Bau Lock§8: §cNobody # Flags -FLAG_COLOR = Color -FLAG_TNT = TNT -FLAG_FIRE = Fire -FLAG_FREEZE = Freeze -FLAG_PROTECT = Protect -FLAG_ITEMS = Items - -FLAG_FIRE_ALLOW = §con -FLAG_FIRE_DENY = §aoff - -FLAG_FREEZE_ACTIVE = §aon -FLAG_FREEZE_INACTIVE = §coff - -FLAG_PROTECT_ACTIVE = §aon -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 - -FLAG_COLOR_WHITE = §fWhite -FLAG_COLOR_ORANGE = §6Orange -FLAG_COLOR_MAGENTA = §dMagenta -FLAG_COLOR_LIGHT_BLUE = §bLight blue -FLAG_COLOR_YELLOW = §eYellow -FLAG_COLOR_LIME = §aLime +FLAG_COLOR=Color +FLAG_TNT=TNT +FLAG_FIRE=Fire +FLAG_FREEZE=Freeze +FLAG_PROTECT=Protect +FLAG_ITEMS=Items +FLAG_FIRE_ALLOW=§con +FLAG_FIRE_DENY=§aoff +FLAG_FREEZE_ACTIVE=§aon +FLAG_FREEZE_INACTIVE=§coff +FLAG_PROTECT_ACTIVE=§aon +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 +FLAG_COLOR_WHITE=§fWhite +FLAG_COLOR_ORANGE=§6Orange +FLAG_COLOR_MAGENTA=§dMagenta +FLAG_COLOR_LIGHT_BLUE=§bLight blue +FLAG_COLOR_YELLOW=§eYellow +FLAG_COLOR_LIME=§aLime ## This cannot be converted -FLAG_COLOR_PINK = §ePink -FLAG_COLOR_GRAY = §8Gray -FLAG_COLOR_LIGHT_GRAY = §7Light gray -FLAG_COLOR_CYAN = §3Cyan -FLAG_COLOR_PURPLE = §5Purple -FLAG_COLOR_BLUE = §1Blue +FLAG_COLOR_PINK=§ePink +FLAG_COLOR_GRAY=§8Gray +FLAG_COLOR_LIGHT_GRAY=§7Light gray +FLAG_COLOR_CYAN=§3Cyan +FLAG_COLOR_PURPLE=§5Purple +FLAG_COLOR_BLUE=§1Blue ## This cannot be converted -FLAG_COLOR_BROWN = §eBrown -FLAG_COLOR_GREEN = §2Green -FLAG_COLOR_RED = §cRed -FLAG_COLOR_BLACK = §0Black - +FLAG_COLOR_BROWN=§eBrown +FLAG_COLOR_GREEN=§2Green +FLAG_COLOR_RED=§cRed +FLAG_COLOR_BLACK=§0Black # Region -REGION_TYPE_NORMAL = Normal -REGION_TYPE_BUILD = Build area -REGION_TYPE_ONLY_TB = Dummy - +REGION_TYPE_NORMAL=Normal +REGION_TYPE_BUILD=Build area +REGION_TYPE_ONLY_TB=Dummy # AttributesCopy -ATTRIBUTES_CANT_COPY = §cYou need to hold the same item type and hover over the same block to copy. -ATTRIBUTES_NO_COPY = §cNo attributes to copy. -ATTRIBUTES_COPIED = §eAttributes copied. - -ATTRIBUTE_REMOVE_COMMAND_HELP = §8/§eattributeremove §8[§eattribute§8|§7all§8|§7*§8] -ATTRIBUTE_REMOVE_ALL = §eAll attributes removed. -ATTRIBUTE_REMOVE_SINGLE = §eAttribute §7{0}§e removed. -ATTRIBUTE_REMOVE_NOT_FOUND = §cAttribute not found - +ATTRIBUTES_CANT_COPY=§cYou need to hold the same item type and hover over the same block to copy. +ATTRIBUTES_NO_COPY=§cNo attributes to copy. +ATTRIBUTES_COPIED=§eAttributes copied. +ATTRIBUTE_REMOVE_COMMAND_HELP=§8/§eattributeremove §8[§eattribute§8|§7all§8|§7*§8] +ATTRIBUTE_REMOVE_ALL=§eAll attributes removed. +ATTRIBUTE_REMOVE_SINGLE=§eAttribute §7{0}§e removed. +ATTRIBUTE_REMOVE_NOT_FOUND=§cAttribute not found # AutoStart -AUTOSTART_COMMAND_HELP = §8/§etimer §8- §7Retrieve AutostartTimer Tool -AUTOSTART_ITEM_NAME = §eAutostartTimer -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}§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 - +AUTOSTART_COMMAND_HELP=§8/§etimer §8- §7Retrieve AutostartTimer Tool +AUTOSTART_ITEM_NAME=§eAutostartTimer +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}§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 BACKUP_HELP_CREATE=§8/§ebackup create §8- §7Create a region backup BACKUP_HELP_LOAD=§8/§ebackup load §8[§7BackupName§8] §8- §7Load a region backup @@ -135,44 +116,38 @@ BACKUP_LOAD=§7Backup loaded BACKUP_INV_NAME=§eBackup BACKUP_ITEM_NAME=§eBackup §7from §e{0} BACKUP_LORE=§eClick to load - # Bau -BAU_COMMAND_HELP_INFO = §8/§ebau info §8- §7Alias for §8/§ebauinfo - -BAU_INFO_ITEM_NAME = §eBau-Management +BAU_COMMAND_HELP_INFO=§8/§ebau info §8- §7Alias for §8/§ebauinfo +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_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§8: §e{0} -BAU_INFO_COMMAND_MEMBER = §7{0} §8[§7{1}§8]§8: §e{2} -BAU_INFO_COMMAND_FLAG = §7{0}§8: §7{1} -BAU_INFO_COMMAND_TPS = §7TPS§8:§e - +BAU_INFO_ITEM_LORE_TNT=§7TNT§8: §e{0} +BAU_INFO_ITEM_LORE_FREEZE=§7Freeze§8: §e{0} +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§8: §e{0} +BAU_INFO_COMMAND_MEMBER=§7{0} §8[§7{1}§8]§8: §e{2} +BAU_INFO_COMMAND_FLAG=§7{0}§8: §7{1} +BAU_INFO_COMMAND_TPS=§7TPS§8:§e # Countingwand -COUNTINGWAND_COMMAND_HELP = §8/§ecountingwand §8- §7Receive a CountingWand -COUNTINGWAND_ITEM_NAME = §eMeterstick -COUNTINGWAND_ITEM_LORE1 = §eLeft-Click §8- §7Set the first position -COUNTINGWAND_ITEM_LORE2 = §eRicht-Click §8- §7Set the second position -COUNTINGWAND_MESSAGE_RCLICK = §7First position at: §8[§7{0}§8, §7{1}§8, §7{2}§8] ({3}§8) ({4}§8) -COUNTINGWAND_MESSAGE_LCLICK = §7Second position at: §8[§7{0}§8, §7{1}§8, §7{2}§8] ({3}§8) ({4}§8) -COUNTINGWAND_MESSAGE_VOLUME = §e{0} -COUNTINGWAND_MESSAGE_DIMENSION = §e{0}§8, §e{1}§8, §e{2} - +COUNTINGWAND_COMMAND_HELP=§8/§ecountingwand §8- §7Receive a CountingWand +COUNTINGWAND_ITEM_NAME=§eMeterstick +COUNTINGWAND_ITEM_LORE1=§eLeft-Click §8- §7Set the first position +COUNTINGWAND_ITEM_LORE2=§eRicht-Click §8- §7Set the second position +COUNTINGWAND_MESSAGE_RCLICK=§7First position at: §8[§7{0}§8, §7{1}§8, §7{2}§8] ({3}§8) ({4}§8) +COUNTINGWAND_MESSAGE_LCLICK=§7Second position at: §8[§7{0}§8, §7{1}§8, §7{2}§8] ({3}§8) ({4}§8) +COUNTINGWAND_MESSAGE_VOLUME=§e{0} +COUNTINGWAND_MESSAGE_DIMENSION=§e{0}§8, §e{1}§8, §e{2} # Design Endstone -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 highlighted -DESIGN_ENDSTONE_DISABLE = §cEndstone is no longer hightlighted - +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 highlighted +DESIGN_ENDSTONE_DISABLE=§cEndstone is no longer hightlighted # Detonator -DETONATOR_LOC_REMOVE = §e{0} removed -DETONATOR_LOC_ADD = §e{0} added +DETONATOR_LOC_REMOVE=§e{0} removed +DETONATOR_LOC_ADD=§e{0} added DETONATOR_BUTTON_SWITCH=Lever DETONATOR_BUTTON_WOOD_BUTTON=Button DETONATOR_BUTTON_STONE_BUTTON=Button @@ -219,318 +194,285 @@ GUI_EDITOR_ITEM_TRASH_LORE=§7Drop item here GUI_EDITOR_ITEM_MORE=§eMore items GUI_EDITOR_ITEM_CLOSE=§eClose GUI_EDITOR_TITLE_MORE=Select item - # Script ## Errors SCRIPT_ERROR_GUI=§cError in parsing script: Line {0} SCRIPT_ERROR_GLOBAL=§cError in global script: Line {0} SCRIPT_ERROR_CLICK=§cError in script: Line {0} SCRIPT_ERROR_ONLY_IN_GLOBAL=§cThis function is only available in global scripts - ## CustomScript -SCRIPT_HOTKEY_ITEM_NAME = §7Hotkey§8: §e{0} -SCRIPT_EVENT_ITEM_NAME = §7Event§8: §e{0} -SCRIPT_COMMAND_ITEM_NAME = §7Command§8: §e/{0} - +SCRIPT_HOTKEY_ITEM_NAME=§7Hotkey§8: §e{0} +SCRIPT_EVENT_ITEM_NAME=§7Event§8: §e{0} +SCRIPT_COMMAND_ITEM_NAME=§7Command§8: §e/{0} ## Script Menu GUI -SCRIPT_MENU_GUI_ITEM_LORE_1 = §7Click to retrieve -SCRIPT_MENU_GUI_ITEM_LORE_2 = §7Shift-Click to copy -SCRIPT_MENU_GUI_ITEM_LORE_3 = §7Right-Click to edit -SCRIPT_MENU_GUI_ITEM_LORE_4 = §7Middle-Click to preview -SCRIPT_MENU_GUI_NAME = §eScript-Menu -SCRIPT_MENU_GUI_ITEM_ADD_NAME = §eInsert -SCRIPT_MENU_GUI_ITEM_ADD_LORE = §7Click with a book to insert - -SCRIPT_MENU_GUI_ENTER_NAME = §eEnter a name +SCRIPT_MENU_GUI_ITEM_LORE_1=§7Click to retrieve +SCRIPT_MENU_GUI_ITEM_LORE_2=§7Shift-Click to copy +SCRIPT_MENU_GUI_ITEM_LORE_3=§7Right-Click to edit +SCRIPT_MENU_GUI_ITEM_LORE_4=§7Middle-Click to preview +SCRIPT_MENU_GUI_NAME=§eScript-Menu +SCRIPT_MENU_GUI_ITEM_ADD_NAME=§eInsert +SCRIPT_MENU_GUI_ITEM_ADD_LORE=§7Click with a book to insert +SCRIPT_MENU_GUI_ENTER_NAME=§eEnter a name SCRIPT_DEPRECATED=§cThe function §8\'§e{0}§8\'§c is deprecated and will be removed in the future. Please use §8\'§e{1}§8\'§c instead. - # Shield Printing -SHIELD_PRINTING_HELP_START = §8/§eshieldprinting start §8- §7Starts the shield printing -SHIELD_PRINTING_HELP_COPY = §8/§eshieldprinting copy §8- §7Copies the shield configuration -SHIELD_PRINTING_HELP_APPLY = §8/§eshieldprinting apply §8- §7Applies the shield configuration -SHIELD_PRINTING_HELP_STOP = §8/§eshieldprinting stop §8- §7Stops the shield printing -SHIELD_PRINTING_HELP_STEP_1 = §81. §7Paste the schematic you want to use -SHIELD_PRINTING_HELP_STEP_2 = §82. §7Start the shield printing with §8/§eshieldprinting start -SHIELD_PRINTING_HELP_STEP_3 = §83. §7Wait until the shield printing is finished -SHIELD_PRINTING_HELP_STEP_4 = §84. §7Edit the shields if necessary -SHIELD_PRINTING_HELP_STEP_5 = §85. §7Copy the shields printing with §8/§eshieldprinting copy -SHIELD_PRINTING_HELP_STEP_6 = §86. §7Paste the original schematic -SHIELD_PRINTING_HELP_STEP_7 = §87. §7Apply the shield printing with §8/§eshieldprinting apply - -SHIELD_PRINTING_NO_REGION = §cYou are not in a region. -SHIELD_PRINTING_NOT_RUNNING = §cThe shield printing is not running. -SHIELD_PRINTING_BOSSBAR = §fMovements: {0} -SHIELD_PRINTING_BOSSBAR_COPIED = §fMovements: {0} Copied: {1} - -SHIELD_PRINTING_GUI_NAME = §7Shield Printing -SHIELD_PRINTING_GUI_APPLY = §aApply -SHIELD_PRINTING_GUI_STATE_PREVIOUS = §7R-Click§8: §7Previous -SHIELD_PRINTING_GUI_STATE_NEXT = §7L-Click§8: §7Next -SHIELD_PRINTING_GUI_STATE_ACTIVE = §e> §7{0} -SHIELD_PRINTING_GUI_STATE_INACTIVE = §8> §7{0} -SHIELD_PRINTING_GUI_STATE_FROM_ORIGINAL = Original -SHIELD_PRINTING_GUI_STATE_FROM_COPY = Copy -SHIELD_PRINTING_GUI_STATE_ALWAYS_ON = On -SHIELD_PRINTING_GUI_STATE_ALWAYS_OFF = Off -SHIELD_PRINTING_GUI_STATE_ALWAYS_OPEN = Open -SHIELD_PRINTING_GUI_STATE_ALWAYS_CLOSED = Closed -SHIELD_PRINTING_GUI_STATE_FENCE = §7{0} §fFence Connections -SHIELD_PRINTING_GUI_STATE_OPENABLE = §7{0} §fOpened -SHIELD_PRINTING_GUI_STATE_PISTON = §7{0} §fExtended -SHIELD_PRINTING_GUI_STATE_POWERABLE = §7{0} §fPowered -SHIELD_PRINTING_GUI_STATE_WALL = §7{0} §fWall Connections - -SHIELD_PRINTING_START = §aThe shield printing has been started. -SHIELD_PRINTING_COPY = §aThe shield has been copied. -SHIELD_PRINTING_APPLY = §aThe shield has been applied. -SHIELD_PRINTING_STOP = §aThe shield printing has been stopped. - +SHIELD_PRINTING_HELP_START=§8/§eshieldprinting start §8- §7Starts the shield printing +SHIELD_PRINTING_HELP_COPY=§8/§eshieldprinting copy §8- §7Copies the shield configuration +SHIELD_PRINTING_HELP_APPLY=§8/§eshieldprinting apply §8- §7Applies the shield configuration +SHIELD_PRINTING_HELP_STOP=§8/§eshieldprinting stop §8- §7Stops the shield printing +SHIELD_PRINTING_HELP_STEP_1=§81. §7Paste the schematic you want to use +SHIELD_PRINTING_HELP_STEP_2=§82. §7Start the shield printing with §8/§eshieldprinting start +SHIELD_PRINTING_HELP_STEP_3=§83. §7Wait until the shield printing is finished +SHIELD_PRINTING_HELP_STEP_4=§84. §7Edit the shields if necessary +SHIELD_PRINTING_HELP_STEP_5=§85. §7Copy the shields printing with §8/§eshieldprinting copy +SHIELD_PRINTING_HELP_STEP_6=§86. §7Paste the original schematic +SHIELD_PRINTING_HELP_STEP_7=§87. §7Apply the shield printing with §8/§eshieldprinting apply +SHIELD_PRINTING_NO_REGION=§cYou are not in a region. +SHIELD_PRINTING_NOT_RUNNING=§cThe shield printing is not running. +SHIELD_PRINTING_BOSSBAR=§fMovements: {0} +SHIELD_PRINTING_BOSSBAR_COPIED=§fMovements: {0} Copied: {1} +SHIELD_PRINTING_GUI_NAME=§7Shield Printing +SHIELD_PRINTING_GUI_APPLY=§aApply +SHIELD_PRINTING_GUI_STATE_PREVIOUS=§7R-Click§8: §7Previous +SHIELD_PRINTING_GUI_STATE_NEXT=§7L-Click§8: §7Next +SHIELD_PRINTING_GUI_STATE_ACTIVE=§e> §7{0} +SHIELD_PRINTING_GUI_STATE_INACTIVE=§8> §7{0} +SHIELD_PRINTING_GUI_STATE_FROM_ORIGINAL=Original +SHIELD_PRINTING_GUI_STATE_FROM_COPY=Copy +SHIELD_PRINTING_GUI_STATE_ALWAYS_ON=On +SHIELD_PRINTING_GUI_STATE_ALWAYS_OFF=Off +SHIELD_PRINTING_GUI_STATE_ALWAYS_OPEN=Open +SHIELD_PRINTING_GUI_STATE_ALWAYS_CLOSED=Closed +SHIELD_PRINTING_GUI_STATE_FENCE=§7{0} §fFence Connections +SHIELD_PRINTING_GUI_STATE_OPENABLE=§7{0} §fOpened +SHIELD_PRINTING_GUI_STATE_PISTON=§7{0} §fExtended +SHIELD_PRINTING_GUI_STATE_POWERABLE=§7{0} §fPowered +SHIELD_PRINTING_GUI_STATE_WALL=§7{0} §fWall Connections +SHIELD_PRINTING_START=§aThe shield printing has been started. +SHIELD_PRINTING_COPY=§aThe shield has been copied. +SHIELD_PRINTING_APPLY=§aThe shield has been applied. +SHIELD_PRINTING_STOP=§aThe shield printing has been stopped. # Unsign Book UNSIGN_HELP=§8/§eunsign §8- §7Make a signed book writable again - # Simulator -SIMULATOR_HELP = §8/§esimulator §8-§7 Gives you the simulator wand -SIMULATOR_CREATE_HELP = §8/§esimulator create §8[§7name§8] §8-§7 Create a new simulator -SIMULATOR_CHANGE_HELP = §8/§esimulator change §8-§7 Change your simulator wand selection -SIMULATOR_DELETE_HELP = §8/§esimulator delete §8[§7name§8] §8-§7 Deletes the simulator -SIMULATOR_START_HELP = §8/§esimulator start §8[§7name§8] §8-§7 Starts the simulator -SIMULATOR_COPY_HELP = §8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Copy the simulator - -SIMULATOR_GUI_ITEM_NAME = §eTNT Simulator - -SIMULATOR_NO_SIM_IN_HAND = §cNo simulator item selected -SIMULATOR_GUI_SELECT_SIM = Simulator selection -SIMULATOR_GUI_CREATE_SIM = §eCreate simulator -SIMULATOR_GUI_CREATE_SIM_GUI = Create simulator -SIMULATOR_NAME_ALREADY_EXISTS = §cSimulator already exists -SIMULATOR_NAME_INVALID = §cInvalid name -SIMULATOR_ERROR_COPY = §cCopy failed -SIMULATOR_NOT_EXISTS = §cSimulator does not exist -SIMULATOR_CREATE = §aSimulator created -SIMULATOR_EDIT_LOCATION = §7Edit position -SIMULATOR_EDIT_PROPERTIES = §7Edit properties -SIMULATOR_EDIT_OTHER = §7Edit other -SIMULATOR_EDIT_GROUP = §7Edit group - -SIMULATOR_EDIT_GROUP_MENU = §eEdit group - -SIMULATOR_WAND_NAME = §eSimulator -SIMULATOR_WAND_NAME_SELECTED = §7Simulator §8- §e{0} -SIMULATOR_WAND_LORE_1 = §eRight click §8- §7Adds a position -SIMULATOR_WAND_LORE_2 = §eSneaking §8- §7Free movement -SIMULATOR_WAND_LORE_3 = §eLeft click §8- §7Start the simulation -SIMULATOR_WAND_LORE_4 = §eRight click in air §8- §7Opens the gui -SIMULATOR_WAND_LORE_5 = §eDouble Sneak §8- §7Swap between TNT and Redstone Block - -SIMULATOR_REGION_FROZEN = §cSimulator cannot be used inside frozen regions - +SIMULATOR_HELP=§8/§esimulator §8-§7 Gives you the simulator wand +SIMULATOR_CREATE_HELP=§8/§esimulator create §8[§7name§8] §8-§7 Create a new simulator +SIMULATOR_CHANGE_HELP=§8/§esimulator change §8-§7 Change your simulator wand selection +SIMULATOR_DELETE_HELP=§8/§esimulator delete §8[§7name§8] §8-§7 Deletes the simulator +SIMULATOR_START_HELP=§8/§esimulator start §8[§7name§8] §8-§7 Starts the simulator +SIMULATOR_COPY_HELP=§8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Copy the simulator +SIMULATOR_GUI_ITEM_NAME=§eTNT Simulator +SIMULATOR_NO_SIM_IN_HAND=§cNo simulator item selected +SIMULATOR_GUI_SELECT_SIM=Simulator selection +SIMULATOR_GUI_CREATE_SIM=§eCreate simulator +SIMULATOR_GUI_CREATE_SIM_GUI=Create simulator +SIMULATOR_NAME_ALREADY_EXISTS=§cSimulator already exists +SIMULATOR_NAME_INVALID=§cInvalid name +SIMULATOR_ERROR_COPY=§cCopy failed +SIMULATOR_NOT_EXISTS=§cSimulator does not exist +SIMULATOR_CREATE=§aSimulator created +SIMULATOR_EDIT_LOCATION=§7Edit position +SIMULATOR_EDIT_PROPERTIES=§7Edit properties +SIMULATOR_EDIT_OTHER=§7Edit other +SIMULATOR_EDIT_GROUP=§7Edit group +SIMULATOR_EDIT_GROUP_MENU=§eEdit group +SIMULATOR_WAND_NAME=§eSimulator +SIMULATOR_WAND_NAME_SELECTED=§7Simulator §8- §e{0} +SIMULATOR_WAND_LORE_1=§eRight click §8- §7Adds a position +SIMULATOR_WAND_LORE_2=§eSneaking §8- §7Free movement +SIMULATOR_WAND_LORE_3=§eLeft click §8- §7Start the simulation +SIMULATOR_WAND_LORE_4=§eRight click in air §8- §7Opens the gui +SIMULATOR_WAND_LORE_5=§eDouble Sneak §8- §7Swap between TNT and Redstone Block +SIMULATOR_REGION_FROZEN=§cSimulator cannot be used inside frozen regions ## Other -SIMULATOR_PLUS_ONE = §7+1 -SIMULATOR_PLUS_PIXEL_SHIFT = §eShift §7Click for §e+0,0625 -SIMULATOR_PLUS_FIVE_SHIFT = §eShift §7Click for §e+5 -SIMULATOR_MINUS_ONE = §7-1 -SIMULATOR_MINUS_PIXEL_SHIFT = §eShift §7Click for §e-0,0625 -SIMULATOR_MINUS_FIVE_SHIFT = §eShift §7Click for §e-5 -SIMULATOR_POSITION_X = §7x-Position -SIMULATOR_POSITION_Y = §7y-Position -SIMULATOR_POSITION_Z = §7z-Position -SIMULATOR_BACK = §eBack - -SIMULATOR_GUI_TOTAL_TNT = §7Total TNT§8: §e{0} - -SIMULATOR_DELETED = §cSimulator deleted - +SIMULATOR_PLUS_ONE=§7+1 +SIMULATOR_PLUS_PIXEL_SHIFT=§eShift §7Click for §e+0,0625 +SIMULATOR_PLUS_FIVE_SHIFT=§eShift §7Click for §e+5 +SIMULATOR_MINUS_ONE=§7-1 +SIMULATOR_MINUS_PIXEL_SHIFT=§eShift §7Click for §e-0,0625 +SIMULATOR_MINUS_FIVE_SHIFT=§eShift §7Click for §e-5 +SIMULATOR_POSITION_X=§7x-Position +SIMULATOR_POSITION_Y=§7y-Position +SIMULATOR_POSITION_Z=§7z-Position +SIMULATOR_BACK=§eBack +SIMULATOR_GUI_TOTAL_TNT=§7Total TNT§8: §e{0} +SIMULATOR_DELETED=§cSimulator deleted ## GUI -SIMULATOR_POSITION_EDIT = §eEdit position -SIMULATOR_POSITION_ADD = §eSet position -SIMULATOR_GUI_TNT_SPAWN_NAME = §eTNT -SIMULATOR_GUI_TNT_SPAWN_LORE_1 = §7TNT-Count§8: §e{0} -SIMULATOR_GUI_TNT_SPAWN_LORE_2 = §7Tick§8: §e{0} -SIMULATOR_GUI_TNT_SPAWN_LORE_3 = §7Lifespan§8: §e{0} -SIMULATOR_GUI_TNT_SPAWN_LORE_4 = §7 -SIMULATOR_GUI_TNT_SPAWN_LORE_5 = §7x§8: §e{0} -SIMULATOR_GUI_TNT_SPAWN_LORE_6 = §7y§8: §e{0} -SIMULATOR_GUI_TNT_SPAWN_LORE_7 = §7z§8: §e{0} -SIMULATOR_GUI_TNT_GROUP_NAME = §eTNT group -SIMULATOR_GUI_TNT_GROUP_LORE_1 = §7Element count§8: §e{0} -SIMULATOR_GUI_TNT_GROUP_LORE_2 = §7Tick§8: §e{0} -SIMULATOR_GUI_TNT_GROUP_LORE_3 = §7 -SIMULATOR_GUI_TNT_GROUP_LORE_4 = §7x§8: §e{0} -SIMULATOR_GUI_TNT_GROUP_LORE_5 = §7y§8: §e{0} -SIMULATOR_GUI_TNT_GROUP_LORE_6 = §7z§8: §e{0} -SIMULATOR_GUI_TNT_DISABLED = §cDisabled -SIMULATOR_GUI_NAME = Simulator -SIMULATOR_GUI_DELETE = §cDelete TNT -SIMULATOR_GUI_AUTO_TRACE = §eAutoTrace§8: §7{0} -SIMULATOR_GUI_MOVE_ALL = §eMove all - -SIMULATOR_ALIGNMENT_CENTER = §7Alignment§8: §eCenter -SIMULATOR_ALIGNMENT_POSITIVE_X = §7Alignment§8: §ePositive X -SIMULATOR_ALIGNMENT_NEGATIVE_X = §7Alignment§8: §eNegative X -SIMULATOR_ALIGNMENT_POSITIVE_Z = §7Alignment§8: §ePositive Z -SIMULATOR_ALIGNMENT_NEGATIVE_Z = §7Alignment§8: §eNegative Z - -SIMULATOR_MOVE_ALL_GUI_NAME = Move TNT - -SIMULATOR_TNT_SPAWN_GUI_NAME = Configure TNT {0} -SIMULATOR_TNT_SPAWN_EDIT_LOCATION = - Location -SIMULATOR_TNT_SPAWN_EDIT_PROPERTIES = - Properties -SIMULATOR_TNT_SPAWN_EDIT_OTHER = - Other -SIMULATOR_TNT_SPAWN_LORE = §eClick to change -SIMULATOR_TNT_SPAWN_COUNT = §7TNT-Count §8- §e{0} -SIMULATOR_TNT_SPAWN_COUNT_ANVIL_GUI_NAME = TNT-Count -SIMULATOR_TNT_SPAWN_TICK = §7Tick §8- §e{0} -SIMULATOR_TNT_SPAWN_TICK_ANVIL_GUI_NAME = Tick offset -SIMULATOR_TNT_SPAWN_FUSE = §7Lifespan §8- §e{0} -SIMULATOR_TNT_SPAWN_FUSE_ANVIL_GUI_NAME = Fuse-Ticks -SIMULATOR_TNT_SPAWN_VELOCITY_NAME = §7TNT -SIMULATOR_TNT_SPAWN_VELOCITY_X = §7TNT §eJump X §8- {0} -SIMULATOR_TNT_SPAWN_VELOCITY_Y = §7TNT §eJump Y §8- {0} -SIMULATOR_TNT_SPAWN_VELOCITY_Z = §7TNT §eJump Z §8- {0} -SIMULATOR_TNT_SPAWN_VELOCITY_ON = §aon -SIMULATOR_TNT_SPAWN_VELOCITY_OFF = §coff -SIMULATOR_TNT_SPAWN_POSITION_X = §7x-Position §8- §e{0} -SIMULATOR_TNT_SPAWN_POSITION_Y = §7y-Position §8- §e{0} -SIMULATOR_TNT_SPAWN_POSITION_Z = §7z-Position §8- §e{0} -SIMULATOR_TNT_SPAWN_ACTIVATED_NAME = §7Primed by -SIMULATOR_TNT_SPAWN_ACTIVATED_WITH = §7Primed by §8- §e{0} -SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_COMPARATOR = Comparator -SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_REPEATER = Repeater -SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_OBSERVER = Observer -SIMULATOR_TNT_SPAWN_INACTIVE = §7> §7{0} -SIMULATOR_TNT_SPAWN_ACTIVE = §e> §7{0} -SIMULATOR_TNT_SPAWN_MATERIAL = §eMaterial -SIMULATOR_TNT_SPAWN_MATERIAL_LORE_1 = §7Current material§8: §e{0} -SIMULATOR_TNT_SPAWN_MATERIAL_LORE_2 = §eLeft-Click §7to change -SIMULATOR_TNT_SPAWN_MATERIAL_LORE_3 = §eRight-Click §7to reset -SIMULATOR_TNT_SPAWN_ENABLED = §aEnabled -SIMULATOR_TNT_SPAWN_DISABLED = §cDisabled -SIMULATOR_MATERIAL_GUI_NAME = Change material -SIMULATOR_MATERIAL_NAME = §e{0} -SIMULATOR_MATERIAL_NAME_LORE = §7Material §8- §e{0} -SIMULATOR_MATERIAL_CLICK = §eClick to choose -SIMULATOR_TNT_SPAWN_ADD_IGNITION_PHASE = §eAdd prime phase -SIMULATOR_TNT_SPAWN_ADD_TNT = §eAdd TNT -SIMULATOR_TNT_SPAWN_REMOVE_TNT = §cRemove -SIMULATOR_TNT_SPAWN_POSITION_ANVIL_GUI_NAME = Position - +SIMULATOR_POSITION_EDIT=§eEdit position +SIMULATOR_POSITION_ADD=§eSet position +SIMULATOR_GUI_TNT_SPAWN_NAME=§eTNT +SIMULATOR_GUI_TNT_SPAWN_LORE_1=§7TNT-Count§8: §e{0} +SIMULATOR_GUI_TNT_SPAWN_LORE_2=§7Tick§8: §e{0} +SIMULATOR_GUI_TNT_SPAWN_LORE_3=§7Lifespan§8: §e{0} +SIMULATOR_GUI_TNT_SPAWN_LORE_4=§7 +SIMULATOR_GUI_TNT_SPAWN_LORE_5=§7x§8: §e{0} +SIMULATOR_GUI_TNT_SPAWN_LORE_6=§7y§8: §e{0} +SIMULATOR_GUI_TNT_SPAWN_LORE_7=§7z§8: §e{0} +SIMULATOR_GUI_TNT_GROUP_NAME=§eTNT group +SIMULATOR_GUI_TNT_GROUP_LORE_1=§7Element count§8: §e{0} +SIMULATOR_GUI_TNT_GROUP_LORE_2=§7Tick§8: §e{0} +SIMULATOR_GUI_TNT_GROUP_LORE_3=§7 +SIMULATOR_GUI_TNT_GROUP_LORE_4=§7x§8: §e{0} +SIMULATOR_GUI_TNT_GROUP_LORE_5=§7y§8: §e{0} +SIMULATOR_GUI_TNT_GROUP_LORE_6=§7z§8: §e{0} +SIMULATOR_GUI_TNT_DISABLED=§cDisabled +SIMULATOR_GUI_NAME=Simulator +SIMULATOR_GUI_DELETE=§cDelete TNT +SIMULATOR_GUI_AUTO_TRACE=§eAutoTrace§8: §7{0} +SIMULATOR_GUI_MOVE_ALL=§eMove all +SIMULATOR_ALIGNMENT_CENTER=§7Alignment§8: §eCenter +SIMULATOR_ALIGNMENT_POSITIVE_X=§7Alignment§8: §ePositive X +SIMULATOR_ALIGNMENT_NEGATIVE_X=§7Alignment§8: §eNegative X +SIMULATOR_ALIGNMENT_POSITIVE_Z=§7Alignment§8: §ePositive Z +SIMULATOR_ALIGNMENT_NEGATIVE_Z=§7Alignment§8: §eNegative Z +SIMULATOR_MOVE_ALL_GUI_NAME=Move TNT +SIMULATOR_TNT_SPAWN_GUI_NAME=Configure TNT {0} +SIMULATOR_TNT_SPAWN_EDIT_LOCATION=- Location +SIMULATOR_TNT_SPAWN_EDIT_PROPERTIES=- Properties +SIMULATOR_TNT_SPAWN_EDIT_OTHER=- Other +SIMULATOR_TNT_SPAWN_LORE=§eClick to change +SIMULATOR_TNT_SPAWN_COUNT=§7TNT-Count §8- §e{0} +SIMULATOR_TNT_SPAWN_COUNT_ANVIL_GUI_NAME=TNT-Count +SIMULATOR_TNT_SPAWN_TICK=§7Tick §8- §e{0} +SIMULATOR_TNT_SPAWN_TICK_ANVIL_GUI_NAME=Tick offset +SIMULATOR_TNT_SPAWN_FUSE=§7Lifespan §8- §e{0} +SIMULATOR_TNT_SPAWN_FUSE_ANVIL_GUI_NAME=Fuse-Ticks +SIMULATOR_TNT_SPAWN_VELOCITY_NAME=§7TNT +SIMULATOR_TNT_SPAWN_VELOCITY_X=§7TNT §eJump X §8- {0} +SIMULATOR_TNT_SPAWN_VELOCITY_Y=§7TNT §eJump Y §8- {0} +SIMULATOR_TNT_SPAWN_VELOCITY_Z=§7TNT §eJump Z §8- {0} +SIMULATOR_TNT_SPAWN_VELOCITY_ON=§aon +SIMULATOR_TNT_SPAWN_VELOCITY_OFF=§coff +SIMULATOR_TNT_SPAWN_POSITION_X=§7x-Position §8- §e{0} +SIMULATOR_TNT_SPAWN_POSITION_Y=§7y-Position §8- §e{0} +SIMULATOR_TNT_SPAWN_POSITION_Z=§7z-Position §8- §e{0} +SIMULATOR_TNT_SPAWN_ACTIVATED_NAME=§7Primed by +SIMULATOR_TNT_SPAWN_ACTIVATED_WITH=§7Primed by §8- §e{0} +SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_COMPARATOR=Comparator +SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_REPEATER=Repeater +SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_OBSERVER=Observer +SIMULATOR_TNT_SPAWN_INACTIVE=§7> §7{0} +SIMULATOR_TNT_SPAWN_ACTIVE=§e> §7{0} +SIMULATOR_TNT_SPAWN_MATERIAL=§eMaterial +SIMULATOR_TNT_SPAWN_MATERIAL_LORE_1=§7Current material§8: §e{0} +SIMULATOR_TNT_SPAWN_MATERIAL_LORE_2=§eLeft-Click §7to change +SIMULATOR_TNT_SPAWN_MATERIAL_LORE_3=§eRight-Click §7to reset +SIMULATOR_TNT_SPAWN_ENABLED=§aEnabled +SIMULATOR_TNT_SPAWN_DISABLED=§cDisabled +SIMULATOR_MATERIAL_GUI_NAME=Change material +SIMULATOR_MATERIAL_NAME=§e{0} +SIMULATOR_MATERIAL_NAME_LORE=§7Material §8- §e{0} +SIMULATOR_MATERIAL_CLICK=§eClick to choose +SIMULATOR_TNT_SPAWN_ADD_IGNITION_PHASE=§eAdd prime phase +SIMULATOR_TNT_SPAWN_ADD_TNT=§eAdd TNT +SIMULATOR_TNT_SPAWN_REMOVE_TNT=§cRemove +SIMULATOR_TNT_SPAWN_POSITION_ANVIL_GUI_NAME=Position # SmartPlace -SMART_PLACE_HELP = §8/§esmartplace §8-§7 Toggles SmartPlace -SMART_PLACE_INFO = §7Places rotatable blocks §eaway§7 from you when §esneaking§7. -SMART_PLACE_ENABLE = §aSmartPlace activated -SMART_PLACE_DISABLE = §cSmartPlace deactivated - +SMART_PLACE_HELP=§8/§esmartplace §8-§7 Toggles SmartPlace +SMART_PLACE_INFO=§7Places rotatable blocks §eaway§7 from you when §esneaking§7. +SMART_PLACE_ENABLE=§aSmartPlace activated +SMART_PLACE_DISABLE=§cSmartPlace deactivated # InventoryFiller -INVENTORY_FILL_HELP = §8/§einventoryfill §8- §7Toggles InventoryFill -INVENTORY_FILL_INFO = §7Helps you fill containers by looking at them while sneaking and dropping the item. Or just scroll on a container to change the amount of the item inside. -INVENTORY_FILL_ENABLE = §aInventoryFiller activated -INVENTORY_FILL_DISABLE = §cInventoryFiller deactivated - +INVENTORY_FILL_HELP=§8/§einventoryfill §8- §7Toggles InventoryFill +INVENTORY_FILL_INFO=§7Helps you fill containers by looking at them while sneaking and dropping the item. Or just scroll on a container to change the amount of the item inside. +INVENTORY_FILL_ENABLE=§aInventoryFiller activated +INVENTORY_FILL_DISABLE=§cInventoryFiller deactivated # Killchecker -KILLCHECKER_HELP_ENABLE = §8/§ekillchecker enable §8- §7Enables Killchecker / Recalculates kills -KILLCHECKER_HELP_DISABLE = §8/§ekillchecker disable §8- §7Disables Killchecker -KILLCHECKER_INFO = §7Shows the overlaps of cannon kills in your build area. -KILLCHECKER_INFO2 = §7Only colorable blocks like Wool, Terractotta, Stained Glass and Concrete are counted. -KILLCHECKER_ENABLE = §aKillchecker activated -KILLCHECKER_DISABLE = §cKillchecker deactivated -KILLCHECKER_BOSSBAR = §e§l{0} §7(§e{1}%§7) §e§l{2}§7 cannons - +KILLCHECKER_HELP_ENABLE=§8/§ekillchecker enable §8- §7Enables Killchecker / Recalculates kills +KILLCHECKER_HELP_DISABLE=§8/§ekillchecker disable §8- §7Disables Killchecker +KILLCHECKER_INFO=§7Shows the overlaps of cannon kills in your build area. +KILLCHECKER_INFO2=§7Only colorable blocks like Wool, Terractotta, Stained Glass and Concrete are counted. +KILLCHECKER_ENABLE=§aKillchecker activated +KILLCHECKER_DISABLE=§cKillchecker deactivated +KILLCHECKER_BOSSBAR=§e§l{0} §7(§e{1}%§7) §e§l{2}§7 cannons # BlockCounter -BLOCK_COUNTER_HELP_TOGGLE = §8/§eblockcounter §8- §7Toggle on/off -BLOCK_COUNTER_HELP_ENABLE = §8/§eblockcounter enable §8- §7Toggles BlockCounter on -BLOCK_COUNTER_HELP_DISABLE = §8/§eblockcounter disable §8- §7Toggles BlockCounter off -BLOCK_COUNTER_MESSAGE = §7Damage §8> §e{0} §7Blocks §e{1} §7TNT §e{2} §7Blocks/TNT §e{3} §7Blocks/tick -BLOCK_COUNTER_MESSAGE_SECOND = §7Damage §8> §e{0} §7Blocks §e{1} §7TNT §e{2} §7Blocks/TNT §e{3} §7Blocks/s -BLOCK_COUNTER_ENABLE = §7BlockCounter activated -BLOCK_COUNTER_DISABLE = §7BlockCounter deactivated - +BLOCK_COUNTER_HELP_TOGGLE=§8/§eblockcounter §8- §7Toggle on/off +BLOCK_COUNTER_HELP_ENABLE=§8/§eblockcounter enable §8- §7Toggles BlockCounter on +BLOCK_COUNTER_HELP_DISABLE=§8/§eblockcounter disable §8- §7Toggles BlockCounter off +BLOCK_COUNTER_MESSAGE=§7Damage §8> §e{0} §7Blocks §e{1} §7TNT §e{2} §7Blocks/TNT §e{3} §7Blocks/tick +BLOCK_COUNTER_MESSAGE_SECOND=§7Damage §8> §e{0} §7Blocks §e{1} §7TNT §e{2} §7Blocks/TNT §e{3} §7Blocks/s +BLOCK_COUNTER_ENABLE=§7BlockCounter activated +BLOCK_COUNTER_DISABLE=§7BlockCounter deactivated # DepthCounter -DEPTH_COUNTER_MESSAGE = §7Depth §8> §7 -DEPTH_COUNTER_COUNT = {0}{1}§8×{2}{3}§8×{4}{5} -DEPTH_COUNTER_HOVER = §7X§8ק7Y§8ק7Z -DEPTH_COUNTER_TNT = §7 TNT§8: §e{0} - +DEPTH_COUNTER_MESSAGE=§7Depth §8> §7 +DEPTH_COUNTER_COUNT={0}{1}§8×{2}{3}§8×{4}{5} +DEPTH_COUNTER_HOVER=§7X§8ק7Y§8ק7Z +DEPTH_COUNTER_TNT=§7 TNT§8: §e{0} # TPSLimit -TPSLIMIT_FREEZE_HELP = §8/§etpslimit 0 §8-§7 Freeze TPS -TPSLIMIT_LIMIT_HELP = §8/§etpslimit §8[§720>x>0.5§8] §8-§7 Slow TPS down -TPSLIMIT_WARP_HELP = §8/§etpslimit §8[§7x>20§8] §8-§7 Speed TPS up -TPSLIMIT_DEFAULT_HELP = §8/§etpslimit default §8-§7 Set TPS to 20 -TPSLIMIT_HELP = §8/§etpslimit §8-§7 Show current TPS - -TICK_FREEZE_HELP = §8/§etick rate 0 §8-§7 Freeze TPS -TICK_FREEZE_HELP_2 = §8/§etick freeze §8-§7 Freeze TPS -TICK_UNFREEZE_HELP = §8/§etick unfreeze §8-§7 Set TPS to 20 -TICK_LIMIT_HELP = §8/§etick rate §8[§720>x>0.5§8] §8-§7 Slow TPS down -TICK_WARP_HELP = §8/§etick rate §8[§7x>20§8] §8-§7 Speed TPS up -TICK_DEFAULT_HELP = §8/§etick rate default §8-§7 Set TPS to 20 -TICK_HELP = §8/§etick rate §8-§7 Show current TPS - -TICK_STEPPING_HELP = §8/§etick step §8<§7Ticks§8> §8-§7 Step n ticks or 1 forward -TICK_WARPING_HELP = §8/§etick warp §8<§7Ticks§8> §8<§7TPS§8> §8-§7 Warp n ticks or 1 forward - -TICK_BOSSBAR = §7Skipped §e{0}§8/§7{1} -TPSLIMIT_GUI_ITEM_NAME = §eTPS limiter -TPSLIMIT_GUI_ITEM_LORE = §7Currently: §e{0} -TPSLIMIT_ANVIL_GUI = New TPS limit -TPSLIMIT_CURRENT = §7Current TPS limit§8: §e{0} -TPSLIMIT_SET = §eSet TPS limit to {0} -TPSLIMIT_FROZEN = §eTPS frozen - +TPSLIMIT_FREEZE_HELP=§8/§etpslimit 0 §8-§7 Freeze TPS +TPSLIMIT_LIMIT_HELP=§8/§etpslimit §8[§720>x>0.5§8] §8-§7 Slow TPS down +TPSLIMIT_WARP_HELP=§8/§etpslimit §8[§7x>20§8] §8-§7 Speed TPS up +TPSLIMIT_DEFAULT_HELP=§8/§etpslimit default §8-§7 Set TPS to 20 +TPSLIMIT_HELP=§8/§etpslimit §8-§7 Show current TPS +TICK_FREEZE_HELP=§8/§etick rate 0 §8-§7 Freeze TPS +TICK_FREEZE_HELP_2=§8/§etick freeze §8-§7 Freeze TPS +TICK_UNFREEZE_HELP=§8/§etick unfreeze §8-§7 Set TPS to 20 +TICK_LIMIT_HELP=§8/§etick rate §8[§720>x>0.5§8] §8-§7 Slow TPS down +TICK_WARP_HELP=§8/§etick rate §8[§7x>20§8] §8-§7 Speed TPS up +TICK_DEFAULT_HELP=§8/§etick rate default §8-§7 Set TPS to 20 +TICK_HELP=§8/§etick rate §8-§7 Show current TPS +TICK_STEPPING_HELP=§8/§etick step §8<§7Ticks§8> §8-§7 Step n ticks or 1 forward +TICK_WARPING_HELP=§8/§etick warp §8<§7Ticks§8> §8<§7TPS§8> §8-§7 Warp n ticks or 1 forward +TICK_BOSSBAR=§7Skipped §e{0}§8/§7{1} +TPSLIMIT_GUI_ITEM_NAME=§eTPS limiter +TPSLIMIT_GUI_ITEM_LORE=§7Currently: §e{0} +TPSLIMIT_ANVIL_GUI=New TPS limit +TPSLIMIT_CURRENT=§7Current TPS limit§8: §e{0} +TPSLIMIT_SET=§eSet TPS limit to {0} +TPSLIMIT_FROZEN=§eTPS frozen # Trace TRACE_RECORD=§aon TRACE_HAS_TRACES=§ehas Traces -TRACE_IDLE_SINGLE=§esingle -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_CLICK_ISOLATE = §eClick to §aisolate§8/§cunisolate -TRACE_MESSAGE_SHOW_AT = §aTNT-positions shown with {0} at {1} -TRACE_MESSAGE_SHOW_FROM = §aAll TNT-positions shown with {0} from {1} -TRACE_MESSAGE_SHOW_FROM_TO = §aAll TNT-positions shown with {0} from {1} to {2} -TRACE_MESSAGE_SHOW_TO_SMALLER = §cTo must be bigger then from - -TRACE_COMMAND_HELP_START = §8/§etrace start §8- §7Starts recording of all TNT-positions -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_SHOW_AT = §8/§etrace show §8(§etime§8|§7fuse§8) §7at §8<§eTIME§8> - §7Shows all Trace Positions at §8<§eTIME§8> -TRACE_COMMAND_HELP_SHOW_FROM = §8/§etrace show §8(§etime§8|§7fuse§8) §7from §8<§eFROM§8> - §7Shows all Trace Positions from §8<§eFROM§8> -TRACE_COMMAND_HELP_SHOW_FROM_TO = §8/§etrace show §8(§etime§8|§7fuse§8) §7from §8<§eFROM§8> §7to §8<§eTO§8> - §7Shows all Trace Positions from §8<§eFROM§8> to §8<§eTO§8> -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_GUI_ITEM_NAME = §eTracer -TRACE_GUI_ITEM_LORE = §7Status§8: {0} -TRACE_GUI_NAME = Trace Gui -TRACE_GUI_TRACE_INACTIVE = §eStart Tracer -TRACE_GUI_TRACE_ACTIVE = §eStop Tracer -TRACE_GUI_TRACE_ACTIVE_AUTO = §eAuto-Trace is active -TRACE_GUI_AUTO_TRACE_INACTIVE = §eacitvate Auto-Tracer -TRACE_GUI_AUTO_TRACE_ACTIVE = §edeactivate Auto-Tracer -TRACE_GUI_DELETE = §eDelete trace - +TRACE_IDLE_AUTO=§eauto +TRACE_MESSAGE_START=§aTNT-Tracer started +TRACE_MESSAGE_AUTO_START=§eAuto TNT-Tracer started +TRACE_MESSAGE_AUTO_STOP=§cAuto TNT-Tracer stopped +TRACE_MESSAGE_STOP=§cTNT-Tracer stopped +TRACE_MESSAGE_CLEAR=§cAll TNT-positions deleted +TRACE_MESSAGE_DELETE=§cTrace TNT-positions deleted +TRACE_MESSAGE_SHOW=§aAll TNT-positions shown +TRACE_MESSAGE_HIDE=§cAll TNT-positions hidden +TRACE_MESSAGE_SHOW_AT=§aTNT-positions shown at {0} +TRACE_MESSAGE_SHOW_FROM=§aAll TNT-positions shown from {0} +TRACE_MESSAGE_SHOW_FROM_TO=§aAll TNT-positions shown from {0} to {1} +TRACE_MESSAGE_SHOW_TO_SMALLER=§cTo must be bigger then from +TRACE_MESSAGE_CLICK_ISOLATE=§eClick to §aisolate§8/§cunisolate +TRACE_MESSAGE_ISOLATE=§eTNT Positions have been isolated +TRACE_MESSAGE_SHARE=§e{0} shared his trace show state. +TRACE_MESSAGE_SHARE_HOVER=§eClick to view +TRACE_MESSAGE_FOLLOW=§aYou are now following {0} Trace show state +TRACE_MESSAGE_FOLLOW_SELF=§cYou cannot follow yourself! +TRACE_MESSAGE_UNFOLLOW=§cYou are no longer following a Trace show state +TRACE_COMMAND_HELP_START=§8/§etrace start §8- §7Starts 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_SHOW=§8/§etrace show §8<§eParameter§8> - §7Shows all TNT-positions +TRACE_COMMAND_HELP_SHOW_AT=§8/§etrace show §7at §8<§eTIME§8> - §7Shows all Trace Positions at §8<§eTIME§8> +TRACE_COMMAND_HELP_SHOW_AT_WITH=§8/§etrace show §7at §8<§eTIME§8> §7with §8<§eParameter§8> - §7Shows all Trace Positions at §8<§eTIME§8> +TRACE_COMMAND_HELP_SHOW_FROM=§8/§etrace show §7from §8<§eFROM§8> - §7Shows all Trace Positions from §8<§eFROM§8> +TRACE_COMMAND_HELP_SHOW_FROM_WITH=§8/§etrace show §7from §8<§eFROM§8> §7with §8<§eParameter§8> - §7Shows all Trace Positions from §8<§eFROM§8> +TRACE_COMMAND_HELP_SHOW_FROM_TO=§8/§etrace show §7from §8<§eFROM§8> §7to §8<§eTO§8> - §7Shows all Trace Positions from §8<§eFROM§8> to §8<§eTO§8> +TRACE_COMMAND_HELP_SHOW_FROM_TO_WITH=§8/§etrace show §7from §8<§eFROM§8> §7to §8<§eTO§8> §7with §8<§eParameter§8> - §7Shows all Trace Positions from §8<§eFROM§8> to §8<§eTO§8> +TRACE_COMMAND_HELP_HIDE=§8/§etrace hide §8- §7Hides all TNT-positions +TRACE_COMMAND_HELP_DELETE=§8/§etrace delete §8[§eTrace§8] §8- §7Deletes all TNT-positions or a Trace +TRACE_COMMAND_HELP_ISOLATE=§8/§etrace isolate §8[§eTrace§8] §8[§eTNT§8] §8- §7Isolates specific TNTs from the Trace +TRACE_COMMAND_HELP_SHARE=§8/§etrace share §8- §7Share your current Trace show state with others +TRACE_COMMAND_HELP_FOLLOW=§8/§etrace follow §8[§ePlayer§8] §8- §7Follow a players Trace show state +TRACE_COMMAND_HELP_UNFOLLOW=§8/§etrace unfollow §8- §7Unfollow the Trace show state +TRACE_GUI_ITEM_NAME=§eTracer +TRACE_GUI_ITEM_LORE=§7Status§8: {0} +TRACE_GUI_NAME=Trace Gui +TRACE_GUI_TRACE_INACTIVE=§eStart Tracer +TRACE_GUI_TRACE_ACTIVE=§eStop Tracer +TRACE_GUI_TRACE_ACTIVE_AUTO=§eAuto-Trace is active +TRACE_GUI_AUTO_TRACE_INACTIVE=§eacitvate Auto-Tracer +TRACE_GUI_AUTO_TRACE_ACTIVE=§edeactivate Auto-Tracer +TRACE_GUI_DELETE=§eDelete trace # Loader -LOADER_SETUP = §eSetup -LOADER_RUNNING = §aRunning -LOADER_PAUSE = §7Pause -LOADER_END = §8Finished - +LOADER_SETUP=§eSetup +LOADER_RUNNING=§aRunning +LOADER_PAUSE=§7Pause +LOADER_END=§8Finished +LOADER_SINGLE=§aSingle LOADER_MESSAGE_INTERACT=§e{0} added {1} LOADER_MESSAGE_UNINTERACT=§eRemoved Element LOADER_BUTTON_TNT=TNT @@ -548,10 +490,10 @@ LOADER_BUTTON_LECTERN=Lectern LOADER_BUTTON_TRAPDOOR=Trapdoor LOADER_BUTTON_DOOR=Door LOADER_BUTTON_FENCEGATE=Fencegate - LOADER_HELP_SETUP=§8/§eloader setup §8- §7Starts recording actions LOADER_SETUP_STOP_FIRST=§cPlease stop the current loader first! -LOADER_HELP_START=§8/§eloader start §8- §7Playback of previously recorded action +LOADER_HELP_START=§8/§eloader start §8- §7Playback of previously recorded actions +LOADER_HELP_SINGLE=§8/§7loader single - §7Single playback of previously recoded actions 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 @@ -562,11 +504,11 @@ 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_SINGLE_CMD=§7The Loader does a single playback. 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_NOTHING_RECORDED=§cYou have not recorded anything yet! LOADER_GUI_TITLE=Loader GUI LOADER_GUI_SHOW_ALL=Show all @@ -583,7 +525,6 @@ 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=§7Click to edit LOADER_GUI_ITEM_NAME=§7{0}§8: §e{1} LOADER_SETTING_NAME=§7{0} @@ -618,7 +559,6 @@ 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 LOADTIMER_HELP_START_1=§8/§eloadtimer start §8-§7 Starts the simple Loadtimer @@ -640,27 +580,25 @@ LOADTIMER_SUMARY_PLAYERTABLE_HEAD=§7Player: §eTNT §7(§eTNT/s§7) LOADTIMER_SUMARY_PLAYERTABLE_PLAYER=§7{0}: §e{1} §7(§e{2}/s§7) LOADTIMER_SUMARY_PLAYERTABLE_ALL=Total LOADTIMER_SUMARY_TIMES_HEAD=§7Time: §eSeconds §7(§eTicks§7) -LOADTIMER_SUMARY_TIMES_START = §7 || §7Start! -LOADTIMER_SUMARY_TIMES_ACTIVATION = §7 || Activation: §e{0}s §7(§e{1}t§7) -LOADTIMER_SUMARY_TIMES_IGNITION = §7 || Priming: §e{0}s §7(§e{1}t§7) -LOADTIMER_SUMARY_TIMES_EXPLOSION = §7 || Explosion: §e{0}s §7(§e{1}t§7) +LOADTIMER_SUMARY_TIMES_START=§7 || §7Start! +LOADTIMER_SUMARY_TIMES_ACTIVATION=§7 || Activation: §e{0}s §7(§e{1}t§7) +LOADTIMER_SUMARY_TIMES_IGNITION=§7 || Priming: §e{0}s §7(§e{1}t§7) +LOADTIMER_SUMARY_TIMES_EXPLOSION=§7 || Explosion: §e{0}s §7(§e{1}t§7) LOADTIMER_SUMARY_TIMES_LAST=§7\\/ LOADTIMER_SUMARY_STATS_HEAD=§7Cannon-Stats§8: LOADTIMER_SUMARY_STATS_TNT=§7TNT: §e{0} LOADTIMER_SUMARY_STATS_FREQ=§7Loading frequency: §e{0}/m§8, §7Shot frequency: §e{1}/m - # Observer -OBSERVER_HELP = §7Right-Click an Observer to get the Trace. Flame particles have to be enabled. The Particles will be shown in the block. -OBSERVER_HELP_ENABLE = §8/§eobserver enable §8-§7 Activates the Observer-Tracer -OBSERVER_HELP_DISABLE = §8/§eobserver disable §8-§7 Deactivates the Observer-Tracer -OBSERVER_HELP_DELETE = §8/§eobserver delete §8-§7 Deletes the Obersver-Tracer -OBSERVER_HELP_RETRACE = §8/§eobserver retrace §8-§7 Retraces The Observer-Tracer -OBSERVER_ENABLE = §7Observer trace started -OBSERVER_DISABLE = §7Observer trace stopped -OBSERVER_DELETE = §7Observer trace deleted -OBSERVER_RETRACE_DONE = §7Observer trace retraced -OBSERVER_RETRACE_NO_TRACE = §7No Observer trace to retrace - +OBSERVER_HELP=§7Right-Click an Observer to get the Trace. Flame particles have to be enabled. The Particles will be shown in the block. +OBSERVER_HELP_ENABLE=§8/§eobserver enable §8-§7 Activates the Observer-Tracer +OBSERVER_HELP_DISABLE=§8/§eobserver disable §8-§7 Deactivates the Observer-Tracer +OBSERVER_HELP_DELETE=§8/§eobserver delete §8-§7 Deletes the Obersver-Tracer +OBSERVER_HELP_RETRACE=§8/§eobserver retrace §8-§7 Retraces The Observer-Tracer +OBSERVER_ENABLE=§7Observer trace started +OBSERVER_DISABLE=§7Observer trace stopped +OBSERVER_DELETE=§7Observer trace deleted +OBSERVER_RETRACE_DONE=§7Observer trace retraced +OBSERVER_RETRACE_NO_TRACE=§7No Observer trace to retrace # Other OTHER_ITEMS_TELEPORT_NAME=§eTeleporter OTHER_ITEMS_TELEPORT_GUI_NAME=Teleport @@ -678,8 +616,8 @@ OTHER_ITEMS_INVENTORY_FILL_LORE_ACTIVE=§aActivated OTHER_ITEMS_INVENTORY_FILL_LORE_INACTIVE=§aDisabled OTHER_SLOT_INVALID_SLOT=§cInvalid slot OTHER_NOCLIP_SLOT_INFO=§7With /slot you can change the selected slot and take another block in the slot. -OTHER_NOCLIP_SLOT_HELP_PICK = §8/§eslot pick §8-§7 Take the faced block into your inventory. -OTHER_NOCLIP_SLOT_HELP_DROP = §8/§eslot drop §8-§7 Clears your slot +OTHER_NOCLIP_SLOT_HELP_PICK=§8/§eslot pick §8-§7 Take the faced block into your inventory. +OTHER_NOCLIP_SLOT_HELP_DROP=§8/§eslot drop §8-§7 Clears your slot OTHER_CLEAR_HELP_SELF=§8/§eclear §8- §7Clears your inventory OTHER_CLEAR_HELP_PLAYER=§8/§eclear §8[§7Player§8] §8- §7Clears a player inventory OTHER_CLEAR_CLEARED=Your inventory was cleared. @@ -693,7 +631,7 @@ OTHER_KILLALL_HELP_SELF=§8/§ekillall §8- §7Remove all entities from your reg OTHER_KILLALL_HELP_ALL=§8/§ekillall §8[§7Global§8/Local§7] §8- §7Remove all entities from your region or globally OTHER_KILLALL_REGION=§a{0} Entities removed OTHER_KILLALL_GLOBAL=§a{0} Entities removed from the world -OTHER_TELEPORT_HELP = §8/§etp §8[§7Player§8] §8-§7 Teleports you to another player +OTHER_TELEPORT_HELP=§8/§etp §8[§7Player§8] §8-§7 Teleports you to another player OTHER_TELEPORT_SELF_0=§cBe one with yourself! OTHER_TELEPORT_SELF_1=§cYou need someone to play with? We have a TeamSpeak! OTHER_TELEPORT_SELF_2=§cBlocks left to travel: 0; ETA: 0:00 @@ -702,9 +640,9 @@ OTHER_TELEPORT_SELF_4=§cFor such a distance? OTHER_TIME_HELP=§8/§etime §8<§7Time 0=Morining§8, §76000=Midday§8, §718000=Midnight§8> - §7Sets the time on the Build OTHER_TIME_INVALID=§cPlease input a time between 0 and 24000 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_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 @@ -716,7 +654,7 @@ OTHER_BIND_MESSAGE_UNBIND=§7Unbound command DEBUG_STICK_COMMAND_HELP=§8/§edebugstick §8-§7 receive a debugstick DEBUG_STICK_NAME=§eDebugstick #Skull Gui -SKULL_GUI_ITEM_NAME = §ePlayer Heads +SKULL_GUI_ITEM_NAME=§ePlayer Heads ANVIL_INV_NAME=Player name # StructureVoid STRUCTURE_VOID_COMMAND_HELP=§8/§estructureVoid §8-§7 Receive a StructureVoid @@ -726,17 +664,16 @@ DRAGON_EGG_COMMAND_HELP=§8/§edragonegg §8-§7 Receive a Dragon Egg NIGHT_VISION_HELP=§8/§enightvision §8-§7 Toggel nightvision. NIGHT_VISION_OFF=§eNightvision deactivated NIGHT_VISION_ON=§eNightvision activated -NIGHT_VISION_ITEM_ON = §7Nightvision: §eActivated -NIGHT_VISION_ITEM_OFF = §7Nightvision: §eDeactivated - +NIGHT_VISION_ITEM_ON=§7Nightvision: §eActivated +NIGHT_VISION_ITEM_OFF=§7Nightvision: §eDeactivated #Navigation Wand NAVIGATION_WAND=§eNavigation Wand NAVIGATION_WAND_LEFT_CLICK=§eLeft click: jump to location NAVIGATION_WAND_RIGHT_CLICK=§eRight click: pass through walls # Material -MATERIAL_SEARCH_PROPERTY_TRUE = §aShould have -MATERIAL_SEARCH_PROPERTY_FALSE = §cShould not have -MATERIAL_SEARCH_PROPERTY_IGNORE = §eIgnore +MATERIAL_SEARCH_PROPERTY_TRUE=§aShould have +MATERIAL_SEARCH_PROPERTY_FALSE=§cShould not have +MATERIAL_SEARCH_PROPERTY_IGNORE=§eIgnore MATERIAL_INV_NAME=§eMaterial {0}/{1} MATERIAL_SEARCH=§eSearch MATERIAL_BACK=§eBack @@ -853,198 +790,171 @@ REGION_TNT_TB=§aTNT-Damage activated outside the building area REGION_TNT_BUILD=§aTNT-Damage activated outside the testblok 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 15 minutes. AFK_WARNING_MESSAGE=§cThis server will stop in one minute if you remain inactive - -SKIN_HELP = §8/§eskin §8[§7Shortform§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Creates the skin schematic. Use 'public' as creator to have no creator, then copy the message to YoyoNow by clicking +SKIN_HELP=§8/§eskin §8[§7Shortform§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Creates the skin schematic. Use 'public' as creator to have no creator, then copy the message to YoyoNow by clicking SKIN_NO_REGION=§7You are not in a region with a changealbe skin SKIN_ALREADY_EXISTS=§cThis skin already exists like this SKIN_MESSAGE=§7Skin created SKIN_MESSAGE_HOVER=§eClick to copy for YoyoNow and send - # Panzern -PANZERN_HELP = §8/§epanzern §8[§7Block§8] §8[§7Slab§8] §8- §7Armor your WorldEdit selection -PANZERN_PREPARE1 = §71. Check, if barrels reach until border of armor. -PANZERN_PREPARE2 = §72. Carpet on the floor in walkways helps with armoring. -PANZERN_PREPARE3 = §73. Shieldtechnology should be encased. -PANZERN_PREPARE4 = §74. Standing in the region that is being armored can improve armoring. -PANZERN_NO_WORLDEDIT = §cYou have no WorldEdit selcetion -PANZERN_PROGRESS = §e{0} §7Blocks left, §e{1} §7Blocks per second, §e{2} §7block delta -PANZERN_DONE = §aDone - +PANZERN_HELP=§8/§epanzern §8[§7Block§8] §8[§7Slab§8] §8- §7Armor your WorldEdit selection +PANZERN_PREPARE1=§71. Check, if barrels reach until border of armor. +PANZERN_PREPARE2=§72. Carpet on the floor in walkways helps with armoring. +PANZERN_PREPARE3=§73. Shieldtechnology should be encased. +PANZERN_PREPARE4=§74. Standing in the region that is being armored can improve armoring. +PANZERN_NO_WORLDEDIT=§cYou have no WorldEdit selcetion +PANZERN_PROGRESS=§e{0} §7Blocks left, §e{1} §7Blocks per second, §e{2} §7block delta +PANZERN_DONE=§aDone # Laufbau -LAUFBAU_HELP = §8/§elaufbau §8[§7smallest§8|§7blastresistant§8] §8- §7Build a barrel in your WorldEdit selection using the traces -LAUFBAU_HELP_SETTINGS = §8/§elaufbau settings §8- §7Opens the settings GUI -LAUFBAU_PREPARE1 = §71. Trace the cannons as often as necessary, in all modes. -LAUFBAU_PREPARE2 = §72. Try to delete all fails from the traces. -LAUFBAU_NO_WORLDEDIT = §cYou don't have a WorldEdit selection -LAUFBAU_STATE_FILTERING_TRACES = Filtering traces -LAUFBAU_STATE_PROCESSING_TRACES = Connnecting traces -LAUFBAU_STATE_CREATE_LAUF = Create Barrel -LAUFBAU_SIMPLE_PROGRESS = §e{0}§8: §e{1}§8/§e{2} §7Time left§8: §e{3} -LAUFBAU_DONE = §aDone - -LAUFBAU_SETTINGS_GUI_NAME = §eLaufbau -LAUFBAU_SETTINGS_ACTIVE = §aActive -LAUFBAU_SETTINGS_INACTIVE = §cInactive -LAUFBAU_SETTINGS_MIXED = §e{0}§8/§e{1} §aActive -LAUFBAU_SETTINGS_GUI_BACK = §eBack - -LAUFBAU_SETTINGS_TOGGLE = §eClick §8-§7 Toggle -LAUFBAU_SETTINGS_ADVANCED = §eMiddle-Click §8-§7 Advanced settings - -LAUFBAU_BLOCK_COBWEB = §eCobweb -LAUFBAU_BLOCK_GRASS_PATH = §eGrass Path -LAUFBAU_BLOCK_SOUL_SAND = §eSoul Sand -LAUFBAU_BLOCK_COCOA = §eCocoa -LAUFBAU_BLOCK_TURTLE_EGG = §eTurtle Eggs -LAUFBAU_BLOCK_CHEST = §eChest -LAUFBAU_BLOCK_SNOW = §eSnow Layer -LAUFBAU_BLOCK_PLAYER_WALL_HEAD = §ePlayer Wall Head -LAUFBAU_BLOCK_STONECUTTER = §eStonecutter -LAUFBAU_BLOCK_PLAYER_HEAD = §ePlayer Head -LAUFBAU_BLOCK_CAKE = §eCake -LAUFBAU_BLOCK_END_STONE_BRICK_SLAB = §eEndstone Brick Slabs -LAUFBAU_BLOCK_SEA_PICKLE = §eSea Pickles -LAUFBAU_BLOCK_CAMPFIRE = §eCampfire -LAUFBAU_BLOCK_FLOWER_POT = §eFlower Pot -LAUFBAU_BLOCK_IRON_TRAPDOOR = §eIron Trapdoor -LAUFBAU_BLOCK_LILY_PAD = §eLily Pad -LAUFBAU_BLOCK_WHITE_CARPET = §eCarpet -LAUFBAU_BLOCK_END_ROD = §eEnd Rod -LAUFBAU_BLOCK_LIGHTNING_ROD = §eLightning Rod -LAUFBAU_BLOCK_CONDUIT = §eConduit -LAUFBAU_BLOCK_BREWING_STAND = §eBrewing Stand -LAUFBAU_BLOCK_BELL = §eBell -LAUFBAU_BLOCK_GRINDSTONE = §eGrindstone -LAUFBAU_BLOCK_HOPPER = §eHopper -LAUFBAU_BLOCK_LANTERN = §eLantern -LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS = §eEndstone Brick Stairs -LAUFBAU_BLOCK_CHORUS_PLANT = §eChorus Plant -LAUFBAU_BLOCK_NETHER_BRICK_FENCE = §eNether Brick Fence -LAUFBAU_BLOCK_IRON_BARS = §eIron Bars -LAUFBAU_BLOCK_END_STONE_BRICK_WALL = §eEndstone Brick Walls -LAUFBAU_BLOCK_SMALL_AMETHYST_BUD = §eSmall Amethyst Bud -LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD = §eMedium Amethyst Bud -LAUFBAU_BLOCK_LARGE_AMETHYST_BUD = §eLarge Amethyst Bud -LAUFBAU_BLOCK_AMETHYST_CLUSTER = §eAmethyst Cluster -LAUFBAU_BLOCK_CHAIN = §eChain -LAUFBAU_BLOCK_BIG_DRIP_LEAF = §eBig Drip Leaf -LAUFBAU_BLOCK_DRAGON_EGG = §eDragon Egg -LAUFBAU_BLOCK_AZALEA = §eAzalea -LAUFBAU_BLOCK_CANDLE = §eCandle -LAUFBAU_BLOCK_CANDLE_CAKE = §eCake with Candle -LAUFBAU_BLOCK_LECTERN = §eLectern - -LAUFBAU_FACING_NORTH = §8-§7 Facing North -LAUFBAU_FACING_SOUTH = §8-§7 Facing South -LAUFBAU_FACING_WEST = §8-§7 Facing West -LAUFBAU_FACING_EAST = §8-§7 Facing East -LAUFBAU_FACING_UP = §8-§7 Facing Up -LAUFBAU_FACING_DOWN = §8-§7 Facing Down - -LAUFBAU_COUNT_1 = §8-§7 Count 1 -LAUFBAU_COUNT_2 = §8-§7 Count 2 -LAUFBAU_COUNT_3 = §8-§7 Count 3 -LAUFBAU_COUNT_4 = §8-§7 Count 4 - -LAUFBAU_LAYERS_8 = §8-§7 Layers 8 -LAUFBAU_LAYERS_7 = §8-§7 Layers 7 -LAUFBAU_LAYERS_6 = §8-§7 Layers 6 -LAUFBAU_LAYERS_3 = §8-§7 Layers 3 -LAUFBAU_LAYERS_2 = §8-§7 Layers 2 - -LAUFBAU_TYPE_BOTTOM = §8-§7 Type bottom -LAUFBAU_TYPE_TOP = §8-§7 Type top - -LAUFBAU_HALF_BOTTOM = §8-§7 Half bottom -LAUFBAU_HALF_TOP = §8-§7 Half top - -LAUFBAU_OPEN = §8-§7 Opened - -LAUFBAU_ATTACHMENT_CEILING = §8-§7 Attachment Ceiling -LAUFBAU_ATTACHMENT_FLOOR = §8-§7 Attachment Floor -LAUFBAU_ATTACHMENT_DOUBLE_WALL = §8-§7 Attachment double Wall -LAUFBAU_ATTACHMENT_SINGLE_WALL = §8-§7 Attachment single Wall -LAUFBAU_ATTACHMENT_WALL = §8-§7 Attachment Wall - -LAUFBAU_CONNECTION_FLOOR = §8-§7 Connection Floor -LAUFBAU_CONNECTION_NORTH = §8-§7 Connection North -LAUFBAU_CONNECTION_SOUTH = §8-§7 Connection South -LAUFBAU_CONNECTION_EAST = §8-§7 Connection East -LAUFBAU_CONNECTION_WEST = §8-§7 Connection West -LAUFBAU_CONNECTION_DOWN = §8-§7 Connection Bottom -LAUFBAU_CONNECTION_UP = §8-§7 Connection Top - -LAUFBAU_HANGING = §8-§7 hanging - -LAUFBAU_SHAPE_STRAIGHT = §8-§7 Shape straight -LAUFBAU_SHAPE_OUTER_LEFT = §8-§7 Shape outer links -LAUFBAU_SHAPE_INNER_LEFT = §8-§7 Shape inner left - -LAUFBAU_TILT_NONE = §8-§7 Tilt none -LAUFBAU_TILT_PARTIAL = §8-§7 Tilt partial - +LAUFBAU_HELP=§8/§elaufbau §8[§7smallest§8|§7blastresistant§8] §8- §7Build a barrel in your WorldEdit selection using the traces +LAUFBAU_HELP_SETTINGS=§8/§elaufbau settings §8- §7Opens the settings GUI +LAUFBAU_PREPARE1=§71. Trace the cannons as often as necessary, in all modes. +LAUFBAU_PREPARE2=§72. Try to delete all fails from the traces. +LAUFBAU_NO_WORLDEDIT=§cYou don't have a WorldEdit selection +LAUFBAU_STATE_FILTERING_TRACES=Filtering traces +LAUFBAU_STATE_PROCESSING_TRACES=Connnecting traces +LAUFBAU_STATE_CREATE_LAUF=Create Barrel +LAUFBAU_SIMPLE_PROGRESS=§e{0}§8: §e{1}§8/§e{2} §7Time left§8: §e{3} +LAUFBAU_DONE=§aDone +LAUFBAU_SETTINGS_GUI_NAME=§eLaufbau +LAUFBAU_SETTINGS_ACTIVE=§aActive +LAUFBAU_SETTINGS_INACTIVE=§cInactive +LAUFBAU_SETTINGS_MIXED=§e{0}§8/§e{1} §aActive +LAUFBAU_SETTINGS_GUI_BACK=§eBack +LAUFBAU_SETTINGS_TOGGLE=§eClick §8-§7 Toggle +LAUFBAU_SETTINGS_ADVANCED=§eMiddle-Click §8-§7 Advanced settings +LAUFBAU_BLOCK_COBWEB=§eCobweb +LAUFBAU_BLOCK_GRASS_PATH=§eGrass Path +LAUFBAU_BLOCK_SOUL_SAND=§eSoul Sand +LAUFBAU_BLOCK_COCOA=§eCocoa +LAUFBAU_BLOCK_TURTLE_EGG=§eTurtle Eggs +LAUFBAU_BLOCK_CHEST=§eChest +LAUFBAU_BLOCK_SNOW=§eSnow Layer +LAUFBAU_BLOCK_PLAYER_WALL_HEAD=§ePlayer Wall Head +LAUFBAU_BLOCK_STONECUTTER=§eStonecutter +LAUFBAU_BLOCK_PLAYER_HEAD=§ePlayer Head +LAUFBAU_BLOCK_CAKE=§eCake +LAUFBAU_BLOCK_END_STONE_BRICK_SLAB=§eEndstone Brick Slabs +LAUFBAU_BLOCK_SEA_PICKLE=§eSea Pickles +LAUFBAU_BLOCK_CAMPFIRE=§eCampfire +LAUFBAU_BLOCK_FLOWER_POT=§eFlower Pot +LAUFBAU_BLOCK_IRON_TRAPDOOR=§eIron Trapdoor +LAUFBAU_BLOCK_LILY_PAD=§eLily Pad +LAUFBAU_BLOCK_WHITE_CARPET=§eCarpet +LAUFBAU_BLOCK_END_ROD=§eEnd Rod +LAUFBAU_BLOCK_LIGHTNING_ROD=§eLightning Rod +LAUFBAU_BLOCK_CONDUIT=§eConduit +LAUFBAU_BLOCK_BREWING_STAND=§eBrewing Stand +LAUFBAU_BLOCK_BELL=§eBell +LAUFBAU_BLOCK_GRINDSTONE=§eGrindstone +LAUFBAU_BLOCK_HOPPER=§eHopper +LAUFBAU_BLOCK_LANTERN=§eLantern +LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS=§eEndstone Brick Stairs +LAUFBAU_BLOCK_CHORUS_PLANT=§eChorus Plant +LAUFBAU_BLOCK_NETHER_BRICK_FENCE=§eNether Brick Fence +LAUFBAU_BLOCK_IRON_BARS=§eIron Bars +LAUFBAU_BLOCK_END_STONE_BRICK_WALL=§eEndstone Brick Walls +LAUFBAU_BLOCK_SMALL_AMETHYST_BUD=§eSmall Amethyst Bud +LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD=§eMedium Amethyst Bud +LAUFBAU_BLOCK_LARGE_AMETHYST_BUD=§eLarge Amethyst Bud +LAUFBAU_BLOCK_AMETHYST_CLUSTER=§eAmethyst Cluster +LAUFBAU_BLOCK_CHAIN=§eChain +LAUFBAU_BLOCK_BIG_DRIP_LEAF=§eBig Drip Leaf +LAUFBAU_BLOCK_DRAGON_EGG=§eDragon Egg +LAUFBAU_BLOCK_AZALEA=§eAzalea +LAUFBAU_BLOCK_CANDLE=§eCandle +LAUFBAU_BLOCK_CANDLE_CAKE=§eCake with Candle +LAUFBAU_BLOCK_LECTERN=§eLectern +LAUFBAU_FACING_NORTH=§8-§7 Facing North +LAUFBAU_FACING_SOUTH=§8-§7 Facing South +LAUFBAU_FACING_WEST=§8-§7 Facing West +LAUFBAU_FACING_EAST=§8-§7 Facing East +LAUFBAU_FACING_UP=§8-§7 Facing Up +LAUFBAU_FACING_DOWN=§8-§7 Facing Down +LAUFBAU_COUNT_1=§8-§7 Count 1 +LAUFBAU_COUNT_2=§8-§7 Count 2 +LAUFBAU_COUNT_3=§8-§7 Count 3 +LAUFBAU_COUNT_4=§8-§7 Count 4 +LAUFBAU_LAYERS_8=§8-§7 Layers 8 +LAUFBAU_LAYERS_7=§8-§7 Layers 7 +LAUFBAU_LAYERS_6=§8-§7 Layers 6 +LAUFBAU_LAYERS_3=§8-§7 Layers 3 +LAUFBAU_LAYERS_2=§8-§7 Layers 2 +LAUFBAU_TYPE_BOTTOM=§8-§7 Type bottom +LAUFBAU_TYPE_TOP=§8-§7 Type top +LAUFBAU_HALF_BOTTOM=§8-§7 Half bottom +LAUFBAU_HALF_TOP=§8-§7 Half top +LAUFBAU_OPEN=§8-§7 Opened +LAUFBAU_ATTACHMENT_CEILING=§8-§7 Attachment Ceiling +LAUFBAU_ATTACHMENT_FLOOR=§8-§7 Attachment Floor +LAUFBAU_ATTACHMENT_DOUBLE_WALL=§8-§7 Attachment double Wall +LAUFBAU_ATTACHMENT_SINGLE_WALL=§8-§7 Attachment single Wall +LAUFBAU_ATTACHMENT_WALL=§8-§7 Attachment Wall +LAUFBAU_CONNECTION_FLOOR=§8-§7 Connection Floor +LAUFBAU_CONNECTION_NORTH=§8-§7 Connection North +LAUFBAU_CONNECTION_SOUTH=§8-§7 Connection South +LAUFBAU_CONNECTION_EAST=§8-§7 Connection East +LAUFBAU_CONNECTION_WEST=§8-§7 Connection West +LAUFBAU_CONNECTION_DOWN=§8-§7 Connection Bottom +LAUFBAU_CONNECTION_UP=§8-§7 Connection Top +LAUFBAU_HANGING=§8-§7 hanging +LAUFBAU_SHAPE_STRAIGHT=§8-§7 Shape straight +LAUFBAU_SHAPE_OUTER_LEFT=§8-§7 Shape outer links +LAUFBAU_SHAPE_INNER_LEFT=§8-§7 Shape inner left +LAUFBAU_TILT_NONE=§8-§7 Tilt none +LAUFBAU_TILT_PARTIAL=§8-§7 Tilt partial # UTILS -SELECT_HELP = §8/§eselect §8[§7RegionsTyp§8] §8- §7Select a region type -SELECT_EXTENSION_HELP = §8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Select a region type with or without extension -SELECT_GLOBAL_REGION = §cThe global region cannot be selected -SELECT_NO_TYPE = §cThis region has no {0} -SELECT_NO_EXTENSION = §cThis region has no extension -SELECT_MESSAGE = §7WorldEdit selection set to {0}, {1}, {2} and {3}, {4}, {5} - -SKULL_HELP = §8/§eskull §8[§eplayer§8] §8-§7 Receive a player head -SKULL_INVALID = §cInvalid player name -SKULL_ITEM = §e{0}§8s Head - -SPEED_HELP = §8/§espeed §8[§71§8-§710§8|§edefault§8] §8-§7 Set your flight and walking speed. -SPEED_CURRENT = §7Current speed§8: §e{0} -SPEED_TOO_SMALL = §c{0} is too small -SPEED_TOO_HIGH = §c{0} is too big -SPEED_ITEM = §eSpeed -SPEED_ITEM_LORE = §7Currently: §e -SPEED_TAB_NAME = Input speed - -WORLDEDIT_WAND = WorldEdit Wand -WORLDEDIT_LEFTCLICK = Left click: select pos #1 -WORLDEDIT_RIGHTCLICK = Right click: select pos #2 - -TNT_CLICK_HEADER = §8---=== §eTNT §8===--- -TNT_CLICK_ORDER = §eEntity Order§8: §e{0} -TNT_CLICK_FUSE_TIME = §eFuseTime§8: §e{0} -TNT_CLICK_POSITION_X = §7Position §eX§8: §e{0} -TNT_CLICK_POSITION_Y = §7Position §eY§8: §e{0} -TNT_CLICK_POSITION_Z = §7Position §eZ§8: §e{0} -TNT_CLICK_VELOCITY_X = §7Velocity §eX§8: §e{0} -TNT_CLICK_VELOCITY_Y = §7Velocity §eY§8: §e{0} -TNT_CLICK_VELOCITY_Z = §7Velocity §eZ§8: §e{0} -TNT_CLICK_COUNT = §7Count §8: §e{0} -TNT_CLICK_ISOLATE = §eIsolate - -SELECT_ITEM_CHOOSE_EXTENSION = Choose extension -SELECT_ITEM_CHOOSE_SELECTION = Choose selection -SELECT_ITEM_NORMAL_EXTENSION = §eNormal -SELECT_ITEM_EXTENDED_EXTENSION= §eExtension -SELECT_ITEM_SELECT= §eSelect -SELECT_ITEM_AUSWAHL= §7Selection: §7{0} {1} +SELECT_HELP=§8/§eselect §8[§7RegionsTyp§8] §8- §7Select a region type +SELECT_EXTENSION_HELP=§8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Select a region type with or without extension +SELECT_GLOBAL_REGION=§cThe global region cannot be selected +SELECT_NO_TYPE=§cThis region has no {0} +SELECT_NO_EXTENSION=§cThis region has no extension +SELECT_MESSAGE=§7WorldEdit selection set to {0}, {1}, {2} and {3}, {4}, {5} +SKULL_HELP=§8/§eskull §8[§eplayer§8] §8-§7 Receive a player head +SKULL_INVALID=§cInvalid player name +SKULL_ITEM=§e{0}§8s Head +SPEED_HELP=§8/§espeed §8[§71§8-§710§8|§edefault§8] §8-§7 Set your flight and walking speed. +SPEED_CURRENT=§7Current speed§8: §e{0} +SPEED_TOO_SMALL=§c{0} is too small +SPEED_TOO_HIGH=§c{0} is too big +SPEED_ITEM=§eSpeed +SPEED_ITEM_LORE=§7Currently: §e +SPEED_TAB_NAME=Input speed +WORLDEDIT_WAND=WorldEdit Wand +WORLDEDIT_LEFTCLICK=Left click: select pos #1 +WORLDEDIT_RIGHTCLICK=Right click: select pos #2 +TNT_CLICK_HEADER=§8---=== §eTNT §8===--- +TNT_CLICK_ORDER=§eEntity Order§8: §e{0} +TNT_CLICK_FUSE_TIME=§eFuseTime§8: §e{0} +TNT_CLICK_POSITION_X=§7Position §eX§8: §e{0} +TNT_CLICK_POSITION_Y=§7Position §eY§8: §e{0} +TNT_CLICK_POSITION_Z=§7Position §eZ§8: §e{0} +TNT_CLICK_VELOCITY_X=§7Velocity §eX§8: §e{0} +TNT_CLICK_VELOCITY_Y=§7Velocity §eY§8: §e{0} +TNT_CLICK_VELOCITY_Z=§7Velocity §eZ§8: §e{0} +TNT_CLICK_COUNT=§7Count §8: §e{0} +TNT_CLICK_ISOLATE=§eIsolate +SELECT_ITEM_CHOOSE_EXTENSION=Choose extension +SELECT_ITEM_CHOOSE_SELECTION=Choose selection +SELECT_ITEM_NORMAL_EXTENSION=§eNormal +SELECT_ITEM_EXTENDED_EXTENSION=§eExtension +SELECT_ITEM_SELECT=§eSelect +SELECT_ITEM_AUSWAHL=§7Selection: §7{0} {1} SELECT_ITEM_RIGHT_CLICK=§7Right-Click to change SELECT_ITEM_BAURAHMEN=§eBuild area SELECT_ITEM_BAUPLATTFORM=§eBuild platform SELECT_ITEM_TESTBLOCK=§eDummy - -CHESTFILLER_FILLED = §eChest filled -CHESTFILLER_COUNT = §7{0}§8: §e§l{1} - -PISTON_HELP_1 = §7Right click on piston with a slime ball to calculate the moved blocks. -PISTON_HELP_2 = §7Count is red, if one unmoveable block is present. -PISTON_HELP_3 = §7Count is yellow, if too many blocks are present. -PISTON_INFO = §7Moved Blocks {0}{1}§8/§712 - +CHESTFILLER_FILLED=§eChest filled +CHESTFILLER_COUNT=§7{0}§8: §e§l{1} +PISTON_HELP_1=§7Right click on piston with a slime ball to calculate the moved blocks. +PISTON_HELP_2=§7Count is red, if one unmoveable block is present. +PISTON_HELP_3=§7Count is yellow, if too many blocks are present. +PISTON_INFO=§7Moved Blocks {0}{1}§8/§712 # Warp -WARP_LOC_X = §7X§8: §e{0} -WARP_LOC_Y = §7Y§8: §e{0} -WARP_LOC_Z = §7Z§8: §e{0} +WARP_LOC_X=§7X§8: §e{0} +WARP_LOC_Y=§7Y§8: §e{0} +WARP_LOC_Z=§7Z§8: §e{0} WARP_EXISTS=§7The warp with the name §e{0} §7already exists WARP_NAME_RESERVED=§7You can not use §c{0} §7as name for a warp WARP_CREATED=§7The warp §e{0} §7was created @@ -1064,30 +974,22 @@ WARP_HELP_INFO=§8/§ewarp info §8[§7name§8] §8- §7Information regarding on WARP_HELP_DELETE=§8/§ewarp delete §8[§7name§8] §8- §7Delete a warp WARP_HELP_GUI=§8/§ewarp gui §8- §7Open the Warp-GUI WARP_HELP_LIST=§8/§ewarp list §8- §7List all warps - # WORLD -STOP_HELP = §8/§estop §8- §7Stops the server -STOP_MESSAGE = §eServer is stopping - -KICKALL_HELP = §8/§ekickall §8- §7Kick all players from the server except the owner - +STOP_HELP=§8/§estop §8- §7Stops the server +STOP_MESSAGE=§eServer is stopping +KICKALL_HELP=§8/§ekickall §8- §7Kick all players from the server except the owner # Techhider -TECHHIDER_HELP = §8/§etechhider §8- §7Toggle Techhider -TECHHIDER_GLOBAL = §cNo techhider in global region -TECHHIDER_ON = §aTechhider activated -TECHHIDER_OFF = §cTechhider deactivated - +TECHHIDER_HELP=§8/§etechhider §8- §7Toggle Techhider +TECHHIDER_GLOBAL=§cNo techhider in global region +TECHHIDER_ON=§aTechhider activated +TECHHIDER_OFF=§cTechhider deactivated # XRAY -XRAY_HELP = §8/§exray §8- §7Toggle Xray -XRAY_GLOBAL = §cNo xray in global region -XRAY_ON = §aXray activated -XRAY_OFF = §cXray deactivated - - +XRAY_HELP=§8/§exray §8- §7Toggle Xray +XRAY_GLOBAL=§cNo xray in global region +XRAY_ON=§aXray activated +XRAY_OFF=§cXray deactivated # WorldEdit -COLORREPLACE_HELP = §8//§ecolorreplace §8[§7color§8] §8[§7color§8] §8- §7Replace all blocks of one color with another - -TYPEREPLACE_HELP = §8//§etyreplace §8[§7type§8] §8[§7type§8] §8- §7Replace all blocks of one type with another - +COLORREPLACE_HELP=§8//§ecolorreplace §8[§7color§8] §8[§7color§8] §8- §7Replace all blocks of one color with another +TYPEREPLACE_HELP=§8//§etyreplace §8[§7type§8] §8[§7type§8] §8- §7Replace all blocks of one type with another # Schematic SCHEMATIC_GUI_ITEM=§eSchematics diff --git a/BauSystem_Main/src/BauSystem_de.properties b/BauSystem_Main/src/BauSystem_de.properties index 46b30880..57df12df 100644 --- a/BauSystem_Main/src/BauSystem_de.properties +++ b/BauSystem_Main/src/BauSystem_de.properties @@ -16,108 +16,89 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - -PREFIX = §eBau§8System§8» -TIME = HH:mm:ss +PREFIX=§eBau§8System§8» +TIME=HH:mm:ss DATE=........ COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===--- ONLY_SCHEMS=§cDu kannst hier keinen Ordner angeben - PAGE_LIST=§e Seite ({0}/{1}) »» LIST_PREVIOUS_PAGE=§eVorherige Seite LIST_NEXT_PAGE=§eNächste Seite - # Permission -NO_PERMISSION = Du darfst dies hier nicht nutzen -SPECTATOR = §fZuschauer - +NO_PERMISSION=Du darfst dies hier nicht nutzen +SPECTATOR=§fZuschauer # Scoreboard -SCOREBOARD_TIME = Uhrzeit -SCOREBOARD_REGION = Region -SCOREBOARD_TRACE = Trace -SCOREBOARD_LOADER = Loader -SCOREBOARD_TPS = TPS -SCOREBOARD_TPS_FROZEN = §eEingefroren - -SCOREBOARD_TRACE_TICKS = Ticks - -SCOREBOARD_TECHHIDER = TechHider§8: §aAn -SCOREBOARD_XRAY = XRay§8: §aAn - -SCOREBOARD_LOCK_TEAM = Bau Lock§8: §eTeam -SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM = Bau Lock§8: §e(Server-) Team -SCOREBOARD_LOCK_SERVERTEAM = Bau Lock§8: §eServerteam -SCOREBOARD_LOCK_NOBODY = Bau Lock§8: §cNiemand - +SCOREBOARD_TIME=Uhrzeit +SCOREBOARD_REGION=Region +SCOREBOARD_TRACE=Trace +SCOREBOARD_LOADER=Loader +SCOREBOARD_TPS=TPS +SCOREBOARD_TPS_FROZEN=§eEingefroren +SCOREBOARD_TRACE_TICKS=Ticks +SCOREBOARD_TECHHIDER=TechHider§8: §aAn +SCOREBOARD_XRAY=XRay§8: §aAn +SCOREBOARD_LOCK_TEAM=Bau Lock§8: §eTeam +SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM=Bau Lock§8: §e(Server-) Team +SCOREBOARD_LOCK_SERVERTEAM=Bau Lock§8: §eServerteam +SCOREBOARD_LOCK_NOBODY=Bau Lock§8: §cNiemand # Flags -FLAG_COLOR = Color -FLAG_TNT = TNT -FLAG_FIRE = Fire -FLAG_FREEZE = Freeze -FLAG_PROTECT = Protect -FLAG_ITEMS = Items - -FLAG_FIRE_ALLOW = §can -FLAG_FIRE_DENY = §aaus - -FLAG_FREEZE_ACTIVE = §aan -FLAG_FREEZE_INACTIVE = §caus - -FLAG_PROTECT_ACTIVE = §aan -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 - -FLAG_COLOR_WHITE = §fWeiß -FLAG_COLOR_ORANGE = §6Orange -FLAG_COLOR_MAGENTA = §dMagenta -FLAG_COLOR_LIGHT_BLUE = §bHellblau -FLAG_COLOR_YELLOW = §eGelb -FLAG_COLOR_LIME = §aHellgrün +FLAG_COLOR=Color +FLAG_TNT=TNT +FLAG_FIRE=Fire +FLAG_FREEZE=Freeze +FLAG_PROTECT=Protect +FLAG_ITEMS=Items +FLAG_FIRE_ALLOW=§can +FLAG_FIRE_DENY=§aaus +FLAG_FREEZE_ACTIVE=§aan +FLAG_FREEZE_INACTIVE=§caus +FLAG_PROTECT_ACTIVE=§aan +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 +FLAG_COLOR_WHITE=§fWeiß +FLAG_COLOR_ORANGE=§6Orange +FLAG_COLOR_MAGENTA=§dMagenta +FLAG_COLOR_LIGHT_BLUE=§bHellblau +FLAG_COLOR_YELLOW=§eGelb +FLAG_COLOR_LIME=§aHellgrün ## This cannot be converted -FLAG_COLOR_PINK = §ePink -FLAG_COLOR_GRAY = §8Grau -FLAG_COLOR_LIGHT_GRAY = §7Hellgrau -FLAG_COLOR_CYAN = §3Cyan -FLAG_COLOR_PURPLE = §5Lila -FLAG_COLOR_BLUE = §1Blau +FLAG_COLOR_PINK=§ePink +FLAG_COLOR_GRAY=§8Grau +FLAG_COLOR_LIGHT_GRAY=§7Hellgrau +FLAG_COLOR_CYAN=§3Cyan +FLAG_COLOR_PURPLE=§5Lila +FLAG_COLOR_BLUE=§1Blau ## This cannot be converted -FLAG_COLOR_BROWN = §eBraun -FLAG_COLOR_GREEN = §2Grün -FLAG_COLOR_RED = §cRot -FLAG_COLOR_BLACK = §0Schwarz - +FLAG_COLOR_BROWN=§eBraun +FLAG_COLOR_GREEN=§2Grün +FLAG_COLOR_RED=§cRot +FLAG_COLOR_BLACK=§0Schwarz # Region -REGION_TYPE_NORMAL = Normal -REGION_TYPE_BUILD = Baubereich -REGION_TYPE_ONLY_TB = Testblock - +REGION_TYPE_NORMAL=Normal +REGION_TYPE_BUILD=Baubereich +REGION_TYPE_ONLY_TB=Testblock # AttributesCopy -ATTRIBUTES_CANT_COPY = §cDu musst den Item Type in der Hand halten wo du auch drauf guckst. -ATTRIBUTES_NO_COPY = §cKeine Attribute kopiert. -ATTRIBUTES_COPIED = §eAttribute kopiert. - -ATTRIBUTE_REMOVE_ALL = §eAlle Attribute entfernt. -ATTRIBUTE_REMOVE_SINGLE = §eAttribut §7{0}§e entfernt. -ATTRIBUTE_REMOVE_NOT_FOUND = §cAttribut nicht gefunden - +ATTRIBUTES_CANT_COPY=§cDu musst den Item Type in der Hand halten wo du auch drauf guckst. +ATTRIBUTES_NO_COPY=§cKeine Attribute kopiert. +ATTRIBUTES_COPIED=§eAttribute kopiert. +ATTRIBUTE_REMOVE_ALL=§eAlle Attribute entfernt. +ATTRIBUTE_REMOVE_SINGLE=§eAttribut §7{0}§e entfernt. +ATTRIBUTE_REMOVE_NOT_FOUND=§cAttribut nicht gefunden # AutoStart -AUTOSTART_COMMAND_HELP = §8/§etimer §8- §7Legt den AutostartTimer ins Inventar -AUTOSTART_ITEM_NAME = §eAutostartTimer -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}§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 - +AUTOSTART_COMMAND_HELP=§8/§etimer §8- §7Legt den AutostartTimer ins Inventar +AUTOSTART_ITEM_NAME=§eAutostartTimer +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}§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 BACKUP_HELP_CREATE=§8/§ebackup create §8- §7Erstelle ein Backup der Region BACKUP_HELP_LOAD=§8/§ebackup load §8[§7BackupName§8] §8- §7 Lade ein Backup @@ -134,44 +115,38 @@ BACKUP_LOAD=§7Backup geladen BACKUP_INV_NAME=§eBackup BACKUP_ITEM_NAME=§eBackup §7von §e{0} BACKUP_LORE=§eKlicken zum Laden - # Bau -BAU_COMMAND_HELP_INFO = §8/§ebau info §8- §7Alias für §8/§ebauinfo - -BAU_INFO_ITEM_NAME = §eBau-Management +BAU_COMMAND_HELP_INFO=§8/§ebau info §8- §7Alias für §8/§ebauinfo +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 = §7Damage§8: §e{0} -BAU_INFO_ITEM_LORE_FIRE = §7Feuer§8: §e{0} -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§8: §e{0} -BAU_INFO_COMMAND_MEMBER = §7{0} §8[§7{1}§8]§8: §e{2} -BAU_INFO_COMMAND_FLAG = §7{0}§8: §7{1} -BAU_INFO_COMMAND_TPS = §7TPS§8:§e - +BAU_INFO_ITEM_LORE_TNT=§7TNT§8: §e{0} +BAU_INFO_ITEM_LORE_FREEZE=§7Freeze§8: §e{0} +BAU_INFO_ITEM_LORE_DAMAGE=§7Damage§8: §e{0} +BAU_INFO_ITEM_LORE_FIRE=§7Feuer§8: §e{0} +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§8: §e{0} +BAU_INFO_COMMAND_MEMBER=§7{0} §8[§7{1}§8]§8: §e{2} +BAU_INFO_COMMAND_FLAG=§7{0}§8: §7{1} +BAU_INFO_COMMAND_TPS=§7TPS§8:§e # Countingwand -COUNTINGWAND_COMMAND_HELP = §8/§ecountingwand §8- §7Gibt dir ein CountingWand -COUNTINGWAND_ITEM_NAME = §eZollstock -COUNTINGWAND_ITEM_LORE1 = §eLinksklick §8- §7Setzt die 1. Position -COUNTINGWAND_ITEM_LORE2 = §eRechtsklick §8- §7Setzt die 2. Position -COUNTINGWAND_MESSAGE_RCLICK = §7Erste Position bei: §8[§7{0}§8, §7{1}§8, §7{2}§8] ({3}§8) ({4}§8) -COUNTINGWAND_MESSAGE_LCLICK = §7Zweite Position bei: §8[§7{0}§8, §7{1}§8, §7{2}§8] ({3}§8) ({4}§8) -COUNTINGWAND_MESSAGE_VOLUME = §e{0} -COUNTINGWAND_MESSAGE_DIMENSION = §e{0}§8, §e{1}§8, §e{2} - +COUNTINGWAND_COMMAND_HELP=§8/§ecountingwand §8- §7Gibt dir ein CountingWand +COUNTINGWAND_ITEM_NAME=§eZollstock +COUNTINGWAND_ITEM_LORE1=§eLinksklick §8- §7Setzt die 1. Position +COUNTINGWAND_ITEM_LORE2=§eRechtsklick §8- §7Setzt die 2. Position +COUNTINGWAND_MESSAGE_RCLICK=§7Erste Position bei: §8[§7{0}§8, §7{1}§8, §7{2}§8] ({3}§8) ({4}§8) +COUNTINGWAND_MESSAGE_LCLICK=§7Zweite Position bei: §8[§7{0}§8, §7{1}§8, §7{2}§8] ({3}§8) ({4}§8) +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 End Stone im Design -DESIGN_ENDSTONE_REGION_ERROR = §cDiese Region hat keinen Baubereich -DESIGN_ENDSTONE_ENABLE = §aEndstone im Design ist angezeigt -DESIGN_ENDSTONE_DISABLE = §cEndstone im Design ist versteckt - +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 im Design ist angezeigt +DESIGN_ENDSTONE_DISABLE=§cEndstone im Design ist versteckt # Detonator -DETONATOR_LOC_REMOVE = §e{0} entfernt -DETONATOR_LOC_ADD = §e{0} hinzugefügt +DETONATOR_LOC_REMOVE=§e{0} entfernt +DETONATOR_LOC_ADD=§e{0} hinzugefügt DETONATOR_BUTTON_SWITCH=Hebel DETONATOR_BUTTON_WOOD_BUTTON=Knopf DETONATOR_BUTTON_STONE_BUTTON=Knopf @@ -218,290 +193,252 @@ GUI_EDITOR_ITEM_TRASH_LORE=§7Item hier rein Legen GUI_EDITOR_ITEM_MORE=§eMehr Items GUI_EDITOR_ITEM_CLOSE=§eSchließen GUI_EDITOR_TITLE_MORE=Item auswählen - # Script ## CustomScript -SCRIPT_HOTKEY_ITEM_NAME = §7Hotkey§8: §e{0} -SCRIPT_EVENT_ITEM_NAME = §7Event§8: §e{0} -SCRIPT_COMMAND_ITEM_NAME = §7Befehl§8: §e/{0} +SCRIPT_HOTKEY_ITEM_NAME=§7Hotkey§8: §e{0} +SCRIPT_EVENT_ITEM_NAME=§7Event§8: §e{0} +SCRIPT_COMMAND_ITEM_NAME=§7Befehl§8: §e/{0} SCRIPT_ERROR_ONLY_IN_GLOBAL=§cDieses Skript kann nur als globales Skript ausgeführt werden - ## Script Menu GUI -SCRIPT_MENU_GUI_ITEM_LORE_1 = §7Klicke zum rausnehmen -SCRIPT_MENU_GUI_ITEM_LORE_2 = §7Shiftklick zum kopieren -SCRIPT_MENU_GUI_ITEM_LORE_3 = §7Rechtsklick zum editieren -SCRIPT_MENU_GUI_ITEM_LORE_4 = §7Mittelklick zum anschauen -SCRIPT_MENU_GUI_NAME = §eSkript-Menü -SCRIPT_MENU_GUI_ITEM_ADD_NAME = §eHinzufügen -SCRIPT_MENU_GUI_ITEM_ADD_LORE = §7Klicke mit einem Buch zum hinzufügen +SCRIPT_MENU_GUI_ITEM_LORE_1=§7Klicke zum rausnehmen +SCRIPT_MENU_GUI_ITEM_LORE_2=§7Shiftklick zum kopieren +SCRIPT_MENU_GUI_ITEM_LORE_3=§7Rechtsklick zum editieren +SCRIPT_MENU_GUI_ITEM_LORE_4=§7Mittelklick zum anschauen +SCRIPT_MENU_GUI_NAME=§eSkript-Menü +SCRIPT_MENU_GUI_ITEM_ADD_NAME=§eHinzufügen +SCRIPT_MENU_GUI_ITEM_ADD_LORE=§7Klicke mit einem Buch zum hinzufügen SCRIPT_DEPRECATED=§cDie Funktion §e{0}§c ist veraltet und wird demnächst entfernt. Bitte benutze §e{1}§c. - # Shield Printing -SHIELD_PRINTING_HELP_START = §8/§eshieldprinting start §8- §7Starte das Schild drucken -SHIELD_PRINTING_HELP_COPY = §8/§eshieldprinting copy §8- §7Kopiert die Schilder -SHIELD_PRINTING_HELP_APPLY = §8/§eshieldprinting apply §8- §7Wendet die Schilder an -SHIELD_PRINTING_HELP_STOP = §8/§eshieldprinting stop §8- §7Stoppt das Schild drucken -SHIELD_PRINTING_HELP_STEP_1 = §81. §7Füge die Schematic in die Welt ein -SHIELD_PRINTING_HELP_STEP_2 = §82. §7Starte das Schild drucken mit §8/§eshieldprinting start -SHIELD_PRINTING_HELP_STEP_3 = §83. §7Warte bis alle Schilde ausgefahren sind -SHIELD_PRINTING_HELP_STEP_4 = §84. §7Editiere die Schilde wenn nötig -SHIELD_PRINTING_HELP_STEP_5 = §85. §7Kopiere das gedruckte mit §8/§eshieldprinting copy -SHIELD_PRINTING_HELP_STEP_6 = §86. §7Füge die originale Schematic wieder ein -SHIELD_PRINTING_HELP_STEP_7 = §87. §7Wende das gedruckte mit §8/§eshieldprinting apply§7 an - -SHIELD_PRINTING_NO_REGION = §cDu bist in keiner Region. -SHIELD_PRINTING_NOT_RUNNING = §cShield printing ist nicht aktiv. -SHIELD_PRINTING_BOSSBAR = §fBewegungen: {0} -SHIELD_PRINTING_BOSSBAR_COPIED = §fBewegungen: {0} Kopiert: {1} - -SHIELD_PRINTING_GUI_NAME = §7Schild Drucken -SHIELD_PRINTING_GUI_APPLY = §aAnwenden -SHIELD_PRINTING_GUI_STATE_PREVIOUS = §7R-Click§8: §7Vorherige -SHIELD_PRINTING_GUI_STATE_NEXT = §7L-Click§8: §7Nächste -SHIELD_PRINTING_GUI_STATE_ACTIVE = §e> §7{0} -SHIELD_PRINTING_GUI_STATE_INACTIVE = §8> §7{0} -SHIELD_PRINTING_GUI_STATE_FROM_ORIGINAL = Original -SHIELD_PRINTING_GUI_STATE_FROM_COPY = Kopie -SHIELD_PRINTING_GUI_STATE_ALWAYS_ON = An -SHIELD_PRINTING_GUI_STATE_ALWAYS_OFF = Aus -SHIELD_PRINTING_GUI_STATE_ALWAYS_OPEN = Offen -SHIELD_PRINTING_GUI_STATE_ALWAYS_CLOSED = Geschlossen -SHIELD_PRINTING_GUI_STATE_FENCE = §7{0} §fZaun Verbindungen -SHIELD_PRINTING_GUI_STATE_OPENABLE = §7{0} §fGeöffnet -SHIELD_PRINTING_GUI_STATE_PISTON = §7{0} §fAusgefahren -SHIELD_PRINTING_GUI_STATE_POWERABLE = §7{0} §fAktiviert -SHIELD_PRINTING_GUI_STATE_WALL = §7{0} §fWand Verbindungen - -SHIELD_PRINTING_START = §aShield printing wurde gestartet. -SHIELD_PRINTING_COPY = §aSchilde wurden kopiert. -SHIELD_PRINTING_APPLY = §aSchilde wurden angewendet. -SHIELD_PRINTING_STOP = §aShield printing wurde gestoppt. - +SHIELD_PRINTING_HELP_START=§8/§eshieldprinting start §8- §7Starte das Schild drucken +SHIELD_PRINTING_HELP_COPY=§8/§eshieldprinting copy §8- §7Kopiert die Schilder +SHIELD_PRINTING_HELP_APPLY=§8/§eshieldprinting apply §8- §7Wendet die Schilder an +SHIELD_PRINTING_HELP_STOP=§8/§eshieldprinting stop §8- §7Stoppt das Schild drucken +SHIELD_PRINTING_HELP_STEP_1=§81. §7Füge die Schematic in die Welt ein +SHIELD_PRINTING_HELP_STEP_2=§82. §7Starte das Schild drucken mit §8/§eshieldprinting start +SHIELD_PRINTING_HELP_STEP_3=§83. §7Warte bis alle Schilde ausgefahren sind +SHIELD_PRINTING_HELP_STEP_4=§84. §7Editiere die Schilde wenn nötig +SHIELD_PRINTING_HELP_STEP_5=§85. §7Kopiere das gedruckte mit §8/§eshieldprinting copy +SHIELD_PRINTING_HELP_STEP_6=§86. §7Füge die originale Schematic wieder ein +SHIELD_PRINTING_HELP_STEP_7=§87. §7Wende das gedruckte mit §8/§eshieldprinting apply§7 an +SHIELD_PRINTING_NO_REGION=§cDu bist in keiner Region. +SHIELD_PRINTING_NOT_RUNNING=§cShield printing ist nicht aktiv. +SHIELD_PRINTING_BOSSBAR=§fBewegungen: {0} +SHIELD_PRINTING_BOSSBAR_COPIED=§fBewegungen: {0} Kopiert: {1} +SHIELD_PRINTING_GUI_NAME=§7Schild Drucken +SHIELD_PRINTING_GUI_APPLY=§aAnwenden +SHIELD_PRINTING_GUI_STATE_PREVIOUS=§7R-Click§8: §7Vorherige +SHIELD_PRINTING_GUI_STATE_NEXT=§7L-Click§8: §7Nächste +SHIELD_PRINTING_GUI_STATE_ACTIVE=§e> §7{0} +SHIELD_PRINTING_GUI_STATE_INACTIVE=§8> §7{0} +SHIELD_PRINTING_GUI_STATE_FROM_ORIGINAL=Original +SHIELD_PRINTING_GUI_STATE_FROM_COPY=Kopie +SHIELD_PRINTING_GUI_STATE_ALWAYS_ON=An +SHIELD_PRINTING_GUI_STATE_ALWAYS_OFF=Aus +SHIELD_PRINTING_GUI_STATE_ALWAYS_OPEN=Offen +SHIELD_PRINTING_GUI_STATE_ALWAYS_CLOSED=Geschlossen +SHIELD_PRINTING_GUI_STATE_FENCE=§7{0} §fZaun Verbindungen +SHIELD_PRINTING_GUI_STATE_OPENABLE=§7{0} §fGeöffnet +SHIELD_PRINTING_GUI_STATE_PISTON=§7{0} §fAusgefahren +SHIELD_PRINTING_GUI_STATE_POWERABLE=§7{0} §fAktiviert +SHIELD_PRINTING_GUI_STATE_WALL=§7{0} §fWand Verbindungen +SHIELD_PRINTING_START=§aShield printing wurde gestartet. +SHIELD_PRINTING_COPY=§aSchilde wurden kopiert. +SHIELD_PRINTING_APPLY=§aSchilde wurden angewendet. +SHIELD_PRINTING_STOP=§aShield printing wurde gestoppt. # Unsign Book UNSIGN_HELP=§8/§eunsign §8- §7Mache ein Buch beschreibbar - # Simulator -SIMULATOR_HELP = §8/§esimulator §8-§7 Legt dir den Simulatorstab ins Inventar -SIMULATOR_CREATE_HELP = §8/§esimulator create §8[§7name§8] §8-§7 Erstelle einen neuen Simulator -SIMULATOR_CHANGE_HELP = §8/§esimulator change §8-§7 Wechsel zu einem anderen Simulator -SIMULATOR_DELETE_HELP = §8/§esimulator delete §8[§7name§8] §8-§7 Löscht den Simulator -SIMULATOR_START_HELP = §8/§esimulator start §8[§7name§8] §8-§7 Startet die Simulation -SIMULATOR_COPY_HELP = §8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Kopiert einen Simulator - -SIMULATOR_GUI_ITEM_NAME = §eTNT Simulator - -SIMULATOR_NO_SIM_IN_HAND = §cKein Simulator Item gewählt -SIMULATOR_GUI_SELECT_SIM = Simulator wählen -SIMULATOR_GUI_CREATE_SIM = §eSimulator erstellen -SIMULATOR_GUI_CREATE_SIM_GUI = Simulator erstellen -SIMULATOR_NAME_ALREADY_EXISTS = §cSimulator existiert bereits -SIMULATOR_NAME_INVALID = §cUngültiger Name -SIMULATOR_ERROR_COPY = §cFehler beim kopieren -SIMULATOR_NOT_EXISTS = §cSimulator existiert nicht -SIMULATOR_CREATE = §aSimulator erstellt -SIMULATOR_EDIT_LOCATION = §7Editiere Positionen -SIMULATOR_EDIT_PROPERTIES = §7Editiere Eigenschaften -SIMULATOR_EDIT_OTHER = §7Editiere Andere -SIMULATOR_EDIT_GROUP = §7Editiere Gruppe - -SIMULATOR_EDIT_GROUP_MENU = §eEditiere Gruppe - -SIMULATOR_WAND_NAME = §eKanonensimulator -SIMULATOR_WAND_NAME_SELECTED = §7Kanonensimulator §8- §e{0} -SIMULATOR_WAND_LORE_1 = §eRechtsklick §8- §7Füge eine Position hinzu -SIMULATOR_WAND_LORE_2 = §eSneaken §8- §7Freie Bewegung -SIMULATOR_WAND_LORE_3 = §eLinksklick §8- §7Starte die Simulation -SIMULATOR_WAND_LORE_4 = §eRechtsklick Luft §8- §7Öffne die GUI -SIMULATOR_WAND_LORE_5 = §eDoppel Shift §8- §7Wechsel zwischen TNT und Redstone Block - -SIMULATOR_REGION_FROZEN = §cSimulator kann nicht in eingefrorenen Regionen genutzt werden - +SIMULATOR_HELP=§8/§esimulator §8-§7 Legt dir den Simulatorstab ins Inventar +SIMULATOR_CREATE_HELP=§8/§esimulator create §8[§7name§8] §8-§7 Erstelle einen neuen Simulator +SIMULATOR_CHANGE_HELP=§8/§esimulator change §8-§7 Wechsel zu einem anderen Simulator +SIMULATOR_DELETE_HELP=§8/§esimulator delete §8[§7name§8] §8-§7 Löscht den Simulator +SIMULATOR_START_HELP=§8/§esimulator start §8[§7name§8] §8-§7 Startet die Simulation +SIMULATOR_COPY_HELP=§8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Kopiert einen Simulator +SIMULATOR_GUI_ITEM_NAME=§eTNT Simulator +SIMULATOR_NO_SIM_IN_HAND=§cKein Simulator Item gewählt +SIMULATOR_GUI_SELECT_SIM=Simulator wählen +SIMULATOR_GUI_CREATE_SIM=§eSimulator erstellen +SIMULATOR_GUI_CREATE_SIM_GUI=Simulator erstellen +SIMULATOR_NAME_ALREADY_EXISTS=§cSimulator existiert bereits +SIMULATOR_NAME_INVALID=§cUngültiger Name +SIMULATOR_ERROR_COPY=§cFehler beim kopieren +SIMULATOR_NOT_EXISTS=§cSimulator existiert nicht +SIMULATOR_CREATE=§aSimulator erstellt +SIMULATOR_EDIT_LOCATION=§7Editiere Positionen +SIMULATOR_EDIT_PROPERTIES=§7Editiere Eigenschaften +SIMULATOR_EDIT_OTHER=§7Editiere Andere +SIMULATOR_EDIT_GROUP=§7Editiere Gruppe +SIMULATOR_EDIT_GROUP_MENU=§eEditiere Gruppe +SIMULATOR_WAND_NAME=§eKanonensimulator +SIMULATOR_WAND_NAME_SELECTED=§7Kanonensimulator §8- §e{0} +SIMULATOR_WAND_LORE_1=§eRechtsklick §8- §7Füge eine Position hinzu +SIMULATOR_WAND_LORE_2=§eSneaken §8- §7Freie Bewegung +SIMULATOR_WAND_LORE_3=§eLinksklick §8- §7Starte die Simulation +SIMULATOR_WAND_LORE_4=§eRechtsklick Luft §8- §7Öffne die GUI +SIMULATOR_WAND_LORE_5=§eDoppel Shift §8- §7Wechsel zwischen TNT und Redstone Block +SIMULATOR_REGION_FROZEN=§cSimulator kann nicht in eingefrorenen Regionen genutzt werden ## Other -SIMULATOR_PLUS_ONE = §7+1 -SIMULATOR_PLUS_PIXEL_SHIFT = §eShift §7Click für §e+0,0625 -SIMULATOR_PLUS_FIVE_SHIFT = §eShift §7Click für §e+5 -SIMULATOR_MINUS_ONE = §7-1 -SIMULATOR_MINUS_PIXEL_SHIFT = §eShift §7Click für §e-0,0625 -SIMULATOR_MINUS_FIVE_SHIFT = §eShift §7Click für §e-5 -SIMULATOR_POSITION_X = §7x-Position -SIMULATOR_POSITION_Y = §7y-Position -SIMULATOR_POSITION_Z = §7z-Position -SIMULATOR_BACK = §eZurück - -SIMULATOR_GUI_TOTAL_TNT = §7Gesamt TNT§8: §e{0} - -SIMULATOR_DELETED = §cSimulator gelöscht - +SIMULATOR_PLUS_ONE=§7+1 +SIMULATOR_PLUS_PIXEL_SHIFT=§eShift §7Click für §e+0,0625 +SIMULATOR_PLUS_FIVE_SHIFT=§eShift §7Click für §e+5 +SIMULATOR_MINUS_ONE=§7-1 +SIMULATOR_MINUS_PIXEL_SHIFT=§eShift §7Click für §e-0,0625 +SIMULATOR_MINUS_FIVE_SHIFT=§eShift §7Click für §e-5 +SIMULATOR_POSITION_X=§7x-Position +SIMULATOR_POSITION_Y=§7y-Position +SIMULATOR_POSITION_Z=§7z-Position +SIMULATOR_BACK=§eZurück +SIMULATOR_GUI_TOTAL_TNT=§7Gesamt TNT§8: §e{0} +SIMULATOR_DELETED=§cSimulator gelöscht ## GUI -SIMULATOR_POSITION_EDIT = §ePosition bearbeiten -SIMULATOR_POSITION_ADD = §ePosition setzen -SIMULATOR_GUI_TNT_SPAWN_NAME = §eTNT -SIMULATOR_GUI_TNT_SPAWN_LORE_1 = §7TNT-Anzahl§8: §e{0} -SIMULATOR_GUI_TNT_SPAWN_LORE_3 = §7Lebensdauer§8: §e{0} -SIMULATOR_GUI_TNT_GROUP_NAME = §eTNT Gruppe -SIMULATOR_GUI_TNT_GROUP_LORE_1 = §7Elementanzahl§8: §e{0} -SIMULATOR_GUI_TNT_DISABLED = §cDisabled -SIMULATOR_GUI_NAME = Kanonensimulator -SIMULATOR_GUI_DELETE = §cTNT löschen -SIMULATOR_GUI_AUTO_TRACE = §eAutoTrace§8: §7{0} -SIMULATOR_GUI_MOVE_ALL = §eAlle Verschieben - -SIMULATOR_ALIGNMENT_CENTER = §7Verschiebung§8: §eMitte -SIMULATOR_ALIGNMENT_POSITIVE_X = §7Verschiebung§8: §ePositive X -SIMULATOR_ALIGNMENT_NEGATIVE_X = §7Verschiebung§8: §eNegative X -SIMULATOR_ALIGNMENT_POSITIVE_Z = §7Verschiebung§8: §ePositive Z -SIMULATOR_ALIGNMENT_NEGATIVE_Z = §7Verschiebung§8: §eNegative Z - -SIMULATOR_MOVE_ALL_GUI_NAME = TNT Verschieben - -SIMULATOR_TNT_SPAWN_GUI_NAME = TNT konfigurieren {0} -SIMULATOR_TNT_SPAWN_LORE = §eZum Ändern klicken -SIMULATOR_TNT_SPAWN_COUNT = §7TNT-Anzahl §8- §e{0} -SIMULATOR_TNT_SPAWN_COUNT_ANVIL_GUI_NAME = Anzahl TNT -SIMULATOR_TNT_SPAWN_TICK = §7Tick §8- §e{0} -SIMULATOR_TNT_SPAWN_TICK_ANVIL_GUI_NAME = Tick Offset -SIMULATOR_TNT_SPAWN_FUSE = §7Lebensdauer §8- §e{0} -SIMULATOR_TNT_SPAWN_FUSE_ANVIL_GUI_NAME = Fuse-Ticks -SIMULATOR_TNT_SPAWN_VELOCITY_NAME = §7TNT -SIMULATOR_TNT_SPAWN_VELOCITY_X = §7TNT §eSprung X §8- {0} -SIMULATOR_TNT_SPAWN_VELOCITY_Y = §7TNT §eSprung Y §8- {0} -SIMULATOR_TNT_SPAWN_VELOCITY_Z = §7TNT §eSprung Z §8- {0} -SIMULATOR_TNT_SPAWN_VELOCITY_ON = §aan -SIMULATOR_TNT_SPAWN_VELOCITY_OFF = §caus -SIMULATOR_TNT_SPAWN_POSITION_X = §7x-Position §8- §e{0} -SIMULATOR_TNT_SPAWN_POSITION_Y = §7y-Position §8- §e{0} -SIMULATOR_TNT_SPAWN_POSITION_Z = §7z-Position §8- §e{0} -SIMULATOR_TNT_SPAWN_ACTIVATED_WITH = §7Gezündet durch §8- §e{0} -SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_COMPARATOR = Comparator -SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_REPEATER = Repeater -SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_OBSERVER = Observer -SIMULATOR_TNT_SPAWN_MATERIAL = §eMaterial -SIMULATOR_TNT_SPAWN_MATERIAL_LORE_1 = §7Jetziges Material§8: §e{0} -SIMULATOR_TNT_SPAWN_MATERIAL_LORE_2 = §eLink-Click §7Zum ändern -SIMULATOR_TNT_SPAWN_MATERIAL_LORE_3 = §eRechts-Click §7Zum zurücksetzten -SIMULATOR_MATERIAL_GUI_NAME = Material ändern -SIMULATOR_MATERIAL_CLICK = §eKlicken zum wählen -SIMULATOR_TNT_SPAWN_ADD_IGNITION_PHASE = §eZündphase hinzufügen -SIMULATOR_TNT_SPAWN_ADD_TNT = §eTNT hinzufügen -SIMULATOR_TNT_SPAWN_REMOVE_TNT = §cEntfernen -SIMULATOR_TNT_SPAWN_POSITION_ANVIL_GUI_NAME = Position - +SIMULATOR_POSITION_EDIT=§ePosition bearbeiten +SIMULATOR_POSITION_ADD=§ePosition setzen +SIMULATOR_GUI_TNT_SPAWN_NAME=§eTNT +SIMULATOR_GUI_TNT_SPAWN_LORE_1=§7TNT-Anzahl§8: §e{0} +SIMULATOR_GUI_TNT_SPAWN_LORE_3=§7Lebensdauer§8: §e{0} +SIMULATOR_GUI_TNT_GROUP_NAME=§eTNT Gruppe +SIMULATOR_GUI_TNT_GROUP_LORE_1=§7Elementanzahl§8: §e{0} +SIMULATOR_GUI_TNT_DISABLED=§cDisabled +SIMULATOR_GUI_NAME=Kanonensimulator +SIMULATOR_GUI_DELETE=§cTNT löschen +SIMULATOR_GUI_AUTO_TRACE=§eAutoTrace§8: §7{0} +SIMULATOR_GUI_MOVE_ALL=§eAlle Verschieben +SIMULATOR_ALIGNMENT_CENTER=§7Verschiebung§8: §eMitte +SIMULATOR_ALIGNMENT_POSITIVE_X=§7Verschiebung§8: §ePositive X +SIMULATOR_ALIGNMENT_NEGATIVE_X=§7Verschiebung§8: §eNegative X +SIMULATOR_ALIGNMENT_POSITIVE_Z=§7Verschiebung§8: §ePositive Z +SIMULATOR_ALIGNMENT_NEGATIVE_Z=§7Verschiebung§8: §eNegative Z +SIMULATOR_MOVE_ALL_GUI_NAME=TNT Verschieben +SIMULATOR_TNT_SPAWN_GUI_NAME=TNT konfigurieren {0} +SIMULATOR_TNT_SPAWN_LORE=§eZum Ändern klicken +SIMULATOR_TNT_SPAWN_COUNT=§7TNT-Anzahl §8- §e{0} +SIMULATOR_TNT_SPAWN_COUNT_ANVIL_GUI_NAME=Anzahl TNT +SIMULATOR_TNT_SPAWN_TICK=§7Tick §8- §e{0} +SIMULATOR_TNT_SPAWN_TICK_ANVIL_GUI_NAME=Tick Offset +SIMULATOR_TNT_SPAWN_FUSE=§7Lebensdauer §8- §e{0} +SIMULATOR_TNT_SPAWN_FUSE_ANVIL_GUI_NAME=Fuse-Ticks +SIMULATOR_TNT_SPAWN_VELOCITY_NAME=§7TNT +SIMULATOR_TNT_SPAWN_VELOCITY_X=§7TNT §eSprung X §8- {0} +SIMULATOR_TNT_SPAWN_VELOCITY_Y=§7TNT §eSprung Y §8- {0} +SIMULATOR_TNT_SPAWN_VELOCITY_Z=§7TNT §eSprung Z §8- {0} +SIMULATOR_TNT_SPAWN_VELOCITY_ON=§aan +SIMULATOR_TNT_SPAWN_VELOCITY_OFF=§caus +SIMULATOR_TNT_SPAWN_POSITION_X=§7x-Position §8- §e{0} +SIMULATOR_TNT_SPAWN_POSITION_Y=§7y-Position §8- §e{0} +SIMULATOR_TNT_SPAWN_POSITION_Z=§7z-Position §8- §e{0} +SIMULATOR_TNT_SPAWN_ACTIVATED_WITH=§7Gezündet durch §8- §e{0} +SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_COMPARATOR=Comparator +SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_REPEATER=Repeater +SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_OBSERVER=Observer +SIMULATOR_TNT_SPAWN_MATERIAL=§eMaterial +SIMULATOR_TNT_SPAWN_MATERIAL_LORE_1=§7Jetziges Material§8: §e{0} +SIMULATOR_TNT_SPAWN_MATERIAL_LORE_2=§eLink-Click §7Zum ändern +SIMULATOR_TNT_SPAWN_MATERIAL_LORE_3=§eRechts-Click §7Zum zurücksetzten +SIMULATOR_MATERIAL_GUI_NAME=Material ändern +SIMULATOR_MATERIAL_CLICK=§eKlicken zum wählen +SIMULATOR_TNT_SPAWN_ADD_IGNITION_PHASE=§eZündphase hinzufügen +SIMULATOR_TNT_SPAWN_ADD_TNT=§eTNT hinzufügen +SIMULATOR_TNT_SPAWN_REMOVE_TNT=§cEntfernen +SIMULATOR_TNT_SPAWN_POSITION_ANVIL_GUI_NAME=Position # SmartPlace -SMART_PLACE_HELP = §8/§esmartplace §8-§7 Toggled SmartPlace -SMART_PLACE_INFO = §7Plaziert rotierbare Blöcke beim §esneaken§7 von dir §eweg§7. -SMART_PLACE_ENABLE = §aSmartPlace aktiviert -SMART_PLACE_DISABLE = §cSmartPlace deaktiviert - +SMART_PLACE_HELP=§8/§esmartplace §8-§7 Toggled SmartPlace +SMART_PLACE_INFO=§7Plaziert rotierbare Blöcke beim §esneaken§7 von dir §eweg§7. +SMART_PLACE_ENABLE=§aSmartPlace aktiviert +SMART_PLACE_DISABLE=§cSmartPlace deaktiviert # InventoryFiller -INVENTORY_FILL_HELP = §8/§einventoryfill §8- §7Toggled InventoryFill -INVENTORY_FILL_INFO = §7Hilft dir, Behälter zu füllen, indem du sie beim sneaken ansiehst und den Gegenstand fallen lässt. Oder scrolle einfach auf einen Behälter, um die Menge des gehaltenen Gegenstandes darin zu ändern. -INVENTORY_FILL_ENABLE = §aInventoryFiller activated -INVENTORY_FILL_DISABLE = §cInventoryFiller deactivated - +INVENTORY_FILL_HELP=§8/§einventoryfill §8- §7Toggled InventoryFill +INVENTORY_FILL_INFO=§7Hilft dir, Behälter zu füllen, indem du sie beim sneaken ansiehst und den Gegenstand fallen lässt. Oder scrolle einfach auf einen Behälter, um die Menge des gehaltenen Gegenstandes darin zu ändern. +INVENTORY_FILL_ENABLE=§aInventoryFiller activated +INVENTORY_FILL_DISABLE=§cInventoryFiller deactivated # Killchecker -KILLCHECKER_HELP_ENABLE = §8/§ekillchecker enable §8- §7Aktiviert Killchecker / Berechnet kills neu -KILLCHECKER_HELP_DISABLE = §8/§ekillchecker disable §8- §7Deaktiviert Killchecker -KILLCHECKER_INFO = §7Zeigt Überlappungen der Kanonen Kills im Baubereich an. -KILLCHECKER_INFO2 = §7Nur farbige Blöcke wie Wolle, Terracotta, Stained Glass und Concrete wird gezählt. -KILLCHECKER_ENABLE = §aKillchecker aktiviert -KILLCHECKER_DISABLE = §cKillchecker deaktiviert -KILLCHECKER_BOSSBAR = §e§l{0} §7(§e{1}%§7) §e§l{2}§7 Kanonnen - +KILLCHECKER_HELP_ENABLE=§8/§ekillchecker enable §8- §7Aktiviert Killchecker / Berechnet kills neu +KILLCHECKER_HELP_DISABLE=§8/§ekillchecker disable §8- §7Deaktiviert Killchecker +KILLCHECKER_INFO=§7Zeigt Überlappungen der Kanonen Kills im Baubereich an. +KILLCHECKER_INFO2=§7Nur farbige Blöcke wie Wolle, Terracotta, Stained Glass und Concrete wird gezählt. +KILLCHECKER_ENABLE=§aKillchecker aktiviert +KILLCHECKER_DISABLE=§cKillchecker deaktiviert +KILLCHECKER_BOSSBAR=§e§l{0} §7(§e{1}%§7) §e§l{2}§7 Kanonnen # BlockCounter -BLOCK_COUNTER_HELP_TOGGLE = §8/§eblockcounter §8- §7Wechsel zwischen an und aus -BLOCK_COUNTER_HELP_ENABLE = §8/§eblockcounter enable §8- §7Schalte den BlockCounter an -BLOCK_COUNTER_HELP_DISABLE = §8/§eblockcounter disable §8- §7Schalte den BlockCounter aus -BLOCK_COUNTER_MESSAGE = §7Schaden §8> §e{0} §7Blöcke §e{1} §7TNT §e{2} §7Blöcke/TNT §e{3} §7Blöcke/tick -BLOCK_COUNTER_MESSAGE_SECOND = §7Schaden §8> §e{0} §7Blöcke §e{1} §7TNT §e{2} §7Blöcke/TNT §e{3} §7Blöcke/s -BLOCK_COUNTER_ENABLE = §7BlockCounter angemacht -BLOCK_COUNTER_DISABLE = §7BlockCounter ausgemacht - +BLOCK_COUNTER_HELP_TOGGLE=§8/§eblockcounter §8- §7Wechsel zwischen an und aus +BLOCK_COUNTER_HELP_ENABLE=§8/§eblockcounter enable §8- §7Schalte den BlockCounter an +BLOCK_COUNTER_HELP_DISABLE=§8/§eblockcounter disable §8- §7Schalte den BlockCounter aus +BLOCK_COUNTER_MESSAGE=§7Schaden §8> §e{0} §7Blöcke §e{1} §7TNT §e{2} §7Blöcke/TNT §e{3} §7Blöcke/tick +BLOCK_COUNTER_MESSAGE_SECOND=§7Schaden §8> §e{0} §7Blöcke §e{1} §7TNT §e{2} §7Blöcke/TNT §e{3} §7Blöcke/s +BLOCK_COUNTER_ENABLE=§7BlockCounter angemacht +BLOCK_COUNTER_DISABLE=§7BlockCounter ausgemacht # DepthCounter -DEPTH_COUNTER_MESSAGE = §7Tiefe §8> §7 - +DEPTH_COUNTER_MESSAGE=§7Tiefe §8> §7 # TPSLimit -TPSLIMIT_FREEZE_HELP = §8/§etpslimit 0 §8-§7 Friere TPS ein -TPSLIMIT_LIMIT_HELP = §8/§etpslimit §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS -TPSLIMIT_WARP_HELP = §8/§etpslimit §8[§7x>20§8] §8-§7 Beschleunige die TPS -TPSLIMIT_DEFAULT_HELP = §8/§etpslimit default §8-§7 Setze die TPS auf 20 -TPSLIMIT_HELP = §8/§etpslimit §8-§7 Zeige die jetzige TPS - -TICK_FREEZE_HELP = §8/§etick rate 0 §8-§7 Friere TPS ein -TICK_FREEZE_HELP_2 = §8/§etick freeze §8-§7 Friere TPS ein -TICK_UNFREEZE_HELP = §8/§etick unfreeze §8-§7 Setze die TPS auf 20 -TICK_LIMIT_HELP = §8/§etick rate §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS -TICK_WARP_HELP = §8/§etick rate §8[§7x>20§8] §8-§7 Beschleunige die TPS -TICK_DEFAULT_HELP = §8/§etick rate default §8-§7 Setze die TPS auf 20 -TICK_HELP = §8/§etick rate §8-§7 Zeige die jetzige TPS - -TICK_STEPPING_HELP = §8/§etick step §8<§7Ticks§8> §8-§7 Spule n ticks oder 1 vor -TICK_WARPING_HELP = §8/§etick warp §8<§7Ticks§8> §8<§7TPS§8> §8-§7 Warpe n ticks oder 1 vor - -TICK_BOSSBAR = §e{0}§8/§7{1} gesprungen -TPSLIMIT_GUI_ITEM_NAME = §eTPS Limiter -TPSLIMIT_GUI_ITEM_LORE = §7Aktuell: §e{0} -TPSLIMIT_ANVIL_GUI = Neues TPS Limit -TPSLIMIT_CURRENT = §7Jetziges TPS limit§8: §e{0} -TPSLIMIT_SET = §eTPS limit auf {0} gesetzt. -TPSLIMIT_FROZEN = §eTPS eingefroren. - +TPSLIMIT_FREEZE_HELP=§8/§etpslimit 0 §8-§7 Friere TPS ein +TPSLIMIT_LIMIT_HELP=§8/§etpslimit §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS +TPSLIMIT_WARP_HELP=§8/§etpslimit §8[§7x>20§8] §8-§7 Beschleunige die TPS +TPSLIMIT_DEFAULT_HELP=§8/§etpslimit default §8-§7 Setze die TPS auf 20 +TPSLIMIT_HELP=§8/§etpslimit §8-§7 Zeige die jetzige TPS +TICK_FREEZE_HELP=§8/§etick rate 0 §8-§7 Friere TPS ein +TICK_FREEZE_HELP_2=§8/§etick freeze §8-§7 Friere TPS ein +TICK_UNFREEZE_HELP=§8/§etick unfreeze §8-§7 Setze die TPS auf 20 +TICK_LIMIT_HELP=§8/§etick rate §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS +TICK_WARP_HELP=§8/§etick rate §8[§7x>20§8] §8-§7 Beschleunige die TPS +TICK_DEFAULT_HELP=§8/§etick rate default §8-§7 Setze die TPS auf 20 +TICK_HELP=§8/§etick rate §8-§7 Zeige die jetzige TPS +TICK_STEPPING_HELP=§8/§etick step §8<§7Ticks§8> §8-§7 Spule n ticks oder 1 vor +TICK_WARPING_HELP=§8/§etick warp §8<§7Ticks§8> §8<§7TPS§8> §8-§7 Warpe n ticks oder 1 vor +TICK_BOSSBAR=§e{0}§8/§7{1} gesprungen +TPSLIMIT_GUI_ITEM_NAME=§eTPS Limiter +TPSLIMIT_GUI_ITEM_LORE=§7Aktuell: §e{0} +TPSLIMIT_ANVIL_GUI=Neues TPS Limit +TPSLIMIT_CURRENT=§7Jetziges TPS limit§8: §e{0} +TPSLIMIT_SET=§eTPS limit auf {0} gesetzt. +TPSLIMIT_FROZEN=§eTPS eingefroren. # Trace TRACE_RECORD=§aan TRACE_HAS_TRACES=§ehat Traces -TRACE_IDLE_SINGLE=§esingle -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_CLICK_ISOLATE = §eKlicken zum §aisolieren§8/§causblenden -TRACE_MESSAGE_SHOW_AT = §aTNT-positions angezeigt mit {0} bei {1} -TRACE_MESSAGE_SHOW_FROM = §aAll TNT-positions angezeigt mit {0} von {1} -TRACE_MESSAGE_SHOW_FROM_TO = §aAll TNT-positions angezeigt mit {0} von {1} bis {2} -TRACE_MESSAGE_SHOW_TO_SMALLER = §cBis muss größer als von sein - -TRACE_COMMAND_HELP_START = §8/§etrace start §8- §7Startet die Aufnahme aller TNT-Positionen -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_SHOW_AT = §8/§etrace show §8(§etime§8|§7fuse§8) §7at §8<§eTIME§8> - §7Zeigt alle TNT-Positionen bei §8<§eTIME§8> an -TRACE_COMMAND_HELP_SHOW_FROM = §8/§etrace show §8(§etime§8|§7fuse§8) §7from §8<§eFROM§8> - §7Zeigt alle TNT-Positionen von §8<§eFROM§8> -TRACE_COMMAND_HELP_SHOW_FROM_TO = §8/§etrace show §8(§etime§8|§7fuse§8) §7from §8<§eFROM§8> §7to §8<§eTO§8> - §7Zeigt alle TNT-Positionen zwischen §8<§eFROM§8> und §8<§eTO§8> -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_GUI_ITEM_NAME = §eTracer -TRACE_GUI_ITEM_LORE = §7Status§8: {0} -TRACE_GUI_NAME = Tracer Gui -TRACE_GUI_TRACE_INACTIVE = §eTracer Starten -TRACE_GUI_TRACE_ACTIVE = §eTracer Stoppen -TRACE_GUI_TRACE_ACTIVE_AUTO = §eAuto-Trace ist Aktiv -TRACE_GUI_AUTO_TRACE_INACTIVE = §eAuto-Tracer Aktivieren -TRACE_GUI_AUTO_TRACE_ACTIVE = §eAuto-Tracer Deaktivieren -TRACE_GUI_DELETE = §eTrace Löschen - +TRACE_MESSAGE_START=§aTNT-Tracer gestartet +TRACE_MESSAGE_AUTO_START=§eAuto TNT-Tracer gestartet +TRACE_MESSAGE_AUTO_STOP=§cAuto TNT-Tracer gestoppt +TRACE_MESSAGE_STOP=§cTNT-Tracer gestoppt +TRACE_MESSAGE_CLEAR=§cAlle TNT-Positionen gelöscht +TRACE_MESSAGE_CLICK_ISOLATE=§eKlicken zum §aisolieren§8/§causblenden +TRACE_MESSAGE_SHOW_AT=§aTNT-positions angezeigt bei {0} +TRACE_MESSAGE_SHOW_FROM=§aAll TNT-positions angezeigt von {0} +TRACE_MESSAGE_SHOW_FROM_TO=§aAll TNT-positions angezeigt von {0} bis {1} +TRACE_MESSAGE_SHARE=§e{0} teilte seinen Trace-Show-Status. +TRACE_MESSAGE_SHARE_HOVER=§eZum Ansehen klicken. +TRACE_MESSAGE_FOLLOW=§aSie folgen nun {0} Trace show state +TRACE_MESSAGE_FOLLOW_SELF=§cSie können sich selbst nicht folgen! +TRACE_MESSAGE_UNFOLLOW=§cSie folgen nicht mehr dem Status einer Trace-Show +TRACE_MESSAGE_SHOW_TO_SMALLER=§cBis muss größer als von sein +TRACE_MESSAGE_ISOLATE=§eTNT Positionen wurden isoliert +TRACE_COMMAND_HELP_SHARE=§8/§etrace share §8- §7Teilt den aktuellen Trace-Show-Status mit anderen +TRACE_COMMAND_HELP_FOLLOW=§8/§etrace follow §8[§ePlayer§8] §8- §7Verfolgen eines Spielers Status anzeigen +TRACE_COMMAND_HELP_UNFOLLOW=§8/§etrace unfollow §8- §7Den Status der Trace-Anzeige aufheben +TRACE_COMMAND_HELP_START=§8/§etrace start §8- §7Startet die 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_SHOW=§8/§etrace show §8<§eParameter§8> - §7Zeigt alle TNT-Positionen +TRACE_COMMAND_HELP_SHOW_AT=§8/§etrace show §8(§etime§8|§7fuse§8) §7at §8<§eTIME§8> - §7Zeigt alle TNT-Positionen bei §8<§eTIME§8> an +TRACE_COMMAND_HELP_SHOW_FROM=§8/§etrace show §8(§etime§8|§7fuse§8) §7from §8<§eFROM§8> - §7Zeigt alle TNT-Positionen von §8<§eFROM§8> +TRACE_COMMAND_HELP_SHOW_FROM_TO=§8/§etrace show §8(§etime§8|§7fuse§8) §7from §8<§eFROM§8> §7to §8<§eTO§8> - §7Zeigt alle TNT-Positionen zwischen §8<§eFROM§8> und §8<§eTO§8> +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_ISOLATE=§8/§etrace isolate §8[§eTrace§8] §8[§eTNT§8] §8- §7Isoliert spezifische TNTs des Traces +TRACE_GUI_ITEM_NAME=§eTracer +TRACE_GUI_ITEM_LORE=§7Status§8: {0} +TRACE_GUI_NAME=Tracer Gui +TRACE_GUI_TRACE_INACTIVE=§eTracer Starten +TRACE_GUI_TRACE_ACTIVE=§eTracer Stoppen +TRACE_GUI_TRACE_ACTIVE_AUTO=§eAuto-Trace ist Aktiv +TRACE_GUI_AUTO_TRACE_INACTIVE=§eAuto-Tracer Aktivieren +TRACE_GUI_AUTO_TRACE_ACTIVE=§eAuto-Tracer Deaktivieren +TRACE_GUI_DELETE=§eTrace Löschen # Loader -LOADER_SETUP = §eEinrichtung -LOADER_RUNNING = §aLaufend -LOADER_PAUSE = §7Pausiert -LOADER_END = §8Beendet - -LOADER_MESSAGE_INTERACT = §e{0} hinzugefügt {1} -LOADER_BUTTON_TNT = TNT +LOADER_SETUP=§eEinrichtung +LOADER_RUNNING=§aLaufend +LOADER_PAUSE=§7Pausiert +LOADER_END=§8Beendet +LOADER_SINGLE=§aEinmal +LOADER_MESSAGE_INTERACT=§e{0} hinzugefügt {1} +LOADER_BUTTON_TNT=TNT LOADER_BUTTON_SWITCH=Hebel LOADER_BUTTON_WOOD_BUTTON=Holzknopf LOADER_BUTTON_STONE_BUTTON=Steinknopf @@ -516,10 +453,10 @@ LOADER_BUTTON_LECTERN=Lectern LOADER_BUTTON_TRAPDOOR=Trapdoor LOADER_BUTTON_DOOR=Door LOADER_BUTTON_FENCEGATE=Fencegate - LOADER_HELP_SETUP=§8/§eloader setup §8- §7Startet die Aufnahme der Aktionen LOADER_SETUP_STOP_FIRST=§cBitte stoppe zuerst den Loader LOADER_HELP_START=§8/§eloader start §8- §7Spielt die zuvor aufgenommenen Aktionen ab +LOADER_HELP_SINGLE=§8/§eloader single §8- §7Spielt die zuvor aufgenommenen Aktionen einmal ab 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 @@ -530,11 +467,11 @@ LOADER_NEW=§7Belade und feuer einmal die Kanone ab, um den Loader zu initialisi 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_SINGLE_CMD=§7Der Loader spielt nun einmal ab. 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_NOTHING_RECORDED=§cEs wurden keine Elemente aufgenommen! LOADER_GUI_TITLE=Loader Einstellungen LOADER_GUI_SHOW_ALL=Zeige alles @@ -551,7 +488,6 @@ 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=§7Klicke zum editieren LOADER_GUI_ITEM_NAME=§7{0}§8: §e{1} LOADER_SETTING_NAME=§7{0} @@ -586,7 +522,6 @@ 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 LOADTIMER_HELP_START_1=§8/§eloadtimer start §8-§7 Startet den einfachen Loadtimer @@ -608,27 +543,25 @@ LOADTIMER_SUMARY_PLAYERTABLE_HEAD=§7Spieler: §eTNT §7(§eTNT/s§7) LOADTIMER_SUMARY_PLAYERTABLE_PLAYER=§7{0}: §e{1} §7(§e{2}/s§7) LOADTIMER_SUMARY_PLAYERTABLE_ALL=Insgesamt LOADTIMER_SUMARY_TIMES_HEAD=§7Zeiten: §eSekunden §7(§eTicks§7) -LOADTIMER_SUMARY_TIMES_START = §7 || §7Start! -LOADTIMER_SUMARY_TIMES_ACTIVATION = §7 || Aktivierung: §e{0}s §7(§e{1}t§7) -LOADTIMER_SUMARY_TIMES_IGNITION = §7 || Zündung: §e{0}s §7(§e{1}t§7) -LOADTIMER_SUMARY_TIMES_EXPLOSION = §7 || Explosion: §e{0}s §7(§e{1}t§7) +LOADTIMER_SUMARY_TIMES_START=§7 || §7Start! +LOADTIMER_SUMARY_TIMES_ACTIVATION=§7 || Aktivierung: §e{0}s §7(§e{1}t§7) +LOADTIMER_SUMARY_TIMES_IGNITION=§7 || Zündung: §e{0}s §7(§e{1}t§7) +LOADTIMER_SUMARY_TIMES_EXPLOSION=§7 || Explosion: §e{0}s §7(§e{1}t§7) LOADTIMER_SUMARY_TIMES_LAST=§7\\/ LOADTIMER_SUMARY_STATS_HEAD=§7Kanonen-Stats§8: LOADTIMER_SUMARY_STATS_TNT=§7TNT: §e{0} LOADTIMER_SUMARY_STATS_FREQ=§7Belade Frequenz: §e{0}/m§8, §7Schuss Frequenz: §e{1}/m - # Observer -OBSERVER_HELP = §7Rechts-Klicke einen Observer um den Trace zu bekommen. Hierfür müssen Flammenpartikel an sein. Die Partikel werden im Block angezeigt. -OBSERVER_HELP_ENABLE = §8/§eobserver enable §8-§7 Aktiviere den Observer Tracer -OBSERVER_HELP_DISABLE = §8/§eobserver disable §8-§7 Deaktiviere den Observer Tracer -OBSERVER_HELP_DELETE = §8/§eobserver delete §8-§7 Lösche den Observer Tracer -OBSERVER_HELP_RETRACE = §8/§eobserver retrace §8-§7 Retrace den Observer Tracer -OBSERVER_ENABLE = §7Observer Trace gestartet -OBSERVER_DISABLE = §7Observer Trace gestoppt -OBSERVER_DELETE = §7Observer Trace gelöscht -OBSERVER_RETRACE_DONE = §7Observer Trace neu berechnet -OBSERVER_RETRACE_NO_TRACE = §7Kein Observer Trace zum neu berechnen - +OBSERVER_HELP=§7Rechts-Klicke einen Observer um den Trace zu bekommen. Hierfür müssen Flammenpartikel an sein. Die Partikel werden im Block angezeigt. +OBSERVER_HELP_ENABLE=§8/§eobserver enable §8-§7 Aktiviere den Observer Tracer +OBSERVER_HELP_DISABLE=§8/§eobserver disable §8-§7 Deaktiviere den Observer Tracer +OBSERVER_HELP_DELETE=§8/§eobserver delete §8-§7 Lösche den Observer Tracer +OBSERVER_HELP_RETRACE=§8/§eobserver retrace §8-§7 Retrace den Observer Tracer +OBSERVER_ENABLE=§7Observer Trace gestartet +OBSERVER_DISABLE=§7Observer Trace gestoppt +OBSERVER_DELETE=§7Observer Trace gelöscht +OBSERVER_RETRACE_DONE=§7Observer Trace neu berechnet +OBSERVER_RETRACE_NO_TRACE=§7Kein Observer Trace zum neu berechnen # Other OTHER_ITEMS_TELEPORT_NAME=§eTeleporter OTHER_ITEMS_TELEPORT_GUI_NAME=Teleportieren @@ -645,8 +578,8 @@ OTHER_ITEMS_INVENTORY_FILL_LORE_ACTIVE=§aAktiviert OTHER_ITEMS_INVENTORY_FILL_LORE_INACTIVE=§aDeaktiviert OTHER_SLOT_INVALID_SLOT=§cInvalider Slot OTHER_NOCLIP_SLOT_INFO=§7Mit /slot kannst du den ausgewählten Slot ändern und einen anderen Block in den Slot nehmen. -OTHER_NOCLIP_SLOT_HELP_PICK = §8/§eslot pick §8-§7 Lege den angeguckten Block ins Inventar -OTHER_NOCLIP_SLOT_HELP_DROP = §8/§eslot drop §8-§7 Cleared deinen Slot +OTHER_NOCLIP_SLOT_HELP_PICK=§8/§eslot pick §8-§7 Lege den angeguckten Block ins Inventar +OTHER_NOCLIP_SLOT_HELP_DROP=§8/§eslot drop §8-§7 Cleared deinen Slot OTHER_CLEAR_HELP_SELF=§8/§eclear §8- §7Leere dein Inventar OTHER_CLEAR_HELP_PLAYER=§8/§eclear §8[§7Player§8] §8- §7Leere ein Spieler Inventar OTHER_CLEAR_CLEARED=Dein Inventar wurde geleert. @@ -660,7 +593,7 @@ OTHER_KILLALL_HELP_SELF=§8/§ekillall §8- §7Entferne alle Entities aus deiner OTHER_KILLALL_HELP_ALL=§8/§ekillall §8[§7Global§8/Local§7] §8- §7Entferne alle Entities aus deiner Region oder global OTHER_KILLALL_REGION=§a{0} Entities aus der Region entfernt OTHER_KILLALL_GLOBAL=§a{0} Entities aus der Welt entfernt -OTHER_TELEPORT_HELP = §8/§etp §8[§7Player§8] §8-§7 Teleportiere dich zu einem Spieler +OTHER_TELEPORT_HELP=§8/§etp §8[§7Player§8] §8-§7 Teleportiere dich zu einem Spieler OTHER_TELEPORT_SELF_0=§cSei eins mit dir selbst! OTHER_TELEPORT_SELF_1=§cDu brauchst Leute zum spielen? Wir haben auch einen TeamSpeak! OTHER_TELEPORT_SELF_2=§cNoch zu reisende Blöcke: 0; ETA: 0:00 @@ -669,9 +602,9 @@ OTHER_TELEPORT_SELF_4=§cFür eine solche Distanz? OTHER_TIME_HELP=§8/§etime §8<§7Zeit 0=Morgen§8, §76000=Mittag§8, §718000=Mitternacht§8> - §7Setzt die Zeit auf dem Bau OTHER_TIME_INVALID=§cBitte gib eine Zahl zwischen 0 und 24000 an 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_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 @@ -681,7 +614,7 @@ OTHER_BIND_MESSAGE_UNBIND=§7Befehl entbunden DEBUG_STICK_COMMAND_HELP=§8/§edebugstick §8-§7 Erhalte einen DebugStick DEBUG_STICK_NAME=§eDebugstick #Skull Gui -SKULL_GUI_ITEM_NAME = §eSpieler Köpfe +SKULL_GUI_ITEM_NAME=§eSpieler Köpfe ANVIL_INV_NAME=Spieler name # StructureVoid STRUCTURE_VOID_COMMAND_HELP=§8/§estructureVoid §8-§7 Erhalte ein StructureVoid @@ -691,17 +624,16 @@ DRAGON_EGG_COMMAND_HELP=§8/§edragonegg §8-§7 Erhalte ein Drachenei NIGHT_VISION_HELP=§8/§enightvision §8-§7 Schalte Nightvision an oder aus. NIGHT_VISION_OFF=§eNightvision deaktiviert NIGHT_VISION_ON=§eNightvision aktiviert -NIGHT_VISION_ITEM_ON = §7Nightvision: §eAktiviert -NIGHT_VISION_ITEM_OFF = §7Nightvision: §eDeaktiviert - +NIGHT_VISION_ITEM_ON=§7Nightvision: §eAktiviert +NIGHT_VISION_ITEM_OFF=§7Nightvision: §eDeaktiviert #Navigation Wand NAVIGATION_WAND=§eNavigation Wand NAVIGATION_WAND_LEFT_CLICK=§eLeft click: jump to location NAVIGATION_WAND_RIGHT_CLICK=§eRight click: pass through walls # Material -MATERIAL_SEARCH_PROPERTY_TRUE = §aHat -MATERIAL_SEARCH_PROPERTY_FALSE = §cHat nicht -MATERIAL_SEARCH_PROPERTY_IGNORE = §eEgal +MATERIAL_SEARCH_PROPERTY_TRUE=§aHat +MATERIAL_SEARCH_PROPERTY_FALSE=§cHat nicht +MATERIAL_SEARCH_PROPERTY_IGNORE=§eEgal MATERIAL_INV_NAME=§eMaterial {0}/{1} MATERIAL_SEARCH=§eSuchen MATERIAL_BACK=§eZurück @@ -817,189 +749,164 @@ REGION_TNT_BUILD_DESTROY=§cEine Explosion hätte Blöcke im Baubereich zerstör REGION_TNT_TB_DESTROY=§cEine Explosion hätte Blöcke im Testblockbereich zerstört AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 15 Minuten nichts passiert. AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt - -SKIN_HELP = §8/§eskin §8[§7Kuerzel§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Erstellt die Skin Schematics. 'public' als Creator nutzen für keinen Creator, danach die nachricht an YoyoNow kopieren (mit Click kopieren) +SKIN_HELP=§8/§eskin §8[§7Kuerzel§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Erstellt die Skin Schematics. 'public' als Creator nutzen für keinen Creator, danach die nachricht an YoyoNow kopieren (mit Click kopieren) SKIN_NO_REGION=§7Du steht in keiner Region, welche mit einem Skin versehen werden kann SKIN_ALREADY_EXISTS=§cDieser Skin existiert in der Form bereits SKIN_MESSAGE=§7Skin erstellt SKIN_MESSAGE_HOVER=§eKlicken zum kopieren für YoyoNow und an diesen senden - # Panzern -PANZERN_HELP = §8/§epanzern §8[§7Block§8] §8[§7Slab§8] §8- §7Panzer deine WorldEdit Auswahl -PANZERN_PREPARE1 = §71. Gucke nochmal nach, ob Läufe auch bis zur Panzergrenze führen. -PANZERN_PREPARE2 = §72. Teppich in Gänge auf dem Boden vereinfacht das panzern. -PANZERN_PREPARE3 = §73. Schildtechnik sollte explizit eingeschlossen sein. -PANZERN_PREPARE4 = §74. Innerhalb der zu panzernden Region zu stehen, beim Befehlausführen kann das Panzern verbessern. -PANZERN_NO_WORLDEDIT = §cDu hast keine WorldEdit Selection -PANZERN_PROGRESS = §e{0} §7Blöcke übrig, §e{1} §7Blöcke pro Sekunde, §e{2} §7Block Delta -PANZERN_DONE = §aZuende gepanzert - +PANZERN_HELP=§8/§epanzern §8[§7Block§8] §8[§7Slab§8] §8- §7Panzer deine WorldEdit Auswahl +PANZERN_PREPARE1=§71. Gucke nochmal nach, ob Läufe auch bis zur Panzergrenze führen. +PANZERN_PREPARE2=§72. Teppich in Gänge auf dem Boden vereinfacht das panzern. +PANZERN_PREPARE3=§73. Schildtechnik sollte explizit eingeschlossen sein. +PANZERN_PREPARE4=§74. Innerhalb der zu panzernden Region zu stehen, beim Befehlausführen kann das Panzern verbessern. +PANZERN_NO_WORLDEDIT=§cDu hast keine WorldEdit Selection +PANZERN_PROGRESS=§e{0} §7Blöcke übrig, §e{1} §7Blöcke pro Sekunde, §e{2} §7Block Delta +PANZERN_DONE=§aZuende gepanzert # Laufbau -LAUFBAU_HELP = §8/§elaufbau §8[§7smallest§8|§7blastresistant§8] §8- §7Baue einen Lauf in deiner WorldEdit Auswahl mit den Traces -LAUFBAU_HELP_SETTINGS = §8/§elaufbau settings §8- §7Öffnet die Settings GUI -LAUFBAU_PREPARE1 = §71. Trace die Kanonen so oft wie nötig, in allen Modi. -LAUFBAU_PREPARE2 = §72. Versuche alle Fails aus dem Trace zu löschen. -LAUFBAU_NO_WORLDEDIT = §cDu hast keine WorldEdit Selection -LAUFBAU_STATE_FILTERING_TRACES = Traces filtern -LAUFBAU_STATE_PROCESSING_TRACES = Traces verbinden -LAUFBAU_STATE_CREATE_LAUF = Lauf erstellen -LAUFBAU_SIMPLE_PROGRESS = §e{0}§8: §e{1}§8/§e{2} §7Übrige Zeit §8: §e{3} -LAUFBAU_DONE = §aZuende gebaut - -LAUFBAU_SETTINGS_GUI_NAME = §eLaufbau -LAUFBAU_SETTINGS_ACTIVE = §aAktiv -LAUFBAU_SETTINGS_INACTIVE = §cInaktiv -LAUFBAU_SETTINGS_MIXED = §e{0}§8/§e{1} §aAktiv -LAUFBAU_SETTINGS_GUI_BACK = §eBack - -LAUFBAU_SETTINGS_TOGGLE = §eClick §8-§7 Toggle -LAUFBAU_SETTINGS_ADVANCED = §eMiddle-Click §8-§7 Erweiterte Einstellung - -LAUFBAU_BLOCK_COBWEB = §eCobweb -LAUFBAU_BLOCK_GRASS_PATH = §eGrass Path -LAUFBAU_BLOCK_SOUL_SAND = §eSoul Sand -LAUFBAU_BLOCK_COCOA = §eCocoa -LAUFBAU_BLOCK_TURTLE_EGG = §eTurtle Eggs -LAUFBAU_BLOCK_CHEST = §eChest -LAUFBAU_BLOCK_SNOW = §eSnow Layer -LAUFBAU_BLOCK_PLAYER_WALL_HEAD = §ePlayer Wall Head -LAUFBAU_BLOCK_STONECUTTER = §eStonecutter -LAUFBAU_BLOCK_PLAYER_HEAD = §ePlayer Head -LAUFBAU_BLOCK_CAKE = §eCake -LAUFBAU_BLOCK_END_STONE_BRICK_SLAB = §eEndstone Brick Slabs -LAUFBAU_BLOCK_SEA_PICKLE = §eSea Pickles -LAUFBAU_BLOCK_CAMPFIRE = §eCampfire -LAUFBAU_BLOCK_FLOWER_POT = §eFlower Pot -LAUFBAU_BLOCK_IRON_TRAPDOOR = §eIron Trapdoor -LAUFBAU_BLOCK_LILY_PAD = §eLily Pad -LAUFBAU_BLOCK_WHITE_CARPET = §eCarpet -LAUFBAU_BLOCK_END_ROD = §eEnd Rod -LAUFBAU_BLOCK_LIGHTNING_ROD = §eLightning Rod -LAUFBAU_BLOCK_CONDUIT = §eConduit -LAUFBAU_BLOCK_BREWING_STAND = §eBrewing Stand -LAUFBAU_BLOCK_BELL = §eBell -LAUFBAU_BLOCK_GRINDSTONE = §eGrindstone -LAUFBAU_BLOCK_HOPPER = §eHopper -LAUFBAU_BLOCK_LANTERN = §eLantern -LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS = §eEndstone Brick Stairs -LAUFBAU_BLOCK_CHORUS_PLANT = §eChorus Plant -LAUFBAU_BLOCK_NETHER_BRICK_FENCE = §eNether Brick Fence -LAUFBAU_BLOCK_IRON_BARS = §eIron Bars -LAUFBAU_BLOCK_END_STONE_BRICK_WALL = §eEndstone Brick Walls -LAUFBAU_BLOCK_CHAIN = §eChain -LAUFBAU_BLOCK_BIG_DRIP_LEAF = §eBig Drip Leaf -LAUFBAU_BLOCK_DRAGON_EGG = §eDragon Egg -LAUFBAU_BLOCK_AZALEA = §eAzalea -LAUFBAU_BLOCK_CANDLE = §eKerze -LAUFBAU_BLOCK_CANDLE_CAKE = §eKuchen mit Kerze -LAUFBAU_BLOCK_LECTERN = §eLectern - -LAUFBAU_FACING_NORTH = §8-§7 Richtung Norden -LAUFBAU_FACING_SOUTH = §8-§7 Richtung Süden -LAUFBAU_FACING_WEST = §8-§7 Richtung Westen -LAUFBAU_FACING_EAST = §8-§7 Richtung Osten -LAUFBAU_FACING_UP = §8-§7 Richtung Oben -LAUFBAU_FACING_DOWN = §8-§7 Richtung Unten - -LAUFBAU_COUNT_1 = §8-§7 Anzahl 1 -LAUFBAU_COUNT_2 = §8-§7 Anzahl 2 -LAUFBAU_COUNT_3 = §8-§7 Anzahl 3 -LAUFBAU_COUNT_4 = §8-§7 Anzahl 4 - -LAUFBAU_LAYERS_8 = §8-§7 Ebenen 8 -LAUFBAU_LAYERS_7 = §8-§7 Ebenen 7 -LAUFBAU_LAYERS_6 = §8-§7 Ebenen 6 -LAUFBAU_LAYERS_3 = §8-§7 Ebenen 3 -LAUFBAU_LAYERS_2 = §8-§7 Ebenen 2 - -LAUFBAU_TYPE_BOTTOM = §8-§7 Type Unten -LAUFBAU_TYPE_TOP = §8-§7 Type Oben - -LAUFBAU_HALF_BOTTOM = §8-§7 Hälfte Unten -LAUFBAU_HALF_TOP = §8-§7 Hälfte Oben - -LAUFBAU_OPEN = §8-§7 Geöffnet - -LAUFBAU_ATTACHMENT_CEILING = §8-§7 Befestigung Decke -LAUFBAU_ATTACHMENT_FLOOR = §8-§7 Befestigung Boden -LAUFBAU_ATTACHMENT_DOUBLE_WALL = §8-§7 Befestigung beidseitige Wand -LAUFBAU_ATTACHMENT_SINGLE_WALL = §8-§7 Befestigung einseitige Wand -LAUFBAU_ATTACHMENT_WALL = §8-§7 Befestigung Wand - -LAUFBAU_CONNECTION_FLOOR = §8-§7 Verbindung Boden -LAUFBAU_CONNECTION_NORTH = §8-§7 Verbindung Norden -LAUFBAU_CONNECTION_SOUTH = §8-§7 Verbindung Süden -LAUFBAU_CONNECTION_EAST = §8-§7 Verbindung Osten -LAUFBAU_CONNECTION_WEST = §8-§7 Verbindung Westen -LAUFBAU_CONNECTION_DOWN = §8-§7 Verbindung Unten -LAUFBAU_CONNECTION_UP = §8-§7 Verbindung Oben - -LAUFBAU_HANGING = §8-§7 hängend - -LAUFBAU_SHAPE_STRAIGHT = §8-§7 Form gerade -LAUFBAU_SHAPE_OUTER_LEFT = §8-§7 Form äußere links -LAUFBAU_SHAPE_INNER_LEFT = §8-§7 Form innere links - -LAUFBAU_TILT_NONE = §8-§7 Neigung keine -LAUFBAU_TILT_PARTIAL = §8-§7 Neigung teilweise - +LAUFBAU_HELP=§8/§elaufbau §8[§7smallest§8|§7blastresistant§8] §8- §7Baue einen Lauf in deiner WorldEdit Auswahl mit den Traces +LAUFBAU_HELP_SETTINGS=§8/§elaufbau settings §8- §7Öffnet die Settings GUI +LAUFBAU_PREPARE1=§71. Trace die Kanonen so oft wie nötig, in allen Modi. +LAUFBAU_PREPARE2=§72. Versuche alle Fails aus dem Trace zu löschen. +LAUFBAU_NO_WORLDEDIT=§cDu hast keine WorldEdit Selection +LAUFBAU_STATE_FILTERING_TRACES=Traces filtern +LAUFBAU_STATE_PROCESSING_TRACES=Traces verbinden +LAUFBAU_STATE_CREATE_LAUF=Lauf erstellen +LAUFBAU_SIMPLE_PROGRESS=§e{0}§8: §e{1}§8/§e{2} §7Übrige Zeit §8: §e{3} +LAUFBAU_DONE=§aZuende gebaut +LAUFBAU_SETTINGS_GUI_NAME=§eLaufbau +LAUFBAU_SETTINGS_ACTIVE=§aAktiv +LAUFBAU_SETTINGS_INACTIVE=§cInaktiv +LAUFBAU_SETTINGS_MIXED=§e{0}§8/§e{1} §aAktiv +LAUFBAU_SETTINGS_GUI_BACK=§eBack +LAUFBAU_SETTINGS_TOGGLE=§eClick §8-§7 Toggle +LAUFBAU_SETTINGS_ADVANCED=§eMiddle-Click §8-§7 Erweiterte Einstellung +LAUFBAU_BLOCK_COBWEB=§eCobweb +LAUFBAU_BLOCK_GRASS_PATH=§eGrass Path +LAUFBAU_BLOCK_SOUL_SAND=§eSoul Sand +LAUFBAU_BLOCK_COCOA=§eCocoa +LAUFBAU_BLOCK_TURTLE_EGG=§eTurtle Eggs +LAUFBAU_BLOCK_CHEST=§eChest +LAUFBAU_BLOCK_SNOW=§eSnow Layer +LAUFBAU_BLOCK_PLAYER_WALL_HEAD=§ePlayer Wall Head +LAUFBAU_BLOCK_STONECUTTER=§eStonecutter +LAUFBAU_BLOCK_PLAYER_HEAD=§ePlayer Head +LAUFBAU_BLOCK_CAKE=§eCake +LAUFBAU_BLOCK_END_STONE_BRICK_SLAB=§eEndstone Brick Slabs +LAUFBAU_BLOCK_SEA_PICKLE=§eSea Pickles +LAUFBAU_BLOCK_CAMPFIRE=§eCampfire +LAUFBAU_BLOCK_FLOWER_POT=§eFlower Pot +LAUFBAU_BLOCK_IRON_TRAPDOOR=§eIron Trapdoor +LAUFBAU_BLOCK_LILY_PAD=§eLily Pad +LAUFBAU_BLOCK_WHITE_CARPET=§eCarpet +LAUFBAU_BLOCK_END_ROD=§eEnd Rod +LAUFBAU_BLOCK_LIGHTNING_ROD=§eLightning Rod +LAUFBAU_BLOCK_CONDUIT=§eConduit +LAUFBAU_BLOCK_BREWING_STAND=§eBrewing Stand +LAUFBAU_BLOCK_BELL=§eBell +LAUFBAU_BLOCK_GRINDSTONE=§eGrindstone +LAUFBAU_BLOCK_HOPPER=§eHopper +LAUFBAU_BLOCK_LANTERN=§eLantern +LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS=§eEndstone Brick Stairs +LAUFBAU_BLOCK_CHORUS_PLANT=§eChorus Plant +LAUFBAU_BLOCK_NETHER_BRICK_FENCE=§eNether Brick Fence +LAUFBAU_BLOCK_IRON_BARS=§eIron Bars +LAUFBAU_BLOCK_END_STONE_BRICK_WALL=§eEndstone Brick Walls +LAUFBAU_BLOCK_CHAIN=§eChain +LAUFBAU_BLOCK_BIG_DRIP_LEAF=§eBig Drip Leaf +LAUFBAU_BLOCK_DRAGON_EGG=§eDragon Egg +LAUFBAU_BLOCK_AZALEA=§eAzalea +LAUFBAU_BLOCK_CANDLE=§eKerze +LAUFBAU_BLOCK_CANDLE_CAKE=§eKuchen mit Kerze +LAUFBAU_BLOCK_LECTERN=§eLectern +LAUFBAU_FACING_NORTH=§8-§7 Richtung Norden +LAUFBAU_FACING_SOUTH=§8-§7 Richtung Süden +LAUFBAU_FACING_WEST=§8-§7 Richtung Westen +LAUFBAU_FACING_EAST=§8-§7 Richtung Osten +LAUFBAU_FACING_UP=§8-§7 Richtung Oben +LAUFBAU_FACING_DOWN=§8-§7 Richtung Unten +LAUFBAU_COUNT_1=§8-§7 Anzahl 1 +LAUFBAU_COUNT_2=§8-§7 Anzahl 2 +LAUFBAU_COUNT_3=§8-§7 Anzahl 3 +LAUFBAU_COUNT_4=§8-§7 Anzahl 4 +LAUFBAU_LAYERS_8=§8-§7 Ebenen 8 +LAUFBAU_LAYERS_7=§8-§7 Ebenen 7 +LAUFBAU_LAYERS_6=§8-§7 Ebenen 6 +LAUFBAU_LAYERS_3=§8-§7 Ebenen 3 +LAUFBAU_LAYERS_2=§8-§7 Ebenen 2 +LAUFBAU_TYPE_BOTTOM=§8-§7 Type Unten +LAUFBAU_TYPE_TOP=§8-§7 Type Oben +LAUFBAU_HALF_BOTTOM=§8-§7 Hälfte Unten +LAUFBAU_HALF_TOP=§8-§7 Hälfte Oben +LAUFBAU_OPEN=§8-§7 Geöffnet +LAUFBAU_ATTACHMENT_CEILING=§8-§7 Befestigung Decke +LAUFBAU_ATTACHMENT_FLOOR=§8-§7 Befestigung Boden +LAUFBAU_ATTACHMENT_DOUBLE_WALL=§8-§7 Befestigung beidseitige Wand +LAUFBAU_ATTACHMENT_SINGLE_WALL=§8-§7 Befestigung einseitige Wand +LAUFBAU_ATTACHMENT_WALL=§8-§7 Befestigung Wand +LAUFBAU_CONNECTION_FLOOR=§8-§7 Verbindung Boden +LAUFBAU_CONNECTION_NORTH=§8-§7 Verbindung Norden +LAUFBAU_CONNECTION_SOUTH=§8-§7 Verbindung Süden +LAUFBAU_CONNECTION_EAST=§8-§7 Verbindung Osten +LAUFBAU_CONNECTION_WEST=§8-§7 Verbindung Westen +LAUFBAU_CONNECTION_DOWN=§8-§7 Verbindung Unten +LAUFBAU_CONNECTION_UP=§8-§7 Verbindung Oben +LAUFBAU_HANGING=§8-§7 hängend +LAUFBAU_SHAPE_STRAIGHT=§8-§7 Form gerade +LAUFBAU_SHAPE_OUTER_LEFT=§8-§7 Form äußere links +LAUFBAU_SHAPE_INNER_LEFT=§8-§7 Form innere links +LAUFBAU_TILT_NONE=§8-§7 Neigung keine +LAUFBAU_TILT_PARTIAL=§8-§7 Neigung teilweise # UTILS -SELECT_HELP = §8/§eselect §8[§7RegionsTyp§8] §8- §7Wähle einen RegionsTyp aus -SELECT_EXTENSION_HELP = §8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Wähle einen RegionsTyp aus mit oder ohne Extension -SELECT_GLOBAL_REGION = §cDie globale Region kannst du nicht auswählen -SELECT_NO_TYPE = §cDiese Region hat keinen {0} -SELECT_NO_EXTENSION = §cDiese Region hat keine Ausfahrmaße -SELECT_MESSAGE = §7WorldEdit auswahl auf {0}, {1}, {2} und {3}, {4}, {5} gesetzt - -SKULL_HELP = §8/§eskull §8[§eSpieler§8] §8-§7 Gibt einen SpielerKopf -SKULL_INVALID = §cUngültiger Spieler -SKULL_ITEM = §e{0}§8s Kopf - -SPEED_HELP = §8/§espeed §8[§71§8-§710§8|§edefault§8] §8-§7 Setzte deine Flug- und Laufgeschindigkeit. -SPEED_CURRENT = §7Aktuelle geschwindigkeit§8: §e{0} -SPEED_TOO_SMALL = §c{0} ist zu klein -SPEED_TOO_HIGH = §c{0} ist zu hoch -SPEED_ITEM = §eGeschwindigkeit -SPEED_ITEM_LORE = §7Aktuell: §e -SPEED_TAB_NAME = Geschwindigkeit eingeben - -WORLDEDIT_WAND = WorldEdit Wand -WORLDEDIT_LEFTCLICK = Left click: select pos #1 -WORLDEDIT_RIGHTCLICK = Right click: select pos #2 - -TNT_CLICK_HEADER = §8---=== §eTNT §8===--- -TNT_CLICK_ORDER = §eEntity Order§8: §e{0} -TNT_CLICK_FUSE_TIME = §eFuseTime§8: §e{0} -TNT_CLICK_POSITION_X = §7Position §eX§8: §e{0} -TNT_CLICK_POSITION_Y = §7Position §eY§8: §e{0} -TNT_CLICK_POSITION_Z = §7Position §eZ§8: §e{0} -TNT_CLICK_VELOCITY_X = §7Velocity §eX§8: §e{0} -TNT_CLICK_VELOCITY_Y = §7Velocity §eY§8: §e{0} -TNT_CLICK_VELOCITY_Z = §7Velocity §eZ§8: §e{0} -TNT_CLICK_COUNT = §7Anzahl §8: §e{0} +SELECT_HELP=§8/§eselect §8[§7RegionsTyp§8] §8- §7Wähle einen RegionsTyp aus +SELECT_EXTENSION_HELP=§8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Wähle einen RegionsTyp aus mit oder ohne Extension +SELECT_GLOBAL_REGION=§cDie globale Region kannst du nicht auswählen +SELECT_NO_TYPE=§cDiese Region hat keinen {0} +SELECT_NO_EXTENSION=§cDiese Region hat keine Ausfahrmaße +SELECT_MESSAGE=§7WorldEdit auswahl auf {0}, {1}, {2} und {3}, {4}, {5} gesetzt +SKULL_HELP=§8/§eskull §8[§eSpieler§8] §8-§7 Gibt einen SpielerKopf +SKULL_INVALID=§cUngültiger Spieler +SKULL_ITEM=§e{0}§8s Kopf +SPEED_HELP=§8/§espeed §8[§71§8-§710§8|§edefault§8] §8-§7 Setzte deine Flug- und Laufgeschindigkeit. +SPEED_CURRENT=§7Aktuelle geschwindigkeit§8: §e{0} +SPEED_TOO_SMALL=§c{0} ist zu klein +SPEED_TOO_HIGH=§c{0} ist zu hoch +SPEED_ITEM=§eGeschwindigkeit +SPEED_ITEM_LORE=§7Aktuell: §e +SPEED_TAB_NAME=Geschwindigkeit eingeben +WORLDEDIT_WAND=WorldEdit Wand +WORLDEDIT_LEFTCLICK=Left click: select pos #1 +WORLDEDIT_RIGHTCLICK=Right click: select pos #2 +TNT_CLICK_HEADER=§8---=== §eTNT §8===--- +TNT_CLICK_ORDER=§eEntity Order§8: §e{0} +TNT_CLICK_FUSE_TIME=§eFuseTime§8: §e{0} +TNT_CLICK_POSITION_X=§7Position §eX§8: §e{0} +TNT_CLICK_POSITION_Y=§7Position §eY§8: §e{0} +TNT_CLICK_POSITION_Z=§7Position §eZ§8: §e{0} +TNT_CLICK_VELOCITY_X=§7Velocity §eX§8: §e{0} +TNT_CLICK_VELOCITY_Y=§7Velocity §eY§8: §e{0} +TNT_CLICK_VELOCITY_Z=§7Velocity §eZ§8: §e{0} +TNT_CLICK_COUNT=§7Anzahl §8: §e{0} TNT_CLICK_ISOLATE=§eIsolieren -SELECT_ITEM_CHOOSE_EXTENSION = Extension auswählen -SELECT_ITEM_CHOOSE_SELECTION = Auswahl auswählen -SELECT_ITEM_NORMAL_EXTENSION = §eNormal -SELECT_ITEM_EXTENDED_EXTENSION= §eAusgefahren -SELECT_ITEM_SELECT= §eSelect -SELECT_ITEM_AUSWAHL= §7Auswahl: §7{0} {1} +SELECT_ITEM_CHOOSE_EXTENSION=Extension auswählen +SELECT_ITEM_CHOOSE_SELECTION=Auswahl auswählen +SELECT_ITEM_NORMAL_EXTENSION=§eNormal +SELECT_ITEM_EXTENDED_EXTENSION=§eAusgefahren +SELECT_ITEM_SELECT=§eSelect +SELECT_ITEM_AUSWAHL=§7Auswahl: §7{0} {1} SELECT_ITEM_RIGHT_CLICK=§7Rechtklick zum ändern SELECT_ITEM_BAURAHMEN=§eBaurahmen SELECT_ITEM_BAUPLATTFORM=§eBauplattform SELECT_ITEM_TESTBLOCK=§eTestblock - -CHESTFILLER_FILLED = §eKiste gefüllt - -PISTON_HELP_1 = §7Rechts Klick auf Piston mit einem Slime Ball berechnet dir die bewegten Blöcke. -PISTON_HELP_2 = §7Die Anzahl ist Rot, wenn ein unmovable Block vorhanden ist. -PISTON_HELP_3 = §7Die Anzahl ist Gelb, wenn zu viele Blöcke vorhanden sind. -PISTON_INFO = §7Bewegte Blöcke {0}{1}§8/§712 - +CHESTFILLER_FILLED=§eKiste gefüllt +PISTON_HELP_1=§7Rechts Klick auf Piston mit einem Slime Ball berechnet dir die bewegten Blöcke. +PISTON_HELP_2=§7Die Anzahl ist Rot, wenn ein unmovable Block vorhanden ist. +PISTON_HELP_3=§7Die Anzahl ist Gelb, wenn zu viele Blöcke vorhanden sind. +PISTON_INFO=§7Bewegte Blöcke {0}{1}§8/§712 # Warp -WARP_LOC_X = §7X§8: §e{0} -WARP_LOC_Y = §7Y§8: §e{0} -WARP_LOC_Z = §7Z§8: §e{0} +WARP_LOC_X=§7X§8: §e{0} +WARP_LOC_Y=§7Y§8: §e{0} +WARP_LOC_Z=§7Z§8: §e{0} WARP_EXISTS=§7Ein Warp mit dem namen §e{0} §7existiert bereits WARP_NAME_RESERVED=§7Du kannst nicht §c{0} §7als name für einen Warp nutzen WARP_CREATED=§7Der Warp §e{0} §7wurde erstellt @@ -1019,30 +926,22 @@ WARP_HELP_INFO=§8/§ewarp info §8[§7Name§8] §8- §7Infos zu einem Punkt WARP_HELP_DELETE=§8/§ewarp delete §8[§7Name§8] §8- §7Lösche einen Warp WARP_HELP_GUI=§8/§ewarp gui §8- §7Öffne die Warp-GUI WARP_HELP_LIST=§8/§ewarp list §8- §7Liste alle Warp-Punkt auf - # WORLD -STOP_HELP = §8/§estop §8- §7Stoppt den Server -STOP_MESSAGE = §eDer Server wird gestoppt - -KICKALL_HELP = §8/§ekickall §8- §7Kickt alle Spieler vom Server außer den Owner - +STOP_HELP=§8/§estop §8- §7Stoppt den Server +STOP_MESSAGE=§eDer Server wird gestoppt +KICKALL_HELP=§8/§ekickall §8- §7Kickt alle Spieler vom Server außer den Owner # Techhider -TECHHIDER_HELP = §8/§etechhider §8- §7Techhider umschalten -TECHHIDER_GLOBAL = §cKein Techhider in der globalen region -TECHHIDER_ON = §aTechhider aktiviert -TECHHIDER_OFF = §cTechHider deaktiviert - +TECHHIDER_HELP=§8/§etechhider §8- §7Techhider umschalten +TECHHIDER_GLOBAL=§cKein Techhider in der globalen region +TECHHIDER_ON=§aTechhider aktiviert +TECHHIDER_OFF=§cTechHider deaktiviert # XRAY -XRAY_HELP = §8/§exray §8- §7Xray umschalten -XRAY_GLOBAL = §cKein Xray in der globalen region -XRAY_ON = §aXray aktiviert -XRAY_OFF = §cXray deaktiviert - - +XRAY_HELP=§8/§exray §8- §7Xray umschalten +XRAY_GLOBAL=§cKein Xray in der globalen region +XRAY_ON=§aXray aktiviert +XRAY_OFF=§cXray deaktiviert # WorldEdit -COLORREPLACE_HELP = §8//§ecolorreplace §8[§7color§8] §8[§7color§8] §8- §7Ersetzt eine Farbe mit einer anderen - -TYPEREPLACE_HELP = §8//§etyreplace §8[§7type§8] §8[§7type§8] §8- §7Ersetzt einen Blockgruppe mit einer anderen - +COLORREPLACE_HELP=§8//§ecolorreplace §8[§7color§8] §8[§7color§8] §8- §7Ersetzt eine Farbe mit einer anderen +TYPEREPLACE_HELP=§8//§etyreplace §8[§7type§8] §8[§7type§8] §8- §7Ersetzt einen Blockgruppe mit einer anderen # Schematics SCHEMATIC_GUI_ITEM=§eSchematics diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java index 266cd65b..d8489a0f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java @@ -39,7 +39,10 @@ import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.player.PlayerQuitEvent; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; public class Loader implements Listener { @@ -78,6 +81,10 @@ public class Loader implements Listener { } if (currentElement >= elements.size()) { currentElement = 0; + if (stage == Stage.SINGLE) { + stage = Stage.PAUSE; + return; + } } while (currentElement < elements.size()) { @@ -92,6 +99,20 @@ public class Loader implements Listener { }, 0, 1); } + public void single() { + if (stage == Stage.END) return; + if (stage == Stage.RUNNING) return; + stage = Stage.SINGLE; + if (recorder != null) { + recorder.stop(); + recorder = null; + } + if (elements.isEmpty()) { + BauSystem.MESSAGE.send("LOADER_NOTHING_RECORDED", p); + stop(); + } + } + public void start() { if (stage == Stage.END) return; if (stage == Stage.RUNNING) return; @@ -349,6 +370,7 @@ public class Loader implements Listener { public enum Stage implements EnumDisplay { SETUP("LOADER_SETUP"), RUNNING("LOADER_RUNNING"), + SINGLE("LOADER_SINGLE"), PAUSE("LOADER_PAUSE"), END("LOADER_END"); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java index ffe27e64..021ad330 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java @@ -20,10 +20,8 @@ package de.steamwar.bausystem.features.loader; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.command.SWCommand; -import de.steamwar.command.TypeValidator; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -105,6 +103,14 @@ public class LoaderCommand extends SWCommand implements Listener { loader.setTicksBetweenBlocks(delay); } + @Register(value = "single", description = "LOADER_HELP_SINGLE") + public void singleLoader(@Validator Player p) { + Loader loader = Loader.getLoader(p); + if (loaderNullCheck(loader, p)) return; + loader.single(); + BauSystem.MESSAGE.send("LOADER_SINGLE_CMD", p); + } + @EventHandler public void onBauMemberUpdate(BauMemberUpdateEvent event) { event.getNewSpectator().forEach(player -> { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java index 07554a68..f615dad3 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java @@ -20,9 +20,6 @@ package de.steamwar.bausystem.features.script.lua.libs; 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; @@ -71,13 +68,13 @@ public class RegionLib implements LuaLib { table.set("freeze", getter(() -> region.get().getPlain(Flag.FREEZE, FreezeMode.class) == FreezeMode.ACTIVE)); table.set("protect", getter(() -> region.get().getPlain(Flag.PROTECT, ProtectMode.class) == ProtectMode.ACTIVE)); - LuaValue traceLib = LuaValue.tableOf(); - traceLib.set("active", getter(() -> !region.get().isGlobal() && Recorder.INSTANCE.get(region.get()) instanceof ActiveTracer)); - traceLib.set("auto", getter(() -> !region.get().isGlobal() && Recorder.INSTANCE.get(region.get()) instanceof AutoTraceRecorder)); - traceLib.set("status", getter(() -> Recorder.INSTANCE.get(region.get()).scriptState())); - traceLib.set("time", getter(() -> Recorder.INSTANCE.get(region.get()).scriptTime())); + //LuaValue traceLib = LuaValue.tableOf(); + //traceLib.set("active", getter(() -> !region.get().isGlobal() && Recorder.INSTANCE.get(region.get()) instanceof ActiveTracer)); + //traceLib.set("auto", getter(() -> !region.get().isGlobal() && Recorder.INSTANCE.get(region.get()) instanceof AutoTraceRecorder)); + //traceLib.set("status", getter(() -> Recorder.INSTANCE.get(region.get()).scriptState())); + //traceLib.set("time", getter(() -> Recorder.INSTANCE.get(region.get()).scriptTime())); - table.set("trace", traceLib); + //table.set("trace", traceLib); Loader loader = Loader.getLoader(player); table.set("loader", getter(() -> loader == null ? "OFF" : loader.getStage().name())); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java index 893161f4..5c3d30e0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java @@ -23,8 +23,7 @@ import de.steamwar.bausystem.features.simulator.data.Simulator; import de.steamwar.bausystem.features.simulator.data.SimulatorElement; import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; import de.steamwar.bausystem.features.tpslimit.TPSUtils; -import de.steamwar.bausystem.features.tracer.record.Recorder; -import de.steamwar.bausystem.features.tracer.record.SingleTraceRecorder; +import de.steamwar.bausystem.features.tracer.TraceRecorder; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.utils.TickEndEvent; import de.steamwar.bausystem.utils.TickStartEvent; @@ -69,6 +68,20 @@ public class SimulatorExecutor implements Listener { @Override public void accept(World world) { currentlyRunning.remove(simulator); + + if (simulator.isAutoTrace()) { + simulator.getGroups() + .stream() + .map(SimulatorGroup::getElements) + .flatMap(List::stream) + .map(SimulatorElement::getPosition) + .map(pos -> pos.toLocation(WORLD)) + .map(Region::getRegion) + .distinct() + .forEach(region -> { + TraceRecorder.instance.stopRecording(region); + }); + } } }); @@ -82,9 +95,7 @@ public class SimulatorExecutor implements Listener { .map(Region::getRegion) .distinct() .forEach(region -> { - if (Recorder.INSTANCE.isDisabled(region)) { - Recorder.INSTANCE.set(region, new SingleTraceRecorder(region)); - } + TraceRecorder.instance.startRecording(region); }); } return true; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java index d53995a3..f33f6af3 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java @@ -20,9 +20,7 @@ package de.steamwar.bausystem.features.slaves.laufbau; import com.sk89q.worldedit.EditSession; -import de.steamwar.bausystem.features.slaves.laufbau.states.FilteringTracesState; import de.steamwar.bausystem.features.slaves.laufbau.states.LaufbauState; -import de.steamwar.bausystem.features.slaves.laufbau.states.CreatingLaufState; import de.steamwar.bausystem.features.slaves.laufbau.states.ProcessingTracesState; import de.steamwar.bausystem.utils.WorldEditUtils; import lombok.Getter; @@ -40,9 +38,7 @@ public class Laufbau { private Location pos1; private Location pos2; - private FilteringTracesState filteringTracesState = null; - private ProcessingTracesState processingTracesState = null; - private CreatingLaufState creatingLaufState = null; + private LaufbauState active; private List elements; @@ -62,8 +58,6 @@ public class Laufbau { int zFactor = (int) (Math.abs(selectionSize.getZ()) / 9.875); factor = Math.max(Math.max(xFactor, Math.max(yFactor, zFactor)), 8); - filteringTracesState = new FilteringTracesState(world, this::inRegion); - editSession = WorldEditUtils.getEditSession(player); elements = BlockBoundingBox.elements.stream().filter(blockBoundingBox -> { @@ -86,49 +80,32 @@ public class Laufbau { return -Double.compare(o1.blockData.getMaterial().getBlastResistance(), o2.blockData.getMaterial().getBlastResistance()); }); } - } - private LaufbauState getActive() { - if (creatingLaufState != null) { - return creatingLaufState; - } - if (processingTracesState != null) { - return processingTracesState; - } - return filteringTracesState; + active = new ProcessingTracesState(world, this::inRegion, editSession, elements, factor); } private void createNextState() { - if (creatingLaufState != null) { - return; - } - if (processingTracesState != null) { - creatingLaufState = new CreatingLaufState(processingTracesState.getBlocks(), processingTracesState.getCuboidIntersectionCache(), world, editSession, elements, factor); - return; - } - processingTracesState = new ProcessingTracesState(filteringTracesState.getTntPositions(), this::inRegion, factor); + if (active == null) return; + active = active.getNextState(); } public String actionBarMessage(Player p) { - return getActive().actionBarMessage(p); + return active.actionBarMessage(p); } public boolean hasNext() { - return getActive().hasNext(); + if (active == null) return false; + return active.hasNext(); } public void next() { - LaufbauState state = getActive(); + LaufbauState state = active; state.next(); if (!state.hasNext()) { createNextState(); } } - private boolean inRegion(Location location, int expansion) { - return inRegion(location.toVector(), expansion); - } - private boolean inRegion(Vector location, int expansion) { if (location.getBlockX() >= pos1.getBlockX() - expansion) { if (location.getBlockY() >= pos1.getBlockY() - expansion) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingLaufState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingLaufState.java index 9522518d..e4ed312b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingLaufState.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingLaufState.java @@ -196,4 +196,9 @@ public class CreatingLaufState implements LaufbauState { } } } + + @Override + public LaufbauState getNextState() { + return null; + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java deleted file mode 100644 index 55e4a0fa..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.slaves.laufbau.states; - -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.utils.FlatteningWrapper; -import lombok.Getter; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiPredicate; - -public class FilteringTracesState implements LaufbauState { - - private long start = System.currentTimeMillis(); - - private World world; - private BiPredicate inRegionCheck; - - private int totalRecord; - private List recordList; - private List tntRecords = new ArrayList<>(); - - @Getter - private List tntPositions = new ArrayList<>(); - - public FilteringTracesState(World world, BiPredicate inRegionCheck) { - recordList = new ArrayList<>(StoredRecords.getRecords()); - totalRecord = recordList.size(); - - this.world = world; - this.inRegionCheck = inRegionCheck; - } - - @Override - public String actionBarMessage(Player p) { - return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_FILTERING_TRACES", p), totalRecord - recordList.size(), totalRecord, eta(p, start, totalRecord - recordList.size(), totalRecord)); - } - - @Override - public boolean hasNext() { - return !recordList.isEmpty() || !tntRecords.isEmpty(); - } - - @Override - public void next() { - if (tntRecords.isEmpty()) { - Record record = recordList.remove(0); - tntRecords.addAll(record.getTnt()); - } - if (tntRecords.isEmpty()) { - return; - } - - Record.TNTRecord tntRecord = tntRecords.remove(0); - tntRecord.getPositions().forEach(tntPosition -> { - if (FlatteningWrapper.impl.inWater(world, tntPosition.getLocation())) { - return; - } - if (inRegionCheck.test(tntPosition.getLocation().toLocation(world), 1)) { - tntPositions.add(tntPosition); - } - if (tntPosition.getPreviousLocation() != null && inRegionCheck.test(tntPosition.getPreviousLocation().toLocation(world), 1)) { - tntPositions.add(tntPosition); - } - }); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java index 6ece3e22..6843db9e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java @@ -45,4 +45,6 @@ public interface LaufbauState { } return LocalTime.ofNanoOfDay(eta).format(DateTimeFormatter.ofPattern(BauSystem.MESSAGE.parse("TIME", p))); } + + LaufbauState getNextState(); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java index c34e5024..cec4c2cb 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java @@ -1,115 +1,128 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * Copyright (C) 2024 SteamWar.de-Serverteam * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.bausystem.features.slaves.laufbau.states; +import com.sk89q.worldedit.EditSession; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox; import de.steamwar.bausystem.features.slaves.laufbau.Cuboid; -import de.steamwar.bausystem.features.tracer.TNTPosition; +import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.bausystem.features.tracer.TraceManager; import de.steamwar.bausystem.region.Point; -import lombok.Getter; +import de.steamwar.bausystem.utils.FlatteningWrapper; +import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.util.*; import java.util.function.BiPredicate; +import java.util.stream.Collectors; public class ProcessingTracesState implements LaufbauState { - private long start = System.currentTimeMillis(); + private final long start = System.currentTimeMillis(); + private final World world; + private final BiPredicate inRegionCheck; + private final EditSession editSession; + private final List elements; + private final int factor; - private int totalCuboids; - private List tntPositionList; - private BiPredicate inRegionCheck; - private int factor; + private final List TNTPoints; + private final int totalTntRecords; - private List toExpand = new ArrayList<>(); + private final Set affectedBlocks = new HashSet<>(); + private final Map> cuboidsPerChunk = new HashMap<>(); - private int cuboidsDone = 0; - - @Getter - private Set blocks = new HashSet<>(); - - @Getter - private Map> cuboidIntersectionCache = new HashMap<>(); - - public ProcessingTracesState(List tntPositionList, BiPredicate inRegionCheck, int factor) { - this.tntPositionList = tntPositionList; - this.totalCuboids = tntPositionList.stream().mapToInt(tntPosition -> tntPosition.getPreviousLocation() == null ? 1 : 3).sum(); + public ProcessingTracesState(World world, BiPredicate inRegionCheck, EditSession editSession, List elements, int factor) { + this.world = world; this.inRegionCheck = inRegionCheck; + this.editSession = editSession; + this.elements = elements; this.factor = factor; + + // TODO: Optimize only retrieving traces inside of the affected regions! + TNTPoints = TraceManager.instance.getAll() + .stream() + .flatMap(trace -> trace.getHistories().stream()) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + totalTntRecords = TNTPoints.size(); } @Override public String actionBarMessage(Player p) { - return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), cuboidsDone, totalCuboids, eta(p, start, cuboidsDone, totalCuboids)); + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), totalTntRecords - TNTPoints.size(), totalTntRecords, eta(p, start, totalTntRecords - TNTPoints.size(), totalTntRecords)); + } + + private boolean inRegion(Vector location, int expansion) { + return inRegionCheck.test(location, expansion); } @Override public boolean hasNext() { - return !tntPositionList.isEmpty() || !toExpand.isEmpty(); + return !TNTPoints.isEmpty(); } @Override public void next() { - if (!toExpand.isEmpty()) { - Cuboid cuboid = toExpand.remove(0); - expandCuboid(cuboid); - } else { - TNTPosition tntPosition = tntPositionList.remove(0); - createCuboid(tntPosition); - } - } + TNTPoint current = TNTPoints.remove(0); + if (FlatteningWrapper.impl.inWater(world, current.getLocation().toVector())) return; + if (!(inRegion(current.getLocation().toVector(), 1) || (current.getPrevious().isPresent() && inRegion(current.getPrevious().get().getLocation().toVector(), 1)))) + return; - private void createCuboid(TNTPosition tntPosition) { - Vector location = tntPosition.getLocation(); - Vector previousLocation = tntPosition.getPreviousLocation(); - - if (previousLocation == null) { - toExpand.add(new Cuboid(location.getX() - 0.49, location.getY(), location.getZ() - 0.49, 0.98, 0.98, 0.98)); - } else { - Vector movement = location.clone().subtract(previousLocation); - toExpand.add(new Cuboid(previousLocation.getX() - 0.49, Math.min(previousLocation.getY(), location.getY()), previousLocation.getZ() - 0.49, 0.98, Math.abs(movement.getY()) + 0.98, 0.98)); - if (Math.abs(tntPosition.getUpdateVelocity().getX()) >= Math.abs(tntPosition.getUpdateVelocity().getZ())) { - toExpand.add(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), previousLocation.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); - toExpand.add(new Cuboid(location.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); + Location location = current.getLocation(); + if (current.getPrevious().isPresent()) { + Vector velocity = current.getPrevious().get().getVelocity(); + Location previousLocation = current.getPrevious().get().getLocation(); + Location movement = location.clone().subtract(previousLocation); + calculateCuboid(new Cuboid(previousLocation.getX() - 0.49, Math.min(previousLocation.getY(), location.getY()), previousLocation.getZ() - 0.49, 0.98, Math.abs(movement.getY()) + 0.98, 0.98)); + if (velocity.getX() >= velocity.getZ()) { + calculateCuboid(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), previousLocation.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); + calculateCuboid(new Cuboid(location.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); } else { - toExpand.add(new Cuboid(previousLocation.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); - toExpand.add(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), location.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); + calculateCuboid(new Cuboid(previousLocation.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); + calculateCuboid(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), location.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); } + } else { + calculateCuboid(new Cuboid(location.getX() - 0.49, location.getY(), location.getZ() - 0.49, 0.98, 0.98, 0.98)); } } - private void expandCuboid(Cuboid cuboid) { - cuboidsDone++; + private void calculateCuboid(Cuboid cuboid) { for (double x = cuboid.getX() - 2; x < cuboid.getX() + cuboid.getDx() + 2; x++) { for (double y = cuboid.getY() - 2; y < cuboid.getY() + cuboid.getDy() + 2; y++) { for (double z = cuboid.getZ() - 2; z < cuboid.getZ() + cuboid.getDz() + 2; z++) { Vector location = new Vector(x, y, z); - if (inRegionCheck.test(location, 0)) { - Point point = new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ()); - blocks.add(point); - cuboidIntersectionCache.computeIfAbsent(point.divide(factor), __ -> new HashSet<>()) + if (inRegion(location, 0)) { + affectedBlocks.add(new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + cuboidsPerChunk.computeIfAbsent(new Point(location.getBlockX() / factor, location.getBlockY() / factor, location.getBlockZ() / factor), __ -> new HashSet<>()) .add(cuboid); } } } } } + + @Override + public LaufbauState getNextState() { + return new CreatingLaufState(affectedBlocks, cuboidsPerChunk, world, editSession, elements, factor); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPoint.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPoint.java new file mode 100644 index 00000000..7a5d5425 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPoint.java @@ -0,0 +1,227 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer; + +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.utils.RegionExtensionType; +import de.steamwar.bausystem.region.utils.RegionType; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.util.Vector; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.util.List; +import java.util.Optional; + +/** + * Recording of a tnt at a specific tick + */ +@Getter +public class TNTPoint implements Externalizable { + /** + * Unique number to identify records being of the same tnt + */ + private int tntId; + + /** + * Whether this is a record of a tnt explosion or an entity + */ + private boolean explosion; + + /** + * Whether this is a record of a tnt that was in water + */ + private boolean inWater; + + /** + * Whether this record was taken after the first tnt exploded + */ + private boolean afterFirstExplosion; + + /** + * Whether this record has destroyed blocks in build area + */ + private boolean destroyedBuildArea; + + /** + * Whether this record has destroyed blocks in testblock area + */ + private boolean destroyedTestBlock; + + /** + * Tick offset, from this record being taken to the start of the trace + */ + private long ticksSinceStart; + + /** + * Fuse ticks of the recorded tnt (0 if this is an explosion) + */ + private int fuse; + + /** + * Location of the recorded tnt + */ + private Location location; + + /** + * Velocity of the recorded tnt + */ + private Vector velocity; + + /** + * List of all tnt records, that are represent the same tnt + */ + private List history; + + /** + * Constructor for deserialization only !! Do not Call !! + */ + public TNTPoint() { + } + + public TNTPoint(int tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart, + List history, List destroyedBlocks) { + this.tntId = tntId; + this.explosion = explosion; + this.inWater = tnt.isInWater(); + this.afterFirstExplosion = afterFirstExplosion; + this.ticksSinceStart = ticksSinceStart; + fuse = tnt.getFuseTicks(); + location = tnt.getLocation(); + velocity = tnt.getVelocity(); + this.history = history; + + boolean buildDestroy = false; + boolean testblockDestroy = false; + for (Block destroyedBlock : destroyedBlocks) { + if (Region.getRegion(destroyedBlock.getLocation()).inRegion(destroyedBlock.getLocation(), RegionType.BUILD, + RegionExtensionType.EXTENSION)) { + buildDestroy = true; + } + if (Region.getRegion(destroyedBlock.getLocation()).inRegion(destroyedBlock.getLocation(), + RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) { + testblockDestroy = true; + } + } + + destroyedBuildArea = buildDestroy; + destroyedTestBlock = testblockDestroy; + } + + /** + * Method for getting the next record of the tnt represented by this record + * + * @return the next record + */ + public Optional getNext() { + int index = history.indexOf(this); + return index == history.size() - 1 ? Optional.empty() : Optional.of(history.get(index + 1)); + } + + /** + * Method for getting the previous record of the tnt represented by this record + * + * @return the previous record + */ + public Optional getPrevious() { + int index = history.indexOf(this); + return index == 0 ? Optional.empty() : Optional.of(history.get(index - 1)); + } + + /** + * Internal methode for setting the history of this record + * during deserialization. + * + * @param history + */ + void setHistory(List history) { + this.history = history; + } + + @Override + public void writeExternal(ObjectOutput objectOutput) throws IOException { + objectOutput.writeInt(tntId); + objectOutput.writeBoolean(explosion); + objectOutput.writeBoolean(inWater); + objectOutput.writeBoolean(afterFirstExplosion); + objectOutput.writeBoolean(destroyedBuildArea); + objectOutput.writeBoolean(destroyedTestBlock); + objectOutput.writeLong(ticksSinceStart); + objectOutput.writeInt(fuse); + objectOutput.writeDouble(location.getX()); + objectOutput.writeDouble(location.getY()); + objectOutput.writeDouble(location.getZ()); + objectOutput.writeDouble(velocity.getX()); + objectOutput.writeDouble(velocity.getY()); + objectOutput.writeDouble(velocity.getZ()); + } + + @Override + public void readExternal(ObjectInput objectInput) throws IOException { + tntId = objectInput.readInt(); + explosion = objectInput.readBoolean(); + inWater = objectInput.readBoolean(); + afterFirstExplosion = objectInput.readBoolean(); + destroyedBuildArea = objectInput.readBoolean(); + destroyedTestBlock = objectInput.readBoolean(); + ticksSinceStart = objectInput.readLong(); + fuse = objectInput.readInt(); + double locX = objectInput.readDouble(); + double locY = objectInput.readDouble(); + double locZ = objectInput.readDouble(); + location = new Location(Bukkit.getWorlds().get(0), locX, locY, locZ); + double velX = objectInput.readDouble(); + double velY = objectInput.readDouble(); + double velZ = objectInput.readDouble(); + velocity = new Vector(velX, velY, velZ); + } + + @Override + public String toString() { + return "TNTPoint{" + + "tntId=" + tntId + + ", explosion=" + explosion + + ", inWater=" + inWater + + ", afterFirstExplosion=" + afterFirstExplosion + + ", destroyedBuildArea=" + destroyedBuildArea + + ", destroyedTestBlock=" + destroyedTestBlock + + ", ticksSinceStart=" + ticksSinceStart + + ", fuse=" + fuse + + ", location=" + location + + ", velocity=" + velocity + + '}'; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof TNTPoint)) return false; + TNTPoint record = (TNTPoint) obj; + if (record.isExplosion() != explosion) return false; + if (!record.getLocation().equals(location)) return false; + if (!record.getVelocity().equals(velocity)) return false; + return true; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java deleted file mode 100644 index 1af2b710..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer; - -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; - -@Getter -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; - - @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; - this.source = source; - this.exploded = exploded; - } - - @Override - public String toString() { - return "Position{" + - "location=" + super.getLocation() + - '}'; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java new file mode 100644 index 00000000..c46a1df3 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java @@ -0,0 +1,339 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer; + +import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; +import de.steamwar.bausystem.features.tracer.rendering.PlayerTraceShowData; +import de.steamwar.bausystem.features.tracer.rendering.TraceEntity; +import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; +import de.steamwar.bausystem.region.Region; +import de.steamwar.entity.REntity; +import de.steamwar.entity.REntityServer; +import lombok.Cleanup; +import lombok.Getter; +import lombok.SneakyThrows; +import org.bukkit.entity.Player; + +import java.io.*; +import java.lang.ref.SoftReference; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.GZIPInputStream; + +public class Trace { + /** + * UUID of the trace used for + */ + @Getter + private final UUID uuid; + + /** + * File the records are saved in + */ + @Getter + private final File recordsSaveFile; + + /** + * File the metadata are saved in + */ + @Getter + private final File metadataSaveFile; + + /** + * Region the trace was recorded in + */ + @Getter + private final Region region; + + /** + * Date the trace was recorded at + */ + @Getter + private final Date date; + + /** + * Records of TNTs, making up the trace + */ + private SoftReference> records; + + /** + * A map of all REntityServers rendering this trace + */ + private final Map entityServerMap = new HashMap<>(); + + /** + * Constructor for the creation of a new trace + * + * @param region the region the trace is created at + * @param recordList the list for the records making up this trace + */ + @SneakyThrows + public Trace(Region region, List recordList) { + this.uuid = UUID.randomUUID(); + recordsSaveFile = new File(TraceManager.tracesFolder, uuid + ".records"); + this.region = region; + this.date = new Date(); + records = new SoftReference<>(recordList); + metadataSaveFile = new File(TraceManager.tracesFolder, uuid + ".meta"); + + @Cleanup + ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(metadataSaveFile)); + outputStream.writeUTF(uuid.toString()); + outputStream.writeUTF(region.getName()); + outputStream.writeObject(date); + } + + /** + * Constructor for serialising a trace from the file system + * + * @param metadataSaveFile the file for this traces metadata + */ + @SneakyThrows + public Trace(File metadataSaveFile) { + String uuid = null; + Region region = null; + Date date = null; + + this.metadataSaveFile = metadataSaveFile; + + try { + @Cleanup + ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(metadataSaveFile)); + uuid = inputStream.readUTF(); + region = Region.getREGION_MAP().get(inputStream.readUTF()); + date = (Date) inputStream.readObject(); + inputStream.close(); + } finally { + this.uuid = UUID.fromString(uuid); + this.region = region; + this.date = date; + recordsSaveFile = new File(TraceManager.tracesFolder, uuid + ".records"); + this.records = new SoftReference<>(null); + } + } + + /** + * Gets the histories of all tnts in this trace + * + * @return the histories of this trace + */ + public Set> getHistories() { + Set> histories = new HashSet<>(); + + for (TNTPoint record : getRecords()) { + histories.add(record.getHistory()); + } + + return histories; + } + + /** + * List of all used ids + */ + public List getUsedIds() { + return getRecords() + .stream() + .map(TNTPoint::getTntId) + .map(i -> i + "") + .collect(Collectors.toList()); + } + + /** + * Renders this traces + * + * @param player The player the trace is rendered to + * @param playerTraceShowData The showData for modifying the rendering + */ + public void render(Player player, PlayerTraceShowData playerTraceShowData) { + REntityServer entityServer = entityServerMap.get(player); + if (entityServer != null) { + entityServer.getEntities().forEach(REntity::die); + } else { + entityServer = new REntityServer(); + entityServer.addPlayer(player); + entityServer.setCallback((p, rEntity, entityAction) -> { + if (entityAction != REntityServer.EntityAction.INTERACT) return; + if (rEntity instanceof TraceEntity) { + ((TraceEntity) rEntity).printIntoChat(p); + } + }); + entityServerMap.put(player, entityServer); + } + render(getRecords(), entityServer, playerTraceShowData); + } + + /** + * Renders specific records to this trace rendering + * + * @param records The records to be rendered + * @param player The player the records are rendered to + * @param playerTraceShowData The showData for modifying the rendering + */ + protected void render(List records, Player player, PlayerTraceShowData playerTraceShowData) { + render(records, entityServerMap.get(player), playerTraceShowData); + } + + /** + * Internal methode to render records to a REntityServer + * + * @param records Records to render + * @param entityServer The show server the trace will be renderd to + * @param playerTraceShowData The showData for modifying the rendering + */ + private void render(List records, REntityServer entityServer, PlayerTraceShowData playerTraceShowData) { + if (records.isEmpty()) { + return; + } + + Set flagList = playerTraceShowData.getEffectiveViewFlags(); + + // Apply filters + Stream workingRecordsStream = records.stream(); + for (ViewFlag flag : flagList) { + workingRecordsStream = flag.filter(workingRecordsStream); + } + List workingRecords = workingRecordsStream.collect(Collectors.toList()); + + // Bundle records at unique positions + List> bundles = bundleRecords(workingRecords, playerTraceShowData.getBundleFilter()); + + // Render bundled records + List entities = new LinkedList<>(); + + for (List bundle : bundles) { + entities.add(new TraceEntity(entityServer, bundle.get(0).getLocation(), bundle.get(0).isExplosion(), bundle, this)); + } + + // Apply modifiers + for (ViewFlag flag : flagList) { + flag.modify(entityServer, entities); + } + } + + /** + * Bundles the passed TNTRecords based on whether they are at the same location + * + * @param records The TNTRecords that are supposed to be bundled + * @param filter A filter specefieng whether records can be bundled + * @return A list of bundles + */ + private List> bundleRecords(List records, BundleFilter filter) { + if (filter == BundleFilter.NONE) { + return records.stream().map(List::of).collect(Collectors.toList()); + } + + List> bundles = new ArrayList<>(); + + recordsLoop: + for (TNTPoint record : records) { + for (int i = bundles.size() - 1; i >= 0; i--) { + List bundle = bundles.get(i); + + Boolean filterResult = filter.function.apply(record, bundle.get(0)); + if (filterResult == null) { + ArrayList newBundle = new ArrayList<>(); + newBundle.add(record); + bundles.add(newBundle); + continue recordsLoop; + } else if (filterResult) { + bundle.add(record); + continue recordsLoop; + } + } + + ArrayList newBundle = new ArrayList<>(); + newBundle.add(record); + bundles.add(newBundle); + } + + return bundles; + } + + /** + * Hides this trail for the given player + * + * @param player + */ + public void hide(Player player) { + REntityServer entityServer = entityServerMap.remove(player); + if (entityServer == null) { + return; + } + entityServer.removePlayer(player); + if (entityServer.getPlayers().isEmpty()) { + entityServer.close(); + } + } + + /** + * Hides this trace for all players + */ + public void hide() { + entityServerMap.forEach((player, entityServer) -> { + entityServer.close(); + }); + entityServerMap.clear(); + } + + /** + * Loads the records of this trace from storage to memory + */ + @SneakyThrows + private void loadRecords() { + List records = new ArrayList<>(); + + FileInputStream fileInputStream = new FileInputStream(recordsSaveFile); + + @Cleanup + ObjectInputStream inputStream = new ObjectInputStream(new GZIPInputStream(fileInputStream)); + while (fileInputStream.getChannel().position() < recordsSaveFile.length()) { + records.add((TNTPoint) inputStream.readObject()); + } + + Map> histories = new HashMap<>(); + for (TNTPoint record : records) { + int tntId = record.getTntId(); + List history = histories.computeIfAbsent(tntId, id -> new ArrayList<>()); + history.add(record); + record.setHistory(history); + } + + this.records = new SoftReference<>(records); + } + + public List getRecords() { + if (records.get() == null) { + loadRecords(); + } + return records.get(); + } + + @Override + public String toString() { + return "Trace{" + + "uuid=" + uuid + + ", region=" + region + + ", creationTime=" + date + + ", recordsSaveFile=" + recordsSaveFile.getName() + + ", records=" + getRecords() + + '}'; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java index 004f841b..828ab9a0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java @@ -1,44 +1,43 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * Copyright (C) 2023 SteamWar.de-Serverteam * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.bausystem.features.tracer; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.Permission; -import de.steamwar.bausystem.features.tracer.record.*; -import de.steamwar.bausystem.features.tracer.show.*; +import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; +import de.steamwar.bausystem.features.tracer.rendering.PlayerTraceShowData; +import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; +import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag; import de.steamwar.bausystem.region.Region; -import de.steamwar.bausystem.shared.ShowMode; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; -import de.steamwar.command.TypeValidator; import de.steamwar.linkage.Linked; -import de.steamwar.linkage.LinkedInstance; -import lombok.AllArgsConstructor; +import net.md_5.bungee.api.chat.ClickEvent; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import java.util.*; -import java.util.function.BiFunction; -import java.util.function.Supplier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.stream.Collectors; +import java.util.stream.Stream; @Linked public class TraceCommand extends SWCommand { @@ -47,199 +46,226 @@ public class TraceCommand extends SWCommand { super("trace", "trail"); } - @LinkedInstance - public Recorder recorder; - - @Register(value = {"start"}, description = "TRACE_COMMAND_HELP_START") - public void startCommand(@Validator Player p) { - Region region = Region.getRegion(p.getLocation()); - recorder.set(region, new SimpleTraceRecorder()); - BauSystem.MESSAGE.send("TRACE_MESSAGE_START", p); + @Register(value = "start", description = "TRACE_COMMAND_HELP_START") + public void start(@Validator Player player) { + Region region = Region.getRegion(player.getLocation()); + TraceRecorder.instance.startRecording(region); + BauSystem.MESSAGE.send("TRACE_MESSAGE_START", player); } - @Register(value = {"single"}, description = "TRACE_COMMAND_HELP_SINGLE") - public void singleCommand(@Validator Player p) { - Region region = Region.getRegion(p.getLocation()); - recorder.set(region, new SingleTraceRecorder(region)); - BauSystem.MESSAGE.send("TRACE_MESSAGE_SINGLE", p); + @Register(value = "stop", description = "TRACE_COMMAND_HELP_STOP") + public void stop(@Validator Player player) { + Region region = Region.getRegion(player.getLocation()); + TraceRecorder.instance.stopRecording(region); + BauSystem.MESSAGE.send("TRACE_MESSAGE_STOP", player); } - @Register(value = {"stop"}, description = "TRACE_COMMAND_HELP_STOP") - public void stopCommand(@Validator Player p) { - Region region = Region.getRegion(p.getLocation()); - recorder.remove(region); - BauSystem.MESSAGE.send("TRACE_MESSAGE_STOP", p); - } - - @Register(value = {"auto"}, description = "TRACE_COMMAND_HELP_AUTO") - @Register({"toggleauto"}) - public void autoCommand(@Validator Player p, @OptionalValue("-explode") @StaticValue({"-explode", "-ignite"}) String type) { - Region region = Region.getRegion(p.getLocation()); - switch (type) { - case "-explode": - recorder.set(region, new AutoExplodeTraceRecorder()); - BauSystem.MESSAGE.send("TRACE_MESSAGE_AUTO_IDLE_EXPLODE", p); - break; - case "-ignite": - recorder.set(region, new AutoIgniteTraceRecorder()); - BauSystem.MESSAGE.send("TRACE_MESSAGE_AUTO_IDLE_IGNITE", p); - break; - default: - break; + @Register(value = "auto", description = "TRACE_COMMAND_HELP_AUTO") + public void auto(@Validator Player player) { + Region region = Region.getRegion(player.getLocation()); + if (TraceRecorder.instance.toggleAutoTrace(region)) { + BauSystem.MESSAGE.send("TRACE_MESSAGE_AUTO_START", player); + } else { + BauSystem.MESSAGE.send("TRACE_MESSAGE_AUTO_STOP", player); } } - @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", description = "TRACE_COMMAND_HELP_SHOW") + public void show(@Validator Player player, @OptionalValue("DEFAULT") BundleFilter bundleFilter, ViewFlag... flags) { + showInternal(player, bundleFilter, flags); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW", player); } - @Register(value = {"show"}, description = "TRACE_COMMAND_HELP_SHOW_AT") - public void showAtCommand(@Validator Player p, @OptionalValue("time") @StaticValue({"time", "fuse"}) String type, @StaticValue("at") String __, @Min(intValue = 0) int at) { - internalSetShowFilter(p, "TRACE_MESSAGE_SHOW_AT", type, at, at); + @Register(value = {"show", "at"}, description = "TRACE_COMMAND_HELP_SHOW_AT_WITH") + public void showAt(@Validator Player player, @Min(intValue = 0) int time, @StaticValue("with") String with, @OptionalValue("DEFAULT") BundleFilter bundleFilter, ViewFlag... flags) { + showInternal(player, time, time, bundleFilter, flags); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_AT", player, time); } - @Register(value = {"show"}, description = "TRACE_COMMAND_HELP_SHOW_FROM") - 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); - BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW", p); - return; - } - internalSetShowFilter(p, "TRACE_MESSAGE_SHOW_FROM", type, from, Integer.MAX_VALUE); + @Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_WITH") + public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("with") String with, @OptionalValue("DEFAULT") BundleFilter bundleFilter, ViewFlag... flags) { + showInternal(player, from, Integer.MAX_VALUE, bundleFilter, flags); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM", player, from); } - @Register(value = {"show"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO") - 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) { - internalSetShowFilter(p, "TRACE_MESSAGE_SHOW_FROM_TO", type, from, to); - } - - private void internalSetShowFilter(Player p, String message, String type, int from, int to) { + @Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO_WITH") + public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString, int to, @StaticValue("with") String with, @OptionalValue("DEFAULT") BundleFilter bundleFilter, ViewFlag... flags) { if (to < from) { - BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_TO_SMALLER", p); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_TO_SMALLER", player); return; } - 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; - } - }); - BauSystem.MESSAGE.send(message, p, type, from, to); + showInternal(player, from, to, bundleFilter, flags); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM_TO", player, from, to); } - // /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(); + + @Register(value = {"show", "at"}, description = "TRACE_COMMAND_HELP_SHOW_AT") + public void showAt(@Validator Player player, @Min(intValue = 0) int time) { + TraceManager.instance.renderAt(player, time, time); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_AT", player, time); + } + + @Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM") + public void showFrom(@Validator Player player, @Min(intValue = 0) int from) { + TraceManager.instance.renderAt(player, from, Integer.MAX_VALUE); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM", player, from); + } + + @Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO") + public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString, int to) { + TraceManager.instance.renderAt(player, from, to); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM_TO", player, from, to); + } + + private void showInternal(Player player, BundleFilter bundleFilter, ViewFlag... flags) { + PlayerTraceShowData playerTraceShowData = new PlayerTraceShowData(bundleFilter, flags); + TraceManager.instance.show(player, playerTraceShowData); + } + + private void showInternal(Player player, int from, int to, BundleFilter bundleFilter, ViewFlag... flags) { + PlayerTraceShowData playerTraceShowData = new PlayerTraceShowData(bundleFilter, flags); + playerTraceShowData.addViewFlag(new AtFlag(from, to)); + TraceManager.instance.show(player, playerTraceShowData); + } + + @Register(value = "hide", description = "TRACE_COMMAND_HELP_HIDE") + public void hide(@Validator Player player) { + TraceManager.instance.hide(player); + BauSystem.MESSAGE.send("TRACE_MESSAGE_HIDE", player); + } + + @Register(value = "clear") + public void clear(@Validator Player player) { + TraceManager.instance.clear(Region.getRegion(player.getLocation())); + BauSystem.MESSAGE.send("TRACE_MESSAGE_CLEAR", player); + } + + @Register(value = "delete", description = "TRACE_COMMAND_HELP_DELETE") + public void delete(@Validator Player player, Trace trace) { + TraceManager.instance.remove(trace); + BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE", player); + } + + @Register(value = "isolate", description = "TRACE_COMMAND_HELP_ISOLATE") + public void isolate(@Validator Player player, Trace trace, @ErrorMessage("TRACE_RECORD_ID_INVALID") TNTPoint... records) { + TraceManager.instance.isolate(player, records); + BauSystem.MESSAGE.send("TRACE_MESSAGE_ISOLATE", player); + } + + @Register(value = "share", description = "TRACE_COMMAND_HELP_SHARE") + public void share(@Validator Player player) { + BauSystem.MESSAGE.broadcast("TRACE_MESSAGE_SHARE", "TRACE_MESSAGE_SHARE_HOVER", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/trace follow " + player.getName()), player.getName()); + } + + @Register(value = "follow", description = "TRACE_COMMAND_HELP_FOLLOW") + public void follow(@Validator Player player, Player toFollow) { + if (player == toFollow) { + BauSystem.MESSAGE.send("TRACE_MESSAGE_FOLLOW_SELF", player); + return; } - for (ShowModeParameterType showModeParameterType : showModeParameterTypes) { - 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); + TraceManager.instance.follow(player, toFollow); + BauSystem.MESSAGE.send("TRACE_MESSAGE_FOLLOW", player, toFollow.getName()); } - @Register(value = {"hide"}, description = "TRACE_COMMAND_HELP_HIDE") - public void hideCommand(@Validator Player p) { - TraceShowManager.hide(p); - BauSystem.MESSAGE.send("TRACE_MESSAGE_HIDE", p); + @Register(value = "unfollow", description = "TRACE_COMMAND_HELP_UNFOLLOW") + public void unfollow(@Validator Player player) { + TraceManager.instance.unfollow(player); + BauSystem.MESSAGE.send("TRACE_MESSAGE_UNFOLLOW", player); } - @Register(value = {"delete"}, description = "TRACE_COMMAND_HELP_DELETE") - @Register({"clear"}) - public void deleteCommand(@Validator Player p) { - Region region = Region.getRegion(p.getLocation()); - StoredRecords.clear(region); - BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE", p); - } - - @AllArgsConstructor - private enum ShowModeType { - ENTITY((player, showModeParameter) -> new EntityShowMode(player, showModeParameter, 16)), - RAW((player, showModeParameter) -> new EntityShowMode(player, showModeParameter, -1)); - - private BiFunction> showModeBiFunction; - } - - @ClassMapper(value = ShowModeParameterType.class, local = true) - public TypeMapper showModeParameterTypesTypeMapper() { - Map> showModeParameterTypeListMap = new EnumMap<>(ShowModeParameterType.class); - for (ShowModeParameterType value : ShowModeParameterType.values()) { - showModeParameterTypeListMap.put(value, value.getTabCompletes()); - } - - Map showModeParameterTypesMap = new HashMap<>(); - showModeParameterTypeListMap.forEach((k, v) -> v.forEach(s -> showModeParameterTypesMap.put(s, k))); - - return new TypeMapper() { + @ClassMapper(value = Trace.class, local = true) + public TypeMapper traceClassMapper() { + return new TypeMapper<>() { @Override - public ShowModeParameterType map(CommandSender commandSender, PreviousArguments previousArguments, String s) { - return showModeParameterTypesMap.get(s); + public Trace map(CommandSender commandSender, String[] previousArguments, String s) { + return TraceManager.instance.get(Integer.parseInt(s)).orElse(null); } @Override - public List tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) { - Set showModeParameterTypeSet = new HashSet<>(); - Arrays.stream(previousArguments.userArgs).map(showModeParameterTypesMap::get).forEach(showModeParameterTypeSet::add); - showModeParameterTypeSet.remove(null); + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + return TraceManager.instance.getAllIds().stream() + .map(Object::toString) + .collect(Collectors.toList()); + } + }; + } - Set removed = showModeParameterTypeSet.stream() - .map(ShowModeParameterType::getRemoved) - .map(Supplier::get) - .flatMap(Arrays::stream) - .collect(Collectors.toSet()); + @ClassMapper(value = TNTPoint.class, local = true) + public TypeMapper recordMapper() { + return new TypeMapper<>() { + @Override + public TNTPoint map(CommandSender commandSender, PreviousArguments previousArguments, String s) { + Trace trace = previousArguments.getFirst(Trace.class).orElse(null); + if (trace == null) return null; - List tabCompletes = new ArrayList<>(); - for (Map.Entry> entry : showModeParameterTypeListMap.entrySet()) { - if (removed.contains(entry.getKey()) || showModeParameterTypeSet.contains(entry.getKey())) { - continue; + int id = Integer.parseInt(s); + return trace.getRecords().stream() + .filter(record -> record.getTntId() == id) + .findFirst() + .orElse(null); + } + + // TODO change when new command framework update + @Override + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + Trace trace = previousArguments.getFirst(Trace.class).orElse(null); + if (trace == null) return null; + return trace.getUsedIds(); + } + }; + } + + @ClassMapper(value = BundleFilter.class, local = true) + public TypeMapper bundleFilterClassMapper() { + return new TypeMapper<>() { + @Override + public BundleFilter map(CommandSender commandSender, String[] previousArguments, String s) { + for (BundleFilter filter : BundleFilter.values()) { + if (s.equals(filter.toString())) { + return filter; } - tabCompletes.addAll(entry.getValue()); } - return tabCompletes; + return null; + } + + @Override + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + if (s.length() == 0) { + return new ArrayList<>(); + } + + return Arrays.stream(BundleFilter.values()) + .map(Enum::toString) + .collect(Collectors.toList()); + } + }; + } + + @ClassMapper(value = ViewFlag.class, local = true) + public TypeMapper viewFlagClassMapper() { + return new TypeMapper() { + @Override + public ViewFlag map(CommandSender commandSender, String[] previousArguments, String s) { + for (ViewFlag flag : ViewFlag.flags) { + if (s.equals("--" + flag.name)) { + return flag; + } + + for (String alias : flag.aliases) { + if (s.equals("-" + alias)) { + return flag; + } + } + } + return null; + } + + @Override + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + return ViewFlag.flags.stream() + .flatMap(viewFlag -> Stream.concat(Stream.of("--" + viewFlag.name), + Arrays.stream(viewFlag.aliases).map(name -> "-" + name))) + .collect(Collectors.toList()); } }; } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java new file mode 100644 index 00000000..d735fe8d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java @@ -0,0 +1,388 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer; + +import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; +import de.steamwar.bausystem.features.tracer.rendering.PlayerTraceShowData; +import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag; +import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.IsolateFlag; +import de.steamwar.bausystem.region.Region; +import de.steamwar.linkage.Linked; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; + +@Linked +public class TraceManager implements Listener { + + public static TraceManager instance; + + { + instance = this; + } + + public static File tracesFolder = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "traces"); + + public TraceManager() { + if (!tracesFolder.exists()) + tracesFolder.mkdir(); + + File[] traceFiles = tracesFolder.listFiles(); + if (traceFiles == null) + return; + + for (File traceFile : traceFiles) { + if (traceFile.getName().contains(".records")) + continue; + + add(new Trace(traceFile)); + } + } + + /** + * List of all current traces + */ + private final Map> tracesByRegion = new HashMap<>(); + + private final Map> showDataPerRegionPerPlayer = new HashMap<>(); + + private final Map> followerMap = new HashMap<>(); + + /** + * Utility variable to keep track of the next open trace id; + */ + private int nextOpenId = 0; + + /** + * Adds a new trace to the global record + * + * @param trace Trace to be added + * @return id of the created trace + */ + protected int add(Trace trace) { + showDataPerRegionPerPlayer.getOrDefault(trace.getRegion(), Collections.emptyMap()).forEach((player, playerTraceShowData) -> { + trace.render(player, playerTraceShowData); + followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> { + trace.render(follower, playerTraceShowData); + }); + }); + + tracesByRegion.computeIfAbsent(trace.getRegion(), region -> new HashMap<>()).put(nextOpenId, trace); + nextOpenId++; + return nextOpenId; + } + + /** + * Get the id of the given trace + * + * @param trace + */ + public int getId(Trace trace) { + for (Map.Entry entry : tracesByRegion.getOrDefault(trace.getRegion(), Collections.emptyMap()).entrySet()) { + if (entry.getValue() == trace) return entry.getKey(); + } + return -1; + } + + /** + * Renders only the given records to the specified trace + * + * @param trace + * @param recordsToAdd + */ + protected void showPartial(Trace trace, List recordsToAdd) { + showDataPerRegionPerPlayer.getOrDefault(trace.getRegion(), Collections.emptyMap()).forEach((player, playerTraceShowData) -> { + trace.render(recordsToAdd, player, playerTraceShowData); + followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> { + trace.render(recordsToAdd, follower, playerTraceShowData); + }); + }); + } + + protected Map getTraceShowDataPlayerMapping(Region region) { + return showDataPerRegionPerPlayer.getOrDefault(region, new HashMap<>()); + } + + /** + * Removes the trace with the given id + * + * @param trace the trace to be removed + */ + public boolean remove(Trace trace) { + Map traces = tracesByRegion.getOrDefault(trace.getRegion(), Collections.emptyMap()); + Integer traceId = traces.entrySet().stream() + .filter(entry -> entry.getValue() == trace) + .map(Map.Entry::getKey) + .findFirst() + .orElse(null); + if (traceId == null) return false; + traces.remove(traceId); + trace.hide(); + return true; + } + + /** + * Clears all traces + */ + public void clear(Region region) { + showDataPerRegionPerPlayer.getOrDefault(region, new HashMap<>()) + .keySet() + .forEach(player -> { + Set players = followerMap.getOrDefault(player, Collections.emptySet()); + tracesByRegion.get(region).values().forEach(trace -> { + trace.hide(player); + players.forEach(trace::hide); + }); + }); + tracesByRegion.getOrDefault(region, new HashMap<>()) + .forEach((i, trace) -> { + if (trace.getRegion() != region) return; + trace.getMetadataSaveFile().delete(); + trace.getRecordsSaveFile().delete(); + }); + tracesByRegion.getOrDefault(region, new HashMap<>()).clear(); + } + + /** + * Methode to get all traces in a certain region + * + * @param region Region to look for traces in + * @return All traces recorded in the given Region + */ + public Collection get(Region region) { + return tracesByRegion.getOrDefault(region, Collections.emptyMap()).values(); + } + + /** + * Methode to get the trace with specific id + * + * @param index index of the trace + * @return the trace with given id + */ + public Optional get(int index) { + for (Map.Entry> intermediate : tracesByRegion.entrySet()) { + if (intermediate.getValue().containsKey(index)) { + return Optional.ofNullable(intermediate.getValue().get(index)); + } + } + return Optional.empty(); + } + + /** + * Methode to get all traces + * + * @return internal list of all current traces + */ + public Collection getAll() { + return tracesByRegion.values().stream().map(Map::values).flatMap(Collection::stream).collect(Collectors.toList()); + } + + /** + * @return all ids of active traces + */ + public Set getAllIds() { + return tracesByRegion.values().stream().map(Map::keySet).flatMap(Collection::stream).collect(Collectors.toSet()); + } + + /** + * Shows traces for the player of the current Region + * + * @param player + * @param playerTraceShowData + */ + public void show(Player player, PlayerTraceShowData playerTraceShowData) { + unfollow(player); + + Region region = Region.getRegion(player.getLocation()); + showDataPerRegionPerPlayer.computeIfAbsent(region, ignored -> new HashMap<>()).put(player, playerTraceShowData); + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.render(player, playerTraceShowData); + followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> { + trace.render(follower, playerTraceShowData); + }); + }); + } + + /** + * Hides traces for the player of the current Region + * + * @param player + */ + public void hide(Player player) { + unfollow(player); + + Region region = Region.getRegion(player.getLocation()); + PlayerTraceShowData previous = showDataPerRegionPerPlayer.getOrDefault(region, Collections.emptyMap()).remove(player); + if (previous == null) return; + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.hide(player); + followerMap.getOrDefault(player, Collections.emptySet()).forEach(trace::hide); + }); + } + + /** + * Makes the given player + * + * @param follower + * @param following + * @return + */ + public boolean follow(Player follower, Player following) { + if (followerMap.containsKey(follower)) return false; + if (followerMap.entrySet().stream().anyMatch(playerSetEntry -> playerSetEntry.getValue().contains(follower))) { + unfollow(follower); + } + + followerMap.computeIfAbsent(following, ignored -> new HashSet<>()).add(follower); + + showDataPerRegionPerPlayer.forEach((region, playerPlayerTraceShowDataMap) -> { + if (playerPlayerTraceShowDataMap.containsKey(follower)) { + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> trace.hide(follower)); + } + + PlayerTraceShowData playerTraceShowData = playerPlayerTraceShowDataMap.get(following); + if (playerTraceShowData == null) return; + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.render(follower, playerTraceShowData); + }); + }); + return true; + } + + public void unfollow(Player follower) { + if (followerMap.containsKey(follower)) return; + List toRemove = new ArrayList<>(); + Set toHide = new HashSet<>(); + followerMap.forEach((player, players) -> { + if (players.remove(follower)) toHide.add(follower); + if (players.isEmpty()) toRemove.add(player); + }); + toRemove.forEach(followerMap::remove); + + showDataPerRegionPerPlayer.forEach((region, playerPlayerTraceShowDataMap) -> { + toHide.forEach(player -> { + if (!playerPlayerTraceShowDataMap.containsKey(player)) return; + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.hide(follower); + }); + }); + + PlayerTraceShowData playerTraceShowData = playerPlayerTraceShowDataMap.get(follower); + if (playerTraceShowData == null) return; + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.render(follower, playerTraceShowData); + }); + }); + } + + /** + * Modifies the render for the given player, to only show tnts at the given time + * interval + * + * @param player + * @param from start of time interval + * @param to end of time interval + */ + public void renderAt(Player player, int from, int to) { + unfollow(player); + + Region region = Region.getRegion(player.getLocation()); + PlayerTraceShowData playerTraceShowData = showDataPerRegionPerPlayer + .computeIfAbsent(region, ignored -> new HashMap<>()) + .computeIfAbsent(player, ignored -> new PlayerTraceShowData(BundleFilter.DEFAULT)); + + AtFlag atFlag = playerTraceShowData.getViewFlag(AtFlag.class); + if (atFlag == null) { + atFlag = new AtFlag(from, to); + playerTraceShowData.addViewFlag(atFlag); + } else { + atFlag.update(from, to); + } + + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.render(player, playerTraceShowData); + followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> { + trace.render(follower, playerTraceShowData); + }); + }); + } + + /** + * Toggles the isolated render for the given records and player + * + * @param player the player the trace is shown to + * @param records the record for which isolation is toggled + */ + public void isolate(Player player, TNTPoint... records) { + unfollow(player); + + Region region = Region.getRegion(player.getLocation()); + PlayerTraceShowData playerTraceShowData = showDataPerRegionPerPlayer + .computeIfAbsent(region, ignored -> new HashMap<>()) + .computeIfAbsent(player, ignored -> new PlayerTraceShowData(BundleFilter.DEFAULT)); + + IsolateFlag isolateFlag; + if (playerTraceShowData.hasViewFlagOnly(IsolateFlag.class)) { + isolateFlag = playerTraceShowData.getViewFlag(IsolateFlag.class); + } else if (playerTraceShowData.hasNoViewFlags()) { + isolateFlag = new IsolateFlag(); + playerTraceShowData.addViewFlag(isolateFlag); + } else { + playerTraceShowData = new PlayerTraceShowData(BundleFilter.DEFAULT); + isolateFlag = new IsolateFlag(); + playerTraceShowData.addViewFlag(isolateFlag); + showDataPerRegionPerPlayer.get(region).put(player, playerTraceShowData); + } + + for (TNTPoint record : records) { + isolateFlag.toggleId(record.getTntId()); + } + + PlayerTraceShowData finalPlayerTraceShowData = playerTraceShowData; + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.render(player, finalPlayerTraceShowData); + followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> { + trace.render(follower, finalPlayerTraceShowData); + }); + }); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + unfollow(event.getPlayer()); + new ArrayList<>(followerMap.getOrDefault(event.getPlayer(), Collections.emptySet())).forEach(this::unfollow); + + showDataPerRegionPerPlayer.forEach((region, playerPlayerTraceShowDataMap) -> { + playerPlayerTraceShowDataMap.remove(event.getPlayer()); + }); + + tracesByRegion.forEach((region, integerTraceMap) -> { + integerTraceMap.forEach((integer, trace) -> { + trace.hide(event.getPlayer()); + }); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java new file mode 100644 index 00000000..52b87156 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java @@ -0,0 +1,239 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.tpslimit.TPSUtils; +import de.steamwar.bausystem.region.Region; +import de.steamwar.linkage.Linked; +import org.bukkit.block.Block; +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.event.entity.EntitySpawnEvent; + +import java.util.*; + +@Linked +public class TraceRecorder implements Listener { + + public static TraceRecorder instance; + + { + instance = this; + } + + /** + * Map for all traces being actively recorded + */ + private final Map activeTraces = new HashMap<>(); + + /** + * Map for all TNTs being traced, by region + */ + private final Map> trackedTNT = new HashMap<>(); + + /** + * Map from TNT to Region the TNT spawned in + */ + private final Map tntSpawnRegion = new HashMap<>(); + + /** + * Maps a tracked tnt entity to its entire recording history + */ + private final Map> historyMap = new HashMap<>(); + + /** + * Regions where auto-trace is enabled + */ + private final Set autoTraceRegions = new HashSet<>(); + + public TraceRecorder() { + BauSystem.runTaskTimer(BauSystem.getInstance(), () -> { + record(); + checkForAutoTraceFinish(); + }, 0, 1); + } + + /** + * Toggles auto trace for the given region + * + * @param region + */ + public boolean toggleAutoTrace(Region region) { + if (!autoTraceRegions.remove(region)) { + autoTraceRegions.add(region); + return true; + } else { + return false; + } + } + + /** + * Makes checks for whether auto traces finished + */ + public void checkForAutoTraceFinish() { + for (Region region : autoTraceRegions) { + if (autoTraceRegions.contains(region) && trackedTNT.getOrDefault(region, Collections.emptyList()).size() == 0) { + stopRecording(region); + } + } + } + + /** + * Starts a recording at the given region + * + * @param region region to be recorded + */ + public int startRecording(Region region) { + if (activeTraces.containsKey(region)) { + return -1; + } + + TraceRecordingWrapper wrappedTrace = new TraceRecordingWrapper(region); + activeTraces.put(region, wrappedTrace); + return TraceManager.instance.add(wrappedTrace.getTrace()); + } + + /** + * Stops the recording at the given region + * + * @param region region to stop recording + */ + public void stopRecording(Region region) { + TraceRecordingWrapper wrappedTrace = activeTraces.getOrDefault(region, null); + if (wrappedTrace == null) return; + + wrappedTrace.finalizeRecording(); + + activeTraces.remove(region); + for (TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) { + historyMap.remove(tnt); + } + trackedTNT.put(region, new ArrayList<>()); + } + + /** + * Internal methode to record all tracked TNT Entities + */ + private void record() { + for (Region region : activeTraces.keySet()) { + TraceRecordingWrapper wrappedTrace = activeTraces.get(region); + for (TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) { + TNTPoint record = record(tnt, wrappedTrace, Collections.emptyList()); + wrappedTrace.addRecord(record); + } + wrappedTrace.commitRecorded(); + } + } + + /** + * Internal methode to record exploded tnt + * + * @param tntPrimed tnt exploding + * @param wrappedTrace the trace to record the tnt for wrapped with metadata + * @param destroyedBlocks the blocks destoryed by the passed tnt + * @return the record creaded of the passed tnt + */ + private TNTPoint record(TNTPrimed tntPrimed, TraceRecordingWrapper wrappedTrace, List destroyedBlocks) { + List history = historyMap.getOrDefault(tntPrimed, new ArrayList<>()); + int tntID; + + if (history.size() == 0) { + historyMap.put(tntPrimed, history); + tntID = wrappedTrace.getNextOpenRecordIdAndIncrement(); + } else { + tntID = history.get(0).getTntId(); + } + + boolean isExplosion = tntPrimed.getFuseTicks() == 0; + if (isExplosion) { + wrappedTrace.activateExplosionRecorded(); + } + boolean afterFirstExplosion = wrappedTrace.isExplosionRecorded(); + + TNTPoint record = new TNTPoint(tntID, tntPrimed, isExplosion, afterFirstExplosion, TPSUtils.currentTick.get() - wrappedTrace.getStartTick(), history, destroyedBlocks); + history.add(record); + + return record; + } + + public boolean isAutoTraceEnabledInRegion(Region region) { + return autoTraceRegions.contains(region); + } + + public boolean isTraceActiveInRegion(Region region) { + return activeTraces.containsKey(region); + } + + public long getStartTimeOfTraceInRegion(Region region) { + TraceRecordingWrapper wrapper = activeTraces.get(region); + if (wrapper == null) return 0; + return wrapper.getStartTick(); + } + + /** + * Event for TNTs beeing spawn. + * Registers newly spawned TNT to be traced if reqired + * + * @param event + */ + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onTNTSpawn(EntitySpawnEvent event) { + if (!(event.getEntity() instanceof TNTPrimed)) return; + + Region region = Region.getRegion(event.getLocation()); + + if (autoTraceRegions.contains(region) && !activeTraces.containsKey(region)) { + startRecording(region); + } + + if (activeTraces.containsKey(region)) { + // Check whether set for tracking already exists. Creating it if necessary + if (!trackedTNT.containsKey(region)) { + trackedTNT.put(region, new ArrayList<>()); + } + + trackedTNT.get(region).add((TNTPrimed) event.getEntity()); + tntSpawnRegion.put((TNTPrimed) event.getEntity(), region); + activeTraces.get(region).addRecord(record((TNTPrimed) event.getEntity(), activeTraces.get(region), Collections.emptyList())); + } + } + + /** + * Event for TNTs exploding + * Unregisters TNTs from beeing traced on explode + * + * @param event + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onTNTExplode(EntityExplodeEvent event) { + if (!(event.getEntity() instanceof TNTPrimed)) return; + + Region region = tntSpawnRegion.getOrDefault((TNTPrimed) event.getEntity(), null); + if (region == null) return; + trackedTNT.get(region).remove((TNTPrimed) event.getEntity()); + tntSpawnRegion.remove((TNTPrimed) event.getEntity()); + + activeTraces.get(region).addRecord(record((TNTPrimed) event.getEntity(), activeTraces.get(region), event.blockList())); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecordingWrapper.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecordingWrapper.java new file mode 100644 index 00000000..783cec84 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecordingWrapper.java @@ -0,0 +1,98 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer; + +import de.steamwar.bausystem.features.tpslimit.TPSUtils; +import de.steamwar.bausystem.region.Region; +import lombok.Getter; +import lombok.SneakyThrows; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.GZIPOutputStream; + +public class TraceRecordingWrapper { + + @Getter + private final long startTick; + private final List recordsToAdd; + private final List recordList; + private final ObjectOutputStream recordsOutputStream; + private int nextOpenRecordId = 0; + @Getter + private boolean explosionRecorded = false; + + @Getter + private final Trace trace; + + @SneakyThrows + public TraceRecordingWrapper(Region region) { + startTick = TPSUtils.currentRealTick.get(); + recordsToAdd = new ArrayList<>(); + recordList = new ArrayList<>(); + + trace = new Trace(region, recordList); + TraceManager.instance.add(trace); + File recordsSaveFile = new File(TraceManager.tracesFolder, trace.getUuid() + ".records"); + recordsOutputStream = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(recordsSaveFile))); + } + + public int getNextOpenRecordIdAndIncrement() { + return nextOpenRecordId++; + } + + public void activateExplosionRecorded() { + explosionRecorded = true; + } + + public void addRecord(TNTPoint record) { + recordsToAdd.add(record); + } + + public void commitRecorded() { + TraceManager.instance.showPartial(trace, recordsToAdd); + + recordsToAdd.forEach(record -> { + try { + recordsOutputStream.writeObject(record); + recordsOutputStream.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + recordList.addAll(recordsToAdd); + recordsToAdd.clear(); + } + + @SneakyThrows + protected void finalizeRecording() { + recordsOutputStream.flush(); + recordsOutputStream.close(); + + if (trace.getRecords().isEmpty()) { + TraceManager.instance.remove(trace); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceScoreboardElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceScoreboardElement.java index 87ae3876..f7b20f8c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceScoreboardElement.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceScoreboardElement.java @@ -1,34 +1,33 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2023 SteamWar.de-Serverteam + * Copyright (C) 2024 SteamWar.de-Serverteam * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.bausystem.features.tracer; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.tracer.record.Recorder; -import de.steamwar.bausystem.features.tracer.show.Record; -import de.steamwar.bausystem.features.tracer.show.StoredRecords; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.features.tpslimit.TPSUtils; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.utils.ScoreboardElement; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; -import java.util.List; +import java.util.Collection; @Linked public class TraceScoreboardElement implements ScoreboardElement { @@ -45,17 +44,18 @@ public class TraceScoreboardElement implements ScoreboardElement { @Override public String get(Region region, Player p) { - String traceScore = Recorder.INSTANCE.get(region).scoreboard(p); - if (traceScore != null) { - return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TRACE", p) + "§8: " + traceScore; + if (!Permission.BUILD.hasPermission(p)) return null; + if (TraceRecorder.instance.isTraceActiveInRegion(region)) { + return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TRACE", p) + "§8: " + BauSystem.MESSAGE.parse("TRACE_RECORD", p) + " §8| §e" + (TPSUtils.currentRealTick.get() - TraceRecorder.instance.getStartTimeOfTraceInRegion(region)) + " §7" + BauSystem.MESSAGE.parse("SCOREBOARD_TRACE_TICKS", p); + } else if (TraceRecorder.instance.isAutoTraceEnabledInRegion(region)) { + return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TRACE", p) + "§8: " + BauSystem.MESSAGE.parse("TRACE_IDLE_AUTO", p); } - List records = StoredRecords.getRecords(region); - if (records.isEmpty()) { + + Collection traces = TraceManager.instance.get(region); + if (traces.isEmpty()) { return null; + } else { + return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TRACE", p) + "§8: " + BauSystem.MESSAGE.parse("TRACE_HAS_TRACES", p); } - if (records.stream().allMatch(record -> record.getTnt().isEmpty())) { - return null; - } - return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TRACE", p) + "§8: " + BauSystem.MESSAGE.parse("TRACE_HAS_TRACES", p); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TracerBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TracerBauGuiItem.java deleted file mode 100644 index 5df2ce7b..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TracerBauGuiItem.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.Permission; -import de.steamwar.bausystem.SWUtils; -import de.steamwar.bausystem.features.tracer.record.*; -import de.steamwar.bausystem.linkage.specific.BauGuiItem; -import de.steamwar.bausystem.region.Region; -import de.steamwar.inventory.SWInventory; -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; -import java.util.Collections; - -@Linked -public class TracerBauGuiItem extends BauGuiItem { - - public TracerBauGuiItem() { - super(21); - } - - @Override - public ItemStack getItem(Player player) { - Region region = Region.getRegion(player.getLocation()); - return SWUtils.setCustomModelData(new SWItem(Material.OBSERVER, BauSystem.MESSAGE.parse("TRACE_GUI_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("TRACE_GUI_ITEM_LORE", player, Recorder.INSTANCE.get(region).scoreboard(player))), false, clickType -> { - }), 1).getItemStack(); - } - - private static void open(Player p) { - Region region = Region.getRegion(p.getLocation()); - TraceRecorder traceRecorder = Recorder.INSTANCE.get(region); - SWInventory inv = new SWInventory(p, 9, BauSystem.MESSAGE.parse("TRACE_GUI_NAME", p)); - if (traceRecorder instanceof ActiveTracer) { - if (traceRecorder instanceof AutoTraceRecorder) { - inv.setItem(1, new SWItem(Material.GRAY_DYE, BauSystem.MESSAGE.parse("TRACE_GUI_TRACE_ACTIVE_AUTO", p))); - } else { - inv.setItem(1, new SWItem(Material.GREEN_DYE, BauSystem.MESSAGE.parse("TRACE_GUI_TRACE_ACTIVE", p), clickType -> { - p.performCommand("trace stop"); - open(p); - })); - } - } else { - inv.setItem(1, new SWItem(Material.RED_DYE, BauSystem.MESSAGE.parse("TRACE_GUI_TRACE_INACTIVE", p), clickType -> { - p.performCommand("trace start"); - open(p); - })); - } - if (traceRecorder instanceof AutoTraceRecorder) { - inv.setItem(3, new SWItem(Material.ENDER_EYE, BauSystem.MESSAGE.parse("TRACE_GUI_AUTO_TRACE_ACTIVE", p), clickType -> { - p.performCommand("trace auto"); - open(p); - })); - } else { - inv.setItem(3, new SWItem(Material.FIREWORK_STAR, BauSystem.MESSAGE.parse("TRACE_GUI_AUTO_TRACE_INACTIVE", p), clickType -> { - p.performCommand("trace auto"); - open(p); - })); - } - inv.setItem(7, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("TRACE_GUI_DELETE", p), clickType -> { - p.performCommand("trace delete"); - open(p); - })); - - inv.open(); - } - - @Override - public boolean click(ClickType click, Player p) { - open(p); - return false; - } - - @Override - public Permission permission() { - return Permission.BUILD; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/ActiveTracer.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/ActiveTracer.java deleted file mode 100644 index b0dfeeed..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/ActiveTracer.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -public interface ActiveTracer { -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoExplodeTraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoExplodeTraceRecorder.java deleted file mode 100644 index 6ff44728..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoExplodeTraceRecorder.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -public class AutoExplodeTraceRecorder extends AutoTraceRecorder { - - @Override - protected String getInactivityMessage() { - return "TRACE_IDLE_AUTO_EXPLODE"; - } - - @Override - protected boolean shouldStartRecording(StartType startType) { - return startType == StartType.EXPLODE; - } - - @Override - protected String getScriptState() { - return "IDLE_AUTO_EXPLODE"; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoIgniteTraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoIgniteTraceRecorder.java deleted file mode 100644 index 932634bb..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoIgniteTraceRecorder.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -public class AutoIgniteTraceRecorder extends AutoTraceRecorder implements ActiveTracer { - - @Override - protected String getInactivityMessage() { - return "TRACE_IDLE_AUTO_IGNITE"; - } - - @Override - protected boolean shouldStartRecording(StartType startType) { - return startType == StartType.IGNITE; - } - - @Override - protected String getScriptState() { - return "IDLE_AUTO_IGNITE"; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoTraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoTraceRecorder.java deleted file mode 100644 index ab326abc..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/AutoTraceRecorder.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.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; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Supplier; - -public abstract class AutoTraceRecorder implements TraceRecorder { - - protected boolean recording = false; - private long startTime = TPSUtils.currentRealTick.get(); - private long lastExplosion = 0; - - private final Map recordMap = new HashMap<>(); - private Record record; - - private Region region; - private Supplier recordSupplier; - - @Setter - @Getter - private TraceRecordAutoDeletion traceRecordAutoDeletion = TraceRecordAutoDeletion.NEVER; - private Record lastRecord; - - private Record.TNTRecord getRecord(TNTPrimed tntPrimed) { - return recordMap.computeIfAbsent(tntPrimed, __ -> record.spawn()); - } - - protected abstract String getInactivityMessage(); - protected abstract boolean shouldStartRecording(StartType startType); - protected void stoppedRecording() { - } - - @Override - public final String scoreboard(Player player) { - if (recording) { - return BauSystem.MESSAGE.parse("TRACE_RECORD", player) + " §8| §e" + (TPSUtils.currentRealTick.get() - startTime) + " §7" + BauSystem.MESSAGE.parse("SCOREBOARD_TRACE_TICKS", player); - } else { - return BauSystem.MESSAGE.parse(getInactivityMessage(), player); - } - } - - 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(); - recording = true; - } - - @Override - public void init(Region region, Supplier recordSupplier) { - this.region = region; - this.recordSupplier = recordSupplier; - } - - @Override - public void postClear() { - recordMap.clear(); - record = recordSupplier.get(); - } - - @Override - public final void spawn(TNTPrimed tntPrimed) { - if (!recording && shouldStartRecording(StartType.IGNITE)) { - startRecording(); - } - if (recording) { - getRecord(tntPrimed).source(tntPrimed); - } - } - - @Override - public final void tick(TNTPrimed tntPrimed) { - if (recording) { - getRecord(tntPrimed).location(tntPrimed); - } - } - - @Override - 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; - } - - @Override - public final void tick() { - lastExplosion++; - if (recording && lastExplosion > 80) { - recording = false; - recordMap.clear(); - lastRecord = record; - record = null; - stoppedRecording(); - } - } - - protected enum StartType { - IGNITE, - EXPLODE - } - - protected abstract String getScriptState(); - - @Override - public String scriptState() { - return recording ? "RECORDING" : getScriptState(); - } - - @Override - public long scriptTime() { - return TPSUtils.currentRealTick.get() - startTime; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java deleted file mode 100644 index 1a310d35..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.tracer.show.Record; -import de.steamwar.bausystem.features.tracer.show.StoredRecords; -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.entity.Entity; -import org.bukkit.entity.Player; -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.event.entity.EntitySpawnEvent; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -@Linked -public class Recorder implements Listener { - - public static Recorder INSTANCE; - - { - INSTANCE = this; - } - - private static class DisabledTracerRecorder implements TraceRecorder { - @Override - public String scoreboard(Player player) { - return null; - } - - @Override - public void spawn(TNTPrimed tntPrimed) { - } - - @Override - public void tick(TNTPrimed tntPrimed) { - } - - @Override - public void explode(TNTPrimed tntPrimed, boolean inBuildArea, boolean inTestblockRegion) { - } - - @Override - public String scriptState() { - return "IDLE"; - } - - @Override - public long scriptTime() { - return 0; - } - } - private static final DisabledTracerRecorder DISABLED = new DisabledTracerRecorder(); - - private Map regionTraceRecorderMap = new HashMap<>(); - private Map tntTraceRecorderMap = new HashMap<>(); - - private TraceRecorder get(TNTPrimed tntPrimed) { - return get(tntTraceRecorderMap.computeIfAbsent(tntPrimed, e -> Region.getRegion(e.getLocation()))); - } - - public boolean isDisabled(Region region) { - return !regionTraceRecorderMap.containsKey(region); - } - - public TraceRecorder get(Region region) { - return regionTraceRecorderMap.getOrDefault(region, DISABLED); - } - - public void set(Region region, TraceRecorder traceRecorder) { - regionTraceRecorderMap.put(region, traceRecorder); - traceRecorder.init(region, () -> { - Record record = new Record(region); - StoredRecords.add(region, record); - return record; - }); - tntTraceRecorderMap.forEach((tntPrimed, rg) -> { - if (rg == region) { - traceRecorder.spawn(tntPrimed); - } - }); - } - - public void remove(Region region) { - regionTraceRecorderMap.remove(region); - } - - public void postClear(Region region) { - get(region).postClear(); - } - - @EventHandler - public void onEntitySpawn(EntitySpawnEvent event) { - Entity entity = event.getEntity(); - if (!(entity instanceof TNTPrimed)) { - return; - } - get((TNTPrimed) entity).spawn((TNTPrimed) entity); - } - - { - BauSystem.runTaskTimer(BauSystem.getInstance(), () -> { - tick(); - tntTraceRecorderMap.keySet() - .stream() - .filter(e -> !e.isValid()) - .collect(Collectors.toList()) - .forEach(tntTraceRecorderMap::remove); - new ArrayList<>(regionTraceRecorderMap.values()).forEach(TraceRecorder::tick); - }, 1, 1); - } - - private void tick() { - TNTPrimedIterator.impl.iterator().forEach(tntPrimed -> { - get(tntPrimed).tick(tntPrimed); - }); - } - - @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) - public void onEntityExplode(EntityExplodeEvent event) { - Entity entity = event.getEntity(); - if (!(entity instanceof TNTPrimed)) { - return; - } - 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)); - boolean inTestblockRegion = event.blockList().stream().anyMatch(block -> region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)); - traceRecorder.explode((TNTPrimed) entity, inBuildRegion, inTestblockRegion); - tntTraceRecorderMap.remove(entity); - tick(); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SimpleTraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SimpleTraceRecorder.java deleted file mode 100644 index 875d25b5..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SimpleTraceRecorder.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.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; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Supplier; - -public class SimpleTraceRecorder implements TraceRecorder, ActiveTracer { - - private final long startTime = TPSUtils.currentRealTick.get(); - private final Map recordMap = new HashMap<>(); - private Record record; - - @Override - public String scoreboard(Player player) { - return BauSystem.MESSAGE.parse("TRACE_RECORD", player) + " §8| §e" + (TPSUtils.currentRealTick.get() - startTime) + " §7" + BauSystem.MESSAGE.parse("SCOREBOARD_TRACE_TICKS", player); - } - - @Override - public void init(Region region, Supplier recordSupplier) { - record = recordSupplier.get(); - } - - @Override - public void postClear() { - recordMap.clear(); - } - - private Record.TNTRecord getRecord(TNTPrimed tntPrimed) { - return recordMap.computeIfAbsent(tntPrimed, __ -> record.spawn()); - } - - @Override - public void spawn(TNTPrimed tntPrimed) { - getRecord(tntPrimed).source(tntPrimed); - } - - @Override - public void tick(TNTPrimed tntPrimed) { - getRecord(tntPrimed).location(tntPrimed); - } - - @Override - 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); - } - - @Override - public String scriptState() { - return "RECORD"; - } - - @Override - public long scriptTime() { - return TPSUtils.currentRealTick.get() - startTime; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SingleTraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SingleTraceRecorder.java deleted file mode 100644 index 046f0368..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/SingleTraceRecorder.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -import de.steamwar.bausystem.region.Region; - -public class SingleTraceRecorder extends AutoTraceRecorder { - - private Region region; - - public SingleTraceRecorder(Region region) { - this.region = region; - } - - @Override - protected String getInactivityMessage() { - return "TRACE_IDLE_SINGLE"; - } - - @Override - protected boolean shouldStartRecording(StartType startType) { - return startType == StartType.IGNITE; - } - - @Override - protected void stoppedRecording() { - Recorder.INSTANCE.remove(region); - } - - @Override - protected String getScriptState() { - return "IDLE_SINGLE"; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator.java deleted file mode 100644 index a6f05b5e..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TNTPrimedIterator.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.core.VersionDependent; -import org.bukkit.entity.TNTPrimed; - -import java.util.stream.Stream; - -public interface TNTPrimedIterator { - TNTPrimedIterator impl = VersionDependent.getVersionImpl(BauSystem.getInstance()); - - Stream iterator(); -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecordAutoDeletion.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecordAutoDeletion.java deleted file mode 100644 index a99eff0e..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecordAutoDeletion.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2023 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.record; - -import de.steamwar.bausystem.features.tracer.show.Record; - -public enum TraceRecordAutoDeletion { - - ALWAYS { - @Override - public boolean test(Record record) { - return true; - } - }, - NEVER { - @Override - public boolean test(Record record) { - return false; - } - }, - NO_BUILD_DESTROY { - @Override - public boolean test(Record record) { - return record.getTnt().stream().noneMatch(Record.TNTRecord::isInBuildArea); - } - }, - BUILD_DESTROY { - @Override - public boolean test(Record record) { - return record.getTnt().stream().anyMatch(Record.TNTRecord::isInBuildArea); - } - }, - NO_TESTBLOCK_DESTROY { - @Override - public boolean test(Record record) { - return record.getTnt().stream().noneMatch(Record.TNTRecord::isInTestblockArea); - } - }, - TESTBLOCK_DESTROY { - @Override - public boolean test(Record record) { - return record.getTnt().stream().anyMatch(Record.TNTRecord::isInTestblockArea); - } - }, - ; - - public abstract boolean test(Record record); -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecorder.java deleted file mode 100644 index c667f4e0..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceRecorder.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.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; - -import java.util.function.Supplier; - -public interface TraceRecorder { - - String scoreboard(Player player); - default void init(Region region, Supplier recordSupplier) { - } - default void postClear() { - } - void spawn(TNTPrimed tntPrimed); - void tick(TNTPrimed tntPrimed); - void explode(TNTPrimed tntPrimed, boolean inBuildRegion, boolean inTestblockRegion); - default void tick() { - } - - String scriptState(); - long scriptTime(); -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/BundleFilter.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/BundleFilter.java new file mode 100644 index 00000000..9380b3f8 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/BundleFilter.java @@ -0,0 +1,69 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer.rendering; + +import de.steamwar.bausystem.features.tracer.TNTPoint; +import lombok.RequiredArgsConstructor; + +import java.util.function.BiFunction; + +/** + * A Comparator for determining whether two records should be bundled + */ +@RequiredArgsConstructor +public enum BundleFilter { + + LOOSE((TNTPoint a, TNTPoint b) -> { + if (a.isExplosion() != b.isExplosion()) return false; + if (a.getLocation().distanceSquared(b.getLocation()) > BundleFilter.pixelSizeSquared * 8) return false; + if (a.getVelocity().distanceSquared(b.getVelocity()) > BundleFilter.pixelSizeSquared * 8) return false; + return true; + }), + + DEFAULT((TNTPoint a, TNTPoint b) -> { + if (a.isExplosion() != b.isExplosion()) return false; + if (a.getTicksSinceStart() != b.getTicksSinceStart()) return null; + if (a.getLocation().distanceSquared(b.getLocation()) > BundleFilter.pixelSizeSquared) return false; + if (a.getVelocity().distanceSquared(b.getVelocity()) > BundleFilter.pixelSizeSquared) return false; + return true; + }), + + RAW((TNTPoint a, TNTPoint b) -> { + if (a.isExplosion() != b.isExplosion()) return false; + if (!a.getLocation().equals(b.getLocation())) return false; + if (!a.getVelocity().equals(b.getVelocity())) return false; + if (a.getTicksSinceStart() != b.getTicksSinceStart()) return null; + return true; + }), + + NONE((TNTPoint a, TNTPoint b) -> { + return null; + }); + + /** + * {@code null}: Bundling can be stopped from this point forward + * {@code false}: No bundling allowed + * {@code true}: Bundling should be applied + */ + public final BiFunction function; + + private static final double pixelSize = 0.0625; + private static final double pixelSizeSquared = pixelSize * pixelSize; +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/PlayerTraceShowData.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/PlayerTraceShowData.java new file mode 100644 index 00000000..4029f2e2 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/PlayerTraceShowData.java @@ -0,0 +1,98 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer.rendering; + +import lombok.Getter; +import lombok.Setter; + +import java.util.*; + +/** + * A holder for the view data of a player trace render + */ +public class PlayerTraceShowData { + + /** + * The bundle filter applied by this class + */ + @Getter + @Setter + private BundleFilter bundleFilter; + + /** + * A map for stating whether a flag is contained in this holder or not + */ + private final Map, ViewFlag> viewFlags = new HashMap<>(); + + public PlayerTraceShowData(BundleFilter bundleFilter, ViewFlag... viewFlags) { + this.bundleFilter = bundleFilter; + for (ViewFlag viewFlag : viewFlags) { + this.viewFlags.put(viewFlag.getClass(), viewFlag); + } + } + + /** + * A methode that returns the flags that should be used by renders according + * to this holder. Especially handles inverse and required flags + * + * @return the flags that should be used in a render according to this holder + */ + public Set getEffectiveViewFlags() { + // Manage flags and required flags + Set flagList = new HashSet<>(); + for (ViewFlag flag : viewFlags.values()) { + flagList.add(flag); + if (flag.required != null) { + flagList.addAll(Arrays.asList(flag.required)); + } + } + + // Manage inverse flags + ViewFlag.inverseFlags.forEach(viewFlag -> { + if (!flagList.remove(viewFlag)) { + flagList.add(viewFlag); + } + }); + + return flagList; + } + + public boolean hasNoViewFlags() { + return viewFlags.isEmpty(); + } + + public boolean hasViewFlag(Class clazz) { + return viewFlags.containsKey(clazz); + } + + public boolean hasViewFlagOnly(Class clazz) { + return viewFlags.containsKey(clazz) && viewFlags.size() == 1; + } + + // TODO ? + @SuppressWarnings("unchecked") + public T getViewFlag(Class clazz) { + return (T) viewFlags.get(clazz); + } + + public void addViewFlag(ViewFlag viewFlag) { + viewFlags.put(viewFlag.getClass(), viewFlag); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java new file mode 100644 index 00000000..dc056a2e --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java @@ -0,0 +1,95 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer.rendering; + +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.bausystem.features.tracer.Trace; +import de.steamwar.bausystem.features.tracer.TraceManager; +import de.steamwar.core.Core; +import de.steamwar.entity.REntity; +import de.steamwar.entity.REntityServer; +import de.steamwar.techhider.BlockIds; +import lombok.Getter; +import net.md_5.bungee.api.chat.ClickEvent; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Wrapper for the rendering of a record bundle + */ +public class TraceEntity extends REntity { + + private static final Reflection.MethodInvoker addEntityMethod = Reflection.getMethod(REntityServer.class, "addEntity", REntity.class); + + /** + * The records represented by this REntity + */ + @Getter + private final List records; + + /** + * A string of all unique tnt records + */ + private final String uniqueTntIdsString; + + private final Trace trace; + + public TraceEntity(REntityServer server, Location location, boolean isExplosion, List records, Trace trace) { + super(server, EntityType.FALLING_BLOCK, location, BlockIds.impl.materialToId(isExplosion ? Material.RED_STAINED_GLASS : Material.TNT) >> (Core.getVersion() <= 12 ? 4 : 0)); + setNoGravity(true); + this.records = records; + uniqueTntIdsString = records.stream().map(TNTPoint::getTntId).distinct().map(Object::toString).collect(Collectors.joining(" ")); + this.trace = trace; + addEntityMethod.invoke(server, this); + } + + /** + * Message for printing the data contained in this wrapper into player chat + * + * @param player the player the message should be printed for + */ + public void printIntoChat(Player player) { + TNTPoint representative = records.get(0); + + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", player); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_FUSE_TIME", player, representative.getFuse()); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_X", player, representative.getLocation().getX() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", player, representative.getLocation().getY() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", player, representative.getLocation().getZ() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", player, representative.getVelocity().getX() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", player, representative.getVelocity().getY() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", player, representative.getVelocity().getZ() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_ISOLATE", player, BauSystem.MESSAGE.parse("TRACE_MESSAGE_CLICK_ISOLATE", player), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/trace isolate " + TraceManager.instance.getId(trace) + " " + uniqueTntIdsString)); + } + + @Override + public boolean equals(Object object) { + if (!(object instanceof TraceEntity)) return false; + TraceEntity entity = (TraceEntity) object; + return records.get(0).equals(entity.getRecords().get(0)); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java new file mode 100644 index 00000000..83ad005d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java @@ -0,0 +1,247 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer.rendering; + +import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.entity.REntityServer; +import de.steamwar.entity.RFallingBlockEntity; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * A settable flag that changes how a trace is rendered + */ +public abstract class ViewFlag { + /** + * Static registry of static flags + */ + public static final List flags = new ArrayList<>(); + + /** + * Inverse flags are used by trace render by default, as long as they are not explicitly added as argument + */ + public static final List inverseFlags = new ArrayList<>(); + + public static ViewFlag EXPLOSION = new ViewFlag(true, false, "explosion", "e") { + @Override + public Stream filter(Stream records) { + return records.filter(TNTPoint::isExplosion); + } + }; + + public static ViewFlag IGNITE = new ViewFlag(true, true, "ignite", "i") { + @Override + public Stream filter(Stream records) { + return records.filter(record -> record.isAfterFirstExplosion()); + } + }; + + public static ViewFlag SOURCE = new ViewFlag(true, false, IGNITE, "source", "s") { + @Override + public Stream filter(Stream records) { + return records.filter(record -> record.getFuse() == 80); + } + }; + + public static ViewFlag BUILD_DESTROY_ONLY = new ViewFlag(true, false, "build-destroy-only") { + @Override + public Stream filter(Stream records) { + return records.filter(record -> record.getHistory().get(record.getHistory().size() - 1).isDestroyedBuildArea()); + } + }; + + public static ViewFlag TESTBLOCK_DESTROY_ONLY = new ViewFlag(true, false, "testblock-destroy-only") { + @Override + public Stream filter(Stream records) { + return records.filter(record -> record.getHistory().get(record.getHistory().size() - 1).isDestroyedTestBlock()); + } + }; + + public static ViewFlag MICROMOTION = new ViewFlag(true, false, "micromotion", "m") { + @Override + public Stream filter(Stream stream) { + List records = stream.collect(Collectors.toList()); + ; + Set seen = new HashSet<>(); + Set toRemove = new HashSet<>(); + + for (TNTPoint uniqueRecord : records) { + if (seen.contains(uniqueRecord.getTntId())) continue; + + boolean hasMicromotion = false; + for (TNTPoint record : uniqueRecord.getHistory()) { + Vector velocity = record.getVelocity(); + if (velocity.getY() == 0 && (Math.abs(velocity.getX()) < 0.001 || Math.abs(velocity.getZ()) < 0.001)) { + hasMicromotion = true; + break; + } + } + + if (!hasMicromotion) + toRemove.add(uniqueRecord); + + seen.add(uniqueRecord.getTntId()); + } + + for (TNTPoint record : toRemove) { + records.removeAll(record.getHistory()); + } + + return records.stream(); + } + }; + + public static ViewFlag ADVANCED = new ViewFlag(true, false, "advanced", "a") { + @Override + public void modify(REntityServer server, List entities) { + for (TraceEntity entity : entities) { + TNTPoint current = entity.getRecords().get(0); + if (current.isExplosion()) continue; + TNTPoint next = current.getNext().orElse(null); + if (next == null) continue; + + Location pos = current.getLocation().clone(); + pos.setY(next.getLocation().getY()); + + if (pos.distanceSquared(current.getLocation()) >= 1.0 / 256.0) { + RFallingBlockEntity y = new RFallingBlockEntity(server, pos, Material.WHITE_STAINED_GLASS); + y.setNoGravity(true); + } + + if (current.getVelocity().getX() >= current.getVelocity().getZ()) { + pos.setX(next.getLocation().getX()); + } else { + pos.setZ(next.getLocation().getZ()); + } + if (pos.distanceSquared(next.getLocation()) >= 1.0 / 256.0) { + RFallingBlockEntity second = new RFallingBlockEntity(server, pos, Material.WHITE_STAINED_GLASS); + second.setNoGravity(true); + } + } + } + }; + + public static ViewFlag COUNT = new ViewFlag(true, false, "count", "c") { + @Override + public void modify(REntityServer server, List entities) { + for (TraceEntity entity : entities) { + entity.setDisplayName(String.valueOf(entity.getRecords().size())); + } + } + }; + + public static ViewFlag FUSE = new ViewFlag(true, false, "fuse", "f") { + @Override + public void modify(REntityServer server, List entities) { + for (TraceEntity entity : entities) { + List fuses = entity.getRecords() + .stream() + .map(TNTPoint::getFuse) + .distinct() + .sorted() + .map(i -> i + "") + .collect(Collectors.toList()); + if (fuses.size() <= 5) { + entity.setDisplayName(String.join(",", fuses)); + } else { + entity.setDisplayName(fuses.stream().limit(5).collect(Collectors.joining(",")) + ", +" + (fuses.size() - 5)); + } + } + } + }; + + public static ViewFlag TIME = new ViewFlag(true, false, "time", "t") { + @Override + public void modify(REntityServer server, List entities) { + for (TraceEntity entity : entities) { + List time = entity.getRecords() + .stream() + .map(TNTPoint::getTicksSinceStart) + .distinct() + .sorted() + .map(i -> i + "") + .collect(Collectors.toList()); + if (time.size() <= 5) { + entity.setDisplayName(String.join(",", time)); + } else { + entity.setDisplayName(time.stream().limit(5).collect(Collectors.joining(",")) + ", +" + (time.size() - 5)); + } + } + } + }; + + /** + * Name of the flag + */ + public final String name; + + /** + * Aliases of the flag + */ + public final String[] aliases; + + /** + * A flag that is used whenever this flag is used + */ + public final ViewFlag[] required; + + protected ViewFlag(boolean isStatic, boolean isInverse, String name, String... aliases) { + this(isStatic, isInverse, new ViewFlag[0], name, aliases); + } + + protected ViewFlag(boolean isStatic, boolean isInverse, ViewFlag required, String name, String... aliases) { + this(isStatic, isInverse, new ViewFlag[]{required}, name, aliases); + } + + protected ViewFlag(boolean isStatic, boolean isInverse, ViewFlag[] required, String name, String... aliases) { + this.name = name; + this.aliases = aliases; + if (isStatic) flags.add(this); + if (isInverse) inverseFlags.add(this); + this.required = required; + } + + /** + * Filters the given records for a given condition + * + * @param records Records to be filtered + * @return Filtered records + */ + public Stream filter(Stream records) { + return records; + } + + /** + * Modifies the trace rendering + * + * @param server the server the trace is rendered on + * @param entities the entities representing tnts + */ + public void modify(REntityServer server, List entities) { + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicflags/AtFlag.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicflags/AtFlag.java new file mode 100644 index 00000000..776eead4 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicflags/AtFlag.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer.rendering.dynamicflags; + +import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; + +import java.util.stream.Stream; + +/** + * A view flag for rendering a trace only in a given time intervall + */ +public class AtFlag extends ViewFlag { + /** + * Start of the time interval + */ + private int start; + /** + * End of the time interval + */ + private int end; + + public AtFlag(int start, int end) { + super(false, false, ViewFlag.IGNITE, null); + this.start = start; + this.end = end; + } + + /** + * Update this flag to represent another time interval + * + * @param start new interval start + * @param end new interval end + */ + public void update(int start, int end) { + this.start = start; + this.end = end; + } + + @Override + public Stream filter(Stream records) { + return records.filter(record -> record.getTicksSinceStart() >= start && record.getTicksSinceStart() <= end); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicflags/IsolateFlag.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicflags/IsolateFlag.java new file mode 100644 index 00000000..4ee99408 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicflags/IsolateFlag.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer.rendering.dynamicflags; + +import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; + +/** + * A flag for rendering only the records of specific tnts + */ +public class IsolateFlag extends ViewFlag { + + /** + * Tnt ids that will be isolated + */ + private final Set tntToIsolate = new HashSet<>(); + + public IsolateFlag() { + super(false, false, ViewFlag.IGNITE, null); + } + + /** + * Toggles the given id to be or not to be rendered + * + * @param id + */ + public void toggleId(int id) { + if (!tntToIsolate.remove(id)) { + tntToIsolate.add(id); + } + } + + @Override + public Stream filter(Stream records) { + if (tntToIsolate.isEmpty()) return records; + return records.filter(record -> tntToIsolate.contains(record.getTntId())); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityShowMode.java deleted file mode 100644 index dfa05ac4..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityShowMode.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2023 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.show; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.tracer.TNTPosition; -import de.steamwar.bausystem.shared.RoundedPosition; -import de.steamwar.bausystem.shared.ShowMode; -import de.steamwar.bausystem.utils.FlatteningWrapper; -import de.steamwar.entity.REntity; -import de.steamwar.entity.REntityServer; -import de.steamwar.entity.RFallingBlockEntity; -import net.md_5.bungee.api.chat.ClickEvent; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import java.util.*; -import java.util.function.BiConsumer; -import java.util.stream.Stream; - -public class EntityShowMode implements ShowMode { - - private final int factor; - private final Player player; - private final ShowModeParameter showModeParameter; - - private REntityServer entityServer; - - private final Map tntEntityMap = new HashMap<>(); - private final Map explodeEntityMap = new HashMap<>(); - private final Map updateEntityMap = new HashMap<>(); - - public EntityShowMode(Player player, ShowModeParameter showModeParameter, int factor) { - this.player = player; - this.showModeParameter = showModeParameter; - this.factor = factor; - } - - @Override - public void show(TNTPosition position) { - if (entityServer == null) { - entityServer = new REntityServer(); - entityServer.setCallback((player, rEntity, entityAction) -> { - if (entityAction != REntityServer.EntityAction.INTERACT) return; - TNTPosition tntPosition = Stream.concat(tntEntityMap.values().stream(), explodeEntityMap.values().stream()) - .filter(entityStack -> entityStack.entity == rEntity) - .findFirst() - .map(entityStack -> entityStack.tntPosition) - .orElse(null); - if (tntPosition == null) return; - - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", player); - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_FUSE_TIME", player, tntPosition.getFuseTicks()); - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_X", player, tntPosition.getLocation().getX() + ""); - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", player, tntPosition.getLocation().getY() + ""); - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", player, tntPosition.getLocation().getZ() + ""); - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", player, tntPosition.getVelocity().getX() + ""); - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", player, tntPosition.getVelocity().getY() + ""); - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", player, tntPosition.getVelocity().getZ() + ""); - BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_ISOLATE", player, BauSystem.MESSAGE.parse("TRACE_MESSAGE_CLICK_ISOLATE", player), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/trace isolate " + tntPosition.getRecord().getId())); - }); - entityServer.addPlayer(player); - } - - if (showModeParameter.isBuildDestroyOnly() && !position.getRecord().isInBuildArea()) { - 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() && !showModeParameter.isMicroMotionLocation() && !hideWater) { - return; - } - } - - if (showModeParameter.isSourceOnly()) { - if (position.isSource()) { - generatePositions(position, false, false); - } - if (!showModeParameter.isMicroMotionLocation() && !hideWater) { - return; - } - } - - 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) -> { - RoundedPosition roundedPosition = new RoundedPosition(vector, factor); - Map map; - if (positionType == PositionType.TNT) { - map = tntEntityMap; - } else if (positionType == PositionType.EXPLODE) { - map = explodeEntityMap; - } else { - map = updateEntityMap; - } - map.computeIfPresent(roundedPosition, (roundedPosition1, entityStack) -> { - if (!entityStack.remove(pos.getRecord())) { - return null; - } - return entityStack; - }); - }); - } - } - return; - } - - generatePositions(position, showModeParameter.isInterpolateY(), showModeParameter.isInterpolateXZ()); - } - - @Override - public void hide() { - tntEntityMap.clear(); - explodeEntityMap.clear(); - updateEntityMap.clear(); - if (entityServer != null) { - entityServer.close(); - entityServer = null; - } - } - - private void generatePositions(TNTPosition position, boolean interpolateY, boolean interpolateXZ) { - generatePositions(position, interpolateY, interpolateXZ, (positionType, vector) -> { - RoundedPosition roundedPosition = new RoundedPosition(vector, factor); - EntityStack entityStack; - if (positionType == PositionType.TNT) { - entityStack = tntEntityMap.computeIfAbsent(roundedPosition, i -> new EntityStack(position, vector, positionType, position.getFuseTicks())); - } else if (positionType == PositionType.EXPLODE) { - entityStack = explodeEntityMap.computeIfAbsent(roundedPosition, i -> new EntityStack(position, vector, positionType, position.getFuseTicks())); - } else { - entityStack = updateEntityMap.computeIfAbsent(roundedPosition, i -> new EntityStack(position, vector, positionType, position.getFuseTicks())); - } - entityStack.add(position.getRecord()); - }); - } - - private boolean checkWater(Vector position) { - return FlatteningWrapper.impl.inWater(player.getWorld(), position); - } - - private REntity createEntity(Vector position, PositionType positionType) { - Material material; - if (positionType == PositionType.TNT) { - material = Material.TNT; - } else if (positionType == PositionType.EXPLODE) { - material = Material.RED_STAINED_GLASS; - } else { - material = Material.WHITE_STAINED_GLASS; - } - RFallingBlockEntity entity = new RFallingBlockEntity(entityServer, position.toLocation(player.getWorld()), material); - entity.setNoGravity(true); - return entity; - } - - private class EntityStack { - - private final TNTPosition tntPosition; - private final Vector position; - private final PositionType positionType; - private final int fuseTicks; - - private REntity entity; - private int count; - private List records = new ArrayList<>(); - - public EntityStack(TNTPosition tntPosition, Vector position, PositionType positionType, int fuseTicks) { - this.tntPosition = tntPosition; - this.position = position; - this.positionType = positionType; - this.fuseTicks = fuseTicks; - } - - public void add(Record.TNTRecord record) { - records.add(record); - if (entity == null) { - entity = createEntity(position, positionType); - } - count++; - if (showModeParameter.isFuse()) { - entity.setDisplayName(fuseTicks + ""); - } else if (showModeParameter.isCount()) { - entity.setDisplayName(new HashSet<>(records).size() + ""); - } - } - - public boolean remove(Record.TNTRecord record) { - if (entity == null) return false; - records.remove(record); - count--; - if (count == 0) { - entity.die(); - entity = null; - return false; - } - return true; - } - } - - public static void generatePositions(TNTPosition position, boolean interpolateY, boolean interpolateXZ, BiConsumer positionCallback) { - positionCallback.accept(position.isExploded() ? PositionType.EXPLODE : PositionType.TNT, position.getLocation()); - if (position.getPreviousLocation() == null) return; - - if (interpolateY) { - Vector updatePointY = position.getPreviousLocation().clone().setY(position.getLocation().getY()); - if (!position.getLocation().equals(updatePointY)) { - positionCallback.accept(PositionType.UPDATE, updatePointY); - } - } - - if (interpolateXZ) { - Vector updatePointXZ = Math.abs(position.getUpdateVelocity().getX()) >= Math.abs(position.getUpdateVelocity().getZ()) - ? position.getLocation().clone().setZ(position.getPreviousLocation().getZ()) - : position.getLocation().clone().setX(position.getPreviousLocation().getX()); - if (!position.getLocation().equals(updatePointXZ)) { - positionCallback.accept(PositionType.UPDATE, updatePointXZ); - } - } - } - - public enum PositionType { - TNT, - EXPLODE, - UPDATE - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java deleted file mode 100644 index fce2d789..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.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; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -@RequiredArgsConstructor -public class Record { - - @Getter - private final List tnt = new ArrayList<>(); - private final Region region; - private final long startTicks = TPSUtils.currentTick.get(); - - public int size() { - return tnt.size(); - } - - public void showAll(ShowMode traceShowMode) { - tnt.forEach(tntRecord -> tntRecord.getPositions().forEach(traceShowMode::show)); - } - - public TNTRecord spawn() { - TNTRecord record = new TNTRecord(this, region); - tnt.add(record); - return record; - } - - public void clear() { - tnt.clear(); - } - - private void checkMicroMotion(Vector explosionPosition) { - for (TNTRecord tntRecord : tnt) { - List positions = tntRecord.positions; - if (positions.isEmpty()) continue; - TNTPosition position = positions.get(positions.size() - 1); - if (position.isExploded()) continue; - if (position.getLocation().distanceSquared(explosionPosition) > 64) continue; - - Vector velocity = position.getVelocity(); - if (velocity.getY() == 0 && ((velocity.getX() != 0 && 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); - } - } - } - - public static class TNTRecord { - - @Getter - private final UUID id = UUID.randomUUID(); - - private Record record; - - @Getter - private final Region region; - - @Getter - private final List positions = new ArrayList<>(82); - - @Getter - @Setter - private boolean inBuildArea = false; - - @Getter - @Setter - private boolean inTestblockArea = false; - - @Getter - private boolean hasMicroMotion = false; - - public TNTRecord(Record record, Region region) { - this.record = record; - this.region = region; - } - - public void source(TNTPrimed tntPrimed) { - add(tntPrimed, true, false); - } - - public void location(TNTPrimed tntPrimed) { - add(tntPrimed, false, false); - } - - public void explode(TNTPrimed tntPrimed) { - add(tntPrimed, false, true); - record.checkMicroMotion(tntPrimed.getLocation().toVector()); - } - - private void add(TNTPrimed tntPrimed, boolean source, boolean exploded) { - TNTPosition position; - if (positions.isEmpty()) { - 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, TPSUtils.currentTick.get() - record.startTicks, positions.get(positions.size() - 1).getLocation(), tntPrimed.getVelocity(), lastVelocity, source, exploded); - } - positions.add(position); - TraceShowManager.show(region, position); - } - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameter.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameter.java deleted file mode 100644 index 1da942eb..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.show; - -import lombok.Getter; - -@Getter -public class ShowModeParameter { - private boolean water = false; - private boolean interpolateY = false; - private boolean interpolateXZ = false; - private boolean sourceOnly = false; - private boolean explodeOnly = false; - private boolean fuse = false; - private boolean count = false; - private boolean buildDestroyOnly = 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; - } - - public void enableInterpolateXZ() { - this.interpolateXZ = true; - } - - public void enableSourceOnly() { - this.sourceOnly = true; - } - - public void enableExplodeOnly() { - this.explodeOnly = true; - } - - public void enableFuse() { - this.fuse = true; - } - - public void enableCount() { - this.count = true; - } - - public void enableBuildDestroyOnly() { - this.buildDestroyOnly = true; - } - - public void enableTestblockDestroyOnly() { - this.testblockDestroyOnly = true; - } - - public void enableMicroMotion() { - this.microMotion = true; - } - - public void enableMicroMotionLocation() { - this.microMotionLocation = true; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameterType.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameterType.java deleted file mode 100644 index 51e1e9a5..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowModeParameterType.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.show; - -import lombok.Getter; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; -import java.util.function.Supplier; - -public enum ShowModeParameterType { - - WATER(ShowModeParameter::enableWater, Arrays.asList("-water"), "EXPLODE", "SOURCE", "BUILD_DESTROY_ONLY"), - INTERPOLATE_Y(ShowModeParameter::enableInterpolateY, Arrays.asList("-interpolatey", "-interpolate-y", "-interpolate_y", "-y"), "ADVANCED"), - INTERPOLATE_XZ(ShowModeParameter::enableInterpolateXZ, Arrays.asList("-interpolatex", "-interpolate-x", "-interpolate_x", "-x", "-interpolatez", "-interpolate-z", "-interpolate_z", "-z", "-interpolatexz", "-interpolate-xz", "-interpolate_xz", "-xz"), "ADVANCED"), - ADVANCED(showModeParameter -> { - showModeParameter.enableInterpolateY(); - showModeParameter.enableInterpolateXZ(); - }, Arrays.asList("-advanced", "-a"), "INTERPOLATE_Y", "INTERPOLATE_XZ"), - 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 - private final Consumer showModeParameterConsumer; - - @Getter - private List tabCompletes; - - @Getter - private final Supplier removed; - private AtomicReference cached = new AtomicReference<>(); - - ShowModeParameterType(Consumer showModeParameterConsumer, List tabCompletes, String... removed) { - this.showModeParameterConsumer = showModeParameterConsumer; - this.tabCompletes = tabCompletes; - this.removed = () -> { - if (cached.get() == null) { - ShowModeParameterType[] showModeParameterTypes = new ShowModeParameterType[removed.length]; - for (int i = 0; i < removed.length; i++) { - showModeParameterTypes[i] = ShowModeParameterType.valueOf(removed[i]); - } - cached.set(showModeParameterTypes); - return showModeParameterTypes; - } - return cached.get(); - }; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java deleted file mode 100644 index 91bc2272..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.show; - -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 java.util.*; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -@UtilityClass -public class StoredRecords { - - private static final Map> records = new HashMap<>(); - - public static void add(Region region, Record record) { - records.computeIfAbsent(region, k -> new ArrayList<>()).add(record); - } - - public static void remove(Region region, Record record) { - records.computeIfAbsent(region, k -> new ArrayList<>()).remove(record); - } - - public static void clear(Region region) { - records.remove(region); - TraceShowManager.clear(region); - Recorder.INSTANCE.postClear(region); - } - - public static List getRecords() { - return records.values().stream() - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } - - public static List getRecords(Region region) { - return records.getOrDefault(region, Collections.emptyList()); - } - - static void show(Region region, Predicate traceShowFilter, ShowMode traceShowMode) { - records.getOrDefault(region, new ArrayList<>()).forEach(record -> { - record.getTnt().forEach(tntRecord -> { - tntRecord.getPositions().stream() - .filter(traceShowFilter) - .forEach(traceShowMode::show); - }); - }); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java deleted file mode 100644 index 7c335052..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.tracer.show; - -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.bausystem.utils.BauMemberUpdateEvent; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Predicate; - -public class TraceShowManager implements Listener { - private TraceShowManager() { - } - - private static final Map>> showModes = new HashMap<>(); - private static final Map>> showFilters = new HashMap<>(); - - public static void show(Player player, ShowMode traceShowMode) { - Region region = Region.getRegion(player.getLocation()); - _hide(region, player, true); - - Map> regionalShowModes = showModes.computeIfAbsent(region, __ -> new HashMap<>()); - regionalShowModes.put(player, traceShowMode); - StoredRecords.show(region, getShowFilter(player, region), traceShowMode); - } - - public static void hide(Player player) { - Region region = Region.getRegion(player.getLocation()); - _hide(region, player, true); - - showFilters.getOrDefault(region, new HashMap<>()).remove(player); - } - - public static void setShowFilter(Player player, Predicate showFilter) { - Region region = Region.getRegion(player.getLocation()); - Map> regionShowFilters = showFilters.computeIfAbsent(region, __ -> new HashMap<>()); - if (showFilter == null) { - regionShowFilters.remove(player); - } else { - regionShowFilters.put(player, showFilter); - } - - _hide(region, player, false); - ShowMode showMode = showModes.computeIfAbsent(region, __ -> new HashMap<>()).computeIfAbsent(player, __ -> new EntityShowMode(player, new ShowModeParameter(), 16)); - StoredRecords.show(region, getShowFilter(player, region), showMode); - } - - public static void reshow(Region region) { - Map> regionalShowModes = showModes.get(region); - if (regionalShowModes == null) { - return; - } - for (Map.Entry> entry : regionalShowModes.entrySet()) { - entry.getValue().hide(); - StoredRecords.show(region, getShowFilter(entry.getKey(), region), entry.getValue()); - } - } - - private static void _hide(Region region, Player player, boolean remove) { - Map> regionalShowModes = showModes.get(region); - if (regionalShowModes == null) { - return; - } - ShowMode showMode; - if (remove) { - showMode = regionalShowModes.remove(player); - } else { - showMode = regionalShowModes.get(player); - } - if (showMode == null) { - return; - } - showMode.hide(); - } - - private static Predicate getShowFilter(Player player, Region region) { - return showFilters.getOrDefault(region, new HashMap<>()).getOrDefault(player, tntPosition -> true); - } - - /* Only to be called by record */ - static void show(Region region, TNTPosition tnt) { - Map> regionalShowModes = showModes.get(region); - if (regionalShowModes == null) { - return; - } - regionalShowModes.forEach((player, tntPositionShowMode) -> { - if (getShowFilter(player, region).test(tnt)) { - tntPositionShowMode.show(tnt); - } - }); - } - - /* Only to be called by StoredRecords */ - static void clear(Region region) { - Map> regionalShowModes = showModes.get(region); - if (regionalShowModes == null) { - return; - } - regionalShowModes.values().forEach(ShowMode::hide); - } - - /* Internal if player leaves*/ - static { - Bukkit.getPluginManager().registerEvents(new TraceShowManager(), BauSystem.getInstance()); - } - - @EventHandler - public void onLeave(PlayerQuitEvent event) { - hideComplete(event.getPlayer()); - } - - @EventHandler - public void onBauMemberUpdate(BauMemberUpdateEvent event) { - event.getNewSpectator().forEach(this::hideComplete); - } - - private void hideComplete(Player player) { - showModes.forEach((region, playerShowModeMap) -> { - ShowMode showMode = playerShowModeMap.remove(player); - if (showMode != null) showMode.hide(); - }); - showFilters.forEach((region, playerPredicateMap) -> { - playerPredicateMap.remove(player); - }); - } -}