Page 1 of 1

[DotP2013] play spell in foe's graveyard then exile it

PostPosted: 08 Mar 2013, 17:20
by BETenner
How to implement this in DotP 2013:

Play target instant or sorcery spell in target opponent's graveyard without paying its mana cost, then exile it after it resolves.

I implemented everything perfectly except the exile part. I can't find a way to exile it after it resolves. Anybody help?

Re: [DotP2013] play spell in foe's graveyard then exile it

PostPosted: 08 Mar 2013, 19:13
by thefiremind
If you look at the official cards, Cast Through Time has
Code: Select all
Object():SetResolutionZone( ZONE_REMOVED_FROM_GAME )
inside the rebound ability it grants. So you should achieve the desired result by granting the following ability to the spell while it is on the stack:
Code: Select all
  <SPELL_ABILITY resource_id="1" active_zone="ZONE_STACK">
    <RESOLUTION_TIME_ACTION>
    Object():SetResolutionZone( ZONE_REMOVED_FROM_GAME )
    </RESOLUTION_TIME_ACTION>
  </SPELL_ABILITY>
There's still one thing to decide: how to grant this ability. It's not obvious because you select the target in the graveyard, so it goes through a zone change before getting to the stack. Hopefully, a Protect_CardPtr should be enough by making the main SPELL_ABILITY like this:
Code: Select all
    <RESOLUTION_TIME_ACTION>
    local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
    if target ~= nil then
       EffectDC():Get_Targets(0):Protect_CardPtr(0)
       target:PlayFreeFromAnywhere( EffectController() )
    end
    </RESOLUTION_TIME_ACTION>
    <CONTINUOUS_ACTION layer="6">
    local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
    if target ~= nil then
       target:GetCurrentCharacteristics():GrantAbility(1)
    end
    </CONTINUOUS_ACTION>
    <DURATION>
    return EffectDC():Get_Targets(0):Get_CardPtr(0) == nil
    </DURATION>
(Target definition, determination and choice omitted.)

Be aware that I'm not sure if it works as expected. Let me know.

P.S.: just in case you need it in the future, remember that instants and sorceries give no problems, but casting permanent cards belonging to another player doesn't work well: even if you are the one who casts the spell, the permanent will enter the battlefield under its owner's control anyway. This prevented me from coding Silent-Blade Oni. Maybe we could invent some trick to make it work, but PlayFreeFromAnywhere has this limit on its own.

Re: [DotP2013] play spell in foe's graveyard then exile it

PostPosted: 09 Mar 2013, 18:43
by BETenner
Actually I'm trying to implement Diluvian Primordial
I used your suggestion like this:
Code: Select all
    <PLAY_TIME_ACTION repeating="1" target_choosing="1">
      local n = MTG():GetActionRepCount()
      local num_starting_players = MTG():GetNumberOfStartingPlayers()
      local player = MTG():GetNthStartingPlayer(n)
      if player ~= nil and n &lt; num_starting_players then
        if player:GetTeam() ~= EffectController():GetTeam() and player:OutOfTheGame() == 0 then
          -- ask the query (target definition is tied directly to the player index)
          EffectController():SetTargetCount( 1 )
          EffectController():SetTargetPrompt( 0, "CARD_QUERY_CHOOSE_INSTANT_OR_SORCERY_TO_CAST" )
          EffectController():ChooseTargetsWithFlags( n, EffectDC():Make_Targets(num_starting_players - n), QUERY_FLAG_CAN_BE_FINISHED_EARLY + QUERY_FLAG_CAN_BE_FINISHED_EARLY_FOR_AI_AS_WELL )
        end
        return true
      else
        return false
      end
    </PLAY_TIME_ACTION>
    <CONTINUOUS_ACTION layer="6">
    local num_players = MTG():GetNumberOfStartingPlayers()
    for i=0,(num_players-1) do
       local targetDC = EffectDC():Get_Targets(i)
       if targetDC ~= nil then
          local target = targetDC:Get_CardPtr(0)
          if target ~= nil then
          target:GetCurrentCharacteristics():GrantAbility(1)
          end
       end
    end
    </CONTINUOUS_ACTION>
    <RESOLUTION_TIME_ACTION>
    local num_players = MTG():GetNumberOfStartingPlayers()
    for i=0,(num_players-1) do
       local targetDC = EffectDC():Get_Targets(i)
       if targetDC ~= nil then
          local target = targetDC:Get_CardPtr(0)
          if target ~= nil then
          target:PlayFreeFromAnywhere(EffectController())
          end
       end
    end
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <SPELL_ABILITY resource_id="1" filter_zone="ZONE_IN_PLAY" active_zone="ZONE_STACK">
    <RESOLUTION_TIME_ACTION>
      if ( Object():GetErstwhileZone() == ZONE_GRAVEYARD and Object():GetResolutionZone() == ZONE_STACK ) then
        Object():SetResolutionZone( ZONE_REMOVED_FROM_GAME )
      end
    </RESOLUTION_TIME_ACTION>
  </SPELL_ABILITY>
But it still doesn't work (no script error)
Do you have any other solution?

Re: [DotP2013] play spell in foe's graveyard then exile it

PostPosted: 09 Mar 2013, 19:04
by thefiremind
You used the same "if" condition as Cast Through Time but we aren't coding rebound here... you should have written the spell ability exactly as I did (with no "if" condition). Anyway, I already coded Diluvian Primordial here:
viewtopic.php?f=64&t=4557&start=330#p110511
I used a different approach because Diluvian Primordial doesn't exactly say what you wrote in your first request... "exile it after it resolves" implies that the spell must resolve, so if it's countered you don't exile it. Diluvian Primordial says "If a card cast this way would be put into a graveyard this turn, exile it instead", which means that no matter how the card goes to the graveyard (because it resolved or because it has been countered), you have to exile it, and this is easier to code.

Re: [DotP2013] play spell in foe's graveyard then exile it

PostPosted: 10 Mar 2013, 02:33
by BETenner
thefiremind wrote:You used the same "if" condition as Cast Through Time but we aren't coding rebound here... you should have written the spell ability exactly as I did (with no "if" condition). Anyway, I already coded Diluvian Primordial here:
viewtopic.php?f=64&t=4557&start=330#p110511
I used a different approach because Diluvian Primordial doesn't exactly say what you wrote in your first request... "exile it after it resolves" implies that the spell must resolve, so if it's countered you don't exile it. Diluvian Primordial says "If a card cast this way would be put into a graveyard this turn, exile it instead", which means that no matter how the card goes to the graveyard (because it resolved or because it has been countered), you have to exile it, and this is easier to code.
Thanks! I learned a lot from this :D