It is currently 11 May 2025, 10:26
   
Text Size

Thefiremind's help requests

Moderator: CCGHQ Admins

Thefiremind's help requests

Postby thefiremind » 07 Nov 2011, 12:04

Hi everybody! I started making cards for DotP2012 some days ago, and I successfully built a couple of decks with easy cards... easy because I have put little effort on them, by copying some code from the other existing cards. :D

Now, I'm trying to make a Goblin deck, and a card that seemed easy to code revealed more trouble than I thought. I'm talking about Goblin Grenade.

Here is my code, copied partly from Tinker and partly from any burn spell. I omitted the localized text parts here, just to make it shorter (of course they exist in the real XML file):
Code: Select all
<?xml version='1.0'?>
<CARD_V2 custom="true">
  <FILENAME text="GOBLIN_GRENADE_999051" />
  <CARDNAME text="GOBLIN_GRENADE" />
  <TITLE>
  <!-- omitted localized text -->
  </TITLE>
  <MULTIVERSEID value="999051" />
  <ARTID value="999051" />
  <FRAMECOLOUR name="R" />
  <COLOUR value="R" />
  <ARTIST name="Kev Walker" />
  <CASTING_COST cost="{R}" />
  <FLAVOURTEXT>
  <!-- omitted localized text -->
  </FLAVOURTEXT>
  <TYPE metaname="Sorcery" order_de-DE="0" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <EXPANSION value="M12" />
  <RARITY metaname="U" />
  <UTILITY_ABILITY>
    <!-- omitted localized text -->
    <COST type="Sacrifice" qualifier="Additional">
      <TARGET_DETERMINATION>
      local filter = Object():GetFilter()
      filter:Clear()
      filter:AddSubType( CREATURE_TYPE_GOBLIN )
      filter:SetController( Object():GetPlayer() )
      filter:SetZone( ZONE_IN_PLAY )
      filter:NotTargetted()
      return TargetGoodF()
      </TARGET_DETERMINATION>
      <PLAYTIME>
      ChooseTarget( "CARD_QUERY_CHOOSE_CREATURE_TO_SACRIFICE" )
      </PLAYTIME>
  </COST>
  </UTILITY_ABILITY>
  <SPELL_ABILITY>
    <!-- omitted localized text -->
    <TARGET_DETERMINATION>
    local filter = Object():GetFilter()
    filter:Clear()
    filter:SetFilterType( FILTER_TYPE_CARDS + FILTER_TYPE_PLAYERS )
    filter:AddCardType( CARD_TYPE_CREATURE )
    filter:SetZone( ZONE_IN_PLAY )
    return TargetBadF()
    </TARGET_DETERMINATION>
    <PLAY_TIME_ACTION target_choosing="1">
    ChooseTarget( "CARD_QUERY_CHOOSE_DEAL_5_DAMAGE" )
    </PLAY_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    if ( Object():GetTargetCard() ~= nil ) then
       Object():GetTargetCard():DealDamage(5, Object())
    elseif ( Object():GetTargetPlayer() ~= nil ) then
       Object():GetTargetPlayer():DealDamage(5, Object())
    end
    </RESOLUTION_TIME_ACTION>
    <SFX text="TARGET_FLAME_PLAY" />
  </SPELL_ABILITY>
