diff --git a/CHANGELOG.md b/CHANGELOG.md index a0357250d..87c285c28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,11 @@ ## [master] (https://github.com/WagicProject/wagic/tree/master) +### 18/11/21 +- *Committed:* Fixed primitives, fixed a commander deck for AI, improved all cards with partner ability, added a "partner=" key to associate the partner to a primitive, added new keywords "withpartner", "partname" and "haspartner" to improve the Target Chooser for cards with partner, improved the Commander rules to allow double commander just with specifc partner, improved background images management for game settings, deck selection, deck editor background, post-match credits, deck editor selection and trophies room (now it's possibile to randomly use up to 10 background images). ([Vitty85](https://github.com/Vitty85)) + ### 15/11/21 -- *Committed:* Fixed primitives, updated italian lang file, added a new setting to sort decks by creation date (by default they will be sorted by name), added new filters to match cards that don't contain a particular color or that are multicolored, fixed an issue when the transformation with uynt is triggered by instant/sorcery or by card that left the battlefield before the ability ending turn, fixed a rendering overlap on mana symbols in deck editor, fixed some crashes on ManaCost parser (e.g. Filter by mana producer). ([Vitty85](https://github.com/Vitty85)) +- *Committed:* Fixed primitives, updated italian lang file, added a new setting to sort decks by creation date (by default they will be sorted by name), added new filters to match cards that don't contain a particular color or that are multicolored, fixed an issue when the transformation with uynt is triggered by instant/sorcery or by card that left the battlefield before the ability ending turn, fixed a rendering overlap on mana symbols in deck editor, fixed some crashes on ManaCost parser (e.g. Filter by mana producer). https://github.com/WagicProject/wagic/commit/477ffa6a0ce1312d73a4a3c82145f1b71e505681 ([Vitty85](https://github.com/Vitty85)) ### 14/11/21 - *Committed:* Fixed "Mana Hellkite" and added its token primitive, fixed token in VOW set. https://github.com/WagicProject/wagic/commit/2eed51dea6339a6c835f0fe89ddfe1caa61ddf1a ([Vitty85](https://github.com/Vitty85)) diff --git a/projects/mtg/bin/Res/ai/baka/deck153.txt b/projects/mtg/bin/Res/ai/baka/deck153.txt index 1271fc2d9..bc49e872f 100644 --- a/projects/mtg/bin/Res/ai/baka/deck153.txt +++ b/projects/mtg/bin/Res/ai/baka/deck153.txt @@ -57,13 +57,13 @@ Mogg Flunkies (*) * 1 Mogg Maniac (*) * 1 Mogg Raider (*) * 1 Moggcatcher (*) * 1 -Mon's Goblin Raiders (*) * 1 +Mons's Goblin Raiders (*) * 1 Mountain (4ED) (*) * 4 Mountain (M10) (*) * 4 Mountain (ICE) (*) * 4 Mountain (M20) (*) * 4 Mountain (MIR) (*) * 4 -Mountain (LEA) (*) * 4 +Mountain (LEA) (*) * 3 Mountain (5ED) (*) * 3 Pashalik Mons (*) * 1 Prophetic Ravings (*) * 1 @@ -82,7 +82,6 @@ Sol Ring (*) * 1 Swiftfoot Boots (*) * 1 Valakut, the Molten Pinnacle (*) * 1 Vandalblast (*) * 1 -Voracious Dragon (*) * 1 Warren Instigator (*) * 1 Whispersilk Cloak (*) * 1 #CMD:Krenko, Mob Boss (*) * 1 \ No newline at end of file diff --git a/projects/mtg/bin/Res/sets/primitives/_macros.txt b/projects/mtg/bin/Res/sets/primitives/_macros.txt index 4d18b7261..f32faee43 100644 --- a/projects/mtg/bin/Res/sets/primitives/_macros.txt +++ b/projects/mtg/bin/Res/sets/primitives/_macros.txt @@ -18,6 +18,9 @@ # Training #AUTO_DEFINE _TRAINING_ @combat(attacking) source(this) restriction{trainer}:name(Training) dotrain +# Partner +#AUTO_DEFINE _PARTNER_ may name(Put partner in hand) moveto(myhand) target(*[partname]|mylibrary) + # Goad #AUTO_DEFINE _GOAD_ transforms((,newability[counter(0/0.1.Goaded)],newability[this(counter{0/0.1.Goaded}>0) mustattack],newability[phaseaction[endofturn next once sourceinplay] removeallcounters(0/0.-1.Goaded)])) forever diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index f7cd85825..cd042c2b1 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -6468,7 +6468,8 @@ toughness=3 [card] name=Blaring Captain abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(blaring recruiter|mylibrary) +partner=Blaring Recruiter +auto=_PARTNER_ auto=_ATTACKING_all(warrior[attacking]) 1/1 text=Partner with Blaring Recruiter (When this creature enters the battlefield, target player may put Blaring Recruiter into their hand from their library, then shuffle.) -- Whenever Blaring Captain attacks, attacking Warriors get +1/+1 until end of turn. mana={3}{B} @@ -6480,7 +6481,8 @@ toughness=2 [card] name=Blaring Recruiter abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(blaring captain|mylibrary) +partner=Blaring Captain +auto=_PARTNER_ auto={2}{W}:create(warrior:creature warrior:1/1:white:) text=Partner with Blaring Captain (When this creature enters the battlefield, target player may put Blaring Captain into their hand from their library, then shuffle.) -- {2}{W}: Create a 1/1 white Warrior creature token. mana={3}{W} @@ -8439,7 +8441,8 @@ type=Artifact [card] name=Brallin, Skyshark Rider abilities=hiddenface,partner -auto=may name(Put partner in hand) moveTo(myhand) target(Shabraz^ the Skyshark|mylibrary) +partner=Shabraz, the Skyshark +auto=_PARTNER_ auto=@discarded(*|myHand):all(this) counter(1/1,1) && damage:1 opponent auto={R}:target(creature[Shark]) trample ueot text=Partner with Shabraz, the Skyshark (When this creature enters the battlefield, target player may put Shabraz into their hand from their library, then shuffle.) -- Whenever you discard a card, put a +1/+1 counter on Brallin, Skyshark Rider and it deals 1 damage to each opponent. -- {R}: Target Shark gains trample until end of turn. @@ -10798,7 +10801,8 @@ type=World Enchantment [card] name=Cazur, Ruthless Stalker abilities=hiddenface,partner -auto=may name(Put partner in hand) moveTo(myhand) target(Ukkima^ Stalking Shadow|mylibrary) +partner=Ukkima, Stalking Shadow +auto=_PARTNER_ auto=@combatdamaged(player) from(creature|myBattlefield):all(trigger[from]) counter(1/1) text=Partner with Ukkima, Stalking Shadow (When this creature enters the battlefield, target player may put Ukkima into their hand from their library, then shuffle.) -- Whenever a creature you control deals combat damage to a player, put a +1/+1 counter on that creature. mana={3}{G} @@ -11151,7 +11155,8 @@ toughness=4 [card] name=Chakram Retriever abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(chakram slinger|mylibrary) +partner=Chakram Slinger +auto=_PARTNER_ auto=@movedTo(*|mystack) restriction{myturnonly}:untap target(creature) text=Partner with Chakram Slinger (When this creature enters the battlefield, target player may put Chakram Slinger into their hand from their library, then shuffle.) -- Whenever you cast a spell during your turn, untap target creature. mana={4}{U} @@ -11163,7 +11168,8 @@ toughness=4 [card] name=Chakram Slinger abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(chakram retriever|mylibrary) +partner=Chakram Retriever +auto=_PARTNER_ auto={R}{T}:damage:2 target(player) text=Partner with Chakram Retriever (When this creature enters the battlefield, target player may put Chakram Retriever into their hand from their library, then shuffle.) -- {R}, {T}: Chakram Slinger deals 2 damage to target player or planeswalker. mana={4}{R} @@ -30519,7 +30525,8 @@ toughness=3 [card] name=Gorm the Great abilities=vigilance,menace,partner -auto=may name(Put partner in hand) moveto(myhand) target(Virtus the Veiled|mylibrary) and!(shuffle)! +partner=Virtus the Veiled +auto=_PARTNER_ auto=_ATTACKING_all(creature|opponentbattlefield) mustblock ueot text=Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.) -- Vigilance -- Gorm the Great must be blocked if able, and Gorm must be blocked by two or more creatures if able. mana={3}{G} @@ -32132,9 +32139,11 @@ toughness=4 [/card] [card] name=Haldan, Avid Arcanist -abilities=hiddenface,canplayfromexile,partner -auto=may name(Put partner in hand) moveTo(myhand) target(Pako^ Arcane Retriever|mylibrary) -auto=lord(*[-creature]|mycastingzone) transforms((,newability[anytypeofmana])) +abilities=partner +partner=Pako, Arcane Retriever +auto=_PARTNER_ +auto=lord(*[-creature;counter{0/0.1.Fetch}]|myexile) transforms((,newability[canplayfromexile],newability[anytypeofmana])) +auto={0}:name(Cast opponent card) name(Cast opponent card) target(*[-creature;counter{0/0.1.Fetch}]|opponentexile) moveto(myexile) and!( transforms((,newability[counter(0/0.1.Fetch)],newability[phaseaction[endofturn once checkex] moveTo(ownerexile)],newability[phaseaction[untap once checkex] counter(0/0.1.Fetch)])) ueot )! text=Partner with Pako, Arcane Retriever (When this creature enters the battlefield, target player may put Pako into their hand from their library, then shuffle.) -- You may play noncreature cards from exile with fetch counters on them if you exiled them, and you may spend mana as though it were mana of any color to cast those spells. mana={2}{U} type=Legendary Creature @@ -35957,7 +35966,9 @@ toughness=1 [/card] [card] name=Impetuous Protege -auto=may name(Put partner on your hand) moveto(myhand) target(Proud Mentor|mylibrary) +abilities=partner +partner=Proud Mentor +auto=_PARTNER_ auto=_ATTACKING_all(this) power:highest:creature[tapped]:opponentbattlefield/0 ueot text=Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.) -- Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control. mana={2}{R} @@ -38631,7 +38642,8 @@ toughness=5 [card] name=Kamber, the Plunderer abilities=lifelink,partner -auto=may name(Put partner in hand) moveto(myhand) target(Laurine^ the Diversion|mylibrary) +partner=Laurine, the Diversion +auto=_PARTNER_ auto=@movedto(creature|graveyard) from(opponentbattlefield):name(Gain life and create blood) life:1 controller && token(Blood) text=Partner with Laurine, the Diversion (When this creature enters the battlefield, target player may put Laurine into their hand from their library, then shuffle.) -- Lifelink -- Whenever a creature an opponent controls dies, you gain 1 life and create a Blood token. (Itâ??s an artifact with â??1, Tap, Discard a card, Sacrifice this artifact: Draw a card.â??) mana={3}{B} @@ -39493,7 +39505,8 @@ toughness=3 [card] name=Khorvath Brightflame abilities=flying,haste,partner -auto=may name(Put partner in hand) moveto(myhand) target(sylvia brightspear|mylibrary) +partner=Sylvia Brightspear +auto=_PARTNER_ auto=lord(knight|myBattlefield) flying auto=lord(knight|myBattlefield) haste text=Partner with Sylvia Brightspear (When this creature enters the battlefield, target player may put Sylvia into their hand from their library, then shuffle.) -- Flying, haste -- Knights your team controls have flying and haste. @@ -40383,7 +40396,8 @@ toughness=4 [card] name=Krav, the Unredeemed abilities=partner -auto=may name(Put partner on your hand) moveto(myhand) target(Regna^ the Redeemer|mylibrary) +partner=Regna, the Redeemer +auto=_PARTNER_ auto={B}{S(creature|myBattlefield)}:name(Sacrifice 1 creature and target yourself) name(Sacrifice 1 creature and target yourself) all(this) counter(1/1,1) && life:1 controller && draw:1 controller auto={B}{S(creature|myBattlefield)}:name(Sacrifice 1 creature and target opponent) name(Sacrifice 1 creature and target opponent) all(this) counter(1/1,1) && life:1 opponent && draw:1 opponent auto={B}{S(creature|myBattlefield)}{S(creature|myBattlefield)}:name(Sacrifice 2 creatures and target yourself) name(Sacrifice 2 creatures and target yourself) all(this) counter(1/1,2) && life:2 controller && draw:2 controller @@ -41149,7 +41163,8 @@ type=Sorcery [card] name=Laurine, the Diversion abilities=first strike,partner -auto=may name(Put partner in hand) moveto(myhand) target(Kamber^ the Plunderer|mylibrary) +partner=Kamber, the Plunderer +auto=_PARTNER_ auto={2}{S(*[artifact;creature]|mybattlefield)}:name(Goad a creature) target(creature|battlefield) _GOAD_ text=Partner with Kamber, the Plunderer (When this creature enters the battlefield, target player may put Kamber into their hand from their library, then shuffle.) -- First strike -- {2}, Sacrifice an artifact or creature: Goad target creature. (Until your next turn, that creature attacks each combat if able and attacks a player other than you if able.) mana={2}{R} @@ -41739,7 +41754,8 @@ type=Artifact [card] name=Ley Weaver abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(lore weaver|mylibrary) +partner=Lore Weaver +auto=_PARTNER_ auto={T}:name(Untap 2 lands) untap target(<2>land) text=Partner with Lore Weaver (When this creature enters the battlefield, target player may put Lore Weaver into their hand from their library, then shuffle.) -- {T}: Untap two target lands. mana={3}{G} @@ -42920,7 +42936,8 @@ toughness=3 [card] name=Lore Weaver abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(ley weaver|mylibrary) +partner=Ley Weaver +auto=_PARTNER_ auto={5}{U}{U}:draw:2 target(player) text=Partner with Ley Weaver (When this creature enters the battlefield, target player may put Ley Weaver into their hand from their library, then shuffle.) -- {5}{U}{U}: Target player draws two cards. mana={3}{U} @@ -48729,7 +48746,8 @@ toughness=5 [card] name=Nikara, Lair Scavenger abilities=menace,partner -auto=may name(Put partner in hand) moveto(myhand) target(Yannik^ Scavenging Sentinel|mylibrary) +partner=Yannik, Scavenging Sentinel +auto=_PARTNER_ auto=@movedTo(other creature[counter{1/1}]|nonbattlezone) from(mybattlefield):draw:1 && life:-1 controller text=Partner with Yannik, Scavenging Sentinel (When this creature enters the battlefield, target player may put Yannik into their hand from their library, then shuffle.) -- Menace -- Whenever another creature you control leaves the battlefield, if it had one or more counters on it, you draw a card and you lose 1 life. mana={2}{B} @@ -51447,8 +51465,9 @@ toughness=2 [card] name=Pako, Arcane Retriever abilities=hiddenface,haste,partner -auto=may name(Put partner in hand) moveTo(myhand) target(Haldan^ Avid Arcanist|mylibrary) -auto=_ATTACKING_NOTCODED +partner=Haldan, Avid Arcanist +auto=_PARTNER_ +auto=@combat(attacking) source(this):name(Exile top cards) all(*[zpos=1]|library) moveto(exile) and!( counter(0/0,1,Fetch) && if cantargetcard(*[-creature]|*) then all(this) counter(1/1) )! text=Partner with Haldan, Avid Arcanist -- Haste -- Whenever Pako, Arcane Retriever attacks, exile the top card of each player's library and put a fetch counter on each of them. Put a +1/+1 counter on Pako for each noncreature card exiled this way. mana={3}{R}{G} type=Legendary Creature @@ -54554,7 +54573,8 @@ type=Artifact [card] name=Proud Mentor abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(impetuous protege|mylibrary) +partner=Impetuous Protege +auto=_PARTNER_ auto={W}{T}:tap target(creature) text=Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.) -- {W}, {T}: Tap target creature. mana={2}{W} @@ -57155,7 +57175,8 @@ type=Sorcery [card] name=Regna, the Redeemer abilities=flying,partner -auto=may name(Put partner in hand) moveto(myhand) target(krav^ the unredeemed|mylibrary) +partner=Krav, the Unredeemed +auto=_PARTNER_ auto=@each endofturn restriction{compare(lifegain)~morethan~0}:create(warrior:creature warrior:1/1:white:)*2 text=Partner with Krav, the Unredeemed (When this creature enters the battlefield, target player may put Krav into their hand from their library, then shuffle.) -- Flying -- At the beginning of each end step, if your team gained life this turn, create two 1/1 white Warrior creature tokens. mana={5}{W} @@ -58094,7 +58115,8 @@ toughness=2 [card] name=Rhoda, Geist Avenger abilities=vigilance,partner -auto=may name(Put partner in hand) moveto(myhand) target(Timin^ Youthful Geist|mylibrary) +partner=Timin, Youthful Geist +auto=_PARTNER_ auto=@tapped(creature[-attacking]|opponentbattlefield):name(Put 1/1 counter) counter(1/1) text=Partner with Timin, Youthful Geist (When this creature enters the battlefield, target player may put Timin into their hand from their library, then shuffle.) -- Vigilance -- Whenever a creature an opponent controls becomes tapped, if it isnâ??t being declared as an attacker, put a +1/+1 counter on Rhoda, Geist Avenger. mana={3}{W} @@ -63105,7 +63127,8 @@ toughness=2 [card] name=Shabraz, the Skyshark abilities=hiddenface,partner -auto=may name(Put partner in hand) moveTo(myhand) target(Brallin^ Skyshark Rider|mylibrary) +partner=Brallin, Skyshark Rider +auto=_PARTNER_ auto=@drawof(player):all(this) counter(1/1,1) && life:1 controller auto={WU}:target(creature[Human]) flying ueot text=Partner with Brallin, Skyshark Rider -- Flying -- Whenever you draw a card, put a +1/+1 counter on Shabraz, the Skyshark and you gain 1 life. -- {W/U}: Target Human gains flying until end of turn. @@ -64674,8 +64697,9 @@ type=Instant [card] name=Silvar, Devourer of the Free abilities=hiddenface,menace,partner -auto=may name(Put partner in hand) moveTo(myhand) target(Trynn^ Champion of Freedom|mylibrary) -auto={S(Human|myBattlefield)}:all(this) counter(1/1) && indestructible ueot +partner=Trynn, Champion of Freedom +auto=_PARTNER_ +auto={S(Human|myBattlefield)}:name(Put 1/1 counter) transforms((,newability[counter(1/1)],newability[indestructible])) ueot text=Partner with Trynn, Champion of Freedom (When this creature enters the battlefield, target player may put Trynn into their hand from their library, then shuffle.) -- Menace -- Sacrifice a Human: Put a +1/+1 counter on Silvar, Devourer of the Free. It gains indestructible until end of turn. mana={3}{B}{R} type=Legendary Creature @@ -67086,7 +67110,8 @@ subtype=Aura [card] name=Soulblade Corrupter abilities=deathtouch,partner -auto=may name(Put partner in hand) moveto(myhand) target(soulblade renewer|mylibrary) +partner=Soulblade Renewer +auto=_PARTNER_ auto=@combat(attacking) source(creature[counter{1/1.1}]|mybattlefield):deathtouch ueot text=Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.) -- Deathtouch -- Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn. mana={4}{B} @@ -67098,7 +67123,8 @@ toughness=3 [card] name=Soulblade Renewer abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(soulblade corrupter|mylibrary) +partner=Soulblade Corrupter +auto=_PARTNER_ auto=target(other creature|battlefield) counter(1/1) text=Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.) -- When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.) mana={4}{G} @@ -71361,8 +71387,9 @@ toughness=3 [card] name=Sylvia Brightspear abilities=double strike,partner +partner=Khorvath Brightflame +auto=_PARTNER_ auto=lord(dragon|myBattlefield) double strike -auto=may name(Put partner in hand) target(khorvath brightflame|mylibrary) moveto(myhand) and!( shuffle )! text=Partner with Khorvath Brightflame (When this creature enters the battlefield, target player may put Khorvath into their hand from their library, then shuffle.) -- Double strike -- Dragons your team controls have double strike. mana={2}{W} type=Legendary Creature @@ -74617,7 +74644,8 @@ toughness=1 [card] name=Timin, Youthful Geist abilities=flying,partner -auto=may name(Put partner in hand) moveto(myhand) target(Rhoda^ Geist Avenger|mylibrary) +partner=Rhoda, Geist Avenger +auto=_PARTNER_ auto=@each combatbegins:may name(Tap a creature) target(creature|battlefield) tap text=Partner with Rhoda, Geist Avenger (When this creature enters the battlefield, target player may put Rhoda into their hand from their library, then shuffle.) -- Flying -- At the beginning of each combat, tap up to one target creature. mana={4}{U} @@ -75105,7 +75133,8 @@ toughness=3 [card] name=Toothy, Imaginary Friend abilities=partner -auto=may name(Put partner in hand) moveto(myhand) target(pir^ imaginative rascal|mylibrary) +partner=Pir, Imaginative Rascal +auto=_PARTNER_ auto=@drawof(player):counter(1/1) auto=@movedTo(this|nonbattlezone) from(myBattlefield):thisforeach(counter{1/1,1}) draw:1 controller text=Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.) -- Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend. -- When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it. @@ -76243,8 +76272,9 @@ toughness=3 [card] name=Trynn, Champion of Freedom abilities=hiddenface,partner -aicode=may name(Put partner in hand) moveTo(myhand) target(Silvar^ Devourer of the Free|mylibrary) -auto=@each my endofturn:if raid then token(Soldier Try) +partner=Silvar, Devourer of the Free +auto=_PARTNER_ +auto=@each my endofturn restriction{compare(pattackedcount)~morethan~0}:name(Create soldier) token(Soldier Try) text=Partner with Silvar, Devourer of the Free (When this creature enters the battlefield, target player may put Silvar into their hand from their library, then shuffle.) -- At the beginning of your end step, if you attacked this turn, create a 1/1 white Human Soldier creature token. mana={3}{W} type=Legendary Creature @@ -76723,7 +76753,8 @@ toughness=0 [card] name=Ukkima, Stalking Shadow abilities=hiddenface,unblockable,partner -auto=may name(Put partner in hand) moveTo(myhand) target(Cazur^ Ruthless Stalker|mylibrary) +partner=Cazur, Ruthless Stalker +auto=_PARTNER_ auto=@movedto(this|nonbattlezone):damage:storedpower target(opponent) && life:storedpower controller text=Partner with Cazur, Ruthless Stalker (When this creature enters the battlefield, target player may put Cazur into their hand from their library, then shuffle.) -- Ukkima, Stalking Shadow can't be blocked. -- When Ukkima leaves the battlefield, it deals X damage to target player and you gain X life, where X is its power. mana={1}{U}{B} @@ -79261,7 +79292,8 @@ type=Sorcery [card] name=Virtus the Veiled abilities=deathtouch,partner -auto=may name(Put partner in hand) moveto(myhand) target(gorm the great|mylibrary) +partner=Gorm the Great +auto=_PARTNER_ auto=@combatdamaged(player) from(this):life:-halfdownopponentlifetotal opponent text=Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.) -- Deathtouch -- Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up. mana={2}{B} @@ -82730,7 +82762,8 @@ toughness=4 [card] name=Yannik, Scavenging Sentinel abilities=vigilance,partner -auto=may name(Put partner in hand) moveto(myhand) target(Nikara^ Lair Scavenger|mylibrary) +partner=Nikara, Lair Scavenger +auto=_PARTNER_ auto=if type(creature[power=0]|myBattlefield)~morethan~0 then choice name(Exile creature with power 0) name(Exile creature with power 0) (blink)forsrc target(other creature[power=0]|mybattlefield) auto=if type(creature[power=1]|myBattlefield)~morethan~0 then choice name(Exile creature with power 1) name(Exile creature with power 1) (blink)forsrc target(other creature[power=1]|mybattlefield) && ability$!name(Assign 1/1 counter) name(Assign 1/1 counter) target(creature) counter(1/1)!$ controller auto=if type(creature[power=2]|myBattlefield)~morethan~0 then choice name(Exile creature with power 2) name(Exile creature with power 2) (blink)forsrc target(other creature[power=2]|mybattlefield) && thisforeach(variable{2}) ability$!name(Assign 1/1 counter) name(Assign 1/1 counter) target(creature) counter(1/1)!$ controller diff --git a/projects/mtg/bin/Res/sets/primitives/planeswalkers.txt b/projects/mtg/bin/Res/sets/primitives/planeswalkers.txt index 505b22047..1ca96bfac 100644 --- a/projects/mtg/bin/Res/sets/primitives/planeswalkers.txt +++ b/projects/mtg/bin/Res/sets/primitives/planeswalkers.txt @@ -2350,6 +2350,7 @@ subtype=Rowan [card] name=Rowan Kenrith abilities=partner,canbecommander +partner=Will Kenrith auto=counter(0/0,4,loyalty) auto={C(0/0,2,Loyalty)}:name(+2: Opponent creatures must attack) all(creature|opponentbattlefield) mustattack ueot auto={C(0/0,2,Loyalty)}:name(+2: Your creatures must attack) all(creature|mybattlefield) mustattack ueot @@ -3173,6 +3174,7 @@ subtype=Vraska [card] name=Will Kenrith abilities=partner,canbecommander +partner=Rowan Kenrith auto=counter(0/0,4,loyalty) auto={C(0/0,2,Loyalty)}:name(+2: Up to two creatures 0/3 no abilities) target(creatures) transforms(setpower=0,settoughness=3,loseabilities) uynt auto={C(0/0,-2,Loyalty)}:name(-2: Draw two cards and cost {2} less) target(player) draw:2 targetedplayer && all(this) transforms((,newability[lord(*[instant;sorcery;planeswalker]|mycastingzone) altercost(colorless,-2)])) uynt diff --git a/projects/mtg/include/CardDescriptor.h b/projects/mtg/include/CardDescriptor.h index 4633af232..2c21b1540 100644 --- a/projects/mtg/include/CardDescriptor.h +++ b/projects/mtg/include/CardDescriptor.h @@ -48,6 +48,7 @@ class CardDescriptor: public MTGCardInstance int hasKickerCost; int hasFlashbackCost; int hasBackSide; + int hasPartner; int hasXCost; int anyCounter; int init(); @@ -56,6 +57,7 @@ class CardDescriptor: public MTGCardInstance void unsecureSetHasKickerCost(int i); void unsecureSetHasFlashbackCost(int i); void unsecureSetHasBackSide(int i); + void unsecureSetHasPartner(int i); void unsecureSetTapped(int i); void unsecuresetfresh(int k); void unsecuresetrecent(int j); diff --git a/projects/mtg/include/CardPrimitive.h b/projects/mtg/include/CardPrimitive.h index 3541f3abd..0071159fd 100644 --- a/projects/mtg/include/CardPrimitive.h +++ b/projects/mtg/include/CardPrimitive.h @@ -55,6 +55,7 @@ public: string name; string nameOrig; string backSide; + string partner; int init(); uint8_t colors; diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index eb6617abe..8372eeab5 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -25,6 +25,7 @@ CardDescriptor::CardDescriptor() hasKickerCost = 0; hasFlashbackCost = 0; hasBackSide = 0; + hasPartner = 0; hasXCost = 0; compareName =""; nameComparisonMode = COMPARISON_NONE; @@ -78,6 +79,11 @@ void CardDescriptor::unsecureSetHasBackSide(int k) hasBackSide = k; } +void CardDescriptor::unsecureSetHasPartner(int k) +{ + hasPartner = k; +} + void CardDescriptor::unsecureSetTapped(int i) { tapped = i; @@ -287,6 +293,11 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card) match = NULL; } + if ((hasPartner == -1 && card->partner != "") || (hasPartner == 1 && card->partner == "")) + { + match = NULL; + } + if ((hasXCost == -1 && card->getManaCost()->hasX()) || (hasXCost == 1 && !card->getManaCost()->hasX())) { match = NULL; diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 38e26aaeb..eeeae6a12 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -1544,6 +1544,18 @@ bool CardGui::FilterCard(MTGCard * _card,string filter) cd.unsecureSetHasBackSide(1); } } + //Has partner + else if (attribute.find("haspartner") != string::npos) + { + if (minus) + { + cd.unsecureSetHasPartner(-1); + } + else + { + cd.unsecureSetHasPartner(1); + } + } //Token else if (attribute.find("token") != string::npos) { diff --git a/projects/mtg/src/Credits.cpp b/projects/mtg/src/Credits.cpp index 7ceedcc48..e9d865f69 100644 --- a/projects/mtg/src/Credits.cpp +++ b/projects/mtg/src/Credits.cpp @@ -517,11 +517,11 @@ void Credits::Render() return; JRenderer * r = JRenderer::GetInstance(); #if !defined (PSP) - //Now it's possibile to randomly use up to 3 background images for post-match credits (if random index is 0, it will be rendered the default "bgdeckeditor.jpg" image). + //Now it's possibile to randomly use up to 10 background images for post-match credits (if random index is 0, it will be rendered the default "bgdeckeditor.jpg" image). JTexture * wpTex = NULL; if(kBgFile == ""){ char temp[4096]; - sprintf(temp, "bgdeckeditor%i.jpg", std::rand() % 3); + sprintf(temp, "bgdeckeditor%i.jpg", std::rand() % 10); kBgFile.assign(temp); wpTex = WResourceManager::Instance()->RetrieveTexture(kBgFile); if (wpTex) { diff --git a/projects/mtg/src/DeckEditorMenu.cpp b/projects/mtg/src/DeckEditorMenu.cpp index 08858d668..08a350af2 100644 --- a/projects/mtg/src/DeckEditorMenu.cpp +++ b/projects/mtg/src/DeckEditorMenu.cpp @@ -11,10 +11,10 @@ DeckEditorMenu::DeckEditorMenu(int id, JGuiListener* listener, int fontId, const DeckMenu(id, listener, fontId, _title), selectedDeck(_selectedDeck), stw(stats) { #if !defined (PSP) - //Now it's possibile to randomly use up to 3 background images for deck editor selection (if random index is 0, it will be rendered the default "menubgdeckeditor.jpg" image). + //Now it's possibile to randomly use up to 10 background images for deck editor selection (if random index is 0, it will be rendered the default "menubgdeckeditor.jpg" image). ostringstream bgFilename; char temp[4096]; - sprintf(temp, "menubgdeckeditor%i", std::rand() % 3); + sprintf(temp, "menubgdeckeditor%i", std::rand() % 10); backgroundName.assign(temp); bgFilename << backgroundName << ".jpg"; JQuadPtr background = WResourceManager::Instance()->RetrieveTempQuad(bgFilename.str(), TEXTURE_SUB_5551); diff --git a/projects/mtg/src/DeckMenu.cpp b/projects/mtg/src/DeckMenu.cpp index 510e182e0..7295755fb 100644 --- a/projects/mtg/src/DeckMenu.cpp +++ b/projects/mtg/src/DeckMenu.cpp @@ -151,7 +151,7 @@ void DeckMenu::RenderBackground() { ostringstream bgFilename; #if !defined (PSP) - if(backgroundName.find("menubgdeckeditor") != string::npos) //Now it's possibile to randomly use up to 3 background images for deck editor selection. + if(backgroundName.find("menubgdeckeditor") != string::npos) //Now it's possibile to randomly use up to 10 background images for deck editor selection. bgFilename << backgroundName << ".jpg"; else bgFilename << backgroundName << ".png"; diff --git a/projects/mtg/src/GameStateAwards.cpp b/projects/mtg/src/GameStateAwards.cpp index 6b2839af5..19b07993b 100644 --- a/projects/mtg/src/GameStateAwards.cpp +++ b/projects/mtg/src/GameStateAwards.cpp @@ -172,18 +172,17 @@ void GameStateAwards::Render() #if defined (PSP) JQuadPtr background = WResourceManager::Instance()->RetrieveTempQuad("pspawardback.jpg", TEXTURE_SUB_5551); #else - //Now it's possibile to randomly use up to 3 background images for trophies room (if random index is 0, it will be rendered the default "awardback.jpg" image). + //Now it's possibile to randomly use up to 10 background images for trophies room (if random index is 0, it will be rendered the default "awardback.jpg" image). JQuadPtr background; if(kAwardFile == ""){ char temp[4096]; - sprintf(temp, "awardback%i.jpg", std::rand() % 3); + sprintf(temp, "awardback%i.jpg", std::rand() % 10); kAwardFile.assign(temp); - JQuadPtr background = WResourceManager::Instance()->RetrieveTempQuad(kAwardFile); + JQuadPtr background = WResourceManager::Instance()->RetrieveTempQuad(kAwardFile, TEXTURE_SUB_5551); if (!background.get()) kAwardFile = "awardback.jpg"; //Fallback to default background image for trophies room. } background = WResourceManager::Instance()->RetrieveTempQuad(kAwardFile, TEXTURE_SUB_5551); - //JQuadPtr background = WResourceManager::Instance()->RetrieveTempQuad("awardback.jpg", TEXTURE_SUB_5551); #endif if (background.get()) diff --git a/projects/mtg/src/GameStateDeckViewer.cpp b/projects/mtg/src/GameStateDeckViewer.cpp index 5e70538dc..0c0df6711 100644 --- a/projects/mtg/src/GameStateDeckViewer.cpp +++ b/projects/mtg/src/GameStateDeckViewer.cpp @@ -1574,11 +1574,11 @@ void GameStateDeckViewer::Render() WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); #if !defined (PSP) - //Now it's possibile to randomly use up to 3 background images for deck editor background (if random index is 0, it will be rendered the default "bgdeckeditor.jpg" image). + //Now it's possibile to randomly use up to 10 background images for deck editor background (if random index is 0, it will be rendered the default "bgdeckeditor.jpg" image). JTexture * wpTex = NULL; if(kBgFile == ""){ char temp[4096]; - sprintf(temp, "bgdeckeditor%i.jpg", std::rand() % 3); + sprintf(temp, "bgdeckeditor%i.jpg", std::rand() % 10); kBgFile.assign(temp); wpTex = WResourceManager::Instance()->RetrieveTexture(kBgFile); if (wpTex) { diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 74cff64f5..98c035c88 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -1087,11 +1087,11 @@ void GameStateDuel::Render() JRenderer::GetInstance()->RenderQuad(wpQuad.get(), 0, 0, 0, SCREEN_WIDTH_F / wpQuad->mWidth, SCREEN_HEIGHT_F / wpQuad->mHeight); } #else - //Now it's possibile to randomly use up to 3 background images for deck selection (if random index is 0, it will be rendered the default "bgdeckeditor.jpg" image). + //Now it's possibile to randomly use up to 10 background images for deck selection (if random index is 0, it will be rendered the default "bgdeckeditor.jpg" image). JTexture * wpTex = NULL; if(kBgFile == ""){ char temp[4096]; - sprintf(temp, "bgdeckeditor%i.jpg", std::rand() % 3); + sprintf(temp, "bgdeckeditor%i.jpg", std::rand() % 10); kBgFile.assign(temp); wpTex = WResourceManager::Instance()->RetrieveTexture(kBgFile); if (wpTex) { diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index 599468e56..9e2ce34fc 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -244,11 +244,11 @@ void GameStateOptions::Render() //Erase JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); #if !defined (PSP) - //Now it's possibile to randomly use up to 3 background images for game settings (if random index is 0, it will be rendered the default "bgdeckeditor.jpg" image). + //Now it's possibile to randomly use up to 10 background images for game settings (if random index is 0, it will be rendered the default "bgdeckeditor.jpg" image). JTexture * wpTex = NULL; if(kBgFile == ""){ char temp[4096]; - sprintf(temp, "bgdeckeditor%i.jpg", std::rand() % 3); + sprintf(temp, "bgdeckeditor%i.jpg", std::rand() % 10); kBgFile.assign(temp); wpTex = WResourceManager::Instance()->RetrieveTexture(kBgFile); if (wpTex) { diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 24cd02c0b..12f9b51ab 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -75,6 +75,7 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to revealedLast = NULL; MadnessPlay = false; backSide = card->data->backSide; + partner = card->data->partner; } MTGCardInstance * MTGCardInstance::createSnapShot() @@ -142,6 +143,7 @@ void MTGCardInstance::copy(MTGCardInstance * card, bool nolegend) setText(data->text); //The text is retrieved from the data anyways setName(data->name); backSide = data->backSide; + partner = data->partner; power = data->power;//layer 7a toughness = data->toughness;//layer 7a power += pbonus;//layer 7b diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index f9c185292..af1dce120 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -314,6 +314,11 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi map::iterator it = primitives.find(val); if (it != primitives.end()) card->setPrimitive(it->second); } + else if (key[1] == 'a' && key[2] == 'r') + { //partner + if (!primitive) primitive = NEW CardPrimitive(); + primitive->partner = val; + } else { //power if (!primitive) primitive = NEW CardPrimitive(); @@ -993,7 +998,7 @@ MTGDeck::MTGDeck(const string& config_file, MTGAllCards * _allcards, int meta_on else if(CommandZone.size() == 1 && newcard->data->hasType("Legendary") && (newcard->data->hasType("Creature") || newcard->data->basicAbilities[Constants::CANBECOMMANDER])){ // If a commander has been added you can add a new one just if both have partner ability. if(newcard && newcard->data->basicAbilities[Constants::PARTNER]){ MTGCard * oldcard = database->getCardById(atoi((CommandZone.at(0)).c_str())); - if(oldcard && oldcard->data->basicAbilities[Constants::PARTNER] && oldcard->data->name != newcard->data->name) + if(oldcard && oldcard->data->basicAbilities[Constants::PARTNER] && (oldcard->data->name != newcard->data->name) && ((oldcard->data->partner == "" && newcard->data->partner == "") || (oldcard->data->partner == newcard->data->name && newcard->data->partner == oldcard->data->name))) CommandZone.push_back(s); } } @@ -1010,7 +1015,7 @@ MTGDeck::MTGDeck(const string& config_file, MTGAllCards * _allcards, int meta_on else if(CommandZone.size() == 1 && newcard->data->hasType("Legendary") && (newcard->data->hasType("Creature") || newcard->data->basicAbilities[Constants::CANBECOMMANDER])){ // If a commander has been added you can add a new one just if both have partner ability. if(newcard->data->basicAbilities[Constants::PARTNER]){ MTGCard * oldcard = database->getCardById(atoi((CommandZone.at(0)).c_str())); - if(oldcard && oldcard->data->basicAbilities[Constants::PARTNER] && oldcard->data->name != newcard->data->name) + if(oldcard && oldcard->data->basicAbilities[Constants::PARTNER] && (oldcard->data->name != newcard->data->name) && ((oldcard->data->partner == "" && newcard->data->partner == "") || (oldcard->data->partner == newcard->data->name && newcard->data->partner == oldcard->data->name))) CommandZone.push_back(str_id.str()); } } diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 7c5858f00..89c2b551b 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -607,6 +607,18 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta cd->unsecureSetHasBackSide(1); } } + //Has partner + else if (attribute.find("haspartner") != string::npos) + { + if (minus) + { + cd->unsecureSetHasPartner(-1); + } + else + { + cd->unsecureSetHasPartner(1); + } + } //Token else if (attribute.find("token") != string::npos) { @@ -1076,6 +1088,26 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta cd->nameComparisonMode = COMPARISON_EQUAL; } + if (attribute.find("backname") != string::npos && card->backSide != "") + { + attributefound = 1; + cd->compareName = card->backSide; + if (minus) + cd->nameComparisonMode = COMPARISON_UNEQUAL; + else + cd->nameComparisonMode = COMPARISON_EQUAL; + } + + if (attribute.find("partname") != string::npos && card->partner != "") + { + attributefound = 1; + cd->compareName = card->partner; + if (minus) + cd->nameComparisonMode = COMPARISON_UNEQUAL; + else + cd->nameComparisonMode = COMPARISON_EQUAL; + } + if (attribute.find("storedname") != string::npos && card->storedCard) { attributefound = 1; diff --git a/projects/mtg/src/WParsedInt.cpp b/projects/mtg/src/WParsedInt.cpp index e20fb7368..6b0016738 100644 --- a/projects/mtg/src/WParsedInt.cpp +++ b/projects/mtg/src/WParsedInt.cpp @@ -1419,12 +1419,14 @@ void WParsedInt::extendedParse(string s, Spell * spell, MTGCardInstance * card) { intValue = (s == "plastshlturn")?card->controller()->lastShuffleTurn:card->controller()->opponent()->lastShuffleTurn; } - else if (s == "hasprey" || s == "dualfaced" || s == "totaldmg") + else if (s == "hasprey" || s == "dualfaced" || s == "withpartner" || s == "totaldmg") { if (s == "hasprey") intValue = (card->hauntedCard)?1:0; else if (s == "dualfaced") intValue = (card->backSide != "")?1:0; + else if (s == "withpartner") + intValue = (card->partner != "")?1:0; else if (s == "totaldmg") intValue = (card->damageToController + card->damageToCreature + card->damageToOpponent); }