It is currently 24 Apr 2024, 12:57
   
Text Size

Challenge Cards?

Moderator: CCGHQ Admins

Challenge Cards?

Postby AlphaMagnum » 19 Mar 2013, 22:58

I'm looking to build a Birthing Pod deck in-game but I'm not sure about the best way to obtain the card.

The "Into the Pod" Challenge (found in DECK_0018_CH.wad) contains a Birthing Pod with the following effect code:

Code: Select all
    <COST type="Mana" cost="{1}{G/P}" />
    <COST type="TapSelf" />
    <COST type="generic">
      <TARGET_DEFINITION id="6">
      local filter = Object():GetFilter()
      filter:Clear()
      filter:AddCardType( CARD_TYPE_CREATURE )
      filter:SetPlayer( EffectController() )
      filter:SetZone( ZONE_IN_PLAY )
      filter:SetHint( HINT_ENEMY, EffectController() )
      filter:NotTargetted()
      </TARGET_DEFINITION>
      <TARGET_DETERMINATION>
      return AtLeastOneTargetFromDefinition(6)
      </TARGET_DETERMINATION>
      <PLAY_TIME_ACTION>
        EffectController():ChooseTarget( 6, "CARD_QUERY_CHOOSE_CREATURE_TO_SACRIFICE", EffectDC():Make_Targets(0) )
      </PLAY_TIME_ACTION>
      <RESOLUTION_TIME_ACTION>
      local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
      if target ~= nil then
            EffectDC():Get_Targets(0):LKIShield_CardPtr(0)
            EffectController():Sacrifice(target) 
      end
      </RESOLUTION_TIME_ACTION></COST>
    <RESOLUTION_TIME_ACTION>
    if EffectDC() ~= nil then
       local sacrifice = EffectDC():Get_Targets(0):Get_CardPtr(0)
       if sacrifice ~= nil then
          local Sac_CMC = (sacrifice:GetConvertedManaCost()) + 1
          local filter = Object():GetFilter()
          local player = EffectController()
          
          player:MarkSearchedLibrary()
          filter:Clear()
          filter:SetZone( ZONE_LIBRARY )
          filter:SetPlayer( player )
          filter:AddCardType(CARD_TYPE_CREATURE)
          filter:SetConvertedCostValue(Sac_CMC)
          filter:NotTargetted()
          player:SetTargetCount( 1 )
          player:ChooseTarget( NO_VALIDATION, "CARD_QUERY_CHOOSE_CREATURE_TO_PUT_ONTO_BATTLEFIELD", EffectDC():Make_Targets(1) )
       end
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    if EffectDC() ~= nil then
       local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
       if  target ~= nil then
          target:PutIntoPlay( EffectController() )
       end
    end
    </RESOLUTION_TIME_ACTION>
...I also found BlindWillow's DLC to include a version of Birthing Pod, with the following code:

