From 4c0ddfbe9b208a5a34bd65da1517cf89c779d400 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Tue, 13 Feb 2024 23:17:39 -0700 Subject: [PATCH 1/8] Fixes 1.20.4 DamageCause on EntityDamageEvent --- .../njol/skript/bukkitutil/HealthUtils.java | 66 ++++++++++-- .../skript/classes/data/BukkitClasses.java | 47 ++++++++ .../expressions/ExprLastDamageCause.java | 100 +++++++++++------- src/main/resources/lang/default.lang | 2 + 4 files changed, 163 insertions(+), 52 deletions(-) diff --git a/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java b/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java index 9af9012eb7f..b2acc06df88 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java +++ b/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java @@ -18,13 +18,21 @@ */ package ch.njol.skript.bukkitutil; +import ch.njol.skript.Skript; import ch.njol.util.Math2; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + import org.bukkit.attribute.Attributable; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.Damageable; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval; +import org.jetbrains.annotations.Nullable; public class HealthUtils { @@ -38,7 +46,7 @@ public static double getHealth(Damageable e) { return 0; return e.getHealth() / 2; } - + /** * Set the health of an entity * @param e Entity to set health for @@ -47,7 +55,7 @@ public static double getHealth(Damageable e) { public static void setHealth(Damageable e, double health) { e.setHealth(Math2.fit(0, health, getMaxHealth(e)) * 2); } - + /** * Get the max health an entity has * @param e Entity to get max health from @@ -58,7 +66,7 @@ public static double getMaxHealth(Damageable e) { assert attributeInstance != null; return attributeInstance.getValue() / 2; } - + /** * Set the max health an entity can have * @param e Entity to set max health for @@ -69,7 +77,7 @@ public static void setMaxHealth(Damageable e, double health) { assert attributeInstance != null; attributeInstance.setBaseValue(health * 2); } - + /** * Apply damage to an entity * @param e Entity to apply damage to @@ -95,21 +103,57 @@ public static void heal(Damageable e, double h) { } setHealth(e, getHealth(e) + h); } - + public static double getDamage(EntityDamageEvent e) { return e.getDamage() / 2; } - + public static double getFinalDamage(EntityDamageEvent e) { return e.getFinalDamage() / 2; } - + public static void setDamage(EntityDamageEvent e, double damage) { e.setDamage(damage * 2); } - - public static void setDamageCause(Damageable e, DamageCause cause) { - e.setLastDamageCause(new EntityDamageEvent(e, cause, 0)); + + /** + * In a late 1.20.4 version. Spigot added a non null DamageSource parameter in all EntityDamageEvent constructors, + * and removed existing constructors that did not contain a DamageSource parameter. + * @ScheduledForRemoval Existing until proper support is added to ExprLastDamageCause for DamageSource + */ + @Deprecated + @ScheduledForRemoval + public static boolean DAMAGE_SOURCE; + + @Nullable + private static Constructor DAMAGE_EVENT_CONSTRUCTOR; + + static { + if (!DAMAGE_SOURCE) { + try { + DAMAGE_EVENT_CONSTRUCTOR = EntityDamageEvent.class.getConstructor(Damageable.class, DamageCause.class, double.class); + // Throws here. DAMAGE_SOURCE should only be set if DAMAGE_EVENT_CONSTRUCTOR doesn't exist. + DAMAGE_SOURCE = Skript.classExists("org.bukkit.damage.DamageSource"); + } catch (NoSuchMethodException | SecurityException e) {} + } + } + + /** + * Used to set the damage cause of a damageable entity in an entity damage event. + * Can only be used in versions below 1.20.4. + * + * @param entity The damaged entity. + * @param cause The damage cause in the damage event. + * @deprecated Only used in versions below 1.20.4. See {@link org.bukkit.damage.DamageSource} + */ + @Deprecated + @ScheduledForRemoval + public static void setDamageCause(Damageable entity, DamageCause cause) { + if (DAMAGE_SOURCE) + return; + try { + entity.setLastDamageCause(DAMAGE_EVENT_CONSTRUCTOR.newInstance(entity, cause, 0)); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {} } - + } diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java index 25000a2390d..bc6ead88d9d 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.Map.Entry; import java.util.UUID; import java.util.regex.Matcher; @@ -37,7 +38,9 @@ import org.bukkit.GameRule; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; +import org.bukkit.Registry; import org.bukkit.SoundCategory; import org.bukkit.World; import org.bukkit.World.Environment; @@ -48,6 +51,8 @@ import org.bukkit.block.DoubleChest; import org.bukkit.block.data.BlockData; import org.bukkit.command.CommandSender; +import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.EnchantmentOffer; import org.bukkit.entity.Cat; @@ -1548,6 +1553,48 @@ public String toVariableNameString(EnchantmentOffer eo) { .name("Transform Reason") .description("Represents a transform reason of an entity transform event.") .since("2.8.0")); + + if (Skript.classExists("org.bukkit.damage.DamageType")) { + Classes.registerClass(new ClassInfo<>(DamageSource.class, "damagesource") + .user("damage ?sources?") + .name("Damage Source") + .description("The damage source in an entity damage event.") + .since("INSERT VERSION")); + + Classes.registerClass(new ClassInfo<>(DamageType.class, "damagetype") + .user("damage ?types?") + .name("Damage Type") + .description("The damage type of a damage source.") + .since("INSERT VERSION") + .parser(new Parser() { + @Override + @Nullable + public DamageType parse(String input, ParseContext context) { + if (input.contains(":")) { + String[] split = input.split(Pattern.quote(":")); + try { + return Registry.DAMAGE_TYPE.get(new NamespacedKey(split[0], split[1])); + } catch (IllegalArgumentException e) {} + } + try { + return Registry.DAMAGE_TYPE.get(NamespacedKey.minecraft(input)); + } catch (IllegalArgumentException e) {} + + return null; + } + + @Override + public String toString(DamageType type, int flags) { + return type.getKey().getNamespace(); + } + + @Override + public String toVariableNameString(DamageType type) { + return "damage type:" + type.getKey().getNamespace(); + } + })); + } + } } diff --git a/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java b/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java index 520d6198a4f..4fc32c05ed9 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java @@ -18,11 +18,21 @@ */ package ch.njol.skript.expressions; +import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.eclipse.jdt.annotation.Nullable; + +import ch.njol.skript.Skript; import ch.njol.skript.bukkitutil.HealthUtils; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.doc.Description; 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.expressions.base.PropertyExpression; import ch.njol.skript.lang.Expression; @@ -30,74 +40,75 @@ import ch.njol.skript.util.Getter; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Event; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.eclipse.jdt.annotation.Nullable; -/** - * @author bensku - * - */ -@Name("Last Damage Cause") -@Description("Cause of last damage done to an entity") -@Examples({"set last damage cause of event-entity to fire tick"}) +@Name("Last Damage Cause/Type") +@Description({ + "Cause of last damage done to an entity.", + "Damage type is more accurate including data pack types and only available in 1.20.4+" +}) +@Examples({ + "set last damage cause of event-entity to fire tick" +}) +@RequiredPlugins("Spigot 1.20.4+ damage type") @Since("2.2-Fixes-V10") -public class ExprLastDamageCause extends PropertyExpression{ - +public class ExprLastDamageCause extends PropertyExpression { + static { - register(ExprLastDamageCause.class, DamageCause.class, "last damage (cause|reason|type)", "livingentities"); + register(ExprLastDamageCause.class, Object.class, "last damage (cause|reason|:type)", "livingentities"); } - @SuppressWarnings({"unchecked", "null"}) + private boolean type; + @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { setExpr((Expression) exprs[0]); + type = parseResult.hasTag("type"); return true; } - + @Override - protected DamageCause[] get(Event e, LivingEntity[] source) { - return get(source, new Getter() { + protected Object[] get(Event event, LivingEntity[] source) { + return get(source, new Getter() { @Override - public DamageCause get(LivingEntity entity) { - EntityDamageEvent dmgEvt = entity.getLastDamageCause(); - if (dmgEvt == null) return DamageCause.CUSTOM; - return dmgEvt.getCause(); + public Object get(LivingEntity entity) { + EntityDamageEvent damageEvent = entity.getLastDamageCause(); + if (damageEvent == null) { + if (type) + return DamageType.GENERIC; + return DamageCause.CUSTOM; + } + if (type) + return damageEvent.getDamageSource().getDamageType(); + return damageEvent.getCause(); } }); } - - @Override - public String toString(@Nullable Event e, boolean debug) { - return "the damage cause " + getExpr().toString(e, debug); - } - + @Override @Nullable public Class[] acceptChange(ChangeMode mode) { - if (mode == ChangeMode.REMOVE_ALL) + if (mode == ChangeMode.REMOVE_ALL || type || HealthUtils.DAMAGE_SOURCE) return null; return CollectionUtils.array(DamageCause.class); } - + @Override - public void change(Event e, @Nullable Object[] delta, ChangeMode mode) { - DamageCause d = delta == null ? DamageCause.CUSTOM : (DamageCause) delta[0]; - assert d != null; + public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { + DamageCause cause = delta == null ? DamageCause.CUSTOM : (DamageCause) delta[0]; + assert cause != null; switch (mode) { case DELETE: case RESET: // Reset damage cause? Umm, maybe it is custom. - for (LivingEntity entity : getExpr().getArray(e)) { + for (LivingEntity entity : getExpr().getArray(event)) { assert entity != null : getExpr(); HealthUtils.setDamageCause(entity, DamageCause.CUSTOM); } break; case SET: - for (LivingEntity entity : getExpr().getArray(e)) { + for (LivingEntity entity : getExpr().getArray(event)) { assert entity != null : getExpr(); - HealthUtils.setDamageCause(entity, d); + HealthUtils.setDamageCause(entity, cause); } break; case REMOVE_ALL: @@ -107,10 +118,17 @@ public void change(Event e, @Nullable Object[] delta, ChangeMode mode) { break; } } - + + @Override + public Class getReturnType() { + return type ? DamageType.class : DamageCause.class; + } + @Override - public Class getReturnType() { - return DamageCause.class; + public String toString(@Nullable Event event, boolean debug) { + if (type) + return "damage type " + getExpr().toString(event, debug); + return "damage cause " + getExpr().toString(event, debug); } } diff --git a/src/main/resources/lang/default.lang b/src/main/resources/lang/default.lang index efd0651babf..ef3af71ee90 100644 --- a/src/main/resources/lang/default.lang +++ b/src/main/resources/lang/default.lang @@ -2059,6 +2059,8 @@ types: quitreason: quit reason¦s @a inventoryclosereason: inventory close reason¦s @an transformreason: transform reason¦s @a + damagesource: damage source¦s @a + damagetype: damage type¦s @a # Skript weathertype: weather type¦s @a From bd2abc4c1adc5e3bf476654fe64dd10f0b7bc089 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 14 Feb 2024 00:38:13 -0700 Subject: [PATCH 2/8] Update BukkitClasses.java --- src/main/java/ch/njol/skript/classes/data/BukkitClasses.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java index bc6ead88d9d..b3c9e5ef10d 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java @@ -1585,12 +1585,12 @@ public DamageType parse(String input, ParseContext context) { @Override public String toString(DamageType type, int flags) { - return type.getKey().getNamespace(); + return type.getKey(); } @Override public String toVariableNameString(DamageType type) { - return "damage type:" + type.getKey().getNamespace(); + return "damage type:" + type.getKey(); } })); } From bd3da126a82a6c6a6fba5886004e6b94320348a5 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 14 Feb 2024 00:39:48 -0700 Subject: [PATCH 3/8] Update BukkitClasses.java --- src/main/java/ch/njol/skript/classes/data/BukkitClasses.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java index b3c9e5ef10d..bd8a5d0a816 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java @@ -1585,12 +1585,12 @@ public DamageType parse(String input, ParseContext context) { @Override public String toString(DamageType type, int flags) { - return type.getKey(); + return Classes.toString(type.getKey()); } @Override public String toVariableNameString(DamageType type) { - return "damage type:" + type.getKey(); + return "damage type: " + Classes.toString(type.getKey()); } })); } From 26e007ab9961a5929dddac9a074ab7be084e2d53 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 14 Feb 2024 00:40:28 -0700 Subject: [PATCH 4/8] Update BukkitClasses.java --- src/main/java/ch/njol/skript/classes/data/BukkitClasses.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java index bd8a5d0a816..7cfd647f8de 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java @@ -1585,12 +1585,12 @@ public DamageType parse(String input, ParseContext context) { @Override public String toString(DamageType type, int flags) { - return Classes.toString(type.getKey()); + return type.getKey(); } @Override public String toVariableNameString(DamageType type) { - return "damage type: " + Classes.toString(type.getKey()); + return "damage type: " + type.getKey(); } })); } From 87eb3935e5f8861e5adca93b547174a6a5c1832b Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 14 Feb 2024 10:04:52 -0700 Subject: [PATCH 5/8] Update BukkitClasses.java --- src/main/java/ch/njol/skript/classes/data/BukkitClasses.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java index 7cfd647f8de..d419e4d0582 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java @@ -1585,12 +1585,12 @@ public DamageType parse(String input, ParseContext context) { @Override public String toString(DamageType type, int flags) { - return type.getKey(); + return type.getKey().toString(); } @Override public String toVariableNameString(DamageType type) { - return "damage type: " + type.getKey(); + return "damage type: " + type.getKey().toString(); } })); } From a87b366e1d8250dc4431b14fdd4cfc001bb6c0f3 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Sat, 9 Mar 2024 19:29:39 -0700 Subject: [PATCH 6/8] Apply suggestions from code review Co-authored-by: Patrick Miller --- .../java/ch/njol/skript/expressions/ExprLastDamageCause.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java b/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java index 4fc32c05ed9..54b3230014f 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java @@ -44,12 +44,12 @@ @Name("Last Damage Cause/Type") @Description({ "Cause of last damage done to an entity.", - "Damage type is more accurate including data pack types and only available in 1.20.4+" + "Using 'damage type' is more accurate as it includes data pack types, but it is only available on versions 1.20.4 and newer." }) @Examples({ "set last damage cause of event-entity to fire tick" }) -@RequiredPlugins("Spigot 1.20.4+ damage type") +@RequiredPlugins("Spigot 1.20.4+ for damage type") @Since("2.2-Fixes-V10") public class ExprLastDamageCause extends PropertyExpression { From ae0b208857fe6c52119d226135a057b4cedc0e91 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Sat, 9 Mar 2024 20:17:59 -0700 Subject: [PATCH 7/8] Fixes --- src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java b/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java index 1217747eb24..561a02567cb 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java +++ b/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java @@ -132,7 +132,7 @@ public static void setDamage(EntityDamageEvent e, double damage) { public static boolean DAMAGE_SOURCE; @Nullable - private static final Constructor DAMAGE_EVENT_CONSTRUCTOR; + private static Constructor DAMAGE_EVENT_CONSTRUCTOR; static { if (!DAMAGE_SOURCE) { @@ -161,7 +161,7 @@ public static void setDamageCause(Damageable entity, DamageCause cause) { entity.setLastDamageCause(DAMAGE_EVENT_CONSTRUCTOR.newInstance(entity, cause, 0)); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { Skript.exception(e, "Failed to set last damage cause"); - } + } } } From bd5d51b5224d9a4140e6247717abedd95d57b75c Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Mon, 29 Apr 2024 16:26:55 -0600 Subject: [PATCH 8/8] Requested changes --- .../expressions/ExprLastDamageCause.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java b/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java index 54b3230014f..ea49626bbf7 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLastDamageCause.java @@ -18,14 +18,6 @@ */ package ch.njol.skript.expressions; -import org.bukkit.damage.DamageSource; -import org.bukkit.damage.DamageType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Event; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.eclipse.jdt.annotation.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.bukkitutil.HealthUtils; import ch.njol.skript.classes.Changer.ChangeMode; @@ -41,18 +33,28 @@ import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; +import org.bukkit.damage.DamageType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.eclipse.jdt.annotation.Nullable; + @Name("Last Damage Cause/Type") @Description({ "Cause of last damage done to an entity.", "Using 'damage type' is more accurate as it includes data pack types, but it is only available on versions 1.20.4 and newer." }) @Examples({ - "set last damage cause of event-entity to fire tick" + "set last damage cause of event-entity to fire tick", + "set last damage type of event-entity to wither" }) @RequiredPlugins("Spigot 1.20.4+ for damage type") @Since("2.2-Fixes-V10") public class ExprLastDamageCause extends PropertyExpression { + private static final boolean DAMAGE_TYPE = Skript.classExists("org.bukkit.damage.DamageType"); + static { register(ExprLastDamageCause.class, Object.class, "last damage (cause|reason|:type)", "livingentities"); } @@ -74,11 +76,11 @@ protected Object[] get(Event event, LivingEntity[] source) { public Object get(LivingEntity entity) { EntityDamageEvent damageEvent = entity.getLastDamageCause(); if (damageEvent == null) { - if (type) + if (type && DAMAGE_TYPE) return DamageType.GENERIC; return DamageCause.CUSTOM; } - if (type) + if (type && DAMAGE_TYPE) return damageEvent.getDamageSource().getDamageType(); return damageEvent.getCause(); } @@ -121,12 +123,12 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { @Override public Class getReturnType() { - return type ? DamageType.class : DamageCause.class; + return type && DAMAGE_TYPE ? DamageType.class : DamageCause.class; } @Override public String toString(@Nullable Event event, boolean debug) { - if (type) + if (type && DAMAGE_TYPE) return "damage type " + getExpr().toString(event, debug); return "damage cause " + getExpr().toString(event, debug); }