Card Development Questions
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
Re: Card Development Questions
by swordshine » 08 Jul 2013, 13:23
Yep, combat in Forge has changed a lot. We need fix that.Sloth wrote:We actually need three triggers:
1. One that triggers only once per attacker (currently "AttackerBlocked"). Example: Alley Grifters.
2. One that triggers for each pair of attacker-blocker (currently "Blocks"). Example: No Quarter, Righteous Indignation.
3. One that triggers only once per blocker (a new trigger?). Example: Lairwatch Giant.
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Re: Card Development Questions
by jsv » 08 Jul 2013, 13:30
Well, that's what happens currently. After my fix the entire script looks like this:swordshine wrote:These two scripts are different. "T:Mode$ Blocks" should only trigger once when it blocks any creatures (Lairwatch Giant and Guardian of the Gateless), this was implemented by ArsenalNut during GTC spoiler season. "T:Mode$ AttackerBlocked" should trigger multiple times for each blocking creature. I have not tested if these scripts are still working as supposed.
- Code: Select all
Name:Tolarian Entrancer
ManaCost:1 U
Types:Creature Human Wizard
PT:1/1
T:Mode$ Blocks | ValidCard$ Creature | ValidBlocked$ Card.Self | DelayedTrigger$ DelTrig | TriggerDescription$ Whenever CARDNAME becomes blocked by a creature, gain control of that creature at end of combat.
SVar:DelTrig:Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigGainControl | TriggerDescription$ Gain control of blocking creature.
SVar:TrigGainControl:AB$ GainControl | Cost$ 0 | Defined$ TriggeredBlocker | NewController$ TriggeredAttackerController
SVar:Picture:http://www.wizards.com/global/images/magic/general/tolarian_entrancer.jpg
Oracle:Whenever Tolarian Entrancer becomes blocked by a creature, gain control of that creature at end of combat.
Previous version:
- Code: Select all
Name:Tolarian Entrancer
ManaCost:1 U
Types:Creature Human Wizard
PT:1/1
T:Mode$ AttackerBlocked | ValidCard$ Card.Self | ValidBlocker$ Creature | DelayedTrigger$ DelTrig | TriggerDescription$ Whenever CARDNAME becomes blocked by a creature, gain control of that creature at end of combat.
SVar:DelTrig:Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigGainControl | TriggerDescription$ Gain control of blocking creature.
SVar:TrigGainControl:AB$ GainControl | Cost$ 0 | Defined$ TriggeredBlocker | NewController$ TriggeredAttackerController
SVar:Picture:http://www.wizards.com/global/images/magic/general/tolarian_entrancer.jpg
Oracle:Whenever Tolarian Entrancer becomes blocked by a creature, gain control of that creature at end of combat.
Guess that's not the way things are supposed to work, but there is no reason to revert my patch just yet.

