mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Merge pull request #113 from Northmoc/mustattack
Must attack keywords -> static ability
This commit is contained in:
@@ -20,6 +20,7 @@ package forge.ai;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import forge.game.staticability.StaticAbilityMustAttack;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
@@ -795,14 +796,15 @@ public class AiAttackController {
|
||||
&& isEffectiveAttacker(ai, attacker, combat, defender)) {
|
||||
mustAttack = true;
|
||||
} else if (seasonOfTheWitch) {
|
||||
// TODO: if there are other ways to tap this creature (like mana creature), then don't need to attack
|
||||
//TODO: if there are other ways to tap this creature (like mana creature), then don't need to attack
|
||||
mustAttack = true;
|
||||
} else {
|
||||
// TODO move to static Ability
|
||||
if (attacker.hasKeyword("CARDNAME attacks each combat if able.") || attacker.hasStartOfKeyword("CARDNAME attacks specific player each combat if able")) {
|
||||
// TODO switch defender if there's one without a cost or it's not the specific player
|
||||
final List<GameEntity> e = StaticAbilityMustAttack.entitiesMustAttack(attacker);
|
||||
if (!e.isEmpty()) {
|
||||
mustAttack = true;
|
||||
} else if (attacker.getController().getMustAttackEntityThisTurn() != null && CombatUtil.getAttackCost(ai.getGame(), attacker, defender) == null) {
|
||||
// TODO switch defender if there's one without a cost or it's not the specific player
|
||||
} else if (attacker.getController().getMustAttackEntityThisTurn() != null &&
|
||||
CombatUtil.getAttackCost(ai.getGame(), attacker, defender) == null) {
|
||||
mustAttack = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ 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;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
@@ -49,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.StaticAbilityMustAttack;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -114,24 +114,11 @@ public class ComputerUtilCombat {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO replace with Static Ability
|
||||
for (final String keyword : attacker.getHiddenExtrinsicKeywords()) {
|
||||
if (keyword.startsWith("CARDNAME attacks specific player each combat if able")) {
|
||||
final String defined = keyword.split(":")[1];
|
||||
final Player player = AbilityUtils.getDefinedPlayers(attacker, defined, null).get(0);
|
||||
if (!defender.equals(player)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final KeywordInterface inst : attacker.getKeywords(Keyword.UNDEFINED)) {
|
||||
final String keyword = inst.getOriginal();
|
||||
if (keyword.startsWith("CARDNAME attacks specific player each combat if able")) {
|
||||
final String defined = keyword.split(":")[1];
|
||||
final Player player = AbilityUtils.getDefinedPlayers(attacker, defined, null).get(0);
|
||||
if (!defender.equals(player)) {
|
||||
return false;
|
||||
}
|
||||
final List<GameEntity> mustAttackEnts = StaticAbilityMustAttack.entitiesMustAttack(attacker);
|
||||
//if it contains only attacker, it only has a non-specific must attack
|
||||
if (mustAttackEnts.size() > 1 || (mustAttackEnts.size() == 1 && mustAttackEnts.get(0) != attacker)) {
|
||||
if (!mustAttackEnts.contains(defender)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package forge.ai;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.Card;
|
||||
@@ -9,6 +10,9 @@ import forge.game.card.CounterEnumType;
|
||||
import forge.game.cost.CostPayEnergy;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbilityMustAttack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CreatureEvaluator implements Function<Card, Integer> {
|
||||
@Override
|
||||
@@ -174,13 +178,16 @@ public class CreatureEvaluator implements Function<Card, Integer> {
|
||||
value = addValue(50 + (c.getCMC() * 5), "useless"); // reset everything - useless
|
||||
} else if (c.hasKeyword("CARDNAME can't block.")) {
|
||||
value -= subValue(10, "cant-block");
|
||||
} else if (c.hasKeyword("CARDNAME attacks each combat if able.")) {
|
||||
value -= subValue(10, "must-attack");
|
||||
} else if (c.hasStartOfKeyword("CARDNAME attacks specific player each combat if able")) {
|
||||
value -= subValue(10, "must-attack-player");
|
||||
}/* else if (c.hasKeyword("CARDNAME can block only creatures with flying.")) {
|
||||
} else {
|
||||
List<GameEntity> mAEnt = StaticAbilityMustAttack.entitiesMustAttack(c);
|
||||
if (mAEnt.contains(c)) {
|
||||
value -= subValue(10, "must-attack");
|
||||
} else if (!mAEnt.isEmpty()) {
|
||||
value -= subValue(10, "must-attack-player");
|
||||
}/* else if (c.hasKeyword("CARDNAME can block only creatures with flying.")) {
|
||||
value -= subValue(toughness * 5, "reverse-reach");
|
||||
}//*/
|
||||
}
|
||||
|
||||
if (c.hasSVar("DestroyWhenDamaged")) {
|
||||
value -= subValue((toughness - 1) * 9, "dies-to-dmg");
|
||||
|
||||
Reference in New Issue
Block a user