It is currently 29 Oct 2025, 17:52
   
Text Size

Implementing new Ability Factories and Card Support Code

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 27 Nov 2012, 17:09

I have several questions related to the Nafs Asp implementation:

1. Can anyone please direct me to the right place where the Nafs Asp script above actually deals damage (no sound is playing there, I want to make sure the proper event is generated) and where the Nafs Asp effect card actually goes away (I'd like to add a sound event for that, too).
2. I was thinking of adding the AI for Nafs Asp along the lines of: 1) if there is enough mana to pay for the ability effect during the player's turn, do it on player's M2 phase (so that all the lands are untapped during the AI's turn again); 2) if there's not enough mana to pay for the damaging effect in player's M2, pay for it during the AI's upkeep phase. Would this be sufficient?
3. If 2 is sufficient, what would be the proper files/routines to look for to link a code like that? I tried looking up the phase code but couldn't even find where the Main2 routines for the AI are supposed to fire by digging from PhaseHandler.java... also, I'm not sure where the AI pays its upkeep costs - is that best linked in the upkeep phase code itself in forge.game.phase.Upkeep (probably not) or is it better to link that to something in forge.game.player.AIPlayer or forge.game.player.ComputerAIGeneral?

Thank you very much in advance for your advice!

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Implementing new Ability Factories and Card Support Code

Postby moomarc » 27 Nov 2012, 17:15

Agetian wrote:I have several questions related to the Nafs Asp implementation:

1. Can anyone please direct me to the right place where the Nafs Asp script above actually deals damage (no sound is playing there, I want to make sure the proper event is generated) and where the Nafs Asp effect card actually goes away (I'd like to add a sound event for that, too).
2. I was thinking of adding the AI for Nafs Asp along the lines of: 1) if there is enough mana to pay for the ability effect during the player's turn, do it on player's M2 phase (so that all the lands are untapped during the AI's turn again); 2) if there's not enough mana to pay for the damaging effect in player's M2, pay for it during the AI's upkeep phase. Would this be sufficient?
3. If 2 is sufficient, what would be the proper files/routines to look for to link a code like that? I tried looking up the phase code but couldn't even find where the Main2 routines for the AI are supposed to fire by digging from PhaseHandler.java... also, I'm not sure where the AI pays its upkeep costs - is that best linked in the upkeep phase code itself in forge.game.phase.Upkeep (probably not) or is it better to link that to something in forge.game.player.AIPlayer or forge.game.player.ComputerAIGeneral?

Thank you very much in advance for your advice!

- Agetian
1 - The delayed "damage" is actually a straightforward loselife. So probably check the life modifying code (can't remember exactly where that is offhand). When the effect disappears, it is linked to changezone exile. I think that was in GameAction.
2 - Sounds like the right solution to me
3 - Beyond my ability to help
-Marc
User avatar
moomarc
Pixel Commander
 
Posts: 2091
Joined: 04 Jun 2010, 15:22
Location: Johannesburg, South Africa
Has thanked: 371 times
Been thanked: 372 times

Re: Implementing new Ability Factories and Card Support Code

Postby friarsol » 27 Nov 2012, 17:20

Agetian wrote:2. I was thinking of adding the AI for Nafs Asp along the lines of: 1) if there is enough mana to pay for the ability effect during the player's turn, do it on player's M2 phase (so that all the lands are untapped during the AI's turn again); 2) if there's not enough mana to pay for the damaging effect in player's M2, pay for it during the AI's upkeep phase. Would this be sufficient?
I would think the right timing to pay for it is during the Discard Phase right before the AI would untap. Other cards that use a similar AI are called something like "Reusable" or something. This is when the AI activates Prodigal Sorcerer and friends to make sure they still do damage but don't do it too early.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 27 Nov 2012, 17:37

Thanks for your advice!
Yep, I agree that the Discard Phase is good timing to pay for it, as long as the AI has mana - if the AI has no mana, probably the upkeep phase should be the phase to pay, right?

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Implementing new Ability Factories and Card Support Code

Postby Sloth » 27 Nov 2012, 21:37

Agetian wrote:Thanks for your advice!
Yep, I agree that the Discard Phase is good timing to pay for it, as long as the AI has mana - if the AI has no mana, probably the upkeep phase should be the phase to pay, right?

- Agetian
Don't make it complicated. Add the parameter "AILogic$ Always" to the script and check for it in the canPlayAI function in ChangeZoneAI to always return true. Finished.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 28 Nov 2012, 03:43

That's nice, Sloth, thanks so much for the valuable tip, I'll implement it ASAP!

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 28 Nov 2012, 05:20

Sloth wrote:Don't make it complicated. Add the parameter "AILogic$ Always" to the script and check for it in the canPlayAI function in ChangeZoneAI to always return true. Finished.
For some reason it doesn't work this way... I'm probably adding things to the wrong place or something, but... I added the following lines to the canPlayAI method of ChangeZoneAi:

Code: Select all
        if (sa.hasParam("AILogic")) {
            System.out.println("HERE");
            if (sa.getParam("AILogic").equals("Always")) {
                return true;
            }
        }
The line "HERE" is never printed to the console, so apparently this check is never made or always fails because AILogic$ Always is added to the wrong place. Here's the current Nafs Asp script:

Code: Select all
Name:Nafs Asp
ManaCost:G
Types:Creature Snake
Text:no text
PT:1/1
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ NafsEffect | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals damage to a player, that player loses 1 life at the beginning of his or her next draw step unless he or she pays 1 before that draw step.
SVar:NafsEffect:AB$ Effect | Cost$ 0 | Name$ Nafs Effect | EffectOwner$ TriggeredTarget | Duration$ Permanent | Triggers$ DrawTrig | Abilities$ PayUp | SVars$ Bleed,ExileEffect
SVar:DrawTrig:Mode$ Phase | Phase$ Draw | ValidPlayer$ You | TriggerZones$ Command | Execute$ Bleed | TriggerDescription$ You lose 1 life at the beginning of your next draw step unless you pay 1 before that draw step.
SVar:Bleed:AB$ LoseLife | Cost$ 0 | Defined$ You | LifeAmount$ 1 | SubAbility$ ExileEffect
SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
SVar:PayUp:AB$ ChangeZone | Cost$ 1 | Defined$ Self | Origin$ Command | Destination$ Exile | Static$ True | AILogic$ Always | SpellDescription$ Pay 1 to remove this effect.
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/nafs_asp.jpg
SetInfo:4ED|Common|http://magiccards.info/scans/en/4e/148.jpg
SetInfo:ARN|Common|http://magiccards.info/scans/en/an/36.jpg|2
Oracle:Whenever Nafs Asp deals damage to a player, that player loses 1 life at the beginning of his or her next draw step unless he or she pays {1} before that draw step.
End
I tried adding the AILogic$ Always line to the PayUp SVar, to the Bleed SVar, to the ExileEffect, as well as to the T:Mode$ line, but the check is never fired (or never succeeds) anyway. Can you please tell me what I'm doing wrong?

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Implementing new Ability Factories and Card Support Code

Postby moomarc » 28 Nov 2012, 07:28

Agetian wrote:
Sloth wrote:Don't make it complicated. Add the parameter "AILogic$ Always" to the script and check for it in the canPlayAI function in ChangeZoneAI to always return true. Finished.
For some reason it doesn't work this way... I'm probably adding things to the wrong place or something, but... I added the following lines to the canPlayAI method of ChangeZoneAi:

Code: Select all
        if (sa.hasParam("AILogic")) {
            System.out.println("HERE");
            if (sa.getParam("AILogic").equals("Always")) {
                return true;
            }
        }
The line "HERE" is never printed to the console, so apparently this check is never made or always fails because AILogic$ Always is added to the wrong place. Here's the current Nafs Asp script:

Code: Select all
Name:Nafs Asp
ManaCost:G
Types:Creature Snake
Text:no text
PT:1/1
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ NafsEffect | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals damage to a player, that player loses 1 life at the beginning of his or her next draw step unless he or she pays 1 before that draw step.
SVar:NafsEffect:AB$ Effect | Cost$ 0 | Name$ Nafs Effect | EffectOwner$ TriggeredTarget | Duration$ Permanent | Triggers$ DrawTrig | Abilities$ PayUp | SVars$ Bleed,ExileEffect
SVar:DrawTrig:Mode$ Phase | Phase$ Draw | ValidPlayer$ You | TriggerZones$ Command | Execute$ Bleed | TriggerDescription$ You lose 1 life at the beginning of your next draw step unless you pay 1 before that draw step.
SVar:Bleed:AB$ LoseLife | Cost$ 0 | Defined$ You | LifeAmount$ 1 | SubAbility$ ExileEffect
SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
SVar:PayUp:AB$ ChangeZone | Cost$ 1 | Defined$ Self | Origin$ Command | Destination$ Exile | Static$ True | AILogic$ Always | SpellDescription$ Pay 1 to remove this effect.
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/nafs_asp.jpg
SetInfo:4ED|Common|http://magiccards.info/scans/en/4e/148.jpg
SetInfo:ARN|Common|http://magiccards.info/scans/en/an/36.jpg|2
Oracle:Whenever Nafs Asp deals damage to a player, that player loses 1 life at the beginning of his or her next draw step unless he or she pays {1} before that draw step.
End
I tried adding the AILogic$ Always line to the PayUp SVar, to the Bleed SVar, to the ExileEffect, as well as to the T:Mode$ line, but the check is never fired (or never succeeds) anyway. Can you please tell me what I'm doing wrong?

- Agetian
My guess is that you tried after the Vanguard branch was merged, so you need to add "ActivationZone$ Command" to the PayUp ability (that should be the only line with AILogic). You can also optionally add "TriggerZones$ Command" to the TrigDraw line. Doesn't really make a difference though.
-Marc
User avatar
moomarc
Pixel Commander
 
Posts: 2091
Joined: 04 Jun 2010, 15:22
Location: Johannesburg, South Africa
Has thanked: 371 times
Been thanked: 372 times

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 28 Nov 2012, 13:38

Oh, that's interesting, I'll give it a shot! Thanks a lot, Moomarc!

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 28 Nov 2012, 13:46

Yay, it works. Submitted to SVN. :) Thanks to everyone involved for help!

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 30 Nov 2012, 15:51

OK, now that the new version is released, I think I'll experiment a bit with my original idea of implementing chained "Unless" costs. I looked at the code again and I'd probably need a bit more clarification here:

1) I found the payCostDuringAbilityResolve method, and I see the costs that require inputs in the end of the method. There is apparently only one cost that must remain by then, at least according to the current code, am I right? I mean, I'm looking at the following:

Code: Select all
if (remainingParts.size() > 1) {
            throw new RuntimeException("GameActionUtil::payCostDuringAbilityResolve - Too many payment types - " + source);
        }
        costPart = remainingParts.get(0);
As far as I can understand, that part has to go and instead, all the calls must be moved up to the main loop which goes like this:

Code: Select all
for (CostPart part : parts) {
...
}
With that in mind, am I correct that each of the input cost constructors (e.g. InputPayReturnCost) must accept something like an extra parameter that would pass the next input after the current one, and unless it is null, it's going to call the next input, etc. etc. until there are no more inputs and the parameter is set to null?

I've read Max's suggested solution above as well, but I'm not sure how InputSelectManyCards can help here - should it replace the calls to e.g. InputPayReturnCost etc.? I'm afraid I'm not quite certain how it's supposed to work in the end... Any clarification would be highly welcome.

Thanks a lot in advance for any help.

- Agetian

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Implementing new Ability Factories and Card Support Code

Postby friarsol » 30 Nov 2012, 16:25

Agetian wrote:OK, now that the new version is released, I think I'll experiment a bit with my original idea of implementing chained "Unless" costs. I looked at the code again and I'd probably need a bit more clarification here:
Was this for combining cards like Propaganda with other cards with attack costs? Or something else? If it was for attack costs, I think the way I'd try to handle it is to merge all required costs into a new single cost and then just pass that into the appropriate function.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 30 Nov 2012, 16:32

Yeah, it was exactly for Propaganda and other similar cards and attack costs. Interesting, but currently all the costs have their own distinct type and each cost, as far as I can see, kind of "handles itself" in its own class, wouldn't combining calls to all of them together in one class be more or less the same as what payCostDuringAbilityResolve currently does? (it serves as the function that tries to take care of all the individual components of the cost in one place)

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Implementing new Ability Factories and Card Support Code

Postby friarsol » 30 Nov 2012, 16:40

Agetian wrote:Yeah, it was exactly for Propaganda and other similar cards and attack costs. Interesting, but currently all the costs have their own distinct type and each cost, as far as I can see, kind of "handles itself" in its own class, wouldn't combining calls to all of them together in one class be more or less the same as what payCostDuringAbilityResolve currently does? (it serves as the function that tries to take care of all the individual components of the cost in one place)
Oh I just looked in CombatUtil.checkPropagandaEffects() and all of the costs are already combined and then passed in wholesale to payCostDuringAbilityResolve(). I think this is the right way to do it for Attacking. Since you may not be able to "Undo" if you only pay like half the costs and each cost was handled separately. Plus it's nice to know how much in advance each attacker is going to cost to attack, as opposed to "Ok pay 2" "Ok now sac a land" etc
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Implementing new Ability Factories and Card Support Code

Postby Agetian » 30 Nov 2012, 16:48

Right, it's already passed completely to payCostDuringAbilityResolve, the problems start inside payCostDuringAbilityResolve when, closer to the end of it, certain calls are executed outside of the chain because they require input on behalf of the user and, as such, happen "delayed"... So, that's where the change must be made, but I'm afraid I can't quite grasp the essence of the change yet (at least outside of what I've outlined above). :\

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 16 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 16 users online :: 0 registered, 0 hidden and 16 guests (based on users active over the past 10 minutes)
Most users ever online was 9298 on 10 Oct 2025, 12:54

Users browsing this forum: No registered users and 16 guests

Login Form