From 5c3a064746cf2e5ac65af807b78d7d056b896f12 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 24 Jan 2017 16:10:35 +0800 Subject: [PATCH] aicode and revised legendary rule added aicode for cards that uses reveal. since reveal cancels for ai, aicode is the alternative code. use basic code only. aicode=activate dosomething... aicode - use with caution, its very basic atm and you must test each card that uses it as it can cause crash. legendary rule moved to game state based effect so it will not conflict with cards with copy effects and andability. the legendary check applies only when legendrule is found. --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 38 +++++++++++++++- projects/mtg/include/AllAbilities.h | 1 + projects/mtg/include/CardPrimitive.h | 3 ++ projects/mtg/include/GameObserver.h | 2 + projects/mtg/src/AllAbilities.cpp | 15 ++++++ projects/mtg/src/CardPrimitive.cpp | 11 +++++ projects/mtg/src/GameObserver.cpp | 48 +++++++++++++++++++- projects/mtg/src/MTGAbility.cpp | 25 +++++++++- projects/mtg/src/MTGCardInstance.cpp | 1 + projects/mtg/src/MTGDeck.cpp | 7 ++- 10 files changed, 145 insertions(+), 6 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index de29caf15..26ce93b85 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -2832,6 +2832,7 @@ type=Instant [card] name=Amnesia target=player +aicode=activate choice reject all(*[-land]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*[-land]|reveal) transforms((,newability[moveto(ownerhand) and!( reject )! all(*[-land]|reveal)])) optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand and discards all nonland cards. mana={3}{U}{U}{U} @@ -4273,6 +4274,7 @@ toughness=1 [card] name=Appetite for Brains target=opponent +aicode=activate moveto(exile) notatarget(*[manacost>=4]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose card) target(*[manacost>=4]|reveal) moveto(exile) optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose a card from it with converted mana cost 4 or greater and exile that card. mana={B} @@ -10547,6 +10549,7 @@ toughness=1 [card] name=Blackmail target=player +aicode=activate reject notatarget(*[-land]|targetedpersonshand) auto=reveal:3 revealzone(targetedpersonshand) optionone name(Put in graveyard) target(<1>*|reveal) moveto(ownergraveyard) optiononeend optiontwo name(put Back) all(*|reveal) moveto(ownerhand) optiontwoend revealend text=Target player reveals three cards from his or her hand and you choose one of them. That player discards that card. mana={B} @@ -13710,6 +13713,7 @@ type=Artifact [/card] [card] name=Brain Maggot +aicode=activate hand(blink)forsrc notatarget(*[-land]|targetedpersonshand) auto=target(opponent) reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone hand(blink)forsrc notatarget(*[-land]|reveal) optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=When Brain Maggot enters the battlefield, target opponent reveals his or her hand and you choose a nonland card from it. Exile that card until Brain Maggot leaves the battlefield. mana={1}{B} @@ -13732,6 +13736,7 @@ toughness=1 [card] name=Brainbite target=opponent +aicode=activate reject notatarget(*[-land]|targetedpersonshand) and!( draw:1 controller )! auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend afterrevealed transforms((,newability[draw:1 controller])) oneshot afterrevealedend revealend text=Target opponent reveals his or her hand. You choose a card from it. That player discards that card. -- Draw a card. mana={2}{U}{B} @@ -16597,6 +16602,7 @@ subtype=Aura [card] name=Castigate target=opponent +aicode=activate moveto(exile) notatarget(*[-land]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose card) target(*[-land]|reveal) moveto(exile) optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose a nonland card from it and exile that card. mana={W}{B} @@ -20412,6 +20418,7 @@ type=Sorcery [card] name=Coercion target=opponent +aicode=activate reject notatarget(*|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose a card from it. That player discards that card. mana={2}{B} @@ -27604,6 +27611,7 @@ toughness=2 [card] name=Despise target=opponent +aicode=activate reject notatarget(*[creature;planeswalker]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*[creature;planeswalker]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose a creature or planeswalker card from it. That player discards that card. mana={B} @@ -28300,6 +28308,7 @@ toughness=4 [card] name=Diplomacy of the Wastes target=opponent +aicode=activate reject notatarget(*[-land]|targetedpersonshand) and!( if type(warrior|mybattlefield)~morethan~0 then life:-2 targetedplayer )! auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) notatarget(*[-land]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend afterrevealed transforms((,newability[if type(*[warrior]|mybattlefield)~morethan~0 then life:-2 opponent])) oneshot afterrevealedend revealend text=Target opponent reveals his or her hand. You choose a nonland card from it. That player discards that card. If you control a Warrior, that player loses 2 life. mana={2}{B} @@ -28932,6 +28941,7 @@ type=Sorcery [card] name=Distress target=player +aicode=activate reject notatarget(*[-land]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) notatarget(*[-land]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand. You choose a nonland card from it. That player discards that card. mana={B}{B} @@ -31540,6 +31550,7 @@ toughness=* [card] name=Duress target=opponent +aicode=activate reject notatarget(*[-creature;-land]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) notatarget(*[-creature;-land]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose a noncreature, nonland card from it. That player discards that card. mana={B} @@ -34310,6 +34321,7 @@ toughness=2 [card] name=Encroach target=player +aicode=activate reject notatarget(*[-land]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) notatarget(*[-basic]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand. You choose a nonbasic land card from it. That player discards that card. mana={B} @@ -34878,7 +34890,8 @@ toughness=2 [/card] [card] name=Entomber Exarch -auto=choice moveTo(myhand) target(creature|mygraveyard) +auto=aslongas(creature|mygraveyard) choice moveTo(myhand) target(creature|mygraveyard) +aicode=activate reject notatarget(*[-creature]|targetedpersonshand) auto=choice target(opponent) reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) notatarget(*[-creature]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=When Entomber Exarch enters the battlefield, choose one - Return target creature card from your graveyard to your hand; or target opponent reveals his or her hand, you choose a noncreature card from it, then that player discards that card. mana={2}{B}{B} @@ -55988,6 +56001,7 @@ type=Sorcery [card] name=Inquisition of Kozilek target=player +aicode=activate reject notatarget(*[-land;manacost<=3]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*[-land;manacost<=3]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand. You choose a nonland card from it with converted mana cost 3 or less. That player discards that card. mana={B} @@ -64117,6 +64131,7 @@ type=Artifact [card] name=Lifebane Zombie abilities=intimidate +aicode=activate moveto(exile) notatarget(creature[green;white]|targetedpersonshand) auto=target(opponent) reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose card) target(creature[green;white]|reveal) moveto(exile) optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Intimidate. -- When Lifebane Zombie enters the battlefield, target opponent reveals his or her hand. You choose a green or white creature card from it and exile that card. mana={1}{B}{B} @@ -65272,6 +65287,7 @@ toughness=4 [card] name=Lobotomy target=player +aicode=activate notatarget(*[-basic]|targetedpersonshand) transforms((,newability[all(*[share!name!]|myhand) moveto(exile)],newability[all(*[share!name!]|mylibrary) moveto(exile) and!( shuffle )!],newability[all(*[share!name!]|mygraveyard) moveto(exile)])) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose card) notatarget(*[-basic]|reveal) moveto(exile) and!( transforms((,newability[all(*[share!name!]|mylibrary) moveto(exile) and!(shuffle)!],newability[all(*[share!name!]|mygraveyard) moveto(exile)],newability[all(*[share!name!]|myhand) moveto(exile)])) oneshot )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand, then you choose a card other than a basic land card from it. Search that player's graveyard, hand, and library for all cards with the same name as the chosen card and exile them. Then that player shuffles his or her library. mana={2}{U}{B} @@ -70180,6 +70196,7 @@ toughness=1 [/card] [card] name=Mesmeric Fiend +aicode=activate hand(blink)forsrc notatarget(*[-land]|targetedpersonshand) auto=target(opponent) reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone hand(blink)forsrc notatarget(*[-land]|reveal) optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=When Mesmeric Fiend enters the battlefield, target opponent reveals his or her hand and you choose a nonland card from it. Exile that card. -- When Mesmeric Fiend leaves the battlefield, return the exiled card to its owner's hand. mana={1}{B} @@ -76466,6 +76483,7 @@ type=Enchantment [card] name=Night Terrors target=player +aicode=activate moveto(exile) notatarget(*[-land]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone target(*[-land]|reveal) moveto(exile) optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand. You choose a nonland card from it. Exile that card. mana={2}{B} @@ -76573,6 +76591,7 @@ subtype=Equipment [card] name=Nightmare Void target=player +aicode=activate reject notatarget(*|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend dredge=dredge(2) text=Target player reveals his or her hand. You choose a card from it. That player discards that card. -- Dredge 2 (If you would draw a card, instead you may put exactly two cards from the top of your library into your graveyard. If you do, return this card from your graveyard to your hand. Otherwise, draw a card.) @@ -76683,7 +76702,7 @@ toughness=1 [card] name=Nightsnare target=opponent -auto=Reveal:type:*:opponenthand revealzone(opponenthand) revealtype(*|opponenthand) optionone choice name(Discard Land) target(land|reveal) transforms((,newability[reject],newability[all(*|reveal) moveto(ownerhand)])) oneshot optiononeend optiontwo name(Give Back) target(*|reveal) transforms((,newability[all(*|reveal) moveto(ownerhand)],newability[ability$!target(<2>*|myhand) reject!$ controller])) ueot optiontwoend revealend +auto=Reveal:type:*:opponenthand revealzone(opponenthand) revealtype(*|opponenthand) optionone choice name(Discard Nonland) target(*[-land]|reveal) transforms((,newability[reject],newability[all(*|reveal) moveto(ownerhand)])) oneshot optiononeend optiontwo name(Give Back) target(*|reveal) transforms((,newability[all(*|reveal) moveto(ownerhand)],newability[ability$!target(<2>*|myhand) reject!$ controller])) ueot optiontwoend revealend text=Target opponent reveals his or her hand. You may choose a nonland card from it. If you do, that player discards that card. If you don't, that player discards two cards. mana={3}{B} type=Sorcery @@ -80163,6 +80182,7 @@ toughness=2 [card] name=Ostracize target=opponent +aicode=activate reject notatarget(creature|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(creature|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose a creature card from it. That player discards that card. mana={B} @@ -81997,6 +82017,7 @@ toughness=4 [card] name=Perish the Thought target=opponent +aicode=activate notatarget(*|targetedpersonshand) transforms((,newability[moveto(ownerlibrary)],newability[shuffle])) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone target(*|reveal) moveto(ownerlibrary) and!( shuffle )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose a card from it. That player shuffles that card into his or her library. mana={2}{B} @@ -85892,6 +85913,7 @@ subtype=Aura [card] name=Psychic Spear target=player +aicode=activate reject notatarget(*[spirit;arcane]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*[spirit;arcane]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand. You choose a Spirit or Arcane card from it. That player discards that card. mana={B} @@ -99459,6 +99481,7 @@ type=Sorcery [card] name=Shattered Dreams target=opponent +aicode=activate reject notatarget(artifact|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose card) notatarget(artifact|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose an artifact card from it. That player discards that card. mana={B} @@ -112875,6 +112898,7 @@ toughness=3 [card] name=Talara's Bane target=opponent +aicode=activate dynamicability reject notatarget(creature[green;white]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose card) target(creature[green;white]|reveal) moveto(ownerhand) and!( dynamicability reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target opponent reveals his or her hand. You choose a green or white creature card from it. You gain life equal that creature card's toughness, then that player discards that card. mana={1}{B} @@ -115372,6 +115396,7 @@ toughness=3 [card] name=Thieving Sprite abilities=flying +aicode=activate reject notatarget(*|targetedpersonshand) auto=target(player) Reveal:type:faerie:mybattlefield revealzone(targetedpersonshand) optionone choice name(choose Discards) target(<1>*|reveal) moveto(ownerhand) and!(reject)! optiononeend optiontwo all(*|reveal) moveto(ownerhand) optiontwoend revealend text=Flying -- When Thieving Sprite enters the battlefield, target player reveals X cards from his or her hand, where X is the number of Faeries you control. You choose one of those cards. That player discards that card. mana={2}{B} @@ -115894,6 +115919,7 @@ type=Sorcery [card] name=Thoughtseize target=player +aicode=activate reject notatarget(*[-land]|targetedpersonshand) and!( life:-2 controller )! auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*[-land]|reveal) moveto(ownerhand) and!( transforms((,newability[reject],newability[all(*|reveal) moveto(ownerhand)])) oneshot )! optiononeend optiontwo name(look) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend afterrevealed transforms((,newability[life:-2 controller])) oneshot afterrevealedend revealend text=Target player reveals his or her hand. You choose a nonland card from it. That player discards that card. You lose 2 life. mana={B} @@ -116791,6 +116817,7 @@ toughness=1 [/card] [card] name=Tidehollow Sculler +aicode=activate hand(blink)forsrc notatarget(*[-land]|targetedpersonshand) auto=target(opponent) reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone hand(blink)forsrc notatarget(*[-land]|reveal) optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=When Tidehollow Sculler enters the battlefield, target opponent reveals his or her hand and you choose a nonland card from it. Exile that card. -- When Tidehollow Sculler leaves the battlefield, return the exiled card to its owner's hand. mana={W}{B} @@ -118598,6 +118625,7 @@ toughness=3 [card] name=Transgress the Mind target=player +aicode=activate moveto(exile) notatarget(*[manacost>=3]|targetedpersonshand) auto=Reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) revealtype(*|targetedpersonshand) optionone name(choose discard) notatarget(*[manacost>=3]|reveal) moveto(ownerexile) optiononeend optiontwo name(Put Back) target(*|reveal) transforms((,newability[all(*|reveal) moveto(ownerhand)])) ueot optiontwoend revealend text=Devoid (This card has no color.) -- Target player reveals his or her hand. You choose a card from it with converted mana cost 3 or greater and exile that card. mana={1}{B} @@ -118667,6 +118695,7 @@ type=Instant [card] name=Trapfinder's Trick target=player +aicode=activate choice reject all(*[trap]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*[trap]|reveal) moveto(ownerhand) and!( transforms((,newability[reject],newability[all(*[trap]|reveal) moveto(ownerhand) and!(reject)!])) oneshot )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand and discards all Trap cards. mana={1}{U} @@ -118790,6 +118819,7 @@ toughness=3 [card] name=Treacherous Urge target=opponent +aicode=activate notatarget(creature|targetedpersonshand) moveto(mybattlefield) and!( transforms((,newability[phaseaction[endofturn] sacrifice all(this)],newability[haste all(this)])) ueot )! auto=Reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) revealtype(*|targetedpersonshand) optionone name(Get Creature) notatarget(creature|reveal) transforms((,newability[moveto(opponentbattlefield)],newability[phaseaction[endofturn] sacrifice all(this)],newability[haste all(this)])) ueot optiononeend optiontwo name(Put Back) target(*|reveal) transforms((,newability[all(*|reveal) moveto(ownerhand)])) ueot optiontwoend revealend text=Target opponent reveals his or her hand. You may put a creature card from it onto the battlefield under your control. That creature gains haste. Sacrifice it at the beginning of the next end step. mana={4}{B} @@ -121242,6 +121272,7 @@ type=Instant [card] name=Unmask target=player +aicode=activate reject notatarget(*[-land]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*[-land]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend other={E(other *[black]|myhand)} name(Exile a Black Card from Hand) text=You may exile a black card from your hand rather than pay Unmask's mana cost. -- Target player reveals his or her hand. You choose a nonland card from it. That player discards that card. @@ -122895,6 +122926,7 @@ type=Land [card] name=Venarian Glimmer target=player +aicode=activate reject notatarget(*[-land;manacost<=castx]|targetedpersonshand) auto=reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose discards) target(*[-land;manacost<=castx]|reveal) moveto(ownerhand) and!( reject )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Target player reveals his or her hand. You choose a nonland card with converted mana cost X or less from it. That player discards that card. mana={X}{U} @@ -122912,6 +122944,7 @@ type=Instant [card] name=Vendilion Clique abilities=flash,flying +aicode=activate name(bottom of library) notatarget(*[-land]|targetedpersonshand) bottomoflibrary and!( draw:1 targetedplayer )! auto=name(target player) target(player) Reveal:type:*:targetedpersonshand revealzone(targetedpersonshand) optionone name(choose card) target(*[-land]|reveal) transforms((,newability[bottomoflibrary],newability[draw:1],newability[all(*|reveal) moveto(ownerhand)])) oneshot optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerhand) and!( all(*|reveal) moveto(ownerhand) )! optiontwoend revealend text=Flash -- Flying -- When Vendilion Clique enters the battlefield, look at target player's hand. You may choose a nonland card from it. If you do, that player reveals the chosen card, puts it on the bottom of his or her library, then draws a card. mana={1}{U}{U} @@ -129710,6 +129743,7 @@ type=Instant [card] name=Withering Gaze target=opponent +aicode=draw:type:*[forest;green]:targetedpersonshand auto=Reveal:type:*:opponenthand revealzone(opponenthand) revealtype(*|opponenthand) optionone choice name(Get Bonus) foreach(forest|reveal) draw:1 && foreach(*[green]|reveal) draw:1 optiononeend optiontwo name(Put Back) target(*|reveal) transforms((,newability[all(*|reveal) moveto(ownerhand)])) ueot optiontwoend revealend text=Target opponent reveals his or her hand. You draw a card for each Forest and green card in it. mana={2}{U} diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index a1f684c96..1c60abfbe 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2045,6 +2045,7 @@ class AALibraryBottom: public ActivatedAbility { public: AALibraryBottom(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target = NULL, ManaCost * _cost = NULL); + MTGAbility * andAbility; int resolve(); const string getMenuText(); AALibraryBottom * clone() const; diff --git a/projects/mtg/include/CardPrimitive.h b/projects/mtg/include/CardPrimitive.h index 15fec378f..ec32b4c0f 100644 --- a/projects/mtg/include/CardPrimitive.h +++ b/projects/mtg/include/CardPrimitive.h @@ -71,6 +71,9 @@ public: string doubleFaced; void setdoubleFaced(const string& value); const string& getdoubleFaced() const; + string AICustomCode; + void setAICustomCode(const string& value); + const string& getAICustomCode() const; vectortypes; CardPrimitive(); diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 2f520043c..48ae903e4 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -125,6 +125,8 @@ class GameObserver{ void enchantmentStatus(); void Affinity(); bool AffinityNeedsUpdate; + bool foundlegendrule; + void checkLegendary(MTGCardInstance * card); void addObserver(MTGAbility * observer); bool removeObserver(ActionElement * observer); void startGame(GameType, Rules * rules); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 9f1e66df8..934574e54 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1484,6 +1484,7 @@ AALibraryBottom::AALibraryBottom(GameObserver* observer, int _id, MTGCardInstanc ActivatedAbility(observer, _id, _source, _cost, 0) { target = _target; + andAbility = NULL; } int AALibraryBottom::resolve() @@ -1503,6 +1504,20 @@ int AALibraryBottom::resolve() newOrder.push_back(rearranged); } library->cards = newOrder; + if(andAbility) + { + MTGAbility * andAbilityClone = andAbility->clone(); + andAbilityClone->target = _target; + if(andAbility->oneShot) + { + andAbilityClone->resolve(); + SAFE_DELETE(andAbilityClone); + } + else + { + andAbilityClone->addToGame(); + } + } return 1; } return 0; diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index 3e399bf66..d2491a240 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -57,6 +57,7 @@ CardPrimitive::CardPrimitive(CardPrimitive * source) setName(source->name); setdoubleFaced(source->doubleFaced); + setAICustomCode(source->AICustomCode); power = source->power; toughness = source->toughness; restrictions = source->restrictions ? source->restrictions->clone() : NULL; @@ -341,6 +342,16 @@ const string& CardPrimitive::getdoubleFaced() const return doubleFaced; } +void CardPrimitive::setAICustomCode(const string& value) +{ + std::transform(AICustomCode.begin(), AICustomCode.end(), AICustomCode.begin(), ::tolower); + AICustomCode = value; +} + +const string& CardPrimitive::getAICustomCode() const +{ + return AICustomCode; +} void CardPrimitive::setName(const string& value) { diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 1f9802025..faa755e69 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -110,6 +110,7 @@ GameObserver::GameObserver(WResourceManager *output, JGE* input) mLayers = NULL; mTrash = new Trash(); mDeckManager = new DeckManager(); + foundlegendrule = false; } GamePhase GameObserver::getCurrentGamePhase() @@ -880,6 +881,7 @@ void GameObserver::gameStateBasedEffects() if(card->life < 1 && !card->has(Constants::INDESTRUCTIBLE)) card->destroy();//manor gargoyle... recheck } + checkLegendary(card); //legendary rule as state based effect } if(card->childrenCards.size()) @@ -935,7 +937,6 @@ void GameObserver::gameStateBasedEffects() p->nomaxhandsize = true; else p->nomaxhandsize = false; - ///////////////////////////////////////////////// //handle end of turn effects while we're at it.// ///////////////////////////////////////////////// @@ -1055,6 +1056,51 @@ void GameObserver::gameStateBasedEffects() } } +void GameObserver::checkLegendary(MTGCardInstance * card) +{ + if(!foundlegendrule) + return; + if(card->has(Constants::NOLEGEND)||card->controller()->opponent()->inPlay()->hasAbility(Constants::NOLEGENDRULE)||card->controller()->inPlay()->hasAbility(Constants::NOLEGENDRULE)) + return; + int destroy = 0; + vectoroldCards; + + MTGGameZone * z = card->controller()->game->inPlay; + int nbcards = z->nb_cards-1; + + for (int r = 0; r < nbcards; r++) + { + MTGCardInstance * comparison = z->cards[r]; + if (comparison != card && comparison->hasType("legendary") && !(comparison->getName().compare(card->getName()))) + { + oldCards.push_back(comparison); + destroy = 1; + } + } + + if(destroy) + { + vectorselection; + MultiAbility * multi = NEW MultiAbility(this, this->mLayers->actionLayer()->getMaxId(), card, card, NULL); + for(unsigned int i = 0;i < oldCards.size();i++) + { + AAMover *a = NEW AAMover(this, this->mLayers->actionLayer()->getMaxId(), card, oldCards[i],"ownergraveyard","Keep New"); + a->oneShot = true; + multi->Add(a); + } + multi->oneShot = 1; + MTGAbility * a1 = multi; + selection.push_back(a1); + AAMover *b = NEW AAMover(this, this->mLayers->actionLayer()->getMaxId(), card, card,"ownergraveyard","Keep Old"); + b->oneShot = true; + MTGAbility * b1 = b; + selection.push_back(b1); + MTGAbility * menuChoice = NEW MenuAbility(this, this->mLayers->actionLayer()->getMaxId(), card, card,true,selection,card->controller(),"Legendary Rule"); + menuChoice->addToGame(); + } + return; +} + void GameObserver::enchantmentStatus() { for (int i = 0; i < 2; i++) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 6db798db9..be533d78a 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1386,7 +1386,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG found = s.find("legendrule"); if(found != string::npos) { - observer->addObserver(NEW MTGLegendRule(observer, -1)); + //I replaced this rule since it broke cards with copy effects and with andability and other + //complex cards. So I moved it to gameobserver state based effects, if there are no more + //abilities that needs resolving then trigger this legend check... example bug: + //cast Phantasmal Image, then copy Vendilion Clique in play, after you choose target player + //there will be infinite menu for legendary rule that conflicts with Phantasmal andAbility + //observer->addObserver(NEW MTGLegendRule(observer, -1)); + observer->foundlegendrule = true; return NULL; } //this handles the planeswalker named legend rule which is dramatically different from above. @@ -2733,6 +2739,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG { MTGAbility * a = NEW AALibraryBottom(observer, id, card, target); a->oneShot = 1; + //andability + if(storedAndAbility.size()) + { + string stored = storedAndAbility; + storedAndAbility.clear(); + ((AALibraryBottom*)a)->andAbility = parseMagicLine(stored, id, spell, card); + } return a; } @@ -3553,7 +3566,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG a->oneShot = 1; a->canBeInterrupted = false; a->named = newName; - return a; + if(card->getAICustomCode().size() && card->controller()->isAI()) + { + MTGAbility * a3 = parseMagicLine(card->getAICustomCode(), id, spell, card); + a3->oneShot = 1; + a3->canBeInterrupted = false; + return a3; + } + else + return a; } //scry:x (activate aility) diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 43d9f3330..687a74dcd 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -130,6 +130,7 @@ void MTGCardInstance::copy(MTGCardInstance * card) alias = data->alias; copiedID = card->copiedID; doubleFaced = data->doubleFaced; + AICustomCode = data->AICustomCode; origpower = card->origpower;//for flip origtoughness = card->origtoughness;//for flip diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 45d71c69d..ce63bd070 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -58,7 +58,12 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi switch (key[0]) { case 'a': - if (key == "auto") + if (key == "aicode")//replacement code for AI. for reveal:number basic version only + { + if (!primitive) primitive = NEW CardPrimitive(); + primitive->setAICustomCode(val); + } + else if (key == "auto") { if (!primitive) primitive = NEW CardPrimitive(); primitive->addMagicText(val);