mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
- Updates to Attach and Pump AI.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
All creatures able to block CARDNAME do so.
|
All creatures able to block CARDNAME do so.
|
||||||
CARDNAME attacks each turn if able.
|
CARDNAME attacks each turn if able.
|
||||||
|
CARDNAME can attack as though it didn't have defender.
|
||||||
CARDNAME can't be regenerated.
|
CARDNAME can't be regenerated.
|
||||||
CARDNAME must be blocked if able.
|
CARDNAME must be blocked if able.
|
||||||
CantBeBlockedByAmount LT2
|
CantBeBlockedByAmount LT2
|
||||||
|
|||||||
@@ -749,7 +749,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
magnetList = CardLists.filter(list, new Predicate<Card>() {
|
magnetList = CardLists.filter(list, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
return c.isCreature();
|
return c.isCreature() && !c.isFortified();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -876,6 +876,11 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
c = ComputerUtilCard.getBestAI(prefList);
|
c = ComputerUtilCard.getBestAI(prefList);
|
||||||
} else {
|
} else {
|
||||||
|
for (Card pref : prefList) {
|
||||||
|
if (pref.isLand() && pref.isUntapped()) {
|
||||||
|
return pref;
|
||||||
|
}
|
||||||
|
}
|
||||||
// If we grant abilities, we may want to put it on something Weak?
|
// If we grant abilities, we may want to put it on something Weak?
|
||||||
// Possibly more defensive?
|
// Possibly more defensive?
|
||||||
c = ComputerUtilCard.getWorstPermanentAI(prefList, false, false, false, false);
|
c = ComputerUtilCard.getWorstPermanentAI(prefList, false, false, false, false);
|
||||||
@@ -1115,7 +1120,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (keyword.equals("CARDNAME can attack as though it didn't have defender.")) {
|
} else if (keyword.equals("CARDNAME can attack as though it didn't have defender.")) {
|
||||||
if (!card.hasKeyword("Defender") || card.hasKeyword("CARDNAME can attack as though it didn't have defender.")) {
|
if (!card.hasKeyword("Defender") || card.getNetCombatDamage() + powerBonus <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (keyword.equals("Shroud") || keyword.equals("Hexproof")) {
|
} else if (keyword.equals("Shroud") || keyword.equals("Hexproof")) {
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
final Combat combat = game.getCombat();
|
final Combat combat = game.getCombat();
|
||||||
final PhaseHandler ph = game.getPhaseHandler();
|
final PhaseHandler ph = game.getPhaseHandler();
|
||||||
final Player opp = ai.getOpponent();
|
final Player opp = ai.getOpponent();
|
||||||
|
final int newPower = card.getNetCombatDamage() + attack;
|
||||||
//int defense = getNumDefense(sa);
|
//int defense = getNumDefense(sa);
|
||||||
if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) {
|
if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -174,7 +175,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
if (evasive) {
|
if (evasive) {
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || combat != null && combat.isAttacking(card))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || combat != null && combat.isAttacking(card))
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -190,7 +191,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
Predicate<Card> flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach"));
|
Predicate<Card> flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach"));
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| !Iterables.any(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
|
|| !Iterables.any(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
|
||||||
Predicates.not(flyingOrReach))) {
|
Predicates.not(flyingOrReach))) {
|
||||||
return false;
|
return false;
|
||||||
@@ -205,14 +206,14 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| CardLists.getNotKeyword(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
|
|| CardLists.getNotKeyword(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
|
||||||
"Horsemanship").isEmpty()) {
|
"Horsemanship").isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (keyword.endsWith("Haste")) {
|
} else if (keyword.endsWith("Haste")) {
|
||||||
if (!card.hasSickness() || ph.isPlayerTurn(opp) || card.isTapped()
|
if (!card.hasSickness() || ph.isPlayerTurn(opp) || card.isTapped()
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| card.hasKeyword("CARDNAME can attack as though it had haste.")
|
|| card.hasKeyword("CARDNAME can attack as though it had haste.")
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| !CombatUtil.canAttackNextTurn(card)) {
|
|| !CombatUtil.canAttackNextTurn(card)) {
|
||||||
@@ -243,13 +244,13 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
} else if (combatRelevant) {
|
} else if (combatRelevant) {
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|
||||||
|| (opp.getCreaturesInPlay().size() < 1)
|
|| opp.getCreaturesInPlay().size() < 1
|
||||||
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (keyword.equals("Double Strike")) {
|
} else if (keyword.equals("Double Strike")) {
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -270,12 +271,12 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| !CombatUtil.canBeBlocked(card, opp)
|
|| !CombatUtil.canBeBlocked(card, opp)
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| card.getNetCombatDamage() + attack <= 1
|
|| newPower <= 1
|
||||||
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (keyword.equals("Infect")) {
|
} else if (keyword.equals("Infect")) {
|
||||||
if (card.getNetCombatDamage() <= 0) {
|
if (newPower <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (combat != null && combat.isBlocking(card)) {
|
if (combat != null && combat.isBlocking(card)) {
|
||||||
@@ -287,12 +288,12 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (keyword.endsWith("Wither")) {
|
} else if (keyword.endsWith("Wither")) {
|
||||||
if (card.getNetCombatDamage() <= 0) {
|
if (newPower <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return combat != null && ( combat.isBlocking(card) || (combat.isAttacking(card) && combat.isBlocked(card)) );
|
return combat != null && ( combat.isBlocking(card) || (combat.isAttacking(card) && combat.isBlocked(card)) );
|
||||||
} else if (keyword.equals("Lifelink")) {
|
} else if (keyword.equals("Lifelink")) {
|
||||||
if (card.getNetCombatDamage() <= 0) {
|
if (newPower <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return combat != null && ( combat.isAttacking(card) || combat.isBlocking(card) );
|
return combat != null && ( combat.isAttacking(card) || combat.isBlocking(card) );
|
||||||
@@ -335,7 +336,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
} else if (keyword.equals("Islandwalk")) {
|
} else if (keyword.equals("Islandwalk")) {
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| CardLists.getType(opp.getLandsInPlay(), "Island").isEmpty()
|
|| CardLists.getType(opp.getLandsInPlay(), "Island").isEmpty()
|
||||||
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -343,7 +344,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
} else if (keyword.equals("Swampwalk")) {
|
} else if (keyword.equals("Swampwalk")) {
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| CardLists.getType(opp.getLandsInPlay(), "Swamp").isEmpty()
|
|| CardLists.getType(opp.getLandsInPlay(), "Swamp").isEmpty()
|
||||||
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -351,7 +352,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
} else if (keyword.equals("Mountainwalk")) {
|
} else if (keyword.equals("Mountainwalk")) {
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| CardLists.getType(opp.getLandsInPlay(), "Mountain").isEmpty()
|
|| CardLists.getType(opp.getLandsInPlay(), "Mountain").isEmpty()
|
||||||
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -359,7 +360,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
} else if (keyword.equals("Forestwalk")) {
|
} else if (keyword.equals("Forestwalk")) {
|
||||||
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || (combat != null && combat.isAttacking(card)))
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
|| card.getNetCombatDamage() <= 0
|
|| newPower <= 0
|
||||||
|| CardLists.getType(opp.getLandsInPlay(), "Forest").isEmpty()
|
|| CardLists.getType(opp.getLandsInPlay(), "Forest").isEmpty()
|
||||||
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -367,7 +368,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
} else if (keyword.endsWith("CARDNAME can attack as though it didn't have defender.")) {
|
} else if (keyword.endsWith("CARDNAME can attack as though it didn't have defender.")) {
|
||||||
if (!ph.isPlayerTurn(ai) || !card.hasKeyword("Defender")
|
if (!ph.isPlayerTurn(ai) || !card.hasKeyword("Defender")
|
||||||
|| ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN)
|
|| ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN)
|
||||||
|| card.isTapped()) {
|
|| card.isTapped() || newPower <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user