Board index Programs with AI or Rules Enforcement Magic: The Gathering - Duels of the Planeswalkers Programming Talk
A function for the heroic keyword
Moderator: CCGHQ Admins
A function for the heroic keyword
by thefiremind » 21 Sep 2013, 23:58
I made a function that acts as trigger condition for the heroic keyword ("Whenever you cast a spell that targets <this>..."). Actually, it's the same principle I used for Hindering Light, and I think it's good, even if it makes an assumption about the other cards.
This is the trigger condition:
This is the function it uses:
The assumption it makes is that no modder will ever use other chests for the targets. I think it's fair enough... we won't see a spell with 101 targets that need to stay in 101 chests, and if a modder uses target chest #100 because he feels special... well, he'll need to make his own heroic function.
A possible alternative would be to use a BECAME_TARGET_OF_SPELL trigger, but then we would need to verify that the trigger didn't already consider the same spell (it wouldn't be easy to do, sumomole knows the problem very well ).
If you have other ideas, feel free to post them. If you find a weak point in my idea (other than the assumption), please warn me. In the meanwhile, I'll keep using this function and try to assemble a "heroic deck".
This is the trigger condition:
- Code: Select all
<TRIGGER value="SPELL_PLAYED" simple_qualifier="objectyoucontrol">
return TEST_IsTargetting( TriggerObject(), EffectSource() )
</TRIGGER>
This is the function it uses:
- Test_IsTargetting function | Open
- Code: Select all
TEST_IsTargetting = function(spell, ...)
-- returns true if the spell is targetting at least one of the other parameters (they can be either cards or players)
local param_count = #arg
if spell ~= nil and param_count > 0 then
local spellDC = spell:GetDataChest()
if spellDC ~= nil then
for i=0,99 do
local targetDC = spellDC:Get_NthTargets(i)
if targetDC ~= nil and targetDC:Count() > 0 then
for j=0,targetDC:Count()-1 do
local target_card = targetDC:Get_CardPtr(j)
local target_player = targetDC:Get_PlayerPtr(j)
for k=1,param_count do
local param = arg[k]
if param ~= nil and (param == target_card or param == target_player) then
return true
end
end
end
end
end
end
end
return false
end
- Variable number of parameters (read if you don't know what "..." and "arg" mean) | Open
- What you see here is an example of a Lua function with a variable number of parameters (or arguments, call them as you like most). That "..." in the function declaration means that Lua will store all the parameters (except for "spell" which is explicitly declared) in a table called "arg", which can be accessed inside the function. The indexes start from 1, and "#arg" returns their count.
The assumption it makes is that no modder will ever use other chests for the targets. I think it's fair enough... we won't see a spell with 101 targets that need to stay in 101 chests, and if a modder uses target chest #100 because he feels special... well, he'll need to make his own heroic function.
A possible alternative would be to use a BECAME_TARGET_OF_SPELL trigger, but then we would need to verify that the trigger didn't already consider the same spell (it wouldn't be easy to do, sumomole knows the problem very well ).
If you have other ideas, feel free to post them. If you find a weak point in my idea (other than the assumption), please warn me. In the meanwhile, I'll keep using this function and try to assemble a "heroic deck".
< 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: A function for the heroic keyword
by gorem2k » 22 Sep 2013, 04:57
I don't really understand why BECAME_TARGET_OF_SPELL would be a problem.
this:
this:
- Code: Select all
<TRIGGER value="BECAME_TARGET_OF_SPELL" simple_qualifier="self">
return SecondaryObject():GetController() == EffectController()
</TRIGGER>
Re: A function for the heroic keyword
by thefiremind » 22 Sep 2013, 08:38
I haven't tested it, but I'm quite positive that BECAME_TARGET_OF_SPELL will trigger twice if you target the same heroic creature twice with the same spell, for example Common Bond (which would really shine in a heroic deck by the way ). This, of course, would be wrong, because the heroic keyword is supposed to trigger when you cast a spell, so it should trigger once per spell, no matter how many times you target the same heroic creature with that.gorem2k wrote:I don't really understand why BECAME_TARGET_OF_SPELL would be a problem.
< 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: A function for the heroic keyword
by gorem2k » 22 Sep 2013, 16:36
I see. then they should have called that BECAME_TARGET_OF_SPELL_ABILITY or simply BECAME_TARGET.thefiremind wrote:I haven't tested it, but I'm quite positive that BECAME_TARGET_OF_SPELL will trigger twice if you target the same heroic creature twice with the same spell, for example Common Bond (which would really shine in a heroic deck by the way ). This, of course, would be wrong, because the heroic keyword is supposed to trigger when you cast a spell, so it should trigger once per spell, no matter how many times you target the same heroic creature with that.gorem2k wrote:I don't really understand why BECAME_TARGET_OF_SPELL would be a problem.
EDIT: tested Common Bond and you're right, it trigger twice.
Re: A function for the heroic keyword
by sumomole » 24 Sep 2013, 16:21
I guess if you usegorem2k wrote:EDIT: tested Common Bond and you're right, it trigger twice.
- Code: Select all
<TARGET tag="CARD_QUERY_CHOOSE_CREATURE_TO_GET_PLUS1_PLUS1_COUNTER" definition="0" compartment="0" count="1" />
<TARGET tag="CARD_QUERY_CHOOSE_CREATURE_TO_GET_PLUS1_PLUS1_COUNTER" definition="1" compartment="1" count="1" />
- Code: Select all
<TARGET tag="CARD_QUERY_CHOOSE_CREATURE_TO_GET_PLUS1_PLUS1_COUNTER" definition="0" compartment="0" count="2" counter_assignment="1" />
-
sumomole - Programmer
- Posts: 611
- Joined: 07 Jun 2011, 08:34
- Has thanked: 51 times
- Been thanked: 234 times
Re: A function for the heroic keyword
by thefiremind » 24 Sep 2013, 18:03
I don't know if I would go against some other rule by coding it like that: I can't think of anything right now, but I guess there must be a reason why they didn't word it as "Distribute two +1/+1 counters among any number of target creatures". However I noticed that the Japanese localised text is worded differently: the 2 abilities have different text (but I can't really be sure about what they say, Google Translate does a very poor job on them ).sumomole wrote:if you use, it will be triggered only once.
- Code: Select all
<TARGET tag="CARD_QUERY_CHOOSE_CREATURE_TO_GET_PLUS1_PLUS1_COUNTER" definition="0" compartment="0" count="2" counter_assignment="1" />
And what about Seeds of Strength? It doesn't give counters, so I don't know if I can use counter_assignment as well.
< 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: A function for the heroic keyword
by BlindWillow » 24 Sep 2013, 22:44
Can't we check in the trigger to see if the same card is being considered as SecondaryObject()?
This seems to work from some initial testing:
This seems to work from some initial testing:
- Code: Select all
<TRIGGER value="BECAME_TARGET_OF_SPELL" simple_qualifier="self">
if SecondaryObject() ~= EffectDC():Get_CardPtr(0) then
EffectDC():Set_CardPtr( 0, SecondaryObject() )
return SecondaryObject():GetController() == EffectController()
end
</TRIGGER>
- BlindWillow
- Posts: 213
- Joined: 19 Jul 2012, 00:26
- Has thanked: 11 times
- Been thanked: 46 times
Re: A function for the heroic keyword
by thefiremind » 24 Sep 2013, 23:05
I don't know how it could possibly work by using EffectDC, since two different triggering instances won't share it. LinkedDC works for that matter, but for heroic you would still need to check if the spell has been cast: a copy that is not cast shouldn't trigger heroic. You could add a check for WasCast, but I still think that my code is safer for heroic. The basic idea behind your code is OK for Wild Defiance and Livewire Lash, though: in fact, that's more or less how I coded those 2 cards.BlindWillow wrote:Can't we check in the trigger to see if the same card is being considered as SecondaryObject()?
This seems to work from some initial testing:
- Code: Select all
<TRIGGER value="BECAME_TARGET_OF_SPELL" simple_qualifier="self">
if SecondaryObject() ~= EffectDC():Get_CardPtr(0) then
EffectDC():Set_CardPtr( 0, SecondaryObject() )
return SecondaryObject():GetController() == EffectController()
end
</TRIGGER>
< 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: A function for the heroic keyword
by BlindWillow » 24 Sep 2013, 23:30
I think it only seemed to work because I had forgotten to consider sumomole's point above. I was testing with Flames of the Firebrand, and of course, it doesn't target the same creature repeatedly. Thanks for the info about EffectDC() too. I had suspected that to be the case, but sometimes I'd code something that would seem to suggest otherwise. Now I can stop trying to go that route with other weird triggers like Phylactery Lich, for instance.
- BlindWillow
- Posts: 213
- Joined: 19 Jul 2012, 00:26
- Has thanked: 11 times
- Been thanked: 46 times
Re: A function for the heroic keyword
by RiiakShiNal » 25 Sep 2013, 00:17
The Japanese version of Common Bond says "Target one creature and target one creature. On the first put a +1/+1 counter, on the second put a +1/+1 counter." If you convert it so that it reads better in English you basically have the original English card.thefiremind wrote:I don't know if I would go against some other rule by coding it like that: I can't think of anything right now, but I guess there must be a reason why they didn't word it as "Distribute two +1/+1 counters among any number of target creatures". However I noticed that the Japanese localised text is worded differently: the 2 abilities have different text (but I can't really be sure about what they say, Google Translate does a very poor job on them ).sumomole wrote:if you use, it will be triggered only once.
- Code: Select all
<TARGET tag="CARD_QUERY_CHOOSE_CREATURE_TO_GET_PLUS1_PLUS1_COUNTER" definition="0" compartment="0" count="2" counter_assignment="1" />
And what about Seeds of Strength? It doesn't give counters, so I don't know if I can use counter_assignment as well.
Well, I guess my Japanese finally paid off.
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: A function for the heroic keyword
by GrovyleXShinyCelebi » 25 Sep 2013, 01:53
Aw, I wish Spanish and Chinese were as cool as Japanese...RiiakShiNal wrote:The Japanese version of Common Bond says "Target one creature and target one creature. On the first put a +1/+1 counter, on the second put a +1/+1 counter." If you convert it so that it reads better in English you basically have the original English card.thefiremind wrote:I don't know if I would go against some other rule by coding it like that: I can't think of anything right now, but I guess there must be a reason why they didn't word it as "Distribute two +1/+1 counters among any number of target creatures". However I noticed that the Japanese localised text is worded differently: the 2 abilities have different text (but I can't really be sure about what they say, Google Translate does a very poor job on them ).sumomole wrote:if you use, it will be triggered only once.
- Code: Select all
<TARGET tag="CARD_QUERY_CHOOSE_CREATURE_TO_GET_PLUS1_PLUS1_COUNTER" definition="0" compartment="0" count="2" counter_assignment="1" />
And what about Seeds of Strength? It doesn't give counters, so I don't know if I can use counter_assignment as well.
Well, I guess my Japanese finally paid off.
Anyways, I'm wondering, what would be the issue of writing the function like this:
- Code: Select all
TEST_IsTargetting = function(spell, source)
-- returns true if the spell is targetting at least one of the other parameters (they can be either cards or players
if spell ~= nil and source ~= nil then
local spellDC = spell:GetDataChest()
if spellDC ~= nil then
for i=0,99 do
local targetDC = spellDC:Get_NthTargets(i)
if targetDC ~= nil and targetDC:Count() > 0 then
for j=0,targetDC:Count()-1 do
local target_card = targetDC:Get_CardPtr(j)
local target_player = targetDC:Get_PlayerPtr(j)
if (source == target_card or source == target_player) then
return true
end
end
end
end
end
end
return false
(in Duels 2014)
Duels 2012: viewtopic.php?f=109&t=12152
Duels 2013: viewtopic.php?f=109&t=12481&p=137458#p137458
Duels 2012: viewtopic.php?f=109&t=12152
Duels 2013: viewtopic.php?f=109&t=12481&p=137458#p137458
-
GrovyleXShinyCelebi - Posts: 294
- Joined: 12 Jun 2013, 18:23
- Has thanked: 14 times
- Been thanked: 37 times
Re: A function for the heroic keyword
by MC Brodie » 25 Sep 2013, 02:26
Everyone in here needs to stop bragging. I barely know English and it's my first language...
-----------------------------------------------------------------------
Song of the Day: 46 and 2 (cover)
Song of the Day: 46 and 2 (cover)
Re: A function for the heroic keyword
by gorem2k » 25 Sep 2013, 02:54
the only problem I have with adding more compliant functions is , they eat more computer resources; my Pentium G850 is getting close to 100% CPU load when I have 2 planeswalkers + manual mana + hundreds of functions! I'm planning to upgrade but I need to find the money first
Re: A function for the heroic keyword
by GrovyleXShinyCelebi » 25 Sep 2013, 03:00
Really? I thought most functions took up very little space, and most of the data in a mod came from the art files. That said I have several mods and DOTP in total only takes up 2-3 GB in my PC. It turned out most of my used space was from backup copies of Starcraft IIgorem2k wrote:the only problem I have with adding more compliant functions is , they eat more computer resources; my Pentium G850 is getting close to 100% CPU load when I have 2 planeswalkers + manual mana + hundreds of functions! I'm planning to upgrade but I need to find the money first
(in Duels 2014)
Duels 2012: viewtopic.php?f=109&t=12152
Duels 2013: viewtopic.php?f=109&t=12481&p=137458#p137458
Duels 2012: viewtopic.php?f=109&t=12152
Duels 2013: viewtopic.php?f=109&t=12481&p=137458#p137458
-
GrovyleXShinyCelebi - Posts: 294
- Joined: 12 Jun 2013, 18:23
- Has thanked: 14 times
- Been thanked: 37 times
Re: A function for the heroic keyword
by gorem2k » 25 Sep 2013, 03:21
yeah, I'm not talking about RAM usage nor Hard Disk storage. but the number CPU cycles DotP has to do.GrovyleXShinyCelebi wrote:Really? I thought most functions took up very little space, and most of the data in a mod came from the art files. That said I have several mods and DOTP in total only takes up 2-3 GB in my PC.
add 999 billion "for i=0, 99 do" inside another loop then you will understand what I mean by that
20 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 7 guests