int GuiCombat::resolve() // Returns the number of damage objects dealt this turn. { DamageStack* stack = NEW DamageStack(observer); for (inner_iterator it = attackers.begin(); it != attackers.end(); ++it) { MTGCardInstance * attacker = (*it)->card; signed dmg = attacker->stepPower(step); for (vector<DefenserDamaged*>::iterator q = (*it)->blockers.begin(); q != (*it)->blockers.end(); ++q) { for (vector<Damage>::iterator d = (*q)->damages.begin(); d != (*q)->damages.end(); ++d) stack->Add(NEW Damage(*d)); dmg -= (*q)->sumDamages(); } if (dmg > 0 && ((!attacker->isBlocked()) || attacker->has(Constants::TRAMPLE))) stack->Add(NEW Damage(observer, (*it)->card, (Damageable*)attacker->isAttacking?(Damageable*)attacker->isAttacking:observer->opponent(), dmg, DAMAGE_COMBAT)); for (vector<Damage>::iterator d = (*it)->damages.begin(); d != (*it)->damages.end(); ++d) stack->Add(NEW Damage(*d)); } int v = stack->mObjects.size(); if (v > 0) { observer->mLayers->stackLayer()->Add(stack); observer->mLayers->stackLayer()->resolve(); // This will delete the damage stack which will in turn delete the Damage it contains } else SAFE_DELETE(stack); return v; }
bool Player::DeadLifeState(bool check) { if ((life <= 0)||(poisonCount >= 10)) { int cantlosers = 0; MTGGameZone * z = game->inPlay; int nbcards = z->nb_cards; for (int j = 0; j < nbcards; ++j) { MTGCardInstance * c = z->cards[j]; if (c->has(Constants::CANTLOSE) || (c->has(Constants::CANTLIFELOSE) && poisonCount < 10)) { cantlosers++; } } MTGGameZone * k = opponent()->game->inPlay; int onbcards = k->nb_cards; for (int m = 0; m < onbcards; ++m) { MTGCardInstance * e = k->cards[m]; if (e->has(Constants::CANTWIN)) { cantlosers++; } } if (cantlosers < 1) { if(!check) { ActionStack * stack = getObserver()->mLayers->stackLayer(); for (int i = stack->mObjects.size() - 1; i >= 0; i--) { Interruptible * current = ((Interruptible *) stack->mObjects[i]); Spell * spell = (Spell *) current; if (current->type == ACTION_SPELL) spell->source->controller()->game->putInGraveyard(spell->source); current->state = RESOLVED_NOK; } } if(check) game->owner->getObserver()->setLoser(this); return true; } } return false; }
MTGCardInstance * MTGInPlay::findALurer() { for (int i = 0; i < nb_cards; i++) { MTGCardInstance * current = cards[i]; if (current->isAttacker() && current->has(Constants::LURE)) { return current; } } return NULL; }
MTGCardInstance * MTGInPlay::getNextLurer(MTGCardInstance * previous) { int foundprevious = 0; if (previous == NULL) { foundprevious = 1; } for (int i = 0; i < nb_cards; i++) { MTGCardInstance * current = cards[i]; if (current == previous) { foundprevious = 1; } else if (foundprevious && current->isAttacker() && current->has(Constants::LURE)) { return current; } } return NULL; }
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(); } } }