Code: Select all
    <COST type="Mana" cost="{1}{G/P}" />
    <COST type="TapSelf" />
    <COST type="generic">
      <TARGET_DEFINITION id="6">
      local filter = Object():GetFilter()
      filter:Clear()
      filter:AddCardType( CARD_TYPE_CREATURE )
      filter:SetPlayer( EffectController() )
      filter:SetZone( ZONE_IN_PLAY )
      filter:SetHint( HINT_ENEMY, EffectController() )
      filter:NotTargetted()
      </TARGET_DEFINITION>
      <TARGET_DETERMINATION>
      return AtLeastOneTargetFromDefinition(6)
      </TARGET_DETERMINATION>
      <PLAY_TIME_ACTION>
      EffectController():ChooseTarget( 6, "CARD_QUERY_CHOOSE_CREATURE_TO_SACRIFICE", EffectDC():Make_Targets(0) )
      </PLAY_TIME_ACTION>
      <RESOLUTION_TIME_ACTION>
      local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
      if target ~= nil then
      local cost = target:GetConvertedManaCost()+1
            EffectDC():Set_Int( 0, cost )
            EffectController():Sacrifice(target) 
      end
      </RESOLUTION_TIME_ACTION></COST>
    <RESOLUTION_TIME_ACTION>
    local filter = Object():GetFilter()
    local player = EffectController()
    local cost = EffectDC():Get_Int(0)
    -- The first if-then prevents the AI stupidly putting two Meliras into play.
    if player:IsAI() ~= 0 and cost == 2 then
   filter:Clear()
   filter:NotTargetted()
   filter:SetZone( ZONE_IN_PLAY )
   filter:SetController( player )
   filter:AddCardName( "MELIRA_SYLVOK_OUTCAST" )
   if filter:CountStopAt(1) ~= 0 then
      player:MarkSearchedLibrary()
      filter:Clear()
      filter:NotTargetted()
      filter:AddCardType( CARD_TYPE_CREATURE )
      filter:SetConvertedCostValue( cost )
      filter:SetZone( ZONE_LIBRARY )
      filter:SetPlayer( player )
      filter:AddCardName( "MELIRA_SYLVOK_OUTCAST" )
      filter:AddExtra( FILTER_EXTRA_FLIP_NAMES )
      player:ChooseTarget( NO_VALIDATION, "CARD_QUERY_CHOOSE_CREATURE_TO_PUT_ONTO_BATTLEFIELD", EffectDC():Make_Targets(1) )
   else
      player:MarkSearchedLibrary()
      filter:Clear()
      filter:NotTargetted()
      filter:AddCardType( CARD_TYPE_CREATURE )
      filter:SetConvertedCostValue( cost )
      filter:SetZone( ZONE_LIBRARY )
      filter:SetPlayer( player )
      player:ChooseTarget( NO_VALIDATION, "CARD_QUERY_CHOOSE_CREATURE_TO_PUT_ONTO_BATTLEFIELD", EffectDC():Make_Targets(1) )
   end
    else
   player:MarkSearchedLibrary()
   filter:Clear()
   filter:NotTargetted()
   filter:AddCardType( CARD_TYPE_CREATURE )
   filter:SetConvertedCostValue( cost )
   filter:SetZone( ZONE_LIBRARY )
   filter:SetPlayer( player )
   player:ChooseTarget( NO_VALIDATION, "CARD_QUERY_CHOOSE_CREATURE_TO_PUT_ONTO_BATTLEFIELD", EffectDC():Make_Targets(1) )
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    if EffectDC() ~= nil then
       local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
       if  target ~= nil then
          target:PutIntoPlay( EffectController() )
       end
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    EffectController():ShuffleLibrary()
    </RESOLUTION_TIME_ACTION>
I'm a total novice so I can't really find the meaningful differences between these two implementations, especially since my only coding experience is an introductory University-level course in Java. I'm not sure if Wizards' version is just a hack-job meant to satisfy the requirements of the Challenge, or if it is actually a fully-functional card. BlindWillow's code is obviously intended to be fully functional, but once again I don't know if that is actually the case.

Which of these two cards is best implemented, in your opinion?

Also, where would you suggest I go to learn the language used in coding these cards? If there are no meaningful changes between DotP 2013 and 2014, I could carry my new knowledge over to create cards in the new game when it comes out.
AlphaMagnum
 
Posts: 37
Joined: 15 Mar 2013, 18:21
Has thanked: 1 time
Been thanked: 0 time

Re: Challenge Cards?

Postby thefiremind » 19 Mar 2013, 23:36

AlphaMagnum wrote:I'm a total novice so I can't really find the meaningful differences between these two implementations, especially since my only coding experience is an introductory University-level course in Java. I'm not sure if Wizards' version is just a hack-job meant to satisfy the requirements of the Challenge, or if it is actually a fully-functional card. BlindWillow's code is obviously intended to be fully functional, but once again I don't know if that is actually the case.
As far as I can see, in this case Wizards didn't use hacks, but BlindWillow used one because he probably saw the AI using Birthing Pod to make Melira, Sylvok Outcast enter the battlefield while it was already controlling a copy of Melira... which is plain dumb of course. With a bit of work, the code could be modified so that the AI can't choose any legendary creature for which it already controls a copy, but it seems a bit exaggerated to me: I'd say, test your deck with a "base version" of Birthing Pod and see if you really need to guide the AI so much. Apart from that, BlindWillow also chose to store the converted mana cost in a register instead of storing a pointer to the sacrificed creature and retrieve the cmc later, which is an easier and safer approach.

