It is currently 19 Apr 2024, 09:10
   
Text Size

Zombie Infestation - Discard mechanic help

Moderator: CCGHQ Admins

Zombie Infestation - Discard mechanic help

Postby Dysgenics » 25 Aug 2012, 19:39

Creating my first non-trivial card (Zombie Infestation) and I'm painfully unfamiliar with this scripting language.

Currently the action prompts the player to select two cards, and then successfully creates the zombie token, but the cards are never discarded.

I assume I'm making some kind of obvious mistake, but haven't been able to figure it out.

Code:
Code: Select all
<?xml version='1.0'?>
<CARD_V2>
  <FILENAME text="ZOMBIE_INFESTATION_29957" />
  <CARDNAME text="ZOMBIE_INFESTATION" />
  <TITLE>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Zombie Infestation]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Zombiebefall]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Infestación de zombies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Infestation de zombies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Infestazione di Zombie]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[ゾンビの横行]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Zombie Infestation]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Нашествие Зомби]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Infestação de Zumbis]]></LOCALISED_TEXT>
  </TITLE>
  <MULTIVERSEID value="29957" />
  <ARTID value="29957" />
  <ARTIST name="Thomas M. Baxa" />
  <CASTING_COST cost="{1}{B}" />
  <FLAVOURTEXT>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[The nomads’ funeral pyres are more practical than ceremonial.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Die Scheiterhaufen der Nomaden sind eher praktischer Natur als unbedingt zeremoniell.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Las piras funerarias de los nómadas son más prácticas que ceremoniales.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[C'est pour des raisons pratiques, et non religieuses, que les nomades brûlent leurs morts.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Le pire funebri dei nomadi sono più per praticità che per cerimonia.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[遊牧の民の火葬用の積み薪は、儀式用というよりもむしろ実用的なものなのだ。]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[The nomads’ funeral pyres are more practical than ceremonial.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Погребальные костры кочевников играют скорее практическую роль, нежели церемониальную.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[As piras funerárias dos nômades são mais funcionais do que cerimoniais.]]></LOCALISED_TEXT>
  </FLAVOURTEXT>
  <TYPE metaname="Enchantment" />
  <EXPANSION value="DPG" />
  <RARITY metaname="U" />
  <ACTIVATED_ABILITY auto_skip="1" filter_zone="ZONE_IN_PLAY">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Discard two cards: Put a 2/2 black Zombie creature token onto the battlefield.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Wirf zwei Karten aus deiner Hand ab: Bringe einen 2/2 schwarzen Zombie-Kreaturenspielstein ins Spiel.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Descartar dos cartas: Pon en el campo de batalla una ficha de criatura Zombie negra 2/2.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Défaussez-vous de deux cartes : Mettez sur le champ de bataille un jeton de créature 2/2 noire Zombie.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Scarta due carte: Metti sul campo di battaglia una pedina creatura Zombie 2/2 nera.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[カードを2枚捨てる:黒の2/2のゾンビ・クリーチャー・トークンを1体戦場に出す。]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Discard two cards: Put a 2/2 black Zombie creature token onto the battlefield.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Сбросьте две карты: положите на поле битвы одну фишку существа 2/2 черный Зомби.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Descarte dois cards: Coloque no campo de batalha uma ficha de criatura preta 2/2 do tipo Zumbi.]]></LOCALISED_TEXT>
   <COST type="Discard">
      <TARGET_DEFINITION id="6">
        local filter = Object():GetFilter()
        filter:Clear()
        filter:NotTargetted()
        filter:SetZone( ZONE_HAND )
        filter:SetPlayer( EffectController() )
      </TARGET_DEFINITION>
      <TARGET_DETERMINATION>
        return AtLeastOneTargetFromDefinition(6)
      </TARGET_DETERMINATION>
      <PLAYTIME>
       EffectController():SetTargetCount( 2 )
       for i = 0,(2-1) do
          EffectController():SetTargetPrompt( i, "CARD_QUERY_CHOOSE_CARD_TO_DISCARD_2" )
       end
      EffectController():ChooseTargets( NO_VALIDATION, EffectDC():Make_Targets(1) )
     </PLAYTIME>
     <PLAYTIME>
      local player = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
      if player ~= nil then
         for i = 0,(2-1) do
            local target_card = EffectDC():Get_Targets(1):Get_CardPtr(i)
            if target_card ~= nil  then
               target_card:Discard()
            end
         end
      end
      </PLAYTIME></COST>
    <RESOLUTION_TIME_ACTION>
      MTG():PutTokensIntoPlay( "TOKEN_ZOMBIE_2_2_277465", 1, EffectController() )
    </RESOLUTION_TIME_ACTION>
    <AI_AVAILABILITY type="in_response" />
    <AI_AVAILABILITY step="end_of_turn" turn="their_turn" />
    <AI_AVAILABILITY step="main_1" turn="my_turn" />
    <AI_AVAILABILITY step="main_2" turn="my_turn" />
    <AI_AVAILABILITY step="declare_blockers" blocking_or_blocked="1" />
  </ACTIVATED_ABILITY>
</CARD_V2>
User avatar
Dysgenics
 
Posts: 13
Joined: 25 Aug 2012, 19:33
Has thanked: 5 times
Been thanked: 0 time

Re: Zombie Infestation - Discard mechanic help

