Implement Damage Batch for Permanent event (#11841)

* implement [WHO] Donna Noble

* Changed trigger to DAMAGED_BATCH_FOR_PERMANENTS, check for need of separate targets

* fix short circuit operator

* simplify control path in paired damage trigger

* Initial commit, missing tests

* use CardUtil.getEventTargets

* Implement Donna Noble using DamagedBatchForOnePermanentEvent

* fix double-effect bug

* remove unnecessary custom effect

* Fix addSimultaneousDamage to avoid adding damage events to existing DamagedBatchForOnePlayerEvent instances when they shouldnt

* Add clarifying comment

* Incorporate batching of DAMAGED_BATCH_FOR_ONE_PERMANENT into if-else if tree to match new logic

* Add tests

* make ability inline

* Move DamageBatchTests

* Change batch events to take first event in constructor
This commit is contained in:
jimga150 2024-03-17 16:15:50 -04:00 committed by GitHub
parent b2aa8abba2
commit 67286aa1a0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 365 additions and 12 deletions

View file

@ -812,15 +812,18 @@ public class GameState implements Serializable, Copyable<GameState> {
// Combine multiple damage events in the single event (batch)
// * per damage type (see GameEvent.DAMAGED_BATCH_FOR_PERMANENTS, GameEvent.DAMAGED_BATCH_FOR_PLAYERS)
// * per player (see GameEvent.DAMAGED_BATCH_FOR_ONE_PLAYER)
// * per permanent (see GameEvent.DAMAGED_BATCH_FOR_ONE_PERMANENT)
//
// Warning, one event can be stored in multiple batches,
// example: DAMAGED_BATCH_FOR_PLAYERS + DAMAGED_BATCH_FOR_ONE_PLAYER
boolean isPlayerDamage = damagedEvent instanceof DamagedPlayerEvent;
boolean isPermanentDamage = damagedEvent instanceof DamagedPermanentEvent;
// existing batch
boolean isDamageBatchUsed = false;
boolean isPlayerBatchUsed = false;
boolean isPermanentBatchUsed = false;
for (GameEvent event : simultaneousEvents) {
if (isPlayerDamage && event instanceof DamagedBatchForOnePlayerEvent) {
@ -831,6 +834,14 @@ public class GameState implements Serializable, Copyable<GameState> {
oldPlayerBatch.addEvent(damagedEvent);
isPlayerBatchUsed = true;
}
} else if (isPermanentDamage && event instanceof DamagedBatchForOnePermanentEvent) {
// per permanent
DamagedBatchForOnePermanentEvent oldPermanentBatch = (DamagedBatchForOnePermanentEvent) event;
if (oldPermanentBatch.getDamageClazz().isInstance(damagedEvent)
&& CardUtil.getEventTargets(event).contains(damagedEvent.getTargetId())) {
oldPermanentBatch.addEvent(damagedEvent);
isPermanentBatchUsed = true;
}
} else if ((event instanceof DamagedBatchEvent)
&& ((DamagedBatchEvent) event).getDamageClazz().isInstance(damagedEvent)) {
// per damage type
@ -842,6 +853,7 @@ public class GameState implements Serializable, Copyable<GameState> {
((DamagedBatchEvent) event).addEvent(damagedEvent);
isDamageBatchUsed = true;
}
}
// new batch
@ -849,8 +861,11 @@ public class GameState implements Serializable, Copyable<GameState> {
addSimultaneousEvent(DamagedBatchEvent.makeEvent(damagedEvent), game);
}
if (!isPlayerBatchUsed && isPlayerDamage) {
DamagedBatchEvent event = new DamagedBatchForOnePlayerEvent(damagedEvent.getTargetId());
event.addEvent(damagedEvent);
DamagedBatchEvent event = new DamagedBatchForOnePlayerEvent(damagedEvent);
addSimultaneousEvent(event, game);
}
if (!isPermanentBatchUsed && isPermanentDamage) {
DamagedBatchEvent event = new DamagedBatchForOnePermanentEvent(damagedEvent);
addSimultaneousEvent(event, game);
}
}

View file

@ -67,11 +67,9 @@ public abstract class DamagedBatchEvent extends GameEvent implements BatchGameEv
public static DamagedBatchEvent makeEvent(DamagedEvent damagedEvent) {
DamagedBatchEvent event;
if (damagedEvent instanceof DamagedPlayerEvent) {
event = new DamagedBatchForPlayersEvent();
event.addEvent(damagedEvent);
event = new DamagedBatchForPlayersEvent(damagedEvent);
} else if (damagedEvent instanceof DamagedPermanentEvent) {
event = new DamagedBatchForPermanentsEvent();
event.addEvent(damagedEvent);
event = new DamagedBatchForPermanentsEvent(damagedEvent);
} else {
throw new IllegalArgumentException("Wrong code usage. Unknown damage event for a new batch: " + damagedEvent.getClass().getName());
}

View file

@ -0,0 +1,10 @@
package mage.game.events;
public class DamagedBatchForOnePermanentEvent extends DamagedBatchEvent {
public DamagedBatchForOnePermanentEvent(DamagedEvent firstEvent) {
super(GameEvent.EventType.DAMAGED_BATCH_FOR_ONE_PERMANENT, DamagedPermanentEvent.class);
addEvent(firstEvent);
setTargetId(firstEvent.getTargetId());
}
}

View file

@ -1,14 +1,13 @@
package mage.game.events;
import java.util.UUID;
/**
* @author Susucr
*/
public class DamagedBatchForOnePlayerEvent extends DamagedBatchEvent {
public DamagedBatchForOnePlayerEvent(UUID playerId) {
public DamagedBatchForOnePlayerEvent(DamagedEvent firstEvent) {
super(EventType.DAMAGED_BATCH_FOR_ONE_PLAYER, DamagedPlayerEvent.class);
this.setPlayerId(playerId);
setPlayerId(firstEvent.getPlayerId());
addEvent(firstEvent);
}
}

View file

@ -5,7 +5,8 @@ package mage.game.events;
*/
public class DamagedBatchForPermanentsEvent extends DamagedBatchEvent {
public DamagedBatchForPermanentsEvent() {
public DamagedBatchForPermanentsEvent(DamagedEvent firstEvent) {
super(EventType.DAMAGED_BATCH_FOR_PERMANENTS, DamagedPermanentEvent.class);
addEvent(firstEvent);
}
}

View file

@ -5,7 +5,8 @@ package mage.game.events;
*/
public class DamagedBatchForPlayersEvent extends DamagedBatchEvent {
public DamagedBatchForPlayersEvent() {
public DamagedBatchForPlayersEvent(DamagedEvent firstEvent) {
super(GameEvent.EventType.DAMAGED_BATCH_FOR_PLAYERS, DamagedPlayerEvent.class);
addEvent(firstEvent);
}
}

View file

@ -450,6 +450,11 @@ public class GameEvent implements Serializable {
*/
DAMAGED_BATCH_FOR_PERMANENTS,
/* DAMAGED_BATCH_FOR_ONE_PERMANENT
combines all permanent damage events to a single batch (event) and split it per damaged permanent
*/
DAMAGED_BATCH_FOR_ONE_PERMANENT,
DESTROY_PERMANENT,
/* DESTROY_PERMANENT_BY_LEGENDARY_RULE
targetId id of the permanent to destroy