diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index ed9712bd8ed..89d57e82647 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -1233,7 +1233,7 @@ public class Game { // it’s revealed after the spell becomes cast or the ability becomes activated. final Map runParams = AbilityKey.mapFromCard(c); runParams.put(AbilityKey.Number, facedownWhileCasting.get(c)); - runParams.put(AbilityKey.Player, this); + runParams.put(AbilityKey.Player, c.getOwner()); runParams.put(AbilityKey.CanReveal, true); // need to hold trigger to clear list first getTriggerHandler().runTrigger(TriggerType.Drawn, runParams, true); diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java index c936cd5ca46..8d7c1cfbf05 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java @@ -224,11 +224,6 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect { c.removeCantHaveKeyword(timestamp); c.removeHiddenExtrinsicKeywords(timestamp, 0); - - // any other unanimate cleanup - if (!c.isCreature()) { - c.unEquipAllCards(); - } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java index 3831cab14fa..6172fa95b54 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java @@ -53,15 +53,13 @@ public class ControlSpellEffect extends SpellAbilityEffect { final Player newController = controllers.isEmpty() ? sa.getActivatingPlayer() : controllers.get(0); final Game game = newController.getGame(); - List tgtSpells = getTargetSpells(sa); - // If an Exchange needs to happen, make sure both parties are still in the right zones - for (SpellAbility spell : tgtSpells) { + for (SpellAbility spell : getTargetSpells(sa)) { Card tgtC = spell.getHostCard(); - SpellAbilityStackInstance si = game.getStack().getInstanceMatchingSpellAbilityID(sa); long tStamp = game.getNextTimestamp(); if (exchange) { + SpellAbilityStackInstance si = game.getStack().getInstanceMatchingSpellAbilityID(sa); // Currently the only Exchange Control for Spells is a Permanent Trigger // Expand this area as it becomes needed // Use "DefinedExchange" to Reference Object that is Exchanging the other direction @@ -101,7 +99,7 @@ public class ControlSpellEffect extends SpellAbilityEffect { tgtC.runChangeControllerCommands(); } tgtC.addTempController(newController, tStamp); - si.setActivatingPlayer(newController); + spell.setActivatingPlayer(newController); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/MustBlockEffect.java b/forge-game/src/main/java/forge/game/ability/effects/MustBlockEffect.java index da2bcdf7bce..0851c72bf72 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/MustBlockEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/MustBlockEffect.java @@ -29,6 +29,9 @@ public class MustBlockEffect extends SpellAbilityEffect { List cards; if (sa.hasParam("DefinedAttacker")) { cards = AbilityUtils.getDefinedCards(host, sa.getParam("DefinedAttacker"), sa); + if (cards.isEmpty()) { + return; + } } else { cards = Lists.newArrayList(host); } 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 e6558d2288a..c73c441546a 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -3632,18 +3632,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return this.isAttachedToEntity(); } - public final void unEquipCard(final Card c) { // equipment.unEquipCard(equippedCard); - this.unattachFromEntity(c); - } - - public final void unEquipAllCards() { - if (isEquipped()) { - for (Card c : getEquippedBy()) { - c.unattachFromEntity(this); - } - } - } - public final GameEntity getEntityAttachedTo() { return entityAttachedTo; } 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 db4a81782cf..ec7edd9d099 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -3158,6 +3158,7 @@ public class Player extends GameEntity implements Comparable { eff.addStaticAbility(mayBePlayedAbility); return eff; } + public void createTheRing(Card host) { final PlayerZone com = getZone(ZoneType.Command); if (theRing == null) { @@ -3224,6 +3225,7 @@ public class Player extends GameEntity implements Comparable { } getTheRing().updateStateForView(); } + public void changeOwnership(Card card) { // If lost then gained, just clear out of lost. // If gained then lost, just clear out of gained. 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 ff9051fe7b8..937dca92baf 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -309,6 +309,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable | Planeswalker$ True | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Valid$ Card.nonLand | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | IsCurse$ True | SubAbility$ DBEffect | StackDescription$ {p:Targeted} exiles cards from the top of their library until they exile a nonland card. Until end of turn, {p:You} may cast that card without paying its mana cost. | SpellDescription$ Target opponent exiles cards from the top of their library until they exile a nonland card. Until end of turn, you may cast that card without paying its mana cost. SVar:DBEffect:DB$ Effect | StaticAbilities$ MayPlay | RememberObjects$ Remembered | ForgetOnMoved$ Exile | SubAbility$ DBCleanup -SVar:MayPlay:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ Until end of turn, you may cast this card without paying its mana cost. +SVar:MayPlay:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonLand | AffectedZone$ Exile | Description$ Until end of turn, you may cast this card without paying its mana cost. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True A:AB$ ChangeZone | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | DefinedPlayer$ Player.Opponent | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ChangeNum$ 2 | Hidden$ True | Mandatory$ True | SpellDescription$ Each opponent exiles two cards from their hand. A:AB$ DealDamage | Cost$ SubCounter<4/LOYALTY> | Planeswalker$ True | NumDmg$ 7 | ValidTgts$ Opponent,Creature.OppCtrl,Planeswalker.OppCtrl | TgtPrompt$ Select target opponent, creature an opponent controls, or planeswalker an opponent controls | SpellDescription$ CARDNAME deals deals 7 damage to target opponent, creature an opponent controls, or planeswalker an opponent controls. diff --git a/forge-gui/res/cardsfolder/p/plargg_dean_of_chaos_augusta_dean_of_order.txt b/forge-gui/res/cardsfolder/p/plargg_dean_of_chaos_augusta_dean_of_order.txt index a3414017504..f7eb621512c 100644 --- a/forge-gui/res/cardsfolder/p/plargg_dean_of_chaos_augusta_dean_of_order.txt +++ b/forge-gui/res/cardsfolder/p/plargg_dean_of_chaos_augusta_dean_of_order.txt @@ -3,7 +3,7 @@ ManaCost:1 R Types:Legendary Creature Orc Shaman PT:2/2 A:AB$ Draw | Cost$ T Discard<1/Card> | NumCards$ 1 | Defined$ You | SpellDescription$ Draw a card. -A:AB$ DigUntil | Cost$ 4 R T | Defined$ You | Amount$ 1 | Valid$ Card.nonLand+nonLegendary+cmcLE3 | FoundDestination$ Library | RevealRandomOrder$ True | RevealedDestination$ Library | ImprintRevealed$ True | RememberFound$ True | SubAbility$ CascadeCast | StackDescription$ SpellDescription | SpellDescription$ Reveal cards from the top of your library until you reveal a nonlegendary, nonland card with mana value 3 or less. You may cast that card without paying its mana cost. Put all revealed cards not cast this way on the bottom of your library in a random order. +A:AB$ DigUntil | Cost$ 4 R T | Defined$ You | Amount$ 1 | Valid$ Card.nonLand+nonLegendary+cmcLE3 | RevealRandomOrder$ True | RevealNoMove$ True | ImprintRevealed$ True | RememberFound$ True | SubAbility$ CascadeCast | StackDescription$ SpellDescription | SpellDescription$ Reveal cards from the top of your library until you reveal a nonlegendary, nonland card with mana value 3 or less. You may cast that card without paying its mana cost. Put all revealed cards not cast this way on the bottom of your library in a random order. SVar:CascadeCast:DB$ Play | Defined$ Remembered | WithoutManaCost$ True | ValidSA$ Spell | Optional$ True | SubAbility$ CascadeMoveToLib SVar:CascadeMoveToLib:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered,Card.IsImprinted | Origin$ Library | Destination$ Library | RandomOrder$ True | LibraryPosition$ -1 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True diff --git a/forge-gui/res/cardsfolder/s/spellshift.txt b/forge-gui/res/cardsfolder/s/spellshift.txt index 76938014574..70315d48839 100644 --- a/forge-gui/res/cardsfolder/s/spellshift.txt +++ b/forge-gui/res/cardsfolder/s/spellshift.txt @@ -2,8 +2,8 @@ Name:Spellshift ManaCost:3 U Types:Instant A:SP$ Counter | Cost$ 3 U | TargetType$ Spell | ValidTgts$ Instant,Sorcery | TgtPrompt$ Select target Instant or Sorcery Spell | SubAbility$ DBDig | SpellDescription$ Counter target instant or sorcery spell. Its controller reveals cards from the top of their library until they reveal an instant or sorcery card. That player may cast that card without paying its mana cost. Then the player shuffles. -SVar:DBDig:DB$ DigUntil | Defined$ TargetedController | Valid$ Instant,Sorcery | ValidDescription$ Sorcery or Instant | FoundDestination$ Library | RevealedDestination$ Library | RememberFound$ True | SubAbility$ DBPlay | Shuffle$ True -SVar:DBPlay:DB$ Play | Defined$ Remembered | Controller$ TargetedController | WithoutManaCost$ True | Optional$ True | SubAbility$ DBShuffle +SVar:DBDig:DB$ DigUntil | Defined$ TargetedController | Valid$ Instant,Sorcery | ValidDescription$ Sorcery or Instant | RevealNoMove$ True | RememberFound$ True | SubAbility$ DBPlay +SVar:DBPlay:DB$ Play | Defined$ Remembered | ValidSA$ Spell | Controller$ TargetedController | WithoutManaCost$ True | Optional$ True | SubAbility$ DBShuffle SVar:DBShuffle:DB$ Shuffle | Defined$ TargetedController | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/s/stolen_goods.txt b/forge-gui/res/cardsfolder/s/stolen_goods.txt index 3a1ac52065c..2943b69a9c2 100644 --- a/forge-gui/res/cardsfolder/s/stolen_goods.txt +++ b/forge-gui/res/cardsfolder/s/stolen_goods.txt @@ -3,6 +3,6 @@ ManaCost:3 U Types:Sorcery A:SP$ DigUntil | ValidTgts$ Opponent | Valid$ Card.nonLand | ValidDescription$ nonland | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | IsCurse$ True | SubAbility$ DBEffect | SpellDescription$ Target opponent exiles cards from the top of their library until they exile a nonland card. Until end of turn, you may cast that card without paying its mana cost. SVar:DBEffect:DB$ Effect | StaticAbilities$ StolenGoodsPlay | ForgetOnMoved$ Exile | RememberObjects$ Remembered | SubAbility$ DBCleanup -SVar:StolenGoodsPlay:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered+OppOwn | AffectedZone$ Exile | Description$ Until end of turn, you may cast this card without paying its mana cost. +SVar:StolenGoodsPlay:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonLand | AffectedZone$ Exile | Description$ Until end of turn, you may cast this card without paying its mana cost. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True Oracle:Target opponent exiles cards from the top of their library until they exile a nonland card. Until end of turn, you may cast that card without paying its mana cost. diff --git a/forge-gui/res/cardsfolder/s/synthesis_pod.txt b/forge-gui/res/cardsfolder/s/synthesis_pod.txt index 4dcf5d99673..b3f9033bcb6 100644 --- a/forge-gui/res/cardsfolder/s/synthesis_pod.txt +++ b/forge-gui/res/cardsfolder/s/synthesis_pod.txt @@ -2,7 +2,7 @@ Name:Synthesis Pod ManaCost:3 UP Types:Artifact A:AB$ DigUntil | Cost$ 1 UP T ExileFromStack<1/Card.YouCtrl/spell you control> | ValidTgts$ Opponent | Valid$ Card.cmcEQX | FoundDestination$ Exile | RevealedDestination$ Library | ImprintFound$ True | Shuffle$ True | SubAbility$ DBPlay | SpellDescription$ Target opponent reveals cards from the top of their library until they reveal a card with mana value equal to 1 plus the exiled spell's mana value. Exile that card, then that player shuffles. You may cast that exiled card without paying its mana cost. -SVar:DBPlay:DB$ Play | Defined$ Imprinted | WithoutManaCost$ True | Optional$ True | SubAbility$ DBCleanup +SVar:DBPlay:DB$ Play | Defined$ Imprinted | ValidSA$ Spell | WithoutManaCost$ True | Optional$ True | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearImprinted$ True SVar:X:Exiled$CardManaCost/Plus.1 AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/t/tibalts_trickery.txt b/forge-gui/res/cardsfolder/t/tibalts_trickery.txt index a494ecf1a96..711eb667197 100644 --- a/forge-gui/res/cardsfolder/t/tibalts_trickery.txt +++ b/forge-gui/res/cardsfolder/t/tibalts_trickery.txt @@ -5,7 +5,7 @@ A:SP$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ SVar:DBRandom:DB$ ChooseNumber | Min$ 1 | Max$ 3 | Defined$ You | Random$ True | SubAbility$ DBMill | StackDescription$ None SVar:DBMill:DB$ Mill | NumCards$ X | Defined$ TargetedController | SubAbility$ DBDig | StackDescription$ None SVar:DBDig:DB$ DigUntil | Defined$ TargetedController | Valid$ Card.nonLand+doesNotShareNameWith Remembered | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | ForgetOtherRemembered$ True | ImprintRevealed$ True | SubAbility$ DBPlay | StackDescription$ None -SVar:DBPlay:DB$ Play | Controller$ TargetedController | Defined$ Remembered | WithoutManaCost$ True | Optional$ True | SubAbility$ DBChangeZone | StackDescription$ None +SVar:DBPlay:DB$ Play | Controller$ TargetedController | Defined$ Remembered | ValidSA$ Spell | WithoutManaCost$ True | Optional$ True | SubAbility$ DBChangeZone | StackDescription$ None SVar:DBChangeZone:DB$ ChangeZoneAll | ChangeType$ Card.IsImprinted | Origin$ Exile | Destination$ Library | RandomOrder$ True | LibraryPosition$ -1 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True SVar:X:Count$ChosenNumber diff --git a/forge-gui/res/cardsfolder/t/treasure_keeper.txt b/forge-gui/res/cardsfolder/t/treasure_keeper.txt index 35521ff6fc4..187d54d7c7c 100644 --- a/forge-gui/res/cardsfolder/t/treasure_keeper.txt +++ b/forge-gui/res/cardsfolder/t/treasure_keeper.txt @@ -3,7 +3,7 @@ ManaCost:4 Types:Artifact Creature Construct PT:3/3 T:Mode$ ChangesZone | ValidCard$ Card.Self | TriggerZones$ Battlefield | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigKeeperCascade | TriggerDescription$ When CARDNAME dies, reveal cards from the top of your library until you reveal a nonland card with mana value 3 or less. You may cast that card without paying its mana cost. Put all revealed cards not cast this way on the bottom of your library in a random order. -SVar:TrigKeeperCascade:DB$ DigUntil | Defined$ You | Amount$ 1 | Valid$ Card.nonLand+cmcLE3 | FoundDestination$ Library | RevealRandomOrder$ True | RevealedDestination$ Library | ImprintRevealed$ True | RememberFound$ True | SubAbility$ CascadeCast +SVar:TrigKeeperCascade:DB$ DigUntil | Defined$ You | Amount$ 1 | Valid$ Card.nonLand+cmcLE3 | RevealNoMove$ True | ImprintRevealed$ True | RememberFound$ True | SubAbility$ CascadeCast SVar:CascadeCast:DB$ Play | Defined$ Remembered | WithoutManaCost$ True | ValidSA$ Spell | Optional$ True | SubAbility$ CascadeMoveToLib SVar:CascadeMoveToLib:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered,Card.IsImprinted | Origin$ Library | Destination$ Library | RandomOrder$ True | LibraryPosition$ -1 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True diff --git a/forge-gui/res/cardsfolder/upcoming/grima_sarumans_footman.txt b/forge-gui/res/cardsfolder/upcoming/grima_sarumans_footman.txt index a21495bc5a0..5ae76eb98fb 100644 --- a/forge-gui/res/cardsfolder/upcoming/grima_sarumans_footman.txt +++ b/forge-gui/res/cardsfolder/upcoming/grima_sarumans_footman.txt @@ -6,6 +6,6 @@ S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | Description$ CARDNAME can't T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDigUntil | TriggerZones$ Battlefield | TriggerDescription$ Whenever NICKNAME deals combat damage to a player, that player exiles cards from the top of their library until they exile an instant or sorcery card. You may cast that card without paying its mana cost. Then that player puts the exiled cards that weren't cast this way on the bottom of their library in a random order. SVar:TrigDigUntil:DB$ DigUntil | Defined$ TriggeredTarget | Valid$ Instant,Sorcery | ValidDescription$ instant or sorcery | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | ImprintRevealed$ True | IsCurse$ True | SubAbility$ DBPlay SVar:DBPlay:DB$ Play | ValidZone$ Exile | Valid$ Instant.IsRemembered,Sorcery.IsRemembered | ValidSA$ Spell | WithoutManaCost$ True | Optional$ True | SubAbility$ DBRestRandomOrder -SVar:DBRestRandomOrder:DB$ ChangeZoneAll | ChangeType$ Card.IsImprinted | Origin$ Exile | Destination$ Library | LibraryPosition$ -1 | RandomOrder$ True | SubAbility$ DBCleanup +SVar:DBRestRandomOrder:DB$ ChangeZoneAll | ChangeType$ Card.IsImprinted,Card.IsRemembered | Origin$ Exile | Destination$ Library | LibraryPosition$ -1 | RandomOrder$ True | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True Oracle:Grima, Saruman's Footman can't be blocked.\nWhenever Grima deals combat damage to a player, that player exiles cards from the top of their library until they exile an instant or sorcery card. You may cast that card without paying its mana cost. Then that player puts the exiled cards that weren't cast this way on the bottom of their library in a random order.