Implement timer event - can be used to create time-limited quests!

This commit is contained in:
Jakub Kolář 2017-07-20 00:15:55 +02:00
parent d13683445d
commit f8bb025b0f
11 changed files with 248 additions and 9 deletions

View File

@ -3,7 +3,7 @@
<groupId>me.blackvein.quests</groupId>
<artifactId>quests</artifactId>
<version>2.9.6</version>
<version>2.10.0</version>
<name>quests</name>
<url>https://github.com/FlyingPikachu/Quests/</url>
<packaging>jar</packaging>

View File

@ -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<QuestMob> mobSpawns = new LinkedList<QuestMob>() {
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<Integer, Quest> 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;
}
}

View File

@ -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) {

View File

@ -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));
}
}
}

View File

@ -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();
}

View File

@ -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<Integer, Quest> 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

View File

@ -46,6 +46,7 @@ public class Quester {
boolean editorMode = false;
boolean hasJournal = false;
public String questToTake;
public ConcurrentHashMap<Integer, Quest> timers = new ConcurrentHashMap<>();
public Map<Quest, Integer> currentQuests = new ConcurrentHashMap<Quest, Integer>() {
private static final long serialVersionUID = 6361484975823846780L;

View File

@ -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";
}

View File

@ -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", "<green>Time left to finish the quest/stage: <red>%s seconds");
langMap.put("timerStart", "<green>You have <red>%s seconds <green>to finish this quest/stage");
//
// Error Messages
langMap.put("questErrorReadingFile", "Error reading Quests file.");

View File

@ -19,4 +19,8 @@ events:
RodEvent:
message: "<green>Here you go!"
items:
- name-fishing_rod:amount-1
- name-fishing_rod:amount-1
TimerEvent:
timer: 40
CancelTimer:
cancel-timer: true

View File

@ -76,4 +76,65 @@ quests:
- "rod"
fish-to-catch: 5
rewards:
exp: 250
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