From 8cc2fc9d5213f72e4580308b87abbc486006f0fe Mon Sep 17 00:00:00 2001 From: "wagic.the.homebrew@gmail.com" Date: Sat, 25 Jul 2009 11:43:36 +0000 Subject: [PATCH] Erwan - The AI can now use May Abilities --- projects/mtg/bin/Res/test/_tests.txt | 1 + projects/mtg/bin/Res/test/kraken_eye3.txt | 20 +++++++ projects/mtg/include/AIPlayer.h | 1 + projects/mtg/include/ActionLayer.h | 3 +- projects/mtg/include/AllAbilities.h | 1 + projects/mtg/src/AIPlayer.cpp | 38 ++++++++++---- projects/mtg/src/ActionLayer.cpp | 13 +++-- projects/mtg/src/ActionStack.cpp | 63 +++++++---------------- projects/mtg/src/GameObserver.cpp | 1 + 9 files changed, 83 insertions(+), 58 deletions(-) create mode 100644 projects/mtg/bin/Res/test/kraken_eye3.txt diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index 710f1e73e..562eea015 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -103,6 +103,7 @@ keldon_warlord2.txt kird_ape.txt kraken_eye.txt kraken_eye2.txt +kraken_eye3.txt kudzu.txt kudzu2.txt lhurgoyf.txt diff --git a/projects/mtg/bin/Res/test/kraken_eye3.txt b/projects/mtg/bin/Res/test/kraken_eye3.txt new file mode 100644 index 000000000..c4aaef647 --- /dev/null +++ b/projects/mtg/bin/Res/test/kraken_eye3.txt @@ -0,0 +1,20 @@ +#Kraken eye works ok if spell cast by opponent ? +[INIT] +FIRSTMAIN +[PLAYER1] +hand:air elemental +manapool:{3}{U}{U} +[PLAYER2] +inplay:kraken's eye +[DO] +air elemental +choice 0 +[ASSERT] +FIRSTMAIN +[PLAYER1] +inplay:air elemental +life:20 +[PLAYER2] +inplay:kraken's eye +life:21 +[END] \ No newline at end of file diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index b3760f13a..3c51e1df3 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -71,6 +71,7 @@ class AIPlayer: public Player{ virtual int chooseTarget(TargetChooser * tc = NULL); virtual int Act(float dt); int isAI(){return 1;}; + int canHandleCost(MTGAbility * ability); int selectAbility(); int createAbilityTargets(MTGAbility * a, MTGCardInstance * c, map * ranking); int useAbility(); diff --git a/projects/mtg/include/ActionLayer.h b/projects/mtg/include/ActionLayer.h index 2d180984b..278b63466 100644 --- a/projects/mtg/include/ActionLayer.h +++ b/projects/mtg/include/ActionLayer.h @@ -27,7 +27,8 @@ class ActionLayer: public GuiLayer, public JGuiListener{ bool CheckUserInput(u32 key); ActionLayer(int id, GameObserver* _game):GuiLayer(id, _game){ menuObject = NULL; abilitiesMenu = NULL; stuffHappened = 0;}; ~ActionLayer(); - int isWaitingForAnswer(); + int cancelCurrentAction(); + ActionElement * isWaitingForAnswer(); int isReactingToTargetClick(Targetable * card); int receiveEvent(WEvent * event); int reactToTargetClick(Targetable * card); diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 93a65bc95..8fc246127 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -140,6 +140,7 @@ public: if (!triggered){ triggered = 1; game->mLayers->actionLayer()->setMenuObject(source); + game->mLayers->stackLayer()->setIsInterrupting(source->controller()); OutputDebugString("SetMenuObject!\n"); } } diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index f2b257dbd..76003aade 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -76,7 +76,7 @@ void AIPlayer::tapLandsForMana(ManaCost * potentialMana, ManaCost * cost){ //Make sure we can use the ability MTGAbility * a = ((MTGAbility *)g->mLayers->actionLayer()->mObjects[i]); AManaProducer * amp = dynamic_cast(a); - if (amp){ + if (amp && canHandleCost(amp)){ MTGCardInstance * card = amp->source; if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost()==1){ used[card] = true; @@ -108,7 +108,7 @@ ManaCost * AIPlayer::getPotentialMana(){ //Make sure we can use the ability MTGAbility * a = ((MTGAbility *)g->mLayers->actionLayer()->mObjects[i]); AManaProducer * amp = dynamic_cast(a); - if (amp){ + if (amp && canHandleCost(amp)){ MTGCardInstance * card = amp->source; if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost()==1){ potentialMana->add(amp->output); @@ -125,6 +125,19 @@ int AIPlayer::getEfficiency(AIAction * action){ return action->getEfficiency(); } +int AIPlayer::canHandleCost(MTGAbility * ability){ + //Can't handle sacrifice costs that require a target yet :( + if (ability->cost){ + ExtraCosts * ec = ability->cost->extraCosts; + if (ec){ + for (size_t i = 0; i < ec->costs.size(); i++){ + if (ec->costs[i]->tc) return 0; + } + } + } + return 1; +} + int AIAction::getEfficiency(){ //TODO add multiplier according to what the player wants if (efficiency != -1) return efficiency; @@ -146,15 +159,8 @@ int AIAction::getEfficiency(){ return 0; } - //Can't handle sacrifice costs that require a target yet :( - if (ability->cost){ - ExtraCosts * ec = ability->cost->extraCosts; - if (ec){ - for (size_t i = 0; i < ec->costs.size(); i++){ - if (ec->costs[i]->tc) return 0; - } - } - } + if (!((AIPlayer *)p)->canHandleCost(ability)) return 0; + switch (a->aType){ case MTGAbility::DAMAGER: { @@ -634,6 +640,10 @@ int AIPlayerBaka::computeActions(){ GameObserver * g = GameObserver::GetInstance(); Player * p = g->currentPlayer; if (!(g->currentlyActing() == this)) return 0; + if (g->mLayers->actionLayer()->menuObject){ + g->mLayers->actionLayer()->doReactTo(0); + return 1; + } if (chooseTarget()) return 1; int currentGamePhase = g->getCurrentGamePhase(); if (g->isInterrupting == this){ // interrupting @@ -709,6 +719,12 @@ int AIPlayerBaka::computeActions(){ int AIPlayerBaka::Act(float dt){ GameObserver * g = GameObserver::GetInstance(); + + if (!(g->currentlyActing() == this)){ + OutputDebugString("Cannot interrupt\n"); + return 0; + } + int currentGamePhase = g->getCurrentGamePhase(); if (currentGamePhase == Constants::MTG_PHASE_CLEANUP && currentGamePhase != oldGamePhase){ diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index b4b592a46..d0a0ea3d5 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -115,12 +115,19 @@ TargetChooser * ActionLayer::getCurrentTargetChooser(){ return NULL; } -int ActionLayer::isWaitingForAnswer(){ +int ActionLayer::cancelCurrentAction(){ + ActionElement * ae = isWaitingForAnswer(); + if (!ae) return 0; + ae->waitingForAnswer = 0; //TODO MOVE THIS IS ActionElement + return 1; +} + +ActionElement * ActionLayer::isWaitingForAnswer(){ for (int i=0;iwaitingForAnswer) return 1; + if(currentAction->waitingForAnswer) return currentAction; } - return 0; + return NULL; } int ActionLayer::stillInUse(MTGCardInstance * card){ diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 5d2d6e687..e459cb54e 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -515,29 +515,6 @@ void ActionStack::repackDamageStacks(){ } if (!found) ++iter; } - -/* - for (int i = mCount-1; i >=0; i--){ - Interruptible * action = ((Interruptible *)mObjects[i]); - if (action->type == ACTION_DAMAGE){ - Damage * damage = (Damage *) action; - for (int j = 0; j < mCount; j++){ - Interruptible * action2 = ((Interruptible *)mObjects[j]); - if (action2->type == ACTION_DAMAGES){ - DamageStack * ds = (DamageStack *) action2; - for (int k = 0; k< ds->mCount; k++){ - Damage * dsdamage = ((Damage *)ds->mObjects[k]); - if (dsdamage==damage){ - //Remove(damage); - mObjects[i] = mObjects[mCount-1]; - mCount--; - } - } - } - } - } - } -*/ } void ActionStack::Update(float dt){ @@ -580,27 +557,27 @@ void ActionStack::Update(float dt){ if (getLatest(NOT_RESOLVED)){ int currentPlayerId = 0; int otherPlayerId = 1; - if (game->currentPlayer != game->players[0]){ - currentPlayerId = 1; - otherPlayerId = 0; - } - if (interruptDecision[currentPlayerId] == 0){ - askIfWishesToInterrupt = game->players[currentPlayerId]; - game->isInterrupting = game->players[currentPlayerId]; - modal = 1; - }else if (interruptDecision[currentPlayerId] == -1){ - game->isInterrupting = game->players[currentPlayerId]; + if (game->currentlyActing() != game->players[0]){ + currentPlayerId = 1; + otherPlayerId = 0; + } + if (interruptDecision[currentPlayerId] == 0){ + askIfWishesToInterrupt = game->players[currentPlayerId]; + game->isInterrupting = game->players[currentPlayerId]; + modal = 1; + }else if (interruptDecision[currentPlayerId] == -1){ + game->isInterrupting = game->players[currentPlayerId]; - }else{ - if (interruptDecision[otherPlayerId] == 0){ - askIfWishesToInterrupt = game->players[otherPlayerId]; - game->isInterrupting = game->players[otherPlayerId]; - modal = 1; - }else if (interruptDecision[otherPlayerId] == -1){ - game->isInterrupting = game->players[otherPlayerId]; - }else{ - resolve(); - } + }else{ + if (interruptDecision[otherPlayerId] == 0){ + askIfWishesToInterrupt = game->players[otherPlayerId]; + game->isInterrupting = game->players[otherPlayerId]; + modal = 1; + }else if (interruptDecision[otherPlayerId] == -1){ + game->isInterrupting = game->players[otherPlayerId]; + }else{ + resolve(); + } } } }else if (mode == ACTIONSTACK_TARGET){ diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 760720e58..7df4ddf4a 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -142,6 +142,7 @@ void GameObserver::nextGamePhase(){ int GameObserver::cancelCurrentAction(){ SAFE_DELETE(targetChooser); + mLayers->actionLayer()->cancelCurrentAction(); return 1; }