From bf5bd91e9adb9e6bdbb254a6c948f81dce1819ce Mon Sep 17 00:00:00 2001
From: Maxmtg
Date: Sun, 2 Jun 2013 15:08:37 +0000
Subject: [PATCH] GameLog - attack and block are powered by events. Combat -
renamed some methods, extracted aside blocker costs
---
.gitattributes | 2 +
src/main/java/forge/GameLog.java | 10 ----
src/main/java/forge/GameLogFormatter.java | 37 +++++++-----
.../event/GameEventAttackersDeclared.java | 31 ++++++++++
.../game/event/GameEventBlockersDeclared.java | 27 +++++++++
.../forge/game/event/IGameEventVisitor.java | 5 ++
src/main/java/forge/game/phase/Combat.java | 4 +-
.../java/forge/game/phase/CombatUtil.java | 12 ++++
.../java/forge/game/phase/PhaseHandler.java | 59 +++++++++++--------
src/main/java/forge/game/phase/PhaseType.java | 12 ++--
src/main/java/forge/game/phase/PhaseUtil.java | 50 +++++++---------
src/main/java/forge/util/Lang.java | 5 +-
12 files changed, 164 insertions(+), 90 deletions(-)
create mode 100644 src/main/java/forge/game/event/GameEventAttackersDeclared.java
create mode 100644 src/main/java/forge/game/event/GameEventBlockersDeclared.java
diff --git a/.gitattributes b/.gitattributes
index f2462ace38e..8f236249a19 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -14234,7 +14234,9 @@ src/main/java/forge/game/ai/ComputerUtilCost.java -text
src/main/java/forge/game/ai/ComputerUtilMana.java -text
src/main/java/forge/game/event/GameEvent.java -text
src/main/java/forge/game/event/GameEventAnteCardsSelected.java -text
+src/main/java/forge/game/event/GameEventAttackersDeclared.java -text
src/main/java/forge/game/event/GameEventBlockerAssigned.java -text
+src/main/java/forge/game/event/GameEventBlockersDeclared.java -text
src/main/java/forge/game/event/GameEventCardDamaged.java -text
src/main/java/forge/game/event/GameEventCardDestroyed.java -text
src/main/java/forge/game/event/GameEventCardDiscarded.java -text
diff --git a/src/main/java/forge/GameLog.java b/src/main/java/forge/GameLog.java
index fde026a5f2e..1719426d697 100644
--- a/src/main/java/forge/GameLog.java
+++ b/src/main/java/forge/GameLog.java
@@ -24,7 +24,6 @@ import java.util.Observable;
import org.apache.commons.lang3.StringUtils;
import forge.game.event.IGameEventVisitor;
-import forge.game.phase.Combat;
/**
@@ -105,15 +104,6 @@ public class GameLog extends Observable {
return result;
}
- public void addCombatAttackers(Combat combat) {
- this.add(GameLogFormatter.describeAttack(combat));
- }
- public void addCombatBlockers(Combat combat) {
- this.add(GameLogFormatter.describeBlock(combat));
- }
- // Special methods
-
-
public IGameEventVisitor> getEventVisitor() {
return formatter;
}
diff --git a/src/main/java/forge/GameLogFormatter.java b/src/main/java/forge/GameLogFormatter.java
index 40851a196d0..fb50464d536 100644
--- a/src/main/java/forge/GameLogFormatter.java
+++ b/src/main/java/forge/GameLogFormatter.java
@@ -1,6 +1,7 @@
package forge;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
@@ -8,6 +9,8 @@ import com.google.common.eventbus.Subscribe;
import forge.card.spellability.TargetChoices;
import forge.game.GameOutcome;
+import forge.game.event.GameEventAttackersDeclared;
+import forge.game.event.GameEventBlockersDeclared;
import forge.game.event.GameEventCardDamaged;
import forge.game.event.GameEventCardDamaged.DamageType;
import forge.game.event.GameEventLandPlayed;
@@ -21,11 +24,11 @@ import forge.game.event.GameEventGameOutcome;
import forge.game.event.GameEvent;
import forge.game.event.GameEventTurnPhase;
import forge.game.event.GameEventPlayerControl;
-import forge.game.phase.Combat;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.game.player.PlayerStatistics;
import forge.util.Lang;
+import forge.util.maps.MapOfLists;
public class GameLogFormatter extends IGameEventVisitor.Base {
private final GameLog log;
@@ -168,40 +171,42 @@ public class GameLogFormatter extends IGameEventVisitor.Base {
return new GameLogEntry(GameLogEntryType.DAMAGE, message);
}
-
- static GameLogEntry describeAttack(final Combat combat) {
+ @Override
+ public GameLogEntry visit(final GameEventAttackersDeclared ev) {
final StringBuilder sb = new StringBuilder();
// Loop through Defenders
// Append Defending Player/Planeswalker
// Not a big fan of the triple nested loop here
- for (GameEntity defender : combat.getDefenders()) {
- List attackers = combat.getAttackersOf(defender);
+ for (Entry> kv : ev.attackersMap.entrySet()) {
+ Collection attackers = kv.getValue();
if (attackers == null || attackers.isEmpty()) {
continue;
}
if ( sb.length() > 0 ) sb.append("\n");
-
- sb.append(combat.getAttackingPlayer()).append(" declared ").append(Lang.joinHomogenous(attackers));
- sb.append(" to attack ").append(defender.toString()).append(".");
+ sb.append(ev.player).append(" assigned ").append(Lang.joinHomogenous(attackers));
+ sb.append(" to attack ").append(kv.getKey().toString()).append(".");
}
+ if ( sb.length() == 0 )
+ sb.append(ev.player).append(" didn't attack this turn.");
return new GameLogEntry(GameLogEntryType.COMBAT, sb.toString());
}
- static GameLogEntry describeBlock(final Combat combat) {
+ @Override
+ public GameLogEntry visit(final GameEventBlockersDeclared ev) {
final StringBuilder sb = new StringBuilder();
// Loop through Defenders
// Append Defending Player/Planeswalker
- List blockers = null;
-
+ Collection blockers = null;
- for (GameEntity defender : combat.getDefenders()) {
- List attackers = combat.getAttackersOf(defender);
+ for (Entry> kv : ev.blockers.entrySet()) {
+ GameEntity defender = kv.getKey();
+ MapOfLists attackers = kv.getValue();
if (attackers == null || attackers.isEmpty()) {
continue;
}
@@ -209,17 +214,17 @@ public class GameLogFormatter extends IGameEventVisitor.Base {
String controllerName = defender instanceof Card ? ((Card)defender).getController().getName() : defender.getName();
boolean firstAttacker = true;
- for (final Card attacker : attackers) {
+ for (final Entry> att : attackers.entrySet()) {
if ( !firstAttacker ) sb.append("\n");
- blockers = combat.getBlockers(attacker);
+ blockers = att.getValue();
if ( blockers.isEmpty() ) {
sb.append(controllerName).append(" didn't block ");
} else {
sb.append(controllerName).append(" assigned ").append(Lang.joinHomogenous(blockers)).append(" to block ");
}
- sb.append(attacker).append(".");
+ sb.append(att.getKey()).append(".");
firstAttacker = false;
}
}
diff --git a/src/main/java/forge/game/event/GameEventAttackersDeclared.java b/src/main/java/forge/game/event/GameEventAttackersDeclared.java
new file mode 100644
index 00000000000..a3501d3be0d
--- /dev/null
+++ b/src/main/java/forge/game/event/GameEventAttackersDeclared.java
@@ -0,0 +1,31 @@
+package forge.game.event;
+
+import forge.Card;
+import forge.GameEntity;
+import forge.game.player.Player;
+import forge.util.maps.MapOfLists;
+
+/**
+ * TODO: Write javadoc for this type.
+ *
+ */
+public class GameEventAttackersDeclared extends GameEvent {
+
+ public final Player player;
+ public final MapOfLists attackersMap;
+
+ public GameEventAttackersDeclared(Player playerTurn, MapOfLists attackersMap) {
+ this.player = playerTurn;
+ this.attackersMap = attackersMap;
+ }
+
+ /* (non-Javadoc)
+ * @see forge.game.event.GameEvent#visit(forge.game.event.IGameEventVisitor)
+ */
+ @Override
+ public T visit(IGameEventVisitor visitor) {
+ // TODO Auto-generated method stub
+ return visitor.visit(this);
+ }
+
+}
diff --git a/src/main/java/forge/game/event/GameEventBlockersDeclared.java b/src/main/java/forge/game/event/GameEventBlockersDeclared.java
new file mode 100644
index 00000000000..f24c8e3d43c
--- /dev/null
+++ b/src/main/java/forge/game/event/GameEventBlockersDeclared.java
@@ -0,0 +1,27 @@
+package forge.game.event;
+
+import java.util.Map;
+
+import forge.Card;
+import forge.GameEntity;
+import forge.util.maps.MapOfLists;
+
+/**
+ * TODO: Write javadoc for this type.
+ *
+ */
+public class GameEventBlockersDeclared extends GameEvent {
+
+ public final Map> blockers;
+
+ public GameEventBlockersDeclared(Map> blockers) {
+ this.blockers = blockers;
+ }
+
+ @Override
+ public T visit(IGameEventVisitor visitor) {
+ // TODO Auto-generated method stub
+ return visitor.visit(this);
+ }
+
+}
diff --git a/src/main/java/forge/game/event/IGameEventVisitor.java b/src/main/java/forge/game/event/IGameEventVisitor.java
index 2bd0f9069a0..0a34fee31ce 100644
--- a/src/main/java/forge/game/event/IGameEventVisitor.java
+++ b/src/main/java/forge/game/event/IGameEventVisitor.java
@@ -5,6 +5,8 @@ package forge.game.event;
*
*/
public interface IGameEventVisitor {
+ T visit(GameEventAttackersDeclared event);
+ T visit(GameEventBlockersDeclared event);
T visit(GameEventBlockerAssigned event);
T visit(GameEventCardDamaged event);
T visit(GameEventCardDestroyed event);
@@ -42,6 +44,8 @@ public interface IGameEventVisitor {
// This is base class for all visitors.
public static class Base implements IGameEventVisitor{
+ public T visit(GameEventAttackersDeclared event) { return null; }
+ public T visit(GameEventBlockersDeclared event) { return null; }
public T visit(GameEventBlockerAssigned event) { return null; }
public T visit(GameEventCardDamaged event) { return null; }
public T visit(GameEventCardDestroyed event) { return null; }
@@ -76,5 +80,6 @@ public interface IGameEventVisitor {
public T visit(GameEventTurnPhase event) { return null; }
public T visit(GameEventPlayerDamaged event) { return null; }
}
+
}
diff --git a/src/main/java/forge/game/phase/Combat.java b/src/main/java/forge/game/phase/Combat.java
index b82beb71612..af69ef7eb4e 100644
--- a/src/main/java/forge/game/phase/Combat.java
+++ b/src/main/java/forge/game/phase/Combat.java
@@ -565,7 +565,7 @@ public class Combat {
* verifyCreaturesInPlay.
*
*/
- public final void verifyCreaturesInPlay() {
+ public final void removeAbsentCombatants() {
final List all = new ArrayList();
all.addAll(this.getAttackers());
all.addAll(this.getAllBlockers());
@@ -582,7 +582,7 @@ public class Combat {
* setUnblocked.
*
*/
- public final void setUnblocked() {
+ public final void setUnblockedAttackers() {
final List attacking = this.getAttackers();
for (final Card attacker : attacking) {
diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java
index 3cdaf590b8e..4a359c55272 100644
--- a/src/main/java/forge/game/phase/CombatUtil.java
+++ b/src/main/java/forge/game/phase/CombatUtil.java
@@ -1405,4 +1405,16 @@ public class CombatUtil {
}
}
+ public static void checkAttackOrBlockAlone(Combat combat) {
+ // Handles removing cards like Mogg Flunkies from combat if group attack
+ // didn't occur
+ for (Card c1 : combat.getAttackers()) {
+ if (c1.hasKeyword("CARDNAME can't attack or block alone.") && c1.isAttacking()) {
+ if (combat.getAttackers().size() < 2) {
+ combat.removeFromCombat(c1);
+ }
+ }
+ }
+ }
+
} // end class CombatUtil
diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java
index 02ab957cf64..6d98689f778 100644
--- a/src/main/java/forge/game/phase/PhaseHandler.java
+++ b/src/main/java/forge/game/phase/PhaseHandler.java
@@ -26,12 +26,15 @@ import org.apache.commons.lang.time.StopWatch;
import forge.Card;
import forge.CardLists;
import forge.FThreads;
+import forge.GameEntity;
import forge.Singletons;
import forge.CardPredicates.Presets;
import forge.card.trigger.TriggerType;
import forge.game.GameAge;
import forge.game.Game;
import forge.game.GameType;
+import forge.game.event.GameEventAttackersDeclared;
+import forge.game.event.GameEventBlockersDeclared;
import forge.game.event.GameEventPlayerPriority;
import forge.game.event.GameEventTurnBegan;
import forge.game.event.GameEventTurnEnded;
@@ -44,6 +47,9 @@ import forge.gui.framework.SDisplayUtil;
import forge.gui.match.CMatchUI;
import forge.gui.match.nonsingleton.VField;
import forge.properties.ForgePreferences.FPref;
+import forge.util.maps.CollectionSuppliers;
+import forge.util.maps.HashMapOfLists;
+import forge.util.maps.MapOfLists;
/**
@@ -270,21 +276,10 @@ public class PhaseHandler implements java.io.Serializable {
playerTurn.getController().declareAttackers();
- game.getCombat().verifyCreaturesInPlay();
-
- // Handles removing cards like Mogg Flunkies from combat if group attack
- // didn't occur
- for (Card c1 : game.getCombat().getAttackers()) {
- if (c1.hasKeyword("CARDNAME can't attack or block alone.") && c1.isAttacking()) {
- if (game.getCombat().getAttackers().size() < 2) {
- game.getCombat().removeFromCombat(c1);
- }
- }
- }
-
-
- // TODO move propaganda to happen as the Attacker is Declared
+ game.getCombat().removeAbsentCombatants();
+ CombatUtil.checkAttackOrBlockAlone(game.getCombat());
+ // TODO move propaganda to happen as the Attacker is Declared
for (final Card c2 : game.getCombat().getAttackers()) {
boolean canAttack = CombatUtil.checkPropagandaEffects(game, c2);
if ( canAttack ) {
@@ -294,10 +289,13 @@ public class PhaseHandler implements java.io.Serializable {
game.getCombat().removeFromCombat(c2);
}
}
-
- // Then run other Attacker bonuses
- // check for exalted:
+ // Prepare and fire event 'attackers declared'
+ MapOfLists attackersMap = new HashMapOfLists(CollectionSuppliers.arrayLists());
+ for(GameEntity ge : game.getCombat().getDefenders()) attackersMap.addAll(ge, game.getCombat().getAttackersOf(ge));
+ game.fireEvent(new GameEventAttackersDeclared(playerTurn, attackersMap));
+
+ // This Exalted handler should be converted to script
if (game.getCombat().getAttackers().size() == 1) {
final Player attackingPlayer = game.getCombat().getAttackingPlayer();
final Card attacker = game.getCombat().getAttackers().get(0);
@@ -305,7 +303,6 @@ public class PhaseHandler implements java.io.Serializable {
int exaltedMagnitude = card.getKeywordAmount("Exalted");
if (exaltedMagnitude > 0) {
CombatUtil.executeExaltedAbility(game, attacker, exaltedMagnitude, card);
- // Make sure exalted effects get applied only once per combat
}
if ("Sovereigns of Lost Alara".equals(card.getName())) {
@@ -314,8 +311,7 @@ public class PhaseHandler implements java.io.Serializable {
}
}
- game.getGameLog().addCombatAttackers(game.getCombat());
-
+ // fire trigger
final HashMap runParams = new HashMap();
runParams.put("Attackers", game.getCombat().getAttackers());
runParams.put("AttackingPlayer", game.getCombat().getAttackingPlayer());
@@ -325,14 +321,14 @@ public class PhaseHandler implements java.io.Serializable {
CombatUtil.checkDeclareAttackers(game, c);
}
game.getStack().unfreezeStack();
-
+
this.bCombat = !game.getCombat().getAttackers().isEmpty();
this.nCombatsThisTurn++;
break;
case COMBAT_DECLARE_BLOCKERS:
- game.getCombat().verifyCreaturesInPlay();
+ game.getCombat().removeAbsentCombatants();
game.getStack().freezeStack();
Player p = playerTurn;
@@ -342,12 +338,25 @@ public class PhaseHandler implements java.io.Serializable {
p.getController().declareBlockers();
} while(p != playerTurn);
- game.getStack().unfreezeStack();
+ game.getCombat().removeAbsentCombatants();
PhaseUtil.handleDeclareBlockers(game);
+
+ // map: defender => (many) attacker => (many) blocker
+ Map> blockers = new HashMap>();
+ for(GameEntity ge : game.getCombat().getDefenders()) {
+ MapOfLists protectThisDefender = new HashMapOfLists(CollectionSuppliers.arrayLists());
+ for(Card att : game.getCombat().getAttackersOf(ge)) {
+ protectThisDefender.addAll(att, game.getCombat().getBlockers(att));
+ }
+ blockers.put(ge, protectThisDefender);
+ }
+ game.fireEvent(new GameEventBlockersDeclared(blockers));
+
+ game.getStack().unfreezeStack();
break;
case COMBAT_FIRST_STRIKE_DAMAGE:
- game.getCombat().verifyCreaturesInPlay();
+ game.getCombat().removeAbsentCombatants();
// no first strikers, skip this step
if (!game.getCombat().assignCombatDamage(true)) {
@@ -359,7 +368,7 @@ public class PhaseHandler implements java.io.Serializable {
break;
case COMBAT_DAMAGE:
- game.getCombat().verifyCreaturesInPlay();
+ game.getCombat().removeAbsentCombatants();
if (!game.getCombat().assignCombatDamage(false)) {
this.givePriorityToPlayer = false;
diff --git a/src/main/java/forge/game/phase/PhaseType.java b/src/main/java/forge/game/phase/PhaseType.java
index 9cadf7094a6..bad75fca00c 100644
--- a/src/main/java/forge/game/phase/PhaseType.java
+++ b/src/main/java/forge/game/phase/PhaseType.java
@@ -15,9 +15,7 @@ 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_BLOCKERS("Declare Blockers"),
- //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"),
@@ -27,11 +25,11 @@ public enum PhaseType {
public static final List 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_FIRST_STRIKE_DAMAGE, COMBAT_DAMAGE, COMBAT_END,
- MAIN2, END_OF_TURN, CLEANUP
+ UNTAP, UPKEEP, DRAW,
+ MAIN1,
+ COMBAT_BEGIN, COMBAT_DECLARE_ATTACKERS, COMBAT_DECLARE_BLOCKERS, COMBAT_FIRST_STRIKE_DAMAGE, COMBAT_DAMAGE, COMBAT_END,
+ MAIN2,
+ END_OF_TURN, CLEANUP
)
);
diff --git a/src/main/java/forge/game/phase/PhaseUtil.java b/src/main/java/forge/game/phase/PhaseUtil.java
index b81ca72cc6a..a4aa69e5e9f 100644
--- a/src/main/java/forge/game/phase/PhaseUtil.java
+++ b/src/main/java/forge/game/phase/PhaseUtil.java
@@ -18,7 +18,6 @@
package forge.game.phase;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import com.google.common.base.Predicate;
@@ -28,7 +27,6 @@ import forge.CardLists;
import forge.card.cost.Cost;
import forge.card.mana.ManaCost;
import forge.card.staticability.StaticAbility;
-import forge.card.trigger.TriggerType;
import forge.game.Game;
import forge.game.player.Player;
import forge.game.player.PlayerController.ManaPaymentPurpose;
@@ -77,7 +75,6 @@ public class PhaseUtil {
*/
public static void handleDeclareBlockers(Game game) {
final Combat combat = game.getCombat();
- combat.verifyCreaturesInPlay();
// Handles removing cards like Mogg Flunkies from combat if group block
// didn't occur
@@ -85,21 +82,7 @@ public class PhaseUtil {
for (Card blocker : filterList) {
final List attackers = new ArrayList(combat.getAttackersBlockedBy(blocker));
for (Card attacker : attackers) {
- Cost blockCost = new Cost(ManaCost.ZERO, true);
- // Sort abilities to apply them in proper order
- for (Card card : game.getCardsIn(ZoneType.Battlefield)) {
- final ArrayList staticAbilities = card.getStaticAbilities();
- for (final StaticAbility stAb : staticAbilities) {
- Cost c1 = stAb.getBlockCost(blocker, attacker);
- if ( c1 != null )
- blockCost.add(c1);
- }
- }
-
- boolean hasPaid = blockCost.getTotalMana().isZero() && blockCost.isOnlyManaCost(); // true if needless to pay
- if (!hasPaid) {
- hasPaid = blocker.getController().getController().payManaOptional(blocker, blockCost, "Pay cost to declare " + blocker + " a blocker", ManaPaymentPurpose.DeclareBlocker);
- }
+ boolean hasPaid = payRequiredBlockCosts(game, blocker, attacker);
if ( !hasPaid ) {
combat.removeBlockAssignment(attacker, blocker);
@@ -114,12 +97,9 @@ public class PhaseUtil {
}
}
- game.getStack().freezeStack();
+ combat.setUnblockedAttackers();
- combat.setUnblocked();
-
- List list = new ArrayList();
- list.addAll(combat.getAllBlockers());
+ List list = combat.getAllBlockers();
list = CardLists.filter(list, new Predicate() {
@Override
@@ -128,16 +108,30 @@ public class PhaseUtil {
}
});
- final List attList = combat.getAttackers();
-
CombatUtil.checkDeclareBlockers(game, list);
- for (final Card a : attList) {
+ for (final Card a : combat.getAttackers()) {
CombatUtil.checkBlockedAttackers(game, a, combat.getBlockers(a));
}
+ }
- game.getStack().unfreezeStack();
- game.getGameLog().addCombatBlockers(game.getCombat());
+ private static boolean payRequiredBlockCosts(Game game, Card blocker, Card attacker) {
+ Cost blockCost = new Cost(ManaCost.ZERO, true);
+ // Sort abilities to apply them in proper order
+ for (Card card : game.getCardsIn(ZoneType.Battlefield)) {
+ final ArrayList staticAbilities = card.getStaticAbilities();
+ for (final StaticAbility stAb : staticAbilities) {
+ Cost c1 = stAb.getBlockCost(blocker, attacker);
+ if ( c1 != null )
+ blockCost.add(c1);
+ }
+ }
+
+ boolean hasPaid = blockCost.getTotalMana().isZero() && blockCost.isOnlyManaCost(); // true if needless to pay
+ if (!hasPaid) {
+ hasPaid = blocker.getController().getController().payManaOptional(blocker, blockCost, "Pay cost to declare " + blocker + " a blocker", ManaPaymentPurpose.DeclareBlocker);
+ }
+ return hasPaid;
}
}
diff --git a/src/main/java/forge/util/Lang.java b/src/main/java/forge/util/Lang.java
index 9a85126b405..291a23635d5 100644
--- a/src/main/java/forge/util/Lang.java
+++ b/src/main/java/forge/util/Lang.java
@@ -1,5 +1,6 @@
package forge.util;
+import java.util.Collection;
import java.util.List;
import com.google.common.base.Function;
@@ -27,8 +28,8 @@ public class Lang {
}
}
- public static String joinHomogenous(List objects) { return joinHomogenous(objects, null); }
- public static String joinHomogenous(List objects, Function accessor) {
+ public static String joinHomogenous(Collection objects) { return joinHomogenous(objects, null); }
+ public static String joinHomogenous(Collection objects, Function accessor) {
int remaining = objects.size();
StringBuilder sb = new StringBuilder();
for(T obj : objects) {