Board index Programs with AI or Rules Enforcement Magic: The Gathering - Duels of the Planeswalkers Programming Talk
Good example for counters management: Hex Parasite
Moderator: CCGHQ Admins
Good example for counters management: Hex Parasite
by thefiremind » 15 Jul 2012, 12:10
I thought it could be useful for someone to see my freshly coded Hex Parasite, as an example of how to manage any type of counter.
Here's the code for the ability:
The "core" of the ability consists in 2 repeat loops: if the target is on my side, I try to remove "bad" counters first and "good" ones afterwards, otherwise I do the opposite. Finally, I save the value of "i" (which has been incremented each time I removed a counter) and add it to the creature's power.
If someone wonders why I explicitly put all permanent types in the filter, it's because I don't want invisible tokens to get in the way. We have no way to select something invisible, but I'm not sure about the AI.
I still have to decide what to write as query string, so CARD_QUERY_CHOOSE_PERMANENT is just a placeholder.
In the attachment you can find the complete code and the illustration (it wasn't so quick to find it hi-res, so take it from there and save a couple of minutes googling).
Here's the code for the ability:
- Code: Select all
<ACTIVATED_ABILITY dangerous="1" filter_zone="ZONE_IN_PLAY">
<COST type="Mana" cost="{X}{B/P}" />
<TARGET_DEFINITION id="0">
if EffectController():IsAI() ~= 0 then
MTG():ClearFilterMarkedObjectsInZone( ZONE_IN_PLAY )
end
local filter = Object():GetFilter()
filter:Clear()
filter:AddCardType( CARD_TYPE_ARTIFACT )
filter:AddCardType( CARD_TYPE_ENCHANTMENT )
filter:AddCardType( CARD_TYPE_LAND )
filter:AddCardType( CARD_TYPE_CREATURE )
filter:AddCardType( CARD_TYPE_PLANESWALKER )
filter:SetZone( ZONE_IN_PLAY )
if EffectController():IsAI() ~= 0 then
local filter_count = filter:EvaluateObjects()
for i=0,filter_count-1 do
local candidate = filter:GetNthEvaluatedObject(i)
if candidate:GetBestOrWorstCounterType(1) ~= 0 or candidate:GetBestOrWorstCounterType(0) ~= 0 then
candidate:MarkForFilter()
end
end
filter:SetMarkedObjectsOnly()
end
filter:SetHint( HINT_NEUTRAL, EffectController() )
</TARGET_DEFINITION>
<TARGET_DETERMINATION>
return AtLeastOneTargetFromDefinition(0)
</TARGET_DETERMINATION>
<PLAY_TIME_ACTION target_choosing="1">
EffectController():ChooseTarget( 0, "CARD_QUERY_CHOOSE_PERMANENT", EffectDC():Make_Targets(0) )
</PLAY_TIME_ACTION>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(0):Get_CardPtr(0)
local max_counters = GetEffectX()
local i = 0
if target ~= nil and target:GetZone() == ZONE_IN_PLAY and max_counters > 0 then
local counter_type = 0
local friend = 0
if target:GetPlayer():GetTeam() == EffectController():GetTeam() then
friend = 1
end
repeat
counter_type = target:GetBestOrWorstCounterType(1-friend)
if i < max_counters and counter_type ~= 0 then
target:RemoveCounters( counter_type, 1 )
i = i+1
end
until i == max_counters or counter_type == 0
repeat
counter_type = target:GetBestOrWorstCounterType(friend)
if i < max_counters and counter_type ~= 0 then
target:RemoveCounters( counter_type, 1 )
i = i+1
end
until i == max_counters or counter_type == 0
end
EffectDC():Set_Int(1, i)
</RESOLUTION_TIME_ACTION>
<CONTINUOUS_ACTION layer="7C">
local power = EffectDC():Get_Int(1)
if EffectSource() ~= nil and power > 0 then
EffectSource():GetCurrentCharacteristics():Power_Add( power )
end
</CONTINUOUS_ACTION>
<DURATION simple_duration="UntilEOT" />
<AI_AVAILABILITY type="in_response" />
<AI_AVAILABILITY type="in_response_dangerous" />
<AI_AVAILABILITY step="declare_blockers" />
</ACTIVATED_ABILITY>
The "core" of the ability consists in 2 repeat loops: if the target is on my side, I try to remove "bad" counters first and "good" ones afterwards, otherwise I do the opposite. Finally, I save the value of "i" (which has been incremented each time I removed a counter) and add it to the creature's power.
If someone wonders why I explicitly put all permanent types in the filter, it's because I don't want invisible tokens to get in the way. We have no way to select something invisible, but I'm not sure about the AI.
I still have to decide what to write as query string, so CARD_QUERY_CHOOSE_PERMANENT is just a placeholder.
In the attachment you can find the complete code and the illustration (it wasn't so quick to find it hi-res, so take it from there and save a couple of minutes googling).
- Attachments
-
- HEX_PARASITE_218008.zip
- Hex Parasite code + illustration
- (112.4 KiB) Downloaded 205 times
< 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
1 post
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 18 guests