</CARD_V2>
It seems all OK to me, but when I use Goblin Grenade, the sacrifice goes well, while the resolution does nothing: no damage at all. #-o
Could anybody help me troubleshooting this? [-o<
Last edited by thefiremind on 09 Dec 2011, 23:34, edited 1 time in total.
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 722 times

Re: Started modding DotP2012, need some help

Postby Persee » 07 Nov 2011, 12:55

Test your card without the utility ability. If it works it means that the utility ability doesn't work with spells.
User avatar
Persee
 
Posts: 168
Joined: 02 Jun 2011, 08:33
Has thanked: 42 times
Been thanked: 24 times

Re: Started modding DotP2012, need some help

Postby thefiremind » 07 Nov 2011, 15:22

Thanks for the tip. It works without the additional cost. My guess is that the game tries to target the sacrificed Goblin instead of the chosen creature/player. Tinker probably works because the real spell target is in the library so it can't be the same as the sacrifice. If anyone has some advice for making Goblin Grenade work, please don't hesitate to post.

In the meanwhile, I think I'll share my code for Ib Halfheart, Goblin Tactician. Nothing really special, but I had to be more creative than usual for the triggered ability. :D
Code: Select all
<?xml version='1.0'?>
<CARD_V2 custom="true">
  <FILENAME text="IB_HALFHEART_GOBLIN_TACTICIAN_999053" />
  <CARDNAME text="IB_HALFHEART_GOBLIN_TACTICIAN" />
  <TITLE>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Ib Halfheart, Goblin Tactician]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </TITLE>
  <MULTIVERSEID value="999053" />
  <ARTID value="999053" />
  <FRAMECOLOUR name="R" />
  <COLOUR value="R" />
  <ARTIST name="Wayne Reynolds" />
  <CASTING_COST cost="{3}{R}" />
  <FLAVOURTEXT>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA["Everybody but me - CHARGE!"]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </FLAVOURTEXT>
  <SUPERTYPE metaname="Legendary" order_de-DE="0" order_es-ES="1" order_fr-FR="1" order_it-IT="1" order_jp-JA="0" />
  <TYPE metaname="Creature" order_de-DE="1" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <SUB_TYPE metaname="Goblin" order_de-DE="0" order_es-ES="1" order_fr-FR="0" order_it-IT="1" order_jp-JA="0" />
  <SUB_TYPE metaname="Advisor" order_de-DE="1" order_es-ES="0" order_fr-FR="1" order_it-IT="0" order_jp-JA="1" />
  <EXPANSION value="TS" />
  <RARITY metaname="R" />
  <POWER value="3" />
  <TOUGHNESS value="2" />
  <TOKEN_REGISTRATION reservation="2" type="TOKEN_GOBLIN_1_1_247086" />
  <TRIGGERED_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Whenever another Goblin you control becomes blocked, sacrifice it. If you do, it deals 4 damage to each creature blocking it.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
    <TRIGGER value="BLOCKING">
    return (SecondaryObject() ~= Object() and
    SecondaryObject():GetSubType():Test( CREATURE_TYPE_GOBLIN ) and
    SecondaryObject():GetPlayer() == Object():GetPlayer())
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    if (TriggerObject() ~= nil and SecondaryObject() ~= nil) then
      if (TriggerObject():GetZone() == ZONE_IN_PLAY and SecondaryObject():GetZone() == ZONE_IN_PLAY) then
        SecondaryObject():Sacrifice()
        TriggerObject():DealDamage(4, SecondaryObject())
      end
    end
    </RESOLUTION_TIME_ACTION>
    <AI_BASE_SCORE score="900" zone="in_play" />
  </TRIGGERED_ABILITY>
  <ACTIVATED_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Sacrifice two Mountains: Put two 1/1 red Goblin creature tokens onto the battlefield.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
    <TARGET_DETERMINATION>
    local filter = Object():GetFilter()
    filter:Clear()
    filter:SetController( Object():GetPlayer() )
    filter:AddSubType( LAND_TYPE_MOUNTAIN )
    filter:SetZone( ZONE_IN_PLAY )
    filter:NotTargetted()
         
    if Object():GetFilter():CountStopAt( 2 ) &lt; 2 then
      return TARGET_DETERMINATION_NONE
    else
      return TARGET_DETERMINATION_ALL
    end
    </TARGET_DETERMINATION>
    <COST type="Sacrifice" number="2">
      <PLAYTIME>
      ChooseTarget( "CARD_QUERY_CHOOSE_LAND_TO_SACRIFICE" )
      </PLAYTIME>
      <TARGET_DETERMINATION>
      local filter = Object():GetFilter()
      filter:Clear()
      filter:SetController( Object():GetPlayer() )
      filter:AddSubType( LAND_TYPE_MOUNTAIN )
      filter:SetZone( ZONE_IN_PLAY )
      filter:NotTargetted()
         
      if Object():GetFilter():CountStopAt( 1 ) &lt; 1 then
        return TARGET_DETERMINATION_NONE
      else
        return TARGET_DETERMINATION_ALL
      end
      </TARGET_DETERMINATION>
    </COST>
    <RESOLUTION_TIME_ACTION>
    PutTokensIntoPlay( "TOKEN_GOBLIN_1_1_247086", 2 )
    </RESOLUTION_TIME_ACTION>
    <AI_BASE_SCORE score="600" zone="in_play" />
  </ACTIVATED_ABILITY>
  <SFX text="COMBAT_BLUNT_LARGE_ATTACK" power_boundary_min="4" power_boundary_max="-1" />
  <SFX text="COMBAT_BLUNT_SMALL_ATTACK" power_boundary_min="1" power_boundary_max="3" />
</CARD_V2>
The tokens are the same as Dragon Fodder, no need to add other ones.

Going to think about some other deck... I'll post again if I come into trouble with other cards. :wink:
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 722 times

Re: Started modding DotP2012, need some help

Postby Persee » 07 Nov 2011, 17:22

Thanks for sharing.

Look at the Goblin Grenade in the kevlahnota's mod : viewtopic.php?f=62&t=5151

