diff --git a/.gitattributes b/.gitattributes index bc28c633c74..65ac7e95861 100644 --- a/.gitattributes +++ b/.gitattributes @@ -509,6 +509,7 @@ forge-game/src/main/java/forge/game/event/GameEventPlayerDamaged.java -text forge-game/src/main/java/forge/game/event/GameEventPlayerLivesChanged.java -text forge-game/src/main/java/forge/game/event/GameEventPlayerPoisoned.java -text forge-game/src/main/java/forge/game/event/GameEventPlayerPriority.java -text +forge-game/src/main/java/forge/game/event/GameEventPlayerStatsChanged.java -text forge-game/src/main/java/forge/game/event/GameEventShuffle.java -text forge-game/src/main/java/forge/game/event/GameEventSpellAbilityCast.java -text forge-game/src/main/java/forge/game/event/GameEventSpellRemovedFromStack.java -text diff --git a/forge-game/src/main/java/forge/game/event/GameEventPlayerStatsChanged.java b/forge-game/src/main/java/forge/game/event/GameEventPlayerStatsChanged.java new file mode 100644 index 00000000000..99fc53f6849 --- /dev/null +++ b/forge-game/src/main/java/forge/game/event/GameEventPlayerStatsChanged.java @@ -0,0 +1,42 @@ +package forge.game.event; + +import java.util.Arrays; +import java.util.Collection; + +import com.google.common.collect.Iterables; + +import forge.game.player.Player; +import forge.util.Lang; + +/** + * This means card's characteristics have changed on server, clients must re-request them + */ +public class GameEventPlayerStatsChanged extends GameEvent { + + public final Collection players; + public GameEventPlayerStatsChanged(Player affected) { + players = Arrays.asList(affected); + } + + public GameEventPlayerStatsChanged(Collection affected) { + players = affected; + } + + /* (non-Javadoc) + * @see forge.game.event.GameEvent#visit(forge.game.event.IGameEventVisitor) + */ + @Override + public T visit(IGameEventVisitor visitor) { + // TODO Auto-generated method stub + return visitor.visit(this); + } + + @Override + public String toString() { + if (null == players || Iterables.isEmpty(players)) { + return "Player state changes: (empty list)"; + } + return String.format("Player state changes: %s", Lang.joinHomogenous(players)); + } + +} diff --git a/forge-game/src/main/java/forge/game/event/IGameEventVisitor.java b/forge-game/src/main/java/forge/game/event/IGameEventVisitor.java index d962525a199..c75bacfe425 100644 --- a/forge-game/src/main/java/forge/game/event/IGameEventVisitor.java +++ b/forge-game/src/main/java/forge/game/event/IGameEventVisitor.java @@ -33,6 +33,7 @@ public interface IGameEventVisitor { T visit(GameEventPlayerDamaged gameEventPlayerDamaged); T visit(GameEventPlayerPoisoned event); T visit(GameEventPlayerPriority event); + T visit(GameEventPlayerStatsChanged event); T visit(GameEventShuffle event); T visit(GameEventSpellAbilityCast gameEventSpellAbilityCast); T visit(GameEventSpellResolved event); @@ -72,6 +73,7 @@ public interface IGameEventVisitor { public T visit(GameEventPlayerControl event) { return null; } public T visit(GameEventPlayerPoisoned event) { return null; } public T visit(GameEventPlayerPriority event) { return null; } + public T visit(GameEventPlayerStatsChanged event) { return null; } public T visit(GameEventShuffle event) { return null; } public T visit(GameEventSpellResolved event) { return null; } public T visit(GameEventSpellAbilityCast event) { return null; } diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index ec6d2a47d48..15cbf7fe95c 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -1159,9 +1159,11 @@ public class Player extends GameEntity implements Comparable { } this.changedKeywords.put(timestamp, new KeywordsChange(addKeywords, removeKeywords, false)); + game.fireEvent(new GameEventPlayerStatsChanged(this)); } public final KeywordsChange removeChangedKeywords(final Long timestamp) { + game.fireEvent(new GameEventPlayerStatsChanged(this)); return changedKeywords.remove(Long.valueOf(timestamp)); } @@ -1205,6 +1207,8 @@ public class Player extends GameEntity implements Comparable { this.changedKeywords.remove(ck.getKey()); } } + + game.fireEvent(new GameEventPlayerStatsChanged(this)); } /* diff --git a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java index 6d9c265478e..4ea2a3b01d1 100644 --- a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java +++ b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java @@ -223,9 +223,6 @@ public class GuiDesktop implements IGuiBase { @Override public void updatePhase() { - //PhaseHandler pH = Singletons.getControl().getObservedGame().getPhaseHandler(); - //PhaseType ph = pH.getPhase(); - final PlayerView p = Singletons.getControl().getGameView().getPlayerTurn(); final PhaseType ph = Singletons.getControl().getGameView().getPhase(); final CMatchUI matchUi = CMatchUI.SINGLETON_INSTANCE; @@ -411,9 +408,9 @@ public class GuiDesktop implements IGuiBase { } @Override - public boolean openZones(final List zones, final Map players) { + public boolean openZones(final Collection zones, final Map players) { if (zones.size() == 1) { - switch (zones.get(0)) { + switch (zones.iterator().next()) { case Battlefield: case Hand: return true; //don't actually need to open anything, but indicate that zone can be opened diff --git a/forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java b/forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java index a7c1a72d081..5fde8edbaeb 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java +++ b/forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java @@ -130,7 +130,7 @@ public class CardDetailPanel extends SkinnedPanel { powerToughnessLabel.setVisible(false); idLabel.setText(""); cdArea.setText(CardDetailUtil.getItemDescription(item)); - this.updateBorder(item instanceof IPaperCard ? ViewUtil.getCardForUi((IPaperCard)item).getOriginal() : null, false); + this.updateBorder(item instanceof IPaperCard ? ViewUtil.getCardForUi((IPaperCard)item).getOriginal() : null); String set = item.getEdition(); setInfoLabel.setText(set); @@ -175,25 +175,21 @@ public class CardDetailPanel extends SkinnedPanel { this.setInfoLabel.setBorder(null); this.cdArea.setText(""); if (card == null) { - this.updateBorder((CardStateView)null, false); + this.updateBorder(null); return; } final CardStateView state = card.getState(isInAltState); - //this.setCard(card.card); - - boolean canShowThis = false; - - //if (Singletons.getControl().mayShowCard(card) || FDialog.isModalOpen()) { //allow showing cards while modal open to account for revealing, picking, and ordering cards - canShowThis = true; if (state.getManaCost().isNoCost()) { this.nameCostLabel.setText(state.getName()); } else { - String manaCost = state.getManaCost().toString(); - //if (state.isSplitCard() && card.getCurState() == CardCharacteristicName.Original) { - // manaCost = card.getRules().getMainPart().getManaCost().toString() + " // " + card.getRules().getOtherPart().getManaCost().toString(); - //} + final String manaCost; + if (card.isSplitCard() && card.hasAltState()) { + manaCost = card.getOriginal().getManaCost() + " // " + card.getAlternate().getManaCost(); + } else { + manaCost = state.getManaCost().toString(); + } this.nameCostLabel.setText(FSkin.encodeSymbols(state.getName() + " - " + manaCost, true)); } this.typeLabel.setText(CardDetailUtil.formatCardType(state)); @@ -240,14 +236,14 @@ public class CardDetailPanel extends SkinnedPanel { this.setInfoLabel.setBorder(BorderFactory.createLineBorder(foreColor)); } - this.updateBorder(state, canShowThis); + this.updateBorder(state); this.powerToughnessLabel.setText(CardDetailUtil.formatPowerToughness(state)); this.idLabel.setText(CardDetailUtil.formatCardId(state)); // fill the card text - this.cdArea.setText(FSkin.encodeSymbols(CardDetailUtil.composeCardText(state, canShowThis), true)); + this.cdArea.setText(FSkin.encodeSymbols(CardDetailUtil.composeCardText(state), true)); SwingUtilities.invokeLater(new Runnable() { @Override @@ -282,7 +278,7 @@ public class CardDetailPanel extends SkinnedPanel { return this.cdArea; } - private void updateBorder(final CardStateView card, final boolean canShow) { + private void updateBorder(final CardStateView card) { // color info if (card == null) { this.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); @@ -290,7 +286,7 @@ public class CardDetailPanel extends SkinnedPanel { return; } - Color color = fromDetailColor(CardDetailUtil.getBorderColor(card, canShow)); + Color color = fromDetailColor(CardDetailUtil.getBorderColor(card)); this.setBorder(BorderFactory.createLineBorder(color, 2)); scrArea.setBorder(BorderFactory.createMatteBorder(2, 0, 0, 0, color)); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index 10107ccff72..ef8c673c71a 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -26,9 +26,9 @@ import java.util.Set; import javax.swing.JMenu; import org.apache.commons.lang3.tuple.Pair; -import org.testng.collections.Maps; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; 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 d8de480c58c..842b205a6a9 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 @@ -34,8 +34,7 @@ import javax.swing.border.Border; import net.miginfocom.swing.MigLayout; -import org.testng.collections.Lists; - +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import forge.control.FControl; diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/ZoneAction.java b/forge-gui-desktop/src/main/java/forge/screens/match/ZoneAction.java index f76e22f4e13..1db3be5629c 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/ZoneAction.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/ZoneAction.java @@ -3,14 +3,15 @@ package forge.screens.match; import java.awt.event.ActionEvent; import java.util.List; -import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import forge.game.zone.ZoneType; import forge.gui.ForgeAction; import forge.gui.GuiChoose; import forge.match.MatchConstants; import forge.view.CardView; import forge.view.CardView.CardStateView; +import forge.view.PlayerView; /** * Receives click and programmatic requests for viewing data stacks in the @@ -19,7 +20,8 @@ import forge.view.CardView.CardStateView; */ public class ZoneAction extends ForgeAction { private static final long serialVersionUID = -5822976087772388839L; - private final Iterable cards; + private final PlayerView player; + private final ZoneType zone; private final String title; /** @@ -32,10 +34,11 @@ public class ZoneAction extends ForgeAction { * @param property *   String obj */ - public ZoneAction(final Iterable cards, final MatchConstants property) { + public ZoneAction(final PlayerView player, final ZoneType zone, final MatchConstants property) { super(property); this.title = property.title; - this.cards = Iterables.unmodifiableIterable(cards); + this.player = player; + this.zone = zone; } /** @@ -63,7 +66,7 @@ public class ZoneAction extends ForgeAction { } protected Iterable getCardsAsIterable() { - return cards; + return player.getCards(zone); } protected void doAction(final CardView c) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java index a8240ad0a72..58237fda9cd 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java @@ -98,8 +98,8 @@ public enum CCombat implements ICDoc { } final Iterable blockers = localCombat.getBlockers(band); - boolean blocked = (blockers == null); - boolean isBand = bandSize > 1; + final boolean blocked = (blockers != null); + final boolean isBand = bandSize > 1; if (isBand) { // Only print Band data if it's actually a band display.append(" > BAND"); diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java index 7cc85c6bf47..536f2bfdd3f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java @@ -26,10 +26,9 @@ import com.google.common.base.Function; import forge.LobbyPlayer; import forge.Singletons; import forge.UiCommand; +import forge.game.zone.ZoneType; import forge.gui.framework.ICDoc; import forge.match.MatchConstants; -import forge.match.input.Input; -import forge.match.input.InputPayMana; import forge.screens.match.ZoneAction; import forge.screens.match.views.VField; import forge.toolbox.MouseTriggerEvent; @@ -57,21 +56,21 @@ public class CField implements ICDoc { /** * Controls Swing components of a player's field instance. * - * @param player2   {@link forge.game.player.Player} + * @param player0   {@link forge.game.player.Player} * @param v0   {@link forge.screens.match.views.VField} * @param playerViewer */ - public CField(final PlayerView player2, final VField v0, LobbyPlayer playerViewer) { - this.player = player2; + public CField(final PlayerView player0, final VField v0, LobbyPlayer playerViewer) { + this.player = player0; this.viewer = playerViewer; this.view = v0; - final ZoneAction handAction = new ZoneAction(player.getHandCards(), MatchConstants.HUMANHAND); - final ZoneAction libraryAction = new ZoneAction(player.getLibraryCards(), MatchConstants.HUMANLIBRARY); - final ZoneAction exileAction = new ZoneAction(player.getExileCards(), MatchConstants.HUMANEXILED); - final ZoneAction graveAction = new ZoneAction(player.getGraveCards(), MatchConstants.HUMANGRAVEYARD); + final ZoneAction handAction = new ZoneAction(player, ZoneType.Hand, MatchConstants.HUMANHAND); + final ZoneAction libraryAction = new ZoneAction(player, ZoneType.Library, MatchConstants.HUMANLIBRARY); + final ZoneAction exileAction = new ZoneAction(player, ZoneType.Exile, MatchConstants.HUMANEXILED); + final ZoneAction graveAction = new ZoneAction(player, ZoneType.Graveyard, MatchConstants.HUMANGRAVEYARD); @SuppressWarnings("serial") - final ZoneAction flashBackAction = new ZoneAction(player.getFlashbackCards(), MatchConstants.HUMANFLASHBACK) { + final ZoneAction flashBackAction = new ZoneAction(player, null, MatchConstants.HUMANFLASHBACK) { @Override protected void doAction(final CardView c) { // activate cards only via your own flashback button @@ -81,16 +80,16 @@ public class CField implements ICDoc { CPrompt.SINGLETON_INSTANCE.selectCard(c, null); } + @Override + protected Iterable getCardsAsIterable() { + return player.getFlashbackCards(); + } }; Function manaAction = new Function() { public Void apply(Byte colorCode) { if (CField.this.player.getLobbyPlayer() == CField.this.viewer) { - final Input in = Singletons.getControl().getInputQueue().getInput(); - if (in instanceof InputPayMana) { - // Do something - ((InputPayMana) in).useManaFromPool(colorCode); - } + Singletons.getControl().getGameView().useMana(colorCode.byteValue()); } return null; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java index 513db434d98..143dd339e41 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java @@ -35,14 +35,12 @@ import javax.swing.border.EmptyBorder; import net.miginfocom.swing.MigLayout; import forge.ImageCache; -import forge.Singletons; import forge.card.CardDetailUtil; import forge.card.CardDetailUtil.DetailColors; import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; -import forge.match.input.InputConfirm; import forge.screens.match.CMatchUI; import forge.screens.match.controllers.CPrompt; import forge.screens.match.controllers.CStack; @@ -219,7 +217,7 @@ public enum VStack implements IVDoc { }); } - DetailColors color = CardDetailUtil.getBorderColor(item.getSource().getOriginal(), !txt.startsWith("Morph ")); + final DetailColors color = CardDetailUtil.getBorderColor(item.getSource().getOriginal()); setBackground(new Color(color.r, color.g, color.b)); setForeground(FSkin.getHighContrastColor(getBackground())); } @@ -275,10 +273,9 @@ public enum VStack implements IVDoc { } else { game.setShouldAlwaysAcceptTrigger(triggerID); - if (game.peekStack() == item && - Singletons.getControl().getInputQueue().getInput() instanceof InputConfirm) { + if (game.peekStack() == item) { //auto-yes if ability is on top of stack - CPrompt.SINGLETON_INSTANCE.selectButtonOk(); + game.confirm(); } } } @@ -294,10 +291,9 @@ public enum VStack implements IVDoc { } else { game.setShouldAlwaysDeclineTrigger(triggerID); - if (game.peekStack() == item && - Singletons.getControl().getInputQueue().getInput() instanceof InputConfirm) { + if (game.peekStack() == item) { //auto-no if ability is on top of stack - CPrompt.SINGLETON_INSTANCE.selectButtonOk(); + game.confirm(); } } } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java b/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java index 6762106ab7e..bcbf8eea929 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java @@ -214,7 +214,7 @@ public class PlayerDetailsPanel extends JPanel { lblHand.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { handAction.actionPerformed(null); } } ); lblFlashback.setHoverable(true); - lblFlashback.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) {flashBackAction.actionPerformed(null); } } ); + lblFlashback.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { flashBackAction.actionPerformed(null); } } ); for(final Pair labelPair : getManaLabels()) { labelPair.getLeft().setHoverable(true); 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 0d456217321..529ed83d75f 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 @@ -615,7 +615,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen final CardView c2 = toDelete.get(i); if (c.getId() == c2.getId()) { if (c.getTimestamp() == c2.getTimestamp()) { - toDelete.remove(i); + toDelete.remove(c2); } else { toReplace.add(c); } diff --git a/forge-gui/src/main/java/forge/card/CardDetailUtil.java b/forge-gui/src/main/java/forge/card/CardDetailUtil.java index fce9f12d42d..928ef6b1d3c 100644 --- a/forge-gui/src/main/java/forge/card/CardDetailUtil.java +++ b/forge-gui/src/main/java/forge/card/CardDetailUtil.java @@ -47,16 +47,25 @@ public class CardDetailUtil { } } - public static DetailColors getBorderColor(final CardStateView card, final boolean canShow) { - return getBorderColors(card.getColors(), card.isLand(), canShow, false).iterator().next(); + public static DetailColors getBorderColor(final CardStateView card) { + if (card == null) { + return getBorderColors(null, false, false, false).iterator().next(); + } + return getBorderColors(card.getColors(), card.isLand(), card.getCard().isUiDisplayable(), false).iterator().next(); } public static DetailColors getBorderColor(final ColorSet cardColors, final boolean isLand, boolean canShow) { return getBorderColors(cardColors, isLand, canShow, false).get(0); } - public static List getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) { + public static List getBorderColors(final CardStateView card) { + if (card == null) { + return getBorderColors(null, false, false, true); + } + return getBorderColors(card.getColors(), card.isLand(), card.getCard().isUiDisplayable(), true); + } + private static List getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) { List borderColors = new ArrayList(); - if (!canShow) { + if (cardColors == null || !canShow) { borderColors.add(DetailColors.FACE_DOWN); } else if (cardColors.isColorless()) { @@ -218,7 +227,7 @@ public class CardDetailUtil { return id > 0 ? "[" + id + "]" : ""; } - public static String composeCardText(final CardStateView state, final boolean canShow) { + public static String composeCardText(final CardStateView state) { final CardView card = state.getCard(); final StringBuilder area = new StringBuilder(); @@ -227,27 +236,25 @@ public class CardDetailUtil { area.append("Token"); } - if (canShow) { - // card text - if (area.length() != 0) { - area.append("\n"); - } - String text = state.getText(); - // LEVEL [0-9]+-[0-9]+ - // LEVEL [0-9]+\+ - - String regex = "LEVEL [0-9]+-[0-9]+ "; - text = text.replaceAll(regex, "$0\r\n"); - - regex = "LEVEL [0-9]+\\+ "; - text = text.replaceAll(regex, "\r\n$0\r\n"); - - // displays keywords that have dots in them a little better: - regex = "\\., "; - text = text.replaceAll(regex, ".\r\n"); - - area.append(text); + // card text + if (area.length() != 0) { + area.append("\n"); } + String text = state.getText(); + // LEVEL [0-9]+-[0-9]+ + // LEVEL [0-9]+\+ + + String regex = "LEVEL [0-9]+-[0-9]+ "; + text = text.replaceAll(regex, "$0\r\n"); + + regex = "LEVEL [0-9]+\\+ "; + text = text.replaceAll(regex, "\r\n$0\r\n"); + + // displays keywords that have dots in them a little better: + regex = "\\., "; + text = text.replaceAll(regex, ".\r\n"); + + area.append(text); if (card.isPhasedOut()) { if (area.length() != 0) { diff --git a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java index ad8935417a3..97ce8606734 100644 --- a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java +++ b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java @@ -35,6 +35,8 @@ import forge.game.event.GameEventPlayerControl; import forge.game.event.GameEventPlayerLivesChanged; import forge.game.event.GameEventPlayerPoisoned; import forge.game.event.GameEventPlayerPriority; +import forge.game.event.GameEventPlayerStatsChanged; +import forge.game.event.GameEventShuffle; import forge.game.event.GameEventSpellAbilityCast; import forge.game.event.GameEventSpellRemovedFromStack; import forge.game.event.GameEventSpellResolved; @@ -125,9 +127,9 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { @Override public Void visit(GameEventAnteCardsSelected ev) { - List options = new ArrayList(); - for (final Entry kv : ((GameEventAnteCardsSelected) ev).cards.entries()) { - Card fakeCard = new Card(-1); //use fake card so real cards appear with proper formatting + final List options = new ArrayList(); + for (final Entry kv : ev.cards.entries()) { + final Card fakeCard = new Card(-1); //use fake card so real cards appear with proper formatting fakeCard.setName(" -- From " + Lang.getPossesive(kv.getKey().getName()) + " deck --"); options.add(fakeCard); options.add(kv.getValue()); @@ -359,6 +361,20 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { return updateManyCards(cardViews); } + @Override + public Void visit(GameEventPlayerStatsChanged event) { + for (final Player p : event.players) { + gui.refreshCardDetails(controller.getCardViews(p.getAllCards())); + } + return null; + } + + @Override + public Void visit(GameEventShuffle event) { + updateZone(event.player.getZone(ZoneType.Library)); + return null; + } + // Update manapool private final List manaPoolUpdate = new Vector(); private final Runnable updManaPool = new Runnable() { diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java index f118e318d2a..42cbd47cfa3 100644 --- a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java +++ b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java @@ -73,7 +73,7 @@ public interface IGuiBase { void finishGame(); Object showManaPool(PlayerView player); void hideManaPool(PlayerView player, Object zoneToRestore); - boolean openZones(List zones, Map players); + boolean openZones(Collection zones, Map players); void restoreOldZones(Map playersToRestoreZonesFor); void updateStack(); void updateZones(List> zonesToUpdate); diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 2d95b1cb033..e1ca44edea7 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -96,6 +96,10 @@ public abstract class PlayerControllerHuman extends PlayerController { return Lists.transform(players, FN_GET_PLAYER_VIEW); } + public final Iterable getPlayerViews(final Iterable players) { + return Iterables.transform(players, FN_GET_PLAYER_VIEW); + } + public abstract Player getPlayer(PlayerView p); public abstract SpellAbilityView getSpellAbilityView(SpellAbility sa); diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerLocal.java b/forge-gui/src/main/java/forge/player/PlayerControllerLocal.java index a58b6abb4ea..44e9cbbdc68 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerLocal.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerLocal.java @@ -77,6 +77,7 @@ import forge.match.input.InputBlock; import forge.match.input.InputConfirm; import forge.match.input.InputConfirmMulligan; import forge.match.input.InputPassPriority; +import forge.match.input.InputPayMana; import forge.match.input.InputProliferate; import forge.match.input.InputSelectCardsForConvoke; import forge.match.input.InputSelectCardsFromList; @@ -1416,6 +1417,13 @@ public class PlayerControllerLocal extends PlayerControllerHuman implements IGam getInputProxy().selectButtonCancel(); } + @Override + public void confirm() { + if (getGui().getInputQueue().getInput() instanceof InputConfirm) { + selectButtonOk(); + } + } + @Override public boolean passPriority() { return getInputProxy().passPriority(); @@ -1426,14 +1434,22 @@ public class PlayerControllerLocal extends PlayerControllerHuman implements IGam return getInputProxy().passPriorityUntilEndOfTurn(); } + @Override + public void useMana(final byte mana) { + final Input input = getGui().getInputQueue().getInput(); + if (input instanceof InputPayMana) { + ((InputPayMana) input).useManaFromPool(mana); + } + } + @Override public void selectPlayer(final PlayerView player, final ITriggerEvent triggerEvent) { getInputProxy().selectPlayer(player, triggerEvent); } @Override - public void selectCard(final CardView card, final ITriggerEvent triggerEvent) { - getInputProxy().selectCard(card, triggerEvent); + public boolean selectCard(final CardView card, final ITriggerEvent triggerEvent) { + return getInputProxy().selectCard(card, triggerEvent); } @Override @@ -1517,8 +1533,8 @@ public class PlayerControllerLocal extends PlayerControllerHuman implements IGam si.getSpellAbility().toUnsuppressedString(), si.getSpellAbility().getSourceTrigger(), si.getStackDescription(), getCardView(si.getSourceCard()), - getPlayerView(si.getActivator()), si.isAbility(), - si.isOptionalTrigger()); + getPlayerView(si.getActivator()), getCardViews(si.getTargetChoices().getTargetCards()), + getPlayerViews(si.getTargetChoices().getTargetPlayers()), si.isAbility(), si.isOptionalTrigger()); stackItems.put(si, newItem); return newItem; } @@ -1542,6 +1558,7 @@ public class PlayerControllerLocal extends PlayerControllerHuman implements IGam view = new PlayerView(p.getLobbyPlayer(), p.getController()); players.put(p, view); getPlayerView(p, view); + view.setOpponents(getPlayerViews(p.getOpponents())); } return view; } @@ -1601,6 +1618,10 @@ public class PlayerControllerLocal extends PlayerControllerHuman implements IGam } private CardView getCardViewFast(final Card c) { + if (c == null) { + return null; + } + final CardView view = cards.get(c); if (!mayShowCard(view)) { view.reset(); @@ -1651,7 +1672,6 @@ public class PlayerControllerLocal extends PlayerControllerHuman implements IGam public boolean mayShowCard(final CardView c) { final Card card = getCard(c); return card == null || card.canBeShownTo(player); - } @Override diff --git a/forge-gui/src/main/java/forge/quest/QuestWinLoseController.java b/forge-gui/src/main/java/forge/quest/QuestWinLoseController.java index ca03f237931..a8c0e89d73b 100644 --- a/forge-gui/src/main/java/forge/quest/QuestWinLoseController.java +++ b/forge-gui/src/main/java/forge/quest/QuestWinLoseController.java @@ -40,7 +40,7 @@ import forge.view.PlayerView; public abstract class QuestWinLoseController { private final IGameView lastGame; - private final IGuiBase gui; + protected final IGuiBase gui; private final transient boolean wonMatch; private final transient boolean isAnte; private final transient QuestController qData; diff --git a/forge-gui/src/main/java/forge/view/CardView.java b/forge-gui/src/main/java/forge/view/CardView.java index d33fbdff81b..e1c7fea4a9e 100644 --- a/forge-gui/src/main/java/forge/view/CardView.java +++ b/forge-gui/src/main/java/forge/view/CardView.java @@ -6,6 +6,7 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; +import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -14,6 +15,7 @@ import com.google.common.collect.Iterables; import forge.ImageKeys; import forge.card.CardEdition; import forge.card.CardRarity; +import forge.card.CardType; import forge.card.ColorSet; import forge.card.mana.ManaCost; import forge.game.card.CounterType; @@ -1009,6 +1011,9 @@ public class CardView extends GameEntityView { this.hasTrample = hasTrample; } + public boolean isBasicLand() { + return this.isLand() && Iterables.any(type, Predicates.in(CardType.getBasicTypes())); + } public boolean isCreature() { return this.type.contains("Creature"); } diff --git a/forge-gui/src/main/java/forge/view/CombatView.java b/forge-gui/src/main/java/forge/view/CombatView.java index 717d25eeeb9..ec48508206e 100644 --- a/forge-gui/src/main/java/forge/view/CombatView.java +++ b/forge-gui/src/main/java/forge/view/CombatView.java @@ -3,6 +3,7 @@ package forge.view; import java.util.Map; import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -20,6 +21,10 @@ public class CombatView { return attackersWithDefenders.size(); } + public boolean isAttacking(final CardView card) { + return attackersWithDefenders.containsKey(card); + } + public Iterable getAttackers() { return attackersWithDefenders.keySet(); } @@ -32,6 +37,14 @@ public class CombatView { return attackersWithDefenders.get(attacker); } + public boolean isBlocking(final CardView card) { + for (final Iterable blockers : attackersWithBlockers.values()) { + if (Iterables.contains(blockers, card)) { + return true; + } + } + return false; + } public Iterable getBlockers(final CardView attacker) { return attackersWithBlockers.get(attacker); } diff --git a/forge-gui/src/main/java/forge/view/IGameView.java b/forge-gui/src/main/java/forge/view/IGameView.java index e06873f6cfd..30841292f5d 100644 --- a/forge-gui/src/main/java/forge/view/IGameView.java +++ b/forge-gui/src/main/java/forge/view/IGameView.java @@ -54,10 +54,12 @@ public interface IGameView { public abstract void selectButtonOk(); public abstract void selectButtonCancel(); + public abstract void confirm(); public abstract boolean passPriority(); public abstract boolean passPriorityUntilEndOfTurn(); + public abstract void useMana(byte mana); public abstract void selectPlayer(PlayerView player, ITriggerEvent triggerEvent); - public abstract void selectCard(CardView card, ITriggerEvent triggerEvent); + public abstract boolean selectCard(CardView card, ITriggerEvent triggerEvent); public abstract void selectAbility(SpellAbilityView sa); // the following method should eventually be replaced by methods returning diff --git a/forge-gui/src/main/java/forge/view/PlayerView.java b/forge-gui/src/main/java/forge/view/PlayerView.java index 553fa797e6d..03f7d6ed2f2 100644 --- a/forge-gui/src/main/java/forge/view/PlayerView.java +++ b/forge-gui/src/main/java/forge/view/PlayerView.java @@ -2,20 +2,24 @@ package forge.view; import java.util.List; import java.util.Map; +import java.util.Set; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import forge.LobbyPlayer; import forge.card.MagicColor; import forge.game.player.PlayerController; +import forge.game.zone.ZoneType; public class PlayerView extends GameEntityView { private final LobbyPlayer lobbyPlayer; private final PlayerController controller; + private Set opponents; private int life, poisonCounters, maxHandSize, numDrawnThisTurn, preventNextDamage; private List keywords; private String commanderInfo; @@ -42,6 +46,14 @@ public class PlayerView extends GameEntityView { return lobbyPlayer; } + public void setOpponents(final Iterable opponents) { + this.opponents = Sets.newHashSet(opponents); + } + + public boolean isOpponentOf(final PlayerView other) { + return opponents.contains(other); + } + /** * @return the controller */ @@ -168,8 +180,7 @@ public class PlayerView extends GameEntityView { * @param anteCards the anteCards to set */ public void setAnteCards(final List anteCards) { - this.anteCards.clear(); - this.anteCards.addAll(anteCards); + this.anteCards = ImmutableList.copyOf(anteCards); } /** @@ -183,8 +194,7 @@ public class PlayerView extends GameEntityView { * @param bfCards the bfCards to set */ public void setBfCards(final List bfCards) { - this.bfCards.clear(); - this.bfCards.addAll(bfCards); + this.bfCards = ImmutableList.copyOf(bfCards); } /** @@ -198,8 +208,7 @@ public class PlayerView extends GameEntityView { * @param commandCards the commandCards to set */ public void setCommandCards(List commandCards) { - this.commandCards.clear(); - this.commandCards.addAll(commandCards); + this.commandCards = ImmutableList.copyOf(commandCards); } /** @@ -213,8 +222,7 @@ public class PlayerView extends GameEntityView { * @param exileCards the exileCards to set */ public void setExileCards(final List exileCards) { - this.exileCards.clear(); - this.exileCards.addAll(exileCards); + this.exileCards = ImmutableList.copyOf(exileCards); } /** @@ -228,8 +236,7 @@ public class PlayerView extends GameEntityView { * @param flashbackCards the flashbackCards to set */ public void setFlashbackCards(final List flashbackCards) { - this.flashbackCards.clear(); - this.flashbackCards.addAll(flashbackCards); + this.flashbackCards = ImmutableList.copyOf(flashbackCards); } /** @@ -243,8 +250,7 @@ public class PlayerView extends GameEntityView { * @param graveCards the graveCards to set */ public void setGraveCards(final List graveCards) { - this.graveCards.clear(); - this.graveCards.addAll(graveCards); + this.graveCards = ImmutableList.copyOf(graveCards); } /** @@ -258,8 +264,7 @@ public class PlayerView extends GameEntityView { * @param handCards the handCards to set */ public void setHandCards(final List handCards) { - this.handCards.clear(); - this.handCards.addAll(handCards); + this.handCards = ImmutableList.copyOf(handCards); } /** @@ -273,8 +278,28 @@ public class PlayerView extends GameEntityView { * @param libraryCards the libraryCards to set */ public void setLibraryCards(final List libraryCards) { - this.libraryCards.clear(); - this.libraryCards.addAll(libraryCards); + this.libraryCards = ImmutableList.copyOf(libraryCards); + } + + public List getCards(final ZoneType zone) { + switch (zone) { + case Ante: + return getAnteCards(); + case Battlefield: + return getBfCards(); + case Command: + return getCommandCards(); + case Exile: + return getExileCards(); + case Graveyard: + return getGraveCards(); + case Hand: + return getHandCards(); + case Library: + return getLibraryCards(); + default: + return ImmutableList.of(); + } } /** @@ -298,22 +323,5 @@ public class PlayerView extends GameEntityView { public 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/StackItemView.java b/forge-gui/src/main/java/forge/view/StackItemView.java index 1142fe5cfda..32047188c3e 100644 --- a/forge-gui/src/main/java/forge/view/StackItemView.java +++ b/forge-gui/src/main/java/forge/view/StackItemView.java @@ -2,19 +2,28 @@ 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; + private final String key; + private final int sourceTrigger; + private final String text; + private final CardView source; + private final PlayerView activatingPlayer; + private final Iterable targetCards; + private final Iterable targetPlayers; + private 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) { + public StackItemView(final String key, final int sourceTrigger, + final String text, final CardView source, + final PlayerView activatingPlayer, + final Iterable targetCards, + final Iterable targetPlayers, final boolean isAbility, + final boolean isOptionalTrigger) { this.key = key; this.sourceTrigger = sourceTrigger; this.text = text; this.source = source; this.activatingPlayer = activatingPlayer; + this.targetCards = targetCards; + this.targetPlayers = targetPlayers; this.ability = isAbility; this.optionalTrigger = isOptionalTrigger; } @@ -39,6 +48,14 @@ public class StackItemView { return activatingPlayer; } + public Iterable getTargetCards() { + return targetCards; + } + + public Iterable getTargetPlayers() { + return targetPlayers; + } + public boolean isAbility() { return ability; }