Add logic to PlayerImpl for protection effects when damage can't be prevented (#10652)

* add failing test

* Check against prevent damage event when damaging player

* Add back game log message
This commit is contained in:
xenohedron 2023-07-27 00:23:27 -04:00 committed by GitHub
parent 1c9fccef35
commit 9e81362ea4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 18 deletions

View file

@ -2124,20 +2124,12 @@ public abstract class PlayerImpl implements Player, Serializable {
if (damage < 1) {
return 0;
}
if (!canDamage(game.getObject(attackerId), game)) {
MageObject sourceObject = game.getObject(attackerId);
game.informPlayers(damage + " damage "
+ (sourceObject == null ? "" : "from " + sourceObject.getLogName())
+ " to " + getLogName()
+ (damage > 1 ? " were" : "was") + " prevented because of protection");
return 0;
}
DamageEvent event = new DamagePlayerEvent(playerId, attackerId, playerId, damage, preventable, combatDamage);
event.setAppliedEffects(appliedEffects);
if (game.replaceEvent(event)) {
return 0;
}
int actualDamage = event.getAmount();
int actualDamage = checkProtectionAbilities(event, attackerId, source, game);
if (actualDamage < 1) {
return 0;
}
@ -2200,6 +2192,22 @@ public abstract class PlayerImpl implements Player, Serializable {
return actualDamage;
}
private int checkProtectionAbilities(GameEvent event, UUID attackerId, Ability source, Game game) {
MageObject attacker = game.getObject(attackerId);
if (attacker != null && hasProtectionFrom(attacker, game)) {
GameEvent preventEvent = new PreventDamageEvent(playerId, attackerId, source, playerId, event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int preventedDamage = event.getAmount();
event.setAmount(0);
game.fireEvent(new PreventedDamageEvent(playerId, attackerId, source, playerId, preventedDamage));
game.informPlayers(preventedDamage + " damage from " + attacker.getLogName() + " to " + getLogName()
+ (preventedDamage > 1 ? " were" : "was") + " prevented because of protection");
return 0;
}
}
return event.getAmount();
}
@Override
public boolean addCounters(Counter counter, UUID playerAddingCounters, Ability source, Game game) {
boolean returnCode = true;
@ -2267,15 +2275,6 @@ public abstract class PlayerImpl implements Player, Serializable {
game.fireEvent(event);
}
protected boolean canDamage(MageObject source, Game game) {
for (ProtectionAbility ability : abilities.getProtectionAbilities()) {
if (!ability.canTarget(source, game)) {
return false;
}
}
return true;
}
@Override
public Abilities<Ability> getAbilities() {
return this.abilities;