He use this code :
Code: Select all
  <SPELL_ABILITY>
         <TARGET_DETERMINATION>
    local filter = Object():GetFilter()
    filter:Clear()
    filter:SetController( Object():GetPlayer() )
    filter:AddSubType( CREATURE_TYPE_GOBLIN )
    filter:SetZone( ZONE_IN_PLAY )
    filter:NotTargetted()
    if filter:CountStopAt( 1 ) &lt; 1 then
       return TARGET_DETERMINATION_NONE
    end
    filter:Clear()
    filter:SetFilterType( FILTER_TYPE_CARDS + FILTER_TYPE_PLAYERS )
    filter:AddCardType( CARD_TYPE_CREATURE )
    filter:SetZone( ZONE_IN_PLAY )
    return TargetBadF()
    </TARGET_DETERMINATION>
    <PLAY_TIME_ACTION target_choosing="1">
    local filter = Object():GetFilter()
    filter:Clear()
    filter:SetController( Object():GetPlayer() )
    filter:AddSubType( CREATURE_TYPE_GOBLIN )
    filter:SetZone( ZONE_IN_PLAY )
    filter:NotTargetted()
    filter:PlayerHint( Object():GetPlayer() )
    Object():GetPlayer():ChooseTargetDC( "CARD_QUERY_CHOOSE_GOBLIN_TO_SACRIFICE", MTG():EffectDataChest():Make_Targets( 0 ))
    </PLAY_TIME_ACTION>
    <PLAY_TIME_ACTION target_choosing="1">
    if (MTG():EffectDataChest():Get_Targets( 0 ) ~= nil and MTG():EffectDataChest():Get_Targets( 0 ):Get_NthCardPtr( 0 ) ~= nil) then
    MTG():EffectDataChest():Get_Targets( 0 ):Get_NthCardPtr( 0 ):Sacrifice()
   
    local filter = Object():GetFilter()
    filter:Clear()
    filter:SetFilterType( FILTER_TYPE_CARDS + FILTER_TYPE_PLAYERS )
    filter:AddCardType( CARD_TYPE_CREATURE )
    filter:SetZone( ZONE_IN_PLAY )
    Object():GetPlayer():ChooseTargetDC( "CARD_QUERY_CHOOSE_DEAL_5_DAMAGE", MTG():EffectDataChest():Make_Targets( 1 ) )
    end
    </PLAY_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    local target_chest = MTG():EffectDataChest():Get_Targets( 1 )
    if target_chest ~= nil then
        local target_card = target_chest:Get_CardPtr( 0 )
        local target_player = target_chest:Get_PlayerPtr(0)

          if target_card ~= nil then
          target_card:DealDamage( 5, Object() )
         elseif target_player ~= nil then
          target_player:DealDamage( 5, Object() )
         end
    end
    </RESOLUTION_TIME_ACTION>
User avatar
Persee
 
Posts: 168
Joined: 02 Jun 2011, 08:33
Has thanked: 42 times
Been thanked: 24 times

Re: Started modding DotP2012, need some help

Postby thefiremind » 07 Nov 2011, 20:37

I didn't want to install other mods besides the modified exe file, but it seems I would find a lot to learn in kev's mod... this is a nice example. Thanks for showing me!
< 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: 722 times

Re: Started modding DotP2012, need some help

Postby thefiremind » 10 Nov 2011, 17:49

I'm trying to make a Wither deck and I stumbled upon another problem. How to code Ashenmoor Liege 's last ability? I tried with this:
Code: Select all
  <TRIGGERED_ABILITY pre_trigger="1">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Whenever Ashenmoor Liege becomes the target of a spell or ability an opponent controls, that player loses 4 life.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
    <TRIGGER value="BECAME_TARGET">
    return (TriggerObject() == Object() and
    SecondaryObject() ~= nil and
    SecondaryObject():GetPlayer() ~= nil and
    SecondaryObject():GetPlayer():GetTeam() ~= Object():GetPlayer():GetTeam())
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    SecondaryObject():GetPlayer():LoseLife(4)
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
...but it does nothing. #-o Either I'm using the wrong syntax, or it can't be coded this way... TriggerObject() is the object that became target, but how to refer to the thing that targets it? SecondaryObject() is probably wrong.

Any suggestions? :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: 722 times

Re: Started modding DotP2012, need some help

Postby thefiremind » 11 Nov 2011, 22:57

I gave up with the Wither deck, not only because of the card in the message above, but also because I couldn't find a way to code Quillspike, which would have been the key of the deck. Of course, if anyone finds a solution for the above problem, I'm still curious to know it. :wink:

