diff --git a/res/lang/en.properties b/res/lang/en.properties index 75cc04c4104..88cac807cba 100644 --- a/res/lang/en.properties +++ b/res/lang/en.properties @@ -76,6 +76,15 @@ Display/nolandlimit/button=Play Unlimited Lands This Turn Display/setlife/menu=Set Player Life Display/setlife/button=Set Player Life +Display/alwaysaccept/menu=Always accept this trigger +Display/alwaysaccept/button=Always accept this trigger + +Display/alwaysdecline/menu=Always decline this trigger +Display/alwaysdecline/button=Always decline this trigger + +Display/alwaysask/menu=Always ask +Display/alwaysask/button=Always ask + DownloadPictures/title=Downloading DownloadPictures/no-more=All card pictures have been downloaded. diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index 680f4305f5c..53f5725ca70 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -1120,7 +1120,7 @@ public class GameAction { AllZone.newGameCleanup(); canShowWinLose = true; forge.card.trigger.Trigger.resetIDs(); - + AllZone.getTriggerHandler().clearTriggerSettings(); { //re-number cards just so their unique numbers are low, just for user friendliness CardFactoryInterface c = AllZone.getCardFactory(); diff --git a/src/main/java/forge/GuiDisplay4.java b/src/main/java/forge/GuiDisplay4.java index 31bf4042eaf..7fc2eb22ab5 100644 --- a/src/main/java/forge/GuiDisplay4.java +++ b/src/main/java/forge/GuiDisplay4.java @@ -52,6 +52,7 @@ import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTextArea; @@ -79,6 +80,7 @@ import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStreamException; import forge.card.cardFactory.CardFactoryUtil; +import forge.card.spellability.SpellAbility; import forge.error.ErrorViewer; import forge.gui.ForgeAction; import forge.gui.GuiUtils; @@ -124,6 +126,8 @@ public class GuiDisplay4 extends JFrame implements CardContainer, Display, NewCo //public Card cCardHQ; //private CardList multiBlockers = new CardList(); + + private TriggerReactionMenu triggerMenu; /** *

Constructor for GuiDisplay4.

@@ -193,6 +197,9 @@ public class GuiDisplay4 extends JFrame implements CardContainer, Display, NewCo *

addMenu.

*/ private void addMenu() { + // Trigger Context Menu creation + triggerMenu = new TriggerReactionMenu(); + // Game Menu Creation Object[] obj = { HUMAN_DECKLIST_ACTION, @@ -716,15 +723,16 @@ public class GuiDisplay4 extends JFrame implements CardContainer, Display, NewCo AllZone.getStack().addObserver(new Observer() { public void update(final Observable a, final Object b) { stackPanel.removeAll(); - MagicStack stack = AllZone.getStack(); + final MagicStack stack = AllZone.getStack(); int count = 1; JLabel label; for (int i = stack.size() - 1; 0 <= i; i--) { + final int curI = i; label = new JLabel("" + (count++) + ". " + stack.peekInstance(i).getStackDescription()); //update card detail - final CardPanel cardPanel = new CardPanel(stack.peekInstance(i).getSourceCard()); + final CardPanel cardPanel = new CardPanel(stack.peekInstance().getSpellAbility().getSourceCard()); cardPanel.setLayout(new BorderLayout()); cardPanel.add(label); cardPanel.addMouseMotionListener(new MouseMotionAdapter() { @@ -734,6 +742,22 @@ public class GuiDisplay4 extends JFrame implements CardContainer, Display, NewCo setCard(cardPanel.getCard()); } //mouseMoved }); + + cardPanel.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(final MouseEvent e) { + if(e.getButton() != MouseEvent.BUTTON3) + { + return; + } + if(!stack.peekInstance(curI).isOptionalTrigger()) + { + return; + } + triggerMenu.setTrigger(stack.peekAbility(curI).getSourceTrigger()); + triggerMenu.show(e.getComponent(),e.getX(),e.getY()); + } + }); stackPanel.add(cardPanel); } @@ -1684,5 +1708,74 @@ public class GuiDisplay4 extends JFrame implements CardContainer, Display, NewCo } } } + + private class TriggerReactionMenu extends JPopupMenu { + private static final long serialVersionUID = 6665085414634139984L; + private int workTrigID; + + public TriggerReactionMenu() + { + super(); + + ForgeAction actAccept = new ForgeAction(LANG.GuiDisplay.TRIGGER.ALWAYSACCEPT) { + private static final long serialVersionUID = -3734674058185367612L; + + @Override + public final void actionPerformed(final ActionEvent e) { + AllZone.getTriggerHandler().setAlwaysAcceptTrigger(workTrigID); + } + }; + + ForgeAction actDecline = new ForgeAction(LANG.GuiDisplay.TRIGGER.ALWAYSDECLINE) { + private static final long serialVersionUID = -1983295769159971502L; + + @Override + public final void actionPerformed(final ActionEvent e) { + AllZone.getTriggerHandler().setAlwaysDeclineTrigger(workTrigID); + } + }; + + ForgeAction actAsk = new ForgeAction(LANG.GuiDisplay.TRIGGER.ALWAYSASK) { + private static final long serialVersionUID = 5045255351332940821L; + + @Override + public final void actionPerformed(final ActionEvent e) { + AllZone.getTriggerHandler().setAlwaysAskTrigger(workTrigID); + } + }; + + JCheckBoxMenuItem jcbmiAccept = new JCheckBoxMenuItem(actAccept); + JCheckBoxMenuItem jcbmiDecline = new JCheckBoxMenuItem(actDecline); + JCheckBoxMenuItem jcbmiAsk = new JCheckBoxMenuItem(actAsk); + + add(jcbmiAccept); + add(jcbmiDecline); + add(jcbmiAsk); + } + + public void setTrigger(final int trigID) + { + workTrigID = trigID; + + if(AllZone.getTriggerHandler().isAlwaysAccepted(trigID)) + { + ((JCheckBoxMenuItem)getComponent(0)).setState(true); + ((JCheckBoxMenuItem)getComponent(1)).setState(false); + ((JCheckBoxMenuItem)getComponent(2)).setState(false); + } + else if (AllZone.getTriggerHandler().isAlwaysDeclined(trigID)) + { + ((JCheckBoxMenuItem)getComponent(0)).setState(false); + ((JCheckBoxMenuItem)getComponent(1)).setState(true); + ((JCheckBoxMenuItem)getComponent(2)).setState(false); + } + else + { + ((JCheckBoxMenuItem)getComponent(0)).setState(false); + ((JCheckBoxMenuItem)getComponent(1)).setState(false); + ((JCheckBoxMenuItem)getComponent(2)).setState(true); + } + } + } } diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index 2db76765161..bad57155537 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -46,6 +46,7 @@ public abstract class SpellAbility { private boolean spell; private boolean trigger = false; + private boolean optionalTrigger = false; private int sourceTrigger = -1; private boolean mandatory = false; private boolean temporarilySuppressed = false; @@ -1141,6 +1142,14 @@ public abstract class SpellAbility { public boolean isTrigger() { return trigger; } + + public void setOptionalTrigger(final boolean optrigger) { + this.optionalTrigger = optrigger; + } + + public boolean isOptionalTrigger() { + return this.optionalTrigger; + } /** *

setSourceTrigger.

diff --git a/src/main/java/forge/card/spellability/SpellAbility_StackInstance.java b/src/main/java/forge/card/spellability/SpellAbility_StackInstance.java index 28851b1310d..dae5cfaa548 100644 --- a/src/main/java/forge/card/spellability/SpellAbility_StackInstance.java +++ b/src/main/java/forge/card/spellability/SpellAbility_StackInstance.java @@ -190,4 +190,8 @@ public class SpellAbility_StackInstance { public boolean isStateTrigger(int ID) { return ability.getSourceTrigger() == ID; } + + public boolean isOptionalTrigger() { + return ability.isOptionalTrigger(); + } } diff --git a/src/main/java/forge/card/trigger/TriggerHandler.java b/src/main/java/forge/card/trigger/TriggerHandler.java index 6988d83566d..8fdbf5a87c3 100644 --- a/src/main/java/forge/card/trigger/TriggerHandler.java +++ b/src/main/java/forge/card/trigger/TriggerHandler.java @@ -453,6 +453,7 @@ public class TriggerHandler { sa[0].setStackDescription(sa[0].toString()); boolean mand = false; if (trigParams.containsKey("OptionalDecider")) { + sa[0].setOptionalTrigger(true); mand = false; decider[0] = AbilityFactory.getDefinedPlayers(host, trigParams.get("OptionalDecider"), sa[0]).get(0); } else { @@ -930,6 +931,16 @@ public class TriggerHandler { public int getSourceTrigger() { return sa[0].getSourceTrigger(); } + + @Override + public void setOptionalTrigger(boolean b) { + sa[0].setOptionalTrigger(b); + } + + @Override + public boolean isOptionalTrigger() { + return sa[0].isOptionalTrigger(); + } //////////////////////////////////////// //THIS ONE IS ALL THAT MATTERS @@ -945,14 +956,25 @@ public class TriggerHandler { if (decider[0] != null) { if (decider[0].isHuman()) { - StringBuilder buildQuestion = new StringBuilder("Use triggered ability of "); - buildQuestion.append(regtrig.getHostCard().getName()).append("(").append(regtrig.getHostCard().getUniqueNumber()).append(")?"); - buildQuestion.append("\r\n("); - buildQuestion.append(regtrig.getMapParams().get("TriggerDescription").replace("CARDNAME", regtrig.getHostCard().getName())); - buildQuestion.append(")"); - if (!GameActionUtil.showYesNoDialog(regtrig.getHostCard(), buildQuestion.toString())) { + if(triggersAlwaysAccept.contains(getSourceTrigger())) + { + //No need to do anything. + } + else if(triggersAlwaysDecline.contains(getSourceTrigger())) + { return; } + else + { + StringBuilder buildQuestion = new StringBuilder("Use triggered ability of "); + buildQuestion.append(regtrig.getHostCard().getName()).append("(").append(regtrig.getHostCard().getUniqueNumber()).append(")?"); + buildQuestion.append("\r\n("); + buildQuestion.append(regtrig.getMapParams().get("TriggerDescription").replace("CARDNAME", regtrig.getHostCard().getName())); + buildQuestion.append(")"); + if (!GameActionUtil.showYesNoDialog(regtrig.getHostCard(), buildQuestion.toString())) { + return; + } + } } else { // This isn't quite right, but better than canPlayAI if (!sa[0].doTrigger(isMandatory)) { @@ -1011,4 +1033,49 @@ public class TriggerHandler { } return true; } + + private final ArrayList triggersAlwaysAccept = new ArrayList(); + private final ArrayList triggersAlwaysDecline = new ArrayList(); + + public void setAlwaysAcceptTrigger(final int trigID) { + if(triggersAlwaysDecline.contains(trigID)) + { + triggersAlwaysDecline.remove((Object)trigID); + } + + if(!triggersAlwaysAccept.contains(trigID)) + { + triggersAlwaysAccept.add(trigID); + } + } + + public void setAlwaysDeclineTrigger(final int trigID) { + if(triggersAlwaysAccept.contains(trigID)) + { + triggersAlwaysAccept.remove((Object)trigID); + } + + if(!triggersAlwaysDecline.contains(trigID)) + { + triggersAlwaysDecline.add(trigID); + } + } + + public void setAlwaysAskTrigger(final int trigID) { + triggersAlwaysAccept.remove((Object)trigID); + triggersAlwaysDecline.remove((Object)trigID); + } + + public boolean isAlwaysAccepted(final int trigID) { + return triggersAlwaysAccept.contains(trigID); + } + + public boolean isAlwaysDeclined(final int trigID) { + return triggersAlwaysDecline.contains(trigID); + } + + public void clearTriggerSettings() { + triggersAlwaysAccept.clear(); + triggersAlwaysDecline.clear(); + } } diff --git a/src/main/java/forge/properties/NewConstants.java b/src/main/java/forge/properties/NewConstants.java index 4c586191578..6820a60c3d5 100644 --- a/src/main/java/forge/properties/NewConstants.java +++ b/src/main/java/forge/properties/NewConstants.java @@ -375,6 +375,12 @@ public interface NewConstants { String BUTTON = "%s/Display/setlife/button"; String MENU = "%s/Display/setlife/menu"; } + + public static interface TRIGGER { + String ALWAYSACCEPT = "%s/Display/alwaysaccept"; + String ALWAYSDECLINE = "%s/Display/alwaysdecline"; + String ALWAYSASK = "%s/Display/alwaysask"; + } } public static interface Gui_DownloadPictures { @@ -460,7 +466,6 @@ public interface NewConstants { String TITLE = "%s/NewGame/help/title"; } - } public static interface ERRORS {