diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.form b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.form
index 5adaf97cd92..4b4f2fa9812 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.form
+++ b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.form
@@ -1,13 +1,6 @@
-
diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java
index 07095dbded2..b0d371c19dc 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java
@@ -1,43 +1,23 @@
/*
-* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are
-* permitted provided that the following conditions are met:
-*
-* 1. Redistributions of source code must retain the above copyright notice, this list of
-* conditions and the following disclaimer.
-*
-* 2. 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.
-*
-* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``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 BetaSteward_at_googlemail.com 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.
-*
-* The views and conclusions contained in the software and documentation are those of the
-* authors and should not be interpreted as representing official policies, either expressed
-* or implied, of BetaSteward_at_googlemail.com.
-*/
-
-/*
- * PickNumberDialog.java
- *
- * Created on Feb 25, 2010, 12:03:39 PM
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
*/
-
package mage.client.dialog;
import java.awt.Point;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;
+import javax.swing.DefaultListModel;
+import javax.swing.JLabel;
import javax.swing.JLayeredPane;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
import mage.choices.Choice;
import mage.client.MageFrame;
import mage.client.util.SettingsManager;
@@ -46,37 +26,103 @@ import mage.client.util.gui.MageDialogState;
/**
*
- * @author BetaSteward_at_googlemail.com
+ * @author JayDi85
*/
+
public class PickChoiceDialog extends MageDialog {
- /** Creates new form PickNumberDialog */
- public PickChoiceDialog() {
- initComponents();
- this.setModal(true);
- }
Choice choice;
- boolean autoSelect;
-
+ ArrayList allItems = new ArrayList<>();
+ DefaultListModel dataModel = new DefaultListModel();
+
+ final private static String HTML_TEMPLATE = "%s
";
+
public void showDialog(Choice choice, UUID objectId, MageDialogState mageDialogState) {
- this.lblMessage.setText("" + choice.getMessage());
this.choice = choice;
- this.autoSelect = false;
- btnAutoSelect.setVisible(choice.isKeyChoice());
- if (choice.isKeyChoice()){
-
- ComboItem[] comboItems = new ComboItem[choice.getKeyChoices().size()];
- int count = 0;
- for (Map.Entry entry : choice.getKeyChoices().entrySet()) {
- comboItems[count] = new ComboItem(entry.getKey(), entry.getValue());
- count++;
+ setLabelText(this.labelMessage, choice.getMessage());
+ setLabelText(this.labelSubMessage, choice.getSubMessage());
+
+ btCancel.setEnabled(!choice.isRequired());
+
+ // 2 modes: string or key-values
+ // sore data in allItems for inremental filtering
+ // http://logicbig.com/tutorials/core-java-tutorial/swing/list-filter/
+ this.allItems.clear();
+ if (choice.isKeyChoice()){
+ for (Map.Entry entry: choice.getKeyChoices().entrySet()) {
+ this.allItems.add(new KeyValueItem(entry.getKey(), entry.getValue()));
}
- this.lstChoices.setListData(comboItems);
} else {
- this.lstChoices.setListData(choice.getChoices().toArray());
+ for (String value: choice.getChoices()){
+ this.allItems.add(new KeyValueItem(value, value));
+ }
}
+ // search
+ if(choice.isSearchEnabled())
+ {
+ panelSearch.setVisible(true);
+ this.editSearch.setText(choice.getSearchText());
+ }else{
+ panelSearch.setVisible(false);
+ this.editSearch.setText("");
+ }
+
+ // listeners for inremental filtering
+ editSearch.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ choice.setSearchText(editSearch.getText());
+ loadData();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ choice.setSearchText(editSearch.getText());
+ loadData();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ choice.setSearchText(editSearch.getText());
+ loadData();
+ }
+ });
+
+ // listeners for select up and down without edit focus lost
+ editSearch.addKeyListener(new KeyListener() {
+ @Override
+ public void keyTyped(KeyEvent e) {
+ //System.out.println("types");
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if(e.getKeyCode() == KeyEvent.VK_UP){
+ doPrevSelect();
+ }else if(e.getKeyCode() == KeyEvent.VK_DOWN){
+ doNextSelect();
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ //System.out.println("released");
+ }
+ });
+
+ // listeners double click choose
+ listChoices.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if(e.getClickCount() == 2){
+ doChoose();
+ }
+ }
+ });
+
+ // window settings
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
if (mageDialogState != null) {
mageDialogState.setStateToDialog(this);
@@ -87,154 +133,308 @@ public class PickChoiceDialog extends MageDialog {
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
}
+ // final load
+ loadData();
this.setVisible(true);
}
-
- public boolean isAutoSelect() {
- return autoSelect;
+
+ private void loadData(){
+ // load data to datamodel after filter or on startup
+ String filter = choice.getSearchText();
+ if (filter == null){ filter = ""; }
+ filter = filter.toLowerCase();
+
+ this.dataModel.clear();
+ for(KeyValueItem item: this.allItems){
+ if(!choice.isSearchEnabled() || item.Value.toLowerCase().contains(filter)){
+ this.dataModel.addElement(item);
+ }
+ }
+ }
+
+ private void setLabelText(JLabel label, String text){
+ if ((text != null) && !text.equals("")){
+ label.setText(String.format(HTML_TEMPLATE, text));
+ label.setVisible(true);
+ }else{
+ label.setText("");
+ label.setVisible(false);
+ }
+ }
+
+ private void doNextSelect(){
+ int newSel = this.listChoices.getSelectedIndex() + 1;
+ int maxSel = this.listChoices.getModel().getSize() - 1;
+ if(newSel <= maxSel){
+ this.listChoices.setSelectedIndex(newSel);
+ this.listChoices.ensureIndexIsVisible(newSel);
+ }
+ }
+
+ private void doPrevSelect(){
+ int newSel = this.listChoices.getSelectedIndex() - 1;
+ if(newSel >= 0){
+ this.listChoices.setSelectedIndex(newSel);
+ this.listChoices.ensureIndexIsVisible(newSel);
+ }
}
- public void setChoice() {
- if (this.lstChoices.getSelectedValue() == null) {
- choice.clearChoice();
+ private void doChoose(){
+ if(setChoice()){
+ this.hideDialog();
+ }
+ }
+
+ private void doCancel(){
+ this.listChoices.clearSelection();
+ this.choice.clearChoice();
+ hideDialog();
+ }
+
+ /**
+ * Creates new form PickChoiceDialog
+ */
+ public PickChoiceDialog() {
+ initComponents();
+ this.listChoices.setModel(dataModel);
+ this.setModal(true);
+
+ // Close the dialog when Esc is pressed
+ /*
+ String cancelName = "cancel";
+ InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName);
+ ActionMap actionMap = getRootPane().getActionMap();
+ actionMap.put(cancelName, new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ doCancel();
+ }
+ });
+ */
+ }
+
+ public boolean setChoice() {
+ KeyValueItem item = (KeyValueItem)this.listChoices.getSelectedValue();
+
+ // auto select one item (after incemental filtering)
+ if((item == null) && (this.listChoices.getModel().getSize() == 1)){
+ this.listChoices.setSelectedIndex(0);
+ item = (KeyValueItem)this.listChoices.getSelectedValue();
}
- if (choice.isKeyChoice()) {
- ComboItem item = (ComboItem)this.lstChoices.getSelectedValue();
- if (item != null) {
- choice.setChoiceByKey(item.getValue());
- } else {
- choice.clearChoice();
+ if(item != null){
+ if(choice.isKeyChoice()){
+ choice.setChoiceByKey(item.getKey());
+ }else{
+ choice.setChoice(item.getKey());
}
- } else {
- choice.setChoice((String)this.lstChoices.getSelectedValue());
+ return true;
+ }else{
+ choice.clearChoice();
+ return false;
}
}
+
+ class KeyValueItem
+ {
+ private final String Key;
+ private final String Value;
+
+ public KeyValueItem(String value, String label) {
+ this.Key = value;
+ this.Value = label;
+ }
- /** This method is called from within the constructor to
- * initialize the form.
- * WARNING: Do NOT modify this code. The content of this method is
- * always regenerated by the Form Editor.
+ public String getKey() {
+ return this.Key;
+ }
+
+ public String getValue() {
+ return this.Value;
+ }
+
+ @Override
+ public String toString() {
+ return this.Value;
+ }
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// //GEN-BEGIN:initComponents
private void initComponents() {
- btnAutoSelect = new javax.swing.JButton();
- btnCancel = new javax.swing.JButton();
- btnOk = new javax.swing.JButton();
- jScrollPane1 = new javax.swing.JScrollPane();
- lstChoices = new javax.swing.JList();
- lblMessage = new javax.swing.JLabel();
+ panelHeader = new javax.swing.JPanel();
+ labelMessage = new javax.swing.JLabel();
+ labelSubMessage = new javax.swing.JLabel();
+ panelSearch = new javax.swing.JPanel();
+ labelSearch = new javax.swing.JLabel();
+ editSearch = new javax.swing.JTextField();
+ scrollList = new javax.swing.JScrollPane();
+ listChoices = new javax.swing.JList();
+ panelCommands = new javax.swing.JPanel();
+ btOK = new javax.swing.JButton();
+ btCancel = new javax.swing.JButton();
- setResizable(true);
- setMinimumSize(new java.awt.Dimension(280, 200));
- setName(""); // NOI18N
+ labelMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ labelMessage.setText("example long message example long message example long message example long message example long message
");
- btnAutoSelect.setText("Auto select");
- btnAutoSelect.setToolTipText("If you select an effect with \"Auto select\", this effect will be selected the next time automatically first.");
- btnAutoSelect.addActionListener(evt -> btnAutoSelectActionPerformed(evt));
+ labelSubMessage.setFont(labelSubMessage.getFont().deriveFont((labelSubMessage.getFont().getStyle() | java.awt.Font.ITALIC) | java.awt.Font.BOLD));
+ labelSubMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ labelSubMessage.setText("example long message example long
");
- btnCancel.setText("Cancel");
- btnCancel.addActionListener(evt -> btnCancelActionPerformed(evt));
+ javax.swing.GroupLayout panelHeaderLayout = new javax.swing.GroupLayout(panelHeader);
+ panelHeader.setLayout(panelHeaderLayout);
+ panelHeaderLayout.setHorizontalGroup(
+ panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelHeaderLayout.createSequentialGroup()
+ .addGroup(panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(labelMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
+ .addComponent(labelSubMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
+ .addGap(0, 0, 0))
+ );
+ panelHeaderLayout.setVerticalGroup(
+ panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelHeaderLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(labelMessage)
+ .addGap(0, 0, 0)
+ .addComponent(labelSubMessage))
+ );
- btnOk.setText("OK");
- btnOk.addActionListener(evt -> btnOkActionPerformed(evt));
+ labelSearch.setText("Search:");
- lstChoices.setModel(new javax.swing.AbstractListModel() {
- final String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
+ editSearch.setText("sample search text");
+
+ javax.swing.GroupLayout panelSearchLayout = new javax.swing.GroupLayout(panelSearch);
+ panelSearch.setLayout(panelSearchLayout);
+ panelSearchLayout.setHorizontalGroup(
+ panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelSearchLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(labelSearch)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(editSearch)
+ .addGap(0, 0, 0))
+ );
+ panelSearchLayout.setVerticalGroup(
+ panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelSearchLayout.createSequentialGroup()
+ .addGap(3, 3, 3)
+ .addGroup(panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(labelSearch)
+ .addComponent(editSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(3, 3, 3))
+ );
+
+ listChoices.setModel(new javax.swing.AbstractListModel() {
+ String[] strings = { "item1", "item2", "item3" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
- jScrollPane1.setViewportView(lstChoices);
+ scrollList.setViewportView(listChoices);
- lblMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
- lblMessage.setText("message");
+ btOK.setText("Choose");
+ btOK.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btOKActionPerformed(evt);
+ }
+ });
+
+ btCancel.setText("Cancel");
+ btCancel.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btCancelActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout panelCommandsLayout = new javax.swing.GroupLayout(panelCommands);
+ panelCommands.setLayout(panelCommandsLayout);
+ panelCommandsLayout.setHorizontalGroup(
+ panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelCommandsLayout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(btOK)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+
+ panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btCancel, btOK});
+
+ panelCommandsLayout.setVerticalGroup(
+ panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelCommandsLayout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(btCancel)
+ .addComponent(btOK))
+ .addContainerGap())
+ );
+
+ getRootPane().setDefaultButton(btOK);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addGroup(layout.createSequentialGroup()
.addContainerGap()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
- .addGroup(layout.createSequentialGroup()
- .addGap(0, 0, Short.MAX_VALUE)
- .addComponent(btnAutoSelect)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnOk)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnCancel))
- .addComponent(lblMessage, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE))
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(scrollList, javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(panelCommands, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelHeader, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelSearch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addGap(6, 6, 6)
- .addComponent(lblMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap()
+ .addComponent(panelHeader, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE)
+ .addComponent(panelSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(btnCancel)
- .addComponent(btnOk)
- .addComponent(btnAutoSelect))
- .addGap(10, 10, 10))
+ .addComponent(scrollList, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
);
pack();
}// //GEN-END:initComponents
- private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed
- setChoice();
- this.hideDialog();
- }//GEN-LAST:event_btnOkActionPerformed
+ private void btOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btOKActionPerformed
+ doChoose();
+ }//GEN-LAST:event_btOKActionPerformed
- private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
- this.lstChoices.clearSelection();
- this.choice.clearChoice();
- this.hideDialog();
- }//GEN-LAST:event_btnCancelActionPerformed
+ private void btCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btCancelActionPerformed
+ doCancel();
+ }//GEN-LAST:event_btCancelActionPerformed
- private void btnAutoSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAutoSelectActionPerformed
- this.autoSelect = true;
- setChoice();
- this.hideDialog();
- }//GEN-LAST:event_btnAutoSelectActionPerformed
+ /**
+ * Closes the dialog
+ */
+ private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
+ doCancel();
+ }//GEN-LAST:event_closeDialog
// Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JButton btnAutoSelect;
- private javax.swing.JButton btnCancel;
- private javax.swing.JButton btnOk;
- private javax.swing.JScrollPane jScrollPane1;
- private javax.swing.JLabel lblMessage;
- private javax.swing.JList lstChoices;
+ private javax.swing.JButton btCancel;
+ private javax.swing.JButton btOK;
+ private javax.swing.JTextField editSearch;
+ private javax.swing.JLabel labelMessage;
+ private javax.swing.JLabel labelSearch;
+ private javax.swing.JLabel labelSubMessage;
+ private javax.swing.JList listChoices;
+ private javax.swing.JPanel panelCommands;
+ private javax.swing.JPanel panelHeader;
+ private javax.swing.JPanel panelSearch;
+ private javax.swing.JScrollPane scrollList;
// End of variables declaration//GEN-END:variables
-
}
- class ComboItem {
-
- private final String value;
- private final String label;
-
- public ComboItem(String value, String label) {
- this.value = value;
- this.label = label;
- }
-
- public String getValue() {
- return this.value;
- }
-
- public String getLabel() {
- return this.label;
- }
-
- @Override
- public String toString() {
- return label;
- }
- }
\ 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 a014167df0a..ab0daf3e706 100644
--- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java
+++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java
@@ -1220,14 +1220,17 @@ public final class GamePanel extends javax.swing.JPanel {
public void getChoice(Choice choice, UUID objectId) {
hideAll();
+ // TODO: remember last choices and search incremental for same events?
PickChoiceDialog pickChoice = new PickChoiceDialog();
pickChoice.showDialog(choice, objectId, choiceWindowState);
if (choice.isKeyChoice()) {
+ SessionHandler.sendPlayerString(gameId, choice.getChoiceKey());
+ /* // old code, auto complete was for auto scripting?
if (pickChoice.isAutoSelect()) {
SessionHandler.sendPlayerString(gameId, '#' + choice.getChoiceKey());
} else {
SessionHandler.sendPlayerString(gameId, choice.getChoiceKey());
- }
+ }*/
} else {
SessionHandler.sendPlayerString(gameId, choice.getChoice());
}
diff --git a/Mage.Sets/src/mage/cards/a/AphettoDredging.java b/Mage.Sets/src/mage/cards/a/AphettoDredging.java
index 3e455021cf0..74df66d9838 100644
--- a/Mage.Sets/src/mage/cards/a/AphettoDredging.java
+++ b/Mage.Sets/src/mage/cards/a/AphettoDredging.java
@@ -65,7 +65,7 @@ public class AphettoDredging extends CardImpl {
if (ability instanceof SpellAbility) {
Player controller = game.getPlayer(ability.getControllerId());
if (controller != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(game.getObject(ability.getSourceId()));
while (!controller.choose(Outcome.PutCreatureInPlay, typeChoice, game)) {
if (!controller.canRespond()) {
return;
diff --git a/Mage.Sets/src/mage/cards/b/BloodlineShaman.java b/Mage.Sets/src/mage/cards/b/BloodlineShaman.java
index c8e5591919d..4e9867eaa16 100644
--- a/Mage.Sets/src/mage/cards/b/BloodlineShaman.java
+++ b/Mage.Sets/src/mage/cards/b/BloodlineShaman.java
@@ -98,7 +98,7 @@ class BloodlineShamanEffect extends OneShotEffect {
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null) {
// Choose a creature type.
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java b/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
index 1249f6b1266..4e440094aa4 100644
--- a/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
+++ b/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
@@ -129,7 +129,7 @@ class ChooseCreatureTypeEffect extends OneShotEffect { // code by LevelX2, but t
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source.getSourceId());
if (controller != null && mageObject != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(mageObject);
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/c/CallousOppressor.java b/Mage.Sets/src/mage/cards/c/CallousOppressor.java
index 63acbd3c2e1..f5b9d78b018 100644
--- a/Mage.Sets/src/mage/cards/c/CallousOppressor.java
+++ b/Mage.Sets/src/mage/cards/c/CallousOppressor.java
@@ -44,7 +44,7 @@ import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
-import mage.choices.ChoiceImpl;
+import mage.choices.ChoiceCreatureType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
@@ -154,9 +154,8 @@ class CallousOppressorChooseCreatureTypeEffect extends OneShotEffect {
}
Player opponent = game.getPlayer(target.getFirstTarget());
if (opponent != null && mageObject != null) {
- Choice typeChoice = new ChoiceImpl(true);
+ Choice typeChoice = new ChoiceCreatureType(mageObject);
typeChoice.setMessage("Choose creature type");
- typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
while (!opponent.choose(outcome, typeChoice, game)) {
if (!opponent.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java b/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java
index d9c068c192c..518dfc76ace 100644
--- a/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java
+++ b/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java
@@ -89,7 +89,7 @@ class CoordinatedBarrageEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- Choice choice = new ChoiceCreatureType();
+ Choice choice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
if (controller.choose(Outcome.Damage, choice, game)) {
String chosenType = choice.getChoice();
FilterControlledPermanent filter = new FilterControlledPermanent();
diff --git a/Mage.Sets/src/mage/cards/d/DistantMelody.java b/Mage.Sets/src/mage/cards/d/DistantMelody.java
index e773eeeedf9..5502cf22328 100644
--- a/Mage.Sets/src/mage/cards/d/DistantMelody.java
+++ b/Mage.Sets/src/mage/cards/d/DistantMelody.java
@@ -89,7 +89,7 @@ class DistantMelodyEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
while (!player.choose(Outcome.BoostCreature, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/e/ElvishSoultiller.java b/Mage.Sets/src/mage/cards/e/ElvishSoultiller.java
index 8b20c146bac..51047e50535 100644
--- a/Mage.Sets/src/mage/cards/e/ElvishSoultiller.java
+++ b/Mage.Sets/src/mage/cards/e/ElvishSoultiller.java
@@ -96,7 +96,7 @@ class ElvishSoultillerEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source.getSourceId());
if (controller != null && mageObject != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(mageObject);
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/e/Extinction.java b/Mage.Sets/src/mage/cards/e/Extinction.java
index 5d263271695..0310e869336 100644
--- a/Mage.Sets/src/mage/cards/e/Extinction.java
+++ b/Mage.Sets/src/mage/cards/e/Extinction.java
@@ -83,7 +83,7 @@ class ExtinctionEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(outcome, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/g/GraveSifter.java b/Mage.Sets/src/mage/cards/g/GraveSifter.java
index df5c373f73e..c60fe13164d 100644
--- a/Mage.Sets/src/mage/cards/g/GraveSifter.java
+++ b/Mage.Sets/src/mage/cards/g/GraveSifter.java
@@ -95,7 +95,7 @@ class GraveSifterEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
typeChoice.setMessage("Choose creature type to return cards from your graveyard");
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
diff --git a/Mage.Sets/src/mage/cards/h/HarshMercy.java b/Mage.Sets/src/mage/cards/h/HarshMercy.java
index 931d63a9386..72f42fb3b70 100644
--- a/Mage.Sets/src/mage/cards/h/HarshMercy.java
+++ b/Mage.Sets/src/mage/cards/h/HarshMercy.java
@@ -96,7 +96,7 @@ class HarshMercyEffect extends OneShotEffect {
PlayerIteration:
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(Outcome.DestroyPermanent, typeChoice, game)) {
if (!player.canRespond()) {
continue PlayerIteration;
diff --git a/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java b/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java
index 56a5c395e37..b287a99d533 100644
--- a/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java
+++ b/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java
@@ -152,7 +152,7 @@ class KaronaFalseGodEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (sourceObject != null && controller != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!controller.choose(Outcome.BoostCreature, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/l/LuminescentRain.java b/Mage.Sets/src/mage/cards/l/LuminescentRain.java
index 5437d5eec37..cb881e2b5e0 100644
--- a/Mage.Sets/src/mage/cards/l/LuminescentRain.java
+++ b/Mage.Sets/src/mage/cards/l/LuminescentRain.java
@@ -86,9 +86,9 @@ class LuminescentRainEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
while (!player.choose(Outcome.BoostCreature, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/m/MistformSliver.java b/Mage.Sets/src/mage/cards/m/MistformSliver.java
index 2ac7c3b16e3..2364d2cd9c4 100644
--- a/Mage.Sets/src/mage/cards/m/MistformSliver.java
+++ b/Mage.Sets/src/mage/cards/m/MistformSliver.java
@@ -92,7 +92,7 @@ class MistformSliverEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(permanent);
while (!player.choose(Outcome.Detriment, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/n/NewBlood.java b/Mage.Sets/src/mage/cards/n/NewBlood.java
index cd2c534219a..a6f3905c73e 100644
--- a/Mage.Sets/src/mage/cards/n/NewBlood.java
+++ b/Mage.Sets/src/mage/cards/n/NewBlood.java
@@ -39,7 +39,7 @@ import mage.abilities.text.TextPartSubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
-import mage.choices.ChoiceImpl;
+import mage.choices.ChoiceCreatureType;
import mage.constants.*;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
@@ -145,9 +145,8 @@ class ChangeCreatureTypeTargetEffect extends ContinuousEffectImpl {
return;
}
if (fromSubType == null) {
- Choice typeChoice = new ChoiceImpl(true);
+ Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
typeChoice.setMessage("Choose creature type to change to Vampire");
- typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return;
diff --git a/Mage.Sets/src/mage/cards/o/Outbreak.java b/Mage.Sets/src/mage/cards/o/Outbreak.java
index 1b6e48355a1..4de53cd1150 100644
--- a/Mage.Sets/src/mage/cards/o/Outbreak.java
+++ b/Mage.Sets/src/mage/cards/o/Outbreak.java
@@ -96,7 +96,7 @@ class OutbreakEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
while (!player.choose(outcome, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/p/PacksDisdain.java b/Mage.Sets/src/mage/cards/p/PacksDisdain.java
index 8b98c53a0eb..88c1951e0b3 100644
--- a/Mage.Sets/src/mage/cards/p/PacksDisdain.java
+++ b/Mage.Sets/src/mage/cards/p/PacksDisdain.java
@@ -93,7 +93,7 @@ class PacksDisdainEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
while (!player.choose(Outcome.UnboostCreature, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/p/PatriarchsBidding.java b/Mage.Sets/src/mage/cards/p/PatriarchsBidding.java
index a964d7f791c..e4500783854 100644
--- a/Mage.Sets/src/mage/cards/p/PatriarchsBidding.java
+++ b/Mage.Sets/src/mage/cards/p/PatriarchsBidding.java
@@ -93,7 +93,7 @@ class PatriarchsBiddingEffect extends OneShotEffect {
Set chosenTypes = new HashSet<>();
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(Outcome.PutCreatureInPlay, typeChoice, game)) {
if (!player.canRespond()) {
break;
diff --git a/Mage.Sets/src/mage/cards/p/PeerPressure.java b/Mage.Sets/src/mage/cards/p/PeerPressure.java
index 8101dc06be5..4ea1cfe77c3 100644
--- a/Mage.Sets/src/mage/cards/p/PeerPressure.java
+++ b/Mage.Sets/src/mage/cards/p/PeerPressure.java
@@ -93,7 +93,7 @@ class PeerPressureEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- Choice choice = new ChoiceCreatureType();
+ Choice choice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
while (!controller.choose(Outcome.GainControl, choice, game)) {
if (!controller.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/r/RiptideChronologist.java b/Mage.Sets/src/mage/cards/r/RiptideChronologist.java
index b4a838bf6a6..c4d0b45ad60 100644
--- a/Mage.Sets/src/mage/cards/r/RiptideChronologist.java
+++ b/Mage.Sets/src/mage/cards/r/RiptideChronologist.java
@@ -94,7 +94,7 @@ class RiptideChronologistEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(outcome, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java b/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java
index 5a5d21a2b94..ec5ee0e3049 100644
--- a/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java
+++ b/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java
@@ -96,7 +96,7 @@ class RiptideShapeshifterEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) {
- Choice choice = new ChoiceCreatureType();
+ Choice choice = new ChoiceCreatureType(sourceObject);
while (!controller.choose(Outcome.BoostCreature, choice, game)) {
if (!controller.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/r/RoarOfTheCrowd.java b/Mage.Sets/src/mage/cards/r/RoarOfTheCrowd.java
index 181d0fa4d95..213b9198079 100644
--- a/Mage.Sets/src/mage/cards/r/RoarOfTheCrowd.java
+++ b/Mage.Sets/src/mage/cards/r/RoarOfTheCrowd.java
@@ -89,7 +89,7 @@ class RoarOfTheCrowdEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
while (!player.choose(Outcome.LoseLife, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/s/Standardize.java b/Mage.Sets/src/mage/cards/s/Standardize.java
index b34c7065372..6a1adee518a 100644
--- a/Mage.Sets/src/mage/cards/s/Standardize.java
+++ b/Mage.Sets/src/mage/cards/s/Standardize.java
@@ -85,7 +85,7 @@ class StandardizeEffect extends OneShotEffect {
MageObject sourceObject = game.getObject(source.getSourceId());
String chosenType = "";
if (player != null && sourceObject != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
typeChoice.setMessage("Choose a creature type other than Wall");
typeChoice.getChoices().remove("Wall");
while (!player.choose(Outcome.BoostCreature, typeChoice, game)) {
diff --git a/Mage.Sets/src/mage/cards/t/TribalUnity.java b/Mage.Sets/src/mage/cards/t/TribalUnity.java
index e3ac24efd3f..fc9653ce1f1 100644
--- a/Mage.Sets/src/mage/cards/t/TribalUnity.java
+++ b/Mage.Sets/src/mage/cards/t/TribalUnity.java
@@ -91,7 +91,7 @@ class TribalUnityEffect extends OneShotEffect {
MageObject sourceObject = game.getObject(source.getSourceId());
int boost = amount.calculate(game, source, this);
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(outcome, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/t/TsabosDecree.java b/Mage.Sets/src/mage/cards/t/TsabosDecree.java
index 36aeb9acc35..b455b455054 100644
--- a/Mage.Sets/src/mage/cards/t/TsabosDecree.java
+++ b/Mage.Sets/src/mage/cards/t/TsabosDecree.java
@@ -90,7 +90,7 @@ class TsabosDecreeEffect extends OneShotEffect {
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
MageObject sourceObject = game.getObject(source.getSourceId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(outcome, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/w/WalkingDesecration.java b/Mage.Sets/src/mage/cards/w/WalkingDesecration.java
index 54988c4923a..f23339c4e2a 100644
--- a/Mage.Sets/src/mage/cards/w/WalkingDesecration.java
+++ b/Mage.Sets/src/mage/cards/w/WalkingDesecration.java
@@ -91,7 +91,7 @@ class WalkingDesecrationEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (player != null) {
- Choice typeChoice = new ChoiceCreatureType();
+ Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(outcome, typeChoice, game)) {
if (!player.canRespond()) {
return false;
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java
index 104cebecbf1..0a3daff161b 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java
@@ -30,6 +30,7 @@ package org.mage.test.cards.mana;
import mage.abilities.keyword.FlyingAbility;
import mage.constants.PhaseStep;
import mage.constants.Zone;
+import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@@ -75,9 +76,10 @@ public class ConditionalManaTest extends CardTestPlayerBase {
@Test
public void testWorkingWithReflectingPool() {
- addCard(Zone.BATTLEFIELD, playerA, "Cavern of Souls", 1);
- addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1); // can create white mana without restriction from the Cavern
- addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Cavern of Souls", 1); // can give {C] or {any} mana ({any} with restrictions)
+ addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1); // must give {C} or {any} mana from the Cavern, but without restrictions
+ addCard(Zone.HAND, playerA, "Silvercoat Lion", 1); // white bear
+ addCard(Zone.BATTLEFIELD, playerA, "Upwelling", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java
index f03c021f1ce..c8bcc3b548d 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java
@@ -33,10 +33,11 @@ import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
+import static org.mage.test.utils.ManaOptionsTestUtils.*;
/**
*
- * @author LevelX2
+ * @author LevelX2, JayDi85
*/
public class HarvesterDruidTest extends CardTestPlayerBase {
@@ -52,8 +53,10 @@ public class HarvesterDruidTest extends CardTestPlayerBase {
execute();
ManaOptions options = playerA.getAvailableManaTest(currentGame);
- Assert.assertEquals("Player should be able to create 2 red and 1 blue mana", "{U}{R}{R}", options.get(0).toString());
- Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{U}{U}{R}", options.get(1).toString());
+ assertDuplicatedManaOptions(options);
+ Assert.assertEquals(2, options.size());
+ assertManaOptions("{U}{R}{R}", options);
+ assertManaOptions("{U}{U}{R}", options);
}
@Test
@@ -68,9 +71,10 @@ public class HarvesterDruidTest extends CardTestPlayerBase {
execute();
ManaOptions options = playerA.getAvailableManaTest(currentGame);
- Assert.assertEquals("Player should be able to create 3 red and 1 blue mana", "{U}{R}{R}{R}", options.get(0).toString());
- Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{U}{U}{R}{R}", options.get(1).toString());
- Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{U}{U}{R}{R}", options.get(2).toString());
- Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{U}{U}{U}{R}", options.get(3).toString());
+ assertDuplicatedManaOptions(options);
+ Assert.assertEquals(3, options.size());
+ assertManaOptions("{U}{R}{R}{R}", options);
+ assertManaOptions("{U}{U}{R}{R}", options);
+ assertManaOptions("{U}{U}{U}{R}", options);
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/NagaVitalistTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/NagaVitalistTest.java
index 9709cb03597..f19d888195a 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/NagaVitalistTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/NagaVitalistTest.java
@@ -1,15 +1,21 @@
package org.mage.test.cards.mana;
+import mage.constants.Duration;
import mage.constants.ManaType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
+import mage.game.permanent.Permanent;
import org.junit.Assert;
+import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
+import org.mage.test.utils.ManaOptionsTestUtils;
+
+import static org.mage.test.utils.ManaOptionsTestUtils.manaOptionsContain;
/**
*
- * @author escplan9
+ * @author escplan9, JayDi85
*/
public class NagaVitalistTest extends CardTestPlayerBase {
@@ -21,21 +27,116 @@ public class NagaVitalistTest extends CardTestPlayerBase {
private final String nagaVitalist = "Naga Vitalist";
/*
- Reported bug (issue #3315)
- Naga Vitalist could not produce any color mana with a Gift of Paradise enchanted on a forest. All lands on board were forests.
- */
- @Test
- public void nagaVitalist_InteractionGiftOfParadise() {
-
- /*
Gift of Paradise 2G
Enchantment - Aura
Enchant - Land
When Gift of Paradise enters the battlefield, you gain 3 life.
Enchanted land has "T: Add two mana of any one color to your mana pool."
- */
- String giftParadise = "Gift of Paradise";
+ */
+ private final String giftParadise = "Gift of Paradise";
+ @Test
+ public void nagaVitalist_GiftOfParadiseCanAnyColor() {
+ addCard(Zone.BATTLEFIELD, playerA, "Upwelling");
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.HAND, playerA, giftParadise);
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
+
+ // manual mana cost, cause auto cost can get swamp to pay
+ activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}");
+ activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}");
+ activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}");
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, giftParadise, "Swamp");
+
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ Assert.assertTrue("playerA must cast {Any}{Any}", manaOptionsContain(playerA.getManaAvailable(currentGame), "{Any}{Any}"));
+ }
+
+ public void nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_Setup(int giftCastTurn, int nagaManaTapTurn, String nagaManaTapColor){
+ // test errors on enchanted ability do not apply for "any mana search" on different steps
+
+ addCard(Zone.BATTLEFIELD, playerA, "Upwelling");
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.HAND, playerA, giftParadise);
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
+ addCard(Zone.BATTLEFIELD, playerA, nagaVitalist, 1);
+
+
+ // cast and enchant swamp land to any color
+ activateManaAbility(giftCastTurn, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}");
+ activateManaAbility(giftCastTurn, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}");
+ activateManaAbility(giftCastTurn, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}");
+ castSpell(giftCastTurn, PhaseStep.PRECOMBAT_MAIN, playerA, giftParadise, "Swamp");
+
+ // activate red mana (by any from enchanted land)
+ activateManaAbility(nagaManaTapTurn, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add to your mana pool one mana of any");
+ setChoice(playerA, nagaManaTapColor);
+
+ setStopAt(nagaManaTapTurn, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+ }
+
+ @Test
+ @Ignore // TODO: need to fix - on naga mana tap swamp do not have added ability "add 2 any mana" (but it have after step complete)
+ public void nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_SameStep1() {
+ nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_Setup(1, 1, "Red");
+
+
+ //logger.info(playerA.getManaPool().getMana().toString());
+ //logger.info(playerA.getManaAvailable(currentGame).toString());
+ //for(Permanent perm: currentGame.getBattlefield().getAllActivePermanents(playerA.getId())){
+ // logger.info(perm.getIdName() + ": " + perm.getAbilities().toString());
+ //}
+
+ assertTapped("Forest", true);
+ assertTapped(giftParadise, false);
+ assertTapped("Swamp", false);
+ assertTapped(nagaVitalist, true);
+ Assert.assertEquals(1, playerA.getManaPool().get(ManaType.RED));
+ }
+
+ @Test
+ public void nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_DiffStep1() {
+ nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_Setup(1, 2, "Red");
+
+ assertTapped("Forest", true);
+ assertTapped(giftParadise, false);
+ assertTapped("Swamp", false);
+ assertTapped(nagaVitalist, true);
+ Assert.assertEquals(1, playerA.getManaPool().get(ManaType.RED));
+ }
+
+ @Test
+ @Ignore // TODO: need to fix - on naga mana tap swamp do not have added ability "add 2 any mana" (but it have after step complete)
+ public void nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_SameStep3() {
+ nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_Setup(3, 3, "Red");
+
+ assertTapped("Forest", true);
+ assertTapped(giftParadise, false);
+ assertTapped("Swamp", false);
+ assertTapped(nagaVitalist, true);
+ Assert.assertEquals(1, playerA.getManaPool().get(ManaType.RED));
+ }
+
+ @Test
+ public void nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_DiffStep2() {
+ nagaVitalist_GiftOfParadisesLandCanGiveAnyColorToNaga_Setup(3, 4, "Red");
+
+ assertTapped("Forest", true);
+ assertTapped(giftParadise, false);
+ assertTapped("Swamp", false);
+ assertTapped(nagaVitalist, true);
+ Assert.assertEquals(1, playerA.getManaPool().get(ManaType.RED));
+ }
+
+ /*
+ Reported bug (issue #3315)
+ Naga Vitalist could not produce any color mana with a Gift of Paradise enchanted on a forest. All lands on board were forests.
+ */
+ @Test
+ public void nagaVitalist_InteractionGiftOfParadise() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Zone.BATTLEFIELD, playerA, nagaVitalist);
addCard(Zone.BATTLEFIELD, playerA, "Upwelling"); // mana pools do not empty at the end of phases or turns
@@ -43,7 +144,7 @@ public class NagaVitalistTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, giftParadise, "Forest");
- activateManaAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add to your mana pool one mana of any type that a land you control could produce");
+ activateManaAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add to your mana pool one mana of any");
setChoice(playerA, "Red");
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
@@ -51,6 +152,8 @@ public class NagaVitalistTest extends CardTestPlayerBase {
assertLife(playerA, 23); // gift of paradise ETB
assertTapped(nagaVitalist, true);
+ assertTapped(giftParadise, false);
+ assertTapped("Forest", false);
Assert.assertEquals("one red mana has to be in the mana pool", 1, playerA.getManaPool().get(ManaType.RED));
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java
index 8479228d8b7..9fb11214c70 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java
@@ -28,15 +28,18 @@
package org.mage.test.cards.mana;
import mage.abilities.mana.ManaOptions;
+import mage.constants.ManaType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
+import static org.mage.test.utils.ManaOptionsTestUtils.*;
+
/**
*
- * @author LevelX2
+ * @author LevelX2, JayDi85
*/
public class ReflectingPoolTest extends CardTestPlayerBase {
@@ -173,16 +176,122 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
execute();
ManaOptions options = playerA.getAvailableManaTest(currentGame);
- Assert.assertEquals("Player A should be able to create the ", "{G}{G}{G}", options.get(0).toString());
- Assert.assertEquals("Player A should be able to create the ", "{W}{G}{G}", options.get(1).toString());
- Assert.assertEquals("Player A should be able to create the ", "{W}{G}{G}", options.get(2).toString()); // ManaOption type optimzing seems not optimal yet
- Assert.assertEquals("Player A should be able to create the ", "{W}{W}{G}", options.get(3).toString());
- Assert.assertEquals("Player A should be able to create only 3 different mana options", 4, options.size());
+ Assert.assertEquals("Player A should be able to create only 3 different mana options", 3, options.size());
+ assertManaOptions("{G}{G}{G}", options);
+ assertManaOptions("{W}{G}{G}", options);
+ assertManaOptions("{W}{W}{G}", options);
options = playerB.getAvailableManaTest(currentGame);
- Assert.assertEquals("Player B should be able to create the ", "{W}{G}", options.get(0).toString());
- Assert.assertEquals("Player B should be able to create the ", "{W}{W}", options.get(1).toString());
- Assert.assertEquals("Player B should be able to create only 3 different mana options", 2, options.size());
+ Assert.assertEquals("Player B should be able to create only 2 different mana options", 2, options.size());
+ assertManaOptions("{W}{G}", options);
+ assertManaOptions("{W}{W}", options);
+ }
+
+ @Test
+ public void testReflectingPoolGiveNonMana() {
+ addCard(Zone.HAND, playerA, bear1, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear1); // do not have any mana
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ Assert.assertEquals(0, playerA.getManaPool().getMana().count());
+ assertPermanentCount(playerA, bear1, 0);
+ }
+
+ @Test
+ public void testReflectingPoolGiveNonMana2() {
+ addCard(Zone.HAND, playerA, bear1, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear1); // do not have any mana
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ Assert.assertEquals(0, playerA.getManaPool().getMana().count());
+ assertPermanentCount(playerA, bear1, 0);
+ }
+
+ @Test
+ public void testReflectingPoolGiveBasicManaNeed() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
+ addCard(Zone.HAND, playerA, bear1G, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear1G); // have {G} mana to cast
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, bear1G, 1);
+ }
+
+ @Test
+ public void testReflectingPoolGiveBasicManaNotNeed() {
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
+ addCard(Zone.HAND, playerA, bear1G, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear1G); // have only {W} mana, can't cast
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, bear1G, 0);
+ }
+
+ @Test
+ public void testReflectingPoolAnyManaNeedWithoutCondition() {
+ // any mana source without conditions (use any mana at any time)
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+ addCard(Zone.BATTLEFIELD, playerA, "City of Brass", 1);
+ String bear2GG = "Razorclaw Bear";
+ addCard(Zone.HAND, playerA, bear2GG, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Upwelling", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear2GG); // 2 plains + 2 any -- can cast
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, bear2GG, 1);
+ }
+
+ @Test
+ public void testReflectingPoolAnyManaNeedWithCondition() {
+ // any mana source have condition to use (Reflecting Pool must ignore that condition)
+ addCard(Zone.BATTLEFIELD, playerA, "Cavern of Souls", 1); // {C} or {any}
+ addCard(Zone.HAND, playerA, bear1G, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Upwelling", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear1G); // {C} from cavern and {any} (green) from reflection
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, bear1G, 1);
+ }
+
+ @Test
+ public void testReflectingPoolAnyManaTapped() {
+ // any mana source with tapped must allow use any too
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "City of Brass", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Upwelling", 1);
+
+ activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add one mana of any");
+ activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {W}");
+ setChoice(playerA,"Black");
+
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ logger.info(playerA.getManaPool().getMana().toString());
+ logger.info(playerA.getManaAvailable(currentGame).toString());
+ assertTapped("City of Brass", true);
+ assertTapped("Plains", true);
+ assertTapped("Reflecting Pool", false);
+ Assert.assertEquals(1, playerA.getManaPool().get(ManaType.BLACK));
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/VorinclexVoiceOfHungerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/VorinclexVoiceOfHungerTest.java
index 8b78d5dccd7..f2c034fbc5c 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/VorinclexVoiceOfHungerTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/VorinclexVoiceOfHungerTest.java
@@ -27,9 +27,11 @@
*/
package org.mage.test.cards.mana;
+import mage.constants.ManaType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
+import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@@ -60,7 +62,28 @@ public class VorinclexVoiceOfHungerTest extends CardTestPlayerBase {
execute();
assertPermanentCount(playerA, "Vedalken Mastermind", 1);
+ }
+ /**
+ * Vorinclex, Voice of Hunger is not mana doubling River of Tears.
+ */
+ @Test
+ @Ignore // TODO: need to fix Vorinclex, Voice of Hunger -- it's double fireup mana tap event
+ public void testVorinclexVoiceofHungerRiverOfTearsManaMultiplier() {
+ addCard(Zone.BATTLEFIELD, playerA, "Upwelling", 1);
+ // Trample
+ // Whenever you tap a land for mana, add one mana to your mana pool of any type that land produced.
+ // Whenever an opponent taps a land for mana, that land doesn't untap during its controller's next untap step.
+ addCard(Zone.BATTLEFIELD, playerA, "Vorinclex, Voice of Hunger", 1);
+ // {T}: Add {U} to your mana pool. If you played a land this turn, add {B} to your mana pool instead.
+ addCard(Zone.BATTLEFIELD, playerA, "River of Tears", 1);
+
+ activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {U} to your mana pool");
+
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertManaPool(playerA, ManaType.BLUE, 2);
}
/**
diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
index fcf5b769b0e..537d8b18422 100644
--- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
+++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
@@ -837,22 +837,22 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
ManaPool manaPool = currentGame.getPlayer(player.getId()).getManaPool();
switch (color){
case COLORLESS:
- Assert.assertEquals(manaPool.getColorless() + manaPool.getConditionalMana().stream().mapToInt(Mana::getColorless).sum(), amount);
+ Assert.assertEquals(amount,manaPool.getColorless() + manaPool.getConditionalMana().stream().mapToInt(Mana::getColorless).sum());
break;
case RED:
- Assert.assertEquals(manaPool.getRed() + manaPool.getConditionalMana().stream().mapToInt(Mana::getRed).sum(), amount);
+ Assert.assertEquals(amount,manaPool.getRed() + manaPool.getConditionalMana().stream().mapToInt(Mana::getRed).sum());
break;
case BLUE:
- Assert.assertEquals(manaPool.getBlue() + manaPool.getConditionalMana().stream().mapToInt(Mana::getBlue).sum(), amount);
+ Assert.assertEquals(amount,manaPool.getBlue() + manaPool.getConditionalMana().stream().mapToInt(Mana::getBlue).sum());
break;
case WHITE:
- Assert.assertEquals(manaPool.getWhite() + manaPool.getConditionalMana().stream().mapToInt(Mana::getWhite).sum(), amount);
+ Assert.assertEquals(amount,manaPool.getWhite() + manaPool.getConditionalMana().stream().mapToInt(Mana::getWhite).sum());
break;
case GREEN:
- Assert.assertEquals(manaPool.getGreen() + manaPool.getConditionalMana().stream().mapToInt(Mana::getGreen).sum(), amount);
+ Assert.assertEquals(amount,manaPool.getGreen() + manaPool.getConditionalMana().stream().mapToInt(Mana::getGreen).sum());
break;
case BLACK:
- Assert.assertEquals(manaPool.getBlack() + manaPool.getConditionalMana().stream().mapToInt(Mana::getBlack).sum(), amount);
+ Assert.assertEquals(amount,manaPool.getBlack() + manaPool.getConditionalMana().stream().mapToInt(Mana::getBlack).sum());
break;
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java
index 91ea81bf863..7bb3f892bed 100644
--- a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java
@@ -35,12 +35,13 @@ import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
+import static org.mage.test.utils.ManaOptionsTestUtils.*;
/**
* This test checks if the calculated possible mana options are correct related
* to the given mana sources available.
*
- * @author LevelX2
+ * @author LevelX2, JayDi85
*/
public class ManaOptionsTest extends CardTestPlayerBase {
@@ -52,9 +53,10 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{G}{G}{G}", getManaOption(0, manaOptions));
+ assertManaOptions("{G}{G}{G}", manaOptions);
}
@@ -69,12 +71,13 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
- Assert.assertEquals("{G}{G}{G}", getManaOption(0, manaOptions));
- Assert.assertEquals("{W}{R}{G}{G}", getManaOption(1, manaOptions));
- Assert.assertEquals("{W}{W}{R}{R}{G}", getManaOption(2, manaOptions));
- Assert.assertEquals("{W}{W}{W}{R}{R}{R}", getManaOption(3, manaOptions));
+ assertManaOptions("{G}{G}{G}", manaOptions);
+ assertManaOptions("{W}{R}{G}{G}", manaOptions);
+ assertManaOptions("{W}{W}{R}{R}{G}", manaOptions);
+ assertManaOptions("{W}{W}{W}{R}{R}{R}", manaOptions);
}
@@ -89,18 +92,19 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 10, manaOptions.size());
- Assert.assertEquals("{C}{C}{C}", getManaOption(0, manaOptions));
- Assert.assertEquals("{C}{C}{W}", getManaOption(1, manaOptions));
- Assert.assertEquals("{C}{C}{U}", getManaOption(2, manaOptions));
- Assert.assertEquals("{C}{W}{W}", getManaOption(3, manaOptions));
- Assert.assertEquals("{C}{W}{U}", getManaOption(4, manaOptions));
- Assert.assertEquals("{C}{U}{U}", getManaOption(5, manaOptions));
- Assert.assertEquals("{W}{W}{W}", getManaOption(6, manaOptions));
- Assert.assertEquals("{W}{W}{U}", getManaOption(7, manaOptions));
- Assert.assertEquals("{W}{U}{U}", getManaOption(8, manaOptions));
- Assert.assertEquals("{U}{U}{U}", getManaOption(9, manaOptions));
+ assertManaOptions("{C}{C}{C}", manaOptions);
+ assertManaOptions("{C}{C}{W}", manaOptions);
+ assertManaOptions("{C}{C}{U}", manaOptions);
+ assertManaOptions("{C}{W}{W}", manaOptions);
+ assertManaOptions("{C}{W}{U}", manaOptions);
+ assertManaOptions("{C}{U}{U}", manaOptions);
+ assertManaOptions("{W}{W}{W}", manaOptions);
+ assertManaOptions("{W}{W}{U}", manaOptions);
+ assertManaOptions("{W}{U}{U}", manaOptions);
+ assertManaOptions("{U}{U}{U}", manaOptions);
}
// Chromatic Sphere
@@ -114,9 +118,10 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{Any}{Any}", getManaOption(0, manaOptions));
+ assertManaOptions("{Any}{Any}", manaOptions);
}
// Orochi Leafcaller
@@ -131,9 +136,10 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{W}{W}{Any}{Any}", getManaOption(0, manaOptions));
+ assertManaOptions("{W}{W}{Any}{Any}", manaOptions);
}
// Crystal Quarry
@@ -149,9 +155,10 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{C}{W}{W}{G}{G}", getManaOption(0, manaOptions));
+ assertManaOptions("{C}{W}{W}{G}{G}", manaOptions);
}
// Crystal Quarry
@@ -167,10 +174,11 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
- Assert.assertEquals("{C}{W}{W}{G}{G}{G}", getManaOption(0, manaOptions));
- Assert.assertEquals("{W}{U}{B}{R}{G}", getManaOption(1, manaOptions));
+ assertManaOptions("{C}{W}{W}{G}{G}{G}", manaOptions);
+ assertManaOptions("{W}{U}{B}{R}{G}", manaOptions);
}
// Nykthos, Shrine to Nyx
@@ -186,28 +194,30 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
- Assert.assertEquals("{C}{G}{G}{G}", getManaOption(0, manaOptions));
- Assert.assertEquals("{G}{G}{G}{G}{G}", getManaOption(1, manaOptions));
+ assertManaOptions("{C}{G}{G}{G}", manaOptions);
+ assertManaOptions("{G}{G}{G}{G}{G}", manaOptions);
}
@Test
public void testNykthos2() {
addCard(Zone.BATTLEFIELD, playerA, "Sedge Scorpion", 4);
addCard(Zone.BATTLEFIELD, playerA, "Akroan Crusader", 3);
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
- addCard(Zone.BATTLEFIELD, playerA, "Nykthos, Shrine to Nyx", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); // {G}
+ addCard(Zone.BATTLEFIELD, playerA, "Nykthos, Shrine to Nyx", 1); // {C}
setStopAt(1, PhaseStep.UPKEEP);
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
- Assert.assertEquals("{C}{G}{G}{G}", getManaOption(0, manaOptions));
- Assert.assertEquals("{G}{G}{G}{G}{G}", getManaOption(1, manaOptions));
- Assert.assertEquals("{R}{R}{R}{G}", getManaOption(2, manaOptions));
+ assertManaOptions("{C}{G}{G}{G}", manaOptions);
+ assertManaOptions("{G}{G}{G}{G}{G}", manaOptions);
+ assertManaOptions("{R}{R}{R}{G}", manaOptions);
}
@Test
@@ -220,13 +230,46 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{C}{G}{Any}", getManaOption(0, manaOptions));
+ assertManaOptions("{C}{G}{Any}", manaOptions);
}
@Test
- public void testMix1() {
+ public void testDuplicatedDontHave1() {
+ addCard(Zone.BATTLEFIELD, playerA, "City of Brass", 2); // Any
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+
+ setStopAt(1, PhaseStep.UPKEEP);
+ execute();
+
+ ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
+ }
+
+ @Test
+ public void testDuplicatedDontHave3() {
+ addCard(Zone.BATTLEFIELD, playerA, "Grove of the Burnwillows", 2); // R or G
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+
+ setStopAt(1, PhaseStep.UPKEEP);
+ execute();
+
+ ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
+ }
+
+ @Test
+ public void testDuplicatedHave() {
+ // getManaAvailable return any combination of mana variants evailable to player
+ // if mana ability cost another mana then if replaced in mana cost
+ // example:
+ // 1x forest
+ // 1x Chromatic Star ({1}, {T}, Sacrifice Chromatic Star: Add one mana of any color to your mana pool.)
+ // give {G}{Any}, but after pay it transform to {Any} (1 green will be pay)
+ // That's why there are can be duplicated records in getManaAvailable
+
// {1}, {T}, Sacrifice Chromatic Star: Add one mana of any color to your mana pool.
// When Chromatic Star is put into a graveyard from the battlefield, draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Chromatic Star", 1);
@@ -242,10 +285,9 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
-
- Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
- Assert.assertEquals("{Any}{Any}", getManaOption(0, manaOptions));
- Assert.assertEquals("{Any}{Any}", getManaOption(1, manaOptions));
+ Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
+ assertDuplicatedManaOptions(manaOptions);
+ assertManaOptions("{Any}{Any}", manaOptions);
}
@Test
@@ -257,12 +299,13 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
- Assert.assertEquals("{C}{W}", getManaOption(0, manaOptions));
- Assert.assertEquals("{W}{W}", getManaOption(1, manaOptions));
- Assert.assertEquals("{W}{B}", getManaOption(2, manaOptions));
- Assert.assertEquals("{B}{B}", getManaOption(3, manaOptions));
+ assertManaOptions("{C}{W}", manaOptions);
+ assertManaOptions("{W}{W}", manaOptions);
+ assertManaOptions("{W}{B}", manaOptions);
+ assertManaOptions("{B}{B}", manaOptions);
}
/**
@@ -278,9 +321,10 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{W}{B}", getManaOption(0, manaOptions));
+ assertManaOptions("{W}{B}", manaOptions);
}
@Test
@@ -293,10 +337,11 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
- Assert.assertEquals("{W}{B}{B}", getManaOption(0, manaOptions));
- Assert.assertEquals("{B}{B}{B}", getManaOption(1, manaOptions));
+ assertManaOptions("{W}{B}{B}", manaOptions);
+ assertManaOptions("{B}{B}{B}", manaOptions);
}
@Test
@@ -312,9 +357,10 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{C}{W}{B}", getManaOption(0, manaOptions));
+ assertManaOptions("{C}{W}{B}", manaOptions);
}
@Test
@@ -331,9 +377,10 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{C}{C}{C}{C}{W}{B}", getManaOption(0, manaOptions));
+ assertManaOptions("{C}{C}{C}{C}{W}{B}", manaOptions);
}
@Test
@@ -349,17 +396,9 @@ public class ManaOptionsTest extends CardTestPlayerBase {
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ assertDuplicatedManaOptions(manaOptions);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- Assert.assertEquals("{B}{B}", getManaOption(0, manaOptions));
- }
-
- // TODO
- // Test Calciform Pools combination mana lands
- private String getManaOption(int index, ManaOptions manaOptions) {
- if (manaOptions.size() < index + 1) {
- return "";
- }
- return manaOptions.get(index).toString();
+ assertManaOptions("{B}{B}", manaOptions);
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTestUtils.java b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTestUtils.java
new file mode 100644
index 00000000000..04d0e8cceac
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTestUtils.java
@@ -0,0 +1,48 @@
+package org.mage.test.utils;
+
+import mage.Mana;
+import mage.abilities.mana.ManaOptions;
+import org.junit.Assert;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class ManaOptionsTestUtils {
+
+ public static String bear1W = "Silvercoat Lion"; // {1}{W}
+ public static String bearG = "Basking Rootwalla"; // {G}
+ public static String bear1 = "Augmenting Automaton"; // {1}
+ public static String bear1G = "Balduvian Bears"; // {1}{G}
+ public static String bear2C = "Matter Reshaper"; // {2}{C}
+
+ //mana info
+ //logger.info(playerA.getManaPool().getMana().toString());
+ //logger.info(playerA.getManaAvailable(currentGame).toString());
+
+ public static boolean manaOptionsContain(ManaOptions list, String searchMana){
+ for(Mana mana: list){
+ if (mana.toString().equals(searchMana)){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void assertManaOptions(String searchMana, ManaOptions manaList){
+ if(!manaOptionsContain(manaList, searchMana)){
+ Assert.fail("Can't find " + searchMana + " in " + manaList.toString());
+ }
+ }
+
+ public static void assertDuplicatedManaOptions(ManaOptions manaList){
+ Set list = new HashSet<>();
+ for(Mana mana: manaList){
+ String s = mana.toString();
+ if(list.contains(s)){
+ Assert.fail("Founded duplicated mana option " + s + " in " + manaList.toString());
+ }else{
+ list.add(s);
+ }
+ }
+ }
+}
diff --git a/Mage/src/main/java/mage/Mana.java b/Mage/src/main/java/mage/Mana.java
index 5e4ea50e9a0..b2461d2b367 100644
--- a/Mage/src/main/java/mage/Mana.java
+++ b/Mage/src/main/java/mage/Mana.java
@@ -221,6 +221,19 @@ public class Mana implements Comparable, Serializable, Copyable {
return new Mana(0, 0, 0, 0, 0, 0, 0, notNegative(num, "Colorless"));
}
+ /**
+ * Creates a {@link Mana} object with the passed in {@code num} of Any
+ * mana. {@code num} can not be a negative value. Negative values will be
+ * logged and set to 0.
+ *
+ * @param num value of Any mana to create.
+ * @return a {@link Mana} object with the passed in {@code num} of Any
+ * mana.
+ */
+ public static Mana AnyMana(int num) {
+ return new Mana(0, 0, 0, 0, 0, 0, notNegative(num, "Any"), 0);
+ }
+
/**
* Adds mana from the passed in {@link Mana} object to this object.
*
diff --git a/Mage/src/main/java/mage/abilities/effects/common/AddManaOfAnyColorEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AddManaOfAnyColorEffect.java
index bd9b5aacee5..52e3a0fb3bf 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/AddManaOfAnyColorEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/AddManaOfAnyColorEffect.java
@@ -69,11 +69,13 @@ public class AddManaOfAnyColorEffect extends BasicManaEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- ChoiceColor choice = new ChoiceColor(true);
+ String mes = String.format("Select color of %d mana to add it to your mana pool", this.amount);
+ ChoiceColor choice = new ChoiceColor(true, mes, game.getObject(source.getSourceId()));
if (controller.choose(outcome, choice, game)) {
if (choice.getColor() == null) {
- return false; // it happens, don't know how
+ // on user's reconnect choice dialog close and return null even with required settings
+ return false;
}
Mana createdMana = choice.getMana(amount);
if (createdMana != null) {
diff --git a/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java
index 3a9b80b9941..f707e908249 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java
@@ -33,6 +33,7 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.choices.Choice;
+import mage.choices.ChoiceCreatureType;
import mage.choices.ChoiceImpl;
import mage.constants.Outcome;
import mage.constants.SubType;
@@ -63,9 +64,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect {
mageObject = game.getObject(source.getSourceId());
}
if (controller != null && mageObject != null) {
- Choice typeChoice = new ChoiceImpl(true);
- typeChoice.setMessage("Choose creature type");
- typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
+ Choice typeChoice = new ChoiceCreatureType(mageObject);
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
diff --git a/Mage/src/main/java/mage/abilities/mana/AnyColorLandsProduceManaAbility.java b/Mage/src/main/java/mage/abilities/mana/AnyColorLandsProduceManaAbility.java
index 3a6b662e4cc..2447bd0c501 100644
--- a/Mage/src/main/java/mage/abilities/mana/AnyColorLandsProduceManaAbility.java
+++ b/Mage/src/main/java/mage/abilities/mana/AnyColorLandsProduceManaAbility.java
@@ -225,6 +225,9 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
if (types.getColorless() > 0) {
netManas.add(Mana.ColorlessMana(1));
}
+ if (types.getAny() > 0) {
+ netManas.add(Mana.AnyMana(1));
+ }
return netManas;
}
diff --git a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java
index f5402422dc5..dd90f3a57d0 100644
--- a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java
+++ b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java
@@ -28,7 +28,10 @@
package mage.abilities.mana;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+
import mage.Mana;
import mage.game.Game;
@@ -326,4 +329,19 @@ public class ManaOptions extends ArrayList {
payCombinations.add(newMana);
payCombinationsStrings.add(newMana.toString());
}
+
+
+ public void removeDuplicated(){
+ Set list = new HashSet<>();
+
+ for(int i = this.size() - 1; i >= 0; i--){
+ String s = this.get(i).toString();
+ if (list.contains(s)){
+ // remove duplicated
+ this.remove(i);
+ }else{
+ list.add(s);
+ }
+ }
+ }
}
diff --git a/Mage/src/main/java/mage/choices/Choice.java b/Mage/src/main/java/mage/choices/Choice.java
index 9a20c066bb4..3bfcffa2a83 100644
--- a/Mage/src/main/java/mage/choices/Choice.java
+++ b/Mage/src/main/java/mage/choices/Choice.java
@@ -37,19 +37,34 @@ import java.util.Set;
*/
public interface Choice {
- boolean isChosen();
- boolean isRequired();
- void clearChoice();
String getMessage();
void setMessage(String message);
- void setChoice(String choice);
- void setChoiceByKey(String choiceKey);
- Set getChoices();
- Map getKeyChoices();
- void setChoices(Set choices);
- void setKeyChoices(Map choices);
- String getChoice();
- String getChoiceKey();
- boolean isKeyChoice();
+
+ String getSubMessage();
+ void setSubMessage(String subMessage);
+
+ void clearChoice();
+ boolean isChosen();
+ boolean isRequired();
+
Choice copy();
+
+ // string choice
+ void setChoices(Set choices);
+ Set getChoices();
+ void setChoice(String choice);
+ String getChoice();
+
+ // key-value choice
+ boolean isKeyChoice();
+ void setKeyChoices(Map choices);
+ Map getKeyChoices();
+ void setChoiceByKey(String choiceKey);
+ String getChoiceKey();
+
+ // search
+ boolean isSearchEnabled();
+ void setSearchEnabled(boolean isEnabled);
+ void setSearchText(String searchText);
+ String getSearchText();
}
diff --git a/Mage/src/main/java/mage/choices/ChoiceColor.java b/Mage/src/main/java/mage/choices/ChoiceColor.java
index 55531613e8d..6f7255a729a 100644
--- a/Mage/src/main/java/mage/choices/ChoiceColor.java
+++ b/Mage/src/main/java/mage/choices/ChoiceColor.java
@@ -27,17 +27,22 @@
*/
package mage.choices;
-import java.util.ArrayList;
+import mage.MageObject;
import mage.Mana;
import mage.ObjectColor;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class ChoiceColor extends ChoiceImpl {
- public static final ArrayList colorChoices = new ArrayList<>();
+ //public static final Set colorChoices = new HashSet<>(); // JayDi85: uncomment 1 of 2 to broke unit tests find wrong tests (?)
+ public static final ArrayList colorChoices = new ArrayList<>();
static {
colorChoices.add("Green");
@@ -52,9 +57,25 @@ public class ChoiceColor extends ChoiceImpl {
}
public ChoiceColor(boolean required) {
+ this(required, "Choose color");
+ }
+
+ public ChoiceColor(boolean required, String chooseMessage){
+ this(required, chooseMessage, "");
+ }
+
+ public ChoiceColor(boolean required, String chooseMessage, MageObject source){
+ this(required, chooseMessage, source.getIdName());
+ }
+
+ public ChoiceColor(boolean required, String chooseMessage, String chooseSubMessage){
super(required);
+
this.choices.addAll(colorChoices);
- this.message = "Choose color";
+ //this.setChoices(colorChoices); // JayDi85: uncomment 2 of 2 to broke unit tests find wrong tests (?)
+
+ this.setMessage(chooseMessage);
+ this.setSubMessage(chooseSubMessage);
}
public ChoiceColor(final ChoiceColor choice) {
diff --git a/Mage/src/main/java/mage/choices/ChoiceCreatureType.java b/Mage/src/main/java/mage/choices/ChoiceCreatureType.java
index 558a6ecb5c4..7ffbab88294 100644
--- a/Mage/src/main/java/mage/choices/ChoiceCreatureType.java
+++ b/Mage/src/main/java/mage/choices/ChoiceCreatureType.java
@@ -1,5 +1,6 @@
package mage.choices;
+import mage.MageObject;
import mage.constants.SubType;
import java.util.LinkedHashSet;
@@ -7,10 +8,28 @@ import java.util.stream.Collectors;
public class ChoiceCreatureType extends ChoiceImpl {
+ private static String DEFAULT_MESSAGE = "Choose a creature type";
+
public ChoiceCreatureType() {
- super(true);
+ this(true, DEFAULT_MESSAGE, null);
+ }
+
+ public ChoiceCreatureType(MageObject source) {
+ this(true, DEFAULT_MESSAGE, source);
+ }
+
+ public ChoiceCreatureType(String chooseMessage, MageObject source) {
+ this(true, chooseMessage, source);
+ }
+
+ public ChoiceCreatureType(boolean required, String chooseMessage, MageObject source){
+ super(required);
this.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
- this.message = "Choose a creature type:";
+ this.setMessage(chooseMessage);
+ if(source != null) {
+ this.setSubMessage(source.getIdName());
+ }
+ this.setSearchEnabled(true);
}
public ChoiceCreatureType(final ChoiceCreatureType choice) {
diff --git a/Mage/src/main/java/mage/choices/ChoiceImpl.java b/Mage/src/main/java/mage/choices/ChoiceImpl.java
index bee47239a86..3656c70d2e5 100644
--- a/Mage/src/main/java/mage/choices/ChoiceImpl.java
+++ b/Mage/src/main/java/mage/choices/ChoiceImpl.java
@@ -40,6 +40,7 @@ import java.util.Set;
*/
public class ChoiceImpl implements Choice, Serializable {
+ // TODO: add sorting to items
protected boolean chosen;
protected final boolean required;
protected String choice;
@@ -47,6 +48,9 @@ public class ChoiceImpl implements Choice, Serializable {
protected Set choices = new LinkedHashSet<>();
protected Map keyChoices = new LinkedHashMap<>();
protected String message;
+ protected String subMessage;
+ protected boolean searchEnabled = true; // enable for all windows by default
+ protected String searchText;
public ChoiceImpl() {
this(false);
@@ -61,6 +65,7 @@ public class ChoiceImpl implements Choice, Serializable {
this.chosen = choice.chosen;
this.required = choice.required;
this.message = choice.message;
+ this.message = choice.subMessage;
this.choices.addAll(choice.choices);
this.choiceKey = choice.choiceKey;
this.keyChoices = choice.keyChoices; // list should never change for the same object so copy by reference
@@ -88,6 +93,12 @@ public class ChoiceImpl implements Choice, Serializable {
this.message = message;
}
+ @Override
+ public String getSubMessage(){ return subMessage; }
+
+ @Override
+ public void setSubMessage(String subMessage){ this.subMessage = subMessage; }
+
@Override
public Set getChoices() {
return choices;
@@ -150,4 +161,24 @@ public class ChoiceImpl implements Choice, Serializable {
return !keyChoices.isEmpty();
}
-}
+ @Override
+ public boolean isSearchEnabled(){
+ return this.searchEnabled;
+ };
+
+ @Override
+ public void setSearchEnabled(boolean isEnabled){
+ this.searchEnabled = isEnabled;
+ };
+
+ @Override
+ public void setSearchText(String searchText){
+ this.searchText = searchText;
+ };
+
+ @Override
+ public String getSearchText(){
+ return this.searchText;
+ };
+
+}
\ No newline at end of file
diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java
index 64c9fde58e0..6233a4ed6f2 100644
--- a/Mage/src/main/java/mage/players/PlayerImpl.java
+++ b/Mage/src/main/java/mage/players/PlayerImpl.java
@@ -2439,6 +2439,10 @@ public abstract class PlayerImpl implements Player, Serializable {
for (Abilities manaAbilities : sourceWithCosts) {
available.addManaWithCost(manaAbilities, game);
}
+
+ // remove duplicated variants (see ManaOptionsTest for info - when thats rises)
+ available.removeDuplicated();
+
return available;
}