Now I'm trying to make a Hellbent deck, and coding Drekavac is driving me crazy! I select the noncreature card from my hand, but the game doesn't discard it! #-o

EDIT: Nevermind, figured it out by myself. I hope my experience can be useful to other new modders: you can't get a target during the same action that chose it. [-X You need to make a separated <RESOLUTION_TIME_ACTION> or whatever it is. :wink:

If someone is interested, I coded a particular card that I couldn't avoid in a Hellbent deck: Ignorant Bliss.
Code: Select all
<?xml version='1.0'?>
<CARD_V2 custom="true">
  <FILENAME text="IGNORANT_BLISS_999116" />
  <CARDNAME text="IGNORANT_BLISS" />
  <TITLE>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Ignorant Bliss]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </TITLE>
  <MULTIVERSEID value="999116" />
  <ARTID value="999116" />
  <FRAMECOLOUR name="R" />
  <COLOUR value="R" />
  <ARTIST name="Jeff Miracola" />
  <CASTING_COST cost="{1}{R}" />
  <FLAVOURTEXT>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA["A quick step beyond oblivion lies a place so full of thoughts that it leaves no room for your own." -Quyzl, chronarch prodigy]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </FLAVOURTEXT>
  <TYPE metaname="Instant" order_de-DE="0" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <EXPANSION value="DS" />
  <RARITY metaname="U" />
  <SPELL_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Exile all cards from your hand face down. At the beginning of the next end step, return those cards to your hand, then draw a card.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
    <RESOLUTION_TIME_ACTION>
    local count = CountCardsInHand( Object():GetPlayer() )
    if count &gt; 0 then
      local store = Storage( Object() )
      store.set( 0, count )
      for i=1,count do
        local card = Object():GetPlayer():Hand_GetRandom()
        store.set( i, card )
        card:RemoveFromGame()
      end
      store.set( count+1, Object():GetPlayer() )
    end
    </RESOLUTION_TIME_ACTION>
  </SPELL_ABILITY>
  <TRIGGERED_ABILITY forced_skip="1" auto_skip="1" active_zone="any">
    <TRIGGER value="BEGINNING_OF_STEP">
      local store = Storage( Object() )
      local zone = Object():GetZone()
      return (store.get( 0 ) ~= nil and store.get( 0 ) &gt; 0 and MTG():GetStep() == STEP_END_OF_TURN and
      (zone == ZONE_REMOVED_FROM_GAME or zone == ZONE_LIBRARY or zone == ZONE_GRAVEYARD or zone == ZONE_HAND))
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
      local store = Storage( Object() )
      local count = store.get( 0 )
      if ( count ~= nil and count &gt; 0 ) then
        for i=1,count do
          card = store.get( i )
          if (card ~= nil and card:GetZone() == ZONE_REMOVED_FROM_GAME) then
            card:PutInHand()
          end
        end
        local player = store.get( count+1 )
        if (player ~= nil) then
          player:DrawCard()
        end
        for i=0,count+1 do
          store.erase( i )
        end
      end
      store.clear()
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
</CARD_V2>
You need nabeshin's storage functions in order for it to work. The code could be improved with some cleaning, but I made a stupid error, so I added a lot of extra checks and unnecessary variable sets before realizing that the error had nothing to do with what I was checking. #-o Anyway, now it works, and that's the important thing, right? :lol:
< 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: 722 times

Re: Started modding DotP2012, need some help

Postby thefiremind » 13 Nov 2011, 20:14

I managed to code Geth, Lord of the Vault, but I'm not 100% satisfied and I'd like to have a suggestion.

The problem with Geth's ability is that the value spent on X excludes or includes possible targets. I can't let the player spend any amount of X and then choose the target: if there's no legal target, the ability shouldn't even be playable. So I made a little workaround. The ability costs {0}, but the target determination allows to play it only if the player has enough mana to pay the right amount of X for at least one legal target. Then, the necessary lands are tapped during the ability resolution, when X has been decided by choosing the target. Here lies the little bug: I don't know if it's even possible to code Stifle in DotP2012, but let's pretend the opponent casts Stifle on Geth's activated ability. The lands won't be tapped because the ability has been countered... but they should have been tapped since they are a cost.

