* Added logic to auto select replacement effects. Some changes to counter size and font size handling.

This commit is contained in:
LevelX2 2014-10-30 20:40:23 +01:00
parent ab9c0ae893
commit df71237f46
28 changed files with 445 additions and 140 deletions

View file

@ -1,6 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo"> <Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties>
<Property name="resizable" type="boolean" value="true"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[280, 200]"/>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
<SyntheticProperties> <SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/> <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties> </SyntheticProperties>
@ -24,6 +31,9 @@
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="1" attributes="0">
<Component id="jScrollPane1" alignment="0" pref="335" max="32767" attributes="0"/> <Component id="jScrollPane1" alignment="0" pref="335" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="btnAutoSelect" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnOk" min="-2" max="-2" attributes="0"/> <Component id="btnOk" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="btnCancel" min="-2" max="-2" attributes="0"/> <Component id="btnCancel" min="-2" max="-2" attributes="0"/>
@ -37,21 +47,31 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Component id="lblMessage" min="-2" pref="37" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="lblMessage" min="-2" max="-2" attributes="0"/> <Component id="jScrollPane1" pref="158" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="165" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnOk" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnOk" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnAutoSelect" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JButton" name="btnAutoSelect">
<Properties>
<Property name="text" type="java.lang.String" value="Auto select"/>
<Property name="toolTipText" type="java.lang.String" value="If you select an effect with &quot;Auto select&quot;, this effect will be selected the next time automatically first."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnAutoSelectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnCancel"> <Component class="javax.swing.JButton" name="btnCancel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" value="Cancel"/> <Property name="text" type="java.lang.String" value="Cancel"/>

View file

