mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-12 08:48:39 +00:00
Merge branch 'cleanup' into 'master'
Cleanup predictDamageTo See merge request core-developers/forge!5413
This commit is contained in:
@@ -78,7 +78,6 @@ public class AiProfileUtil {
|
||||
|
||||
List<String> lines = FileUtil.readFile(buildFileName(profileName));
|
||||
for (String line : lines) {
|
||||
|
||||
if (line.startsWith("#") || (line.length() == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -576,7 +576,7 @@ public class ComputerUtil {
|
||||
int count = 0;
|
||||
|
||||
while (count < amount) {
|
||||
Card prefCard = ComputerUtil.getCardPreference(ai, source, "SacCost", typeList);
|
||||
Card prefCard = getCardPreference(ai, source, "SacCost", typeList);
|
||||
if (prefCard == null) {
|
||||
prefCard = ComputerUtilCard.getWorstAI(typeList);
|
||||
}
|
||||
@@ -1051,7 +1051,7 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
if (card.isCreature() && !cardState.hasKeyword(Keyword.DEFENDER)
|
||||
&& (cardState.hasKeyword(Keyword.HASTE) || ComputerUtil.hasACardGivingHaste(ai, true) || sa.isDash())) {
|
||||
&& (cardState.hasKeyword(Keyword.HASTE) || hasACardGivingHaste(ai, true) || sa.isDash())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1556,7 +1556,7 @@ public class ComputerUtil {
|
||||
sub = sub.getSubAbility();
|
||||
}
|
||||
if (sa == null || (sa != spell && sa != sub)) {
|
||||
Iterables.addAll(objects, ComputerUtil.predictThreatenedObjects(ai, sa, spell));
|
||||
Iterables.addAll(objects, predictThreatenedObjects(ai, sa, spell));
|
||||
}
|
||||
if (top) {
|
||||
break; // only evaluate top-stack
|
||||
@@ -1892,7 +1892,7 @@ public class ComputerUtil {
|
||||
}
|
||||
}
|
||||
|
||||
Iterables.addAll(threatened, ComputerUtil.predictThreatenedObjects(aiPlayer, saviour, topStack.getSubAbility()));
|
||||
Iterables.addAll(threatened, predictThreatenedObjects(aiPlayer, saviour, topStack.getSubAbility()));
|
||||
return threatened;
|
||||
}
|
||||
|
||||
@@ -1927,7 +1927,7 @@ public class ComputerUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
willDieFromSpell = !noStackCheck && ComputerUtil.predictThreatenedObjects(creature.getController(), excludeSa).contains(creature);
|
||||
willDieFromSpell = !noStackCheck && predictThreatenedObjects(creature.getController(), excludeSa).contains(creature);
|
||||
|
||||
return willDieInCombat || willDieFromSpell;
|
||||
}
|
||||
@@ -1950,7 +1950,7 @@ public class ComputerUtil {
|
||||
List<Card> willBeKilled = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(Card card) {
|
||||
return card.isCreature() && ComputerUtil.predictCreatureWillDieThisTurn(ai, card, excludeSa);
|
||||
return card.isCreature() && predictCreatureWillDieThisTurn(ai, card, excludeSa);
|
||||
}
|
||||
});
|
||||
list.removeAll(willBeKilled);
|
||||
|
||||
@@ -375,13 +375,13 @@ public class ComputerUtilCard {
|
||||
public static Card getBestAI(final Iterable<Card> list) {
|
||||
// Get Best will filter by appropriate getBest list if ALL of the list is of that type
|
||||
if (Iterables.all(list, CardPredicates.Presets.CREATURES)) {
|
||||
return ComputerUtilCard.getBestCreatureAI(list);
|
||||
return getBestCreatureAI(list);
|
||||
}
|
||||
if (Iterables.all(list, CardPredicates.Presets.LANDS)) {
|
||||
return getBestLandAI(list);
|
||||
}
|
||||
// TODO - Once we get an EvaluatePermanent this should call getBestPermanent()
|
||||
return ComputerUtilCard.getMostExpensivePermanentAI(list);
|
||||
return getMostExpensivePermanentAI(list);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -422,7 +422,7 @@ public class ComputerUtilCard {
|
||||
int biggestvalue = -1;
|
||||
|
||||
for (Card card : CardLists.filter(list, CardPredicates.Presets.CREATURES)) {
|
||||
int newvalue = ComputerUtilCard.evaluateCreature(card);
|
||||
int newvalue = evaluateCreature(card);
|
||||
newvalue += card.isToken() ? tokenBonus : 0; // raise the value of tokens
|
||||
|
||||
if (biggestvalue < newvalue) {
|
||||
@@ -453,7 +453,7 @@ public class ComputerUtilCard {
|
||||
* @return a {@link forge.game.card.Card} object.
|
||||
*/
|
||||
public static Card getWorstAI(final Iterable<Card> list) {
|
||||
return ComputerUtilCard.getWorstPermanentAI(list, false, false, false, false);
|
||||
return getWorstPermanentAI(list, false, false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -956,43 +956,43 @@ public class ComputerUtilCard {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
|
||||
if (logic.equals("MostProminentInHumanDeck")) {
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(game.getCardsInGame(), opp), colorChoices));
|
||||
chosen.add(getMostProminentColor(CardLists.filterControlledBy(game.getCardsInGame(), opp), colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerDeck")) {
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(game.getCardsInGame(), ai), colorChoices));
|
||||
chosen.add(getMostProminentColor(CardLists.filterControlledBy(game.getCardsInGame(), ai), colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentDualInComputerDeck")) {
|
||||
List<String> prominence = ComputerUtilCard.getColorByProminence(CardLists.filterControlledBy(game.getCardsInGame(), ai));
|
||||
List<String> prominence = getColorByProminence(CardLists.filterControlledBy(game.getCardsInGame(), ai));
|
||||
chosen.add(prominence.get(0));
|
||||
chosen.add(prominence.get(1));
|
||||
}
|
||||
else if (logic.equals("MostProminentInGame")) {
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(game.getCardsInGame(), colorChoices));
|
||||
chosen.add(getMostProminentColor(game.getCardsInGame(), colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentHumanCreatures")) {
|
||||
CardCollectionView list = opp.getCreaturesInPlay();
|
||||
if (list.isEmpty()) {
|
||||
list = CardLists.filter(CardLists.filterControlledBy(game.getCardsInGame(), opp), CardPredicates.Presets.CREATURES);
|
||||
}
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(list, colorChoices));
|
||||
chosen.add(getMostProminentColor(list, colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentComputerControls")) {
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield), colorChoices));
|
||||
chosen.add(getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield), colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentHumanControls")) {
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(opp.getCardsIn(ZoneType.Battlefield), colorChoices));
|
||||
chosen.add(getMostProminentColor(opp.getCardsIn(ZoneType.Battlefield), colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentPermanent")) {
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(game.getCardsIn(ZoneType.Battlefield), colorChoices));
|
||||
chosen.add(getMostProminentColor(game.getCardsIn(ZoneType.Battlefield), colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentAttackers") && game.getPhaseHandler().inCombat()) {
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(game.getCombat().getAttackers(), colorChoices));
|
||||
chosen.add(getMostProminentColor(game.getCombat().getAttackers(), colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentInActivePlayerHand")) {
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(game.getPhaseHandler().getPlayerTurn().getCardsIn(ZoneType.Hand), colorChoices));
|
||||
chosen.add(getMostProminentColor(game.getPhaseHandler().getPlayerTurn().getCardsIn(ZoneType.Hand), colorChoices));
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerDeckButGreen")) {
|
||||
List<String> prominence = ComputerUtilCard.getColorByProminence(CardLists.filterControlledBy(game.getCardsInGame(), ai));
|
||||
List<String> prominence = getColorByProminence(CardLists.filterControlledBy(game.getCardsInGame(), ai));
|
||||
if (prominence.get(0).equals(MagicColor.Constant.GREEN)) {
|
||||
chosen.add(prominence.get(1));
|
||||
} else {
|
||||
@@ -1097,7 +1097,7 @@ public class ComputerUtilCard {
|
||||
for (Card attacker : currCombat.getAttackersBlockedBy(c)) {
|
||||
if (attacker.getShieldCount() == 0 && ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, currCombat)) {
|
||||
CardCollection blockers = currCombat.getBlockers(attacker);
|
||||
ComputerUtilCard.sortByEvaluateCreature(blockers);
|
||||
sortByEvaluateCreature(blockers);
|
||||
Combat combat = new Combat(ai);
|
||||
combat.addAttacker(attacker, opp);
|
||||
for (Card blocker : blockers) {
|
||||
@@ -1188,7 +1188,7 @@ public class ComputerUtilCard {
|
||||
float threat = 0;
|
||||
if (c.isCreature()) {
|
||||
// the base value for evaluate creature is 100
|
||||
threat += (-1 + 1.0f * ComputerUtilCard.evaluateCreature(c) / 100) / costRemoval;
|
||||
threat += (-1 + 1.0f * evaluateCreature(c) / 100) / costRemoval;
|
||||
if (ai.getLife() > 0 && ComputerUtilCombat.canAttackNextTurn(c)) {
|
||||
Combat combat = game.getCombat();
|
||||
threat += 1.0f * ComputerUtilCombat.damageIfUnblocked(c, opp, combat, true) / ai.getLife();
|
||||
@@ -1335,7 +1335,7 @@ public class ComputerUtilCard {
|
||||
&& phase.isPlayerTurn(ai)
|
||||
&& SpellAbilityAi.isSorcerySpeed(sa) || main1Preferred
|
||||
&& power > 0
|
||||
&& ComputerUtilCard.doesCreatureAttackAI(ai, c)) {
|
||||
&& doesCreatureAttackAI(ai, c)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1360,7 +1360,7 @@ public class ComputerUtilCard {
|
||||
//create and buff attackers
|
||||
if (phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai) && opp.getLife() > 0) {
|
||||
//1. become attacker for whatever reason
|
||||
if (!ComputerUtilCard.doesCreatureAttackAI(ai, c) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||
if (!doesCreatureAttackAI(ai, c) && doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||
float threat = 1.0f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat, true) / opp.getLife();
|
||||
if (CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(pumped)).isEmpty()) {
|
||||
threat *= 2;
|
||||
@@ -1407,7 +1407,7 @@ public class ComputerUtilCard {
|
||||
}
|
||||
}
|
||||
// combat Haste: only grant it if the creature will attack
|
||||
if (ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||
if (doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||
combatChance += 0.5f + (0.5f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat, true) / opp.getLife());
|
||||
}
|
||||
chance += nonCombatChance + combatChance;
|
||||
@@ -1416,7 +1416,7 @@ public class ComputerUtilCard {
|
||||
//3. grant evasive
|
||||
if (!CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(c)).isEmpty()) {
|
||||
if (CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(pumped)).isEmpty()
|
||||
&& ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||
&& doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||
chance += 0.5f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat, true) / opp.getLife();
|
||||
}
|
||||
}
|
||||
@@ -1714,7 +1714,7 @@ public class ComputerUtilCard {
|
||||
}
|
||||
final long timestamp2 = c.getGame().getNextTimestamp(); //is this necessary or can the timestamp be re-used?
|
||||
pumped.addChangedCardKeywordsInternal(toCopy, null, false, false, timestamp2, 0, true);
|
||||
ComputerUtilCard.applyStaticContPT(ai.getGame(), pumped, new CardCollection(c));
|
||||
applyStaticContPT(ai.getGame(), pumped, new CardCollection(c));
|
||||
return pumped;
|
||||
}
|
||||
|
||||
@@ -1794,7 +1794,7 @@ public class ComputerUtilCard {
|
||||
}
|
||||
}
|
||||
if (!threatenedTargets.isEmpty()) {
|
||||
ComputerUtilCard.sortByEvaluateCreature(threatenedTargets);
|
||||
sortByEvaluateCreature(threatenedTargets);
|
||||
for (Card c : threatenedTargets) {
|
||||
if (sa.canAddMoreTarget()) {
|
||||
sa.getTargets().add(c);
|
||||
@@ -1953,7 +1953,7 @@ public class ComputerUtilCard {
|
||||
// A special case which checks that this creature will attack if it's the AI's turn
|
||||
if (needsToPlay.equalsIgnoreCase("WillAttack")) {
|
||||
if (sa != null && game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {
|
||||
return ComputerUtilCard.doesSpecifiedCreatureAttackAI(sa.getActivatingPlayer(), card) ?
|
||||
return doesSpecifiedCreatureAttackAI(sa.getActivatingPlayer(), card) ?
|
||||
AiPlayDecision.WillPlay : AiPlayDecision.BadEtbEffects;
|
||||
} else {
|
||||
return AiPlayDecision.WillPlay; // not our turn, skip this check for the possible Flash use etc.
|
||||
|
||||
@@ -86,7 +86,7 @@ public class ComputerUtilCombat {
|
||||
final Iterable<GameEntity> defenders = CombatUtil.getAllPossibleDefenders(attacker.getController());
|
||||
return Iterables.any(defenders, new Predicate<GameEntity>() {
|
||||
@Override public boolean apply(final GameEntity input) {
|
||||
return ComputerUtilCombat.canAttackNextTurn(attacker, input);
|
||||
return canAttackNextTurn(attacker, input);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -162,7 +162,7 @@ public class ComputerUtilCombat {
|
||||
}
|
||||
});
|
||||
|
||||
return ComputerUtilCombat.totalDamageOfBlockers(attacker, list);
|
||||
return totalDamageOfBlockers(attacker, list);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,9 +212,9 @@ public class ComputerUtilCombat {
|
||||
return 0;
|
||||
}
|
||||
|
||||
damage += ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities);
|
||||
damage += predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities);
|
||||
if (!attacker.hasKeyword(Keyword.INFECT)) {
|
||||
sum = ComputerUtilCombat.predictDamageTo(attacked, damage, attacker, true);
|
||||
sum = predictDamageTo(attacked, damage, attacker, true);
|
||||
if (attacker.hasKeyword(Keyword.DOUBLE_STRIKE)) {
|
||||
sum *= 2;
|
||||
}
|
||||
@@ -237,9 +237,9 @@ public class ComputerUtilCombat {
|
||||
public static int poisonIfUnblocked(final Card attacker, final Player attacked) {
|
||||
int damage = attacker.getNetCombatDamage();
|
||||
int poison = 0;
|
||||
damage += ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, null, null, false);
|
||||
damage += predictPowerBonusOfAttacker(attacker, null, null, false);
|
||||
if (attacker.hasKeyword(Keyword.INFECT)) {
|
||||
int pd = ComputerUtilCombat.predictDamageTo(attacked, damage, attacker, true);
|
||||
int pd = predictDamageTo(attacked, damage, attacker, true);
|
||||
poison += pd;
|
||||
if (attacker.hasKeyword(Keyword.DOUBLE_STRIKE)) {
|
||||
poison += pd;
|
||||
@@ -265,7 +265,7 @@ public class ComputerUtilCombat {
|
||||
public static int sumDamageIfUnblocked(final Iterable<Card> attackers, final Player attacked) {
|
||||
int sum = 0;
|
||||
for (final Card attacker : attackers) {
|
||||
sum += ComputerUtilCombat.damageIfUnblocked(attacker, attacked, null, false);
|
||||
sum += damageIfUnblocked(attacker, attacked, null, false);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
@@ -284,7 +284,7 @@ public class ComputerUtilCombat {
|
||||
public static int sumPoisonIfUnblocked(final List<Card> attackers, final Player attacked) {
|
||||
int sum = 0;
|
||||
for (final Card attacker : attackers) {
|
||||
sum += ComputerUtilCombat.poisonIfUnblocked(attacker, attacked);
|
||||
sum += poisonIfUnblocked(attacker, attacked);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
@@ -313,14 +313,14 @@ public class ComputerUtilCombat {
|
||||
+ "as though it weren't blocked.")) {
|
||||
unblocked.add(attacker);
|
||||
} else if (attacker.hasKeyword(Keyword.TRAMPLE)
|
||||
&& (ComputerUtilCombat.getAttack(attacker) > ComputerUtilCombat.totalShieldDamage(attacker, blockers))) {
|
||||
&& (getAttack(attacker) > totalShieldDamage(attacker, blockers))) {
|
||||
if (!attacker.hasKeyword(Keyword.INFECT)) {
|
||||
damage += ComputerUtilCombat.getAttack(attacker) - ComputerUtilCombat.totalShieldDamage(attacker, blockers);
|
||||
damage += getAttack(attacker) - totalShieldDamage(attacker, blockers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
damage += ComputerUtilCombat.sumDamageIfUnblocked(unblocked, ai);
|
||||
damage += sumDamageIfUnblocked(unblocked, ai);
|
||||
|
||||
if (!ai.canLoseLife()) {
|
||||
damage = 0;
|
||||
@@ -358,9 +358,9 @@ public class ComputerUtilCombat {
|
||||
+ " as though it weren't blocked.")) {
|
||||
unblocked.add(attacker);
|
||||
} else if (attacker.hasKeyword(Keyword.TRAMPLE)
|
||||
&& (ComputerUtilCombat.getAttack(attacker) > ComputerUtilCombat.totalShieldDamage(attacker, blockers))) {
|
||||
&& (getAttack(attacker) > totalShieldDamage(attacker, blockers))) {
|
||||
if (attacker.hasKeyword(Keyword.INFECT)) {
|
||||
poison += ComputerUtilCombat.getAttack(attacker) - ComputerUtilCombat.totalShieldDamage(attacker, blockers);
|
||||
poison += getAttack(attacker) - totalShieldDamage(attacker, blockers);
|
||||
}
|
||||
if (attacker.hasKeyword(Keyword.POISONOUS)) {
|
||||
poison += attacker.getKeywordMagnitude(Keyword.POISONOUS);
|
||||
@@ -368,7 +368,7 @@ public class ComputerUtilCombat {
|
||||
}
|
||||
}
|
||||
|
||||
poison += ComputerUtilCombat.sumPoisonIfUnblocked(unblocked, ai);
|
||||
poison += sumPoisonIfUnblocked(unblocked, ai);
|
||||
|
||||
return ai.getPoisonCounters() + poison;
|
||||
}
|
||||
@@ -456,12 +456,12 @@ public class ComputerUtilCombat {
|
||||
maxTreshold--;
|
||||
}
|
||||
|
||||
if (ComputerUtilCombat.lifeThatWouldRemain(ai, combat) - payment < Math.min(threshold, ai.getLife())
|
||||
if (lifeThatWouldRemain(ai, combat) - payment < Math.min(threshold, ai.getLife())
|
||||
&& !ai.cantLoseForZeroOrLessLife()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (ComputerUtilCombat.resultingPoison(ai, combat) > Math.max(7, ai.getPoisonCounters()));
|
||||
return resultingPoison(ai, combat) > Math.max(7, ai.getPoisonCounters());
|
||||
}
|
||||
|
||||
// Checks if the life of the attacked Player would be reduced
|
||||
@@ -475,7 +475,7 @@ public class ComputerUtilCombat {
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean wouldLoseLife(final Player ai, final Combat combat) {
|
||||
return (ComputerUtilCombat.lifeThatWouldRemain(ai, combat) < ai.getLife());
|
||||
return lifeThatWouldRemain(ai, combat) < ai.getLife();
|
||||
}
|
||||
|
||||
// Checks if the life of the attacked Player/Planeswalker is in danger
|
||||
@@ -497,7 +497,7 @@ public class ComputerUtilCombat {
|
||||
return false;
|
||||
}
|
||||
|
||||
final List<Card> threateningCommanders = ComputerUtilCombat.getLifeThreateningCommanders(ai, combat);
|
||||
final List<Card> threateningCommanders = getLifeThreateningCommanders(ai, combat);
|
||||
|
||||
// check for creatures that must be blocked
|
||||
final List<Card> attackers = combat.getAttackersOf(ai);
|
||||
@@ -515,11 +515,11 @@ public class ComputerUtilCombat {
|
||||
}
|
||||
}
|
||||
|
||||
if (ComputerUtilCombat.lifeThatWouldRemain(ai, combat) - payment < 1 && !ai.cantLoseForZeroOrLessLife()) {
|
||||
if (lifeThatWouldRemain(ai, combat) - payment < 1 && !ai.cantLoseForZeroOrLessLife()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (ComputerUtilCombat.resultingPoison(ai, combat) > 9);
|
||||
return resultingPoison(ai, combat) > 9;
|
||||
}
|
||||
|
||||
|
||||
@@ -543,7 +543,7 @@ public class ComputerUtilCombat {
|
||||
}
|
||||
|
||||
for (final Card defender : defenders) {
|
||||
damage += ComputerUtilCombat.dealsDamageAsBlocker(attacker, defender);
|
||||
damage += dealsDamageAsBlocker(attacker, defender);
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
@@ -561,7 +561,7 @@ public class ComputerUtilCombat {
|
||||
}
|
||||
|
||||
for (final Card defender : defenders) {
|
||||
damage += ComputerUtilCombat.predictDamageByBlockerWithoutDoubleStrike(attacker, defender);
|
||||
damage += predictDamageByBlockerWithoutDoubleStrike(attacker, defender);
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
@@ -620,9 +620,9 @@ public class ComputerUtilCombat {
|
||||
|
||||
int defenderDamage;
|
||||
if (defender.toughnessAssignsDamage()) {
|
||||
defenderDamage = defender.getNetToughness() + ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, defender, true);
|
||||
defenderDamage = defender.getNetToughness() + predictToughnessBonusOfBlocker(attacker, defender, true);
|
||||
} else {
|
||||
defenderDamage = defender.getNetPower() + ComputerUtilCombat.predictPowerBonusOfBlocker(attacker, defender, true);
|
||||
defenderDamage = defender.getNetPower() + predictPowerBonusOfBlocker(attacker, defender, true);
|
||||
}
|
||||
|
||||
// consider static Damage Prevention
|
||||
@@ -646,7 +646,7 @@ public class ComputerUtilCombat {
|
||||
int defenderDefense = 0;
|
||||
|
||||
for (final Card defender : defenders) {
|
||||
defenderDefense += ComputerUtilCombat.shieldDamage(attacker, defender);
|
||||
defenderDefense += shieldDamage(attacker, defender);
|
||||
}
|
||||
|
||||
return defenderDefense;
|
||||
@@ -666,7 +666,7 @@ public class ComputerUtilCombat {
|
||||
* @return a int.
|
||||
*/
|
||||
public static int shieldDamage(final Card attacker, final Card blocker) {
|
||||
if (ComputerUtilCombat.canDestroyBlockerBeforeFirstStrike(blocker, attacker, false)) {
|
||||
if (canDestroyBlockerBeforeFirstStrike(blocker, attacker, false)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -705,10 +705,10 @@ public class ComputerUtilCombat {
|
||||
*/
|
||||
public static boolean combatantWouldBeDestroyed(Player ai, final Card combatant, Combat combat) {
|
||||
if (combat.isAttacking(combatant)) {
|
||||
return ComputerUtilCombat.attackerWouldBeDestroyed(ai, combatant, combat);
|
||||
return attackerWouldBeDestroyed(ai, combatant, combat);
|
||||
}
|
||||
if (combat.isBlocking(combatant)) {
|
||||
return ComputerUtilCombat.blockerWouldBeDestroyed(ai, combatant, combat);
|
||||
return blockerWouldBeDestroyed(ai, combatant, combat);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -729,7 +729,7 @@ public class ComputerUtilCombat {
|
||||
int firstStrikeBlockerDmg = 0;
|
||||
|
||||
for (final Card defender : blockers) {
|
||||
if (ComputerUtilCombat.canDestroyAttacker(ai, attacker, defender, combat, true)
|
||||
if (canDestroyAttacker(ai, attacker, defender, combat, true)
|
||||
&& !(defender.hasKeyword(Keyword.WITHER) || defender.hasKeyword(Keyword.INFECT))) {
|
||||
return true;
|
||||
}
|
||||
@@ -740,10 +740,10 @@ public class ComputerUtilCombat {
|
||||
|
||||
// Consider first strike and double strike
|
||||
if (attacker.hasKeyword(Keyword.FIRST_STRIKE) || attacker.hasKeyword(Keyword.DOUBLE_STRIKE)) {
|
||||
return firstStrikeBlockerDmg >= ComputerUtilCombat.getDamageToKill(attacker);
|
||||
return firstStrikeBlockerDmg >= getDamageToKill(attacker);
|
||||
}
|
||||
|
||||
return ComputerUtilCombat.totalDamageOfBlockers(attacker, blockers) >= ComputerUtilCombat.getDamageToKill(attacker);
|
||||
return totalDamageOfBlockers(attacker, blockers) >= getDamageToKill(attacker);
|
||||
}
|
||||
|
||||
// Will this trigger trigger?
|
||||
@@ -956,7 +956,7 @@ public class ComputerUtilCombat {
|
||||
for (final Trigger trigger : theTriggers) {
|
||||
final Card source = trigger.getHostCard();
|
||||
|
||||
if (!ComputerUtilCombat.combatTriggerWillTrigger(attacker, blocker, trigger, null)) {
|
||||
if (!combatTriggerWillTrigger(attacker, blocker, trigger, null)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1074,7 +1074,7 @@ public class ComputerUtilCombat {
|
||||
for (final Trigger trigger : theTriggers) {
|
||||
final Card source = trigger.getHostCard();
|
||||
|
||||
if (!ComputerUtilCombat.combatTriggerWillTrigger(attacker, blocker, trigger, null)) {
|
||||
if (!combatTriggerWillTrigger(attacker, blocker, trigger, null)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1089,7 +1089,7 @@ public class ComputerUtilCombat {
|
||||
continue;
|
||||
}
|
||||
int damage = AbilityUtils.calculateAmount(source, sa.getParam("NumDmg"), sa);
|
||||
toughness -= predictDamageTo(blocker, damage, 0, source, false);
|
||||
toughness -= predictDamageTo(blocker, damage, source, false);
|
||||
} else
|
||||
|
||||
// -1/-1 PutCounter triggers
|
||||
@@ -1216,9 +1216,9 @@ public class ComputerUtilCombat {
|
||||
// if the defender has first strike and wither the attacker will deal
|
||||
// less damage than expected
|
||||
if (null != blocker) {
|
||||
if (ComputerUtilCombat.dealsFirstStrikeDamage(blocker, withoutAbilities, combat)
|
||||
if (dealsFirstStrikeDamage(blocker, withoutAbilities, combat)
|
||||
&& (blocker.hasKeyword(Keyword.WITHER) || blocker.hasKeyword(Keyword.INFECT))
|
||||
&& !ComputerUtilCombat.dealsFirstStrikeDamage(attacker, withoutAbilities, combat)
|
||||
&& !dealsFirstStrikeDamage(attacker, withoutAbilities, combat)
|
||||
&& !attacker.canReceiveCounters(CounterEnumType.M1M1)) {
|
||||
power -= blocker.getNetCombatDamage();
|
||||
}
|
||||
@@ -1250,7 +1250,7 @@ public class ComputerUtilCombat {
|
||||
for (final Trigger trigger : theTriggers) {
|
||||
final Card source = trigger.getHostCard();
|
||||
|
||||
if (!ComputerUtilCombat.combatTriggerWillTrigger(attacker, blocker, trigger, combat)) {
|
||||
if (!combatTriggerWillTrigger(attacker, blocker, trigger, combat)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1451,7 +1451,7 @@ public class ComputerUtilCombat {
|
||||
for (final Trigger trigger : theTriggers) {
|
||||
final Card source = trigger.getHostCard();
|
||||
|
||||
if (!ComputerUtilCombat.combatTriggerWillTrigger(attacker, blocker, trigger, combat)) {
|
||||
if (!combatTriggerWillTrigger(attacker, blocker, trigger, combat)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1472,7 +1472,7 @@ public class ComputerUtilCombat {
|
||||
}
|
||||
int damage = AbilityUtils.calculateAmount(source, sa.getParam("NumDmg"), sa);
|
||||
|
||||
toughness -= predictDamageTo(attacker, damage, 0, source, false);
|
||||
toughness -= predictDamageTo(attacker, damage, source, false);
|
||||
continue;
|
||||
} else if (ApiType.Pump.equals(sa.getApi())) {
|
||||
if (sa.hasParam("Cost")) {
|
||||
@@ -1600,8 +1600,8 @@ public class ComputerUtilCombat {
|
||||
}
|
||||
|
||||
//Check triggers that deal damage or shrink the attacker
|
||||
if (ComputerUtilCombat.getDamageToKill(attacker)
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities) <= 0) {
|
||||
if (getDamageToKill(attacker)
|
||||
+ predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities) <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1613,7 +1613,7 @@ public class ComputerUtilCombat {
|
||||
for (Trigger trigger : theTriggers) {
|
||||
final Card source = trigger.getHostCard();
|
||||
|
||||
if (!ComputerUtilCombat.combatTriggerWillTrigger(attacker, blocker, trigger, null)) {
|
||||
if (!combatTriggerWillTrigger(attacker, blocker, trigger, null)) {
|
||||
continue;
|
||||
}
|
||||
SpellAbility sa = trigger.ensureAbility();
|
||||
@@ -1735,17 +1735,17 @@ public class ComputerUtilCombat {
|
||||
int attackerDamage;
|
||||
if (blocker.toughnessAssignsDamage()) {
|
||||
defenderDamage = blocker.getNetToughness()
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
+ predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
} else {
|
||||
defenderDamage = blocker.getNetPower()
|
||||
+ ComputerUtilCombat.predictPowerBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
+ predictPowerBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
}
|
||||
if (attacker.toughnessAssignsDamage()) {
|
||||
attackerDamage = attacker.getNetToughness()
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
+ predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
} else {
|
||||
attackerDamage = attacker.getNetPower()
|
||||
+ ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
+ predictPowerBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
}
|
||||
|
||||
int possibleDefenderPrevention = 0;
|
||||
@@ -1762,10 +1762,10 @@ public class ComputerUtilCombat {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int defenderLife = ComputerUtilCombat.getDamageToKill(blocker)
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
final int attackerLife = ComputerUtilCombat.getDamageToKill(attacker)
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
final int defenderLife = getDamageToKill(blocker)
|
||||
+ predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
final int attackerLife = getDamageToKill(attacker)
|
||||
+ predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
|
||||
if (blocker.hasKeyword(Keyword.DOUBLE_STRIKE)) {
|
||||
if (defenderDamage > 0 && (hasKeyword(blocker, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) {
|
||||
@@ -1832,7 +1832,7 @@ public class ComputerUtilCombat {
|
||||
final List<Card> attackers = combat.getAttackersBlockedBy(blocker);
|
||||
|
||||
for (Card attacker : attackers) {
|
||||
if (ComputerUtilCombat.canDestroyBlocker(ai, blocker, attacker, combat, true)
|
||||
if (canDestroyBlocker(ai, blocker, attacker, combat, true)
|
||||
&& !(attacker.hasKeyword(Keyword.WITHER) || attacker.hasKeyword(Keyword.INFECT))) {
|
||||
return true;
|
||||
}
|
||||
@@ -1856,7 +1856,7 @@ public class ComputerUtilCombat {
|
||||
if (flankingMagnitude >= blocker.getNetToughness()) {
|
||||
return true;
|
||||
}
|
||||
if ((flankingMagnitude >= ComputerUtilCombat.getDamageToKill(blocker))
|
||||
if ((flankingMagnitude >= getDamageToKill(blocker))
|
||||
&& !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1867,8 +1867,8 @@ public class ComputerUtilCombat {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ComputerUtilCombat.getDamageToKill(blocker)
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities) <= 0) {
|
||||
if (getDamageToKill(blocker)
|
||||
+ predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities) <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1880,7 +1880,7 @@ public class ComputerUtilCombat {
|
||||
for (Trigger trigger : theTriggers) {
|
||||
final Card source = trigger.getHostCard();
|
||||
|
||||
if (!ComputerUtilCombat.combatTriggerWillTrigger(attacker, blocker, trigger, null)) {
|
||||
if (!combatTriggerWillTrigger(attacker, blocker, trigger, null)) {
|
||||
continue;
|
||||
}
|
||||
SpellAbility sa = trigger.ensureAbility();
|
||||
@@ -1956,17 +1956,17 @@ public class ComputerUtilCombat {
|
||||
int attackerDamage;
|
||||
if (blocker.toughnessAssignsDamage()) {
|
||||
defenderDamage = blocker.getNetToughness()
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
+ predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
} else {
|
||||
defenderDamage = blocker.getNetPower()
|
||||
+ ComputerUtilCombat.predictPowerBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
+ predictPowerBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
}
|
||||
if (attacker.toughnessAssignsDamage()) {
|
||||
attackerDamage = attacker.getNetToughness()
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
+ predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
} else {
|
||||
attackerDamage = attacker.getNetPower()
|
||||
+ ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
+ predictPowerBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
}
|
||||
|
||||
int possibleDefenderPrevention = 0;
|
||||
@@ -1991,15 +1991,15 @@ public class ComputerUtilCombat {
|
||||
if (combat != null) {
|
||||
for (Card atkr : combat.getAttackersBlockedBy(blocker)) {
|
||||
if (!atkr.equals(attacker)) {
|
||||
attackerDamage += predictDamageTo(blocker, atkr.getNetCombatDamage(), 0, atkr, true);
|
||||
attackerDamage += predictDamageTo(blocker, atkr.getNetCombatDamage(), atkr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int defenderLife = ComputerUtilCombat.getDamageToKill(blocker)
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
final int attackerLife = ComputerUtilCombat.getDamageToKill(attacker)
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
final int defenderLife = getDamageToKill(blocker)
|
||||
+ predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
|
||||
final int attackerLife = getDamageToKill(attacker)
|
||||
+ predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities, withoutAttackerStaticAbilities);
|
||||
|
||||
if (attacker.hasKeyword(Keyword.DOUBLE_STRIKE)) {
|
||||
if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || blocker.hasSVar("DestroyWhenDamaged"))) {
|
||||
@@ -2082,8 +2082,7 @@ public class ComputerUtilCombat {
|
||||
|
||||
// trample
|
||||
if (hasTrample) {
|
||||
|
||||
int dmgToKill = ComputerUtilCombat.getEnoughDamageToKill(blocker, dmgCanDeal, attacker, true);
|
||||
int dmgToKill = getEnoughDamageToKill(blocker, dmgCanDeal, attacker, true);
|
||||
|
||||
if (dmgCanDeal < dmgToKill) {
|
||||
dmgToKill = Math.min(blocker.getLethalDamage(), dmgCanDeal);
|
||||
@@ -2113,7 +2112,7 @@ public class ComputerUtilCombat {
|
||||
Card lastBlocker = null;
|
||||
for (final Card b : block) {
|
||||
lastBlocker = b;
|
||||
final int dmgToKill = ComputerUtilCombat.getEnoughDamageToKill(b, dmgCanDeal, attacker, true);
|
||||
final int dmgToKill = getEnoughDamageToKill(b, dmgCanDeal, attacker, true);
|
||||
if (dmgToKill <= dmgCanDeal) {
|
||||
damageMap.put(b, dmgToKill);
|
||||
dmgCanDeal -= dmgToKill;
|
||||
@@ -2175,7 +2174,7 @@ public class ComputerUtilCombat {
|
||||
*/
|
||||
public static final int getEnoughDamageToKill(final Card c, final int maxDamage, final Card source, final boolean isCombat,
|
||||
final boolean noPrevention) {
|
||||
final int killDamage = c.isPlaneswalker() ? c.getCurrentLoyalty() : ComputerUtilCombat.getDamageToKill(c);
|
||||
final int killDamage = c.isPlaneswalker() ? c.getCurrentLoyalty() : getDamageToKill(c);
|
||||
|
||||
if (c.hasKeyword(Keyword.INDESTRUCTIBLE) || c.getShieldCount() > 0) {
|
||||
if (!(source.hasKeyword(Keyword.WITHER) || source.hasKeyword(Keyword.INFECT))) {
|
||||
@@ -2241,70 +2240,10 @@ public class ComputerUtilCombat {
|
||||
* a boolean.
|
||||
* @return a int.
|
||||
*/
|
||||
|
||||
public final static int predictDamageTo(final Player target, final int damage, final Card source, final boolean isCombat) {
|
||||
final Game game = target.getGame();
|
||||
int restDamage = damage;
|
||||
|
||||
restDamage = target.staticReplaceDamage(restDamage, source, isCombat);
|
||||
|
||||
// Predict replacement effects
|
||||
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
|
||||
for (final ReplacementEffect re : ca.getReplacementEffects()) {
|
||||
if (!re.getMode().equals(ReplacementType.DamageDone) ||
|
||||
(!re.hasParam("PreventionEffect") && !re.hasParam("Prevent"))) {
|
||||
continue;
|
||||
}
|
||||
// Immortal Coil prevents the damage but has a similar negative effect
|
||||
if ("Immortal Coil".equals(ca.getName())) {
|
||||
continue;
|
||||
}
|
||||
if (!re.matchesValidParam("ValidSource", source)) {
|
||||
continue;
|
||||
}
|
||||
if (!re.matchesValidParam("ValidTarget", target)) {
|
||||
continue;
|
||||
}
|
||||
if (re.hasParam("IsCombat")) {
|
||||
if (re.getParam("IsCombat").equals("True") != isCombat) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (re.hasParam("Prevent")) {
|
||||
return 0;
|
||||
} else if (re.getOverridingAbility() != null) {
|
||||
SpellAbility repSA = re.getOverridingAbility();
|
||||
if (repSA.getApi() == ApiType.ReplaceDamage) {
|
||||
return Math.max(0, restDamage - AbilityUtils.calculateAmount(ca, repSA.getParam("Amount"), repSA));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
restDamage = target.staticDamagePrevention(restDamage, 0, source, isCombat);
|
||||
|
||||
return restDamage;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* predictDamage.
|
||||
* </p>
|
||||
*
|
||||
* @param damage
|
||||
* a int.
|
||||
* @param source
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* @param isCombat
|
||||
* a boolean.
|
||||
* @return a int.
|
||||
*/
|
||||
public final static int predictDamageTo(final Card target, final int damage, final Card source, final boolean isCombat) {
|
||||
public final static int predictDamageTo(final GameEntity target, final int damage, final Card source, final boolean isCombat) {
|
||||
return predictDamageTo(target, damage, 0, source, isCombat);
|
||||
}
|
||||
|
||||
|
||||
// This function helps the AI calculate the actual amount of damage an
|
||||
// effect would deal
|
||||
/**
|
||||
@@ -2322,7 +2261,7 @@ public class ComputerUtilCombat {
|
||||
* a boolean.
|
||||
* @return a int.
|
||||
*/
|
||||
public final static int predictDamageTo(final Card target, final int damage, final int possiblePrevention, final Card source, final boolean isCombat) {
|
||||
public final static int predictDamageTo(final GameEntity target, final int damage, final int possiblePrevention, final Card source, final boolean isCombat) {
|
||||
int restDamage = damage;
|
||||
|
||||
restDamage = target.staticReplaceDamage(restDamage, source, isCombat);
|
||||
@@ -2529,13 +2468,13 @@ public class ComputerUtilCombat {
|
||||
|
||||
if (combat.isBlocked(c)) {
|
||||
for (Card blk : combat.getBlockers(c)) {
|
||||
if (ComputerUtilCombat.blockerWouldBeDestroyed(ai, blk, combat)) {
|
||||
if (blockerWouldBeDestroyed(ai, blk, combat)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (combat.isBlocking(c)) {
|
||||
for (Card atk : combat.getAttackersBlockedBy(c)) {
|
||||
if (ComputerUtilCombat.attackerWouldBeDestroyed(ai, atk, combat)) {
|
||||
if (attackerWouldBeDestroyed(ai, atk, combat)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class ComputerUtilMana {
|
||||
return payManaCost(sa, ai, false, 0, true);
|
||||
}
|
||||
private static boolean payManaCost(final SpellAbility sa, final Player ai, final boolean test, final int extraMana, boolean checkPlayable) {
|
||||
ManaCostBeingPaid cost = ComputerUtilMana.calculateManaCost(sa, test, extraMana);
|
||||
ManaCostBeingPaid cost = calculateManaCost(sa, test, extraMana);
|
||||
return payManaCost(cost, sa, ai, test, checkPlayable);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public class ComputerUtilMana {
|
||||
* Return the number of colors used for payment for Converge
|
||||
*/
|
||||
public static int getConvergeCount(final SpellAbility sa, final Player ai) {
|
||||
ManaCostBeingPaid cost = ComputerUtilMana.calculateManaCost(sa, true, 0);
|
||||
ManaCostBeingPaid cost = calculateManaCost(sa, true, 0);
|
||||
if (payManaCost(cost, sa, ai, true, true)) {
|
||||
return cost.getSunburst();
|
||||
}
|
||||
@@ -608,7 +608,7 @@ public class ComputerUtilMana {
|
||||
}
|
||||
|
||||
// arrange all mana abilities by color produced.
|
||||
final ListMultimap<Integer, SpellAbility> manaAbilityMap = ComputerUtilMana.groupSourcesByManaColor(ai, true);
|
||||
final ListMultimap<Integer, SpellAbility> manaAbilityMap = groupSourcesByManaColor(ai, true);
|
||||
if (manaAbilityMap.isEmpty()) {
|
||||
refundMana(manaSpentToPay, ai, sa);
|
||||
|
||||
@@ -617,7 +617,7 @@ public class ComputerUtilMana {
|
||||
}
|
||||
|
||||
// select which abilities may be used for each shard
|
||||
Multimap<ManaCostShard, SpellAbility> sourcesForShards = ComputerUtilMana.groupAndOrderToPayShards(ai, manaAbilityMap, cost);
|
||||
Multimap<ManaCostShard, SpellAbility> sourcesForShards = groupAndOrderToPayShards(ai, manaAbilityMap, cost);
|
||||
|
||||
sortManaAbilities(sourcesForShards, sa);
|
||||
|
||||
@@ -919,7 +919,7 @@ public class ComputerUtilMana {
|
||||
final SpellAbility sa, final Player ai, final boolean test, final boolean checkPlayable,
|
||||
List<Mana> manaSpentToPay, final boolean hasConverge, final boolean ignoreColor, final boolean ignoreType) {
|
||||
// arrange all mana abilities by color produced.
|
||||
final ListMultimap<Integer, SpellAbility> manaAbilityMap = ComputerUtilMana.groupSourcesByManaColor(ai, checkPlayable);
|
||||
final ListMultimap<Integer, SpellAbility> manaAbilityMap = groupSourcesByManaColor(ai, checkPlayable);
|
||||
if (manaAbilityMap.isEmpty()) {
|
||||
// no mana abilities, bailing out
|
||||
refundMana(manaSpentToPay, ai, sa);
|
||||
@@ -931,7 +931,7 @@ public class ComputerUtilMana {
|
||||
}
|
||||
|
||||
// select which abilities may be used for each shard
|
||||
ListMultimap<ManaCostShard, SpellAbility> sourcesForShards = ComputerUtilMana.groupAndOrderToPayShards(ai, manaAbilityMap, cost);
|
||||
ListMultimap<ManaCostShard, SpellAbility> sourcesForShards = groupAndOrderToPayShards(ai, manaAbilityMap, cost);
|
||||
if (hasConverge) {
|
||||
// add extra colors for paying converge
|
||||
final int unpaidColors = cost.getUnpaidColors() + cost.getColorsPaid() ^ ManaCostShard.COLORS_SUPERPOSITION;
|
||||
@@ -1540,7 +1540,7 @@ public class ComputerUtilMana {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
mCost = ManaCost.combine(mCost, mkCost);
|
||||
ManaCostBeingPaid mcbp = new ManaCostBeingPaid(mCost);
|
||||
if (!ComputerUtilMana.canPayManaCost(mcbp, sa, sa.getActivatingPlayer())) {
|
||||
if (!canPayManaCost(mcbp, sa, sa.getActivatingPlayer())) {
|
||||
sa.getHostCard().setSVar("NumTimes", "Number$" + i);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ public class CreatureEvaluator implements Function<Card, Integer> {
|
||||
public int evaluateCreature(final Card c) {
|
||||
return evaluateCreature(c, true, true);
|
||||
}
|
||||
|
||||
public int evaluateCreature(final Card c, final boolean considerPT, final boolean considerCMC) {
|
||||
int value = 80;
|
||||
if (!c.isToken()) {
|
||||
|
||||
@@ -157,7 +157,7 @@ public class DamageAllAi extends SpellAbilityAi {
|
||||
// || (ai.sa.getPayCosts(). ??? )
|
||||
{
|
||||
// would take zero damage, and hurt opponent, do it!
|
||||
if (ComputerUtilCombat.predictDamageTo(ai, dmg, source, false)<1) {
|
||||
if (ComputerUtilCombat.predictDamageTo(ai, dmg, source, false) < 1) {
|
||||
return 1;
|
||||
}
|
||||
// enemy is expected to die faster than AI from damage if repeated
|
||||
|
||||
@@ -70,7 +70,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
|
||||
// This should be also usable by the AI to forecast an effect (so it must
|
||||
// not change the game state)
|
||||
public int staticDamagePrevention(final int damage, final int possiblePrevention, final Card source, final boolean isCombat) {
|
||||
public int staticDamagePrevention(int damage, final int possiblePrevention, final Card source, final boolean isCombat) {
|
||||
if (damage <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -88,6 +88,10 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
(!re.hasParam("PreventionEffect") && !re.hasParam("Prevent"))) {
|
||||
continue;
|
||||
}
|
||||
// Immortal Coil prevents the damage but has a similar negative effect
|
||||
if ("Immortal Coil".equals(ca.getName())) {
|
||||
continue;
|
||||
}
|
||||
if (!re.matchesValidParam("ValidSource", source)) {
|
||||
continue;
|
||||
}
|
||||
@@ -104,10 +108,11 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
} else if (re.getOverridingAbility() != null) {
|
||||
SpellAbility repSA = re.getOverridingAbility();
|
||||
if (repSA.getApi() == ApiType.ReplaceDamage) {
|
||||
return Math.max(0, damage - AbilityUtils.calculateAmount(ca, repSA.getParam("Amount"), repSA));
|
||||
damage = Math.max(0, damage - AbilityUtils.calculateAmount(ca, repSA.getParam("Amount"), repSA));
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5239,13 +5239,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
} else if (c.getName().equals("Furnace of Rath")) {
|
||||
if (isCreature()) {
|
||||
restDamage += restDamage;
|
||||
restDamage *= 2;
|
||||
}
|
||||
} else if (c.getName().equals("Dictate of the Twin Gods")) {
|
||||
restDamage += restDamage;
|
||||
} else if (c.getName().equals("Gratuitous Violence")) {
|
||||
if (c.getController().equals(source.getController()) && source.isCreature() && isCreature()) {
|
||||
restDamage += restDamage;
|
||||
restDamage *= 2;
|
||||
}
|
||||
} else if (c.getName().equals("Fire Servant")) {
|
||||
if (c.getController().equals(source.getController()) && source.isRed()
|
||||
@@ -5419,7 +5419,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
return (c != null ? c.getImageKey() : "");
|
||||
}
|
||||
|
||||
|
||||
public final boolean isTributed() { return tributed; }
|
||||
|
||||
public final void setTributed(final boolean b) {
|
||||
|
||||
@@ -742,10 +742,10 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
restDamage += 2;
|
||||
}
|
||||
} else if (c.getName().equals("Furnace of Rath") || c.getName().equals("Dictate of the Twin Gods")) {
|
||||
restDamage += restDamage;
|
||||
restDamage *= 2;
|
||||
} else if (c.getName().equals("Gratuitous Violence")) {
|
||||
if (c.getController().equals(source.getController()) && source.isCreature()) {
|
||||
restDamage += restDamage;
|
||||
restDamage *= 2;
|
||||
}
|
||||
} else if (c.getName().equals("Fire Servant")) {
|
||||
if (c.getController().equals(source.getController()) && source.isRed()
|
||||
|
||||
@@ -139,7 +139,6 @@ public class ReplaceDamage extends ReplacementEffect {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
|
||||
@@ -66,8 +66,6 @@ public class ReplaceDraw extends ReplacementEffect {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
|
||||
@@ -61,8 +61,6 @@ public class ReplaceDrawCards extends ReplacementEffect {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
|
||||
@@ -51,8 +51,6 @@ public class ReplaceMill extends ReplacementEffect {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user