New game modes, bug fixes in primitives, improving AI, new planeswalkers type rule
New rules based on vanguard, 3 new random game modes, one is tribal and one uses any card in the game. Several corrections and bugs fixes. Cards with x in their cost and that can target any player used to crash the game. Teaching AI new things and changing values of efficiency. You can have multiple "Jace" planeswalkers, you can't have two of the exact same name (no two Jace, the mind sculptor).
This commit is contained in:
@@ -46,14 +46,15 @@ int OrderedAIAction::getEfficiency(AADamager * aad)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(p == target->controller())
|
||||
return 0;
|
||||
if(p && target)
|
||||
if(p == target->controller())
|
||||
return 0;
|
||||
|
||||
if (dTarget && aad && (aad->getDamage() >= dTarget->toughness))
|
||||
return 100;
|
||||
|
||||
if (dTarget && dTarget->toughness)
|
||||
return (50 * aad->getDamage()) / dTarget->toughness;
|
||||
return (10 * aad->getDamage()) / dTarget->toughness; // Don't waste damage spells
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -129,8 +130,12 @@ int OrderedAIAction::getEfficiency()
|
||||
{
|
||||
efficiency = 95;
|
||||
}
|
||||
//TODO If the card is the target of a damage spell
|
||||
break;
|
||||
//TODO If the card is the target of a damage spell
|
||||
if (!coreAbilityCardTarget->regenerateTokens && (MTGCardInstance*)target == a->source)
|
||||
{
|
||||
efficiency = 95;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MTGAbility::STANDARD_PREVENT:
|
||||
{
|
||||
@@ -271,7 +276,7 @@ int OrderedAIAction::getEfficiency()
|
||||
}
|
||||
case MTGAbility::STANDARD_PUMP:
|
||||
{
|
||||
efficiency = 0;
|
||||
efficiency = 0;
|
||||
if(!coreAbilityCardTarget)
|
||||
break;
|
||||
if(!target && !dynamic_cast<ALord*> (a) && (((MTGCardInstance *)a->source)->hasSubtype(Subtypes::TYPE_AURA) || ((MTGCardInstance *)a->source)->hasSubtype(Subtypes::TYPE_EQUIPMENT)))
|
||||
@@ -291,9 +296,9 @@ int OrderedAIAction::getEfficiency()
|
||||
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
||||
//i do not set a starting eff. on this ability, this allows Ai to sometimes randomly do it as it normally does.
|
||||
int currentPhase = g->getCurrentGamePhase();
|
||||
if ((currentPhase == MTG_PHASE_COMBATBLOCKERS) || (currentPhase == MTG_PHASE_COMBATATTACKERS))
|
||||
if (suggestion == BAKA_EFFECT_GOOD && target->controller() == p)
|
||||
{
|
||||
if (suggestion == BAKA_EFFECT_GOOD && target->controller() == p)
|
||||
if ((currentPhase == MTG_PHASE_COMBATBLOCKERS) || (currentPhase == MTG_PHASE_COMBATATTACKERS))
|
||||
{
|
||||
if(coreAbilityCardTarget->defenser || coreAbilityCardTarget->blockers.size())
|
||||
{
|
||||
@@ -315,6 +320,10 @@ int OrderedAIAction::getEfficiency()
|
||||
efficiency -= coreAbilityCardTarget->power;//we don't need to go overboard. better to not put all your eggs in a single basket.
|
||||
}
|
||||
}
|
||||
if (currentPhase == MTG_PHASE_FIRSTMAIN)
|
||||
{
|
||||
efficiency = 10;
|
||||
}
|
||||
}
|
||||
if (suggestion == BAKA_EFFECT_BAD && target->controller() != p && target->toughness > 0)
|
||||
{
|
||||
@@ -326,28 +335,41 @@ int OrderedAIAction::getEfficiency()
|
||||
{
|
||||
if(!coreAbilityCardTarget)
|
||||
break;
|
||||
|
||||
// It used to skip most effects, with no other condition efficiency is -1
|
||||
// Becomes is generally good so setting a value, but don't want to spam it
|
||||
if (coreAbilityCardTarget && !coreAbilityCardTarget->isLand())
|
||||
{
|
||||
// Bonus if almost no cards in hand
|
||||
if (p->game->hand->nb_cards <= 1)
|
||||
{
|
||||
efficiency = 60;
|
||||
}
|
||||
else efficiency = 30;
|
||||
}
|
||||
//nothing huge here, just ensuring that Ai makes his noncreature becomers into creatures during first main, so it can actually use them in combat.
|
||||
if (coreAbilityCardTarget && !coreAbilityCardTarget->isCreature() && currentPhase == MTG_PHASE_FIRSTMAIN)
|
||||
{
|
||||
efficiency = 100;
|
||||
}
|
||||
efficiency = 60;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MTGAbility::MANA_PRODUCER://only way to hit this condition is nested manaabilities, ai skips manaproducers by defualt when finding an ability to use.
|
||||
{
|
||||
AManaProducer * manamaker = dynamic_cast<AManaProducer*>(a);
|
||||
GenericActivatedAbility * GAA = dynamic_cast<GenericActivatedAbility*>(ability);
|
||||
AForeach * forMana = dynamic_cast<AForeach*>(GAA->ability);
|
||||
if (manamaker && forMana)
|
||||
{
|
||||
int outPut = forMana->checkActivation();
|
||||
if (ability->getCost() && outPut > int(ability->getCost()->getConvertedCost() +1) && currentPhase == MTG_PHASE_FIRSTMAIN && ability->source->controller()->game->hand->nb_cards > 1)
|
||||
efficiency = 90;//might be a bit random, but better than never using them.
|
||||
}
|
||||
else
|
||||
efficiency = 0;
|
||||
break;
|
||||
AManaProducer * manamaker = dynamic_cast<AManaProducer*>(a);
|
||||
GenericActivatedAbility * GAA = dynamic_cast<GenericActivatedAbility*>(ability);
|
||||
if(GAA)
|
||||
{
|
||||
AForeach * forMana = dynamic_cast<AForeach*>(GAA->ability);
|
||||
if (manamaker && forMana)
|
||||
{
|
||||
int outPut = forMana->checkActivation();
|
||||
if (ability->getCost() && outPut > int(ability->getCost()->getConvertedCost() +1) && currentPhase == MTG_PHASE_FIRSTMAIN && ability->source->controller()->game->hand->nb_cards > 1)
|
||||
efficiency = 60;//might be a bit random, but better than never using them.
|
||||
}
|
||||
}
|
||||
else
|
||||
efficiency = 0;
|
||||
break;
|
||||
}
|
||||
case MTGAbility::STANDARDABILITYGRANT:
|
||||
{
|
||||
@@ -426,11 +448,12 @@ int OrderedAIAction::getEfficiency()
|
||||
|
||||
case MTGAbility::LIFER:
|
||||
{
|
||||
//use life abilities whenever possible.
|
||||
//use life abilities whenever possible. Well yes, but actually no
|
||||
//limits mana and in case of Zuran Orb it just sacrifices all lands
|
||||
AALifer * alife = (AALifer *) a;
|
||||
Targetable * _t = alife->getTarget();
|
||||
|
||||
efficiency = 100;
|
||||
efficiency = 80;
|
||||
AbilityFactory af(g);
|
||||
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
||||
|
||||
@@ -566,6 +589,12 @@ int OrderedAIAction::getEfficiency()
|
||||
{
|
||||
if (z == p->game->hand)
|
||||
efficiency = 10 + (owner->getRandomGenerator()->random() % 10);//random chance to bounce their own card;
|
||||
}
|
||||
// We don't want to return cards in play to own hand, save rare combos
|
||||
else if(target->currentZone == p->game->inPlay)
|
||||
{
|
||||
if (z == p->game->hand || z == p->game->library)
|
||||
efficiency = (owner->getRandomGenerator()->random() % 10);//random chance to bounce their own card;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -574,7 +603,11 @@ int OrderedAIAction::getEfficiency()
|
||||
}
|
||||
else
|
||||
{
|
||||
efficiency = 50;
|
||||
// We don't want to return the ability source cards in play to own hand, save rare combos
|
||||
// cards like Blinking Spirit use to be auto lose for AI
|
||||
if(z == p->game->hand || z == p->game->library)
|
||||
efficiency = 1;
|
||||
else efficiency = 50;
|
||||
//may abilities target the source until thier nested ability is activated, so 50% chance to use this
|
||||
//mover, until we can come up with something more elegent....
|
||||
}
|
||||
@@ -639,7 +672,7 @@ int OrderedAIAction::getEfficiency()
|
||||
{
|
||||
AIPlayer * chk = (AIPlayer*)p;
|
||||
if(may->ability && may->ability->getActionTc() && chk->chooseTarget(may->ability->getActionTc(),NULL,NULL,true))
|
||||
efficiency = 50 + (owner->getRandomGenerator()->random() % 50);
|
||||
efficiency = 80 + (owner->getRandomGenerator()->random() % 50);
|
||||
}
|
||||
if (p->game->hand->nb_cards == 0)
|
||||
efficiency = (int) ((float) efficiency * 1.3); //increase chance of using ability if hand is empty
|
||||
@@ -666,13 +699,18 @@ int OrderedAIAction::getEfficiency()
|
||||
}
|
||||
else if (dynamic_cast<MTGAlternativeCostRule *>(a))
|
||||
{
|
||||
efficiency += 55;
|
||||
efficiency += 65;
|
||||
}
|
||||
else if (dynamic_cast<MTGSuspendRule *>(a))
|
||||
{
|
||||
efficiency += 55;
|
||||
}
|
||||
SAFE_DELETE(transAbility);
|
||||
|
||||
if (ability->source)
|
||||
if(ability->source->hasType(Subtypes::TYPE_PLANESWALKER))
|
||||
efficiency += 50;
|
||||
|
||||
SAFE_DELETE(transAbility);
|
||||
return efficiency;
|
||||
}
|
||||
|
||||
@@ -944,7 +982,7 @@ int OrderedAIAction::getRevealedEfficiency(MTGAbility * ability2)
|
||||
//nothing huge here, just ensuring that Ai makes his noncreature becomers into creatures during first main, so it can actually use them in combat.
|
||||
if (coreAbilityCardTarget && !coreAbilityCardTarget->isCreature() && currentPhase == MTG_PHASE_FIRSTMAIN)
|
||||
{
|
||||
eff2 = 100;
|
||||
eff2 = 70;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -957,7 +995,7 @@ int OrderedAIAction::getRevealedEfficiency(MTGAbility * ability2)
|
||||
{
|
||||
int outPut = forMana->checkActivation();
|
||||
if (ability2->getCost() && outPut > int(ability2->getCost()->getConvertedCost() +1) && currentPhase == MTG_PHASE_FIRSTMAIN && ability2->source->controller()->game->hand->nb_cards > 1)
|
||||
eff2 = 90;//might be a bit random, but better than never using them.
|
||||
eff2 = 60;//might be a bit random, but better than never using them.
|
||||
}
|
||||
else
|
||||
eff2 = 0;
|
||||
@@ -2447,11 +2485,10 @@ int AIPlayerBaka::getEfficiency(MTGAbility * ability)
|
||||
int AIPlayerBaka::selectMenuOption()
|
||||
{
|
||||
ActionLayer * object = observer->mLayers->actionLayer();
|
||||
int doThis = -1;
|
||||
int doThis = 0; // The AI just passes on things if set to -1, getEfficiency should be improved
|
||||
if (object->menuObject)
|
||||
{
|
||||
int checkedLast = 0;
|
||||
|
||||
if(object->abilitiesMenu->isMultipleChoice && object->currentActionCard)
|
||||
{
|
||||
MenuAbility * currentMenu = NULL;
|
||||
@@ -2510,7 +2547,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
||||
{
|
||||
nextCardToPlay = comboCards.back();
|
||||
gotPayments.clear();
|
||||
if((!pMana->canAfford(nextCardToPlay->getManaCost()) || nextCardToPlay->getManaCost()->getKicker()))
|
||||
if((!pMana->canAfford(nextCardToPlay->getManaCost()) || nextCardToPlay->getManaCost()->getKicker() || nextCardToPlay->getManaCost()->getBestow()))
|
||||
gotPayments = canPayMana(nextCardToPlay,nextCardToPlay->getManaCost());
|
||||
DebugTrace("ai is doing a combo:" << nextCardToPlay->getName());
|
||||
comboCards.pop_back();
|
||||
@@ -2524,11 +2561,26 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
||||
card = NULL;
|
||||
gotPayments = vector<MTGAbility*>();
|
||||
//canplayfromgraveyard
|
||||
while ((card = cd.nextmatch(game->graveyard, card))&& card->has(Constants::CANPLAYFROMGRAVEYARD))
|
||||
{
|
||||
while ((card = cd.nextmatch(game->graveyard, card)))
|
||||
{
|
||||
bool hasFlashback = false;
|
||||
|
||||
if(card->getManaCost())
|
||||
if(card->getManaCost()->getFlashback())
|
||||
hasFlashback = true;
|
||||
|
||||
if( card->has(Constants::CANPLAYFROMGRAVEYARD) || card->has(Constants::TEMPFLASHBACK) || hasFlashback )
|
||||
{
|
||||
if (!CanHandleCost(card->getManaCost(),card))
|
||||
continue;
|
||||
|
||||
if (hasFlashback && !CanHandleCost(card->getManaCost()->getFlashback(),card))
|
||||
continue;
|
||||
|
||||
// Case were manacost is equal to flashback cost, if they are different the AI hangs
|
||||
if (hasFlashback && (card->getManaCost() != card->getManaCost()->getFlashback()) )
|
||||
continue;
|
||||
|
||||
if (card->hasType(Subtypes::TYPE_LAND))
|
||||
{
|
||||
if (game->playRestrictions->canPutIntoZone(card, game->inPlay) == PlayRestriction::CANT_PLAY)
|
||||
@@ -2619,27 +2671,27 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
||||
}
|
||||
else
|
||||
{
|
||||
int shouldPlay = effectBadOrGood(card);
|
||||
if (shouldPlay == BAKA_EFFECT_GOOD)
|
||||
// Refactor to not check effect of lands since it always returned BAKA_EFFECT_DONTKNOW
|
||||
// If it is a land, play it
|
||||
if (card->isLand())
|
||||
{
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else if (BAKA_EFFECT_DONTKNOW == shouldPlay)
|
||||
{
|
||||
//previously shouldPlayPercentage = 80;, I found this a little to high
|
||||
//for cards which AI had no idea how to use.
|
||||
shouldPlayPercentage = 60;
|
||||
}
|
||||
else if (card->isLand())
|
||||
{
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldPlay == baka_effect_bad giving it a 1 for odd ball lottery chance.
|
||||
shouldPlayPercentage = 1;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
int shouldPlay = effectBadOrGood(card);
|
||||
if (shouldPlay == BAKA_EFFECT_GOOD) {
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else if (BAKA_EFFECT_DONTKNOW == shouldPlay) {
|
||||
//previously shouldPlayPercentage = 80;, I found this a little to high
|
||||
//for cards which AI had no idea how to use.
|
||||
shouldPlayPercentage = 60;
|
||||
}
|
||||
else {
|
||||
// shouldPlay == baka_effect_bad giving it a 10 for odd ball lottery chance.
|
||||
shouldPlayPercentage = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Reduce the chances of playing a spell with X cost if available mana is low
|
||||
if (hasX)
|
||||
@@ -2677,6 +2729,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
||||
if (hasX)
|
||||
maxCost = pMana->getConvertedCost();
|
||||
}
|
||||
}
|
||||
}
|
||||
//canplayfromexile
|
||||
while ((card = cd.nextmatch(game->exile, card))&& card->has(Constants::CANPLAYFROMEXILE))
|
||||
@@ -2774,27 +2827,27 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
||||
}
|
||||
else
|
||||
{
|
||||
int shouldPlay = effectBadOrGood(card);
|
||||
if (shouldPlay == BAKA_EFFECT_GOOD)
|
||||
// Refactor to not check effect of lands since it always returned BAKA_EFFECT_DONTKNOW
|
||||
// If it is a land, play it
|
||||
if (card->isLand())
|
||||
{
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else if (BAKA_EFFECT_DONTKNOW == shouldPlay)
|
||||
{
|
||||
//previously shouldPlayPercentage = 80;, I found this a little to high
|
||||
//for cards which AI had no idea how to use.
|
||||
shouldPlayPercentage = 60;
|
||||
}
|
||||
else if (card->isLand())
|
||||
{
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldPlay == baka_effect_bad giving it a 1 for odd ball lottery chance.
|
||||
shouldPlayPercentage = 1;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
int shouldPlay = effectBadOrGood(card);
|
||||
if (shouldPlay == BAKA_EFFECT_GOOD) {
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else if (BAKA_EFFECT_DONTKNOW == shouldPlay) {
|
||||
//previously shouldPlayPercentage = 80;, I found this a little to high
|
||||
//for cards which AI had no idea how to use.
|
||||
shouldPlayPercentage = 60;
|
||||
}
|
||||
else {
|
||||
// shouldPlay == baka_effect_bad giving it a 10 for odd ball lottery chance.
|
||||
shouldPlayPercentage = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Reduce the chances of playing a spell with X cost if available mana is low
|
||||
if (hasX)
|
||||
@@ -2928,27 +2981,27 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
||||
}
|
||||
else
|
||||
{
|
||||
int shouldPlay = effectBadOrGood(card);
|
||||
if (shouldPlay == BAKA_EFFECT_GOOD)
|
||||
// Refactor to not check effect of lands since it always returned BAKA_EFFECT_DONTKNOW
|
||||
// If it is a land, play it
|
||||
if (card->isLand())
|
||||
{
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else if (BAKA_EFFECT_DONTKNOW == shouldPlay)
|
||||
{
|
||||
//previously shouldPlayPercentage = 80;, I found this a little to high
|
||||
//for cards which AI had no idea how to use.
|
||||
shouldPlayPercentage = 60;
|
||||
}
|
||||
else if (card->isLand())
|
||||
{
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldPlay == baka_effect_bad giving it a 1 for odd ball lottery chance.
|
||||
shouldPlayPercentage = 1;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
int shouldPlay = effectBadOrGood(card);
|
||||
if (shouldPlay == BAKA_EFFECT_GOOD) {
|
||||
shouldPlayPercentage = 90;
|
||||
}
|
||||
else if (BAKA_EFFECT_DONTKNOW == shouldPlay) {
|
||||
//previously shouldPlayPercentage = 80;, I found this a little to high
|
||||
//for cards which AI had no idea how to use.
|
||||
shouldPlayPercentage = 60;
|
||||
}
|
||||
else {
|
||||
// shouldPlay == baka_effect_bad giving it a 10 for odd ball lottery chance.
|
||||
shouldPlayPercentage = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Reduce the chances of playing a spell with X cost if available mana is low
|
||||
if (hasX)
|
||||
|
||||
@@ -463,7 +463,7 @@ void CardGui::Render()
|
||||
string buff = "";
|
||||
string starMark = "";
|
||||
if(card->exerted)
|
||||
starMark += "*";
|
||||
starMark += "exerted";
|
||||
if(card->isToken && !card->isACopier)
|
||||
buff = "T";
|
||||
if(card->isToken && card->isACopier)
|
||||
|
||||
@@ -417,10 +417,11 @@ ManaCost* CardPrimitive::getManaCost()
|
||||
|
||||
bool CardPrimitive::hasType(int _type)
|
||||
{
|
||||
for (size_t i = 0; i < types.size(); i++)
|
||||
if (types[i] == _type)
|
||||
return true;
|
||||
return false;
|
||||
if (types.size() > 400) {return false;} // Null pointer?
|
||||
for (size_t i = 0; i < types.size(); i++)
|
||||
if (types[i] == _type)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CardPrimitive::hasSubtype(int _subtype)
|
||||
|
||||
@@ -770,7 +770,10 @@ void GameStateDuel::Update(float dt)
|
||||
musictrack = "ai_baka_music_momir.mp3";
|
||||
else if (mParent->gameType == GAME_TYPE_RANDOM1 || mParent->gameType == GAME_TYPE_RANDOM2) musictrack
|
||||
= "ai_baka_music_random.mp3";
|
||||
|
||||
else if (mParent->gameType == GAME_TYPE_RANDOM3 || mParent->gameType == GAME_TYPE_RANDOM5) musictrack
|
||||
= "ai_baka_music_random.mp3";
|
||||
else if (mParent->gameType == GAME_TYPE_HORDE) musictrack
|
||||
= "ai_baka_music_momir.mp3";
|
||||
if (!MusicExist(musictrack))
|
||||
musictrack = "ai_baka_music.mp3";
|
||||
|
||||
|
||||
@@ -312,7 +312,7 @@ void GuiPlay::Render()
|
||||
MTGCardInstance * ctarget = ((MTGCardInstance *)(*it)->card->isAttacking);
|
||||
if(ctarget->hasType(Subtypes::TYPE_PLANESWALKER) && observer->isInPlay(ctarget) && observer->getCurrentGamePhase() < MTG_PHASE_COMBATEND)
|
||||
{
|
||||
JRenderer::GetInstance()->DrawLine((*it)->actX,(*it)->actY,ctarget->view->actX,ctarget->view->actY,0.5f,ARGB(128 - wave, 255, 20, 0));
|
||||
JRenderer::GetInstance()->DrawLine((*it)->actX,(*it)->actY,ctarget->view->actX,ctarget->view->actY,0.5f,ARGB(128 - wave, 255, 40, 40));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1835,7 +1835,8 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
tc->targetter = NULL;
|
||||
}
|
||||
else
|
||||
tc->targetter->bypassTC = false;
|
||||
if (tc->targetter)
|
||||
tc->targetter->bypassTC = false;
|
||||
sWithoutTc = splitTarget[0];
|
||||
sWithoutTc.append(splitTarget[2]);
|
||||
}
|
||||
@@ -1935,7 +1936,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
{
|
||||
if (!(spell && spell->FullfilledAlternateCost(kAlternateCostIds[i])))
|
||||
{
|
||||
DebugTrace("INFO parseMagicLine: Alternative Cost was not fulfilled for " << s);
|
||||
DebugTrace("INFO parseMagicLine: Alternative Cost was not fulfilled for " << spell << s);
|
||||
SAFE_DELETE(tc);
|
||||
return NULL;
|
||||
}
|
||||
@@ -3512,7 +3513,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
|
||||
//produce additional mana when a mana is engaged
|
||||
if (s.find("producecolor:") != string::npos)
|
||||
{
|
||||
{
|
||||
return NEW AEngagedManaAbility(observer, id, card,s.substr(13));
|
||||
}
|
||||
|
||||
@@ -4094,13 +4095,14 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
return NEW ANewAffinity(observer, id, card, tcString, manaString);
|
||||
}
|
||||
|
||||
//proliferate
|
||||
//proliferate, rule changes in War of the Spark set
|
||||
found = s.find("proliferate");
|
||||
if (found != string::npos)
|
||||
{
|
||||
MTGAbility * a = NEW AAProliferate(observer, id, card, target);
|
||||
a->oneShot = 1;
|
||||
a->canBeInterrupted = false;
|
||||
((AAProliferate*)a)->allcounters = true;
|
||||
return a;
|
||||
}
|
||||
//proliferate all counters
|
||||
@@ -4545,6 +4547,8 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode, Targ
|
||||
return BAKA_EFFECT_BAD;
|
||||
if (dynamic_cast<AManaProducer *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AARemoveAllCounter *> (a))
|
||||
return BAKA_EFFECT_BAD;
|
||||
|
||||
// Equipment that gets immediately attached. Todo: check the abilities associated with Equip, to make sure they're good (for now it seems to be the majority of the cases)?
|
||||
if (dynamic_cast<AEquip *> (a))
|
||||
@@ -4568,12 +4572,12 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode, Targ
|
||||
if (AAMover * aam = dynamic_cast<AAMover *>(a))
|
||||
{
|
||||
MTGGameZone * z = aam->destinationZone(target);
|
||||
if (tc && tc->targetsZone(p->game->library))
|
||||
if (tc && tc->targetsZone(p->game->library)||tc && tc->targetsZone(p->game->graveyard))
|
||||
{
|
||||
if (z == p->game->hand || z == p->game->inPlay)
|
||||
return BAKA_EFFECT_GOOD;
|
||||
}
|
||||
return BAKA_EFFECT_BAD; //TODO
|
||||
return BAKA_EFFECT_DONTKNOW; //TODO
|
||||
}
|
||||
|
||||
if (dynamic_cast<AACopier *> (a))
|
||||
@@ -4598,6 +4602,31 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode, Targ
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<ABushidoAbility *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AACascade *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AACastCard *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AAFlip *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AAImprint *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<ABestow *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AExert *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<ALoseAbilities *> (a))
|
||||
return BAKA_EFFECT_BAD;
|
||||
if (dynamic_cast<AModularAbility *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<APaired *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AProduceMana *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AACloner *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
if (dynamic_cast<AAModTurn *> (a))
|
||||
return BAKA_EFFECT_GOOD;
|
||||
|
||||
if (PTInstant * abi = dynamic_cast<PTInstant *>(a))
|
||||
return (abi->wppt->power.getValue() >= 0 && abi->wppt->toughness.getValue() >= 0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
||||
if (APowerToughnessModifier * abi = dynamic_cast<APowerToughnessModifier *>(a))
|
||||
@@ -4628,6 +4657,8 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode, Targ
|
||||
badAbilities[(int)Constants::NOLIFEGAINOPPONENT] = true;
|
||||
badAbilities[(int)Constants::MUSTBLOCK] = true;
|
||||
badAbilities[(int)Constants::FLYERSONLY] = true;
|
||||
badAbilities[(int)Constants::TREASON] = true;
|
||||
badAbilities[(int)Constants::SHACKLER] = true;
|
||||
|
||||
if (AInstantBasicAbilityModifierUntilEOT * abi = dynamic_cast<AInstantBasicAbilityModifierUntilEOT *>(a))
|
||||
{
|
||||
@@ -4694,7 +4725,7 @@ int AbilityFactory::getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCar
|
||||
card->exileEffects = true;
|
||||
break;
|
||||
}
|
||||
if (dest == zones->library)
|
||||
if (dest == zones->library)
|
||||
{
|
||||
magicText = card->magicTexts["library"];
|
||||
break;
|
||||
@@ -4788,7 +4819,7 @@ int AbilityFactory::getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCar
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugTrace("ABILITYFACTORY ERROR: Parser returned NULL");
|
||||
DebugTrace("ABILITYFACTORY ERROR: Parser returned NULL " + magicText);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -4804,7 +4835,7 @@ int AbilityFactory::getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCar
|
||||
* - doTap (a dirty way to know if tapping is included in the cost...
|
||||
*/
|
||||
int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card, int mode, TargetChooser * tc, MTGGameZone * dest)
|
||||
{
|
||||
{try{
|
||||
int dryMode = 0;
|
||||
if (!spell && !dest)
|
||||
dryMode = 1;
|
||||
@@ -4888,6 +4919,11 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card, int
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch(exception) {
|
||||
DebugTrace("MAGIC TEST ERROR: Parser returned NULL");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AbilityFactory::addAbilities(int _id, Spell * spell)
|
||||
|
||||
@@ -505,6 +505,20 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card)
|
||||
}
|
||||
delete withKickerCost;
|
||||
}
|
||||
if (card->getManaCost()->getBestow())
|
||||
{
|
||||
ManaCost * withBestowCost= NEW ManaCost(card->getManaCost());
|
||||
withBestowCost->add(withBestowCost->getBestow());
|
||||
|
||||
DebugTrace("AltCost BESTOW " << withBestowCost);
|
||||
if (previousManaPool->canAfford(withBestowCost))
|
||||
{
|
||||
player->getManaPool()->pay(card->getManaCost()->getBestow());
|
||||
payResult = ManaCost::MANA_PAID_WITH_BESTOW;
|
||||
}
|
||||
delete withBestowCost;
|
||||
}
|
||||
|
||||
card->getManaCost()->doPayExtra();
|
||||
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
|
||||
|
||||
@@ -652,6 +666,19 @@ int MTGKickerRule::reactToClick(MTGCardInstance * card)
|
||||
payResult = ManaCost::MANA_PAID_WITH_KICKER;
|
||||
}
|
||||
delete withKickerCost;
|
||||
}
|
||||
// Handles bestow,also has to go in isExtraPaymentSet
|
||||
if (card->getManaCost()->getBestow())
|
||||
{
|
||||
ManaCost * withBestowCost= NEW ManaCost(card->getManaCost());
|
||||
withBestowCost->add(withBestowCost->getBestow());
|
||||
|
||||
if (previousManaPool->canAfford(withBestowCost))
|
||||
{
|
||||
player->getManaPool()->pay(card->getManaCost()->getBestow());
|
||||
payResult = ManaCost::MANA_PAID_WITH_BESTOW;
|
||||
}
|
||||
delete withBestowCost;
|
||||
}
|
||||
card->getManaCost()->doPayExtra();
|
||||
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
|
||||
@@ -3486,7 +3513,7 @@ PermanentAbility(observer, _id)
|
||||
}
|
||||
|
||||
int MTGNewPlaneswalker::receiveEvent(WEvent * e)
|
||||
{
|
||||
{
|
||||
if(game->getCurrentTargetChooser() || game->mLayers->actionLayer()->isWaitingForAnswer())
|
||||
return 0;
|
||||
if (WEventZoneChange* ev1 = dynamic_cast<WEventZoneChange*>(e))
|
||||
@@ -3494,7 +3521,7 @@ int MTGNewPlaneswalker::receiveEvent(WEvent * e)
|
||||
if (ev1->to == game->players[0]->game->inPlay || ev1->to == game->players[1]->game->inPlay)
|
||||
{
|
||||
MTGCardInstance * card = ev1->card;
|
||||
if(card && card->hasType(Subtypes::TYPE_PLANESWALKER))
|
||||
if(card && card->countDuplicateCardNames() > 1 && card->hasType(Subtypes::TYPE_LEGENDARY))
|
||||
{
|
||||
CheckPW(card);
|
||||
return 1;
|
||||
@@ -3504,7 +3531,7 @@ int MTGNewPlaneswalker::receiveEvent(WEvent * e)
|
||||
else if(WEventCardControllerChange* ev2 = dynamic_cast<WEventCardControllerChange*>(e))
|
||||
{
|
||||
MTGCardInstance * card = ev2->card;
|
||||
if(card && card->hasType(Subtypes::TYPE_PLANESWALKER))
|
||||
if(card && card->countDuplicateCardNames() > 1 && card->hasType(Subtypes::TYPE_LEGENDARY))
|
||||
{
|
||||
CheckPW(card);
|
||||
return 1;
|
||||
@@ -3513,7 +3540,7 @@ int MTGNewPlaneswalker::receiveEvent(WEvent * e)
|
||||
else if(WEventCardTransforms* ev3 = dynamic_cast<WEventCardTransforms*>(e))
|
||||
{
|
||||
MTGCardInstance * card = ev3->card;
|
||||
if(card && card->hasType(Subtypes::TYPE_PLANESWALKER))
|
||||
if(card && card->countDuplicateCardNames() > 1 && card->hasType(Subtypes::TYPE_LEGENDARY))
|
||||
{
|
||||
CheckPW(card);
|
||||
return 1;
|
||||
@@ -3522,7 +3549,7 @@ int MTGNewPlaneswalker::receiveEvent(WEvent * e)
|
||||
else if(WEventCardCopiedACard* ev4 = dynamic_cast<WEventCardCopiedACard*>(e))
|
||||
{
|
||||
MTGCardInstance * card = ev4->card;
|
||||
if(card && card->hasType(Subtypes::TYPE_PLANESWALKER))
|
||||
if(card && card->countDuplicateCardNames() > 1 && card->hasType(Subtypes::TYPE_LEGENDARY))
|
||||
{
|
||||
CheckPW(card);
|
||||
return 1;
|
||||
@@ -3531,7 +3558,7 @@ int MTGNewPlaneswalker::receiveEvent(WEvent * e)
|
||||
else if(WEventCardFaceUp* ev5 = dynamic_cast<WEventCardFaceUp*>(e))
|
||||
{
|
||||
MTGCardInstance * card = ev5->card;
|
||||
if(card && card->hasType(Subtypes::TYPE_PLANESWALKER))
|
||||
if(card && card->countDuplicateCardNames() > 1 && card->hasType(Subtypes::TYPE_LEGENDARY))
|
||||
{
|
||||
CheckPW(card);
|
||||
return 1;
|
||||
@@ -3540,7 +3567,7 @@ int MTGNewPlaneswalker::receiveEvent(WEvent * e)
|
||||
else if(WEventCardPhasesIn* ev6 = dynamic_cast<WEventCardPhasesIn*>(e))
|
||||
{
|
||||
MTGCardInstance * card = ev6->card;
|
||||
if(card && card->hasType(Subtypes::TYPE_PLANESWALKER))
|
||||
if(card && card->countDuplicateCardNames() > 1 && card->hasType(Subtypes::TYPE_LEGENDARY))
|
||||
{
|
||||
CheckPW(card);
|
||||
return 1;
|
||||
@@ -3550,23 +3577,26 @@ int MTGNewPlaneswalker::receiveEvent(WEvent * e)
|
||||
}
|
||||
int MTGNewPlaneswalker::CheckPW(MTGCardInstance * card)
|
||||
{
|
||||
if(!card)
|
||||
if(!card)
|
||||
return 0;
|
||||
if(card->isPhased)
|
||||
return 0;
|
||||
if(card->countDuplicateCardTypes() < 1)
|
||||
if (card->hasType(Subtypes::TYPE_LEGENDARY) && card->controller()->game->inPlay->hasCard(card))
|
||||
if(card->has(Constants::NOLEGEND)||card->controller()->opponent()->inPlay()->hasAbility(Constants::NOLEGENDRULE)||card->controller()->inPlay()->hasAbility(Constants::NOLEGENDRULE))
|
||||
return 0;
|
||||
if(card->countDuplicateCardNames() <= 2)
|
||||
return 0;
|
||||
|
||||
MovePW(card);
|
||||
return 1;
|
||||
}
|
||||
void MTGNewPlaneswalker::MovePW(MTGCardInstance * card)
|
||||
{
|
||||
{
|
||||
game->LPWeffect = true;
|
||||
vector<MTGAbility*>selection;
|
||||
MTGCardInstance * myClone = NEW MTGCardInstance(card, card->controller()->game);
|
||||
TargetChooserFactory tfL(game);
|
||||
tcP = tfL.createTargetChooser("planeswalker[share!types!]|mybattlefield",myClone);
|
||||
tcP = tfL.createTargetChooser("*[share!name!]|mybattlefield",myClone);
|
||||
tcP->targetter = NULL;
|
||||
tcP->maxtargets = 1;
|
||||
PWrule = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), myClone, NULL,"ownergraveyard","Put in Graveyard");
|
||||
@@ -3679,24 +3709,27 @@ ListMaintainerAbility(observer, _id)
|
||||
|
||||
int MTGPlaneWalkerRule::canBeInList(MTGCardInstance * card)
|
||||
{
|
||||
if(card->isPhased)
|
||||
if(card->isPhased)
|
||||
return 0;
|
||||
if (card->hasType(Subtypes::TYPE_PLANESWALKER) && card->controller()->game->inPlay->hasCard(card))
|
||||
if (card->hasType(Subtypes::TYPE_LEGENDARY) && card->controller()->game->inPlay->hasCard(card))
|
||||
{
|
||||
return 1;
|
||||
if(card->has(Constants::NOLEGEND)||card->controller()->opponent()->inPlay()->hasAbility(Constants::NOLEGENDRULE)||card->controller()->inPlay()->hasAbility(Constants::NOLEGENDRULE))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MTGPlaneWalkerRule::added(MTGCardInstance * card)
|
||||
{
|
||||
map<MTGCardInstance *, bool>::iterator it;
|
||||
map<MTGCardInstance *, bool>::iterator it;
|
||||
int destroy = 0;
|
||||
vector<MTGCardInstance*>oldCards;
|
||||
for (it = cards.begin(); it != cards.end(); it++)
|
||||
{
|
||||
MTGCardInstance * comparison = (*it).first;
|
||||
if (comparison != card && comparison->types == card->types && comparison->controller() == card->controller())
|
||||
if (comparison != card && comparison->controller() == card->controller() && !(comparison->getName().compare(card->getName())))
|
||||
if (!(game->getCurrentTargetChooser() || game->mLayers->actionLayer()->isWaitingForAnswer()))
|
||||
{
|
||||
oldCards.push_back(comparison);
|
||||
@@ -3704,11 +3737,10 @@ int MTGPlaneWalkerRule::added(MTGCardInstance * card)
|
||||
game->LPWeffect = true;
|
||||
}
|
||||
}
|
||||
if (destroy)
|
||||
if(destroy)
|
||||
{
|
||||
vector<MTGAbility*>selection;
|
||||
|
||||
MultiAbility * multi = NEW MultiAbility(game,game->mLayers->actionLayer()->getMaxId(), card, card, NULL);
|
||||
MultiAbility * multi = NEW MultiAbility(game, game->mLayers->actionLayer()->getMaxId(), card, card, NULL);
|
||||
for(unsigned int i = 0;i < oldCards.size();i++)
|
||||
{
|
||||
AAMover *a = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), card, oldCards[i],"ownergraveyard","Keep New");
|
||||
@@ -3722,7 +3754,7 @@ int MTGPlaneWalkerRule::added(MTGCardInstance * card)
|
||||
b->oneShot = true;
|
||||
MTGAbility * b1 = b;
|
||||
selection.push_back(b1);
|
||||
MTGAbility * menuChoice = NEW MenuAbility(game, game->mLayers->actionLayer()->getMaxId(), card, card,true,selection,card->controller(),"Planeswalker Rule");
|
||||
MTGAbility * menuChoice = NEW MenuAbility(game, game->mLayers->actionLayer()->getMaxId(), card, card,true,selection,card->controller(),"Legendary Rule");
|
||||
menuChoice->addToGame();
|
||||
}
|
||||
return 1;
|
||||
|
||||
@@ -579,6 +579,8 @@ int ManaCost::hasAnotherCost()
|
||||
if(kicker)
|
||||
result = 1;
|
||||
//kicker is the only one ai knows for now, later hasAnotherCost() can be used to determine other cost types.
|
||||
if(Retrace || BuyBack || alternative || FlashBack || morph || suspend || Bestow)
|
||||
result = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -730,7 +732,7 @@ int ManaCost::getCost(int color)
|
||||
{
|
||||
if (cost.size() <= (size_t)color)
|
||||
{
|
||||
DebugTrace("Seems ManaCost was not properly initialized");
|
||||
DebugTrace("in GetCost Seems ManaCost was not properly initialized");
|
||||
return 0;
|
||||
}
|
||||
return cost[color];
|
||||
|
||||
+164
-1
@@ -168,6 +168,10 @@ void Rules::addExtraRules(GameObserver* g)
|
||||
difficultyRating = 0;
|
||||
else if(g->mRules->gamemode == GAME_TYPE_RANDOM1 || g->mRules->gamemode == GAME_TYPE_RANDOM2)
|
||||
difficultyRating = 0;
|
||||
else if(g->mRules->gamemode == GAME_TYPE_RANDOM3 || g->mRules->gamemode == GAME_TYPE_RANDOM5)
|
||||
difficultyRating = 0;
|
||||
else if(g->mRules->gamemode == GAME_TYPE_HORDE)
|
||||
difficultyRating = 0;
|
||||
else if (g->mRules->gamemode == GAME_TYPE_STORY)
|
||||
difficultyRating = 0;
|
||||
else if (a->aType == MTGAbility::STANDARD_DRAW)
|
||||
@@ -196,9 +200,11 @@ void Rules::addExtraRules(GameObserver* g)
|
||||
a->resolve();
|
||||
else if(g->mRules->gamemode == GAME_TYPE_RANDOM1 || g->mRules->gamemode == GAME_TYPE_RANDOM2)
|
||||
a->resolve();
|
||||
else if(g->mRules->gamemode == GAME_TYPE_RANDOM3 || g->mRules->gamemode == GAME_TYPE_RANDOM5)
|
||||
a->resolve();
|
||||
else if (g->mRules->gamemode == GAME_TYPE_STORY)
|
||||
a->resolve();
|
||||
else//stupid protections to keep this out of mimor and other game modes.
|
||||
else//stupid protections to keep this out of momir and other game modes.
|
||||
{
|
||||
handsize = ((AADrawer *)a)->getNumCards();
|
||||
if(difficultyRating == EASY)
|
||||
@@ -305,6 +311,154 @@ Player * Rules::loadPlayerRandom(GameObserver* observer, int isAI, int mode)
|
||||
return player;
|
||||
}
|
||||
|
||||
Player * Rules::loadPlayerRandomThree(GameObserver* observer, int isAI)
|
||||
{
|
||||
int color1 = 1 + observer->getRandomGenerator()->random() % 5;
|
||||
int color2 = 1 + observer->getRandomGenerator()->random() % 5;
|
||||
int color3 = 1 + observer->getRandomGenerator()->random() % 5;
|
||||
int color0 = Constants::MTG_COLOR_ARTIFACT;
|
||||
|
||||
int colors[] = { color1, color2, color3, color0 };
|
||||
int nbcolors = 4;
|
||||
|
||||
string lands[] = { "", "forest", "island", "mountain", "swamp", "plains", "" };
|
||||
|
||||
MTGDeck * tempDeck = NEW MTGDeck(MTGCollection());
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, lands[color1].c_str());
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, lands[color2].c_str());
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, lands[color3].c_str());
|
||||
tempDeck->addRandomCards(6, 0, 0, 'R', lands[color1].c_str());
|
||||
tempDeck->addRandomCards(6, 0, 0, 'R', lands[color2].c_str());
|
||||
tempDeck->addRandomCards(6, 0, 0, 'R', lands[color3].c_str());
|
||||
tempDeck->addRandomCards(3, 0, 0, -1, "land");
|
||||
tempDeck->addRandomCards(1, 0, 0, 'U', "land");
|
||||
tempDeck->addRandomCards(1, 0, 0, 'R', "land");
|
||||
tempDeck->addRandomCards(18, 0, 0, -1, "creature", colors, nbcolors);
|
||||
tempDeck->addRandomCards(1, 0, 0, 'R', "creature", colors, nbcolors);
|
||||
tempDeck->addRandomCards(1, 0, 0, 'M', "creature", colors, nbcolors);
|
||||
tempDeck->addRandomCards(3, 0, 0, -1, "sorcery", colors, nbcolors);
|
||||
tempDeck->addRandomCards(3, 0, 0, -1, "enchantment", colors, nbcolors);
|
||||
tempDeck->addRandomCards(3, 0, 0, -1, "instant", colors, nbcolors);
|
||||
tempDeck->addRandomCards(4, 0, 0, -1, "artifact", colors, nbcolors);
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, "planeswalker", colors, nbcolors);
|
||||
|
||||
string deckFile = "random";
|
||||
string deckFileSmall = "random";
|
||||
|
||||
Player *player = NULL;
|
||||
if (!isAI) // Human Player
|
||||
player = NEW HumanPlayer(observer, deckFile, deckFileSmall, false, tempDeck);
|
||||
else
|
||||
player = NEW AIPlayerBaka(observer, deckFile, deckFileSmall, "", tempDeck);
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
Player * Rules::loadPlayerRandomFive(GameObserver* observer, int isAI)
|
||||
{
|
||||
MTGDeck * tempDeck = NEW MTGDeck(MTGCollection());
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, "plains");
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, "island");
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, "swamp");
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, "mountain");
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, "forest");
|
||||
tempDeck->addRandomCards(3, 0, 0, 'R', "plains");
|
||||
tempDeck->addRandomCards(3, 0, 0, 'R', "island");
|
||||
tempDeck->addRandomCards(3, 0, 0, 'R', "swamp");
|
||||
tempDeck->addRandomCards(3, 0, 0, 'R', "mountain");
|
||||
tempDeck->addRandomCards(3, 0, 0, 'R', "forest");
|
||||
tempDeck->addRandomCards(4, 0, 0, -1, "land");
|
||||
tempDeck->addRandomCards(1, 0, 0, 'U', "land");
|
||||
tempDeck->addRandomCards(1, 0, 0, 'R', "land");
|
||||
tempDeck->addRandomCards(18, 0, 0, -1, "creature");
|
||||
tempDeck->addRandomCards(1, 0, 0, 'R', "creature");
|
||||
tempDeck->addRandomCards(1, 0, 0, 'M', "creature");
|
||||
tempDeck->addRandomCards(3, 0, 0, -1, "sorcery");
|
||||
tempDeck->addRandomCards(3, 0, 0, -1, "enchantment");
|
||||
tempDeck->addRandomCards(3, 0, 0, -1, "instant");
|
||||
tempDeck->addRandomCards(4, 0, 0, -1, "artifact");
|
||||
tempDeck->addRandomCards(1, 0, 0, -1, "planeswalker");
|
||||
|
||||
string deckFile = "random";
|
||||
string deckFileSmall = "random";
|
||||
|
||||
Player *player = NULL;
|
||||
if (!isAI) // Human Player
|
||||
player = NEW HumanPlayer(observer, deckFile, deckFileSmall, false, tempDeck);
|
||||
else
|
||||
player = NEW AIPlayerBaka(observer, deckFile, deckFileSmall, "", tempDeck);
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
Player * Rules::loadPlayerHorde(GameObserver* observer, int isAI)
|
||||
{
|
||||
int nbColors = 1;
|
||||
string randomTribe = "";
|
||||
int tribeColor[] = { observer->getRandomGenerator()->random() % 6 };
|
||||
|
||||
string lands[] = { "land", "forest", "island", "mountain", "swamp", "plains" };
|
||||
|
||||
const char* const multicolorTribes[] = { "Ally", "Atog", "Eldrazi", "Elemental", "Human", "Knight",
|
||||
"Myr", "Samurai", "Shaman", "Shapeshifter", "Sliver", "Soldier", "Spellshaper" };
|
||||
const char* const whiteTribes[] = { "Angel","Cat", "Griffin", "Kithkin", "Knight", "Pegasus", "Soldier" };
|
||||
const char* const blueTribes[] = { "Artificer", "Merfolk", "Drake", "Faerie", "Illusion", "Vedalken" };
|
||||
const char* const blackTribes[] = { "Demon", "Faerie", "Horror", "Pirate", "Rat", "Shade", "Skeleton", "Vampire", "Zombie" };
|
||||
const char* const redTribes[] = { "Barbarian", "Berserker","Cat", "Devil", "Goblin", "Minotaur", "Werewolf" };
|
||||
const char* const greenTribes[] = { "Beast", "Cat", "Centaur", "Dinosaur", "Druid", "Elf", "Fungus",
|
||||
"Saproling", "Spider", "Treefolk", "Werewolf" };
|
||||
|
||||
int multicolorTribesSize = sizeof(multicolorTribes)/sizeof(multicolorTribes[0]);
|
||||
int whiteTribesSize = sizeof(whiteTribes)/sizeof(whiteTribes[0]);
|
||||
int blueTribesSize = sizeof(blueTribes)/sizeof(blueTribes[0]);
|
||||
int blackTribesSize = sizeof(blackTribes)/sizeof(blackTribes[0]);
|
||||
int redTribesSize = sizeof(redTribes)/sizeof(redTribes[0]);
|
||||
int greenTribesSize = sizeof(greenTribes)/sizeof(greenTribes[0]);
|
||||
|
||||
switch (tribeColor[0])
|
||||
{
|
||||
case Constants::MTG_COLOR_ARTIFACT :
|
||||
randomTribe = multicolorTribes[observer->getRandomGenerator()->random() % multicolorTribesSize];
|
||||
nbColors = 0;
|
||||
break;
|
||||
case Constants::MTG_COLOR_WHITE :
|
||||
randomTribe = whiteTribes[observer->getRandomGenerator()->random() % whiteTribesSize];
|
||||
break;
|
||||
case Constants::MTG_COLOR_BLUE :
|
||||
randomTribe = blueTribes[observer->getRandomGenerator()->random() % blueTribesSize];
|
||||
break;
|
||||
case Constants::MTG_COLOR_BLACK :
|
||||
randomTribe = blackTribes[observer->getRandomGenerator()->random() % blackTribesSize];
|
||||
break;
|
||||
case Constants::MTG_COLOR_RED :
|
||||
randomTribe = redTribes[observer->getRandomGenerator()->random() % redTribesSize];
|
||||
break;
|
||||
case Constants::MTG_COLOR_GREEN :
|
||||
randomTribe = greenTribes[observer->getRandomGenerator()->random() % greenTribesSize];
|
||||
break;
|
||||
}
|
||||
|
||||
MTGDeck * tempDeck = NEW MTGDeck(MTGCollection());
|
||||
tempDeck->addRandomCards(16, 0, 0, -1, lands[tribeColor[0]].c_str());
|
||||
tempDeck->addRandomCards(4, 0, 0, 'R', lands[tribeColor[0]].c_str());
|
||||
tempDeck->addRandomCards(4, 0, 0, -1, "land");
|
||||
tempDeck->addRandomCards(21, 0, 0, -1, randomTribe);
|
||||
tempDeck->addRandomCards(5, 0, 0, -1, "enchantment", tribeColor, nbColors);
|
||||
tempDeck->addRandomCards(5, 0, 0, -1, "instant", tribeColor, nbColors);
|
||||
tempDeck->addRandomCards(5, 0, 0, -1, "sorcery", tribeColor, nbColors);
|
||||
|
||||
string deckFile = "random";
|
||||
string deckFileSmall = "random";
|
||||
|
||||
Player *player = NULL;
|
||||
if (!isAI) // Human Player
|
||||
player = NEW HumanPlayer(observer, deckFile, deckFileSmall, false, tempDeck);
|
||||
else
|
||||
player = NEW AIPlayerBaka(observer, deckFile, deckFileSmall, "", tempDeck);
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
Player * Rules::initPlayer(GameObserver *g, int playerId)
|
||||
{
|
||||
Player * p = g->players.size() > 1?g->players[playerId]:NULL;
|
||||
@@ -322,6 +476,12 @@ Player * Rules::initPlayer(GameObserver *g, int playerId)
|
||||
return loadPlayerRandom(g, isAI, GAME_TYPE_RANDOM1);
|
||||
case GAME_TYPE_RANDOM2:
|
||||
return loadPlayerRandom(g, isAI, GAME_TYPE_RANDOM2);
|
||||
case GAME_TYPE_RANDOM3:
|
||||
return loadPlayerRandomThree(g, isAI);
|
||||
case GAME_TYPE_RANDOM5:
|
||||
return loadPlayerRandomFive(g, isAI);
|
||||
case GAME_TYPE_HORDE:
|
||||
return loadPlayerHorde(g, isAI);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -627,6 +787,9 @@ GameType Rules::strToGameMode(string s)
|
||||
if (s.compare("momir") == 0) return GAME_TYPE_MOMIR;
|
||||
if (s.compare("random1") == 0) return GAME_TYPE_RANDOM1;
|
||||
if (s.compare("random2") == 0) return GAME_TYPE_RANDOM2;
|
||||
if (s.compare("random3") == 0) return GAME_TYPE_RANDOM3;
|
||||
if (s.compare("random5") == 0) return GAME_TYPE_RANDOM5;
|
||||
if (s.compare("horde") == 0) return GAME_TYPE_HORDE;
|
||||
if (s.compare("story") == 0) return GAME_TYPE_STORY;
|
||||
if (s.compare("stonehewer") == 0) return GAME_TYPE_STONEHEWER;
|
||||
if (s.compare("hermit") == 0) return GAME_TYPE_HERMIT;
|
||||
|
||||
Reference in New Issue
Block a user