Merge branch 'master' into minmax
This commit is contained in:
@@ -1359,6 +1359,13 @@ int AAFizzler::resolve()
|
||||
sCard = sTarget->source;
|
||||
if (!sCard || !sTarget || sCard->has(Constants::NOFIZZLE))
|
||||
return 0;
|
||||
if (source->alias == 111057 && sTarget)//Draining Whelk
|
||||
{
|
||||
for (int j = sTarget->cost->getConvertedCost(); j > 0; j--)
|
||||
{
|
||||
source->counters->addCounter(1,1);
|
||||
}
|
||||
}
|
||||
stack->Fizzle(sTarget, fizzleMode);
|
||||
return 1;
|
||||
}
|
||||
@@ -2482,35 +2489,49 @@ int AACloner::resolve()
|
||||
|
||||
Player * targetPlayer = who == 1 ? source->controller()->opponent() : source->controller();
|
||||
|
||||
MTGCardInstance * myClone = NEW MTGCardInstance(clone, targetPlayer->game);
|
||||
targetPlayer->game->temp->addCard(myClone);
|
||||
int tokenize = 1;//tokenizer support for cloning
|
||||
if (targetPlayer->game->battlefield->hasAbility(Constants::TOKENIZER))
|
||||
{
|
||||
int nbcards = targetPlayer->game->battlefield->nb_cards;
|
||||
for (int j = 0; j < nbcards; j++)
|
||||
{
|
||||
if (targetPlayer->game->battlefield->cards[j]->has(Constants::TOKENIZER))
|
||||
tokenize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < tokenize; ++i)
|
||||
{
|
||||
MTGCardInstance * myClone = NEW MTGCardInstance(clone, targetPlayer->game);
|
||||
targetPlayer->game->temp->addCard(myClone);
|
||||
|
||||
Spell * spell = NEW Spell(game, myClone);
|
||||
spell->source->isToken = 1;
|
||||
spell->resolve();
|
||||
spell->source->fresh = 1;
|
||||
spell->source->model = spell->source;
|
||||
spell->source->model->data = spell->source;
|
||||
if(_target->isToken)
|
||||
{
|
||||
spell->source->power = _target->origpower;
|
||||
spell->source->toughness = _target->origtoughness;
|
||||
spell->source->life = _target->origtoughness;
|
||||
Spell * spell = NEW Spell(game, myClone);
|
||||
spell->source->isToken = 1;
|
||||
spell->resolve();
|
||||
spell->source->fresh = 1;
|
||||
spell->source->model = spell->source;
|
||||
spell->source->model->data = spell->source;
|
||||
if(_target->isToken)
|
||||
{
|
||||
spell->source->power = _target->origpower;
|
||||
spell->source->toughness = _target->origtoughness;
|
||||
spell->source->life = _target->origtoughness;
|
||||
}
|
||||
list<int>::iterator it;
|
||||
for (it = awith.begin(); it != awith.end(); it++)
|
||||
{
|
||||
spell->source->basicAbilities[*it] = 1;
|
||||
}
|
||||
for (it = colors.begin(); it != colors.end(); it++)
|
||||
{
|
||||
spell->source->setColor(*it);
|
||||
}
|
||||
for (it = typesToAdd.begin(); it != typesToAdd.end(); it++)
|
||||
{
|
||||
spell->source->addType(*it);
|
||||
}
|
||||
delete spell;
|
||||
}
|
||||
list<int>::iterator it;
|
||||
for (it = awith.begin(); it != awith.end(); it++)
|
||||
{
|
||||
spell->source->basicAbilities[*it] = 1;
|
||||
}
|
||||
for (it = colors.begin(); it != colors.end(); it++)
|
||||
{
|
||||
spell->source->setColor(*it);
|
||||
}
|
||||
for (it = typesToAdd.begin(); it != typesToAdd.end(); it++)
|
||||
{
|
||||
spell->source->addType(*it);
|
||||
}
|
||||
delete spell;
|
||||
return 1;
|
||||
|
||||
}
|
||||
@@ -2941,6 +2962,32 @@ AAShuffle * AAShuffle::clone() const
|
||||
return NEW AAShuffle(*this);
|
||||
}
|
||||
|
||||
// Mulligan
|
||||
AAMulligan::AAMulligan(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, int who) :
|
||||
ActivatedAbilityTP(observer, _id, card, _target, _cost, who)
|
||||
{
|
||||
}
|
||||
|
||||
int AAMulligan::resolve()
|
||||
{
|
||||
Player * player = getPlayerFromTarget(getTarget());
|
||||
if (player)
|
||||
{
|
||||
player->serumMulligan();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const string AAMulligan::getMenuText()
|
||||
{
|
||||
return "Mulligan";
|
||||
}
|
||||
|
||||
AAMulligan * AAMulligan::clone() const
|
||||
{
|
||||
return NEW AAMulligan(*this);
|
||||
}
|
||||
|
||||
// Remove Mana From ManaPool
|
||||
AARemoveMana::AARemoveMana(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, string manaDesc, int who) :
|
||||
ActivatedAbilityTP(observer, _id, card, _target, NULL, who)
|
||||
|
||||
@@ -151,6 +151,44 @@ int LifeCost::doPay()
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Specific life cost
|
||||
SpecificLifeCost * SpecificLifeCost::clone() const
|
||||
{
|
||||
SpecificLifeCost * ec = NEW SpecificLifeCost(*this);
|
||||
if (tc)
|
||||
ec->tc = tc->clone();
|
||||
return ec;
|
||||
}
|
||||
|
||||
SpecificLifeCost::SpecificLifeCost(TargetChooser *_tc, int slc)
|
||||
: ExtraCost("Life", _tc), slc(slc)
|
||||
{
|
||||
}
|
||||
|
||||
int SpecificLifeCost::canPay()
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if(_target->controller()->life >= slc)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SpecificLifeCost::doPay()
|
||||
{
|
||||
if (!target)
|
||||
return 0;
|
||||
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
|
||||
_target->controller()->loseLife(slc);
|
||||
target = NULL;
|
||||
if (tc)
|
||||
tc->initTargets();
|
||||
return 1;
|
||||
}
|
||||
|
||||
//life or Mana cost
|
||||
LifeorManaCost * LifeorManaCost::clone() const
|
||||
{
|
||||
|
||||
@@ -1909,6 +1909,13 @@ void GameObserver::Mulligan(Player* player)
|
||||
player->takeMulligan();
|
||||
}
|
||||
|
||||
void GameObserver::serumMulligan(Player* player)
|
||||
{
|
||||
if(!player) player = currentPlayer;
|
||||
logAction(player, "mulligan serum powder");
|
||||
player->serumMulligan();
|
||||
}
|
||||
|
||||
Player* GameObserver::createPlayer(const string& playerMode
|
||||
#ifdef TESTSUITE
|
||||
, TestSuiteGame* testgame
|
||||
|
||||
@@ -236,8 +236,8 @@ void GameStateOptions::Render()
|
||||
"Nakano, Niegen, Kaioshin, Psyringe, r1c47, Superhiro,",
|
||||
"Szei, Thanatos02, Whismer, Wololo",
|
||||
"",
|
||||
"Thanks also go to Dr.Watson, Orine, Raphael, Sakya, Tyranid",
|
||||
"for their help.",
|
||||
"Thanks also go to Dr.Watson, KF1, Orine, Raphael, Sakya,",
|
||||
"Tacoghandi, Tyranid for their help.",
|
||||
"",
|
||||
"Thanks to everyone who contributes code/content on the forums!",
|
||||
"",
|
||||
|
||||
@@ -2532,6 +2532,16 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
return a;
|
||||
}
|
||||
|
||||
//Serum Powder
|
||||
found = s.find("serumpowder");
|
||||
if (found != string::npos)
|
||||
{
|
||||
Targetable * t = spell? spell->getNextTarget() : NULL;
|
||||
MTGAbility * a = NEW AAMulligan(observer, id, card, t, NULL, who);
|
||||
a->oneShot = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
//Remove Mana from ManaPool
|
||||
vector<string> splitRemove = parseBetween(s, "removemana(", ")");
|
||||
if (splitRemove.size())
|
||||
@@ -4284,6 +4294,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell)
|
||||
}
|
||||
else if (card->alternateCostPaid[ManaCost::MANA_PAID_WITH_BUYBACK] > 0)
|
||||
{
|
||||
card->alternateCostPaid[ManaCost::MANA_PAID_WITH_BUYBACK] = 0;
|
||||
zones->putInZone(card, zones->stack, Endzones->hand);
|
||||
}
|
||||
else if (card->alternateCostPaid[ManaCost::MANA_PAID_WITH_FLASHBACK] > 0)
|
||||
|
||||
@@ -132,7 +132,8 @@ const char* Constants::MTGBasicAbilities[] = {
|
||||
"soulbond",
|
||||
"lure",
|
||||
"nolegend",
|
||||
"canplayfromgraveyard"
|
||||
"canplayfromgraveyard",
|
||||
"tokenizer"//parallel lives
|
||||
};
|
||||
|
||||
map<string,int> Constants::MTGBasicAbilitiesMap;
|
||||
|
||||
@@ -580,6 +580,24 @@ unsigned int MTGGameZone::countTotalManaSymbols(TargetChooser * tc, int color)
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int MTGGameZone::countDevotion(TargetChooser * tc, int color)
|
||||
{
|
||||
if (!tc) {
|
||||
return 0;
|
||||
}
|
||||
// we don't care if cards have protection.
|
||||
bool withoutProtections = true;
|
||||
int result = 0;
|
||||
for (int i = 0; i < nb_cards; i++)
|
||||
{
|
||||
if (tc->canTarget(cards[i], withoutProtections))
|
||||
{
|
||||
result += cards[i]->getManaCost()->getManaSymbolsHybridMerged(color);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MTGCardInstance * MTGGameZone::findByName(string name)
|
||||
{
|
||||
for (int i = 0; i < (nb_cards); i++)
|
||||
|
||||
@@ -159,10 +159,19 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
||||
{ //Mill to exile yourself as a cost (Library 2 Exile)
|
||||
manaCost->addExtraCost(NEW MillExileCost(tc));
|
||||
}
|
||||
else
|
||||
else if (value == "l")
|
||||
{ //Life cost
|
||||
manaCost->addExtraCost(NEW LifeCost(tc));
|
||||
}
|
||||
else
|
||||
{ //Specific Life cost
|
||||
vector<string>valSplit = parseBetween(value,"l:"," ",false);
|
||||
if (valSplit.size()) {
|
||||
WParsedInt* lifetopay = NEW WParsedInt(valSplit[1], NULL, c);
|
||||
manaCost->addExtraCost(NEW SpecificLifeCost(tc,lifetopay->getValue()));
|
||||
SAFE_DELETE(lifetopay);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'd': //DiscardRandom cost
|
||||
if (value == "d")
|
||||
@@ -609,6 +618,27 @@ int ManaCost::getManaSymbols(int color)
|
||||
return result;
|
||||
}
|
||||
|
||||
int ManaCost::getManaSymbolsHybridMerged(int color)
|
||||
{
|
||||
int result = cost[color];
|
||||
for (size_t i = 0; i < hybrids.size(); ++i)
|
||||
{
|
||||
result = hybrids[i].getManaSymbolsHybridMerged(color);//removed +
|
||||
}
|
||||
if (extraCosts && extraCosts->costs.size())
|
||||
{
|
||||
for (size_t i = 0; i < extraCosts->costs.size(); ++i)
|
||||
{
|
||||
LifeorManaCost * phyrexianMana = dynamic_cast<LifeorManaCost*>(extraCosts->costs[i]);
|
||||
if (phyrexianMana)
|
||||
{
|
||||
result += phyrexianMana->getManaCost()->getManaSymbolsHybridMerged(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int ManaCost::parseManaSymbol(char symbol)
|
||||
{
|
||||
switch (symbol)
|
||||
|
||||
@@ -58,6 +58,14 @@ int ManaCostHybrid::getManaSymbols(int color)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ManaCostHybrid::getManaSymbolsHybridMerged(int color)
|
||||
{
|
||||
// we assume that color1 and color2 are different
|
||||
if (color1 == color) return value1;
|
||||
if (color2 == color) return value2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ManaCostHybrid::hasColor(int color)
|
||||
{
|
||||
if (((color1 == color) && value1) || ((color2 == color) && value2))
|
||||
|
||||
@@ -217,6 +217,22 @@ void Player::takeMulligan()
|
||||
//Draw hand with 1 less card penalty //almhum
|
||||
}
|
||||
|
||||
void Player::serumMulligan()
|
||||
{
|
||||
MTGPlayerCards * currentPlayerZones = game;
|
||||
int cardsinhand = currentPlayerZones->hand->nb_cards;
|
||||
for (int i = 0; i < cardsinhand; i++) //Exile
|
||||
currentPlayerZones->putInZone(currentPlayerZones->hand->cards[0],
|
||||
currentPlayerZones->hand,
|
||||
currentPlayerZones->exile);
|
||||
|
||||
currentPlayerZones->library->shuffle(); //Shuffle
|
||||
|
||||
for (int i = 0; i < (cardsinhand); i++)
|
||||
game->drawFromLibrary();
|
||||
//Draw hand no penalty
|
||||
}
|
||||
|
||||
//Cleanup phase at the end of a turn
|
||||
void Player::cleanupPhase()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user