Added context menu to switch between manual and automatic usage of the mana in mana pool. Manual usage is done by clicking on the mana symbol in the player panel. Still some fine tuning to do.

This commit is contained in:
LevelX2 2014-05-24 02:56:35 +02:00
parent eeead4a8b4
commit 71fb7bf25b
26 changed files with 415 additions and 100 deletions

View file

@ -31,6 +31,7 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
@ -39,6 +40,7 @@ import java.util.UUID;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
@ -158,7 +160,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.getSession().passTurnPriority(gameId);;
gamePanel.getSession().passTurnPriority(gameId);
}
});
@ -175,6 +177,21 @@ public class PlayAreaPanel extends javax.swing.JPanel {
popupMenu.addSeparator();
menuItem = new JCheckBoxMenuItem("Use mana from pool automatically", true);
menuItem.setMnemonic(KeyEvent.VK_M);
menuItem.setToolTipText("If not active, you have to click the type of mana you want to pay in the player panel.");
popupMenu.add(menuItem);
// Auto pay mana from mana pool
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.getSession().setManaPoolMode(((JCheckBoxMenuItem)e.getSource()).getState(), gameId);
}
});
popupMenu.addSeparator();
menuItem = new JMenuItem("Concede game");
popupMenu.add(menuItem);

View file

