diff --git a/.gitattributes b/.gitattributes index 4e2295115ad..398b37ce1bf 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10559,6 +10559,7 @@ src/main/java/forge/FileUtil.java svneol=native#text/plain src/main/java/forge/GameAction.java svneol=native#text/plain src/main/java/forge/GameActionUtil.java svneol=native#text/plain src/main/java/forge/GameEntity.java -text +src/main/java/forge/GameLog.java -text src/main/java/forge/GuiDisplay.java svneol=native#text/plain src/main/java/forge/GuiDisplayUtil.java svneol=native#text/plain src/main/java/forge/GuiDownloadPicturesLQ.java svneol=native#text/plain diff --git a/src/main/java/forge/AllZone.java b/src/main/java/forge/AllZone.java index 65696578647..63fa28dd2b8 100644 --- a/src/main/java/forge/AllZone.java +++ b/src/main/java/forge/AllZone.java @@ -292,6 +292,24 @@ public final class AllZone { return null; } + /** + *

+ * getGameLog. + *

+ * + * @return a {@link forge.GameLog} object; may be null. + * @since 1.2.0 + */ + public static GameLog getGameLog() { + final FGameState gameState = Singletons.getModel().getGameState(); + + if (gameState != null) { + return gameState.getGameLog(); + } + + return null; + } + /** *

* getCardFactory. diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index e6c72b3daeb..5162d0c66a9 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -1486,6 +1486,8 @@ public class GameAction { AllZone.getInputControl().setInput(new InputMulligan()); Phase.setGameBegins(1); + + AllZone.getGameLog().add("Turn", "Turn " + AllZone.getPhase().getTurn() + " (" + AllZone.getPhase().getPlayerTurn()+")", 0); } // newGame() // this is where the computer cheats diff --git a/src/main/java/forge/GameLog.java b/src/main/java/forge/GameLog.java new file mode 100644 index 00000000000..f4466d30307 --- /dev/null +++ b/src/main/java/forge/GameLog.java @@ -0,0 +1,82 @@ + +package forge; + +import java.util.ArrayList; + + +/** + *

+ * GameLog class. + *

+ * + * Logging level: + * 0 - Turn + * 2 - Stack items + * 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 log = new ArrayList(); + + public GameLog() { + + } + + public void add(final String type, final String message, final int level) { + log.add(new LogEntry(type, message, level)); + this.updateObservers(); + } + + public String getLogText() { + return getLogText(10); + } + + 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()); + sb.append("\r\n"); + } + return sb.toString(); + } + + public void reset() { + log.clear(); + this.updateObservers(); + } + + public LogEntry getLogEntry(int index) { + return log.get(index); + } + + private class LogEntry { + private String type; + private String message; + private int level; + + 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; + } + } +} // end class GameLog diff --git a/src/main/java/forge/MagicStack.java b/src/main/java/forge/MagicStack.java index 8ba69da1b44..906597f4974 100644 --- a/src/main/java/forge/MagicStack.java +++ b/src/main/java/forge/MagicStack.java @@ -375,6 +375,7 @@ public class MagicStack extends MyObservable { if (sp instanceof AbilityMana) { // Mana Abilities go straight through sp.resolve(); sp.resetOnceResolved(); + AllZone.getGameLog().add("Mana", sp.getSourceCard() + " - " + sp.getDescription(), 4); return; } @@ -383,6 +384,28 @@ public class MagicStack extends MyObservable { this.getFrozenStack().push(si); return; } + + //============= GameLog ====================== + StringBuilder sb = new StringBuilder(); + sb.append(sp.getActivatingPlayer()); + if (sp.isSpell()) { + sb.append(" cast "); + } + else if (sp.isAbility()) { + sb.append(" activated "); + } + sb.append(sp.getSourceCard()); + + if (sp.getTarget() != null) { + sb.append(" targeting "); + for (TargetChoices ch : chosenTargets) { + sb.append(ch.getTargetedString()); + } + } + sb.append("."); + + AllZone.getGameLog().add("AddToStack", sb.toString(), 2); + //============= GameLog ====================== // if activating player slips through the cracks, assign activating // Player to the controller here @@ -938,7 +961,8 @@ public class MagicStack extends MyObservable { } } } - + + AllZone.getGameLog().add("ResolveStack", sa.getStackDescription(), 2); } /** diff --git a/src/main/java/forge/Phase.java b/src/main/java/forge/Phase.java index 4e478217072..24e81cd8438 100644 --- a/src/main/java/forge/Phase.java +++ b/src/main/java/forge/Phase.java @@ -526,11 +526,14 @@ public class Phase extends MyObservable implements java.io.Serializable { this.bRepeat = false; } } + + AllZone.getGameLog().add("Phase", getPlayerTurn() + " " + getPhase(), 6); // **** Anything BELOW Here is actually in the next phase. Maybe move // this to handleBeginPhase if (this.getPhase().equals(Constant.Phase.UNTAP)) { this.turn++; + AllZone.getGameLog().add("Turn", "Turn " + turn + " ("+getPlayerTurn()+")", 0); } // Visual indicators diff --git a/src/main/java/forge/Player.java b/src/main/java/forge/Player.java index 04954655d93..b5505702ba8 100644 --- a/src/main/java/forge/Player.java +++ b/src/main/java/forge/Player.java @@ -1680,6 +1680,9 @@ public abstract class Player extends GameEntity { // check state effects for static animate (Living Lands, Conversion, // etc...) AllZone.getGameAction().checkStateEffects(); + + //add to log + AllZone.getGameLog().add("Land", this + " played " + land, 2); // Run triggers final HashMap runParams = new HashMap(); diff --git a/src/main/java/forge/control/match/ControlTabber.java b/src/main/java/forge/control/match/ControlTabber.java index 520ca868421..1ae4d464d62 100644 --- a/src/main/java/forge/control/match/ControlTabber.java +++ b/src/main/java/forge/control/match/ControlTabber.java @@ -73,8 +73,17 @@ public class ControlTabber extends MyObservable { ControlTabber.this.view.updateStack(); } }; + + //Game Log + final Observer o2 = new Observer() { + @Override + public void update(final Observable a, final Object b) { + ControlTabber.this.view.updateConsole(); + } + }; AllZone.getStack().addObserver(o1); + AllZone.getGameLog().addObserver(o2); } /** Adds listeners to various components in tabber. */ diff --git a/src/main/java/forge/model/FGameState.java b/src/main/java/forge/model/FGameState.java index 809c30f0c73..b9cfb93a0bf 100644 --- a/src/main/java/forge/model/FGameState.java +++ b/src/main/java/forge/model/FGameState.java @@ -25,6 +25,7 @@ import forge.DefaultPlayerZone; import forge.EndOfCombat; import forge.EndOfTurn; import forge.GameAction; +import forge.GameLog; import forge.HumanPlayer; import forge.MagicStack; import forge.Phase; @@ -57,6 +58,7 @@ public class FGameState { private StaticEffects staticEffects = new StaticEffects(); private TriggerHandler triggerHandler = new TriggerHandler(); private Combat combat = new Combat(); + private GameLog gameLog = new GameLog(); private PlayerZone stackZone = new DefaultPlayerZone(Constant.Zone.Stack, null); @@ -287,6 +289,25 @@ public class FGameState { this.combat = combat0; } + /** + * Gets the game log. + * + * @return the game log + */ + public final GameLog getGameLog() { + return this.gameLog; + } + + /** + * Sets the game log. + * + * @param combat0 + * the combat to set + */ + public final void setgameLog(final GameLog gl) { + this.gameLog = gl; + } + /** * Gets the stack zone. * @@ -356,6 +377,8 @@ public class FGameState { this.getPhase().reset(); this.getStack().reset(); this.getCombat().reset(); + + this.getGameLog().reset(); for (final Player p : this.getPlayers()) { for (final Zone z : Player.ALL_ZONES) { diff --git a/src/main/java/forge/view/match/ViewTabber.java b/src/main/java/forge/view/match/ViewTabber.java index 37f1e46002e..0faaa23e377 100644 --- a/src/main/java/forge/view/match/ViewTabber.java +++ b/src/main/java/forge/view/match/ViewTabber.java @@ -39,6 +39,7 @@ import javax.swing.border.MatteBorder; import net.miginfocom.swing.MigLayout; import forge.AllZone; import forge.Constant; +import forge.GameLog; import forge.MagicStack; import forge.Player; import forge.card.spellability.SpellAbilityStackInstance; @@ -229,6 +230,36 @@ public class ViewTabber extends FRoundedPanel { this.pnlCombat.add(tar, "w 95%!, gapleft 3%, gaptop 1%, h 95%"); } + /** + * Sets the text for the GameLog + * + * @param s + *   String message + */ + public void updateConsole() { + final GameLog gl = AllZone.getGameLog(); + + this.pnlConsole.removeAll(); + + final Font font = this.skin.getFont1().deriveFont(Font.PLAIN, 14); + final Border border = new MatteBorder(0, 0, 1, 0, this.skin.getClrBorders()); + + //by default, grab everything logging level 2 or less + //TODO - some option to make this configurable is probably desirable + JTextArea tar = new JTextArea(gl.getLogText(2)); + tar.setOpaque(false); + tar.setBorder(border); + tar.setFont(font); + tar.setForeground(this.skin.getClrText()); + + tar.setFocusable(false); + tar.setEditable(false); + tar.setLineWrap(true); + tar.setWrapStyleWord(true); + + this.pnlConsole.add(tar, "w 95%!, gapleft 3%, gaptop 1%"); + } + /** * Updates labels in the "player" panel, which display non-critical details * about each player in the game. @@ -276,6 +307,15 @@ public class ViewTabber extends FRoundedPanel { return this.pnlCombat; } + /** + * Gets the pnl console. + * + * @return FPanel + */ + public FPanel getPnlConsole() { + return this.pnlConsole; + } + /** * Gets the pnl players. * @@ -489,7 +529,7 @@ public class ViewTabber extends FRoundedPanel { log.setFont(this.skin.getFont1().deriveFont(Font.PLAIN, 12)); log.setBorder(new MatteBorder(1, 0, 0, 0, this.skin.getClrBorders())); - log.setText("Not implemented yet. Input codes entered above. " + "Output data recorded below."); + log.setText("No log information yet. Input codes entered above. " + "Output data recorded below."); this.pnlConsole.setLayout(new MigLayout("insets 0, gap 0, wrap 2"));