Here is the code:
Code: Select all
<?xml version='1.0'?>
<CARD_V2 custom="true">
  <FILENAME text="GETH_LORD_OF_THE_VAULT_999143" />
  <CARDNAME text="GETH_LORD_OF_THE_VAULT" />
  <TITLE>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Geth, Lord of the Vault]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </TITLE>
  <MULTIVERSEID value="999143" />
  <ARTID value="999143" />
  <FRAMECOLOUR name="B" />
  <COLOUR value="B" />
  <ARTIST name="Whit Brachna" />
  <CASTING_COST cost="{4}{B}{B}" />
  <SUPERTYPE metaname="Legendary" order_de-DE="0" order_es-ES="1" order_fr-FR="1" order_it-IT="1" order_jp-JA="0" />
  <TYPE metaname="Creature" order_de-DE="1" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <SUB_TYPE metaname="Zombie" order_de-DE="0" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <EXPANSION value="SOM" />
  <RARITY metaname="M" />
  <POWER value="5" />
  <TOUGHNESS value="5" />
  <STATIC_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Intimidate]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
    <CONTINUOUS_ACTION>
    Object():GetCurrentCharacteristics():Badge_Set( BADGE_INTIMIDATE )
    </CONTINUOUS_ACTION>
  </STATIC_ABILITY>
  <ACTIVATED_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[{X}{B}: Put target artifact or creature card with converted mana cost X from an opponent's graveyard onto the battlefield under your control tapped. Then that player puts the top X cards of his or her library into his or her graveyard.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
    <COST type="mana" cost="{0}" />
    <TARGET_DETERMINATION>
    local filter = Object():GetFilter()
    filter:Clear()
    filter:AddCardType( CARD_TYPE_ARTIFACT )
    filter:AddCardType( CARD_TYPE_CREATURE )
    filter:SetZone( ZONE_GRAVEYARD )
    local num_players = MTG():GetNumberOfPlayers()
    for p=0,num_players-1 do
      local player = MTG():GetNthPlayer(p)
      if player:GetTeam() ~= Object():GetPlayer():GetTeam() then
        filter:SetPlayer( player )
      end
    end
    if filter:CountStopAt( 1 ) == 1 then
      local maxcost = 16
      local maxafford = 0
      for i=1,maxcost do
        if Object():GetPlayer():CanAfford("{"..i.."}{B}", nil) == 1 then
          maxafford = i
        end
      end
      filter:SetConvertedCostMax( maxafford )
      if filter:CountStopAt( 1 ) == 1 then
        return TARGET_DETERMINATION_ALL
      end
    end
    return TARGET_DETERMINATION_NONE
    </TARGET_DETERMINATION>
    <PLAY_TIME_ACTION>
    local filter = Object():GetFilter()
    filter:Clear()
    filter:AddCardType( CARD_TYPE_ARTIFACT )
    filter:AddCardType( CARD_TYPE_CREATURE )
    filter:SetZone( ZONE_GRAVEYARD )
    local num_players = MTG():GetNumberOfPlayers()
    for p=0,num_players-1 do
      local player = MTG():GetNthPlayer(p)
      if player:GetTeam() ~= Object():GetPlayer():GetTeam() then
        filter:SetPlayer( player )
      end
    end
    if filter:CountStopAt( 1 ) == 1 then
      local maxcost = 16
      local maxafford = 0
      for i=1,maxcost do
        if Object():GetPlayer():CanAfford("{"..i.."}{B}", nil) == 1 then
          maxafford = i
        end
      end
      filter:SetConvertedCostMax( maxafford )
      if filter:CountStopAt( 1 ) == 1 then
        ChooseTarget( "CARD_QUERY_CHOOSE_CARD_TO_PUT_ONTO_BATTLEFIELD" )
      end
    end
    </PLAY_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    local target_card = Object():GetTargetCard()
    if target_card ~= nil then
      local cmc = target_card:GetConvertedManaCost()
      Object():GetPlayer():TapLand("{"..cmc.."}{B}")
      if target_card:GetZone() == ZONE_GRAVEYARD then
        MTG():SetProtectedMove(1)
        target_card:PutIntoPlayTapped( Object():GetPlayer() )
       MTG():SetProtectedMove(0)
      end
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    local target_card = Object():GetTargetCard()
    if target_card ~= nil then
      MillCards( target_card:GetOwner(), target_card:GetConvertedManaCost() )
    end
    </RESOLUTION_TIME_ACTION>
    <AI_BASE_SCORE score="1200" zone="in_play" />
  </ACTIVATED_ABILITY>
</CARD_V2>
The obvious answer would be: put the land tapping in a PLAY_TIME_ACTION before the resolution. I already tried it, but the ability stopped working by doing this change, and I can't understand why. I thought that maybe the game checks the target determination once again before the resolution, and since the lands are tapped, the target determination fails. So I added another condition on the "if...then" before the TARGET_DETERMINATION_ALL that prevents it from failing when the ability is resolving (by using a register), but it was still broken, so I came back to the working - but not perfect - solution.

Any ideas?

P.S.: Don't ask me what's the use of "SetProtectedMove", I just took that part from Beacon of Unrest. :lol:
< 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: 722 times

Re: Thefiremind's help requests

Postby thefiremind » 09 Dec 2011, 23:45

I stumbled upon a strange problem, so I'm reusing this topic (I changed the title since it said "Started modding" and it's not true anymore :wink:).

