diff --git a/JGE/src/SDLmain.cpp b/JGE/src/SDLmain.cpp index bf09628fd..063657644 100644 --- a/JGE/src/SDLmain.cpp +++ b/JGE/src/SDLmain.cpp @@ -293,17 +293,18 @@ static const struct { LocalKeySym keysym; JButton keycode; } gDefaultBindings[] { SDLK_DOWN, JGE_BTN_DOWN }, { SDLK_LEFT, JGE_BTN_LEFT }, { SDLK_RIGHT, JGE_BTN_RIGHT }, - { SDLK_z, JGE_BTN_UP }, - { SDLK_d, JGE_BTN_RIGHT }, + { SDLK_w, JGE_BTN_UP }, { SDLK_s, JGE_BTN_DOWN }, - { SDLK_q, JGE_BTN_LEFT }, - { SDLK_a, JGE_BTN_PREV }, + { SDLK_a, JGE_BTN_LEFT }, + { SDLK_d, JGE_BTN_RIGHT }, + { SDLK_q, JGE_BTN_PREV }, { SDLK_e, JGE_BTN_NEXT }, { SDLK_i, JGE_BTN_CANCEL }, { SDLK_l, JGE_BTN_OK }, { SDLK_SPACE, JGE_BTN_OK }, { SDLK_k, JGE_BTN_SEC }, { SDLK_j, JGE_BTN_PRI }, + { SDLK_b, JGE_BTN_SOUND }, { SDLK_f, JGE_BTN_FULLSCREEN }, /* old Qt ones, basically modified to comply with the N900 keyboard diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index ed81266c8..1b00a4714 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -15844,6 +15844,15 @@ mana={2}{R} type=Enchantment [/card] [card] +name=Burning Wish +auto=moveTo(exile) +aicode=activate target(sorcery|mysideboard) moveto(myhand) +auto=name(search card) reveal:type:*:mysideboard revealzone(mysideboard) optionone name(choose card) target(<1>sorcery|reveal) moveto(myhand) and!(all(other *|reveal) moveto(ownersideboard))! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownersideboard) and!(all(other *|reveal) moveto(ownersideboard))! optiontwoend revealend +text=You may choose a sorcery card you own from outside the game, reveal that card, and put it into your hand. Exile Burning Wish. +mana={1}{R} +type=Sorcery +[/card] +[card] name=Burning-Tree Emissary auto=Add{R}{G} text=When Burning-Tree Emissary enters the battlefield, add {R}{G} to your mana pool. @@ -24844,6 +24853,15 @@ mana={3}{U}{R} type=Instant [/card] [card] +name=Cunning Wish +auto=moveTo(exile) +aicode=activate target(instant|mysideboard) moveto(myhand) +auto=name(search card) reveal:type:*:mysideboard revealzone(mysideboard) optionone name(choose card) target(<1>instant|reveal) moveto(myhand) and!(all(other *|reveal) moveto(ownersideboard))! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownersideboard) and!(all(other *|reveal) moveto(ownersideboard))! optiontwoend revealend +text=You may choose an instant card you own from outside the game, reveal that card, and put it into your hand. Exile Cunning Wish. +mana={2}{U} +type=Instant +[/card] +[card] name=Cunning target=creature auto=3/3 @@ -27072,6 +27090,16 @@ mana={X}{B} type=Instant [/card] [card] +name=Death Wish +auto=moveTo(exile) +auto=life:-halfdownlifetotal +aicode=activate target(*|mysideboard) moveto(myhand) +auto=name(search card) reveal:type:*:mysideboard revealzone(mysideboard) optionone name(choose card) target(<1>*|reveal) moveto(myhand) and!(all(other *|reveal) moveto(ownersideboard))! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownersideboard) and!(all(other *|reveal) moveto(ownersideboard))! optiontwoend revealend +text=You may choose a card you own from outside the game and put it into your hand. You lose half your life, rounded up. Exile Death Wish. +mana={1}{B}{B} +type=Sorcery +[/card] +[card] name=Deathbellow Raider abilities=mustattack auto={2}{B}:regenerate @@ -47043,6 +47071,15 @@ power=1 toughness=1 [/card] [card] +name=Glittering Wish +auto=moveTo(exile) +aicode=activate target(*[multicolor]|mysideboard) moveto(myhand) +auto=name(search card) reveal:type:*:mysideboard revealzone(mysideboard) optionone name(choose card) target(<1>*[multicolor]|reveal) moveto(myhand) and!(all(other *|reveal) moveto(ownersideboard))! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownersideboard) and!(all(other *|reveal) moveto(ownersideboard))! optiontwoend revealend +text=You may choose a multicolored card you own from outside the game, reveal that card, and put it into your hand. Exile Glittering Wish. +mana={G}{W} +type=Sorcery +[/card] +[card] name=Gloomdrifter abilities=flying auto=aslongas(*|mygraveyard) -2/-2 target(creature) ueot >6 oneshot @@ -48636,6 +48673,15 @@ mana={1} type=Artifact [/card] [card] +name=Golden Wish +auto=moveTo(exile) +aicode=activate target(*[artifact;enchantment]|mysideboard) moveto(myhand) +auto=name(search card) reveal:type:*:mysideboard revealzone(mysideboard) optionone name(choose card) target(<1>*[artifact;enchantment]|reveal) moveto(myhand) and!(all(other *|reveal) moveto(ownersideboard))! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownersideboard) and!(all(other *|reveal) moveto(ownersideboard))! optiontwoend revealend +text=You may choose an artifact or enchantment card you own from outside the game, reveal that card, and put it into your hand. Exile Golden Wish. +mana={3}{W}{W} +type=Sorcery +[/card] +[card] name=Goldenglow Moth abilities=flying auto=@combat(blocking) source(this):life:4 @@ -67626,6 +67672,15 @@ power=0 toughness=6 [/card] [card] +name=Living Wish +auto=moveTo(exile) +aicode=activate target(*[land;creature]|mysideboard) moveto(myhand) +auto=name(search card) reveal:type:*:mysideboard revealzone(mysideboard) optionone name(choose card) target(<1>*[land;creature]|reveal) moveto(myhand) and!(all(other *|reveal) moveto(ownersideboard))! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownersideboard) and!(all(other *|reveal) moveto(ownersideboard))! optiontwoend revealend +text=You may choose a creature or land card you own from outside the game, reveal that card, and put it into your hand. Exile Living Wish. +mana={1}{G} +type=Sorcery +[/card] +[card] name=Livonya Silone abilities=first strike,legendarylandwalk text=First strike, legendary landwalk @@ -110150,15 +110205,16 @@ type=Land [/card] [card] name=Spawnsire of Ulamog -mana={10} auto=@combat(attacking) source(this):name(Annihilate) ability$!name(sacrifice a permanent) notatarget(<1>*|mybattlefield) sacrifice!$ opponent auto={4}:token(Eldrazi Spawn,Creature Eldrazi Spawn,0/1) and!( transforms((,newability[{S}:Add{1}])) forever )!*2 -auto={20}:name(Cast Eldrazi's) ability$!castcard(named!:Emrakul, the Aeons Torn:!) _ castcard(named!:It That Betrays:!) _ castcard(named!:Ulamog, the Infinite Gyre:!) _ castcard(named!:Kozilek, Butcher of Truth:!) _ castcard(named!:Spawnsire of Ulamog:!) _ castcard(named!:Artisan of Kozilek:!) _ castcard(named!:Hand of Emrakul:!) _ castcard(named!:Ulamog's Crusher:!)!$ controller +aicode=activate target(*[eldrazi]|mysideboard) castcard(normal) +auto={20}:name(Cast Eldrazi's) reveal:type:*:mysideboard revealzone(mysideboard) optionone name(choose card) target(*[eldrazi]|reveal) moveto(ownersideboard) and!( becomes(tobecast) ueot )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownersideboard) and!( all(*|reveal) moveto(ownersideboard) )! optiontwoend afterrevealed all(tobecast|mysideboard) moveto(ownersideboard) and!(activate castcard(normal))! afterrevealedend revealend +text=Annihilator 1 (Whenever this creature attacks, defending player sacrifices a permanent.) -- {4}: Put two 0/1 colorless Eldrazi Spawn creature tokens onto the battlefield. They have "Sacrifice this creature: Add {1} to your mana pool." -- {20}: Cast any number of Eldrazi cards you own from outside the game without paying their mana costs. +mana={10} type=Creature subtype=Eldrazi power=7 toughness=11 -text=Annihilator 1 (Whenever this creature attacks, defending player sacrifices a permanent.) -- {4}: Put two 0/1 colorless Eldrazi Spawn creature tokens onto the battlefield. They have "Sacrifice this creature: Add {1} to your mana pool." -- {20}: Cast any number of Eldrazi cards you own from outside the game without paying their mana costs. [/card] [card] name=Spawnwrithe diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index c51a04960..99ed3d1b2 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -1668,12 +1668,6 @@ mana={2}{R}{R}{R} type=Sorcery [/card] [card] -name=Burning Wish -text=You may choose a sorcery card you own from outside the game, reveal that card, and put it into your hand. Exile Burning Wish. -mana={1}{R} -type=Sorcery -[/card] -[card] name=Burning-Eye Zubera text=When Burning-Eye Zubera dies, if 4 or more damage was dealt to it this turn, Burning-Eye Zubera deals 3 damage to target creature or player. mana={2}{R}{R} @@ -3087,12 +3081,6 @@ mana={4}{U}{U} type=Sorcery [/card] [card] -name=Cunning Wish -text=You may choose an instant card you own from outside the game, reveal that card, and put it into your hand. Exile Cunning Wish. -mana={2}{U} -type=Instant -[/card] -[card] name=Curious Homunculus text={T}: Add {C} to your mana pool. Spend this mana only to cast an instant or sorcery spell. -- At the beginning of your upkeep, if there are three or more instant and/or sorcery cards in your graveyard, transform Curious Homunculus. mana={1}{U} @@ -3461,12 +3449,6 @@ mana={4}{W} type=Sorcery [/card] [card] -name=Death Wish -text=You may choose a card you own from outside the game and put it into your hand. You lose half your life, rounded up. Exile Death Wish. -mana={1}{B}{B} -type=Sorcery -[/card] -[card] name=Death-Mask Duplicant text=Imprint — {1}: Exile target creature card from your graveyard. -- As long as a card exiled with Death-Mask Duplicant has flying, Death-Mask Duplicant has flying. The same is true for fear, first strike, double strike, haste, landwalk, protection, and trample. mana={7} @@ -5865,12 +5847,6 @@ power=1 toughness=1 [/card] [card] -name=Glittering Wish -text=You may choose a multicolored card you own from outside the game, reveal that card, and put it into your hand. Exile Glittering Wish. -mana={G}{W} -type=Sorcery -[/card] -[card] name=Global Ruin text=Each player chooses from the lands he or she controls a land of each basic land type, then sacrifices the rest. mana={4}{W} @@ -6073,12 +6049,6 @@ type=Legendary Artifact subtype=Equipment [/card] [card] -name=Golden Wish -text=You may choose an artifact or enchantment card you own from outside the game, reveal that card, and put it into your hand. Exile Golden Wish. -mana={3}{W}{W} -type=Sorcery -[/card] -[card] name=Goldenhide Ox text=Constellation — Whenever Goldenhide Ox or another enchantment enters the battlefield under your control, target creature must be blocked this turn if able. mana={5}{G} @@ -8879,12 +8849,6 @@ power=* toughness=* [/card] [card] -name=Living Wish -text=You may choose a creature or land card you own from outside the game, reveal that card, and put it into your hand. Exile Living Wish. -mana={1}{G} -type=Sorcery -[/card] -[card] name=Loafing Giant text=Whenever Loafing Giant attacks or blocks, put the top card of your library into your graveyard. If that card is a land card, prevent all combat damage Loafing Giant would deal this turn. mana={4}{R} diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 650444b44..66844189c 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -411,8 +411,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, p->game->exile }; - for (int k = 0; k < 5; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile, p->game->sideboard };//wish cards use sideboard + for (int k = 0; k < 6; k++) { MTGGameZone * zone = zones[k]; if (tc->targetsZone(zone, card)) diff --git a/projects/mtg/include/GameStateDeckViewer.h b/projects/mtg/include/GameStateDeckViewer.h index 9791eb97c..9c9ca9021 100644 --- a/projects/mtg/include/GameStateDeckViewer.h +++ b/projects/mtg/include/GameStateDeckViewer.h @@ -29,7 +29,11 @@ enum MENU_DECK_SELECTION = 10, MENU_DECK_BUILDER = 11, MENU_FIRST_DUEL_SUBMENU = 102, - MENU_LANGUAGE_SELECTION = 103 + MENU_LANGUAGE_SELECTION = 103, + SBMENU_CHOICE = 802, + SBMENU_ADD_NORMAL = 803, + SBMENU_ADD_SB = 804, + SBMENU_ADD_CANCEL = 805 }; // enums for menu options @@ -71,18 +75,20 @@ private: DeckViewerStages mStage; JMusic * bgMusic; - InteractiveButton *toggleDeckButton, *sellCardButton, *statsPrevButton, *filterButton, *toggleViewButton, *toggleUpButton, *toggleDownButton, *toggleLeftButton, *toggleRightButton; + InteractiveButton *toggleDeckButton, *sbButton, *sellCardButton, *statsPrevButton, *filterButton, *toggleViewButton, *toggleUpButton, *toggleDownButton, *toggleLeftButton, *toggleRightButton; WGuiFilters * filterMenu; WSrcDeckViewer * source; DeckEditorMenu * welcome_menu; SimpleMenu * subMenu; + SimpleMenu * sbMenu; DeckEditorMenu * deckMenu; PriceList* pricelist; PlayerData * playerdata; DeckDataWrapper * myDeck; DeckDataWrapper * myCollection; + DeckDataWrapper * mySideboard; StatsWrapper * mStatsWrapper; int hudAlpha; @@ -105,6 +111,7 @@ private: void RenderButtons(); void setupView(AvailableView view, DeckDataWrapper *deck); void toggleView(); + void insertSideBoard(); public: GameStateDeckViewer(GameApp* parent); virtual ~GameStateDeckViewer(); @@ -112,9 +119,12 @@ public: void updateFilters(); void rebuildFilters(); void toggleCollection(); + void toggleSideBoard(); void Start(); virtual void End(); void addRemove(MTGCard * card); + void SBaddRemove(MTGCard * card); + void choiceAddRemove(MTGCard * card); virtual void Update(float dt); void renderOnScreenBasicInfo(); void renderSlideBar(); diff --git a/projects/mtg/include/InteractiveButton.h b/projects/mtg/include/InteractiveButton.h index 1ab79321e..c0372c15d 100644 --- a/projects/mtg/include/InteractiveButton.h +++ b/projects/mtg/include/InteractiveButton.h @@ -22,17 +22,18 @@ using std::string; const int kDismissButtonId = 10000; const int kToggleDeckActionId = 10001; const int kSellCardActionId = 10002; -const int kMenuButtonId = 10003; -const int kFilterButtonId = 10004; -const int kNextStatsButtonId = 10005; -const int kPrevStatsButtonId = 10006; -const int kCycleCardsButtonId = 10007; -const int kShowCardListButtonId = 10008; -const int kSwitchViewButton = 10009; -const int kToggleUpButton = 10010; -const int kToggleDownButton = 10011; -const int kToggleLeftButton = 10012; -const int kToggleRightButton = 10013; +const int kSBActionId = 10003; +const int kMenuButtonId = 10004; +const int kFilterButtonId = 10005; +const int kNextStatsButtonId = 10006; +const int kPrevStatsButtonId = 10007; +const int kCycleCardsButtonId = 10008; +const int kShowCardListButtonId = 10009; +const int kSwitchViewButton = 10010; +const int kToggleUpButton = 10011; +const int kToggleDownButton = 10012; +const int kToggleLeftButton = 10013; +const int kToggleRightButton = 10014; class InteractiveButton: public SimpleButton { diff --git a/projects/mtg/include/MTGDeck.h b/projects/mtg/include/MTGDeck.h index cb901f2a7..053ea1a00 100644 --- a/projects/mtg/include/MTGDeck.h +++ b/projects/mtg/include/MTGDeck.h @@ -214,6 +214,7 @@ public: string meta_desc; string meta_name; vector meta_AIHints; + vector Sideboard; string meta_unlockRequirements; int meta_id; @@ -230,6 +231,7 @@ public: int removeAll(); int add(MTGCard * card); int remove(MTGCard * card); + void replaceSB(vector newSB = vector()); string getFilename(); int save(); int save(const string& destFileName, bool useExpandedDescriptions, const string& deckTitle, const string& deckDesc); diff --git a/projects/mtg/include/MTGGameZones.h b/projects/mtg/include/MTGGameZones.h index 5219cb5f7..90a4d48eb 100644 --- a/projects/mtg/include/MTGGameZones.h +++ b/projects/mtg/include/MTGGameZones.h @@ -80,6 +80,13 @@ class MTGGameZone { OWNER_REVEAL = 76, TARGETED_PLAYER_REVEAL = 77, + MY_SIDEBOARD = 81, + OPPONENT_SIDEBOARD = 82, + TARGET_OWNER_SIDEBOARD = 83, + TARGET_CONTROLLER_SIDEBOARD = 84, + SIDEBOARD = 85, + OWNER_SIDEBOARD = 86, + TARGETED_PLAYER_SIDEBOARD = 87, }; Player * owner; @@ -204,6 +211,7 @@ public: MTGGameZone * garbage; MTGGameZone * garbageLastTurn; MTGGameZone * reveal; + MTGGameZone * sideboard; MTGGameZone * temp; MTGPlayerCards(); diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index e1288ca57..690bcf67d 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -1861,7 +1861,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,p->game->exile, p->game->reveal }; + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay,p->game->stack,p->game->exile, p->game->reveal, p->game->sideboard }; if(a->getActionTc()->canTarget((Targetable*)p)) { if(a->getActionTc()->maxtargets == 1) @@ -2344,8 +2344,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,playerZones->exile,playerZones->reveal }; - for (int j = 0; j < 7; j++) + MTGGameZone * zones[] = { playerZones->hand, playerZones->library, playerZones->inPlay, playerZones->graveyard,playerZones->stack,playerZones->exile,playerZones->reveal, playerZones->sideboard }; + for (int j = 0; j < 8; j++) { MTGGameZone * zone = zones[j]; for (int k = 0; k < zone->nb_cards; k++) diff --git a/projects/mtg/src/DeckEditorMenu.cpp b/projects/mtg/src/DeckEditorMenu.cpp index beb100ec8..710fe3d54 100644 --- a/projects/mtg/src/DeckEditorMenu.cpp +++ b/projects/mtg/src/DeckEditorMenu.cpp @@ -58,10 +58,11 @@ void DeckEditorMenu::Render() DeckMenu::Render(); if (deckTitle.size() > 0) { + float modt = (float)deckTitle.size()/2; WFont *mainFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT); DWORD currentColor = mainFont->GetColor(); mainFont->SetColor(ARGB(255,255,255,255)); - mainFont->DrawString(deckTitle.c_str(), (SCREEN_WIDTH_F / 2)-15, (statsHeight / 2)+4, JGETEXT_CENTER); + mainFont->DrawString(deckTitle.c_str(), (SCREEN_WIDTH_F / 2)-modt, (statsHeight / 2)+4, JGETEXT_CENTER); mainFont->SetColor(currentColor); } @@ -75,7 +76,7 @@ void DeckEditorMenu::drawDeckStatistics() deckStatsString << _("------- Deck Summary -----") << endl - << _("Cards: ") << stw->cardCount << endl + << _("Cards: ") << stw->cardCount << " Sideboard: " << selectedDeck->parent->Sideboard.size() << endl << _("Creatures: ") << setw(2) << stw->countCreatures << _(" Enchantments: ") << stw->countEnchantments << endl << _("Instants: ") << setw(4) << stw->countInstants diff --git a/projects/mtg/src/GameStateDeckViewer.cpp b/projects/mtg/src/GameStateDeckViewer.cpp index 891ae15fd..87d558a03 100644 --- a/projects/mtg/src/GameStateDeckViewer.cpp +++ b/projects/mtg/src/GameStateDeckViewer.cpp @@ -37,16 +37,19 @@ GameStateDeckViewer::GameStateDeckViewer(GameApp* parent) : welcome_menu = NULL; myCollection = NULL; myDeck = NULL; + mySideboard = NULL; filterMenu = NULL; source = NULL; hudAlpha = 0; subMenu = NULL; + sbMenu = NULL; deckMenu = NULL; mStatsWrapper = NULL; statsPrevButton = NEW InteractiveButton(NULL, kPrevStatsButtonId, Fonts::MAIN_FONT, "Stats", SCREEN_WIDTH_F - 35, SCREEN_HEIGHT_F - 20, JGE_BTN_PREV); toggleDeckButton = NEW InteractiveButton(NULL, kToggleDeckActionId, Fonts::MAIN_FONT, "View Deck", 10, SCREEN_HEIGHT_F - 20, JGE_BTN_PRI); - sellCardButton = NEW InteractiveButton(NULL, kSellCardActionId, Fonts::MAIN_FONT, "Sell Card", (SCREEN_WIDTH_F/ 2) - 100, SCREEN_HEIGHT_F - 20, JGE_BTN_SEC); + sellCardButton = NEW InteractiveButton(NULL, kSellCardActionId, Fonts::MAIN_FONT, "Sell Card", (SCREEN_WIDTH_F/ 2) - 125, SCREEN_HEIGHT_F - 20, JGE_BTN_SEC); + sbButton = NEW InteractiveButton(NULL, kSBActionId, Fonts::MAIN_FONT, "View SB", (SCREEN_WIDTH_F/ 2) - 35, SCREEN_HEIGHT_F - 20, JGE_BTN_SOUND); filterButton = NEW InteractiveButton(NULL, kFilterButtonId, Fonts::MAIN_FONT, "Filter", (SCREEN_WIDTH_F - 116), SCREEN_HEIGHT_F - 20, JGE_BTN_CTRL); //TODO: Check if that button is available: toggleViewButton = NEW InteractiveButton(NULL, kSwitchViewButton, Fonts::MAIN_FONT, "Grid", (SCREEN_WIDTH_F/ 2) + 50, SCREEN_HEIGHT_F - 20, JGE_BTN_MAX); @@ -61,6 +64,7 @@ GameStateDeckViewer::~GameStateDeckViewer() SAFE_DELETE(bgMusic); SAFE_DELETE(toggleDeckButton); SAFE_DELETE(sellCardButton); + SAFE_DELETE(sbButton); SAFE_DELETE(statsPrevButton); SAFE_DELETE(filterButton); SAFE_DELETE(toggleViewButton); @@ -75,6 +79,11 @@ GameStateDeckViewer::~GameStateDeckViewer() SAFE_DELETE(myDeck->parent); SAFE_DELETE(myDeck); } + if (mySideboard) + { + SAFE_DELETE(mySideboard->parent); + SAFE_DELETE(mySideboard); + } if (myCollection) { SAFE_DELETE(myCollection->parent); @@ -110,9 +119,12 @@ void GameStateDeckViewer::updateFilters() void GameStateDeckViewer::toggleCollection() { + if(mView->deck() == mySideboard) + return; + if (mView->deck() == myCollection) { - toggleDeckButton->setText("View Collection"); + toggleDeckButton->setText("Collection"); mView->SetDeck(myDeck); } else @@ -124,6 +136,23 @@ void GameStateDeckViewer::toggleCollection() updateFilters(); } +void GameStateDeckViewer::toggleSideBoard() +{ + if(mView->deck() == myDeck) + return; + + if (mView->deck() == myCollection) + { + mView->SetDeck(mySideboard); + } + else + { + mView->SetDeck(myCollection); + } + //source->swapSrc(); + //updateFilters(); +} + //after renaming and on the first start. //reloadWelcomeMenu void GameStateDeckViewer::updateDecks() @@ -164,7 +193,9 @@ void GameStateDeckViewer::Start() hudAlpha = 0; mSwitching = false; subMenu = NULL; + sbMenu = NULL; myDeck = NULL; + mySideboard = NULL; mStage = STAGE_WELCOME; last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; @@ -215,6 +246,7 @@ void GameStateDeckViewer::End() SAFE_DELETE(welcome_menu); SAFE_DELETE(deckMenu); SAFE_DELETE(subMenu); + SAFE_DELETE(sbMenu); WResourceManager::Instance()->Release(pspIconsTexture); if (myCollection) @@ -226,6 +258,11 @@ void GameStateDeckViewer::End() SAFE_DELETE(myDeck->parent); SAFE_DELETE(myDeck); } + if (mySideboard) + { + SAFE_DELETE(mySideboard->parent); + SAFE_DELETE(mySideboard); + } SAFE_DELETE(pricelist); SAFE_DELETE(playerdata); SAFE_DELETE(filterMenu); @@ -254,6 +291,75 @@ void GameStateDeckViewer::addRemove(MTGCard * card) mView->reloadIndexes(); } +void GameStateDeckViewer::SBaddRemove(MTGCard * card) +{ + if (!card) return; + if ((card->getRarity() == Constants::RARITY_T) || (card->getId() < 1)) return; + if (mView->deck()->Remove(card, 1, (mView->deck() == mySideboard))) + { + if (mView->deck() == myCollection) + { + mySideboard->Add(card); + mySideboard->Sort(WSrcCards::SORT_ALPHA); + } + else + { + myCollection->Add(card); + } + } + myCollection->validate(); + mySideboard->validate(); + mStatsWrapper->needUpdate = true; + mView->reloadIndexes(); +} + +void GameStateDeckViewer::choiceAddRemove(MTGCard * card) +{ + if (!card) return; + if ((card->getRarity() == Constants::RARITY_T) || (card->getId() < 1)) return; + last_user_activity = 0; + const float menuXOffset = SCREEN_WIDTH_F - 300; + const float menuYOffset = SCREEN_HEIGHT_F / 2; + SAFE_DELETE(sbMenu); + { + if (mView->deck() == myCollection) + { + sbMenu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), SBMENU_CHOICE, this, Fonts::MAIN_FONT, menuXOffset, menuYOffset, "Add/Remove Cards"); + sbMenu->Add(SBMENU_ADD_NORMAL, "Add to Deck"); + sbMenu->Add(SBMENU_ADD_SB, "Add to Sideboard"); + sbMenu->Add(SBMENU_ADD_CANCEL, "Cancel"); + } + else + { + sbMenu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), SBMENU_CHOICE, this, Fonts::MAIN_FONT, menuXOffset, menuYOffset, "Add/Remove Cards"); + sbMenu->Add(SBMENU_ADD_NORMAL, "Remove Card"); + //sbMenu->Add(SBMENU_ADD_SB, "Add to Sideboard"); + sbMenu->Add(SBMENU_ADD_CANCEL, "Cancel"); + } + } + mStatsWrapper->needUpdate = true; +} + +void GameStateDeckViewer::insertSideBoard() +{ + if(mySideboard->getCount()) + { + vector newSB; + for (int i = 0; i < mySideboard->Size(true); i++) + { + MTGCard * current = mySideboard->getCard(i, true); + int howmanyinDeck = mySideboard->count(current); + for (int i = 0; i < howmanyinDeck; i++) + { + stringstream cid; + cid << current->getMTGId(); + newSB.push_back(cid.str()); + } + } + myDeck->parent->replaceSB(newSB); + } +} + void GameStateDeckViewer::saveDeck() { //update the corresponding meta data object @@ -261,6 +367,9 @@ void GameStateDeckViewer::saveDeck() if ( newDeckname.length() > 0 ) metaData->setDeckName( newDeckname ); mSwitching = true; + //insert sideboards to mydeck parents + insertSideBoard(); + //save deck myDeck->save(); playerdata->save(); pricelist->save(); @@ -315,6 +424,7 @@ bool GameStateDeckViewer::userPressedButton() { return ((toggleDeckButton->ButtonPressed()) || (sellCardButton->ButtonPressed()) + || (sbButton->ButtonPressed()) || (statsPrevButton->ButtonPressed()) || (filterButton->ButtonPressed()) || (toggleViewButton->ButtonPressed()) @@ -329,6 +439,7 @@ void GameStateDeckViewer::setButtonState(bool state) { toggleDeckButton->setIsSelectionValid(state); sellCardButton->setIsSelectionValid(state); + sbButton->setIsSelectionValid(state); statsPrevButton->setIsSelectionValid(state); filterButton->setIsSelectionValid(state); toggleViewButton->setIsSelectionValid(state); @@ -340,9 +451,13 @@ void GameStateDeckViewer::setButtonState(bool state) void GameStateDeckViewer::RenderButtons() { - toggleDeckButton->Render(); + if(mView->deck() != mySideboard) + toggleDeckButton->Render(); sellCardButton->Render(); - filterButton->Render(); + if(mView->deck() != myDeck) + sbButton->Render(); + if(mView->deck() != mySideboard) + filterButton->Render(); statsPrevButton->Render(); toggleViewButton->Render(); toggleUpButton->Render(); @@ -418,6 +533,15 @@ void GameStateDeckViewer::Update(float dt) } return; } + if (sbMenu) + { + sbMenu->Update(dt); + if (sbMenu->isClosed()) + { + SAFE_DELETE(sbMenu); + } + return; + } if (mStage == STAGE_WAITING || mStage == STAGE_ONSCREEN_MENU) { JButton button = mEngine->ReadButton(); @@ -436,6 +560,13 @@ void GameStateDeckViewer::Update(float dt) case JGE_BTN_CANCEL: options[Options::DISABLECARDS].number = !options[Options::DISABLECARDS].number; break; + case JGE_BTN_SOUND: + if (last_user_activity > 0.2) + { + last_user_activity = 0; + toggleSideBoard(); + } + break; case JGE_BTN_PRI: if (last_user_activity > 0.2) { @@ -465,14 +596,16 @@ void GameStateDeckViewer::Update(float dt) mEngine->LeftClickedProcessed(); if(mView->Click(x, y) != NULL) { - addRemove(mView->getActiveCard()); + //addRemove(mView->getActiveCard()); + choiceAddRemove(mView->getActiveCard()); } } else { if(mView->Click() != NULL) { - addRemove(mView->getActiveCard()); + //addRemove(mView->getActiveCard()); + choiceAddRemove(mView->getActiveCard()); } } @@ -485,11 +618,20 @@ void GameStateDeckViewer::Update(float dt) break; case JGE_BTN_MENU: - mStage = STAGE_MENU; - buildEditorMenu(); + if(mView->deck() == mySideboard) + { + toggleSideBoard(); + } + else + { + mStage = STAGE_MENU; + buildEditorMenu(); + } break; case JGE_BTN_CTRL: - if(!mView->ButtonPressed(JGE_BTN_CTRL)) + if (mView->deck() == mySideboard) + break;//SB is for viewing add or remove only + else if(!mView->ButtonPressed(JGE_BTN_CTRL)) { mStage = STAGE_FILTERS; if (!filterMenu) @@ -774,27 +916,21 @@ void GameStateDeckViewer::renderOnScreenMenu() char buffer[300]; int nb_letters = 0; int value = myDeck->getCount(WSrcDeck::UNFILTERED_COPIES); - - sprintf(buffer, _("Your Deck: %i cards").c_str(), value); - font->DrawString(buffer, SCREEN_WIDTH - 200 + rightTransition, SCREEN_HEIGHT / 2 + 25); + int sb_value = mySideboard->getCount(WSrcDeck::UNFILTERED_COPIES); + + sprintf(buffer, _("Your Deck: %i cards.\nSideboard: %i cards").c_str(), value, sb_value); + font->DrawString(buffer, SCREEN_WIDTH - 200 + rightTransition, SCREEN_HEIGHT / 2 + 15); for (int j = 0; j < Constants::NB_Colors; j++) { int value = myDeck->getCount(j); - if (value > 0) + if(value > 0) { + int modx = value < 9?2:0; + r->RenderQuad(mIcons[j].get(), SCREEN_WIDTH - 190 + rightTransition + nb_letters * 8, SCREEN_HEIGHT / 2 + 49, 0, 0.45f,0.45f); sprintf(buffer, "%i", value); - font->DrawString(buffer, SCREEN_WIDTH - 190 + rightTransition + nb_letters * 13, SCREEN_HEIGHT / 2 + 40); - r->RenderQuad(mIcons[j].get(), SCREEN_WIDTH - 197 + rightTransition + nb_letters * 13, SCREEN_HEIGHT / 2 + 46, 0, 0.5, - 0.5); - if (value > 9) - { - nb_letters += 3; - } - else - { - nb_letters += 2; - } + font->DrawString(buffer, SCREEN_WIDTH - 195 + rightTransition + modx + nb_letters * 8, SCREEN_HEIGHT / 2 + 55); + nb_letters += 3; } } @@ -1330,6 +1466,8 @@ void GameStateDeckViewer::Render() if (subMenu) subMenu->Render(); + if (sbMenu) sbMenu->Render(); + if (filterMenu && !filterMenu->isFinished()) { setButtonState(false); @@ -1372,6 +1510,7 @@ int GameStateDeckViewer::loadDeck(int deckid) // Check whether the cards in the deck are actually available in the player's collection: int cheatmode = options[Options::CHEATMODE].number; bool bPure = true; + bool cPure = true; for (int i = 0; i < myDeck->Size(true); i++) { MTGCard * current = myDeck->getCard(i, true); @@ -1398,8 +1537,56 @@ int GameStateDeckViewer::loadDeck(int deckid) myDeck->validate(); myCollection->validate(); } + //sb + if (mySideboard) + { + SAFE_DELETE(mySideboard->parent); + SAFE_DELETE(mySideboard); + } + //temp deck for sb? + MTGDeck * tempDeck = NEW MTGDeck(MTGCollection()); + if(myDeck->parent) + {//add cards from sdeboard lists + if(myDeck->parent->Sideboard.size()) + { + for(unsigned int j = 0; j < myDeck->parent->Sideboard.size(); j++) + { + string cardID = myDeck->parent->Sideboard[j]; + tempDeck->add(atoi(cardID.c_str())); + } + } + } + mySideboard = NEW DeckDataWrapper(tempDeck); + for (int i = 0; i < mySideboard->Size(true); i++) + { + MTGCard * current = mySideboard->getCard(i, true); + int howmanyinDeck = mySideboard->count(current); + for (int i = myCollection->count(current); i < howmanyinDeck; i++) + { + cPure = false; + if (cheatmode) + { //Are we cheating? + playerdata->collection->add(current); //Yup, add it to collection permanently. + myCollection->Add(current); + } + else + { + mySideboard->Remove(current,howmanyinDeck-i); //Nope. Remove it from sb. + break; + } + } + + myCollection->Remove(current, mySideboard->count(current)); + } + if (!cPure) + { + mySideboard->validate(); + myCollection->validate(); + } + //endsb myDeck->Sort(WSrcCards::SORT_ALPHA); + mySideboard->Sort(WSrcCards::SORT_ALPHA); SAFE_DELETE(filterMenu); rebuildFilters(); mView->reloadIndexes(); @@ -1537,6 +1724,30 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) subMenu->Close(); break; } + + case SBMENU_CHOICE: // sideboard + switch (controlId) + { + case SBMENU_ADD_NORMAL: + { + MTGCard * card = mView->getActiveCard(); + if (card) + addRemove(card); + sbMenu->Close(); + break; + } + case SBMENU_ADD_SB: + { + MTGCard * card = mView->getActiveCard(); + if (card) + SBaddRemove(card); + sbMenu->Close(); + break; + } + case SBMENU_ADD_CANCEL: + sbMenu->Close(); + break; + } } } diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 3ae5ff9de..643c635f6 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -6081,8 +6081,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, p->game->exile ,p->game->reveal }; - for (int k = 0; k < 7; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile ,p->game->reveal, p->game->sideboard }; + for (int k = 0; k < 8; k++) { MTGGameZone * zone = zones[k]; if (canTarget(zone)) @@ -6153,8 +6153,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, p->game->exile, p->game->reveal }; - for (int k = 0; k < 7; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile, p->game->reveal, p->game->sideboard }; + for (int k = 0; k < 8; k++) { MTGGameZone * zone = zones[k]; if (canTarget(zone)) diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index d971423c4..b778a0b4f 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -880,6 +880,12 @@ MTGDeck::MTGDeck(const string& config_file, MTGAllCards * _allcards, int meta_on meta_unlockRequirements = s.substr(found + 7); continue; } + found = s.find("SB:"); + if (found != string::npos) + { + Sideboard.push_back(s.substr(found + 3)); + continue; + } continue; } if (meta_only) break; @@ -1101,6 +1107,16 @@ int MTGDeck::removeAll() return 1; } +void MTGDeck::replaceSB(vector newSB) +{ + if(newSB.size()) + { + Sideboard.clear(); + Sideboard = newSB; + } + return; +} + int MTGDeck::remove(int cardid) { if (cards.find(cardid) == cards.end() || cards[cardid] == 0) return 0; @@ -1170,6 +1186,18 @@ int MTGDeck::save(const string& destFileName, bool useExpandedDescriptions, cons } } } + //save sideboards + if(Sideboard.size()) + { + sort(Sideboard.begin(), Sideboard.end()); + for(unsigned int k = 0; k < Sideboard.size(); k++) + { + int checkID = atoi(Sideboard[k].c_str()); + if(checkID) + file << "#SB:" << checkID << "\n"; + } + } + file.close(); JFileSystem::GetInstance()->Rename(tmp, destFileName); } diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 277f92371..9c9baa4fa 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -63,6 +63,21 @@ void MTGPlayerCards::initDeck(MTGDeck * deck) } } } + //sb init + if(deck->Sideboard.size()) + { + for(unsigned int j = 0; j < deck->Sideboard.size(); j++) + { + string cardID = deck->Sideboard[j]; + MTGCard * card = MTGCollection()->getCardById(atoi(cardID.c_str())); + if(card) + { + MTGCardInstance * newCard = NEW MTGCardInstance(card, this); + //sb zone + sideboard->addCard(newCard); + } + } + } } MTGPlayerCards::~MTGPlayerCards() @@ -75,6 +90,7 @@ MTGPlayerCards::~MTGPlayerCards() SAFE_DELETE(removedFromGame); SAFE_DELETE(garbage); SAFE_DELETE(reveal); + SAFE_DELETE(sideboard); SAFE_DELETE(temp); SAFE_DELETE(playRestrictions); } @@ -93,6 +109,7 @@ void MTGPlayerCards::beforeBeginPhase() removedFromGame->beforeBeginPhase(); garbage->beforeBeginPhase(); reveal->beforeBeginPhase(); + sideboard->beforeBeginPhase(); temp->beforeBeginPhase(); } @@ -108,6 +125,7 @@ void MTGPlayerCards::setOwner(Player * player) garbage->setOwner(player); garbageLastTurn->setOwner(player); reveal->setOwner(player); + sideboard->setOwner(player); temp->setOwner(player); } @@ -276,6 +294,7 @@ void MTGPlayerCards::init() garbage = NEW MTGGameZone(); garbageLastTurn = garbage; reveal = NEW MTGGameZone(); + sideboard = NEW MTGGameZone(); temp = NEW MTGGameZone(); playRestrictions = NEW PlayRestrictions(); @@ -1084,6 +1103,13 @@ MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2) case REVEAL: return p->game->reveal; + case MY_SIDEBOARD: + return p->game->sideboard; + case OPPONENT_SIDEBOARD: + return p->opponent()->game->sideboard; + case SIDEBOARD: + return p->game->sideboard; + } if (!p2) return NULL; switch (zoneId) @@ -1109,6 +1135,9 @@ MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2) case TARGET_CONTROLLER_REVEAL: return p2->game->reveal; + case TARGET_CONTROLLER_SIDEBOARD: + return p2->game->sideboard; + default: return NULL; } @@ -1218,6 +1247,17 @@ MTGGameZone * MTGGameZone::intToZone(GameObserver *g, int zoneId, MTGCardInstanc return source->playerTarget->game->reveal; else return source->controller()->game->reveal; + case TARGET_OWNER_SIDEBOARD: + return target->owner->game->sideboard; + case SIDEBOARD: + return target->owner->game->sideboard; + case OWNER_SIDEBOARD: + return target->owner->game->sideboard; + case TARGETED_PLAYER_SIDEBOARD: + if (source->playerTarget) + return source->playerTarget->game->sideboard; + else return source->controller()->game->sideboard; + default: return NULL; } @@ -1245,7 +1285,9 @@ int MTGGameZone::zoneStringToId(string zoneName) "mystack", "opponentstack", "targetownerstack", "targetcontrollerstack", "ownerstack", "stack","targetedpersonsstack", - "myreveal", "opponentreveal", "targetownerreveal", "targetcontrollerreveal", "ownerreveal", "reveal","targetedpersonsreveal", + "myreveal", "opponentreveal", "targetownerreveal", "targetcontrollerreveal", "ownerreveal", "reveal","targetedpersonsreveal", + + "mysideboard", "opponentsideboard", "targetownersideboard", "targetcontrollersideboard", "ownersideboard", "sideboard","targetedpersonssideboard", }; @@ -1268,7 +1310,9 @@ int MTGGameZone::zoneStringToId(string zoneName) MY_STACK, OPPONENT_STACK, TARGET_OWNER_STACK, TARGET_CONTROLLER_STACK, OWNER_STACK, STACK,TARGETED_PLAYER_STACK, - MY_REVEAL, OPPONENT_REVEAL, TARGET_OWNER_REVEAL, TARGET_CONTROLLER_REVEAL, OWNER_REVEAL, REVEAL,TARGETED_PLAYER_REVEAL }; + MY_REVEAL, OPPONENT_REVEAL, TARGET_OWNER_REVEAL, TARGET_CONTROLLER_REVEAL, OWNER_REVEAL, REVEAL,TARGETED_PLAYER_REVEAL, + + MY_SIDEBOARD, OPPONENT_SIDEBOARD, TARGET_OWNER_SIDEBOARD, TARGET_CONTROLLER_SIDEBOARD, OWNER_SIDEBOARD, SIDEBOARD,TARGETED_PLAYER_SIDEBOARD }; int max = sizeof(values) / sizeof *(values); diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index e1b50df2b..1fb5c3afd 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -414,13 +414,14 @@ 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, p->game->exile , p->game->reveal }; + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay, p->game->exile , p->game->reveal, p->game->sideboard }; 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, initState.playerData[i].player->game->exile, - initState.playerData[i].player->game->reveal }; + initState.playerData[i].player->game->reveal, + initState.playerData[i].player->game->sideboard }; for (int j = 0; j < 5; j++) { MTGGameZone * zone = playerZones[j]; diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 8a82bbf35..29c26ca85 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -156,6 +156,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta { zones[nbzones++] = MTGGameZone::ALL_ZONES; } + else if (zoneName.compare("sideboard") == 0) + { + zones[nbzones++] = MTGGameZone::MY_SIDEBOARD; + zones[nbzones++] = MTGGameZone::OPPONENT_SIDEBOARD; + } else if (zoneName.compare("reveal") == 0) { zones[nbzones++] = MTGGameZone::MY_REVEAL; @@ -1111,8 +1116,8 @@ bool TargetChooser::validTargetsExist(int maxTargets) int maxAmount = 0; Player *p = observer->players[i]; if (canTarget(p)) return true; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile, p->game->stack, p->game->reveal }; - for (int k = 0; k < 7; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile, p->game->stack, p->game->reveal, p->game->sideboard }; + for (int k = 0; k < 8; k++) { MTGGameZone * z = zones[k]; if (targetsZone(z)) @@ -1145,8 +1150,8 @@ int TargetChooser::countValidTargets(bool withoutProtections) Player *p = observer->players[i]; if(canTarget(p)) result++; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile, p->game->stack, p->game->reveal }; - for (int k = 0; k < 7; k++) + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile, p->game->stack, p->game->reveal, p->game->sideboard }; + for (int k = 0; k < 8; k++) { MTGGameZone * z = zones[k]; if (targetsZone(z))