Improve DealsCombatDamageEquippedTriggeredAbility (#10767)

* improve variable name

* add test for Jitte trample damage

* fix duplicated triggers when trampling over to player

* bring corresponding ability into alignment

* adjust authorship, comment
This commit is contained in:
xenohedron 2023-08-06 23:04:53 -04:00 committed by GitHub
parent 9ba0da00ff
commit 35a5cc48a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 166 additions and 19 deletions

View file

@ -10,21 +10,25 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
* @author TheElk801
* @author TheElk801, xenohedron
*/
public class DealsCombatDamageEquippedTriggeredAbility extends TriggeredAbilityImpl {
private boolean usedThisStep;
public DealsCombatDamageEquippedTriggeredAbility(Effect effect) {
this(effect, false);
}
public DealsCombatDamageEquippedTriggeredAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
this.usedThisStep = false;
setTriggerPhrase("Whenever equipped creature deals combat damage, ");
}
protected DealsCombatDamageEquippedTriggeredAbility(final DealsCombatDamageEquippedTriggeredAbility ability) {
super(ability);
this.usedThisStep = ability.usedThisStep;
}
@Override
@ -34,12 +38,18 @@ public class DealsCombatDamageEquippedTriggeredAbility extends TriggeredAbilityI
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER_BATCH
|| event.getType() == GameEvent.EventType.DAMAGED_PERMANENT_BATCH;
return event instanceof DamagedBatchEvent || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRE) {
usedThisStep = false; // clear before damage
return false;
}
if (usedThisStep || !(event instanceof DamagedBatchEvent)) {
return false; // trigger only on DamagedEvent and if not yet triggered this step
}
Permanent sourcePermanent = getSourcePermanentOrLKI(game);
if (sourcePermanent == null || sourcePermanent.getAttachedTo() == null) {
return false;
@ -54,7 +64,11 @@ public class DealsCombatDamageEquippedTriggeredAbility extends TriggeredAbilityI
if (amount < 1) {
return false;
}
usedThisStep = true;
this.getEffects().setValue("damage", amount);
// TODO: this value saved will not be correct if both permanent and player damaged by a single creature
// Need to rework engine logic to fire a single DamagedBatchEvent including both permanents and players
// Only Sword of Hours is currently affected.
return true;
}
}

View file

@ -4,29 +4,30 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.DamagedBatchEvent;
import mage.game.events.DamagedEvent;
import mage.game.events.GameEvent;
/**
* This triggers only once for each phase the source creature deals damage.
* This triggers only once for each combat damage step the source creature deals damage.
* So a creature blocked by two creatures and dealing damage to both blockers in the same
* combat damage step triggers only once.
*
* @author LevelX
* @author LevelX, xenohedron
*/
public class DealsCombatDamageTriggeredAbility extends TriggeredAbilityImpl {
private boolean usedInPhase;
private boolean usedThisStep;
public DealsCombatDamageTriggeredAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
this.usedInPhase = false;
this.usedThisStep = false;
setTriggerPhrase("Whenever {this} deals combat damage, ");
}
protected DealsCombatDamageTriggeredAbility(final DealsCombatDamageTriggeredAbility ability) {
super(ability);
this.usedInPhase = ability.usedInPhase;
this.usedThisStep = ability.usedThisStep;
}
@Override
@ -36,22 +37,33 @@ public class DealsCombatDamageTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event instanceof DamagedEvent || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRE;
return event instanceof DamagedBatchEvent || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event instanceof DamagedEvent
&& !usedInPhase
&& event.getSourceId().equals(this.sourceId)
&& ((DamagedEvent) event).isCombatDamage()) {
usedInPhase = true;
getEffects().setValue("damage", event.getAmount());
return true;
}
if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRE) {
usedInPhase = false;
usedThisStep = false; // clear before damage
return false;
}
return false;
if (usedThisStep || !(event instanceof DamagedBatchEvent)) {
return false; // trigger only on DamagedEvent and if not yet triggered this step
}
int amount = ((DamagedBatchEvent) event)
.getEvents()
.stream()
.filter(DamagedEvent::isCombatDamage)
.filter(e -> e.getAttackerId().equals(this.sourceId))
.mapToInt(GameEvent::getAmount)
.sum();
if (amount < 1) {
return false;
}
usedThisStep = true;
this.getEffects().setValue("damage", amount);
// TODO: this value saved will not be correct if both permanent and player damaged by a single creature
// Need to rework engine logic to fire a single DamagedBatchEvent including both permanents and players
// Only Aisha of Sparks and Smoke is currently affected.
return true;
}
}