@ -74,6 +74,7 @@ import mage.client.util.Command;
import mage.client.util.ImageHelper;
import mage.client.util.gui.BufferedImageBuilder;
import mage.components.ImagePanel;
import mage.constants.ManaType;
import mage.remote.Session;
import mage.utils.timer.PriorityTimer;
import mage.view.CardView;
@ -440,51 +441,104 @@ public class PlayerPanelExt extends javax.swing.JPanel {
}
});
// Add mana symbols
BufferedImage imageManaW = ManaSymbols.getManaSymbolImageSmall("W");
ImagePanel manaW = new ImagePanel(imageManaW, ImagePanel.ACTUAL);
manaW.setOpaque(false);
JLabel manaCountLabelW = new JLabel();
manaCountLabelW.setToolTipText("White mana");
manaCountLabelW.setText("0");
manaLabels.put("W", manaCountLabelW);
r = new Rectangle(12, 12);
BufferedImage imageManaW = ManaSymbols.getManaSymbolImageSmall("W");
HoverButton btnWhiteMana = new HoverButton(null, imageManaW, imageManaW, imageManaW, r);
btnWhiteMana.setToolTipText("White mana");
btnWhiteMana.setOpaque(false);
btnWhiteMana.setObserver(new Command() {
@Override
public void execute() {
btnManaActionPerformed(ManaType.WHITE);
}
});
BufferedImage imageManaU = ManaSymbols.getManaSymbolImageSmall("U");
ImagePanel manaU = new ImagePanel(imageManaU, ImagePanel.ACTUAL);
manaU.setOpaque(false);
JLabel manaCountLabelU = new JLabel();
manaCountLabelU.setToolTipText("Blue mana");
manaCountLabelU.setText("0");
manaLabels.put("U", manaCountLabelU);
r = new Rectangle(12, 12);
BufferedImage imageManaU = ManaSymbols.getManaSymbolImageSmall("U");
HoverButton btnBlueMana = new HoverButton(null, imageManaU, imageManaU, imageManaU, r);
btnBlueMana.setToolTipText("Blue mana");
btnBlueMana.setOpaque(false);
btnBlueMana.setObserver(new Command() {
@Override
public void execute() {
btnManaActionPerformed(ManaType.BLUE);
}
});
BufferedImage imageManaB = ManaSymbols.getManaSymbolImageSmall("B");
ImagePanel manaB = new ImagePanel(imageManaB, ImagePanel.ACTUAL);
manaB.setOpaque(false);
JLabel manaCountLabelB = new JLabel();
manaCountLabelB.setToolTipText("Black mana");
manaCountLabelB.setText("0");
manaLabels.put("B", manaCountLabelB);
r = new Rectangle(12, 12);
BufferedImage imageManaB = ManaSymbols.getManaSymbolImageSmall("B");
HoverButton btnBlackMana = new HoverButton(null, imageManaB, imageManaB, imageManaB, r);
btnBlackMana.setToolTipText("Black mana");
btnBlackMana.setOpaque(false);
btnBlackMana.setObserver(new Command() {
@Override
public void execute() {
btnManaActionPerformed(ManaType.BLACK);
}
});
BufferedImage imageManaR = ManaSymbols.getManaSymbolImageSmall("R");
ImagePanel manaR = new ImagePanel(imageManaR, ImagePanel.ACTUAL);
manaR.setOpaque(false);
JLabel manaCountLabelR = new JLabel();
manaCountLabelR.setToolTipText("Red mana");
manaCountLabelR.setText("0");
manaLabels.put("R", manaCountLabelR);
r = new Rectangle(12, 12);
BufferedImage imageManaR = ManaSymbols.getManaSymbolImageSmall("R");
HoverButton btnRedMana = new HoverButton(null, imageManaR, imageManaR, imageManaR, r);
btnRedMana.setToolTipText("Red mana");
btnRedMana.setOpaque(false);
btnRedMana.setObserver(new Command() {
@Override
public void execute() {
btnManaActionPerformed(ManaType.RED);
}
});
BufferedImage imageManaG = ManaSymbols.getManaSymbolImageSmall("G");
ImagePanel manaG = new ImagePanel(imageManaG, ImagePanel.ACTUAL);
manaG.setOpaque(false);
JLabel manaCountLabelG = new JLabel();
manaCountLabelG.setToolTipText("Green mana");
manaCountLabelG.setText("0");
manaLabels.put("G", manaCountLabelG);
r = new Rectangle(12, 12);
BufferedImage imageManaG = ManaSymbols.getManaSymbolImageSmall("G");
HoverButton btnGreenMana = new HoverButton(null, imageManaG, imageManaG, imageManaG, r);
btnGreenMana.setToolTipText("Green mana");
btnGreenMana.setOpaque(false);
btnGreenMana.setObserver(new Command() {
@Override
public void execute() {
btnManaActionPerformed(ManaType.GREEN);
}
});
BufferedImage imageManaX = ManaSymbols.getManaSymbolImageSmall("X");
ImagePanel manaX = new ImagePanel(imageManaX, ImagePanel.ACTUAL);
manaX.setOpaque(false);
JLabel manaCountLabelX = new JLabel();
manaCountLabelX.setToolTipText("Colorless mana");
manaCountLabelX.setText("0");
manaLabels.put("X", manaCountLabelX);
GroupLayout gl_panelBackground = new GroupLayout(panelBackground);
r = new Rectangle(12, 12);
BufferedImage imageManaX = ManaSymbols.getManaSymbolImageSmall("X");
HoverButton btnColorlessMana = new HoverButton(null, imageManaX, imageManaX, imageManaX, r);
btnColorlessMana.setToolTipText("Colorless mana");
btnColorlessMana.setOpaque(false);
btnColorlessMana.setObserver(new Command() {
@Override
public void execute() {
btnManaActionPerformed(ManaType.COLORLESS);
}
});
GroupLayout gl_panelBackground = new GroupLayout(panelBackground);
gl_panelBackground.setHorizontalGroup(
gl_panelBackground.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panelBackground.createSequentialGroup()
@ -506,13 +560,13 @@ public class PlayerPanelExt extends javax.swing.JPanel {
.addComponent(poison, GroupLayout.PREFERRED_SIZE, 14, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(2)
.addComponent(manaW, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(btnWhiteMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(2)
.addComponent(manaU, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(btnBlueMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(2)
.addComponent(manaB, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(btnBlackMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(grave, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
)
.addGroup(gl_panelBackground.createParallelGroup(Alignment.LEADING)
@ -524,7 +578,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
.addComponent(poisonLabel, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(20)
.addComponent(manaR, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(btnRedMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(1)
.addComponent(manaCountLabelW, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE)))
@ -536,12 +590,12 @@ public class PlayerPanelExt extends javax.swing.JPanel {
.addComponent(manaCountLabelB, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE)
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(19)
.addComponent(manaX, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)))
.addComponent(btnColorlessMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)))
.addGap(5)
.addComponent(manaCountLabelX, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(20)
.addComponent(manaG, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(btnGreenMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(40)
.addComponent(manaCountLabelG, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE))
@ -594,11 +648,11 @@ public class PlayerPanelExt extends javax.swing.JPanel {
.addGap(4)
.addComponent(poison, GroupLayout.PREFERRED_SIZE, 14, GroupLayout.PREFERRED_SIZE)
.addGap(4)
.addComponent(manaW, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
.addComponent(btnWhiteMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
.addGap(2)
.addComponent(manaU, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
.addComponent(btnBlueMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
.addGap(2)
.addComponent(manaB, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
.addComponent(btnBlackMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
.addGap(5)
.addComponent(grave, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
)
@ -611,7 +665,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
.addComponent(library, GroupLayout.PREFERRED_SIZE, 19, GroupLayout.PREFERRED_SIZE))
.addComponent(poisonLabel, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE))
.addGap(2)
.addComponent(manaR, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(btnRedMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(14)
.addComponent(manaCountLabelW, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE))
@ -623,11 +677,11 @@ public class PlayerPanelExt extends javax.swing.JPanel {
.addComponent(manaCountLabelB, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE)
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(8)
.addComponent(manaX, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(btnColorlessMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(manaCountLabelX, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE)))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(39)
.addComponent(manaG, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addComponent(btnGreenMana, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panelBackground.createSequentialGroup()
.addGap(31)
.addComponent(manaCountLabelG, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE))
@ -680,6 +734,10 @@ public class PlayerPanelExt extends javax.swing.JPanel {
}
}
private void btnManaActionPerformed(ManaType manaType) {
session.sendPlayerManaType(gameId, manaType);
}
private void btnGraveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGraveActionPerformed
/*if (graveyard == null) {
graveyard = new ShowCardsDialog();
@ -706,6 +764,10 @@ public class PlayerPanelExt extends javax.swing.JPanel {
private ImagePanel life;
private ImagePanel poison;
private ImagePanel hand;
// private HoverButton btnWhiteMana;
// private HoverButton btnBlueMana;
private HoverButton grave;
private ImagePanel library;
private CardView topCard;

View file

@ -28,18 +28,25 @@
package mage.interfaces;
import java.util.List;
import java.util.UUID;
import mage.MageException;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
import mage.cards.repository.ExpansionInfo;
import mage.constants.ManaType;
import mage.game.GameException;
import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions;
import mage.utils.MageVersion;
import mage.view.*;
import java.util.List;
import java.util.UUID;
import mage.view.DraftPickView;
import mage.view.GameView;
import mage.view.MatchView;
import mage.view.TableView;
import mage.view.TournamentView;
import mage.view.UserDataView;
import mage.view.UserView;
import mage.view.UsersView;
/**
*
@ -107,9 +114,11 @@ public interface MageServer {
void sendPlayerString(UUID gameId, String sessionId, String data) throws MageException;
void sendPlayerBoolean(UUID gameId, String sessionId, Boolean data) throws MageException;
void sendPlayerInteger(UUID gameId, String sessionId, Integer data) throws MageException;
void sendPlayerManaType(UUID gameId, String sessionId, ManaType data) throws MageException;
void concedeGame(UUID gameId, String sessionId) throws MageException;
void quitMatch(UUID gameId, String sessionId) throws MageException;
void undo(UUID gameId, String sessionId) throws MageException;
void setManaPoolMode(UUID gameId, String sessionId, boolean autoPayment) throws MageException;
GameView getGameView(UUID gameId, String sessionId, UUID playerId) throws MageException;
//priority methods

View file

@ -57,6 +57,7 @@ import org.jboss.remoting.transporter.TransporterClient;
import javax.swing.*;
import java.net.*;
import java.util.*;
import mage.constants.ManaType;
/**
*
@ -623,6 +624,21 @@ public class SessionImpl implements Session {
return false;
}
@Override
public boolean sendPlayerManaType(UUID gameId, ManaType data) {
try {
if (isConnected()) {
server.sendPlayerManaType(gameId, sessionId, data);
return true;
}
} catch (MageException ex) {
handleMageException(ex);
} catch (Throwable t) {
handleThrowable(t);
}
return false;
}
@Override
public DraftPickView sendCardPick(UUID draftId, UUID cardId) {
try {
@ -1165,6 +1181,21 @@ public class SessionImpl implements Session {
return false;
}
@Override
public boolean setManaPoolMode(boolean autoPayment, UUID gameId) {
try {
if (isConnected()) {
server.setManaPoolMode(gameId, sessionId, autoPayment);
return true;
}
} catch (MageException ex) {
handleMageException(ex);
} catch (Throwable t) {
handleThrowable(t);
}
return false;
}
@Override
public boolean cheat(UUID gameId, UUID playerId, DeckCardLists deckList) {
try {

View file

@ -27,10 +27,10 @@
*/
package mage.remote.interfaces;
import mage.cards.decks.DeckCardLists;
import mage.view.DraftPickView;
import java.util.UUID;
import mage.cards.decks.DeckCardLists;
import mage.constants.ManaType;
import mage.view.DraftPickView;
/**
* @author noxx
@ -51,6 +51,8 @@ public interface GamePlay {
boolean sendPlayerString(UUID gameId, String data);
boolean sendPlayerManaType(UUID gameId, ManaType data);
boolean concedeGame(UUID gameId);
boolean quitMatch(UUID gameId);
@ -99,4 +101,13 @@ public interface GamePlay {
*/
boolean restorePriority(UUID gameId);
/**
* This method toggles usage of mana pool
*
* @param automatic true mana in pool will be used automatically
* @param gameId
* @return
*/
boolean setManaPoolMode(boolean automatic, UUID gameId);
}

View file

@ -60,6 +60,7 @@ import mage.cards.Cards;
import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.RangeOfInfluence;
import static mage.constants.SpellAbilityType.SPLIT;
@ -511,7 +512,10 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
}
}
}
}
} else if (response.getManaType() != null) {
// this mana type can be paid once from pool
this.getManaPool().unlockManaType(response.getManaType());
}
return true;
}
@ -826,7 +830,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
protected void specialAction(Game game) {
updateGameStatePriority("specialAction", game);
LinkedHashMap<UUID, SpecialAction> specialActions = game.getState().getSpecialActions().getControlledBy(playerId);
game.fireGetChoiceEvent(playerId, name, null, new ArrayList<SpecialAction>(specialActions.values()));
game.fireGetChoiceEvent(playerId, name, null, new ArrayList<>(specialActions.values()));
waitForResponse(game);
if (response.getUUID() != null) {
if (specialActions.containsKey(response.getUUID())) {
@ -844,7 +848,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
return;
}
}
game.fireGetChoiceEvent(playerId, name, object, new ArrayList<ActivatedAbility>(abilities.values()));
game.fireGetChoiceEvent(playerId, name, object, new ArrayList<>(abilities.values()));
waitForResponse(game);
if (response.getUUID() != null) {
if (abilities.containsKey(response.getUUID())) {
@ -887,7 +891,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
if (useableAbilities != null && useableAbilities.size() == 1) {
return (SpellAbility) useableAbilities.values().iterator().next();
} else if (useableAbilities != null && useableAbilities.size() > 0) {
game.fireGetChoiceEvent(playerId, name, object, new ArrayList<ActivatedAbility>(useableAbilities.values()));
game.fireGetChoiceEvent(playerId, name, object, new ArrayList<>(useableAbilities.values()));
waitForResponse(game);
if (response.getUUID() != null) {
if (useableAbilities.containsKey(response.getUUID())) {
@ -907,7 +911,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
updateGameStatePriority("chooseMode", game);
if (modes.size() > 1) {
MageObject obj = game.getObject(source.getSourceId());
Map<UUID, String> modeMap = new LinkedHashMap<UUID, String>();
Map<UUID, String> modeMap = new LinkedHashMap<>();
for (Mode mode: modes.values()) {
if (!modes.getSelectedModes().contains(mode.getId()) // show only modes not already selected
&& mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and where targets are available
@ -954,6 +958,15 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
}
}
@Override
public void setResponseManaType(ManaType manaType) {
synchronized(response) {
response.setManaType(manaType);
response.notify();
log.debug("Got response mana type from player: " + getId());
}
}
@Override
public void setResponseUUID(UUID responseUUID) {
synchronized(response) {

View file

@ -30,6 +30,7 @@ package mage.player.human;
import java.io.Serializable;
import java.util.UUID;
import mage.constants.ManaType;
/**
*
@ -41,12 +42,14 @@ public class PlayerResponse implements Serializable {
private UUID responseUUID;
private Boolean responseBoolean;
private Integer responseInteger;
private ManaType responseManaType;
public void clear() {
responseString = null;
responseUUID = null;
responseBoolean = null;
responseInteger = null;
responseManaType = null;
}
public String getString() {
@ -81,4 +84,12 @@ public class PlayerResponse implements Serializable {
this.responseInteger = responseInteger;
}
public ManaType getManaType() {
return responseManaType;
}
public void setManaType(ManaType responseManaType) {
this.responseManaType = responseManaType;
}
}

View file

@ -65,6 +65,7 @@ import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import mage.constants.ManaType;
/**
*
@ -568,6 +569,21 @@ public class MageServerImpl implements MageServer {
});
}
@Override
public void sendPlayerManaType(final UUID gameId, final String sessionId, final ManaType data) throws MageException {
execute("sendPlayerManaType", sessionId, new Action() {
@Override
public void execute() {
User user = SessionManager.getInstance().getUser(sessionId);
if (user != null) {
user.sendPlayerManaType(gameId, data);
} else {
logger.warn("Your session expired: gameId=" + gameId + ", sessionId=" + sessionId);
}
}
});
}
@Override
public void sendPlayerBoolean(final UUID gameId, final String sessionId, final Boolean data) throws MageException {
execute("sendPlayerBoolean", sessionId, new Action() {
@ -609,6 +625,17 @@ public class MageServerImpl implements MageServer {
});
}
@Override
public void setManaPoolMode(final UUID gameId, final String sessionId, final boolean autoPayment) throws MageException {
execute("setManaPoolMode", sessionId, new Action() {
@Override
public void execute() {
UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId();
GameManager.getInstance().setManaPoolMode(gameId, userId, autoPayment);
}
});
}
@Override
public void concedeGame(final UUID gameId, final String sessionId) throws MageException {
execute("concedeGame", sessionId, new Action() {

View file

@ -36,6 +36,7 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import mage.cards.decks.Deck;
import mage.constants.ManaType;
import mage.game.Table;
import mage.interfaces.callback.ClientCallback;
import mage.players.net.UserData;
@ -137,7 +138,7 @@ public class User {
public String getDisconnectDuration() {
long secondsDisconnected = SystemUtil.getDateDiff(lastActivity, new Date(), TimeUnit.SECONDS);
long secondsLeft = 0;
long secondsLeft;
String sign = "";
if (secondsDisconnected > (3 * 60)) {
sign="-";
@ -222,6 +223,11 @@ public class User {
GameManager.getInstance().sendPlayerString(gameId, userId, data);
}
public void sendPlayerManaType(final UUID gameId, final ManaType data) {
lastActivity = new Date();
GameManager.getInstance().sendPlayerManaType(gameId, userId, data);
}
public void sendPlayerBoolean(final UUID gameId, final Boolean data) {
lastActivity = new Date();
GameManager.getInstance().sendPlayerBoolean(gameId, userId, data);

View file

@ -54,6 +54,7 @@ import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.constants.ManaType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.GameException;
@ -356,6 +357,10 @@ public class GameController implements GameCallback {
game.concede(getPlayerId(userId));
}
public void setManaPoolMode(UUID userId, boolean autoPayment) {
game.setManaPoolMode(getPlayerId(userId), autoPayment);
}
public void quit(UUID userId) {
game.quit(getPlayerId(userId));
}
@ -470,6 +475,15 @@ public class GameController implements GameCallback {
});
}
public void sendPlayerManaType(UUID userId, final ManaType data) {
sendMessage(userId, new Command() {
@Override
public void execute(UUID playerId) {
getGameSession(playerId).sendPlayerManaType(data);
}
});
}
public void sendPlayerBoolean(UUID userId, final Boolean data) {
sendMessage(userId, new Command() {
@Override

View file

@ -28,12 +28,12 @@
package mage.server.game;
import mage.cards.decks.DeckCardLists;
import mage.game.Game;
import mage.view.GameView;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import mage.cards.decks.DeckCardLists;
import mage.constants.ManaType;
import mage.game.Game;
import mage.view.GameView;
/**
*
@ -85,6 +85,12 @@ public class GameManager {
}
}
public void sendPlayerManaType(UUID gameId, UUID userId, ManaType data) {
if (gameControllers.containsKey(gameId)) {
gameControllers.get(gameId).sendPlayerManaType(userId, data);
}
}
public void sendPlayerBoolean(UUID gameId, UUID userId, Boolean data) {
if (gameControllers.containsKey(gameId)) {
gameControllers.get(gameId).sendPlayerBoolean(userId, data);
@ -97,6 +103,12 @@ public class GameManager {
}
}
public void setManaPoolMode(UUID gameId, UUID userId, boolean autoPayment) {
if (gameControllers.containsKey(gameId)) {
gameControllers.get(gameId).setManaPoolMode(userId, autoPayment);
}
}
public void concedeGame(UUID gameId, UUID userId) {
if (gameControllers.containsKey(gameId)) {
gameControllers.get(gameId).concede(userId);

View file

@ -29,12 +29,18 @@
package mage.server.game;
import java.io.Serializable;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import mage.cards.Cards;
import mage.constants.ManaType;
import mage.game.Game;
import mage.game.match.Match;
import mage.interfaces.callback.ClientCallback;
@ -215,6 +221,11 @@ public class GameSession extends GameWatcher {
game.getPlayer(playerId).setResponseString(data);
}
public void sendPlayerManaType(ManaType manaType) {
cancelTimeout();
game.getPlayer(playerId).setResponseManaType(manaType);
}
public void sendPlayerBoolean(Boolean data) {
cancelTimeout();
game.getPlayer(playerId).setResponseBoolean(data);

View file

@ -27,19 +27,18 @@
*/
package mage.sets.lorwyn;
import mage.constants.CardType;
import mage.constants.Rarity;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author Loki
*/
@ -54,7 +53,7 @@ public class SpringleafDrum extends CardImpl<SpringleafDrum> {
public SpringleafDrum(UUID ownerId) {
super(ownerId, 261, "Springleaf Drum", Rarity.COMMON, new CardType[]{CardType.ARTIFACT}, "{1}");
this.expansionSetCode = "LRW";
// {tap}, Tap an untapped creature you control: Add one mana of any color to your mana pool.
// {T}, Tap an untapped creature you control: Add one mana of any color to your mana pool.
Ability ability = new AnyColorManaAbility();
ability.addCost(new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false)));
this.addAbility(ability);

View file

@ -28,9 +28,9 @@
package mage.abilities.costs.mana;
import mage.constants.ColoredManaSymbol;
import mage.Mana;
import mage.abilities.Ability;
import mage.constants.ColoredManaSymbol;
import mage.game.Game;
import mage.players.ManaPool;

View file

@ -60,8 +60,9 @@ public class GenericManaCost extends ManaCostImpl<GenericManaCost> {
@Override
public boolean isPaid() {
if (paid)
if (paid) {
return true;
}
return this.isColorlessPaid(mana);
}

View file

@ -60,10 +60,7 @@ public class HybridManaCost extends ManaCostImpl<HybridManaCost> {
@Override
public boolean isPaid() {
if (paid || isColoredPaid(this.mana1) || isColoredPaid(this.mana2)) {
return true;
}
return false;
return paid || isColoredPaid(this.mana1) || isColoredPaid(this.mana2);
}
@Override

View file

@ -28,9 +28,9 @@
package mage.abilities.costs.mana;
import mage.abilities.Ability;
import mage.abilities.costs.*;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.mana.ManaOptions;
import mage.constants.ColoredManaSymbol;
import mage.filter.Filter;

View file

@ -28,20 +28,22 @@
package mage.abilities.costs.mana;
import java.util.*;
import mage.constants.ColoredManaSymbol;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.VariableCost;
import mage.abilities.mana.ManaOptions;
import mage.constants.ColoredManaSymbol;
import mage.filter.Filter;
import mage.game.Game;
import mage.players.ManaPool;
import mage.players.Player;
import mage.target.Targets;
/**
* @author BetaSteward_at_googlemail.com
* @param <T>
@ -50,7 +52,7 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
protected UUID id;
private static Map<String, ManaCosts> costs = new HashMap<String, ManaCosts>();
private static Map<String, ManaCosts> costs = new HashMap<>();
public ManaCostsImpl() {
this.id = UUID.randomUUID();
@ -204,6 +206,11 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
@Override
public void assignPayment(Game game, Ability ability, ManaPool pool) {
if (!pool.isAutoPayment() && pool.getUnlockedManaType() == null) {
// if auto payment is inactive and no mana type was clicked manually - do nothing
return;
}
//attempt to pay colored costs first
for (ManaCost cost : this) {
@ -235,6 +242,8 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
cost.assignPayment(game, ability, pool);
}
}
// stop using mana of the clicked mana type
pool.lockManaType();
}
@Override

View file

@ -35,7 +35,7 @@ import mage.players.ManaPool;
public class MonoHybridManaCost extends ManaCostImpl<MonoHybridManaCost> {
private ColoredManaSymbol mana;
private final ColoredManaSymbol mana;
private int mana2 = 2;
public MonoHybridManaCost(ColoredManaSymbol mana) {

View file

@ -12,7 +12,7 @@ public enum ManaType {
WHITE ("white"),
COLORLESS("colorless");
private String text;
private final String text;
ManaType(String text) {
this.text = text;

View file

@ -28,6 +28,13 @@
package mage.game;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import mage.MageItem;
import mage.MageObject;
import mage.abilities.Ability;
@ -36,6 +43,7 @@ import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffects;
import mage.abilities.effects.PreventionEffectData;
import mage.actions.impl.MageAction;
import mage.cards.Card;
import mage.cards.Cards;
@ -46,6 +54,7 @@ import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.game.combat.Combat;
import mage.game.command.Commander;
import mage.game.command.Emblem;
import mage.game.events.GameEvent;
import mage.game.events.Listener;
@ -64,11 +73,6 @@ import mage.players.PlayerList;
import mage.players.Players;
import mage.util.functions.ApplyToPermanent;
import java.io.Serializable;
import java.util.*;
import mage.abilities.effects.PreventionEffectData;
import mage.game.command.Commander;
public interface Game extends MageItem, Serializable {
MatchType getGameType();
@ -222,6 +226,7 @@ public interface Game extends MageItem, Serializable {
void timerTimeout(UUID playerId);
void idleTimeout(UUID playerId);
void concede(UUID playerId);
void setManaPoolMode(UUID playerId, boolean autoPayment);
void undo(UUID playerId);
void emptyManaPools();
void addEffect(ContinuousEffect continuousEffect, Ability source);

View file

@ -28,6 +28,23 @@
package mage.game;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
@ -51,7 +68,13 @@ import mage.cards.CardsImpl;
import mage.cards.SplitCard;
import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.MultiplayerAttackOption;
import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.Filter;
import mage.filter.FilterPermanent;
@ -66,8 +89,14 @@ import mage.game.combat.Combat;
import mage.game.command.CommandObject;
import mage.game.command.Commander;
import mage.game.command.Emblem;
import mage.game.events.*;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.Listener;
import mage.game.events.PlayerQueryEvent;
import mage.game.events.PlayerQueryEventSource;
import mage.game.events.TableEvent;
import mage.game.events.TableEvent.EventType;
import mage.game.events.TableEventSource;
import mage.game.permanent.Battlefield;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
@ -85,16 +114,14 @@ import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
import mage.util.functions.ApplyToPermanent;
import mage.watchers.common.*;
import mage.watchers.common.CastSpellLastTurnWatcher;
import mage.watchers.common.MiracleWatcher;
import mage.watchers.common.MorbidWatcher;
import mage.watchers.common.PlayerDamagedBySourceWatcher;
import mage.watchers.common.PlayerLostLifeWatcher;
import mage.watchers.common.SoulbondWatcher;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializable {
private static final transient Logger logger = Logger.getLogger(GameImpl.class);
@ -959,6 +986,14 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
}
}
@Override
public synchronized void setManaPoolMode(UUID playerId, boolean autoPayment) {
Player player = state.getPlayer(playerId);
if (player != null) {
player.getManaPool().setAutoPayment(autoPayment);
}
}
@Override
public synchronized void restorePriority(UUID playerId) {
Player player = state.getPlayer(playerId);
@ -1184,7 +1219,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
copiedCard.assignNewId();
copiedCard.setControllerId(newController);
copiedCard.setCopy(true);
Set<Card> cards = new HashSet<Card>();
Set<Card> cards = new HashSet<>();
cards.add(copiedCard);
loadCards(cards, source.getControllerId());
@ -2003,7 +2038,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
if (lkiMap != null) {
lkiMap.put(objectId, copy);
} else {
HashMap<UUID, MageObject> newMap = new HashMap<UUID, MageObject>();
HashMap<UUID, MageObject> newMap = new HashMap<>();
newMap.put(objectId, copy);
lki.put(zone, newMap);
}
@ -2012,7 +2047,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
if (shortLivingLkiMap != null) {
shortLivingLkiMap.put(objectId, copy);
} else {
HashMap<UUID, MageObject> newMap = new HashMap<UUID, MageObject>();
HashMap<UUID, MageObject> newMap = new HashMap<>();
newMap.put(objectId, copy);
shortLivingLKI.put(zone, newMap);
}
@ -2147,7 +2182,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
if (cards == null) {
return;
}
Set<Card> set = new HashSet<Card>(cards);
Set<Card> set = new HashSet<>(cards);
loadCards(set, ownerId);
}
@ -2158,7 +2193,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
removeCard(card);
}
player.getLibrary().clear();
Set<Card> cards = new HashSet<Card>();
Set<Card> cards = new HashSet<>();
for (Card card : cardsDownToTop) {
cards.add(card);
}

View file

@ -50,14 +50,22 @@ import mage.game.events.ManaEvent;
*/
public class ManaPool implements Serializable {
private List<ManaPoolItem> manaItems = new ArrayList<ManaPoolItem>();
private final List<ManaPoolItem> manaItems = new ArrayList<>();
public ManaPool() {}
private boolean autoPayment; // auto payment from mana pool: true - mode is active
private ManaType unlockedManaType; // type of mana that was selected to pay manually
public ManaPool() {
autoPayment = true;
unlockedManaType = null;
}
public ManaPool(final ManaPool pool) {
for (ManaPoolItem item: pool.manaItems) {
manaItems.add(item.copy());
}
this.autoPayment = pool.autoPayment;
this.unlockedManaType = pool.unlockedManaType;
}
public int getRed() {
@ -81,8 +89,13 @@ public class ManaPool implements Serializable {
}
public boolean pay(ManaType manaType, Ability ability, Filter filter, Game game) {
if (!autoPayment && !manaType.equals(unlockedManaType)) {
// if manual payment and the needed mana type was not unlocked, nothing will be paid
return false;
}
if (getConditional(manaType, ability, filter, game) > 0) {
removeConditional(manaType, ability, game);
lockManaType(); // pay only one mana if mana payment is set to manually
return true;
}
for (ManaPoolItem mana : manaItems) {
@ -95,6 +108,7 @@ public class ManaPool implements Serializable {
} else {
mana.remove(manaType);
}
lockManaType(); // pay only one mana if mana payment is set to manually
return true;
}
}
@ -302,7 +316,7 @@ public class ManaPool implements Serializable {
}
public List<ConditionalMana> getConditionalMana() {
List<ConditionalMana> conditionalMana = new ArrayList<ConditionalMana>();
List<ConditionalMana> conditionalMana = new ArrayList<>();
for (ManaPoolItem item: manaItems) {
if (item.isConditional()) {
conditionalMana.add(item.getConditionalMana());
@ -332,4 +346,25 @@ public class ManaPool implements Serializable {
}
}
}
public boolean isAutoPayment() {
return autoPayment;
}
public void setAutoPayment(boolean autoPayment) {
this.autoPayment = autoPayment;
}
public ManaType getUnlockedManaType() {
return unlockedManaType;
}
public void unlockManaType(ManaType manaType) {
this.unlockedManaType = manaType;
}
public void lockManaType() {
this.unlockedManaType = null;
}
}

View file

@ -50,6 +50,7 @@ import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
@ -277,6 +278,7 @@ public interface Player extends MageItem, Copyable<Player> {
void setResponseUUID(UUID responseUUID);
void setResponseBoolean(Boolean responseBoolean);
void setResponseInteger(Integer data);
void setResponseManaType(ManaType responseManaType);
boolean priority(Game game);
boolean choose(Outcome outcome, Target target, UUID sourceId, Game game);

View file

@ -75,9 +75,9 @@ import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.SplitCard;
import mage.cards.decks.Deck;
import mage.constants.AbilityType;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.RangeOfInfluence;
import mage.constants.SpellAbilityType;
@ -117,7 +117,7 @@ import org.apache.log4j.Logger;
/**
*
* * @param <T>
* @param <T>
*/
public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Serializable {
@ -1470,6 +1470,9 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
@Override
public void setResponseString(String responseString) {}
@Override
public void setResponseManaType(ManaType responseManaType) {}
@Override
public void setResponseUUID(UUID responseUUID) {}

View file

@ -1,11 +1,16 @@
package mage.util;
import mage.Mana;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.mana.*;
import java.util.LinkedHashMap;
import java.util.UUID;
import mage.Mana;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.mana.BasicManaAbility;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.ManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
/**
* @author noxx