added log event for player control,

moved log's string-building code to GameLogFormatter.java
This commit is contained in:
Maxmtg
2013-05-27 12:47:36 +00:00
parent f702fbda09
commit 4a9930defb
8 changed files with 193 additions and 136 deletions

2
.gitattributes vendored
View File

@@ -13766,6 +13766,7 @@ src/main/java/forge/GameEntity.java -text
src/main/java/forge/GameEventType.java -text src/main/java/forge/GameEventType.java -text
src/main/java/forge/GameLog.java -text src/main/java/forge/GameLog.java -text
src/main/java/forge/GameLogEntry.java -text src/main/java/forge/GameLogEntry.java -text
src/main/java/forge/GameLogFormatter.java -text
src/main/java/forge/ImageCache.java svneol=native#text/plain src/main/java/forge/ImageCache.java svneol=native#text/plain
src/main/java/forge/ImageLoader.java -text src/main/java/forge/ImageLoader.java -text
src/main/java/forge/Singletons.java svneol=native#text/plain src/main/java/forge/Singletons.java svneol=native#text/plain
@@ -14256,6 +14257,7 @@ src/main/java/forge/game/event/LandPlayedEvent.java -text
src/main/java/forge/game/event/LifeLossEvent.java -text src/main/java/forge/game/event/LifeLossEvent.java -text
src/main/java/forge/game/event/ManaBurnEvent.java -text src/main/java/forge/game/event/ManaBurnEvent.java -text
src/main/java/forge/game/event/MulliganEvent.java -text src/main/java/forge/game/event/MulliganEvent.java -text
src/main/java/forge/game/event/PlayerControlEvent.java -text
src/main/java/forge/game/event/PoisonCounterEvent.java -text src/main/java/forge/game/event/PoisonCounterEvent.java -text
src/main/java/forge/game/event/SetTappedEvent.java -text src/main/java/forge/game/event/SetTappedEvent.java -text
src/main/java/forge/game/event/ShuffleEvent.java -text src/main/java/forge/game/event/ShuffleEvent.java -text

View File

