It is currently 10 May 2025, 06:03
   
Text Size

Hindering Light

Moderator: CCGHQ Admins

Hindering Light

Postby --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?
--Dream--
 
Posts: 65
Joined: 28 Jul 2012, 12:01
Has thanked: 4 times
Been thanked: 0 time

Re: Hindering Light

Postby --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 &gt; 0) do
         NumCards = NumCards - 1
         EffectController():DrawCard()
      end
    </RESOLUTION_TIME_ACTION>
  </SPELL_ABILITY>
</CARD_V2>
It doesnt seem to get any targets.
--Dream--
 
Posts: 65
Joined: 28 Jul 2012, 12:01
Has thanked: 4 times
Been thanked: 0 time

Re: Hindering Light

Postby 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().
< 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: Hindering Light

Postby --Dream-- » 01 Sep 2012, 21:04

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().
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.
--Dream--
 
Posts: 65
Joined: 28 Jul 2012, 12:01
Has thanked: 4 times
Been thanked: 0 time

Re: Hindering Light

Postby --Dream-- » 02 Sep 2012, 17:15

Still no luck :(

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 &gt; 0) do
         NumCards = NumCards - 1
         EffectController():DrawCard()
      end
    </RESOLUTION_TIME_ACTION>
  </SPELL_ABILITY>
</CARD_V2>
So basically I'm making a chest that stores all the cards that target Hindering Light's controller or a card that player controls. Then the spell ability checks what spells in the stack are also in the chest... it should work, right?

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? :?
--Dream--
 
Posts: 65
Joined: 28 Jul 2012, 12:01
Has thanked: 4 times
Been thanked: 0 time


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