So my advice would be to use a mix of the two implementations:
Code: Select all
    <COST type="Mana" cost="{1}{G/P}" />
    <COST type="TapSelf" />
    <COST type="generic">
      <TARGET_DEFINITION id="6">
      local filter = Object():GetFilter()
      filter:Clear()
      filter:AddCardType( CARD_TYPE_CREATURE )
      filter:SetPlayer( EffectController() )
      filter:SetZone( ZONE_IN_PLAY )
      filter:SetHint( HINT_ENEMY, EffectController() )
      filter:NotTargetted()
      </TARGET_DEFINITION>
      <TARGET_DETERMINATION>
      return AtLeastOneTargetFromDefinition(6)
      </TARGET_DETERMINATION>
      <PLAY_TIME_ACTION>
        EffectController():ChooseTarget( 6, "CARD_QUERY_CHOOSE_CREATURE_TO_SACRIFICE", EffectDC():Make_Targets(0) )
      </PLAY_TIME_ACTION>
      <RESOLUTION_TIME_ACTION>
      local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
      if target ~= nil then
            EffectDC():Set_Int( 2, target:GetConvertedManaCost()+1 )
            EffectController():Sacrifice(target) 
      end
      </RESOLUTION_TIME_ACTION></COST>
    <RESOLUTION_TIME_ACTION>
    if EffectDC() ~= nil then
       local Sac_CMC = EffectDC():Get_Int(2)
       local filter = Object():GetFilter()
       local player = EffectController()

       player:MarkSearchedLibrary()
       filter:Clear()
       filter:SetZone( ZONE_LIBRARY )
       filter:SetPlayer( player )
       filter:AddCardType( CARD_TYPE_CREATURE )
       filter:SetConvertedCostValue( Sac_CMC )
       filter:NotTargetted()
       player:ChooseTarget( NO_VALIDATION, "CARD_QUERY_CHOOSE_CREATURE_TO_PUT_ONTO_BATTLEFIELD", EffectDC():Make_Targets(1) )
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    local target = EffectDC() and EffectDC():Get_Targets(1) and EffectDC():Get_Targets(1):Get_CardPtr(0)
    if target ~= nil then
       target:PutIntoPlay( EffectController() )
    end
    </RESOLUTION_TIME_ACTION>
Just for your information, on the last action I used the power of the logical operators in Lua to remove the exceeding "if" checks: (A and B and C) returns C if no operand is nil, otherwise it returns nil, and even if both B and C need the previous operands to be called, the "short-circuit rule" stops the evaluation at the first nil it meets because there's no reason to look at the other operands. This prevents nil-pointer exceptions from firing with no reason.
On a side note, the "short-circuit rule" is effective also in Java, which you already know: when A is false in (A && B), the interpreter doesn't bother B at all because the result of the logical operation has been already decided.

AlphaMagnum wrote:Also, where would you suggest I go to learn the language used in coding these cards? If there are no meaningful changes between DotP 2013 and 2014, I could carry my new knowledge over to create cards in the new game when it comes out.
The changes between DotP2012 and 2013 weren't that many, so you can definitely carry your knowledge over.
I didn't know about Lua language before starting to mod DotP2012, and I learned how it works just by looking at the existing cards' code. After all, it's a sort of C++ with a lot of freedom on variables (you don't need to declare the data type, any variable can contain any type), and I already knew enough of C++ (and Java which is similar as well). If you programmed in Java you shouldn't have problems understanding the code, you just have to become familiar with the functions offered by the game executable, but it's just like learning the contents of a new C++/Java/whatever-language library. :wink:
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: Challenge Cards?

Postby AlphaMagnum » 20 Mar 2013, 03:32

Thanks for the heads up! I'm trying to work in a Phantasmal Image-based Birthing Pod chain, so I have one question about that:

I know in paper MTG that clones should copy their target's converted mana cost. One of the key elements of this chain is the following:

Phantasmal Image (CMC 2) ETBs and copies Deceiver Exarch (CMC 3).
The "Phantasmal Exarch" (should be CMC 3) untaps Birthing Pod, and we use the Pod to sacrifice it for a Restoration Angel (CMC 4).
Resto Angel then blinks the original Deceiver Exarch, which untaps Birthing Pod upon re-entry so we can use it again to sac the Angel for Kiki-Jiki.

