diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 8ad454fe0..26b5993f1 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -441,19 +441,12 @@ int AIAction::getEfficiency() AbilityFactory af; int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY); - if ((suggestion == BAKA_EFFECT_BAD && p == target->controller()) || (suggestion == BAKA_EFFECT_GOOD && p - != target->controller())) - { - efficiency = 0; - //stop giving trample to the players creatures. - } - - if (suggestion == BAKA_EFFECT_BAD && p != target->controller() && target->has(a->abilitygranted)) + if (suggestion == BAKA_EFFECT_BAD && p != target->controller() && target->has(a->abilitygranted) && p->isAI()) { efficiency += (25 * target->DangerRanking()) / p->game->hand->nb_cards; } - if (!target->has(a->abilitygranted) && g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBEGIN) + if (!target->has(a->abilitygranted) && g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBEGIN && p == target->controller() && p->isAI()) { efficiency += (25 * target->DangerRanking()) / p->game->hand->nb_cards; @@ -464,6 +457,13 @@ int AIAction::getEfficiency() //trying to avoid Ai giving ie:flying creatures ie:flying twice. efficiency = 0; } + + if ((suggestion == BAKA_EFFECT_BAD && p == target->controller()) || (suggestion == BAKA_EFFECT_GOOD && p + != target->controller())) + { + efficiency = 0; + //stop giving trample to the players creatures. + } break; } @@ -519,9 +519,9 @@ int AIAction::getEfficiency() efficiency = int(20 + p->game->library->nb_cards) - int(p->game->hand->nb_cards * 7); if(p->game->hand->nb_cards > 8)//reduce by 50 if cards in hand are over 8, high chance ai cant play them. { - efficiency -= 50; + efficiency -= 70; } - if(a->nbcardAmount >= p->game->library->nb_cards || p->game->hand->nb_cards > 10) + if((a->nbcardAmount >= p->game->library->nb_cards && p->isAI()) || (p->game->hand->nb_cards > 10 && p->isAI())) { //if the amount im drawing will mill me to death or i have more then 10 cards in hand, eff is 0; efficiency = 0; diff --git a/projects/mtg/src/AIStats.cpp b/projects/mtg/src/AIStats.cpp index 132ab47c7..27ded1d03 100644 --- a/projects/mtg/src/AIStats.cpp +++ b/projects/mtg/src/AIStats.cpp @@ -104,6 +104,8 @@ int AIStats::receiveEvent(WEvent * event) //TODO:what does this do? bool AIStats::isInTop(MTGCardInstance * card, unsigned int max, bool tooSmallCountsForTrue) { + //return true; + //uncomment the above return to make Ai always multiblock your creatures. if (stats.size() < max) return tooSmallCountsForTrue; unsigned int n = 0; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 2f0243c2a..57b528f6e 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -196,36 +196,60 @@ void GameObserver::nextCombatStep() void GameObserver::userRequestNextGamePhase() { - if (mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED)) - return; - if (getCurrentTargetChooser()) - return; - + if (mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED)) + return; + if (getCurrentTargetChooser()) + return; + if (mLayers->actionLayer()->isWaitingForAnswer()) + return; // Wil 12/5/10: additional check, not quite understanding why TargetChooser doesn't seem active at this point. // If we deem that an extra cost payment needs to be made, don't allow the next game phase to proceed. // Here's what I find weird - if the extra cost is something like a sacrifice, doesn't that imply a TargetChooser? - if (WaitForExtraPayment(NULL)) + if (WaitForExtraPayment(NULL)) return; bool executeNextPhaseImmediately = true; + Phase * cPhaseOld = phaseRing->getCurrentPhase(); + if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) || (cPhaseOld->id + == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == TRIGGERS) || cPhaseOld->id + == Constants::MTG_PHASE_COMBATDAMAGE || (opponent()->isAI() && currentPlayer->isAI())//test suite + ||options[Options::optionInterrupt(currentGamePhase)].number ||(cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE && combatStep == FIRST_STRIKE)) + { + executeNextPhaseImmediately = false; + } - Phase * cPhaseOld = phaseRing->getCurrentPhase(); - if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) || (cPhaseOld->id - == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == TRIGGERS) || cPhaseOld->id - == Constants::MTG_PHASE_COMBATDAMAGE || opponent()->isAI() - || options[Options::optionInterrupt(currentGamePhase)].number) - { - executeNextPhaseImmediately = false; - } + //this is a stupid case added just for phase pass automation, without it the phase ring breaks. + //we might want to consider moving phase pass automation into stateeffects() and out of update() + //and have it use phasering->forward instead of making a call to this function. + if((cPhaseOld->id == Constants::MTG_PHASE_UPKEEP || cPhaseOld->id == Constants::MTG_PHASE_DRAW )&& opponent()->isAI()) + executeNextPhaseImmediately = false; + + + if (combatStep == TRIGGERS) + { + if (mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED) || targetChooser || mLayers->actionLayer()->isWaitingForAnswer()) + executeNextPhaseImmediately = false;//if theres one of the above actions taking place, then dont just move to next. + } + + if (cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE && combatStep == END_FIRST_STRIKE) + executeNextPhaseImmediately = true;//change this to false to add an interupt after firststrike/doublestrike damage + + if (executeNextPhaseImmediately) + { + nextGamePhase(); + } + else + { + if (cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == TRIGGERS) + { + mLayers->stackLayer()->AddNextCombatStep(); + } + else + { + mLayers->stackLayer()->AddNextGamePhase(); + } + } - if (executeNextPhaseImmediately) - { - nextGamePhase(); - } - else - { - mLayers->stackLayer()->AddNextGamePhase(); - } } int GameObserver::forceShuffleLibraries() @@ -341,6 +365,7 @@ GameObserver::~GameObserver() void GameObserver::Update(float dt) { Player * player = currentPlayer; + if (Constants::MTG_PHASE_COMBATBLOCKERS == currentGamePhase && BLOCKERS == combatStep) player = player->opponent(); @@ -356,14 +381,6 @@ void GameObserver::Update(float dt) stateEffects(); oldGamePhase = currentGamePhase; - if (combatStep == TRIGGERS) - { - if (!mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED)) - { - mLayers->stackLayer()->AddNextCombatStep(); - } - } - //Auto skip Phases int skipLevel = (player->playMode == Player::MODE_TEST_SUITE) ? Constants::ASKIP_NONE : options[Options::ASPHASES].number; int nrCreatures = currentPlayer->game->inPlay->countByType("Creature"); @@ -375,15 +392,14 @@ void GameObserver::Update(float dt) == Constants::MTG_PHASE_COMBATATTACKERS) && (nrCreatures == 0)) || currentGamePhase == Constants::MTG_PHASE_COMBATEND || currentGamePhase == Constants::MTG_PHASE_ENDOFTURN || ((currentGamePhase == Constants::MTG_PHASE_CLEANUP) && (currentPlayer->game->hand->nb_cards < 8)))) - userRequestNextGamePhase(); + userRequestNextGamePhase(); } if (skipLevel == Constants::ASKIP_FULL) { - if ((opponent()->isAI() && !(isInterrupting)) && (currentGamePhase == Constants::MTG_PHASE_UPKEEP || currentGamePhase + if ((opponent()->isAI() && !(isInterrupting)) && (currentGamePhase == Constants::MTG_PHASE_UPKEEP || currentGamePhase == Constants::MTG_PHASE_COMBATDAMAGE)) userRequestNextGamePhase(); - - } + } } //applies damage to creatures after updates @@ -444,6 +460,13 @@ void GameObserver::stateEffects() for (int i = 0; i < 2; i++) if (players[i]->poisonCount >= 10) gameOver = players[i]; + + if (combatStep == TRIGGERS) + { + if (!mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED) && !targetChooser && !mLayers->actionLayer()->isWaitingForAnswer()) + userRequestNextGamePhase(); + } + } void GameObserver::Render() diff --git a/projects/mtg/src/GuiCombat.cpp b/projects/mtg/src/GuiCombat.cpp index e7eafc90c..3a85f32d6 100644 --- a/projects/mtg/src/GuiCombat.cpp +++ b/projects/mtg/src/GuiCombat.cpp @@ -648,7 +648,7 @@ int GuiCombat::receiveEventMinus(WEvent* e) cursor_pos = ATK; } else - go->nextCombatStep(); + go->userRequestNextGamePhase(); return 1; case END_DAMAGE: step = END_DAMAGE;