Board index Programs with AI or Rules Enforcement Magic: The Gathering - Duels of the Planeswalkers Programming Talk
Zombie Infestation - Discard mechanic help
Moderator: CCGHQ Admins
Zombie Infestation - Discard mechanic help
by 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:
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>
Re: Zombie Infestation - Discard mechanic help
by 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).
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...
Currently busy with life...
-
thefiremind - Programmer
- Posts: 3515
- Joined: 07 Nov 2011, 10:55
- Has thanked: 118 times
- Been thanked: 721 times
Re: Zombie Infestation - Discard mechanic help
by 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
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.
In case anyone is interested in the card, I'll attach it here. (EDIT: updated & fixed)
Thanks again for the help!
Also noticed through debugging that
- Code: Select all
local player = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
if player ~= nil then
<!-- Discard Segment -->
end
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.
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.
Re: Zombie Infestation - Discard mechanic help
by 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.
— Ben Kuchera, Mordern Warfare 3 review.
-
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
by 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.
I updated the card and I'll replace my previous upload in the above post.
Re: Zombie Infestation - Discard mechanic help
by 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:
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.
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>
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" />
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.
— Ben Kuchera, Mordern Warfare 3 review.
-
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
by thefiremind » 27 Aug 2012, 18:35
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.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.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
Currently busy with life...
-
thefiremind - Programmer
- Posts: 3515
- Joined: 07 Nov 2011, 10:55
- Has thanked: 118 times
- Been thanked: 721 times
7 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 20 guests