From 97bd418aac5ed56cdc147db592fee43fe43157cd Mon Sep 17 00:00:00 2001 From: "omegablast2002@yahoo.com" Date: Tue, 13 Mar 2012 16:20:19 +0000 Subject: [PATCH] in this commit, if we move a card from the library to the library then we were intending on placing that card on top of the library. taught ai when not to play a planeswalker, told ai to look for planeswalkers as a card type to play. fixed a crash related to tokens and cardgui..tokens dont have models.... made a 1 line change to deckveiwer that makes it usable on touch devices and improves the overall look and feel of deckveiwer.... --- projects/mtg/include/MTGGameZones.h | 2 ++ projects/mtg/src/AIPlayerBaka.cpp | 33 +++++++++++++++++++++--- projects/mtg/src/AIStats.cpp | 4 +-- projects/mtg/src/CardGui.cpp | 4 +-- projects/mtg/src/CardPrimitive.cpp | 3 +++ projects/mtg/src/DeckMenu.cpp | 6 ++--- projects/mtg/src/GameStateDeckViewer.cpp | 2 +- projects/mtg/src/GameStateMenu.cpp | 4 +++ projects/mtg/src/MTGGameZones.cpp | 27 ++++++++++++++++--- 9 files changed, 70 insertions(+), 15 deletions(-) diff --git a/projects/mtg/include/MTGGameZones.h b/projects/mtg/include/MTGGameZones.h index 4f8647dcb..6780990a2 100644 --- a/projects/mtg/include/MTGGameZones.h +++ b/projects/mtg/include/MTGGameZones.h @@ -98,6 +98,7 @@ class MTGGameZone { //returns true if one of the cards in the zone has the type bool hasType(const char * value); + bool hasTypeSpecificInt(int value1,int value); bool hasSpecificType(const char* value, const char* secondvalue); bool hasPrimaryType(const char* value, const char* secondvalue); bool hasTypeButNotType(const char* value, const char* secondvalue); @@ -124,6 +125,7 @@ class MTGGameZone { class MTGLibrary: public MTGGameZone { public: + vectorplaceOnTop; virtual ostream& toString(ostream&) const; const char * getName(){return "library";} }; diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index ba0a1ecd7..f6d38f141 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -74,6 +74,17 @@ int OrderedAIAction::getEfficiency() if (s->has(ability)) return 0; MTGAbility * a = AbilityFactory::getCoreAbility(ability); + MTGAbility * transAbility = NULL; + if(ATransformerInstant * atia = dynamic_cast(a)) + { + if(atia->newAbilityFound) + { + AbilityFactory af(g); + transAbility = af.parseMagicLine(atia->newAbilitiesList[atia->newAbilitiesList.size()-1], 0, NULL, atia->source); + transAbility->target = ability->target; + a = transAbility; + } + } if (!a) { DebugTrace("FATAL: Ability is NULL in AIAction::getEfficiency()"); @@ -81,8 +92,10 @@ int OrderedAIAction::getEfficiency() } if (!((AIPlayerBaka *)owner)->canHandleCost(ability)) + { + SAFE_DELETE(transAbility); return 0; - + } MTGCardInstance * coreAbilityCardTarget = dynamic_cast(a->target); //CoreAbility shouldn't return a Lord, but it does. @@ -183,6 +196,9 @@ int OrderedAIAction::getEfficiency() efficiency = 15 * (target->DangerRanking()); efficiency -= 5 * (target->equipment); } + + if ( efficiency < 20 && efficiency > 0 ) + efficiency += target->controller()->getObserver()->getRandomGenerator()->random() % 30; break; } case MTGAbility::STANDARD_LEVELUP: @@ -544,6 +560,12 @@ int OrderedAIAction::getEfficiency() efficiency = 10 + (owner->getRandomGenerator()->random() % 5); } } + else + { + efficiency = 50; + //may abilities target the source until thier nested ability is activated, so 50% chance to use this + //mover, until we can come up with something more elegent.... + } } else if (dynamic_cast(a)) { @@ -574,7 +596,6 @@ int OrderedAIAction::getEfficiency() } } } - //At this point the "basic" efficiency is computed, we further tweak it depending on general decisions, independent of theAbility type MayAbility * may = dynamic_cast(ability); @@ -607,6 +628,7 @@ int OrderedAIAction::getEfficiency() { efficiency += 65; } + SAFE_DELETE(transAbility); return efficiency; } @@ -1643,6 +1665,9 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty if (card->hasType(Subtypes::TYPE_LEGENDARY) && game->inPlay->findByName(card->name)) continue; + if (card->hasType(Subtypes::TYPE_PLANESWALKER) && card->types.size() > 0 && game->inPlay->hasTypeSpecificInt(Subtypes::TYPE_PLANESWALKER,card->types[1])) + continue; + int currentCost = card->getManaCost()->getConvertedCost(); int hasX = card->getManaCost()->hasX(); gotPayments.clear(); @@ -1885,9 +1910,9 @@ int AIPlayerBaka::computeActions() nextCardToPlay = FindCardToPlay(currentMana, "land"); //look for the most expensive creature we can afford. If not found, try enchantment, then artifact, etc... - const char* types[] = {"creature", "enchantment", "artifact", "sorcery", "instant"}; + const char* types[] = {"planeswalker","creature", "enchantment", "artifact", "sorcery", "instant"}; int count = 0; - while (!nextCardToPlay && count < 5) + while (!nextCardToPlay && count < 6) { if(clickstream.size()) //don't find cards while we have clicking to do. { diff --git a/projects/mtg/src/AIStats.cpp b/projects/mtg/src/AIStats.cpp index 970572a8e..3e9a59664 100644 --- a/projects/mtg/src/AIStats.cpp +++ b/projects/mtg/src/AIStats.cpp @@ -102,9 +102,9 @@ int AIStats::receiveEvent(WEvent * event) } stats.sort(compare_aistats); //this could be slow, if it is, let's run it only at the end of the turn - return 1; //is this meant to return 0 or 1? + return 1; } -//TODO:what does this do? +//the following tells ai if a creature should be blocked or targeted bool AIStats::isInTop(MTGCardInstance * card, unsigned int max, bool tooSmallCountsForTrue) { //return true; diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 0c5de2b71..13888887a 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -142,7 +142,7 @@ void CardGui::Render() bool alternate = true; JQuadPtr quad = game? game->getResourceManager()->RetrieveCard(card, CACHE_THUMB):WResourceManager::Instance()->RetrieveCard(card, CACHE_THUMB); - if(card && card->name != card->model->data->name) + if(card && !card->isToken && card->name != card->model->data->name) { MTGCard * fcard = MTGCollection()->getCardByName(card->name); quad = game->getResourceManager()->RetrieveCard(fcard, CACHE_THUMB); @@ -969,7 +969,7 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos) JQuadPtr quad = WResourceManager::Instance()->RetrieveCard(card); MTGCardInstance * kcard = dynamic_cast(card); - if(kcard && kcard->name != kcard->model->data->name) + if(kcard && !kcard->isToken && kcard->name != kcard->model->data->name) { MTGCard * fcard = MTGCollection()->getCardByName(kcard->name); quad = WResourceManager::Instance()->RetrieveCard(fcard); diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index 39e0f0abd..cbfc8ddfe 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -37,6 +37,8 @@ CardPrimitive::CardPrimitive() CardPrimitive::CardPrimitive(CardPrimitive * source) { + if(!source) + return; if(!source) return; basicAbilities = source->basicAbilities; @@ -218,6 +220,7 @@ void CardPrimitive::setSubtype(const string& value) } } + int id = MTGAllCards::add(value, parentType); addType(id); } diff --git a/projects/mtg/src/DeckMenu.cpp b/projects/mtg/src/DeckMenu.cpp index a85132cb2..4ed8f87c1 100644 --- a/projects/mtg/src/DeckMenu.cpp +++ b/projects/mtg/src/DeckMenu.cpp @@ -17,8 +17,8 @@ namespace { const float kVerticalMargin = 16; const float kHorizontalMargin = 20; - const float kLineHeight = 20; - const float kDescriptionVerticalBoxPadding = 5; + const float kLineHeight = 25; + const float kDescriptionVerticalBoxPadding = 35; const float kDescriptionHorizontalBoxPadding = 5; const float kDefaultFontScale = 1.0f; @@ -76,7 +76,7 @@ JGuiController(JGE::GetInstance(), id, listener), fontId(fontId), mShowDetailsSc mScroller = NEW VerticalTextScroller(Fonts::MAIN_FONT, 14, 235, scrollerWidth, scrollerHeight, kVerticalScrollSpeed); mAutoTranslate = true; - maxItems = 7; + maxItems = 6; mHeight = 2 * kVerticalMargin + (maxItems * kLineHeight); // we want to cap the deck titles to 15 characters to avoid overflowing deck names diff --git a/projects/mtg/src/GameStateDeckViewer.cpp b/projects/mtg/src/GameStateDeckViewer.cpp index a86c670f4..b4858b374 100644 --- a/projects/mtg/src/GameStateDeckViewer.cpp +++ b/projects/mtg/src/GameStateDeckViewer.cpp @@ -1416,7 +1416,7 @@ void GameStateDeckViewer::renderCard(int id, float rotation) float max_scale = 0.96f; float x_center_0 = 180; - float right_border = SCREEN_WIDTH - 20; + float right_border = SCREEN_WIDTH + 180; float x_center = x_center_0 + cos((rotation + 8 - id) * M_PI / 12) * (right_border - x_center_0); float scale = max_scale / 1.12f * cos((x_center - x_center_0) * 1.5f / (right_border - x_center_0)) + 0.2f * max_scale * cos( diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index fa30f2964..b686e2472 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -789,7 +789,11 @@ void GameStateMenu::ButtonPressed(int controllerId, int controlId) subMenuController = NEW SimpleMenu(JGE::GetInstance(), MENU_FIRST_DUEL_SUBMENU, this, Fonts::MENU_FONT, 150, 60); if (subMenuController) { +#ifdef NETWORK_SUPPORT subMenuController->Add(SUBMENUITEM_1PLAYER, "1 Player"); +#else + subMenuController->Add(SUBMENUITEM_1PLAYER, "Play Game"); +#endif // TODO Put 2 players mode back // This requires to fix the hand (to accept 2 players) OR to implement network game #ifdef NETWORK_SUPPORT diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 03b449566..20b770a6d 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -333,9 +333,16 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone } MTGCardInstance * ret = copy; - + for(int i = 0; i < 2; ++i) + { + if(to == g->players[i]->game->library && from == g->players[i]->game->library)//if its going to the library from the library we intend to put it on top. + { + g->players[i]->game->temp->addCard(copy); + g->players[i]->game->library->placeOnTop.push_back(copy); + return ret;//don't send event + } + } to->addCard(copy); - //The "Temp" zone are purely for code purposes, and we don't want the abilities engine to //Trigger when cards move in this zone // Additionally, when they move "from" this zone, @@ -456,6 +463,8 @@ MTGCardInstance * MTGGameZone::removeCard(MTGCardInstance * card, int createCopy //if (card->isToken) //TODO better than this ? // return card; //card->lastController = card->controller(); + if(!card) + return NULL; if (createCopy) { copy = card->clone(); @@ -463,6 +472,7 @@ MTGCardInstance * MTGGameZone::removeCard(MTGCardInstance * card, int createCopy copy->view = card->view; copy->isToken = card->isToken; copy->X = card->X; + copy->castX = card->castX; copy->kicked = card->kicked; //stupid bug with tokens... @@ -554,6 +564,18 @@ bool MTGGameZone::hasType(const char * value) return false; } +bool MTGGameZone::hasTypeSpecificInt(int value1,int value) +{ + for (int i = 0; i < (nb_cards); i++) + { + if (cards[i]->hasType(value1) && cards[i]->hasType(value)) + { + return true; + } + } + return false; +} + bool MTGGameZone::hasPrimaryType(const char * value,const char * secondvalue) { for (int i = 0; i < (nb_cards); i++) @@ -802,7 +824,6 @@ MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2) case STACK: return p->game->stack; } - if (!p2) return NULL; switch (zoneId) {