diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderRecorder.java index 4bc9f071..329cfd55 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderRecorder.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderRecorder.java @@ -37,15 +37,14 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.inventory.EquipmentSlot; -import java.util.HashSet; +import java.util.HashMap; import java.util.List; -import java.util.Set; +import java.util.Map; public class LoaderRecorder implements Listener { private Player player; private List loaderElementList; - private Set blockSet = new HashSet<>(); private long lastInteraction = TPSUtils.currentTick.get(); public LoaderRecorder(Player player, List loaderElementList) { @@ -132,56 +131,53 @@ public class LoaderRecorder implements Listener { } } + private Map blockSet = new HashMap<>(); + private Map movementSet = new HashMap<>(); + @EventHandler public void onPlayerMove(PlayerMoveEvent event) { if (event.getPlayer() != player) return; Block fromBlock = event.getTo().getBlock(); Block toBlock = event.getTo().getBlock(); - if (!blockSet.contains(toBlock.getLocation())) { - blockSet.remove(fromBlock.getLocation()); - blockSet.add(toBlock.getLocation()); - - addWaitTime(false); - Material type = toBlock.getType(); - switch (type) { - case TRIPWIRE: - loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Tripwire", Material.STRING, 30)); - break; - case LIGHT_WEIGHTED_PRESSURE_PLATE: - case HEAVY_WEIGHTED_PRESSURE_PLATE: - loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Weighted Pressure Plate", type, 20)); - break; - default: - if (type.name().endsWith("PRESSURE_PLATE")) { - loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Pressure Plate", type, 30)); - } - break; - } - } + calcMovementBlocks(fromBlock, toBlock); fromBlock = fromBlock.getRelative(0, 1, 0); toBlock = toBlock.getRelative(0, 1, 0); - if (!blockSet.contains(toBlock.getLocation())) { - blockSet.remove(fromBlock.getLocation()); - blockSet.add(toBlock.getLocation()); + calcMovementBlocks(fromBlock, toBlock); + } + + private void calcMovementBlocks(Block fromBlock, Block toBlock) { + if (!blockSet.containsKey(toBlock.getLocation())) { + Long startTime = blockSet.remove(fromBlock.getLocation()); + LoaderMovement loaderMovement = movementSet.remove(fromBlock.getLocation()); + if (loaderMovement != null && startTime != null) { + loaderMovement.setInitialTicks(TPSUtils.currentTick.get() - startTime); + } + + blockSet.put(toBlock.getLocation(), TPSUtils.currentTick.get()); addWaitTime(false); + loaderMovement = null; Material type = toBlock.getType(); switch (type) { case TRIPWIRE: - loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Tripwire", Material.STRING, 30)); + loaderMovement = new LoaderMovement(toBlock.getLocation(), "Tripwire", Material.STRING); break; case LIGHT_WEIGHTED_PRESSURE_PLATE: case HEAVY_WEIGHTED_PRESSURE_PLATE: - loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Weighted Pressure Plate", type, 20)); + loaderMovement = new LoaderMovement(toBlock.getLocation(), "Weighted Pressure Plate", type); break; default: if (type.name().endsWith("PRESSURE_PLATE")) { - loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Pressure Plate", type, 30)); + loaderMovement = new LoaderMovement(toBlock.getLocation(), "Pressure Plate", type); } break; } + if (loaderMovement != null) { + movementSet.put(toBlock.getLocation(), loaderMovement); + loaderElementList.add(loaderMovement); + } } } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderMovement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderMovement.java new file mode 100644 index 00000000..ee1f11ac --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderMovement.java @@ -0,0 +1,226 @@ +/* + * 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.loadern.elements.impl; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.loadern.elements.ElementSettings; +import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement; +import de.steamwar.inventory.SWAnvilInv; +import de.steamwar.inventory.SWInventory; +import de.steamwar.inventory.SWItem; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.data.AnaloguePowerable; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Powerable; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.Collections; + +public class LoaderMovement extends LoaderInteractionElement { + + private String name; + private Material material; + private boolean analogue; + + public LoaderMovement(Location location, String name, Material material) { + super(location); + this.name = name; + this.material = material; + this.analogue = location.getBlock().getBlockData() instanceof AnaloguePowerable; + } + + public void setInitialTicks(long ticks) { + elements.get(currentShot).ticks = ticks; + } + + public class MovementSettings implements ElementSettings { + + private boolean noop = false; + private boolean waitFor = true; + private int power = 0; + private long ticks = 1; + + @Override + public SWItem menu(Player player) { + return menu(player, noop, waitFor); + } + + private SWItem menu(Player player, boolean noop, boolean waitFor) { + SWItem swItem; + if (noop) { + swItem = new SWItem(Material.STRUCTURE_VOID, "§7" + name + "§8: §eNOOP"); + } else if (waitFor) { + swItem = new SWItem(material, "§7" + name + "§8: §eWaitFor"); + swItem.getItemStack().setAmount((int) Math.min(ticks, 64)); + } else { + swItem = new SWItem(material, "§7" + name + "§8: §eNoWaitFor"); + swItem.getItemStack().setAmount((int) Math.min(ticks, 64)); + swItem.setEnchanted(true); + } + swItem.setLore(Arrays.asList("§7Click to edit")); + return swItem; + } + + @Override + public void execute(Runnable nextAction) { + if (location.getBlock().getType() != material) { + nextAction.run(); + return; + } + if (noop) { + nextAction.run(); + return; + } + + BlockData blockData = location.getBlock().getBlockData(); + if (blockData instanceof AnaloguePowerable) { + AnaloguePowerable analoguePowerable = (AnaloguePowerable) location.getBlock().getBlockData(); + analoguePowerable.setPower(power); + } else if (blockData instanceof Powerable) { + Powerable powerable = (Powerable) location.getBlock().getBlockData(); + if (ticks < 0) { + powerable.setPowered(power > 0); + } else { + powerable.setPowered(true); + } + } + + location.getBlock().setBlockData(blockData); + update(location.getBlock()); + if (ticks >= 0) { + boolean finalWaitFor = waitFor; + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + if (blockData instanceof AnaloguePowerable) { + ((AnaloguePowerable) blockData).setPower(0); + } else { + ((Powerable) blockData).setPowered(false); + } + location.getBlock().setBlockData(blockData); + update(location.getBlock()); + if (finalWaitFor) { + nextAction.run(); + } + }, ticks); + if (!finalWaitFor) { + nextAction.run(); + } + } + } + + @Override + public void click(Player player, Runnable backAction, Runnable deleteAction) { + SWInventory swInventory = new SWInventory(player, analogue ? 45 : 27, "Settings"); + for (int i = analogue ? 36 : 18; i < (analogue ? 44 : 26); i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7")); + swInventory.setItem(analogue ? 36 : 18, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run()); + swInventory.setItem(analogue ? 44 : 26, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run()); + + swInventory.setItem(3, item(player, true, false).getItemStack(), clickType -> { + noop = true; + click(player, backAction, deleteAction); + }); + if (ticks >= 0) { + swInventory.setItem(5, item(player, false, false).getItemStack(), clickType -> { + noop = false; + waitFor = false; + click(player, backAction, deleteAction); + }); + swInventory.setItem(6, item(player, false, true).getItemStack(), clickType -> { + noop = false; + waitFor = true; + click(player, backAction, deleteAction); + }); + } + + swInventory.setItem(12, new SWItem(SWItem.getDye(1), "§c-1").getItemStack(), clickType -> { + ticks -= clickType.isShiftClick() ? 5 : 1; + if (ticks < 1) ticks = 1; + swInventory.setItem(13, item(player)); + }); + swInventory.setItem(13, item(player).getItemStack(), clickType -> { + SWAnvilInv swAnvilInv = new SWAnvilInv(player, "Ticks", ticks + ""); + swAnvilInv.setCallback(s -> { + try { + ticks = Long.parseLong(s); + if (ticks < 1) ticks = 1; + } catch (NumberFormatException ignored) { + } + click(player, backAction, deleteAction); + }); + swAnvilInv.open(); + }); + swInventory.setItem(14, new SWItem(SWItem.getDye(10), "§a+1").getItemStack(), clickType -> { + ticks += clickType.isShiftClick() ? 5 : 1; + swInventory.setItem(13, item(player)); + }); + + if (analogue) { + for (int i = 0; i < 16; i++) { + int finalI = i; + int finalI2 = i; + if (i >= 9) finalI2++; + swInventory.setItem(finalI2 + 18, item(player, finalI).getItemStack(), clickType -> { + power = finalI; + click(player, backAction, deleteAction); + }); + } + } + + swInventory.open(); + } + + private SWItem item(Player player, boolean noop, boolean waitFor) { + SWItem swItem = menu(player, noop, waitFor); + if (swItem.getItemStack().equals(menu(player, this.noop, this.waitFor).getItemStack())) { + swItem.setEnchanted(true); + } + swItem.setLore(Collections.emptyList()); + return swItem; + } + + private SWItem item(Player player, int power) { + SWItem swItem = new SWItem(power == 0 ? Material.GUNPOWDER : Material.REDSTONE, "§7Power §8:§e " + power); + swItem.getItemStack().setAmount(power == 0 ? 1 : power); + if (!this.noop && this.power == power) swItem.setEnchanted(true); + return swItem; + } + + private SWItem item(Player player) { + SWItem swItem = new SWItem(Material.CLOCK, "§7Ticks§8: §e" + ticks); + swItem.getItemStack().setAmount((int) Math.min(ticks, 64)); + swItem.setLore(Arrays.asList("§7Click to edit")); + return swItem; + } + } + + @Override + public SWItem menu(Player player) { + SWItem swItem = new SWItem(material, "§7" + name); + swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit")); + return swItem; + } + + @Override + public MovementSettings createNewElement() { + return new MovementSettings(); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTicks.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTicks.java index 54e63d34..8e203d7d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTicks.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTicks.java @@ -35,12 +35,12 @@ import org.bukkit.entity.Player; import java.util.Arrays; import java.util.Collections; -public class LoaderTicks extends LoaderInteractionElement { +public class LoaderTicks extends LoaderInteractionElement { - protected String name; - protected Material material; - protected boolean analogue; - protected int ticks; + private String name; + private Material material; + private boolean analogue; + private int ticks; public LoaderTicks(Location location, String name, Material material, int ticks) { super(location); @@ -50,7 +50,7 @@ public class LoaderTicks extends LoaderInteractionElement { try { delay = Long.parseLong(s); + if (delay < 0) delay = 0; } catch (NumberFormatException ignored) { } click(player, backAction);