diff --git a/src/main/java/forge/control/input/InputAttack.java b/src/main/java/forge/control/input/InputAttack.java index 4d23e46dcb2..ed5557a3b84 100644 --- a/src/main/java/forge/control/input/InputAttack.java +++ b/src/main/java/forge/control/input/InputAttack.java @@ -99,6 +99,8 @@ public class InputAttack extends InputBase { public final void selectButtonOK() { // Propaganda costs could have been paid here. setCurrentDefender(null); // remove highlights + + game.getPhaseHandler().setCombat(!game.getCombat().getAttackers().isEmpty()); game.getPhaseHandler().setPlayersPriorityPermission(false); Singletons.getModel().getMatch().getInput().updateObservers(); } diff --git a/src/main/java/forge/game/ai/ComputerUtilBlock.java b/src/main/java/forge/game/ai/ComputerUtilBlock.java index 85701996508..bb0f553b23a 100644 --- a/src/main/java/forge/game/ai/ComputerUtilBlock.java +++ b/src/main/java/forge/game/ai/ComputerUtilBlock.java @@ -265,17 +265,19 @@ public class ComputerUtilBlock { return blockers; } - /** - *

- * sortPotentialAttackers. - *

- * - * @param combat - * a {@link forge.game.phase.Combat} object. - * @return a {@link forge.CardList} object. - */ + + + public final static List> sortAttackerByDefender(Combat combat) { + List defenders = combat.getDefenders(); + final ArrayList> attackers = new ArrayList>(defenders.size()); + for (GameEntity defender : defenders) { + attackers.add(combat.getAttackersOf(defender)); + } + return attackers; + } + public static List sortPotentialAttackers(final Player ai, final Combat combat) { - final List> attackerLists = combat.sortAttackerByDefender(); + final List> attackerLists = sortAttackerByDefender(combat); final List sortedAttackers = new ArrayList(); final List firstAttacker = attackerLists.get(0); diff --git a/src/main/java/forge/game/phase/Combat.java b/src/main/java/forge/game/phase/Combat.java index d6c5e9b2235..8864d4f021c 100644 --- a/src/main/java/forge/game/phase/Combat.java +++ b/src/main/java/forge/game/phase/Combat.java @@ -229,26 +229,14 @@ public class Combat { } } - /** - *

- * sortAttackerByDefender. - *

- * - * @return an array of {@link forge.CardList} objects. - */ - public final List> sortAttackerByDefender() { - int size = this.defenders.size(); - final ArrayList> attackers = new ArrayList>(size); - for (int i = 0; i < size; i++) { - attackers.add(getAttackersByDefenderSlot(i)); - } - return attackers; - } - public final List getAttackersByDefenderSlot(int slot) { GameEntity entity = this.defenders.get(slot); return this.defenderMap.get(entity); } + + public final List getAttackersOf(GameEntity defender) { + return defenderMap.get(defender); + } /** *

diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index e061432856b..d637f8570b1 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -59,6 +59,7 @@ import forge.gui.GuiDialog; import forge.gui.framework.EDocID; import forge.gui.framework.SDisplayUtil; import forge.gui.match.controllers.CCombat; +import forge.util.Lang; /** @@ -977,22 +978,18 @@ public class CombatUtil { // Loop through Defenders // Append Defending Player/Planeswalker final Combat combat = game.getCombat(); - final List defenders = combat.getDefenders(); - final List> attackers = combat.sortAttackerByDefender(); + // Not a big fan of the triple nested loop here - for (int def = 0; def < defenders.size(); def++) { - List attacker = attackers.get(def); - if ((attacker == null) || (attacker.size() == 0)) { + for (GameEntity defender : combat.getDefenders()) { + List attackers = combat.getAttackersOf(defender); + if (attackers == null || attackers.isEmpty()) { continue; } + if ( sb.length() > 0 ) sb.append("\n"); - sb.append(combat.getAttackingPlayer()).append(" declared "); - for (final Card atk : attacker) { - sb.append(atk).append(" "); - } - - sb.append("attacking ").append(defenders.get(def).toString()).append("."); + sb.append(combat.getAttackingPlayer()).append(" declared ").append(Lang.joinHomogenous(attackers)); + sb.append(" to attack ").append(defender.toString()).append("."); } return sb.toString(); @@ -1007,35 +1004,34 @@ public class CombatUtil { public static String getCombatBlockForLog(GameState game) { final StringBuilder sb = new StringBuilder(); - List defend = null; - // Loop through Defenders // Append Defending Player/Planeswalker final Combat combat = game.getCombat(); - final List defenders = combat.getDefenders(); - final List> attackers = combat.sortAttackerByDefender(); + List blockers = null; + - // Not a big fan of the triple nested loop here - for (int def = 0; def < defenders.size(); def++) { - final List list = attackers.get(def); + for (GameEntity defender : combat.getDefenders()) { + List attackers = combat.getAttackersOf(defender); + if (attackers == null || attackers.isEmpty()) { + continue; + } + if ( sb.length() > 0 ) sb.append("\n"); - for (final Card attacker : list) { - - - defend = game.getCombat().getBlockers(attacker); - sb.append(combat.getDefenderByAttacker(attacker)).append(" assigned "); - - if (!defend.isEmpty()) { - // loop through blockers - for (final Card blocker : defend) { - sb.append(blocker).append(" "); - } + String controllerName = defender instanceof Card ? ((Card)defender).getController().getName() : defender.getName(); + boolean firstAttacker = true; + for (final Card attacker : attackers) { + if ( !firstAttacker ) sb.append("\n"); + + blockers = game.getCombat().getBlockers(attacker); + if ( blockers.isEmpty() ) { + sb.append(controllerName).append(" didn't block "); } else { - sb.append(" "); + sb.append(controllerName).append(" assigned ").append(Lang.joinHomogenous(blockers)).append(" to block "); } - - sb.append("to block ").append(attacker).append(". "); - } // loop through attackers + + sb.append(attacker).append("."); + firstAttacker = false; + } } return sb.toString(); diff --git a/src/main/java/forge/gui/match/controllers/CCombat.java b/src/main/java/forge/gui/match/controllers/CCombat.java index 21b3e4c24f3..45e24106cf4 100644 --- a/src/main/java/forge/gui/match/controllers/CCombat.java +++ b/src/main/java/forge/gui/match/controllers/CCombat.java @@ -7,8 +7,10 @@ import forge.Command; import forge.GameEntity; import forge.game.GameState; import forge.game.phase.Combat; +import forge.game.player.Player; import forge.gui.framework.ICDoc; import forge.gui.match.views.VCombat; +import forge.util.Lang; /** * Controls the combat panel in the match UI. @@ -57,37 +59,34 @@ public enum CCombat implements ICDoc { private static String getCombatDescription(Combat combat) { final StringBuilder display = new StringBuilder(); - // Loop through Defenders - // Append Defending Player/Planeswalker - final List defenders = combat.getDefenders(); - final List> attackers = combat.sortAttackerByDefender(); - // Not a big fan of the triple nested loop here - for (int def = 0; def < defenders.size(); def++) { - List atk = attackers.get(def); - if ((atk == null) || (atk.size() == 0)) { + for (GameEntity defender : combat.getDefenders()) { + List atk = combat.getAttackersOf(defender); + if (atk == null || atk.isEmpty()) { continue; } - if (def > 0) { + if (display.length() > 0) { display.append("\n"); } - display.append("Defender - "); - display.append(defenders.get(def).toString()); - display.append("\n"); + if (defender instanceof Card) { + Player controller = ((Card) defender).getController(); + display.append(Lang.getPossesive(controller.getName())).append(" "); + } + + display.append(defender.getName()).append(" is attacked by:\n"); for (final Card c : atk) { // loop through attackers - display.append("-> "); + display.append(" > "); display.append(combatantToString(c)).append("\n"); List blockers = combat.getBlockers(c); // loop through blockers for (final Card element : blockers) { - display.append(" [ "); - display.append(combatantToString(element)).append("\n"); + display.append(" < ").append(combatantToString(element)).append("\n"); } } // loop through attackers } @@ -107,10 +106,11 @@ public enum CCombat implements ICDoc { final StringBuilder sb = new StringBuilder(); final String name = (c.isFaceDown()) ? "Morph" : c.getName(); - + + sb.append("( ").append(c.getNetAttack()).append(" / ").append(c.getNetDefense()).append(" ) ... "); sb.append(name); - sb.append(" (").append(c.getUniqueNumber()).append(") "); - sb.append(c.getNetAttack()).append("/").append(c.getNetDefense()); + sb.append(" [").append(c.getUniqueNumber()).append("] "); + return sb.toString(); } diff --git a/src/main/java/forge/util/Lang.java b/src/main/java/forge/util/Lang.java index 843c56a7d81..1044bec063d 100644 --- a/src/main/java/forge/util/Lang.java +++ b/src/main/java/forge/util/Lang.java @@ -42,4 +42,13 @@ public class Lang { } return sb.toString(); } + + /** + * TODO: Write javadoc for this method. + * @param name + * @return + */ + public static String getPossesive(String name) { + return name.endsWith("s") ? name + "'" : name + "'s"; + } }