Card: add Keyword methods that work with Keyword Enum

This commit is contained in:
Hanmac
2018-05-06 16:54:53 +02:00
parent e0b1bc7cd0
commit 91d80f49f4
21 changed files with 249 additions and 164 deletions

View File

@@ -358,7 +358,7 @@ public class AiAttackController {
// In addition, if the computer guesses it needs no blockers, make sure
// that
// it won't be surprised by Exalted
final int humanExaltedBonus = countExaltedBonus(opp);
final int humanExaltedBonus = opp.countExaltedBonus();
if (humanExaltedBonus > 0) {
final boolean finestHour = opp.isCardInPlay("Finest Hour");
@@ -1049,24 +1049,6 @@ public class AiAttackController {
}
} // getAttackers()
/**
* <p>
* countExaltedBonus.
* </p>
*
* @param player
* a {@link forge.game.player.Player} object.
* @return a int.
*/
public final static int countExaltedBonus(final Player player) {
int bonus = 0;
for (Card c : player.getCardsIn(ZoneType.Battlefield)) {
bonus += c.getAmountOfKeyword("Exalted");
}
return bonus;
}
/**
* <p>
* getAttack.

View File

@@ -36,6 +36,7 @@ import forge.game.card.*;
import forge.game.combat.Combat;
import forge.game.combat.CombatUtil;
import forge.game.cost.CostPayment;
import forge.game.keyword.Keyword;
import forge.game.keyword.KeywordInterface;
import forge.game.phase.Untap;
import forge.game.player.Player;
@@ -226,14 +227,15 @@ public class ComputerUtilCombat {
int damage = attacker.getNetCombatDamage();
int poison = 0;
damage += ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, null, null, false);
if (attacker.hasKeyword("Infect")) {
poison += ComputerUtilCombat.predictDamageTo(attacked, damage, attacker, true);
if (attacker.hasKeyword("Double Strike")) {
poison += ComputerUtilCombat.predictDamageTo(attacked, damage, attacker, true);
if (attacker.hasKeyword(Keyword.INFECT)) {
int pd = ComputerUtilCombat.predictDamageTo(attacked, damage, attacker, true);
poison += pd;
if (attacker.hasKeyword(Keyword.DOUBLE_STRIKE)) {
poison += pd;
}
}
if (attacker.hasKeyword("Poisonous") && (damage > 0)) {
poison += attacker.getKeywordMagnitude("Poisonous");
if (attacker.hasKeyword(Keyword.POISONOUS) && (damage > 0)) {
poison += attacker.getKeywordMagnitude(Keyword.POISONOUS);
}
return poison;
}
@@ -343,13 +345,13 @@ public class ComputerUtilCombat {
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage"
+ " as though it weren't blocked.")) {
unblocked.add(attacker);
} else if (attacker.hasKeyword("Trample")
} else if (attacker.hasKeyword(Keyword.TRAMPLE)
&& (ComputerUtilCombat.getAttack(attacker) > ComputerUtilCombat.totalShieldDamage(attacker, blockers))) {
if (attacker.hasKeyword("Infect")) {
if (attacker.hasKeyword(Keyword.INFECT)) {
poison += ComputerUtilCombat.getAttack(attacker) - ComputerUtilCombat.totalShieldDamage(attacker, blockers);
}
if (attacker.hasKeyword("Poisonous")) {
poison += attacker.getKeywordMagnitude("Poisonous");
if (attacker.hasKeyword(Keyword.POISONOUS)) {
poison += attacker.getKeywordMagnitude(Keyword.POISONOUS);
}
}
}
@@ -595,20 +597,21 @@ public class ComputerUtilCombat {
}
int flankingMagnitude = 0;
if (attacker.hasKeyword("Flanking") && !defender.hasKeyword("Flanking")) {
if (attacker.hasKeyword(Keyword.FLANKING) && !defender.hasKeyword(Keyword.FLANKING)) {
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
flankingMagnitude = attacker.getAmountOfKeyword(Keyword.FLANKING);
if (flankingMagnitude >= defender.getNetToughness()) {
return 0;
}
if ((flankingMagnitude >= (defender.getNetToughness() - defender.getDamage()))
&& !defender.hasKeyword("Indestructible")) {
&& !defender.hasKeyword(Keyword.INDESTRUCTIBLE)) {
return 0;
}
} // flanking
if (attacker.hasKeyword("Indestructible") && !(defender.hasKeyword("Wither") || defender.hasKeyword("Infect"))) {
if (attacker.hasKeyword(Keyword.INDESTRUCTIBLE)
&& !(defender.hasKeyword(Keyword.WITHER) || defender.hasKeyword(Keyword.INFECT))) {
return 0;
}
@@ -667,21 +670,21 @@ public class ComputerUtilCombat {
}
int flankingMagnitude = 0;
if (attacker.hasKeyword("Flanking") && !blocker.hasKeyword("Flanking")) {
if (attacker.hasKeyword(Keyword.FLANKING) && !blocker.hasKeyword(Keyword.FLANKING)) {
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
flankingMagnitude = attacker.getAmountOfKeyword(Keyword.FLANKING);
if (flankingMagnitude >= blocker.getNetToughness()) {
return 0;
}
if ((flankingMagnitude >= (blocker.getNetToughness() - blocker.getDamage()))
&& !blocker.hasKeyword("Indestructible")) {
&& !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
return 0;
}
} // flanking
final int defBushidoMagnitude = blocker.getKeywordMagnitude("Bushido");
final int defBushidoMagnitude = blocker.getKeywordMagnitude(Keyword.BUSHIDO);
final int defenderDefense = (blocker.getLethalDamage() - flankingMagnitude) + defBushidoMagnitude;
@@ -727,16 +730,16 @@ public class ComputerUtilCombat {
for (final Card defender : blockers) {
if (ComputerUtilCombat.canDestroyAttacker(ai, attacker, defender, combat, true)
&& !(defender.hasKeyword("Wither") || defender.hasKeyword("Infect"))) {
&& !(defender.hasKeyword(Keyword.WITHER) || defender.hasKeyword(Keyword.INFECT))) {
return true;
}
if (defender.hasKeyword("First Strike") || defender.hasKeyword("Double Strike")) {
if (defender.hasKeyword(Keyword.FIRST_STRIKE) || defender.hasKeyword(Keyword.DOUBLE_STRIKE)) {
firstStrikeBlockerDmg += defender.getNetCombatDamage();
}
}
// Consider first strike and double strike
if (attacker.hasKeyword("First Strike") || attacker.hasKeyword("Double Strike")) {
if (attacker.hasKeyword(Keyword.FIRST_STRIKE) || attacker.hasKeyword(Keyword.DOUBLE_STRIKE)) {
return firstStrikeBlockerDmg >= ComputerUtilCombat.getDamageToKill(attacker);
}
@@ -1069,8 +1072,8 @@ public class ComputerUtilCombat {
public static int predictToughnessBonusOfBlocker(final Card attacker, final Card blocker, boolean withoutAbilities) {
int toughness = 0;
if (attacker.hasKeyword("Flanking") && !blocker.hasKeyword("Flanking")) {
toughness -= attacker.getAmountOfKeyword("Flanking");
if (attacker.hasKeyword(Keyword.FLANKING) && !blocker.hasKeyword(Keyword.FLANKING)) {
toughness -= attacker.getAmountOfKeyword(Keyword.FLANKING);
}
if (blocker.getName().equals("Shape Stealer")) {
@@ -1239,9 +1242,7 @@ public class ComputerUtilCombat {
//check Exalted only for the first attacker
if (combat != null && combat.getAttackers().isEmpty()) {
for (Card card : attacker.getController().getCardsIn(ZoneType.Battlefield)) {
power += card.getAmountOfKeyword("Exalted");
}
power += attacker.getController().countExaltedBonus();
}
// Serene Master switches power with attacker
@@ -1263,8 +1264,8 @@ public class ComputerUtilCombat {
// less damage than expected
if (null != blocker) {
if (ComputerUtilCombat.dealsFirstStrikeDamage(blocker, withoutAbilities, combat)
&& (blocker.hasKeyword("Wither") || blocker.hasKeyword("Infect"))
&& !ComputerUtilCombat.dealsFirstStrikeDamage(attacker, withoutAbilities, combat)
&& (blocker.hasKeyword(Keyword.WITHER) || blocker.hasKeyword(Keyword.INFECT))
&& !ComputerUtilCombat.dealsFirstStrikeDamage(attacker, withoutAbilities, combat)
&& !attacker.hasKeyword("CARDNAME can't have counters put on it.")) {
power -= blocker.getNetCombatDamage();
}
@@ -1446,9 +1447,7 @@ public class ComputerUtilCombat {
//check Exalted only for the first attacker
if (combat != null && combat.getAttackers().isEmpty()) {
for (Card card : attacker.getController().getCardsIn(ZoneType.Battlefield)) {
toughness += card.getAmountOfKeyword("Exalted");
}
toughness += attacker.getController().countExaltedBonus();
}
if (blocker != null && attacker.getName().equals("Shape Stealer")) {
@@ -1766,24 +1765,24 @@ public class ComputerUtilCombat {
}
int flankingMagnitude = 0;
if (attacker.hasKeyword("Flanking") && !blocker.hasKeyword("Flanking")) {
if (attacker.hasKeyword(Keyword.FLANKING) && !blocker.hasKeyword(Keyword.FLANKING)) {
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
flankingMagnitude = attacker.getAmountOfKeyword(Keyword.FLANKING);
if (flankingMagnitude >= blocker.getNetToughness()) {
return false;
}
if ((flankingMagnitude >= (blocker.getNetToughness() - blocker.getDamage()))
&& !blocker.hasKeyword("Indestructible")) {
&& !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
return false;
}
} // flanking
if (((attacker.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(ai, attacker) && !withoutAbilities))
&& !(blocker.hasKeyword("Wither") || blocker.hasKeyword("Infect")))
|| (attacker.hasKeyword("Persist") && !attacker.canReceiveCounters(CounterType.M1M1) && (attacker
if (((attacker.hasKeyword(Keyword.INDESTRUCTIBLE) || (ComputerUtil.canRegenerate(ai, attacker) && !withoutAbilities))
&& !(blocker.hasKeyword(Keyword.WITHER) || blocker.hasKeyword(Keyword.INFECT)))
|| (attacker.hasKeyword(Keyword.PERSIST) && !attacker.canReceiveCounters(CounterType.M1M1) && (attacker
.getCounters(CounterType.M1M1) == 0))
|| (attacker.hasKeyword("Undying") && !attacker.canReceiveCounters(CounterType.P1P1) && (attacker
|| (attacker.hasKeyword(Keyword.UNDYING) && !attacker.canReceiveCounters(CounterType.P1P1) && (attacker
.getCounters(CounterType.P1P1) == 0))) {
return false;
}
@@ -1895,7 +1894,7 @@ public class ComputerUtilCombat {
for (Card attacker : attackers) {
if (ComputerUtilCombat.canDestroyBlocker(ai, blocker, attacker, combat, true)
&& !(attacker.hasKeyword("Wither") || attacker.hasKeyword("Infect"))) {
&& !(attacker.hasKeyword(Keyword.WITHER) || attacker.hasKeyword(Keyword.INFECT))) {
return true;
}
}
@@ -1913,19 +1912,21 @@ public class ComputerUtilCombat {
}
int flankingMagnitude = 0;
if (attacker.hasKeyword("Flanking") && !blocker.hasKeyword("Flanking")) {
if (attacker.hasKeyword(Keyword.FLANKING) && !blocker.hasKeyword(Keyword.FLANKING)) {
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
flankingMagnitude = attacker.getAmountOfKeyword(Keyword.FLANKING);
if (flankingMagnitude >= blocker.getNetToughness()) {
return true;
}
if ((flankingMagnitude >= ComputerUtilCombat.getDamageToKill(blocker)) && !blocker.hasKeyword("Indestructible")) {
if ((flankingMagnitude >= ComputerUtilCombat.getDamageToKill(blocker))
&& !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
return true;
}
} // flanking
if (blocker.hasKeyword("Indestructible") || dontTestRegen || ComputerUtil.canRegenerate(blocker.getController(), blocker)) {
if (blocker.hasKeyword(Keyword.INDESTRUCTIBLE) || dontTestRegen
|| ComputerUtil.canRegenerate(blocker.getController(), blocker)) {
return false;
}
@@ -2516,7 +2517,7 @@ public class ComputerUtilCombat {
public static boolean attackerHasThreateningAfflict(Card attacker, Player aiDefender) {
// TODO: expand this to account for more complex situations like the Wildfire Eternal unblocked trigger
int afflictDmg = attacker.getKeywordMagnitude("Afflict");
int afflictDmg = attacker.getKeywordMagnitude(Keyword.AFFLICT);
return afflictDmg > attacker.getNetPower() || afflictDmg >= aiDefender.getLife();
}

View File

@@ -7,6 +7,7 @@ import forge.game.ability.ApiType;
import forge.game.card.Card;
import forge.game.card.CounterType;
import forge.game.cost.CostPayEnergy;
import forge.game.keyword.Keyword;
import forge.game.keyword.KeywordInterface;
import forge.game.spellability.SpellAbility;
@@ -53,10 +54,10 @@ public class CreatureEvaluator implements Function<Card, Integer> {
}
// Evasion keywords
if (c.hasKeyword("Flying")) {
if (c.hasKeyword(Keyword.FLYING)) {
value += addValue(power * 10, "flying");
}
if (c.hasKeyword("Horsemanship")) {
if (c.hasKeyword(Keyword.HORSEMANSHIP)) {
value += addValue(power * 10, "horses");
}
if (c.hasKeyword("Unblockable")) {
@@ -65,13 +66,13 @@ public class CreatureEvaluator implements Function<Card, Integer> {
if (c.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
value += addValue(power * 6, "thorns");
}
if (c.hasKeyword("Fear")) {
if (c.hasKeyword(Keyword.FEAR)) {
value += addValue(power * 6, "fear");
}
if (c.hasKeyword("Intimidate")) {
if (c.hasKeyword(Keyword.INTIMIDATE)) {
value += addValue(power * 6, "intimidate");
}
if (c.hasStartOfKeyword("Menace")) {
if (c.hasKeyword(Keyword.MENACE)) {
value += addValue(power * 4, "menace");
}
if (c.hasStartOfKeyword("CantBeBlockedBy")) {
@@ -81,49 +82,49 @@ public class CreatureEvaluator implements Function<Card, Integer> {
// Other good keywords
if (power > 0) {
if (c.hasKeyword("Double Strike")) {
if (c.hasKeyword(Keyword.DOUBLE_STRIKE)) {
value += addValue(10 + (power * 15), "ds");
} else if (c.hasKeyword("First Strike")) {
value += addValue(10 + (power * 5), "fs");
}
if (c.hasKeyword("Deathtouch")) {
if (c.hasKeyword(Keyword.DEATHTOUCH)) {
value += addValue(25, "dt");
}
if (c.hasKeyword("Lifelink")) {
if (c.hasKeyword(Keyword.LIFELINK)) {
value += addValue(power * 10, "lifelink");
}
if (power > 1 && c.hasKeyword("Trample")) {
if (power > 1 && c.hasKeyword(Keyword.TRAMPLE)) {
value += addValue((power - 1) * 5, "trample");
}
if (c.hasKeyword("Vigilance")) {
if (c.hasKeyword(Keyword.VIGILANCE)) {
value += addValue((power * 5) + (toughness * 5), "vigilance");
}
if (c.hasKeyword("Wither")) {
if (c.hasKeyword(Keyword.WITHER)) {
value += addValue(power * 10, "Wither");
}
if (c.hasKeyword("Infect")) {
if (c.hasKeyword(Keyword.INFECT)) {
value += addValue(power * 15, "infect");
}
value += addValue(c.getKeywordMagnitude("Rampage"), "rampage");
value += addValue(c.getKeywordMagnitude("Afflict") * 5, "afflict");
value += addValue(c.getKeywordMagnitude(Keyword.RAMPAGE), "rampage");
value += addValue(c.getKeywordMagnitude(Keyword.AFFLICT) * 5, "afflict");
}
value += addValue(c.getKeywordMagnitude("Bushido") * 16, "bushido");
value += addValue(c.getAmountOfKeyword("Flanking") * 15, "flanking");
value += addValue(c.getAmountOfKeyword("Exalted") * 15, "exalted");
value += addValue(c.getKeywordMagnitude("Annihilator") * 50, "eldrazi");
value += addValue(c.getKeywordMagnitude("Absorb") * 11, "absorb");
value += addValue(c.getKeywordMagnitude(Keyword.BUSHIDO) * 16, "bushido");
value += addValue(c.getAmountOfKeyword(Keyword.FLANKING) * 15, "flanking");
value += addValue(c.getAmountOfKeyword(Keyword.EXALTED) * 15, "exalted");
value += addValue(c.getKeywordMagnitude(Keyword.ANNIHILATOR) * 50, "eldrazi");
value += addValue(c.getKeywordMagnitude(Keyword.ABSORB) * 11, "absorb");
// Keywords that may produce temporary or permanent buffs over time
if (c.hasKeyword("Prowess")) {
value += addValue(5, "prowess");
}
if (c.hasKeyword("Outlast")) {
if (c.hasKeyword(Keyword.OUTLAST)) {
value += addValue(10, "outlast");
}
// Defensive Keywords
if (c.hasKeyword("Reach") && !c.hasKeyword("Flying")) {
if (c.hasKeyword(Keyword.REACH) && !c.hasKeyword(Keyword.FLYING)) {
value += addValue(5, "reach");
}
if (c.hasKeyword("CARDNAME can block creatures with shadow as though they didn't have shadow.")) {
@@ -131,7 +132,7 @@ public class CreatureEvaluator implements Function<Card, Integer> {
}
// Protection
if (c.hasKeyword("Indestructible")) {
if (c.hasKeyword(Keyword.INDESTRUCTIBLE)) {
value += addValue(70, "darksteel");
}
if (c.hasKeyword("Prevent all damage that would be dealt to CARDNAME.")) {
@@ -139,20 +140,17 @@ public class CreatureEvaluator implements Function<Card, Integer> {
} else if (c.hasKeyword("Prevent all combat damage that would be dealt to CARDNAME.")) {
value += addValue(50, "fogbank");
}
if (c.hasKeyword("Hexproof")) {
if (c.hasKeyword(Keyword.HEXPROOF)) {
value += addValue(35, "hexproof");
} else if (c.hasKeyword("Shroud")) {
} else if (c.hasKeyword(Keyword.SHROUD)) {
value += addValue(30, "shroud");
}
if (c.hasStartOfKeyword("Protection")) {
value += addValue(20, "protection");
}
if (c.hasStartOfKeyword("PreventAllDamageBy")) {
value += addValue(10, "prevent-dmg");
}
// Bad keywords
if (c.hasKeyword("Defender") || c.hasKeyword("CARDNAME can't attack.")) {
if (c.hasKeyword(Keyword.DEFENDER) || c.hasKeyword("CARDNAME can't attack.")) {
value -= subValue((power * 9) + 40, "defender");
} else if (c.getSVar("SacrificeEndCombat").equals("True")) {
value -= subValue(40, "sac-end");
@@ -195,10 +193,10 @@ public class CreatureEvaluator implements Function<Card, Integer> {
if (c.hasStartOfKeyword("At the beginning of your upkeep, CARDNAME deals")) {
value -= subValue(20, "upkeep-dmg");
}
if (c.hasStartOfKeyword("Fading")) {
if (c.hasKeyword(Keyword.FADING)) {
value -= subValue(20, "fading");
}
if (c.hasStartOfKeyword("Vanishing")) {
if (c.hasKeyword(Keyword.VANISHING)) {
value -= subValue(20, "vanishing");
}
if (c.getSVar("Targeting").equals("Dies")) {