- Fixed logic in reserving mana for combat tricks.

This commit is contained in:
Agetian
2018-11-11 17:38:32 +03:00
parent 829a82b98f
commit fcc3a28b86
3 changed files with 23 additions and 10 deletions

View File

@@ -628,16 +628,19 @@ public class AiController {
return null; return null;
} }
public void reserveManaSources(SpellAbility sa) { public boolean reserveManaSources(SpellAbility sa) {
reserveManaSources(sa, PhaseType.MAIN2, false); return reserveManaSources(sa, PhaseType.MAIN2, false);
} }
public void reserveManaSources(SpellAbility sa, PhaseType phaseType, boolean enemy) { public boolean reserveManaSources(SpellAbility sa, PhaseType phaseType, boolean enemy) {
ManaCostBeingPaid cost = ComputerUtilMana.calculateManaCost(sa, true, 0); ManaCostBeingPaid cost = ComputerUtilMana.calculateManaCost(sa, true, 0);
CardCollection manaSources = ComputerUtilMana.getManaSourcesToPayCost(cost, sa, player); CardCollection manaSources = ComputerUtilMana.getManaSourcesToPayCost(cost, sa, player);
AiCardMemory.MemorySet memSet; if (manaSources.isEmpty()) {
return false;
}
AiCardMemory.MemorySet memSet;
switch (phaseType) { switch (phaseType) {
case MAIN2: case MAIN2:
memSet = AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2; memSet = AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2;
@@ -656,6 +659,10 @@ public class AiController {
for (Card c : manaSources) { for (Card c : manaSources) {
AiCardMemory.rememberCard(player, c, memSet); AiCardMemory.rememberCard(player, c, memSet);
} }
// This is a simplification, since one mana source can produce more than one mana,
// but should work in most circumstances to ensure safety in whatever the AI is using this for.
return manaSources.size() >= cost.getConvertedManaCost();
} }
// This is for playing spells regularly (no Cascade/Ripple etc.) // This is for playing spells regularly (no Cascade/Ripple etc.)

View File

@@ -1508,14 +1508,18 @@ public class ComputerUtilCard {
// Attempt to hold combat tricks until blockers are declared, and try to lure the opponent into blocking // Attempt to hold combat tricks until blockers are declared, and try to lure the opponent into blocking
// (The AI will only do it for one attacker at the moment, otherwise it risks running his attackers into // (The AI will only do it for one attacker at the moment, otherwise it risks running his attackers into
// an army of opposing blockers with only one combat trick in hand) // an army of opposing blockers with only one combat trick in hand)
AiCardMemory.rememberCard(ai, c, AiCardMemory.MemorySet.MANDATORY_ATTACKERS);
AiCardMemory.rememberCard(ai, c, AiCardMemory.MemorySet.TRICK_ATTACKERS);
// Reserve the mana until Declare Blockers such that the AI doesn't tap out before having a chance to use // Reserve the mana until Declare Blockers such that the AI doesn't tap out before having a chance to use
// the combat trick // the combat trick
boolean reserved = false;
if (ai.getController().isAI()) { if (ai.getController().isAI()) {
((PlayerControllerAi) ai.getController()).getAi().reserveManaSources(sa, PhaseType.COMBAT_DECLARE_BLOCKERS, false); reserved = ((PlayerControllerAi) ai.getController()).getAi().reserveManaSources(sa, PhaseType.COMBAT_DECLARE_BLOCKERS, false);
} // Only proceed with this if we could actually reserve mana
if (reserved) {
AiCardMemory.rememberCard(ai, c, AiCardMemory.MemorySet.MANDATORY_ATTACKERS);
AiCardMemory.rememberCard(ai, c, AiCardMemory.MemorySet.TRICK_ATTACKERS);
return false; return false;
}
}
} else { } else {
// Don't try to mix "lure" and "precast" paradigms for combat tricks, since that creates issues with // Don't try to mix "lure" and "precast" paradigms for combat tricks, since that creates issues with
// the AI overextending the attack // the AI overextending the attack

View File

@@ -45,9 +45,11 @@ public class FogAi extends SpellAbilityAi {
|| (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS))) || (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)))
&& (AiCardMemory.isMemorySetEmpty(ai, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT)) && (AiCardMemory.isMemorySetEmpty(ai, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT))
&& (ComputerUtil.aiLifeInDanger(ai, false, 0))) { && (ComputerUtil.aiLifeInDanger(ai, false, 0))) {
((PlayerControllerAi) ai.getController()).getAi().reserveManaSources(sa, PhaseType.COMBAT_DECLARE_BLOCKERS, true); boolean reserved = ((PlayerControllerAi) ai.getController()).getAi().reserveManaSources(sa, PhaseType.COMBAT_DECLARE_BLOCKERS, true);
if (reserved) {
AiCardMemory.rememberCard(ai, hostCard, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT); AiCardMemory.rememberCard(ai, hostCard, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT);
} }
}
// AI should only activate this during Human's Declare Blockers phase // AI should only activate this during Human's Declare Blockers phase
if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) { if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {