diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 334fd63fd30..4902eebdcd9 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -1029,7 +1029,7 @@ public class PlayerControllerAi extends PlayerController { */ if (sa.isMayChooseNewTargets() && !sa.setupTargets()) { if (sa.isSpell()) { - sa.getHostCard().ceaseToExist(); + sa.getHostCard().ceaseToExist(false); } continue; } diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 1a3659d3d2d..0527a1e0063 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -769,12 +769,19 @@ public class Game { p.revealFaceDownCards(); } - for(Card c : cards) { + for (Card c : cards) { + // CR 800.4d if card is controlled by opponent, LTB should trigger + if (c.getOwner().equals(p) && c.getController().equals(p)) { + c.getCurrentState().clearTriggers(); + } + } + + for (Card c : cards) { if (c.getController().equals(p) && (c.isPlane() || c.isPhenomenon())) { planarControllerLost = true; } - if(isMultiplayer) { + if (isMultiplayer) { // unattach all "Enchant Player" c.removeAttachedTo(p); if (c.getOwner().equals(p)) { @@ -783,7 +790,9 @@ public class Game { cc.removeEncodedCard(c); cc.removeRemembered(c); } - c.ceaseToExist(); + c.ceaseToExist(false); + // CR 603.2f owner of trigger source lost game + triggerHandler.clearDelayedTrigger(c); } else { // return stolen permanents if (c.getController().equals(p) && c.isInZone(ZoneType.Battlefield)) { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 1aaf6a1dba9..2e590f74a3c 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -6756,11 +6756,15 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } - public void ceaseToExist() { - getGame().getTriggerHandler().suppressMode(TriggerType.ChangesZone); - getZone().remove(this); - setZone(null); - getGame().getTriggerHandler().clearSuppression(TriggerType.ChangesZone); + public void ceaseToExist(boolean skipTrig) { + // CR 603.6c other players LTB triggers should work + if (skipTrig) { + getZone().remove(this); + setZone(getOwner().getZone(ZoneType.None)); + } + else { + game.getAction().moveTo(ZoneType.None, this, null); + } } public void forceTurnFaceUp() { diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index b5dd3af1353..bc8f479f3ef 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -133,7 +133,7 @@ import forge.util.collect.FCollectionView; public class Player extends GameEntity implements Comparable { public static final List ALL_ZONES = Collections.unmodifiableList(Arrays.asList(ZoneType.Battlefield, ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante, - ZoneType.Sideboard, ZoneType.PlanarDeck, ZoneType.SchemeDeck, ZoneType.Merged, ZoneType.Subgame)); + ZoneType.Sideboard, ZoneType.PlanarDeck, ZoneType.SchemeDeck, ZoneType.Merged, ZoneType.Subgame, ZoneType.None)); private final Map commanderDamage = Maps.newHashMap(); diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 6245c3fe132..145c9fe8413 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -2361,7 +2361,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit public void rollback() { for (Card c : rollbackEffects) { - c.ceaseToExist(); + c.ceaseToExist(true); } rollbackEffects.clear(); } diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java index 7ddf5b28cff..656829d12b1 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java @@ -631,13 +631,12 @@ public class TriggerHandler { } public void onPlayerLost(Player p) { - List lost = new ArrayList<>(); - for (Trigger t : delayedTriggers) { - // CR 603.2f owner of trigger source lost game || 800.4d trigger controller lost game - if (game.getCardState(t.getHostCard(), null) == null || t.getHostCard().getOwner().equals(p)) { - lost.add(t); + List lost = new ArrayList<>(delayedTriggers); + for (Trigger t : lost) { + // CR 800.4d trigger controller lost game + if (t.getHostCard().getOwner().equals(p)) { + delayedTriggers.remove(t); } } - delayedTriggers.removeAll(lost); } } diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index 0c0e5ea7500..434d854065a 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -586,7 +586,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable