From 98410c85c79c62d99180468698f1f4abc7c7e55a Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 18 Apr 2021 21:58:54 +0200 Subject: [PATCH] Loader v! Signed-off-by: Chaoscaot --- BauSystem_Main/build.gradle | 4 +- .../bausystem/features/loader/Loader.java | 191 ++++++++++++++++++ .../features/loader/LoaderButton.java | 85 ++++++++ .../features/loader/LoaderCommand.java | 78 +++++++ .../activations/AbstractLoaderActivation.java | 36 ++++ .../BlockPlaceLoaderActivation.java | 56 +++++ .../activations/InteractionActivation.java | 168 +++++++++++++++ 7 files changed, 616 insertions(+), 2 deletions(-) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderButton.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/AbstractLoaderActivation.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/BlockPlaceLoaderActivation.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/InteractionActivation.java diff --git a/BauSystem_Main/build.gradle b/BauSystem_Main/build.gradle index 80be0760..3dcb25f8 100644 --- a/BauSystem_Main/build.gradle +++ b/BauSystem_Main/build.gradle @@ -1,7 +1,7 @@ /* * This file is a part of the SteamWar software. * - * Copyright (C) 2020 SteamWar.de-Serverteam + * Copyright (C) 2021 SteamWar.de-Serverteam * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -46,7 +46,7 @@ dependencies { implementation project(":BauSystem_15") implementation project(":BauSystem_API") - implementation 'yoyosource:YAPION:0.25.1' + implementation 'yoyosource:YAPION:0.25.0' compileOnly 'org.projectlombok:lombok:1.18.6' testCompileOnly 'org.projectlombok:lombok:1.18.6' diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java new file mode 100644 index 00000000..b1af5c77 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java @@ -0,0 +1,191 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.loader; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.config.ColorConfig; +import de.steamwar.bausystem.features.loader.activations.AbstractLoaderActivation; +import de.steamwar.bausystem.features.loader.activations.BlockPlaceLoaderActivation; +import de.steamwar.bausystem.features.loader.activations.InteractionActivation; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.scheduler.BukkitTask; + +import java.util.*; + +public class Loader implements Listener { + + private static final Map LOADER_MAP = new HashMap<>(); + @Getter + private final Player p; + @Getter + private final List actions = new LinkedList<>(); + private final BukkitTask task; + @Getter + private final int ticksBetweenShots = 80; + @Getter + private final int ticksBetweenBlocks = 1; + @Getter + private Stage stage; + @Getter + private int lastActivation = -1; + @Getter + @Setter + private int countdown = 0; + private AbstractLoaderActivation current; + private ListIterator iterator; + + private Loader(Player p) { + this.p = p; + stage = Stage.SETUP; + Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance()); + task = Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), this::run, 1, 1); + } + + public static Loader getLoader(Player p) { + return LOADER_MAP.getOrDefault(p, null); + } + + public static Loader newLoader(Player p) { + return LOADER_MAP.put(p, new Loader(p)); + } + + public void start() { + iterator = actions.listIterator(); + countdown = 0; + current = null; + stage = Stage.RUNNING; + } + + public void pause() { + if (stage == Stage.PAUSE) { + resume(); + return; + } + stage = Stage.PAUSE; + } + + public void resume() { + stage = Stage.RUNNING; + } + + public void setup() { + stage = Stage.SETUP; + iterator = null; + current = null; + countdown = 0; + } + + public void stop() { + stage = Stage.END; + task.cancel(); + LOADER_MAP.remove(p, this); + } + + public void clear() { + actions.clear(); + } + + public void run() { + if (stage == Stage.SETUP && lastActivation >= 0) + lastActivation++; + + if (stage != Stage.RUNNING) { + return; + } + + if (countdown-- > 0) { + return; + } + + if (!iterator.hasNext()) { + countdown = getTicksBetweenShots(); + iterator = actions.listIterator(); + return; + } + + current = iterator.next(); + + try { + current.execute(); + countdown = current.delay(this); + } catch (Exception e) { + pause(); + p.sendMessage(BauSystem.PREFIX + ColorConfig.ERROR + "Ein Fehler beim ausführen ist passiert, Autoloader wurde pausiert."); + } + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) { + if (event.getPlayer() != p) { + return; + } + + if (stage != Stage.SETUP) { + return; + } + + if (event.getBlock().getType() != Material.TNT) { + return; + } + + actions.add(new BlockPlaceLoaderActivation(p, event.getBlock().getLocation(), Material.TNT)); + SWUtils.sendToActionbar(p, ColorConfig.HIGHLIGHT + "TNT hinzugefügt " + actions.size()); + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getPlayer() != p) { + return; + } + + if (stage != Stage.SETUP) { + return; + } + + if (LoaderButton.fromBlock(event.getClickedBlock()) != LoaderButton.INVALID) { + actions.add(InteractionActivation.construct(p, event.getClickedBlock().getLocation(), this)); + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (event.getPlayer() != p) { + return; + } + stop(); + } + + private enum Stage { + SETUP, + RUNNING, + PAUSE, + END + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderButton.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderButton.java new file mode 100644 index 00000000..87b230d5 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderButton.java @@ -0,0 +1,85 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.loader; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.block.Block; + +@AllArgsConstructor +public enum LoaderButton { + SWITCH(0, true, "Hebel"), + WOOD_BUTTON(30, "Knopf"), + STONE_BUTTON(20, "Knopf"), + PRESSURE_PLATE(30, "Druckplatte"), + WEIGHTED_PRESSURE_PLATE(20, "Druckplatte"), + TRIPWIRE(30, "Tripwire"), + NOTEBLOCK(1, "Noteblock"), + DAYLIGHTSENSOR(0, true, "Tageslichtsensor"), + INVALID(-1, "Invalider"); + + @Getter + private final int time; + @Getter + private final boolean toggle; + @Getter + private final String name; + + LoaderButton(int time, String name) { + this.time = time; + this.name = name; + toggle = false; + } + + public static LoaderButton fromBlock(Block block) { + switch (block.getType()) { + case LEVER: + return LoaderButton.SWITCH; + case ACACIA_BUTTON: + case BIRCH_BUTTON: + case DARK_OAK_BUTTON: + case JUNGLE_BUTTON: + case OAK_BUTTON: + case SPRUCE_BUTTON: + return LoaderButton.WOOD_BUTTON; + case STONE_BUTTON: + return LoaderButton.STONE_BUTTON; + case ACACIA_PRESSURE_PLATE: + case BIRCH_PRESSURE_PLATE: + case DARK_OAK_PRESSURE_PLATE: + case JUNGLE_PRESSURE_PLATE: + case OAK_PRESSURE_PLATE: + case SPRUCE_PRESSURE_PLATE: + case STONE_PRESSURE_PLATE: + return LoaderButton.PRESSURE_PLATE; + case HEAVY_WEIGHTED_PRESSURE_PLATE: + case LIGHT_WEIGHTED_PRESSURE_PLATE: + return LoaderButton.WEIGHTED_PRESSURE_PLATE; + case TRIPWIRE: + return LoaderButton.TRIPWIRE; + case NOTE_BLOCK: + return LoaderButton.NOTEBLOCK; + case DAYLIGHT_DETECTOR: + return LoaderButton.DAYLIGHTSENSOR; + default: + return LoaderButton.INVALID; + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java new file mode 100644 index 00000000..31bcbc10 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java @@ -0,0 +1,78 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.loader; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.config.ColorConfig; +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; + +@Linked(LinkageType.COMMAND) +public class LoaderCommand extends SWCommand { + + protected LoaderCommand() { + super("loader", "autoloader", "al"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("@Help@"); + } + + private boolean loaderNullCheck(Loader loader, Player p) { + if (loader == null) { + p.sendMessage(BauSystem.PREFIX + ColorConfig.ERROR + "Du hast noch keinen Loader. Erstelle dir einen mit /loader setup"); + return true; + } + + return false; + } + + @Register("setup") + public void setupLoader(Player p) { + if (Loader.getLoader(p) != null) { + Loader.getLoader(p).setup(); + p.sendMessage(BauSystem.PREFIX + ColorConfig.HIGHLIGHT + "Dein Loader ist nun wieder im Setup"); + } else { + Loader.newLoader(p); + p.sendMessage(BauSystem.PREFIX + ColorConfig.HIGHLIGHT + "Belade und feuer einmal die Kanone ab, um den Loader zu initialisieren."); + } + } + + @Register("start") + public void startLoader(Player p) { + Loader loader = Loader.getLoader(p); + if (loaderNullCheck(loader, p)) + return; + loader.start(); + p.sendMessage(BauSystem.PREFIX + ColorConfig.HIGHLIGHT + "Der Loader ist nun aktiviert."); + } + + @Register("stop") + public void stopLoader(Player p) { + Loader loader = Loader.getLoader(p); + if (loaderNullCheck(loader, p)) + return; + loader.stop(); + p.sendMessage(BauSystem.PREFIX + ColorConfig.HIGHLIGHT + "Der Loader ist nun gestoppt."); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/AbstractLoaderActivation.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/AbstractLoaderActivation.java new file mode 100644 index 00000000..3afb8750 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/AbstractLoaderActivation.java @@ -0,0 +1,36 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.loader.activations; + +import de.steamwar.bausystem.features.loader.Loader; +import org.bukkit.entity.Player; + +public abstract class AbstractLoaderActivation { + + Player p; + + public AbstractLoaderActivation(Player p) { + this.p = p; + } + + public abstract void execute(); + + public abstract int delay(Loader loader); +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/BlockPlaceLoaderActivation.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/BlockPlaceLoaderActivation.java new file mode 100644 index 00000000..b433000d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/BlockPlaceLoaderActivation.java @@ -0,0 +1,56 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.loader.activations; + +import de.steamwar.bausystem.features.loader.Loader; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +public class BlockPlaceLoaderActivation extends AbstractLoaderActivation { + + private final Location location; + private final Material material; + + public BlockPlaceLoaderActivation(Player p, Location location, Material material) { + super(p); + this.location = location; + if (!material.isBlock()) { + throw new IllegalStateException("Only Blocks, " + material.name() + " is not a Block"); + } + this.material = material; + } + + @Override + public void execute() { + Block currBlock = location.getBlock(); + if (currBlock.getType() != Material.AIR && currBlock.getType() != Material.WATER) { + return; + } + + currBlock.setType(material, true); + } + + @Override + public int delay(Loader loader) { + return loader.getTicksBetweenBlocks(); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/InteractionActivation.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/InteractionActivation.java new file mode 100644 index 00000000..11957f03 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/activations/InteractionActivation.java @@ -0,0 +1,168 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.loader.activations; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.loader.Loader; +import de.steamwar.bausystem.features.loader.LoaderButton; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.*; +import org.bukkit.block.data.type.DaylightDetector; +import org.bukkit.block.data.type.Switch; +import org.bukkit.entity.Player; + +public abstract class InteractionActivation extends AbstractLoaderActivation { + + Location location; + LoaderButton button; + + InteractionActivation(Player p, Location location, LoaderButton button) { + super(p); + this.location = location; + this.button = button; + } + + public static InteractionActivation construct(Player p, Location location, Loader loader) { + LoaderButton button = LoaderButton.fromBlock(location.getBlock()); + if (button.isToggle()) { + return new ToggleActivation(p, location, button, loader.getLastActivation()); + } else { + return new TimedActivation(p, location, button); + } + } + + void updateButton() { + Block block = location.getBlock(); + if (block.getBlockData() instanceof Switch) { + Switch sw = (Switch) block.getBlockData(); + FaceAttachable.AttachedFace face = sw.getAttachedFace(); + if (face == FaceAttachable.AttachedFace.FLOOR) { + update(block.getRelative(BlockFace.DOWN)); + } else if (face == FaceAttachable.AttachedFace.CEILING) { + update(block.getRelative(BlockFace.UP)); + } else { + update(block.getRelative(sw.getFacing().getOppositeFace())); + } + } else if (button == LoaderButton.TRIPWIRE) { + update(block); + } else if (button == LoaderButton.PRESSURE_PLATE || button == LoaderButton.WEIGHTED_PRESSURE_PLATE) { + update(block.getRelative(BlockFace.DOWN)); + } + } + + void update(Block block) { + BlockData data = block.getBlockData(); + block.setType(Material.BARRIER, true); + block.setBlockData(data, true); + } + + boolean getBlockPower() { + Block block = location.getBlock(); + BlockData data = block.getBlockData(); + if (data instanceof Powerable) { + Powerable pow = (Powerable) data; + return pow.isPowered(); + } + if (data instanceof DaylightDetector) { + DaylightDetector detector = (DaylightDetector) data; + return detector.isInverted(); + } + if (data instanceof AnaloguePowerable) { + AnaloguePowerable powerable = (AnaloguePowerable) data; + return powerable.getPower() > 0; + } + return false; + } + + void setBlockPower(boolean state) { + Block block = location.getBlock(); + BlockData data = block.getBlockData(); + if (data instanceof Powerable) { + Powerable pow = (Powerable) data; + pow.setPowered(state); + } + if (data instanceof Openable) { + Openable openable = (Openable) data; + openable.setOpen(state); + } + if (data instanceof DaylightDetector) { + DaylightDetector detector = (DaylightDetector) data; + detector.setInverted(state); + } + if (data instanceof AnaloguePowerable) { + AnaloguePowerable powerable = (AnaloguePowerable) data; + if (block.getType() == Material.REDSTONE_WIRE) { + powerable.setPower(state ? 15 : 0); + } else { + powerable.setPower(state ? 1 : 0); + } + } + block.setBlockData(data); + } + + public static class ToggleActivation extends InteractionActivation { + + private final int delay; + + public ToggleActivation(Player p, Location location, LoaderButton button, int delay) { + super(p, location, button); + this.delay = Math.max(delay, 0); + } + + @Override + public void execute() { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + setBlockPower(getBlockPower()); + updateButton(); + }, delay); + } + + @Override + public int delay(Loader loader) { + return delay; + } + } + + public static class TimedActivation extends InteractionActivation { + + public TimedActivation(Player p, Location location, LoaderButton button) { + super(p, location, button); + } + + @Override + public void execute() { + setBlockPower(true); + updateButton(); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + setBlockPower(getBlockPower()); + updateButton(); + }, button.getTime()); + } + + @Override + public int delay(Loader loader) { + return button.getTime(); + } + } +}