-
-
Notifications
You must be signed in to change notification settings - Fork 104
/
HurtCommand.java
142 lines (134 loc) · 6.34 KB
/
HurtCommand.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
package com.denizenscript.denizen.scripts.commands.entity;
import com.denizenscript.denizen.nms.NMSHandler;
import com.denizenscript.denizen.utilities.Utilities;
import com.denizenscript.denizen.utilities.debugging.Debug;
import com.denizenscript.denizen.objects.EntityTag;
import com.denizenscript.denizencore.exceptions.InvalidArgumentsException;
import com.denizenscript.denizencore.objects.Argument;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.ArgumentHelper;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.scripts.ScriptEntry;
import com.denizenscript.denizencore.scripts.commands.AbstractCommand;
import com.denizenscript.denizencore.utilities.Deprecations;
import org.bukkit.event.entity.EntityDamageEvent;
import java.util.ArrayList;
import java.util.List;
public class HurtCommand extends AbstractCommand {
public HurtCommand() {
setName("hurt");
setSyntax("hurt (<#.#>) ({player}/<entity>|...) (cause:<cause>) (source:<entity>)");
setRequiredArguments(0, 5);
isProcedural = false;
}
// <--[command]
// @Name Hurt
// @Syntax hurt (<#.#>) ({player}/<entity>|...) (cause:<cause>) (source:<entity>)
// @Required 0
// @Maximum 4
// @Short Hurts the player or a list of entities.
// @Synonyms Damage,Injure
// @Group entity
//
// @Description
// Does damage to a list of entities, or to any single entity.
//
// If no entities are specified: if there is a linked player, the command targets that. If there is no linked
// player but there is a linked NPC, the command targets the NPC. If neither is available, the command will error.
//
// Does a specified amount of damage usually, but, if no damage is specified, does precisely 1HP worth of damage (half a heart).
//
// Optionally, specify (source:<entity>) to make the system treat that entity as the attacker.
//
// You may also specify a damage cause to fire a proper damage event with the given cause, only doing the damage if the event wasn't cancelled.
// Calculates the 'final damage' rather than using the raw damage input number. See <@link language damage cause> for damage causes.
//
// Using a valid 'cause' value is best when trying to replicate natural damage, excluding it is best when trying to force the raw damage through.
// Note that using invalid or impossible causes may lead to bugs
//
// @Tags
// <EntityTag.health>
// <EntityTag.last_damage.amount>
// <EntityTag.last_damage.cause>
// <EntityTag.last_damage.duration>
// <EntityTag.last_damage.max_duration>
//
// @Usage
// Use to hurt the player for 1 HP.
// - hurt
//
// @Usage
// Use to hurt the NPC for 5 HP.
// - hurt 5 <npc>
//
// @Usage
// Use to cause the player to hurt the NPC for all its health (if unarmored).
// - hurt <npc.health> <npc> cause:CUSTOM source:<player>
// -->
@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {
for (Argument arg : scriptEntry) {
if (!scriptEntry.hasObject("amount")
&& (arg.matchesFloat()
|| arg.matchesInteger())) {
scriptEntry.addObject("amount", arg.asElement());
}
else if (!scriptEntry.hasObject("source")
&& arg.matchesPrefix("source", "s")
&& arg.matchesArgumentType(EntityTag.class)) {
scriptEntry.addObject("source", arg.asType(EntityTag.class));
}
else if (!scriptEntry.hasObject("entities")
&& arg.matchesArgumentList(EntityTag.class)) {
scriptEntry.addObject("entities", arg.asType(ListTag.class).filter(EntityTag.class, scriptEntry));
}
else if (!scriptEntry.hasObject("cause")
&& arg.matchesEnum(EntityDamageEvent.DamageCause.values())) {
scriptEntry.addObject("cause", arg.asElement());
}
else if (!scriptEntry.hasObject("source_once")
&& arg.matches("source_once")) {
Deprecations.hurtSourceOne.warn(scriptEntry);
scriptEntry.addObject("source_once", new ElementTag(true));
}
else {
arg.reportUnhandled();
}
}
if (!scriptEntry.hasObject("amount")) {
scriptEntry.addObject("amount", new ElementTag(1.0d));
}
if (!scriptEntry.hasObject("entities")) {
List<EntityTag> entities = new ArrayList<>();
if (Utilities.getEntryPlayer(scriptEntry) != null) {
entities.add(Utilities.getEntryPlayer(scriptEntry).getDenizenEntity());
}
else if (Utilities.getEntryNPC(scriptEntry) != null) {
entities.add(Utilities.getEntryNPC(scriptEntry).getDenizenEntity());
}
else {
throw new InvalidArgumentsException("No valid target entities found.");
}
scriptEntry.addObject("entities", entities);
}
}
@Override
public void execute(ScriptEntry scriptEntry) {
List<EntityTag> entities = (List<EntityTag>) scriptEntry.getObject("entities");
EntityTag source = scriptEntry.getObjectTag("source");
ElementTag amountElement = scriptEntry.getElement("amount");
ElementTag cause = scriptEntry.getElement("cause");
if (scriptEntry.dbCallShouldDebug()) {
Debug.report(scriptEntry, getName(), amountElement, db("entities", entities), cause, source);
}
double amount = amountElement.asDouble();
for (EntityTag entity : entities) {
if (entity.getLivingEntity() == null) {
Debug.echoDebug(scriptEntry, entity + " is not a living entity!");
continue;
}
EntityDamageEvent.DamageCause causeEnum = cause == null ? null : EntityDamageEvent.DamageCause.valueOf(cause.asString().toUpperCase());
NMSHandler.getEntityHelper().damage(entity.getLivingEntity(), (float) amount, source == null ? null : source.getBukkitEntity(), causeEnum);
}
}
}