Board index
Programs with AI or Rules Enforcement
Magic: The Gathering - Duels of the Planeswalkers
Programming Talk



Hindering Light
Moderator: CCGHQ Admins
Hindering Light
by --Dream-- » 01 Sep 2012, 19:20
What do you guys think is the best way to code Hindering Light? I mean, the "countering a spell that targets the player or a permanent he owns" part?
Re: Hindering Light
by --Dream-- » 01 Sep 2012, 20:24
Here's what I have so far:
- Code: Select all
<?xml version='1.0'?>
<CARD_V2>
<FILENAME text="HINDERING_LIGHT_177598" />
<CARDNAME text="HINDERING_LIGHT" />
<TITLE>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
</TITLE>
<MULTIVERSEID value="177598" />
<ARTID value="177598" />
<ARTIST name="Chris Rahn" />
<CASTING_COST cost="{W}{U}" />
<FLAVOURTEXT>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
</FLAVOURTEXT>
<TYPE metaname="Instant" />
<EXPANSION value="DPG" />
<RARITY metaname="C" />
<SPELL_ABILITY filter_zone="ZONE_IN_PLAY">
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<TARGET_DEFINITION id="0">
MTG():ClearFilterMarkedObjectsInZone(ZONE_STACK)
local filter = Object():GetFilter()
filter:Clear()
filter:SetZone( ZONE_STACK )
local filter_count = filter:EvaluateObjects()
for i=0,filter_count-1 do
local candidate = filter:GetNthEvaluatedObject(i)
if candidate ~= nil then
local target_card = candidate:GetTargetCard()
local target_player = candidate:GetTargetPlayer()
if target_card ~= nil then
if target_card:GetOwner() == EffectController() then
candidate:MarkForFilter()
end
elseif target_player ~= nil then
if target_player == EffectController() then
candidate:MarkForFilter()
end
end
end
end
filter:SetMarkedObjectsOnly()
filter:SetHint( HINT_ENEMY_ONLY, EffectController() )
</TARGET_DEFINITION>
<TARGET_DETERMINATION>
return AtLeastOneTargetFromDefinition(0)
</TARGET_DETERMINATION>
<PLAY_TIME_ACTION target_choosing="1">
EffectController():ChooseTarget( 0, "CARD_QUERY_CHOOSE_SPELL_TO_COUNTER", EffectDC():Make_Targets(0) )
</PLAY_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
if EffectSource():GetTargetCard() ~= nil then
EffectSource():GetTargetCard():CounterSpell()
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
<SPELL_ABILITY>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<RESOLUTION_TIME_ACTION>
local NumCards = 1
while (NumCards > 0) do
NumCards = NumCards - 1
EffectController():DrawCard()
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
</CARD_V2>
Re: Hindering Light
by thefiremind » 01 Sep 2012, 20:57
By looking at the code for Counterspell, I see you forgot to include
filter:SetStackObjectType( STACK_OBJECT_CARD )
but even with that, this card would have problems: GetTargetCard() and GetTargetPlayer() only read target register number 0. If a card uses register number 0 for something else (a sacrifice as additional cost for example), you couldn't check it.
I'm not sure if it can be done, but maybe a possible solution could be a trigger that saves the cards that target you or a permanent you control (the code for Ashenmoor Liege could help), so that you can mark only them. Those saved cards should be deleted when they leave the stack. Not easy.
P.S.: This has nothing to do with the general functionality, but Hindering Light says "permanent you control", not "permanent you own", so you should use GetController() instead of GetOwner().
filter:SetStackObjectType( STACK_OBJECT_CARD )
but even with that, this card would have problems: GetTargetCard() and GetTargetPlayer() only read target register number 0. If a card uses register number 0 for something else (a sacrifice as additional cost for example), you couldn't check it.
I'm not sure if it can be done, but maybe a possible solution could be a trigger that saves the cards that target you or a permanent you control (the code for Ashenmoor Liege could help), so that you can mark only them. Those saved cards should be deleted when they leave the stack. Not easy.
P.S.: This has nothing to do with the general functionality, but Hindering Light says "permanent you control", not "permanent you own", so you should use GetController() instead of GetOwner().
< 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: 722 times
Re: Hindering Light
by --Dream-- » 01 Sep 2012, 21:04
Yep, even after adding the missing line it doesnt get any valid targets. I was hoping there would be an easier way than the trigger, but the code for Ashenmoor Liege or Giltspire Avenger should do the trick. Ill post back the results.thefiremind wrote:By looking at the code for Counterspell, I see you forgot to include
filter:SetStackObjectType( STACK_OBJECT_CARD )
but even with that, this card would have problems: GetTargetCard() and GetTargetPlayer() only read target register number 0. If a card uses register number 0 for something else (a sacrifice as additional cost for example), you couldn't check it.
I'm not sure if it can be done, but maybe a possible solution could be a trigger that saves the cards that target you or a permanent you control (the code for Ashenmoor Liege could help), so that you can mark only them. Those saved cards should be deleted when they leave the stack. Not easy.
P.S.: This has nothing to do with the general functionality, but Hindering Light says "permanent you control", not "permanent you own", so you should use GetController() instead of GetOwner().
Re: Hindering Light
by --Dream-- » 02 Sep 2012, 17:15
Still no luck 
Also, dont I need to check when other players and their respective permanents are targetted as well? In case someone plays a card like Chancellor of the Spires or Spelltwine and manages to cast the Hindering Light?

