diff --git a/Mage.Client/src/main/java/mage/TrayIconDemo.java b/Mage.Client/src/main/java/mage/TrayIconDemo.java new file mode 100644 index 00000000000..e2c259172f4 --- /dev/null +++ b/Mage.Client/src/main/java/mage/TrayIconDemo.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle or the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package mage; +/* + * TrayIconDemo.java + */ + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.net.URL; + +public class TrayIconDemo { + public static void main(String[] args) { + /* Use an appropriate Look and Feel */ + try { + //UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + //UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); + } catch (UnsupportedLookAndFeelException ex) { + ex.printStackTrace(); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } catch (InstantiationException ex) { + ex.printStackTrace(); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + } + /* Turn off metal's use of bold fonts */ + UIManager.put("swing.boldMetal", Boolean.FALSE); + //Schedule a job for the event-dispatching thread: + //adding TrayIcon. + SwingUtilities.invokeLater(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + } + + private static void createAndShowGUI() { + //Check the SystemTray support + if (!SystemTray.isSupported()) { + System.out.println("SystemTray is not supported"); + return; + } + final PopupMenu popup = new PopupMenu(); + final TrayIcon trayIcon = + new TrayIcon(createImage("images/bulb.gif", "tray icon")); + final SystemTray tray = SystemTray.getSystemTray(); + + // Create a popup menu components + MenuItem aboutItem = new MenuItem("About"); + CheckboxMenuItem cb1 = new CheckboxMenuItem("Set auto size"); + CheckboxMenuItem cb2 = new CheckboxMenuItem("Set tooltip"); + Menu displayMenu = new Menu("Display"); + MenuItem errorItem = new MenuItem("Error"); + MenuItem warningItem = new MenuItem("Warning"); + MenuItem infoItem = new MenuItem("Info"); + MenuItem noneItem = new MenuItem("None"); + MenuItem exitItem = new MenuItem("Exit"); + + //Add components to popup menu + popup.add(aboutItem); + popup.addSeparator(); + popup.add(cb1); + popup.add(cb2); + popup.addSeparator(); + popup.add(displayMenu); + displayMenu.add(errorItem); + displayMenu.add(warningItem); + displayMenu.add(infoItem); + displayMenu.add(noneItem); + popup.add(exitItem); + + trayIcon.setPopupMenu(popup); + + try { + tray.add(trayIcon); + } catch (AWTException e) { + System.out.println("TrayIcon could not be added."); + return; + } + + trayIcon.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JOptionPane.showMessageDialog(null, + "This dialog box is run from System Tray"); + } + }); + + aboutItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JOptionPane.showMessageDialog(null, + "This dialog box is run from the About menu item"); + } + }); + + cb1.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + int cb1Id = e.getStateChange(); + if (cb1Id == ItemEvent.SELECTED){ + trayIcon.setImageAutoSize(true); + } else { + trayIcon.setImageAutoSize(false); + } + } + }); + + cb2.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + int cb2Id = e.getStateChange(); + if (cb2Id == ItemEvent.SELECTED){ + trayIcon.setToolTip("Sun TrayIcon"); + } else { + trayIcon.setToolTip(null); + } + } + }); + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + MenuItem item = (MenuItem)e.getSource(); + //TrayIcon.MessageType type = null; + System.out.println(item.getLabel()); + if ("Error".equals(item.getLabel())) { + //type = TrayIcon.MessageType.ERROR; + trayIcon.displayMessage("Sun TrayIcon Demo", + "This is an error message", TrayIcon.MessageType.ERROR); + + } else if ("Warning".equals(item.getLabel())) { + //type = TrayIcon.MessageType.WARNING; + trayIcon.displayMessage("Sun TrayIcon Demo", + "This is a warning message", TrayIcon.MessageType.WARNING); + + } else if ("Info".equals(item.getLabel())) { + //type = TrayIcon.MessageType.INFO; + trayIcon.displayMessage("Sun TrayIcon Demo", + "This is an info message", TrayIcon.MessageType.INFO); + + } else if ("None".equals(item.getLabel())) { + //type = TrayIcon.MessageType.NONE; + trayIcon.displayMessage("Sun TrayIcon Demo", + "This is an ordinary message", TrayIcon.MessageType.NONE); + } + } + }; + + errorItem.addActionListener(listener); + warningItem.addActionListener(listener); + infoItem.addActionListener(listener); + noneItem.addActionListener(listener); + + exitItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + tray.remove(trayIcon); + System.exit(0); + } + }); + } + + //Obtain the image URL + protected static Image createImage(String path, String description) { + URL imageURL = TrayIconDemo.class.getResource(path); + + if (imageURL == null) { + System.err.println("Resource not found: " + path); + return null; + } else { + return (new ImageIcon(imageURL, description)).getImage(); + } + } +} \ No newline at end of file diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java index 0b7d3f4df80..a1aee0ba074 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -397,7 +397,7 @@ public class GamePanel extends javax.swing.JPanel { } } - this.stack.loadCards(game.getStack(), bigCard, gameId, game.getStackOrder()); + this.stack.loadCards(game.getStack(), bigCard, gameId, null); GameManager.getInstance().setStackSize(game.getStack().size()); for (ExileView exile: game.getExile()) { diff --git a/Mage.Client/src/main/java/mage/images/bulb.gif b/Mage.Client/src/main/java/mage/images/bulb.gif new file mode 100644 index 00000000000..b807111c29f Binary files /dev/null and b/Mage.Client/src/main/java/mage/images/bulb.gif differ diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java index 1b74297114d..f7810ea2f6f 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java @@ -810,6 +810,9 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { sb.append("\n").append(card.getLoyalty()); } + if (card.getRules() == null) { + card.overrideRules(new ArrayList()); + } for (String rule : card.getRules()) { sb.append("\n").append(rule); } diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index ca559959b78..34d9c09d19b 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -28,6 +28,7 @@ package mage.view; +import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.MageObject; @@ -38,6 +39,7 @@ import mage.game.permanent.Permanent; import mage.game.permanent.PermanentToken; import mage.game.permanent.token.Token; import mage.game.stack.Spell; +import mage.game.stack.StackAbility; import mage.target.Target; import mage.target.Targets; @@ -150,6 +152,15 @@ public class CardView extends SimpleCardView { this.expansionSetCode = ((PermanentToken) card).getExpansionSetCode(); this.rules = ((PermanentToken) card).getRules(); } + if (name.equals("") && card instanceof StackAbility) { + StackAbility stackAbility = (StackAbility)card; + if (stackAbility.getZone().equals(Constants.Zone.COMMAND)) { + this.name = "Emblem"; + this.rarity = Rarity.NA; + this.rules = new ArrayList(); + this.rules.add(stackAbility.getRule()); + } + } } protected CardView() { @@ -164,6 +175,11 @@ public class CardView extends SimpleCardView { fillEmpty(); } + public CardView(String name) { + this(true); + this.name = name; + } + private void fillEmpty() { this.name = "Face Down"; this.rules = new ArrayList(); diff --git a/Mage.Common/src/mage/view/CardsView.java b/Mage.Common/src/mage/view/CardsView.java index 0d350ab4fc7..c254bcfa377 100644 --- a/Mage.Common/src/mage/view/CardsView.java +++ b/Mage.Common/src/mage/view/CardsView.java @@ -28,9 +28,6 @@ package mage.view; -import java.util.Collection; -import java.util.HashMap; -import java.util.UUID; import mage.Constants.Zone; import mage.abilities.Ability; import mage.cards.Card; @@ -38,11 +35,15 @@ import mage.game.Game; import mage.game.GameState; import mage.game.permanent.Permanent; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com */ -public class CardsView extends HashMap { +public class CardsView extends LinkedHashMap { public CardsView() {} @@ -66,6 +67,10 @@ public class CardsView extends HashMap { if (sourceCard == null) sourceCard = (Permanent)game.getLastKnownInformation(ability.getSourceId(), Zone.BATTLEFIELD); break; + case COMMAND: + ability.newId(); + this.put(ability.getId(), new AbilityView(ability, "Emblem", new CardView("Emblem"))); + break; } if (sourceCard != null) { this.put(ability.getId(), new AbilityView(ability, sourceCard.getName(), new CardView(sourceCard))); diff --git a/Mage.Common/src/mage/view/GameView.java b/Mage.Common/src/mage/view/GameView.java index f4e5f5a8ea9..df87c991b0c 100644 --- a/Mage.Common/src/mage/view/GameView.java +++ b/Mage.Common/src/mage/view/GameView.java @@ -57,7 +57,7 @@ public class GameView implements Serializable { private SimpleCardsView hand; private Map opponentHands; private CardsView stack = new CardsView(); - private List stackOrder = new ArrayList(); + //private List stackOrder = new ArrayList(); private List exiles = new ArrayList(); private List revealed = new ArrayList(); private List lookedAt = new ArrayList(); @@ -87,15 +87,17 @@ public class GameView implements Serializable { updateLatestCardView(game, card, stackObject.getId()); } } else if (object != null) { - stack.put(stackObject.getId(), new CardView(object)); + StackAbility stackAbility = ((StackAbility)object); + stackAbility.newId(); + stack.put(stackObject.getId(), new CardView(stackAbility)); } } else { stack.put(stackObject.getId(), new CardView((Spell)stackObject)); } - stackOrder.add(stackObject.getId()); + //stackOrder.add(stackObject.getId()); } - Collections.reverse(stackOrder); + //Collections.reverse(stackOrder); for (ExileZone exileZone: state.getExile().getExileZones()) { exiles.add(new ExileView(exileZone, game)); } @@ -203,7 +205,7 @@ public class GameView implements Serializable { return special; } - public List getStackOrder() { + /*public List getStackOrder() { return stackOrder; - } + }*/ } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/emblems/EmblemsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/emblems/EmblemsTest.java index 522782ebc34..eb6505b9132 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/emblems/EmblemsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/emblems/EmblemsTest.java @@ -107,6 +107,7 @@ public class EmblemsTest extends CardTestPlayerBase { execute(); assertEmblemCount(playerA, 2); + assertPermanentCount(playerA, "Elite Vanguard", 0); assertHandCount(playerA, 1); boolean found = false; diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index 047221524a8..781163383d5 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -44,7 +44,6 @@ import mage.cards.Card; import mage.choices.Choice; import mage.choices.Choices; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.Targets; import org.apache.log4j.Logger; @@ -459,7 +458,11 @@ public abstract class AbilityImpl> implements Ability { @Override public boolean isInUseableZone(Game game, boolean checkLKI) { - Permanent permanent = game.getPermanent(getSourceId()); + + // emblem are always actual + if (zone.equals(Zone.COMMAND)) { + return true; + } // try LKI first if (checkLKI) { diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index cfddf3bfcf2..abfbb84601e 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -53,6 +53,7 @@ import mage.filter.Filter; import mage.filter.Filter.ComparisonScope; import mage.filter.common.*; import mage.game.combat.Combat; +import mage.game.command.CommandObject; import mage.game.command.Emblem; import mage.game.events.*; import mage.game.events.TableEvent.EventType; @@ -253,10 +254,16 @@ public abstract class GameImpl> implements Game, Serializa } } object = getCard(objectId); - if (object != null) - return object; - return null; + if (object == null) { + for (CommandObject commandObject : state.getCommand()) { + if (commandObject.getId().equals(objectId)) { + return commandObject; + } + } + } + + return object; } @Override @@ -748,6 +755,9 @@ public abstract class GameImpl> implements Game, Serializa newEmblem.setControllerId(source.getControllerId()); newEmblem.assignNewId(); newEmblem.getAbilities().newId(); + for (Ability ability : newEmblem.getAbilities()) { + ability.setSourceId(newEmblem.getId()); + } state.addEmblem(newEmblem); } diff --git a/Mage/src/mage/game/GameState.java b/Mage/src/mage/game/GameState.java index e97c36f1cc9..2e401897b13 100644 --- a/Mage/src/mage/game/GameState.java +++ b/Mage/src/mage/game/GameState.java @@ -449,7 +449,7 @@ public class GameState implements Serializable, Copyable { } } else if (ability instanceof TriggeredAbility) { - addTriggeredAbility((TriggeredAbility)ability); + this.triggers.add((TriggeredAbility)ability); } } diff --git a/Mage/src/mage/game/stack/StackAbility.java b/Mage/src/mage/game/stack/StackAbility.java index 9affe0a7bea..99fc2696895 100644 --- a/Mage/src/mage/game/stack/StackAbility.java +++ b/Mage/src/mage/game/stack/StackAbility.java @@ -295,7 +295,9 @@ public class StackAbility implements StackObject, Ability { } @Override - public void newId() {} + public void newId() { + this.ability.newId(); + } @Override public void newOriginalId() {}