From 37fd0ebbd28ec4dd1bc278bd8684efb2a3f74fa7 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Mon, 18 Jul 2016 19:02:03 -0400 Subject: [PATCH 1/2] readded the "fakebar" size adjustments based on string lengths. in debug there is a strange line drawn sometimes on screen, like the buttons on main screen, this is not present in release builds, I'm guessing its some kind of debug related thing with JGE and quads. --- projects/mtg/src/GuiPhaseBar.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/projects/mtg/src/GuiPhaseBar.cpp b/projects/mtg/src/GuiPhaseBar.cpp index 9f879ecbb..c96fc78ab 100644 --- a/projects/mtg/src/GuiPhaseBar.cpp +++ b/projects/mtg/src/GuiPhaseBar.cpp @@ -151,10 +151,11 @@ void GuiPhaseBar::Render() sprintf(buf, _("(%s%s) %s").c_str(), currentP.c_str(), interrupt.c_str(),phaseNameToTranslate.c_str()); if(phaseinfo.get()) { - phaseinfo->SetHotSpot(phaseinfo->mWidth-2.f,0); - //phaseinfo->mWidth = font->GetStringWidth(buf)+12.f; + + phaseinfo->mWidth = font->GetStringWidth(buf)+12.f; + phaseinfo->SetHotSpot(phaseinfo->mWidth -4, 0); //phaseinfo->mHeight = font->GetHeight()+5.f; - JRenderer::GetInstance()->RenderQuad(phaseinfo.get(),SCREEN_WIDTH_F,0,0,SCREEN_WIDTH_F / phaseinfo->mWidth, SCREEN_HEIGHT_F / phaseinfo->mHeight); + JRenderer::GetInstance()->RenderQuad(phaseinfo.get(),SCREEN_WIDTH_F,0,0,2.2f, SCREEN_HEIGHT_F / phaseinfo->mHeight); } font->DrawString(buf, SCREEN_WIDTH - 5, 2, JGETEXT_RIGHT); } From 6316577ec7c5fd1963448ff6a1a25c004164e0af Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Mon, 18 Jul 2016 22:03:16 -0400 Subject: [PATCH 2/2] taught AI basic attack and block cost. added functionality to send specific abilities to AI "selectAbility" to have it find mana, targets, and use a selected ability at our command. --- projects/mtg/include/AIPlayerBaka.h | 2 +- projects/mtg/src/AIPlayerBaka.cpp | 103 ++++++++++++++++++++++++++-- projects/mtg/src/MTGRules.cpp | 18 +++-- 3 files changed, 113 insertions(+), 10 deletions(-) diff --git a/projects/mtg/include/AIPlayerBaka.h b/projects/mtg/include/AIPlayerBaka.h index 65816c015..e2275ce7b 100644 --- a/projects/mtg/include/AIPlayerBaka.h +++ b/projects/mtg/include/AIPlayerBaka.h @@ -107,7 +107,7 @@ class AIPlayerBaka: public AIPlayer{ virtual bool payTheManaCost(ManaCost * cost, MTGCardInstance * card = NULL,vector gotPayment = vector()); virtual int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0); virtual ManaCost * getPotentialMana(MTGCardInstance * card = NULL); - virtual int selectAbility(); + virtual int selectAbility(MTGAbility * Specific = NULL); public: enum { diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index c7f679fb3..1b2595510 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -1369,7 +1369,7 @@ int AIPlayerBaka::selectHintAbility() return 0; } -int AIPlayerBaka::selectAbility() +int AIPlayerBaka::selectAbility(MTGAbility * Specific) { if(observer->mExtraPayment && observer->mExtraPayment->source && observer->mExtraPayment->source->controller() == this) { @@ -1410,12 +1410,14 @@ int AIPlayerBaka::selectAbility() for (size_t i = 1; i < observer->mLayers->actionLayer()->mObjects.size(); i++) { //0 is not a mtgability...hackish MTGAbility * a = ((MTGAbility *) observer->mLayers->actionLayer()->mObjects[i]); + if (Specific && Specific != a) + continue; //Skip mana abilities for performance if (dynamic_cast (a)) continue; //Make sure we can use the ability for (int j = 0; j < game->inPlay->nb_cards; j++) - { + {//zeth fox: note to self, this is where I can teach it suspend and other cost types. MTGCardInstance * card = game->inPlay->cards[j]; if(a->getCost() && !a->isReactingToClick(card, totalPotentialMana))//for performance reason only look for specific mana if the payment couldnt be made with potential. { @@ -1444,7 +1446,32 @@ int AIPlayerBaka::selectAbility() ManaCost * pMana = getPotentialMana(card); pMana->add(this->getManaPool()); if (a->isReactingToClick(card, pMana)) + { createAbilityTargets(a, card, ranking); + if (Specific) + { + if (!Specific->getCost()) + { + //attackcost, blockcost + if (a->aType == MTGAbility::ATTACK_COST) + { + ManaCost * specificCost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); + specificCost->add(0, card->attackCostBackup); + abilityPayment = canPayMana(card, specificCost); + SAFE_DELETE(specificCost); + } + else if (a->aType == MTGAbility::BLOCK_COST) + { + ManaCost * specificCost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); + specificCost->add(0, card->blockCostBackup); + abilityPayment = canPayMana(card, specificCost); + SAFE_DELETE(specificCost); + } + } + delete (pMana); + break; + } + } delete (pMana); } } @@ -1458,6 +1485,8 @@ int AIPlayerBaka::selectAbility() if (!forceBestAbilityUse) chance = 1 + randomGenerator.random() % 100; int actionScore = action.getEfficiency(); + if (Specific) + actionScore = 95; if(action.ability->getCost() && action.ability->getCost()->hasX() && this->game->hand->cards.size()) actionScore = actionScore/int(this->game->hand->cards.size());//reduce chance for "x" abilities if cards are in hand. if (actionScore >= chance) @@ -1469,6 +1498,35 @@ int AIPlayerBaka::selectAbility() DebugTrace(" Ai knows exactly what mana to use for this ability."); } DebugTrace("AIPlayer:Using Activated ability"); + if (Specific) + { + if (!Specific->getCost()) + { + //attackcost, blockcost + if (action.ability->aType == MTGAbility::ATTACK_COST) + { + ManaCost * specificCost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); + specificCost->add(0, action.click->attackCostBackup); + if (payTheManaCost(specificCost, action.click, abilityPayment)) + clickstream.push(NEW AIAction(action)); + SAFE_DELETE(specificCost); + } + else if (action.ability->aType == MTGAbility::BLOCK_COST) + { + ManaCost * specificCost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); + specificCost->add(0, action.click->blockCostBackup); + if (payTheManaCost(specificCost, action.click, abilityPayment)) + clickstream.push(NEW AIAction(action)); + SAFE_DELETE(specificCost); + } + } + else + { + if (payTheManaCost(action.ability->getCost(), action.click, abilityPayment)) + clickstream.push(NEW AIAction(action)); + } + } + else if (payTheManaCost(action.ability->getCost(), action.click,abilityPayment)) clickstream.push(NEW AIAction(action)); } @@ -2624,8 +2682,19 @@ int AIPlayerBaka::chooseAttackers() MTGCardInstance * card = NULL; while ((card = cd.nextmatch(game->inPlay, card))) { - if(hints && hints->HintSaysAlwaysAttack(observer,card)) - observer->cardClick(card, MTGAbility::MTG_ATTACK_RULE); + if (hints && hints->HintSaysAlwaysAttack(observer, card)) + { + if (!card->isAttacker()) + { + if (card->attackCost) + { + MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::ATTACK_COST); + selectAbility(a); + observer->cardClick(card, MTGAbility::ATTACK_COST); + } + } + observer->cardClick(card, MTGAbility::MTG_ATTACK_RULE); + } } if (attack) @@ -2638,8 +2707,16 @@ int AIPlayerBaka::chooseAttackers() { if(hints && hints->HintSaysDontAttack(observer,card)) continue; - if(!card->isAttacker()) + if (!card->isAttacker()) + { + if (card->attackCost) + { + MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::ATTACK_COST); + selectAbility(a); + observer->cardClick(card, MTGAbility::ATTACK_COST); + } observer->cardClick(card, MTGAbility::MTG_ATTACK_RULE); + } } } return 1; @@ -2716,6 +2793,12 @@ int AIPlayerBaka::chooseBlockers() } else { + if (card->blockCost) + { + MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::BLOCK_COST); + selectAbility(a); + observer->cardClick(card, MTGAbility::BLOCK_COST); + } observer->cardClick(card, MTGAbility::MTG_BLOCK_RULE); } } @@ -2746,6 +2829,11 @@ int AIPlayerBaka::chooseBlockers() continue; if (!card->defenser) { + if (card->blockCost) + { + MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::BLOCK_COST); + selectAbility(a); + } observer->cardClick(card, MTGAbility::MTG_BLOCK_RULE); int set = 0; while (!set) @@ -2760,6 +2848,11 @@ int AIPlayerBaka::chooseBlockers() if (opponentsToughness[attacker] <= 0 || (card->toughness <= attacker->power && opponentForce * 2 < life && !canFirstStrikeKill(card, attacker)) || attacker->nbOpponents() > 1) { + if (card->blockCost) + { + MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::BLOCK_COST); + selectAbility(a); + } observer->cardClick(card, MTGAbility::MTG_BLOCK_RULE); } else diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 2cab2b17f..995fb30bb 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1553,7 +1553,7 @@ MTGAttackCostRule::MTGAttackCostRule(GameObserver* observer, int _id) : scost = "Pay to attack"; } -int MTGAttackCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) +int MTGAttackCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * aiCheck) { if (currentPhase == MTG_PHASE_COMBATATTACKERS && card->controller() == game->currentPlayer && card->controller() == game->currentlyActing())//on my turn and when I am the acting player. @@ -1571,8 +1571,12 @@ int MTGAttackCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) attackcost->extraCosts->costs[i]->setSource(card); } scost = attackcost->getConvertedCost(); - if (playerMana->canAfford(attackcost)) + if ((aiCheck && aiCheck->canAfford(attackcost)) || playerMana->canAfford(attackcost)) + { + SAFE_DELETE(attackcost); return 1; + } + SAFE_DELETE(attackcost); } return 0; } @@ -1588,6 +1592,7 @@ int MTGAttackCostRule::reactToClick(MTGCardInstance * card) playerMana->pay(attackcost);//I think you can't pay partial cost to attack cost so you pay full (508.1i) card->attackCost = 0; card->attackPlaneswalkerCost = 0; + SAFE_DELETE(attackcost); return 1; /* 508.1g: If any of the chosen creatures require paying costs to attack, the active player determines the total cost to attack. @@ -1622,7 +1627,7 @@ MTGBlockCostRule::MTGBlockCostRule(GameObserver* observer, int _id) : aType = MTGAbility::BLOCK_COST; scost = "Pay to block"; } -int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) +int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * aiCheck) { if (currentPhase == MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting && card->controller() != game->currentPlayer @@ -1642,8 +1647,12 @@ int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) blockcost->extraCosts->costs[i]->setSource(card); } scost = blockcost->getConvertedCost(); - if (playerMana->canAfford(blockcost)) + if ((aiCheck && aiCheck->canAfford(blockcost)) || playerMana->canAfford(blockcost)) + { + SAFE_DELETE(blockcost); return 1; + } + SAFE_DELETE(blockcost); } return 0; } @@ -1658,6 +1667,7 @@ int MTGBlockCostRule::reactToClick(MTGCardInstance * card) ManaCost * playerMana = player->getManaPool(); playerMana->pay(blockcost);//I think you can't pay partial cost to block cost so you pay full (509.1f) card->blockCost = 0; + SAFE_DELETE(blockcost); return 1; /* 509.1d: If any of the chosen creatures require paying costs to block, the defending player determines the total cost to block.