diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 38ddcef8a..2cab901d8 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -52,6 +52,8 @@ public: { MTGCardInstance * target = card->target; intValue = 0; + bool halfup = false; + bool halfdown = false; if (!target) target = card; int multiplier = 1; if (s[0] == '-') @@ -59,6 +61,20 @@ public: s = s.substr(1); multiplier = -1; } + //rounding values, the words can be written anywhere in the line, + //they are erased after parsing. + if(s.find("halfup") != string::npos) + { + halfup = true; + size_t hU = s.find("halfup"); + s.erase(hU,hU + 6); + } + if(s.find("halfdown") != string::npos) + { + halfdown = true; + size_t hD = s.find("halfdown"); + s.erase(hD,hD + 8); + } if (s == "x" || s == "X") { intValue = computeX(spell, card); @@ -180,6 +196,17 @@ public: { intValue = atoi(s.c_str()); } + if(intValue > 0) + { + if(halfup) + { + if(intValue%2 == 1) + intValue++; + intValue = intValue/2; + } + if(halfdown) + intValue = intValue/2;//got lucky here, by default C++ rounds down. + } intValue *= multiplier; } @@ -3704,6 +3731,9 @@ MTGCardInstance * manaReducer; AAlterCost(int id, MTGCardInstance * source, MTGCardInstance * target, int amount, int type); int addToGame(); int testDestroy(); + void refreshCost(MTGCardInstance * card = NULL); + void increaseTheCost(MTGCardInstance * card = NULL); + void decreaseTheCost(MTGCardInstance * card = NULL); AAlterCost * clone() const; ~AAlterCost(); }; @@ -4676,66 +4706,6 @@ public: } }; -//1235 Aspect of Wolf -class AAspectOfWolf: public ListMaintainerAbility -{ -public: - int color; - AAspectOfWolf(int _id, MTGCardInstance * _source, MTGCardInstance * _target) : - ListMaintainerAbility(_id, _source, _target) - { - } - - int canBeInList(MTGCardInstance * card) - { - - if (card->controller() == source->controller() && card->hasType("forest") && game->isInPlay(card)) return 1; - return 0; - } - - int added(MTGCardInstance * card) - { - MTGCardInstance * _target = (MTGCardInstance *) target; - int size = cards.size(); - if (size % 2 == 0) - { - _target->power += 1; - } - else - { - _target->addToToughness(1); - } - return 1; - } - - int removed(MTGCardInstance * card) - { - MTGCardInstance * _target = (MTGCardInstance *) target; - int size = cards.size(); - if (size % 2 == 1) - { - _target->power -= 1; - } - else - { - _target->addToToughness(-1); - } - return 1; - } - - virtual ostream& toString(ostream& out) const - { - out << "AAspectOfWolf ::: color : " << color << " ("; - return ListMaintainerAbility::toString(out) << ")"; - } - AAspectOfWolf * clone() const - { - AAspectOfWolf * a = NEW AAspectOfWolf(*this); - a->isClone = 1; - return a; - } -}; - //1288 EarthBind class AEarthbind: public ABasicAbilityModifier { diff --git a/projects/mtg/include/CardPrimitive.h b/projects/mtg/include/CardPrimitive.h index 8ec1a0b10..89754dc0f 100644 --- a/projects/mtg/include/CardPrimitive.h +++ b/projects/mtg/include/CardPrimitive.h @@ -17,6 +17,8 @@ class CardPrimitive { ManaCost manaCost; public: + ManaCost reducedCost; + ManaCost increasedCost; string text; string name; int init(); @@ -71,6 +73,8 @@ class CardPrimitive { void setManaCost(string value); ManaCost * getManaCost(); + ManaCost * getReducedManaCost(); + ManaCost * getIncreasedManaCost(); bool isCreature(); bool isLand(); bool isSpell(); diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index cacbb0822..feb665f84 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -80,6 +80,7 @@ public: int tryToPayHybrids(ManaCostHybrid * _hybrids[], int _nbhybrids, int diff[]); void randomDiffHybrids(ManaCost * _cost, int diff[]); int add(ManaCost * _cost); + int remove(ManaCost * _cost); int pay (ManaCost * _cost); //return 1 if _cost can be paid with current data, 0 otherwise diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index b409532e5..a190b902b 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -88,13 +88,28 @@ bool AIPlayer::tapLandsForMana(ManaCost * cost, MTGCardInstance * target) DebugTrace(" AI attempting to tap land for mana." << endl << "- Target: " << (target ? target->name : "None" ) << endl << "- Cost: " << (cost ? cost->toString() : "NULL") ); + if(cost && !cost->getConvertedCost()) + { + DebugTrace("Card has free to play. "); + return true; + //return true becuase we don't need to do anything with a cost of 0; + //special case for 0 cost, which is valid + } if (!cost) { DebugTrace("Mana cost is NULL. "); return false; } - - ManaCost * pMana = getPotentialMana(target); + ManaCost * pMana = NULL; + if(!target) + pMana = getPotentialMana(); + else + pMana = getPotentialMana(target); + if(!pMana->canAfford(cost)) + { + delete pMana; + return false; + } ManaCost * diff = pMana->Diff(cost); delete (pMana); GameObserver * g = GameObserver::GetInstance(); @@ -1369,10 +1384,12 @@ int AIPlayerBaka::computeActions() { if (ipotential) { - tapLandsForMana(nextCardToPlay->getManaCost()); + if(tapLandsForMana(nextCardToPlay->getManaCost(),nextCardToPlay)) + { + AIAction * a = NEW AIAction(nextCardToPlay); + clickstream.push(a); + } } - AIAction * a = NEW AIAction(nextCardToPlay); - clickstream.push(a); findingCard = false; nextCardToPlay = NULL; return 1; @@ -1445,10 +1462,12 @@ int AIPlayerBaka::computeActions() delete (SunCheck); } ///////////////////////// - tapLandsForMana(nextCardToPlay->getManaCost()); } - AIAction * a = NEW AIAction(nextCardToPlay); - clickstream.push(a); + if(tapLandsForMana(nextCardToPlay->getManaCost(),nextCardToPlay)) + { + AIAction * a = NEW AIAction(nextCardToPlay); + clickstream.push(a); + } return 1; } else diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index e6c5e6b0d..dc274f24f 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2139,44 +2139,41 @@ GenericTargetAbility::~GenericTargetAbility() //Alter Cost AAlterCost::AAlterCost(int id, MTGCardInstance * source, MTGCardInstance * target, int amount, int type) : - MTGAbility(id, source, target), amount(amount), type(type) +MTGAbility(id, source, target), amount(amount), type(type) { -manaReducer = source; + manaReducer = source; } int AAlterCost::addToGame() { MTGCardInstance * _target = (MTGCardInstance *) target; - if (amount < 0) + if(!_target || _target->hasType("land")) { - tempAmount = abs(amount); - if (_target->getManaCost()->hasColor(type)) + this->forceDestroy = 1; + return MTGAbility::addToGame(); + } + if (amount > 0) + { + if(!_target->getIncreasedManaCost()->getConvertedCost()) { - if (_target->getManaCost()->getConvertedCost() >= 1) - { - _target->getManaCost()->remove(type, tempAmount); - if (_target->getManaCost()->alternative > 0) - { - _target->getManaCost()->alternative->remove(type, tempAmount); - } - if (_target->getManaCost()->BuyBack > 0) - { - _target->getManaCost()->BuyBack->remove(type, tempAmount); - } - } + ManaCost * increased = NEW ManaCost(); + increased->init(); + _target->getIncreasedManaCost()->copy(increased); + delete increased; + } + _target->getIncreasedManaCost()->add(type,amount); } else { - _target->getManaCost()->add(type, amount); - if (_target->getManaCost()->alternative > 0) + if(!_target->getReducedManaCost()->getConvertedCost()) { - _target->getManaCost()->alternative->add(type, amount); - } - if (_target->getManaCost()->BuyBack > 0) - { - _target->getManaCost()->BuyBack->add(type, amount); + ManaCost * reduced = NEW ManaCost(); + reduced->init(); + _target->getReducedManaCost()->copy(reduced); + delete reduced; } + _target->getReducedManaCost()->add(type,abs(amount)); } return MTGAbility::addToGame(); } @@ -2188,23 +2185,66 @@ int AAlterCost::testDestroy() { if (amount > 0) { - _target->getManaCost()->remove(type, amount); - if (_target->getManaCost()->alternative) - { - _target->getManaCost()->alternative->remove(type, amount); - } - if (_target->getManaCost()->BuyBack) - { - _target->getManaCost()->BuyBack->remove(type, amount); - } + _target->getIncreasedManaCost()->remove(type,amount); + refreshCost(_target);//special case for 0 cost. } else { - _target->controller()->game->putInHand(_target); + _target->getReducedManaCost()->remove(type,abs(amount)); + refreshCost(_target);//special case for 0 cost. } return MTGAbility::testDestroy(); } -return 0; + return 0; +} +void AAlterCost::refreshCost(MTGCardInstance * card) +{ + ManaCost * original = NEW ManaCost(); + original->copy(card->model->data->getManaCost()); + original->add(card->getIncreasedManaCost()); + original->remove(card->getReducedManaCost()); + card->getManaCost()->copy(original); + delete original; + return; + } +void AAlterCost::increaseTheCost(MTGCardInstance * card) +{ + if(card->getIncreasedManaCost()->getConvertedCost()) + { + for(int k = Constants::MTG_COLOR_ARTIFACT; k < Constants::MTG_NB_COLORS;k++) + { + card->getManaCost()->add(k,card->getIncreasedManaCost()->getCost(k)); + if (card->getManaCost()->alternative) + { + card->getManaCost()->alternative->add(k,card->getIncreasedManaCost()->getCost(k)); + } + if (card->getManaCost()->BuyBack) + { + card->getManaCost()->BuyBack->add(k,card->getIncreasedManaCost()->getCost(k)); + } + } + } + return; +} + +void AAlterCost::decreaseTheCost(MTGCardInstance * card) +{ + if(card->getReducedManaCost()->getConvertedCost()) + { + for(int k = Constants::MTG_COLOR_ARTIFACT; k < Constants::MTG_NB_COLORS;k++) + { + card->getManaCost()->remove(k,card->getReducedManaCost()->getCost(k)); + if (card->getManaCost()->alternative) + { + card->getManaCost()->alternative->remove(k,card->getReducedManaCost()->getCost(k)); + } + if (card->getManaCost()->BuyBack) + { + card->getManaCost()->BuyBack->remove(k,card->getReducedManaCost()->getCost(k)); + } + } + } + return; } AAlterCost * AAlterCost::clone() const diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index 429d7b8fa..d9eef23b0 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -23,6 +23,8 @@ CardPrimitive::CardPrimitive(CardPrimitive * source) for (int i = 0; i < Constants::MTG_NB_COLORS; ++i) colors[i] = source->colors[i]; manaCost.copy(source->getManaCost()); + reducedCost.copy(source->getReducedManaCost()); + increasedCost.copy(source->getIncreasedManaCost()); if(source->getManaCost()->alternative) manaCost.alternative->alternativeName = source->getManaCost()->alternative->alternativeName; @@ -270,6 +272,15 @@ ManaCost* CardPrimitive::getManaCost() return &manaCost; } +ManaCost* CardPrimitive::getReducedManaCost() +{ + return &reducedCost; +} +ManaCost* CardPrimitive::getIncreasedManaCost() +{ + return &increasedCost; +} + bool CardPrimitive::hasType(int _type) { for (size_t i = 0; i < types.size(); i++) diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 64ee5f018..91d0e32a6 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -487,7 +487,7 @@ void GameObserver::gameStateBasedEffects() for (int j = 0; j < nbcards; ++j) { MTGCardInstance * c = z->cards[j]; - if (c->has(Constants::CANTLOSE) || c->has(Constants::CANTLIFELOSE)) + if (c->has(Constants::CANTLOSE) || (c->has(Constants::CANTLIFELOSE && players[i]->poisonCount < 10))) { cantlosers++; } @@ -710,6 +710,17 @@ void GameObserver::Affinity() int color = 0; string type = ""; //only do any of the following if a card with the stated ability is in your hand. + ManaCost * original = NEW ManaCost(); + original->copy(card->model->data->getManaCost()); + //have to run alter cost before affinity or the 2 cancel each other out. + if(card && (card->getIncreasedManaCost()->getConvertedCost()||card->getReducedManaCost()->getConvertedCost())) + { + if(card->getIncreasedManaCost()->getConvertedCost()) + original->add(card->getIncreasedManaCost()); + if(card->getReducedManaCost()->getConvertedCost()) + original->remove(card->getReducedManaCost()); + card->getManaCost()->copy(original); + } if(card && (card->has(Constants::AFFINITYARTIFACTS)|| card->has(Constants::AFFINITYFOREST)|| @@ -747,7 +758,6 @@ void GameObserver::Affinity() color = 1; type = "creature"; } - ManaCost * original = card->model->data->getManaCost(); card->getManaCost()->copy(original); int reduce = 0; if(card->has(Constants::AFFINITYGREENCREATURES)) @@ -767,6 +777,8 @@ void GameObserver::Affinity() card->getManaCost()->remove(color,1); } } + if(original) + delete original; } } } diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 49e5591ff..5dd374006 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -902,6 +902,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG { size_t end = sWithoutTc.find(")", found); newName = sWithoutTc.substr(found + 5, end - found - 5); + s.erase(found, end - found + 1); + //we erase the name section from the string to avoid + //accidently building an mtg ability with the text meant for menuText. } //Target Abilities found = s.find("target("); @@ -2404,9 +2407,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG found = s.find("counter("); if (found != string::npos) { - size_t start = s.find("("); + size_t start = s.find("counter("); size_t end = s.find(")"); - string counterString = s.substr(start + 1, end - start - 1); + string counterString = s.substr(start + 8, end - start - 8); Counter * counter = parseCounter(counterString, target, spell); if (counter) { @@ -2423,9 +2426,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG found = s.find("removeallcounters("); if (found != string::npos) { - size_t start = s.find("("); + size_t start = s.find("removeallcounters("); size_t end = s.find(")"); - string counterString = s.substr(start + 1, end - start - 1); + string counterString = s.substr(start + 18, end - start - 18); if(counterString.find("all") != string::npos) { bool all = true; @@ -3034,12 +3037,17 @@ int AbilityFactory::getAbilities(vector * v, Spell * spell, MTGCar MTGCardInstance * target = card->target; if (!target) target = card; - card->getManaCost()->copy(card->model->data->getManaCost()); + //card->getManaCost()->copy(card->model->data->getManaCost()); + //zeth:i added this originally for no reason really, however + //i didn't realize ai runs this function about a million times during a match. + //it litterally distroys any altering cost effects. + //if for some reason i added this becuase of some bug...we need to think of a more clever way + //to do this. string magicText; - card->graveEffects = false; - card->exileEffects = false; if (dest) { + card->graveEffects = false; + card->exileEffects = false; GameObserver * g = GameObserver::GetInstance(); for (int i = 0; i < 2; ++i) { @@ -3158,7 +3166,6 @@ int AbilityFactory::getAbilities(vector * v, Spell * spell, MTGCar line = magicText; magicText = ""; } - MTGAbility * a = parseMagicLine(line, result, spell, card, 0, 0, 0, 0, dest); if (a) { @@ -3548,11 +3555,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell) game->addObserver(NEW AControlStealAura(_id, card, card->target)); break; } - case 1235: //Aspect of Wolf - { - game->addObserver(NEW AAspectOfWolf(_id, card, card->target)); - break; - } case 1231: //Volcanic Eruption { int x = computeX(spell, card); diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 6746670ad..0ed914f87 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -148,13 +148,17 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi { string value = val; std::transform(value.begin(), value.end(), value.begin(), ::tolower); - cost->alternative = ManaCost::parseManaCost(value); size_t name = value.find("name("); - if(name != string::npos) - { - size_t endName = value.find(")",name); - cost->alternative->alternativeName = value.substr(name + 5,endName - name - 5); - } + string theName = ""; + if(name != string::npos) + { + size_t endName = value.find(")",name); + theName = value.substr(name + 5,endName - name - 5); + s.erase(name, endName - name + 1); + } + cost->alternative = ManaCost::parseManaCost(value); + if(theName.size()) + cost->alternative->alternativeName.append(theName); } } break; diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index bf2cb2310..bdedfd83e 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -397,7 +397,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) } ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); - int payResult = player->getManaPool()->pay(card->getManaCost()); + int payResult = player->getManaPool()->pay(cost); card->getManaCost()->doPayExtra(); ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index 40c4f4147..2b84975ab 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -528,6 +528,17 @@ int ManaCost::add(ManaCost * _cost) return 1; } +int ManaCost::remove(ManaCost * _cost) +{ + if (!_cost) + return 0; + for (unsigned int i = 0; i < Constants::MTG_NB_COLORS; i++) + { + cost[i] -= _cost->getCost(i); + } + return 1; +} + int ManaCost::addHybrid(int c1, int v1, int c2, int v2) { ManaCostHybrid * h = NEW ManaCostHybrid(c1, v1, c2, v2);