diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index 1878486b..b511dc73 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -44,6 +44,11 @@ SCOREBOARD_TRACE_TICKS = Ticks SCOREBOARD_TECHHIDER = TechHider§8: §aOn SCOREBOARD_XRAY = XRay§8: §aOn +SCOREBOARD_LOCK_TEAM = Bau Lock§8: §eTeam +SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM = Bau Lock§8: §e(Server) Team +SCOREBOARD_LOCK_SERVERTEAM = Bau Lock§8: §eServer Team +SCOREBOARD_LOCK_NOBODY = Bau Lock§8: §cNobody + # Flags FLAG_COLOR = Color FLAG_TNT = TNT diff --git a/BauSystem_Main/src/BauSystem_de.properties b/BauSystem_Main/src/BauSystem_de.properties index ff2cfe89..a32ebe68 100644 --- a/BauSystem_Main/src/BauSystem_de.properties +++ b/BauSystem_Main/src/BauSystem_de.properties @@ -44,6 +44,11 @@ SCOREBOARD_TRACE_TICKS = Ticks SCOREBOARD_TECHHIDER = TechHider§8: §aAn SCOREBOARD_XRAY = XRay§8: §aAn +SCOREBOARD_LOCK_TEAM = Bau Lock§8: §eTeam +SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM = Bau Lock§8: §e(Server-) Team +SCOREBOARD_LOCK_SERVERTEAM = Bau Lock§8: §eServerteam +SCOREBOARD_LOCK_NOBODY = Bau Lock§8: §cNiemand + # Flags FLAG_COLOR = Color FLAG_TNT = TNT diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java index 8967951d..898b68a7 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java @@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.script.lua.libs; import com.google.gson.*; import de.steamwar.bausystem.region.Region; +import de.steamwar.core.Core; import de.steamwar.linkage.Linked; import de.steamwar.linkage.api.Disable; import de.steamwar.linkage.api.Enable; @@ -54,6 +55,7 @@ public class StorageLib implements LuaLib, Enable, Disable { @Override public void enable() { + if (Core.getVersion() <= 15) return; if (!storageDirectory.exists()) storageDirectory.mkdirs(); try { @@ -129,6 +131,7 @@ public class StorageLib implements LuaLib, Enable, Disable { @Override public void disable() { + if (Core.getVersion() <= 15) return; if (!storageDirectory.exists()) storageDirectory.mkdirs(); try { FileWriter fileWriter = new FileWriter(new File(storageDirectory, "global.json")); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java index bc09a7b3..0c335c02 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java @@ -27,6 +27,8 @@ import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.features.simulator.data.Simulator; import de.steamwar.bausystem.features.simulator.data.SimulatorElement; import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement; import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase; import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; @@ -60,10 +62,7 @@ import org.bukkit.event.player.*; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; @@ -79,6 +78,7 @@ public class SimulatorCursor implements Listener { private Map cursorType = Collections.synchronizedMap(new HashMap<>()); private Map cursors = Collections.synchronizedMap(new HashMap<>()); + private final Set calculating = new HashSet<>(); public static boolean isSimulatorItem(ItemStack itemStack) { return ItemUtils.isItem(itemStack, "simulator"); @@ -125,6 +125,9 @@ public class SimulatorCursor implements Listener { public void onPlayerQuit(PlayerQuitEvent event) { cursorType.remove(event.getPlayer()); cursors.remove(event.getPlayer()); + synchronized (calculating) { + calculating.remove(event.getPlayer()); + } } private static final Map LAST_SNEAKS = new HashMap<>(); @@ -151,11 +154,18 @@ public class SimulatorCursor implements Listener { } } - public synchronized void calcCursor(Player player) { + public void calcCursor(Player player) { + synchronized (calculating) { + if (calculating.contains(player)) return; + calculating.add(player); + } if (Permission.SPECTATOR.hasPermission(player) || (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand()))) { if (removeCursor(player) || SimulatorWatcher.show(null, player)) { SWUtils.sendToActionbar(player, ""); } + synchronized (calculating) { + calculating.remove(player); + } return; } Simulator simulator = SimulatorStorage.getSimulator(player); @@ -170,10 +180,16 @@ public class SimulatorCursor implements Listener { } else { SWUtils.sendToActionbar(player, "§eOpen Simulator"); } + synchronized (calculating) { + calculating.remove(player); + } return; } showCursor(player, rayTraceResult, simulator != null); + synchronized (calculating) { + calculating.remove(player); + } } private synchronized boolean removeCursor(Player player) { @@ -226,7 +242,7 @@ public class SimulatorCursor implements Listener { } } - public static Vector getPosTNT(Player player, RayTraceUtils.RRayTraceResult result) { + public static Vector getPosFree(Player player, RayTraceUtils.RRayTraceResult result) { Vector pos = result.getHitPosition(); BlockFace face = result.getHitBlockFace(); @@ -266,7 +282,7 @@ public class SimulatorCursor implements Listener { return pos; } - private static Vector getPosRedstoneBlock(Player player, RayTraceUtils.RRayTraceResult result) { + private static Vector getPosBlockAligned(Player player, RayTraceUtils.RRayTraceResult result) { Vector pos = result.getHitPosition(); BlockFace face = result.getHitBlockFace(); @@ -305,8 +321,9 @@ public class SimulatorCursor implements Listener { @Getter @AllArgsConstructor public enum CursorType { - TNT(Material.TNT, SimulatorCursor::getPosTNT, "TNT", vector -> new TNTElement(vector).add(new TNTPhase())), - REDSTONE_BLOCK(Material.REDSTONE_BLOCK, SimulatorCursor::getPosRedstoneBlock, "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())), + TNT(Material.TNT, SimulatorCursor::getPosFree, "TNT", vector -> new TNTElement(vector).add(new TNTPhase())), + REDSTONE_BLOCK(Material.REDSTONE_BLOCK, SimulatorCursor::getPosBlockAligned, "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())), + OBSERVER(Material.OBSERVER, SimulatorCursor::getPosBlockAligned, "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())), ; private Material material; @@ -318,6 +335,9 @@ public class SimulatorCursor implements Listener { if (this == TNT) { return REDSTONE_BLOCK; } + if (this == REDSTONE_BLOCK) { + return OBSERVER; + } return TNT; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java new file mode 100644 index 00000000..de0d2b69 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java @@ -0,0 +1,35 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.data; + +import org.bukkit.Material; +import org.bukkit.util.Vector; + +public abstract class SimulatorBlockAlignedElement extends SimulatorElement { + + protected SimulatorBlockAlignedElement(Material material, Vector position) { + super(material, position); + } + + @Override + public final boolean canBeInGroup(SimulatorGroup simulatorGroup) { + return simulatorGroup.getElements().stream().allMatch(SimulatorBlockAlignedElement.class::isInstance); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java new file mode 100644 index 00000000..7fdff328 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java @@ -0,0 +1,99 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.data.observer; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorBlockAlignedElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import de.steamwar.bausystem.features.simulator.gui.SimulatorObserverGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; + +public final class ObserverElement extends SimulatorBlockAlignedElement { + + public ObserverElement(Vector position) { + super(Material.OBSERVER, position); + } + + @Override + public String getName(Player player) { + return "Observer"; + } + + @Override + public Material getWorldMaterial() { + return Material.OBSERVER; + } + + @Override + public Material getWorldDisabledMaterial() { + return Material.GRAY_STAINED_GLASS; + } + + public void toSimulatorActions(BiConsumer tickStart, BiConsumer tickEnd) { + if (disabled) return; + phases.forEach(phase -> { + phase.toSimulatorActions(position.clone(), tickStart, tickEnd); + }); + + int end = phases.stream().mapToInt(SimulatorPhase::getTickOffset).max().orElse(0) + 4; + AtomicReference blockState = new AtomicReference<>(); + tickStart.accept(0, new SimulatorAction(-100, 1) { + @Override + public void accept(World world) { + Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + blockState.set(block.getState()); + block.setType(Material.OBSERVER, false); + } + }); + tickEnd.accept(end, new SimulatorAction(0, 1) { + @Override + public void accept(World world) { + BlockState oldState = blockState.get(); + if (oldState != null) { + oldState.update(true, true); + } else { + Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + block.setType(Material.AIR); + } + } + }); + } + + @Override + public void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back) { + new SimulatorObserverGui(player, simulator, group, this, back).open(); + } + + @Override + public String getType() { + return "Observer"; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java new file mode 100644 index 00000000..e3707c3e --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java @@ -0,0 +1,81 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.data.observer; + +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.type.Observer; +import org.bukkit.util.Vector; +import yapion.hierarchy.types.YAPIONObject; + +import java.util.function.BiConsumer; + +@NoArgsConstructor +public final class ObserverPhase extends SimulatorPhase { + + @Getter + @Setter + private BlockFace orientation = BlockFace.UP; + + public ObserverPhase(int tickOffset) { + this.tickOffset = tickOffset; + } + + { + this.lifetime = 0; + } + + @Override + public void toSimulatorActions(Vector position, BiConsumer tickStart, BiConsumer tickEnd) { + Observer observer = (Observer) Material.OBSERVER.createBlockData(); + observer.setFacing(orientation.getOppositeFace()); + observer.setPowered(true); + + tickStart.accept(tickOffset, new SimulatorAction(order, 1) { + @Override + public void accept(World world) { + Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + Block updateBlock = block.getRelative(orientation); + BlockState state = updateBlock.getState(); + updateBlock.setType(Material.SPONGE, true); + block.setBlockData(observer, true); + state.update(true, true); + } + }); + } + + @Override + public void saveExtra(YAPIONObject phaseObject) { + phaseObject.add("orientation", orientation.name()); + } + + @Override + public void loadExtra(YAPIONObject phaseObject) { + orientation = BlockFace.valueOf(phaseObject.getPlainValue("orientation")); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java index 2eb7aca2..3b949609 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java @@ -20,7 +20,7 @@ package de.steamwar.bausystem.features.simulator.data.redstone; import de.steamwar.bausystem.features.simulator.data.Simulator; -import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorBlockAlignedElement; import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; import de.steamwar.bausystem.features.simulator.gui.SimulatorRedstoneGui; import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; @@ -28,7 +28,7 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -public final class RedstoneElement extends SimulatorElement { +public final class RedstoneElement extends SimulatorBlockAlignedElement { public RedstoneElement(Vector position) { super(Material.REDSTONE_BLOCK, position); @@ -49,11 +49,6 @@ public final class RedstoneElement extends SimulatorElement { return Material.WHITE_STAINED_GLASS; } - @Override - public boolean canBeInGroup(SimulatorGroup simulatorGroup) { - return simulatorGroup.getElements().stream().allMatch(RedstoneElement.class::isInstance); - } - @Override public Vector getWorldPos() { return position.clone().add(new Vector(0.5, 0, 0.5)); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java index 4af3dc15..2e913bdd 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java @@ -21,9 +21,14 @@ package de.steamwar.bausystem.features.simulator.data.tnt; import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.flags.Flag; +import de.steamwar.bausystem.region.flags.flagvalues.FreezeMode; +import de.steamwar.bausystem.region.tags.Tag; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.TNTPrimed; import org.bukkit.util.Vector; @@ -59,7 +64,9 @@ public final class TNTPhase extends SimulatorPhase { tickStart.accept(tickOffset, new SimulatorAction(order, count) { @Override public void accept(World world) { - TNTPrimed tnt = world.spawn(position.toLocation(world), TNTPrimed.class); + Location location = position.toLocation(world); + if (Region.getRegion(location).get(Flag.FREEZE) == FreezeMode.ACTIVE) return; + TNTPrimed tnt = world.spawn(location, TNTPrimed.class); if (!xJump) tnt.setVelocity(tnt.getVelocity().setX(0)); if (!yJump) tnt.setVelocity(tnt.getVelocity().setY(0)); if (!zJump) tnt.setVelocity(tnt.getVelocity().setZ(0)); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java new file mode 100644 index 00000000..42669387 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java @@ -0,0 +1,188 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class SimulatorObserverGui extends SimulatorScrollGui { + + private final SimulatorGroup parent; + private final ObserverElement observer; + private final SimulatorBaseGui back; + + public SimulatorObserverGui(Player player, Simulator simulator, SimulatorGroup parent, ObserverElement observer, SimulatorBaseGui back) { + super(player, simulator, 6 * 9, observer.getPhases()); + this.parent = parent; + this.observer = observer; + this.back = back; + } + + @Override + public String baseTitle() { + return "Observer"; + } + + @Override + public void headerAndFooter() { + if (observer.getPhases().isEmpty()) { + back.open(); + SimulatorWatcher.update(simulator); + return; + } + + observer.sort(); + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + if (parent.getElements().contains(observer)) { + back.open(); + } else { + SimulatorGroup newParent = observer.getGroup(simulator); + if (newParent == null) { + player.closeInventory(); + return; + } + SimulatorGui simulatorGui = new SimulatorGui(player, simulator); + if (newParent.getElements().size() == 1) { + simulatorGui.open(); + } else { + new SimulatorGroupGui(player, simulator, newParent, simulatorGui).open(); + } + } + })); + + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + observer.getPhases().clear(); + SimulatorWatcher.update(simulator); + })); + + // Material Chooser + inventory.setItem(4, observer.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, observer::getMaterial, observer::setMaterial, this).open(); + })); + + // Settings + inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> { + new SimulatorObserverSettingsGui(player, simulator, observer, this).open(); + })); + + // Enable/Disable + inventory.setItem(48, new SWItem(observer.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, observer.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { + observer.setDisabled(!observer.isDisabled()); + SimulatorWatcher.update(simulator); + })); + + // Group chooser + inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> { + new SimulatorGroupChooserGui(player, simulator, observer, observer.getGroup(simulator), this).open(); + })); + } + + @Override + public SWItem[] column(ObserverPhase observerPhase, int index) { + int min; + if (index > 0) { + min = data.get(index - 1).getTickOffset() + 4; + } else { + min = 0; + } + + int max; + if (index < data.size() - 1) { + max = data.get(index + 1).getTickOffset() - 4; + } else { + max = Integer.MAX_VALUE - 4; + } + + List lore = new ArrayList<>(); + lore.add("§7Time§8:§e " + observerPhase.getTickOffset()); + lore.add("§7Order§8:§e " + observerPhase.getOrder()); + lore.add(""); + lore.add("§7Orientation§8:§e " + observerPhase.getOrientation().name()); + lore.add(""); + lore.add("§7Click§8:§e Edit"); + lore.add("§7Middle-Click§8:§e Remove"); + SWItem observer = new SWItem(Material.OBSERVER, "§eObserver", lore, false, clickType -> { + if (clickType == ClickType.MIDDLE) { + this.observer.getPhases().remove(observerPhase); + SimulatorWatcher.update(simulator); + } else { + new SimulatorObserverPhaseSettingsGui(player, simulator, this.observer, observerPhase, this).open(); + } + }); + observer.getItemStack().setAmount(Math.min(Math.max(observerPhase.getTickOffset(), 1), 64)); + + Supplier getter = observerPhase::getTickOffset; + Consumer setter = observerPhase::setTickOffset; + return new SWItem[] { + new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> { + setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }), + observer, + new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> { + setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }), + new SWItem(Material.ANVIL, "§eEdit Activation", clickType -> { + new SimulatorObserverPhaseSettingsGui(player, simulator, this.observer, observerPhase, this).open(); + }), + }; + } + + @Override + public SWItem[] lastColumn() { + return new SWItem[]{ + new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> { + addNewPhase(clickType.isShiftClick()); + }), + new SWItem(Material.QUARTZ, "§eObserver§8:§a New Phase", clickType -> { + addNewPhase(false); + }), + new SWItem(SWItem.getDye(8), "§7", clickType -> { + }), + }; + } + + private void addNewPhase(boolean shift) { + ObserverPhase lastElement = observer.getPhases().get(observer.getPhases().size() - 1); + ObserverPhase newPhase = new ObserverPhase(lastElement.getTickOffset() + 4); + if (shift) newPhase.setTickOffset(newPhase.getTickOffset() + 5); + scroll += 2; + observer.add(newPhase); + SimulatorWatcher.update(simulator); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java new file mode 100644 index 00000000..f7925c34 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java @@ -0,0 +1,172 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.core.Core; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui { + + private final ObserverElement observerElement; + private final ObserverPhase observer; + private final SimulatorBaseGui back; + + public SimulatorObserverPhaseSettingsGui(Player player, Simulator simulator, ObserverElement observerElement, ObserverPhase observer, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.observerElement = observerElement; + this.observer = observer; + this.back = back; + } + + @Override + public String title() { + return "Observer"; + } + + @Override + public void populate() { + if (!observerElement.getPhases().contains(observer)) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, observerElement.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, observerElement::getMaterial, observerElement::setMaterial, this).open(); + })); + + // Delete + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + observerElement.getPhases().remove(observer); + back.open(); + SimulatorWatcher.update(simulator); + })); + + int index = observerElement.getPhases().indexOf(observer); + int min; + if (index > 0) { + ObserverPhase previous = observerElement.getPhases().get(index - 1); + min = previous.getTickOffset() + 4; + } else { + min = 0; + } + + int max; + if (index < observerElement.getPhases().size() - 1) { + ObserverPhase next = observerElement.getPhases().get(index + 1); + max = next.getTickOffset() - 4; + } else { + max = Integer.MAX_VALUE - 4; + } + + //Tick Offset + int offset = observer.getTickOffset(); + inventory.setItem(10, SWItem.getDye(offset < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.setTickOffset(Math.min(max, offset + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + SWItem offsetItem = new SWItem(Material.REPEATER, "§eStart at§8:§7 " + offset, clickType -> { + new SimulatorAnvilGui<>(player, "Start at", offset + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + observer.setTickOffset(Math.min(Math.max(integer, min), max)); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64))); + inventory.setItem(19, offsetItem); + + inventory.setItem(28, SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + //Order + int order = observer.getOrder(); + inventory.setItem(13, SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + Material negativeNumbers = Material.getMaterial(Core.getVersion() >= 19 ? "RECOVERY_COMPASS" : "FIREWORK_STAR"); + SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : negativeNumbers, "§eActivation Order§8:§7 " + order, clickType -> { + new SimulatorAnvilGui<>(player, "Activation Order", order + "", Integer::parseInt, integer -> { + if (integer < -SimulatorPhase.ORDER_LIMIT) return false; + if (integer > SimulatorPhase.ORDER_LIMIT) return false; + observer.setOrder(integer); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(order >= 0 ? Material.COMPASS : negativeNumbers).open(); + }); + orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30))); + inventory.setItem(22, orderItem); + + inventory.setItem(31, SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + // Update orientation + inventory.setItem(25, new SWItem(Material.SUNFLOWER, "§7", clickType -> { + })); + inventory.setItem(15, new SWItem(observer.getOrientation() == BlockFace.UP ? Material.LIME_CONCRETE : Material.GRAY_CONCRETE, "§eUp", clickType -> { + observer.setOrientation(BlockFace.UP); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(33, new SWItem(observer.getOrientation() == BlockFace.DOWN ? Material.RED_CONCRETE : Material.GRAY_CONCRETE, "§eDown", clickType -> { + observer.setOrientation(BlockFace.DOWN); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(16, new SWItem(observer.getOrientation() == BlockFace.NORTH ? Material.LIME_WOOL : Material.GRAY_WOOL, "§eNorth", clickType -> { + observer.setOrientation(BlockFace.NORTH); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(34, new SWItem(observer.getOrientation() == BlockFace.SOUTH ? Material.RED_WOOL : Material.GRAY_WOOL, "§eSouth", clickType -> { + observer.setOrientation(BlockFace.SOUTH); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(24, new SWItem(observer.getOrientation() == BlockFace.EAST ? Material.LIME_STAINED_GLASS : Material.GRAY_STAINED_GLASS, "§eEast", clickType -> { + observer.setOrientation(BlockFace.EAST); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(26, new SWItem(observer.getOrientation() == BlockFace.WEST ? Material.RED_STAINED_GLASS : Material.GRAY_STAINED_GLASS, "§eWest", clickType -> { + observer.setOrientation(BlockFace.WEST); + SimulatorWatcher.update(simulator); + })); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java new file mode 100644 index 00000000..8084c7b1 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java @@ -0,0 +1,142 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SimulatorObserverSettingsGui extends SimulatorBaseGui { + + private final ObserverElement observer; + private final SimulatorBaseGui back; + + public SimulatorObserverSettingsGui(Player player, Simulator simulator, ObserverElement observer, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.observer = observer; + this.back = back; + } + + @Override + public String title() { + return "Observer"; + } + + @Override + public void populate() { + if (observer.getPhases().isEmpty()) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, observer.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, observer::getMaterial, observer::setMaterial, this).open(); + })); + + // Base Tick + int baseTicks = observer.getBaseTick(); + inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.changeBaseTicks(clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + SWItem baseTick = new SWItem(Material.REPEATER, "§eTicks§8:§7 " + baseTicks, clickType -> { + new SimulatorAnvilGui<>(player, "Ticks", baseTicks + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + observer.changeBaseTicks(integer - baseTicks); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64))); + inventory.setItem(18, baseTick); + inventory.setItem(27, SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) { + observer.changeBaseTicks(-baseTicks); + } else { + observer.changeBaseTicks(clickType.isShiftClick() ? -5 : -1); + } + SimulatorWatcher.update(simulator); + }); + + //Pos X + inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.move(clickType.isShiftClick() ? 5 : 1, 0, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(24, new SWItem(Material.PAPER, "§eX§8:§7 " + observer.getPosition().getBlockX(), clickType -> { + new SimulatorAnvilGui<>(player, "X", observer.getPosition().getBlockX() + "", Integer::parseInt, i -> { + observer.getPosition().setX(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.move(clickType.isShiftClick() ? -5 : -1, 0, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Y + inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.move(0, clickType.isShiftClick() ? 5 : 1, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(25, new SWItem(Material.PAPER, "§eY§8:§7 " + observer.getPosition().getBlockY(), clickType -> { + new SimulatorAnvilGui<>(player, "Y", observer.getPosition().getBlockY() + "", Integer::parseInt, i -> { + observer.getPosition().setY(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.move(0, clickType.isShiftClick() ? -5 : -1, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Z + inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.move(0, 0, clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(26, new SWItem(Material.PAPER, "§eZ§8:§7 " + observer.getPosition().getBlockZ(), clickType -> { + new SimulatorAnvilGui<>(player, "Z", observer.getPosition().getBlockZ() + "", Integer::parseInt, i -> { + observer.getPosition().setZ(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.move(0, 0, clickType.isShiftClick() ? -5 : -1); + SimulatorWatcher.update(simulator); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java index 1475cee4..2e288895 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java @@ -101,20 +101,20 @@ public class SimulatorRedstoneGui extends SimulatorScrollGui { + inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> { new SimulatorRedstoneSettingsGui(player, simulator, redstone, this).open(); })); - // Group chooser - inventory.setItem(49, new SWItem(Material.LEAD, "§eJoin Group", clickType -> { - new SimulatorGroupChooserGui(player, simulator, redstone, redstone.getGroup(simulator), this).open(); - })); - // Enable/Disable - inventory.setItem(50, new SWItem(redstone.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, redstone.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { + inventory.setItem(48, new SWItem(redstone.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, redstone.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { redstone.setDisabled(!redstone.isDisabled()); SimulatorWatcher.update(simulator); })); + + // Group chooser + inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> { + new SimulatorGroupChooserGui(player, simulator, redstone, redstone.getGroup(simulator), this).open(); + })); } @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java index a6d6c944..a9c178ce 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java @@ -93,8 +93,9 @@ public class SimulatorTNTGui extends SimulatorScrollGui { inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> { new SimulatorTNTSettingsGui(player, simulator, tnt, this).open(); })); - inventory.setItem(48, new SWItem(Material.LEAD, "§eJoin Group", clickType -> { - new SimulatorGroupChooserGui(player, simulator, tnt, tnt.getGroup(simulator), this).open(); + inventory.setItem(48, new SWItem(tnt.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, tnt.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { + tnt.setDisabled(!tnt.isDisabled()); + SimulatorWatcher.update(simulator); })); inventory.setItem(50, new SWItem(Material.CHEST, parent.getElements().size() == 1 ? "§eMake Group" : "§eAdd another TNT to Group", clickType -> { TNTElement tntElement = new TNTElement(tnt.getPosition().clone()); @@ -103,9 +104,8 @@ public class SimulatorTNTGui extends SimulatorScrollGui { new SimulatorGroupGui(player, simulator, parent, new SimulatorGui(player, simulator)).open(); SimulatorWatcher.update(simulator); })); - inventory.setItem(51, new SWItem(tnt.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, tnt.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { - tnt.setDisabled(!tnt.isDisabled()); - SimulatorWatcher.update(simulator); + inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> { + new SimulatorGroupChooserGui(player, simulator, tnt, tnt.getGroup(simulator), this).open(); })); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java index 9f79a613..41f95a88 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java @@ -62,6 +62,10 @@ public abstract class SimulatorBaseGui { player.getOpenInventory().setTitle(title()); } populate(); + if (player.getOpenInventory().getTopInventory() == inv) { + inventory.open(); + SimulatorWatcher.watch(player, simulator, this::open); + } return; } @@ -76,9 +80,9 @@ public abstract class SimulatorBaseGui { SimulatorWatcher.watch(player, null, null); }); - inventory.open(); SimulatorWatcher.watch(player, simulator, this::open); populate(); + inventory.open(); } private void setup() { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java index 15af2e4a..218c89a4 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java @@ -23,6 +23,8 @@ import de.steamwar.bausystem.features.simulator.data.Simulator; import de.steamwar.bausystem.features.simulator.data.SimulatorElement; import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement; import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase; import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; @@ -94,6 +96,10 @@ public class SimFormatSimulatorLoader implements SimulatorLoader { element = new RedstoneElement(position); phaseConstructor = RedstonePhase::new; break; + case "Observer": + element = new ObserverElement(position); + phaseConstructor = ObserverPhase::new; + break; default: element = null; phaseConstructor = null; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java index ea6faa46..de40c6c7 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java @@ -40,7 +40,10 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -74,6 +77,7 @@ public class SmartPlaceListener implements Plain, Listener { IGNORED.add(Material.TNT); IGNORED.add(Material.REDSTONE_ORE); IGNORED.add(SWItem.getMaterial("BEEHIVE")); + IGNORED.add(SWItem.getMaterial("SEA_PICKLE")); IGNORED.remove(Material.STONE); IGNORED.remove(Material.BARRIER); } @@ -94,26 +98,34 @@ public class SmartPlaceListener implements Plain, Listener { if(!Permission.BUILD.hasPermission(player)) return packet; if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return packet; Block block = player.getTargetBlockExact(6); - boolean shouldSneak = !(block != null && (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) && !CONTAINERS.contains(block.getType()) && !IGNORED.contains(block.getType())); + boolean shouldSneak = false; + if (block != null) { + if (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) { + shouldSneak = true; + } + if (CONTAINERS.contains(block.getType())) { + ItemStack itemStack = player.getInventory().getItemInMainHand(); + if (itemStack.getType() == Material.TNT) { + if (block.getType() == Material.CHEST || block.getType() == Material.BARREL || block.getType().name().endsWith("SHULKER_BOX")) { + shouldSneak = false; + } + } + } else { + shouldSneak = false; + } + if (IGNORED.contains(block.getType())) { + shouldSneak = false; + } + } boolean sneaking = player.isSneaking(); - run(player, packet, true, sneaking, shouldSneak); - return null; - }); - } - - private void run(Player player, Object packet, boolean first, boolean sneaking, boolean shouldSneak) { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { if (sneaking) SMART_PLACING.add(player); player.setSneaking(shouldSneak || sneaking); - packetExecutor.invoke(playerConnection.get(getHandle.invoke(player)), packet); - SMART_PLACING.remove(player); - player.setSneaking(sneaking); - - if (!WAS_EXECUTED.contains(player) && first) { - run(player, packet, false, sneaking, shouldSneak); - } - WAS_EXECUTED.remove(player); - }, first ? 0 : 1); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + SMART_PLACING.remove(player); + player.setSneaking(sneaking); + }, 0); + return packet; + }); } @EventHandler diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauLockStateScoreboard.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauLockStateScoreboard.java new file mode 100644 index 00000000..ab3630d4 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauLockStateScoreboard.java @@ -0,0 +1,68 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.config.BauServer; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.utils.ScoreboardElement; +import de.steamwar.linkage.Linked; +import de.steamwar.sql.UserConfig; +import org.bukkit.entity.Player; + +@Linked +public class BauLockStateScoreboard implements ScoreboardElement { + + private static final String BAU_LOCK_CONFIG_NAME = "baulockstate"; + + @Override + public ScoreboardGroup getGroup() { + return ScoreboardGroup.FOOTER; + } + + @Override + public int order() { + return -10; + } + + @Override + public String get(Region region, Player p) { + if (!BauServer.getInstance().getOwner().equals(p.getUniqueId())) { + return null; + } + String state = UserConfig.getConfig(p.getUniqueId(), BAU_LOCK_CONFIG_NAME); + switch (state == null ? BauLockState.OPEN : BauLockState.valueOf(state)) { + case OPEN: + return null; + default: + return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_LOCK_" + state.toUpperCase(), p); + } + } + + public enum BauLockState { + + NOBODY, + SERVERTEAM, + TEAM_AND_SERVERTEAM, + TEAM, + OPEN + } + +}