diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/fight/event/CauseOfTag.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/fight/event/CauseOfTag.java index 9cbc001e..8250cda4 100644 --- a/eternalcombat-api/src/main/java/com/eternalcode/combat/fight/event/CauseOfTag.java +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/fight/event/CauseOfTag.java @@ -34,6 +34,11 @@ public enum CauseOfTag { ENDER_PEARL, + /** + * The player's combat tag was kept active because they were below the void combat height. + */ + VOID, + /** * A custom cause, typically defined by external plugins or systems, applied the combat tag. */ diff --git a/eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/CombatSettings.java b/eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/CombatSettings.java index 8378dae9..557615a7 100644 --- a/eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/CombatSettings.java +++ b/eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/CombatSettings.java @@ -90,6 +90,19 @@ public class CombatSettings extends OkaeriConfig { }) public EventPriority quitPunishmentEventPriority = EventPriority.NORMAL; + @Comment({ + "# Keep a player's combat tag continuously active while they are below 'voidCombatHeight'.", + "# This prevents players from evading combat by falling into the void (e.g. in the End).", + "# Set to 'true' to keep resetting the combat timer to its full duration while below that height." + }) + public boolean keepCombatActiveInVoid = false; + + @Comment({ + "# The Y height below which the combat timer is kept active (see 'keepCombatActiveInVoid').", + "# Default: 0, matching the void threshold in worlds such as the End." + }) + public double voidCombatHeight = 0; + @Comment({ "# List of kick reasons where players will NOT be punished for combat logging.", "# If this list is empty, players are ALWAYS punished when kicked during combat.", diff --git a/eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/FightTask.java b/eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/FightTask.java index 9f78f18b..95a62679 100644 --- a/eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/FightTask.java +++ b/eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/FightTask.java @@ -1,7 +1,9 @@ package com.eternalcode.combat.fight; import com.eternalcode.combat.config.implementation.PluginConfig; +import com.eternalcode.combat.fight.event.CauseOfTag; import com.eternalcode.combat.fight.event.CauseOfUnTag; +import com.eternalcode.combat.fight.event.FightTagEvent; import com.eternalcode.combat.notification.NoticeService; import com.eternalcode.combat.util.DurationUtil; import java.util.Optional; @@ -41,6 +43,16 @@ public void run() { return; } + if (this.config.combat.keepCombatActiveInVoid + && player.getLocation().getY() < this.config.combat.voidCombatHeight + && !this.config.settings.ignoredWorlds.contains(player.getWorld().getName())) { + FightTagEvent tagEvent = this.fightManager.tag(playerUniqueId, this.config.settings.combatTimerDuration, CauseOfTag.VOID, fightTag.getTagger()); + + if (!tagEvent.isCancelled()) { + fightTag = this.fightManager.getTag(playerUniqueId); + } + } + Duration remaining = fightTag.getRemainingDuration(); String opponent = Optional.ofNullable(fightTag.getTagger())