Update code to enter dungeons to new Game system

This commit is contained in:
Daniel Saukel 2021-02-24 20:35:37 +01:00
parent 79adbd3b31
commit 119ab85611
18 changed files with 133 additions and 216 deletions

View File

@ -186,6 +186,14 @@ public interface Game {
*/
boolean isEmpty();
/**
* Returns and, if necessary, instantiates the game world.
*
* @param ignoreLimit if the instance limit set in the main config shall be ignored
* @return the game world
*/
GameWorld ensureWorldIsLoaded(boolean ignoreLimit);
/**
* Starts the game. This is what happens when the ready sign is triggered by everyone.
*

View File

@ -294,14 +294,9 @@ public interface PlayerGroup {
*
* @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);
default GameWorld getGameWorld() {
return getGame() != null ? getGame().getWorld() : null;
}
/**
* Returns the dungeon the group is playing or has remembered to play next.

View File

@ -119,10 +119,23 @@ public interface ResourceWorld {
/**
* Returns a new game instance of this resource.
*
* @see de.erethon.dungeonsxl.api.dungeon.Game#ensureWorldIsLoaded(boolean)
* @param ignoreLimit if the instance limit set in the main config shall be ignored
* @return a new game instance of this resource
*/
GameWorld instantiateGameWorld(boolean ignoreLimit);
default GameWorld instantiateGameWorld(boolean ignoreLimit) {
return instantiateGameWorld(getSingleFloorDungeon(), ignoreLimit);
}
/**
* Returns a new game instance of this resource.
*
* @see de.erethon.dungeonsxl.api.dungeon.Game#ensureWorldIsLoaded(boolean)
* @param dungeon the dungeon this game world will be part of
* @param ignoreLimit if the instance limit set in the main config shall be ignored
* @return a new game instance of this resource
*/
GameWorld instantiateGameWorld(Dungeon dungeon, boolean ignoreLimit);
/**
* Returns the single floor dungeon of this resource.

View File

@ -17,6 +17,7 @@
package de.erethon.dungeonsxl.announcer;
import de.erethon.dungeonsxl.DungeonsXL;
import de.erethon.dungeonsxl.api.dungeon.Game;
import de.erethon.dungeonsxl.api.world.GameWorld;
import de.erethon.dungeonsxl.api.world.ResourceWorld;
import de.erethon.dungeonsxl.config.DMessage;
@ -69,7 +70,7 @@ public class AnnouncerStartGameTask extends BukkitRunnable {
return;
}
DGame game = null;
Game game = null;
for (DGroup dGroup : announcer.getDGroups()) {
if (dGroup == null) {
@ -85,18 +86,16 @@ public class AnnouncerStartGameTask extends BukkitRunnable {
cancel();
return;
}
GameWorld gameWorld = resource.instantiateGameWorld(false);
game = new DGame(plugin, dGroup.getDungeon(), dGroup);
GameWorld gameWorld = game.ensureWorldIsLoaded(false);
if (gameWorld == null) {
dGroup.sendMessage(DMessage.ERROR_TOO_MANY_INSTANCES.getMessage());
cancel();
return;
}
game = new DGame(plugin, dGroup, gameWorld);
} else {
game.addGroup(dGroup);
}
dGroup.setGameWorld(game.getWorld());
}
if (game == null) {

View File

@ -83,7 +83,6 @@ public class EnterCommand extends DCommand {
return;
}
joining.setGameWorld(game.getWorld());
game.addGroup(joining);
joining.sendMessage(DMessage.CMD_ENTER_SUCCESS.getMessage(joining.getName(), target.getName()));

View File

@ -18,6 +18,7 @@ package de.erethon.dungeonsxl.command;
import de.erethon.dungeonsxl.DungeonsXL;
import de.erethon.dungeonsxl.api.dungeon.Dungeon;
import de.erethon.dungeonsxl.api.dungeon.Game;
import de.erethon.dungeonsxl.api.event.group.GroupCreateEvent;
import de.erethon.dungeonsxl.api.player.GlobalPlayer;
import de.erethon.dungeonsxl.api.world.GameWorld;
@ -86,12 +87,12 @@ public class PlayCommand extends DCommand {
return;
}
GameWorld gameWorld = dungeon.getMap().instantiateGameWorld(false);
Game game = new DGame(plugin, dungeon, group);
GameWorld gameWorld = game.ensureWorldIsLoaded(false);
if (gameWorld == null) {
MessageUtil.sendMessage(player, DMessage.ERROR_TOO_MANY_INSTANCES.getMessage());
return;
}
new DGame(plugin, group, gameWorld);
for (Player groupPlayer : group.getMembers().getOnlinePlayers()) {
new DGamePlayer(plugin, groupPlayer, group.getGameWorld());
}

View File

@ -19,17 +19,17 @@ package de.erethon.dungeonsxl.command;
import de.erethon.dungeonsxl.DungeonsXL;
import de.erethon.dungeonsxl.api.dungeon.Dungeon;
import de.erethon.dungeonsxl.api.dungeon.Game;
import de.erethon.dungeonsxl.api.event.group.GroupCreateEvent;
import de.erethon.dungeonsxl.api.player.GlobalPlayer;
import de.erethon.dungeonsxl.api.player.PlayerGroup;
import de.erethon.dungeonsxl.api.world.GameWorld;
import de.erethon.dungeonsxl.api.world.ResourceWorld;
import de.erethon.dungeonsxl.config.DMessage;
import de.erethon.dungeonsxl.dungeon.DGame;
import de.erethon.dungeonsxl.player.DEditPlayer;
import de.erethon.dungeonsxl.player.DGamePlayer;
import de.erethon.dungeonsxl.player.DGroup;
import de.erethon.dungeonsxl.player.DInstancePlayer;
import de.erethon.dungeonsxl.player.DPermission;
import de.erethon.dungeonsxl.util.commons.chat.MessageUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -41,8 +41,8 @@ public class TestCommand extends DCommand {
public TestCommand(DungeonsXL plugin) {
super(plugin);
setCommand("test");
setMinArgs(0);
setMaxArgs(0);
setMinArgs(1);
setMaxArgs(1);
setHelp(DMessage.CMD_TEST_HELP.getMessage());
setPermission(DPermission.TEST.getNode());
setPlayerCommand(true);
@ -53,47 +53,49 @@ public class TestCommand extends DCommand {
public void onExecute(String[] args, CommandSender sender) {
Player player = (Player) sender;
GlobalPlayer dPlayer = dPlayers.get(player);
if (!(dPlayer instanceof DEditPlayer)) {
PlayerGroup dGroup = dPlayer.getGroup();
if (dGroup == null) {
MessageUtil.sendMessage(sender, DMessage.ERROR_JOIN_GROUP.getMessage());
if (dPlayer instanceof DInstancePlayer) {
MessageUtil.sendMessage(player, DMessage.ERROR_LEAVE_DUNGEON.getMessage());
return;
}
if (!dGroup.getLeader().equals(player) && !DPermission.hasPermission(player, DPermission.BYPASS)) {
MessageUtil.sendMessage(sender, DMessage.ERROR_NOT_LEADER.getMessage());
Dungeon dungeon = plugin.getDungeonRegistry().get(args[1]);
if (dungeon == null) {
MessageUtil.sendMessage(player, DMessage.ERROR_NO_SUCH_DUNGEON.getMessage(args[1]));
return;
}
GameWorld gameWorld = dGroup.getGameWorld();
DGroup group = (DGroup) dPlayer.getGroup();
if (group != null && group.isPlaying()) {
MessageUtil.sendMessage(player, DMessage.ERROR_LEAVE_GROUP.getMessage());
return;
} else if (group == null) {
group = new DGroup(plugin, player, dungeon);
GroupCreateEvent event = new GroupCreateEvent(group, dPlayer, GroupCreateEvent.Cause.COMMAND);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
plugin.getGroupCache().remove(group);
group = null;
}
}
if (!group.getLeader().equals(player) && !DPermission.hasPermission(player, DPermission.BYPASS)) {
MessageUtil.sendMessage(player, DMessage.ERROR_NOT_LEADER.getMessage());
return;
}
group.setDungeon(dungeon);
if (!dPlayer.checkRequirements(dungeon)) {
return;
}
Game game = new DGame(plugin, dungeon, group);
game.setRewards(false);
GameWorld gameWorld = game.ensureWorldIsLoaded(false);
if (gameWorld == null) {
MessageUtil.sendMessage(sender, DMessage.ERROR_NOT_IN_DUNGEON.getMessage());
return;
}
Game game = gameWorld.getGame();
if (game != null && game.hasStarted()) {
MessageUtil.sendMessage(sender, DMessage.ERROR_LEAVE_DUNGEON.getMessage());
return;
}
for (Player groupPlayer : dGroup.getMembers().getOnlinePlayers()) {
((DGamePlayer) dPlayers.getGamePlayer(groupPlayer)).ready();
}
} else {
DEditPlayer editPlayer = (DEditPlayer) dPlayer;
editPlayer.leave();
ResourceWorld resource = editPlayer.getEditWorld().getResource();
Dungeon dungeon = resource.getSingleFloorDungeon();
GameWorld instance = resource.instantiateGameWorld(false);
if (instance == null) {
MessageUtil.sendMessage(player, DMessage.ERROR_TOO_MANY_INSTANCES.getMessage());
return;
}
DGame game = new DGame(plugin, new DGroup(plugin, player, dungeon), instance);
new DGamePlayer(plugin, player, game.getWorld());
for (Player groupPlayer : group.getMembers().getOnlinePlayers()) {
new DGamePlayer(plugin, groupPlayer, group.getGameWorld());
}
}

View File

@ -30,7 +30,6 @@ import de.erethon.dungeonsxl.player.DGroup;
import de.erethon.dungeonsxl.sign.windup.MobSign;
import de.erethon.dungeonsxl.trigger.ProgressTrigger;
import de.erethon.dungeonsxl.world.DGameWorld;
import de.erethon.dungeonsxl.world.DResourceWorld;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@ -61,48 +60,26 @@ public class DGame implements Game {
private Map<String, Integer> gameKills = new HashMap<>();
private Map<String, Integer> waveKills = new HashMap<>();
public DGame(DungeonsXL plugin, PlayerGroup group) {
public DGame(DungeonsXL plugin, Dungeon dungeon) {
this.plugin = plugin;
plugin.getGameCache().add(this);
dungeon = group.getDungeon();
if (dungeon == null) {
this.dungeon = dungeon;
if (this.dungeon == null) {
throw new IllegalStateException("Game initialized without dungeon");
}
tutorial = false;
started = false;
}
public DGame(DungeonsXL plugin, Dungeon dungeon, PlayerGroup group) {
this(plugin, dungeon);
addGroup(group);
}
public DGame(DungeonsXL plugin, PlayerGroup group, GameWorld world) {
this.plugin = plugin;
plugin.getGameCache().add(this);
this.world = world;
dungeon = world.getDungeon();
if (dungeon == null) {
throw new IllegalStateException("Game initialized without dungeon");
}
tutorial = false;
started = false;
addGroup(group);
}
public DGame(DungeonsXL plugin, List<PlayerGroup> groups, GameWorld world) {
this.plugin = plugin;
plugin.getGameCache().add(this);
this.groups = groups;
this.world = world;
dungeon = world.getDungeon();
if (dungeon == null) {
throw new IllegalStateException("Game initialized without dungeon");
}
tutorial = false;
started = true;
public DGame(DungeonsXL plugin, Dungeon dungeon, List<PlayerGroup> groups) {
this(plugin, dungeon);
groups.forEach(this::addGroup);
}
@ -126,7 +103,6 @@ public class DGame implements Game {
groups.add(group);
((DGroup) group).setGame(this);
group.setGameWorld(world);
group.setInitialLives(getRules().getState(GameRule.INITIAL_GROUP_LIVES));
group.setLives(getRules().getState(GameRule.INITIAL_GROUP_LIVES));
group.setScore(getRules().getState(GameRule.INITIAL_SCORE));
@ -311,6 +287,15 @@ public class DGame implements Game {
return groups.isEmpty();
}
@Override
public GameWorld ensureWorldIsLoaded(boolean ignoreLimit) {
if (world != null) {
return world;
}
world = dungeon.getMap().instantiateGameWorld(dungeon, ignoreLimit);
return world;
}
@Override
public boolean start() {
getWorld().setWeather(getRules());
@ -356,7 +341,7 @@ public class DGame implements Game {
waveCount++;
resetWaveKills();
Set<ProgressTrigger> triggers = ProgressTrigger.getByGameWorld((DGameWorld) world);
Set<ProgressTrigger> triggers = ProgressTrigger.getByGameWorld(getWorld());
for (ProgressTrigger trigger : triggers) {
if (getWaveCount() >= trigger.getWaveCount() & getFloorCount() >= trigger.getFloorCount() - 1 || !getUnplayedFloors().contains(trigger.getFloor()) & trigger.getFloor() != null) {
trigger.onTrigger();

View File

@ -257,45 +257,15 @@ public class DPortal extends GlobalProtection {
return;
}
GameWorld target = group.getGameWorld();
Game game = group.getGame();
if (target == null && game != null) {
target = game.getWorld();
if (target == null) {
for (PlayerGroup otherTeam : game.getGroups()) {
if (otherTeam.getGameWorld() != null) {
target = otherTeam.getGameWorld();
break;
if (game == null) {
game = new DGame(plugin, dungeon, group);
}
}
}
}
if (target == null) {
ResourceWorld resource = dungeon.getMap();
if (resource != null) {
target = resource.instantiateGameWorld(false);
GameWorld target = game.ensureWorldIsLoaded(false);
if (target == null) {
MessageUtil.sendActionBarMessage(player, DMessage.ERROR_TOO_MANY_INSTANCES.getMessage());
return;
}
group.setGameWorld(target);
}
}
if (target == null) {
MessageUtil.sendActionBarMessage(player, DMessage.ERROR_NO_SUCH_DUNGEON.getMessage());
return;
}
if (game == null) {
game = new DGame(plugin, group, target);
} else {
game.setWorld(target);
group.setGameWorld(target);
}
new DGamePlayer(plugin, player, target);
}

View File

@ -153,7 +153,7 @@ public class GameSign extends JoinSign {
}
dGroup.setDungeon(dungeon);
game = new DGame(plugin, dGroup);
game = new DGame(plugin, dungeon, dGroup);
update();
} else if (topSign.getLine(0).equals(DMessage.SIGN_GLOBAL_JOIN_GAME.getMessage())) {

View File

@ -90,10 +90,6 @@ public class DGamePlayer extends DInstancePlayer implements GamePlayer {
Game game = world.getGame();
dGroup = (DGroup) plugin.getPlayerGroup(player);
if (game == null) {
game = new DGame(plugin, dGroup);
}
GameRuleContainer rules = game.getRules();
player.setGameMode(GameMode.SURVIVAL);
@ -508,7 +504,7 @@ public class DGamePlayer extends DInstancePlayer implements GamePlayer {
Game game = dGroup.getGame();
if (game == null) {
game = new DGame(plugin, dGroup, dGroup.getGameWorld());
game = new DGame(plugin, dGroup.getDungeon(), dGroup);
}
game.setRewards(rewards);

View File

@ -20,6 +20,7 @@ import de.erethon.dungeonsxl.DungeonsXL;
import de.erethon.dungeonsxl.api.Requirement;
import de.erethon.dungeonsxl.api.Reward;
import de.erethon.dungeonsxl.api.dungeon.Dungeon;
import de.erethon.dungeonsxl.api.dungeon.Game;
import de.erethon.dungeonsxl.api.dungeon.GameRule;
import de.erethon.dungeonsxl.api.dungeon.GameRuleContainer;
import de.erethon.dungeonsxl.api.event.group.GroupCreateEvent;
@ -552,10 +553,9 @@ public class DGlobalPlayer implements GlobalPlayer {
return;
}
// The maxInstances check is already done in the listener
GameWorld gameWorld = dungeon.getMap().instantiateGameWorld(true);
dGroup.setGameWorld(gameWorld);
new DGame(plugin, dGroup, gameWorld).setTutorial(true);
Game game = new DGame(plugin, dungeon, dGroup);
game.setTutorial(true);
GameWorld gameWorld = game.ensureWorldIsLoaded(true);
new DGamePlayer(plugin, player, gameWorld);
}

View File

@ -74,7 +74,6 @@ public class DGroup implements PlayerGroup {
private PlayerCollection invitedPlayers = new PlayerCollection();
private Dungeon dungeon;
private Game game;
private GameWorld gameWorld;
private boolean playing;
private List<Reward> rewards = new ArrayList<>();
private BukkitTask timeIsRunningTask;
@ -326,21 +325,8 @@ public class DGroup implements PlayerGroup {
invitedPlayers.removeAll(toRemove);
}
@Override
public GameWorld getGameWorld() {
return gameWorld;
}
@Override
public void setGameWorld(GameWorld gameWorld) {
this.gameWorld = gameWorld;
}
@Override
public Game getGame() {
if (game == null && gameWorld != null) {
game = gameWorld.getGame();
}
return game;
}
@ -380,7 +366,7 @@ public class DGroup implements PlayerGroup {
}
public String getMapName() {
return gameWorld == null ? null : gameWorld.getName();
return getGameWorld() == null ? null : getGameWorld().getName();
}
@Override
@ -498,48 +484,15 @@ public class DGroup implements PlayerGroup {
return false;
}
GameWorld target = dungeon.getMap().instantiateGameWorld(false);
Game game = getGame();
if (target == null && game != null) {
target = game.getWorld();
if (game == null) {
game = new DGame(plugin, dungeon, this);
}
if (target == null) {
if (game != null) {
for (PlayerGroup otherTeam : game.getGroups()) {
if (otherTeam.getGameWorld() != null) {
target = otherTeam.getGameWorld();
break;
}
}
}
}
if (target == null && dungeon != null) {
ResourceWorld resource = dungeon.getMap();
if (resource != null) {
target = resource.instantiateGameWorld(false);
GameWorld target = game.ensureWorldIsLoaded(false);
if (target == null) {
sendMessage(DMessage.ERROR_TOO_MANY_INSTANCES.getMessage());
return false;
}
gameWorld = target;
}
}
if (target == null) {
sendMessage(DMessage.ERROR_NO_SUCH_DUNGEON.getMessage());
return false;
}
if (game == null) {
game = new DGame(plugin, this, target);
} else {
game.setWorld(target);
gameWorld = target;
}
for (OfflinePlayer offline : players.getOfflinePlayers()) {
if (!offline.isOnline()) {
@ -575,10 +528,10 @@ public class DGroup implements PlayerGroup {
Game game = getGame();
DungeonConfig dConfig = ((DDungeon) dungeon).getConfig();
int floorsLeft = getDungeon().getFloors().size() - game.getFloorCount(); //floorCount contains start floor, but dungeon floor list doesn't
game.removeUnplayedFloor((DResourceWorld) gameWorld.getResource(), false);
game.removeUnplayedFloor(game.getWorld().getResource(), false);
ResourceWorld newFloor = null;
GameWorld.Type type = null;
if (gameWorld.getType() == GameWorld.Type.END_FLOOR) {
if (game.getWorld().getType() == GameWorld.Type.END_FLOOR) {
finish();
return;
} else if (specifiedFloor != null) {
@ -593,7 +546,7 @@ public class DGroup implements PlayerGroup {
type = GameWorld.Type.END_FLOOR;
}
GroupFinishFloorEvent event = new GroupFinishFloorEvent(this, gameWorld, newFloor);
GroupFinishFloorEvent event = new GroupFinishFloorEvent(this, game.getWorld(), newFloor);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
@ -601,7 +554,6 @@ public class DGroup implements PlayerGroup {
GameWorld gameWorld = newFloor.instantiateGameWorld(true);
gameWorld.setType(type);
this.gameWorld = gameWorld;
game.setWorld(gameWorld);
for (DGamePlayer player : getDGamePlayers()) {

View File

@ -98,9 +98,13 @@ public class DGameWorld extends DInstanceWorld implements GameWorld {
private boolean readySign;
DGameWorld(DungeonsXL plugin, DResourceWorld resourceWorld, File folder) {
DGameWorld(DungeonsXL plugin, DResourceWorld resourceWorld, File folder, Game game) {
super(plugin, resourceWorld, folder);
caliburn = plugin.getCaliburn();
if (game == null) {
throw new IllegalArgumentException("Game must not be null");
}
this.game = game;
}
@Override
@ -115,14 +119,6 @@ public class DGameWorld extends DInstanceWorld implements GameWorld {
@Override
public Game getGame() {
if (game == null) {
for (Game game : plugin.getGameCache()) {
if (game.getWorld() == this) {
this.game = game;
}
}
}
return game;
}

View File

@ -18,6 +18,7 @@ package de.erethon.dungeonsxl.world;
import de.erethon.dungeonsxl.DungeonsXL;
import de.erethon.dungeonsxl.api.dungeon.Dungeon;
import de.erethon.dungeonsxl.api.dungeon.Game;
import de.erethon.dungeonsxl.api.dungeon.GameRuleContainer;
import de.erethon.dungeonsxl.api.event.world.EditWorldGenerateEvent;
import de.erethon.dungeonsxl.api.event.world.ResourceWorldInstantiateEvent;
@ -25,7 +26,7 @@ import de.erethon.dungeonsxl.api.player.EditPlayer;
import de.erethon.dungeonsxl.api.world.EditWorld;
import de.erethon.dungeonsxl.api.world.GameWorld;
import de.erethon.dungeonsxl.api.world.ResourceWorld;
import de.erethon.dungeonsxl.util.commons.chat.MessageUtil;
import de.erethon.dungeonsxl.dungeon.DGame;
import de.erethon.dungeonsxl.util.commons.compatibility.Internals;
import de.erethon.dungeonsxl.util.commons.compatibility.Version;
import de.erethon.dungeonsxl.util.commons.misc.FileUtil;
@ -176,12 +177,12 @@ public class DResourceWorld implements ResourceWorld {
FileUtil.copyDir(folder, target);
}
public DInstanceWorld instantiate(boolean game) {
public DInstanceWorld instantiate(Game game) {
plugin.setLoadingWorld(true);
String name = DInstanceWorld.generateName(game);
String name = DInstanceWorld.generateName(game != null);
File instanceFolder = new File(Bukkit.getWorldContainer(), name);
DInstanceWorld instance = game ? new DGameWorld(plugin, this, instanceFolder) : new DEditWorld(plugin, this, instanceFolder);
DInstanceWorld instance = game != null ? new DGameWorld(plugin, this, instanceFolder, game) : new DEditWorld(plugin, this, instanceFolder);
ResourceWorldInstantiateEvent event = new ResourceWorldInstantiateEvent(this, name);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
@ -199,7 +200,7 @@ public class DResourceWorld implements ResourceWorld {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "dynmap pause none");
}
if (game) {
if (game != null) {
signData.deserializeSigns((DGameWorld) instance);
instance.getWorld().setAutoSave(false);
} else {
@ -227,19 +228,19 @@ public class DResourceWorld implements ResourceWorld {
return null;
}
editWorld = (EditWorld) instantiate(false);
editWorld = (EditWorld) instantiate(null);
return editWorld;
}
@Override
public GameWorld instantiateGameWorld(boolean ignoreLimit) {
public GameWorld instantiateGameWorld(Dungeon dungeon, boolean ignoreLimit) {
if (plugin.isLoadingWorld()) {
return null;
}
if (!ignoreLimit && plugin.getMainConfig().getMaxInstances() <= plugin.getInstanceCache().size()) {
return null;
}
return (DGameWorld) instantiate(true);
return (DGameWorld) instantiate(new DGame(plugin, dungeon));
}
@Override

View File

@ -107,7 +107,7 @@ cmd:
status:
help: "/dxl status - Shows the technical status of DungeonsXL"
test:
help: "/dxl test - Starts the game in test mode"
help: "/dxl test [name] - Starts the game in test mode"
uninvite:
help: "/dxl uninvite [player] [map] - Uninvite a player from editing a map"
success: "&4&v1&6's permission to edit the map &4&v2&6 has been removed successfully."

View File

@ -107,7 +107,7 @@ cmd:
status:
help: "/dxl status - Affiche le status technique de DungeonsXL"
test:
help: "/dxl test - Lance une partie en mode test"
help: "/dxl test [name] - Lance une partie en mode test"
uninvite:
help: "/dxl uninvite [player] [dungeon] - Désinvite un joueur à éditer un donjon"
success: "&4&v1&6 a été désinviter avec succès à éditer la carte &4&v1&6."

View File

@ -107,7 +107,7 @@ cmd:
status:
help: "/dxl status - Zeigt den technischen Status von DungeonsXL"
test:
help: "/dxl test - Startet das Spiel im Testmodus"
help: "/dxl test [name] - Startet das Spiel im Testmodus"
uninvite:
help: "/dxl uninvite [player] [map] - Lädt einen Spieler davon aus, eine Welt zu bearbeiten"
success: "&4&v1&6's Berechtigung zum Bearbeiten der Welt &4&v2&6 wurde erfolgreich entfernt."