bool AIHints::HintSaysDontAttack(GameObserver* observer,MTGCardInstance * card) { TargetChooserFactory tfc(observer); TargetChooser * hintTc = NULL; for(unsigned int i = 0; i < hints.size();i++) { if (hints[i]->mCombatAttackTip.size()) { hintTc = tfc.createTargetChooser(hints[i]->mCombatAttackTip,card); if(hintTc && hintTc->canTarget(card,true)) { SAFE_DELETE(hintTc); return true; } SAFE_DELETE(hintTc); } } return false; }
void ActionStack::Update(float dt) { //This is a hack to avoid updating the stack while tuto messages are being shown //Ideally, the tuto messages should be moved to a layer above this one //No need for Tuto when no human in game if (getCurrentTutorial() && (observer->players[0]->isHuman() || observer->players[1]->isHuman() ) ) return; askIfWishesToInterrupt = NULL; //modal = 0; TargetChooser * tc = observer->getCurrentTargetChooser(); int newState = observer->getCurrentGamePhase(); currentState = newState; if (!tc) checked = 0; //Select Stack's display mode if (mode == ACTIONSTACK_STANDARD && tc && !checked) { checked = 1; for (size_t i = 0; i < mObjects.size(); i++) { Interruptible * current = (Interruptible *) mObjects[i]; if (tc->canTarget(current)) { if (mCurr < (int) mObjects.size() && mObjects[mCurr]) mObjects[mCurr]->Leaving(JGE_BTN_UP); current->display = 1; mCurr = i; mObjects[mCurr]->Entering(); mode = ACTIONSTACK_TARGET; modal = 1; } else { current->display = 0; } } if (mode != ACTIONSTACK_TARGET) { } } else if (mode == ACTIONSTACK_TARGET && !tc) { mode = ACTIONSTACK_STANDARD; checked = 0; } if (mode == ACTIONSTACK_STANDARD) { modal = 0; if (getLatest(NOT_RESOLVED) && !tc) { Interruptible * currentSpell = (Interruptible *)getLatest(NOT_RESOLVED); MTGCardInstance * card = currentSpell->source; if(card && card->has(Constants::SPLITSECOND)) { resolve(); } else { int currentPlayerId = 0; int otherPlayerId = 1; if (observer->currentlyActing() != observer->players[0]) { currentPlayerId = 1; otherPlayerId = 0; } if (interruptDecision[currentPlayerId] == NOT_DECIDED) { askIfWishesToInterrupt = observer->players[currentPlayerId]; observer->isInterrupting = observer->players[currentPlayerId]; modal = 1; } else if (interruptDecision[currentPlayerId] == INTERRUPT) { observer->isInterrupting = observer->players[currentPlayerId]; } else { if (interruptDecision[otherPlayerId] == NOT_DECIDED) { askIfWishesToInterrupt = observer->players[otherPlayerId]; observer->isInterrupting = observer->players[otherPlayerId]; modal = 1; } else if (interruptDecision[otherPlayerId] == INTERRUPT) { observer->isInterrupting = observer->players[otherPlayerId]; } else { resolve(); } } } } } else if (mode == ACTIONSTACK_TARGET) { GuiLayer::Update(dt); } if (askIfWishesToInterrupt) { // WALDORF - added code to use a game option setting to determine how // long the Interrupt timer should be. If it is set to zero (0), the // game will wait for ever for the user to make a selection. if (options[Options::INTERRUPT_SECONDS].number > 0) { int extraTime = 0; //extraTime is a multiplier, it counts the number of unresolved stack actions //then is used to extend the time you have to interupt. //this prevents you from "running out of time" while deciding. //before this int was added, it was possible to run out of time if you had 10 stack actions //and set the timer to 4 secs. BUG FIX //http://code.google.com/p/wagic/issues/detail?id=464 extraTime = count(0, NOT_RESOLVED, 0); if (extraTime == 0) extraTime = 1;//we never want this int to be 0. if (timer < 0) timer = static_cast<float>(options[Options::INTERRUPT_SECONDS].number * extraTime); timer -= dt; if (timer < 0) cancelInterruptOffer(); } } }
bool AIHints::HintSaysItsForCombo(GameObserver* observer,MTGCardInstance * card) { TargetChooserFactory tfc(observer); TargetChooser * hintTc = NULL; bool forCombo = false; for(unsigned int i = 0; i < hints.size();i++) { if (hints[i]->combos.size()) { //time to find the parts and condiations of the combo. string part = ""; if(!hints[i]->partOfCombo.size() && hints[i]->combos.size()) { for(unsigned int cPart = 0; cPart < hints[i]->combos.size(); cPart++) { //here we disect the different parts of a given combo part = hints[i]->combos[cPart]; hints[i]->partOfCombo = split(part,'^'); for(unsigned int dPart = 0; dPart < hints[i]->partOfCombo.size(); dPart++) { vector<string>asTc; asTc = parseBetween(hints[i]->partOfCombo[dPart],"hold(",")"); if(asTc.size()) { hints[i]->hold.push_back(asTc[1]); asTc.clear(); } asTc = parseBetween(hints[i]->partOfCombo[dPart],"until(",")"); if(asTc.size()) { hints[i]->until.push_back(asTc[1]); asTc.clear(); } asTc = parseBetween(hints[i]->partOfCombo[dPart],"restriction{","}"); if(asTc.size()) { hints[i]->restrict.push_back(asTc[1]); asTc.clear(); } asTc = parseBetween(hints[i]->partOfCombo[dPart],"cast(",")"); if(asTc.size()) { hints[i]->cardTargets[asTc[1]] = parseBetween(hints[i]->partOfCombo[dPart],"targeting(",")")[1]; } asTc = parseBetween(hints[i]->partOfCombo[dPart],"totalmananeeded(",")"); if(asTc.size()) { hints[i]->manaNeeded = asTc[1]; asTc.clear(); } } } }//we collect the peices of a combo on first run. for(unsigned int hPart = 0; hPart < hints[i]->hold.size(); hPart++) { hintTc = tfc.createTargetChooser(hints[i]->hold[hPart],card); if(hintTc && hintTc->canTarget(card,true) && hintTc->countValidTargets() <= hintTc->maxtargets) { forCombo = true; } SAFE_DELETE(hintTc); } } } return forCombo;//return forCombo that way all hints that are combos are predisected. }