@@ -6,6 +6,7 @@ public enum GameEventType {
TURN("Turn"), TURN("Turn"),
MULLIGAN("Mulligan"), MULLIGAN("Mulligan"),
ANTE("Ante"), ANTE("Ante"),
PLAYER_CONROL("Player contol"),
COMBAT("Combat"), COMBAT("Combat"),
EFFECT_REPLACED("Replacement Effect"), EFFECT_REPLACED("Replacement Effect"),
LAND("Land"), LAND("Land"),

View File

@@ -20,18 +20,12 @@ package forge;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import forge.game.GameOutcome;
import forge.game.event.DuelOutcomeEvent;
import forge.game.event.Event; import forge.game.event.Event;
import forge.game.phase.Combat; import forge.game.phase.Combat;
import forge.game.player.LobbyPlayer;
import forge.game.player.PlayerStatistics;
import forge.util.Lang;
import forge.util.MyObservable; import forge.util.MyObservable;
@@ -74,15 +68,11 @@ public class GameLog extends MyObservable {
this.updateObservers(); this.updateObservers();
} }
/** private void add(GameLogEntry entry) {
* Gets the log text. log.add(entry);
* this.updateObservers();
* @return the log text }
*/
public String getLogText() {
return getLogText(null);
}
public String getLogText(final GameEventType logLevel) { public String getLogText(final GameEventType logLevel) {
List<GameLogEntry> filteredAndReversed = getLogEntries(logLevel); List<GameLogEntry> filteredAndReversed = getLogEntries(logLevel);
return StringUtils.join(filteredAndReversed, "\r\n"); return StringUtils.join(filteredAndReversed, "\r\n");
@@ -121,127 +111,19 @@ public class GameLog extends MyObservable {
@Subscribe @Subscribe
public void receiveGameEvent(Event ev) { public void receiveGameEvent(Event ev) {
if(ev instanceof DuelOutcomeEvent) { GameLogEntry record = GameLogFormatter.logEvent(ev, this);
fillOutcome( ((DuelOutcomeEvent) ev).result, ((DuelOutcomeEvent) ev).history ); if( null != record ) {
add(record);
} }
} }
/**
* Generates and adds
*/
private void fillOutcome(GameOutcome result, List<GameOutcome> history) {
// add result entries to the game log
final LobbyPlayer human = Singletons.getControl().getLobby().getGuiPlayer();
final List<String> outcomes = new ArrayList<String>();
for (Entry<LobbyPlayer, PlayerStatistics> p : result) {
String whoHas = p.getKey().equals(human) ? "You have" : p.getKey().getName() + " has";
String outcome = String.format("%s %s", whoHas, p.getValue().getOutcome().toString());
outcomes.add(outcome);
this.add(GameEventType.GAME_OUTCOME, outcome);
}
final String statsSummary = generateSummary(history);
this.add(GameEventType.MATCH_RESULTS, statsSummary);
}
private static String generateSummary(List<GameOutcome> gamesPlayed) {
GameOutcome outcome1 = gamesPlayed.get(0);
int[] wins = new int[outcome1.getNumPlayers()];
LobbyPlayer[] players = new LobbyPlayer[outcome1.getNumPlayers()];
for(int i = 0; i < wins.length; wins[i++] = 0);
for (GameOutcome go : gamesPlayed) {
int i = 0;
for(Entry<LobbyPlayer, PlayerStatistics> ps : go) {
players[i] = ps.getKey();
if( ps.getValue().getOutcome().hasWon() )
wins[i]++;
i++;
}
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < wins.length; i++) {
sb.append(players[i].getName()).append(": ").append(wins[i]).append(" ");
}
return sb.toString();
}
public void addCombatAttackers(Combat combat) { public void addCombatAttackers(Combat combat) {
this.add(GameEventType.COMBAT, describeAttack(combat)); this.add(GameLogFormatter.describeAttack(combat));
} }
public void addCombatBlockers(Combat combat) { public void addCombatBlockers(Combat combat) {
this.add(GameEventType.COMBAT, describeBlock(combat)); this.add(GameLogFormatter.describeBlock(combat));
} }
// Special methods // Special methods
}
private static String describeAttack(final Combat combat) {
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<Card> attackers = combat.getAttackersOf(defender);
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(".");
}
return sb.toString();
}
private static String describeBlock(final Combat combat) {
final StringBuilder sb = new StringBuilder();
// Loop through Defenders
// Append Defending Player/Planeswalker
List<Card> blockers = null;
for (GameEntity defender : combat.getDefenders()) {
List<Card> attackers = combat.getAttackersOf(defender);
if (attackers == null || attackers.isEmpty()) {
continue;
}
if ( sb.length() > 0 ) sb.append("\n");
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 = combat.getBlockers(attacker);
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(".");
firstAttacker = false;
}
}
return sb.toString();
}
} // end class GameLog

View File

@@ -0,0 +1,145 @@
package forge;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import forge.game.GameOutcome;
import forge.game.event.DuelOutcomeEvent;
import forge.game.event.Event;
import forge.game.event.PlayerControlEvent;
import forge.game.phase.Combat;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.game.player.PlayerStatistics;
import forge.util.Lang;
public class GameLogFormatter {
// Some events produce several log entries. I've let them added into log directly
static GameLogEntry logEvent(Event ev, GameLog log) {
if(ev instanceof DuelOutcomeEvent) {
return GameLogFormatter.fillOutcome(log, ((DuelOutcomeEvent) ev).result, ((DuelOutcomeEvent) ev).history );
} else if ( ev instanceof PlayerControlEvent ) {
LobbyPlayer newController = ((PlayerControlEvent) ev).getNewController();
Player p = ((PlayerControlEvent) ev).getPlayer();
final String message;
if( newController == null )
message = p.getName() + " has restored control over themself";
else
message = String.format("%s is controlled by %s", p.getName(), newController.getName());
return new GameLogEntry(GameEventType.PLAYER_CONROL, message);
}
return null;
}
/**
* Generates and adds
*/
private static GameLogEntry fillOutcome(GameLog log, GameOutcome result, List<GameOutcome> history) {
// add result entries to the game log
final LobbyPlayer human = Singletons.getControl().getLobby().getGuiPlayer();
final List<String> outcomes = new ArrayList<String>();
for (Entry<LobbyPlayer, PlayerStatistics> p : result) {
String whoHas = p.getKey().equals(human) ? "You have" : p.getKey().getName() + " has";
String outcome = String.format("%s %s", whoHas, p.getValue().getOutcome().toString());
outcomes.add(outcome);
log.add(GameEventType.GAME_OUTCOME, outcome);
}
return generateSummary(history);
}
private static GameLogEntry generateSummary(List<GameOutcome> gamesPlayed) {
GameOutcome outcome1 = gamesPlayed.get(0);
int[] wins = new int[outcome1.getNumPlayers()];
LobbyPlayer[] players = new LobbyPlayer[outcome1.getNumPlayers()];
for(int i = 0; i < wins.length; wins[i++] = 0);
for (GameOutcome go : gamesPlayed) {
int i = 0;
for(Entry<LobbyPlayer, PlayerStatistics> ps : go) {
players[i] = ps.getKey();
if( ps.getValue().getOutcome().hasWon() )
wins[i]++;
i++;
}
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < wins.length; i++) {
sb.append(players[i].getName()).append(": ").append(wins[i]).append(" ");
}
return new GameLogEntry(GameEventType.MATCH_RESULTS, sb.toString());
}
static GameLogEntry describeAttack(final Combat combat) {
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<Card> attackers = combat.getAttackersOf(defender);
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(".");
}
return new GameLogEntry(GameEventType.COMBAT, sb.toString());
}
static GameLogEntry describeBlock(final Combat combat) {
final StringBuilder sb = new StringBuilder();
// Loop through Defenders
// Append Defending Player/Planeswalker
List<Card> blockers = null;
for (GameEntity defender : combat.getDefenders()) {
List<Card> attackers = combat.getAttackersOf(defender);
if (attackers == null || attackers.isEmpty()) {
continue;
}
if ( sb.length() > 0 ) sb.append("\n");
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 = combat.getBlockers(attacker);
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(".");
firstAttacker = false;
}
}
return new GameLogEntry(GameEventType.COMBAT, sb.toString());
}
} // end class GameLog

