/**
* BetonQuest - advanced quests for Bukkit
* Copyright (C) 2016 Jakub "Co0sh" Sapalski
*
* 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 <http://www.gnu.org/licenses/>.
*/
package pl.betoncraft.betonquest.objectives;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.Map.Entry;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import pl.betoncraft.betonquest.BetonQuest;
import pl.betoncraft.betonquest.Instruction;
import pl.betoncraft.betonquest.InstructionParseException;
import pl.betoncraft.betonquest.api.Objective;
import pl.betoncraft.betonquest.config.Config;
/**
* Player has to wait specified amount of time. He may logout, the objective
* will be completed as soon as the time is up and he logs in again.
*
* @author Jakub Sapalski
*/
public class DelayObjective extends Objective {
private final long delay;
private BukkitTask runnable;
private int interval;
public DelayObjective(Instruction instruction) throws InstructionParseException {
super(instruction);
template = DelayData.class;
delay = instruction.getLong();
if (delay < 0) {
throw new InstructionParseException("Delay cannot be less than 0");
}
interval = instruction.getInt(instruction.getOptional("interval"), 20 * 10);
if (interval < 1) {
throw new InstructionParseException("Interval cannot be less than 1 tick");
}
}
@Override
public void start() {
runnable = new BukkitRunnable() {
@Override
public void run() {
LinkedList<String> players = new LinkedList<>();
long time = new Date().getTime();
for (Entry<String, ObjectiveData> entry : dataMap.entrySet()) {
String playerID = entry.getKey();
DelayData playerData = (DelayData) entry.getValue();
if (time >= playerData.getTime() && checkConditions(playerID)) {
// don't complete the objective, it will throw CME/
// store the player instead, complete later
players.add(playerID);
}
}
for (String playerID : players) {
completeObjective(playerID);
}
}
}.runTaskTimer(BetonQuest.getInstance(), 0, interval);
}
@Override
public void stop() {
if (runnable != null)
runnable.cancel();
}
@Override
public String getDefaultDataInstruction() {
return Long.toString(new Date().getTime() + delay * 1000 * 60);
}
@Override
public String getProperty(String name, String playerID) {
if (name.equalsIgnoreCase("left")) {
String lang = BetonQuest.getInstance().getPlayerData(playerID).getLanguage();
String daysWord = Config.getMessage(lang, "days");
String hoursWord = Config.getMessage(lang, "hours");
String minutesWord = Config.getMessage(lang, "minutes");
String secondsWord = Config.getMessage(lang, "seconds");
long timeLeft = ((DelayData) dataMap.get(playerID)).getTime() - new Date().getTime();
long s = (timeLeft / (1000)) % 60;
long m = (timeLeft / (1000 * 60)) % 60;
long h = (timeLeft / (1000 * 60 * 60)) % 24;
long d = (timeLeft / (1000 * 60 * 60 * 24));
StringBuilder time = new StringBuilder();
String[] words = new String[3];
if (d > 0)
words[0] = d + " " + daysWord;
if (h > 0)
words[1] = h + " " + hoursWord;
if (m > 0)
words[2] = m + " " + minutesWord;
int count = 0;
for (String word : words) {
if (word != null)
count++;
}
if (count == 0) {
time.append(s + " " + secondsWord);
} else if (count == 1) {
for (String word : words) {
if (word == null)
continue;
time.append(word);
}
} else if (count == 2) {
boolean second = false;
for (String word : words) {
if (word == null)
continue;
if (second) {
time.append(" " + word);
} else {
time.append(word + " " + Config.getMessage(lang, "and"));
second = true;
}
}
} else {
time.append(words[0] + ", " + words[1] + " " + Config.getMessage(lang, "and ") + words[2]);
}
return time.toString();
} else if (name.equalsIgnoreCase("date")) {
return new SimpleDateFormat(Config.getString("config.date_format"))
.format(new Date(((DelayData) dataMap.get(playerID)).getTime()));
}
return "";
}
public static class DelayData extends ObjectiveData {
private final long timestamp;
public DelayData(String instruction, String playerID, String objID) {
super(instruction, playerID, objID);
timestamp = Long.parseLong(instruction);
}
private long getTime() {
return timestamp;
}
}
}