taught AI basic attack and block cost.
added functionality to send specific abilities to AI "selectAbility" to have it find mana, targets, and use a selected ability at our command.
This commit is contained in:
@@ -107,7 +107,7 @@ class AIPlayerBaka: public AIPlayer{
|
||||
virtual bool payTheManaCost(ManaCost * cost, MTGCardInstance * card = NULL,vector<MTGAbility*> gotPayment = vector<MTGAbility*>());
|
||||
virtual int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0);
|
||||
virtual ManaCost * getPotentialMana(MTGCardInstance * card = NULL);
|
||||
virtual int selectAbility();
|
||||
virtual int selectAbility(MTGAbility * Specific = NULL);
|
||||
|
||||
public:
|
||||
enum {
|
||||
|
||||
@@ -1369,7 +1369,7 @@ int AIPlayerBaka::selectHintAbility()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AIPlayerBaka::selectAbility()
|
||||
int AIPlayerBaka::selectAbility(MTGAbility * Specific)
|
||||
{
|
||||
if(observer->mExtraPayment && observer->mExtraPayment->source && observer->mExtraPayment->source->controller() == this)
|
||||
{
|
||||
@@ -1410,12 +1410,14 @@ int AIPlayerBaka::selectAbility()
|
||||
for (size_t i = 1; i < observer->mLayers->actionLayer()->mObjects.size(); i++)
|
||||
{ //0 is not a mtgability...hackish
|
||||
MTGAbility * a = ((MTGAbility *) observer->mLayers->actionLayer()->mObjects[i]);
|
||||
if (Specific && Specific != a)
|
||||
continue;
|
||||
//Skip mana abilities for performance
|
||||
if (dynamic_cast<AManaProducer*> (a))
|
||||
continue;
|
||||
//Make sure we can use the ability
|
||||
for (int j = 0; j < game->inPlay->nb_cards; j++)
|
||||
{
|
||||
{//zeth fox: note to self, this is where I can teach it suspend and other cost types.
|
||||
MTGCardInstance * card = game->inPlay->cards[j];
|
||||
if(a->getCost() && !a->isReactingToClick(card, totalPotentialMana))//for performance reason only look for specific mana if the payment couldnt be made with potential.
|
||||
{
|
||||
@@ -1444,7 +1446,32 @@ int AIPlayerBaka::selectAbility()
|
||||
ManaCost * pMana = getPotentialMana(card);
|
||||
pMana->add(this->getManaPool());
|
||||
if (a->isReactingToClick(card, pMana))
|
||||
{
|
||||
createAbilityTargets(a, card, ranking);
|
||||
if (Specific)
|
||||
{
|
||||
if (!Specific->getCost())
|
||||
{
|
||||
//attackcost, blockcost
|
||||
if (a->aType == MTGAbility::ATTACK_COST)
|
||||
{
|
||||
ManaCost * specificCost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL));
|
||||
specificCost->add(0, card->attackCostBackup);
|
||||
abilityPayment = canPayMana(card, specificCost);
|
||||
SAFE_DELETE(specificCost);
|
||||
}
|
||||
else if (a->aType == MTGAbility::BLOCK_COST)
|
||||
{
|
||||
ManaCost * specificCost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL));
|
||||
specificCost->add(0, card->blockCostBackup);
|
||||
abilityPayment = canPayMana(card, specificCost);
|
||||
SAFE_DELETE(specificCost);
|
||||
}
|
||||
}
|
||||
delete (pMana);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete (pMana);
|
||||
}
|
||||
}
|
||||
@@ -1458,6 +1485,8 @@ int AIPlayerBaka::selectAbility()
|
||||
if (!forceBestAbilityUse)
|
||||
chance = 1 + randomGenerator.random() % 100;
|
||||
int actionScore = action.getEfficiency();
|
||||
if (Specific)
|
||||
actionScore = 95;
|
||||
if(action.ability->getCost() && action.ability->getCost()->hasX() && this->game->hand->cards.size())
|
||||
actionScore = actionScore/int(this->game->hand->cards.size());//reduce chance for "x" abilities if cards are in hand.
|
||||
if (actionScore >= chance)
|
||||
@@ -1469,6 +1498,35 @@ int AIPlayerBaka::selectAbility()
|
||||
DebugTrace(" Ai knows exactly what mana to use for this ability.");
|
||||
}
|
||||
DebugTrace("AIPlayer:Using Activated ability");
|
||||
if (Specific)
|
||||
{
|
||||
if (!Specific->getCost())
|
||||
{
|
||||
//attackcost, blockcost
|
||||
if (action.ability->aType == MTGAbility::ATTACK_COST)
|
||||
{
|
||||
ManaCost * specificCost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL));
|
||||
specificCost->add(0, action.click->attackCostBackup);
|
||||
if (payTheManaCost(specificCost, action.click, abilityPayment))
|
||||
clickstream.push(NEW AIAction(action));
|
||||
SAFE_DELETE(specificCost);
|
||||
}
|
||||
else if (action.ability->aType == MTGAbility::BLOCK_COST)
|
||||
{
|
||||
ManaCost * specificCost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL));
|
||||
specificCost->add(0, action.click->blockCostBackup);
|
||||
if (payTheManaCost(specificCost, action.click, abilityPayment))
|
||||
clickstream.push(NEW AIAction(action));
|
||||
SAFE_DELETE(specificCost);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (payTheManaCost(action.ability->getCost(), action.click, abilityPayment))
|
||||
clickstream.push(NEW AIAction(action));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (payTheManaCost(action.ability->getCost(), action.click,abilityPayment))
|
||||
clickstream.push(NEW AIAction(action));
|
||||
}
|
||||
@@ -2625,8 +2683,19 @@ int AIPlayerBaka::chooseAttackers()
|
||||
while ((card = cd.nextmatch(game->inPlay, card)))
|
||||
{
|
||||
if (hints && hints->HintSaysAlwaysAttack(observer, card))
|
||||
{
|
||||
if (!card->isAttacker())
|
||||
{
|
||||
if (card->attackCost)
|
||||
{
|
||||
MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::ATTACK_COST);
|
||||
selectAbility(a);
|
||||
observer->cardClick(card, MTGAbility::ATTACK_COST);
|
||||
}
|
||||
}
|
||||
observer->cardClick(card, MTGAbility::MTG_ATTACK_RULE);
|
||||
}
|
||||
}
|
||||
|
||||
if (attack)
|
||||
{
|
||||
@@ -2639,9 +2708,17 @@ int AIPlayerBaka::chooseAttackers()
|
||||
if(hints && hints->HintSaysDontAttack(observer,card))
|
||||
continue;
|
||||
if (!card->isAttacker())
|
||||
{
|
||||
if (card->attackCost)
|
||||
{
|
||||
MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::ATTACK_COST);
|
||||
selectAbility(a);
|
||||
observer->cardClick(card, MTGAbility::ATTACK_COST);
|
||||
}
|
||||
observer->cardClick(card, MTGAbility::MTG_ATTACK_RULE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2716,6 +2793,12 @@ int AIPlayerBaka::chooseBlockers()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (card->blockCost)
|
||||
{
|
||||
MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::BLOCK_COST);
|
||||
selectAbility(a);
|
||||
observer->cardClick(card, MTGAbility::BLOCK_COST);
|
||||
}
|
||||
observer->cardClick(card, MTGAbility::MTG_BLOCK_RULE);
|
||||
}
|
||||
}
|
||||
@@ -2746,6 +2829,11 @@ int AIPlayerBaka::chooseBlockers()
|
||||
continue;
|
||||
if (!card->defenser)
|
||||
{
|
||||
if (card->blockCost)
|
||||
{
|
||||
MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::BLOCK_COST);
|
||||
selectAbility(a);
|
||||
}
|
||||
observer->cardClick(card, MTGAbility::MTG_BLOCK_RULE);
|
||||
int set = 0;
|
||||
while (!set)
|
||||
@@ -2760,6 +2848,11 @@ int AIPlayerBaka::chooseBlockers()
|
||||
if (opponentsToughness[attacker] <= 0 || (card->toughness <= attacker->power && opponentForce * 2 < life
|
||||
&& !canFirstStrikeKill(card, attacker)) || attacker->nbOpponents() > 1)
|
||||
{
|
||||
if (card->blockCost)
|
||||
{
|
||||
MTGAbility * a = observer->mLayers->actionLayer()->getAbility(MTGAbility::BLOCK_COST);
|
||||
selectAbility(a);
|
||||
}
|
||||
observer->cardClick(card, MTGAbility::MTG_BLOCK_RULE);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1553,7 +1553,7 @@ MTGAttackCostRule::MTGAttackCostRule(GameObserver* observer, int _id) :
|
||||
scost = "Pay to attack";
|
||||
}
|
||||
|
||||
int MTGAttackCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
int MTGAttackCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * aiCheck)
|
||||
{
|
||||
|
||||
if (currentPhase == MTG_PHASE_COMBATATTACKERS && card->controller() == game->currentPlayer && card->controller() == game->currentlyActing())//on my turn and when I am the acting player.
|
||||
@@ -1571,9 +1571,13 @@ int MTGAttackCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
attackcost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
scost = attackcost->getConvertedCost();
|
||||
if (playerMana->canAfford(attackcost))
|
||||
if ((aiCheck && aiCheck->canAfford(attackcost)) || playerMana->canAfford(attackcost))
|
||||
{
|
||||
SAFE_DELETE(attackcost);
|
||||
return 1;
|
||||
}
|
||||
SAFE_DELETE(attackcost);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1588,6 +1592,7 @@ int MTGAttackCostRule::reactToClick(MTGCardInstance * card)
|
||||
playerMana->pay(attackcost);//I think you can't pay partial cost to attack cost so you pay full (508.1i)
|
||||
card->attackCost = 0;
|
||||
card->attackPlaneswalkerCost = 0;
|
||||
SAFE_DELETE(attackcost);
|
||||
return 1;
|
||||
/*
|
||||
508.1g: If any of the chosen creatures require paying costs to attack, the active player determines the total cost to attack.
|
||||
@@ -1622,7 +1627,7 @@ MTGBlockCostRule::MTGBlockCostRule(GameObserver* observer, int _id) :
|
||||
aType = MTGAbility::BLOCK_COST;
|
||||
scost = "Pay to block";
|
||||
}
|
||||
int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * aiCheck)
|
||||
{
|
||||
if (currentPhase == MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting
|
||||
&& card->controller() != game->currentPlayer
|
||||
@@ -1642,9 +1647,13 @@ int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
blockcost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
scost = blockcost->getConvertedCost();
|
||||
if (playerMana->canAfford(blockcost))
|
||||
if ((aiCheck && aiCheck->canAfford(blockcost)) || playerMana->canAfford(blockcost))
|
||||
{
|
||||
SAFE_DELETE(blockcost);
|
||||
return 1;
|
||||
}
|
||||
SAFE_DELETE(blockcost);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1658,6 +1667,7 @@ int MTGBlockCostRule::reactToClick(MTGCardInstance * card)
|
||||
ManaCost * playerMana = player->getManaPool();
|
||||
playerMana->pay(blockcost);//I think you can't pay partial cost to block cost so you pay full (509.1f)
|
||||
card->blockCost = 0;
|
||||
SAFE_DELETE(blockcost);
|
||||
return 1;
|
||||
/*
|
||||
509.1d: If any of the chosen creatures require paying costs to block, the defending player determines the total cost to block.
|
||||
|
||||
Reference in New Issue
Block a user