From 01c2648555b3d512d8ec3106da3443558422aee6 Mon Sep 17 00:00:00 2001 From: elcnesh Date: Tue, 2 Sep 2014 10:37:11 +0000 Subject: [PATCH] Add views to GUI refactoring, and update some more code. --- .gitattributes | 8 + .../forge/screens/match/TargetingOverlay.java | 137 ++- .../forge/screens/match/VAssignDamage.java | 50 +- .../main/java/forge/view/arcane/PlayArea.java | 6 +- .../forge/player/PlayerControllerHuman.java | 63 +- .../main/java/forge/util/gui/SGuiDialog.java | 15 +- .../src/main/java/forge/view/CardView.java | 1027 +++++++++++++++++ .../src/main/java/forge/view/CombatView.java | 37 + .../main/java/forge/view/GameEntityView.java | 5 + .../src/main/java/forge/view/IGameView.java | 61 + .../src/main/java/forge/view/PlayerView.java | 303 +++++ .../java/forge/view/SpellAbilityView.java | 21 + .../main/java/forge/view/StackItemView.java | 50 + .../src/main/java/forge/view/ViewUtil.java | 90 ++ 14 files changed, 1749 insertions(+), 124 deletions(-) create mode 100644 forge-gui/src/main/java/forge/view/CardView.java create mode 100644 forge-gui/src/main/java/forge/view/CombatView.java create mode 100644 forge-gui/src/main/java/forge/view/GameEntityView.java create mode 100644 forge-gui/src/main/java/forge/view/IGameView.java create mode 100644 forge-gui/src/main/java/forge/view/PlayerView.java create mode 100644 forge-gui/src/main/java/forge/view/SpellAbilityView.java create mode 100644 forge-gui/src/main/java/forge/view/StackItemView.java create mode 100644 forge-gui/src/main/java/forge/view/ViewUtil.java diff --git a/.gitattributes b/.gitattributes index 2fe032880b3..8af802ef69c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16842,6 +16842,14 @@ forge-gui/src/main/java/forge/util/gui/SGuiChoose.java -text forge-gui/src/main/java/forge/util/gui/SGuiDialog.java -text forge-gui/src/main/java/forge/util/gui/SOptionPane.java -text forge-gui/src/main/java/forge/util/package-info.java -text +forge-gui/src/main/java/forge/view/CardView.java -text +forge-gui/src/main/java/forge/view/CombatView.java -text +forge-gui/src/main/java/forge/view/GameEntityView.java -text +forge-gui/src/main/java/forge/view/IGameView.java -text +forge-gui/src/main/java/forge/view/PlayerView.java -text +forge-gui/src/main/java/forge/view/SpellAbilityView.java -text +forge-gui/src/main/java/forge/view/StackItemView.java -text +forge-gui/src/main/java/forge/view/ViewUtil.java -text forge-gui/src/main/resources/proxy-template.ftl -text forge-gui/src/site/apt/index.apt -text forge-gui/tools/PerSetTracking.py svneol=native#text/x-python diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java b/forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java index fb094a3c014..b1a072b571e 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java @@ -17,20 +17,11 @@ */ package forge.screens.match; -import forge.Singletons; -import forge.game.card.Card; -import forge.game.combat.Combat; -import forge.gui.framework.FScreen; -import forge.screens.match.controllers.CDock; -import forge.screens.match.views.VField; -import forge.toolbox.FSkin; -import forge.toolbox.FSkin.SkinnedPanel; -import forge.view.FView; -import forge.view.arcane.CardPanel; - -import javax.swing.*; - -import java.awt.*; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.GeneralPath; @@ -39,6 +30,22 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.swing.JPanel; + +import org.testng.collections.Lists; + +import forge.Singletons; +import forge.gui.framework.FScreen; +import forge.screens.match.controllers.CDock; +import forge.screens.match.views.VField; +import forge.toolbox.FSkin; +import forge.toolbox.FSkin.SkinnedPanel; +import forge.view.CardView; +import forge.view.CombatView; +import forge.view.FView; +import forge.view.GameEntityView; +import forge.view.arcane.CardPanel; + /** * Semi-transparent overlay panel. Should be used with layered panes. * @@ -74,7 +81,7 @@ public enum TargetingOverlay { // TODO - this is called every repaint, regardless if card // positions have changed or not. Could perform better if // it checked for a state change. Doublestrike 28-09-12 - private void assembleArcs(Combat combat) { + private void assembleArcs(final CombatView combat) { //List fields = VMatchUI.SINGLETON_INSTANCE.getFieldViews(); arcsCombat.clear(); arcsOther.clear(); @@ -115,7 +122,7 @@ public enum TargetingOverlay { for (CardPanel c : cardPanels) { if (c.isShowing()) { cardLocOnScreen = c.getCardLocationOnScreen(); - endpoints.put(c.getCard().getUniqueNumber(), new Point( + endpoints.put(c.getCard().getId(), new Point( (int) (cardLocOnScreen.getX() - locOnScreen.getX() + c.getWidth() / 4), (int) (cardLocOnScreen.getY() - locOnScreen.getY() + c.getHeight() / 2) )); @@ -124,16 +131,16 @@ public enum TargetingOverlay { if (CDock.SINGLETON_INSTANCE.getArcState() == 1) { // Only work with the active panel - Card c = activePanel.getCard(); + final CardView c = activePanel.getCard(); addArcsForCard(c, endpoints, combat); } else { // Work with all card panels currently visible - List visualized = new ArrayList(); - for (CardPanel c : cardPanels) { + final List visualized = Lists.newArrayList(); + for (final CardPanel c : cardPanels) { if (!c.isShowing()) { continue; } - Card card = c.getCard(); + final CardView card = c.getCard(); if (visualized.contains(card)) { continue; } visualized.addAll(addArcsForCard(card, endpoints, combat)); @@ -141,23 +148,22 @@ public enum TargetingOverlay { } } - private List addArcsForCard(final Card c, final Map endpoints, final Combat combat) { - List cardsVisualized = new ArrayList(); - cardsVisualized.add(c); + private List addArcsForCard(final CardView c, final Map endpoints, final CombatView combat) { + final List cardsVisualized = Lists.newArrayList(c); - Card enchanting = c.getEnchantingCard(); - Card equipping = c.getEquippingCard(); - Card fortifying = c.getFortifyingCard(); - List enchantedBy = c.getEnchantedBy(); - List equippedBy = c.getEquippedBy(); - List fortifiedBy = c.getFortifiedBy(); - Card paired = c.getPairedWith(); + final CardView enchanting = c.getEnchantingCard(); + final CardView equipping = c.getEquipping(); + final CardView fortifying = c.getFortifying(); + final Iterable enchantedBy = c.getEnchantedBy(); + final Iterable equippedBy = c.getEquippedBy(); + final Iterable fortifiedBy = c.getFortifiedBy(); + final CardView paired = c.getPairedWith(); if (null != enchanting) { if (!enchanting.getController().equals(c.getController())) { arcsOther.add(new Point[] { - endpoints.get(enchanting.getUniqueNumber()), - endpoints.get(c.getUniqueNumber()) + endpoints.get(enchanting.getId()), + endpoints.get(c.getId()) }); cardsVisualized.add(enchanting); } @@ -165,8 +171,8 @@ public enum TargetingOverlay { if (null != equipping) { if (!equipping.getController().equals(c.getController())) { arcsOther.add(new Point[] { - endpoints.get(equipping.getUniqueNumber()), - endpoints.get(c.getUniqueNumber()) + endpoints.get(equipping.getId()), + endpoints.get(c.getId()) }); cardsVisualized.add(equipping); } @@ -174,40 +180,40 @@ public enum TargetingOverlay { if (null != fortifying) { if (!fortifying.getController().equals(c.getController())) { arcsOther.add(new Point[] { - endpoints.get(fortifying.getUniqueNumber()), - endpoints.get(c.getUniqueNumber()) + endpoints.get(fortifying.getId()), + endpoints.get(c.getId()) }); cardsVisualized.add(fortifying); } } if (null != enchantedBy) { - for (Card enc : enchantedBy) { + for (final CardView enc : enchantedBy) { if (!enc.getController().equals(c.getController())) { arcsOther.add(new Point[] { - endpoints.get(c.getUniqueNumber()), - endpoints.get(enc.getUniqueNumber()) + endpoints.get(c.getId()), + endpoints.get(enc.getId()) }); cardsVisualized.add(enc); } } } if (null != equippedBy) { - for (Card eq : equippedBy) { + for (final CardView eq : equippedBy) { if (!eq.getController().equals(c.getController())) { arcsOther.add(new Point[] { - endpoints.get(c.getUniqueNumber()), - endpoints.get(eq.getUniqueNumber()) + endpoints.get(c.getId()), + endpoints.get(eq.getId()) }); cardsVisualized.add(eq); } } } if (null != fortifiedBy) { - for (Card eq : fortifiedBy) { + for (final CardView eq : fortifiedBy) { if (!eq.getController().equals(c.getController())) { arcsOther.add(new Point[] { - endpoints.get(c.getUniqueNumber()), - endpoints.get(eq.getUniqueNumber()) + endpoints.get(c.getId()), + endpoints.get(eq.getId()) }); cardsVisualized.add(eq); } @@ -215,29 +221,35 @@ public enum TargetingOverlay { } if (null != paired) { arcsOther.add(new Point[] { - endpoints.get(paired.getUniqueNumber()), - endpoints.get(c.getUniqueNumber()) + endpoints.get(paired.getId()), + endpoints.get(c.getId()) }); cardsVisualized.add(paired); } - if ( null != combat ) { - for (Card planeswalker : combat.getDefendingPlaneswalkers()) { - List cards = combat.getAttackersOf(planeswalker); - for (Card pwAttacker : cards) { - if (!planeswalker.equals(c) && !pwAttacker.equals(c)) { continue; } - arcsCombat.add(new Point[] { - endpoints.get(planeswalker.getUniqueNumber()), - endpoints.get(pwAttacker.getUniqueNumber()) + if (null != combat) { + final GameEntityView defender = combat.getDefender(c); + // if c is attacking a planeswalker + if (defender instanceof CardView) { + arcsCombat.add(new Point[] { + endpoints.get(((CardView)defender).getId()), + endpoints.get(c.getId()) }); - } } - for (Card attackingCard : combat.getAttackers()) { - List cards = combat.getBlockers(attackingCard); - for (Card blockingCard : cards) { + // if c is a planeswalker that's being attacked + final Iterable attackers = combat.getAttackersOf(c); + for (final CardView pwAttacker : attackers) { + arcsCombat.add(new Point[] { + endpoints.get(c.getId()), + endpoints.get(pwAttacker.getId()) + }); + } + for (final CardView attackingCard : combat.getAttackers()) { + final Iterable cards = combat.getBlockers(attackingCard); + for (final CardView blockingCard : cards) { if (!attackingCard.equals(c) && !blockingCard.equals(c)) { continue; } arcsCombat.add(new Point[] { - endpoints.get(attackingCard.getUniqueNumber()), - endpoints.get(blockingCard.getUniqueNumber()) + endpoints.get(attackingCard.getId()), + endpoints.get(blockingCard.getId()) }); cardsVisualized.add(blockingCard); } @@ -340,7 +352,6 @@ public enum TargetingOverlay { */ @Override public void paintComponent(final Graphics g) { - final Combat combat = Singletons.getControl().getObservedGame().getCombat(); // this will get deprecated too // No need for this except in match view if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } @@ -351,7 +362,7 @@ public enum TargetingOverlay { if (overlaystate == 0) { return; } // Arc drawing - assembleArcs(combat); + assembleArcs(Singletons.getControl().getGameView().getCombat()); if (arcsCombat.isEmpty() && arcsOther.isEmpty()) { return; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java b/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java index 555db808de3..fe31b773494 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java @@ -17,11 +17,28 @@ */ package forge.screens.match; +import java.awt.Dialog.ModalityType; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; +import java.util.Map; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.border.Border; + +import net.miginfocom.swing.MigLayout; + +import org.testng.collections.Lists; + +import com.google.common.collect.Maps; + import forge.control.FControl; -import forge.game.GameEntity; -import forge.game.card.Card; -import forge.game.card.CounterType; -import forge.game.player.Player; import forge.gui.SOverlayUtils; import forge.toolbox.FButton; import forge.toolbox.FLabel; @@ -33,25 +50,6 @@ import forge.view.FDialog; import forge.view.GameEntityView; import forge.view.PlayerView; import forge.view.arcane.CardPanel; -import net.miginfocom.swing.MigLayout; - -import javax.swing.*; -import javax.swing.border.Border; - -import org.testng.collections.Lists; - -import com.google.common.collect.Maps; - -import java.awt.Dialog.ModalityType; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; /** * Assembles Swing components of assign damage dialog. @@ -200,13 +198,13 @@ public class VAssignDamage { if (defender instanceof CardView) fakeCard = (CardView)defender; else if (defender instanceof PlayerView) { - fakeCard = new CardView(null, -1); + fakeCard = new CardView(null, -1, true); fakeCard.getState().setName(this.defender.toString()); final PlayerView p = (PlayerView)defender; - fakeCard.getState().setOwner(p); + fakeCard.setOwner(p); fakeCard.getState().setImageKey(CMatchUI.SINGLETON_INSTANCE.avatarImages.get(p.getLobbyPlayer())); } else { - fakeCard = new CardView(null, -2); + fakeCard = new CardView(null, -2, true); fakeCard.getState().setName(this.defender.toString()); } addPanelForDefender(pnlDefenders, fakeCard); diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java index 775d1708769..0ee0321df71 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java @@ -623,13 +623,13 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen } } - List toAdd = new ArrayList(model); + final List toAdd = new ArrayList(model); toAdd.removeAll(oldCards); toAdd.addAll(toReplace); - List newPanels = new ArrayList(); + final List newPanels = new ArrayList(); for (final CardView card : toAdd) { - if (card.getCardForUi() == card) { //only include cards that are meant for display + if (card.isUiDisplayable()) { //only include cards that are meant for display final CardPanel placeholder = new CardPanel(card); placeholder.setDisplayEnabled(false); this.getCardPanels().add(placeholder); diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 55127481dd6..488ddac2a14 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -88,6 +88,7 @@ import forge.util.gui.SGuiChoose; import forge.util.gui.SGuiDialog; import forge.util.gui.SOptionPane; import forge.view.CardView; +import forge.view.CombatView; import forge.view.GameEntityView; import forge.view.IGameView; import forge.view.PlayerView; @@ -226,7 +227,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameView private final boolean assignDamageAsIfNotBlocked(final Card attacker) { return attacker.hasKeyword("CARDNAME assigns its combat damage as though it weren't blocked.") || (attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.") - && SGuiDialog.confirm(attacker, "Do you want to assign its combat damage as though it weren't blocked?")); + && SGuiDialog.confirm(getCardView(attacker), "Do you want to assign its combat damage as though it weren't blocked?")); } /* (non-Javadoc) @@ -359,18 +360,18 @@ public class PlayerControllerHuman extends PlayerController implements IGameView */ @Override public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) { - return SGuiDialog.confirm(sa.getHostCard(), message); + return SGuiDialog.confirm(getCardView(sa.getHostCard()), message); } @Override public boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode bidlife, String string, int bid, Player winner) { - return SGuiDialog.confirm(sa.getHostCard(), string + " Highest Bidder " + winner); + return SGuiDialog.confirm(getCardView(sa.getHostCard()), string + " Highest Bidder " + winner); } @Override public boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message) { - return SGuiDialog.confirm(hostCard, message); + return SGuiDialog.confirm(getCardView(hostCard), message); } @Override @@ -500,10 +501,11 @@ public class PlayerControllerHuman extends PlayerController implements IGameView } @Override - public boolean willPutCardOnTop(Card c) { - PaperCard pc = FModel.getMagicDb().getCommonCards().getCard(c.getName()); - Card c1 = (pc != null ? Card.fromPaperCard(pc, null) : c); - return SGuiDialog.confirm(c1, "Put " + c1.getName() + " on the top or bottom of your library?", new String[]{"Top", "Bottom"}); + public boolean willPutCardOnTop(final Card c) { + final PaperCard pc = FModel.getMagicDb().getCommonCards().getCard(c.getName()); + final Card c1 = (pc != null ? Card.fromPaperCard(pc, null) : c); + final CardView view = getCardView(c1); + return SGuiDialog.confirm(view, "Put " + view + " on the top or bottom of your library?", new String[]{"Top", "Bottom"}); } @Override @@ -542,8 +544,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameView } @Override - public void playMiracle(SpellAbility miracle, Card card) { - if (SGuiDialog.confirm(card, card + " - Drawn. Play for Miracle Cost?")) { + public void playMiracle(final SpellAbility miracle, final Card card) { + final CardView view = getCardView(card); + if (SGuiDialog.confirm(view, view + " - Drawn. Play for Miracle Cost?")) { HumanPlay.playSpellAbility(player, miracle); } } @@ -659,7 +662,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameView */ @Override public boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question) { - return SGuiDialog.confirm(replacementEffect.getHostCard(), question); + return SGuiDialog.confirm(getCardView(replacementEffect.getHostCard()), question); } @Override @@ -870,7 +873,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameView default: labels = kindOfChoice.toString().split("Or"); } - return SGuiDialog.confirm(sa.getHostCard(), question, defaultVal == null || defaultVal.booleanValue(), labels); + return SGuiDialog.confirm(getCardView(sa.getHostCard()), question, defaultVal == null || defaultVal.booleanValue(), labels); } @Override @@ -1040,7 +1043,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameView if (colorNames.length > 2) { return MagicColor.fromName(SGuiChoose.one(message, colorNames)); } - int idxChosen = SGuiDialog.confirm(c, message, colorNames) ? 0 : 1; + int idxChosen = SGuiDialog.confirm(getCardView(c), message, colorNames) ? 0 : 1; return MagicColor.fromName(colorNames[idxChosen]); } @@ -1136,7 +1139,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameView final String p1Str = String.format("Pile 1 (%s cards)", pile1.size()); final String p2Str = String.format("Pile 2 (%s cards)", pile2.size()); final String[] possibleValues = { p1Str , p2Str }; - return SGuiDialog.confirm(sa.getHostCard(), "Choose a Pile", possibleValues); + return SGuiDialog.confirm(getCardView(sa.getHostCard()), "Choose a Pile", possibleValues); } else { final Card[] disp = new Card[pile1.size() + pile2.size() + 2]; disp[0] = new Card(-1); @@ -1230,6 +1233,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameView /** Cache of stack items. */ private final BiMap stackItems = HashBiMap.create(); + /** Combat view. */ + private final CombatView combatView = new CombatView(); /* (non-Javadoc) * @see forge.view.IGameView#isCommander() @@ -1324,15 +1329,23 @@ public class PlayerControllerHuman extends PlayerController implements IGameView game.subscribeToEvents(subscriber); } - // the following methods should eventually be replaced by methods returning - // View classes /* (non-Javadoc) * @see forge.view.IGameView#getCombat() */ @Override - public Combat getCombat() { - return game.getCombat(); + public CombatView getCombat() { + updateCombatView(game.getCombat()); + return combatView; } + + private final void updateCombatView(final Combat combat) { + for (final Card c : combat.getAttackers()) { + final GameEntity defender = combat.getDefenderByAttacker(c); + final List blockers = combat.getBlockers(c); + combatView.addAttacker(getCardView(c), getGameEntityView(defender), getCardViews(blockers)); + } + } + /* (non-Javadoc) * @see forge.view.IGameView#getGameLog() */ @@ -1474,14 +1487,15 @@ public class PlayerControllerHuman extends PlayerController implements IGameView return null; } + final Card cUi = c.getCardForUi(); final CardView view; - if (cards.containsKey(c)) { - view = cards.get(c); - writeCardToView(c, view); + if (cards.containsKey(cUi)) { + view = cards.get(cUi); + writeCardToView(cUi, view); } else { - view = new CardView(c, c.getUniqueNumber()); - writeCardToView(c, view); - cards.put(c, view); + view = new CardView(cUi, cUi.getUniqueNumber(), cUi == c); + writeCardToView(cUi, view); + cards.put(cUi, view); } return view; } @@ -1539,6 +1553,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameView view.setHauntedBy(getCardViews(c.getHauntedBy())); view.setHaunting(getCardView(c.getHaunting())); view.setMustBlock(c.getMustBlockCards() == null ? Collections.emptySet() : Iterables.transform(c.getMustBlockCards(), FN_GET_CARD_VIEW)); + view.setPairedWith(getCardView(c.getPairedWith())); } @Override diff --git a/forge-gui/src/main/java/forge/util/gui/SGuiDialog.java b/forge-gui/src/main/java/forge/util/gui/SGuiDialog.java index eb7975980b6..d18a1238605 100644 --- a/forge-gui/src/main/java/forge/util/gui/SGuiDialog.java +++ b/forge-gui/src/main/java/forge/util/gui/SGuiDialog.java @@ -1,9 +1,9 @@ package forge.util.gui; -import forge.game.card.Card; - import org.apache.commons.lang3.StringUtils; +import forge.view.CardView; + /** * Holds player interactions using standard windows * @@ -11,19 +11,18 @@ import org.apache.commons.lang3.StringUtils; public class SGuiDialog { private static final String[] defaultConfirmOptions = { "Yes", "No" }; - public static boolean confirm(final Card c, final String question) { + public static boolean confirm(final CardView c, final String question) { return SGuiDialog.confirm(c, question, true, null); } - public static boolean confirm(final Card c, final String question, final boolean defaultChoice) { + public static boolean confirm(final CardView c, final String question, final boolean defaultChoice) { return SGuiDialog.confirm(c, question, defaultChoice, null); } - public static boolean confirm(final Card c, final String question, String[] options) { + public static boolean confirm(final CardView c, final String question, String[] options) { return SGuiDialog.confirm(c, question, true, options); } - public static boolean confirm(Card c, final String question, final boolean defaultIsYes, final String[] options) { - c = Card.getCardForUi(c); - final String title = c == null ? "Question" : c.getName() + " - Ability"; + public static boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options) { + final String title = c == null ? "Question" : c + " - Ability"; String questionToUse = StringUtils.isBlank(question) ? "Activate card's ability?" : question; String[] opts = options == null ? defaultConfirmOptions : options; int answer = SOptionPane.showCardOptionDialog(c, questionToUse, title, SOptionPane.QUESTION_ICON, opts, defaultIsYes ? 0 : 1); diff --git a/forge-gui/src/main/java/forge/view/CardView.java b/forge-gui/src/main/java/forge/view/CardView.java new file mode 100644 index 00000000000..9770907190f --- /dev/null +++ b/forge-gui/src/main/java/forge/view/CardView.java @@ -0,0 +1,1027 @@ +package forge.view; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +import forge.card.CardRarity; +import forge.card.ColorSet; +import forge.card.mana.ManaCost; +import forge.game.card.Card; +import forge.game.card.CounterType; +import forge.game.zone.ZoneType; +import forge.item.IPaperCard; + +public class CardView extends GameEntityView { + + private final CardStateView + original = new CardStateView(), + alternate = new CardStateView(); + + private boolean hasAltState; + + private final int id; + /** Will be false for {@link forge.game.ability.effects.DetachedCardEffect}. */ + private final boolean isUiDisplayable; + private PlayerView owner, controller; + private ZoneType zone; + private int foilIndex; + private boolean isCloned, isFaceDown, isFlipCard, isFlipped, isSplitCard, isTransformed; + private String setCode; + private CardRarity rarity; + private long timestamp; + private boolean isAttacking, isBlocking, isPhasedOut, isSick, isTapped, isToken; + private Map counters; + private int damage, assignedDamage, regenerationShields, preventNextDamage; + private String chosenType; + private List chosenColors; + private PlayerView chosenPlayer; + private String namedCard; + private CardView equipping; + private Iterable equippedBy; + private CardView enchantingCard; + private PlayerView enchantingPlayer; + private Iterable enchantedBy; + private CardView fortifying; + private Iterable fortifiedBy; + private Iterable gainControlTargets; + private CardView cloneOrigin; + private Iterable imprinted, hauntedBy; + private CardView haunting; + private Iterable mustBlock; + private CardView pairedWith; + + @Deprecated + public final Card card; + + public CardView(@Deprecated final Card card, final int id, final boolean isUiDisplayable) { + this.card = card; + this.id = id; + this.isUiDisplayable = isUiDisplayable; + this.reset(); + } + + public void reset() { + final Iterable emptyIterable = ImmutableSet.of(); + this.hasAltState = false; + this.owner = null; + this.controller = null; + this.zone = null; + this.foilIndex = 0; + this.isCloned = false; + this.isFaceDown = false; + this.isFlipped = false; + this.isSplitCard = false; + this.isTransformed = false; + this.setCode = StringUtils.EMPTY; + this.rarity = CardRarity.Unknown; + this.timestamp = 0L; + this.isAttacking = this.isBlocking = this.isPhasedOut = this.isSick = this.isTapped = false; + this.counters = ImmutableMap.of(); + this.damage = this.assignedDamage = this.regenerationShields = this.preventNextDamage = 0; + this.chosenType = StringUtils.EMPTY; + this.chosenColors = ImmutableList.of(); + this.chosenPlayer = null; + this.namedCard = StringUtils.EMPTY; + this.equipping = null; + this.equippedBy = emptyIterable; + this.enchantingCard = null; + this.enchantingPlayer = null; + this.enchantedBy = emptyIterable; + this.fortifying = null; + this.fortifiedBy = emptyIterable; + this.gainControlTargets = emptyIterable; + this.cloneOrigin = null; + this.imprinted = emptyIterable; + this.hauntedBy = emptyIterable; + this.haunting = null; + this.mustBlock = emptyIterable; + } + + /** + * @return the id + */ + public int getId() { + return id; + } + + public boolean isUiDisplayable() { + return isUiDisplayable; + } + + /** + * @return the owner + */ + public PlayerView getOwner() { + return owner; + } + + /** + * @param owner the owner to set + */ + public void setOwner(PlayerView owner) { + this.owner = owner; + } + + /** + * @return the controller + */ + public PlayerView getController() { + return controller; + } + + /** + * @param controller the controller to set + */ + public void setController(final PlayerView controller) { + this.controller = controller; + } + + /** + * @return the zone + */ + public ZoneType getZone() { + return zone; + } + + /** + * @param zone the zone to set + */ + public void setZone(ZoneType zone) { + this.zone = zone; + } + + /** + * @return the hasAltState + */ + public boolean hasAltState() { + return hasAltState; + } + + /** + * @param hasAltState the hasAltState to set + */ + public void setHasAltState(final boolean hasAltState) { + this.hasAltState = hasAltState; + } + + public boolean isInAltState() { + return this.isFaceDown || this.isFlipped || this.isTransformed; + } + + /** + * @return the foilIndex + */ + public int getFoilIndex() { + return foilIndex; + } + + /** + * @param foilIndex the foilIndex to set + */ + public void setFoilIndex(final int foilIndex) { + this.foilIndex = foilIndex; + } + + /** + * @return the isCloned + */ + public boolean isCloned() { + return isCloned; + } + + /** + * @param isCloned the isCloned to set + */ + public void setCloned(boolean isCloned) { + this.isCloned = isCloned; + } + + /** + * @return the isFaceDown + */ + public boolean isFaceDown() { + return isFaceDown; + } + + /** + * @param isFaceDown the isFaceDown to set + */ + public void setFaceDown(final boolean isFaceDown) { + this.isFaceDown = isFaceDown; + } + + /** + * @return the isFlipCard + */ + public boolean isFlipCard() { + return isFlipCard; + } + + /** + * @param isFlipCard the isFlipCard to set + */ + public void setFlipCard(boolean isFlipCard) { + this.isFlipCard = isFlipCard; + } + + /** + * @return the isFlipped + */ + public boolean isFlipped() { + return isFlipped; + } + + /** + * @param isFlipped the isFlipped to set + */ + public void setFlipped(final boolean isFlipped) { + this.isFlipped = isFlipped; + } + + /** + * @return the isSplitCard + */ + public boolean isSplitCard() { + return isSplitCard; + } + + /** + * @param isSplitCard the isSplitCard to set + */ + public void setSplitCard(boolean isSplitCard) { + this.isSplitCard = isSplitCard; + } + + /** + * @return the isTransformed + */ + public boolean isTransformed() { + return isTransformed; + } + + /** + * @param isTransformed the isTransformed to set + */ + public void setTransformed(final boolean isTransformed) { + this.isTransformed = isTransformed; + } + + /** + * @return the setCode + */ + public String getSetCode() { + return setCode; + } + + /** + * @param setCode the setCode to set + */ + public void setSetCode(final String setCode) { + this.setCode = setCode; + } + + /** + * @return the rarity + */ + public CardRarity getRarity() { + return rarity; + } + + /** + * @param rarity the rarity to set + */ + public void setRarity(final CardRarity rarity) { + this.rarity = rarity; + } + + /** + * @return the timestamp + */ + public long getTimestamp() { + return timestamp; + } + + /** + * @param timestamp the timestamp to set + */ + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /** + * @return the isAttacking + */ + public boolean isAttacking() { + return isAttacking; + } + + /** + * @param isAttacking the isAttacking to set + */ + public void setAttacking(boolean isAttacking) { + this.isAttacking = isAttacking; + } + + /** + * @return the isBlocking + */ + public boolean isBlocking() { + return isBlocking; + } + + /** + * @param isBlocking the isBlocking to set + */ + public void setBlocking(boolean isBlocking) { + this.isBlocking = isBlocking; + } + + /** + * @return the isPhasedOut + */ + public boolean isPhasedOut() { + return isPhasedOut; + } + + /** + * @param isPhasedOut the isPhasedOut to set + */ + public void setPhasedOut(final boolean isPhasedOut) { + this.isPhasedOut = isPhasedOut; + } + + /** + * @return the isSick + */ + public boolean isSick() { + return isSick; + } + + /** + * @param isSick the isSick to set + */ + public void setSick(boolean isSick) { + this.isSick = isSick; + } + + /** + * @return the isTapped + */ + public boolean isTapped() { + return isTapped; + } + + /** + * @param isTapped the isTapped to set + */ + public void setTapped(boolean isTapped) { + this.isTapped = isTapped; + } + + /** + * @return the isToken + */ + public boolean isToken() { + return isToken; + } + + /** + * @return the counters + */ + public Map getCounters() { + return counters; + } + + /** + * @param counters the counters to set + */ + public void setCounters(final Map counters) { + this.counters = Collections.unmodifiableMap(counters); + } + + /** + * @return the damage + */ + public int getDamage() { + return damage; + } + + /** + * @param damage the damage to set + */ + public void setDamage(final int damage) { + this.damage = damage; + } + + /** + * @return the assignedDamage + */ + public int getAssignedDamage() { + return assignedDamage; + } + + /** + * @param assignedDamage the assignedDamage to set + */ + public void setAssignedDamage(final int assignedDamage) { + this.assignedDamage = assignedDamage; + } + + public int getLethalDamage() { + return this.getState().getToughness() - this.getDamage() - this.getAssignedDamage(); + } + + /** + * @return the regenerationShields + */ + public int getRegenerationShields() { + return regenerationShields; + } + + /** + * @param regenerationShields the regenerationShields to set + */ + public void setRegenerationShields(final int regenerationShields) { + this.regenerationShields = regenerationShields; + } + + /** + * @return the preventNextDamage + */ + public int getPreventNextDamage() { + return preventNextDamage; + } + + /** + * @param preventNextDamage the preventNextDamage to set + */ + public void setPreventNextDamage(final int preventNextDamage) { + this.preventNextDamage = preventNextDamage; + } + + /** + * @return the chosenType + */ + public String getChosenType() { + return chosenType; + } + + /** + * @param chosenType the chosenType to set + */ + public void setChosenType(final String chosenType) { + this.chosenType = chosenType; + } + + /** + * @return the chosenColors + */ + public List getChosenColors() { + return chosenColors; + } + + /** + * @param chosenColors the chosenColors to set + */ + public void setChosenColors(final List chosenColors) { + this.chosenColors = Collections.unmodifiableList(chosenColors); + } + + /** + * @return the chosenPlayer + */ + public PlayerView getChosenPlayer() { + return chosenPlayer; + } + + /** + * @param chosenPlayer the chosenPlayer to set + */ + public void setChosenPlayer(final PlayerView chosenPlayer) { + this.chosenPlayer = chosenPlayer; + } + + /** + * @param isToken the isToken to set + */ + public void setToken(final boolean isToken) { + this.isToken = isToken; + } + + /** + * @return the namedCard + */ + public String getNamedCard() { + return namedCard; + } + + /** + * @param namedCard the namedCard to set + */ + public void setNamedCard(final String namedCard) { + this.namedCard = namedCard; + } + + /** + * @return the equipping + */ + public CardView getEquipping() { + return equipping; + } + + /** + * @param equipping the equipping to set + */ + public void setEquipping(final CardView equipping) { + this.equipping = equipping; + } + + /** + * @return the equippedBy + */ + public Iterable getEquippedBy() { + return equippedBy; + } + + /** + * @param equippedBy the equippedBy to set + */ + public void setEquippedBy(final Iterable equippedBy) { + this.equippedBy = Iterables.unmodifiableIterable(equippedBy); + } + + public boolean isEquipped() { + return this.getEquippedBy().iterator().hasNext(); + } + + /** + * @return the enchantingCard + */ + public CardView getEnchantingCard() { + return enchantingCard; + } + + /** + * @param enchantingCard the enchantingCards to set + */ + public void setEnchantingCard(final CardView enchantingCard) { + this.enchantingCard = enchantingCard; + } + + /** + * @return the enchantingPlayer + */ + public PlayerView getEnchantingPlayer() { + return enchantingPlayer; + } + + /** + * @param enchantingPlayer the enchantingPlayer to set + */ + public void setEnchantingPlayer(final PlayerView enchantingPlayer) { + this.enchantingPlayer = enchantingPlayer; + } + + /** + * @return the enchantedBy + */ + public Iterable getEnchantedBy() { + return enchantedBy; + } + + /** + * @param enchantedBy the enchantedBy to set + */ + public void setEnchantedBy(final Iterable enchantedBy) { + this.enchantedBy = Iterables.unmodifiableIterable(enchantedBy); + } + + public boolean isEnchanted() { + return getEnchantedBy().iterator().hasNext(); + } + + /** + * @return the fortifying + */ + public CardView getFortifying() { + return fortifying; + } + + /** + * @param fortifying the fortifying to set + */ + public void setFortifying(CardView fortifying) { + this.fortifying = fortifying; + } + + /** + * @return the fortifiedBy + */ + public Iterable getFortifiedBy() { + return fortifiedBy; + } + + /** + * @param fortifiedBy the fortifiedBy to set + */ + public void setFortifiedBy(final Iterable fortifiedBy) { + this.fortifiedBy = Iterables.unmodifiableIterable(fortifiedBy); + } + + public boolean isFortified() { + return getFortifiedBy().iterator().hasNext(); + } + + /** + * @return the gainControlTargets + */ + public Iterable getGainControlTargets() { + return gainControlTargets; + } + + /** + * @param gainControlTargets the gainControlTargets to set + */ + public void setGainControlTargets(final Iterable gainControlTargets) { + this.gainControlTargets = Iterables.unmodifiableIterable(gainControlTargets); + } + + /** + * @return the cloneOrigin + */ + public CardView getCloneOrigin() { + return cloneOrigin; + } + + /** + * @param cloneOrigin the cloneOrigin to set + */ + public void setCloneOrigin(final CardView cloneOrigin) { + this.cloneOrigin = cloneOrigin; + } + + /** + * @return the imprinted + */ + public Iterable getImprinted() { + return imprinted; + } + + /** + * @param imprinted the imprinted to set + */ + public void setImprinted(final Iterable imprinted) { + this.imprinted = Iterables.unmodifiableIterable(imprinted); + } + + /** + * @return the hauntedBy + */ + public Iterable getHauntedBy() { + return hauntedBy; + } + + /** + * @param hauntedBy the hauntedBy to set + */ + public void setHauntedBy(final Iterable hauntedBy) { + this.hauntedBy = Iterables.unmodifiableIterable(hauntedBy); + } + + /** + * @return the haunting + */ + public CardView getHaunting() { + return haunting; + } + + /** + * @param haunting the haunting to set + */ + public void setHaunting(final CardView haunting) { + this.haunting = haunting; + } + + /** + * @return the mustBlock + */ + public Iterable getMustBlock() { + return mustBlock; + } + + /** + * @param mustBlock the mustBlock to set + */ + public void setMustBlock(final Iterable mustBlock) { + this.mustBlock = Iterables.unmodifiableIterable(mustBlock); + } + + public CardView getPairedWith() { + return pairedWith; + } + + public void setPairedWith(final CardView pairedWith) { + this.pairedWith = pairedWith; + } + + public CardStateView getOriginal() { + return this.original; + } + + public CardStateView getAlternate() { + return this.alternate; + } + + public CardStateView getState(final boolean alternate) { + return alternate ? this.alternate : this.original; + } + + public CardStateView getState() { + return this.getState(this.isInAltState()); + } + + @Override + public final String toString() { + return this.getState().getName() + " (" + this.getId() + ")"; + } + + public class CardStateView { + private String name; + private ColorSet colors; + private String imageKey; + private List type; + private ManaCost manaCost; + private int power, toughness, loyalty; + private String text; + private Map changedColorWords, + changedTypes; + private boolean hasDeathtouch, hasInfect, hasStorm, hasTrample; + + public CardStateView() { + this.reset(); + } + + public void reset() { + this.colors = ColorSet.getNullColor(); + this.imageKey = StringUtils.EMPTY; + this.type = Collections.emptyList(); + this.manaCost = null; + this.power = 0; + this.toughness = 0; + this.loyalty = 0; + this.text = StringUtils.EMPTY; + this.changedColorWords = ImmutableMap.of(); + this.changedTypes = ImmutableMap.of(); + this.hasDeathtouch = false; + this.hasInfect = false; + this.hasStorm = false; + this.hasTrample = false; + } + + public CardView getCard() { + return CardView.this; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the colors + */ + public ColorSet getColors() { + return colors; + } + + /** + * @param colors the colors to set + */ + public void setColors(final ColorSet colors) { + this.colors = colors; + } + + /** + * @return the imageKey + */ + public String getImageKey() { + return imageKey; + } + + /** + * @param imageKey the imageKey to set + */ + public void setImageKey(final String imageKey) { + this.imageKey = imageKey; + } + + /** + * @return the type + */ + public List getType() { + return type; + } + + /** + * @param type the type to set + */ + public void setType(final List type) { + this.type = Collections.unmodifiableList(type); + } + + /** + * @return the manaCost + */ + public ManaCost getManaCost() { + return manaCost; + } + + /** + * @param manaCost the manaCost to set + */ + public void setManaCost(final ManaCost manaCost) { + this.manaCost = manaCost; + } + + /** + * @return the power + */ + public int getPower() { + return power; + } + + /** + * @param power the power to set + */ + public void setPower(final int power) { + this.power = power; + } + + /** + * @return the toughness + */ + public int getToughness() { + return toughness; + } + + /** + * @param toughness the toughness to set + */ + public void setToughness(final int toughness) { + this.toughness = toughness; + } + + /** + * @return the loyalty + */ + public int getLoyalty() { + return loyalty; + } + + /** + * @param loyalty the loyalty to set + */ + public void setLoyalty(final int loyalty) { + this.loyalty = loyalty; + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @param text the text to set + */ + public void setText(final String text) { + this.text = text; + } + + /** + * @return the changedColorWords + */ + public Map getChangedColorWords() { + return changedColorWords; + } + + /** + * @param changedColorWords the changedColorWords to set + */ + public void setChangedColorWords(final Map changedColorWords) { + this.changedColorWords = Collections.unmodifiableMap(changedColorWords); + } + + /** + * @return the changedTypes + */ + public Map getChangedTypes() { + return changedTypes; + } + + /** + * @param changedTypes the changedTypes to set + */ + public void setChangedTypes(final Map changedTypes) { + this.changedTypes = Collections.unmodifiableMap(changedTypes); + } + + + /** + * @return the hasDeathtouch + */ + public boolean hasDeathtouch() { + return hasDeathtouch; + } + + /** + * @param hasDeathtouch the hasDeathtouch to set + */ + public void setHasDeathtouch(boolean hasDeathtouch) { + this.hasDeathtouch = hasDeathtouch; + } + + /** + * @return the hasInfect + */ + public boolean hasInfect() { + return hasInfect; + } + + /** + * @param hasInfect the hasInfect to set + */ + public void setHasInfect(boolean hasInfect) { + this.hasInfect = hasInfect; + } + + /** + * @return the hasStorm + */ + public boolean hasStorm() { + return hasStorm; + } + + /** + * @param hasStorm the hasStorm to set + */ + public void setHasStorm(boolean hasStorm) { + this.hasStorm = hasStorm; + } + + /** + * @return the hasTrample + */ + public boolean hasTrample() { + return hasTrample; + } + + /** + * @param hasTrample the hasTrample to set + */ + public void setHasTrample(boolean hasTrample) { + this.hasTrample = hasTrample; + } + + public boolean isCreature() { + return this.type.contains("Creature"); + } + public boolean isLand() { + return this.type.contains("Land"); + } + public boolean isPlane() { + return this.type.contains("Plane"); + } + public boolean isPhenomenon() { + return this.type.contains("Phenomenon"); + } + public boolean isPlaneswalker() { + return this.type.contains("Planeswalker"); + } + } + + public static CardView getCardForUi(final IPaperCard pc) { + final Card c = Card.getCardForUi(pc); + final CardView view = new CardView(c, -1, true); + ViewUtil.writeNonDependentCardViewProperties(c, view); + return view; + } +} diff --git a/forge-gui/src/main/java/forge/view/CombatView.java b/forge-gui/src/main/java/forge/view/CombatView.java new file mode 100644 index 00000000000..15c545bd9c9 --- /dev/null +++ b/forge-gui/src/main/java/forge/view/CombatView.java @@ -0,0 +1,37 @@ +package forge.view; + +import java.util.Map; + +import com.google.common.base.Predicates; +import com.google.common.collect.Maps; + +public class CombatView { + + private Map attackersWithDefenders; + private Map> attackersWithBlockers; + + public CombatView() { + } + + public Iterable getAttackers() { + return attackersWithDefenders.keySet(); + } + + public GameEntityView getDefender(final CardView attacker) { + return attackersWithDefenders.get(attacker); + } + + public Iterable getBlockers(final CardView attacker) { + return attackersWithBlockers.get(attacker); + } + + public Iterable getAttackersOf(final GameEntityView defender) { + return Maps.filterValues(attackersWithDefenders, Predicates.equalTo(defender)).keySet(); + } + + public void addAttacker(final CardView attacker, final GameEntityView defender, final Iterable blockers) { + this.attackersWithDefenders.put(attacker, defender); + this.attackersWithBlockers.put(attacker, blockers); + } + +} diff --git a/forge-gui/src/main/java/forge/view/GameEntityView.java b/forge-gui/src/main/java/forge/view/GameEntityView.java new file mode 100644 index 00000000000..48063ca270f --- /dev/null +++ b/forge-gui/src/main/java/forge/view/GameEntityView.java @@ -0,0 +1,5 @@ +package forge.view; + +public abstract class GameEntityView { + +} diff --git a/forge-gui/src/main/java/forge/view/IGameView.java b/forge-gui/src/main/java/forge/view/IGameView.java new file mode 100644 index 00000000000..f146a011048 --- /dev/null +++ b/forge-gui/src/main/java/forge/view/IGameView.java @@ -0,0 +1,61 @@ +package forge.view; + +import java.util.List; + +import forge.LobbyPlayer; +import forge.game.GameLog; +import forge.game.GameOutcome; +import forge.game.GameType; +import forge.game.phase.PhaseType; +import forge.game.player.Player; +import forge.game.player.RegisteredPlayer; + +public interface IGameView { + + public abstract boolean isCommander(); + + public abstract GameType getGameType(); + + public abstract boolean isWinner(LobbyPlayer p); + public abstract LobbyPlayer getWinningPlayer(); + public abstract int getWinningTeam(); + + public abstract boolean isFirstGameInMatch(); + public abstract boolean isMatchOver(); + public abstract int getNumPlayedGamesInMatch(); + public abstract boolean isMatchWonBy(LobbyPlayer p); + public abstract int getGamesWonBy(LobbyPlayer p); + public abstract GameOutcome.AnteResult getAnteResult(); + + public abstract boolean isCombatDeclareAttackers(); + + public abstract boolean isGameOver(); + + public abstract int getPoisonCountersToLose(); + + public abstract void subscribeToEvents(Object subscriber); + + public abstract CombatView getCombat(); + + // the following methods should eventually be replaced by methods returning + // View classes + @Deprecated + public abstract GameLog getGameLog(); + @Deprecated + public abstract RegisteredPlayer getGuiRegisteredPlayer(LobbyPlayer p); + + public abstract List getPlayers(); + + public abstract PlayerView getPlayerTurn(); + + public abstract PhaseType getPhase(); + + public abstract List getStack(); + public abstract StackItemView peekStack(); + + public abstract boolean mayShowCard(CardView c, Player viewer); + + public abstract boolean getDisableAutoYields(); + public abstract void setDisableAutoYields(boolean b); + +} \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/view/PlayerView.java b/forge-gui/src/main/java/forge/view/PlayerView.java new file mode 100644 index 00000000000..bd237ef2e74 --- /dev/null +++ b/forge-gui/src/main/java/forge/view/PlayerView.java @@ -0,0 +1,303 @@ +package forge.view; + +import java.util.List; +import java.util.Map; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; + +import forge.LobbyPlayer; +import forge.card.MagicColor; +import forge.game.player.PlayerController; + +public class PlayerView extends GameEntityView { + + private final LobbyPlayer lobbyPlayer; + private final PlayerController controller; + + private int life, poisonCounters, maxHandSize, numDrawnThisTurn, preventNextDamage; + private List keywords; + private String commanderInfo; + private List anteCards, bfCards, commandCards, exileCards, flashbackCards, graveCards, handCards, libraryCards; + private boolean hasUnlimitedHandSize; + private Map mana = Maps.newHashMapWithExpectedSize(MagicColor.NUMBER_OR_COLORS + 1); + + public PlayerView(final LobbyPlayer lobbyPlayer, final PlayerController controller) { + this.lobbyPlayer = lobbyPlayer; + this.controller = controller; + } + + /** + * @return the lobbyPlayer + */ + public LobbyPlayer getLobbyPlayer() { + return lobbyPlayer; + } + + /** + * @return the controller + */ + @Deprecated + public PlayerController getController() { + return controller; + } + + public String getName() { + return this.getLobbyPlayer().getName(); + } + + @Override + public String toString() { + return this.getName(); + } + + /** + * @return the life + */ + public int getLife() { + return life; + } + + /** + * @param life the life to set + */ + public void setLife(final int life) { + this.life = life; + } + + /** + * @return the poisonCounters + */ + public int getPoisonCounters() { + return poisonCounters; + } + + /** + * @param poisonCounters the poisonCounters to set + */ + public void setPoisonCounters(final int poisonCounters) { + this.poisonCounters = poisonCounters; + } + + /** + * @return the maxHandSize + */ + public int getMaxHandSize() { + return maxHandSize; + } + + /** + * @param maxHandSize the maxHandSize to set + */ + public void setMaxHandSize(final int maxHandSize) { + this.maxHandSize = maxHandSize; + } + + /** + * @return the numDrawnThisTurn + */ + public int getNumDrawnThisTurn() { + return numDrawnThisTurn; + } + + /** + * @param numDrawnThisTurn the numDrawnThisTurn to set + */ + public void setNumDrawnThisTurn(final int numDrawnThisTurn) { + this.numDrawnThisTurn = numDrawnThisTurn; + } + + /** + * @return the preventNextDamage + */ + public int getPreventNextDamage() { + return preventNextDamage; + } + + /** + * @param preventNextDamage the preventNextDamage to set + */ + public void setPreventNextDamage(final int preventNextDamage) { + this.preventNextDamage = preventNextDamage; + } + + /** + * @return the keywords + */ + public List getKeywords() { + return keywords; + } + + /** + * @param keywords the keywords to set + */ + public void setKeywords(final List keywords) { + this.keywords = ImmutableList.copyOf(keywords); + } + + /** + * @return the commanderInfo + */ + public String getCommanderInfo() { + return commanderInfo; + } + + /** + * @param commanderInfo the commanderInfo to set + */ + public void setCommanderInfo(final String commanderInfo) { + this.commanderInfo = commanderInfo; + } + + /** + * @return the anteCards + */ + public List getAnteCards() { + return anteCards; + } + + /** + * @param anteCards the anteCards to set + */ + public void setAnteCards(final List anteCards) { + this.anteCards = ImmutableList.copyOf(anteCards); + } + + /** + * @return the bfCards + */ + public List getBfCards() { + return bfCards; + } + + /** + * @param bfCards the bfCards to set + */ + public void setBfCards(final List bfCards) { + this.bfCards = ImmutableList.copyOf(bfCards); + } + + /** + * @return the commandCards + */ + public List getCommandCards() { + return commandCards; + } + + /** + * @param commandCards the commandCards to set + */ + public void setCommandCards(List commandCards) { + this.commandCards = commandCards; + } + + /** + * @return the exileCards + */ + public List getExileCards() { + return exileCards; + } + + /** + * @param exileCards the exileCards to set + */ + public void setExileCards(final List exileCards) { + this.exileCards = ImmutableList.copyOf(exileCards); + } + + /** + * @return the flashbackCards + */ + public List getFlashbackCards() { + return flashbackCards; + } + + /** + * @param flashbackCards the flashbackCards to set + */ + public void setFlashbackCards(final List flashbackCards) { + this.flashbackCards = ImmutableList.copyOf(flashbackCards); + } + + /** + * @return the graveCards + */ + public List getGraveCards() { + return graveCards; + } + + /** + * @param graveCards the graveCards to set + */ + public void setGraveCards(final List graveCards) { + this.graveCards = ImmutableList.copyOf(graveCards); + } + + /** + * @return the handCards + */ + public List getHandCards() { + return handCards; + } + + /** + * @param handCards the handCards to set + */ + public void setHandCards(final List handCards) { + this.handCards = ImmutableList.copyOf(handCards); + } + + /** + * @return the libraryCards + */ + public List getLibraryCards() { + return libraryCards; + } + + /** + * @param libraryCards the libraryCards to set + */ + public void setLibraryCards(final List libraryCards) { + this.libraryCards = ImmutableList.copyOf(libraryCards); + } + + /** + * @return the hasUnlimitedHandSize + */ + public boolean hasUnlimitedHandSize() { + return hasUnlimitedHandSize; + } + + /** + * @param hasUnlimitedHandSize the hasUnlimitedHandSize to set + */ + public void setHasUnlimitedHandSize(final boolean hasUnlimitedHandSize) { + this.hasUnlimitedHandSize = hasUnlimitedHandSize; + } + + public int getMana(final Byte color) { + return this.mana.get(color).intValue(); + } + + private void setMana(final byte color, final int mana) { + this.mana.put(Byte.valueOf(color), Integer.valueOf(mana)); + } + public void setWhiteMana(final int mana) { + this.setMana(MagicColor.WHITE, mana); + } + public void setBlueMana(final int mana) { + this.setMana(MagicColor.BLUE, mana); + } + public void setBlackMana(final int mana) { + this.setMana(MagicColor.BLACK, mana); + } + public void setRedMana(final int mana) { + this.setMana(MagicColor.RED, mana); + } + public void setGreenMana(final int mana) { + this.setMana(MagicColor.GREEN, mana); + } + public void setColorlessMana(final int mana) { + this.setMana(MagicColor.COLORLESS, mana); + } +} \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/view/SpellAbilityView.java b/forge-gui/src/main/java/forge/view/SpellAbilityView.java new file mode 100644 index 00000000000..ee3ad329ef0 --- /dev/null +++ b/forge-gui/src/main/java/forge/view/SpellAbilityView.java @@ -0,0 +1,21 @@ +package forge.view; + +public class SpellAbilityView { + + private CardView hostCard; + + /** + * @return the hostCard + */ + public CardView getHostCard() { + return hostCard; + } + + /** + * @param hostCard the hostCard to set + */ + public void setHostCard(CardView hostCard) { + this.hostCard = hostCard; + } + +} diff --git a/forge-gui/src/main/java/forge/view/StackItemView.java b/forge-gui/src/main/java/forge/view/StackItemView.java new file mode 100644 index 00000000000..214eacace0a --- /dev/null +++ b/forge-gui/src/main/java/forge/view/StackItemView.java @@ -0,0 +1,50 @@ +package forge.view; + +public class StackItemView { + + final String key; + final int sourceTrigger; + final String text; + final CardView source; + final PlayerView activatingPlayer; + final boolean ability, optionalTrigger; + + public StackItemView(final String key, final int sourceTrigger, final String text, final CardView source, final PlayerView activatingPlayer, final boolean isAbility, final boolean isOptionalTrigger) { + this.key = key; + this.sourceTrigger = sourceTrigger; + this.text = text; + this.source = source; + this.activatingPlayer = activatingPlayer; + this.ability = isAbility; + this.optionalTrigger = isOptionalTrigger; + } + + public String getKey() { + return key; + } + + public int getSourceTrigger() { + return sourceTrigger; + } + + public String getText() { + return text; + } + + public CardView getSource() { + return source; + } + + public PlayerView getActivatingPlayer() { + return activatingPlayer; + } + + public boolean isAbility() { + return ability; + } + + public boolean isOptionalTrigger() { + return optionalTrigger; + } + +} diff --git a/forge-gui/src/main/java/forge/view/ViewUtil.java b/forge-gui/src/main/java/forge/view/ViewUtil.java new file mode 100644 index 00000000000..ef4a6ce41d2 --- /dev/null +++ b/forge-gui/src/main/java/forge/view/ViewUtil.java @@ -0,0 +1,90 @@ +package forge.view; + +import java.util.Collections; + +import forge.card.CardCharacteristicName; +import forge.game.card.Card; +import forge.game.card.CardCharacteristics; +import forge.view.CardView.CardStateView; + +public final class ViewUtil { + + private ViewUtil() { + } + + /** + * Write those properties of a {@link Card} to a {@link CardView} that do + * not depend on other cards. + * + * @param c + * the {@link Card} to read from. + * @param view + * the {@link CardView} to write to. + */ + public static void writeNonDependentCardViewProperties(final Card c, final CardView view) { + final boolean hasAltState = c.isDoubleFaced() || c.isFlipCard() || c.isFaceDown(); + view.setZone(c.getZone().getZoneType()); + view.setHasAltState(hasAltState); + view.setFaceDown(c.isFaceDown()); + view.setFoilIndex(c.getFoil()); + view.setCloned(c.isCloned()); + view.setFlipCard(c.isFlipCard()); + view.setFlipped(c.getCurState().equals(CardCharacteristicName.Flipped)); + view.setSplitCard(c.isSplitCard()); + view.setTransformed(c.getCurState().equals(CardCharacteristicName.Transformed)); + view.setSetCode(c.getCurSetCode()); + view.setRarity(c.getRarity()); + view.setTimestamp(c.getTimestamp()); + view.setPhasedOut(c.isPhasedOut()); + view.setSick(c.isInPlay() && c.isSick()); + view.setTapped(c.isTapped()); + view.setToken(c.isToken()); + view.setCounters(c.getCounters()); + view.setDamage(c.getDamage()); + view.setAssignedDamage(c.getTotalAssignedDamage()); + view.setRegenerationShields(c.getShield().size()); + view.setPreventNextDamage(c.getPreventNextDamageTotalShields()); + view.setChosenType(c.getChosenType()); + view.setChosenColors(c.getChosenColor()); + view.setNamedCard(c.getNamedCard()); + + final CardStateView origView = view.getOriginal(); + origView.setName(c.getName()); + origView.setColors(c.determineColor()); + origView.setImageKey(c.getImageKey()); + origView.setType(Collections.unmodifiableList(c.getType())); + origView.setManaCost(c.getManaCost()); + origView.setPower(c.getNetAttack()); + origView.setToughness(c.getNetDefense()); + origView.setLoyalty(c.getCurrentLoyalty()); + origView.setText(c.getText()); + origView.setChangedColorWords(c.getChangedTextColorWords()); + origView.setChangedTypes(c.getChangedTextTypeWords()); + origView.setManaCost(c.getManaCost()); + + final CardStateView altView = view.getAlternate(); + CardCharacteristicName altState = null; + if (hasAltState) { + for (final CardCharacteristicName s : c.getStates()) { + if (!s.equals(CardCharacteristicName.Original) && !s.equals(CardCharacteristicName.FaceDown)) { + altState = s; + } + } + if (altState != null) { + final CardCharacteristics alt = c.getState(altState); + altView.setName(alt.getName()); + altView.setColors(alt.determineColor()); + altView.setImageKey(alt.getImageKey()); + altView.setType(Collections.unmodifiableList(alt.getType())); + altView.setManaCost(alt.getManaCost()); + altView.setPower(alt.getBaseAttack()); + altView.setPower(alt.getBaseDefense()); + altView.setLoyalty(0); // FIXME why is loyalty not a property of CardCharacteristic? + } + } + + if (altState == null) { + altView.reset(); + } + } +}