GN3: Imaryll, Elfhame Elite (+ refactor another quasi-keyword -> static) (#1033)

* AI stuff refactor keyword to check StaticAbilityAssignCombatDamageAsUnblocked

* ComputerUtilCombat refactor keyword to check StaticAbilityAssignCombatDamageAsUnblocked

* CreatureEvaluator refactor keyword to check StaticAbilityAssignCombatDamageAsUnblocked

* Combat.java refactor keyword to check StaticAbilityAssignCombatDamageAsUnblocked

* AnimateAllEffect.resolve support "staticAbilities" for garruk_savage_herald.txt

* imaryll_elfhame_elite.txt

* StaticAbilityAssignCombatDamageAsUnblocked.java

* refactor old cards

* AnimateAllEffect remove no longer needed

* AiBlockController.makeGoodBlocks restore lost '!'
This commit is contained in:
Northmoc
2022-07-05 14:23:40 -04:00
committed by GitHub
parent 0fdfe26eff
commit d7eff45cd1
24 changed files with 109 additions and 38 deletions

View File

@@ -20,6 +20,7 @@ package forge.ai;
import java.util.ArrayList;
import java.util.List;
import forge.game.staticability.StaticAbilityAssignCombatDamageAsUnblocked;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Predicate;
@@ -540,7 +541,7 @@ public class AiAttackController {
for (Card attacker : categorizedAttackers) {
if (!CombatUtil.canBeBlocked(attacker, accountedBlockers, null)
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|| StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker)) {
unblockedAttackers.add(attacker);
} else {
if (predictEvasion) {

View File

@@ -42,6 +42,7 @@ import forge.game.cost.Cost;
import forge.game.keyword.Keyword;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbilityAssignCombatDamageAsUnblocked;
import forge.game.staticability.StaticAbilityCantAttackBlock;
import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerType;
@@ -204,7 +205,7 @@ public class AiBlockController {
}
blocker = ComputerUtilCard.getWorstCreatureAI(killingBlockers);
// 2.Blockers that won't get destroyed
} else if (!attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
} else if (!StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker)
&& !ComputerUtilCombat.attackerHasThreateningAfflict(attacker, ai)) {
blocker = ComputerUtilCard.getWorstCreatureAI(safeBlockers);
// check whether it's better to block a creature without trample to absorb more damage
@@ -215,7 +216,7 @@ public class AiBlockController {
|| other.hasKeyword(Keyword.TRAMPLE)
|| ComputerUtilCombat.attackerHasThreateningAfflict(other, ai)
|| ComputerUtilCombat.canDestroyBlocker(ai, blocker, other, combat, false)
|| other.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|| StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(other)) {
continue;
}
@@ -668,7 +669,7 @@ public class AiBlockController {
Card attacker = attackers.get(0);
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > 1
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|| StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker)
|| ComputerUtilCombat.attackerHasThreateningAfflict(attacker, ai)) {
attackers.remove(0);
makeChumpBlocks(combat, attackers);
@@ -689,7 +690,7 @@ public class AiBlockController {
}
if (other.getNetCombatDamage() >= damageAbsorbed
&& !other.hasKeyword(Keyword.TRAMPLE)
&& !other.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
&& !StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(other)
&& !ComputerUtilCombat.attackerHasThreateningAfflict(other, ai)
&& CombatUtil.canBlock(other, blocker, combat)) {
combat.addBlocker(other, blocker);
@@ -756,7 +757,7 @@ public class AiBlockController {
for (final Card attacker : tramplingAttackers) {
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > combat.getBlockers(attacker).size()
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|| StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker)
|| attacker.hasKeyword("CARDNAME can't be blocked unless all creatures defending player controls block it.")) {
continue;
}

View File

@@ -48,6 +48,7 @@ import forge.game.replacement.ReplacementLayer;
import forge.game.replacement.ReplacementType;
import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbility;
import forge.game.staticability.StaticAbilityAssignCombatDamageAsUnblocked;
import forge.game.staticability.StaticAbilityMustAttack;
import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerType;
@@ -325,8 +326,7 @@ public class ComputerUtilCombat {
final List<Card> blockers = combat.getBlockers(attacker);
if (blockers.size() == 0
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage "
+ "as though it weren't blocked.")) {
|| StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker)) {
unblocked.add(attacker);
} else if (attacker.hasKeyword(Keyword.TRAMPLE)
&& getAttack(attacker) > totalShieldDamage(attacker, blockers)) {
@@ -367,8 +367,7 @@ public class ComputerUtilCombat {
final List<Card> blockers = combat.getBlockers(attacker);
if (blockers.size() == 0
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage"
+ " as though it weren't blocked.")) {
|| StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker)) {
unblocked.add(attacker);
} else if (attacker.hasKeyword(Keyword.TRAMPLE)
&& getAttack(attacker) > totalShieldDamage(attacker, blockers)) {

View File

@@ -10,6 +10,7 @@ import forge.game.card.CounterEnumType;
import forge.game.cost.CostPayEnergy;
import forge.game.keyword.Keyword;
import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbilityAssignCombatDamageAsUnblocked;
import forge.game.staticability.StaticAbilityMustAttack;
import java.util.List;
@@ -62,7 +63,8 @@ public class CreatureEvaluator implements Function<Card, Integer> {
if (c.hasKeyword("Unblockable")) {
value += addValue(power * 10, "unblockable");
} else {
if (c.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
if (StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(c)
|| StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(c, false)) {
value += addValue(power * 6, "thorns");
}
if (c.hasKeyword(Keyword.FEAR)) {