/
EngageCommand.java
159 lines (139 loc) · 5.49 KB
/
EngageCommand.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package net.aufdemrand.denizen.scripts.commands.npc;
import net.aufdemrand.denizen.Settings;
import net.aufdemrand.denizen.objects.dNPC;
import net.aufdemrand.denizen.utilities.Utilities;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizencore.objects.Duration;
import net.aufdemrand.denizencore.objects.aH;
import net.aufdemrand.denizencore.scripts.ScriptEntry;
import net.aufdemrand.denizencore.scripts.commands.AbstractCommand;
import net.citizensnpcs.api.npc.NPC;
import java.util.HashMap;
import java.util.Map;
public class EngageCommand extends AbstractCommand {
// <--[command]
// @Name Engage
// @Syntax engage (<duration>)
// @Required 0
// @Plugin Citizens
// @Short Temporarily disables an NPCs toggled interact script-container triggers.
// @Group npc
//
// @Description
// Engaging an NPC will temporarily disable any interact script-container triggers. To reverse
// this behavior, use either the disengage command, or specify a duration in which the engage
// should timeout. Specifying an engage without a duration will render the NPC engaged until
// a disengage is used on the NPC. Engaging an NPC affects all players attempting to interact
// with the NPC.
//
// While engaged, all triggers and actions associated with triggers will not 'fire', except
// the 'on unavailable' assignment script-container action, which will fire for triggers that
// were enabled previous to the engage command.
//
// Engage can be useful when NPCs are carrying out a task that shouldn't be interrupted, or
// to provide a good way to avoid accidental 'retrigger'.
//
// See <@link command Disengage>
//
// @Tags
// <n@npc.is_engaged>
//
// @Usage
// Use to make an NPC appear 'busy'.
// - engage
// - chat 'Give me a few minutes while I mix you a potion!'
// - walk <npc.anchor[mixing_station]>
// - wait 10s
// - walk <npc.anchor[service_station]>
// - chat 'Here you go!'
// - give potion <player>
// - disengage
//
// @Usage
// Use to avoid 'retrigger'.
// - engage 5s
// - take quest_item
// - flag player finished_quests:->:super_quest
// -->
@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {
// Check for NPC
if (!Utilities.entryHasNPC(scriptEntry)) {
throw new InvalidArgumentsException("This command requires a linked NPC!");
}
// Parse arguments
for (aH.Argument arg : aH.interpretArguments(scriptEntry.aHArgs)) {
if (!scriptEntry.hasObject("duration")
&& arg.matchesArgumentType(Duration.class)) {
scriptEntry.addObject("duration", arg.asType(Duration.class));
}
else {
arg.reportUnhandled();
}
}
scriptEntry.defaultObject("duration", new Duration(0));
}
@Override
public void execute(ScriptEntry scriptEntry) {
Duration duration = scriptEntry.getdObject("duration");
dNPC npc = Utilities.getEntryNPC(scriptEntry);
// Report to dB
if (scriptEntry.dbCallShouldDebug()) {
dB.report(scriptEntry, getName(), npc.debug() + duration.debug());
}
if (duration.getSecondsAsInt() > 0) {
setEngaged(npc.getCitizen(), duration.getSecondsAsInt());
}
else {
setEngaged(npc.getCitizen(), true);
}
}
/*
* Engaged NPCs cannot interact with Players
*/
private static Map<NPC, Long> currentlyEngaged = new HashMap<>();
/**
* Checks if the dNPC is ENGAGED. Engaged NPCs do not respond to
* Player interaction.
*
* @param npc the Denizen NPC being checked
* @return if the dNPC is currently engaged
*/
public static boolean getEngaged(NPC npc) {
if (currentlyEngaged.containsKey(npc)) {
if (currentlyEngaged.get(npc) > System.currentTimeMillis()) {
return true;
}
}
return false;
}
/**
* Sets a dNPC's ENGAGED status. Engaged NPCs do not respond to Player
* interaction. Note: Denizen NPC will automatically disengage after the
* engage_timeout_in_seconds which is set in the Denizen config.yml.
*
* @param npc the dNPC affected
* @param engaged true sets the dNPC engaged, false sets the dNPC as disengaged
*/
public static void setEngaged(NPC npc, boolean engaged) {
if (engaged) {
currentlyEngaged.put(npc, System.currentTimeMillis()
+ (long) (Duration.valueOf(Settings.engageTimeoutInSeconds()).getSeconds()) * 1000);
}
if (!engaged) {
currentlyEngaged.remove(npc);
}
}
/**
* Sets a dNPC as ENGAGED for a specific amount of seconds. Engaged NPCs do not
* respond to Player interaction. If the NPC is previously engaged, using this will
* over-ride the previously set duration.
*
* @param npc the dNPC to set as engaged
* @param duration the number of seconds to engage the dNPC
*/
public static void setEngaged(NPC npc, int duration) {
currentlyEngaged.put(npc, System.currentTimeMillis() + duration * 1000);
}
}