Board index Programs with AI or Rules Enforcement Magic: The Gathering - Duels of the Planeswalkers Programming Talk
[DotP2013] Help with Cipher
Moderator: CCGHQ Admins
[DotP2013] Help with Cipher
by BETenner » 13 Mar 2013, 03:45
I need help again... for Cipher.
My code doesn't work for the cipher part:
My code doesn't work for the cipher part:
- Code: Select all
<SPELL_ABILITY dangerous="1" filter_zone="ZONE_IN_PLAY">
<TARGET_DEFINITION id="0">
local filter = Object():GetFilter()
filter:Clear()
filter:AddCardType( CARD_TYPE_CREATURE )
filter:SetControllersTeam( EffectController():GetTeam() )
filter:AddExtra( FILTER_EXTRA_FLIP_TEAM )
filter:SetHint( HINT_ENEMY_ONLY, EffectController() )
filter:SetZone( ZONE_IN_PLAY )
</TARGET_DEFINITION>
<TARGET_DETERMINATION>
return AtLeastOneTargetFromDefinition(0)
</TARGET_DETERMINATION>
<TARGET_DEFINITION id="1">
local filter = Object():GetFilter()
filter:Clear()
filter:AddCardType( CARD_TYPE_CREATURE )
filter:SetPlayer( EffectController() )
filter:SetZone( ZONE_IN_PLAY )
</TARGET_DEFINITION>
<PLAY_TIME_ACTION target_choosing="1">
EffectController():ChooseTarget( 0, "CARD_QUERY_CHOOSE_CREATURE_TO_TAPHOLD", EffectDC():Make_Targets(0) )
</PLAY_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
if (target ~= nil) then
target:TapAndHold()
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
if (Object():GetErstwhileZone() ~= ZONE_NOWHERE_YET) then
local filter = Object():LoadTargetDefinition(1)
if (filter:CountStopAt(1) == 1) then
EffectController():ChooseTargetWithFlags( 1, "CARD_QUERY_CHOOSE_CREATURE_TO_CIPHER", EffectDC():Make_Targets(1), QUERY_FLAG_CAN_BE_FINISHED_EARLY + QUERY_FLAG_CAN_BE_FINISHED_EARLY_FOR_AI_AS_WELL )
end
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if (target ~= nil) then
ObjectDC():Set_CardPtr(0, target)
ObjectDC():Protect_CardPtr(0)
Object():SetResolutionZone( ZONE_REMOVED_FROM_GAME )
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local target = ObjectDC():Get_CardPtr(0)
if (target ~= nil) then
Object():NailOnto(target)
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
<TRIGGERED_ABILITY internal="1" active_zone="ZONE_REMOVED_FROM_GAME">
<TRIGGER value="CREATURE_DEALS_COMBAT_DAMAGE_TO_PLAYER">
local target = ObjectDC():Get_CardPtr(0)
return (target ~= nil and target == TriggerObject())
</TRIGGER>
<RESOLUTION_TIME_ACTION>
local target = ObjectDC():Get_CardPtr(0)
if (target ~= nil) then
local player = target:GetController()
if (Object():CanBePlayed(player)) then
player:CopySpellWithNewTargets(Object())
end
end
</RESOLUTION_TIME_ACTION>
</TRIGGERED_ABILITY>
Re: [DotP2013] Help with Cipher
by thefiremind » 13 Mar 2013, 10:32
First of all, I would put cipher in a separate spell ability: the card will work the same way, but it will be easier to copy cipher to other cards when needed. You also forgot NotTargetted() in the second target definition: cipher says "on a creature you control", not "on target creature you control"... I would have integrated the target filter directly in the resolution time action but that's just a personal choice.
Now, for the problem that prevents cipher from working: I think that it's because ObjectDC gets wiped when the card changes zone. You protected the card pointer, but it's useless because the whole ObjectDC gets wiped. Actually, not all zone changes wipe ObjectDC, that's something I never completely understood and that's why I like to avoid using ObjectDC when I can... but in this case you must use it. I'd suggest to exile the card first, and save the pointer to the target later. So this action:
Now, for the problem that prevents cipher from working: I think that it's because ObjectDC gets wiped when the card changes zone. You protected the card pointer, but it's useless because the whole ObjectDC gets wiped. Actually, not all zone changes wipe ObjectDC, that's something I never completely understood and that's why I like to avoid using ObjectDC when I can... but in this case you must use it. I'd suggest to exile the card first, and save the pointer to the target later. So this action:
- Code: Select all
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if (target ~= nil) then
ObjectDC():Set_CardPtr(0, target)
ObjectDC():Protect_CardPtr(0)
Object():SetResolutionZone( ZONE_REMOVED_FROM_GAME )
end
</RESOLUTION_TIME_ACTION>
- Code: Select all
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if (target ~= nil) then
Object():RemoveFromGame()
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if (target ~= nil) then
ObjectDC():Set_CardPtr(0, target)
end
</RESOLUTION_TIME_ACTION>
< 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: [DotP2013] Help with Cipher
by BETenner » 13 Mar 2013, 11:56
Thanks!
I'll try and test it in DotP2013.
I'll try and test it in DotP2013.
Re: [DotP2013] Help with Cipher
by BETenner » 13 Mar 2013, 13:18
It doesn't work.
Even if you exile the card first, then save the card pointer later. I still can't get the saved card pointer in the trigger (always get nil).
So any other idea?
Even if you exile the card first, then save the card pointer later. I still can't get the saved card pointer in the trigger (always get nil).
So any other idea?
- Code: Select all
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if (target ~= nil) then
Object():RemoveFromGame()
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if (target ~= nil) then
ObjectDC():Set_CardPtr(0, target)
Object():NailOnto(target)
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
<TRIGGERED_ABILITY internal="1" active_zone="ZONE_REMOVED_FROM_GAME">
<TRIGGER value="CREATURE_DEALS_COMBAT_DAMAGE_TO_PLAYER">
local target = ObjectDC():Get_CardPtr(0) -- Always get nil here
return (target ~= nil and target == TriggerObject())
</TRIGGER>
<RESOLUTION_TIME_ACTION>
local target = ObjectDC():Get_CardPtr(0)
if (target ~= nil) then
local player = target:GetController()
if (Object():CanBePlayed(player)) then
player:CopySpellWithNewTargets(Object())
end
end
</RESOLUTION_TIME_ACTION>
</TRIGGERED_ABILITY>
Re: [DotP2013] Help with Cipher
by RiiakShiNal » 13 Mar 2013, 13:39
What about using a delayed trigger to handle this? Then you don't have to mess around with whether the ObjectDC() gets wiped or not and you can simply use EffectDC().
- Code: Select all
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if (target ~= nil) then
local delayDC = EffectDC():Make_Chest(2)
delayDC:Set_CardPtr(0, target)
delayDC:Set_ProtectedCardPtr(1, Object())
Object():RemoveFromGame()
Object():NailOnto(target)
MTG():CreateDelayedTrigger(1, delayDC)
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
<TRIGGERED_ABILITY resource_id="1" active_zone="ZONE_REMOVED_FROM_GAME">
<TRIGGER value="CREATURE_DEALS_COMBAT_DAMAGE_TO_PLAYER">
local target = EffectDC():Get_CardPtr(0)
return (target ~= nil and target == TriggerObject())
</TRIGGER>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_CardPtr(0)
local spell = EffectDC():Get_ProtectedCardPtr(1)
if (target ~= nil) then
local player = target:GetController()
if (spell ~= nil) then
if (spell:CanBePlayed(player)) then
player:CopySpellAndCastIt(spell)
end
end
end
</RESOLUTION_TIME_ACTION>
<CLEANUP>
-- Remove DelayedTrigger when creature is no longer valid (changed zones)
local target = EffectDC():Get_CardPtr(0)
return (target == nil)
</CLEANUP>
</TRIGGERED_ABILITY>
Last edited by RiiakShiNal on 31 Mar 2013, 15:41, edited 1 time in total.
Just getting started: Xander9009's DotP 2014 Community Wad
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
- RiiakShiNal
- Programmer
- Posts: 2183
- Joined: 16 May 2011, 21:37
- Has thanked: 75 times
- Been thanked: 496 times
Re: [DotP2013] Help with Cipher
by BETenner » 13 Mar 2013, 14:17
DelayedTrigger works!
Finally, cipher is done!
Thanks to you masters!
The final code are:
Finally, cipher is done!
Thanks to you masters!
The final code are:
- Code: Select all
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if (target ~= nil) then
local delayDC = EffectDC():Make_Chest(2)
delayDC:Set_CardPtr(0, target)
delayDC:Set_ProtectedCardPtr(1, Object())
Object():RemoveFromGame()
Object():NailOnto(target)
MTG():CreateDelayedTrigger(1, delayDC)
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
<TRIGGERED_ABILITY resource_id="1" active_zone="ZONE_REMOVED_FROM_GAME">
<TRIGGER value="CREATURE_DEALS_COMBAT_DAMAGE_TO_PLAYER">
local target = EffectDC():Get_CardPtr(0)
return (target ~= nil and target == TriggerObject())
</TRIGGER>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_CardPtr(0)
local spell = EffectDC():Get_ProtectedCardPtr(1)
if (target ~= nil) then
local player = target:GetController()
if (spell ~= nil) then
if (spell:CanBePlayed(player)) then
-- Ask the player whether wants to play the ciphered spell or not
player:BeginNewMultipleChoice()
player:AddMultipleChoiceAnswer("CARD_QUERY_OPTION_YES")
player:AddMultipleChoiceAnswer("CARD_QUERY_OPTION_NO")
player:AskMultipleChoiceQuestion("CARD_QUERY_ASK_PLAY_CIPHERED_SPELL")
end
end
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_CardPtr(0)
local spell = EffectDC():Get_ProtectedCardPtr(1)
if (target ~= nil) then
local player = target:GetController()
if (spell ~= nil) then
if (spell:CanBePlayed(player)) then
if (Object():GetMultipleChoiceResult() == 0) then
player:CopySpellWithNewTargets(spell)
end
end
end
end
</RESOLUTION_TIME_ACTION>
<CLEANUP>
-- Remove DelayedTrigger when creature is no longer valid (changed zones)
local target = EffectDC():Get_CardPtr(0)
return (target == nil)
</CLEANUP>
</TRIGGERED_ABILITY>
Re: [DotP2013] Help with Cipher
by thefiremind » 13 Mar 2013, 14:49
Thanks from me, too: I was still missing a confirmation that the <CLEANUP> block can contain custom code like the <DURATION> block.
< 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: [DotP2013] Help with Cipher
by BETenner » 13 Mar 2013, 16:13
A small problem:
My Hands of Binding now works perfectly (all actions are done correctly including cipher mechanic). But I found the following line in SCRIPT_LOG.TXT:
My Hands of Binding now works perfectly (all actions are done correctly including cipher mechanic). But I found the following line in SCRIPT_LOG.TXT:
- Code: Select all
[lua] [string "HANDS_OF_BINDING_GTC_037_TITLE (RESOLUTION_TIME_ACTION) [902]"]:2: attempt to index a nil value
Re: [DotP2013] Help with Cipher
by thefiremind » 13 Mar 2013, 17:31
There must be some scenario where a pointer gets deleted but everything working as expected anyway.BETenner wrote:A small problem:
My Hands of Binding now works perfectly (all actions are done correctly including cipher mechanic). But I found the following line in SCRIPT_LOG.TXT:What could possibly wrong?
- Code: Select all
[lua] [string "HANDS_OF_BINDING_GTC_037_TITLE (RESOLUTION_TIME_ACTION) [902]"]:2: attempt to index a nil value
First, a bit of knowledge about SCRIPT_LOG.TXT: the message you got basically means that this error occurred in the 2nd line of a RESOLUTION_TIME_ACTION, where the 2nd line is actually the 1st line of code (I think it adds one line internally when picking up the code). The problem is, it doesn't tell you which RESOLUTION_TIME_ACTION it refers to... but in this case I think I can't go wrong: the EffectDC inside the delayed trigger is always initialised by the CreateDelayedTrigger, so it must be the RESOLUTION_TIME_ACTION before it. Try to change
- Code: Select all
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
- Code: Select all
local target = EffectDC():Get_Targets(1) and EffectDC():Get_Targets(1):Get_CardPtr(0)
- Code: Select all
(non_nil_value and A) = A
(nil and A) = nil
< 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: [DotP2013] Help with Cipher
by RiiakShiNal » 13 Mar 2013, 19:57
Eh, it was more of a guess, but I thought why not.thefiremind wrote:Thanks from me, too: I was still missing a confirmation that the <CLEANUP> block can contain custom code like the <DURATION> block.
Just getting started: Xander9009's DotP 2014 Community Wad
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
- RiiakShiNal
- Programmer
- Posts: 2183
- Joined: 16 May 2011, 21:37
- Has thanked: 75 times
- Been thanked: 496 times
Re: [DotP2013] Help with Cipher
by sumomole » 17 Mar 2013, 22:01
702.97a Cipher appears on some instants and sorceries. It represents two static abilities, one that functions while the spell is on the stack and one that functions while the card with cipher is in the exile zone. "Cipher" means "If this spell is represented by a card, you may exile this card encoded on a creature you control" and "As long as this card is encoded on that creature, that creature has 'Whenever this creature deals combat damage to a player, you may copy this card and you may cast the copy without paying its mana cost.'"
The triggered ability on the endowed creature rather than the card with cipher. So you should use "GrantAbility", not "CreateDelayedTrigger".
I use an unconventional way to code Whispering Madness.
The triggered ability on the endowed creature rather than the card with cipher. So you should use "GrantAbility", not "CreateDelayedTrigger".
I use an unconventional way to code Whispering Madness.
- Code: Select all
<SPELL_ABILITY filter_zone="ZONE_IN_PLAY">
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Cipher]]></LOCALISED_TEXT>
<RESOLUTION_TIME_ACTION>
if EffectSource() ~= nil and EffectSource():IsToken() == 0 then
local filter = Object():GetFilter()
filter:Clear()
filter:May()
filter:NotTargetted()
filter:AddCardType( CARD_TYPE_CREATURE )
filter:SetZone( ZONE_IN_PLAY )
filter:SetController( EffectController() )
filter:SetHint( HINT_ALLIED, EffectController() )
EffectController():ChooseTarget( NO_VALIDATION, "CARD_QUERY_CHOOSE_CREATURE_TO_ENCODE", EffectDC():Make_Targets(0) )
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
if EffectDC():Get_Targets(0) ~= nil then
local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
if target ~= nil then
EffectDC():Protect_CardPtr(COMPARTMENT_ID_EFFECT_SOURCE)
EffectSource():RemoveFromGame()
end
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
if EffectDC():Get_Targets(0) ~= nil then
local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
if target ~= nil then
if EffectSource():GetZone() == ZONE_REMOVED_FROM_GAME then
EffectSource():NailOnto( target )
end
end
end
</RESOLUTION_TIME_ACTION>
<CONTINUOUS_ACTION layer="6">
if EffectDC():Get_Targets(0) ~= nil then
local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
if target ~= nil then
target:GetCurrentCharacteristics():GrantAbility(2)
end
end
</CONTINUOUS_ACTION>
<DURATION>
return EffectSource():GetZone() ~= ZONE_REMOVED_FROM_GAME or EffectSource() == nil
</DURATION>
</SPELL_ABILITY>
- Code: Select all
<TRIGGERED_ABILITY resource_id="2" filter_zone="ZONE_IN_PLAY">
<TRIGGER value="CREATURE_DEALS_COMBAT_DAMAGE_TO_PLAYER" simple_qualifier="self" />
<RESOLUTION_TIME_ACTION>
if EffectSource() ~= nil then
local filter = Object():GetFilter()
filter:Clear()
filter:SetUnique()
filter:NotTargetted()
filter:SetZone( ZONE_REMOVED_FROM_GAME )
filter:AddCardName( "WHISPERING_MADNESS" )
local total = filter:EvaluateObjects()
if total > 0 then
local cipherDC = EffectDC():Make_Chest(0)
for i=0,total-1 do
local card = filter:GetNthEvaluatedObject(i)
if card ~= nil then
cipherDC:Set_CardPtr(0, card)
end
end
end
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local browser = EffectDC():Get_Chest(0)
local player = EffectController()
if player ~= nil then
if browser ~= nil then
player:SetTargetCount( 1 )
player:SetTargetPrompt( 0, "CARD_QUERY_CHOOSE_CARD_TO_PLAY" )
player:ChooseTargetsFromDCWithFlags( NO_VALIDATION, browser, EffectDC():Make_Targets(1), QUERY_FLAG_CAN_BE_FINISHED_EARLY + QUERY_FLAG_CAN_BE_FINISHED_EARLY_FOR_AI_AS_WELL )
end
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
if EffectDC():Get_Targets(1) ~= nil then
local target = EffectDC():Get_Targets(1):Get_CardPtr(0)
if target ~= nil then
if target:CanBePlayed(EffectController()) then
EffectController():CopySpellAndCastIt( target )
end
end
end
</RESOLUTION_TIME_ACTION>
</TRIGGERED_ABILITY>
-
sumomole - Programmer
- Posts: 611
- Joined: 07 Jun 2011, 08:34
- Has thanked: 51 times
- Been thanked: 234 times
Re: [DotP2013] Help with Cipher
by BETenner » 18 Mar 2013, 15:32
It's easier to implement with "CreateDelayedTrigger", the result actually the same as the ruling. If you want to be more real, you can grant a "fake" static ability (just has text) to the encoded creature so that you can read "Whenever this creature deals combat damage to a player, you may copy the ciphered card and you may cast the copy without paying its mana cost." on the creature card.
Re: [DotP2013] Help with Cipher
by thefiremind » 29 Mar 2013, 12:12
That's not entirely true. Being a granted ability means that Snakeform, for example, can shut it down.BETenner wrote:It's easier to implement with "CreateDelayedTrigger", the result actually the same as the ruling.
I started from sumomole's idea and tried to simplify the code as much as I could, this is the result on Last Thoughts:
- Code: Select all
<?xml version='1.0' encoding='UTF-8'?>
<CARD_V2>
<FILENAME text="LAST_THOUGHTS_366407" />
<CARDNAME text="LAST_THOUGHTS" />
<TITLE>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Last Thoughts]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Dernières pensées]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Últimos pensamientos]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Letzter Gedanken]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Ultimi Pensieri]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[最後の思考]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[마지막 생각]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Последние Мысли]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Últimos Pensamentos]]></LOCALISED_TEXT>
</TITLE>
<MULTIVERSEID value="366407" />
<ARTID value="A366407" />
<ARTIST name="Peter Mohrbacher" />
<CASTING_COST cost="{3}{U}" />
<TYPE metaname="Sorcery" />
<EXPANSION value="GTC" />
<RARITY metaname="C" />
<SPELL_ABILITY>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Piochez une carte.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Roba una carta.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Ziehe eine Karte.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Pesca una carta.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[カードを1枚引く。]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[카드 한 장을 뽑는다.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Возьмите карту.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Compre um card.]]></LOCALISED_TEXT>
<RESOLUTION_TIME_ACTION>
EffectController():DrawCard()
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
<SPELL_ABILITY>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Cipher]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Cryptage]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Cifrar.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Chiffrieren]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Cifrare]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[暗号]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[암호문]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Шифр]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Cifrar]]></LOCALISED_TEXT>
<RESOLUTION_TIME_ACTION>
if EffectSource():GetErstwhileZone() ~= ZONE_CEASED_TO_EXIST then
local player = EffectController()
local filter = Object():GetFilter()
filter:Clear()
filter:NotTargetted()
filter:May()
filter:SetZone( ZONE_IN_PLAY )
filter:AddCardType( CARD_TYPE_CREATURE )
filter:SetPlayer( player )
filter:SetHint( HINT_ALLIED, player )
if filter:CountStopAt(1) == 1 then
player:ChooseTarget( NO_VALIDATION, "CARD_QUERY_CHOOSE_CREATURE_YOU_CONTROL", EffectDC():Make_Targets(3) )
end
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local creature = EffectDC():Get_Targets(3) and EffectDC():Get_Targets(3):Get_CardPtr(0)
if creature ~= nil then
EffectDC():Protect_CardPtr( COMPARTMENT_ID_EFFECT_SOURCE )
EffectSource():RemoveFromGame()
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local creature = EffectDC():Get_Targets(3) and EffectDC():Get_Targets(3):Get_CardPtr(0)
if creature ~= nil then
local source = EffectSource()
if source ~= nil then
source:NailOnto(creature)
end
end
</RESOLUTION_TIME_ACTION>
<CONTINUOUS_ACTION layer="6">
local creature = EffectDC():Get_Targets(3) and EffectDC():Get_Targets(3):Get_CardPtr(0)
if creature ~= nil then
creature:GetCurrentCharacteristics():GrantAbility(1)
end
</CONTINUOUS_ACTION>
<DURATION>
return EffectSource() == nil or ( EffectDC():Get_Targets(3) and EffectDC():Get_Targets(3):Get_CardPtr(0) ) == nil
</DURATION>
</SPELL_ABILITY>
<TRIGGERED_ABILITY resource_id="1">
<TRIGGER value="CREATURE_DEALS_COMBAT_DAMAGE_TO_PLAYER" simple_qualifier="self" />
<RESOLUTION_TIME_ACTION>
local player = EffectController()
local filter = Object():GetFilter()
filter:Clear()
filter:NotTargetted()
filter:SetZone( ZONE_REMOVED_FROM_GAME )
filter:AddCardName( "LAST_THOUGHTS" )
local filter_count = filter:EvaluateObjects()
if filter_count > 0 then
local browser = EffectDC():Make_Chest(0)
browser:Set_CardPtr( 0, filter:GetNthEvaluatedObject(0) )
player:SetTargetCount( 1 )
player:SetTargetPrompt( 0, "CARD_QUERY_CHOOSE_SPELL_TO_COPY" )
player:ChooseTargetsFromDCWithFlags( NO_VALIDATION, browser, EffectDC():Make_Targets(1),
QUERY_FLAG_CAN_BE_FINISHED_EARLY + QUERY_FLAG_CAN_BE_FINISHED_EARLY_FOR_AI_AS_WELL )
end
</RESOLUTION_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local player = EffectController()
local spell = EffectDC() and EffectDC():Get_Targets(1) and EffectDC():Get_Targets(1):Get_CardPtr(0)
if spell ~= nil and spell:CanBePlayed(player) then
player:CopySpellAndCastIt(spell)
end
</RESOLUTION_TIME_ACTION>
</TRIGGERED_ABILITY>
</CARD_V2>
- Code: Select all
filter:AddCardName( "LAST_THOUGHTS" )
Incidentally, this allowed me to discover that a spell copy starts from ZONE_NOWHERE_YET but makes a zone change to ZONE_CEASED_TO_EXIST before going to the stack.
EDIT: I didn't notice it before, but the implementations of cipher before sumomole's post are using "CopySpellWithNewTargets" instead of "CopySpellAndCastIt", this is wrong.
< 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
13 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 3 guests