@ -34,13 +34,15 @@
package mage.client.dialog; package mage.client.dialog;
import java.awt.Point;
import java.util.Map;
import java.util.UUID;
import javax.swing.JLayeredPane;
import mage.choices.Choice;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.util.SettingsManager; import mage.client.util.SettingsManager;
import mage.client.util.gui.GuiDisplayUtil; import mage.client.util.gui.GuiDisplayUtil;
import javax.swing.*;
import java.awt.*;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -52,10 +54,28 @@ public class PickChoiceDialog extends MageDialog {
initComponents(); initComponents();
this.setModal(true); this.setModal(true);
} }
Choice choice;
boolean autoSelect;
public void showDialog(Choice choice, UUID objectId) {
this.lblMessage.setText("<html>" + 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<String, String> entry : choice.getKeyChoices().entrySet()) {
comboItems[count] = new ComboItem(entry.getKey(), entry.getValue());
count++;
}
this.lstChoices.setListData(comboItems);
} else {
this.lstChoices.setListData(choice.getChoices().toArray());
}
public void showDialog(String message, String[] choices) {
this.lblMessage.setText(message);
this.lstChoices.setListData(choices);
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER); MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
Point centered = SettingsManager.getInstance().getComponentPosition(getWidth(), getHeight()); Point centered = SettingsManager.getInstance().getComponentPosition(getWidth(), getHeight());
@ -65,8 +85,21 @@ public class PickChoiceDialog extends MageDialog {
this.setVisible(true); this.setVisible(true);
} }
public String getChoice() { public boolean isAutoSelect() {
return (String)this.lstChoices.getSelectedValue(); return autoSelect;
}
public void setChoice() {
if (this.lstChoices.getSelectedValue() == null) {
choice.clearChoice();
}
if (choice.isKeyChoice()) {
ComboItem item = (ComboItem)this.lstChoices.getSelectedValue();
choice.setChoiceByKey(item.getValue());
} else {
choice.setChoice((String)this.lstChoices.getSelectedValue());
}
} }
/** This method is called from within the constructor to /** This method is called from within the constructor to
@ -78,12 +111,25 @@ public class PickChoiceDialog extends MageDialog {
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
btnAutoSelect = new javax.swing.JButton();
btnCancel = new javax.swing.JButton(); btnCancel = new javax.swing.JButton();
btnOk = new javax.swing.JButton(); btnOk = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane(); jScrollPane1 = new javax.swing.JScrollPane();
lstChoices = new javax.swing.JList(); lstChoices = new javax.swing.JList();
lblMessage = new javax.swing.JLabel(); lblMessage = new javax.swing.JLabel();
setResizable(true);
setMinimumSize(new java.awt.Dimension(280, 200));
setName(""); // NOI18N
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(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnAutoSelectActionPerformed(evt);
}
});
btnCancel.setText("Cancel"); btnCancel.setText("Cancel");
btnCancel.addActionListener(new java.awt.event.ActionListener() { btnCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -117,6 +163,9 @@ public class PickChoiceDialog extends MageDialog {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(btnAutoSelect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnOk) .addComponent(btnOk)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCancel)) .addComponent(btnCancel))
@ -126,30 +175,40 @@ public class PickChoiceDialog extends MageDialog {
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap() .addGap(6, 6, 6)
.addComponent(lblMessage) .addComponent(lblMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 165, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnCancel) .addComponent(btnCancel)
.addComponent(btnOk)) .addComponent(btnOk)
.addContainerGap()) .addComponent(btnAutoSelect))
.addGap(10, 10, 10))
); );
pack(); pack();
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed
setChoice();
this.hideDialog(); this.hideDialog();
}//GEN-LAST:event_btnOkActionPerformed }//GEN-LAST:event_btnOkActionPerformed
private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
this.lstChoices.clearSelection(); this.lstChoices.clearSelection();
this.choice.clearChoice();
this.hideDialog(); this.hideDialog();
}//GEN-LAST:event_btnCancelActionPerformed }//GEN-LAST:event_btnCancelActionPerformed
private void btnAutoSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAutoSelectActionPerformed
this.autoSelect = true;
setChoice();
this.hideDialog();
}//GEN-LAST:event_btnAutoSelectActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnAutoSelect;
private javax.swing.JButton btnCancel; private javax.swing.JButton btnCancel;
private javax.swing.JButton btnOk; private javax.swing.JButton btnOk;
private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane1;
@ -158,3 +217,26 @@ public class PickChoiceDialog extends MageDialog {
// End of variables declaration//GEN-END:variables // 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;
}
}

View file

@ -27,8 +27,53 @@
*/ */
package mage.client.game; package mage.client.game;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import javax.swing.AbstractAction;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
import mage.choices.Choice;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.cards.BigCard; import mage.client.cards.BigCard;
import mage.client.chat.ChatPanel; import mage.client.chat.ChatPanel;
@ -37,7 +82,12 @@ import mage.client.components.HoverButton;
import mage.client.components.MageComponents; import mage.client.components.MageComponents;
import mage.client.components.ext.dlg.DialogManager; import mage.client.components.ext.dlg.DialogManager;
import mage.client.components.layout.RelativeLayout; import mage.client.components.layout.RelativeLayout;
import mage.client.dialog.*; import mage.client.dialog.ExileZoneDialog;
import mage.client.dialog.PickChoiceDialog;
import mage.client.dialog.PickNumberDialog;
import mage.client.dialog.PickPileDialog;
import mage.client.dialog.PreferencesDialog;
import mage.client.dialog.ShowCardsDialog;
import mage.client.game.FeedbackPanel.FeedbackMode; import mage.client.game.FeedbackPanel.FeedbackMode;
import mage.client.plugins.adapters.MageActionCallback; import mage.client.plugins.adapters.MageActionCallback;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
@ -48,25 +98,31 @@ import mage.client.util.gui.ArrowBuilder;
import mage.constants.Constants; import mage.constants.Constants;
import mage.constants.EnlargeMode; import mage.constants.EnlargeMode;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import static mage.constants.PhaseStep.BEGIN_COMBAT;
import static mage.constants.PhaseStep.COMBAT_DAMAGE;
import static mage.constants.PhaseStep.DECLARE_ATTACKERS;
import static mage.constants.PhaseStep.DECLARE_BLOCKERS;
import static mage.constants.PhaseStep.DRAW;
import static mage.constants.PhaseStep.END_COMBAT;
import static mage.constants.PhaseStep.END_TURN;
import static mage.constants.PhaseStep.FIRST_COMBAT_DAMAGE;
import static mage.constants.PhaseStep.UNTAP;
import static mage.constants.PhaseStep.UPKEEP;
import mage.constants.PlayerAction;
import mage.remote.Session; import mage.remote.Session;
import mage.view.*; import mage.view.AbilityPickerView;
import mage.view.CardView;
import mage.view.CardsView;
import mage.view.ExileView;
import mage.view.GameView;
import mage.view.LookedAtView;
import mage.view.MatchView;
import mage.view.PlayerView;
import mage.view.RevealedView;
import mage.view.SimpleCardsView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.plugins.card.utils.impl.ImageManagerImpl; import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import java.util.*;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import javax.swing.border.EmptyBorder;
import mage.constants.PlayerAction;
/** /**
* *
@ -797,11 +853,19 @@ public final class GamePanel extends javax.swing.JPanel {
} }
} }
public void getChoice(String message, String[] choices) { public void getChoice(Choice choice, UUID objectId) {
hideAll(); hideAll();
PickChoiceDialog pickChoice = new PickChoiceDialog(); PickChoiceDialog pickChoice = new PickChoiceDialog();
pickChoice.showDialog(message, choices); pickChoice.showDialog(choice, objectId);
session.sendPlayerString(gameId, pickChoice.getChoice()); if (choice.isKeyChoice()) {
if (pickChoice.isAutoSelect()) {
session.sendPlayerString(gameId, "#" + choice.getChoiceKey());
} else {
session.sendPlayerString(gameId, choice.getChoiceKey());
}
} else {
session.sendPlayerString(gameId, choice.getChoice());
}
pickChoice.removeDialog(); pickChoice.removeDialog();
} }
@ -1367,7 +1431,7 @@ public final class GamePanel extends javax.swing.JPanel {
.addComponent(phasesContainer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(phasesContainer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
) )
//.addPreferredGap(ComponentPlacement.RELATED) //.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_jPanel3.createParallelGroup(Alignment.LEADING) .addGroup(gl_jPanel3.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_jPanel3.createSequentialGroup() .addGroup(gl_jPanel3.createSequentialGroup()
.addComponent(pnlShortCuts, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(pnlShortCuts, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(0) .addGap(0)

View file

@ -216,6 +216,19 @@ public class PlayAreaPanel extends javax.swing.JPanel {
} }
}); });
menuItem = new JMenuItem("Replacement effects - reset auto select");
menuItem.setMnemonic(KeyEvent.VK_R);
menuItem.setToolTipText("Reset all effects that were added to the list of auto select replacement effects this game.");
popupMenu.add(menuItem);
// Reset the replacement effcts that were auto selected for the game
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.getSession().sendPlayerAction(PlayerAction.RESET_AUTO_SELECT_REPLACEMENT_EFFECTS, gameId);
}
});
popupMenu.addSeparator(); popupMenu.addSeparator();
menuItem = new JMenuItem("Concede game"); menuItem = new JMenuItem("Concede game");

View file

@ -32,6 +32,7 @@ import java.util.UUID;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.chat.ChatPanel; import mage.client.chat.ChatPanel;
import static mage.client.chat.ChatPanel.ChatType.TABLES; import static mage.client.chat.ChatPanel.ChatType.TABLES;
@ -72,7 +73,7 @@ public class CallbackClientImpl implements CallbackClient {
private static final Logger logger = Logger.getLogger(CallbackClientImpl.class); private static final Logger logger = Logger.getLogger(CallbackClientImpl.class);
private final MageFrame frame; private final MageFrame frame;
private int messageId = 0; private int messageId = 0;
// private int gameInformMessageId = 0; private int gameInformMessageId = 0;
public CallbackClientImpl(MageFrame frame) { public CallbackClientImpl(MageFrame frame) {
this.frame = frame; this.frame = frame;
@ -244,12 +245,13 @@ public class CallbackClientImpl implements CallbackClient {
panel.pickPile(message.getMessage(), message.getPile1(), message.getPile2()); panel.pickPile(message.getMessage(), message.getPile1(), message.getPile2());
} break; } break;
} }
case "gameChoose": case "gameChooseChoice":
{ {
GameClientMessage message = (GameClientMessage) callback.getData(); GameClientMessage message = (GameClientMessage) callback.getData();
GamePanel panel = MageFrame.getGame(callback.getObjectId()); GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) { if (panel != null) {
panel.getChoice(message.getMessage(), message.getStrings()); panel.getChoice(message.getChoice(), callback.getObjectId());
} break; } break;
} }
case "gamePlayMana": case "gamePlayMana":
@ -292,7 +294,7 @@ public class CallbackClientImpl implements CallbackClient {
JOptionPane.showMessageDialog(null, messageData.get(1), messageData.get(0), JOptionPane.WARNING_MESSAGE); JOptionPane.showMessageDialog(null, messageData.get(1), messageData.get(0), JOptionPane.WARNING_MESSAGE);
} break; } break;
case "gameInform": case "gameInform":
// if (callback.getMessageId() > gameInformMessageId) { if (callback.getMessageId() > gameInformMessageId) {
{ {
GameClientMessage message = (GameClientMessage) callback.getData(); GameClientMessage message = (GameClientMessage) callback.getData();
GamePanel panel = MageFrame.getGame(callback.getObjectId()); GamePanel panel = MageFrame.getGame(callback.getObjectId());
@ -301,11 +303,11 @@ public class CallbackClientImpl implements CallbackClient {
} }
} }
// no longer needed because phase skip handling on server side now // no longer needed because phase skip handling on server side now
// } else { } else {
// logger.warn(new StringBuilder("message out of sequence - ignoring").append("MessageId = ").append(callback.getMessageId()).append(" method = ").append(callback.getMethod())); logger.warn(new StringBuilder("message out of sequence - ignoring").append("MessageId = ").append(callback.getMessageId()).append(" method = ").append(callback.getMethod()));
// //logger.warn("message out of sequence - ignoring"); //logger.warn("message out of sequence - ignoring");
// } }
// gameInformMessageId = messageId; gameInformMessageId = messageId;
break; break;
case "gameInformPersonal": case "gameInformPersonal":
{ {

View file

@ -12,6 +12,8 @@ import java.awt.Rectangle;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener; import java.awt.event.MouseMotionListener;
@ -60,7 +62,7 @@ import org.mage.plugins.card.utils.impl.ImageManagerImpl;
* @author arcane, nantuko, noxx * @author arcane, nantuko, noxx
*/ */
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
public class CardPanel extends MagePermanent implements MouseListener, MouseMotionListener, MouseWheelListener { public class CardPanel extends MagePermanent implements MouseListener, MouseMotionListener, MouseWheelListener, ComponentListener {
private static final long serialVersionUID = -3272134219262184410L; private static final long serialVersionUID = -3272134219262184410L;
private static final Logger log = Logger.getLogger(CardPanel.class); private static final Logger log = Logger.getLogger(CardPanel.class);
@ -83,6 +85,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
private static final float ROT_CENTER_TO_BOTTOM_CORNER = 0.7071067811865475244008443621048f; private static final float ROT_CENTER_TO_BOTTOM_CORNER = 0.7071067811865475244008443621048f;
public CardView gameCard; public CardView gameCard;
public CardView updateCard;
// for two faced cards // for two faced cards
public CardView temporary; public CardView temporary;
@ -259,6 +262,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
addMouseListener(this); addMouseListener(this);
addMouseMotionListener(this); addMouseMotionListener(this);
addMouseWheelListener(this); addMouseWheelListener(this);
addComponentListener(this);
displayTitleAnyway = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_CARD_NAMES, "true").equals("true"); displayTitleAnyway = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_CARD_NAMES, "true").equals("true");
titleText = new GlowText(); titleText = new GlowText();
@ -532,7 +536,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
} }
@Override @Override
public void layout() { public void doLayout() {
int borderSize = Math.round(cardWidth * BLACK_BORDER_SIZE); int borderSize = Math.round(cardWidth * BLACK_BORDER_SIZE);
imagePanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); imagePanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize);
imagePanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); imagePanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2);
@ -764,6 +768,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override @Override
public void update(CardView card) { public void update(CardView card) {
this.updateCard = card;
if (isPermanent && (card instanceof PermanentView)) { if (isPermanent && (card instanceof PermanentView)) {
boolean needsTapping = isTapped() != ((PermanentView) card).isTapped(); boolean needsTapping = isTapped() != ((PermanentView) card).isTapped();
boolean needsFlipping = isFlipped() != ((PermanentView) card).isFlipped(); boolean needsFlipping = isFlipped() != ((PermanentView) card).isFlipped();
@ -886,7 +891,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
private static ImageIcon getCounterImageWithAmount(int amount, BufferedImage image, int cardWidth) { private static ImageIcon getCounterImageWithAmount(int amount, BufferedImage image, int cardWidth) {
int factor = cardWidth > WIDTH_LIMIT ? 2 :1; int factor = cardWidth > WIDTH_LIMIT ? 2 :1;
int xOffset = amount > 9 ? 2 : 5; int xOffset = amount > 9 ? 2 : 5;
int fontSize = amount < 10 ? 9 : amount < 100 ? 9 : 8; int fontSize = factor == 1 ? amount < 10 ? 12 : amount < 100 ? 10 : amount < 1000 ? 7: 6
:amount < 10 ? 19 : amount < 100 ? 15 : amount < 1000 ? 12: amount < 10000 ?9 : 8;
BufferedImage newImage; BufferedImage newImage;
if (cardWidth > WIDTH_LIMIT) { if (cardWidth > WIDTH_LIMIT) {
newImage = ImageManagerImpl.deepCopy(image); newImage = ImageManagerImpl.deepCopy(image);
@ -895,7 +901,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
} }
Graphics graphics = newImage.getGraphics(); Graphics graphics = newImage.getGraphics();
graphics.setColor(Color.BLACK); graphics.setColor(Color.BLACK);
graphics.setFont(new Font("Arial Black", Font.BOLD, factor * fontSize )); graphics.setFont(new Font("Arial Black", amount > 100 ? Font.PLAIN : Font.BOLD, fontSize ));
graphics.drawString(Integer.toString(amount), xOffset * factor, 11 * factor); graphics.drawString(Integer.toString(amount), xOffset * factor, 11 * factor);
return new ImageIcon(newImage); return new ImageIcon(newImage);
} }
@ -1151,4 +1157,26 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
public JPanel getCardArea() { public JPanel getCardArea() {
return cardArea; return cardArea;
} }
@Override
public void componentResized(ComponentEvent ce) {
doLayout();
if (updateCard != null) {
update(updateCard);
}
}
@Override
public void componentMoved(ComponentEvent ce) {
}
@Override
public void componentShown(ComponentEvent ce) {
}
@Override
public void componentHidden(ComponentEvent ce) {
}
} }

View file

@ -32,6 +32,7 @@ import java.io.Serializable;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.choices.Choice;
/** /**
* *
@ -50,6 +51,7 @@ public class GameClientMessage implements Serializable {
private int min; private int min;
private int max; private int max;
private Map<String, Serializable> options; private Map<String, Serializable> options;
private Choice choice;
public GameClientMessage(GameView gameView) { public GameClientMessage(GameView gameView) {
this.gameView = gameView; this.gameView = gameView;
@ -101,6 +103,10 @@ public class GameClientMessage implements Serializable {
this.message = name; this.message = name;
} }
public GameClientMessage(Choice choice) {
this.choice = choice;
}
public GameView getGameView() { public GameView getGameView() {
return gameView; return gameView;
} }
@ -144,4 +150,9 @@ public class GameClientMessage implements Serializable {
public Map<String, Serializable> getOptions() { public Map<String, Serializable> getOptions() {
return options; return options;
} }
public Choice getChoice() {
return choice;
}
} }

View file

@ -1336,8 +1336,8 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
@Override @Override
public int chooseEffect(List<String> rEffects, Game game) { public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
log.debug("chooseEffect"); log.debug("chooseReplacementEffect");
//TODO: implement this //TODO: implement this
return 0; return 0;
} }

View file

@ -375,11 +375,11 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
} }
@Override @Override
public int chooseEffect(List<String> rEffects, Game game) { public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
if (this.isHuman()) { if (this.isHuman()) {
return rnd.nextInt(rEffects.size()); return rnd.nextInt(rEffects.size());
} }
return super.chooseEffect(rEffects, game); return super.chooseReplacementEffect(rEffects, game);
} }
@Override @Override

View file

@ -82,6 +82,7 @@ public class HumanPlayer extends PlayerImpl {
protected static FilterAttackingCreature filterAttack = new FilterAttackingCreature(); protected static FilterAttackingCreature filterAttack = new FilterAttackingCreature();
protected static FilterBlockingCreature filterBlock = new FilterBlockingCreature(); protected static FilterBlockingCreature filterBlock = new FilterBlockingCreature();
protected static final Choice replacementEffectChoice = new ChoiceImpl(true); protected static final Choice replacementEffectChoice = new ChoiceImpl(true);
private static final Map<String, Serializable> staticOptions = new HashMap<>(); private static final Map<String, Serializable> staticOptions = new HashMap<>();
private static final Logger log = Logger.getLogger(HumanPlayer.class); private static final Logger log = Logger.getLogger(HumanPlayer.class);
@ -91,6 +92,8 @@ public class HumanPlayer extends PlayerImpl {
staticOptions.put("UI.right.btn.text", "Done"); staticOptions.put("UI.right.btn.text", "Done");
} }
protected HashSet<String> autoSelectReplacementEffects = new HashSet<>();
public HumanPlayer(String name, RangeOfInfluence range, int skill) { public HumanPlayer(String name, RangeOfInfluence range, int skill) {
super(name, range); super(name, range);
human = true; human = true;
@ -167,29 +170,43 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public int chooseEffect(List<String> rEffects, Game game) { public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
updateGameStatePriority("chooseEffect", game); updateGameStatePriority("chooseEffect", game);
replacementEffectChoice.getChoices().clear(); if (rEffects.size() == 1) {
int count = 1;
for (String effectText: rEffects) {
replacementEffectChoice.getChoices().add(count + ". " + effectText);
count++;
}
if (replacementEffectChoice.getChoices().size() == 1) {
return 0; return 0;
} }
if (!autoSelectReplacementEffects.isEmpty()) {
for (String autoKey :autoSelectReplacementEffects) {
int count = 0;
for (String effectKey : rEffects.keySet()) {
if (effectKey.equals(autoKey)) {
return count;
}
count++;
}
}
}
replacementEffectChoice.getChoices().clear();
replacementEffectChoice.setKeyChoices(rEffects);
while (!abort) { while (!abort) {
game.fireChooseEvent(playerId, replacementEffectChoice); game.fireChooseChoiceEvent(playerId, replacementEffectChoice);
waitForResponse(game); waitForResponse(game);
log.debug("Choose effect: " + response.getString()); log.debug("Choose effect: " + response.getString());
if (response.getString() != null) { if (response.getString() != null) {
replacementEffectChoice.setChoice(response.getString()); if (response.getString().startsWith("#")) {
count = 1; autoSelectReplacementEffects.add(response.getString().substring(1));
for (int i = 0; i < rEffects.size(); i++) { replacementEffectChoice.setChoiceByKey(response.getString().substring(1));
if (replacementEffectChoice.getChoice().equals(count + ". " + rEffects.get(i))) { } else {
return i; replacementEffectChoice.setChoiceByKey(response.getString());
} }
count++; int index = 0;
for (String key : rEffects.keySet()) {
if (replacementEffectChoice.getChoiceKey().equals(key)) {
return index;
}
index++;
} }
} }
} }
@ -200,7 +217,7 @@ public class HumanPlayer extends PlayerImpl {
public boolean choose(Outcome outcome, Choice choice, Game game) { public boolean choose(Outcome outcome, Choice choice, Game game) {
updateGameStatePriority("choose(3)", game); updateGameStatePriority("choose(3)", game);
while (!abort) { while (!abort) {
game.fireChooseEvent(playerId, choice); game.fireChooseChoiceEvent(playerId, choice);
waitForResponse(game); waitForResponse(game);
if (response.getString() != null) { if (response.getString() != null) {
choice.setChoice(response.getString()); choice.setChoice(response.getString());
@ -895,7 +912,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireGetAmountEvent(playerId, message, min, max); game.fireGetAmountEvent(playerId, message, min, max);
waitForIntegerResponse(game); waitForIntegerResponse(game);
if (response != null && response.getInteger() != null) { if (response != null && response.getInteger() != null) {
return response.getInteger().intValue(); return response.getInteger();
} else { } else {
return 0; return 0;
} }
@ -1106,5 +1123,12 @@ public class HumanPlayer extends PlayerImpl {
game.getState().setPriorityPlayerId(getId()); game.getState().setPriorityPlayerId(getId());
} }
@Override
public void sendPlayerAction(PlayerAction playerAction, Game game) {
if (PlayerAction.RESET_AUTO_SELECT_REPLACEMENT_EFFECTS.equals(playerAction)) {
autoSelectReplacementEffects.clear();
} else {
super.sendPlayerAction(playerAction, game);
}
}
} }

View file

@ -65,6 +65,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import mage.choices.Choice;
import mage.constants.PlayerAction; import mage.constants.PlayerAction;
/** /**
@ -215,8 +216,8 @@ public class GameController implements GameCallback {
case CHOOSE_MODE: case CHOOSE_MODE:
chooseMode(event.getPlayerId(), event.getModes()); chooseMode(event.getPlayerId(), event.getModes());
break; break;
case CHOOSE: case CHOOSE_CHOICE:
choose(event.getPlayerId(), event.getMessage(), event.getChoices()); chooseChoice(event.getPlayerId(), event.getChoice());
break; break;
case AMOUNT: case AMOUNT:
amount(event.getPlayerId(), event.getMessage(), event.getMin(), event.getMax()); amount(event.getPlayerId(), event.getMessage(), event.getMin(), event.getMax());
@ -582,11 +583,11 @@ public class GameController implements GameCallback {
}); });
} }
private synchronized void choose(UUID playerId, final String message, final Set<String> choices) throws MageException { private synchronized void chooseChoice(UUID playerId, final Choice choice) throws MageException {
perform(playerId, new Command() { perform(playerId, new Command() {
@Override @Override
public void execute(UUID playerId) { public void execute(UUID playerId) {
getGameSession(playerId).choose(message, choices); getGameSession(playerId).chooseChoice(choice);
} }
}); });
} }

View file

@ -48,6 +48,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import mage.choices.Choice;
import mage.game.Table; import mage.game.Table;
/** /**
@ -123,12 +124,12 @@ public class GameSession extends GameWatcher {
} }
} }
public void choose(final String message, final Set<String> choices) { public void chooseChoice(final Choice choice) {
if (!killed) { if (!killed) {
setupTimeout(); setupTimeout();
User user = UserManager.getInstance().getUser(userId); User user = UserManager.getInstance().getUser(userId);
if (user != null) { if (user != null) {
user.fireCallback(new ClientCallback("gameChoose", game.getId(), new GameClientMessage(choices.toArray(new String[choices.size()]), message))); user.fireCallback(new ClientCallback("gameChooseChoice", game.getId(), new GameClientMessage(choice)));
} }
} }
} }

View file

@ -126,26 +126,13 @@ class DoublingSeasonCounterEffect extends ReplacementEffectImpl {
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Permanent p = game.getPermanent(event.getTargetId()); event.setAmount(event.getAmount() * 2);
String counterName = event.getData();
if (p != null && counterName != null) {
Counter counter;
if (counterName.equals("+1/+1")) {
counter = CounterType.P1P1.createInstance(event.getAmount() * 2);
} else if (counterName.equals("-1/-1")) {
counter = CounterType.M1M1.createInstance(event.getAmount() * 2);
} else {
counter = new Counter(counterName, event.getAmount() * 2);
}
p.addCounters(counter, game, event.getAppliedEffects());
return true;
}
return false; return false;
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ADD_COUNTER) { if (event.getType() == GameEvent.EventType.ADD_COUNTERS) {
Permanent target = game.getPermanent(event.getTargetId()); Permanent target = game.getPermanent(event.getTargetId());
if (target != null && target.getControllerId().equals(source.getControllerId())) { if (target != null && target.getControllerId().equals(source.getControllerId())) {
return true; return true;

View file

@ -356,7 +356,7 @@ public class RandomPlayer extends ComputerPlayer {
} }
@Override @Override
public int chooseEffect(List<String> rEffects, Game game) { public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
return rnd.nextInt(rEffects.size()); return rnd.nextInt(rEffects.size());
} }

View file

@ -283,7 +283,7 @@ public class TestPlayer extends ComputerPlayer {
} }
@Override @Override
public int chooseEffect(List<String> rEffects, Game game) { public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
if (!choices.isEmpty()) { if (!choices.isEmpty()) {
for (String choice: choices) { for (String choice: choices) {
for (int index = 0; index < rEffects.size(); index++) { for (int index = 0; index < rEffects.size(); index++) {
@ -294,7 +294,7 @@ public class TestPlayer extends ComputerPlayer {
} }
} }
} }
return super.chooseEffect(rEffects, game); return super.chooseReplacementEffect(rEffects, game);
} }
@Override @Override

View file

@ -37,6 +37,7 @@ import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -675,7 +676,7 @@ public class ContinuousEffects implements Serializable {
} else { } else {
//20100716 - 616.1c //20100716 - 616.1c
Player player = game.getPlayer(event.getPlayerId()); Player player = game.getPlayer(event.getPlayerId());
index = player.chooseEffect(getReplacementEffectsTexts(rEffects, game), game); index = player.chooseReplacementEffect(getReplacementEffectsTexts(rEffects, game), game);
} }
// get the selected effect // get the selected effect
int checked = 0; int checked = 0;
@ -867,7 +868,10 @@ public class ContinuousEffects implements Serializable {
} }
public void addEffect(ContinuousEffect effect, Ability source) { public void addEffect(ContinuousEffect effect, Ability source) {
if (source == null && effect != null) { if (effect == null) {
logger.error("Effect is null: " + source.toString());
return;
} else if (source == null) {
logger.warn("Adding effect without ability : " +effect.toString()); logger.warn("Adding effect without ability : " +effect.toString());
} }
switch (effect.getEffectType()) { switch (effect.getEffectType()) {
@ -980,16 +984,17 @@ public class ContinuousEffects implements Serializable {
return effects; return effects;
} }
public List<String> getReplacementEffectsTexts(HashMap<ReplacementEffect, HashSet<Ability>> rEffects, Game game) {
List<String> texts = new ArrayList<>(); public Map<String, String> getReplacementEffectsTexts(HashMap<ReplacementEffect, HashSet<Ability>> rEffects, Game game) {
Map<String, String> texts = new LinkedHashMap<>();
for (Map.Entry<ReplacementEffect, HashSet<Ability>> entry : rEffects.entrySet()) { for (Map.Entry<ReplacementEffect, HashSet<Ability>> entry : rEffects.entrySet()) {
if (entry.getValue() != null) { if (entry.getValue() != null) {
for (Ability ability :entry.getValue()) { for (Ability ability :entry.getValue()) {
MageObject object = game.getObject(ability.getSourceId()); MageObject object = game.getObject(ability.getSourceId());
if (object != null) { if (object != null) {
texts.add(ability.getRule(object.getLogName())); texts.put(ability.getId().toString() + "_" + entry.getKey().getId().toString(), ability.getRule(object.getLogName()));
} else { } else {
texts.add(entry.getKey().getText(null)); texts.put(ability.getId().toString() + "_" + entry.getKey().getId().toString(), entry.getKey().getText(null));
} }
} }
} else { } else {

View file

@ -28,6 +28,7 @@
package mage.abilities.effects.common.continious; package mage.abilities.effects.common.continious;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ProtectionAbility;
@ -64,16 +65,27 @@ public class GainProtectionFromColorTargetEffect extends GainAbilityTargetEffect
} }
@Override @Override
public boolean apply(Game game, Ability source) { public void init(Ability source, Game game) {
Permanent creature = game.getPermanent(source.getFirstTarget()); super.init(source, game); //To change body of generated methods, choose Tools | Templates.
Player player = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId());
if (creature != null && player != null) { Player controller = game.getPlayer(source.getControllerId());
if (sourceObject != null && controller != null) {
while (!choice.isChosen()) { while (!choice.isChosen()) {
player.choose(Outcome.Protect, choice, game); controller.choose(Outcome.Protect, choice, game);
if (!player.isInGame()) { if (!controller.isInGame()) {
return false; return;
} }
} }
if (choice.isChosen()) {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getName() + " has chosen protection from " + choice.getChoice());
}
}
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (creature != null) {
FilterCard protectionFilter = (FilterCard)((ProtectionAbility)ability).getFilter(); FilterCard protectionFilter = (FilterCard)((ProtectionAbility)ability).getFilter();
protectionFilter.add(new ColorPredicate(choice.getColor())); protectionFilter.add(new ColorPredicate(choice.getColor()));
protectionFilter.setMessage(choice.getChoice()); protectionFilter.setMessage(choice.getChoice());
@ -89,8 +101,6 @@ public class GainProtectionFromColorTargetEffect extends GainAbilityTargetEffect
if (staticText != null && !staticText.isEmpty()) { if (staticText != null && !staticText.isEmpty()) {
return staticText; return staticText;
} }
else {
return "target creature you control gains protection from the color of your choice " + duration.toString(); return "target creature you control gains protection from the color of your choice " + duration.toString();
} }
} }
}

View file

@ -120,11 +120,13 @@ public class AddCountersSourceEffect extends OneShotEffect {
countersToAdd--; countersToAdd--;
} }
newCounter.add(countersToAdd); newCounter.add(countersToAdd);
int before = permanent.getCounters().getCount(newCounter.getName());
permanent.addCounters(newCounter, game); permanent.addCounters(newCounter, game);
int amountAdded = permanent.getCounters().getCount(newCounter.getName()) - before;
if (informPlayers) { if (informPlayers) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null) { if (player != null) {
game.informPlayers(new StringBuilder(player.getName()).append(" puts ").append(newCounter.getCount()).append(" ").append(newCounter.getName().toLowerCase()).append(" counter on ").append(permanent.getLogName()).toString()); game.informPlayers(player.getName()+" puts "+amountAdded+" "+newCounter.getName().toLowerCase()+" counter on "+permanent.getLogName());
} }
} }
} }

View file

@ -91,12 +91,12 @@ public class AddCountersTargetEffect extends OneShotEffect {
if (counter != null) { if (counter != null) {
Counter newCounter = counter.copy(); Counter newCounter = counter.copy();
newCounter.add(amount.calculate(game, source, this)); newCounter.add(amount.calculate(game, source, this));
int before = permanent.getCounters().getCount(counter.getName());
permanent.addCounters(newCounter, game); permanent.addCounters(newCounter, game);
int numberAdded = permanent.getCounters().getCount(counter.getName()) - before;
affectedTargets ++; affectedTargets ++;
game.informPlayers(new StringBuilder(sourceObject.getLogName()).append(": ") game.informPlayers(sourceObject.getLogName() +": "+ controller.getName()+ " puts " +
.append(controller.getName()).append(" puts ") numberAdded + " " + counter.getName().toLowerCase() + " counter on " + permanent.getLogName());
.append(counter.getCount()).append(" ").append(counter.getName().toLowerCase())
.append(" counter on ").append(permanent.getLogName()).toString());
} }
} else { } else {
Player player = game.getPlayer(uuid); Player player = game.getPlayer(uuid);

View file

@ -28,6 +28,7 @@
package mage.choices; package mage.choices;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
@ -42,9 +43,13 @@ public interface Choice {
String getMessage(); String getMessage();
void setMessage(String message); void setMessage(String message);
void setChoice(String choice); void setChoice(String choice);
void setChoiceByKey(String choiceKey);
Set<String> getChoices(); Set<String> getChoices();
Map<String,String> getKeyChoices();
void setChoices(Set<String> choices); void setChoices(Set<String> choices);
void setKeyChoices(Map<String, String> choices);
String getChoice(); String getChoice();
String getChoiceKey();
boolean isKeyChoice();
Choice copy(); Choice copy();
} }

View file

@ -29,7 +29,9 @@
package mage.choices; package mage.choices;
import java.io.Serializable; import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
@ -41,7 +43,9 @@ public class ChoiceImpl implements Choice, Serializable {
protected boolean chosen; protected boolean chosen;
protected boolean required; protected boolean required;
protected String choice; protected String choice;
protected String choiceKey;
protected Set<String> choices = new LinkedHashSet<>(); protected Set<String> choices = new LinkedHashSet<>();
protected Map<String, String> keyChoices = new LinkedHashMap<>();
protected String message; protected String message;
public ChoiceImpl() { public ChoiceImpl() {
@ -58,6 +62,8 @@ public class ChoiceImpl implements Choice, Serializable {
this.required = choice.required; this.required = choice.required;
this.message = choice.message; this.message = choice.message;
this.choices.addAll(choice.choices); 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
} }
@Override @Override
@ -114,4 +120,33 @@ public class ChoiceImpl implements Choice, Serializable {
return new ChoiceImpl(this); return new ChoiceImpl(this);
} }
@Override
public Map<String, String> getKeyChoices() {
return keyChoices;
}
@Override
public void setKeyChoices(Map<String, String> choices) {
keyChoices = choices;
}
@Override
public String getChoiceKey() {
return choiceKey;
}
@Override
public void setChoiceByKey(String choiceKey) {
String choiceToSet = keyChoices.get(choiceKey);
if (choiceToSet != null) {
this.choice = choiceToSet;
this.choiceKey = choiceKey;
}
}
@Override
public boolean isKeyChoice() {
return !keyChoices.isEmpty();
}
} }

View file

@ -41,5 +41,6 @@ public enum PlayerAction {
UNDO, UNDO,
CONCEDE, CONCEDE,
MANA_AUTO_PAYMENT_ON, MANA_AUTO_PAYMENT_ON,
MANA_AUTO_PAYMENT_OFF MANA_AUTO_PAYMENT_OFF,
RESET_AUTO_SELECT_REPLACEMENT_EFFECTS
} }

View file

@ -153,7 +153,7 @@ public interface Game extends MageItem, Serializable {
void addTableEventListener(Listener<TableEvent> listener); void addTableEventListener(Listener<TableEvent> listener);
void addPlayerQueryEventListener(Listener<PlayerQueryEvent> listener); void addPlayerQueryEventListener(Listener<PlayerQueryEvent> listener);
void fireAskPlayerEvent(UUID playerId, String message); void fireAskPlayerEvent(UUID playerId, String message);
void fireChooseEvent(UUID playerId, Choice choice); void fireChooseChoiceEvent(UUID playerId, Choice choice);
void fireSelectTargetEvent(UUID playerId, String message, Set<UUID> targets, boolean required, Map<String, Serializable> options); void fireSelectTargetEvent(UUID playerId, String message, Set<UUID> targets, boolean required, Map<String, Serializable> options);
void fireSelectTargetEvent(UUID playerId, String message, Cards cards, boolean required, Map<String, Serializable> options); void fireSelectTargetEvent(UUID playerId, String message, Cards cards, boolean required, Map<String, Serializable> options);
void fireSelectTargetEvent(UUID playerId, String message, List<TriggeredAbility> abilities); void fireSelectTargetEvent(UUID playerId, String message, List<TriggeredAbility> abilities);

View file

@ -1794,11 +1794,11 @@ public abstract class GameImpl implements Game, Serializable {
} }
@Override @Override
public void fireChooseEvent(UUID playerId, Choice choice) { public void fireChooseChoiceEvent(UUID playerId, Choice choice) {
if (simulation) { if (simulation) {
return; return;
} }
playerQueryEventSource.choose(playerId, choice.getMessage(), choice.getChoices()); playerQueryEventSource.chooseChoice(playerId, choice);
} }
@Override @Override

View file

@ -37,6 +37,7 @@ import mage.game.permanent.Permanent;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
import mage.choices.Choice;
/** /**
* *
@ -45,7 +46,7 @@ import java.util.*;
public class PlayerQueryEvent extends EventObject implements ExternalEvent, Serializable { public class PlayerQueryEvent extends EventObject implements ExternalEvent, Serializable {
public enum QueryType { public enum QueryType {
ASK, CHOOSE, CHOOSE_ABILITY, CHOOSE_MODE, PICK_TARGET, PICK_ABILITY, SELECT, PLAY_MANA, PLAY_X_MANA, AMOUNT, PICK_CARD, CONSTRUCT, CHOOSE_PILE, PERSONAL_MESSAGE ASK, CHOOSE_CHOICE, CHOOSE_ABILITY, CHOOSE_MODE, PICK_TARGET, PICK_ABILITY, SELECT, PLAY_MANA, PLAY_X_MANA, AMOUNT, PICK_CARD, CONSTRUCT, CHOOSE_PILE, PERSONAL_MESSAGE
} }
private String message; private String message;
@ -64,6 +65,7 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
private Map<UUID, String> modes; private Map<UUID, String> modes;
private List<? extends Card> pile1; private List<? extends Card> pile1;
private List<? extends Card> pile2; private List<? extends Card> pile2;
private Choice choice;
private PlayerQueryEvent(UUID playerId, String message, List<? extends Ability> abilities, Set<String> choices, Set<UUID> targets, Cards cards, QueryType queryType, int min, int max, boolean required, Map<String, Serializable> options) { private PlayerQueryEvent(UUID playerId, String message, List<? extends Ability> abilities, Set<String> choices, Set<UUID> targets, Cards cards, QueryType queryType, int min, int max, boolean required, Map<String, Serializable> options) {
@ -135,6 +137,13 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
this.playerId = playerId; this.playerId = playerId;
} }
private PlayerQueryEvent(UUID playerId, Choice choice) {
super(playerId);
this.queryType = QueryType.CHOOSE_CHOICE;
this.choice = choice;
this.playerId = playerId;
}
public static PlayerQueryEvent askEvent(UUID playerId, String message) { public static PlayerQueryEvent askEvent(UUID playerId, String message) {
return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.ASK, 0, 0, false); return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.ASK, 0, 0, false);
} }
@ -142,7 +151,7 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
public static PlayerQueryEvent chooseAbilityEvent(UUID playerId, String message, String objectName, List<? extends ActivatedAbility> choices) { public static PlayerQueryEvent chooseAbilityEvent(UUID playerId, String message, String objectName, List<? extends ActivatedAbility> choices) {
Set<String> nameAsSet = null; Set<String> nameAsSet = null;
if (objectName != null) { if (objectName != null) {
nameAsSet = new HashSet<String>(); nameAsSet = new HashSet<>();
nameAsSet.add(objectName); nameAsSet.add(objectName);
} }
return new PlayerQueryEvent(playerId, message, choices, nameAsSet, null, null, QueryType.CHOOSE_ABILITY, 0, 0, false); return new PlayerQueryEvent(playerId, message, choices, nameAsSet, null, null, QueryType.CHOOSE_ABILITY, 0, 0, false);
@ -156,8 +165,8 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
return new PlayerQueryEvent(playerId, message, modes); return new PlayerQueryEvent(playerId, message, modes);
} }
public static PlayerQueryEvent chooseEvent(UUID playerId, String message, Set<String> choices) { public static PlayerQueryEvent chooseChoiceEvent(UUID playerId, Choice choice) {
return new PlayerQueryEvent(playerId, message, null, choices, null, null, QueryType.CHOOSE, 0, 0, false); return new PlayerQueryEvent(playerId, choice);
} }
public static PlayerQueryEvent targetEvent(UUID playerId, String message, Set<UUID> targets, boolean required) { public static PlayerQueryEvent targetEvent(UUID playerId, String message, Set<UUID> targets, boolean required) {
@ -276,4 +285,8 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
return pile2; return pile2;
} }
public Choice getChoice() {
return choice;
}
} }

View file

@ -36,6 +36,7 @@ import mage.game.permanent.Permanent;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
import mage.choices.Choice;
/** /**
* *
@ -107,8 +108,8 @@ public class PlayerQueryEventSource implements EventSource<PlayerQueryEvent>, Se
dispatcher.fireEvent(PlayerQueryEvent.amountEvent(playerId, message, min, max)); dispatcher.fireEvent(PlayerQueryEvent.amountEvent(playerId, message, min, max));
} }
public void choose(UUID playerId, String message, Set<String> choices) { public void chooseChoice(UUID playerId, Choice choice) {
dispatcher.fireEvent(PlayerQueryEvent.chooseEvent(playerId, message, choices)); dispatcher.fireEvent(PlayerQueryEvent.chooseChoiceEvent(playerId, choice));
} }
public void playXMana(UUID playerId, String message) { public void playXMana(UUID playerId, String message) {

View file

@ -308,7 +308,7 @@ public interface Player extends MageItem, Copyable<Player> {
// set the value for non mana X costs // set the value for non mana X costs
int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost); int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost);
int chooseEffect(List<String> rEffects, Game game); int chooseReplacementEffect(Map<String, String> abilityMap, Game game);
TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game); TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game);
Mode chooseMode(Modes modes, Ability source, Game game); Mode chooseMode(Modes modes, Ability source, Game game);
void selectAttackers(Game game, UUID attackingPlayerId); void selectAttackers(Game game, UUID attackingPlayerId);

View file

@ -1643,8 +1643,8 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
@Override @Override
public void sendPlayerAction(PlayerAction passPriorityAction, Game game) { public void sendPlayerAction(PlayerAction playerAction, Game game) {
switch(passPriorityAction) { switch(playerAction) {
case PASS_PRIORITY_UNTIL_MY_NEXT_TURN: // F9 case PASS_PRIORITY_UNTIL_MY_NEXT_TURN: // F9
passedUntilNextMain = false; passedUntilNextMain = false;
passedUntilEndOfTurn = false; passedUntilEndOfTurn = false;
@ -1681,7 +1681,7 @@ public abstract class PlayerImpl implements Player, Serializable {
passedUntilEndOfTurn = false; passedUntilEndOfTurn = false;
passedUntilNextMain = false; passedUntilNextMain = false;
} }
logger.trace("PASS Priority: " + passPriorityAction.toString()); logger.trace("PASS Priority: " + playerAction.toString());
} }
@Override @Override