I tried to code Serra Avenger, here is the code:
Code: Select all
<?xml version='1.0'?>
<CARD_V2 custom="true">
  <FILENAME text="SERRA_AVENGER_999188" />
  <CARDNAME text="SERRA_AVENGER" />
  <TITLE>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Serra Avenger]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </TITLE>
  <MULTIVERSEID value="999188" />
  <ARTID value="999188" />
  <FRAMECOLOUR name="W" />
  <COLOUR value="W" />
  <ARTIST name="Scott M. Fischer" />
  <CASTING_COST cost="{W}{W}" />
  <FLAVOURTEXT>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA["Those who endure in the face of suffering, those whose faith shines long in evil days, they shall see salvation." -Song of All, canto 904]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </FLAVOURTEXT>
  <TYPE metaname="Creature" order_de-DE="0" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <SUB_TYPE metaname="Angel" order_de-DE="0" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <EXPANSION value="TS" />
  <RARITY metaname="R" />
  <POWER value="3" />
  <TOUGHNESS value="3" />
  <STATIC_ABILITY zone="hand">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[You can’t cast Serra Avenger during your first, second, or third turns of the game.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
    <CONTINUOUS_ACTION>
    local store = Storage( Object() )
    local ended_turns = store.get( Object():GetOwner() )
    if Object():GetOwner():MyTurn() ~= 0 and (ended_turns == nil or ended_turns &lt; 3) then
      Object():GetCurrentCharacteristics():Bool_Set( CHARACTERISTIC_CANT_BE_PLAYED, 1 )
    end
    </CONTINUOUS_ACTION>
  </STATIC_ABILITY>
  <TRIGGERED_ABILITY internal="1" pre_trigger="1" auto_skip="1" forced_skip="1" active_zone="any">
    <TRIGGER value="SPELL_PLAYED" simple_qualifier="self">
    if Object():GetZone() == ZONE_HAND then
      return false
    end
    local store = Storage( Object() )
    local ended_turns = store.get( TriggerObject():GetPlayer() )
    if (ended_turns == nil or ended_turns &lt; 3) then
      override = true
      return true
    else
      return false
    end
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    -- Do nothing, the spell just can't be played
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <TRIGGERED_ABILITY internal="1" auto_skip="1" forced_skip="1" active_zone="any">
    <TRIGGER value="BEGINNING_OF_STEP">
    return (MTG():GetStep() == STEP_END_OF_TURN and TriggerPlayer():MyTurn() ~= 0)
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    local store = Storage( Object() )
    local ended_turns = store.get( TriggerPlayer() )
    if ended_turns == nil then
      ended_turns = 1
    else
      ended_turns = ended_turns + 1
    end
    store.set( TriggerPlayer(), ended_turns )
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <STATIC_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Flying]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Vol]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Fliegend]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Vuela]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Volare]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[飛行]]></LOCALISED_TEXT>
    <CONTINUOUS_ACTION>
    local characteristics = Object():GetCurrentCharacteristics()
    characteristics:Badge_Set( BADGE_FLYING )
    characteristics:FX_Set( SPECIAL_EFFECT_FLYING)
    characteristics:CanOnlyBeBlockedBy_Set(EVASION_INDEX_FLYING )
    characteristics:CanBlock_Set( EVASION_INDEX_FLYING )
    </CONTINUOUS_ACTION>
  </STATIC_ABILITY>
  <STATIC_ABILITY commaspace="1">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[vigilance]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[vigilance]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Wachsamkeit]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[vigilancia.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[cautela]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[警戒]]></LOCALISED_TEXT>
    <CONTINUOUS_ACTION>
    Object():GetCurrentCharacteristics():Badge_Set( BADGE_VIGILANCE )
    Object():GetCurrentCharacteristics():Bool_Set( CHARACTERISTIC_VIGILANCE, 1 )
    </CONTINUOUS_ACTION>
  </STATIC_ABILITY>
  <HELP title="MORE_INFO_BADGE_TITLE_10" body="MORE_INFO_BADGE_BODY_10" zone="Any" />
  <HELP title="MORE_INFO_BADGE_TITLE_13" body="MORE_INFO_BADGE_BODY_13" zone="Any" />
  <SFX text="COMBAT_ANGEL_LARGE_ATTACK" power_boundary_min="4" power_boundary_max="-1" />
  <SFX text="COMBAT_ANGEL_SMALL_ATTACK" power_boundary_min="1" power_boundary_max="3" />
