From 0594822872017c719204c4c9f615c70eb950d0cc Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sun, 25 Oct 2015 17:55:45 +0800 Subject: [PATCH 01/22] added card equipped event --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 3 +-- projects/mtg/include/WEvent.h | 6 ++++++ projects/mtg/src/AllAbilities.cpp | 2 ++ projects/mtg/src/GuiPlay.cpp | 2 ++ projects/mtg/src/WEvent.cpp | 11 +++++++++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 9ab640264..936610a2d 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -73407,8 +73407,7 @@ toughness=* [/card] [card] name=Plague Sliver -auto=@each my upkeep:life:-type:sliver:mybattlefield controller -auto=@each opponent upkeep:life:-type:sliver:opponentbattlefield opponent +auto=lord(sliver) transforms((,newabililty[@each my upkeep:damage:1 controller])) text=All Slivers have "At the beginning of your upkeep, this permanent deals 1 damage to you." mana={2}{B}{B} type=Creature diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h index 94043218e..0f9b546ec 100644 --- a/projects/mtg/include/WEvent.h +++ b/projects/mtg/include/WEvent.h @@ -279,6 +279,12 @@ struct WEventCardUnattached : public WEventCardUpdate { virtual Targetable * getTarget(int target); }; +//event when card-equipment attached/equipped +struct WEventCardEquipped : public WEventCardUpdate { + WEventCardEquipped(MTGCardInstance * card); + virtual Targetable * getTarget(int target); +}; + //event when card moves from player/opponent battlefield to player/opponent battlefield struct WEventCardControllerChange : public WEventCardUpdate { WEventCardControllerChange(MTGCardInstance * card); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index a02bc3912..aad2664fb 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -5611,6 +5611,8 @@ int AEquip::equip(MTGCardInstance * equipped) //we equip... a->addToGame(); } + WEvent * e = NEW WEventCardEquipped(source); + game->receiveEvent(e); return 1; } diff --git a/projects/mtg/src/GuiPlay.cpp b/projects/mtg/src/GuiPlay.cpp index eee380023..e4fc0bd7c 100644 --- a/projects/mtg/src/GuiPlay.cpp +++ b/projects/mtg/src/GuiPlay.cpp @@ -412,6 +412,8 @@ int GuiPlay::receiveEventPlus(WEvent * e) Replace(); else if (dynamic_cast (e)) Replace(); + else if (dynamic_cast (e)) + Replace(); else if (dynamic_cast (e)) Replace(); Replace(); diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index 4b1db1029..09f4b4214 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -165,6 +165,11 @@ WEventCardUnattached::WEventCardUnattached(MTGCardInstance * card) : { } +WEventCardEquipped::WEventCardEquipped(MTGCardInstance * card) : + WEventCardUpdate(card) +{ +} + WEventCardControllerChange::WEventCardControllerChange(MTGCardInstance * card) : WEventCardUpdate(card) { @@ -324,6 +329,12 @@ Targetable * WEventCardUnattached::getTarget(int target) return NULL; } +Targetable * WEventCardEquipped::getTarget(int target) +{ + if (target) return card; + return NULL; +} + Targetable * WEventCardControllerChange::getTarget(int target) { if (target) return card; From cf0f9d43fa1ac48e5c89c4d44c416cae6fe1ae78 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 26 Oct 2015 06:50:19 +0800 Subject: [PATCH 02/22] exile zone player only, todo opponent and ability activation for exile --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 5 ++- projects/mtg/include/GuiAvatars.h | 2 + projects/mtg/include/GuiStatic.h | 10 +++++ projects/mtg/include/PlayGuiObject.h | 1 + projects/mtg/src/GameObserver.cpp | 2 + projects/mtg/src/GuiAvatars.cpp | 18 +++++--- projects/mtg/src/GuiStatic.cpp | 46 ++++++++++++++++++++ 7 files changed, 76 insertions(+), 8 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 936610a2d..4489f959d 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -19622,8 +19622,8 @@ toughness=4 [/card] [card] name=Cranial Archive -auto={2}{E}:name(shuffle graveyard) target(player) donothing && moveto(ownerlibrary) and!(shuffle)! all(*|targetedpersonsgraveyard) -text={2}, Exile Cranial Archive: Target player shuffles his or her graveyard into his or her library. +auto={2}{E}:name(shuffle graveyard) target(player) donothing && moveto(ownerlibrary) and!(shuffle && draw:1 controller)! all(*|targetedpersonsgraveyard) +text={2}, Exile Cranial Archive: Target player shuffles his or her graveyard into his or her library. Draw a card. mana={2} type=Artifact [/card] @@ -74363,6 +74363,7 @@ type=Sorcery [/card] [card] name=Preyseizer Dragon +abilities=flying auto=may target(other creature|mybattlefield) sacrifice && counter(1/1,2) all(this) auto=@combat(attacking) source(this)::target(creature,player) dynamicability text=Flying -- Devour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.) -- Whenever Preyseizer Dragon attacks, it deals damage to target creature or player equal to the number of +1/+1 counters on Preyseizer Dragon. diff --git a/projects/mtg/include/GuiAvatars.h b/projects/mtg/include/GuiAvatars.h index 2baf6822c..36622051b 100644 --- a/projects/mtg/include/GuiAvatars.h +++ b/projects/mtg/include/GuiAvatars.h @@ -7,6 +7,7 @@ struct GuiAvatar; class GuiGraveyard; class GuiLibrary; class GuiOpponentHand; +class GuiExile; class GuiAvatars: public GuiLayer { protected: @@ -14,6 +15,7 @@ protected: GuiGraveyard* selfGraveyard, *opponentGraveyard; GuiLibrary* selfLibrary, *opponentLibrary; GuiOpponentHand *opponentHand; + GuiExile* selfExile, *opponentExile; GuiAvatar* active; public: diff --git a/projects/mtg/include/GuiStatic.h b/projects/mtg/include/GuiStatic.h index 9fb352a7a..513d7848b 100644 --- a/projects/mtg/include/GuiStatic.h +++ b/projects/mtg/include/GuiStatic.h @@ -88,4 +88,14 @@ public: virtual ostream& toString(ostream& out) const; }; +class GuiExile: public GuiGameZone +{ +public: + Player * player; + GuiExile(float _x, float _y, bool hasFocus, Player * player, GuiAvatars* parent); + int receiveEventPlus(WEvent*); + int receiveEventMinus(WEvent*); + virtual ostream& toString(ostream& out) const; +}; + #endif // _GUISTATIC_H_ diff --git a/projects/mtg/include/PlayGuiObject.h b/projects/mtg/include/PlayGuiObject.h index c09d1a4c8..2f4dbcf67 100644 --- a/projects/mtg/include/PlayGuiObject.h +++ b/projects/mtg/include/PlayGuiObject.h @@ -10,6 +10,7 @@ #define GUI_GRAVEYARD 3 #define GUI_LIBRARY 4 #define GUI_OPPONENTHAND 5 +#define GUI_EXILE 6 #include #include "WEvent.h" diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 4a0d6300b..3aba8dd97 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1134,6 +1134,8 @@ void GameObserver::ButtonPressed(PlayGuiObject * target) } else if (GuiGraveyard* graveyard = dynamic_cast(target)) graveyard->toggleDisplay(); + else if (GuiExile* exile = dynamic_cast(target)) + exile->toggleDisplay(); //opponenthand else if (GuiOpponentHand* opponentHand = dynamic_cast(target)) if (opponentHand->showCards) diff --git a/projects/mtg/src/GuiAvatars.cpp b/projects/mtg/src/GuiAvatars.cpp index e364bae3c..6b5e922a7 100644 --- a/projects/mtg/src/GuiAvatars.cpp +++ b/projects/mtg/src/GuiAvatars.cpp @@ -14,6 +14,7 @@ GuiAvatars::GuiAvatars(DuelLayers* duelLayers) : self->zoom = 0.9f; Add(selfGraveyard = NEW GuiGraveyard(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 1, false, mpDuelLayers->getRenderedPlayer(), this)); Add(selfLibrary = NEW GuiLibrary(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 5 + GuiGameZone::Height + 5, false, mpDuelLayers->getRenderedPlayer(), this)); + Add(selfExile = NEW GuiExile(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 + 20, SCREEN_HEIGHT - GuiAvatar::Height, false, mpDuelLayers->getRenderedPlayer(), this)); Add(opponent = NEW GuiAvatar(0, 0, false, mpDuelLayers->getRenderedPlayerOpponent(), GuiAvatar::TOP_LEFT, this)); opponent->zoom = 0.9f; @@ -28,12 +29,13 @@ GuiAvatars::GuiAvatars(DuelLayers* duelLayers) : observer->getCardSelector()->Add(self); observer->getCardSelector()->Add(selfGraveyard); + observer->getCardSelector()->Add(selfExile); observer->getCardSelector()->Add(selfLibrary); observer->getCardSelector()->Add(opponent); observer->getCardSelector()->Add(opponentGraveyard); observer->getCardSelector()->Add(opponentLibrary); observer->getCardSelector()->Add(opponentHand); - selfGraveyard->alpha = selfLibrary->alpha = opponentGraveyard->alpha = opponentLibrary->alpha = opponentHand->alpha = 0; + selfGraveyard->alpha = selfExile->alpha = selfLibrary->alpha = opponentGraveyard->alpha = opponentLibrary->alpha = opponentHand->alpha = 0; } float GuiAvatars::LeftBoundarySelf() @@ -56,9 +58,9 @@ void GuiAvatars::Activate(PlayGuiObject* c) active = opponent; opponent->zoom = 1.2f; } - else if ((selfGraveyard == c) || (selfLibrary == c) || (self == c)) + else if ((selfGraveyard == c) || (selfExile == c) || (selfLibrary == c) || (self == c)) { - selfGraveyard->alpha = selfLibrary->alpha = 128.0f; + selfGraveyard->alpha = selfExile->alpha = selfLibrary->alpha = 128.0f; self->zoom = 1.0f; active = self; } @@ -75,9 +77,9 @@ void GuiAvatars::Deactivate(PlayGuiObject* c) opponent->zoom = 0.9f; active = NULL; } - else if ((selfGraveyard == c) || (selfLibrary == c) || (self == c)) + else if ((selfGraveyard == c) || (selfExile == c) || (selfLibrary == c) || (self == c)) { - selfGraveyard->alpha = selfLibrary->alpha = 0; + selfGraveyard->alpha = selfExile->alpha = selfLibrary->alpha = 0; self->zoom = 0.5f; active = NULL; } @@ -85,12 +87,13 @@ void GuiAvatars::Deactivate(PlayGuiObject* c) int GuiAvatars::receiveEventPlus(WEvent* e) { - return selfGraveyard->receiveEventPlus(e) | opponentGraveyard->receiveEventPlus(e) | opponentHand->receiveEventPlus(e); + return selfGraveyard->receiveEventPlus(e) | selfExile->receiveEventPlus(e) | opponentGraveyard->receiveEventPlus(e) | opponentHand->receiveEventPlus(e); } int GuiAvatars::receiveEventMinus(WEvent* e) { selfGraveyard->receiveEventMinus(e); + selfExile->receiveEventMinus(e); opponentGraveyard->receiveEventMinus(e); opponentHand->receiveEventMinus(e); return 1; @@ -104,6 +107,8 @@ bool GuiAvatars::CheckUserInput(JButton key) return true; if (selfGraveyard->CheckUserInput(key)) return true; + if (selfExile->CheckUserInput(key)) + return true; if (opponentGraveyard->CheckUserInput(key)) return true; if (opponentHand->CheckUserInput(key)) @@ -120,6 +125,7 @@ void GuiAvatars::Update(float dt) self->Update(dt); opponent->Update(dt); selfGraveyard->Update(dt); + selfExile->Update(dt); opponentHand->Update(dt); opponentGraveyard->Update(dt); selfLibrary->Update(dt); diff --git a/projects/mtg/src/GuiStatic.cpp b/projects/mtg/src/GuiStatic.cpp index 28e00ec2d..c7eb7e795 100644 --- a/projects/mtg/src/GuiStatic.cpp +++ b/projects/mtg/src/GuiStatic.cpp @@ -298,6 +298,52 @@ ostream& GuiGraveyard::toString(ostream& out) const return out << "GuiGraveyard :::"; } +GuiExile::GuiExile(float x, float y, bool hasFocus, Player * player, GuiAvatars* parent) : + GuiGameZone(x, y, hasFocus, player->game->exile, parent), player(player) +{ + type = GUI_EXILE; +} + +int GuiExile::receiveEventPlus(WEvent* e) +{ + if (WEventZoneChange* event = dynamic_cast(e)) + if (event->to == zone) + { + CardView* t; + if (event->card->view) + t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); + else + t = NEW CardView(CardView::nullZone, event->card, x, y); + t->x = x + Width / 2; + t->y = y + Height / 2; + t->zoom = 0.6f; + t->alpha = 0; + cards.push_back(t); + return 1; + } + return 0; +} + +int GuiExile::receiveEventMinus(WEvent* e) +{ + if (WEventZoneChange* event = dynamic_cast(e)) + if (event->from == zone) + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + if (event->card->previous == (*it)->card) + { + CardView* cv = *it; + cards.erase(it); + zone->owner->getObserver()->mTrash->trash(cv); + return 1; + } + return 0; +} + +ostream& GuiExile::toString(ostream& out) const +{ + return out << "GuiExile :::"; +} + //opponenthand begins GuiOpponentHand::GuiOpponentHand(float x, float y, bool hasFocus, Player * player, GuiAvatars* parent) : GuiGameZone(x, y, hasFocus, player->game->hand, parent), player(player) From cdf94b281f384d4c465e561ed126ec527ac61156 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 26 Oct 2015 19:14:50 +0800 Subject: [PATCH 03/22] exile zone enabled exile zones for both players --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 2 +- projects/mtg/include/AllAbilities.h | 57 ++++++++++---------- projects/mtg/src/AIPlayerBaka.cpp | 12 ++--- projects/mtg/src/AllAbilities.cpp | 24 +++++++-- projects/mtg/src/GameObserver.cpp | 11 ++-- projects/mtg/src/GuiAvatars.cpp | 32 +++++++---- projects/mtg/src/GuiStatic.cpp | 16 +++++- projects/mtg/src/MTGAbility.cpp | 15 +++--- projects/mtg/src/Rules.cpp | 16 +++--- projects/mtg/src/TestSuiteAI.cpp | 21 ++++---- 10 files changed, 125 insertions(+), 81 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 4489f959d..eaed73793 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -68670,7 +68670,7 @@ type=Sorcery [card] name=Obzedat, Ghost Council auto=ability$!choice life:-2 target(opponent) && life:2 controller!$ controller -auto=@each my end:may name(exile) all(this) transforms((,newability[moveto(exile)],newability[phaseactionmulti[my upkeep once] moveto(ownerbattlefield) && all(this) haste])) +auto=@each my end:may name(exile) all(this) transforms((,newability[moveto(exile)],newability[phaseactionmulti[my upkeep once checkex] moveto(ownerbattlefield) && all(this) haste])) text=When Obzedat, Ghost Council enters the battlefield, target opponent loses 2 life and you gain 2 life. -- At the beginning of your end step, you may exile Obzedat. If you do, return it to the battlefield under its owner's control at the beginning of your next upkeep. It gains haste. mana={1}{W}{W}{B}{B} type=Legendary Creature diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index cbc9fb7fd..2f6d40e6c 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -207,8 +207,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -227,8 +227,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -247,8 +247,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -267,8 +267,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -287,8 +287,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -307,8 +307,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -327,8 +327,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -347,8 +347,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -367,8 +367,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -387,8 +387,8 @@ private: for (int i = 0; i < 2; i++) { Player * dp = card->getObserver()->players[i]; - MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { dp->game->inPlay, dp->game->graveyard, dp->game->hand, dp->game->library, dp->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (dtc->targetsZone(zone, card)&&dp == card->controller()) @@ -424,8 +424,8 @@ private: for (int i = 0; i < 2; i++) { Player * p = card->getObserver()->players[i]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = zones[k]; if (tc->targetsZone(zone, card)) @@ -516,8 +516,8 @@ private: for (int i = 0; i < 2; i++) { Player * p = card->getObserver()->players[i]; - MTGGameZone * zones[] = { p->game->battlefield, p->game->graveyard, p->game->hand, p->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * zones[] = { p->game->battlefield, p->game->graveyard, p->game->hand, p->game->library, p->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = zones[k]; if(tc->targetsZone(zone,target)) @@ -2916,8 +2916,8 @@ public: for (int i = 0; i < 2; i++) { Player * p = game->players[i]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = zones[k]; Value = zone->countByCanTarget(tc); @@ -4913,10 +4913,11 @@ public: bool myturn; bool opponentturn; bool once; + bool checkexile; Player * abilityOwner; APhaseAction(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * target, string sAbility, int restrictions = 0, int _phase = - MTG_PHASE_UPKEEP,bool forcedestroy = false,bool next = true,bool myturn = true,bool opponentturn = true,bool once = false); + MTG_PHASE_UPKEEP,bool forcedestroy = false,bool next = true,bool myturn = true,bool opponentturn = true,bool once = false, bool checkexile = false); void Update(float dt); int resolve(); const string getMenuText(); @@ -4931,7 +4932,7 @@ public: string sAbility; APhaseAction * ability; APhaseActionGeneric(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * target, string sAbility, int restrictions = 0, int _phase = - MTG_PHASE_UPKEEP,bool forcedestroy = false,bool next = true,bool myturn = false,bool opponentturn = false,bool once = false); + MTG_PHASE_UPKEEP,bool forcedestroy = false,bool next = true,bool myturn = false,bool opponentturn = false,bool once = false,bool checkexile = false); int resolve(); const string getMenuText(); APhaseActionGeneric * clone() const; diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index b126eb040..d75616eaf 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -650,8 +650,8 @@ MTGCardInstance * AIPlayerBaka::chooseCard(TargetChooser * tc, MTGCardInstance * } for(int players = 0; players < 2;++players) { - MTGGameZone * zones[] = { playerZones->hand, playerZones->library, playerZones->inPlay, playerZones->graveyard,playerZones->stack }; - for (int j = 0; j < 5; j++) + MTGGameZone * zones[] = { playerZones->hand, playerZones->library, playerZones->inPlay, playerZones->graveyard,playerZones->stack,playerZones->exile }; + for (int j = 0; j < 6; j++) { MTGGameZone * zone = zones[j]; for (int k = 0; k < zone->nb_cards; k++) @@ -1214,7 +1214,7 @@ int AIPlayerBaka::createAbilityTargets(MTGAbility * a, MTGCardInstance * c, Rank for (int i = 0; i < 2; i++) { Player * p = observer->players[i]; - MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay,p->game->stack }; + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay,p->game->stack,p->game->exile }; if(a->getActionTc()->canTarget((Targetable*)p)) { if(a->getActionTc()->maxtargets == 1) @@ -1225,7 +1225,7 @@ int AIPlayerBaka::createAbilityTargets(MTGAbility * a, MTGCardInstance * c, Rank else potentialTargets.push_back(p); } - for (int j = 0; j < 5; j++) + for (int j = 0; j < 6; j++) { MTGGameZone * zone = playerZones[j]; for (int k = 0; k < zone->nb_cards; k++) @@ -1553,8 +1553,8 @@ int AIPlayerBaka::chooseTarget(TargetChooser * _tc, Player * forceTarget,MTGCard } } MTGPlayerCards * playerZones = target->game; - MTGGameZone * zones[] = { playerZones->hand, playerZones->library, playerZones->inPlay, playerZones->graveyard,playerZones->stack }; - for (int j = 0; j < 5; j++) + MTGGameZone * zones[] = { playerZones->hand, playerZones->library, playerZones->inPlay, playerZones->graveyard,playerZones->stack,playerZones->exile }; + for (int j = 0; j < 6; j++) { MTGGameZone * zone = zones[j]; for (int k = 0; k < zone->nb_cards; k++) diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index aad2664fb..1a48ccc74 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -5092,8 +5092,8 @@ AUpkeep::~AUpkeep() } //A Phase based Action -APhaseAction::APhaseAction(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance *, string sAbility, int, int _phase,bool forcedestroy,bool next,bool myturn,bool opponentturn,bool once) : -MTGAbility(observer, _id, card),sAbility(sAbility), phase(_phase),forcedestroy(forcedestroy),next(next),myturn(myturn),opponentturn(opponentturn),once(once) +APhaseAction::APhaseAction(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance *, string sAbility, int, int _phase,bool forcedestroy,bool next,bool myturn,bool opponentturn,bool once, bool checkexile) : +MTGAbility(observer, _id, card),sAbility(sAbility), phase(_phase),forcedestroy(forcedestroy),next(next),myturn(myturn),opponentturn(opponentturn),once(once),checkexile(checkexile) { abilityId = _id; abilityOwner = card->controller(); @@ -5110,6 +5110,14 @@ MTGAbility(observer, _id, card),sAbility(sAbility), phase(_phase),forcedestroy(f void APhaseAction::Update(float dt) { + if(checkexile) + { + if(((MTGCardInstance *)target)->next->getCurrentZone() != ((MTGCardInstance *)target)->owner->game->exile) + { + this->forceDestroy = 1; + return; + } + } if (newPhase != currentPhase) { if((myturn && game->currentPlayer == source->controller())|| @@ -5186,11 +5194,11 @@ APhaseAction::~APhaseAction() } // the main ability -APhaseActionGeneric::APhaseActionGeneric(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * target, string sAbility, int restrictions, int _phase,bool forcedestroy,bool next,bool myturn,bool opponentturn,bool once) : +APhaseActionGeneric::APhaseActionGeneric(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * target, string sAbility, int restrictions, int _phase,bool forcedestroy,bool next,bool myturn,bool opponentturn,bool once, bool checkexile) : InstantAbility(observer, _id, card, target) { MTGCardInstance * _target = target; - ability = NEW APhaseAction(game, _id, card,_target, sAbility, restrictions, _phase,forcedestroy,next,myturn,opponentturn,once); + ability = NEW APhaseAction(game, _id, card,_target, sAbility, restrictions, _phase,forcedestroy,next,myturn,opponentturn,once,checkexile); } int APhaseActionGeneric::resolve() @@ -5236,7 +5244,7 @@ void ABlink::Update(float dt) resolveBlink(); } - if ((blinkueot && currentPhase == MTG_PHASE_ENDOFTURN) || (blinkForSource && !source->isInPlay(game))) + if ((blinkueot && currentPhase == MTG_PHASE_ENDOFTURN) || (blinkForSource && !source->isInPlay(game)) && Blinked->blinked) { if (Blinked == NULL) MTGAbility::Update(dt); @@ -5272,6 +5280,7 @@ void ABlink::resolveBlink() return; } _target = _target->next; + _target->blinked = true; Blinked = _target; if(!blinkueot && !blinkForSource) { @@ -5282,6 +5291,11 @@ void ABlink::resolveBlink() void ABlink::returnCardIntoPlay(MTGCardInstance* _target) { MTGCardInstance * Blinker = NULL; + if(!_target->blinked) + { + this->forceDestroy = 1; + return; + } if (!blinkhand) Blinker = _target->controller()->game->putInZone( _target, diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 3aba8dd97..933ec20cf 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -518,12 +518,13 @@ bool GameObserver::operator==(const GameObserver& aGame) { error++; } - MTGGameZone * aZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay }; + MTGGameZone * aZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->exile }; MTGGameZone * thisZones[] = { players[i]->game->graveyard, players[i]->game->library, players[i]->game->hand, - players[i]->game->inPlay }; - for (int j = 0; j < 4; j++) + players[i]->game->inPlay, + players[i]->game->exile }; + for (int j = 0; j < 5; j++) { MTGGameZone * zone = aZones[j]; if (zone->nb_cards != thisZones[j]->nb_cards) @@ -595,8 +596,8 @@ void GameObserver::gameStateBasedEffects() ///////////////////////////////////// for (int d = 0; d < 2; d++) { - MTGGameZone * dzones[] = { players[d]->game->inPlay, players[d]->game->graveyard, players[d]->game->hand, players[d]->game->library }; - for (int k = 0; k < 4; k++) + MTGGameZone * dzones[] = { players[d]->game->inPlay, players[d]->game->graveyard, players[d]->game->hand, players[d]->game->library, players[d]->game->exile }; + for (int k = 0; k < 5; k++) { MTGGameZone * zone = dzones[k]; if (mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) diff --git a/projects/mtg/src/GuiAvatars.cpp b/projects/mtg/src/GuiAvatars.cpp index 6b5e922a7..7db23774d 100644 --- a/projects/mtg/src/GuiAvatars.cpp +++ b/projects/mtg/src/GuiAvatars.cpp @@ -14,16 +14,21 @@ GuiAvatars::GuiAvatars(DuelLayers* duelLayers) : self->zoom = 0.9f; Add(selfGraveyard = NEW GuiGraveyard(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 1, false, mpDuelLayers->getRenderedPlayer(), this)); Add(selfLibrary = NEW GuiLibrary(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 5 + GuiGameZone::Height + 5, false, mpDuelLayers->getRenderedPlayer(), this)); - Add(selfExile = NEW GuiExile(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 + 20, SCREEN_HEIGHT - GuiAvatar::Height, false, mpDuelLayers->getRenderedPlayer(), this)); + //myexile + Add(selfExile = NEW GuiExile(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 + 10, SCREEN_HEIGHT - GuiAvatar::Height, false, mpDuelLayers->getRenderedPlayer(), this)); Add(opponent = NEW GuiAvatar(0, 0, false, mpDuelLayers->getRenderedPlayerOpponent(), GuiAvatar::TOP_LEFT, this)); opponent->zoom = 0.9f; - //opponenthandveiw button - Add(opponentHand = NEW GuiOpponentHand(-30 + GuiAvatar::Width * 1.2 - GuiGameZone::Width / 2, 35 + GuiGameZone::Height - 10, + //opponentExile + Add(opponentExile = NEW GuiExile(-30 + GuiAvatar::Width * 1.2 - GuiGameZone::Width / 2, 35 + GuiGameZone::Height - 10, false, mpDuelLayers->getRenderedPlayerOpponent(), this)); - //opponenthandveiwends - Add(opponentGraveyard = NEW GuiGraveyard(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5, false, + //opponentHand + Add(opponentHand = NEW GuiOpponentHand(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5, false, mpDuelLayers->getRenderedPlayerOpponent(), this)); + //opponentGraveyard + Add(opponentGraveyard = NEW GuiGraveyard(-15 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 35 + GuiGameZone::Height - 10, false, + mpDuelLayers->getRenderedPlayerOpponent(), this)); + //opponentLibrary Add(opponentLibrary = NEW GuiLibrary(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5 + GuiGameZone::Height + 5, false, mpDuelLayers->getRenderedPlayerOpponent(), this)); @@ -33,9 +38,10 @@ GuiAvatars::GuiAvatars(DuelLayers* duelLayers) : observer->getCardSelector()->Add(selfLibrary); observer->getCardSelector()->Add(opponent); observer->getCardSelector()->Add(opponentGraveyard); + observer->getCardSelector()->Add(opponentExile); observer->getCardSelector()->Add(opponentLibrary); observer->getCardSelector()->Add(opponentHand); - selfGraveyard->alpha = selfExile->alpha = selfLibrary->alpha = opponentGraveyard->alpha = opponentLibrary->alpha = opponentHand->alpha = 0; + selfGraveyard->alpha = selfExile->alpha = opponentExile->alpha = selfLibrary->alpha = opponentGraveyard->alpha = opponentLibrary->alpha = opponentHand->alpha = 0; } float GuiAvatars::LeftBoundarySelf() @@ -52,9 +58,9 @@ void GuiAvatars::Activate(PlayGuiObject* c) c->zoom = 1.2f; c->mHasFocus = true; - if ((opponentGraveyard == c) || (opponentLibrary == c) || (opponent == c) || (opponentHand == c)) + if ((opponentGraveyard == c) || (opponentExile == c) || (opponentLibrary == c) || (opponent == c) || (opponentHand == c)) { - opponentGraveyard->alpha = opponentLibrary->alpha = opponentHand->alpha = 128.0f; + opponentGraveyard->alpha = opponentExile->alpha = opponentLibrary->alpha = opponentHand->alpha = 128.0f; active = opponent; opponent->zoom = 1.2f; } @@ -71,9 +77,9 @@ void GuiAvatars::Deactivate(PlayGuiObject* c) { c->zoom = 1.0; c->mHasFocus = false; - if ((opponentGraveyard == c) || (opponentLibrary == c) || (opponentHand == c) || (opponent == c)) + if ((opponentGraveyard == c) || (opponentExile == c) || (opponentLibrary == c) || (opponentHand == c) || (opponent == c)) { - opponentGraveyard->alpha = opponentLibrary->alpha = opponentHand->alpha = 0; + opponentGraveyard->alpha = opponentExile->alpha = opponentLibrary->alpha = opponentHand->alpha = 0; opponent->zoom = 0.9f; active = NULL; } @@ -87,7 +93,7 @@ void GuiAvatars::Deactivate(PlayGuiObject* c) int GuiAvatars::receiveEventPlus(WEvent* e) { - return selfGraveyard->receiveEventPlus(e) | selfExile->receiveEventPlus(e) | opponentGraveyard->receiveEventPlus(e) | opponentHand->receiveEventPlus(e); + return selfGraveyard->receiveEventPlus(e) | selfExile->receiveEventPlus(e) | opponentExile->receiveEventPlus(e) | opponentGraveyard->receiveEventPlus(e) | opponentHand->receiveEventPlus(e); } int GuiAvatars::receiveEventMinus(WEvent* e) @@ -95,6 +101,7 @@ int GuiAvatars::receiveEventMinus(WEvent* e) selfGraveyard->receiveEventMinus(e); selfExile->receiveEventMinus(e); opponentGraveyard->receiveEventMinus(e); + opponentExile->receiveEventMinus(e); opponentHand->receiveEventMinus(e); return 1; } @@ -111,6 +118,8 @@ bool GuiAvatars::CheckUserInput(JButton key) return true; if (opponentGraveyard->CheckUserInput(key)) return true; + if (opponentExile->CheckUserInput(key)) + return true; if (opponentHand->CheckUserInput(key)) return true; if (selfLibrary->CheckUserInput(key)) @@ -128,6 +137,7 @@ void GuiAvatars::Update(float dt) selfExile->Update(dt); opponentHand->Update(dt); opponentGraveyard->Update(dt); + opponentExile->Update(dt); selfLibrary->Update(dt); opponentLibrary->Update(dt); } diff --git a/projects/mtg/src/GuiStatic.cpp b/projects/mtg/src/GuiStatic.cpp index c7eb7e795..04506ead0 100644 --- a/projects/mtg/src/GuiStatic.cpp +++ b/projects/mtg/src/GuiStatic.cpp @@ -164,7 +164,10 @@ void GuiGameZone::Render() JQuadPtr quad = WResourceManager::Instance()->GetQuad(kGenericCardThumbnailID); float scale = defaultHeight / quad->mHeight; quad->SetColor(ARGB((int)(actA),255,255,255)); - + if(type == GUI_EXILE) + { + quad->SetColor(ARGB((int)(actA),150,150,150)); + } JRenderer::GetInstance()->RenderQuad(quad.get(), actX, actY, 0.0, scale * actZ, scale * actZ); float x0 = actX; @@ -182,7 +185,16 @@ void GuiGameZone::Render() mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); char buffer[11]; int mAlpha = (int) (actA); - sprintf(buffer, "%i", zone->nb_cards); + /*if(type == GUI_GRAVEYARD) + sprintf(buffer, "%i\ng", zone->nb_cards); + else if(type == GUI_LIBRARY) + sprintf(buffer, "%i\nl", zone->nb_cards); + else if(type == GUI_OPPONENTHAND) + sprintf(buffer, "%i\nh", zone->nb_cards); + else if(type == GUI_EXILE) + sprintf(buffer, "%i\ne", zone->nb_cards); + else*/ + sprintf(buffer, "%i", zone->nb_cards); mFont->SetColor(ARGB(mAlpha,0,0,0)); mFont->DrawString(buffer, x0 + 1, actY + 1); if (actA > 120) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 92007d42a..af7a2b667 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -558,8 +558,8 @@ int AbilityFactory::countCards(TargetChooser * tc, Player * player, int option) { if (player && player != observer->players[i]) continue; - MTGGameZone * zones[] = { observer->players[i]->game->inPlay, observer->players[i]->game->graveyard, observer->players[i]->game->hand }; - for (int k = 0; k < 3; k++) + MTGGameZone * zones[] = { observer->players[i]->game->inPlay, observer->players[i]->game->graveyard, observer->players[i]->game->hand, observer->players[i]->game->exile }; + for (int k = 0; k < 4; k++) { for (int j = zones[k]->nb_cards - 1; j >= 0; j--) { @@ -3412,6 +3412,7 @@ MTGAbility * AbilityFactory::parsePhaseActionAbility(string s,MTGCardInstance * bool opponentturn = (s1.find("my") == string::npos); bool myturn = (s1.find("opponent") == string::npos); bool sourceinPlay = (s1.find("sourceinplay") != string::npos); + bool checkexile = (s1.find("checkex") != string::npos); bool next = (s1.find("next") == string::npos); //Why is this one the opposite of the two others? That's completely inconsistent bool once = (s1.find("once") != string::npos); @@ -3420,7 +3421,7 @@ MTGAbility * AbilityFactory::parsePhaseActionAbility(string s,MTGCardInstance * _target = spell->getNextCardTarget(); if(!_target) _target = target; - return NEW APhaseActionGeneric(observer, id, card,_target, trim(splitActions[2]), restrictions, phase,sourceinPlay,next,myturn,opponentturn,once); + return NEW APhaseActionGeneric(observer, id, card,_target, trim(splitActions[2]), restrictions, phase,sourceinPlay,next,myturn,opponentturn,once,checkexile); } MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance * card,Spell *,MTGCardInstance * target, int, int id) @@ -5257,8 +5258,8 @@ void ListMaintainerAbility::updateTargets() for (int i = 0; i < 2; i++) { Player * p = game->players[i]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack }; - for (int k = 0; k < 5; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; + for (int k = 0; k < 6; k++) { MTGGameZone * zone = zones[k]; if (canTarget(zone)) @@ -5329,8 +5330,8 @@ void ListMaintainerAbility::checkTargets() for (int i = 0; i < 2; i++) { Player * p = game->players[i]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack }; - for (int k = 0; k < 5; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; + for (int k = 0; k < 6; k++) { MTGGameZone * zone = zones[k]; if (canTarget(zone)) diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index adf7ff8a3..e5f095454 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -79,8 +79,8 @@ MTGCardInstance * Rules::getCardByMTGId(GameObserver* g, int mtgid) for (int i = 0; i < 2; i++) { Player * p = g->players[i]; - MTGGameZone * zones[] = { p->game->library, p->game->hand, p->game->inPlay, p->game->graveyard }; - for (int j = 0; j < 4; j++) + MTGGameZone * zones[] = { p->game->library, p->game->hand, p->game->inPlay, p->game->graveyard, p->game->exile }; + for (int j = 0; j < 5; j++) { MTGGameZone * zone = zones[j]; for (int k = 0; k < zone->nb_cards; k++) @@ -340,9 +340,10 @@ MTGDeck * Rules::buildDeck(int playerId) MTGGameZone * loadedPlayerZones[] = { initState.playerData[playerId].player->game->graveyard, initState.playerData[playerId].player->game->library, initState.playerData[playerId].player->game->hand, - initState.playerData[playerId].player->game->inPlay }; + initState.playerData[playerId].player->game->inPlay, + initState.playerData[playerId].player->game->exile }; - for (int j = 0; j < 4; j++) + for (int j = 0; j < 5; j++) { for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) { @@ -412,12 +413,13 @@ void Rules::initGame(GameObserver *g, bool currentPlayerSet) { p->mAvatarName = initState.playerData[i].player->mAvatarName; } - MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay }; + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->exile }; MTGGameZone * loadedPlayerZones[] = { initState.playerData[i].player->game->graveyard, initState.playerData[i].player->game->library, initState.playerData[i].player->game->hand, - initState.playerData[i].player->game->inPlay }; - for (int j = 0; j < 4; j++) + initState.playerData[i].player->game->inPlay, + initState.playerData[i].player->game->exile }; + for (int j = 0; j < 5; j++) { MTGGameZone * zone = playerZones[j]; for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index bb7e236ce..beab3ded7 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -46,8 +46,8 @@ MTGCardInstance * TestSuiteAI::getCard(string action) for (int i = 0; i < 2; i++) { Player * p = observer->players[i]; - MTGGameZone * zones[] = { p->game->library, p->game->hand, p->game->inPlay, p->game->graveyard }; - for (int j = 0; j < 4; j++) + MTGGameZone * zones[] = { p->game->library, p->game->hand, p->game->inPlay, p->game->graveyard, p->game->exile }; + for (int j = 0; j < 5; j++) { MTGGameZone * zone = zones[j]; for (int k = 0; k < zone->nb_cards; k++) @@ -394,12 +394,13 @@ void TestSuiteGame::assertGame() error++; } - MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay }; + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->exile }; MTGGameZone * endstateZones[] = { endState.players[i]->game->graveyard, endState.players[i]->game->library, endState.players[i]->game->hand, - endState.players[i]->game->inPlay }; - for (int j = 0; j < 4; j++) + endState.players[i]->game->inPlay, + endState.players[i]->game->exile }; + for (int j = 0; j < 5; j++) { MTGGameZone * zone = playerZones[j]; if (zone->nb_cards != endstateZones[j]->nb_cards) @@ -853,12 +854,13 @@ void TestSuiteGame::initGame() stringstream stream; stream << initState.players[i]->getRandomGenerator()->saveLoadedRandValues(stream); p->getRandomGenerator()->loadRandValues(stream.str()); - MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay }; + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->exile }; MTGGameZone * loadedPlayerZones[] = { initState.players[i]->game->graveyard, initState.players[i]->game->library, initState.players[i]->game->hand, - initState.players[i]->game->inPlay }; - for (int j = 0; j < 4; j++) + initState.players[i]->game->inPlay, + initState.players[i]->game->exile }; + for (int j = 0; j < 5; j++) { MTGGameZone * zone = playerZones[j]; for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) @@ -910,9 +912,10 @@ MTGPlayerCards * TestSuiteGame::buildDeck(Player* player, int playerId) MTGGameZone * loadedPlayerZones[] = { initState.players[playerId]->game->graveyard, initState.players[playerId]->game->library, initState.players[playerId]->game->hand, + initState.players[playerId]->game->exile, initState.players[playerId]->game->inPlay }; - for (int j = 0; j < 4; j++) + for (int j = 0; j < 5; j++) { for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) { From 4853c8d314439271737ae4302c4d003a66d7290a Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 27 Oct 2015 01:03:24 +0800 Subject: [PATCH 04/22] Exile Corrections Todo: Update tests to include exile card count... --- projects/mtg/src/GuiAvatars.cpp | 12 +++++++----- projects/mtg/src/GuiStatic.cpp | 2 +- projects/mtg/src/MTGGameZones.cpp | 9 +++++++++ projects/mtg/src/TestSuiteAI.cpp | 12 ++++++------ 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/projects/mtg/src/GuiAvatars.cpp b/projects/mtg/src/GuiAvatars.cpp index 7db23774d..173604e05 100644 --- a/projects/mtg/src/GuiAvatars.cpp +++ b/projects/mtg/src/GuiAvatars.cpp @@ -15,18 +15,18 @@ GuiAvatars::GuiAvatars(DuelLayers* duelLayers) : Add(selfGraveyard = NEW GuiGraveyard(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 1, false, mpDuelLayers->getRenderedPlayer(), this)); Add(selfLibrary = NEW GuiLibrary(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 5 + GuiGameZone::Height + 5, false, mpDuelLayers->getRenderedPlayer(), this)); //myexile - Add(selfExile = NEW GuiExile(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 + 10, SCREEN_HEIGHT - GuiAvatar::Height, false, mpDuelLayers->getRenderedPlayer(), this)); + Add(selfExile = NEW GuiExile(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 30, false, mpDuelLayers->getRenderedPlayer(), this)); Add(opponent = NEW GuiAvatar(0, 0, false, mpDuelLayers->getRenderedPlayerOpponent(), GuiAvatar::TOP_LEFT, this)); opponent->zoom = 0.9f; //opponentExile Add(opponentExile = NEW GuiExile(-30 + GuiAvatar::Width * 1.2 - GuiGameZone::Width / 2, 35 + GuiGameZone::Height - 10, false, mpDuelLayers->getRenderedPlayerOpponent(), this)); - //opponentHand - Add(opponentHand = NEW GuiOpponentHand(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5, false, - mpDuelLayers->getRenderedPlayerOpponent(), this)); //opponentGraveyard - Add(opponentGraveyard = NEW GuiGraveyard(-15 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 35 + GuiGameZone::Height - 10, false, + Add(opponentGraveyard = NEW GuiGraveyard(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5, false, + mpDuelLayers->getRenderedPlayerOpponent(), this)); + //opponentHand + Add(opponentHand = NEW GuiOpponentHand(-15 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 35 + GuiGameZone::Height - 10, false, mpDuelLayers->getRenderedPlayerOpponent(), this)); //opponentLibrary Add(opponentLibrary = NEW GuiLibrary(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5 + GuiGameZone::Height + 5, false, @@ -149,10 +149,12 @@ void GuiAvatars::Render() float h = 54; if (opponent == active) { + r->FillRect(opponent->actX, opponent->actY, 40 * opponent->actZ, h+20 * opponent->actZ, ARGB(200,0,0,0)); r->FillRect(opponent->actX, opponent->actY, w * opponent->actZ, h * opponent->actZ, ARGB(200,0,0,0)); } else if (self == active) { + r->FillRect(self->actX - w * self->actZ - 4.5f, self->actY - h-28 * self->actZ, 24 * self->actZ, h+28 * self->actZ, ARGB(200,0,0,0)); r->FillRect(self->actX - w * self->actZ - 4.5f, self->actY - h * self->actZ, w * self->actZ, h * self->actZ, ARGB(200,0,0,0)); } GuiLayer::Render(); diff --git a/projects/mtg/src/GuiStatic.cpp b/projects/mtg/src/GuiStatic.cpp index 04506ead0..2b7c6c93d 100644 --- a/projects/mtg/src/GuiStatic.cpp +++ b/projects/mtg/src/GuiStatic.cpp @@ -166,7 +166,7 @@ void GuiGameZone::Render() quad->SetColor(ARGB((int)(actA),255,255,255)); if(type == GUI_EXILE) { - quad->SetColor(ARGB((int)(actA),150,150,150)); + quad->SetColor(ARGB((int)(actA),255,240,255)); } JRenderer::GetInstance()->RenderQuad(quad.get(), actX, actY, 0.0, scale * actZ, scale * actZ); diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 4cea41c66..f74227a18 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -1289,6 +1289,10 @@ ostream& operator<<(ostream& out, const MTGPlayerCards& z) out << "hand="; out << *(z.hand) << endl; } + if(z.removedFromGame->cards.size()) { + out << "exile="; + out << *(z.hand) << endl; + } return out; } @@ -1321,6 +1325,11 @@ bool MTGPlayerCards::parseLine(const string& s) battlefield->parseLine(s.substr(limiter+1)); return true; } + else if (areaS.compare("removedfromgame") == 0 || areaS.compare("exile") == 0) + { + removedFromGame->parseLine(s.substr(limiter+1)); + return true; + } } return false; diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index beab3ded7..35bb7e60f 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -46,7 +46,7 @@ MTGCardInstance * TestSuiteAI::getCard(string action) for (int i = 0; i < 2; i++) { Player * p = observer->players[i]; - MTGGameZone * zones[] = { p->game->library, p->game->hand, p->game->inPlay, p->game->graveyard, p->game->exile }; + MTGGameZone * zones[] = { p->game->library, p->game->hand, p->game->inPlay, p->game->graveyard, p->game->removedFromGame }; for (int j = 0; j < 5; j++) { MTGGameZone * zone = zones[j]; @@ -394,12 +394,12 @@ void TestSuiteGame::assertGame() error++; } - MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->exile }; + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->removedFromGame }; MTGGameZone * endstateZones[] = { endState.players[i]->game->graveyard, endState.players[i]->game->library, endState.players[i]->game->hand, endState.players[i]->game->inPlay, - endState.players[i]->game->exile }; + endState.players[i]->game->removedFromGame }; for (int j = 0; j < 5; j++) { MTGGameZone * zone = playerZones[j]; @@ -854,12 +854,12 @@ void TestSuiteGame::initGame() stringstream stream; stream << initState.players[i]->getRandomGenerator()->saveLoadedRandValues(stream); p->getRandomGenerator()->loadRandValues(stream.str()); - MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->exile }; + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->removedFromGame }; MTGGameZone * loadedPlayerZones[] = { initState.players[i]->game->graveyard, initState.players[i]->game->library, initState.players[i]->game->hand, initState.players[i]->game->inPlay, - initState.players[i]->game->exile }; + initState.players[i]->game->removedFromGame }; for (int j = 0; j < 5; j++) { MTGGameZone * zone = playerZones[j]; @@ -912,7 +912,7 @@ MTGPlayerCards * TestSuiteGame::buildDeck(Player* player, int playerId) MTGGameZone * loadedPlayerZones[] = { initState.players[playerId]->game->graveyard, initState.players[playerId]->game->library, initState.players[playerId]->game->hand, - initState.players[playerId]->game->exile, + initState.players[playerId]->game->removedFromGame, initState.players[playerId]->game->inPlay }; for (int j = 0; j < 5; j++) From bd5449a9a2a3ec0714c2c9c6c15a348a08a16cdd Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 27 Oct 2015 06:35:22 +0800 Subject: [PATCH 05/22] updated old tests the new exile zone is utilized in comparing the number of cards it has(since its enabled and viewable, the value is now counted) --- projects/mtg/bin/Res/test/aegis_of_the_meek.txt | 1 + projects/mtg/bin/Res/test/angry_mob1.txt | 1 + projects/mtg/bin/Res/test/angry_mob2.txt | 1 + projects/mtg/bin/Res/test/angry_mob3.txt | 1 + projects/mtg/bin/Res/test/angry_mob4.txt | 1 + projects/mtg/bin/Res/test/angry_mob4b.txt | 1 + projects/mtg/bin/Res/test/angry_mob5.txt | 1 + projects/mtg/bin/Res/test/angry_mob7.txt | 1 + projects/mtg/bin/Res/test/celestial_purge.txt | 1 + projects/mtg/bin/Res/test/control_magic2.txt | 1 + projects/mtg/bin/Res/test/cranial_plating.txt | 1 + projects/mtg/bin/Res/test/fists_of_ironwood.txt | 1 + projects/mtg/bin/Res/test/fizzleto_exile.txt | 1 + projects/mtg/bin/Res/test/generic/rampage3.txt | 1 + projects/mtg/bin/Res/test/karns_touch_i233.txt | 1 + projects/mtg/bin/Res/test/leveler.txt | 1 + projects/mtg/bin/Res/test/necrogenesis.txt | 1 + projects/mtg/bin/Res/test/sword_to_plowshares.txt | 1 + projects/mtg/bin/Res/test/thelon_of_havenwood.txt | 1 + projects/mtg/bin/Res/test/unearth3.txt | 1 + 20 files changed, 20 insertions(+) diff --git a/projects/mtg/bin/Res/test/aegis_of_the_meek.txt b/projects/mtg/bin/Res/test/aegis_of_the_meek.txt index 114710b9d..8104e890c 100644 --- a/projects/mtg/bin/Res/test/aegis_of_the_meek.txt +++ b/projects/mtg/bin/Res/test/aegis_of_the_meek.txt @@ -23,6 +23,7 @@ firstmain [PLAYER1] inplay:Aegis of the Meek,Steppe Lynx,Savannah Lions,Courier Hawk graveyard:Swords to Plowshares +exile:Raging Goblin life:22 [PLAYER2] [END] diff --git a/projects/mtg/bin/Res/test/angry_mob1.txt b/projects/mtg/bin/Res/test/angry_mob1.txt index b67b42e3b..63d7dbde4 100644 --- a/projects/mtg/bin/Res/test/angry_mob1.txt +++ b/projects/mtg/bin/Res/test/angry_mob1.txt @@ -16,6 +16,7 @@ Angry Mob firstmain [PLAYER1] graveyard:Swords to Plowshares +exile:Angry Mob life:25 [PLAYER2] inplay:1373,1374,1375 diff --git a/projects/mtg/bin/Res/test/angry_mob2.txt b/projects/mtg/bin/Res/test/angry_mob2.txt index eba0817f5..7ccb6de6f 100644 --- a/projects/mtg/bin/Res/test/angry_mob2.txt +++ b/projects/mtg/bin/Res/test/angry_mob2.txt @@ -19,6 +19,7 @@ Angry Mob [ASSERT] firstmain [PLAYER1] +exile:Angry Mob graveyard:Swords to Plowshares,Boomerang life:24 [PLAYER2] diff --git a/projects/mtg/bin/Res/test/angry_mob3.txt b/projects/mtg/bin/Res/test/angry_mob3.txt index 00a84e8d6..936a7a8e1 100644 --- a/projects/mtg/bin/Res/test/angry_mob3.txt +++ b/projects/mtg/bin/Res/test/angry_mob3.txt @@ -22,6 +22,7 @@ Angry Mob [ASSERT] firstmain [PLAYER1] +exile:Angry Mob life:22 [PLAYER2] inplay:1373,1374,1375,Plains diff --git a/projects/mtg/bin/Res/test/angry_mob4.txt b/projects/mtg/bin/Res/test/angry_mob4.txt index e2a08256a..0077db594 100644 --- a/projects/mtg/bin/Res/test/angry_mob4.txt +++ b/projects/mtg/bin/Res/test/angry_mob4.txt @@ -25,6 +25,7 @@ Angry Mob [ASSERT] firstmain [PLAYER1] +exile:Angry Mob life:22 [PLAYER2] inplay:1373,1374,1375,Plains diff --git a/projects/mtg/bin/Res/test/angry_mob4b.txt b/projects/mtg/bin/Res/test/angry_mob4b.txt index 76be465d0..38a33177a 100644 --- a/projects/mtg/bin/Res/test/angry_mob4b.txt +++ b/projects/mtg/bin/Res/test/angry_mob4b.txt @@ -29,6 +29,7 @@ Angry Mob [ASSERT] firstmain [PLAYER1] +exile:Angry Mob life:22 [PLAYER2] inplay:1373,1374,Plains diff --git a/projects/mtg/bin/Res/test/angry_mob5.txt b/projects/mtg/bin/Res/test/angry_mob5.txt index 12d26b0be..85e812dd1 100644 --- a/projects/mtg/bin/Res/test/angry_mob5.txt +++ b/projects/mtg/bin/Res/test/angry_mob5.txt @@ -23,6 +23,7 @@ Angry Mob [ASSERT] firstmain [PLAYER1] +exile:Angry Mob inplay:Plains graveyard:Swords to Plowshares life:25 diff --git a/projects/mtg/bin/Res/test/angry_mob7.txt b/projects/mtg/bin/Res/test/angry_mob7.txt index d82073fa7..2ca2eb106 100644 --- a/projects/mtg/bin/Res/test/angry_mob7.txt +++ b/projects/mtg/bin/Res/test/angry_mob7.txt @@ -22,6 +22,7 @@ Angry Mob firstmain [PLAYER1] graveyard:Swords to Plowshares,Annex,Demystify +exile:Angry Mob life:25 [PLAYER2] inplay:1373,1374,1375 diff --git a/projects/mtg/bin/Res/test/celestial_purge.txt b/projects/mtg/bin/Res/test/celestial_purge.txt index 69492a32e..fccdd052c 100644 --- a/projects/mtg/bin/Res/test/celestial_purge.txt +++ b/projects/mtg/bin/Res/test/celestial_purge.txt @@ -15,4 +15,5 @@ FIRSTMAIN graveyard:183055 manapool:{0} [PLAYER2] +exile:184994 [END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/control_magic2.txt b/projects/mtg/bin/Res/test/control_magic2.txt index a64751632..67e6f0099 100644 --- a/projects/mtg/bin/Res/test/control_magic2.txt +++ b/projects/mtg/bin/Res/test/control_magic2.txt @@ -28,6 +28,7 @@ graveyard:1194 manapool:{0} life:24 [PLAYER2] +exile:1366 graveyard:1367 inplay:1397 manapool:{0} diff --git a/projects/mtg/bin/Res/test/cranial_plating.txt b/projects/mtg/bin/Res/test/cranial_plating.txt index 3de1d04f2..184321939 100644 --- a/projects/mtg/bin/Res/test/cranial_plating.txt +++ b/projects/mtg/bin/Res/test/cranial_plating.txt @@ -19,6 +19,7 @@ Grizzly Bears [ASSERT] combatattackers [PLAYER1] +exile:Grizzly Bears inplay:Cranial Plating,Rod of Ruin graveyard:Swords to Plowshares life:24 diff --git a/projects/mtg/bin/Res/test/fists_of_ironwood.txt b/projects/mtg/bin/Res/test/fists_of_ironwood.txt index 7e852fa3b..8cfb9a324 100644 --- a/projects/mtg/bin/Res/test/fists_of_ironwood.txt +++ b/projects/mtg/bin/Res/test/fists_of_ironwood.txt @@ -19,6 +19,7 @@ endinterruption [ASSERT] FIRSTMAIN [PLAYER1] +exile:grizzly bears graveyard:fists of ironwood life:22 [PLAYER2] diff --git a/projects/mtg/bin/Res/test/fizzleto_exile.txt b/projects/mtg/bin/Res/test/fizzleto_exile.txt index cb9e4fe7a..3ca6532a3 100644 --- a/projects/mtg/bin/Res/test/fizzleto_exile.txt +++ b/projects/mtg/bin/Res/test/fizzleto_exile.txt @@ -17,6 +17,7 @@ endinterruption [ASSERT] FIRSTMAIN [PLAYER1] +exile:bad moon manapool:{0} life:20 [PLAYER2] diff --git a/projects/mtg/bin/Res/test/generic/rampage3.txt b/projects/mtg/bin/Res/test/generic/rampage3.txt index 04ff5c715..8e598e1f0 100644 --- a/projects/mtg/bin/Res/test/generic/rampage3.txt +++ b/projects/mtg/bin/Res/test/generic/rampage3.txt @@ -26,6 +26,7 @@ secondmain [PLAYER1] inplay:Plains graveyard:Swords to Plowshares +exile:Frost Giant life:28 [PLAYER2] graveyard:Suntail Hawk,Scryb Sprites,Raging Goblin diff --git a/projects/mtg/bin/Res/test/karns_touch_i233.txt b/projects/mtg/bin/Res/test/karns_touch_i233.txt index 7c0b36aab..aa9ac8c17 100644 --- a/projects/mtg/bin/Res/test/karns_touch_i233.txt +++ b/projects/mtg/bin/Res/test/karns_touch_i233.txt @@ -18,6 +18,7 @@ Jayemdae Tome [ASSERT] firstmain [PLAYER1] +exile:Jayemdae Tome graveyard:Karn's Touch,Swords to Plowshares life:24 [PLAYER2] diff --git a/projects/mtg/bin/Res/test/leveler.txt b/projects/mtg/bin/Res/test/leveler.txt index a00f1860a..a58558a75 100644 --- a/projects/mtg/bin/Res/test/leveler.txt +++ b/projects/mtg/bin/Res/test/leveler.txt @@ -11,6 +11,7 @@ leveler [ASSERT] FIRSTMAIN [PLAYER1] +exile:swamp,mountain inplay:leveler [PLAYER2] [END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/necrogenesis.txt b/projects/mtg/bin/Res/test/necrogenesis.txt index a330a02d0..fbe6bbcb4 100644 --- a/projects/mtg/bin/Res/test/necrogenesis.txt +++ b/projects/mtg/bin/Res/test/necrogenesis.txt @@ -16,4 +16,5 @@ FIRSTMAIN inplay:necrogenesis,* manapool:{0} [PLAYER2] +exile:1250 [END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/sword_to_plowshares.txt b/projects/mtg/bin/Res/test/sword_to_plowshares.txt index 16fda5125..5ca45d047 100644 --- a/projects/mtg/bin/Res/test/sword_to_plowshares.txt +++ b/projects/mtg/bin/Res/test/sword_to_plowshares.txt @@ -16,5 +16,6 @@ FIRSTMAIN graveyard:1367 manapool:{0} [PLAYER2] +exile:141935 life:23 [END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/thelon_of_havenwood.txt b/projects/mtg/bin/Res/test/thelon_of_havenwood.txt index 5d1853199..6a697f9a4 100644 --- a/projects/mtg/bin/Res/test/thelon_of_havenwood.txt +++ b/projects/mtg/bin/Res/test/thelon_of_havenwood.txt @@ -25,6 +25,7 @@ next [assert] secondmain [player1] +exile:fungusaur inplay:Thelon Of Havenwood,Thallid,Deathspore Thallid,forest,swamp [player2] life:14 diff --git a/projects/mtg/bin/Res/test/unearth3.txt b/projects/mtg/bin/Res/test/unearth3.txt index 7c6e8af54..2344bb1f5 100644 --- a/projects/mtg/bin/Res/test/unearth3.txt +++ b/projects/mtg/bin/Res/test/unearth3.txt @@ -24,6 +24,7 @@ next [ASSERT] CLEANUP [PLAYER1] +exile:Dregscape Zombie inplay:129754 [PLAYER2] graveyard:Grizzly Bears From 56fc735b3652629a1081ac10e7091f680bce79d1 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 27 Oct 2015 07:05:57 +0800 Subject: [PATCH 06/22] Parenthesis Try to fix PSP compilation --- projects/mtg/src/AllAbilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 1a48ccc74..4a796159c 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -5244,7 +5244,7 @@ void ABlink::Update(float dt) resolveBlink(); } - if ((blinkueot && currentPhase == MTG_PHASE_ENDOFTURN) || (blinkForSource && !source->isInPlay(game)) && Blinked->blinked) + if ((blinkueot && currentPhase == MTG_PHASE_ENDOFTURN) || (blinkForSource && !source->isInPlay(game)) && (Blinked->blinked)) { if (Blinked == NULL) MTGAbility::Update(dt); From d2f3e2cd60c183ab668bfd6840fc537002fdd1c3 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 27 Oct 2015 19:44:22 +0800 Subject: [PATCH 07/22] Castcard, Rebound and other fixes --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 174 +++++++++++++----- .../bin/Res/sets/primitives/unsupported.txt | 56 ------ projects/mtg/src/AllAbilities.cpp | 33 +++- projects/mtg/src/MTGAbility.cpp | 15 ++ projects/mtg/src/TargetChooser.cpp | 4 + 5 files changed, 175 insertions(+), 107 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index eaed73793..4f595bec7 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -7313,7 +7313,7 @@ type=Enchantment name=Banishing Stroke target=*[artifact;creature;enchantment] auto=bottomoflibrary -autohand=restriction{miracle} pay[[{W}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{W}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Put target artifact, creature, or enchantment on the bottom of its owner's library. -- Miracle {W} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={5}{W} type=Instant @@ -9657,7 +9657,7 @@ subtype=Aura [card] name=Blessings of Nature auto=ability$!counter(1/1,1) target(creature)!$ controller && ability$!counter(1/1,1) target(creature)!$ controller && ability$!counter(1/1,1) target(creature)!$ controller && ability$!counter(1/1,1) target(creature)!$ controller -autohand=restriction{miracle} pay[[{G}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{G}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Distribute four +1/+1 counters among any number of target creatures. -- Miracle {G} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={4}{G} type=Sorcery @@ -12231,7 +12231,7 @@ type=Instant [card] name=Brand of Ill Omen target=creature -auto=cumulativeupcost[{R}] sacrifice +auto=cumulativeupcostmulti[{R}] sacrifice all(this) auto=transforms((,newability[maxCast(creature)0 controller])) text=Enchant creature -- Cumulative upkeep {R} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Enchanted creature's controller can't cast creature spells. mana={3}{R} @@ -15829,7 +15829,7 @@ name=Chandra Ablaze auto=counter(0/0,5,loyalty) auto={C(0/0,1,Loyalty)}:name(discard a card) all(this) transforms((,newability[reject notatarget(*|myhand)],newability[@discarded(*[red]|myhand) once:damage:4 target(*[creature;player])])) ueot auto={C(0/0,-2,Loyalty)}:name(discard hand) reject all(*|hand) && draw:3 all(player) -auto={C(0/0,-7,Loyalty)}:name(cast cards) castcard(normal) target(*[instant;sorcery]|mygraveyard) +auto={C(0/0,-7,Loyalty)}:name(cast cards) castcard(restricted) target(*[instant;sorcery]|mygraveyard) text=+1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to target creature or player. -- -2: Each player discards his or her hand, then draws three cards. -- -7: Cast any number of red instant and/or sorcery cards from your graveyard without paying their mana costs. mana={4}{R}{R} type=Planeswalker @@ -24428,7 +24428,7 @@ type=Sorcery [card] name=Devastation Tide auto=moveTo(ownerhand) all(*[-land]) -autohand=restriction{miracle} pay[[{1}{U}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{1}{U}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Return all nonland permanents to their owners' hands. -- Miracle {1}{U} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={3}{U}{U} type=Sorcery @@ -24711,7 +24711,7 @@ toughness=1 [card] name=Diluvian Primordial abilities=flying -auto=may target(*[instant;sorcery]|opponentgraveyard) castcard(normal) and!(transforms((,newability[exiledeath])) forever)! +auto=may target(*[instant;sorcery]|opponentgraveyard) castcard(restricted) and!(transforms((,newability[exiledeath])) forever)! text=Flying -- When Diluvian Primordial enters the battlefield, for each opponent, you may cast up to one target instant or sorcery card from that player's graveyard without paying its mana cost. If a card cast this way would be put into a graveyard this turn, exile it instead. mana={5}{U}{U} type=Creature @@ -25416,6 +25416,16 @@ mana={X}{U}{U}{U} type=Sorcery [/card] [card] +name=Distortion Strike +target=creature +auto=1/0 +auto=unblockable +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={U} +type=Sorcery +text=Target creature gets +1/+0 until end of turn and is unblockable this turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Distress target=player auto=if type(*[-land]|targetedpersonshand)~lessthan~1 then name(look) donothing notatarget(*|targetedpersonshand) else reject notatarget(*[-land]|targetedpersonshand) @@ -29901,6 +29911,19 @@ power=2 toughness=3 [/card] [card] +name=Emerge Unscathed +target=creature|mybattlefield +auto=choice name(green) transforms((,newability[protection from green])) ueot +auto=choice name(red) transforms((,newability[protection from red])) ueot +auto=choice name(blue) transforms((,newability[protection from blue])) ueot +auto=choice name(black) transforms((,newability[protection from black])) ueot +auto=choice name(white) transforms((,newability[protection from white])) ueot +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={W} +type=Instant +text=Target creature you control gains protection from the color of your choice until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Emeria, the Sky Ruin auto=tap auto={T}:add{W} @@ -33113,8 +33136,12 @@ type=Instant [card] name=Feat of Resistance target=creature|mybattlefield +auto=choice name(green) transforms((,newability[protection from green])) ueot +auto=choice name(red) transforms((,newability[protection from red])) ueot +auto=choice name(blue) transforms((,newability[protection from blue])) ueot +auto=choice name(black) transforms((,newability[protection from black])) ueot +auto=choice name(white) transforms((,newability[protection from white])) ueot auto=counter(1/1) -auto=activatechooseacolor protection from(*[chosencolor]) ueot activatechooseend text=Put a +1/+1 counter on target creature you control. It gains protection from the color of your choice until end of turn. mana={1}{W} type=Instant @@ -53638,7 +53665,7 @@ toughness=2 [card] name=Knowledge Exploitation target=opponent -auto=target(*[instant;sorcery]|targetedpersonslibrary) castcard(normal) +auto=target(*[instant;sorcery]|targetedpersonslibrary) castcard(restricted) other={3}{U} name(Prowl) otherrestriction=prowl text=Prowl {3}{U} (You may cast this for its prowl cost if you dealt combat damage to a player this turn with a Rogue.) -- Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles his or her library. @@ -54502,7 +54529,7 @@ toughness=1 name=Krovikan Whispers alias=1194 target=creature -auto=cumulativeupcost[{U}{B}] sacrifice +auto=cumulativeupcostmulti[{U}{B}] sacrifice all(this) auto=@movedTo(this|graveyard) from(battlefield):thisforeach(counter{0/0.1.Age}) life:-2 controller text=Enchant creature -- Cumulative upkeep {U} or {B} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- You control enchanted creature. -- When Krovikan Whispers is put into a graveyard from the battlefield, you lose 2 life for each age counter on it. mana={3}{U} @@ -58425,7 +58452,7 @@ subtype=Mountain name=Maddening Wind target=creature auto=@each targetcontroller upkeep:damage:2 targetController -auto=cumulativeupcost[{G}] sacrifice +auto=cumulativeupcostmulti[{G}] sacrifice all(this) text=Enchant creature -- Cumulative upkeep {G} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- At the beginning of the upkeep of enchanted creature's controller, Maddening Wind deals 2 damage to that player. mana={2}{G} type=Enchantment @@ -58444,7 +58471,7 @@ toughness=4 [card] name=Maelstrom Archangel abilities=flying -auto=@combatdamaged(player) from(this):may target(*[-land]|myhand) castcard(normal) +auto=@combatdamaged(player) from(this):may target(*[-land]|myhand) castcard(restricted) text=Flying -- Whenever Maelstrom Archangel deals combat damage to a player, you may cast a nonland card from your hand without paying its mana cost. mana={W}{U}{B}{R}{G} type=Creature @@ -58911,7 +58938,7 @@ toughness=4 [/card] [card] name=Magus of the Jar -auto={T}{S}:name(hand blink) all(*|hand) transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once] reject all(*|hand)],newability[phaseaction[endofturn once] moveTo(ownerhand)])) && draw:7 all(player) +auto={T}{S}:name(hand blink) all(*|hand) transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] moveto(ownerhand)])) && ability$!draw:7 all(player) _ phaseaction[endofturn once] reject all(*|hand)!$ controller text={T}, Sacrifice Magus of the Jar: Each player exiles all cards from his or her hand face down and draws seven cards. At the beginning of the next end step, each player discards his or her hand and returns to his or her hand each card he or she exiled this way. mana={3}{U}{U} type=Creature @@ -61113,7 +61140,7 @@ type=Enchantment [/card] [card] name=Memory Jar -auto={T}{S}:name(hand blink) all(*|hand) transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once] reject all(*|hand)],newability[phaseaction[endofturn once] moveTo(ownerhand)])) && draw:7 all(player) +auto={T}{S}:name(hand blink) all(*|hand) transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] moveto(ownerhand)])) && ability$!draw:7 all(player) _ phaseaction[endofturn once] reject all(*|hand)!$ controller text={T}, Sacrifice Memory Jar: Each player exiles all cards from his or her hand face down and draws seven cards. At the beginning of the next end step, each player discards his or her hand and returns to his or her hand each card he or she exiled this way. mana={5} type=Artifact @@ -61129,7 +61156,7 @@ type=Instant [card] name=Memory Plunder target=*[instant;sorcery]|opponentgraveyard -auto=castcard(normal) +auto=castcard(restricted) text=You may cast target instant or sorcery card from an opponent's graveyard without paying its mana cost. mana={UB}{UB}{UB}{UB} type=Instant @@ -62175,7 +62202,7 @@ type=Instant [card] name=Mind Harness target=creature(red;green) -auto=cumulativeupcost[{1}] sacrifice +auto=cumulativeupcostmulti[{1}] sacrifice all(this) text=Enchant red or green creature -- Cumulative upkeep {1} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- You control enchanted creature. mana={U} type=Enchantment @@ -62334,7 +62361,7 @@ toughness=1 [/card] [card] name=Mindclaw Shaman -auto=choice name(target opponent) target(opponent) donothing && all(this) transforms((,newability[if type(*[instant;sorcery]|targetedpersonshand)~lessthan~1 then name(look) donothing notatarget(*|targetedpersonshand) else may castcard(normal) notatarget(*[instant;sorcery]|targetedpersonshand)])) forever +auto=choice name(target opponent) target(opponent) donothing && all(this) transforms((,newability[if type(*[instant;sorcery]|targetedpersonshand)~lessthan~1 then name(look) donothing notatarget(*|targetedpersonshand) else may castcard(restricted) notatarget(*[instant;sorcery]|targetedpersonshand)])) forever text=When Mindclaw Shaman enters the battlefield, target opponent reveals his or her hand. You may cast an instant or sorcery card from it without paying its mana cost. mana={4}{R} type=Creature @@ -62383,8 +62410,8 @@ toughness=1 [card] name=Mindleech Mass abilities=trample -auto=@combatdamagefoeof(player) from(this):may target(*[-land]|opponenthand) castcard(normal) -auto=@combatdamageof(player) from(this):may target(*[-land]|myhand) castcard(normal) +auto=@combatdamagefoeof(player) from(this):may target(*[-land]|opponenthand) castcard(restricted) +auto=@combatdamageof(player) from(this):may target(*[-land]|myhand) castcard(restricted) text=Trample -- Whenever Mindleech Mass deals combat damage to a player, you may look at that player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost. mana={5}{U}{B}{B} type=Creature @@ -65603,7 +65630,7 @@ type=Instant [card] name=Mystic Might target=land|myBattlefield -auto=cumulativeupcost[{1}{U}] sacrifice +auto=cumulativeupcostmulti[{1}{U}] sacrifice all(this) auto=teach(land) {T}:2/2 target(creature) text=Enchant land you control -- Cumulative upkeep {1}{U} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Enchanted land has "{T}: Target creature gets +2/+2 until end of turn." mana={U} @@ -67876,6 +67903,14 @@ power=2 toughness=1 [/card] [card] +name=Nomads' Assembly +auto=token(Kor Soldier,Creature Kor Soldier,1/1,white)*type:creature:mybattlefield +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={4}{W}{W} +type=Sorcery +text=Put a 1/1 white Kor Soldier creature token onto the battlefield for each creature you control. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Nomad Decoy auto={W}{T}:tap target(creature) auto=aslongas(*|mygraveyard) {W}{W}{T}:target(<2>creature) tap >6 @@ -74374,6 +74409,15 @@ power=4 toughness=4 [/card] [card] +name=Prey's Vengeance +target=creature +auto=2/2 +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={G} +type=Instant +text=Target creature gets +2/+2 until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Price of Glory auto=lord(land) transforms((,newability[@tappedformana(this) restriction{opponentturnonly}:destroy])) text=Whenever a player taps a land for mana, if it's not that player's turn, destroy that land. @@ -78541,6 +78585,15 @@ mana={3}{W} type=Instant [/card] [card] +name=Recurring Insight +target=opponent +auto=draw:type:*:targetedpersonshand controller +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={4}{U}{U} +type=Sorcery +text=Draw cards equal to the number of cards in target opponent's hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Recurring Nightmare auto={S(creature|myBattlefield)}{H}:moveto(mybattlefield) target(creature|mygraveyard) asSorcery text=Sacrifice a creature, Return Recurring Nightmare to its owner's hand: Return target creature card from your graveyard to the battlefield. Activate this ability only any time you could cast a sorcery. @@ -78702,7 +78755,7 @@ name=Reforge the Soul auto=reject all(*|hand) auto=draw:7 opponent auto=draw:7 controller -autohand=restriction{miracle} pay[[{1}{R}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{1}{R}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Each player discards his or her hand and draws seven cards. -- Miracle {1}{R} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={3}{R}{R} type=Sorcery @@ -79802,7 +79855,7 @@ target=creature auto=6/6 auto=trample auto=lure -autohand=restriction{miracle} pay[[{G}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{G}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Until end of turn, target creature gets +6/+6 and gains trample, and all creatures able to block it this turn do so. -- Miracle {G} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={4}{G}{G} type=Sorcery @@ -87501,11 +87554,12 @@ toughness=2 [/card] [card] name=Shelter -auto=choice protection from white target(creature|myBattlefield) ueot -auto=choice protection from blue target(creature|myBattlefield) ueot -auto=choice protection from black target(creature|myBattlefield) ueot -auto=choice protection from red target(creature|myBattlefield) ueot -auto=choice protection from green target(creature|myBattlefield) ueot +target=creature|mybattlefield +auto=choice name(green) transforms((,newability[protection from green])) ueot +auto=choice name(red) transforms((,newability[protection from red])) ueot +auto=choice name(blue) transforms((,newability[protection from blue])) ueot +auto=choice name(black) transforms((,newability[protection from black])) ueot +auto=choice name(white) transforms((,newability[protection from white])) ueot auto=draw:1 controller text=Target creature you control gains protection from the color of your choice until end of turn. -- Draw a card. mana={1}{W} @@ -88995,8 +89049,8 @@ toughness=4 [card] name=Silent-Blade Oni autohand={4}{U}{B}{N}:ninjutsu -auto=@combatdamagefoeof(player) from(this):may target(*[-land]|opponenthand) castcard(normal) -auto=@combatdamageof(player) from(this):may target(*[-land]|myhand) castcard(normal) +auto=@combatdamagefoeof(player) from(this):may target(*[-land]|opponenthand) castcard(restricted) +auto=@combatdamageof(player) from(this):may target(*[-land]|myhand) castcard(restricted) text=Ninjutsu {4}{U}{B} ({4}{U}{B}, Return an unblocked attacker you control to hand: Put this card onto the battlefield from your hand tapped and attacking.) -- Whenever Silent-Blade Oni deals combat damage to a player, look at that player's hand. You may cast a nonland card in it without paying that card's mana cost. mana={3}{U}{U}{B}{B} type=Creature @@ -95173,6 +95227,15 @@ power=0 toughness=0 [/card] [card] +name=Staggershock +target=creature,player +auto=damage:2 +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={2}{R} +type=Instant +text=Staggershock deals 2 damage to target creature or player. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Stalker Hag abilities=swampwalk,forestwalk text=Swampwalk, forestwalk @@ -95558,11 +95621,11 @@ toughness=2 [card] name=Stave Off target=creature -auto=choice name(protection from white) target(creature) protection from white -auto=choice name(protection from blue) target(creature) protection from blue -auto=choice name(protection from black) target(creature) protection from black -auto=choice name(protection from red) target(creature) protection from red -auto=choice name(protection from green) target(creature) protection from green +auto=choice name(green) transforms((,newability[protection from green])) ueot +auto=choice name(red) transforms((,newability[protection from red])) ueot +auto=choice name(blue) transforms((,newability[protection from blue])) ueot +auto=choice name(black) transforms((,newability[protection from black])) ueot +auto=choice name(white) transforms((,newability[protection from white])) ueot text=Target creature gains protection from the color of your choice until end of turn. mana={W} type=Instant @@ -97715,7 +97778,7 @@ toughness=1 name=Sunforger auto={3}:equip auto=4/0 -auto=teach(creature) {unattach}{R}{W}:castcard(normal) notatarget(instant[red;white;manacost<=4]|mylibrary) +auto=teach(creature) {unattach}{R}{W}:castcard(restricted) notatarget(instant[red;white;manacost<=4]|mylibrary) text=Equipped creature gets +4/+0. -- {R}{W}, Unattach Sunforger: Search your library for a red or white instant card with converted mana cost 4 or less and cast that card without paying its mana cost. Then shuffle your library. -- Equip {3} mana={3} type=Artifact @@ -98223,6 +98286,14 @@ power=2 toughness=1 [/card] [card] +name=Surreal Memoir +auto=moverandom(instant) from(mygraveyard) to(myhand) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={3}{R} +type=Sorcery +text=Return an instant card at random from your graveyard to your hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Surveilling Sprite abilities=flying auto=@movedto(this|graveyard) from(battlefield):may draw:1 @@ -98242,6 +98313,15 @@ mana={4}{R} type=Sorcery [/card] [card] +name=Survival Cache +auto=life:2 controller +auto=if compare(lifetotal)~morethan~compare(opponentlifetotal) then draw:1 controller +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={2}{W} +type=Sorcery +text=You gain 2 life. Then if you have more life than an opponent, draw a card. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Survival of the Fittest auto={G}{discard(creature|myhand)}:moveTo(myhand) target(creature|myLibrary) text={G}, Discard a creature card: Search your library for a creature card, reveal that card, and put it into your hand. Then shuffle your library. @@ -100425,7 +100505,7 @@ type=Sorcery name=Temporal Mastery auto=turns:+1 controller auto=exiledeath -autohand=restriction{miracle} pay[[{1}{U}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{1}{U}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Take an extra turn after this one. Exile Temporal Mastery. -- Miracle {1}{U} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={5}{U}{U} type=Sorcery @@ -100678,7 +100758,7 @@ type=Instant [card] name=Terminus auto=all(creature) bottomoflibrary -autohand=restriction{miracle} pay[[{W}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{W}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Put all creatures on the bottom of their owners' libraries. -- Miracle {W} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={4}{W}{W} type=Sorcery @@ -102261,7 +102341,7 @@ type=Sorcery name=Thunderblade Charge target=creature,player auto=damage:3 -autograveyard=@combatdamaged(player) from(creature|mybattlefield):pay({2}{R}{R}{R}) name(pay to cast) activate name(pay to cast) castcard(normal) +autograveyard=@combatdamaged(player) from(creature|mybattlefield):pay({2}{R}{R}{R}) name(pay to cast) activate name(pay to cast) castcard(restricted) text=Thunderblade Charge deals 3 damage to target creature or player. -- Whenever one or more creatures you control deal combat damage to a player, if Thunderblade Charge is in your graveyard, you may pay {2}{R}{R}{R}. If you do, you may cast it without paying its mana cost. mana={1}{R}{R} type=Sorcery @@ -102405,7 +102485,7 @@ subtype=Aura name=Thunderous Wrath target=creature,player auto=damage:5 -autohand=restriction{miracle} pay[[{R}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{R}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Thunderous Wrath deals 5 damage to target creature or player. -- Miracle {R} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={4}{R}{R} type=Instant @@ -103628,7 +103708,7 @@ type=Enchantment [/card] [card] name=Toshiro Umezawa -auto=@movedto(graveyard) from(creature|opponentBattlefield):may target(*[instant]|mygraveyard) castcard(normal) and!(transforms((,newability[exiledeath])) forever)! +auto=@movedto(graveyard) from(creature|opponentBattlefield):may target(*[instant]|mygraveyard) castcard(restricted) and!(transforms((,newability[exiledeath])) forever)! auto=bushido(1/1) text=Bushido 1 (When this blocks or becomes blocked, it gets +1/+1 until end of turn.) -- Whenever a creature an opponent controls is put into a graveyard from the battlefield, you may cast target instant card from your graveyard. If that card would be put into a graveyard this turn, exile it instead. mana={1}{B}{B} @@ -107520,7 +107600,7 @@ subtype=Aura name=Vanishment target=*[-land] auto=moveTo(ownerlibrary) -autohand=restriction{miracle} pay[[{U}]] name(Miracle) activate name(Miracle) castcard(normal) +autohand=restriction{miracle} pay[[{U}]] name(Miracle) activate name(Miracle) castcard(restricted) text=Put target nonland permanent on top of its owner's library. -- Miracle {U} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) mana={4}{U} type=Instant @@ -109399,6 +109479,16 @@ power=1 toughness=1 [/card] [card] +name=Virulent Swipe +target=creature +auto=2/0 +auto=deathtouch +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={B} +type=Instant +text=Target creature gets +2/+0 and gains deathtouch until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Visara the Dreadful abilities=flying auto={T}:bury target(creature) @@ -114872,8 +114962,8 @@ type=Sorcery [card] name=Wrexial, the Risen Deep abilities=islandwalk,swampwalk -auto=@combatdamagefoeof(player) from(this):may target(*[instant;sorcery]|opponentgraveyard) castcard(normal) and!(transforms((,newability[exiledeath])) forever)! -auto=@combatdamageof(player) from(this):may target(*[instant;sorcery]|mygraveyard) castcard(normal) and!(transforms((,newability[exiledeath])) forever)! +auto=@combatdamagefoeof(player) from(this):may target(*[instant;sorcery]|opponentgraveyard) castcard(restricted) and!(transforms((,newability[exiledeath])) forever)! +auto=@combatdamageof(player) from(this):may target(*[instant;sorcery]|mygraveyard) castcard(restricted) and!(transforms((,newability[exiledeath])) forever)! text=Islandwalk, swampwalk -- Whenever Wrexial, the Risen Deep deals combat damage to a player, you may cast target instant or sorcery card from that player's graveyard without paying its mana cost. If that card would be put into a graveyard this turn, exile it instead. mana={3}{U}{U}{B} type=Legendary Creature diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 4be2a582b..98c44b964 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -3912,12 +3912,6 @@ mana={2}{U}{U} type=Sorcery [/card] [card] -name=Distortion Strike -mana={U} -type=Sorcery -text=Target creature gets +1/+0 until end of turn and is unblockable this turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Divert text=Change the target of target spell with a single target unless that spell's controller pays {2}. mana={U} @@ -4444,12 +4438,6 @@ toughness=1 text=Whenever another creature comes into play, you may stand up and say in a deep, booming voice "Presenting . . . " and that creature's name. If you do, put a +1/+1 counter on that creature. [/card] [card] -name=Emerge Unscathed -mana={W} -type=Instant -text=Target creature you control gains protection from the color of your choice until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Empyrial Archangel text=Flying, shroud -- All damage that would be dealt to you is dealt to Empyrial Archangel instead. mana={4}{G}{W}{W}{U} @@ -10865,14 +10853,6 @@ power=1 toughness=1 [/card] [card] -name=Nomads' Assembly -auto=token(Kor Soldier,Creature Kor Soldier,1/1,white)*type:creature:mybattlefield -auto=@movedto(this|stack) from(myhand) restriction{casted(this)}:moveto(exile) and!( transforms((,newability[@each my upkeep once:may activate castcard(restricted)])) )! forever -mana={4}{W}{W} -type=Sorcery -text=Put a 1/1 white Kor Soldier creature token onto the battlefield for each creature you control. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Norn's Annex #cant choose mana or life mana={3}{p(W)}{p(W)} @@ -12141,12 +12121,6 @@ mana={U} type=Sorcery [/card] [card] -name=Prey's Vengeance -mana={G} -type=Instant -text=Target creature gets +2/+2 until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Primal Beyond text=As Primal Beyond enters the battlefield, you may reveal an Elemental card from your hand. If you don't, Primal Beyond enters the battlefield tapped. -- {T}: Add {1} to your mana pool. -- {T}: Add one mana of any color to your mana pool. Spend this mana only to cast Elemental spells or activate abilities of Elementals. type=Land @@ -12929,12 +12903,6 @@ mana={2}{G} type=Sorcery [/card] [card] -name=Recurring Insight -mana={4}{U}{U} -type=Sorcery -text=Draw cards equal to the number of cards in target opponent's hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Recycle text=Skip your draw step. -- Whenever you play a card, draw a card. -- Your maximum hand size is two. mana={4}{G}{G} @@ -15679,12 +15647,6 @@ mana={3} type=Artifact [/card] [card] -name=Staggershock -mana={2}{R} -type=Instant -text=Staggershock deals 2 damage to target creature or player. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Stalking Yeti text=When Stalking Yeti enters the battlefield, if it's on the battlefield, it deals damage equal to its power to target creature an opponent controls and that creature deals damage equal to its power to Stalking Yeti. -- {2}{S}i}: Return Stalking Yeti to its owner's hand. Activate this ability only any time you could cast a sorcery. ({S}i} can be paid with one mana from a snow permanent.) mana={2}{R}{R} @@ -16184,18 +16146,6 @@ power=2 toughness=1 [/card] [card] -name=Surreal Memoir -mana={3}{R} -type=Sorcery -text=Return an instant card at random from your graveyard to your hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] -name=Survival Cache -mana={2}{W} -type=Sorcery -text=You gain 2 life. Then if you have more life than an opponent, draw a card. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Sutured Ghoul text=Trample -- As Sutured Ghoul enters the battlefield, exile any number of creature cards from your graveyard. -- Sutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. mana={4}{B}{B}{B} @@ -17808,12 +17758,6 @@ mana={1}{R}{G} type=Instant [/card] [card] -name=Virulent Swipe -mana={B} -type=Instant -text=Target creature gets +2/+0 and gains deathtouch until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Virulent Wound mana={B} type=Instant diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 4a796159c..7fe81b1c3 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -5244,12 +5244,15 @@ void ABlink::Update(float dt) resolveBlink(); } - if ((blinkueot && currentPhase == MTG_PHASE_ENDOFTURN) || (blinkForSource && !source->isInPlay(game)) && (Blinked->blinked)) + if ((blinkueot && currentPhase == MTG_PHASE_ENDOFTURN) || (blinkForSource && !source->isInPlay(game))) { - if (Blinked == NULL) - MTGAbility::Update(dt); - MTGCardInstance * _target = Blinked; - returnCardIntoPlay(_target); + if(Blinked->blinked) + { + if (Blinked == NULL) + MTGAbility::Update(dt); + MTGCardInstance * _target = Blinked; + returnCardIntoPlay(_target); + } } MTGAbility::Update(dt); } @@ -5724,16 +5727,28 @@ void AACastCard::Update(float dt) this->forceDestroy = 1; return; } - if(!toCheck->hasType(Subtypes::TYPE_INSTANT) && !(game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)) + /*if(!toCheck->hasType(Subtypes::TYPE_INSTANT) && !(game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)) + { + processed = true; + this->forceDestroy = 1; + return; + }*/ + } + MTGCardInstance * toCheck = (MTGCardInstance*)target; + if(theNamedCard) + toCheck = theNamedCard; + if(toCheck && toCheck->spellTargetType.size()) + { + TargetChooserFactory tcf(game); + TargetChooser * stc = tcf.createTargetChooser(toCheck->spellTargetType,toCheck); + if (!stc->validTargetsExist()||toCheck->isToken) { processed = true; this->forceDestroy = 1; return; } + SAFE_DELETE(stc); } - MTGCardInstance * toCheck = (MTGCardInstance*)target; - if(theNamedCard) - toCheck = theNamedCard; if (Spell * checkSpell = dynamic_cast(target)) { toCheck = checkSpell->source; diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index af7a2b667..c08e6288c 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -310,6 +310,21 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe return 0; } } + check = restriction[i].find("rebound"); + if(check != string::npos) + { + int count = 0; + for(unsigned int k = 0; k < player->game->stack->cardsSeenThisTurn.size(); k++) + { + MTGCardInstance * stackCard = player->game->stack->cardsSeenThisTurn[k]; + if(stackCard->next && stackCard->next == card && card->previousZone == card->controller()->game->hand) + count++; + if(stackCard == card && card->previousZone == card->controller()->game->hand) + count++; + } + if(!count) + return 0; + } check = restriction[i].find("morbid"); if(check != string::npos) { diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 9d58f058d..0b361ef2a 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -739,6 +739,10 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta { return NEW CardTargetChooser(observer, card->storedSourceCard, card, zones, nbzones); } + else if (typeName.compare("abilitycontroller") == 0) + { + return NEW PlayerTargetChooser(observer, card, 1, card->storedSourceCard->controller()); + } else { tc = NEW TypeTargetChooser(observer, typeName.c_str(), zones, nbzones, card, maxtargets, other, targetMin); From 40db1180dfff7fa6d4947d8c4fd75f5168a8fb4d Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 29 Oct 2015 06:38:59 +0800 Subject: [PATCH 08/22] pay zero todo: all zones --- projects/mtg/include/MTGDefinitions.h | 3 ++- projects/mtg/src/MTGDefinitions.cpp | 3 ++- projects/mtg/src/MTGRules.cpp | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index 6a0d398fe..b321943e7 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -234,7 +234,8 @@ class Constants PROTECTIONFROMCOLOREDSPELLS = 116, MYGCREATUREEXILER = 117, OPPGCREATUREEXILER = 118, - NB_BASIC_ABILITIES = 119, + PAYZERO = 119, + NB_BASIC_ABILITIES = 120, RARITY_S = 'S', //Special Rarity diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index 0dd76ef59..91bbc8148 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -147,7 +147,8 @@ const char* Constants::MTGBasicAbilities[] = { "madness", "protectionfromcoloredspells", "mygcreatureexiler", - "oppgcreatureexiler" + "oppgcreatureexiler", + "payzero" }; map Constants::MTGBasicAbilitiesMap; diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 458e63789..396b46c70 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1139,6 +1139,8 @@ int MTGPlayFromGraveyardRule::isReactingToClick(MTGCardInstance * card, ManaCost { Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); + if (card->has(Constants::PAYZERO)) + cost = ManaCost::parseManaCost("{0}",NULL,NULL); if (!player->game->graveyard->hasCard(card)) return 0; @@ -1154,7 +1156,8 @@ int MTGPlayFromGraveyardRule::reactToClick(MTGCardInstance * card) return 0; ManaCost * cost = card->getManaCost(); - + if (card->has(Constants::PAYZERO)) + cost = ManaCost::parseManaCost("{0}",NULL,NULL); card->paymenttype = MTGAbility::PUT_INTO_PLAY; return MTGAlternativeCostRule::reactToClick(card, cost, ManaCost::MANA_PAID); From 8793feb9baa5d6779cd496dda027ead634184d9b Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Fri, 30 Oct 2015 07:11:16 +0800 Subject: [PATCH 09/22] Altercost Altercost alter cards to be cast... Removed Trinisphere temporarily... --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 11 +- .../bin/Res/sets/primitives/unsupported.txt | 9 + projects/mtg/include/AllAbilities.h | 7 +- projects/mtg/include/MTGCardInstance.h | 2 + projects/mtg/include/MTGDefinitions.h | 3 +- projects/mtg/src/AllAbilities.cpp | 43 ++- projects/mtg/src/CardDescriptor.cpp | 7 +- projects/mtg/src/GameObserver.cpp | 345 ++++++++++++------ projects/mtg/src/MTGAbility.cpp | 9 +- projects/mtg/src/MTGCardInstance.cpp | 2 + projects/mtg/src/MTGDefinitions.cpp | 3 +- projects/mtg/src/MTGRules.cpp | 5 +- 12 files changed, 297 insertions(+), 149 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 4f595bec7..82dc987c7 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -104963,15 +104963,6 @@ mana={5} type=Artifact [/card] [card] -name=Trinisphere -auto=this(untapped) lord(*[manacost=0]|hand) altercost(colorless, +3) -auto=this(untapped) lord(*[manacost=1]|hand) altercost(colorless, +2) -auto=this(untapped) lord(*[manacost=2]|hand) altercost(colorless, +1) -text=As long as Trinisphere is untapped, each spell that would cost less than three mana to cast costs three mana to cast. (Additional mana in the cost may be paid with any color of mana or colorless mana. For example, a spell that would cost {1}{B} to cast costs {2}{B} to cast instead.) -mana={3} -type=Artifact -[/card] -[card] name=Trinket Mage auto=may moveTo(myhand) target(artifact[manacost<=1]|mylibrary) text=When Trinket Mage enters the battlefield, you may search your library for an artifact card with converted mana cost 1 or less, reveal that card, and put it into your hand. If you do, shuffle your library. @@ -111696,7 +111687,7 @@ toughness=2 [card] name=Warden of Evos Isle abilities=flying -auto=lord(creature[flying]|myhand) altercost(colorless, -1) +auto=lord(creature[flying]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) text=Flying. -- Creature spells with flying you cast cost 1 less to cast. mana={2}{U} type=Creature diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 98c44b964..1432ba3ff 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -17156,6 +17156,15 @@ mana={U} type=Instant [/card] [card] +name=Trinisphere +auto=this(untapped) lord(*[manacost=0]|hand) altercost(colorless, +3) +auto=this(untapped) lord(*[manacost=1]|hand) altercost(colorless, +2) +auto=this(untapped) lord(*[manacost=2]|hand) altercost(colorless, +1) +text=As long as Trinisphere is untapped, each spell that would cost less than three mana to cast costs three mana to cast. (Additional mana in the cost may be paid with any color of mana or colorless mana. For example, a spell that would cost {1}{B} to cast costs {2}{B} to cast instead.) +mana={3} +type=Artifact +[/card] +[card] name=Trumpeting Armodon text={1}{G}: Target creature blocks Trumpeting Armodon this turn if able. mana={3}{G} diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 2f6d40e6c..88b6a4d78 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -195,10 +195,11 @@ private: } else if (s == "manacost") { + int convertedvalue = card->currentZone == card->controller()->game->battlefield ? card->getManaCost()->getConvertedCost():card->model->data->getManaCost()->getConvertedCost(); if (target->currentZone == target->controller()->game->stack)//X is 0 except if it's on the stack intValue = target->getManaCost()->getConvertedCost() + target->castX; else - intValue = target->getManaCost()->getConvertedCost(); + intValue = convertedvalue; } else if (s == "azorius")//devotion blue white { @@ -6360,13 +6361,13 @@ class GenericPaidAbility: public ActivatedAbility public: MTGAbility * baseAbility; ManaCost * optionalCost; - + bool asAlternate; string newName; string restrictions; string baseCost; string baseAbilityStr; - GenericPaidAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target,string _newName,string _castRestriction,string _mayCost, string toAdd, ManaCost * cost = NULL); + GenericPaidAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target,string _newName,string _castRestriction,string _mayCost, string toAdd, bool asAlternate = false, ManaCost * cost = NULL); int resolve(); const string getMenuText(); GenericPaidAbility * clone() const; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 5146b4940..6600e7a1e 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -253,6 +253,8 @@ public: int cardistargetted; bool isTargetter(); int cardistargetter; + int tmodifier; + int tmodifierb; void eventattacked(); void eventattackedAlone(); diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index b321943e7..cc45e19b2 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -235,7 +235,8 @@ class Constants MYGCREATUREEXILER = 117, OPPGCREATUREEXILER = 118, PAYZERO = 119, - NB_BASIC_ABILITIES = 120, + TRINISPHERE = 120, + NB_BASIC_ABILITIES = 121, RARITY_S = 'S', //Special Rarity diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 7fe81b1c3..ccf0e714d 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1146,9 +1146,9 @@ AASetCoin::~AASetCoin() //paying for an ability as an effect but as a cost GenericPaidAbility::GenericPaidAbility(GameObserver* observer, int id, MTGCardInstance * source, - Targetable * target, string _newName, string _castRestriction, string mayCost, string _toAdd, ManaCost * cost) : + Targetable * target, string _newName, string _castRestriction, string mayCost, string _toAdd, bool asAlternate, ManaCost * cost) : ActivatedAbility(observer, id, source, cost, 0), - newName(_newName), restrictions(_castRestriction), baseCost(mayCost), baseAbilityStr(_toAdd) + newName(_newName), restrictions(_castRestriction), baseCost(mayCost), baseAbilityStr(_toAdd), asAlternate(asAlternate) { this->GetId(); baseAbility = NULL; @@ -1172,6 +1172,8 @@ int GenericPaidAbility::resolve() AbilityFactory Af(game); vector baseAbilityStrSplit = split(baseAbilityStr,'?'); vector selection; + MTGAbility * nomenuAbility = NULL; + bool nomenu = false; if (baseAbilityStrSplit.size() > 1) { baseAbility = Af.parseMagicLine(baseAbilityStrSplit[0], this->GetId(), NULL, source); @@ -1200,10 +1202,12 @@ int GenericPaidAbility::resolve() } else { + nomenu = true; baseAbility = Af.parseMagicLine(baseAbilityStrSplit[0], this->GetId(), NULL, source); baseAbility->target = target; optionalCost = ManaCost::parseManaCost(baseCost, NULL, source); MTGAbility * set = baseAbility->clone(); + nomenuAbility = baseAbility->clone(); set->oneShot = true; selection.push_back(set); } @@ -1211,10 +1215,37 @@ int GenericPaidAbility::resolve() if (selection.size()) { bool must = baseAbilityStrSplit.size() > 1 ? true : false; - MenuAbility * a1 = NEW MenuAbility(game, this->GetId(), target, source, must, selection, NULL, newName); - a1->optionalCosts.push_back(NEW ManaCost(optionalCost)); - game->mLayers->actionLayer()->currentActionCard = (MTGCardInstance *)target; - a1->resolve(); + //todo get increased - reduced cost if asAlternate cost to cast using castcard + if(asAlternate) + { + must = true; + //cost increase - reduce + trinisphere effect ability todo... + if(((MTGCardInstance *)target)->getIncreasedManaCost()->getConvertedCost()) + optionalCost->add(((MTGCardInstance *)target)->getIncreasedManaCost()); + if(((MTGCardInstance *)target)->getReducedManaCost()->getConvertedCost()) + optionalCost->remove(((MTGCardInstance *)target)->getReducedManaCost()); + //trinisphere effect must be hardcoded...here.. + /*if(((MTGCardInstance *)target)->has(Constants::TRINISPHERE)) + { + if(optionalCost->getConvertedCost() == 2) + optionalCost->add(Constants::MTG_COLOR_ARTIFACT, 1); + else if(optionalCost->getConvertedCost() == 1) + optionalCost->add(Constants::MTG_COLOR_ARTIFACT, 2); + else if(optionalCost->getConvertedCost() < 1) + optionalCost->add(Constants::MTG_COLOR_ARTIFACT, 3); + }*/ + } + if(nomenu && optionalCost->getConvertedCost() < 1) + { + nomenuAbility->resolve(); + } + else + { + MenuAbility * a1 = NEW MenuAbility(game, this->GetId(), target, source, must, selection, NULL, newName); + a1->optionalCosts.push_back(NEW ManaCost(optionalCost)); + game->mLayers->actionLayer()->currentActionCard = (MTGCardInstance *)target; + a1->resolve(); + } } return 1; } diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index c6ae1e7a7..a3bc1c773 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -125,11 +125,12 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card) } // Quantified restrictions are always AND-ed: + int convertedvalue = card->currentZone == card->controller()->game->battlefield ? card->getManaCost()->getConvertedCost():card->model->data->getManaCost()->getConvertedCost(); if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power)) return NULL; if (toughnessComparisonMode && !valueInRange(toughnessComparisonMode, card->getToughness(), toughness)) return NULL; - if (manacostComparisonMode && !valueInRange(manacostComparisonMode, card->getManaCost()->getConvertedCost(), convertedManacost)) + if (manacostComparisonMode && !valueInRange(manacostComparisonMode, convertedvalue, convertedManacost)) return NULL; if (nameComparisonMode && compareName != card->name) return NULL; @@ -165,12 +166,12 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card) if ((mColorExclusions & card->colors) != 0) match = NULL; } - + int convertedvalue = card->currentZone == card->controller()->game->battlefield ? card->getManaCost()->getConvertedCost():card->model->data->getManaCost()->getConvertedCost(); if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power)) match = NULL; if (toughnessComparisonMode && !valueInRange(toughnessComparisonMode, card->getToughness(), toughness)) match = NULL; - if (manacostComparisonMode && !valueInRange(manacostComparisonMode, card->getManaCost()->getConvertedCost(), convertedManacost)) + if (manacostComparisonMode && !valueInRange(manacostComparisonMode, convertedvalue, convertedManacost)) match = NULL; if(nameComparisonMode && compareName != card->name) match = NULL; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 933ec20cf..01a1fc1ab 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -604,8 +604,8 @@ void GameObserver::gameStateBasedEffects() { for (int c = zone->nb_cards - 1; c >= 0; c--) { - zone->cards[c]->cardistargetted = 0; - zone->cards[c]->cardistargetter = 0; + zone->cards[c]->cardistargetted = 0; + zone->cards[c]->cardistargetter = 0; } } }//check for losers if its GAMEOVER clear the stack to allow gamestateeffects to continue @@ -878,8 +878,90 @@ void GameObserver::gameStateBasedEffects() enchantmentStatus(); ///////////////////////////// // Check affinity on a card// + // plus modify costs // ///////////////////////////// Affinity(); + //trinisphere? + /*for (int td = 0; td < 2; td++) + { + MTGGameZone * dzones[] = { players[td]->game->graveyard, players[td]->game->hand, players[td]->game->library, players[td]->game->exile }; + for (int tk = 0; tk < 4; tk++) + { + MTGGameZone * zone = dzones[tk]; + for (int ct = zone->nb_cards - 1; ct >= 0; ct--) + { + if(zone->cards[ct]->has(Constants::TRINISPHERE)) + { + if(zone->cards[ct]->getManaCost()->getConvertedCost() == 2) + { + zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 1); + zone->cards[ct]->tmodifier = 1; + } + else if(zone->cards[ct]->getManaCost()->getConvertedCost() == 1) + { + zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 2); + zone->cards[ct]->tmodifier = 2; + } + else if(zone->cards[ct]->getManaCost()->getConvertedCost() < 1) + { + zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 3); + zone->cards[ct]->tmodifier = 3; + } + //alternate + if(zone->cards[ct]->getManaCost()->getAlternative() && zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() == 2) + { + zone->cards[ct]->getManaCost()->getAlternative()->add(Constants::MTG_COLOR_ARTIFACT, 1); + zone->cards[ct]->tmodifierb = 1; + } + else if(zone->cards[ct]->getManaCost()->getAlternative() && zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() == 1) + { + zone->cards[ct]->getManaCost()->getAlternative()->add(Constants::MTG_COLOR_ARTIFACT, 2); + zone->cards[ct]->tmodifierb = 2; + } + else if(zone->cards[ct]->getManaCost()->getAlternative() && zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() < 1) + { + zone->cards[ct]->getManaCost()->getAlternative()->add(Constants::MTG_COLOR_ARTIFACT, 3); + zone->cards[ct]->tmodifierb = 3; + } + } + else + { + if(zone->cards[ct]->tmodifier == 1) + { + zone->cards[ct]->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, 1); + zone->cards[ct]->tmodifier = 0; + } + else if(zone->cards[ct]->tmodifier == 2) + { + zone->cards[ct]->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, 2); + zone->cards[ct]->tmodifier = 0; + } + else if(zone->cards[ct]->tmodifier == 3) + { + zone->cards[ct]->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, 3); + zone->cards[ct]->tmodifier = 0; + } + //alternate + if(zone->cards[ct]->tmodifierb == 1) + { + zone->cards[ct]->getManaCost()->getAlternative()->remove(Constants::MTG_COLOR_ARTIFACT, 1); + zone->cards[ct]->tmodifierb = 0; + } + else if(zone->cards[ct]->tmodifierb == 2) + { + zone->cards[ct]->getManaCost()->getAlternative()->remove(Constants::MTG_COLOR_ARTIFACT, 2); + zone->cards[ct]->tmodifierb = 0; + } + else if(zone->cards[ct]->tmodifierb == 3) + { + zone->cards[ct]->getManaCost()->getAlternative()->remove(Constants::MTG_COLOR_ARTIFACT, 3); + zone->cards[ct]->tmodifierb = 0; + } + } + } + } + }*/ + //end trinisphere ///////////////////////////////////// // Check colored statuses on cards // ///////////////////////////////////// @@ -954,46 +1036,140 @@ void GameObserver::enchantmentStatus() void GameObserver::Affinity() { - for (int i = 0; i < 2; i++) + for (int dd = 0; dd < 2; dd++) { - MTGGameZone * zone = players[i]->game->hand; - for (int k = zone->nb_cards - 1; k >= 0; k--) + MTGGameZone * dzones[] = { players[dd]->game->graveyard, players[dd]->game->hand, players[dd]->game->library, players[dd]->game->exile }; + for (int kk = 0; kk < 4; kk++) { - MTGCardInstance * card = zone->cards[k]; - if (!card) - continue; + MTGGameZone * zone = dzones[kk]; + for (int cc = zone->nb_cards - 1; cc >= 0; cc--) + {//start + MTGCardInstance * card = zone->cards[cc]; + if (!card) + continue; - int color = 0; - string type = ""; - //only do any of the following if a card with the stated ability is in your hand. - ManaCost * original = NEW ManaCost(); - original->copy(card->model->data->getManaCost()); - //have to run alter cost before affinity or the 2 cancel each other out. - if(card->getIncreasedManaCost()->getConvertedCost()||card->getReducedManaCost()->getConvertedCost()) - { - if(card->getIncreasedManaCost()->getConvertedCost()) - original->add(card->getIncreasedManaCost()); - if(card->getReducedManaCost()->getConvertedCost()) - original->remove(card->getReducedManaCost()); - card->getManaCost()->copy(original); - if(card->getManaCost()->extraCosts) + int color = 0; + string type = ""; + //only do any of the following if a card with the stated ability is in your hand. + ManaCost * original = NEW ManaCost(); + ManaCost * alternate = NEW ManaCost(); + original->copy(card->model->data->getManaCost()); + alternate->copy(card->model->data->getManaCost()->getAlternative()); + if (card->has(Constants::PAYZERO)) + original = ManaCost::parseManaCost("{0}",NULL,card);//can't figure out 2 or more alternative... + //have to run alter cost before affinity or the 2 cancel each other out. + if(card->getIncreasedManaCost()->getConvertedCost()||card->getReducedManaCost()->getConvertedCost()) { - for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) + if(card->getIncreasedManaCost()->getConvertedCost()) { - card->getManaCost()->extraCosts->costs[i]->setSource(card); + original->add(card->getIncreasedManaCost()); + for(int kc = Constants::MTG_COLOR_ARTIFACT; kc < Constants::NB_Colors;kc++) + { + if (card->getManaCost()->getAlternative()) + { + alternate->add(kc,card->getIncreasedManaCost()->getCost(kc)); + } + } + } + if(card->getReducedManaCost()->getConvertedCost()) + { + original->remove(card->getReducedManaCost()); + for(int kc = Constants::MTG_COLOR_ARTIFACT; kc < Constants::NB_Colors;kc++) + { + if (card->getManaCost()->getAlternative()) + { + alternate->remove(kc,card->getReducedManaCost()->getCost(kc)); + } + } + } + card->getManaCost()->copy(original); + card->getManaCost()->setAlternative(alternate); + if(card->getManaCost()->extraCosts) + { + for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) + { + card->getManaCost()->extraCosts->costs[i]->setSource(card); + } } } - } - int reducem = 0; - bool resetCost = false; - for(unsigned int na = 0; na < card->cardsAbilities.size();na++) - { - ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if(newAff) + int reducem = 0; + bool resetCost = false; + for(unsigned int na = 0; na < card->cardsAbilities.size();na++) { - if(!resetCost) + ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); + if(newAff) { - resetCost = true; + if(!resetCost) + { + resetCost = true; + card->getManaCost()->copy(original); + if(card->getManaCost()->extraCosts) + { + for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) + { + card->getManaCost()->extraCosts->costs[i]->setSource(card); + } + } + } + TargetChooserFactory tf(this); + TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); + + for (int w = 0; w < 2; ++w) + { + Player *p = this->players[w]; + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; + for (int k = 0; k < 6; k++) + { + MTGGameZone * z = zones[k]; + if (tcn->targetsZone(z)) + { + reducem += z->countByCanTarget(tcn); + } + } + } + SAFE_DELETE(tcn); + ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); + for(int j = 0; j < reducem; j++) + card->getManaCost()->remove(removingCost); + SAFE_DELETE(removingCost); + } + } + if(card->has(Constants::AFFINITYARTIFACTS)|| + card->has(Constants::AFFINITYFOREST)|| + card->has(Constants::AFFINITYGREENCREATURES)|| + card->has(Constants::AFFINITYISLAND)|| + card->has(Constants::AFFINITYMOUNTAIN)|| + card->has(Constants::AFFINITYPLAINS)|| + card->has(Constants::AFFINITYSWAMP)){ + if (card->has(Constants::AFFINITYARTIFACTS)) + { + type = "artifact"; + } + else if (card->has(Constants::AFFINITYSWAMP)) + { + type = "swamp"; + } + else if (card->has(Constants::AFFINITYMOUNTAIN)) + { + type = "mountain"; + } + else if (card->has(Constants::AFFINITYPLAINS)) + { + type = "plains"; + } + else if (card->has(Constants::AFFINITYISLAND)) + { + type = "island"; + } + else if (card->has(Constants::AFFINITYFOREST)) + { + type = "forest"; + } + else if (card->has(Constants::AFFINITYGREENCREATURES)) + { + color = 1; + type = "creature"; + } card->getManaCost()->copy(original); if(card->getManaCost()->extraCosts) { @@ -1002,94 +1178,27 @@ void GameObserver::Affinity() card->getManaCost()->extraCosts->costs[i]->setSource(card); } } - } - TargetChooserFactory tf(this); - TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); - - for (int w = 0; w < 2; ++w) - { - Player *p = this->players[w]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; - for (int k = 0; k < 6; k++) + int reduce = 0; + if(card->has(Constants::AFFINITYGREENCREATURES)) { - MTGGameZone * z = zones[k]; - if (tcn->targetsZone(z)) - { - reducem += z->countByCanTarget(tcn); - } + TargetChooserFactory tf(this); + TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); + reduce = card->controller()->game->battlefield->countByCanTarget(tc); + SAFE_DELETE(tc); } - } - SAFE_DELETE(tcn); - ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); - for(int j = 0; j < reducem; j++) - card->getManaCost()->remove(removingCost); - SAFE_DELETE(removingCost); + else + { + reduce = card->controller()->game->battlefield->countByType(type); + } + for(int i = 0; i < reduce;i++) + { + if(card->getManaCost()->getCost(color) > 0) + card->getManaCost()->remove(color,1); + } + } - } - if(card->has(Constants::AFFINITYARTIFACTS)|| - card->has(Constants::AFFINITYFOREST)|| - card->has(Constants::AFFINITYGREENCREATURES)|| - card->has(Constants::AFFINITYISLAND)|| - card->has(Constants::AFFINITYMOUNTAIN)|| - card->has(Constants::AFFINITYPLAINS)|| - card->has(Constants::AFFINITYSWAMP)){ - if (card->has(Constants::AFFINITYARTIFACTS)) - { - type = "artifact"; - } - else if (card->has(Constants::AFFINITYSWAMP)) - { - type = "swamp"; - } - else if (card->has(Constants::AFFINITYMOUNTAIN)) - { - type = "mountain"; - } - else if (card->has(Constants::AFFINITYPLAINS)) - { - type = "plains"; - } - else if (card->has(Constants::AFFINITYISLAND)) - { - type = "island"; - } - else if (card->has(Constants::AFFINITYFOREST)) - { - type = "forest"; - } - else if (card->has(Constants::AFFINITYGREENCREATURES)) - { - color = 1; - type = "creature"; - } - card->getManaCost()->copy(original); - if(card->getManaCost()->extraCosts) - { - for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) - { - card->getManaCost()->extraCosts->costs[i]->setSource(card); - } - } - int reduce = 0; - if(card->has(Constants::AFFINITYGREENCREATURES)) - { - TargetChooserFactory tf(this); - TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); - reduce = card->controller()->game->battlefield->countByCanTarget(tc); - SAFE_DELETE(tc); - } - else - { - reduce = card->controller()->game->battlefield->countByType(type); - } - for(int i = 0; i < reduce;i++) - { - if(card->getManaCost()->getCost(color) > 0) - card->getManaCost()->remove(color,1); - } - - } - SAFE_DELETE(original); + SAFE_DELETE(original); + }//end } } } diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index c08e6288c..870927178 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1079,6 +1079,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG MTGGameZone * dest) { size_t found; + bool asAlternate = false; trim(s); //TODO This block redundant with calling function if (!card && spell) @@ -1088,7 +1089,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG MTGCardInstance * target = card->target; if (!target) target = card; - + //pay and castcard? + if(s.find("pay(") != string::npos || s.find("pay[[") != string::npos && s.find("castcard(restricted") != string::npos) + asAlternate = true; //MTG Specific rules //adds the bonus credit system found = s.find("bonusrule"); @@ -1586,7 +1589,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG vector splitMayPay = parseBetween(s, "pay(", ")", true); if(splitMayPay.size()) { - GenericPaidAbility * a = NEW GenericPaidAbility(observer, id, card, target,newName,castRestriction,splitMayPay[1],storedPayString); + GenericPaidAbility * a = NEW GenericPaidAbility(observer, id, card, target,newName,castRestriction,splitMayPay[1],storedPayString,asAlternate); a->oneShot = 1; a->canBeInterrupted = false; return a; @@ -2091,7 +2094,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG vector splitMayPaysub = parseBetween(s, "pay[[","]]", true); if (splitMayPaysub.size()) { - GenericPaidAbility * a = NEW GenericPaidAbility(observer, id, card, target,newName,castRestriction,splitMayPaysub[1],storedPayString); + GenericPaidAbility * a = NEW GenericPaidAbility(observer, id, card, target,newName,castRestriction,splitMayPaysub[1],storedPayString,asAlternate); a->oneShot = 1; a->canBeInterrupted = false; return a; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 140c4f5cf..287acfdb7 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -65,6 +65,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to LKItoughness = toughness; cardistargetted = 0; cardistargetter = 0; + tmodifier = 0; + tmodifierb = 0; } MTGCardInstance * MTGCardInstance::createSnapShot() diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index 91bbc8148..a2530cdb4 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -148,7 +148,8 @@ const char* Constants::MTGBasicAbilities[] = { "protectionfromcoloredspells", "mygcreatureexiler", "oppgcreatureexiler", - "payzero" + "payzero", + "trinisphere" }; map Constants::MTGBasicAbilitiesMap; diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 396b46c70..458e63789 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1139,8 +1139,6 @@ int MTGPlayFromGraveyardRule::isReactingToClick(MTGCardInstance * card, ManaCost { Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); - if (card->has(Constants::PAYZERO)) - cost = ManaCost::parseManaCost("{0}",NULL,NULL); if (!player->game->graveyard->hasCard(card)) return 0; @@ -1156,8 +1154,7 @@ int MTGPlayFromGraveyardRule::reactToClick(MTGCardInstance * card) return 0; ManaCost * cost = card->getManaCost(); - if (card->has(Constants::PAYZERO)) - cost = ManaCost::parseManaCost("{0}",NULL,NULL); + card->paymenttype = MTGAbility::PUT_INTO_PLAY; return MTGAlternativeCostRule::reactToClick(card, cost, ManaCost::MANA_PAID); From c580d89c9412a853ee0576a6f3c2521a6ae0e426 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sat, 31 Oct 2015 10:59:37 +0800 Subject: [PATCH 10/22] Altercost, Exile Zone & Handsize Modifier --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 252 +++++++++++------- .../bin/Res/sets/primitives/unsupported.txt | 54 ---- projects/mtg/include/AllAbilities.h | 19 +- projects/mtg/include/GameObserver.h | 2 + projects/mtg/include/MTGCardInstance.h | 1 + projects/mtg/include/Player.h | 1 + projects/mtg/src/AllAbilities.cpp | 43 +++ projects/mtg/src/CardDescriptor.cpp | 7 +- projects/mtg/src/GameObserver.cpp | 173 ++++++------ projects/mtg/src/MTGAbility.cpp | 9 + projects/mtg/src/MTGCardInstance.cpp | 1 + projects/mtg/src/Player.cpp | 1 + 12 files changed, 324 insertions(+), 239 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 82dc987c7..fc838d55b 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1908,7 +1908,7 @@ toughness=3 [/card] [card] name=Alabaster Leech -auto=lord(*[white]|myhand) altercost(white, +1) +auto=lord(*[white]|myhand,mylibrary,mygraveyard,myexile) altercost(white, +1) text=White spells you cast cost {W} more to cast. mana={W} type=Creature @@ -2989,7 +2989,7 @@ type=Land [/card] [card] name=Andradite Leech -auto=lord(*[black]|myhand) altercost(black,+1) +auto=lord(*[black]|myhand,mylibrary,mygraveyard,myexile) altercost(black,+1) auto={B}:1/1 text=Black spells you cast cost {B} more to cast. -- {B}: Andradite Leech gets +1/+1 until end of turn. mana={2}{B} @@ -3367,7 +3367,7 @@ subtype=Aura name=Animar, Soul of Elements abilities=protection from white,protection from black auto=@movedTo(creature|mystack):counter(1/1,1) -auto=thisforeach(counter{1/1,1}) lord(creature|myhand) altercost(colorless, -1) +auto=thisforeach(counter{1/1,1}) lord(creature|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) text=Protection from white and from black -- Whenever you cast a creature spell, put a +1/+1 counter on Animar, Soul of Elements. -- Creature spells you cast cost 1 less to cast for each +1/+1 counter on Animar. mana={U}{R}{G} type=Legendary Creature @@ -4030,8 +4030,8 @@ type=Enchantment [/card] [card] name=Arcane Melee -auto=lord(instant|hand) altercost(colorless,-2) -auto=lord(sorcery|hand) altercost(colorless,-2) +auto=lord(instant|hand,library,graveyard,exile) altercost(colorless,-2) +auto=lord(sorcery|hand,library,graveyard,exile) altercost(colorless,-2) text=Instant and sorcery spells cost {2} less to cast. mana={4}{U} type=Enchantment @@ -5809,8 +5809,8 @@ subtype=Aura [/card] [card] name=Aura of Silence -auto=lord(artifact|opponenthand) altercost(colorless, +2) -auto=lord(enchantment|opponenthand) altercost(colorless, +2) +auto=lord(artifact|opponenthand,opponentlibrary,opponentgraveyard,opponentexile) altercost(colorless, +2) +auto=lord(enchantment|opponenthand,opponentlibrary,opponentgraveyard,opponentexile) altercost(colorless, +2) auto={S}:destroy target(artifact,enchantment) text=Artifact and enchantment spells your opponents cast cost {2} more to cast. -- Sacrifice Aura of Silence: Destroy target artifact or enchantment. mana={1}{W}{W} @@ -7153,7 +7153,7 @@ toughness=2 [/card] [card] name=Ballyrush Banneret -auto=lord(*[soldier;kithkin]|myhand) altercost(colorless, -1) +auto=lord(*[soldier;kithkin]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) text=Kithkin spells and Soldier spells you cast cost {1} less to cast. mana={1}{W} type=Creature @@ -11869,7 +11869,7 @@ toughness=7 [/card] [card] name=Bosk Banneret -auto=lord(*[treefolk;shaman]|myhand) altercost(colorless, -1) +auto=lord(*[treefolk;shaman]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) text=Treefolk spells and Shaman spells you cast cost {1} less to cast. mana={1}{G} type=Creature @@ -12583,7 +12583,7 @@ type=Enchantment [/card] [card] name=Brighthearth Banneret -auto=lord(*[elemental;warrior]|myhand) altercost(colorless, -1) +auto=lord(*[elemental;warrior]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) autohand={1}{R}{discard}:counter(1/1,1) target(creature) text=Elemental spells and Warrior spells you cast cost {1} less to cast. -- Reinforce 1 - {1}{R} ({1}{R}, Discard this card: Put a +1/+1 counter on target creature.) mana={1}{R} @@ -15323,7 +15323,7 @@ toughness=3 [/card] [card] name=Centaur Omenreader -auto=this(tapped) lord(*|myhand) altercost(colorless, -2) ueot +auto=this(tapped) lord(*|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -2) ueot auto=@untapped(this):all(*|myhand) moveto(myhand) text=As long as Centaur Omenreader is tapped, creature spells you cast cost {2} less to cast. mana={3}{G} @@ -16360,8 +16360,8 @@ toughness=1 [/card] [card] name=Chill -auto=lord(*[red]|myhand) altercost(colorless, +2) -auto=lord(*[red]|opponenthand) altercost(colorless, +2) +auto=lord(*[red]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, +2) +auto=lord(*[red]|opponenthand,opponentlibrary,opponentgraveyard,opponentexile) altercost(colorless, +2) text=Red spells cost {2} more to cast. mana={1}{U} type=Enchantment @@ -17636,11 +17636,11 @@ auto=choice name(Creature) counter(0/0,1,CloudKeyC) all(this) auto=choice name(Enchantment) counter(0/0,1,CloudKeyE) all(this) auto=choice name(Instant) counter(0/0,1,CloudKeyI) all(this) auto=choice name(Sorcery) counter(0/0,1,CloudKeyS) all(this) -auto=this(counter{0/0.1.CloudKeyA}) lord(Artifact|myhand) altercost(colorless,-1) -auto=this(counter{0/0.1.CloudKeyC}) lord(Creature|myhand) altercost(colorless,-1) -auto=this(counter{0/0.1.CloudKeyE}) lord(Enchantment|myhand) altercost(colorless,-1) -auto=this(counter{0/0.1.CloudKeyI}) lord(Instant|myhand) altercost(colorless,-1) -auto=this(counter{0/0.1.CloudKeyS}) lord(Sorcery|myhand) altercost(colorless,-1) +auto=this(counter{0/0.1.CloudKeyA}) lord(Artifact|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) +auto=this(counter{0/0.1.CloudKeyC}) lord(Creature|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) +auto=this(counter{0/0.1.CloudKeyE}) lord(Enchantment|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) +auto=this(counter{0/0.1.CloudKeyI}) lord(Instant|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) +auto=this(counter{0/0.1.CloudKeyS}) lord(Sorcery|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=As Cloud Key enters the battlefield, choose artifact, creature, enchantment, instant, or sorcery. -- Spells you cast of the chosen type cost {1} less to cast. mana={3} type=Artifact @@ -22109,7 +22109,7 @@ toughness=1 [/card] [card] name=Daru Warchief -auto=lord(soldier|myhand) altercost(colorless, -1) +auto=lord(soldier|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) auto=lord(soldier|myBattlefield) 1/2 text=Soldier spells you cast cost {1} less to cast. -- Soldier creatures you control get +1/+2. mana={2}{W}{W} @@ -24106,7 +24106,7 @@ toughness=1 [/card] [card] name=Derelor -auto=lord(*[black]|myhand) altercost(black, +1) +auto=lord(*[black]|myhand,mylibrary,mygraveyard,myexile) altercost(black, +1) text=Black spells you cast cost {B} more to cast. mana={3}{B} type=Creature @@ -26364,7 +26364,7 @@ toughness=5 [/card] [card] name=Dragonlord's Servant -auto=lord(dragon|myhand) altercost(colorless, -1) +auto=lord(dragon|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) text=Dragon spells you cast cost {1} less to cast. mana={1}{R} type=Creature @@ -26431,7 +26431,7 @@ toughness=2 [/card] [card] name=Dragonspeaker Shaman -auto=lord(dragon|myhand) altercost(colorless,-2) +auto=lord(dragon|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) text=Dragon spells you cast cost {2} less to cast. mana={1}{R}{R} type=Creature @@ -28662,8 +28662,8 @@ type=Instant [/card] [card] name=Edgewalker -auto=lord(cleric|myhand) altercost(white,-1) -auto=lord(cleric|myhand) altercost(black, -1) +auto=lord(cleric|myhand,mylibrary,mygraveyard,myexile) altercost(white,-1) +auto=lord(cleric|myhand,mylibrary,mygraveyard,myexile) altercost(black, -1) text=Cleric spells you cast cost {W}{B} less to cast. This effect reduces only the amount of colored mana you pay. (For example, if you cast a Cleric spell with mana cost {1}{W}, it costs {1} to cast.) mana={1}{W}{B} type=Creature @@ -29895,7 +29895,7 @@ toughness=1 [/card] [card] name=Emerald Medallion -auto=lord(*[green]|myhand) altercost(colorless,-1) +auto=lord(*[green]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Green spells you cast cost {1} less to cast. mana={2} type=Artifact @@ -31394,7 +31394,7 @@ type=Artifact [/card] [card] name=Etherium Sculptor -auto=lord(artifact|myhand) altercost(colorless,-1) +auto=lord(artifact|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Artifact spells you cast cost {1} less to cast. mana={1}{U} type=Artifact Creature @@ -32043,7 +32043,7 @@ mana={3}{W} [/card] [card] name=Eye of Ugin -auto=lord(eldrazi[iscolorless]|myhand) altercost(colorless,-2) +auto=lord(eldrazi[iscolorless]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) auto={7}{T}:moveTo(myhand) target(creature[iscolorless]|myLibrary) text=Colorless Eldrazi spells you cast cost {2} less to cast. -- {7}, {T}: Search your library for a colorless creature card, reveal it, and put it into your hand. Then shuffle your library. type=Legendary Land @@ -33457,7 +33457,7 @@ subtype=Aura [/card] [card] name=Feroz's Ban -auto=lord(creature|hand) altercost(colorless,+2) +auto=lord(creature|hand,library,graveyard,exile) altercost(colorless,+2) text=Creature spells cost {2} more to cast. mana={6} type=Artifact @@ -36592,7 +36592,7 @@ toughness=2 [card] name=Frogtosser Banneret abilities=haste -auto=lord(*[goblin;rogue]|myhand) altercost(colorless, -1) +auto=lord(*[goblin;rogue]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) text=Haste -- Goblin spells and Rogue spells you cast cost {1} less to cast. mana={1}{B} type=Creature @@ -39588,8 +39588,8 @@ toughness=3 [/card] [card] name=Glowrider -auto=lord(*[-creature]|myhand) altercost(colorless,+1) -auto=lord(*[-creature]|opponenthand) altercost(colorless, +1) +auto=lord(*[-creature]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,+1) +auto=lord(*[-creature]|opponenthand,opponentlibrary,opponentgraveyard,opponentexile) altercost(colorless, +1) text=Noncreature spells cost {1} more to cast. mana={2}{W} type=Creature @@ -39665,6 +39665,16 @@ power=3 toughness=1 [/card] [card] +name=Gnat Miser +auto=hmodifer:-1 opponent +text=Each opponent's maximum hand size is reduced by one. +mana={B} +type=Creature +subtype=Rat Shaman +power=1 +toughness=1 +[/card] +[card] name=Gnathosaur auto={S(artifact|mybattlefield)}:trample text=Sacrifice an artifact: Gnathosaur gains trample until end of turn. @@ -40023,7 +40033,7 @@ toughness=4 [/card] [card] name=Goblin Electromancer -auto=lord(*[instant;sorcery]|myhand) altercost(colorless,-1) +auto=lord(*[instant;sorcery]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Instant and sorcery spells you cast cost {1} less to cast. mana={U}{R} type=Creature @@ -40694,7 +40704,7 @@ toughness=3 [/card] [card] name=Goblin Warchief -auto=lord(goblin|myhand) altercost(colorless,-1) +auto=lord(goblin|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) auto=lord(goblin|myBattlefield) haste text=Goblin spells you cast cost {1} less to cast. -- Goblin creatures you control have haste. mana={1}{R}{R} @@ -41381,9 +41391,9 @@ toughness=2 [/card] [card] name=Grand Arbiter Augustin IV -auto=lord(*[white]|myhand) altercost(colorless,-1) -auto=lord(*[blue]|myhand) altercost(colorless,-1) -auto=lord(*|opponenthand) altercost( colorless,+1) +auto=lord(*[white]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) +auto=lord(*[blue]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) +auto=lord(*|opponenthand,opponentlibrary,opponentgraveyard,opponentexile) altercost( colorless,+1) text=White spells you cast cost {1} less to cast. -- Blue spells you cast cost {1} less to cast. -- Spells your opponents cast cost {1} more to cast. mana={2}{W}{U} type=Legendary Creature @@ -44707,7 +44717,7 @@ toughness=3 [card] name=Heartless Summoning auto=lord(creature|myBattlefield) -1/-1 -auto=lord(creature|myhand) altercost( colorless,-2) +auto=lord(creature|myhand,mylibrary,mygraveyard,myexile) altercost( colorless,-2) text=Creature spells you cast cost {2} less to cast. -- Creatures you control get -1/-1 mana={1}{B} type=Enchantment @@ -45272,7 +45282,7 @@ toughness=1 [/card] [card] name=Helm of Awakening -auto=lord(*|hand) altercost(colorless,-1) +auto=lord(*|hand,library,graveyard,exile) altercost(colorless,-1) text=Spells cost {1} less to cast. mana={2} type=Artifact @@ -45385,7 +45395,7 @@ toughness=4 name=Herald of War abilities=flying auto=@combat(attacking) source(this):counter(1/1,1) -auto=thisforeach(counter{1/1,1}) lord(*[angel;human]|myhand) altercost(colorless, -1) +auto=thisforeach(counter{1/1,1}) lord(*[angel;human]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) text=Flying -- Whenever Herald of War attacks, put a +1/+1 counter on it. -- Angel spells and Human spells you cast cost {1} less to cast for each +1/+1 counter on Herald of War. mana={3}{W}{W} type=Creature @@ -45423,7 +45433,7 @@ toughness=2 [/card] [card] name=Herald of the Pantheon -auto=lord(enchantment|myhand) altercost(colorless, -1) +auto=lord(enchantment|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) auto=@movedto(enchantment|mystack):choice life:1 controller text=Enchantment spells you cast cost {1} less to cast. -- Whenever you cast an enchantment spell, you gain 1 life. mana={1}{G} @@ -45478,7 +45488,7 @@ toughness=4 [/card] [card] name=Hero of Iroas -auto=lord(aura|myhand) altercost(colorless,-1) +auto=lord(aura|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) auto=@targeted(this) from(*[instant;sorcery;enchantment]|myhand,mygraveyard):counter(1/1,1) text=Aura spells you cast cost 1 less to cast. -- Heroic -- Whenever you cast a spell that targets Hero of Iroas, put a +1/+1 counter on Hero of Iroas. mana={1}{W} @@ -45744,7 +45754,7 @@ toughness=1 [/card] [card] name=High Seas -auto=lord(creature[red;green]|hand) altercost(colorless,+1) +auto=lord(creature[red;green]|hand,library,graveyard,exile) altercost(colorless,+1) text=Red creature spells and green creature spells cost {1} more to cast. mana={2}{U} type=Enchantment @@ -49462,7 +49472,7 @@ toughness=2 [/card] [card] name=Irini Sengir -auto=lord(enchantment[white;green]|hand) altercost(colorless,+1) +auto=lord(enchantment[white;green]|hand,library,graveyard,exile) altercost(colorless,+1) text=White enchantment spells and green enchantment spells cost {2} more to cast. mana={2}{B}{B} type=Legendary Creature @@ -50063,7 +50073,7 @@ toughness=8 [/card] [card] name=Jade Leech -auto=lord(*[green]|myhand) altercost(green,+1) +auto=lord(*[green]|myhand,mylibrary,mygraveyard,myexile) altercost(green,+1) text=Green spells you cast cost {G} more to cast. mana={2}{G}{G} type=Creature @@ -50418,7 +50428,7 @@ type=Artifact [/card] [card] name=Jet Medallion -auto=lord(*[black]|myhand) altercost(colorless,-1) +auto=lord(*[black]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Black spells you cast cost {1} less to cast. mana={2} type=Artifact @@ -50552,7 +50562,7 @@ type=Instant name=Jin-Gitaxias, Core Augur abilities=flash auto=@each my end:draw:7 -auto=@each opponent cleanup:name(check handsize) ability$!choice name(reduce handsize) reject notatarget(<7>*|myhand)!$ opponent +auto=hmodifer:-7 opponent mana={8}{U}{U} type=Legendary Creature subtype=Praetor @@ -54377,7 +54387,7 @@ toughness=2 [/card] [card] name=Krosan Drover -auto=lord(creature[manacost>=6]|myhand) altercost(colorless,-2) +auto=lord(creature[manacost>=6]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) text=Creature spells you cast with converted mana cost 6 or more cost {2} less to cast. mana={3}{G} type=Creature @@ -54437,7 +54447,7 @@ toughness=5 [card] name=Krosan Warchief auto={1}{G}:regenerate target(beast) -auto=lord(beast|myhand) altercost(colorless,-1) +auto=lord(beast|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Beast spells you cast cost {1} less to cast. -- {1}{G}: Regenerate target Beast. mana={2}{G} type=Creature @@ -57324,7 +57334,7 @@ toughness=2 [/card] [card] name=Locust Miser -auto=@each opponent cleanup:name(check handsize) ability$!choice name(reduce handsize) reject notatarget(<2>*|myhand)!$ opponent +auto=hmodifer:-2 opponent text=Each opponent's maximum hand size is reduced by two. mana={2}{B}{B} type=Creature @@ -57354,7 +57364,7 @@ type=Artifact [/card] [card] name=Lodestone Golem -auto=lord(*[-artifact]|hand) altercost(colorless,+1) +auto=lord(*[-artifact]|hand,library,graveyard,exile) altercost(colorless,+1) text=Nonartifact spells cost {1} more to cast. mana={4} type=Artifact Creature @@ -57413,7 +57423,7 @@ toughness=2 [/card] [card] name=Long-Forgotten Gohei -auto=lord(arcane|myhand) altercost(colorless,-1) +auto=lord(arcane|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) auto=lord(spirit|myBattlefield) 1/1 text=Arcane spells you cast cost {1} less to cast. -- Spirit creatures you control get +1/+1. mana={3} @@ -59285,8 +59295,8 @@ type=Instant [/card] [card] name=Mana Matrix -auto=lord(instant|myhand) altercost(colorless,-2) -auto=lord(enchantment|myhand) altercost(colorless,-2) +auto=lord(instant|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=lord(enchantment|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) text=Instant and enchantment spells you cast cost up to {2} less to cast. mana={6} type=Artifact @@ -62150,6 +62160,17 @@ mana={2}{G} type=Sorcery [/card] [card] +name=Minamo Scrollkeeper +abilities=defender +auto=hmodifer:1 controller +text=Defender (This creature can't attack.) -- Your maximum hand size is increased by one. +mana={1}{U} +type=Creature +subtype=Human Wizard +power=2 +toughness=3 +[/card] +[card] name=Minamo Sightbender auto={X}{T}:target(creature[power <=X]) unblockable text={X}, {T}: Target creature with power X or less is unblockable this turn. @@ -63277,7 +63298,7 @@ toughness=4 [/card] [card] name=Mistform Warchief -auto=lord(creature[share!types!]|myhand) altercost(colorless,-1) chooseend +auto=lord(creature[share!types!]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) chooseend auto={T}:activatechooseatype all(this) becomes(removecreaturesubtypes) && becomes(chosentype) ueot activatechooseend text=Creature spells you cast that share a creature type with Mistform Warchief cost {1} less to cast. -- {T}: Mistform Warchief becomes the creature type of your choice until end of turn. mana={2}{U} @@ -67326,7 +67347,7 @@ toughness=1 [/card] [card] name=Nightscape Familiar -auto=lord(*[blue;red]|myhand) altercost(colorless,-1) +auto=lord(*[blue;red]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) auto={1}{B}:regenerate text=Blue spells and red spells you cast cost {1} less to cast. -- {1}{B}: Regenerate Nightscape Familiar. mana={1}{B} @@ -71453,7 +71474,7 @@ toughness=7 [/card] [card] name=Pearl Medallion -auto=lord(*[white]|myhand) altercost(colorless,-1) +auto=lord(*[white]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=White spells you cast cost {1} less to cast. mana={2} type=Artifact @@ -73586,7 +73607,7 @@ type=Sorcery [/card] [card] name=Planar Gate -auto=lord(creature|myhand) altercost(colorless,-2) +auto=lord(creature|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) text=Creature spells you cast cost up to {2} less to cast. mana={6} type=Artifact @@ -76774,8 +76795,8 @@ toughness=3 [/card] [card] name=Ragemonger -auto=lord(minotaur|myhand) altercost(black,-1) -auto=lord(minotaur|myhand) altercost(red,-1) +auto=lord(minotaur|myhand,mylibrary,mygraveyard,myexile) altercost(black,-1) +auto=lord(minotaur|myhand,mylibrary,mygraveyard,myexile) altercost(red,-1) text=Minotaur spells you cast cost BlackRed less to cast. This effect reduces only the amount of colored mana you pay. (For example, if you cast a Minotaur spell with mana cost 2Red, it costs 2 to cast.) mana={1}{B}{R} type=Creature @@ -81893,7 +81914,7 @@ toughness=* [card] name=Ruby Leech abilities=first strike -auto=lord(*[red]|myhand) altercost(red,+1) +auto=lord(*[red]|myhand,mylibrary,mygraveyard,myexile) altercost(red,+1) text=First strike -- Red spells you cast cost {R} more to cast. mana={1}{R} type=Creature @@ -81903,7 +81924,7 @@ toughness=2 [/card] [card] name=Ruby Medallion -auto=lord(*[red]|myhand) altercost(colorless,-1) +auto=lord(*[red]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Red spells you cast cost {1} less to cast. mana={2} type=Artifact @@ -83470,7 +83491,7 @@ toughness=4 [card] name=Sapphire Leech abilities=flying -auto=lord(*[blue]|myhand) altercost(blue,+1) +auto=lord(*[blue]|myhand,mylibrary,mygraveyard,myexile) altercost(blue,+1) text=Flying -- Blue spells you cast cost {U} more to cast. mana={1}{U} type=Creature @@ -83480,7 +83501,7 @@ toughness=2 [/card] [card] name=Sapphire Medallion -auto=lord(*[blue]|myhand) altercost(colorless,-1) +auto=lord(*[blue]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Blue spells you cast cost {1} less to cast. mana={2} type=Artifact @@ -86257,20 +86278,20 @@ auto=choice name(Sorcery) moveTo(myexile) notatarget(sorcery|myhand) && counter( auto=choice name(Tribal Instant) moveTo(myexile) notatarget(instant[tribal]|myhand) && counter(0/0,1,TribalInstant) all(this) auto=choice name(Tribal Sorcery) moveTo(myexile) notatarget(sorcery[tribal]|myhand) && counter(0/0,1,TribalSorcery) all(this) auto=choice name(cancel) donothing -auto=this(counter{0/0.1.Artifact}) lord(artifact|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.ArtifactCreature}) lord(artifact[-creature]|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.ArtifactCreature}) lord(creature[-artifact]|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.ArtifactCreature}) lord(creature[artifact]|myhand) altercost(colorless,-2 ) -auto=this(counter{0/0.1.Creature}) lord(creature|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.Enchantment}) lord(enchantment|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.Instant}) lord(instant|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.Sorcery}) lord(sorcery|myhand) altercost( colorless, -2 ) -auto=this(counter{0/0.1.TribalInstant}) lord(tribal[-instant]|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.TribalInstant}) lord(instant[-tribal]|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.TribalInstant}) lord(instant[tribal]|myhand) altercost(colorless,-2 ) -auto=this(counter{0/0.1.TribalSorcery}) lord(tribal[-sorcery]|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.TribalSorcery}) lord(sorcery[-tribal]|myhand) altercost(colorless,-2) -auto=this(counter{0/0.1.TribalSorcery}) lord(sorcery[tribal]|myhand) altercost(colorless,-2) +auto=this(counter{0/0.1.Artifact}) lord(artifact|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.ArtifactCreature}) lord(artifact[-creature]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.ArtifactCreature}) lord(creature[-artifact]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.ArtifactCreature}) lord(creature[artifact]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2 ) +auto=this(counter{0/0.1.Creature}) lord(creature|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.Enchantment}) lord(enchantment|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.Instant}) lord(instant|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.Sorcery}) lord(sorcery|myhand,mylibrary,mygraveyard,myexile) altercost( colorless, -2 ) +auto=this(counter{0/0.1.TribalInstant}) lord(tribal[-instant]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.TribalInstant}) lord(instant[-tribal]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.TribalInstant}) lord(instant[tribal]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2 ) +auto=this(counter{0/0.1.TribalSorcery}) lord(tribal[-sorcery]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.TribalSorcery}) lord(sorcery[-tribal]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) +auto=this(counter{0/0.1.TribalSorcery}) lord(sorcery[tribal]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) text=Imprint - When Semblance Anvil enters the battlefield, you may exile a nonland card from your hand. -- Spells you cast that share a card type with the exiled card cost {2} less to cast. mana={3} type=Artifact @@ -93716,7 +93737,7 @@ toughness=3 [/card] [card] name=Sphere of Resistance -auto=lord(*|hand) altercost(colorless,+1) +auto=lord(*|hand,library,graveyard,exile) altercost(colorless,+1) text=Spells cost {1} more to cast. mana={2} type=Artifact @@ -95069,7 +95090,7 @@ type=Artifact [card] name=Squeeze text=Sorcery spells cost {3} more to cast. -auto=lord(sorcery|hand) altercost(colorless,+3) +auto=lord(sorcery|hand,library,graveyard,exile) altercost(colorless,+3) mana={3}{U} type=Enchantment [/card] @@ -96065,7 +96086,7 @@ toughness=1 [/card] [card] name=Stinkdrinker Daredevil -auto=lord(giant|myhand) altercost(colorless,-2) +auto=lord(giant|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) text=Giant spells you cast cost {2} less to cast. mana={2}{R} type=Creature @@ -96206,7 +96227,7 @@ subtype=Mountain Forest [/card] [card] name=Stone Calendar -auto=lord(*|myhand) altercost(colorless,-1) +auto=lord(*|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Spells you cast cost up to {1} less to cast. mana={5} type=Artifact @@ -96477,7 +96498,7 @@ toughness=2 [card] name=Stonybrook Banneret abilities=islandwalk -auto=lord(*[merfolk;wizard]|myhand) altercost(colorless, -1) +auto=lord(*[merfolk;wizard]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless, -1) text=Islandwalk -- Merfolk spells and Wizard spells you cast cost {1} less to cast. mana={1}{U} type=Creature @@ -96664,7 +96685,7 @@ toughness=1 [card] name=Stormscape Familiar abilities=flying -auto=lord(*[white;black]|myhand) altercost(colorless,-1) +auto=lord(*[white;black]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Flying -- White spells and black spells you cast cost {1} less to cast. mana={1}{U} type=Creature @@ -97918,7 +97939,7 @@ toughness=1 [card] name=Sunscape Familiar abilities=defender -auto=lord(*[green;blue]|myhand) altercost(colorless,-1) +auto=lord(*[green;blue]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Defender (This creature can't attack.) -- Green spells and blue spells you cast cost {1} less to cast. mana={1}{W} type=Creature @@ -101111,8 +101132,8 @@ toughness=2 [card] name=Thalia, Guardian of Thraben abilities=first strike -auto=lord(*[-creature]|myhand) altercost(colorless,+1) -auto=lord(*[-creature]|opponenthand) altercost(colorless, +1) +auto=lord(*[-creature]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,+1) +auto=lord(*[-creature]|opponenthand,opponentlibrary,opponentgraveyard,opponentexile) altercost(colorless, +1) text=First Strike -- Noncreature spells cost {1} more to cast. mana={1}{W} type=Legendary Creature @@ -101583,7 +101604,7 @@ toughness=7 [/card] [card] name=Thorn of Amethyst -auto=lord(*[-creature]|hand) altercost(colorless,+1) +auto=lord(*[-creature]|hand,library,graveyard,exile) altercost(colorless,+1) text=Noncreature spells cost {1} more to cast. mana={2} type=Artifact @@ -101657,7 +101678,7 @@ toughness=1 [/card] [card] name=Thornscape Familiar -auto=lord(*[red;white]|myhand) altercost(colorless,-1) +auto=lord(*[red;white]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=Red spells and white spells you cast cost {1} less to cast. mana={1}{G} type=Creature @@ -101753,6 +101774,28 @@ power=1 toughness=1 [/card] [card] +name=Thought Devourer +abilities=flying +auto=hmodifer:-4 controller +text=Flying -- Your maximum hand size is reduced by four. +mana={2}{U}{U} +type=Creature +subtype=Beast +power=4 +toughness=4 +[/card] +[card] +name=Thought Eater +abilities=flying +auto=hmodifer:-3 controller +text=Flying -- Your maximum hand size is reduced by three. +mana={1}{U} +type=Creature +subtype=Beast +power=2 +toughness=2 +[/card] +[card] name=Thought Gorger abilities=trample auto=foreach(*|myhand) counter(1/1,1) && reject all(*|myhand) @@ -101773,6 +101816,17 @@ mana={2}{U}{U} type=Enchantment [/card] [card] +name=Thought Nibbler +abilities=flying +auto=hmodifer:-2 controller +text=Flying -- Your maximum hand size is reduced by two. +mana={U} +type=Creature +subtype=Beast +power=1 +toughness=1 +[/card] +[card] name=Thought Reflection auto=replacedraw draw:2 noreplace text=If you would draw a card, draw two cards instead. @@ -102504,7 +102558,7 @@ toughness=1 [card] name=Thunderscape Familiar abilities=first strike -auto=lord(*[black;green]|myhand) altercost(colorless,-1) +auto=lord(*[black;green]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-1) text=First strike -- Black spells and green spells you cast cost {1} less to cast. mana={1}{R} type=Creature @@ -105301,6 +105355,17 @@ mana={2}{R} type=Instant [/card] [card] +name=Trusted Advisor +auto=hmodifer:2 controller +auto=@each my upkeep:moveTo(ownerhand) notatarget(creature[blue]|myBattlefield) +text=Your maximum hand size is increased by two. -- At the beginning of your upkeep, return a blue creature you control to its owner's hand. +mana={U} +type=Creature +subtype=Human Advisor +power=1 +toughness=2 +[/card] +[card] name=Trusted Forcemage auto=soulbond 1/1 abilities=soulbond @@ -106196,7 +106261,7 @@ toughness=2 [card] name=Undead Warchief auto=lord(zombie|myBattlefield) 2/1 -auto=lord(zombie|myhand) altercost( colorless,-1) +auto=lord(zombie|myhand,mylibrary,mygraveyard,myexile) altercost( colorless,-1) text=Zombie spells you cast cost {1} less to cast. -- Zombie creatures you control get +2/+1. mana={2}{B}{B} type=Creature @@ -107088,7 +107153,7 @@ subtype=Urza's [/card] [card] name=Urza's Filter -auto=lord(*[multicolor]|hand) altercost(colorless,-2) +auto=lord(*[multicolor]|hand,library,graveyard,exile) altercost(colorless,-2) text=Multicolored spells cost up to {2} less to cast. mana={4} type=Artifact @@ -107102,7 +107167,7 @@ type=Sorcery [/card] [card] name=Urza's Incubator -auto=chooseatype lord(creature[chosentype]|myhand) altercost(colorless,-2) chooseend +auto=chooseatype lord(creature[chosentype]|myhand,mylibrary,mygraveyard,myexile) altercost(colorless,-2) chooseend text=As Urza's Incubator enters the battlefield, choose a creature type. -- Creature spells of the chosen type cost {2} less to cast. mana={3} type=Artifact @@ -110468,8 +110533,7 @@ color=black [card] name=Vryn Wingmare abilities=flying -auto=lord(*[-creature]|myhand) altercost(colorless,+1) -auto=lord(*[-creature]|opponenthand) altercost(colorless, +1) +auto=lord(*[-creature]|hand,library,graveyard,exile) altercost(colorless, +1) text=Flying -- Noncreature spells cost {1} more to cast. mana={2}{W} type=Creature diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 1432ba3ff..77ec526d5 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -6120,15 +6120,6 @@ mana={G} type=Instant [/card] [card] -name=Gnat Miser -text=Each opponent's maximum hand size is reduced by one. -mana={B} -type=Creature -subtype=Rat Shaman -power=1 -toughness=1 -[/card] -[card] name=Goblin Artisans text={T}: Flip a coin. If you win the flip, draw a card. If you lose the flip, counter target artifact spell you control that isn't the target of an ability from another creature named Goblin Artisans. mana={R} @@ -9837,15 +9828,6 @@ type=Artifact text=Imprint — Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with Mimic Vat to its owner's graveyard. {3}, {T}: Put a token onto the battlefield that's a copy of the exiled card. It gains haste. Exile it at the beginning of the next end step. [/card] [card] -name=Minamo Scrollkeeper -text=Defender (This creature can't attack.) -- Your maximum hand size is increased by one. -mana={1}{U} -type=Creature -subtype=Human Wizard -power=2 -toughness=3 -[/card] -[card] name=Minamo's Meddling text=Counter target spell. That spell's controller reveals his or her hand, then discards each card with the same name as a card spliced onto that spell. mana={2}{U}{U} @@ -16641,45 +16623,18 @@ power=2 toughness=2 [/card] [card] -name=Thought Devourer -text=Flying -- Your maximum hand size is reduced by four. -mana={2}{U}{U} -type=Creature -subtype=Beast -power=4 -toughness=4 -[/card] -[card] name=Thought Dissector text={X}, {T}: Target opponent reveals cards from the top of his or her library until an artifact card or X cards are revealed, whichever comes first. If an artifact card is revealed this way, put it onto the battlefield under your control and sacrifice Thought Dissector. Put the rest of the revealed cards into that player's graveyard. mana={4} type=Artifact [/card] [card] -name=Thought Eater -text=Flying -- Your maximum hand size is reduced by three. -mana={1}{U} -type=Creature -subtype=Beast -power=2 -toughness=2 -[/card] -[card] name=Thought Hemorrhage text=Name a nonland card. Target player reveals his or her hand. Thought Hemorrhage deals 3 damage to that player for each card with that name revealed this way. Search that player's graveyard, hand, and library for all cards with that name and exile them. Then that player shuffles his or her library. mana={2}{B}{R} type=Sorcery [/card] [card] -name=Thought Nibbler -text=Flying -- Your maximum hand size is reduced by two. -mana={U} -type=Creature -subtype=Beast -power=1 -toughness=1 -[/card] -[card] name=Thought Prison text=Imprint - When Thought Prison enters the battlefield, you may have target player reveal his or her hand. If you do, choose a nonland card from it and exile that card. -- Whenever a player casts a spell that shares a color or converted mana cost with the exiled card, Thought Prison deals 2 damage to that player. mana={5} @@ -17174,15 +17129,6 @@ power=3 toughness=3 [/card] [card] -name=Trusted Advisor -text=Your maximum hand size is increased by two. -- At the beginning of your upkeep, return a blue creature you control to its owner's hand. -mana={U} -type=Creature -subtype=Human Advisor -power=1 -toughness=2 -[/card] -[card] name=Truth or Tale text=Reveal the top five cards of your library and separate them into two piles. An opponent chooses one of those piles. Put a card from the chosen pile into your hand, then put all other cards revealed this way on the bottom of your library in any order. mana={1}{U} diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 88b6a4d78..dbf7edf41 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -195,11 +195,10 @@ private: } else if (s == "manacost") { - int convertedvalue = card->currentZone == card->controller()->game->battlefield ? card->getManaCost()->getConvertedCost():card->model->data->getManaCost()->getConvertedCost(); if (target->currentZone == target->controller()->game->stack)//X is 0 except if it's on the stack - intValue = target->getManaCost()->getConvertedCost() + target->castX; + intValue = target->myconvertedcost + target->castX; else - intValue = convertedvalue; + intValue = target->myconvertedcost; } else if (s == "azorius")//devotion blue white { @@ -4087,6 +4086,20 @@ public: } }; +//Modify Hand +class AModifyHand: public AbilityTP +{ +public: + string hand; + AModifyHand(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, string hand, int who = TargetChooser::UNSET); + int addToGame(); + int destroy(); + const string getMenuText(); + AModifyHand * clone() const; + //~AModifyHand(); + +}; + //set a players hand size class AASetHand: public ActivatedAbilityTP { diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 25fcf745b..3771a3c27 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -122,6 +122,8 @@ class GameObserver{ void gameStateBasedEffects(); void enchantmentStatus(); void Affinity(); + void ComputeTrinisphere(); + void RemoveTrinisphere(MTGCardInstance * card); void addObserver(MTGAbility * observer); bool removeObserver(ActionElement * observer); void startGame(GameType, Rules * rules); diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 6600e7a1e..56c887459 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -255,6 +255,7 @@ public: int cardistargetter; int tmodifier; int tmodifierb; + int myconvertedcost; void eventattacked(); void eventattackedAlone(); diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index eac30a20e..2d356e24f 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -45,6 +45,7 @@ public: int epic; int initLife; int raidcount; + int handmodifier; vector prowledTypes; vectorcurses; Player(GameObserver *observer, string deckFile, string deckFileSmall, MTGDeck * deck = NULL); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index ccf0e714d..81f7d33d8 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2501,6 +2501,49 @@ AALifer * AALifer::clone() const return NEW AALifer(*this); } +//players modify hand size +AModifyHand::AModifyHand(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, string hand, int who) : + AbilityTP(observer, _id, _source, _target, who), hand(hand) +{ +} + +int AModifyHand::addToGame() +{ + Damageable * _target = (Damageable *) getTarget(); + Player * p = getPlayerFromDamageable(_target); + + if (!p) + return 0; + + WParsedInt handmodifier(hand, NULL, source); + p->handmodifier += handmodifier.getValue(); + + return MTGAbility::addToGame(); +} + +int AModifyHand::destroy() +{ + Damageable * _target = (Damageable *) getTarget(); + Player * p = getPlayerFromDamageable(_target); + + if (!p) + return 0; + + WParsedInt handmodifier(hand, NULL, source); + p->handmodifier -= handmodifier.getValue(); + + return 1; +} + +const string AModifyHand::getMenuText() +{ + return "Modify Hand Size"; +} + +AModifyHand * AModifyHand::clone() const +{ + return NEW AModifyHand(*this); +} //players max hand size AASetHand::AASetHand(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, int hand, ManaCost * _cost, diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index a3bc1c773..64951c818 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -125,12 +125,11 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card) } // Quantified restrictions are always AND-ed: - int convertedvalue = card->currentZone == card->controller()->game->battlefield ? card->getManaCost()->getConvertedCost():card->model->data->getManaCost()->getConvertedCost(); if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power)) return NULL; if (toughnessComparisonMode && !valueInRange(toughnessComparisonMode, card->getToughness(), toughness)) return NULL; - if (manacostComparisonMode && !valueInRange(manacostComparisonMode, convertedvalue, convertedManacost)) + if (manacostComparisonMode && !valueInRange(manacostComparisonMode, card->myconvertedcost, convertedManacost)) return NULL; if (nameComparisonMode && compareName != card->name) return NULL; @@ -166,12 +165,12 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card) if ((mColorExclusions & card->colors) != 0) match = NULL; } - int convertedvalue = card->currentZone == card->controller()->game->battlefield ? card->getManaCost()->getConvertedCost():card->model->data->getManaCost()->getConvertedCost(); + if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power)) match = NULL; if (toughnessComparisonMode && !valueInRange(toughnessComparisonMode, card->getToughness(), toughness)) match = NULL; - if (manacostComparisonMode && !valueInRange(manacostComparisonMode, convertedvalue, convertedManacost)) + if (manacostComparisonMode && !valueInRange(manacostComparisonMode, card->myconvertedcost, convertedManacost)) match = NULL; if(nameComparisonMode && compareName != card->name) match = NULL; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 01a1fc1ab..a84429bd1 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -225,8 +225,12 @@ void GameObserver::nextGamePhase() if (mCurrentGamePhase == MTG_PHASE_AFTER_EOT) { + int handmodified = 0; + handmodified = currentPlayer->handsize+currentPlayer->handmodifier; //Auto Hand cleaning, in case the player didn't do it himself - while (currentPlayer->game->hand->nb_cards > currentPlayer->handsize && currentPlayer->nomaxhandsize == false) + if(handmodified < 0) + handmodified = 0; + while (currentPlayer->game->hand->nb_cards > handmodified && currentPlayer->nomaxhandsize == false) { WEvent * e = NEW WEventCardDiscard(currentPlayer->game->hand->cards[0]); receiveEvent(e); @@ -881,86 +885,8 @@ void GameObserver::gameStateBasedEffects() // plus modify costs // ///////////////////////////// Affinity(); - //trinisphere? - /*for (int td = 0; td < 2; td++) - { - MTGGameZone * dzones[] = { players[td]->game->graveyard, players[td]->game->hand, players[td]->game->library, players[td]->game->exile }; - for (int tk = 0; tk < 4; tk++) - { - MTGGameZone * zone = dzones[tk]; - for (int ct = zone->nb_cards - 1; ct >= 0; ct--) - { - if(zone->cards[ct]->has(Constants::TRINISPHERE)) - { - if(zone->cards[ct]->getManaCost()->getConvertedCost() == 2) - { - zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 1); - zone->cards[ct]->tmodifier = 1; - } - else if(zone->cards[ct]->getManaCost()->getConvertedCost() == 1) - { - zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 2); - zone->cards[ct]->tmodifier = 2; - } - else if(zone->cards[ct]->getManaCost()->getConvertedCost() < 1) - { - zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 3); - zone->cards[ct]->tmodifier = 3; - } - //alternate - if(zone->cards[ct]->getManaCost()->getAlternative() && zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() == 2) - { - zone->cards[ct]->getManaCost()->getAlternative()->add(Constants::MTG_COLOR_ARTIFACT, 1); - zone->cards[ct]->tmodifierb = 1; - } - else if(zone->cards[ct]->getManaCost()->getAlternative() && zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() == 1) - { - zone->cards[ct]->getManaCost()->getAlternative()->add(Constants::MTG_COLOR_ARTIFACT, 2); - zone->cards[ct]->tmodifierb = 2; - } - else if(zone->cards[ct]->getManaCost()->getAlternative() && zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() < 1) - { - zone->cards[ct]->getManaCost()->getAlternative()->add(Constants::MTG_COLOR_ARTIFACT, 3); - zone->cards[ct]->tmodifierb = 3; - } - } - else - { - if(zone->cards[ct]->tmodifier == 1) - { - zone->cards[ct]->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, 1); - zone->cards[ct]->tmodifier = 0; - } - else if(zone->cards[ct]->tmodifier == 2) - { - zone->cards[ct]->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, 2); - zone->cards[ct]->tmodifier = 0; - } - else if(zone->cards[ct]->tmodifier == 3) - { - zone->cards[ct]->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, 3); - zone->cards[ct]->tmodifier = 0; - } - //alternate - if(zone->cards[ct]->tmodifierb == 1) - { - zone->cards[ct]->getManaCost()->getAlternative()->remove(Constants::MTG_COLOR_ARTIFACT, 1); - zone->cards[ct]->tmodifierb = 0; - } - else if(zone->cards[ct]->tmodifierb == 2) - { - zone->cards[ct]->getManaCost()->getAlternative()->remove(Constants::MTG_COLOR_ARTIFACT, 2); - zone->cards[ct]->tmodifierb = 0; - } - else if(zone->cards[ct]->tmodifierb == 3) - { - zone->cards[ct]->getManaCost()->getAlternative()->remove(Constants::MTG_COLOR_ARTIFACT, 3); - zone->cards[ct]->tmodifierb = 0; - } - } - } - } - }*/ + //trinisphere? buggy... + //ComputeTrinisphere(); //end trinisphere ///////////////////////////////////// // Check colored statuses on cards // @@ -1082,8 +1008,10 @@ void GameObserver::Affinity() } } } - card->getManaCost()->copy(original); - card->getManaCost()->setAlternative(alternate); + if(card->getManaCost()) + card->getManaCost()->copy(original); + if(card->getManaCost()->getAlternative()) + card->getManaCost()->setAlternative(alternate); if(card->getManaCost()->extraCosts) { for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) @@ -1202,6 +1130,79 @@ void GameObserver::Affinity() } } } + +void GameObserver::ComputeTrinisphere() +{ + for (int td = 0; td < 2; td++) + { + MTGGameZone * dzones[] = { players[td]->game->graveyard, players[td]->game->hand, players[td]->game->library, players[td]->game->exile }; + for (int tk = 0; tk < 4; tk++) + { + MTGGameZone * zone = dzones[tk]; + for (int ct = zone->nb_cards - 1; ct >= 0; ct--) + { + if(zone->cards[ct]->has(Constants::TRINISPHERE)) + { + if(zone->cards[ct]->getManaCost()->getConvertedCost() == 2) + { + zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 1); + zone->cards[ct]->tmodifier = 1; + } + else if(zone->cards[ct]->getManaCost()->getConvertedCost() == 1) + { + zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 2); + zone->cards[ct]->tmodifier = 2; + } + else if(zone->cards[ct]->getManaCost()->getConvertedCost() < 1) + { + zone->cards[ct]->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 3); + zone->cards[ct]->tmodifier = 3; + } + if(zone->cards[ct]->getManaCost()->getAlternative()) + { + ManaCost * currentAlternate = NEW ManaCost(); + currentAlternate->copy(zone->cards[ct]->getManaCost()->getAlternative()); + if(zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() == 2) + zone->cards[ct]->tmodifierb = 1; + else if(zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() == 1) + zone->cards[ct]->tmodifierb = 2; + else if(zone->cards[ct]->getManaCost()->getAlternative()->getConvertedCost() < 1) + zone->cards[ct]->tmodifierb = 3; + currentAlternate->add(Constants::MTG_COLOR_ARTIFACT, zone->cards[ct]->tmodifierb); + zone->cards[ct]->getManaCost()->setAlternative(currentAlternate); + } + } + else + RemoveTrinisphere(zone->cards[ct]); + if(zone->cards[ct]->getManaCost()->extraCosts) + { + for(unsigned int i = 0; i < zone->cards[ct]->getManaCost()->extraCosts->costs.size();i++) + { + zone->cards[ct]->getManaCost()->extraCosts->costs[i]->setSource(zone->cards[ct]); + } + } + } + } + } +} +void GameObserver::RemoveTrinisphere(MTGCardInstance * card) +{ + if(card->has(Constants::TRINISPHERE)) + return; + if(card->tmodifier) + { + card->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, card->tmodifier); + card->tmodifier = 0; + } + if(card->getManaCost()->getAlternative() && card->tmodifierb) + { + ManaCost * newalternate = NEW ManaCost(); + newalternate->copy(card->getManaCost()->getAlternative()); + newalternate->remove(Constants::MTG_COLOR_ARTIFACT, card->tmodifierb); + card->getManaCost()->setAlternative(newalternate); + card->tmodifierb = 0; + } +} void GameObserver::Render() { if(mLayers) @@ -1367,6 +1368,7 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object, bool lo { Player * clickedPlayer = NULL; int toReturn = 0; + int handmodified = 0; MTGGameZone* zone = NULL; size_t index = 0; MTGCardInstance* backup = NULL; @@ -1484,8 +1486,11 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object, bool lo } //Current player's hand + handmodified = currentPlayer->handsize+currentPlayer->handmodifier; + if(handmodified < 0) + handmodified = 0; if (currentPlayer->game->hand->hasCard(card) && mCurrentGamePhase == MTG_PHASE_CLEANUP - && currentPlayer->game->hand->nb_cards > currentPlayer->handsize && currentPlayer->nomaxhandsize == false) + && currentPlayer->game->hand->nb_cards > handmodified && currentPlayer->nomaxhandsize == false) { WEvent * e = NEW WEventCardDiscard(currentPlayer->game->hand->cards[0]); receiveEvent(e); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 870927178..475d8e68f 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2583,6 +2583,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } + //modify hand size - reduce maximum or increase + vector splitHandMod = parseBetween(s, "hmodifer:", " ", false); + if (splitHandMod.size()) + { + Damageable * t = spell ? spell->getNextDamageableTarget() : NULL; + MTGAbility * a = NEW AModifyHand(observer, id, card, t, splitHandMod[1], who); + return a; + } + //set hand size vector splitSetHand = parseBetween(s, "sethand:", " ", false); if (splitSetHand.size()) diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 287acfdb7..02d5086fa 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -67,6 +67,7 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to cardistargetter = 0; tmodifier = 0; tmodifierb = 0; + myconvertedcost = getManaCost()->getConvertedCost(); } MTGCardInstance * MTGCardInstance::createSnapShot() diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index cd1a2c77a..fe5c07931 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -35,6 +35,7 @@ Player::Player(GameObserver *observer, string file, string fileSmall, MTGDeck * drawCounter = 0; epic = 0; raidcount = 0; + handmodifier = 0; prowledTypes.clear(); doesntEmpty = NEW ManaCost(); poolDoesntEmpty = NEW ManaCost(); From ba7355a831b7b2c1436f54e52bc143d4df6d565d Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sat, 31 Oct 2015 11:38:35 +0800 Subject: [PATCH 11/22] moved rebound cards to borderline until castcard supports increased cost due to altercost... --- .../bin/Res/sets/primitives/borderline.txt | 85 +++++++++++++++++++ projects/mtg/bin/Res/sets/primitives/mtg.txt | 85 ------------------- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index a9f5903f0..aca91e968 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -99,6 +99,29 @@ mana={4}{B}{B} type=Instant [/card] [card] +name=Distortion Strike +target=creature +auto=1/0 +auto=unblockable +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={U} +type=Sorcery +text=Target creature gets +1/+0 until end of turn and is unblockable this turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] +name=Emerge Unscathed +target=creature|mybattlefield +auto=choice name(green) transforms((,newability[protection from green])) ueot +auto=choice name(red) transforms((,newability[protection from red])) ueot +auto=choice name(blue) transforms((,newability[protection from blue])) ueot +auto=choice name(black) transforms((,newability[protection from black])) ueot +auto=choice name(white) transforms((,newability[protection from white])) ueot +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={W} +type=Instant +text=Target creature you control gains protection from the color of your choice until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Feral Hydra type=Creature subtype=Hydra Beast @@ -247,6 +270,14 @@ power=1 toughness=1 [/card] [card] +name=Nomads' Assembly +auto=token(Kor Soldier,Creature Kor Soldier,1/1,white)*type:creature:mybattlefield +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={4}{W}{W} +type=Sorcery +text=Put a 1/1 white Kor Soldier creature token onto the battlefield for each creature you control. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Obsessive Search abilities=madness autoexile=restriction{discarded} pay({U}) name(pay U to cast) activate name(pay U to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard) @@ -266,6 +297,15 @@ power=3 toughness=1 [/card] [card] +name=Prey's Vengeance +target=creature +auto=2/2 +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={G} +type=Instant +text=Target creature gets +2/+2 until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Psychotic Haze abilities=madness autoexile=restriction{discarded} pay({1}{B}) name(pay 1B to cast) activate name(pay 1B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard) @@ -305,6 +345,15 @@ power=4 toughness=4 [/card] [card] +name=Recurring Insight +target=opponent +auto=draw:type:*:targetedpersonshand controller +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={4}{U}{U} +type=Sorcery +text=Draw cards equal to the number of cards in target opponent's hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Sacellum Godspeaker auto={T}:foreach(creaure[power>4]|myhand) add{G} text={T}: Reveal any number of creature cards with power 5 or greater from your hand. Add {G} to your mana pool for each card revealed this way. @@ -363,6 +412,15 @@ mana={G}{W} type=Instant [/card] [card] +name=Staggershock +target=creature,player +auto=damage:2 +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={2}{R} +type=Instant +text=Staggershock deals 2 damage to target creature or player. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Strength of Isolation abilities=madness autoexile=restriction{discarded} pay({W}) name(pay W to cast) activate name(pay W to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard) @@ -387,6 +445,33 @@ type=Enchantment subtype=Aura [/card] [card] +name=Surreal Memoir +auto=moverandom(instant) from(mygraveyard) to(myhand) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={3}{R} +type=Sorcery +text=Return an instant card at random from your graveyard to your hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] +name=Survival Cache +auto=life:2 controller +auto=if compare(lifetotal)~morethan~compare(opponentlifetotal) then draw:1 controller +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={2}{W} +type=Sorcery +text=You gain 2 life. Then if you have more life than an opponent, draw a card. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] +name=Virulent Swipe +target=creature +auto=2/0 +auto=deathtouch +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +mana={B} +type=Instant +text=Target creature gets +2/+0 and gains deathtouch until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) +[/card] +[card] name=Zombie Brute abilities=trample auto=foreach(zombie|myhand) counter(1/1,1) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index fc838d55b..5f633d64b 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -25416,16 +25416,6 @@ mana={X}{U}{U}{U} type=Sorcery [/card] [card] -name=Distortion Strike -target=creature -auto=1/0 -auto=unblockable -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={U} -type=Sorcery -text=Target creature gets +1/+0 until end of turn and is unblockable this turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Distress target=player auto=if type(*[-land]|targetedpersonshand)~lessthan~1 then name(look) donothing notatarget(*|targetedpersonshand) else reject notatarget(*[-land]|targetedpersonshand) @@ -29911,19 +29901,6 @@ power=2 toughness=3 [/card] [card] -name=Emerge Unscathed -target=creature|mybattlefield -auto=choice name(green) transforms((,newability[protection from green])) ueot -auto=choice name(red) transforms((,newability[protection from red])) ueot -auto=choice name(blue) transforms((,newability[protection from blue])) ueot -auto=choice name(black) transforms((,newability[protection from black])) ueot -auto=choice name(white) transforms((,newability[protection from white])) ueot -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={W} -type=Instant -text=Target creature you control gains protection from the color of your choice until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Emeria, the Sky Ruin auto=tap auto={T}:add{W} @@ -67924,14 +67901,6 @@ power=2 toughness=1 [/card] [card] -name=Nomads' Assembly -auto=token(Kor Soldier,Creature Kor Soldier,1/1,white)*type:creature:mybattlefield -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={4}{W}{W} -type=Sorcery -text=Put a 1/1 white Kor Soldier creature token onto the battlefield for each creature you control. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Nomad Decoy auto={W}{T}:tap target(creature) auto=aslongas(*|mygraveyard) {W}{W}{T}:target(<2>creature) tap >6 @@ -74430,15 +74399,6 @@ power=4 toughness=4 [/card] [card] -name=Prey's Vengeance -target=creature -auto=2/2 -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={G} -type=Instant -text=Target creature gets +2/+2 until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Price of Glory auto=lord(land) transforms((,newability[@tappedformana(this) restriction{opponentturnonly}:destroy])) text=Whenever a player taps a land for mana, if it's not that player's turn, destroy that land. @@ -78606,15 +78566,6 @@ mana={3}{W} type=Instant [/card] [card] -name=Recurring Insight -target=opponent -auto=draw:type:*:targetedpersonshand controller -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={4}{U}{U} -type=Sorcery -text=Draw cards equal to the number of cards in target opponent's hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Recurring Nightmare auto={S(creature|myBattlefield)}{H}:moveto(mybattlefield) target(creature|mygraveyard) asSorcery text=Sacrifice a creature, Return Recurring Nightmare to its owner's hand: Return target creature card from your graveyard to the battlefield. Activate this ability only any time you could cast a sorcery. @@ -95248,15 +95199,6 @@ power=0 toughness=0 [/card] [card] -name=Staggershock -target=creature,player -auto=damage:2 -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={2}{R} -type=Instant -text=Staggershock deals 2 damage to target creature or player. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Stalker Hag abilities=swampwalk,forestwalk text=Swampwalk, forestwalk @@ -98307,14 +98249,6 @@ power=2 toughness=1 [/card] [card] -name=Surreal Memoir -auto=moverandom(instant) from(mygraveyard) to(myhand) -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={3}{R} -type=Sorcery -text=Return an instant card at random from your graveyard to your hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Surveilling Sprite abilities=flying auto=@movedto(this|graveyard) from(battlefield):may draw:1 @@ -98334,15 +98268,6 @@ mana={4}{R} type=Sorcery [/card] [card] -name=Survival Cache -auto=life:2 controller -auto=if compare(lifetotal)~morethan~compare(opponentlifetotal) then draw:1 controller -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={2}{W} -type=Sorcery -text=You gain 2 life. Then if you have more life than an opponent, draw a card. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Survival of the Fittest auto={G}{discard(creature|myhand)}:moveTo(myhand) target(creature|myLibrary) text={G}, Discard a creature card: Search your library for a creature card, reveal that card, and put it into your hand. Then shuffle your library. @@ -109535,16 +109460,6 @@ power=1 toughness=1 [/card] [card] -name=Virulent Swipe -target=creature -auto=2/0 -auto=deathtouch -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) -mana={B} -type=Instant -text=Target creature gets +2/+0 and gains deathtouch until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) -[/card] -[card] name=Visara the Dreadful abilities=flying auto={T}:bury target(creature) From 896b12c16b46da6ccf46ebdd06b0421f7c4f9fbc Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sat, 31 Oct 2015 15:01:29 +0800 Subject: [PATCH 12/22] werror init on psp compilation --- projects/mtg/include/AllAbilities.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index dbf7edf41..66b33ff29 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -6374,11 +6374,11 @@ class GenericPaidAbility: public ActivatedAbility public: MTGAbility * baseAbility; ManaCost * optionalCost; - bool asAlternate; string newName; string restrictions; string baseCost; string baseAbilityStr; + bool asAlternate; GenericPaidAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target,string _newName,string _castRestriction,string _mayCost, string toAdd, bool asAlternate = false, ManaCost * cost = NULL); int resolve(); From 3a9b4f3491b7ac9b1d064ccc1bbeb0561dbe150d Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sat, 31 Oct 2015 15:23:39 +0800 Subject: [PATCH 13/22] parenthesis... --- projects/mtg/src/MTGAbility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 475d8e68f..44c40898d 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1090,7 +1090,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG if (!target) target = card; //pay and castcard? - if(s.find("pay(") != string::npos || s.find("pay[[") != string::npos && s.find("castcard(restricted") != string::npos) + if(s.find("castcard(restricted") != string::npos && (s.find("pay(") != string::npos || s.find("pay[[") != string::npos)) asAlternate = true; //MTG Specific rules //adds the bonus credit system From 1bd3b7743b280e13d2b6382c90701c8dc228e0a8 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sun, 1 Nov 2015 21:59:54 +0800 Subject: [PATCH 14/22] bug fix --- .../mtg/bin/Res/sets/primitives/borderline.txt | 18 +++++++++--------- projects/mtg/src/AllAbilities.cpp | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index aca91e968..017a69c27 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -103,7 +103,7 @@ name=Distortion Strike target=creature auto=1/0 auto=unblockable -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={U} type=Sorcery text=Target creature gets +1/+0 until end of turn and is unblockable this turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) @@ -116,7 +116,7 @@ auto=choice name(red) transforms((,newability[protection from red])) ueot auto=choice name(blue) transforms((,newability[protection from blue])) ueot auto=choice name(black) transforms((,newability[protection from black])) ueot auto=choice name(white) transforms((,newability[protection from white])) ueot -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={W} type=Instant text=Target creature you control gains protection from the color of your choice until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) @@ -272,7 +272,7 @@ toughness=1 [card] name=Nomads' Assembly auto=token(Kor Soldier,Creature Kor Soldier,1/1,white)*type:creature:mybattlefield -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={4}{W}{W} type=Sorcery text=Put a 1/1 white Kor Soldier creature token onto the battlefield for each creature you control. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) @@ -300,7 +300,7 @@ toughness=1 name=Prey's Vengeance target=creature auto=2/2 -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={G} type=Instant text=Target creature gets +2/+2 until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) @@ -348,7 +348,7 @@ toughness=4 name=Recurring Insight target=opponent auto=draw:type:*:targetedpersonshand controller -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={4}{U}{U} type=Sorcery text=Draw cards equal to the number of cards in target opponent's hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) @@ -415,7 +415,7 @@ type=Instant name=Staggershock target=creature,player auto=damage:2 -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={2}{R} type=Instant text=Staggershock deals 2 damage to target creature or player. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) @@ -447,7 +447,7 @@ subtype=Aura [card] name=Surreal Memoir auto=moverandom(instant) from(mygraveyard) to(myhand) -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={3}{R} type=Sorcery text=Return an instant card at random from your graveyard to your hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) @@ -456,7 +456,7 @@ text=Return an instant card at random from your graveyard to your hand. Rebound name=Survival Cache auto=life:2 controller auto=if compare(lifetotal)~morethan~compare(opponentlifetotal) then draw:1 controller -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={2}{W} type=Sorcery text=You gain 2 life. Then if you have more life than an opponent, draw a card. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) @@ -466,7 +466,7 @@ name=Virulent Swipe target=creature auto=2/0 auto=deathtouch -auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[endofturn once checkex] activate may activate castcard(restricted)])) +auto=if rebound then transforms((,newability[moveto(exile)],newability[phaseaction[my upkeep once checkex] activate may activate castcard(restricted)])) mana={B} type=Instant text=Target creature gets +2/+0 and gains deathtouch until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 81f7d33d8..b681dfc36 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1235,7 +1235,7 @@ int GenericPaidAbility::resolve() optionalCost->add(Constants::MTG_COLOR_ARTIFACT, 3); }*/ } - if(nomenu && optionalCost->getConvertedCost() < 1) + if(asAlternate && nomenu && optionalCost->getConvertedCost() < 1) { nomenuAbility->resolve(); } From 55a5b9d0baf6df2606c399811348726774437ac0 Mon Sep 17 00:00:00 2001 From: xawotihs Date: Sun, 1 Nov 2015 22:49:14 +0100 Subject: [PATCH 15/22] Now uses unofficial SDL mirror --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index b43724010..99e41138b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,4 @@ url = https://github.com/madler/zlib [submodule "thirdparty/SDL2"] path = thirdparty/SDL2 - url = https://github.com/emscripten-ports/SDL2.git + url = https://github.com/spurious/SDL-mirror.git From 2312381b825fb754520d35d27fa992bcc511b393 Mon Sep 17 00:00:00 2001 From: xawotihs Date: Sun, 1 Nov 2015 23:26:03 +0100 Subject: [PATCH 16/22] Updated git submodules --- .gitmodules | 4 ++-- thirdparty/SDL2 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 99e41138b..53fad2b33 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "thirdparty/zlib"] path = thirdparty/zlib url = https://github.com/madler/zlib -[submodule "thirdparty/SDL2"] - path = thirdparty/SDL2 +[submodule ".\\thirdparty\\SDL2"] + path = .\\thirdparty\\SDL2 url = https://github.com/spurious/SDL-mirror.git diff --git a/thirdparty/SDL2 b/thirdparty/SDL2 index e60718c37..9b526d28c 160000 --- a/thirdparty/SDL2 +++ b/thirdparty/SDL2 @@ -1 +1 @@ -Subproject commit e60718c37e5b4dbabdc87c21193ee9e6e9bf562a +Subproject commit 9b526d28cb2d7f0ccff0613c94bb52abc8f53b6f From e62c065e2cc081e5af4191ec73072b85874aface Mon Sep 17 00:00:00 2001 From: xawotihs Date: Sun, 1 Nov 2015 23:34:03 +0100 Subject: [PATCH 17/22] Should fix git submodules --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 53fad2b33..99e41138b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "thirdparty/zlib"] path = thirdparty/zlib url = https://github.com/madler/zlib -[submodule ".\\thirdparty\\SDL2"] - path = .\\thirdparty\\SDL2 +[submodule "thirdparty/SDL2"] + path = thirdparty/SDL2 url = https://github.com/spurious/SDL-mirror.git From 19091ade7b0abcd2e1262bfe3ce4a813920ad8ad Mon Sep 17 00:00:00 2001 From: xawotihs Date: Sun, 1 Nov 2015 23:51:07 +0100 Subject: [PATCH 18/22] Updated appveyor to use SDL2.0.3 release and not SDL head. --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index b0c629972..2472be5ae 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,6 +27,9 @@ install: - "C:/Python27/Scripts/pip.exe install pyjavaproperties" - "C:/Python27/Scripts/pip.exe install github3.py" - git submodule update --init --recursive + - cd thirdparty/SDL2 + - git checkout release-2.0.3 + - cd ../.. #---------------------------------# # build configuration # From e272925f3df1e0cd8ed0d3a2484dc5c65dc0fc58 Mon Sep 17 00:00:00 2001 From: xawotihs Date: Mon, 2 Nov 2015 00:00:26 +0100 Subject: [PATCH 19/22] Removed extra/stdint.h --- projects/mtg/extra/stdint.h | 232 ------------------------------------ 1 file changed, 232 deletions(-) delete mode 100644 projects/mtg/extra/stdint.h diff --git a/projects/mtg/extra/stdint.h b/projects/mtg/extra/stdint.h deleted file mode 100644 index e032ff160..000000000 --- a/projects/mtg/extra/stdint.h +++ /dev/null @@ -1,232 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#if (_MSC_VER < 1300) && defined(__cplusplus) - extern "C++" { -#endif -# include -#if (_MSC_VER < 1300) && defined(__cplusplus) - } -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types -typedef __int8 int8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] From 87f5e7f3a65d2543341f53d9771906f110308ad6 Mon Sep 17 00:00:00 2001 From: xawotihs Date: Mon, 2 Nov 2015 23:00:57 +0100 Subject: [PATCH 20/22] Emscripten flavor now compiles correctly --- CMakeLists.txt | 6 ++-- platforms/emscripten/configure.cmake | 8 ++++-- projects/mtg/src/SDLmain.cpp | 42 ++++++++++++++++++---------- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a69ac68ed..74d2d2143 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,7 @@ WAGIC_OPTION(BUILD_PNG "build png from source" (WIN32 OR APPLE OR PSP OR WAGIC_OPTION(BUILD_UNZIP "build unzip from source" ON) WAGIC_OPTION(BUILD_TINYXML "build tinyxml from source" (WIN32 OR APPLE OR PSP OR ANDROID OR EMSCRIPTEN)) WAGIC_OPTION(BUILD_ZIPFS "build zipfs from source" ON) -WAGIC_OPTION(BUILD_SDL2 "build SDL2 from source" (backend_sdl AND (UNIX OR WIN32 OR ANDROID OR EMSCRIPTEN))) +WAGIC_OPTION(BUILD_SDL2 "build SDL2 from source" (backend_sdl AND (UNIX OR WIN32 OR ANDROID) AND (NOT EMSCRIPTEN))) #project options if(ANDROID) @@ -138,6 +138,8 @@ include(FindOrBuild) if(PSP) FindOrBuildPSPSDK() include(platforms/psp/configure.cmake) +elseif(EMSCRIPTEN) + include(platforms/emscripten/configure.cmake) elseif(WIN32) include(platforms/win/configure.cmake) elseif(APPLE) @@ -146,8 +148,6 @@ elseif(UNIX) include(platforms/unix/configure.cmake) elseif(ANDROID) include(platforms/android/configure.cmake) -elseif(EMSCRIPTEN) - include(platforms/emscripten/configure.cmake) endif() #set backend dependend configurations diff --git a/platforms/emscripten/configure.cmake b/platforms/emscripten/configure.cmake index 0c6954c49..bdbedc639 100644 --- a/platforms/emscripten/configure.cmake +++ b/platforms/emscripten/configure.cmake @@ -1,3 +1,5 @@ -set_target_properties(wagic PROPERTIES LINK_FLAGS "-s USE_SDL=2") -set(CMAKE_CXX_FLAGS "-s USE_SDL=2") -set(CMAKE_EXECUTABLE_SUFFIX ".html") \ No newline at end of file +set(CMAKE_CXX_FLAGS "-s USE_SDL=2 -std=c++11") +set(CMAKE_EXECUTABLE_SUFFIX ".html") +add_definitions(-DLINUX) +add_definitions(-DUSERDIR=".wagic") +add_definitions(-DRESDIR="Res") diff --git a/projects/mtg/src/SDLmain.cpp b/projects/mtg/src/SDLmain.cpp index 39b537485..6b1d9d95f 100644 --- a/projects/mtg/src/SDLmain.cpp +++ b/projects/mtg/src/SDLmain.cpp @@ -19,6 +19,10 @@ #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif + #if (defined FORCE_GLES) #undef GL_ES_VERSION_2_0 #undef GL_VERSION_2_0 @@ -101,7 +105,7 @@ class SdlApp public: /* For easy interfacing with JGE static functions */ bool Running; SDL_Window* window; - SDL_GLContext gl_context; + SDL_GLContext gl_context; SDL_Rect viewPort; Uint32 lastMouseUpTime; Uint32 lastFingerDownTime; @@ -112,10 +116,27 @@ public: /* For easy interfacing with JGE static functions */ int mMouseDownX; int mMouseDownY; + static SdlApp* sInstance; public: SdlApp() : Running(true), window(NULL), gl_context(NULL), lastMouseUpTime(0), lastFingerDownTime(0), mMouseDownX(0), mMouseDownY(0) { + sInstance = this; + } + + static void OneIter() + { + SDL_Event Event; + if (g_engine) + { + for (int x = 0; x < 5 && SDL_WaitEventTimeout(&Event, 10); ++x) + { + if(!g_engine->IsPaused()) + sInstance->OnEvent(&Event); + } + if(!g_engine->IsPaused()) + sInstance->OnUpdate(); + } } int OnExecute() @@ -125,22 +146,14 @@ public: return -1; } - SDL_Event Event; - +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(OneIter, 60, 1); +#else while(Running) { - if (g_engine) - { - for (int x = 0; x < 5 && SDL_WaitEventTimeout(&Event, 10); ++x) - { - if(!g_engine->IsPaused()) - OnEvent(&Event); - } - if(!g_engine->IsPaused()) - OnUpdate(); - } + OneIter(); } - +#endif OnCleanup(); return 0; @@ -280,6 +293,7 @@ public: SDL_Quit(); } }; +SdlApp* SdlApp::sInstance = 0; static const struct { LocalKeySym keysym; JButton keycode; } gDefaultBindings[] = { From 20a792f1353c8d8788c348cc372a67064ea4c7ea Mon Sep 17 00:00:00 2001 From: Xawotihs Date: Tue, 3 Nov 2015 23:02:12 +0100 Subject: [PATCH 21/22] Refering DXSDK and not windows SDK --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 2472be5ae..c3c6f383f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,6 +17,7 @@ skip_tags: true #---------------------------------# environment: + DXSDK_DIR: "C:\Program Files (x86)\Microsoft DirectX SDK" GH_TOKEN: secure: dYnBDQkiY5oVjIlswzBX9BJigNtBGXgGlp1tK3XbHzrDEDrs2vaKD5m+Oz5OSz1C From 603d491bed8647e5557a676917e0dcf431c016fd Mon Sep 17 00:00:00 2001 From: Xawotihs Date: Tue, 3 Nov 2015 23:06:14 +0100 Subject: [PATCH 22/22] Without quotes --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c3c6f383f..e138216a8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,7 @@ skip_tags: true #---------------------------------# environment: - DXSDK_DIR: "C:\Program Files (x86)\Microsoft DirectX SDK" + DXSDK_DIR: C:\Program Files (x86)\Microsoft DirectX SDK GH_TOKEN: secure: dYnBDQkiY5oVjIlswzBX9BJigNtBGXgGlp1tK3XbHzrDEDrs2vaKD5m+Oz5OSz1C