From 9b2dcbef79d59e338e37dff27a254aa0cda885af Mon Sep 17 00:00:00 2001 From: Skye Date: Thu, 13 Feb 2025 23:47:05 +0900 Subject: [PATCH] Check for damage invulnerability when simulating overcast *Normally* since overcast bypasses invuln this should never trigger, but weird interactions with mods can happen, like FAPI FakePlayers being invulnerable to all damage. This checks for the sole exception of isInvulnerableTo checked by trulyHurt, so it should close the loophole as trulyHurt will forcibly set target's HP if it's invulnerable using another method. This still has a possible TOCTTOU for free overcast, but it should be rare enough that it's not practically feasible to exploit. --- .../hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java index 750a48fa23..83e58a818b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java @@ -147,6 +147,9 @@ protected long extractMediaFromInventory(long costLeft, boolean allowOvercast, b double healthToRemove = Math.max(costLeft / mediaToHealth, 0.5); if (simulate) { long simulatedRemovedMedia = Mth.ceil(Math.min(this.caster.getHealth(), healthToRemove) * mediaToHealth); + if (this.caster.isInvulnerableTo(this.caster.damageSources().source(HexDamageTypes.OVERCAST))) { + simulatedRemovedMedia = 0; + } costLeft -= simulatedRemovedMedia; } else { var mediaAbleToCastFromHP = this.caster.getHealth() * mediaToHealth;