cleanup DelayedTriggeredAbility on player leave

This commit is contained in:
Susucre 2024-05-17 13:33:45 +02:00
parent 6cc3c5384a
commit 8db7a4d307
4 changed files with 88 additions and 35 deletions

View file

@ -27,11 +27,9 @@ public class DelayedTriggeredAbilities extends AbilitiesImpl<DelayedTriggeredAbi
// TODO: add same integrity checks as TriggeredAbilities?!
for (Iterator<DelayedTriggeredAbility> it = this.iterator(); it.hasNext(); ) {
DelayedTriggeredAbility ability = it.next();
if (ability.getDuration() == Duration.Custom) {
if (ability.isInactive(game)) {
it.remove();
continue;
}
if (ability.isInactive(game)) {
it.remove();
continue;
}
if (!ability.checkEventType(event, game)) {
continue;

View file

@ -4,6 +4,7 @@ import mage.abilities.effects.Effect;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
/**
* @author BetaSteward_at_googlemail.com
@ -64,6 +65,11 @@ public abstract class DelayedTriggeredAbility extends TriggeredAbilityImpl {
}
public boolean isInactive(Game game) {
return false;
// discard as soon as possible for leaved player
// 800.4d. If an object that would be owned by a player who has left the game would be created in any zone, it isn't created.
// If a triggered ability that would be controlled by a player who has left the game would be put onto the stack, it isn't put on the stack.
Player player = game.getPlayer(getControllerId());
boolean canDelete = player == null || (!player.isInGame() && player.hasReachedNextTurnAfterLeaving());
return canDelete;
}
}

View file

@ -310,22 +310,12 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
return false;
}
boolean canDelete;
Player player = game.getPlayer(startingControllerId);
// discard on start of turn for leaved player
// 800.4i When a player leaves the game, any continuous effects with durations that last until that player's next turn
// or until a specific point in that turn will last until that turn would have begun.
// They neither expire immediately nor last indefinitely.
switch (duration) {
case UntilYourNextTurn:
case UntilEndOfYourNextTurn:
canDelete = player == null || (!player.isInGame() && player.hasReachedNextTurnAfterLeaving());
break;
default:
canDelete = false;
}
boolean canDelete = player == null || (!player.isInGame() && player.hasReachedNextTurnAfterLeaving());
if (canDelete) {
return true;
}
@ -333,28 +323,20 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
// discard on another conditions (start of your turn)
switch (duration) {
case UntilYourNextTurn:
if (player != null && player.isInGame()) {
return this.isYourNextTurn(game);
}
break;
return this.isYourNextTurn(game);
case UntilYourNextEndStep:
if (player != null && player.isInGame()) {
return this.isYourNextEndStep(game);
}
break;
return this.isYourNextEndStep(game);
case UntilEndCombatOfYourNextTurn:
if (player != null && player.isInGame()) {
return this.isEndCombatOfYourNextTurn(game);
}
break;
return this.isEndCombatOfYourNextTurn(game);
case UntilYourNextUpkeepStep:
if (player != null && player.isInGame()) {
return this.isYourNextUpkeepStep(game);
}
break;
return this.isYourNextUpkeepStep(game);
case UntilEndOfYourNextTurn:
// cleanup handled by ContinuousEffectsList::removeEndOfTurnEffects
// TODO: should those be aligned to all be handled in the same place?
return false;
default: // Should handle all the duration that do pass the first switch.
throw new IllegalStateException("Missing case for isInactive's Duration:" + duration);
}
return canDelete;
}
@Override