+ * All players in an edit world have one wrapper object that is an instance of EditPlayer.
+ *
+ * @author Daniel Saukel
+ */
+public interface EditPlayer extends InstancePlayer {
+
+ /**
+ * Returns the {@link de.erethon.dungeonsxl.api.world.EditWorld} the player is editing.
+ *
+ * @return the {@link de.erethon.dungeonsxl.api.world.EditWorld} the player is editing
+ */
+ EditWorld getEditWorld();
+
+ /**
+ * Returns the lines of a sign the player has copied with a stick tool in an array with the length of four.
+ *
+ * @return the lines of a sign the player has copied with a stick tool in an array with the length of four
+ */
+ String[] getCopiedLines();
+
+ /**
+ * Sets the memorized sign lines.
+ *
+ * @param copiedLines the lines
+ */
+ void setCopiedLines(String[] copiedLines);
+
+ /**
+ * Makes the player leave the edit world without saving the progress.
+ */
+ void escape();
+
+}
diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/player/GamePlayer.java b/api/src/main/java/de/erethon/dungeonsxl/api/player/GamePlayer.java
new file mode 100644
index 00000000..2ff84a93
--- /dev/null
+++ b/api/src/main/java/de/erethon/dungeonsxl/api/player/GamePlayer.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2012-2020 Frank Baumann
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ * All players in a game world have one wrapper object that is an instance of GamePlayer. + * + * @author Daniel Saukel + */ +public interface GamePlayer extends InstancePlayer { + + /** + * Returns if the player is ready to start the game. + *
+ * This is usually achieved by triggering a ready sign. + * + * @return if the player is ready to start the game + */ + boolean isReady(); + + /** + * Returns if the player finished the game. + *
+ * This is usually achieved by triggering an end sign. + *
+ * It is used for both the end of a whole dungeon and the end of a floor. + * + * @return if the player finished the game + */ + boolean isFinished(); + + /** + * Sets if the player finished their game. + * + * @param finished if the player finished the game + */ + void setFinished(boolean finished); + + /** + * Returns the player's class or null if they have none. + * + * @return the player's class + */ + PlayerClass getPlayerClass(); + + /** + * Sets and applies the given class. + * + * @param playerClass the class + */ + void setPlayerClass(PlayerClass playerClass); + + /** + * Returns the location of the last checkpoint the player reached. + * + * @return the location of the last checkpoint the player reached + */ + Location getLastCheckpoint(); + + /** + * Sets the location of the last checkpoint the player reached. + *
+ * This is where the player respawns if they die and have -1 or >0 {@link #getLives() lives} left. + * + * @param checkpoint the checkpoint location + */ + void setLastCheckpoint(Location checkpoint); + + /** + * Returns the saved time millis from when the player went offline. + * + * @return the saved time millis from when the player went offline + */ + long getOfflineTimeMillis(); + + /** + * Sets the saved time millis from when the player went offline. + * + * @param time the time millis + */ + void setOfflineTimeMillis(long time); + + /** + * Returns the original amount of lives the player had in the current game or -1 if lives aren't used. + * + * @return the original amount of lives the player had in the current game or -1 if lives aren't used + */ + int getInitialLives(); + + /** + * Sets the original amount of lives the player had in the current game; -1 means lives aren't used. + * + * @param lives the amount of lives + */ + void setInitialLives(int lives); + + /** + * Returns the lives the player has left or -1 if per player lives aren't used. + * + * @return the lives the player has left or -1 if per player lives aren't used + */ + int getLives(); + + /** + * Sets the lives the player has left. + *
+ * This is not to be used if the dungeon uses group lives. + * + * @param lives the lives + */ + void setLives(int lives); + + /** + * Returns if the player is stealing another group's flag. + * + * @return if the player is stealing another group's flag + */ + boolean isStealingFlag(); + + /** + * Returns the group whose flag the player robbed; null if the player isn't stealing any. + * + * @return the group whose flag the player robbed; null if the player isn't stealing any + */ + PlayerGroup getRobbedGroup(); + + /** + * Sets the player to be stealing the team flag of the given group. + * + * @param group the group + */ + void setRobbedGroup(PlayerGroup group); + + /* Actions */ + /** + * Scores a point. + */ + void captureFlag(); + + /** + * Makes the player leave his group and dungeon. + *
+ * This sends default messages to the player. + */ + @Override + default void leave() { + leave(true); + } + + /** + * Makes the player leave his group and dungeon. + * + * @param sendMessages if default messages shall be sent to the player + */ + void leave(boolean sendMessages); + + /** + * Treats the player as if they lost their last life and kicks them from the dungeon. + */ + void kill(); + + /** + * Sets the player to be ready to start the dungeon game, like when a ready sign is triggered. + *
+ * If all other players in the group are already {@link #isReady() ready}, the game is started. + * + * @return if the game has been started. + */ + boolean ready(); + + /** + * Respawns the player. Also teleports DXL pets if there are any. + */ + void respawn(); + + /** + * The player finishs the current game. + *
+ * This sends default messages to the player.
+ */
+ default void finish() {
+ finish(true);
+ }
+
+ /**
+ * The player finishs the current game.
+ *
+ * @param sendMessages if default messages shall be sent to the player
+ */
+ void finish(boolean sendMessages);
+
+}
diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/player/GlobalPlayer.java b/api/src/main/java/de/erethon/dungeonsxl/api/player/GlobalPlayer.java
new file mode 100644
index 00000000..b5782975
--- /dev/null
+++ b/api/src/main/java/de/erethon/dungeonsxl/api/player/GlobalPlayer.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2012-2020 Frank Baumann
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ * All players on the server, including the ones in dungeons, have one wrapper object that is an instance of GlobalPlayer.
+ *
+ * @author Daniel Saukel
+ */
+public interface GlobalPlayer extends PlayerWrapper {
+
+ /**
+ * Returns the player's group.
+ *
+ * @return the player's group.
+ */
+ PlayerGroup getGroup();
+
+ /**
+ * Returns if the player uses the built-in group chat.
+ *
+ * @return if the player uses the built-in group chat
+ */
+ boolean isInGroupChat();
+
+ /**
+ * Sets if the player uses the built-in group chat.
+ *
+ * @param groupChat if the player shall use the built-in group chat
+ */
+ void setInGroupChat(boolean groupChat);
+
+ /**
+ * Returns if the player may read messages from the built-in group chat.
+ *
+ * @return if the player may read messages from the built-in group chat
+ */
+ boolean isInChatSpyMode();
+
+ /**
+ * Sets if the player may read messages from the built-in group chat.
+ *
+ * @param chatSpyMode if the player may read messages from the built-in group chat
+ */
+ void setInChatSpyMode(boolean chatSpyMode);
+
+ /**
+ * Checks if the player has the given permission.
+ *
+ * @param permission the permission
+ * @return if the player has the given permission
+ */
+ default boolean hasPermission(String permission) {
+ return getPlayer().hasPermission(permission);
+ }
+
+ /**
+ * Returns the reward items a player collected in a dungeon game.
+ *
+ * @return the reward items a player collected in a dungeon game
+ */
+ public List
+ * All players in a world instantiated by DungeonsXL, have one wrapper object that is an instance of InstancePlayer.
+ *
+ * @author Daniel Saukel
+ */
+public interface InstancePlayer extends GlobalPlayer {
+
+ /**
+ * The world of the instance, where the player is supposed to be.
+ *
+ * @return the world of the instance
+ */
+ World getWorld();
+
+ /**
+ * Makes the player leave his group and dungeon.
+ */
+ void leave();
+
+}
diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/player/PlayerClass.java b/api/src/main/java/de/erethon/dungeonsxl/api/player/PlayerClass.java
new file mode 100644
index 00000000..b0aba711
--- /dev/null
+++ b/api/src/main/java/de/erethon/dungeonsxl/api/player/PlayerClass.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2012-2020 Frank Baumann
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ * This is the name used e.g. in messages.
+ *
+ * @return the formatted name
+ */
+ String getName();
+
+ /**
+ * Returns the raw, unformatted name.
+ *
+ * This is the name used e.g. in command arguments.
+ *
+ * @return the raw, unformatted name
+ */
+ String getRawName();
+
+ /**
+ * Sets the name.
+ *
+ * @param name the name
+ */
+ void setName(String name);
+
+ /**
+ * Sets the name to a default value taken from the color.
+ *
+ * In the default implementation, this is nameOfTheColor#{@link #getId()}
+ *
+ * @param color the color
+ */
+ default void setName(Color color) {
+ setName(color.toString() + "#" + getId());
+ }
+
+ /**
+ * The player who has permission to manage the group.
+ *
+ * @return the player who has permission to manage the group
+ */
+ Player getLeader();
+
+ /**
+ * Sets the leader to another group member.
+ *
+ * @param player the new leader
+ */
+ void setLeader(Player player);
+
+ /**
+ * Returns a PlayerCollection of the group members
+ *
+ * @return a PlayerCollection of the group members
+ */
+ PlayerCollection getMembers();
+
+ /**
+ * Adds a player to the group.
+ *
+ * The default implemenation calls {@link #addPlayer(Player, boolean)} with messages set to true.
+ *
+ * @param player the player to add
+ */
+ default void addPlayer(Player player) {
+ addPlayer(player, true);
+ }
+
+ /**
+ * Adds a player to the group.
+ *
+ * @param player the player to add
+ * @param message if messages shall be sent
+ */
+ void addPlayer(Player player, boolean message);
+
+ /**
+ * Removes a player from the group.
+ *
+ * The default implemenation calls {@link #removePlayer(Player, boolean)} with messages set to true.
+ *
+ * @param player the player to add
+ */
+ default void removePlayer(Player player) {
+ addPlayer(player, true);
+ }
+
+ /**
+ * Removes a player from the group.
+ *
+ * @param player the player to add
+ * @param message if messages shall be sent
+ */
+ void removePlayer(Player player, boolean message);
+
+ /**
+ * Returns a PlayerCollection of the players who are invited to join the group but did not yet do so.
+ *
+ * @return a PlayerCollection of the players who are invited to join the group but did not yet do so
+ */
+ PlayerCollection getInvitedPlayers();
+
+ /**
+ * Invites a player to join the group.
+ *
+ * @param player the player to invite
+ * @param message if messages shall be sent
+ */
+ void addInvitedPlayer(Player player, boolean message);
+
+ /**
+ * Removes an invitation priviously made for a player to join the group.
+ *
+ * @param player the player to uninvite
+ * @param message if messages shall be sent
+ */
+ void removeInvitedPlayer(Player player, boolean message);
+
+ /**
+ * Removes all invitations for players who are not online.
+ */
+ void clearOfflineInvitedPlayers();
+
+ /**
+ * Returns the game world the group is in.
+ *
+ * @return the game world the group is in
+ */
+ GameWorld getGameWorld();
+
+ /**
+ * Sets the game world the group is in.
+ *
+ * @param gameWorld the game world to set
+ */
+ void setGameWorld(GameWorld gameWorld);
+
+ /**
+ * Returns the dungeon the group is playing or has remembered to play next.
+ *
+ * The latter is for example used when a group is created by a group sign sothat a portal or the auto-join function knows where to send the group.
+ *
+ * @return the dungeon the group is playing or has remembered to play next
+ */
+ Dungeon getDungeon();
+
+ /**
+ * Returns if the group is already playing its remembered {@link #getDungeon() dungeon}.
+ *
+ * @return if the group is already playing its remembered {@link #getDungeon() dungeon}
+ */
+ boolean isPlaying();
+
+ /**
+ * Returns the amount of lives the group currently has left or -1 if group lives are not used.
+ *
+ * @return the amount of lives the group currently has left or -1 if group lives are not used
+ */
+ int getLives();
+
+ /**
+ * Sets the amount of lives the group currently has left.
+ *
+ * The value must be >=0 or -1, which means unlimited lives.
+ *
+ * @param lives the amount of lives the group currently has left
+ */
+ void setLives(int lives);
+
+}
diff --git a/api/src/main/java/de/erethon/dungeonsxl/util/DColor.java b/api/src/main/java/de/erethon/dungeonsxl/util/DColor.java
deleted file mode 100644
index a5a24826..00000000
--- a/api/src/main/java/de/erethon/dungeonsxl/util/DColor.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2012-2019 Frank Baumann
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see