diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/DungeonsAPI.java b/api/src/main/java/de/erethon/dungeonsxl/api/DungeonsAPI.java index ba6ee457..bca9a15a 100644 --- a/api/src/main/java/de/erethon/dungeonsxl/api/DungeonsAPI.java +++ b/api/src/main/java/de/erethon/dungeonsxl/api/DungeonsAPI.java @@ -15,18 +15,18 @@ package de.erethon.dungeonsxl.api; import de.erethon.commons.misc.Registry; -import de.erethon.dungeonsxl.api.dungeon.Dungeon; import de.erethon.dungeonsxl.api.player.PlayerClass; import de.erethon.dungeonsxl.api.player.PlayerGroup; -import de.erethon.dungeonsxl.api.sign.DungeonSignType; +import de.erethon.dungeonsxl.api.sign.DungeonSign; import java.io.File; import java.util.Collection; import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; /** * @author Daniel Saukel */ -public interface DungeonsAPI { +public interface DungeonsAPI extends Plugin { static final File PLUGIN_ROOT = new File("plugins/DungeonsXL"); static final File BACKUPS = new File(PLUGIN_ROOT, "backups"); @@ -46,6 +46,20 @@ public interface DungeonsAPI { */ Registry getClassRegistry(); + /** + * Returns a {@link Registry} of the sign types. + * + * @return a {@link Registry} of the sign types + */ + Registry> getSignTypes(); + + /** + * Returns a {@link Registry} of the trigger types. + * + * @return a {@link Registry} of the trigger types + */ + Registry> getTriggerTypes(); + /* Object initialization */ /** * Creates a new group. diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/Trigger.java b/api/src/main/java/de/erethon/dungeonsxl/api/Trigger.java new file mode 100644 index 00000000..baa66f76 --- /dev/null +++ b/api/src/main/java/de/erethon/dungeonsxl/api/Trigger.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014-2020 Daniel Saukel + * + * This library is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 GNULesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package de.erethon.dungeonsxl.api; + +import org.bukkit.entity.Player; + +/** + * @deprecated stub + * + * @author Daniel Saukel + */ +@Deprecated +public interface Trigger { + + @Deprecated + boolean isTriggered(); + + @Deprecated + Player getPlayer(); + +} diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/player/PlayerGroup.java b/api/src/main/java/de/erethon/dungeonsxl/api/player/PlayerGroup.java index 99997480..6e9007c4 100644 --- a/api/src/main/java/de/erethon/dungeonsxl/api/player/PlayerGroup.java +++ b/api/src/main/java/de/erethon/dungeonsxl/api/player/PlayerGroup.java @@ -19,7 +19,7 @@ import de.erethon.caliburn.item.VanillaItem; import de.erethon.commons.chat.MessageUtil; import de.erethon.commons.compatibility.Version; import de.erethon.commons.player.PlayerCollection; -import de.erethon.dungeonsxl.api.dungeon.Dungeon; +import de.erethon.dungeonsxl.api.Dungeon; import de.erethon.dungeonsxl.api.world.GameWorld; import org.bukkit.ChatColor; import org.bukkit.DyeColor; diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/sign/AbstractDSign.java b/api/src/main/java/de/erethon/dungeonsxl/api/sign/AbstractDSign.java new file mode 100644 index 00000000..b03d0585 --- /dev/null +++ b/api/src/main/java/de/erethon/dungeonsxl/api/sign/AbstractDSign.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2014-2020 Daniel Saukel + * + * This library is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 GNULesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package de.erethon.dungeonsxl.api.sign; + +import de.erethon.caliburn.item.VanillaItem; +import de.erethon.commons.chat.MessageUtil; +import de.erethon.dungeonsxl.api.DungeonsAPI; +import de.erethon.dungeonsxl.api.Trigger; +import de.erethon.dungeonsxl.api.world.GameWorld; +import java.util.HashSet; +import java.util.Set; +import org.bukkit.ChatColor; +import org.bukkit.block.Sign; + +/** + * Skeletal implementation of {@link DungeonSign}. + * + * @author Daniel Saukel + */ +public abstract class AbstractDSign implements DungeonSign { + + public static final String ERROR_0 = ChatColor.DARK_RED + "## ERROR ##"; + public static final String ERROR_1 = ChatColor.WHITE + "Please"; + public static final String ERROR_2 = ChatColor.WHITE + "contact an"; + public static final String ERROR_3 = ChatColor.WHITE + "Admin!"; + + protected DungeonsAPI api; + private Sign sign; + private String[] lines; + private GameWorld gameWorld; + private Set triggers = new HashSet<>(); + private boolean initialized; + private boolean erroneous; + + protected AbstractDSign(DungeonsAPI api, Sign sign, String[] lines, GameWorld gameWorld) { + this.api = api; + this.sign = sign; + this.lines = lines; + this.gameWorld = gameWorld; + } + + @Override + public Sign getSign() { + return sign; + } + + @Override + public String[] getLines() { + return lines; + } + + @Override + public GameWorld getGameWorld() { + return gameWorld; + } + + @Override + public Set getTriggers() { + return triggers; + } + + @Override + public void addTrigger(Trigger trigger) { + triggers.add(trigger); + } + + @Override + public void removeTrigger(Trigger trigger) { + triggers.remove(trigger); + } + + @Override + public boolean isInitialized() { + return initialized; + } + + @Override + public boolean setToAir() { + sign.getBlock().setType(VanillaItem.AIR.getMaterial()); + return true; + } + + @Override + public boolean isErroneous() { + return erroneous; + } + + @Override + public void markAsErroneous(String reason) { + erroneous = true; + sign.setLine(0, ERROR_0); + sign.setLine(1, ERROR_1); + sign.setLine(2, ERROR_2); + sign.setLine(3, ERROR_3); + sign.update(); + + MessageUtil.log(api, "&4A sign at &6" + sign.getX() + ", " + sign.getY() + ", " + sign.getZ() + "&4 is erroneous!"); + MessageUtil.log(api, getName() + ": " + reason); + } + +} diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/sign/Button.java b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Button.java new file mode 100644 index 00000000..d27451ca --- /dev/null +++ b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Button.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014-2020 Daniel Saukel + * + * This library is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 GNULesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package de.erethon.dungeonsxl.api.sign; + +import de.erethon.dungeonsxl.api.DungeonsAPI; +import de.erethon.dungeonsxl.api.Trigger; +import de.erethon.dungeonsxl.api.world.GameWorld; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; + +/** + * @author Daniel Saukel + */ +public abstract class Button extends AbstractDSign { + + protected Button(DungeonsAPI api, Sign sign, String[] lines, GameWorld gameWorld) { + super(api, sign, lines, gameWorld); + } + + public void push() { + getGameWorld().getPlayers().forEach(p -> push(p.getPlayer())); + } + + public boolean push(Player player) { + push(); + return true; + } + + @Override + public void update() { + if (isErroneous()) { + return; + } + + for (Trigger trigger : getTriggers()) { + if (!trigger.isTriggered()) { + return; + } + + if (trigger.getPlayer() == null) { + continue; + } + + if (push(trigger.getPlayer())) { + return; + } + } + + push(); + } + + /** + * This is the same as {@link #push(org.bukkit.entity.Player)}. + * + * @param player the player + */ + @Override + public void trigger(Player player) { + push(player); + } + +} diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/sign/Deactivatable.java b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Deactivatable.java new file mode 100644 index 00000000..a751f461 --- /dev/null +++ b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Deactivatable.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2014-2020 Daniel Saukel + * + * This library is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 GNULesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package de.erethon.dungeonsxl.api.sign; + +import de.erethon.commons.player.PlayerCollection; +import de.erethon.dungeonsxl.api.DungeonsAPI; +import de.erethon.dungeonsxl.api.Trigger; +import de.erethon.dungeonsxl.api.world.GameWorld; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; + +/** + * A {@link DungeonSign} that changes its state when triggered. + * + * @author Daniel Saukel + */ +public abstract class Deactivatable extends AbstractDSign { + + protected boolean active; + private PlayerCollection playersActivated = new PlayerCollection(); + + protected Deactivatable(DungeonsAPI api, Sign sign, String[] lines, GameWorld gameWorld) { + super(api, sign, lines, gameWorld); + } + + public void activate() { + active = true; + } + + public boolean activate(Player player) { + return playersActivated.add(player); + } + + public void deactivate() { + active = false; + } + + public boolean deactivate(Player player) { + return playersActivated.remove(player); + } + + public boolean isActive() { + return active; + } + + public boolean isActive(Player player) { + return playersActivated.contains(player); + } + + @Override + public void update() { + if (isErroneous()) { + return; + } + + for (Trigger trigger : getTriggers()) { + if (!trigger.isTriggered()) { + deactivate(); + return; + } + + if (trigger.getPlayer() == null) { + continue; + } + + if (activate(trigger.getPlayer())) { + return; + } + } + + activate(); + } + +} diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/sign/DungeonSign.java b/api/src/main/java/de/erethon/dungeonsxl/api/sign/DungeonSign.java new file mode 100644 index 00000000..78df378d --- /dev/null +++ b/api/src/main/java/de/erethon/dungeonsxl/api/sign/DungeonSign.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2014-2020 Daniel Saukel + * + * This library is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 GNULesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package de.erethon.dungeonsxl.api.sign; + +import de.erethon.dungeonsxl.api.Trigger; +import de.erethon.dungeonsxl.api.world.GameWorld; +import java.util.Set; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; + +/** + * Interface for all dungeon signs. + * + * @author Frank Baumann, Milan Albrecht, Daniel Saukel + */ +public interface DungeonSign { + + /** + * Returns the name to identify the sign. + * + * @return the name + */ + String getName(); + + /** + * Returns the permission node that is required to build a sign of this type. + * + * @return the build permission + */ + String getBuildPermission(); + + /** + * Returns if the sign gets initialized when the dungeon is loaded instead of when the game starts. + * + * @return if the sign gets initialized when the dungeon is loaded instead of when the game starts + */ + boolean isOnDungeonInit(); + + /** + * Returns if the sign block is breakable after the initialization. + * + * @return if the sign block is breakable after the initialization + */ + boolean isProtected(); + + /** + * Returns if the block type of the sign is set to air after the initialization. + * + * @return if the block type of the sign is set to air after the initialization + */ + boolean isSetToAir(); + + /** + * Returns the sign that represents event point. + * + * @return the sign that represents event point + */ + Sign getSign(); + + /** + * Returns the raw lines of this sign in an array with 4 elements. + * + * @return the raw lines of this sign in an array with 4 elements + */ + String[] getLines(); + + /** + * Returns the game world this sign is in; null if this is an edit world. + * + * @return the game world this sign is in; null if this is an edit world + */ + GameWorld getGameWorld(); + + /** + * Returns a Set of the triggers registered for this sign. + * + * @return a Set of the triggers registered for this sign + */ + Set getTriggers(); + + /** + * Returns if the sign has triggers. + * + * @return if the sign has triggers + */ + default boolean hasTriggers() { + return !getTriggers().isEmpty(); + } + + /** + * Adds a trigger to the sign. + * + * @param trigger the trigger + */ + void addTrigger(Trigger trigger); + + /** + * Attempts to remove a trigger from the sign. + * + * @param trigger the trigger + */ + void removeTrigger(Trigger trigger); + + /** + * Makes the sign listen for its triggers if it {@link #hasTriggers()}. + *

+ * {@link #trigger(org.bukkit.entity.Player)}s the sign if it does not have any triggers. + * (Note that some signs have interaction triggers by default, like ready signs). + */ + void initialize(); + + /** + * Returns if the sign is {@link #initialize()}d. + * + * @return if the sign is {@link #initialize()}d + */ + boolean isInitialized(); + + /** + * Triggers the sign. The effects are defined by the implementation. + * + * @param player the player that triggered the sign or null + */ + void trigger(Player player); + + /** + * Updates the sign. + */ + void update(); + + /** + * Sets the sign to air if it is not erroneous and if its type requires this. + * + * @return if the sign type was set to air + */ + boolean setToAir(); + + /** + * Returns if the sign is valid. + * + * @return if the sign is valid + */ + default boolean validate() { + return true; + } + + /** + * Returns if the sign is erroneous. + * + * @return if the sign is erroneous + */ + boolean isErroneous(); + + /** + * Set a placeholder to show that the sign is setup incorrectly. + * + * @param reason the reason why the sign is marked as erroneous + */ + void markAsErroneous(String reason); + +} diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/sign/Passive.java b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Passive.java new file mode 100644 index 00000000..bee8a32f --- /dev/null +++ b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Passive.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014-2020 Daniel Saukel + * + * This library is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 GNULesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package de.erethon.dungeonsxl.api.sign; + +import de.erethon.dungeonsxl.api.DungeonsAPI; +import de.erethon.dungeonsxl.api.world.GameWorld; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; + +/** + * @author Daniel Saukel + */ +public abstract class Passive extends AbstractDSign { + + protected Passive(DungeonsAPI api, Sign sign, String[] lines, GameWorld gameWorld) { + super(api, sign, lines, gameWorld); + } + + @Override + public final void update() { + } + + @Override + public final void trigger(Player player) { + } + +} diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/sign/Rocker.java b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Rocker.java new file mode 100644 index 00000000..c20f368a --- /dev/null +++ b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Rocker.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014-2020 Daniel Saukel + * + * This library is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 GNULesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package de.erethon.dungeonsxl.api.sign; + +import de.erethon.dungeonsxl.api.DungeonsAPI; +import de.erethon.dungeonsxl.api.world.GameWorld; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; + +/** + * A {@link Deactivatable} that, if triggered, and already activated, is deactivated. + * + * @author Daniel Saukel + */ +public abstract class Rocker extends Deactivatable { + + protected Rocker(DungeonsAPI api, Sign sign, String[] lines, GameWorld gameWorld) { + super(api, sign, lines, gameWorld); + } + + @Override + public void trigger(Player player) { + if (!isActive()) { + activate(player); + } else { + deactivate(); + } + } + +} diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/sign/Windup.java b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Windup.java new file mode 100644 index 00000000..01404099 --- /dev/null +++ b/api/src/main/java/de/erethon/dungeonsxl/api/sign/Windup.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2014-2020 Daniel Saukel + * + * This library is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 GNULesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package de.erethon.dungeonsxl.api.sign; + +import de.erethon.dungeonsxl.api.DungeonsAPI; +import de.erethon.dungeonsxl.api.world.GameWorld; +import org.bukkit.block.Sign; + +/** + * @author Daniel Saukel + */ +public abstract class Windup extends Deactivatable { + + protected double interval = -1; + + protected Windup(DungeonsAPI api, Sign sign, String[] lines, GameWorld gameWorld) { + super(api, sign, lines, gameWorld); + } + + public double getIntervalSeconds() { + return interval; + } + + public long getIntervalTicks() { + return (long) (interval * 20L); + } + +}