From 9c7d1fe8b68f7cbcef8faae087a7719e37ed094c Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Tue, 23 Oct 2012 19:36:47 +0000 Subject: [PATCH] removed CombatUtil.canAttack method without specifying attack target --- src/main/java/forge/CardPredicates.java | 14 ----- .../abilityfactory/AbilityFactoryAttach.java | 12 ++--- .../abilityfactory/AbilityFactoryDebuff.java | 8 +-- .../abilityfactory/AbilityFactoryEffect.java | 21 ++++---- .../AbilityFactoryPermanentState.java | 17 ++++-- .../abilityfactory/AbilityFactoryPump.java | 54 +++++++++++-------- .../card/spellability/SpellPermanent.java | 2 +- .../forge/card/trigger/TriggerLosesGame.java | 1 - src/main/java/forge/game/phase/Combat.java | 2 +- .../java/forge/game/phase/CombatUtil.java | 27 +--------- .../java/forge/game/player/ComputerUtil.java | 7 ++- .../forge/game/player/ComputerUtilAttack.java | 38 ++++--------- .../java/forge/gui/match/QuestWinLose.java | 11 ++-- 13 files changed, 91 insertions(+), 123 deletions(-) diff --git a/src/main/java/forge/CardPredicates.java b/src/main/java/forge/CardPredicates.java index ec7c1c18f85..ac07aff71ed 100644 --- a/src/main/java/forge/CardPredicates.java +++ b/src/main/java/forge/CardPredicates.java @@ -120,13 +120,6 @@ public final class CardPredicates { }; } - public static final Predicate possibleAttackers = new Predicate() { - @Override - public boolean apply(final Card c) { - return (c.isCreature() && CombatUtil.canAttack(c)); - } - }; - public final static Predicate isProtectedFrom(final Card source) { return new Predicate() { @Override @@ -184,13 +177,6 @@ public final class CardPredicates { }; - public static final Predicate CREATURES_CAN_ATTACK = new Predicate() { - @Override - public boolean apply(final Card c) { - return c.isCreature() && CombatUtil.canAttack(c); - } - }; - /** * a Predicate to get all enchantments. */ diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryAttach.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryAttach.java index 67d4bf7968e..ce461fafb97 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryAttach.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryAttach.java @@ -392,11 +392,11 @@ public class AbilityFactoryAttach { * the logic * @return the card */ - public static Card attachGeneralAI(final Player aiPlayer, final SpellAbility sa, final List list, final boolean mandatory, + public static Card attachGeneralAI(final Player ai, final SpellAbility sa, final List list, final boolean mandatory, final Card attachSource, final String logic) { - Player prefPlayer = aiPlayer.getOpponent(); + Player prefPlayer = ai.getOpponent(); if ("Pump".equals(logic) || "Animate".equals(logic) ) { - prefPlayer = aiPlayer; + prefPlayer = ai; } // Some ChangeType cards are beneficial, and PrefPlayer should be // changed to represent that @@ -415,7 +415,7 @@ public class AbilityFactoryAttach { } else if ("Curse".equals(logic)) { c = AbilityFactoryAttach.attachAICursePreference(sa, prefList, mandatory, attachSource); } else if ("Pump".equals(logic)) { - c = AbilityFactoryAttach.attachAIPumpPreference(sa, prefList, mandatory, attachSource); + c = AbilityFactoryAttach.attachAIPumpPreference(ai, sa, prefList, mandatory, attachSource); } else if ("ChangeType".equals(logic)) { c = AbilityFactoryAttach.attachAIChangeTypePreference(sa, prefList, mandatory, attachSource); } else if ("KeepTapped".equals(logic)) { @@ -688,7 +688,7 @@ public class AbilityFactoryAttach { * the attach source * @return the card */ - public static Card attachAIPumpPreference(final SpellAbility sa, final List list, final boolean mandatory, + public static Card attachAIPumpPreference(final Player ai, final SpellAbility sa, final List list, final boolean mandatory, final Card attachSource) { // AI For choosing a Card to Pump Card c = null; @@ -724,7 +724,7 @@ public class AbilityFactoryAttach { magnetList = CardLists.filter(magnetList, new Predicate() { @Override public boolean apply(final Card c) { - return CombatUtil.canAttack(c); + return CombatUtil.canAttack(c, ai.getOpponent()); } }); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java index c3e8466e312..a5f65834200 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java @@ -800,7 +800,8 @@ public final class AbilityFactoryDebuff { // final Card source = sa.getSourceCard(); final Card hostCard = af.getHostCard(); final HashMap params = af.getMapParams(); - + final Player opp = ai.getOpponent(); + final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); // to // prevent // runaway @@ -812,16 +813,17 @@ public final class AbilityFactoryDebuff { List comp = ai.getCardsIn(ZoneType.Battlefield); comp = CardLists.getValidCards(comp, valid, hostCard.getController(), hostCard); - List human = ai.getOpponent().getCardsIn(ZoneType.Battlefield); + List human = opp.getCardsIn(ZoneType.Battlefield); human = CardLists.getValidCards(human, valid, hostCard.getController(), hostCard); // TODO - add blocking situations here also + // only count creatures that can attack human = CardLists.filter(human, new Predicate() { @Override public boolean apply(final Card c) { - return CombatUtil.canAttack(c); + return CombatUtil.canAttack(c, opp); } }); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java index d90978650ce..45c20d8c5ff 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java @@ -41,6 +41,7 @@ import forge.card.spellability.Target; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerType; +import forge.game.GameState; import forge.game.phase.CombatUtil; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; @@ -252,39 +253,41 @@ public class AbilityFactoryEffect { * @return a boolean. */ public static boolean effectCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { + final GameState game = Singletons.getModel().getGame(); final Random r = MyRandom.getRandom(); final HashMap params = af.getMapParams(); boolean randomReturn = r.nextFloat() <= .6667; + final Player opp = ai.getOpponent(); String logic = ""; if (params.containsKey("AILogic")) { logic = params.get("AILogic"); - final PhaseHandler phase = Singletons.getModel().getGame().getPhaseHandler(); + final PhaseHandler phase = game.getPhaseHandler(); if (logic.equals("BeginningOfOppTurn")) { if (phase.isPlayerTurn(ai.getOpponent()) || phase.getPhase().isAfter(PhaseType.DRAW)) { return false; } randomReturn = true; } else if (logic.equals("Fog")) { - if (Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) { + if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) { return false; } - if (!Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { + if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { return false; } - if (Singletons.getModel().getGame().getStack().size() != 0) { + if (game.getStack().size() != 0) { return false; } - if (Singletons.getModel().getGame().getPhaseHandler().isPreventCombatDamageThisTurn()) { + if (game.getPhaseHandler().isPreventCombatDamageThisTurn()) { return false; } - if (!CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())) { + if (!CombatUtil.lifeInDanger(ai, game.getCombat())) { return false; } final Target tgt = sa.getTarget(); if (tgt != null) { tgt.resetTargets(); - List list = Singletons.getModel().getGame().getCombat().getAttackerList(); + List list = game.getCombat().getAttackerList(); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); list = CardLists.getTargetableCards(list, sa); Card target = CardFactoryUtil.getBestCreatureAI(list); @@ -298,13 +301,13 @@ public class AbilityFactoryEffect { randomReturn = true; } else if (logic.equals("Evasion")) { List comp = ai.getCreaturesInPlay(); - List human = ai.getOpponent().getCreaturesInPlay(); + List human = opp.getCreaturesInPlay(); // only count creatures that can attack or block comp = CardLists.filter(comp, new Predicate() { @Override public boolean apply(final Card c) { - return CombatUtil.canAttack(c); + return CombatUtil.canAttack(c, opp); } }); human = CardLists.filter(human, new Predicate() { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java index 6125a47551e..92219e250bb 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java @@ -40,6 +40,7 @@ import forge.card.spellability.AbilitySub; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; +import forge.game.phase.CombatUtil; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.ComputerUtil; @@ -998,7 +999,7 @@ public class AbilityFactoryPermanentState { */ private static boolean tapPrefTargeting(final Player ai, final Card source, final Target tgt, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { - Player opp = ai.getOpponent(); + final Player opp = ai.getOpponent(); List tapList = opp.getCardsIn(ZoneType.Battlefield); tapList = CardLists.filter(tapList, Presets.UNTAPPED); tapList = CardLists.getValidCards(tapList, tgt.getValidTgts(), source.getController(), source); @@ -1038,7 +1039,12 @@ public class AbilityFactoryPermanentState { //Combat has already started attackers = Singletons.getModel().getGame().getCombat().getAttackerList(); } else { - attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES_CAN_ATTACK); + attackers = CardLists.filter(ai.getCreaturesInPlay(), new Predicate() { + @Override + public boolean apply(final Card c) { + return CombatUtil.canAttack(c, opp); + } + }); attackers.remove(sa.getSourceCard()); } Predicate findBlockers = CardPredicates.possibleBlockerForAtLeastOne(attackers); @@ -1051,7 +1057,12 @@ public class AbilityFactoryPermanentState { && phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) { // Tap creatures possible blockers before combat during AI's turn. if (Iterables.any(tapList, CardPredicates.Presets.CREATURES)) { - List creatureList = CardLists.filter(tapList, CardPredicates.Presets.CREATURES_CAN_ATTACK); + List creatureList = CardLists.filter(tapList, new Predicate() { + @Override + public boolean apply(final Card c) { + return c.isCreature() && CombatUtil.canAttack(c, opp); + } + }); choice = CardFactoryUtil.getBestCreatureAI(creatureList); } else { // no creatures available choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java index 8783a6c1e2a..43cc18f69bb 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java @@ -318,20 +318,20 @@ public class AbilityFactoryPump { if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) { return false; } else if (keyword.equals("Defender") || keyword.endsWith("CARDNAME can't attack.")) { - if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card) + if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card, human) || (card.getNetCombatDamage() <= 0) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { return false; } } else if (keyword.endsWith("CARDNAME can't attack or block.")) { if (sa.getAbilityFactory().getMapParams().containsKey("UntilYourNextTurn")) { - if (CombatUtil.canAttack(card) || CombatUtil.canBlock(card, true)) { + if (CombatUtil.canAttack(card, human) || CombatUtil.canBlock(card, true)) { return true; } return false; } if (ph.isPlayerTurn(human)) { - if (!CombatUtil.canAttack(card) + if (!CombatUtil.canAttack(card, human) || (card.getNetCombatDamage() <= 0) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { return false; @@ -342,7 +342,12 @@ public class AbilityFactoryPump { return false; } - List attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers); + List attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), new Predicate() { + @Override + public boolean apply(final Card c) { + return (c.isCreature() && CombatUtil.canAttack(c, human)); + } + }); if (!CombatUtil.canBlockAtLeastOne(card, attackers)) { return false; } @@ -353,7 +358,12 @@ public class AbilityFactoryPump { return false; } - List attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers); + List attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), new Predicate() { + @Override + public boolean apply(final Card c) { + return (c.isCreature() && CombatUtil.canAttack(c, human)); + } + }); if (!CombatUtil.canBlockAtLeastOne(card, attackers)) { return false; } @@ -376,7 +386,7 @@ public class AbilityFactoryPump { return false; } } else if (keyword.endsWith("CARDNAME attacks each turn if able.")) { - if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card) + if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card, human) || !CombatUtil.canBeBlocked(card) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { return false; } @@ -418,7 +428,7 @@ public class AbilityFactoryPump { || keyword.contains("Bushido")); // give evasive keywords to creatures that can or do attack if (evasive) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || cardsCanBlock.isEmpty()) { @@ -434,7 +444,7 @@ public class AbilityFactoryPump { return true; } Predicate flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach")); - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || !Iterables.any(cardsCanBlock, Predicates.not(flyingOrReach))) { return false; @@ -447,7 +457,7 @@ public class AbilityFactoryPump { && CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())) { return true; } - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || CardLists.getNotKeyword(cardsCanBlock, "Horsemanship").isEmpty()) { @@ -474,7 +484,7 @@ public class AbilityFactoryPump { } } } else if (ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) - && CombatUtil.canAttack(card)) { + && CombatUtil.canAttack(card, opp)) { List blockers = opp.getCreaturesInPlay(); for (Card blocker : blockers) { if (CombatUtil.canBlock(card, blocker, combat) @@ -485,32 +495,32 @@ public class AbilityFactoryPump { } return false; } else if (combatRelevant) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) || (opp.getCreaturesInPlay().size() < 1) || cardsCanBlock.isEmpty()) { return false; } } else if (keyword.equals("Double Strike")) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || card.getNetCombatDamage() <= 0 || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { return false; } } else if (keyword.startsWith("Rampage")) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || cardsCanBlock.size() < 2) { return false; } } else if (keyword.startsWith("Flanking")) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || CardLists.getNotKeyword(cardsCanBlock, "Flanking").isEmpty()) { return false; } } else if (keyword.startsWith("Trample")) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || !CombatUtil.canBeBlocked(card) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || cardsCanBlock.isEmpty() @@ -525,7 +535,7 @@ public class AbilityFactoryPump { return true; } if ((ph.isPlayerTurn(opp)) - || !(CombatUtil.canAttack(card) || card.isAttacking()) + || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { return false; } @@ -548,7 +558,7 @@ public class AbilityFactoryPump { return false; } } else if (keyword.equals("Vigilance")) { - if (ph.isPlayerTurn(opp) || !CombatUtil.canAttack(card) + if (ph.isPlayerTurn(opp) || !CombatUtil.canAttack(card, opp) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) || CardLists.getNotKeyword(opp.getCreaturesInPlay(), "Defender").size() < 1) { return false; @@ -584,7 +594,7 @@ public class AbilityFactoryPump { return false; } } else if (keyword.equals("Islandwalk")) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || CardLists.getType(opp.getLandsInPlay(), "Island").isEmpty() @@ -592,7 +602,7 @@ public class AbilityFactoryPump { return false; } } else if (keyword.equals("Swampwalk")) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || CardLists.getType(opp.getLandsInPlay(), "Swamp").isEmpty() @@ -600,7 +610,7 @@ public class AbilityFactoryPump { return false; } } else if (keyword.equals("Mountainwalk")) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || CardLists.getType(opp.getLandsInPlay(), "Mountain").isEmpty() @@ -608,7 +618,7 @@ public class AbilityFactoryPump { return false; } } else if (keyword.equals("Forestwalk")) { - if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || CardLists.getType(opp.getLandsInPlay(), "Forest").isEmpty() @@ -1810,7 +1820,7 @@ public class AbilityFactoryPump { if (phase.equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) && c.isAttacking()) { return true; } - if (phase.isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && CombatUtil.canAttack(c)) { + if (phase.isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && CombatUtil.canAttack(c, opp)) { return true; } return false; diff --git a/src/main/java/forge/card/spellability/SpellPermanent.java b/src/main/java/forge/card/spellability/SpellPermanent.java index 7f400a5bdc0..5ad8a705c84 100644 --- a/src/main/java/forge/card/spellability/SpellPermanent.java +++ b/src/main/java/forge/card/spellability/SpellPermanent.java @@ -291,7 +291,7 @@ public class SpellPermanent extends Spell { } // Wait for Main2 if possible if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.MAIN1) - && !ComputerUtil.castPermanentInMain1(this, ai)) { + && !ComputerUtil.castPermanentInMain1(ai, this)) { return false; } // save cards with flash for surprise blocking diff --git a/src/main/java/forge/card/trigger/TriggerLosesGame.java b/src/main/java/forge/card/trigger/TriggerLosesGame.java index 426eacb4652..8ebe30f0357 100644 --- a/src/main/java/forge/card/trigger/TriggerLosesGame.java +++ b/src/main/java/forge/card/trigger/TriggerLosesGame.java @@ -3,7 +3,6 @@ package forge.card.trigger; import java.util.HashMap; import forge.Card; -import forge.card.TriggerReplacementBase; import forge.card.spellability.SpellAbility; /** diff --git a/src/main/java/forge/game/phase/Combat.java b/src/main/java/forge/game/phase/Combat.java index 3164b938e7b..7483e5b87d9 100644 --- a/src/main/java/forge/game/phase/Combat.java +++ b/src/main/java/forge/game/phase/Combat.java @@ -546,7 +546,7 @@ public class Combat { */ public Player getDefendingPlayerRelatedTo(final Card source) { - Player defender = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().getOpponent(); + Player defender = getDefenderPlayerByAttacker(source); Card attacker = source; if (source.isAura()) { attacker = source.getEnchantingCard(); diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index d0ab25a04cf..cbee9d9d105 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -810,32 +810,9 @@ public class CombatUtil { if (cntAttackers > 0 && Singletons.getModel().getGame().isCardInPlay("Dueling Grounds")) { return false; } - - Player defender = c.getController().getOpponent(); - if (combat != null) { - final GameEntity def = combat.getDefender(); - if (def instanceof Player) { - defender = (Player) def; - } else { - defender = ((Card) def).getController(); - } - } - return CombatUtil.canAttack(c, defender); - } - - // can a creature attack at the moment? - /** - *

- * canAttack. - *

- * - * @param c - * a {@link forge.Card} object. - * @return a boolean. - */ - public static boolean canAttack(final Card c) { - return canAttack(c, c.getController().getOpponent()); + final GameEntity def = combat.getDefender(); + return CombatUtil.canAttack(c, def instanceof Player ? (Player) def : ((Card) def).getController()); } // can a creature attack at the moment? diff --git a/src/main/java/forge/game/player/ComputerUtil.java b/src/main/java/forge/game/player/ComputerUtil.java index e4da5ac0933..9a7412fedbf 100644 --- a/src/main/java/forge/game/player/ComputerUtil.java +++ b/src/main/java/forge/game/player/ComputerUtil.java @@ -1768,8 +1768,7 @@ public class ComputerUtil { */ public static Combat getAttackers(final Player ai) { final Player opp = ai.getOpponent(); - final ComputerUtilAttack att = new ComputerUtilAttack(ai.getCardsIn(ZoneType.Battlefield), - opp.getCardsIn(ZoneType.Battlefield)); + final ComputerUtilAttack att = new ComputerUtilAttack(ai, opp); return att.getAttackers(ai, opp); } @@ -2040,7 +2039,7 @@ public class ComputerUtil { * a SpellAbility object. * @return a boolean. */ - public static boolean castPermanentInMain1(final SpellAbility sa, final Player ai) { + public static boolean castPermanentInMain1(final Player ai, final SpellAbility sa) { final Card card = sa.getSourceCard(); if (card.getSVar("PlayMain1").equals("TRUE")) { return true; @@ -2061,7 +2060,7 @@ public class ComputerUtil { return true; } } - if (card.isEquipment() && buffedcard.isCreature() && CombatUtil.canAttack(buffedcard)) { + if (card.isEquipment() && buffedcard.isCreature() && CombatUtil.canAttack(buffedcard, ai.getOpponent())) { return true; } if (card.isCreature() && buffedcard.hasKeyword("Soulbond") && !buffedcard.isPaired()) { diff --git a/src/main/java/forge/game/player/ComputerUtilAttack.java b/src/main/java/forge/game/player/ComputerUtilAttack.java index d68340a97ff..04e00ffac7b 100644 --- a/src/main/java/forge/game/player/ComputerUtilAttack.java +++ b/src/main/java/forge/game/player/ComputerUtilAttack.java @@ -26,7 +26,6 @@ import com.google.common.base.Predicate; import forge.Card; import forge.CardLists; -import forge.CardPredicates; import forge.Counters; import forge.GameEntity; import forge.Singletons; @@ -74,15 +73,16 @@ public class ComputerUtilAttack { * @param possibleBlockers * a {@link forge.CardList} object. */ - public ComputerUtilAttack(final List possibleAttackers, final List possibleBlockers) { - this.humanList = new ArrayList(possibleBlockers); - this.humanList = CardLists.filter(this.humanList, CardPredicates.Presets.CREATURES); + public ComputerUtilAttack(final Player ai, final Player human) { + this.humanList = human.getCreaturesInPlay(); + this.computerList = ai.getCreaturesInPlay(); - this.computerList = new ArrayList(possibleAttackers); - this.computerList = CardLists.filter(this.computerList, CardPredicates.Presets.CREATURES); - - this.attackers = this.getPossibleAttackers(possibleAttackers); - this.blockers = this.getPossibleBlockers(possibleBlockers, this.attackers); + this.attackers = new ArrayList(); + for(Card c : computerList) + if (CombatUtil.canAttack(c, human)) + attackers.add(c); + + this.blockers = this.getPossibleBlockers(humanList, this.attackers); } // constructor /** @@ -157,26 +157,6 @@ public class ComputerUtilAttack { return false; } - /** - *

- * getPossibleAttackers. - *

- * - * @param in - * a {@link forge.CardList} object. - * @return a {@link forge.CardList} object. - */ - public final List getPossibleAttackers(final List in) { - List list = new ArrayList(in); - list = CardLists.filter(list, new Predicate() { - @Override - public boolean apply(final Card c) { - return CombatUtil.canAttack(c); - } - }); - return list; - } // getPossibleAttackers() - /** *

* getPossibleBlockers. diff --git a/src/main/java/forge/gui/match/QuestWinLose.java b/src/main/java/forge/gui/match/QuestWinLose.java index adcca0887cd..06a1fb1f921 100644 --- a/src/main/java/forge/gui/match/QuestWinLose.java +++ b/src/main/java/forge/gui/match/QuestWinLose.java @@ -164,6 +164,7 @@ public class QuestWinLose extends ControlWinLose { // TODO: We don't have a enum for difficulty? int difficulty = qData.getAchievements().getDifficulty(); + final int wins = qData.getAchievements().getWin(); // Win case if (this.wonMatch) { @@ -189,17 +190,17 @@ public class QuestWinLose extends ControlWinLose { if ((wins > 0) && ((wins % 80) == 0)) { this.awardJackpot(); } + + // Unlock new sets? + if (wins % 50 == 49) { + unlockSets(); + } } // Lose case else { this.penalizeLoss(); } - // Unlock new sets? - if (this.wonMatch && wins % 50 == 49) { - unlockSets(); - } - // Grant booster on a win, or on a loss in easy mode if (this.wonMatch || difficulty == 0) { final int outcome = this.wonMatch ? wins : qData.getAchievements().getLost();