[TLA] Implement Razor Rings, rework excess damage (#13910)

* [TLA] Implement Razor Rings

* add overflow protection
This commit is contained in:
Evan Kranzler 2025-08-15 16:37:55 -04:00 committed by GitHub
parent 96dbfc757e
commit b64f1dce45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 209 additions and 153 deletions

View file

@ -6,9 +6,11 @@ import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Controllable;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.Optional;
/**
* @author TheElk801
@ -47,12 +49,12 @@ public class DamageWithExcessEffect extends OneShotEffect {
return false;
}
int damage = amount.calculate(game, source, this);
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
lethal = Math.min(lethal, damage);
permanent.damage(lethal, source.getSourceId(), source, game);
Player player = game.getPlayer(permanent.getControllerId());
if (player != null && lethal < damage) {
player.damage(damage - lethal, source.getSourceId(), source, game);
int excess = permanent.damageWithExcess(damage, source, game);
if (excess > 0) {
Optional.ofNullable(permanent)
.map(Controllable::getControllerId)
.map(game::getPlayer)
.ifPresent(player -> player.damage(excess, source, game));
}
return true;
}

View file

@ -8,6 +8,7 @@ import mage.constants.Zone;
import mage.game.Controllable;
import mage.game.Game;
import mage.game.GameState;
import mage.util.CardUtil;
import java.util.List;
import java.util.Set;
@ -177,6 +178,23 @@ public interface Permanent extends Card, Controllable {
int getLethalDamage(UUID attackerId, Game game);
/**
* Same arguments as regular damage method, but returns the amount of excess damage dealt instead
*
* @return
*/
default int damageWithExcess(int damage, Ability source, Game game) {
return this.damageWithExcess(damage, source.getSourceId(), source, game);
}
default int damageWithExcess(int damage, UUID attackerId, Ability source, Game game) {
int lethal = getLethalDamage(attackerId, game);
int excess = Math.max(CardUtil.overflowDec(damage, lethal), 0);
int dealt = Math.min(lethal, damage);
this.damage(dealt, attackerId, source, game);
return excess;
}
void removeAllDamage(Game game);
void reset(Game game);