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