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

Update healing event and related expressions #6339

Merged
merged 12 commits into from
Jul 1, 2024
Merged
94 changes: 94 additions & 0 deletions src/main/java/ch/njol/skript/events/EvtHealing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.events;

import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.entity.EntityData;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptEvent;
import ch.njol.skript.lang.SkriptParser.ParseResult;

public class EvtHealing extends SkriptEvent {

static {
Skript.registerEvent("Heal", EvtHealing.class, EntityRegainHealthEvent.class, "heal[ing] [of %-entitydatas%] [(from|due to|by) %-healreasons%]", "%entitydatas% heal[ing] [(from|due to|by) %-healreasons%]")
.description("Called when an entity is healed, e.g. by eating (players), being fed (pets), or by the effect of a potion of healing (overworld mobs) or harm (nether mobs).")
.examples("on heal:", "on player healing from a regeneration potion:",
"on healing of a zombie, cow or a wither:" +
"\theal reason is healing potion" +
"\tcancel event"
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
)
.since("1.0, INSERT VERSION (by entity)");
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
}

@Nullable
private Literal<EntityData<?>> entityDatas;

@Nullable
private Literal<RegainReason> healReasons;

@Override
@SuppressWarnings("unchecked")
public boolean init(Literal<?>[] args, int matchedPattern, ParseResult parser) {
entityDatas = (Literal<EntityData<?>>) args[0];
healReasons = (Literal<RegainReason>) args[1];
return true;
}

@Override
public boolean check(Event event) {
if (!(event instanceof EntityRegainHealthEvent))
return false;
EntityRegainHealthEvent healthEvent = (EntityRegainHealthEvent) event;
if (entityDatas != null) {
Entity compare = healthEvent.getEntity();
boolean result = false;
for (EntityData<?> entityData : entityDatas.getArray()) {
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
if (entityData.isInstance(compare))
result = true;
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
}
if (!result)
return false;
}
if (healReasons != null) {
RegainReason compare = healthEvent.getRegainReason();
boolean result = false;
for (RegainReason healReason : healReasons.getArray()) {
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
if (healReason == compare)
result = true;
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
}
if (!result)
return false;
}
return true;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "heal" + (entityDatas != null ? " of " + entityDatas.toString(event, debug) : "") +
(healReasons != null ? " by " + healReasons.toString(event, debug) : "");
}

}
5 changes: 0 additions & 5 deletions src/main/java/ch/njol/skript/events/SimpleEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityPortalEnterEvent;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityResurrectEvent;
import org.bukkit.event.entity.EntityTameEvent;
import org.bukkit.event.entity.EntityToggleGlideEvent;
Expand Down Expand Up @@ -209,10 +208,6 @@ public class SimpleEvents {
.description("Called when an entity enters a nether portal or an end portal. Please note that this event will be fired many times for a nether portal.")
.examples("on portal enter:")
.since("1.0");
Skript.registerEvent("Heal", SimpleEvent.class, EntityRegainHealthEvent.class, "heal[ing]")
.description("Called when an entity is healed, e.g. by eating (players), being fed (pets), or by the effect of a potion of healing (overworld mobs) or harm (nether mobs).")
.examples("on heal:")
.since("1.0");
Skript.registerEvent("Tame", SimpleEvent.class, EntityTameEvent.class, "[entity] tam(e|ing)")
.description("Called when a player tames a wolf or ocelot. Can be cancelled to prevent the entity from being tamed.")
.examples("on tame:")
Expand Down
75 changes: 41 additions & 34 deletions src/main/java/ch/njol/skript/expressions/ExprHealAmount.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,56 +25,57 @@

import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Events;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.log.ErrorQuality;
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;

@Name("Heal Amount")
@Description("The amount of health healed in a healing event.")
@Examples({"increase heal amount by 2",
"remove 0.5 from heal amount"})
@Since("2.5.1")
@Description("The amount of health healed in a <a href='./events.html#heal'>heal event</a>.")
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
@Examples({
"on player healing:",
"\tincrease the heal amount by 2",
"\tremove 0.5 from the healing amount"
})
@Events("heal")
public class ExprHealAmount extends SimpleExpression<Number> {

@Since("2.5.1")
public class ExprHealAmount extends SimpleExpression<Double> {

static {
Skript.registerExpression(ExprHealAmount.class, Number.class, ExpressionType.SIMPLE, "[the] heal amount");
Skript.registerExpression(ExprHealAmount.class, Double.class, ExpressionType.SIMPLE, "[the] heal[ing] amount");
}

@SuppressWarnings("null")

private Kleenean delay;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!getParser().isCurrentEvent(EntityRegainHealthEvent.class)) {
Skript.error("The expression 'heal amount' may only be used in a healing event", ErrorQuality.SEMANTIC_ERROR);
Skript.error("The expression 'heal amount' may only be used in a healing event");
return false;
}
delay = isDelayed;
return true;
}

@Nullable
@Override
protected Number[] get(Event e) {
if (!(e instanceof EntityRegainHealthEvent))
protected Double[] get(Event event) {
if (!(event instanceof EntityRegainHealthEvent))
return null;

return new Number[]{((EntityRegainHealthEvent) e).getAmount()};
return new Double[]{((EntityRegainHealthEvent) event).getAmount()};
}

@Nullable
@Override
public Class<?>[] acceptChange(Changer.ChangeMode mode) {
public Class<?>[] acceptChange(ChangeMode mode) {
if (delay != Kleenean.FALSE) {
Skript.error("The heal amount cannot be changed after the event has already passed");
return null;
Expand All @@ -83,42 +84,48 @@ public Class<?>[] acceptChange(Changer.ChangeMode mode) {
return null;
return CollectionUtils.array(Number.class);
}

@Override
public void change(Event e, @Nullable Object[] delta, Changer.ChangeMode mode) {
if (!(e instanceof EntityRegainHealthEvent))
public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
if (!(event instanceof EntityRegainHealthEvent))
return;

EntityRegainHealthEvent healthEvent = (EntityRegainHealthEvent) event;
double value = delta == null ? 0 : ((Number) delta[0]).doubleValue();
switch (mode) {
case SET:
case DELETE:
((EntityRegainHealthEvent) e).setAmount(value);
healthEvent.setAmount(value);
break;
case ADD:
((EntityRegainHealthEvent) e).setAmount(((EntityRegainHealthEvent) e).getAmount() + value);
healthEvent.setAmount(healthEvent.getAmount() + value);
break;
case REMOVE:
((EntityRegainHealthEvent) e).setAmount(((EntityRegainHealthEvent) e).getAmount() - value);
healthEvent.setAmount(healthEvent.getAmount() - value);
break;
default:
break;
}
}


@Override
public boolean setTime(int time) {
return super.setTime(time);
}
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved

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

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

@Override
public String toString(@Nullable Event e, boolean debug) {
public String toString(@Nullable Event event, boolean debug) {
return "heal amount";
}

}
47 changes: 28 additions & 19 deletions src/main/java/ch/njol/skript/expressions/ExprHealReason.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,60 +25,69 @@

import ch.njol.skript.Skript;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Events;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.log.ErrorQuality;
import ch.njol.skript.registrations.EventValues;
import ch.njol.util.Kleenean;


@Name("Heal Reason")
@Description("The <a href='./classes.html#healreason'>heal reason</a> of a heal event. Please click on the link for more information.")
@Examples({"on heal:",
"\tif heal reason = satiated:",
"\t\tsend \"You ate enough food and gained health back!\" to player"})
@Description("The <a href='./classes.html#healreason'>heal reason</a> of a <a href='./events.html#heal'>heal event</a>.")
@Examples({
"on heal:",
"\theal reason is satiated",
"\tsend \"You ate enough food and gained full health back!\""
})
@Events("heal")
@Since("2.5")
public class ExprHealReason extends SimpleExpression<RegainReason> {
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved

static {
Skript.registerExpression(ExprHealReason.class, RegainReason.class, ExpressionType.SIMPLE, "(regen|health regain|heal) (reason|cause)");
Skript.registerExpression(ExprHealReason.class, RegainReason.class, ExpressionType.SIMPLE, "(regen|health regain|heal[ing]) (reason|cause)");
}

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!getParser().isCurrentEvent(EntityRegainHealthEvent.class)) {
Skript.error("Heal reason can only be used in an on heal event", ErrorQuality.SEMANTIC_ERROR);
Skript.error("The expression 'heal reason' may only be used in a healing event");
return false;
}
return true;
}

@Nullable
@Override
protected RegainReason[] get(Event e) {
if (!(e instanceof EntityRegainHealthEvent))
protected RegainReason[] get(Event event) {
if (!(event instanceof EntityRegainHealthEvent))
return null;
return new RegainReason[]{((EntityRegainHealthEvent) event).getRegainReason()};
}

return new RegainReason[]{((EntityRegainHealthEvent) e).getRegainReason()};
@Override
public boolean setTime(int time) {
if (time == EventValues.TIME_FUTURE)
return false;
return super.setTime(time);
}
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved

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

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

@Override
public String toString(@Nullable Event e, boolean debug) {
public String toString(@Nullable Event event, boolean debug) {
return "heal reason";
}

}