few changes here, mostly small bug fixes,
recoded altercost, its finally not using a dirty clean up. this fixes the bug with it not effecting ai also and the bug where it was ineffective when combined with affinity creatures... removed a aspect of the wolf class... soft coded support for aspect of the wolf...using word variable subkeyword "halfup" and "halfdown" it can go anywhere a parsable word vairable is stringing...i preffer the front of it... these are Wparsedint subkeywords, not keywords you can use with standard abilities... its meant to return half the varible rounds up, or down... fixed player not losing with cantlifelose when they have 10 or more poison...the player should die. reworked taplandformana, i send the main card as a target now, check against the cost if its affordable...anyways, i discussed this bool function a while back with devs and wololo saw the same issues i saw in it...he then removed it from being used as an if statement...i changed it back to an if statement with the new checks...we are either going to go back to a void, or go all the way bool, but not inbetween.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<MTGAbility *> * 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<MTGAbility *> * 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user