Add dungeon sign API

This commit is contained in:
Daniel Saukel 2020-01-27 01:31:54 +01:00
parent 43027ae8a9
commit eb18ee9bce
10 changed files with 618 additions and 4 deletions

View File

@ -15,18 +15,18 @@
package de.erethon.dungeonsxl.api; package de.erethon.dungeonsxl.api;
import de.erethon.commons.misc.Registry; 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.PlayerClass;
import de.erethon.dungeonsxl.api.player.PlayerGroup; 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.io.File;
import java.util.Collection; import java.util.Collection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
/** /**
* @author Daniel Saukel * @author Daniel Saukel
*/ */
public interface DungeonsAPI { public interface DungeonsAPI extends Plugin {
static final File PLUGIN_ROOT = new File("plugins/DungeonsXL"); static final File PLUGIN_ROOT = new File("plugins/DungeonsXL");
static final File BACKUPS = new File(PLUGIN_ROOT, "backups"); static final File BACKUPS = new File(PLUGIN_ROOT, "backups");
@ -46,6 +46,20 @@ public interface DungeonsAPI {
*/ */
Registry<String, PlayerClass> getClassRegistry(); Registry<String, PlayerClass> getClassRegistry();
/**
* Returns a {@link Registry} of the sign types.
*
* @return a {@link Registry} of the sign types
*/
Registry<String, Class<? extends DungeonSign>> getSignTypes();
/**
* Returns a {@link Registry} of the trigger types.
*
* @return a {@link Registry} of the trigger types
*/
Registry<String, Class<? extends Trigger>> getTriggerTypes();
/* Object initialization */ /* Object initialization */
/** /**
* Creates a new group. * Creates a new group.

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
}

View File

@ -19,7 +19,7 @@ import de.erethon.caliburn.item.VanillaItem;
import de.erethon.commons.chat.MessageUtil; import de.erethon.commons.chat.MessageUtil;
import de.erethon.commons.compatibility.Version; import de.erethon.commons.compatibility.Version;
import de.erethon.commons.player.PlayerCollection; 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 de.erethon.dungeonsxl.api.world.GameWorld;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Trigger> 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<Trigger> 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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Trigger> 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()}.
* <p>
* {@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);
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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) {
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}