- Code: Select all
<?xml version='1.0'?>
<CARD_V2>
<FILENAME text="HINDERING_LIGHT_177598" />
<CARDNAME text="HINDERING_LIGHT" />
<TITLE>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Hindering Light]]></LOCALISED_TEXT>
</TITLE>
<MULTIVERSEID value="177598" />
<ARTID value="177598" />
<ARTIST name="Chris Rahn" />
<CASTING_COST cost="{W}{U}" />
<FLAVOURTEXT>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Centuries of careful practice have elevated the casting of protective spells to an art form. What little offensive magic remains on Bant stands little chance of breaching them.]]></LOCALISED_TEXT>
</FLAVOURTEXT>
<TYPE metaname="Instant" />
<EXPANSION value="DPG" />
<RARITY metaname="C" />
<TRIGGERED_ABILITY active_zone="ZONE_ANY" internal="1">
-- create chests at beginning of turn
<TRIGGER value="BEGINNING_OF_STEP">
return ( MTG():GetStep() == STEP_UPKEEP )
</TRIGGER>
<RESOLUTION_TIME_ACTION>
local nsp = MTG():GetNumberOfStartingPlayers()
for i=0,nsp-1 do
if MTG():GetNthStartingPlayer(i) ~= nil then
local chest = ObjectDC():Get_Chest(i)
if chest ~= nil then
chest:Clear()
end
ObjectDC():Make_Chest(i)
end
end
</RESOLUTION_TIME_ACTION>
</TRIGGERED_ABILITY>
<TRIGGERED_ABILITY internal="1" active_zone="ZONE_ANY">
-- make ObjectDC() undeletable
<TRIGGER value="ZONECHANGE_BEGIN" simple_qualifier="self" to_zone="ZONE_ANY" from_zone="ZONE_ANY">
if ObjectDC() ~= nil then
Object():RetainDataChest()
end
return false
</TRIGGER>
</TRIGGERED_ABILITY>
<TRIGGERED_ABILITY active_zone="ZONE_ANY" internal="1">
-- store all cards that target an object the player controls
<TRIGGER value="CARD_CONSIDERED_FOR_TARGETTING" simple_qualifier="objectyoucontrol">
return ( SecondaryObject() ~= nil and
SecondaryObject():GetZone() == ZONE_STACK and
SecondaryObject():WasCast() ~= 0 and
TriggerPlayer() ~= nil and
TriggerObject() ~= nil )
</TRIGGER>
<RESOLUTION_TIME_ACTION>
local player = TriggerPlayer()
local target = TriggerObject()
local spell = SecondaryObject()
local player_index = -1
local nsp = MTG():GetNumberOfStartingPlayers()
for i=0,nsp-1 do
if MTG():GetNthStartingPlayer(i) == player then
player_index = i
end
end
local player_chest = ObjectDC():Get_Chest(player_index)
local num_cards_so_far = player_chest:Count()
player_chest:Set_CardPtr(num_cards_so_far, spell)
</RESOLUTION_TIME_ACTION>
</TRIGGERED_ABILITY>
<TRIGGERED_ABILITY active_zone="ZONE_ANY" internal="1">
-- store all cards that target hindering lights controller
<TRIGGER value="PLAYER_CONSIDERED_FOR_TARGETTING" simple_qualifier="controller">
return ( SecondaryObject() ~= nil and
SecondaryObject():GetZone() == ZONE_STACK and
SecondaryObject():WasCast() ~= 0 and
TriggerPlayer() ~= nil )
</TRIGGER>
<RESOLUTION_TIME_ACTION>
local player = TriggerPlayer()
local spell = SecondaryObject()
local player_index = -1
local nsp = MTG():GetNumberOfStartingPlayers()
for i=0,nsp-1 do
if MTG():GetNthStartingPlayer(i) == player then
player_index = i
end
end
local player_chest = ObjectDC():Get_Chest(player_index)
local num_cards_so_far = player_chest:Count()
player_chest:Set_CardPtr(num_cards_so_far, spell)
</RESOLUTION_TIME_ACTION>
</TRIGGERED_ABILITY>
<SPELL_ABILITY dangerous="1" filter_zone="ZONE_IN_PLAY">
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Counter target spell that targets you or a permanent you control.]]></LOCALISED_TEXT>
<TARGET_DEFINITION id="0">
local player = EffectController()
local player_index = -1
local nsp = MTG():GetNumberOfStartingPlayers()
for i=0,nsp-1 do
if MTG():GetNthStartingPlayer(i) == player then
player_index = i
end
end
local player_chest = ObjectDC():Get_Chest(player_index)
local target_spells = player_chest:Count()
MTG():ClearFilterMarkedObjectsInZone( ZONE_STACK )
local filter = Object():GetFilter()
filter:Clear()
filter:SetZone( ZONE_STACK )
filter:SetStackObjectType( STACK_OBJECT_CARD )
local filter_count = filter:EvaluateObjects()
for i=0,filter_count-1 do
local candidate = filter:GetNthEvaluatedObject(i)
for j=0,target_spells-1 do
if candidate == player_chest:Get_CardPtr(j) then
candidate:MarkForFilter()
end
end
end
filter:SetMarkedObjectsOnly()
filter:SetHint( HINT_ENEMY_ONLY, EffectController() )
</TARGET_DEFINITION>
<TARGET_DETERMINATION>
return AtLeastOneTargetFromDefinition(0)
</TARGET_DETERMINATION>
<PLAY_TIME_ACTION target_choosing="1">
EffectController():ChooseTarget( 0, "CARD_QUERY_CHOOSE_SPELL_TO_COUNTER", EffectDC():Make_Targets(0) )
</PLAY_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
if EffectSource():GetTargetCard() ~= nil then
EffectSource():GetTargetCard():CounterSpell()
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
<SPELL_ABILITY>
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
<RESOLUTION_TIME_ACTION>
local NumCards = 1
while (NumCards > 0) do
NumCards = NumCards - 1
EffectController():DrawCard()
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
</CARD_V2>
Also, dont I need to check when other players and their respective permanents are targetted as well? In case someone plays a card like Chancellor of the Spires or Spelltwine and manages to cast the Hindering Light?

5 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 3 guests