diff --git a/pom.xml b/pom.xml
index f88cadbb4..c62c118e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
me.blackvein.quests
quests
- 2.9.6
+ 2.10.0
quests
https://github.com/FlyingPikachu/Quests/
jar
diff --git a/src/main/java/me/blackvein/quests/Event.java b/src/main/java/me/blackvein/quests/Event.java
index 584d7f085..7185f27d9 100644
--- a/src/main/java/me/blackvein/quests/Event.java
+++ b/src/main/java/me/blackvein/quests/Event.java
@@ -21,6 +21,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import me.blackvein.quests.util.ItemUtil;
+import me.blackvein.quests.util.Lang;
import me.blackvein.quests.util.QuestMob;
public class Event {
@@ -37,6 +38,8 @@ public class Event {
int stormDuration = 0;
World thunderWorld = null;
int thunderDuration = 0;
+ Integer timer = 0;
+ Boolean cancelTimer = false;
public LinkedList mobSpawns = new LinkedList() {
private static final long serialVersionUID = -761974607799449780L;
@@ -66,6 +69,10 @@ public class Event {
float health = -1;
Location teleport;
+ public Event(final Quests plugin) {
+ this.plugin = plugin;
+ }
+
public int hashCode() {
assert false : "hashCode not designed";
return 42; // any arbitrary constant will do
@@ -232,13 +239,58 @@ public class Event {
if (failQuest == true) {
quest.failQuest(quester);
}
+ if (timer > 0) {
+ player.sendMessage(Quests.parseString(String.format(Lang.get("timerStart"), timer), quest));
+ if (timer > 60) {
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 60, false)
+ .runTaskLaterAsynchronously(plugin, (timer-60)*20).getTaskId(), quest);
+ }
+ if (timer > 30) {
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 30, false)
+ .runTaskLaterAsynchronously(plugin, (timer-30)*20).getTaskId(), quest);
+ }
+ if (timer > 10) {
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 10, false)
+ .runTaskLaterAsynchronously(plugin, (timer-10)*20).getTaskId(), quest);
+ }
+ if (timer > 5) {
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 5, false)
+ .runTaskLaterAsynchronously(plugin, (timer-5)*20).getTaskId(), quest);
+ }
+ if (timer > 4) {
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 4, false)
+ .runTaskLaterAsynchronously(plugin, (timer-4)*20).getTaskId(), quest);
+ }
+ if (timer > 3) {
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 3, false)
+ .runTaskLaterAsynchronously(plugin, (timer-3)*20).getTaskId(), quest);
+ }
+ if (timer > 2) {
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 2, false)
+ .runTaskLaterAsynchronously(plugin, (timer-2)*20).getTaskId(), quest);
+ }
+ if (timer > 1) {
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 1, false)
+ .runTaskLaterAsynchronously(plugin, (timer-1)*20).getTaskId(), quest);
+ }
+ quester.timers.put(new ObjectiveTimer(plugin, quester, quest, 0, true)
+ .runTaskLaterAsynchronously(plugin, timer*20).getTaskId(), quest);
+ }
+ if (cancelTimer) {
+ for (Map.Entry entry : quester.timers.entrySet()) {
+ if (entry.getValue().getName().equals(quest.getName())) {
+ plugin.getServer().getScheduler().cancelTask(entry.getKey());
+ quester.timers.remove(entry.getKey());
+ }
+ }
+ }
}
public static Event loadEvent(String name, Quests plugin) {
if (name == null || plugin == null) {
return null;
}
- Event event = new Event();
+ Event event = new Event(plugin);
FileConfiguration data = new YamlConfiguration();
try {
data.load(new File(plugin.getDataFolder(), "events.yml"));
@@ -513,6 +565,22 @@ public class Event {
return null;
}
}
+ if (data.contains(eventKey + "timer")) {
+ if (data.isInt(eventKey + "timer")) {
+ event.timer = data.getInt(eventKey + "timer");
+ } else {
+ plugin.getLogger().severe(ChatColor.GOLD + "[Quests] " + ChatColor.RED + "timer: " + ChatColor.GOLD + "inside Event " + ChatColor.DARK_PURPLE + name + ChatColor.GOLD + " is not a number!");
+ return null;
+ }
+ }
+ if (data.contains(eventKey + "cancel-timer")) {
+ if (data.isBoolean(eventKey + "cancel-timer")) {
+ event.cancelTimer = data.getBoolean(eventKey + "cancel-timer");
+ } else {
+ plugin.getLogger().severe(ChatColor.GOLD + "[Quests] " + ChatColor.RED + "cancel-timer: " + ChatColor.GOLD + "inside Event " + ChatColor.DARK_PURPLE + name + ChatColor.GOLD + " is not a boolean!");
+ return null;
+ }
+ }
return event;
}
}
diff --git a/src/main/java/me/blackvein/quests/EventFactory.java b/src/main/java/me/blackvein/quests/EventFactory.java
index 7b89f2f35..68f121b3e 100644
--- a/src/main/java/me/blackvein/quests/EventFactory.java
+++ b/src/main/java/me/blackvein/quests/EventFactory.java
@@ -163,6 +163,8 @@ public class EventFactory implements ConversationAbandonedListener {
context.setSessionData(CK.E_HEALTH, null);
context.setSessionData(CK.E_TELEPORT, null);
context.setSessionData(CK.E_COMMANDS, null);
+ context.setSessionData(CK.E_TIMER, null);
+ context.setSessionData(CK.E_CANCEL_TIMER, null);
}
public static void loadData(Event event, ConversationContext context) {
@@ -251,6 +253,12 @@ public class EventFactory implements ConversationAbandonedListener {
if (event.commands != null) {
context.setSessionData(CK.E_COMMANDS, event.commands);
}
+ if (event.timer > 0) {
+ context.setSessionData(CK.E_TIMER, event.timer);
+ }
+ if (event.cancelTimer) {
+ context.setSessionData(CK.E_CANCEL_TIMER, true);
+ }
}
private class SelectEditPrompt extends StringPrompt {
@@ -358,7 +366,7 @@ public class EventFactory implements ConversationAbandonedListener {
private class CreateMenuPrompt extends FixedSetPrompt {
public CreateMenuPrompt() {
- super("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19");
+ super("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21");
}
@SuppressWarnings("unchecked")
@@ -477,8 +485,17 @@ public class EventFactory implements ConversationAbandonedListener {
text += ChatColor.GRAY + " - " + ChatColor.AQUA + s + "\n";
}
}
- text += ChatColor.GREEN + "" + ChatColor.BOLD + "18" + ChatColor.RESET + ChatColor.YELLOW + " - " + Lang.get("done") + "\n";
- text += ChatColor.RED + "" + ChatColor.BOLD + "19" + ChatColor.RESET + ChatColor.YELLOW + " - " + Lang.get("quit");
+ if (context.getSessionData(CK.E_TIMER) == null) {
+ text += ChatColor.BLUE + "" + ChatColor.BOLD + "18" + ChatColor.RESET + ChatColor.YELLOW + " - " + Lang.get("eventEditorSetTimer") + ChatColor.GRAY + " (" + Lang.get("noneSet") + ")\n";
+ } else {
+ text += ChatColor.BLUE + "" + ChatColor.BOLD + "18" + ChatColor.RESET + ChatColor.YELLOW + " - " + Lang.get("eventEditorSetTimer") + "(" + ChatColor.AQUA + "\"" + context.getSessionData(CK.E_TIMER) + "\"" + ChatColor.YELLOW + ")\n";
+ }
+ if (context.getSessionData(CK.E_CANCEL_TIMER) == null) {
+ context.setSessionData(CK.E_CANCEL_TIMER, "No");
+ }
+ text += ChatColor.BLUE + "" + ChatColor.BOLD + "19" + ChatColor.RESET + ChatColor.YELLOW + " - " + Lang.get("eventEditorCancelTimer") + ": " + ChatColor.AQUA + context.getSessionData(CK.E_CANCEL_TIMER) + "\n";
+ text += ChatColor.GREEN + "" + ChatColor.BOLD + "20" + ChatColor.RESET + ChatColor.YELLOW + " - " + Lang.get("done") + "\n";
+ text += ChatColor.RED + "" + ChatColor.BOLD + "21" + ChatColor.RESET + ChatColor.YELLOW + " - " + Lang.get("quit");
return text;
}
@@ -534,18 +551,42 @@ public class EventFactory implements ConversationAbandonedListener {
} else if (input.equalsIgnoreCase("17")) {
return new CommandsPrompt();
} else if (input.equalsIgnoreCase("18")) {
+ return new TimerPrompt();
+ } else if (input.equalsIgnoreCase("19")) {
+ String s = (String) context.getSessionData(CK.E_CANCEL_TIMER);
+ if (s.equalsIgnoreCase(Lang.get("yesWord"))) {
+ context.setSessionData(CK.E_CANCEL_TIMER, Lang.get("noWord"));
+ } else {
+ context.setSessionData(CK.E_CANCEL_TIMER, Lang.get("yesWord"));
+ }
+ return new CreateMenuPrompt();
+ } else if (input.equalsIgnoreCase("20")) {
if (context.getSessionData(CK.E_OLD_EVENT) != null) {
return new FinishPrompt((String) context.getSessionData(CK.E_OLD_EVENT));
} else {
return new FinishPrompt(null);
}
- } else if (input.equalsIgnoreCase("19")) {
+ } else if (input.equalsIgnoreCase("21")) {
return new QuitPrompt();
}
return null;
}
}
+ private class TimerPrompt extends NumericPrompt {
+
+ @Override
+ protected Prompt acceptValidatedInput(final ConversationContext context, final Number number) {
+ context.setSessionData(CK.E_TIMER, number);
+ return new CreateMenuPrompt();
+ }
+
+ @Override
+ public String getPromptText(final ConversationContext conversationContext) {
+ return ChatColor.YELLOW + Lang.get("eventEditorEnterTimerSeconds");
+ }
+ }
+
private class QuitPrompt extends StringPrompt {
@Override
@@ -821,6 +862,15 @@ public class EventFactory implements ConversationAbandonedListener {
if (context.getSessionData(CK.E_TELEPORT) != null) {
section.set("teleport-location", getCString(context, CK.E_TELEPORT));
}
+ if (context.getSessionData(CK.E_TIMER) != null && (int) context.getSessionData(CK.E_TIMER) > 0) {
+ section.set("timer", getCInt(context, CK.E_TIMER));
+ }
+ if (context.getSessionData(CK.E_CANCEL_TIMER) != null) {
+ String s = getCString(context, CK.E_CANCEL_TIMER);
+ if (s.equalsIgnoreCase(Lang.get("yesWord"))) {
+ section.set("cancel-timer", true);
+ }
+ }
try {
data.save(eventsFile);
} catch (IOException e) {
diff --git a/src/main/java/me/blackvein/quests/ObjectiveTimer.java b/src/main/java/me/blackvein/quests/ObjectiveTimer.java
new file mode 100644
index 000000000..b4c86b6e1
--- /dev/null
+++ b/src/main/java/me/blackvein/quests/ObjectiveTimer.java
@@ -0,0 +1,33 @@
+package me.blackvein.quests;
+
+import org.bukkit.scheduler.BukkitRunnable;
+
+import me.blackvein.quests.util.Lang;
+
+public class ObjectiveTimer extends BukkitRunnable {
+
+ Quester quester;
+ Quests plugin;
+ Quest quest;
+ private int time;
+ private boolean last;
+
+ ObjectiveTimer(Quests plugin, Quester quester, Quest quest, int time, boolean last) {
+ this.quester = quester;
+ this.quest = quest;
+ this.plugin = plugin;
+ this.time = time;
+ this.last = last;
+ }
+
+ @Override
+ public void run() {
+ quester.timers.remove(getTaskId());
+ if (last) {
+ quest.failQuest(quester);
+ quester.updateJournal();
+ } else {
+ quester.getPlayer().sendMessage(Quests.parseString(String.format(Lang.get("timerMessage"), time), quest));
+ }
+ }
+}
diff --git a/src/main/java/me/blackvein/quests/PlayerListener.java b/src/main/java/me/blackvein/quests/PlayerListener.java
index e91c11196..661b75418 100644
--- a/src/main/java/me/blackvein/quests/PlayerListener.java
+++ b/src/main/java/me/blackvein/quests/PlayerListener.java
@@ -48,7 +48,6 @@ import org.bukkit.projectiles.ProjectileSource;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
-
import me.blackvein.quests.util.ItemUtil;
import me.blackvein.quests.util.Lang;
import net.citizensnpcs.api.CitizensAPI;
@@ -650,6 +649,12 @@ public class PlayerListener implements Listener {
currentStage.disconnectEvent.fire(quester, quest);
}
}
+ quester.timers.keySet().forEach(timerId -> {
+ plugin.getServer().getScheduler().cancelTask(timerId);
+ quester.timers.get(timerId).failQuest(quester);
+ quester.timers.remove(timerId);
+ });
+
if (quester.hasData()) {
quester.saveData();
}
diff --git a/src/main/java/me/blackvein/quests/Quest.java b/src/main/java/me/blackvein/quests/Quest.java
index 3b28dae6c..66c62c587 100644
--- a/src/main/java/me/blackvein/quests/Quest.java
+++ b/src/main/java/me/blackvein/quests/Quest.java
@@ -100,6 +100,9 @@ public class Quest {
completeQuest(q);
} else {
try {
+ if (q.getCurrentStage(this).finishEvent != null) {
+ q.getCurrentStage(this).finishEvent.fire(q, this);
+ }
setStage(q, q.currentQuests.get(this) + 1);
} catch (InvalidStageException e) {
e.printStackTrace();
@@ -257,6 +260,12 @@ public class Quest {
q.completedQuests.add(name);
String none = ChatColor.GRAY + "- (" + Lang.get("none") + ")";
final String ps = Quests.parseString(finished, this);
+ for (Map.Entry entry : q.timers.entrySet()) {
+ if (entry.getValue().getName().equals(getName())) {
+ plugin.getServer().getScheduler().cancelTask(entry.getKey());
+ q.timers.remove(entry.getKey());
+ }
+ }
org.bukkit.Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
@Override
diff --git a/src/main/java/me/blackvein/quests/Quester.java b/src/main/java/me/blackvein/quests/Quester.java
index 75668fb2f..534afe92d 100644
--- a/src/main/java/me/blackvein/quests/Quester.java
+++ b/src/main/java/me/blackvein/quests/Quester.java
@@ -46,6 +46,7 @@ public class Quester {
boolean editorMode = false;
boolean hasJournal = false;
public String questToTake;
+ public ConcurrentHashMap timers = new ConcurrentHashMap<>();
public Map currentQuests = new ConcurrentHashMap() {
private static final long serialVersionUID = 6361484975823846780L;
diff --git a/src/main/java/me/blackvein/quests/util/CK.java b/src/main/java/me/blackvein/quests/util/CK.java
index 520883569..e1b510f1e 100644
--- a/src/main/java/me/blackvein/quests/util/CK.java
+++ b/src/main/java/me/blackvein/quests/util/CK.java
@@ -132,6 +132,8 @@ public class CK {
public static final String E_HEALTH = "evtHealth";
public static final String E_TELEPORT = "evtTeleportLocation";
public static final String E_COMMANDS = "evtCommands";
+ public static final String E_TIMER = "evtTimer";
+ public static final String E_CANCEL_TIMER = "evtCancelTimer";
// Party
public static final String P_INVITER = "inviter";
}
\ No newline at end of file
diff --git a/src/main/java/me/blackvein/quests/util/Lang.java b/src/main/java/me/blackvein/quests/util/Lang.java
index ce7554706..ddf2969ee 100644
--- a/src/main/java/me/blackvein/quests/util/Lang.java
+++ b/src/main/java/me/blackvein/quests/util/Lang.java
@@ -433,6 +433,9 @@ public class Lang {
langMap.put("eventEditorSetHunger", "Set player hunger level");
langMap.put("eventEditorSetSaturation", "Set player saturation level");
langMap.put("eventEditorSetHealth", "Set player health level");
+ langMap.put("eventEditorEnterTimerSeconds", "Set number of seconds left before the quest fails (use cancel-timer event to cancel timers)");
+ langMap.put("eventEditorSetTimer", "Set time to fail quest");
+ langMap.put("eventEditorCancelTimer", "Cancel the quest timer");
langMap.put("eventEditorSetTeleport", "Set player teleport location");
langMap.put("eventEditorSetCommands", "Set commands to execute");
langMap.put("eventEditorItems", "Event Items");
@@ -944,6 +947,9 @@ public class Lang {
langMap.put("valRequired", "Value required");
langMap.put("enchantedItem", "*Enchanted*");
langMap.put("experience", "Experience");
+ // Timers
+ langMap.put("timerMessage", "Time left to finish the quest/stage: %s seconds");
+ langMap.put("timerStart", "You have %s seconds to finish this quest/stage");
//
// Error Messages
langMap.put("questErrorReadingFile", "Error reading Quests file.");
diff --git a/src/main/resources/events.yml b/src/main/resources/events.yml
index 01b7fdfbe..319a2dafd 100644
--- a/src/main/resources/events.yml
+++ b/src/main/resources/events.yml
@@ -19,4 +19,8 @@ events:
RodEvent:
message: "Here you go!"
items:
- - name-fishing_rod:amount-1
\ No newline at end of file
+ - name-fishing_rod:amount-1
+ TimerEvent:
+ timer: 40
+ CancelTimer:
+ cancel-timer: true
\ No newline at end of file
diff --git a/src/main/resources/quests.yml b/src/main/resources/quests.yml
index 29f9e6f91..e3dd39009 100644
--- a/src/main/resources/quests.yml
+++ b/src/main/resources/quests.yml
@@ -76,4 +76,65 @@ quests:
- "rod"
fish-to-catch: 5
rewards:
- exp: 250
\ No newline at end of file
+ exp: 250
+
+ TimedQuest:
+ name: 'Timed Quest'
+ ask-message: 'This is timed quest, mine dirt before time runs out!'
+ finish-message: 'You did it in time!'
+ stages:
+ ordered:
+ '1':
+ break-block-names:
+ - DIRT
+ break-block-amounts:
+ - 10
+ break-block-durability:
+ - 0
+ start-event: TimerEvent
+
+ TimedQuest2:
+ name: 'Timed Quest 2'
+ ask-message: 'This is timed quest 2, mine dirt and then grass before time runs out!'
+ finish-message: 'You did it in time!'
+ stages:
+ ordered:
+ '1':
+ break-block-names:
+ - DIRT
+ break-block-amounts:
+ - 10
+ break-block-durability:
+ - 0
+ start-event: TimerEvent
+ finish-event: CancelTimer
+ '2':
+ break-block-names:
+ - GRASS
+ break-block-amounts:
+ - 10
+ break-block-durability:
+ - 0
+ start-event: TimerEvent
+
+ TimedQuest3:
+ name: 'Timed Quest 3'
+ ask-message: 'This is timed quest 3, mine dirt and then grass before time runs out!'
+ finish-message: 'You did it in time!'
+ stages:
+ ordered:
+ '1':
+ break-block-names:
+ - DIRT
+ break-block-amounts:
+ - 10
+ break-block-durability:
+ - 0
+ start-event: TimerEvent
+ '2':
+ break-block-names:
+ - GRASS
+ break-block-amounts:
+ - 10
+ break-block-durability:
+ - 0
\ No newline at end of file