diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index d1292b334..8c6e08358 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -30,6 +30,13 @@ power=1 toughness=1 [/card] [card] +name=AEther Flash +auto=@movedto(creature|battlefield):all(trigger) damage:2 +text=Whenever a creature enters the battlefield, Ęther Flash deals 2 damage to it. +mana={2}{R}{R} +type=Enchantment +[/card] +[card] name=AEther Mutation target=creature auto=moveTo(ownerhand) @@ -5017,6 +5024,17 @@ power=0 toughness=3 [/card] [card] +name=Bramblewood Paragon +auto=@movedto(other warrior|myBattlefield):all(trigger) counter(1/1,1) +auto=lord(creature[counter{1/1.1}]|myBattlefield) trample +text=Each other Warrior creature you control enters the battlefield with an additional +1/+1 counter on it. -- Each creature you control with a +1/+1 counter on it has trample. +mana={1}{G} +type=Creature +subtype=Elf Warrior +power=2 +toughness=2 +[/card] +[card] name=Branded Brawlers auto=aslongas(land[-tapped]|opponentBattlefield) cantattack auto=aslongas(land[-tapped]|myBattlefield) cantblock @@ -14821,6 +14839,16 @@ type=Enchantment auto={G}{G}:counter(0/0,1,Spore) target(fungus) [/card] [card] +name=Fungus Sliver +auto=@damaged(sliver):all(trigger[to]) counter(1/1) +text=All Sliver creatures have "Whenever this creature is dealt damage, put a +1/+1 counter on it." (The damage is dealt before the counter is put on.) +mana={3}{G} +type=Creature +subtype=Fungus Sliver +power=2 +toughness=2 +[/card] +[card] name=Fungusaur auto=@damaged(this):counter(1/1,1) text=Whenever Fungusaur is dealt damage, put a +1/+1 counter on it. @@ -19324,6 +19352,14 @@ type=Enchantment subtype=Aura [/card] [card] +name=In the Web of War +auto=@movedto(creature|myBattlefield):all(trigger) 2/0 ueot +auto=@movedto(creature|myBattlefield):all(trigger) haste ueot +text=Whenever a creature enters the battlefield under your control, it gets +2/+0 and gains haste until end of turn. +mana={3}{R}{R} +type=Enchantment +[/card] +[card] name=Incendiary target=creature auto=@each my upkeep:counter(0/0,1,Fuse) @@ -20562,6 +20598,17 @@ power=1 toughness=1 [/card] [card] +name=Juniper Order Ranger +auto=@movedto(other creature|myBattlefield):counter(1/1,1) +auto=@movedto(other creature|myBattlefield):all(trigger) counter(1/1) +text=Whenever another creature enters the battlefield under your control, put a +1/+1 counter on that creature and a +1/+1 counter on Juniper Order Ranger. +mana={3}{G}{W} +type=Creature +subtype=Human Knight +power=2 +toughness=4 +[/card] +[card] name=Junk Diver abilities=flying auto=@movedTo(this|graveyard) from(battlefield):moveTo(myhand) target(other artifact|mygraveyard) @@ -25793,6 +25840,13 @@ power=* toughness=* [/card] [card] +name=Mortuary +auto=@movedTo(creature|mygraveyard) from(myBattlefield):all(trigger) moveTo(myLibrary) +text=Whenever a creature is put into your graveyard from the battlefield, put that card on top of your library. +mana={2}{B} +type=Enchantment +[/card] +[card] name=Mosquito Guard abilities=first strike autohand={1}{W}{S}:counter(1/1,1) target(creature) @@ -29700,6 +29754,16 @@ mana={2}{G} type=Instant [/card] [card] +name=Primal Forcemage +auto=@movedto(creature|myBattlefield):all(trigger) 3/3 ueot +text=Whenever another creature enters the battlefield under your control, that creature gets +3/+3 until end of turn. +mana={2}{G} +type=Creature +subtype=Elf Shaman +power=2 +toughness=2 +[/card] +[card] name=Primal Frenzy target=Creature auto=trample @@ -35556,6 +35620,17 @@ text=Simic Growth Chamber enters the battlefield tapped. -- When Simic Growth Ch type=Land [/card] [card] +name=Simic Initiate +text=Graft 1 (This creature enters the battlefield with a +1/+1 counter on it. Whenever another creature enters the battlefield, you may move a +1/+1 counter from this creature onto it.) +auto=counter(1/1) +auto=@movedto(creature|battlefield):this(counter{1/1}) all(trigger) counter(1/1) && this(counter{1/1}) counter(1/1,-1) +mana={G} +type=Creature +subtype=Human Mutant +power=0 +toughness=0 +[/card] +[card] name=Simic Ragworm auto={U}:untap text={U}: Untap Simic Ragworm. @@ -47259,4 +47334,5 @@ type=Creature subtype=Human Wizard power=1 toughness=1 -[/card] \ No newline at end of file +[/card] +########### \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index 4b976768f..9eff1eb10 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -1,7 +1,6 @@ ######################## #Generic engine features ######################## -zzz.txt generic/attacks_each_turn.txt generic/cycling.txt generic/cycling2.txt @@ -73,6 +72,7 @@ generic/wither.txt act_of_treason.txt aegis_of_the_meek.txt aether_mutation.txt +aether_flash.txt afflict.txt akron_legionnaire.txt alluring_siren.txt @@ -140,6 +140,7 @@ boggart_arsonists.txt borderland_behemoth.txt bottle_gnomes.txt bottle_gnomes2.txt +bramblewood_paragon.txt brass_man.txt brass_man_i161.txt cage_of_hands.txt @@ -216,6 +217,7 @@ farmstead.txt fastbond.txt fastbond2.txt fault_line.txt +feral_hydra.txt fire_tempest.txt fists_of_ironwood.txt flagstones.txt @@ -233,6 +235,7 @@ force_of_nature.txt force_of_nature2.txt force_of_nature3.txt fountain_of_youth.txt +fungus_sliver.txt gamble.txt gempalm_avenger.txt ghost_warden.txt @@ -278,6 +281,7 @@ iron_will_i270.txt jodahs_avenger.txt juggernaut.txt jump.txt +juniper_order_ranger.txt karns_touch_i233.txt keldon_warlord.txt keldon_warlord2.txt @@ -313,6 +317,7 @@ millstone.txt misc01.txt moat.txt mobile_fort.txt +mortuary.txt nantuko_husk.txt necrogenesis.txt Nevinyrrals_Disk.txt @@ -383,6 +388,7 @@ shock.txt shock2.txt siege_gang_commander.txt silent_arbiter.txt +simic_initiate.txt slate_of_ancestry.txt sleeper_agent.txt slith_bloodletter.txt diff --git a/projects/mtg/bin/Res/test/aether_flash.txt b/projects/mtg/bin/Res/test/aether_flash.txt new file mode 100644 index 000000000..fda89e2f3 --- /dev/null +++ b/projects/mtg/bin/Res/test/aether_flash.txt @@ -0,0 +1,16 @@ +[init] +firstmain +[player1] +inplay:Aether Flash +hand:Grizzly Bears +manapool:{G}{G} +[player2] +[do] +Grizzly Bears +[assert] +firstmain +[player1] +inplay:Aether Flash +graveyard:Grizzly Bears +[player2] +[end] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/bramblewood_paragon.txt b/projects/mtg/bin/Res/test/bramblewood_paragon.txt new file mode 100644 index 000000000..57f14b51e --- /dev/null +++ b/projects/mtg/bin/Res/test/bramblewood_paragon.txt @@ -0,0 +1,24 @@ +[init] +firstmain +[player1] +inplay:Bramblewood Paragon +hand:Goblin Chariot +manapool:{2}{R} +[player2] +inplay:Drudge Skeletons +[do] +goblin chariot +next +next +goblin chariot +next +drudge skeletons +eot +[assert] +untap +[player1] +inplay:Bramblewood Paragon,Goblin Chariot +[player2] +life:18 +graveyard:Drudge Skeletons +[end] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/feral_hydra.txt b/projects/mtg/bin/Res/test/feral_hydra.txt new file mode 100644 index 000000000..d1db67c5f --- /dev/null +++ b/projects/mtg/bin/Res/test/feral_hydra.txt @@ -0,0 +1,24 @@ +[init] +secondmain +[player1] +manapool:{5}{G} +hand:Feral Hydra +[player2] +[do] +Feral Hydra +eot +eot +next +next +next +next +next +Feral Hydra +eot +[assert] +untap +[player1] +inplay:feral hydra +[player2] +life:15 +[end] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/fungus_sliver.txt b/projects/mtg/bin/Res/test/fungus_sliver.txt new file mode 100644 index 000000000..4d832ed37 --- /dev/null +++ b/projects/mtg/bin/Res/test/fungus_sliver.txt @@ -0,0 +1,24 @@ +[init] +firstmain +[player1] +inplay:Fungus Sliver,Sliver Overlord,Fury Sliver +hand:Lightning Bolt,Resounding Thunder +manapool:{2}{R}{R} +[player2] +[do] +lightning bolt +sliver overlord +resounding thunder +fury sliver +next +next +sliver overlord +eot +[assert] +untap +[player1] +inplay:Fungus Sliver,Sliver Overlord +graveyard:Lightning bolt,resounding thunder,fury sliver +[player2] +life:12 +[end] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/juniper_order_ranger.txt b/projects/mtg/bin/Res/test/juniper_order_ranger.txt new file mode 100644 index 000000000..b7917edc6 --- /dev/null +++ b/projects/mtg/bin/Res/test/juniper_order_ranger.txt @@ -0,0 +1,26 @@ +[init] +firstmain +[player1] +inplay:Juniper Order Ranger +hand:eager cadet +manapool:{W} +[player2] +[do] +eager cadet +eot +eot +next +next +next +next +next +eager cadet +juniper order ranger +eot +[assert] +untap +[player1] +inplay:eager cadet,juniper order ranger +[player2] +life:15 +[end] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/mortuary.txt b/projects/mtg/bin/Res/test/mortuary.txt new file mode 100644 index 000000000..6b385372d --- /dev/null +++ b/projects/mtg/bin/Res/test/mortuary.txt @@ -0,0 +1,18 @@ +[init] +firstmain +[player1] +inplay:Mortuary,Raging Goblin +hand:Lightning Bolt +manapool:{R} +[player2] +[do] +lightning bolt +raging goblin +[assert] +firstmain +[player1] +inplay:Mortuary +graveyard:Lightning Bolt +library:Raging Goblin +[player2] +[end] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/simic_initiate.txt b/projects/mtg/bin/Res/test/simic_initiate.txt new file mode 100644 index 000000000..5678aa5cc --- /dev/null +++ b/projects/mtg/bin/Res/test/simic_initiate.txt @@ -0,0 +1,27 @@ +[init] +firstmain +[player1] +hand:simic initiate,grizzly bears +manapool:{G}{G}{G} +[player2] +[do] +simic initiate +grizzly bears +choice 0 +eot +eot +next +next +next +next +next +grizzly bears +eot +[assert] +untap +[player1] +inplay:grizzly bears +graveyard:simic initiate +[player2] +life:17 +[end] \ No newline at end of file diff --git a/projects/mtg/bin/daily_build/template.exe b/projects/mtg/bin/daily_build/template.exe index 06199f304..018085d65 100644 Binary files a/projects/mtg/bin/daily_build/template.exe and b/projects/mtg/bin/daily_build/template.exe differ diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index e4931684a..623079e39 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -275,13 +275,12 @@ class AAFizzler:public ActivatedAbility{ //MayAbility: May do ... -class MayAbility:public MTGAbility{ +class MayAbility:public MTGAbility, public NestedAbility{ public: int triggered; bool must; - MTGAbility * ability; MTGAbility * mClone; - MayAbility(int _id, MTGAbility * _ability, MTGCardInstance * _source, bool must = false):MTGAbility(_id,_source),must(must),ability(_ability){ + MayAbility(int _id, MTGAbility * _ability, MTGCardInstance * _source, bool must = false):MTGAbility(_id,_source),must(must),NestedAbility(_ability){ triggered = 0; mClone = NULL; } @@ -389,13 +388,12 @@ public: //Generic Activated Ability -class GenericActivatedAbility:public ActivatedAbility{ +class GenericActivatedAbility:public ActivatedAbility, public NestedAbility{ public: - MTGAbility * ability; int limitPerTurn; int counters; MTGGameZone * activeZone; - GenericActivatedAbility(int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost, int _tap = 0, int limit = 0, int restrictions = 0, MTGGameZone * dest = NULL):ActivatedAbility(_id, card,_cost,restrictions,_tap),ability(a),limitPerTurn(limit),activeZone(dest){ + GenericActivatedAbility(int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost, int _tap = 0, int limit = 0, int restrictions = 0, MTGGameZone * dest = NULL):ActivatedAbility(_id, card,_cost,restrictions,_tap),NestedAbility(a),limitPerTurn(limit),activeZone(dest){ counters = 0; target = ability->target; } @@ -1399,10 +1397,9 @@ class APowerToughnessModifierUntilEndOfTurn: public ActivatedAbility{ }; -class GenericInstantAbility: public InstantAbility{ +class GenericInstantAbility: public InstantAbility, public NestedAbility{ public: - MTGAbility * ability; - GenericInstantAbility(int _id, MTGCardInstance * _source, Damageable * _target, MTGAbility * ability): InstantAbility(_id, _source, _target), ability(ability){ + GenericInstantAbility(int _id, MTGCardInstance * _source, Damageable * _target, MTGAbility * ability): InstantAbility(_id, _source, _target), NestedAbility(ability){ ability->target = _target; } @@ -1643,13 +1640,12 @@ class AConvertLandToCreatures:public ListMaintainerAbility{ }; //Generic Kird Ape -class AAsLongAs:public ListMaintainerAbility{ +class AAsLongAs:public ListMaintainerAbility, public NestedAbility{ public: - MTGAbility * ability; MTGAbility * a; int includeSelf; int mini,maxi; - AAsLongAs(int _id, MTGCardInstance * _source, Damageable * _target, TargetChooser * _tc, int _includeSelf, MTGAbility * ability,int mini = 0, int maxi = 0):ListMaintainerAbility(_id, _source,_target),ability(ability),mini(mini),maxi(maxi){ + AAsLongAs(int _id, MTGCardInstance * _source, Damageable * _target, TargetChooser * _tc, int _includeSelf, MTGAbility * ability,int mini = 0, int maxi = 0):ListMaintainerAbility(_id, _source,_target),NestedAbility(ability),mini(mini),maxi(maxi){ tc = _tc; includeSelf = _includeSelf; tc->targetter = NULL; @@ -1731,13 +1727,12 @@ class AAsLongAs:public ListMaintainerAbility{ }; //Lords (Merfolk lord...) give power and toughness to OTHER creatures of their type, they can give them special abilities, regeneration -class ALord:public ListMaintainerAbility{ +class ALord:public ListMaintainerAbility, public NestedAbility{ public: - MTGAbility * ability; int includeSelf; map abilities; - ALord(int _id, MTGCardInstance * card, TargetChooser * _tc, int _includeSelf, MTGAbility * a):ListMaintainerAbility(_id,card), ability(a){ + ALord(int _id, MTGCardInstance * card, TargetChooser * _tc, int _includeSelf, MTGAbility * a):ListMaintainerAbility(_id,card), NestedAbility(a){ tc = _tc; tc->targetter = NULL; includeSelf = _includeSelf; @@ -1811,14 +1806,13 @@ class ALord:public ListMaintainerAbility{ //Foreach (plague rats...) -class AForeach:public ListMaintainerAbility{ +class AForeach:public ListMaintainerAbility, public NestedAbility{ public: - MTGAbility * ability; int includeSelf; int mini; int maxi; map abilities; - AForeach(int _id, MTGCardInstance * card,Damageable * _target, TargetChooser * _tc, int _includeSelf, MTGAbility * a, int mini = 0, int maxi = 0):ListMaintainerAbility(_id,card,_target), ability(a),mini(mini),maxi(maxi){ + AForeach(int _id, MTGCardInstance * card,Damageable * _target, TargetChooser * _tc, int _includeSelf, MTGAbility * a, int mini = 0, int maxi = 0):ListMaintainerAbility(_id,card,_target), NestedAbility(a),mini(mini),maxi(maxi){ tc = _tc; tc->targetter = NULL; includeSelf = _includeSelf; @@ -1877,12 +1871,11 @@ class AForeach:public ListMaintainerAbility{ }; -class AThis:public MTGAbility{ - public: - MTGAbility * ability; +class AThis:public MTGAbility, public NestedAbility{ +public: MTGAbility * a; ThisDescriptor * td; - AThis(int _id, MTGCardInstance * _source, Damageable * _target, ThisDescriptor * _td, MTGAbility * ability):MTGAbility(_id, _source,_target),ability(ability){ + AThis(int _id, MTGCardInstance * _source, Damageable * _target, ThisDescriptor * _td, MTGAbility * ability):MTGAbility(_id, _source,_target),NestedAbility(ability){ td = _td; ability->source = source; ability->target = target; @@ -1941,12 +1934,11 @@ class AThis:public MTGAbility{ } }; -class AThisForEach:public MTGAbility{ +class AThisForEach:public MTGAbility, public NestedAbility{ public: - MTGAbility * ability; ThisDescriptor * td; vector abilities; - AThisForEach(int _id, MTGCardInstance * _source, Damageable * _target, ThisDescriptor * _td, MTGAbility * ability):MTGAbility(_id, _source,_target),ability(ability){ + AThisForEach(int _id, MTGCardInstance * _source, Damageable * _target, ThisDescriptor * _td, MTGAbility * ability):MTGAbility(_id, _source,_target),NestedAbility(ability){ td = _td; ability->source = source; ability->target = target; diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index ff4ecf69b..b94bd9528 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -83,6 +83,11 @@ class MTGAbility: public ActionElement{ }; }; +class NestedAbility{ + public: + MTGAbility * ability; + NestedAbility(MTGAbility * _ability); +}; class TriggeredAbility:public MTGAbility{ public: @@ -164,9 +169,8 @@ class ActivatedAbility:public MTGAbility{ virtual ostream& toString(ostream& out) const; }; -class TargetAbility:public ActivatedAbility{ +class TargetAbility:public ActivatedAbility, public NestedAbility{ public: - MTGAbility * ability; TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); virtual int reactToClick(MTGCardInstance * card); @@ -233,16 +237,16 @@ class TriggerNextPhase:public TriggerAtPhase{ }; -class GenericTriggeredAbility:public TriggeredAbility{ +class GenericTriggeredAbility:public TriggeredAbility, public NestedAbility{ public: TriggeredAbility * t; - MTGAbility * ability; MTGAbility * destroyCondition; GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a,MTGAbility * dc = NULL, Targetable * _target = NULL); virtual int trigger(); virtual int triggerOnEvent(WEvent * e); virtual int resolve(); virtual int testDestroy(); + void setTriggerTargets(WEvent * e, MTGAbility * a); void Update(float dt); virtual GenericTriggeredAbility* clone() const; const char * getMenuText(); diff --git a/projects/mtg/include/TargetChooser.h b/projects/mtg/include/TargetChooser.h index fe3a573c1..c787f8b3c 100644 --- a/projects/mtg/include/TargetChooser.h +++ b/projects/mtg/include/TargetChooser.h @@ -53,8 +53,6 @@ class TargetChooser: public TargetsList { virtual ~TargetChooser(){}; int targetListSet(); virtual TargetChooser* clone() const = 0; - - }; @@ -166,5 +164,15 @@ class DamageTargetChooser:public TargetChooser{ virtual DamageTargetChooser * clone() const; }; +//Should only be used for triggered abilities. +class TriggerTargetChooser:public TargetChooser{ +public: + Targetable * target; + int triggerTarget; + TriggerTargetChooser(int _triggerTarget); + virtual bool targetsZone(MTGGameZone * z); + virtual bool canTarget(Targetable * _target); + virtual TriggerTargetChooser * clone() const; +}; #endif diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h index 3fc988de5..ccac7557d 100644 --- a/projects/mtg/include/WEvent.h +++ b/projects/mtg/include/WEvent.h @@ -19,10 +19,18 @@ public: DAMAGE = 2, CHANGE_PHASE = 3, }; + //for getTargets, in case event has more than one possible "target", like with damage events. + enum { + TARGET_NONE = 0, + TARGET_TO, + TARGET_FROM, + }; int type; //Deprecated, use dynamic casting instead WEvent(int type = NOT_SPECIFIED); virtual ~WEvent() {}; virtual std::ostream& toString(std::ostream& out) const; + virtual int getValue() {return 0;}; + virtual Targetable * getTarget(int target) {return 0;}; }; struct WEventZoneChange : public WEvent { @@ -32,6 +40,7 @@ struct WEventZoneChange : public WEvent { WEventZoneChange(MTGCardInstance * card, MTGGameZone * from, MTGGameZone *to); virtual ~WEventZoneChange() {}; virtual std::ostream& toString(std::ostream& out) const; + virtual Targetable * getTarget(int target); }; @@ -39,6 +48,8 @@ struct WEventDamage : public WEvent { Damage * damage; WEventDamage(Damage * damage); virtual std::ostream& toString(std::ostream& out) const; + virtual int getValue(); + virtual Targetable * getTarget(int target); }; struct WEventPhaseChange : public WEvent { @@ -67,6 +78,7 @@ struct WEventCardTap : public WEventCardUpdate { bool before; bool after; WEventCardTap(MTGCardInstance * card, bool before, bool after); + virtual Targetable * getTarget(int target); }; //Event when a card's "attacker" status changes diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 51b29acc7..8b0c6cf3f 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -223,7 +223,7 @@ MTGAbility * AbilityFactory::getCoreAbility(MTGAbility * a){ } //Parses a string and returns the corresponding MTGAbility object -// Returns NULL if parsing failed +//Returns NULL if parsing failed //Beware, Spell CAN be null when the function is called by the AI trying to analyze the effects of a given card MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTGCardInstance *card, int activated, int forceUEOT, MTGGameZone * dest){ size_t found; @@ -1805,6 +1805,10 @@ ostream& MTGAbility::toString(ostream& out) const << " ; source : " << source; } +NestedAbility::NestedAbility(MTGAbility * _ability){ + ability = _ability; +} + // ActivatedAbility::ActivatedAbility(int id, MTGCardInstance * card, ManaCost * _cost, int restrictions,int tap):MTGAbility(id,card), restrictions(restrictions), needsTapping(tap){ @@ -1893,14 +1897,12 @@ ostream& ActivatedAbility::toString(ostream& out) const } -TargetAbility::TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){ +TargetAbility::TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap), NestedAbility(NULL){ tc = _tc; - ability = NULL; } -TargetAbility::TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){ +TargetAbility::TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap), NestedAbility(NULL){ tc = NULL; - ability = NULL; } @@ -2187,10 +2189,9 @@ TriggerNextPhase* TriggerNextPhase::clone() const{ return a; } -GenericTriggeredAbility::GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a , MTGAbility * dc, Targetable * _target ): TriggeredAbility(id, _source,_target){ +GenericTriggeredAbility::GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a , MTGAbility * dc, Targetable * _target ): TriggeredAbility(id, _source,_target), NestedAbility(a){ if (!target) target = source; t = _t; - ability = a; destroyCondition = dc; t->source = source; @@ -2209,7 +2210,30 @@ int GenericTriggeredAbility::trigger(){ int GenericTriggeredAbility::triggerOnEvent(WEvent * e){ - return t->triggerOnEvent(e); + if (t->triggerOnEvent(e)) { + + setTriggerTargets(e,ability); + return 1; + } + return 0; +} + +void GenericTriggeredAbility::setTriggerTargets(WEvent * e,MTGAbility * a){ + TriggerTargetChooser * ttc = dynamic_cast(a->tc); + if (ttc) { + a->target = e->getTarget(ttc->triggerTarget); + ttc->target = e->getTarget(ttc->triggerTarget); + } + + NestedAbility * na = dynamic_cast(a); + if (na) setTriggerTargets(e,na->ability); + + MultiAbility * ma = dynamic_cast(a); + if (ma) { + for (int i = 0; i < ma->abilities.size(); i++) { + setTriggerTargets(e,ma->abilities[i]); + } + } } void GenericTriggeredAbility::Update(float dt){ diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index cf60de4ae..83f8969f8 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -5,7 +5,7 @@ #include "../include/GameObserver.h" #include "../include/Subtypes.h" #include "../include/Counters.h" - +#include "../include/WEvent.h" TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInstance * card, MTGAbility * ability){ @@ -29,6 +29,16 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta s=s.substr(6); } + found = s.find("trigger"); + if (found == 0){ + if (s.length() > 7 && s.find("[") == 7) { + string s1 = s.substr(7,s.find("]")); + if (s1.find("to") != string::npos) return NEW TriggerTargetChooser(WEvent::TARGET_TO); + if (s1.find("from") != string::npos) return NEW TriggerTargetChooser(WEvent::TARGET_FROM); + } + return NEW TriggerTargetChooser(1); + } + found = s.find("player"); if (found != string::npos){ int maxtargets = 1; @@ -761,3 +771,22 @@ bool DamageTargetChooser::canTarget(Targetable * target){ DamageTargetChooser * a = NEW DamageTargetChooser(*this); return a; } + + TriggerTargetChooser::TriggerTargetChooser(int _triggerTarget){ + triggerTarget = _triggerTarget; + target = NULL; + } + + bool TriggerTargetChooser::targetsZone(MTGGameZone * z){ + return true; + } + + bool TriggerTargetChooser::canTarget(Targetable * _target){ + if (_target == target) return true; + return false; + } + + TriggerTargetChooser * TriggerTargetChooser::clone() const{ + TriggerTargetChooser * a = NEW TriggerTargetChooser(*this); + return a; + } \ No newline at end of file diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index 46ba3a3fb..9f4198ab0 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -30,6 +30,30 @@ WEventEmptyManaPool::WEventEmptyManaPool(ManaPool * source) : WEvent(), source(s WEventCombatStepChange::WEventCombatStepChange(CombatStep step) : WEvent(), step(step) {}; +Targetable * WEventDamage::getTarget(int target) { + switch (target) { + case TARGET_TO : + return damage->target; + case TARGET_FROM : + return damage->source; + } + return NULL; +} + +int WEventDamage::getValue() { + return damage->damage; +} + +Targetable * WEventZoneChange::getTarget(int target) { + if (target) return card; + return NULL; +} + +Targetable * WEventCardTap::getTarget(int target){ + if (target) return card; + return NULL; +} + std::ostream& WEvent::toString(std::ostream& out) const { return out << "EVENT";