Re: Card Development Questions
by swordshine » 08 Jul 2013, 13:42
In current version, both Lairwatch Giant and Guardian of the Gateless trigger once when blocks, but it's weird to assign the damage. I chose damage order twice and dealt damage twice.
My test:1) I cast a Lairwatch Giant and Gideon Jura, gave ai two Abbey Matron.
2) Activated Gideon Jura, force ai to attack.
3) When Lairwatch Giant blocks two Abbey Matron, I chose damage order twice and assigned damage twice.
4) Both Abbey Matron died in FirstStrike step (Lairwatch Giant is 5/3 with First Strike, and Abbey Matron is 1/3).
My test:1) I cast a Lairwatch Giant and Gideon Jura, gave ai two Abbey Matron.
2) Activated Gideon Jura, force ai to attack.
3) When Lairwatch Giant blocks two Abbey Matron, I chose damage order twice and assigned damage twice.
4) Both Abbey Matron died in FirstStrike step (Lairwatch Giant is 5/3 with First Strike, and Abbey Matron is 1/3).
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Re: Card Development Questions
by Sloth » 08 Jul 2013, 14:07
No, your fix sets it right: Tolarian Entrancer has to use a "Blocks" trigger and not an "AttackerBlocked" trigger.jsv wrote:Guess that's not the way things are supposed to work, but there is no reason to revert my patch just yet.
There was still something broken with the TriggeringObjects of AttackerBlocked, but Tolarian Entrancer shouldn't have worked the way it was scripted.
You are right the "Blocks" trigger triggers only once per blocker, but this also means that Righteous Indignation does not work correctly with creatures blocking more than one attacker.swordshine wrote:In current version, both Lairwatch Giant and Guardian of the Gateless trigger once when blocks, ...
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Card Development Questions
by friarsol » 08 Jul 2013, 14:35
I believe the problem is when Max flattened the Blockers->AttackingBand HashMap, he didn't account for Blockers being able to appear in more than one AttackingBand object in getAllBlockers().swordshine wrote:but it's weird to assign the damage. I chose damage order twice and dealt damage twice.
My test:1) I cast a Lairwatch Giant and Gideon Jura, gave ai two Abbey Matron.
2) Activated Gideon Jura, force ai to attack.
3) When Lairwatch Giant blocks two Abbey Matron, I chose damage order twice and assigned damage twice.
4) Both Abbey Matron died in FirstStrike step (Lairwatch Giant is 5/3 with First Strike, and Abbey Matron is 1/3).
Not at a machine that can commit, but I believe getAllBlockers() should be accumulating a Set<Card> which then gets converted to a List before it returns.
I believe this was in Combat.java
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by swordshine » 28 Jul 2013, 07:50
A question about Gilded Drake: I'm thinking of adding a param "CantFizzle" for this card in MagicStack.hasFizzled, around Line 698, in order to make this card not to be counted by rules(if the targed card is destroyed, this etb ability should be resolved and Gilded Drake should be sacrificed as a result).
if (sa.hasParam("CantFizzle") {fizzle = false;}
Is that a good solution?
if (sa.hasParam("CantFizzle") {fizzle = false;}
Is that a good solution?
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Re: Card Development Questions
by Sloth » 28 Jul 2013, 10:33
I searched the comprehensive rules for other possibilities of abilities being countered by the rules, but couldn't find any.swordshine wrote:A question about Gilded Drake: I'm thinking of adding a param "CantFizzle" for this card in MagicStack.hasFizzled, around Line 698, in order to make this card not to be counted by rules(if the targed card is destroyed, this etb ability should be resolved and Gilded Drake should be sacrificed as a result).
if (sa.hasParam("CantFizzle") {fizzle = false;}
Is that a good solution?
Your solution sounds good.
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Card Development Questions
by swordshine » 01 Aug 2013, 11:02
I'm going to convert the Devour ability to a replacement effect to support Jund. Two devour ability cannot be compatible in the original code. I'll move Devour effect (a new param Devour$ True) and trigger (Kresh Avatar) to sacrifice effect. clearDevoured() will be run in GameAction.changeZone when the destination is not the Battlefield.
Is there something important missing?
Is there something important missing?
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Re: Card Development Questions
by swordshine » 01 Aug 2013, 13:39
Some preparations for Strionic Resonator: Convert some keywords to correct triggers (
including Undying, Annihilator, Persist, Cascade, Poisonous, Vanishing, Ripple, Recover, Bushido, Fading, Echo, Cumulative upkeep).
Convert wome cards to script (Celestial Mantle, Scalpelexis)
Fix some keywords (Frenzy, current script for Frency Sliver is a hacked one, the trigger should be granted to each sliver; Replicate, should be similar to Storm, the second part is a triggered ability)
Add "Amount$ All" for some cards with play effect linked with triggered ability, e.g. Elite Arcanist.
Maybe we should go through all the triggered ability with Remembered or Imprinted.
including Undying, Annihilator, Persist, Cascade, Poisonous, Vanishing, Ripple, Recover, Bushido, Fading, Echo, Cumulative upkeep).
Convert wome cards to script (Celestial Mantle, Scalpelexis)
Fix some keywords (Frenzy, current script for Frency Sliver is a hacked one, the trigger should be granted to each sliver; Replicate, should be similar to Storm, the second part is a triggered ability)
Add "Amount$ All" for some cards with play effect linked with triggered ability, e.g. Elite Arcanist.
Maybe we should go through all the triggered ability with Remembered or Imprinted.
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Re: Card Development Questions
by friarsol » 01 Aug 2013, 14:37
Specifically for Elite Arcanist and Isochron Scepter, you can cast 0-All of the cards exiled by the triggered ability (after they are copied).swordshine wrote:Some preparations for Strionic Resonator
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by swordshine » 01 Aug 2013, 14:56
I thought it could be handled by adding "Amount$ All" because they are optional effects. I copied code from TriggerHandler.runSingleTrigger to copy Elite Arcanist' s ability, however, I encountered a bug that the played card was not removed from the list in PlayEffect, weird.
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Re: Card Development Questions
by swordshine » 02 Aug 2013, 03:35
I think I've got Strionic Resonator working for many cards:
Intrinsic trigger with targets(Sun Titan)
Intrinsic trigger without targets (Primeval Titan)
Temporary trigger (Frenzy Sliver, also converted this card to AddTrigger)
Converted Celestial Mantle
Converted Annihilator, Poisonous
Set Bushido isTrigger(true)
Intrinsic trigger with targets(Sun Titan)
Intrinsic trigger without targets (Primeval Titan)
Temporary trigger (Frenzy Sliver, also converted this card to AddTrigger)
Converted Celestial Mantle
Converted Annihilator, Poisonous
Set Bushido isTrigger(true)
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Re: Card Development Questions
by swordshine » 02 Aug 2013, 12:42
OK, I've updated Playeffect and scripts for Spellbinder, Isochron Scepter, Elite Arcanist and all lands with Hideaway keyword. Now they are compatible with Strionic Resonator.
I'll do some tests and commit the changes in two days when I'm back.
Remaining keywords that are not functionized as triggers in Forge (cannot be targeted by Stifle or Strionic Resonator, should be converted):
Undying
Persist
Cascade
Vanishing
Fading
Ripple
Recover
Echo
Cumulative upkeep (this one is complicated, current code is not correct)
Replicate
Madness
Miracle
At the beginning of... sacrifice/exile/destroy
I'll do some tests and commit the changes in two days when I'm back.
Remaining keywords that are not functionized as triggers in Forge (cannot be targeted by Stifle or Strionic Resonator, should be converted):
Undying
Persist
Ripple
Cumulative upkeep (this one is complicated, current code is not correct)
Replicate
Madness
Miracle
At the beginning of... sacrifice/exile/destroy
Last edited by swordshine on 08 Aug 2013, 08:12, edited 5 times in total.
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Re: Card Development Questions
by friarsol » 02 Aug 2013, 13:13
Cascade shouldn't be too terrible. DigUntil nonLand card with CMC LT X where X = CMC of Cascading card. Remember the found Card, and then potentially cast it for free.swordshine wrote:Cascade (this one is crazy)
....
Cumulative upkeep (this one is complicated, current code is not corrent, adding counters should be part of the resolving)
I looked at Cumulative Upkeep a few months back and it was pretty atrocious. We really need a cost multiplier that just appends multiple costs together, since each Cumulative Upkeep cost is paid separately. So if you have 3 age counters on Illusionary Forces you pay U three times. But if you have Jotun Grunt with three age counters, you get to choose a different graveyard three times.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by swordshine » 04 Aug 2013, 06:53
- swordshine
- Posts: 682
- Joined: 11 Jul 2010, 02:37
- Has thanked: 116 times
- Been thanked: 87 times
Who is online
Users browsing this forum: No registered users and 59 guests