MTGCardInstance * CardDescriptor::match(MTGCardInstance * card) { MTGCardInstance * match = card; if (mode == CD_AND) { match = match_and(card); } else if (mode == CD_OR) { match = match_or(card); } //Abilities BasicAbilitiesSet set = basicAbilities & card->basicAbilities; if (set != basicAbilities) return NULL; BasicAbilitiesSet excludedSet = mAbilityExclusions & card->basicAbilities; if (excludedSet.any()) return NULL; if ((tapped == -1 && card->isTapped()) || (tapped == 1 && !card->isTapped())) { match = NULL; } if ((fresh == -1 && card->fresh) || (fresh == 1 && !card->fresh)) { match = NULL; } if ((isMultiColored == -1 && card->isMultiColored) || (isMultiColored == 1 && !card->isMultiColored)) { match = NULL; } if ((isLeveler == -1 && card->isLeveler) || (isLeveler == 1 && !card->isLeveler)) { match = NULL; } if ((CDenchanted == -1 && card->enchanted) || (CDenchanted == 1 && !card->enchanted)) { match = NULL; } if ((CDdamaged == -1 && card->wasDealtDamage) || (CDdamaged == 1 && !card->wasDealtDamage)) { match = NULL; } if(CDopponentDamaged == -1 || CDopponentDamaged == 1) { Player * p = card->controller()->opponent();//controller()->opponent(); if ((CDopponentDamaged == -1 && card->damageToOpponent && card->controller() == p) || (CDopponentDamaged == 1 && !card->damageToOpponent && card->controller() == p) || (CDopponentDamaged == -1 && card->damageToController && card->controller() == p->opponent()) || (CDopponentDamaged == 1 && !card->damageToController && card->controller() == p->opponent())) { match = NULL; } if ((CDcontrollerDamaged == -1 && card->damageToController && card->controller() == p) || (CDcontrollerDamaged == 1 && !card->damageToController && card->controller() == p) || (CDcontrollerDamaged == -1 && card->damageToOpponent && card->controller() == p->opponent()) || (CDcontrollerDamaged == 1 && !card->damageToOpponent && card->controller() == p->opponent())) { match = NULL; } } if ((isToken == -1 && card->isToken) || (isToken == 1 && !card->isToken)) { match = NULL; } if (attacker == 1) { if (defenser == &AnyCard) { if (!card->attacker && !card->defenser) match = NULL; } else { if (!card->attacker) match = NULL; } } else if (attacker == -1) { if (defenser == &NoCard) { if (card->attacker || card->defenser) match = NULL; } else { if (card->attacker) match = NULL; } } else { if (defenser == &NoCard) { if (card->defenser) match = NULL; } else if (defenser == &AnyCard) { if (!card->defenser) match = NULL; } else { // we don't care about the attack/blocker state } } //Counters if (anyCounter) { if (!(card->counters->mCount)) { match = NULL; } else { int hasCounter = 0; for (int i = 0; i < card->counters->mCount; i++) { if (card->counters->counters[i]->nb > 0) hasCounter = 1; } if (!hasCounter) match = NULL; } } else { if (counterComparisonMode) { Counter * targetCounter = card->counters->hasCounter(counterName.c_str(), counterPower, counterToughness); if (targetCounter) { if (!valueInRange(counterComparisonMode, targetCounter->nb, counterNB)) match = NULL; } else { if (counterComparisonMode != COMPARISON_LESS && counterComparisonMode != COMPARISON_AT_MOST) match = NULL; } } } return match; }
MTGCardInstance * CardDescriptor::match(MTGCardInstance * card) { MTGCardInstance * match = card; if (mode == CD_AND) { match = match_and(card); } else if (mode == CD_OR) { match = match_or(card); } //Position in zone for reveal if ( zonePosition ) { vector< MTGCardInstance* > zoneCards = card->currentZone->cards; int nZoneCards = static_cast< int >( zoneCards.size() ); bool posFound = false; for ( int i = 1; i <= zonePosition; i++ ) { if ( zoneCards[ nZoneCards - i ] == card ) { posFound = true; break; } } if ( !posFound ) { return NULL; } } //Abilities BasicAbilitiesSet set = basicAbilities & card->basicAbilities; if (set != basicAbilities) return NULL; BasicAbilitiesSet excludedSet = mAbilityExclusions & card->basicAbilities; if (excludedSet.any()) return NULL; if ((tapped == -1 && card->isTapped()) || (tapped == 1 && !card->isTapped())) { match = NULL; } if ((fresh == -1 && card->fresh) || (fresh == 1 && !card->fresh)) { match = NULL; } if ((entersBattlefield == -1 && card->entersBattlefield) || (entersBattlefield == 1 && !card->entersBattlefield)) { match = NULL; } if ((CDgeared == -1 && card->equipment > 0) || (CDgeared == 1 && card->equipment < 1)) { match = NULL; } if (CDblocked == -1) { if(!card->isAttacker()) match = NULL; else { if(card->isBlocked()) match = NULL; } } if (CDblocked == 1) { if(!card->isAttacker()) match = NULL; else { if(!card->isBlocked()) match = NULL; } } if ((CDcanProduceC == -1 && card->canproduceC == 1) || (CDcanProduceC == 1 && card->canproduceC == 0)) { match = NULL; } if ((CDcanProduceG == -1 && card->canproduceG == 1) || (CDcanProduceG == 1 && card->canproduceG == 0)) { match = NULL; } if ((CDcanProduceU == -1 && card->canproduceU == 1) || (CDcanProduceU == 1 && card->canproduceU == 0)) { match = NULL; } if ((CDcanProduceR == -1 && card->canproduceR == 1) || (CDcanProduceR == 1 && card->canproduceR == 0)) { match = NULL; } if ((CDcanProduceB == -1 && card->canproduceB == 1) || (CDcanProduceB == 1 && card->canproduceB == 0)) { match = NULL; } if ((CDcanProduceW == -1 && card->canproduceW == 1) || (CDcanProduceW == 1 && card->canproduceW == 0)) { match = NULL; } if ((CDnocolor == -1 && card->getColor() == 0)) { match = NULL; } else if(CDnocolor == 1) { if(!card->has(Constants::DEVOID)) if(card->getColor()>0) match = NULL; } if ((isMultiColored == -1 && card->isMultiColored) || (isMultiColored == 1 && !card->isMultiColored)) { match = NULL; } if ((isLeveler == -1 && card->isLeveler) || (isLeveler == 1 && !card->isLeveler)) { match = NULL; } if ((CDenchanted == -1 && card->enchanted) || (CDenchanted == 1 && !card->enchanted)) { match = NULL; } if ((CDdamaged == -1 && card->wasDealtDamage) || (CDdamaged == 1 && !card->wasDealtDamage)) { match = NULL; } if ((CDdamager == -1 && (card->damageToOpponent || card->damageToController || card->damageToCreature)) || (CDdamager == 1 && !(card->damageToOpponent || card->damageToController || card->damageToCreature))) { match = NULL; } if(CDopponentDamaged == -1 || CDopponentDamaged == 1) { Player * p = card->controller()->opponent();//controller()->opponent(); if ((CDopponentDamaged == -1 && card->damageToOpponent && card->controller() == p) || (CDopponentDamaged == 1 && !card->damageToOpponent && card->controller() == p) || (CDopponentDamaged == -1 && card->damageToController && card->controller() == p->opponent()) || (CDopponentDamaged == 1 && !card->damageToController && card->controller() == p->opponent())) { match = NULL; } if ((CDcontrollerDamaged == -1 && card->damageToController && card->controller() == p) || (CDcontrollerDamaged == 1 && !card->damageToController && card->controller() == p) || (CDcontrollerDamaged == -1 && card->damageToOpponent && card->controller() == p->opponent()) || (CDcontrollerDamaged == 1 && !card->damageToOpponent && card->controller() == p->opponent())) { match = NULL; } } if ((isToken == -1 && card->isToken) || (isToken == 1 && !card->isToken)) { match = NULL; } if (attacker == 1) { if (defenser == &AnyCard) { if (!card->attacker && !card->defenser) match = NULL; } else { if (!card->attacker) match = NULL; } } else if (attacker == -1) { if (defenser == &NoCard) { if (card->attacker || card->defenser) match = NULL; } else { if (card->attacker) match = NULL; } } else { if (defenser == &NoCard) { if (card->defenser) match = NULL; } else if (defenser == &AnyCard) { if (!card->defenser) match = NULL; } else { // we don't care about the attack/blocker state } } //Counters if (anyCounter) { if (!(card->counters->mCount)) { match = NULL; } else { int hasCounter = 0; for (int i = 0; i < card->counters->mCount; i++) { if (card->counters->counters[i]->nb > 0) hasCounter = 1; } if (!hasCounter) match = NULL; } } else { if (counterComparisonMode) { Counter * targetCounter = card->counters->hasCounter(counterName.c_str(), counterPower, counterToughness); if (targetCounter) { if (!valueInRange(counterComparisonMode, targetCounter->nb, counterNB)) match = NULL; } else { if (counterComparisonMode != COMPARISON_LESS && counterComparisonMode != COMPARISON_AT_MOST) match = NULL; } } } return match; }