Deleted 2 steps that never existed in original game rules: COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY and COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY

This commit is contained in:
Maxmtg
2013-06-02 06:41:12 +00:00
parent d89c998b66
commit 0db4131009
31 changed files with 130 additions and 141 deletions

View File

@@ -60,7 +60,7 @@ public class AnimateAi extends SpellAbilityAi {
// don't use instant speed animate abilities outside humans
// Combat_Declare_Attackers_InstantAbility step
if ((!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
if ((!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| (game.getCombat().getAttackers().isEmpty()))
&& game.getPhaseHandler().isPlayerTurn(opponent)) {
return false;

View File

@@ -77,7 +77,7 @@ public class AttachAi extends SpellAbilityAi {
source.setSVar("PayX", Integer.toString(xPay));
}
if (ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
if (ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
&& !"Curse".equals(sa.getParam("AILogic"))) {
return false;
}

View File

@@ -22,7 +22,7 @@ public class BecomesBlockedAi extends SpellAbilityAi {
final Target tgt = sa.getTarget();
final Game game = aiPlayer.getGame();
if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)
|| !game.getPhaseHandler().getPlayerTurn().isOpponentOf(aiPlayer)) {
return false;
}

View File

@@ -743,7 +743,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
}
// Save combatants
else if (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
else if (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
final List<Card> combatants = CardLists.filter(aiPermanents, CardPredicates.Presets.CREATURES);
CardLists.sortByEvaluateCreature(combatants);
@@ -799,7 +799,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
if (origin.equals(ZoneType.Battlefield)
&& destination.equals(ZoneType.Exile)
&& (subApi == ApiType.DelayedTrigger || (subApi == ApiType.ChangeZone && subAffected.equals("Remembered")))
&& !(ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || sa
&& !(ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS) || sa
.isAbility())) {
return false;
}

View File

@@ -62,7 +62,7 @@ public class ChooseCardAi extends SpellAbilityAi {
} else if (sa.getParam("AILogic").equals("Never")) {
return false;
} else if (sa.getParam("AILogic").equals("NeedsPrevention")) {
if (!game.getPhaseHandler().getPhase() .equals(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (!game.getPhaseHandler().getPhase() .equals(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return false;
}
choices = CardLists.filter(choices, new Predicate<Card>() {

View File

@@ -99,8 +99,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
}
return true;
}
if (!game.getPhaseHandler().getPhase()
.equals(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (game.getPhaseHandler().getPhase() != PhaseType.COMBAT_DECLARE_BLOCKERS) {
return false;
}
List<Card> choices = game.getCardsIn(ZoneType.Battlefield);

View File

@@ -45,7 +45,7 @@ public class CloneAi extends SpellAbilityAi {
// don't use instant speed clone abilities outside humans
// Combat_Declare_Attackers_InstantAbility step
if ((!phase.is(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
if ((!phase.is(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| game.getCombat().getAttackers().isEmpty())
&& !phase.isPlayerTurn(ai)) {
return false;

View File

@@ -108,7 +108,7 @@ public class CountersPutAllAi extends SpellAbilityAi {
&& sa.getPayCosts() != null && sa.getPayCosts().hasTapCost()
&& sa instanceof AbilitySub
&& (!phase.getNextTurn().equals(ai)
|| phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY))) {
|| phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS))) {
boolean combatants = false;
for (Card c : hList) {
if (!c.equals(source) && c.isUntapped()) {

View File

@@ -65,7 +65,7 @@ public class DamagePreventAi extends SpellAbilityAi {
}
} else {
PhaseHandler handler = game.getPhaseHandler();
if (handler.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (handler.is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
boolean flag = false;
for (final Object o : objects) {
if (o instanceof Card) {
@@ -119,7 +119,7 @@ public class DamagePreventAi extends SpellAbilityAi {
}
} // Protect combatants
else if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
else if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
if (sa.canTarget(ai) && ComputerUtilCombat.wouldLoseLife(ai, game.getCombat())
&& (ComputerUtilCombat.lifeInDanger(ai, game.getCombat()) || sa.isAbility())
&& game.getPhaseHandler().isPlayerTurn(ai.getOpponent())) {
@@ -198,7 +198,7 @@ public class DamagePreventAi extends SpellAbilityAi {
if (compTargetables.size() > 0) {
final List<Card> combatants = CardLists.filter(compTargetables, CardPredicates.Presets.CREATURES);
CardLists.sortByEvaluateCreature(combatants);
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
for (final Card c : combatants) {
if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
tgt.addTarget(c);

View File

@@ -43,7 +43,7 @@ public class DamagePreventAllAi extends SpellAbilityAi {
// control
} // Protect combatants
else if (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
else if (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
// TODO
}

View File

@@ -53,8 +53,8 @@ public class DebuffAi extends SpellAbilityAi {
final PhaseHandler ph = ai.getGame().getPhaseHandler();
// Phase Restrictions
if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|| !ai.getGame().getStack().isEmpty()) {
// Instant-speed pumps should not be cast outside of combat when the
// stack is empty
@@ -124,7 +124,7 @@ public class DebuffAi extends SpellAbilityAi {
*/
private boolean debuffTgtAI(final Player ai, final SpellAbility sa, final List<String> kws, final boolean mandatory) {
// this would be for evasive things like Flying, Unblockable, etc
if (!mandatory && ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (!mandatory && ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return false;
}

View File

@@ -46,7 +46,7 @@ public class EffectAi extends SpellAbilityAi {
if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {
return false;
}
if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return false;
}
if (!game.getStack().isEmpty()) {

View File

@@ -20,7 +20,7 @@ public class FogAi extends SpellAbilityAi {
if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {
return false;
}
if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return false;
}

View File

@@ -172,7 +172,7 @@ public class ProtectAi extends SpellAbilityAi {
private boolean protectTgtAI(final Player ai, final SpellAbility sa, final boolean mandatory) {
final Game game = ai.getGame();
if (!mandatory && game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (!mandatory && game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return false;
}

View File

@@ -186,7 +186,7 @@ public class PumpAi extends PumpAiBase {
if (!mandatory
&& !sa.isTrigger()
&& game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
&& game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
&& !(sa.isCurse() && (defense < 0))
&& !this.containsNonCombatKeyword(keywords)
&& !sa.hasParam("UntilYourNextTurn")) {

View File

@@ -117,7 +117,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|| keyword.endsWith("Prevent all damage that would be dealt by CARDNAME.")) {
if (ph.isPlayerTurn(ai) && (!(CombatUtil.canBlock(card) || card.isBlocking())
|| card.getNetCombatDamage() <= 0
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|| ph.getPhase().isBefore(PhaseType.MAIN1)
|| CardLists.getNotKeyword(ai.getCreaturesInPlay(), "Defender").isEmpty())) {
return false;
@@ -172,14 +172,14 @@ public abstract class PumpAiBase extends SpellAbilityAi {
// give evasive keywords to creatures that can or do attack
if (evasive) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false;
}
} else if (keyword.endsWith("Flying")) {
if (ph.isPlayerTurn(opp)
&& ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
&& ph.getPhase() == PhaseType.COMBAT_DECLARE_ATTACKERS
&& !CardLists.getKeyword(game.getCombat().getAttackers(), "Flying").isEmpty()
&& !card.hasKeyword("Reach")
&& CombatUtil.canBlock(card)
@@ -188,7 +188,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
Predicate<Card> flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach"));
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0
|| !Iterables.any(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
Predicates.not(flyingOrReach))) {
@@ -196,14 +196,14 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
} else if (keyword.endsWith("Horsemanship")) {
if (ph.isPlayerTurn(opp)
&& ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
&& ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS)
&& !CardLists.getKeyword(game.getCombat().getAttackers(), "Horsemanship").isEmpty()
&& CombatUtil.canBlock(card)
&& ComputerUtilCombat.lifeInDanger(ai, game.getCombat())) {
return true;
}
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0
|| CardLists.getNotKeyword(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
"Horsemanship").isEmpty()) {
@@ -221,7 +221,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
return true;
} else if (keyword.endsWith("Deathtouch")) {
Combat combat = game.getCombat();
if (ph.isPlayerTurn(opp) && ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)) {
if (ph.isPlayerTurn(opp) && ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
List<Card> attackers = combat.getAttackers();
for (Card attacker : attackers) {
if (CombatUtil.canBlock(attacker, card, combat)
@@ -242,7 +242,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
return false;
} else if (combatRelevant) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|| (opp.getCreaturesInPlay().size() < 1)
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false;
@@ -250,18 +250,18 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} else if (keyword.equals("Double Strike")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| card.getNetCombatDamage() <= 0
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return false;
}
} else if (keyword.startsWith("Rampage")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).size() < 2) {
return false;
}
} else if (keyword.startsWith("Flanking")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| CardLists.getNotKeyword(CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)),
"Flanking").isEmpty()) {
return false;
@@ -269,7 +269,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
} else if (keyword.startsWith("Trample")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| !CombatUtil.canBeBlocked(card)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() + attack <= 1
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
return false;
@@ -283,7 +283,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
if ((ph.isPlayerTurn(opp))
|| !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return false;
}
} else if (keyword.endsWith("Wither")) {
@@ -312,7 +312,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
} else if (keyword.equals("Reach")) {
if (ph.isPlayerTurn(ai)
|| !ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| !ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| CardLists.getKeyword(game.getCombat().getAttackers(), "Flying").isEmpty()
|| card.hasKeyword("Flying")
|| !CombatUtil.canBlock(card)) {
@@ -320,7 +320,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
} else if (keyword.endsWith("CARDNAME can block an additional creature.")) {
if (ph.isPlayerTurn(ai)
|| !ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)) {
|| !ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
return false;
}
int canBlockNum = 1 + card.getKeywordAmount("CARDNAME can block an additional creature.");
@@ -342,7 +342,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
} else if (keyword.equals("Islandwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Island").isEmpty()
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
@@ -350,7 +350,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
} else if (keyword.equals("Swampwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Swamp").isEmpty()
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
@@ -358,7 +358,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
} else if (keyword.equals("Mountainwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Mountain").isEmpty()
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
@@ -366,7 +366,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
} else if (keyword.equals("Forestwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| card.getNetCombatDamage() <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Forest").isEmpty()
|| CardLists.filter(opp.getCreaturesInPlay(), CardPredicates.possibleBlockers(card)).isEmpty()) {
@@ -422,7 +422,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
// is the creature blocking and unable to destroy the attacker
// or would be destroyed itself?
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && c.isBlocking()) {
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS) && c.isBlocking()) {
if (defense > 0 && ComputerUtilCombat.blockerWouldBeDestroyed(ai, c)) {
return true;
}
@@ -435,13 +435,13 @@ public abstract class PumpAiBase extends SpellAbilityAi {
}
// is the creature unblocked and the spell will pump its power?
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS)
&& game.getCombat().isAttacking(c) && game.getCombat().isUnblocked(c) && attack > 0) {
return true;
}
// is the creature blocked and the blocker would survive
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && attack > 0
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS) && attack > 0
&& game.getCombat().isAttacking(c)
&& game.getCombat().isBlocked(c)
&& game.getCombat().getBlockers(c) != null
@@ -457,7 +457,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
attackerHasTrample |= b.hasKeyword("Trample");
}
if (phase.getPhase().equals(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
if (phase.getPhase().equals(PhaseType.COMBAT_DECLARE_BLOCKERS)
&& phase.isPlayerTurn(ai.getOpponent())
&& c.isBlocking()
&& defense > 0

View File

@@ -78,8 +78,8 @@ public class PumpAllAi extends PumpAiBase {
}); // leaves all creatures that will be destroyed
} // -X/-X end
else if (power < 0) { // -X/-0
if (phase.isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
|| phase.isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
if (phase.isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|| phase.isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())
|| game.getPhaseHandler().isPreventCombatDamageThisTurn()) {
return false;
@@ -90,7 +90,7 @@ public class PumpAllAi extends PumpAiBase {
continue;
}
totalPower += Math.min(c.getNetAttack(), power * -1);
if (phase == PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY
if (phase == PhaseType.COMBAT_DECLARE_BLOCKERS
&& game.getCombat().getUnblockedAttackers().contains(c)) {
if (ComputerUtilCombat.lifeInDanger(sa.getActivatingPlayer(), game.getCombat())) {
return true;
@@ -113,7 +113,7 @@ public class PumpAllAi extends PumpAiBase {
} // end Curse
// don't use non curse PumpAll after Combat_Begin until AI is improved
if (phase.isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || phase.isBefore(PhaseType.MAIN1)) {
if (phase.isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || phase.isBefore(PhaseType.MAIN1)) {
return false;
}
@@ -124,7 +124,7 @@ public class PumpAllAi extends PumpAiBase {
if (power <= 0 && !containsUsefulKeyword(ai, keywords, c, sa, power)) {
return false;
}
if (phase.equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) && c.isAttacking()) {
if (phase.equals(PhaseType.COMBAT_DECLARE_ATTACKERS) && c.isAttacking()) {
return true;
}
if (phase.isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && CombatUtil.canAttack(c, opp)) {

View File

@@ -92,7 +92,7 @@ public class RegenerateAi extends SpellAbilityAi {
}
}
} else {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
boolean flag = false;
for (final Card c : list) {
@@ -136,7 +136,7 @@ public class RegenerateAi extends SpellAbilityAi {
chance = true;
}
} else {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
final List<Card> combatants = CardLists.filter(targetables, CardPredicates.Presets.CREATURES);
CardLists.sortByEvaluateCreature(combatants);
@@ -194,7 +194,7 @@ public class RegenerateAi extends SpellAbilityAi {
if (compTargetables.size() > 0) {
final List<Card> combatants = CardLists.filter(compTargetables, CardPredicates.Presets.CREATURES);
CardLists.sortByEvaluateCreature(combatants);
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
for (final Card c : combatants) {
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
tgt.addTarget(c);
@@ -207,7 +207,7 @@ public class RegenerateAi extends SpellAbilityAi {
// can target
// choose my best X without regen
if (CardLists.getNotType(compTargetables, "Creature").size() == 0) {
if (CardLists.getNotType(compTargetables, "Creature").isEmpty()) {
for (final Card c : combatants) {
if (c.getShield() == 0) {
tgt.addTarget(c);

View File

@@ -65,7 +65,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
}
}
} else {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
final List<Card> combatants = CardLists.filter(list, CardPredicates.Presets.CREATURES);
for (final Card c : combatants) {

View File

@@ -111,7 +111,7 @@ public class TokenAi extends SpellAbilityAi {
}
if ((ph.isPlayerTurn(ai)
|| ph.getPhase().isBefore(
PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY))
PhaseType.COMBAT_DECLARE_ATTACKERS))
&& !sa.hasParam("ActivationPhases") && !sa.hasParam("PlayerTurn")
&& !SpellAbilityAi.isSorcerySpeed(sa) && !haste) {
return false;
@@ -170,7 +170,7 @@ public class TokenAi extends SpellAbilityAi {
return true;
}
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)) {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
return true;
}
if (sa.isAbility()) {

View File

@@ -49,7 +49,7 @@ public class UnattachAllAi extends SpellAbilityAi {
source.setSVar("PayX", Integer.toString(xPay));
}
if (ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
if (ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
&& !"Curse".equals(sa.getParam("AILogic"))) {
return false;
}

View File

@@ -128,7 +128,7 @@ public class SpellPermanent extends Spell {
&& (ai.isUnlimitedHandSize() || ai.getCardsIn(ZoneType.Hand).size() <= ai.getMaxHandSize())
&& ai.getManaPool().totalMana() <= 0
&& (game.getPhaseHandler().isPlayerTurn(ai)
|| game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
&& !card.hasETBTrigger())
&& !ComputerUtil.castPermanentInMain1(ai, this)) {
return false;

View File

@@ -68,8 +68,8 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
switch(ev.phase) {
case COMBAT_END:
case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY:
case COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY:
case COMBAT_DECLARE_ATTACKERS:
case COMBAT_DECLARE_BLOCKERS:
if( fc.getObservedGame().getPhaseHandler().inCombat() )
pauseForEvent(combatDelay);
break;

View File

@@ -787,16 +787,6 @@ public class AiController {
public void onPriorityRecieved() {
final PhaseType phase = game.getPhaseHandler().getPhase();
switch(phase) {
case COMBAT_DECLARE_ATTACKERS:
declareAttackers();
break;
case COMBAT_DECLARE_BLOCKERS:
final List<Card> blockers = player.getCreaturesInPlay();
game.setCombat(ComputerUtilBlock.getBlockers(player, game.getCombat(), blockers));
CombatUtil.orderMultipleCombatants(game.getCombat());
break;
case MAIN1:
case MAIN2:
Log.debug("Computer " + phase.nameForUi);
@@ -809,9 +799,15 @@ public class AiController {
break;
}
}
public void declateBlockers() {
final List<Card> blockers = player.getCreaturesInPlay();
game.setCombat(ComputerUtilBlock.getBlockers(player, game.getCombat(), blockers));
CombatUtil.orderMultipleCombatants(game.getCombat());
}
private void declareAttackers() {
public void declareAttackers() {
// 12/2/10(sol) the decision making here has moved to getAttackers()
game.setCombat(new AiAttackController(player, player.getOpponent()).getAttackers());

View File

@@ -1017,7 +1017,7 @@ public class ComputerUtil {
return (sa.getSourceCard().isCreature()
&& sa.getPayCosts().hasTapCost()
&& (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
&& (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)
|| !ph.getNextTurn().equals(sa.getActivatingPlayer())));
}

View File

@@ -264,17 +264,30 @@ public class PhaseHandler implements java.io.Serializable {
break;
case COMBAT_DECLARE_ATTACKERS:
break;
case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY:
game.getStack().freezeStack();
playerTurn.getController().declareAttackers();
PhaseUtil.handleDeclareAttackers(game);
this.bCombat = !game.getCombat().getAttackers().isEmpty();
game.getStack().unfreezeStack();
this.nCombatsThisTurn++;
break;
case COMBAT_DECLARE_BLOCKERS:
game.getCombat().verifyCreaturesInPlay();
break;
case COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY:
game.getStack().freezeStack();
Player p = playerTurn;
do {
p = game.getNextPlayerAfter(p);
if ( game.getCombat().isPlayerAttacked(p) )
p.getController().declareBlockers();
} while(p != playerTurn);
game.getStack().unfreezeStack();
PhaseUtil.handleDeclareBlockers(game);
break;
@@ -402,17 +415,7 @@ public class PhaseHandler implements java.io.Serializable {
case UNTAP:
this.nCombatsThisTurn = 0;
break;
case COMBAT_DECLARE_ATTACKERS:
this.bCombat = !game.getCombat().getAttackers().isEmpty();
game.getStack().unfreezeStack();
this.nCombatsThisTurn++;
break;
case COMBAT_DECLARE_BLOCKERS:
game.getStack().unfreezeStack();
break;
case COMBAT_END:
game.getCombat().reset(playerTurn);
this.getPlayerTurn().resetAttackedThisCombat();
@@ -445,9 +448,7 @@ public class PhaseHandler implements java.io.Serializable {
case COMBAT_DECLARE_ATTACKERS:
return playerTurn.isSkippingCombat();
case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY:
case COMBAT_DECLARE_BLOCKERS:
case COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY:
case COMBAT_FIRST_STRIKE_DAMAGE:
case COMBAT_DAMAGE:
return !this.inCombat();
@@ -684,20 +685,13 @@ public class PhaseHandler implements java.io.Serializable {
while (!game.isGameOver()) { // loop only while is playing
boolean givePriority = givePriorityToPlayer ;
if ( phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
givePriority = game.getCombat().isPlayerAttacked(pPlayerPriority);
if ( phase == PhaseType.COMBAT_DECLARE_ATTACKERS && playerTurn != pPlayerPriority )
givePriority = false;
if( DEBUG_PHASES ) {
System.out.println("\t\tStack: " + game.getStack());
System.out.print(FThreads.prependThreadId(debugPrintState(givePriority)));
System.out.print(FThreads.prependThreadId(debugPrintState(givePriorityToPlayer)));
}
if( givePriority ) {
if( givePriorityToPlayer ) {
if( DEBUG_PHASES )
sw.start();
@@ -747,13 +741,6 @@ public class PhaseHandler implements java.io.Serializable {
game.fireEvent(new GameEventGameRestarted(playerTurn));
return;
}
// Time to handle priority to next player.
if ( phase == PhaseType.COMBAT_DECLARE_ATTACKERS || phase == PhaseType.COMBAT_DECLARE_BLOCKERS)
game.getStack().freezeStack();
}
}

View File

@@ -15,9 +15,9 @@ public enum PhaseType {
MAIN1("Main, precombat", "Main1"),
COMBAT_BEGIN("Begin Combat", "BeginCombat"),
COMBAT_DECLARE_ATTACKERS("Declare Attackers"),
COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY("Declare Attackers - Play Instants and Abilities"),
//COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY("Declare Attackers - Play Instants and Abilities"),
COMBAT_DECLARE_BLOCKERS("Declare Blockers"),
COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY("Declare Blockers - Play Instants and Abilities"),
//COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY("Declare Blockers - Play Instants and Abilities"),
COMBAT_FIRST_STRIKE_DAMAGE("First Strike Damage"),
COMBAT_DAMAGE("Combat Damage"),
COMBAT_END("End Combat", "EndCombat"),
@@ -28,8 +28,8 @@ public enum PhaseType {
public static final List<PhaseType> ALL_PHASES = Collections.unmodifiableList(
Arrays.asList(
UNTAP, UPKEEP, DRAW, MAIN1,
COMBAT_BEGIN, COMBAT_DECLARE_ATTACKERS, COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY,
COMBAT_DECLARE_BLOCKERS, COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY,
COMBAT_BEGIN, COMBAT_DECLARE_ATTACKERS, //COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY,
COMBAT_DECLARE_BLOCKERS, // COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY,
COMBAT_FIRST_STRIKE_DAMAGE, COMBAT_DAMAGE, COMBAT_END,
MAIN2, END_OF_TURN, CLEANUP
)

View File

@@ -135,7 +135,10 @@ public abstract class PlayerController {
public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question);
public abstract List<Card> getCardsToMulligan(boolean isCommander, Player firstPlayer);
public abstract void declareAttackers();
public abstract void declareBlockers();
public abstract void takePriority();
public abstract List<Card> chooseCardsToDiscardToMaximumHandSize(int numDiscard);
public abstract boolean payManaOptional(Card card, Cost cost, String prompt, ManaPaymentPurpose purpose);
}

View File

@@ -286,6 +286,17 @@ public class PlayerControllerAi extends PlayerController {
return ComputerUtil.getPartialParisCandidates(player);
}
@Override
public void declareAttackers() {
brains.declareAttackers();
}
@Override
public void declareBlockers() {
brains.declateBlockers();
}
@Override
public void takePriority() {
if ( !game.isGameOver() )

View File

@@ -469,19 +469,21 @@ public class PlayerControllerHuman extends PlayerController {
return inp.isKeepHand() ? null : isCommander ? inp.getSelectedCards() : player.getCardsIn(ZoneType.Hand);
}
private void showDefaultInput() {
SpellAbility chosenSa = null;
do {
if (chosenSa != null) {
HumanPlay.playSpellAbility(player, chosenSa);
}
InputPassPriority defaultInput = new InputPassPriority(player);
Singletons.getControl().getInputQueue().setInputAndWait(defaultInput);
chosenSa = defaultInput.getChosenSa();
} while( chosenSa != null );
@Override
public void declareAttackers() {
game.getCombat().initiatePossibleDefenders(player.getOpponents());
// This input should not modify combat object itself, but should return user choice
InputSynchronized inpAttack = new InputAttack(player, game.getCombat());
Singletons.getControl().getInputQueue().setInputAndWait(inpAttack);
}
@Override
public void declareBlockers() {
// This input should not modify combat object itself, but should return user choice
InputSynchronized inpBlock = new InputBlock(player, game.getCombat());
Singletons.getControl().getInputQueue().setInputAndWait(inpBlock);
}
@Override
public void takePriority() {
@@ -492,22 +494,15 @@ public class PlayerControllerHuman extends PlayerController {
} else
autoPassCancel(); // probably cancel, since something has happened
switch(phase) {
case COMBAT_DECLARE_ATTACKERS:
game.getCombat().initiatePossibleDefenders(player.getOpponents());
InputSynchronized inpAttack = new InputAttack(player, game.getCombat());
Singletons.getControl().getInputQueue().setInputAndWait(inpAttack);
return;
case COMBAT_DECLARE_BLOCKERS:
InputSynchronized inpBlock = new InputBlock(player, game.getCombat());
Singletons.getControl().getInputQueue().setInputAndWait(inpBlock);
return;
default:
showDefaultInput();
}
SpellAbility chosenSa = null;
do {
if (chosenSa != null) {
HumanPlay.playSpellAbility(player, chosenSa);
}
InputPassPriority defaultInput = new InputPassPriority(player);
Singletons.getControl().getInputQueue().setInputAndWait(defaultInput);
chosenSa = defaultInput.getChosenSa();
} while( chosenSa != null );
}
@Override

View File

@@ -532,10 +532,8 @@ public class VField implements IVDoc<CField> {
case COMBAT_BEGIN:
return this.getLblBeginCombat();
case COMBAT_DECLARE_ATTACKERS:
case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY:
return this.getLblDeclareAttackers();
case COMBAT_DECLARE_BLOCKERS:
case COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY:
return this.getLblDeclareBlockers();
case COMBAT_DAMAGE:
return this.getLblCombatDamage();