From 3d6bbad132146c45d101ad579a72db74f615595b Mon Sep 17 00:00:00 2001 From: tool4ever Date: Tue, 6 Feb 2024 11:40:14 +0100 Subject: [PATCH] Cybership fix (#4638) * Cybership fix * Fix check to avoid LKI for Mishra Meld --- .../src/main/java/forge/game/GameAction.java | 2 +- .../game/ability/SpellAbilityEffect.java | 4 +-- .../forge/game/ability/effects/DigEffect.java | 31 +++++++++++-------- .../main/java/forge/game/combat/Combat.java | 1 - .../cardsfolder/a/anoint_with_affliction.txt | 4 +-- forge-gui/res/cardsfolder/c/cybership.txt | 2 +- ...claimed_by_gix_mishra_lost_to_phyrexia.txt | 6 ++-- .../upcoming/yarus_roar_of_the_old_gods.txt | 2 +- forge-gui/res/cardsfolder/w/wilfred_mott.txt | 2 +- 9 files changed, 28 insertions(+), 26 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 52ccf36c2d9..a7a578ff23e 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -421,7 +421,7 @@ private Card changeZone(final Zone zoneFrom, Zone zoneTo, final Card c, Integer CardCollection cards = new CardCollection(c.getMergedCards()); // replace top card with copied card for correct name for human to choose. cards.set(cards.indexOf(c), copied); - // 723.3b + // 725.3b if (cause != null && zoneTo.getZoneType() == ZoneType.Exile) { cards = (CardCollection) cause.getHostCard().getController().getController().orderMoveToZoneList(cards, zoneTo.getZoneType(), cause); } else { diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index a8760f9644b..19299c95342 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -694,9 +694,7 @@ protected static boolean addToCombat(Card c, SpellAbility sa, String attackingPa defender = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(defs, sa, Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())), false, params); - final GameEntity originalDefender = combat.getDefenderByAttacker(c); - if (defender != null && - (originalDefender == null || !originalDefender.equals(defender))) { + if (defender != null && !combat.getAttackersOf(defender).contains(c)) { // we might be reselecting combat.removeFromCombat(c); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java index 399cb2dc495..287717b656d 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java @@ -106,10 +106,10 @@ protected String getStackDescription(SpellAbility sa) { @Override public void resolve(SpellAbility sa) { final Card host = sa.getHostCard(); - final Player player = sa.getActivatingPlayer(); - final Game game = player.getGame(); + final Player activator = sa.getActivatingPlayer(); + final Game game = activator.getGame(); final Player cont = host.getController(); - Player chooser = player; + Player chooser = activator; int digNum = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa); final ZoneType srcZone = sa.hasParam("SourceZone") ? ZoneType.smartValueOf(sa.getParam("SourceZone")) : ZoneType.Library; @@ -215,7 +215,7 @@ else if (!sa.hasParam("NoLooking")) { if (noMove) { // Let the activating player see the cards even if they're not moved - game.getAction().revealTo(top, player); + game.getAction().revealTo(top, activator); } } @@ -228,7 +228,7 @@ else if (!sa.hasParam("NoLooking")) { if (sa.hasParam("Choser")) { final FCollectionView choosers = AbilityUtils.getDefinedPlayers(host, sa.getParam("Choser"), sa); if (!choosers.isEmpty()) { - chooser = player.getController().chooseSingleEntityForEffect(choosers, null, sa, Localizer.getInstance().getMessage("lblChooser") + ":", false, p, null); + chooser = activator.getController().chooseSingleEntityForEffect(choosers, null, sa, Localizer.getInstance().getMessage("lblChooser") + ":", false, p, null); } if (sa.hasParam("SetChosenPlayer")) { host.setChosenPlayer(chooser); @@ -258,7 +258,7 @@ else if (!sa.hasParam("NoLooking")) { if (forceRevealToController) { // Force revealing the card to the player activating the ability (e.g. Explorer's Scope) - game.getAction().revealTo(top, player); + game.getAction().revealTo(top, activator); delayedReveal = null; // top is already seen by the player, do not reveal twice } @@ -368,7 +368,12 @@ else if (!sa.hasParam("NoLooking")) { Collections.reverse(movedCards); if (destZone1.equals(ZoneType.Battlefield) || destZone1.equals(ZoneType.Library)) { - movedCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, movedCards, destZone1, sa); + if (sa.hasParam("GainControl")) { + // for Cybership + movedCards = (CardCollection) activator.getController().orderMoveToZoneList(rest, destZone2, sa); + } else { + movedCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, movedCards, destZone1, sa); + } } Map moveParams = AbilityKey.newMap(); @@ -390,12 +395,12 @@ else if (!sa.hasParam("NoLooking")) { if (destZone1.equals(ZoneType.Battlefield)) { moveParams.put(AbilityKey.SimultaneousETB, movedCards); if (sa.hasParam("GainControl")) { - c.setController(player, game.getNextTimestamp()); + c.setController(activator, game.getNextTimestamp()); } if (sa.hasParam("WithCounter")) { final int numCtr = AbilityUtils.calculateAmount(host, sa.getParamOrDefault("WithCounterNum", "1"), sa); - c.addEtbCounter(CounterType.getType(sa.getParam("WithCounter")), numCtr, player); + c.addEtbCounter(CounterType.getType(sa.getParam("WithCounter")), numCtr, activator); } } if (sa.hasAdditionalAbility("AnimateSubAbility")) { @@ -415,7 +420,7 @@ else if (!sa.hasParam("NoLooking")) { } } else if (destZone1.equals(ZoneType.Exile)) { if (sa.hasParam("ExileWithCounter")) { - c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable); + c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, activator, counterTable); } handleExiledWith(c, sa); } @@ -425,7 +430,7 @@ else if (!sa.hasParam("NoLooking")) { c.turnFaceDown(true); } if (sa.hasParam("WithMayLook")) { - c.addMayLookFaceDownExile(player); + c.addMayLookFaceDownExile(activator); } if (sa.hasParam("Imprint")) { host.addImprintedCard(c); @@ -472,7 +477,7 @@ else if (!sa.hasParam("NoLooking")) { c = game.getAction().moveTo(destZone2, c, sa, moveParams); if (destZone2 == ZoneType.Exile) { if (sa.hasParam("ExileWithCounter")) { - c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable); + c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, activator, counterTable); } handleExiledWith(c, sa); if (remZone2) { @@ -490,7 +495,7 @@ else if (!sa.hasParam("NoLooking")) { game.updateCombatForView(); game.fireEvent(new GameEventCombatChanged()); } - //table trigger there + table.triggerChangesZoneAll(game, sa); counterTable.replaceCounterEffect(game, sa, true); } diff --git a/forge-game/src/main/java/forge/game/combat/Combat.java b/forge-game/src/main/java/forge/game/combat/Combat.java index 47d11289f8b..6d7cddb4d08 100644 --- a/forge-game/src/main/java/forge/game/combat/Combat.java +++ b/forge-game/src/main/java/forge/game/combat/Combat.java @@ -299,7 +299,6 @@ public final Player getDefenderPlayerByAttacker(final Card c) { } else { return def.getController(); } - } return null; diff --git a/forge-gui/res/cardsfolder/a/anoint_with_affliction.txt b/forge-gui/res/cardsfolder/a/anoint_with_affliction.txt index 26abb635bcc..e6284d5971c 100644 --- a/forge-gui/res/cardsfolder/a/anoint_with_affliction.txt +++ b/forge-gui/res/cardsfolder/a/anoint_with_affliction.txt @@ -1,8 +1,8 @@ Name:Anoint with Affliction ManaCost:1 B Types:Instant -A:SP$ ChangeZone | Defined$ Targeted | ValidTgts$ Creature | ConditionCheckSVar$ X | CondtionSVarCompare$ GE3 | Origin$ Battlefield | Destination$ Exile | SubAbility$ NotPoisoned | SpellDescription$ Exile target creature if it has mana value 3 or less. Corrupted — Exile that creature instead if its controller has three or more poison counters. -SVar:NotPoisoned:DB$ ChangeZone | Defined$ Targeted | Origin$ Battlefield | Destination$ Exile | ConditionDefined$ Targeted | ConditionPresent$ Permanent.nonLand+cmcLE3 +A:SP$ ChangeZone | Defined$ Targeted | ValidTgts$ Creature | ConditionCheckSVar$ X | ConditionSVarCompare$ GE3 | Origin$ Battlefield | Destination$ Exile | SubAbility$ NotPoisoned | SpellDescription$ Exile target creature if it has mana value 3 or less. Corrupted — Exile that creature instead if its controller has three or more poison counters. +SVar:NotPoisoned:DB$ ChangeZone | Defined$ Targeted | Origin$ Battlefield | Destination$ Exile | ConditionDefined$ Targeted | ConditionPresent$ Creature.cmcLE3 DeckHints:Ability$Proliferate & Keyword$Infect|Toxic SVar:X:TargetedController$PoisonCounters Oracle:Exile target creature if it has mana value 3 or less.\nCorrupted — Exile that creature instead if its controller has three or more poison counters. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/c/cybership.txt b/forge-gui/res/cardsfolder/c/cybership.txt index 6f6f6499cac..e5c02c271d0 100644 --- a/forge-gui/res/cardsfolder/c/cybership.txt +++ b/forge-gui/res/cardsfolder/c/cybership.txt @@ -7,4 +7,4 @@ K:Crew:4 T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigDig | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, put the top two cards of that player's library onto the battlefield face down under your control. They're 2/2 Cyberman artifact creatures. SVar:TrigDig:DB$ Dig | Defined$ TriggeredTarget | DigNum$ 2 | GainControl$ True | ChangeNum$ All | DestinationZone$ Battlefield | FaceDown$ True | FaceDownPower$ 2 | FaceDownToughness$ 2 | FaceDownSetType$ Artifact & Creature & Cyberman DeckHas:Type$Cyberman -Oracle:Flying\nWhenever Cybership deals combat damage to a player, put the top two cards of that player’s library onto the battlefield face down under your control. They're 2/2 Cyberman artifact creatures.\nCrew 4 \ No newline at end of file +Oracle:Flying\nWhenever Cybership deals combat damage to a player, put the top two cards of that player's library onto the battlefield face down under your control. They're 2/2 Cyberman artifact creatures.\nCrew 4 \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/m/mishra_claimed_by_gix_mishra_lost_to_phyrexia.txt b/forge-gui/res/cardsfolder/m/mishra_claimed_by_gix_mishra_lost_to_phyrexia.txt index 1573613a71b..2b5faa1b3bc 100644 --- a/forge-gui/res/cardsfolder/m/mishra_claimed_by_gix_mishra_lost_to_phyrexia.txt +++ b/forge-gui/res/cardsfolder/m/mishra_claimed_by_gix_mishra_lost_to_phyrexia.txt @@ -2,7 +2,7 @@ Name:Mishra, Claimed by Gix ManaCost:2 B R Types:Legendary Creature Phyrexian Human Artificer PT:3/5 -T:Mode$ AttackersDeclared | AttackingPlayer$ You | AttackedTarget$ Player,Planeswalker | Execute$ TrigDrain | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, each opponent loses X life and you gain X life, where X is the number of attacking creatures. If CARDNAME and a creature named Phyrexian Dragon Engine are attacking, and you both own and control them, exile them, then meld them into Mishra, Lost to Phyrexia. It enters the battlefield tapped and attacking +T:Mode$ AttackersDeclared | AttackingPlayer$ You | AttackedTarget$ Player,Planeswalker | Execute$ TrigDrain | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, each opponent loses X life and you gain X life, where X is the number of attacking creatures. If CARDNAME and a creature named Phyrexian Dragon Engine are attacking, and you both own and control them, exile them, then meld them into Mishra, Lost to Phyrexia. It enters the battlefield tapped and attacking. SVar:TrigDrain:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ X | SubAbility$ DBGainLife SVar:DBGainLife:DB$ GainLife | LifeAmount$ X | SubAbility$ Meld SVar:Meld:DB$ Meld | ConditionPresent$ Card.Self+YouCtrl+YouOwn+attacking | ConditionCheckSVar$ Y | Name$ Mishra, Lost to Phyrexia | Tapped$ True | Attacking$ True | Primary$ Mishra, Claimed by Gix | Secondary$ Phyrexian Dragon Engine @@ -21,8 +21,8 @@ ManaCost:no cost Types:Legendary Artifact Creature Phyrexian Artificer PT:9/9 Colors:black,red -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, ABILITY. -T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, ABILITY. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, ABILITY +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, ABILITY SVar:TrigCharm:DB$ Charm | Choices$ DBDamage,DBDestroy,DBPump,DBCurse,DBToken | CharmNum$ 3 SVar:DBDamage:DB$ DealDamage | NumDmg$ 3 | ValidTgts$ Any | SpellDescription$ NICKNAME deals 3 damage to any target. SVar:DBDestroy:DB$ Destroy | TargetMax$ 1 | ValidTgts$ Artifact,Planeswalker | TgtPrompt$ Select target artifact or planeswalker | SpellDescription$ Destroy target artifact or planeswalker diff --git a/forge-gui/res/cardsfolder/upcoming/yarus_roar_of_the_old_gods.txt b/forge-gui/res/cardsfolder/upcoming/yarus_roar_of_the_old_gods.txt index 0c3c913e194..d798181a1c2 100644 --- a/forge-gui/res/cardsfolder/upcoming/yarus_roar_of_the_old_gods.txt +++ b/forge-gui/res/cardsfolder/upcoming/yarus_roar_of_the_old_gods.txt @@ -6,7 +6,7 @@ S:Mode$ Continuous | Affected$ Creature.YouCtrl+Other | AddKeyword$ Haste | Desc T:Mode$ DamageDoneOnce | CombatDamage$ True | ValidSource$ Creature.faceDown+YouCtrl | ValidTarget$ Player | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever one or more face-down creatures you control deal combat damage to a player, draw a card. SVar:TrigDraw:DB$ Draw | NumCards$ 1 T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.faceDown+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ Whenever a face-down creature you control dies, return it to the battlefield face down under its owner's control if it's a permanent card, then turn it face up. -SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | RememberChanged$ True | Defined$ TriggeredCard | SubAbility$ DBTurnFaceUp | ConditionDefined$ TriggeredCard | ConditionPresent$ Card.Permanent +SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | FaceDown$ True | RememberChanged$ True | Defined$ TriggeredNewCardLKICopy | SubAbility$ DBTurnFaceUp | ConditionDefined$ TriggeredCard | ConditionPresent$ Card.Permanent SVar:DBTurnFaceUp:DB$ SetState | Defined$ Remembered | Mode$ TurnFaceUp | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True DeckHints:Keyword$Morph|Disguise diff --git a/forge-gui/res/cardsfolder/w/wilfred_mott.txt b/forge-gui/res/cardsfolder/w/wilfred_mott.txt index 112d6424bc5..ef4d9c4aa0e 100644 --- a/forge-gui/res/cardsfolder/w/wilfred_mott.txt +++ b/forge-gui/res/cardsfolder/w/wilfred_mott.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Human Soldier PT:2/4 T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Look to the Stars — At the beginning of your upkeep, put a time counter on CARDNAME. Then look at the top X cards of your library, where X is the number of time counters on CARDNAME. You may put a nonland permanent card with mana value 3 or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ TIME | CounterNum$ 1 | SubAbility$ DBDig -SVar:DBDig:DB$ Dig | DigNum$ X | ChangeNum$ 1 | Optional$ True | ChangeValid$ Card.nonLand+cmcLE3 | DestinationZone$ Battlefield | RestRandomOrder$ True +SVar:DBDig:DB$ Dig | DigNum$ X | ChangeNum$ 1 | Optional$ True | ChangeValid$ Permanent.nonLand+cmcLE3 | DestinationZone$ Battlefield | RestRandomOrder$ True SVar:X:Count$CardCounters.Time DeckHas:Ability$Counters Oracle:Look to the Stars — At the beginning of your upkeep, put a time counter on Wilfred Mott. Then look at the top X cards of your library, where X is the number of time counters on Wilfred Mott. You may put a nonland permanent card with mana value 3 or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order.