mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Game Outcome strings are now built in GameLog class, because MatchController should not compose logs
GameLog is subscribed to DuelOutcomeEvent. GameLog uses enum to indicate record priority, as well as its kind ViewWinLose takes strings from log.
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -13759,6 +13759,8 @@ src/main/java/forge/CounterType.java svneol=native#text/plain
|
||||
src/main/java/forge/FThreads.java -text
|
||||
src/main/java/forge/GameEntity.java -text
|
||||
src/main/java/forge/GameLog.java -text
|
||||
src/main/java/forge/GameLogEntry.java -text
|
||||
src/main/java/forge/GameLogLevel.java -text
|
||||
src/main/java/forge/ImageCache.java svneol=native#text/plain
|
||||
src/main/java/forge/ImageLoader.java -text
|
||||
src/main/java/forge/Singletons.java svneol=native#text/plain
|
||||
|
||||
@@ -3169,7 +3169,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public final void equipCard(final Card c) {
|
||||
if (c.hasKeyword("CARDNAME can't be equipped.")) {
|
||||
getGame().getGameLog().add("ResolveStack", "Trying to equip " + c.getName()
|
||||
+ " but it can't be equipped.", 2);
|
||||
+ " but it can't be equipped.", GameLogLevel.STACK);
|
||||
return;
|
||||
}
|
||||
if (this.hasStartOfKeyword("CantEquip")) {
|
||||
@@ -3179,7 +3179,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
final String[] restrictions = k[1].split(",");
|
||||
if (c.isValid(restrictions, this.getController(), this)) {
|
||||
getGame().getGameLog().add("ResolveStack", "Trying to equip " + c.getName()
|
||||
+ " but it can't be equipped.", 2);
|
||||
+ " but it can't be equipped.", GameLogLevel.STACK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3372,7 +3372,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public final void enchantEntity(final GameEntity entity) {
|
||||
if (entity.hasKeyword("CARDNAME can't be enchanted.")) {
|
||||
getGame().getGameLog().add("ResolveStack", "Trying to enchant " + entity.getName()
|
||||
+ " but it can't be enchanted.", 2);
|
||||
+ " but it can't be enchanted.", GameLogLevel.STACK);
|
||||
return;
|
||||
}
|
||||
this.addEnchanting(entity);
|
||||
@@ -7460,7 +7460,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
game.getEvents().post(new CardDamagedEvent());
|
||||
}
|
||||
|
||||
getGame().getGameLog().add("Damage", String.format("Dealing %d damage to %s. %s", damageToAdd, this.getName(), additionalLog), 3);
|
||||
getGame().getGameLog().add("Damage", String.format("Dealing %d damage to %s. %s", damageToAdd, this.getName(), additionalLog), GameLogLevel.DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,27 +20,38 @@ package forge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.game.GameOutcome;
|
||||
import forge.game.event.DuelOutcomeEvent;
|
||||
import forge.game.event.Event;
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import forge.game.player.PlayerStatistics;
|
||||
import forge.util.MyObservable;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* GameLog class.
|
||||
* </p>
|
||||
*
|
||||
* Logging level:
|
||||
* 0 - Turn
|
||||
* 2 - Stack items
|
||||
* 3 - Poison Counters
|
||||
* 4 - Mana abilities
|
||||
* 6 - All Phase information
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: GameLog.java 12297 2011-11-28 19:56:47Z slapshot5 $
|
||||
*/
|
||||
public class GameLog extends MyObservable {
|
||||
private ArrayList<LogEntry> log = new ArrayList<LogEntry>();
|
||||
private List<GameLogEntry> log = new ArrayList<GameLogEntry>();
|
||||
|
||||
/** Logging level:
|
||||
* 0 - Turn
|
||||
* 2 - Stack items
|
||||
* 3 - Poison Counters
|
||||
* 4 - Mana abilities
|
||||
* 6 - All Phase information
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a new game log.
|
||||
@@ -49,6 +60,58 @@ public class GameLog extends MyObservable {
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void receiveGameEvent(Event ev) {
|
||||
if(ev instanceof DuelOutcomeEvent) {
|
||||
fillOutcome( ((DuelOutcomeEvent) ev).result, ((DuelOutcomeEvent) ev).history );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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("Final", outcome, GameLogLevel.GAME_OUTCOME);
|
||||
}
|
||||
|
||||
final String statsSummary = generateSummary(history);
|
||||
this.add("Final", statsSummary, GameLogLevel.MATCH_RESULTS);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the.
|
||||
*
|
||||
@@ -56,8 +119,8 @@ public class GameLog extends MyObservable {
|
||||
* @param message the message
|
||||
* @param level the level
|
||||
*/
|
||||
public void add(final String type, final String message, final int level) {
|
||||
log.add(new LogEntry(type, message, level));
|
||||
public void add(final String type, final String message, final GameLogLevel level) {
|
||||
log.add(new GameLogEntry(type, message, level));
|
||||
this.updateObservers();
|
||||
}
|
||||
|
||||
@@ -67,54 +130,13 @@ public class GameLog extends MyObservable {
|
||||
* @return the log text
|
||||
*/
|
||||
public String getLogText() {
|
||||
return getLogText(10);
|
||||
return getLogText(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the log text.
|
||||
*
|
||||
* @param logLevel the log level
|
||||
* @return the log text
|
||||
*/
|
||||
public String getLogText(final int logLevel) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = log.size() - 1; i >= 0; i--) {
|
||||
LogEntry le = log.get(i);
|
||||
if (le.getLevel() > logLevel) {
|
||||
continue;
|
||||
}
|
||||
sb.append(le.getType()).append(": ").append(le.getMessage());
|
||||
if (i > 0) {
|
||||
sb.append("\r\n");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset.
|
||||
*/
|
||||
public void reset() {
|
||||
log.clear();
|
||||
this.updateObservers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the log entry.
|
||||
*
|
||||
* @param index the index
|
||||
* @return the log entry
|
||||
*/
|
||||
public LogEntry getLogEntry(int index) {
|
||||
return log.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the log entries as a list.
|
||||
* @return List<LogEntry>
|
||||
*/
|
||||
public List<LogEntry> getLogEntries() {
|
||||
return log;
|
||||
public String getLogText(final GameLogLevel logLevel) {
|
||||
List<GameLogEntry> filteredAndReversed = getLogEntries(logLevel);
|
||||
return StringUtils.join(filteredAndReversed, "\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,41 +145,26 @@ public class GameLog extends MyObservable {
|
||||
* @param logLevel the log level
|
||||
* @return the log text
|
||||
*/
|
||||
public List<LogEntry> getLogEntries(final int logLevel) {
|
||||
final List<LogEntry> entries = new ArrayList<LogEntry>();
|
||||
public List<GameLogEntry> getLogEntries(final GameLogLevel logLevel) { // null to fetch all
|
||||
final List<GameLogEntry> result = new ArrayList<GameLogEntry>();
|
||||
|
||||
for (int i = log.size() - 1; i >= 0; i--) {
|
||||
LogEntry le = log.get(i);
|
||||
if (le.getLevel() > logLevel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entries.add(le);
|
||||
GameLogEntry le = log.get(i);
|
||||
if(logLevel == null || le.level.compareTo(logLevel) <= 0 )
|
||||
result.add(le);
|
||||
}
|
||||
return entries;
|
||||
return result;
|
||||
}
|
||||
|
||||
public class LogEntry {
|
||||
private String type;
|
||||
private String message;
|
||||
private int level;
|
||||
public List<GameLogEntry> getLogEntriesExact(final GameLogLevel logLevel) { // null to fetch all
|
||||
final List<GameLogEntry> result = new ArrayList<GameLogEntry>();
|
||||
|
||||
LogEntry(final String typeIn, final String messageIn, final int levelIn) {
|
||||
type = typeIn;
|
||||
message = messageIn;
|
||||
level = levelIn;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
for (int i = log.size() - 1; i >= 0; i--) {
|
||||
GameLogEntry le = log.get(i);
|
||||
if(logLevel == null || le.level.compareTo(logLevel) == 0 )
|
||||
result.add(le);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // end class GameLog
|
||||
|
||||
22
src/main/java/forge/GameLogEntry.java
Normal file
22
src/main/java/forge/GameLogEntry.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package forge;
|
||||
|
||||
public class GameLogEntry {
|
||||
public final String type;
|
||||
public final String message;
|
||||
public final GameLogLevel level;
|
||||
|
||||
GameLogEntry(final String typeIn, final String messageIn, final GameLogLevel levelIn) {
|
||||
type = typeIn;
|
||||
message = messageIn;
|
||||
level = levelIn;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO Auto-generated method stub
|
||||
return type + ": " + message;
|
||||
}
|
||||
}
|
||||
25
src/main/java/forge/GameLogLevel.java
Normal file
25
src/main/java/forge/GameLogLevel.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package forge;
|
||||
|
||||
public enum GameLogLevel {
|
||||
GAME_OUTCOME("Game outcome"),
|
||||
MATCH_RESULTS("Match result"),
|
||||
TURN("Turn"),
|
||||
MULLIGAN("Mulligan"),
|
||||
ANTE("Ante"),
|
||||
COMBAT("Combat"),
|
||||
EFFECT_REPLACED("ReplacementEffect"),
|
||||
LAND("Land"),
|
||||
STACK("Stack"),
|
||||
DAMAGE("Damage"),
|
||||
MANA("Mana"),
|
||||
PHASE("Phase");
|
||||
|
||||
private final String caption;
|
||||
private GameLogLevel(String name) {
|
||||
this.caption = name;
|
||||
}
|
||||
|
||||
public String getCaption() {
|
||||
return caption;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import forge.Command;
|
||||
import forge.Constant;
|
||||
import forge.CounterType;
|
||||
import forge.GameEntity;
|
||||
import forge.GameLogLevel;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
@@ -207,7 +208,7 @@ public class CardFactoryUtil {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(this.getActivatingPlayer()).append(" has unmorphed ");
|
||||
sb.append(sourceCard.getName());
|
||||
sourceCard.getGame().getGameLog().add("ResolveStack", sb.toString(), 2);
|
||||
sourceCard.getGame().getGameLog().add("ResolveStack", sb.toString(), GameLogLevel.STACK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +434,7 @@ public class CardFactoryUtil {
|
||||
sb.append(this.getActivatingPlayer()).append(" has suspended ");
|
||||
sb.append(c.getName()).append("with ");
|
||||
sb.append(counters).append(" time counters on it.");
|
||||
game.getGameLog().add("ResolveStack", sb.toString(), 2);
|
||||
game.getGameLog().add("ResolveStack", sb.toString(), GameLogLevel.STACK);
|
||||
}
|
||||
};
|
||||
final StringBuilder sbDesc = new StringBuilder();
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import forge.Card;
|
||||
import forge.GameLogLevel;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
@@ -149,7 +150,7 @@ public class ReplacementHandler {
|
||||
ReplacementResult res = this.executeReplacement(runParams, chosenRE, decider, game);
|
||||
if (res != ReplacementResult.NotReplaced) {
|
||||
chosenRE.setHasRun(false);
|
||||
game.getGameLog().add("ReplacementEffect", chosenRE.toString(), 2);
|
||||
game.getGameLog().add("ReplacementEffect", chosenRE.toString(), GameLogLevel.EFFECT_REPLACED);
|
||||
return res;
|
||||
} else {
|
||||
if (possibleReplacers.size() == 0) {
|
||||
|
||||
@@ -375,5 +375,8 @@ public enum FControl {
|
||||
}
|
||||
|
||||
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
|
||||
//Set Field shown to current player.
|
||||
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(game.getPlayers().get(0));
|
||||
SDisplayUtil.showTab(nextField);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.google.common.collect.Lists;
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.GameLogLevel;
|
||||
import forge.card.trigger.Trigger;
|
||||
import forge.card.trigger.TriggerHandler;
|
||||
import forge.card.trigger.TriggerType;
|
||||
@@ -313,10 +314,10 @@ public class GameNew {
|
||||
Predicate<Card> goodForAnte = Predicates.not(CardPredicates.Presets.BASIC_LANDS);
|
||||
Card ante = Aggregates.random(Iterables.filter(lib, goodForAnte));
|
||||
if (ante == null) {
|
||||
game.getGameLog().add("Ante", "Only basic lands found. Will ante one of them", 0);
|
||||
game.getGameLog().add("Ante", "Only basic lands found. Will ante one of them", GameLogLevel.ANTE);
|
||||
ante = Aggregates.random(lib);
|
||||
}
|
||||
game.getGameLog().add("Ante", p + " anted " + ante, 0);
|
||||
game.getGameLog().add("Ante", p + " anted " + ante, GameLogLevel.ANTE);
|
||||
game.getAction().moveTo(ZoneType.Ante, ante);
|
||||
msg.append(p.getName()).append(" ante: ").append(ante).append(nl);
|
||||
}
|
||||
|
||||
@@ -17,14 +17,16 @@
|
||||
*/
|
||||
package forge.game;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerOutcome;
|
||||
import forge.game.player.PlayerStatistics;
|
||||
|
||||
/**
|
||||
@@ -39,7 +41,7 @@ import forge.game.player.PlayerStatistics;
|
||||
// This class might be divided in two parts: the very summary (immutable with
|
||||
// only getters) and
|
||||
// GameObserver class - who should be notified of any considerable ingame event
|
||||
public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStatistics>> {
|
||||
public final class GameOutcome implements Iterable<Pair<LobbyPlayer, PlayerStatistics>> {
|
||||
|
||||
|
||||
/** The player got first turn. */
|
||||
@@ -49,55 +51,32 @@ public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStat
|
||||
private int lastTurnNumber = 0;
|
||||
|
||||
/** The player rating. */
|
||||
private final Map<LobbyPlayer, PlayerStatistics> playerRating = new HashMap<LobbyPlayer, PlayerStatistics>(4);
|
||||
private final List<Pair<LobbyPlayer, PlayerStatistics>> playerRating = new ArrayList<Pair<LobbyPlayer, PlayerStatistics>>(2);
|
||||
|
||||
private GameEndReason winCondition;
|
||||
|
||||
/**
|
||||
* Instantiates a new game summary.
|
||||
*
|
||||
* @param names
|
||||
* the names
|
||||
*/
|
||||
public GameOutcome(GameEndReason reason, final Player... names) {
|
||||
this(reason, Arrays.asList(names));
|
||||
}
|
||||
|
||||
public GameOutcome(GameEndReason reason, final Iterable<Player> list) {
|
||||
winCondition = reason;
|
||||
for (final Player n : list) {
|
||||
this.playerRating.put(n.getLobbyPlayer(), n.getStats());
|
||||
this.playerRating.add(Pair.of(n.getLobbyPlayer(), n.getStats()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if is draw.
|
||||
*
|
||||
* @return true, if is draw
|
||||
*/
|
||||
public boolean isDraw() {
|
||||
for (PlayerStatistics pv : playerRating.values()) {
|
||||
|
||||
if (pv.getOutcome().hasWon()) {
|
||||
for (Pair<LobbyPlayer, PlayerStatistics> pv : playerRating) {
|
||||
if (pv.getValue().getOutcome().hasWon()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is winner.
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @return true, if is winner
|
||||
*/
|
||||
|
||||
public boolean isWinner(final LobbyPlayer who) {
|
||||
PlayerStatistics stats = playerRating.get(who);
|
||||
if ( stats == null )
|
||||
return false;
|
||||
return stats.getOutcome().hasWon();
|
||||
for (Pair<LobbyPlayer, PlayerStatistics> pv : playerRating)
|
||||
if (pv.getValue().getOutcome().hasWon() && pv.getKey() == who )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,8 +85,7 @@ public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStat
|
||||
* @return the winner
|
||||
*/
|
||||
public LobbyPlayer getWinner() {
|
||||
for (Entry<LobbyPlayer, PlayerStatistics> ps : playerRating.entrySet()) {
|
||||
|
||||
for (Entry<LobbyPlayer, PlayerStatistics> ps : playerRating) {
|
||||
if (ps.getValue().getOutcome().hasWon()) {
|
||||
return ps.getKey();
|
||||
}
|
||||
@@ -124,17 +102,6 @@ public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStat
|
||||
return this.winCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player rating.
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @return the player rating
|
||||
*/
|
||||
public PlayerStatistics getStatistics(final LobbyPlayer name) {
|
||||
return this.playerRating.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the turn game ended.
|
||||
*
|
||||
@@ -159,10 +126,10 @@ public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStat
|
||||
* @return the win spell effect
|
||||
*/
|
||||
public String getWinSpellEffect() {
|
||||
for (PlayerStatistics pv : playerRating.values()) {
|
||||
|
||||
if (pv.getOutcome().hasWon()) {
|
||||
return pv.getOutcome().altWinSourceName;
|
||||
for (Pair<LobbyPlayer, PlayerStatistics> pv : playerRating) {
|
||||
PlayerOutcome po = pv.getValue().getOutcome();
|
||||
if (po.hasWon()) {
|
||||
return po.altWinSourceName;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -172,8 +139,8 @@ public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStat
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
@Override
|
||||
public Iterator<Entry<LobbyPlayer, PlayerStatistics>> iterator() {
|
||||
return playerRating.entrySet().iterator();
|
||||
public Iterator<Pair<LobbyPlayer, PlayerStatistics>> iterator() {
|
||||
return playerRating.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,4 +151,12 @@ public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStat
|
||||
lastTurnNumber = turnNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @return
|
||||
*/
|
||||
public int getNumPlayers() {
|
||||
return playerRating.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@ package forge.game;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -18,11 +15,8 @@ import forge.game.event.DuelOutcomeEvent;
|
||||
import forge.game.event.FlipCoinEvent;
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerStatistics;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.gui.match.CMatchUI;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.gui.match.ViewWinLose;
|
||||
import forge.gui.match.nonsingleton.VField;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
@@ -95,32 +89,12 @@ public class MatchController {
|
||||
result.setTurnsPlayed(game.getPhaseHandler().getTurn());
|
||||
gamesPlayed.add(result);
|
||||
|
||||
// Play the win/lose sound
|
||||
game.getEvents().post(new DuelOutcomeEvent(result.getWinner()));
|
||||
game.getGameLog().add("Final", result.getWinner() + " won", 0);
|
||||
|
||||
// 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);
|
||||
game.getGameLog().add("Final", outcome, 0);
|
||||
}
|
||||
|
||||
final String statsSummary = generateSummary();
|
||||
game.getGameLog().add("Final", statsSummary, 0);
|
||||
|
||||
// The log shall listen to events and generate text internally
|
||||
game.getEvents().post(new DuelOutcomeEvent(result, gamesPlayedRo));
|
||||
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
||||
String title = result.getWinner().getName() + " Won!";
|
||||
ViewWinLose v = new ViewWinLose(MatchController.this);
|
||||
v.setTitle(title);
|
||||
v.setOutcomes(outcomes);
|
||||
v.setStatsSummary(statsSummary);
|
||||
SOverlayUtils.showOverlay();
|
||||
} });
|
||||
}
|
||||
|
||||
@@ -149,10 +123,6 @@ public class MatchController {
|
||||
if(currentGame.getType() == GameType.Planechase)
|
||||
firstPlayer.initPlane();
|
||||
|
||||
//Set Field shown to current player.
|
||||
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(firstPlayer);
|
||||
SDisplayUtil.showTab(nextField);
|
||||
|
||||
// Update observers
|
||||
currentGame.getGameLog().updateObservers();
|
||||
|
||||
@@ -191,6 +161,10 @@ public class MatchController {
|
||||
return gamesPlayed.isEmpty() ? null : gamesPlayed.get(gamesPlayed.size() - 1);
|
||||
}
|
||||
|
||||
public Iterable<GameOutcome> getOutcomes() {
|
||||
return gamesPlayedRo;
|
||||
}
|
||||
|
||||
public GameState getCurrentGame() {
|
||||
return currentGame;
|
||||
}
|
||||
@@ -238,29 +212,6 @@ public class MatchController {
|
||||
return sum;
|
||||
}
|
||||
|
||||
public String generateSummary() {
|
||||
HashMap<LobbyPlayer, Integer> playerWins = new HashMap<LobbyPlayer, Integer>();
|
||||
|
||||
for(Pair<LobbyPlayer, PlayerStartConditions> playerPair : this.players) {
|
||||
playerWins.put(playerPair.getKey(), 0);
|
||||
}
|
||||
|
||||
for (GameOutcome go : gamesPlayed) {
|
||||
LobbyPlayer p = go.getWinner();
|
||||
if (p != null) {
|
||||
int incrementWins = playerWins.get(p) + 1;
|
||||
playerWins.put(p, incrementWins);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder("");
|
||||
for(LobbyPlayer p : playerWins.keySet()) {
|
||||
sb.append(p.getName()).append(": ");
|
||||
sb.append(playerWins.get(p)).append(" ");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
*
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package forge.game.event;
|
||||
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import java.util.List;
|
||||
|
||||
import forge.game.GameOutcome;
|
||||
|
||||
public class DuelOutcomeEvent extends Event {
|
||||
public final LobbyPlayer winner;
|
||||
public final GameOutcome result;
|
||||
public final List<GameOutcome> history;
|
||||
|
||||
public DuelOutcomeEvent(LobbyPlayer winner) {
|
||||
this.winner = winner;
|
||||
public DuelOutcomeEvent(GameOutcome lastOne, List<GameOutcome> history) {
|
||||
this.result = lastOne;
|
||||
this.history = history;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -970,12 +970,12 @@ public class CombatUtil {
|
||||
*
|
||||
* @return a String
|
||||
*/
|
||||
public static String getCombatAttackForLog(GameState game) {
|
||||
public static String getCombatAttackForLog(final Combat combat) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
// Loop through Defenders
|
||||
// Append Defending Player/Planeswalker
|
||||
final Combat combat = game.getCombat();
|
||||
|
||||
|
||||
|
||||
// Not a big fan of the triple nested loop here
|
||||
@@ -999,12 +999,12 @@ public class CombatUtil {
|
||||
*
|
||||
* @return a String
|
||||
*/
|
||||
public static String getCombatBlockForLog(GameState game) {
|
||||
public static String getCombatBlockForLog(final Combat combat) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
// Loop through Defenders
|
||||
// Append Defending Player/Planeswalker
|
||||
final Combat combat = game.getCombat();
|
||||
|
||||
List<Card> blockers = null;
|
||||
|
||||
|
||||
@@ -1020,7 +1020,7 @@ public class CombatUtil {
|
||||
for (final Card attacker : attackers) {
|
||||
if ( !firstAttacker ) sb.append("\n");
|
||||
|
||||
blockers = game.getCombat().getBlockers(attacker);
|
||||
blockers = combat.getBlockers(attacker);
|
||||
if ( blockers.isEmpty() ) {
|
||||
sb.append(controllerName).append(" didn't block ");
|
||||
} else {
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import forge.Card;
|
||||
import forge.FThreads;
|
||||
import forge.GameLogLevel;
|
||||
import forge.Singletons;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.game.GameState;
|
||||
@@ -507,15 +508,16 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
game.getGameLog().add(sb.toString(), this.getPlayerTurn() + " " + this.getPhase().Name, 6);
|
||||
|
||||
|
||||
// **** Anything BELOW Here is actually in the next phase. Maybe move
|
||||
// this to handleBeginPhase
|
||||
if (this.phase == PhaseType.UNTAP) {
|
||||
this.turn++;
|
||||
game.getGameLog().add("Turn", "Turn " + this.turn + " (" + this.getPlayerTurn() + ")", 0);
|
||||
game.getGameLog().add("Turn", "Turn " + this.turn + " (" + this.getPlayerTurn() + ")", GameLogLevel.TURN);
|
||||
}
|
||||
|
||||
game.getGameLog().add(sb.toString(), this.getPlayerTurn() + " " + this.getPhase().Name, GameLogLevel.PHASE);
|
||||
PhaseUtil.visuallyActivatePhase(this.getPlayerTurn(), this.getPhase());
|
||||
|
||||
// When consecutively skipping phases (like in combat) this section
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.google.common.base.Predicate;
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.GameLogLevel;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.spellability.Ability;
|
||||
@@ -175,7 +176,7 @@ public class PhaseUtil {
|
||||
|
||||
}
|
||||
|
||||
game.getGameLog().add("Combat", CombatUtil.getCombatAttackForLog(game), 1);
|
||||
game.getGameLog().add("Combat", CombatUtil.getCombatAttackForLog(game.getCombat()), GameLogLevel.COMBAT);
|
||||
|
||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||
runParams.put("Attackers", list);
|
||||
@@ -271,7 +272,7 @@ public class PhaseUtil {
|
||||
|
||||
game.getStack().unfreezeStack();
|
||||
|
||||
game.getGameLog().add("Combat", CombatUtil.getCombatBlockForLog(game), 1);
|
||||
game.getGameLog().add("Combat", CombatUtil.getCombatBlockForLog(game.getCombat()), GameLogLevel.COMBAT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import forge.CardLists;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.CounterType;
|
||||
import forge.FThreads;
|
||||
import forge.GameLogLevel;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
import forge.card.ability.effects.CharmEffect;
|
||||
@@ -355,7 +356,7 @@ public class HumanPlay {
|
||||
|
||||
if (false == source.canReceiveCounters(counterType)) {
|
||||
String message = String.format("Won't be able to pay upkeep for %s but it can't have %s counters put on it.", source, counterType.getName());
|
||||
p.getGame().getGameLog().add("ResolveStack", message, 2);
|
||||
p.getGame().getGameLog().add("ResolveStack", message, GameLogLevel.STACK);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import forge.Constant.Preferences;
|
||||
import forge.CounterType;
|
||||
import forge.FThreads;
|
||||
import forge.GameEntity;
|
||||
import forge.GameLogLevel;
|
||||
import forge.Singletons;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
@@ -680,7 +681,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
game.getTriggerHandler().runTrigger(TriggerType.DamageDone, runParams, false);
|
||||
|
||||
game.getGameLog().add("Damage", String.format("Dealing %d damage to %s. %s",
|
||||
damageToDo, this.getName(), additionalLog), 3);
|
||||
damageToDo, this.getName(), additionalLog), GameLogLevel.DAMAGE);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1028,7 +1029,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
this.poisonCounters += num;
|
||||
|
||||
game.getEvents().post(new PoisonCounterEvent(this, source, num));
|
||||
game.getGameLog().add("Poison", this + " receives a poison counter from " + source, 3);
|
||||
game.getGameLog().add("Poison", this + " receives a poison counter from " + source, GameLogLevel.DAMAGE);
|
||||
|
||||
this.updateObservers();
|
||||
}
|
||||
@@ -1255,7 +1256,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
|
||||
game.getEvents().post(new MulliganEvent(this)); // quest listener may interfere here
|
||||
final int newHand = getCardsIn(ZoneType.Hand).size();
|
||||
game.getGameLog().add("Mulligan", this + " has mulliganed down to " + newHand + " cards.", 0);
|
||||
game.getGameLog().add("Mulligan", this + " has mulliganed down to " + newHand + " cards.", GameLogLevel.MULLIGAN);
|
||||
stats.notifyHasMulliganed();
|
||||
stats.notifyOpeningHandSize(newHand);
|
||||
}
|
||||
@@ -1799,7 +1800,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
game.getAction().checkStateEffects();
|
||||
|
||||
// add to log
|
||||
game.getGameLog().add("Land", this + " played " + land, 2);
|
||||
game.getGameLog().add("Land", this + " played " + land, GameLogLevel.LAND);
|
||||
|
||||
// play a sound
|
||||
game.getEvents().post(new LandPlayedEvent(this, land));
|
||||
@@ -3159,7 +3160,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
public void onMulliganned() {
|
||||
game.getEvents().post(new MulliganEvent(this)); // quest listener may interfere here
|
||||
final int newHand = getCardsIn(ZoneType.Hand).size();
|
||||
game.getGameLog().add("Mulligan", this + " has mulliganed down to " + newHand + " cards.", 0);
|
||||
game.getGameLog().add("Mulligan", this + " has mulliganed down to " + newHand + " cards.", GameLogLevel.MULLIGAN);
|
||||
stats.notifyHasMulliganed();
|
||||
stats.notifyOpeningHandSize(newHand);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.FThreads;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.GameLogLevel;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
@@ -310,7 +311,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
||||
AbilityUtils.resolve(sp, false);
|
||||
//sp.resolve();
|
||||
sp.resetOnceResolved();
|
||||
game.getGameLog().add("Mana", sp.getSourceCard() + " - " + sp.getDescription(), 4);
|
||||
game.getGameLog().add("Mana", sp.getSourceCard() + " - " + sp.getDescription(), GameLogLevel.MANA);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -354,7 +355,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
||||
}
|
||||
sb.append(".");
|
||||
|
||||
game.getGameLog().add("AddToStack", sb.toString(), 2);
|
||||
game.getGameLog().add("AddToStack", sb.toString(), GameLogLevel.STACK);
|
||||
//============= GameLog ======================
|
||||
|
||||
// if activating player slips through the cracks, assign activating
|
||||
@@ -603,7 +604,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
||||
|
||||
boolean thisHasFizzled = this.hasFizzled(sa, source, false);
|
||||
String messageForLog = thisHasFizzled ? source.getName() + " ability fizzles." : sa.getStackDescription();
|
||||
game.getGameLog().add("ResolveStack", messageForLog, 2);
|
||||
game.getGameLog().add("ResolveStack", messageForLog, GameLogLevel.STACK);
|
||||
if (thisHasFizzled) { // Fizzle
|
||||
// TODO: Spell fizzles, what's the best way to alert player?
|
||||
Log.debug(source.getName() + " ability fizzles.");
|
||||
|
||||
@@ -5,8 +5,6 @@ import java.awt.Font;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
@@ -15,9 +13,11 @@ import javax.swing.SwingUtilities;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.Command;
|
||||
import forge.GameLog;
|
||||
import forge.GameLogEntry;
|
||||
import forge.GameLogLevel;
|
||||
import forge.Singletons;
|
||||
import forge.game.MatchController;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.gui.toolbox.FButton;
|
||||
import forge.gui.toolbox.FLabel;
|
||||
import forge.gui.toolbox.FOverlay;
|
||||
@@ -37,8 +37,6 @@ public class ViewWinLose {
|
||||
private final JLabel lblStats = new JLabel("WinLoseFrame > lblStats needs updating.");
|
||||
private final JPanel pnlOutcomes = new JPanel(new MigLayout("wrap, align center"));
|
||||
|
||||
/**
|
||||
* @param match */
|
||||
@SuppressWarnings("serial")
|
||||
public ViewWinLose(MatchController match) {
|
||||
final JPanel overlay = FOverlay.SINGLETON_INSTANCE.getPanel();
|
||||
@@ -177,21 +175,15 @@ public class ViewWinLose {
|
||||
}
|
||||
});
|
||||
|
||||
SOverlayUtils.showOverlay();
|
||||
}
|
||||
lblTitle.setText(match.getLastGameOutcome().getWinner().getName() + " Won!");
|
||||
|
||||
public void setTitle(String title) {
|
||||
lblTitle.setText(title);
|
||||
}
|
||||
GameLog log = match.getCurrentGame().getGameLog();
|
||||
|
||||
public void setOutcomes(List<String> outcomes) {
|
||||
for (String o : outcomes) {
|
||||
pnlOutcomes.add(new FLabel.Builder().text(o).fontSize(14).build(), "h 20!");
|
||||
}
|
||||
}
|
||||
for (GameLogEntry o : log.getLogEntriesExact(GameLogLevel.GAME_OUTCOME))
|
||||
pnlOutcomes.add(new FLabel.Builder().text(o.message).fontSize(14).build(), "h 20!");
|
||||
|
||||
public void setStatsSummary(String statsSummary) {
|
||||
lblStats.setText(statsSummary);
|
||||
for (GameLogEntry o : log.getLogEntriesExact(GameLogLevel.MATCH_RESULTS))
|
||||
lblStats.setText(o.message);
|
||||
}
|
||||
|
||||
/** @return {@link forge.gui.toolbox.FButton} */
|
||||
|
||||
@@ -26,7 +26,8 @@ import javax.swing.border.EmptyBorder;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.GameLog;
|
||||
import forge.GameLog.LogEntry;
|
||||
import forge.GameLogEntry;
|
||||
import forge.GameLogLevel;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
@@ -118,13 +119,13 @@ public enum VLog implements IVDoc<CLog> {
|
||||
|
||||
// TODO - some option to make this configurable is probably desirable
|
||||
// By default, grab everything log level 3 or less.
|
||||
final List<LogEntry> data = model.getLogEntries(3);
|
||||
final List<GameLogEntry> data = model.getLogEntries(GameLogLevel.DAMAGE);
|
||||
final int size = data.size();
|
||||
|
||||
pnl.removeAll();
|
||||
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
JTextArea tar = new JTextArea(data.get(i).getMessage());
|
||||
JTextArea tar = new JTextArea(data.get(i).message);
|
||||
|
||||
if (i % 2 == 1) { tar.setOpaque(false); }
|
||||
else { tar.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA)); }
|
||||
|
||||
@@ -81,7 +81,7 @@ public class EventVisualizer {
|
||||
return getSoundEffectForTapState(((SetTappedEvent) evt).Tapped);
|
||||
}
|
||||
if (evt instanceof DuelOutcomeEvent) {
|
||||
return getSoundEffectForDuelOutcome(((DuelOutcomeEvent) evt).winner.getType() == PlayerType.HUMAN);
|
||||
return getSoundEffectForDuelOutcome(((DuelOutcomeEvent) evt).result.getWinner().getType() == PlayerType.HUMAN);
|
||||
}
|
||||
|
||||
return fromMap;
|
||||
|
||||
Reference in New Issue
Block a user