Board index Programs with AI or Rules Enforcement Magic: The Gathering - Duels of the Planeswalkers Programming Talk
FilteredCard() with independent DURATION
Moderator: CCGHQ Admins
FilteredCard() with independent DURATION
by Xander9009 » 18 Nov 2014, 18:54
I'm trying to help code a custom ability, and one of the things required is that all of the affected cards (chosen in a filter block) have a continuous ability applied to them. Upon becoming tapped for mana, the effect should end for that particular card, but it shouldn't affect the others. The cards being affected do not belong to EffectController. What's the easiest way to manage this kind of effect?
Initially, I had it using a duration that checked a LinkedDC() int, but the granted triggered ability for BECAME_TAPPED_FOR_MANA wont be able to set the int since it would be firing from a different card (I think).
I thought about using a delayed trigger upon BECAME_TAPPED_FOR_MANA, but I couldn't figure out how to make a separate delayed trigger for each FilteredCard(). I came closest with this approach, but the DURATION still exists as a single block which I think will apply to all of the cards, ending the effect on them all as soon as it's forced to end for one.
Finally, I thought about granting the SetController() ability to the affected card with the duration block included and using a linked_ability_group. This would probably work, but I can't figure out to grant an ability to SetController(), since it would still require knowing the person controlling the effect. This can be achieved with an ObjectDC, but I'm hoping to manage it without requiring any constants or otherwise risking interference.
If necessary, I'll use ObjectDC, but even so, does anyone have any advice on this?
Initially, I had it using a duration that checked a LinkedDC() int, but the granted triggered ability for BECAME_TAPPED_FOR_MANA wont be able to set the int since it would be firing from a different card (I think).
I thought about using a delayed trigger upon BECAME_TAPPED_FOR_MANA, but I couldn't figure out how to make a separate delayed trigger for each FilteredCard(). I came closest with this approach, but the DURATION still exists as a single block which I think will apply to all of the cards, ending the effect on them all as soon as it's forced to end for one.
Finally, I thought about granting the SetController() ability to the affected card with the duration block included and using a linked_ability_group. This would probably work, but I can't figure out to grant an ability to SetController(), since it would still require knowing the person controlling the effect. This can be achieved with an ObjectDC, but I'm hoping to manage it without requiring any constants or otherwise risking interference.
If necessary, I'll use ObjectDC, but even so, does anyone have any advice on this?
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
-
Xander9009 - Programmer
- Posts: 2905
- Joined: 29 Jun 2013, 07:44
- Location: Indiana, United States
- Has thanked: 121 times
- Been thanked: 445 times
Re: FilteredCard() with independent DURATION
by thefiremind » 18 Nov 2014, 19:00
Are you aware that the BECAME_TAPPED_FOR_MANA trigger doesn't work?
< 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: FilteredCard() with independent DURATION
by Xander9009 » 18 Nov 2014, 19:06
The ability filter already requires that the affected permanents use Riiak's MM functions, and his functions manually fire the trigger. Although, no, I wasn't aware that it doesn't work for normal cards (but I'm lucky, 'cause in this case, it shouldn't matter).thefiremind wrote:Are you aware that the BECAME_TAPPED_FOR_MANA trigger doesn't work?
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
-
Xander9009 - Programmer
- Posts: 2905
- Joined: 29 Jun 2013, 07:44
- Location: Indiana, United States
- Has thanked: 121 times
- Been thanked: 445 times
Re: FilteredCard() with independent DURATION
by Xander9009 » 18 Nov 2014, 19:09
Unrelated to the previous (but I'm putting it here just 'cause I don't wanna spam the forum), shouldn't it theoretically be possible to produce a set of functions for declaring constants which aren't actually constants? As in, instead of declaring a constant, you declare the constant and then call a function on the constant. That function would set the constant to the first number not yet used by the function (which would require a manager).
In this way, everyone could just call something like "MY_CONST = InitConst()" and InitConst simply returns the one more than it did the last time it was called. That would mean everyone could be very certain they're not going to declare a constant that conflicts with anyone else's, and they don't even have to bother trying to track which numbers they've used before, because it doesn't matter what the number is, so long as it doesn't change throughout the game from the first time it's called.
In this way, everyone could just call something like "MY_CONST = InitConst()" and InitConst simply returns the one more than it did the last time it was called. That would mean everyone could be very certain they're not going to declare a constant that conflicts with anyone else's, and they don't even have to bother trying to track which numbers they've used before, because it doesn't matter what the number is, so long as it doesn't change throughout the game from the first time it's called.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
-
Xander9009 - Programmer
- Posts: 2905
- Joined: 29 Jun 2013, 07:44
- Location: Indiana, United States
- Has thanked: 121 times
- Been thanked: 445 times
Re: FilteredCard() with independent DURATION
by RiiakShiNal » 19 Nov 2014, 00:42
The easiest way I can think of to do this is to put all affected cards into a LinkedDC() when the effect starts along with the total number of affected cards. The STATIC_ABILITY that applies the CONTINUOUS_ACTION would then loop through the total number of cards stored in the LinkedDC() and apply the desired effect to any CardPtr that isn't nil. In a DelayedTrigger on BECAME_TAPPED_FOR_MANA you would search through the LinkedDC() (potentially looking through all registers until you hit the total number of affected cards) looking for the one that was tapped and upon finding that register it would clear the CardPtr (either by setting it to nil explicitly or setting an int value of 0 on that register). For the DelayedTrigger you can set the clean-up to happen once all of the CardPtrs are nil.Xander9009 wrote:I'm trying to help code a custom ability, and one of the things required is that all of the affected cards (chosen in a filter block) have a continuous ability applied to them. Upon becoming tapped for mana, the effect should end for that particular card, but it shouldn't affect the others. The cards being affected do not belong to EffectController. What's the easiest way to manage this kind of effect?
Initially, I had it using a duration that checked a LinkedDC() int, but the granted triggered ability for BECAME_TAPPED_FOR_MANA wont be able to set the int since it would be firing from a different card (I think).
I thought about using a delayed trigger upon BECAME_TAPPED_FOR_MANA, but I couldn't figure out how to make a separate delayed trigger for each FilteredCard(). I came closest with this approach, but the DURATION still exists as a single block which I think will apply to all of the cards, ending the effect on them all as soon as it's forced to end for one.
Finally, I thought about granting the SetController() ability to the affected card with the duration block included and using a linked_ability_group. This would probably work, but I can't figure out to grant an ability to SetController(), since it would still require knowing the person controlling the effect. This can be achieved with an ObjectDC, but I'm hoping to manage it without requiring any constants or otherwise risking interference.
If necessary, I'll use ObjectDC, but even so, does anyone have any advice on this?
In that way once the card has been tapped for mana it is cleared from the LinkedDC() meaning it will no longer get the effect from the STATIC_ABILITY.
If you need this method to support multiple activations then you can assign each activation to use a separate chest in the LinkedDC() and have the STATIC_ABILITY loop through all of the chests that have been assigned. When a chest is emptied you can then set that register to nil and when looking for a new index to assign a chest to you look for the first register with a nil chest (which could be less than the previously set max number of chests). If you have to go beyond the previously set max number of chests you simply pick the next register create a chest there and increment the max number of chests and set that as the new max.
This probably wouldn't work right unless you link the constant with some other identifier because global variable state is not preserved between actions (meaning "MY_CONST = InitConst()" would be called for every action resulting in lots of duplicate work and eventually running out registers). You could, however, create a set of functions such that if you call GetConst("MyConstIdentifier") it would return either a previously set constant for that identifier or set a new number and assign it to that identifier even without the need for a manager. This would allow people to use descriptive constant names to get a register index which would be less likely to conflict (you could still have a conflict if 2 different modders used the same string identifier). Though it should be noted that storing and retrieving strings to then compare is generally slow and it is just better to use unique indexes and set them statically. If people prefix the IDs they use for their constants with their reserved IdBlocks then conflicts really shouldn't happen.Xander9009 wrote:Unrelated to the previous (but I'm putting it here just 'cause I don't wanna spam the forum), shouldn't it theoretically be possible to produce a set of functions for declaring constants which aren't actually constants? As in, instead of declaring a constant, you declare the constant and then call a function on the constant. That function would set the constant to the first number not yet used by the function (which would require a manager).
In this way, everyone could just call something like "MY_CONST = InitConst()" and InitConst simply returns the one more than it did the last time it was called. That would mean everyone could be very certain they're not going to declare a constant that conflicts with anyone else's, and they don't even have to bother trying to track which numbers they've used before, because it doesn't matter what the number is, so long as it doesn't change throughout the game from the first time it's called.
Example:
Person A has IdBlock 1234 reserved and Person B has IdBlock 2345 reserved and they set the indexes like this:
- Code: Select all
PERSON_A_CONST = 1234001
PERSON_B_CONST = 2345001
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: 2185
- Joined: 16 May 2011, 21:37
- Has thanked: 75 times
- Been thanked: 497 times
Re: FilteredCard() with independent DURATION
by Xander9009 » 21 Nov 2014, 17:52
Because of the complexity of this ability, we've changed how we're doing it. First up, here's the current code.
Of interest here is the first continuous action.
- Current version - not working | Open
- Code: Select all
<ACTIVATED_ABILITY>
<COST mana_cost="{0}" type="Mana" />
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[{0}:Exchange control of all cards target opponent controls with all cards you control. They gain hase. Activate this ability again to restore the permanents to their original controllers.]]></LOCALISED_TEXT>
<SFX text="GLOBAL_WARP_PLAY" />
<SFX text="GLOBAL_WARP_PLAY" />
<TARGET tag="CARD_QUERY_CHOOSE_OPPONENT" definition="0" compartment="0" count="1" />
<TARGET_DEFINITION id="0">
local filter = ClearFilter()
filter:SetFilterType( FILTER_TYPE_PLAYERS )
filter:Add( FE_TEAM, OP_NOT, EffectController():GetTeam() )
</TARGET_DEFINITION>
<RESOLUTION_TIME_ACTION>
--EffectController():DisplayMessage("A")
local ObjectDC = RSN_GetObjectDC(EffectSource(), true)
if ObjectDC ~= nil then
--EffectController():DisplayMessage("B")
local ability_active = ObjectDC:Get_Int(43322345)
if ability_active == nil then
ability_active = 0
end
if ability_active == 0 then
ObjectDC:Set_Int(43322345, 1)
ability_active = 1
--EffectController():DisplayMessage("B - 1: "..ability_active.." - "..ObjectDC:Get_Int(43322345))
else
ObjectDC:Set_Int(43322345, 0)
ability_active = 0
--EffectController():DisplayMessage("B - 0: "..ability_active.." - "..ObjectDC:Get_Int(43322345))
end
if ability_active == 1 and EffectDC():Get_Targets(0) ~= nil and EffectDC():Get_Targets(0):Get_PlayerPtr(0) ~= nil then
--EffectController():DisplayMessage("C")
local PlayerDC = EffectDC():Make_Chest(2)
local TargetDC = EffectDC():Make_Chest(3)
local target_player = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
PlayerDC:Set_PlayerPtr(0, target_player)
TargetDC:Set_PlayerPtr(0, EffectController())
local filter = ClearFilter()
filter:Add( FE_CONTROLLER, OP_IS, EffectController() )
filter:Add( FE_CARD_INSTANCE, OP_NOT, EffectSource() )
filter:SetZone( ZONE_ANYWHERE )
local filter_count = filter:EvaluateObjects()
PlayerDC:Set_Int(0, filter_count)
for i=0,filter_count-1 do
local card = filter:GetNthEvaluatedObject(i)
if card~= nil then
PlayerDC:Set_CardPtr(i, card)
end
end
filter = ClearFilter()
filter:Add( FE_CONTROLLER, OP_IS, target_player )
filter:Add( FE_CARD_INSTANCE, OP_NOT, EffectSource() )
filter:SetZone( ZONE_ANYWHERE )
filter_count = filter:EvaluateObjects()
TargetDC:Set_Int(0, filter_count)
for i=0,filter_count-1 do
local card = filter:GetNthEvaluatedObject(i)
if card~= nil then
TargetDC:Set_CardPtr(i, card)
end
end
end
end
</RESOLUTION_TIME_ACTION>
<CONTINUOUS_ACTION layer="2">
--EffectController():SetLifeTotal(20)
local ObjectDC = RSN_GetObjectDC(EffectSource())
if ObjectDC ~= nil then
--EffectController():GainLife(1)
local ability_active = ObjectDC:Get_Int(43322345)
if ability_active ~= nil and ability_active == 1 then
--EffectController():GainLife(1)
local PlayerDC = EffectDC():Get_Chest(2)
local TargetDC = EffectDC():Get_Chest(3)
if PlayerDC ~= nil and TargetDC ~= nil then
--EffectController():GainLife(1)
local PlayerCount = PlayerDC:Get_Int(0)
local TargetCount = TargetDC:Get_Int(0)
local PlayerNewController = PlayerDC:Get_PlayerPtr(0)
local TargetNewController = TargetDC:Get_PlayerPtr(0)
if PlayerCount ~= nil and TargetCount ~= nil and PlayerNewController ~= nil and TargetNewController ~= nil then
--EffectController():GainLife(1)
if PlayerCount > 0 then
--EffectController():GainLife(1)
for i = 0 , PlayerCount - 1 do
local card = TargetDC:Get_CardPtr(i)
if card ~= nil then
card:SetController(PlayerNewController)
end
end
end
if TargetCount > 0 then
EffectController():GainLife(1)
for i = 0 , TargetCount - 1 do
local card = PlayerDC:Get_CardPtr(i)
if card ~= nil then
card:SetController(TargetNewController)
end
end
end
else
EffectController():SetLifeTotal(20)
if PlayerCount == nil then
EffectController():GainLife(1)
end
if TargetCount == nil then
EffectController():GainLife(2)
end
if PlayerNewController == nil then
EffectController():GainLife(4)
end
if TargetNewController == nil then
EffectController():GainLife(8)
end
end
end
end
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="6">
local ObjectDC = RSN_GetObjectDC(EffectSource())
if ObjectDC ~= nil then
local ability_active = ObjectDC:Get_Int(43322345)
if ability_active ~= nil and ability_active == 1 then
local PlayerDC = EffectDC():Get_Chest(2)
local TargetDC = EffectDC():Get_Chest(3)
if PlayerDC ~= nil and TargetDC ~= nil then
local PlayerCount = PlayerDC:Get_Int(0)
local TargetCount = TargetDC:Get_Int(0)
local PlayerNewController = PlayerDC:Get_PlayerPtr(0)
local TargetNewController = TargetDC:Get_PlayerPtr(0)
if PlayerCount ~= nil and TargetCount ~= nil and PlayerNewController ~= nil and TargetNewController ~= nil then
if PlayerCount > 0 then
for i = 0 , PlayerCount - 1 do
local card = TargetDC:Get_CardPtr(i)
if card ~= nil then
local characteristics = card:GetCurrentCharacteristics()
characteristics:Bool_Set( CHARACTERISTIC_HASTE, 1 )
end
end
end
if TargetCount > 0 then
for i = 0 , TargetCount - 1 do
card = PlayerDC:Get_CardPtr(i)
if card ~= nil then
local characteristics = card:GetCurrentCharacteristics()
characteristics:Bool_Set( CHARACTERISTIC_HASTE, 1 )
end
end
end
end
end
end
end
</CONTINUOUS_ACTION>
<DURATION>
local ObjectDC = RSN_GetObjectDC(EffectSource())
local PlayerDC = EffectDC():Get_Chest(2)
local TargetDC = EffectDC():Get_Chest(3)
if EffectSource() ~= nil and ObjectDC ~= nil and PlayerDC ~= nil and TargetDC~= nil then
local ability_active = ObjectDC:Get_Int(43322345)
local PlayerNewController = PlayerDC:Get_PlayerPtr(0)
local TargetNewController = TargetDC:Get_PlayerPtr(0)
if ability_active ~= nil and ability_active == 1 and PlayerNewController ~= nil and TargetNewController ~= nil then
return true
end
end
return false
</DURATION>
</ACTIVATED_ABILITY>
Of interest here is the first continuous action.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
-
Xander9009 - Programmer
- Posts: 2905
- Joined: 29 Jun 2013, 07:44
- Location: Indiana, United States
- Has thanked: 121 times
- Been thanked: 445 times
Re: FilteredCard() with independent DURATION
by NeoAnderson » 21 Nov 2014, 18:01
Xander but you are trying to code this ability :Xander9009 wrote:Because of the complexity of this ability, we've changed how we're doing it. First up, here's the current code.
First up, the unindented lines are debug lines. They'll be removed when it's working. They're just there to let me know how far the code gets before failing. The first set of debug lines, the ones that print letters, prints all of the letters and the variables there are what they should be. The next section (at the beginning of the continuous action) gives me 23 life, telling me this check fails "if PlayerCount ~= nil and TargetCount ~= nil and PlayerNewController ~= nil and TargetNewController ~= nil then". The last set of debug code gives me 32 life, telling me PlayerNewController and TargetNewController are both nil. They're both stored from within the preceding RESOLUTION_TIME_ACTION, and the pointer which gets stored in TargetNewController is checked against nil before being stored (and the code continues after that, so it wasn't nil and should have worked). Anyone have any ideas?
Of interest here is the first continuous action.
"Exchange control of all cards target opponent controls with all cards you control. They gain haste. Activate this ability again to restore the permanents to their original controllers" ???
Because falleangle asks to me about this ability and i have coded it for him :
Here you can find the code you are looking for :
- Exchange control ability | Open
- Code: Select all
<ACTIVATED_ABILITY linked_ability_group="1" >
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[{0}:Exchange control of all cards target opponent controls with all cards you control. They gain haste. Activate this ability again to restore the permanents to their original controlers.]]></LOCALISED_TEXT>
<COST type="Generic">
<PREREQUISITE>
return true
</PREREQUISITE>
<PLAY_TIME_ACTION>
if LinkedDC():Get_Int(20) ~= 2 then
LinkedDC():Set_Int(20, 2)
else
LinkedDC():Set_Int(20, 1)
end
</PLAY_TIME_ACTION>
</COST>
<COST mana_cost="{0}" type="Mana" />
<SFX text="GLOBAL_WARP_PLAY" />
<TARGET tag="CARD_QUERY_CHOOSE_A_PLAYER_TO_TARGET" definition="0" compartment="0" count="1" />
<TARGET_DEFINITION id="0">
local filter = ClearFilter()
filter:SetFilterType( FILTER_TYPE_PLAYERS )
filter:Add( FE_TEAM, OP_NOT, EffectController():GetTeam() )
</TARGET_DEFINITION>
<FILTER filter_id="1">
local target_player = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
local filter = ClearFilter()
filter:Add( FE_CONTROLLER, OP_IS, target_player )
local subfilter = filter:AddSubFilter_Or()
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_ARTIFACT )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_CREATURE )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_ENCHANTMENT )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_LAND )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_PLANESWALKER )
</FILTER>
<FILTER filter_id="0">
local filter = ClearFilter()
filter:Add( FE_CONTROLLER, OP_IS, EffectController())
filter:Add( FE_CARD_INSTANCE, OP_NOT, EffectSource() )
local subfilter = filter:AddSubFilter_Or()
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_ARTIFACT )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_CREATURE )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_ENCHANTMENT )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_LAND )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_PLANESWALKER )
</FILTER>
<CONTINUOUS_ACTION layer="2" filter_id="0">
local targetPlayer = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
if targetPlayer ~= nil then
FilteredCard():SetController( targetPlayer )
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="2" filter_id="1">
if EffectController() ~= nil then
FilteredCard():SetController( EffectController() )
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="6" filter_id="0">
if FilteredCard() ~= nil then
if FilteredCard():GetCardType():Test( CARD_TYPE_CREATURE ) then
local characteristics = FilteredCard():GetCurrentCharacteristics()
characteristics:Bool_Set( CHARACTERISTIC_HASTE, 1 )
end
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="6" filter_id="1">
if FilteredCard() ~= nil then
if FilteredCard():GetCardType():Test( CARD_TYPE_CREATURE ) then
local characteristics = FilteredCard():GetCurrentCharacteristics()
characteristics:Bool_Set( CHARACTERISTIC_HASTE, 1 )
end
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="8" filter_id="0">
if FilteredCard() ~= nil then
local characteristics = FilteredCard():GetCurrentCharacteristics()
characteristics:AI_SetWorthless()
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="8" filter_id="1">
if FilteredCard() ~= nil then
local characteristics = FilteredCard():GetCurrentCharacteristics()
characteristics:AI_SetWorthless()
end
</CONTINUOUS_ACTION>
<DURATION>
return LinkedDC():Get_Int(20) == 1
</DURATION>
</ACTIVATED_ABILITY>
- Code: Select all
filter:Add( FE_CARD_INSTANCE, OP_NOT, EffectSource() )
Hope is what you are looking for.Obviously i have presumed you guys where talking of permanents onto battlefield.
Last edited by NeoAnderson on 21 Nov 2014, 18:22, edited 1 time in total.
- NeoAnderson
- Posts: 914
- Joined: 10 Sep 2013, 07:49
- Has thanked: 18 times
- Been thanked: 139 times
Re: FilteredCard() with independent DURATION
by Xander9009 » 21 Nov 2014, 18:20
I thought about doing it that way (since it's the simple way) but I didn't know how well it would work with the filters affecting multiple cards, all changing controllers. Anyway, I have no idea if the source should change control, but the ability text doesn't say 'other' so I didn't exclude it. And yeah, it's for fallenangel. However, I think the main thing about our conversation has been that I havent' been writing the code, I've been telling him how to write it. It's just that it got this point and now I don't know why those two things are returning nil.NeoAnderson wrote:Xander but you are trying to code this ability :Xander9009 wrote:Because of the complexity of this ability, we've changed how we're doing it. First up, here's the current code.
First up, the unindented lines are debug lines. They'll be removed when it's working. They're just there to let me know how far the code gets before failing. The first set of debug lines, the ones that print letters, prints all of the letters and the variables there are what they should be. The next section (at the beginning of the continuous action) gives me 23 life, telling me this check fails "if PlayerCount ~= nil and TargetCount ~= nil and PlayerNewController ~= nil and TargetNewController ~= nil then". The last set of debug code gives me 32 life, telling me PlayerNewController and TargetNewController are both nil. They're both stored from within the preceding RESOLUTION_TIME_ACTION, and the pointer which gets stored in TargetNewController is checked against nil before being stored (and the code continues after that, so it wasn't nil and should have worked). Anyone have any ideas?
Of interest here is the first continuous action.
"Exchange control of all cards target opponent controls with all cards you control. They gain haste. Activate this ability again to restore the permanents to their original controllers" ???
Because falleangle asks to me about this ability and i have coded it for him :
Here you can find the code you are looking for :Honestly i haven't understand if you want that also the card with this ability is exchanged, so now the code avoid that the card with this ability change controller but if you want to exchange also this card you have just to remove the line:
- Exchange control ability | Open
- Code: Select all
<ACTIVATED_ABILITY linked_ability_group="1" >
<LOCALISED_TEXT LanguageCode="en-US"><![CDATA[{0}:Exchange control of all cards target opponent controls with all cards you control. They gain haste. Activate this ability again to restore the permanents to their original controllers.]]></LOCALISED_TEXT>
<COST type="Generic">
<PREREQUISITE>
return true
</PREREQUISITE>
<PLAY_TIME_ACTION>
if LinkedDC():Get_Int(20) ~= 2 then
LinkedDC():Set_Int(20, 2)
else
LinkedDC():Set_Int(20, 1)
end
</PLAY_TIME_ACTION>
</COST>
<COST mana_cost="{0}" type="Mana" />
<SFX text="GLOBAL_WARP_PLAY" />
<TARGET tag="CARD_QUERY_CHOOSE_A_PLAYER_TO_TARGET" definition="0" compartment="0" count="1" />
<TARGET_DEFINITION id="0">
local filter = ClearFilter()
filter:SetFilterType( FILTER_TYPE_PLAYERS )
filter:Add( FE_TEAM, OP_NOT, EffectController():GetTeam() )
</TARGET_DEFINITION>
<FILTER filter_id="1">
local target_player = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
local filter = ClearFilter()
filter:Add( FE_CONTROLLER, OP_IS, target_player )
local subfilter = filter:AddSubFilter_Or()
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_ARTIFACT )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_CREATURE )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_ENCHANTMENT )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_LAND )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_PLANESWALKER )
</FILTER>
<FILTER filter_id="0">
local filter = ClearFilter()
filter:Add( FE_CONTROLLER, OP_IS, EffectController())
filter:Add( FE_CARD_INSTANCE, OP_NOT, EffectSource() )
local subfilter = filter:AddSubFilter_Or()
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_ARTIFACT )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_CREATURE )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_ENCHANTMENT )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_LAND )
subfilter:Add( FE_TYPE, OP_IS, CARD_TYPE_PLANESWALKER )
</FILTER>
<CONTINUOUS_ACTION layer="2" filter_id="0">
local targetPlayer = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
if targetPlayer ~= nil then
FilteredCard():SetController( targetPlayer )
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="2" filter_id="1">
if EffectController() ~= nil then
FilteredCard():SetController( EffectController() )
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="6" filter_id="0">
if FilteredCard() ~= nil then
if FilteredCard():GetCardType():Test( CARD_TYPE_CREATURE ) then
local characteristics = FilteredCard():GetCurrentCharacteristics()
characteristics:Bool_Set( CHARACTERISTIC_HASTE, 1 )
end
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="6" filter_id="1">
if FilteredCard() ~= nil then
if FilteredCard():GetCardType():Test( CARD_TYPE_CREATURE ) then
local characteristics = FilteredCard():GetCurrentCharacteristics()
characteristics:Bool_Set( CHARACTERISTIC_HASTE, 1 )
end
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="8" filter_id="0">
if FilteredCard() ~= nil then
local characteristics = FilteredCard():GetCurrentCharacteristics()
characteristics:AI_SetWorthless()
end
</CONTINUOUS_ACTION>
<CONTINUOUS_ACTION layer="8" filter_id="1">
if FilteredCard() ~= nil then
local characteristics = FilteredCard():GetCurrentCharacteristics()
characteristics:AI_SetWorthless()
end
</CONTINUOUS_ACTION>
<DURATION>
return LinkedDC():Get_Int(20) == 1
</DURATION>
</ACTIVATED_ABILITY>inside the filter_id="0" block.
- Code: Select all
filter:Add( FE_CARD_INSTANCE, OP_NOT, EffectSource() )
Hope is what you are looking for.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
-
Xander9009 - Programmer
- Posts: 2905
- Joined: 29 Jun 2013, 07:44
- Location: Indiana, United States
- Has thanked: 121 times
- Been thanked: 445 times
Re: FilteredCard() with independent DURATION
by NeoAnderson » 21 Nov 2014, 18:25
Obviously i have presumed that you guys were talking of permanents onto battlefield.
If is not so i don't think you can exchange control of something into library or other zones.
If is not so i don't think you can exchange control of something into library or other zones.
- NeoAnderson
- Posts: 914
- Joined: 10 Sep 2013, 07:49
- Has thanked: 18 times
- Been thanked: 139 times
Re: FilteredCard() with independent DURATION
by Xander9009 » 21 Nov 2014, 18:37
Thank you. I didn't catch that. I also didn't catch that he'd in fact included the exclusion. I'll leave in the exclusion, but the ability text will need to have 'other' added to it. Either way, I was also assuming he was talking about cards on the battlefield. I just didn't catch the distinction. I'm still curious why those two variables would be nil, though...NeoAnderson wrote:Obviously i have presumed that you guys were talking of permanents onto battlefield.
If is not so i don't think you can exchange control of something into library or other zones.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
-
Xander9009 - Programmer
- Posts: 2905
- Joined: 29 Jun 2013, 07:44
- Location: Indiana, United States
- Has thanked: 121 times
- Been thanked: 445 times
10 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 42 guests