diff --git a/src/main/java/forge/control/input/InputBlock.java b/src/main/java/forge/control/input/InputBlock.java index 9e0e2833592..7ce06a203e3 100644 --- a/src/main/java/forge/control/input/InputBlock.java +++ b/src/main/java/forge/control/input/InputBlock.java @@ -25,6 +25,7 @@ import forge.Card; import forge.Singletons; import forge.game.phase.CombatUtil; +import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; import forge.gui.framework.SDisplayUtil; @@ -46,6 +47,15 @@ public class InputBlock extends Input { private Card currentAttacker = null; private final HashMap> allBlocking = new HashMap>(); + private final Player defender; + + /** + * TODO: Write javadoc for Constructor. + * @param priority + */ + public InputBlock(Player priority) { + defender = priority; + } /** *

@@ -86,7 +96,7 @@ public class InputBlock extends Input { /** {@inheritDoc} */ @Override public final void selectButtonOK() { - if (CombatUtil.finishedMandatoryBlocks(Singletons.getModel().getGame().getCombat())) { + if (CombatUtil.finishedMandatoryBlocks(Singletons.getModel().getGame().getCombat(), defender)) { // Done blocking ButtonUtil.reset(); CombatUtil.orderMultipleCombatants(Singletons.getModel().getGame().getCombat()); @@ -106,8 +116,8 @@ public class InputBlock extends Input { reminder = false; } else { // Make sure this card is valid to even be a blocker - if (this.currentAttacker != null && card.isCreature() && card.getController().isHuman() - && zone.is(ZoneType.Battlefield, Singletons.getControl().getPlayer())) { + if (this.currentAttacker != null && card.isCreature() && card.getController().equals(defender) + && zone.is(ZoneType.Battlefield, defender)) { // Create a new blockedBy list if it doesn't exist if (!this.allBlocking.containsKey(card)) { this.allBlocking.put(card, new ArrayList()); diff --git a/src/main/java/forge/control/input/InputControl.java b/src/main/java/forge/control/input/InputControl.java index 86e95f29b09..db4551cadc3 100644 --- a/src/main/java/forge/control/input/InputControl.java +++ b/src/main/java/forge/control/input/InputControl.java @@ -212,7 +212,7 @@ public class InputControl extends MyObservable implements java.io.Serializable { } if ( priority.isHuman() ) - return new InputBlock(); + return new InputBlock(priority); // ai is under attack priority.getController().getAiInput().getComputer().declareBlockers(); diff --git a/src/main/java/forge/game/phase/Combat.java b/src/main/java/forge/game/phase/Combat.java index 33f9b354e4d..7483e5b87d9 100644 --- a/src/main/java/forge/game/phase/Combat.java +++ b/src/main/java/forge/game/phase/Combat.java @@ -66,7 +66,6 @@ public class Combat { private final HashMap attackerToDefender = new HashMap(); private Player attackingPlayer = null; - private Player defendingPlayer = null; /** *

@@ -90,7 +89,6 @@ public class Combat { this.defendingDamageMap.clear(); this.attackingPlayer = null; - this.defendingPlayer = null; this.currentDefender = 0; this.nextDefender = 0; @@ -250,18 +248,6 @@ public class Combat { this.attackingPlayer = player; } - /** - *

- * Setter for the field defendingPlayer. - *

- * - * @param player - * a {@link forge.game.player.Player} object. - */ - public final void setDefendingPlayer(final Player player) { - this.defendingPlayer = player; - } - /** *

* Getter for the field attackingPlayer. @@ -277,20 +263,6 @@ public class Combat { } } - /** - *

- * Getter for the field defendingPlayer. - *

- * - * @return a {@link forge.game.player.Player} object. - */ - public final Player getDefendingPlayer() { - if (this.attackingPlayer != null) { - return this.defendingPlayer; - } else { - return Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().getOpponent(); - } - } /** *

@@ -410,6 +382,19 @@ public class Combat { return this.attackerToDefender.get(c); } + public final Player getDefenderPlayerByAttacker(final Card c) { + GameEntity defender = getDefenderByAttacker(c); + + // System.out.println(c.toString() + " attacks " + defender.toString()); + if ( defender instanceof Player) + return (Player) defender; + + // maybe attack on a controlled planeswalker? + if ( defender instanceof Card ) + return ((Card)defender).getController(); + return null; + } + public final GameEntity getDefendingEntity(final Card c) { GameEntity defender = this.attackerToDefender.get(c); @@ -561,7 +546,7 @@ public class Combat { */ public Player getDefendingPlayerRelatedTo(final Card source) { - Player defender = this.getDefendingPlayer(); + Player defender = getDefenderPlayerByAttacker(source); Card attacker = source; if (source.isAura()) { attacker = source.getEnchantingCard(); @@ -1002,16 +987,7 @@ public class Combat { // System.out.println("\nWho attacks attacks " + priority.toString() + "?"); for(Card c : getAttackers()) { - GameEntity defender = getDefenderByAttacker(c); - // System.out.println(c.toString() + " attacks " + defender.toString()); - - if ( defender.equals(priority) ) { - return true; - } - // maybe attack on a controlled planeswalker? - if (!(defender instanceof Card)) continue; - Card pw = (Card)defender; - if( pw.getController().equals(priority) ) { + if ( priority.equals(getDefenderPlayerByAttacker(c)) ) { return true; } } diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index b121293cfcc..78c8430c76e 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -377,7 +377,7 @@ public class CombatUtil { * a {@link forge.game.phase.Combat} object. * @return a boolean. */ - public static boolean finishedMandatoryBlocks(final Combat combat) { + public static boolean finishedMandatoryBlocks(final Combat combat, final Player defending) { final List blockers = Singletons.getControl().getPlayer().getCreaturesInPlay(); final List attackers = combat.getAttackerList(); @@ -395,7 +395,7 @@ public class CombatUtil { if (CombatUtil.canBlock(attacker, blocker, combat)) { boolean must = true; if (attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures.")) { - final List possibleBlockers = CardLists.filter(combat.getDefendingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES); + final List possibleBlockers = CardLists.filter(defending.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES); possibleBlockers.remove(blocker); if (!CombatUtil.canBeBlocked(attacker, possibleBlockers)) { must = false; @@ -455,16 +455,14 @@ public class CombatUtil { private static void orderBlockingMultipleAttackers(final Combat combat) { // If there are multiple blockers, the Attacker declares the Assignment Order - final Player player = combat.getDefendingPlayer(); - final List blockers = combat.getAllBlockers(); - for (final Card blocker : blockers) { + for (final Card blocker : combat.getAllBlockers()) { List attackers = combat.getAttackersBlockedBy(blocker); if (attackers.size() <= 1) { continue; } List orderedAttacker = null; - if (player.isHuman()) { + if (blocker.getController().isHuman()) { List ordered = GuiChoose.getOrderChoices("Choose Blocking Order", "Damaged First", 0, attackers, null, blocker); orderedAttacker = new ArrayList(); @@ -518,7 +516,7 @@ public class CombatUtil { if (CombatUtil.canBeBlocked(attacker, combat) && CombatUtil.canBlock(attacker, blocker)) { boolean canBe = true; if (attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures.")) { - final List blockers = CardLists.filter(combat.getDefendingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES); + final List blockers = combat.getDefenderPlayerByAttacker(attacker).getCreaturesInPlay(); blockers.remove(blocker); if (!CombatUtil.canBeBlocked(attacker, blockers)) { canBe = false; @@ -535,7 +533,7 @@ public class CombatUtil { if (CombatUtil.canBeBlocked(attacker, combat) && CombatUtil.canBlock(attacker, blocker)) { boolean canBe = true; if (attacker.hasKeyword("CARDNAME can't be blocked except by two or more creatures.")) { - final List blockers = CardLists.filter(combat.getDefendingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES); + final List blockers = combat.getDefenderPlayerByAttacker(attacker).getCreaturesInPlay(); blockers.remove(blocker); if (!CombatUtil.canBeBlocked(attacker, blockers)) { canBe = false; @@ -2523,10 +2521,11 @@ public class CombatUtil { final List list = attackers.get(def); for (final Card attacker : list) { - sb.append(combat.getDefendingPlayer()).append(" assigned "); + defend = Singletons.getModel().getGame().getCombat().getBlockers(attacker); - + sb.append(combat.getDefenderByAttacker(attacker)).append(" assigned "); + if (!defend.isEmpty()) { // loop through blockers for (final Card blocker : defend) { diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index ad01c7d9e5e..728bab7a2ba 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -26,7 +26,6 @@ import com.esotericsoftware.minlog.Log; import forge.Card; import forge.CardLists; import forge.CardPredicates; -import forge.GameActionUtil; import forge.Singletons; import forge.card.trigger.TriggerType; import forge.game.GameState; @@ -455,13 +454,11 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { // that give extra combat can do it like ExtraTurn stack ExtraPhases if (this.extraCombats > 0) { final Player player = this.getPlayerTurn(); - final Player opp = player.getOpponent(); this.bCombat = true; this.extraCombats--; game.getCombat().reset(); game.getCombat().setAttackingPlayer(player); - game.getCombat().setDefendingPlayer(opp); this.phase = PhaseType.COMBAT_BEGIN; } break; @@ -539,7 +536,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { if (!this.extraTurns.isEmpty()) { ExtraTurn extraTurn = this.extraTurns.pop(); nextTurn = extraTurn.getPlayer(); - if (skipTurnTimeVault(nextTurn)) { + if (nextTurn.skipTurnTimeVault()) { return getNextActivePlayer(); } if (extraTurn.isLoseAtEndStep()) { @@ -550,42 +547,13 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { } return nextTurn; } - if (skipTurnTimeVault(nextTurn)) { + if (nextTurn.skipTurnTimeVault()) { this.setPlayerTurn(nextTurn); return getNextActivePlayer(); } return nextTurn; } - /** - *

- * skipTurnTimeVault. - *

- * - * @param turn - * a {@link forge.game.player.Player} object. - * @return a {@link forge.game.player.Player} object. - */ - private boolean skipTurnTimeVault(Player turn) { - // time vault: - List vaults = turn.getCardsIn(ZoneType.Battlefield, "Time Vault"); - vaults = CardLists.filter(vaults, CardPredicates.Presets.TAPPED); - - if (vaults.size() > 0) { - final Card crd = vaults.get(0); - - if (turn.isHuman()) { - if (GameActionUtil.showYesNoDialog(crd, "Untap " + crd + "?")) { - crd.untap(); - return true; - } - } else { - // TODO Should AI skip his turn for time vault? - } - } - return false; - } - /** *

* is. diff --git a/src/main/java/forge/game/phase/PhaseUtil.java b/src/main/java/forge/game/phase/PhaseUtil.java index 995614f229e..e1c8db33c45 100644 --- a/src/main/java/forge/game/phase/PhaseUtil.java +++ b/src/main/java/forge/game/phase/PhaseUtil.java @@ -81,7 +81,6 @@ public class PhaseUtil { game.getCombat().reset(); game.getCombat().setAttackingPlayer(turn); - game.getCombat().setDefendingPlayer(turn.getOpponent()); // Tokens starting game in play now actually suffer from Sum. Sickness // again diff --git a/src/main/java/forge/game/player/ComputerUtil.java b/src/main/java/forge/game/player/ComputerUtil.java index 4beaae9be7a..e4da5ac0933 100644 --- a/src/main/java/forge/game/player/ComputerUtil.java +++ b/src/main/java/forge/game/player/ComputerUtil.java @@ -1771,7 +1771,7 @@ public class ComputerUtil { final ComputerUtilAttack att = new ComputerUtilAttack(ai.getCardsIn(ZoneType.Battlefield), opp.getCardsIn(ZoneType.Battlefield)); - return att.getAttackers(ai); + return att.getAttackers(ai, opp); } /** diff --git a/src/main/java/forge/game/player/ComputerUtilAttack.java b/src/main/java/forge/game/player/ComputerUtilAttack.java index 8af3f02bec0..d68340a97ff 100644 --- a/src/main/java/forge/game/player/ComputerUtilAttack.java +++ b/src/main/java/forge/game/player/ComputerUtilAttack.java @@ -493,7 +493,7 @@ public class ComputerUtilAttack { * * @return a {@link forge.game.phase.Combat} object. */ - public final Combat getAttackers(final Player ai) { + public final Combat getAttackers(final Player ai, final Player opponent) { // if this method is called multiple times during a turn, // it will always return the same value // randomInt is used so that the computer doesn't always @@ -505,9 +505,9 @@ public class ComputerUtilAttack { final Combat combat = new Combat(); combat.setAttackingPlayer(game.getCombat().getAttackingPlayer()); - combat.setDefendingPlayer(game.getCombat().getDefendingPlayer()); - game.getCombat().initiatePossibleDefenders(game.getCombat().getDefendingPlayer()); + + game.getCombat().initiatePossibleDefenders(opponent); combat.setDefenders(game.getCombat().getDefenders()); if (this.attackers.isEmpty()) { diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index 5d5f8df16e7..d21f84e55da 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -2865,5 +2865,32 @@ public abstract class Player extends GameEntity implements Comparable { return false; } + + /** + *

+ * skipTurnTimeVault. + *

+ * + * @return a {@link forge.game.player.Player} object. + */ + public boolean skipTurnTimeVault() { + // time vault: + List vaults = getCardsIn(ZoneType.Battlefield, "Time Vault"); + vaults = CardLists.filter(vaults, Presets.TAPPED); + + if (vaults.size() > 0) { + final Card crd = vaults.get(0); + + if (isHuman()) { + if (GameActionUtil.showYesNoDialog(crd, "Untap " + crd + "?")) { + crd.untap(); + return true; + } + } else { + // TODO Should AI skip his turn for time vault? + } + } + return false; + } }