Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add damage support for PlayerItemDamageEvent #5269

Closed
wants to merge 11 commits into from
111 changes: 72 additions & 39 deletions src/main/java/ch/njol/skript/expressions/ExprDamage.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.bukkit.event.Event;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.eclipse.jdt.annotation.Nullable;

Expand All @@ -30,6 +31,7 @@
import ch.njol.skript.doc.Events;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.RequiredPlugins;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
Expand All @@ -39,47 +41,71 @@
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;

/**
* @author Peter Güttinger
*/
@Name("Damage")
@Description("How much damage is done in a damage event, possibly ignoring armour, criticals and/or enchantments. Can be changed (remember that in Skript '1' is one full heart, not half a heart).")
@Examples({"increase the damage by 2"})
@Description({
"How much damage is done in a damage event, possibly ignoring armour, criticals and/or enchantments.",
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
"Can be changed (remember that in Skript '1' is one full heart, not half a heart)."
})
@Examples({
"on damage of player:",
"\tdamage cause was lightning",
"\tvictim is wearing a leather helmet",
"\tsubtract 2.5 from the damage",
"\tmessage \"The smite was lessened by your leather helmet!\" to the victim"
})
@Since("1.3.5")
@RequiredPlugins("Spigot 1.14+ for the item damage event.")
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
@Events("damage")
public class ExprDamage extends SimpleExpression<Number> {


private final static boolean ITEM_DAMAGE = Skript.classExists("org.bukkit.event.player.PlayerItemDamageEvent");

static {
Skript.registerExpression(ExprDamage.class, Number.class, ExpressionType.SIMPLE, "[the] damage");
}

@SuppressWarnings("null")

private Kleenean delay;

@Override
public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) {
if (!getParser().isCurrentEvent(EntityDamageEvent.class, VehicleDamageEvent.class)) {
Skript.error("The expression 'damage' may only be used in damage events", ErrorQuality.SEMANTIC_ERROR);
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (ITEM_DAMAGE) {
if (!getParser().isCurrentEvent(EntityDamageEvent.class, VehicleDamageEvent.class, PlayerItemDamageEvent.class)) {
Skript.error("The expression 'damage' may only be used in damage events");
return false;
}
} else if (!getParser().isCurrentEvent(EntityDamageEvent.class, VehicleDamageEvent.class)) {
Skript.error("The expression 'damage' may only be used in damage events");
return false;
}
delay = isDelayed;
return true;
}

@Override
@Nullable
protected Number[] get(final Event e) {
if (!(e instanceof EntityDamageEvent || e instanceof VehicleDamageEvent))
protected Number[] get(Event event) {
if (!(event instanceof EntityDamageEvent || event instanceof VehicleDamageEvent))
return new Number[0];
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved

if (e instanceof VehicleDamageEvent)
return CollectionUtils.array(((VehicleDamageEvent) e).getDamage());
return CollectionUtils.array(HealthUtils.getDamage((EntityDamageEvent) e));
}

if (event instanceof VehicleDamageEvent)
return CollectionUtils.array(((VehicleDamageEvent) event).getDamage());

if (event instanceof EntityDamageEvent)
return CollectionUtils.array(HealthUtils.getDamage((EntityDamageEvent) event));

if (ITEM_DAMAGE) {
if (!(event instanceof PlayerItemDamageEvent))
return new Number[0];
return CollectionUtils.array(((PlayerItemDamageEvent) event).getDamage());
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
}

assert false;
return new Number[0];
}

@Override
@Nullable
public Class<?>[] acceptChange(final ChangeMode mode) {
public Class<?>[] acceptChange(ChangeMode mode) {
if (delay != Kleenean.FALSE) {
Skript.error("Can't change the damage anymore after the event has already passed");
return null;
Expand All @@ -88,48 +114,55 @@ public Class<?>[] acceptChange(final ChangeMode mode) {
return null;
return CollectionUtils.array(Number.class);
}

@Override
public void change(final Event e, final @Nullable Object[] delta, final ChangeMode mode) throws UnsupportedOperationException {
if (!(e instanceof EntityDamageEvent || e instanceof VehicleDamageEvent))
public void change(Event event, @Nullable Object[] delta, ChangeMode mode) throws UnsupportedOperationException {
if (!(event instanceof EntityDamageEvent || event instanceof VehicleDamageEvent || (ITEM_DAMAGE && event instanceof PlayerItemDamageEvent))) {
return;
double d = delta == null ? 0 : ((Number) delta[0]).doubleValue();
}
Number damage = delta == null ? 0 : (Number) delta[0];
switch (mode) {
case SET:
case DELETE:
if (e instanceof VehicleDamageEvent)
((VehicleDamageEvent) e).setDamage(d);
else
HealthUtils.setDamage((EntityDamageEvent) e, d);
if (event instanceof VehicleDamageEvent) {
((VehicleDamageEvent) event).setDamage(damage.doubleValue());
} else if (ITEM_DAMAGE && event instanceof PlayerItemDamageEvent) {
((PlayerItemDamageEvent) event).setDamage(damage.intValue());
} else {
HealthUtils.setDamage((EntityDamageEvent) event, damage.doubleValue());
}
break;
case REMOVE:
d = -d;
damage = -damage.doubleValue();
//$FALL-THROUGH$
case ADD:
if (e instanceof VehicleDamageEvent)
((VehicleDamageEvent) e).setDamage(((VehicleDamageEvent) e).getDamage() + d);
else
HealthUtils.setDamage((EntityDamageEvent) e, HealthUtils.getDamage((EntityDamageEvent) e) + d);
if (event instanceof VehicleDamageEvent) {
((VehicleDamageEvent) event).setDamage(((VehicleDamageEvent) event).getDamage() + damage.doubleValue());
} else if (ITEM_DAMAGE && event instanceof PlayerItemDamageEvent) {
((PlayerItemDamageEvent) event).setDamage(((PlayerItemDamageEvent) event).getDamage() + damage.intValue());
} else {
HealthUtils.setDamage((EntityDamageEvent) event, HealthUtils.getDamage((EntityDamageEvent) event) + damage.doubleValue());
}
break;
case REMOVE_ALL:
case RESET:
assert false;
}
}

@Override
public boolean isSingle() {
return true;
}

@Override
public Class<? extends Number> getReturnType() {
return Number.class;
}

@Override
public String toString(final @Nullable Event e, final boolean debug) {
public String toString(@Nullable Event event, boolean debug) {
return "the damage";
}

}