View File

@@ -1,14 +1,9 @@
package forge.game.event; package forge.game.event;
/**
*
*
*/
public class CounterAddedEvent extends Event { public class CounterAddedEvent extends Event {
public final int Amount; public final int Amount;
public CounterAddedEvent(int n) { public CounterAddedEvent(int n) {
Amount = n; Amount = n;
} }
} }

View File

@@ -0,0 +1,28 @@
package forge.game.event;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
public class PlayerControlEvent extends Event {
private final Player player;
private final LobbyPlayer oldController;
private final LobbyPlayer newController;
public PlayerControlEvent(Player p, LobbyPlayer old, LobbyPlayer new1) {
player = p;
oldController = old;
newController = new1;
}
public final Player getPlayer() {
return player;
}
public final LobbyPlayer getOldController() {
return oldController;
}
public final LobbyPlayer getNewController() {
return newController;
}
}

View File

@@ -62,6 +62,7 @@ import forge.game.event.DrawCardEvent;
import forge.game.event.LandPlayedEvent; import forge.game.event.LandPlayedEvent;
import forge.game.event.LifeLossEvent; import forge.game.event.LifeLossEvent;
import forge.game.event.MulliganEvent; import forge.game.event.MulliganEvent;
import forge.game.event.PlayerControlEvent;
import forge.game.event.PoisonCounterEvent; import forge.game.event.PoisonCounterEvent;
import forge.game.event.ShuffleEvent; import forge.game.event.ShuffleEvent;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
@@ -2727,10 +2728,13 @@ public class Player extends GameEntity implements Comparable<Player> {
public final void releaseControl() { public final void releaseControl() {
controller = controllerCreator; controller = controllerCreator;
game.getEvents().post(new PlayerControlEvent(this, getLobbyPlayer(), null));
} }
public final void obeyNewMaster(PlayerController pc) { public final void obeyNewMaster(PlayerController pc) {
LobbyPlayer oldController = getLobbyPlayer();
controller = pc; controller = pc;
game.getEvents().post(new PlayerControlEvent(this, oldController, pc.getLobbyPlayer()));
} }

View File

@@ -106,7 +106,7 @@ public class ViewWinLose {
// Assemble game log scroller. // Assemble game log scroller.
final FTextArea txtLog = new FTextArea(); final FTextArea txtLog = new FTextArea();
txtLog.setText(match.getCurrentGame().getGameLog().getLogText()); txtLog.setText(match.getCurrentGame().getGameLog().getLogText(null));
txtLog.setFont(FSkin.getFont(14)); txtLog.setFont(FSkin.getFont(14));
txtLog.setFocusable(true); // allow highlighting and copying of log txtLog.setFocusable(true); // allow highlighting and copying of log