Postby thefiremind » 25 Aug 2012, 20:52

When you use a predefined cost type (such as "Discard" in your code), there's a limit on how much you can customize the choice. One thing is sure: the predefined cost types act automatically on the selected cards (if they work), so you can remove the second <PLAYTIME> block and see if it works. If it doesn't work, then it means that you can't use a predefined cost type, but you must use "Generic": you'll have to substitute "Discard" with "Generic", rename the first <PLAYTIME> to <PLAY_TIME_ACTION> and the second <PLAYTIME> to <RESOLUTION_TIME_ACTION> (the "Generic" costs are coded as normal abilities, and you can do anything you want inside them).
There are 2 other little problems: since you need 2 cards, the TARGET_DETERMINATION for the discard should be return AtLeastNTargetsFromDefinition(6, 2), and you forgot to include the TOKEN_REGISTRATION block for the zombie token (without that, the game will crash at the end of the duel).
< 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: Zombie Infestation - Discard mechanic help

Postby Dysgenics » 25 Aug 2012, 22:04

Thanks for the advice and the explanations, it really helped me learn something here.

Also noticed through debugging that
Code: Select all
local player = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
if player ~= nil then
    <!-- Discard Segment -->
end
was returning false, causing the discard segment to be ignored.

Is this check necessary to prevent problems with a specific end-game scenario, or is omitting it kosher?
It seems to be working perfectly now, but I want to make sure I cover everything. :D

In case anyone is interested in the card, I'll attach it here. (EDIT: updated & fixed)

Thanks again for the help!
Attachments
ZOMBIE_INFESTATION.rar
(115.47 KiB) Downloaded 211 times
Last edited by Dysgenics on 26 Aug 2012, 18:17, edited 1 time in total.
User avatar
Dysgenics
 
Posts: 13
Joined: 25 Aug 2012, 19:33
Has thanked: 5 times
Been thanked: 0 time

Re: Zombie Infestation - Discard mechanic help

Postby pcastellazzi » 26 Aug 2012, 02:26

The check is necessary. You will notice the effect if you kill the player playing the card before it resolves. Common cases are direct damage (Lightning Bolt), triggered effects (Megrim), an activated ability (Cunning Sparkmage), among others.
The lights then came up and the crowd erupted in applause, because that's what the crowd does after it watches destruction on a large screen.
— Ben Kuchera, Mordern Warfare 3 review.
User avatar
pcastellazzi
 
Posts: 184
Joined: 25 Apr 2012, 00:40
Location: Montevideo, Uruguay
Has thanked: 11 times
Been thanked: 30 times

Re: Zombie Infestation - Discard mechanic help

Postby Dysgenics » 26 Aug 2012, 18:16

Ah, thanks for the heads up.
I updated the card and I'll replace my previous upload in the above post.
User avatar
Dysgenics
 
Posts: 13
Joined: 25 Aug 2012, 19:33
Has thanked: 5 times
Been thanked: 0 time

Re: Zombie Infestation - Discard mechanic help

Postby pcastellazzi » 27 Aug 2012, 02:31

A few extra notes.

DOTP 2012 supported the number attribute for the cost tag. Never tried it on 2013 yet, but it may help you to clean up your code a little. You could have used:

Code: Select all
<COST type="discard" number="2">
  <TARGET_DETERMINATION>
    return AtLeastOneTargetFromDefinition(6)
  </TARGET_DETERMINATION>
  <TARGET_DEFINITION id="6">
    local filter = Object():GetFilter()
    filter:Clear()
    filter:NotTargetted()
    filter:SetZone(ZONE_HAND)
    filter:SetPlayer(EffectController())
  </TARGET_DEFINITION>
  <PLAYTIME>
    EffectController():ChooseTarget(6, "CARD_QUERY_CHOOSE_CARD_TO_DISCARD")
  </PLAYTIME>
</COST>
There is no need to write code for the player to discard a card, it's done automatically by the engine. Also the prompt should be a generic one, not matter if you need to discard one, two, or ten.

As i said, a similar code used to work on 2012. bit i not tried it on 2013 yet. I think is worth a try.

Another gotcha, you forgot the token registration tag.

Code: Select all
<TOKEN_REGISTRATION reservation="1" type="TOKEN_ZOMBIE_2_2_277465" />
You may take a look at the code of Grave Titan for a complete example.
The lights then came up and the crowd erupted in applause, because that's what the crowd does after it watches destruction on a large screen.
— Ben Kuchera, Mordern Warfare 3 review.
User avatar
pcastellazzi
 
Posts: 184
Joined: 25 Apr 2012, 00:40
Location: Montevideo, Uruguay
Has thanked: 11 times
Been thanked: 30 times

Re: Zombie Infestation - Discard mechanic help

Postby thefiremind » 27 Aug 2012, 18:35

pcastellazzi wrote:A few extra notes.

DOTP 2012 supported the number attribute for the cost tag. Never tried it on 2013 yet, but it may help you to clean up your code a little.
Personally I don't like how the game automatically handled multiple targets for costs in DotP2012: Grim Lavamancer made the user select the first card to exile, then it exiled that card, then made the user select the second card to exile, then it exiled that card. It's much more coherent to the rest of the game if you choose all the targets first and treat them after. That's why I didn't even try that on DotP2013 and used the generic tag.
< 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


Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 20 guests

cron

Who is online

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

Login Form