</CARD_V2>
There's a trigger that counts how many turns each player ended, and if the owner has ended less than 3 turns, the card can't be played from the hand. The other trigger prevents the card from being played with means like Wrexial, the Risen Deep (who can't make a player cast creatures, but you know that I keep an eye on future compatibilities): that's why I keep track of each player's turns rather than only the owner's. I already used this trick successfully with Ethersworn Canonist (even if the Canonist doesn't affect herself, while Serra Avenger does, so there's a difference).

Serra Avenger works as intended... but only for me! I can play as many Serra Avengers as I want from the 4th turn, but the AI keeps them in hand and never plays them. I really can't understand why. #-o
< 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: 722 times

Re: Thefiremind's help requests

Postby Persee » 10 Dec 2011, 06:49

Try with <AI_PLAY_SCORE>.

For example the code I made for Tithe :

Code: Select all
  <AI_PLAY_SCORE>
    local filter = Object():GetFilter()
    local player = Object():GetPlayer()
    filter:Clear()
    filter:SetZone( ZONE_IN_PLAY )
    filter:AddCardType( CARD_TYPE_LAND )
    filter:SetController( Object():GetController() )
    filter:NotTargetted()
    local LNG_PLAYER_LANDS = filter:Count()
    local LNG_HASLESSLANDS = 0
   local OBJ_PLAYER_TEAM = Object():GetController():GetTeam()
    for LNG_PLAYER_INDEX = 0, MTG():GetNumberOfPlayers()-1 do
    local OBJ_SELECTED_PLAYER = MTG():GetNthPlayer( LNG_PLAYER_INDEX )
    if ( OBJ_SELECTED_PLAYER:GetTeam() ~= OBJ_PLAYER_TEAM ) then
    filter:Clear()
    filter:SetZone( ZONE_IN_PLAY )
    filter:AddCardType( CARD_TYPE_LAND )
    filter:SetController( OBJ_SELECTED_PLAYER )
    local LNG_OPPONENT_LANDCOUNT = filter:Count()
    if ( LNG_OPPONENT_LANDCOUNT > LNG_PLAYER_LANDS ) then
   LNG_HASLESSLANDS = 1
   end
   end
   end
   
    if ( MTG():GetStep() == STEP_MAIN_2 and Object():GetController():MyTurn() == 0 and LNG_HASLESSLANDS == 1 and CountCardsInHand( player ) &lt; 7 ) then
        return (50000)
      else
      return (-10000)
    end
  </AI_PLAY_SCORE>
With this code, the AI plays Tithe only during my turn and if I have more lands than it and when it has less than 7 cards in hand.

ps: sorry for my bad english.
User avatar
Persee
 
Posts: 168
Joined: 02 Jun 2011, 08:33
Has thanked: 42 times
Been thanked: 24 times

Re: Thefiremind's help requests

Postby thefiremind » 10 Dec 2011, 10:45

I thought about that, but I should make a Serra Avenger version only for the AI that uses the score rule instead of the real rule... I'll remember about this option, in the meanwhile I'll experiment a bit more and try to find out if something else can be done. Thanks for the tip.

EDIT: I made it! I had the intuition that the AI doesn't like taking decisions based on nabeshin's storage, because it doesn't recognize it or something like that. So, I just used a data chest when the decision must be made for the owner. The AI waited for the 5th turn before playing the first Serra Avenger (maybe he didn't have any on the 4th turn even if it's highly improbable in a testing deck with 25 of them :shock:), anyway it's better than not playing it at all! :lol:
Here is the revised code:
Code: Select all
<?xml version='1.0'?>
<CARD_V2 custom="true">
  <FILENAME text="SERRA_AVENGER_999188" />
  <CARDNAME text="SERRA_AVENGER" />
  <TITLE>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Serra Avenger]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </TITLE>
  <MULTIVERSEID value="999188" />
  <ARTID value="999188" />
  <FRAMECOLOUR name="W" />
  <COLOUR value="W" />
  <ARTIST name="Scott M. Fischer" />
  <CASTING_COST cost="{W}{W}" />
  <FLAVOURTEXT>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA["Those who endure in the face of suffering, those whose faith shines long in evil days, they shall see salvation." -Song of All, canto 904]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
  </FLAVOURTEXT>
  <TYPE metaname="Creature" order_de-DE="0" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <SUB_TYPE metaname="Angel" order_de-DE="0" order_es-ES="0" order_fr-FR="0" order_it-IT="0" order_jp-JA="0" />
  <EXPANSION value="TS" />
  <RARITY metaname="R" />
  <POWER value="3" />
  <TOUGHNESS value="3" />
  <STATIC_ABILITY zone="hand">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[You can’t cast Serra Avenger during your first, second, or third turns of the game.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[]]></LOCALISED_TEXT>
    <CONTINUOUS_ACTION>
    if Object():GetOwner():MyTurn() ~= 0 and MTG():ObjectDataChest():Get_Int(1) &lt; 3 then
      Object():GetCurrentCharacteristics():Bool_Set( CHARACTERISTIC_CANT_BE_PLAYED, 1 )
    else
      Object():GetCurrentCharacteristics():Bool_Set( CHARACTERISTIC_CANT_BE_PLAYED, 0 )
    end
    </CONTINUOUS_ACTION>
  </STATIC_ABILITY>
  <TRIGGERED_ABILITY internal="1" pre_trigger="1" auto_skip="1" forced_skip="1" active_zone="any">
    <TRIGGER value="SPELL_PLAYED" simple_qualifier="self">
    if Object():GetZone() == ZONE_HAND then
      return false
    end
    local store = Storage( Object() )
    local ended_turns = store.get( TriggerObject():GetPlayer() )
    if (ended_turns == nil or ended_turns &lt; 3) then
      override = true
      return true
    else
      return false
    end
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    -- Do nothing, the spell just can't be played
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <TRIGGERED_ABILITY internal="1" auto_skip="1" forced_skip="1" active_zone="any">
    <TRIGGER value="BEGINNING_OF_STEP">
    return (MTG():GetStep() == STEP_END_OF_TURN and TriggerPlayer():MyTurn() ~= 0)
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    local store = Storage( Object() )
    local ended_turns = store.get( TriggerPlayer() )
    if ended_turns == nil then
      ended_turns = 1
    else
      ended_turns = ended_turns + 1
    end
    store.set( TriggerPlayer(), ended_turns )
    if TriggerPlayer() == Object():GetOwner() then
      MTG():ObjectDataChest():Set_Int(1, ended_turns)
    end
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <TRIGGERED_ABILITY internal="1" pre_trigger="1" active_zone="any">
    <TRIGGER value="ZONECHANGE" simple_qualifier="self" />
    <RESOLUTION_TIME_ACTION>
    if Object():GetDataChest() ~= nil then
      Object():RetainDataChest()
    end
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <STATIC_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Flying]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Vol]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Fliegend]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Vuela]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Volare]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[飛行]]></LOCALISED_TEXT>
    <CONTINUOUS_ACTION>
    local characteristics = Object():GetCurrentCharacteristics()
    characteristics:Badge_Set( BADGE_FLYING )
    characteristics:FX_Set( SPECIAL_EFFECT_FLYING)
    characteristics:CanOnlyBeBlockedBy_Set(EVASION_INDEX_FLYING )
    characteristics:CanBlock_Set( EVASION_INDEX_FLYING )
    </CONTINUOUS_ACTION>
  </STATIC_ABILITY>
  <STATIC_ABILITY commaspace="1">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[vigilance]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[vigilance]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Wachsamkeit]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[vigilancia.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[cautela]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[警戒]]></LOCALISED_TEXT>
    <CONTINUOUS_ACTION>
    Object():GetCurrentCharacteristics():Badge_Set( BADGE_VIGILANCE )
    Object():GetCurrentCharacteristics():Bool_Set( CHARACTERISTIC_VIGILANCE, 1 )
    </CONTINUOUS_ACTION>
  </STATIC_ABILITY>
  <AI_BASE_SCORE score="1800" zone="hand" />
  <HELP title="MORE_INFO_BADGE_TITLE_10" body="MORE_INFO_BADGE_BODY_10" zone="Any" />
  <HELP title="MORE_INFO_BADGE_TITLE_13" body="MORE_INFO_BADGE_BODY_13" zone="Any" />
  <SFX text="COMBAT_ANGEL_LARGE_ATTACK" power_boundary_min="4" power_boundary_max="-1" />
  <SFX text="COMBAT_ANGEL_SMALL_ATTACK" power_boundary_min="1" power_boundary_max="3" />
</CARD_V2>
As you can see, now the turn counter writes the owner's ended turns in register 1 of the data chest, and the decision is made on that. I also had to add the retain of the data chest in case Serra Avenger changes zone, and I added the Bool_Set to 0 when the turns condition is false, just to be 100% sure that this dumb AI knows when it's time to play! :lol:
The score of 1800 can be risen up if you think so... anyway I'm sure it's not what makes the card work for the AI because I tried to add it yesterday, too.
< 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: 722 times


Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 4 guests


Who is online

In total there are 4 users online :: 0 registered, 0 hidden and 4 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 4 guests

Login Form