The above is only possible if:
1) Clone effects in DotP 2013 copy CMC as intended.
2) The copied CMC is retained in code somehow once the creature is sacrificed to Birthing Pod.

Do you know if things would work that way in-game?
AlphaMagnum
 
Posts: 37
Joined: 15 Mar 2013, 18:21
Has thanked: 1 time
Been thanked: 0 time

Re: Challenge Cards?

Postby sumomole » 20 Mar 2013, 03:48

AlphaMagnum wrote:1) Clone effects in DotP 2013 copy CMC as intended.
2) The copied CMC is retained in code somehow once the creature is sacrificed to Birthing Pod.
1) Yes
2) Yes
User avatar
sumomole
Programmer
 
Posts: 611
Joined: 07 Jun 2011, 08:34
Has thanked: 51 times
Been thanked: 234 times

Re: Challenge Cards?

Postby thefiremind » 20 Mar 2013, 10:02

This is a perfect way to re-test what pcastellazzi found some time ago: after a duel where you brought a Clone or similar creature in play through Birthing Pod, could you please check if a SCRIPT_LOG.TXT appeared in your game directory? I'm curious to see if that apparently nonsense nil-pointer exception is still raised with your (our? :lol:) implementation of Birthing Pod.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: Challenge Cards?

Postby AlphaMagnum » 21 Mar 2013, 22:16

thefiremind wrote:This is a perfect way to re-test what pcastellazzi found some time ago: after a duel where you brought a Clone or similar creature in play through Birthing Pod, could you please check if a SCRIPT_LOG.TXT appeared in your game directory? I'm curious to see if that apparently nonsense nil-pointer exception is still raised with your (our? :lol:) implementation of Birthing Pod.
Um...I have a SCRIPT_LOG.TXT file full of the following:

[lua] ?:0: attempt to index field '?' (a nil value)

It's literally a 600kb txt file that consists of repeats of the above line.

Additionally, for some reason this new implementation of Birthing Pod doesn't seem to let me use the ability on my opponent's turn. The first time I thought it was like 'summoning sickness' for artifacts, but there were no swirlies (which usually indicate summoning sickness) over the card and my inability to use it on my opponent's turn persisted, despite having more than enough mana to use the ability. The card only gains the orange highlighting on my turn.

What do you think is wrong?
AlphaMagnum
 
Posts: 37
Joined: 15 Mar 2013, 18:21
Has thanked: 1 time
Been thanked: 0 time

Re: Challenge Cards?

Postby thefiremind » 21 Mar 2013, 22:51

AlphaMagnum wrote:Um...I have a SCRIPT_LOG.TXT file full of the following:

[lua] ?:0: attempt to index field '?' (a nil value)
This isn't the error I was talking about, and finding the source of this error is really hard since there is no clue at all... you should make a test deck and include only a small part of the cards, so you can find the culprit by exclusion.

AlphaMagnum wrote:Additionally, for some reason this new implementation of Birthing Pod doesn't seem to let me use the ability on my opponent's turn.
There's nothing wrong... have you read the last sentence of the ability? :roll: :mrgreen:
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: Challenge Cards?

Postby AlphaMagnum » 22 Mar 2013, 02:37

thefiremind wrote:
AlphaMagnum wrote:Um...I have a SCRIPT_LOG.TXT file full of the following:

[lua] ?:0: attempt to index field '?' (a nil value)
This isn't the error I was talking about, and finding the source of this error is really hard since there is no clue at all... you should make a test deck and include only a small part of the cards, so you can find the culprit by exclusion.

AlphaMagnum wrote:Additionally, for some reason this new implementation of Birthing Pod doesn't seem to let me use the ability on my opponent's turn.
There's nothing wrong... have you read the last sentence of the ability? :roll: :mrgreen:
I will try and make a test deck to investigate this issue further.

And thanks for the reminder! I can't believe I missed that...I feel really silly lol.
AlphaMagnum
 
Posts: 37
Joined: 15 Mar 2013, 18:21
Has thanked: 1 time
Been thanked: 0 time


Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 11 guests


Who is online

In total there are 11 users online :: 0 registered, 0 hidden and 11 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 11 guests

Login Form