diff --git a/src/main/java/io/github/dre2n/dungeonsxl/config/MessageConfig.java b/src/main/java/io/github/dre2n/dungeonsxl/config/MessageConfig.java index a6a9caef..2ac67c82 100644 --- a/src/main/java/io/github/dre2n/dungeonsxl/config/MessageConfig.java +++ b/src/main/java/io/github/dre2n/dungeonsxl/config/MessageConfig.java @@ -67,6 +67,8 @@ public class MessageConfig { PLAYER_READY("Player_Ready", "&6You are now ready for the Dungeon!"), PLAYER_SIGN_CREATED("Player_SignCreated", "&6Sign created!"), PLAYER_SIGN_COPIED("Player_SignCopied", "&6Copied!"), + PLAYER_TIME_LEFT("Player_TimeLeft", "&v1You have &6&v2 &v1seconds left to finish the dungeon!"), + PLAYER_TIME_KICK("Player_TimeKick", "&2&v1&6's time expired."), PLAYER_TREASURES("Player_Treasures", "&1Treasures"), PLAYER_WAIT_FOR_OTHER_PLAYERS("Player_WaitForOtherPlayers", "&6Waiting for teammates..."), diff --git a/src/main/java/io/github/dre2n/dungeonsxl/config/WorldConfig.java b/src/main/java/io/github/dre2n/dungeonsxl/config/WorldConfig.java index fd267633..ae23343b 100644 --- a/src/main/java/io/github/dre2n/dungeonsxl/config/WorldConfig.java +++ b/src/main/java/io/github/dre2n/dungeonsxl/config/WorldConfig.java @@ -81,6 +81,7 @@ public class WorldConfig { private int timeToNextLoot = 0; private int timeUntilKickOfflinePlayer = -1; + private int timeToFinish = -1; private List requirements = new ArrayList<>(); private List rewards = new ArrayList<>(); @@ -91,7 +92,6 @@ public class WorldConfig { private GameType forcedGameType; - // MobTypes private Set mobTypes = new HashSet<>(); private List gameCommandWhitelist = new ArrayList<>(); @@ -301,6 +301,12 @@ public class WorldConfig { timeUntilKickOfflinePlayer = plugin.getDefaultConfig().timeUntilKickOfflinePlayer; } + if (configFile.contains("timeToFinish")) { + timeToFinish = configFile.getInt("timeToFinish"); + } else { + timeToFinish = plugin.getDefaultConfig().timeToFinish; + } + /* Dungeon Requirements */ if (configFile.contains("requirements")) { for (String identifier : configFile.getConfigurationSection("requirements").getKeys(false)) { @@ -580,6 +586,20 @@ public class WorldConfig { return timeUntilKickOfflinePlayer; } + /** + * @return if the game is "time is running" + */ + public boolean isTimeIsRunning() { + return timeToFinish != -1; + } + + /** + * @return the time until a player gets kicked from his group + */ + public int getTimeToFinish() { + return timeToFinish; + } + /** * @return the requirements */ diff --git a/src/main/java/io/github/dre2n/dungeonsxl/event/dplayer/DPlayerKickEvent.java b/src/main/java/io/github/dre2n/dungeonsxl/event/dplayer/DPlayerKickEvent.java index 2e35210c..612b8d3a 100644 --- a/src/main/java/io/github/dre2n/dungeonsxl/event/dplayer/DPlayerKickEvent.java +++ b/src/main/java/io/github/dre2n/dungeonsxl/event/dplayer/DPlayerKickEvent.java @@ -30,6 +30,7 @@ public class DPlayerKickEvent extends DPlayerEvent implements Cancellable { COMMAND, DEATH, OFFLINE, + TIME_EXPIRED, CUSTOM } diff --git a/src/main/java/io/github/dre2n/dungeonsxl/game/GameWorld.java b/src/main/java/io/github/dre2n/dungeonsxl/game/GameWorld.java index 04b3f35b..f7938d2d 100644 --- a/src/main/java/io/github/dre2n/dungeonsxl/game/GameWorld.java +++ b/src/main/java/io/github/dre2n/dungeonsxl/game/GameWorld.java @@ -447,7 +447,7 @@ public class GameWorld { } } - // Statics + /* Statics */ public static GameWorld load(String name) { GameWorldLoadEvent event = new GameWorldLoadEvent(name); @@ -520,7 +520,10 @@ public class GameWorld { public static GameWorld getByWorld(World world) { for (GameWorld gameWorld : plugin.getGameWorlds()) { - if (gameWorld.world.equals(world)) { + if (gameWorld.getWorld() == null) { + continue; + + } else if (gameWorld.getWorld().equals(world)) { return gameWorld; } } diff --git a/src/main/java/io/github/dre2n/dungeonsxl/player/DGroup.java b/src/main/java/io/github/dre2n/dungeonsxl/player/DGroup.java index 804bc33b..6e070023 100644 --- a/src/main/java/io/github/dre2n/dungeonsxl/player/DGroup.java +++ b/src/main/java/io/github/dre2n/dungeonsxl/player/DGroup.java @@ -35,6 +35,7 @@ import io.github.dre2n.dungeonsxl.global.GameSign; import io.github.dre2n.dungeonsxl.global.GroupSign; import io.github.dre2n.dungeonsxl.requirement.Requirement; import io.github.dre2n.dungeonsxl.reward.Reward; +import io.github.dre2n.dungeonsxl.task.TimeIsRunningTask; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -42,6 +43,7 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; /** * @author Frank Baumann, Daniel Saukel @@ -63,6 +65,7 @@ public class DGroup { private int floorCount; private int waveCount; private List rewards = new ArrayList<>(); + private BukkitTask timeIsRunningTask; public DGroup(String name, Player player) { plugin.getDGroups().add(this); @@ -418,6 +421,21 @@ public class DGroup { rewards.remove(reward); } + /** + * @return the "Time is Running" task of the game + */ + public BukkitTask getTimeIsRunningTask() { + return timeIsRunningTask; + } + + /** + * @param task + * the task to set + */ + public void setTimeIsRunningTask(BukkitTask task) { + this.timeIsRunningTask = task; + } + /** * @return whether there are players in the group */ @@ -430,9 +448,15 @@ public class DGroup { */ public void delete() { plugin.getDGroups().remove(this); + + if (timeIsRunningTask != null) { + timeIsRunningTask.cancel(); + } + if (Game.getByDGroup(this) != null) { Game.getByDGroup(this).removeDGroup(this); } + GameSign.updatePerGame(Game.getByDGroup(this)); GroupSign.updatePerGroup(this); } @@ -477,6 +501,10 @@ public class DGroup { for (Player player : getPlayers()) { DPlayer dPlayer = DPlayer.getByPlayer(player); + if (dPlayer == null) { + continue; + } + dPlayer.respawn(); if (plugin.getMainConfig().getSendFloorTitle()) { @@ -503,9 +531,15 @@ public class DGroup { GameType gameType = game.getType(); if (gameType == GameTypeDefault.DEFAULT) { player.setGameMode(config.getGameMode()); + if (config.isTimeIsRunning()) { + timeIsRunningTask = new TimeIsRunningTask(this, config.getTimeToFinish()).runTaskTimer(plugin, 20, 20); + } } else { player.setGameMode(gameType.getGameMode()); + if (gameType.getShowTime()) { + timeIsRunningTask = new TimeIsRunningTask(this, config.getTimeToFinish()).runTaskTimer(plugin, 20, 20); + } } } } diff --git a/src/main/java/io/github/dre2n/dungeonsxl/task/TimeIsRunningTask.java b/src/main/java/io/github/dre2n/dungeonsxl/task/TimeIsRunningTask.java new file mode 100644 index 00000000..5307a089 --- /dev/null +++ b/src/main/java/io/github/dre2n/dungeonsxl/task/TimeIsRunningTask.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2016 Daniel Saukel + * + * 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 . + */ +package io.github.dre2n.dungeonsxl.task; + +import io.github.dre2n.commons.util.messageutil.MessageUtil; +import io.github.dre2n.dungeonsxl.DungeonsXL; +import io.github.dre2n.dungeonsxl.config.MessageConfig; +import io.github.dre2n.dungeonsxl.config.MessageConfig.Messages; +import io.github.dre2n.dungeonsxl.event.dplayer.DPlayerKickEvent; +import io.github.dre2n.dungeonsxl.player.DGroup; +import io.github.dre2n.dungeonsxl.player.DPlayer; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +/** + * @author Daniel Saukel + */ +public class TimeIsRunningTask extends BukkitRunnable { + + protected static MessageConfig messageConfig = DungeonsXL.getInstance().getMessageConfig(); + + private DGroup dGroup; + private int time; + private int timeLeft; + + public TimeIsRunningTask(DGroup dGroup, int time) { + this.dGroup = dGroup; + this.time = time; + this.timeLeft = time; + } + + @Override + public void run() { + timeLeft--; + + String color = ChatColor.GREEN.toString(); + + try { + color = (double) timeLeft / (double) time > 0.25 ? ChatColor.GREEN.toString() : ChatColor.DARK_RED.toString(); + + } catch (ArithmeticException exception) { + color = ChatColor.DARK_RED.toString(); + + } finally { + for (Player player : dGroup.getPlayers()) { + MessageUtil.sendActionBarMessage(player, messageConfig.getMessage(Messages.PLAYER_TIME_LEFT, color, String.valueOf(timeLeft))); + + DPlayer dPlayer = DPlayer.getByPlayer(player); + if (timeLeft > 0) { + continue; + } + + DPlayerKickEvent dPlayerKickEvent = new DPlayerKickEvent(dPlayer, DPlayerKickEvent.Cause.TIME_EXPIRED); + + if (!dPlayerKickEvent.isCancelled()) { + MessageUtil.broadcastMessage(messageConfig.getMessage(Messages.PLAYER_TIME_KICK, player.getName())); + dPlayer.leave(); + if (dGroup.getGameWorld().getConfig().getKeepInventoryOnEscape()) { + dPlayer.applyRespawnInventory(); + } + } + + cancel(); + } + } + + } +}