mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
Closed #169: Make it possible to untap lands
This commit is contained in:
parent
dd9aec6a49
commit
29b84e0d92
24 changed files with 244 additions and 207 deletions
|
@ -43,7 +43,6 @@ import mage.client.util.gui.ArrowBuilder;
|
|||
import mage.remote.Session;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.Serializable;
|
||||
|
@ -117,6 +116,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
|
|||
this.btnRight.setVisible(true);
|
||||
this.btnRight.setText("Cancel");
|
||||
this.helper.setState("", false, "Cancel", true);
|
||||
this.helper.setUndoEnabled(false);
|
||||
break;
|
||||
case SELECT:
|
||||
this.btnLeft.setVisible(false);
|
||||
|
@ -149,7 +149,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
|
|||
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
this.helper.setLinks(btnLeft, btnRight, btnSpecial);
|
||||
this.helper.setLinks(btnLeft, btnRight, btnSpecial, btnUndo);
|
||||
|
||||
this.helper.setVisible(true);
|
||||
}
|
||||
|
@ -205,7 +205,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
|
|||
}
|
||||
|
||||
public void clear() {
|
||||
// stopModal();
|
||||
this.btnLeft.setVisible(false);
|
||||
this.btnRight.setVisible(false);
|
||||
this.btnSpecial.setVisible(false);
|
||||
|
@ -213,138 +212,14 @@ public class FeedbackPanel extends javax.swing.JPanel {
|
|||
logger.debug("feedback - clear");
|
||||
}
|
||||
|
||||
// public void clear0() {
|
||||
// stopModal();
|
||||
// }
|
||||
|
||||
// private synchronized void startModal() {
|
||||
//
|
||||
// try {
|
||||
// if (SwingUtilities.isEventDispatchThread()) {
|
||||
// EventQueue theQueue = getToolkit().getSystemEventQueue();
|
||||
// while (!selected) {
|
||||
// AWTEvent event = theQueue.getNextEvent();
|
||||
// Object source = event.getSource();
|
||||
// boolean dispatch = true;
|
||||
//
|
||||
// if (event instanceof MouseEvent) {
|
||||
// MouseEvent e = (MouseEvent) event;
|
||||
// MouseEvent m = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, this);
|
||||
// if (!this.contains(m.getPoint()) && e.getID() != MouseEvent.MOUSE_DRAGGED) {
|
||||
// dispatch = false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (dispatch) {
|
||||
// if (event instanceof ActiveEvent) {
|
||||
// ((ActiveEvent) event).dispatch();
|
||||
// } else if (source instanceof Component) {
|
||||
// ((Component) source).dispatchEvent(event);
|
||||
// } else if (source instanceof MenuComponent) {
|
||||
// ((MenuComponent) source).dispatchEvent(event);
|
||||
// } else {
|
||||
// logger.warn("Unable to dispatch: " + event);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// while (!selected) {
|
||||
// wait();
|
||||
// }
|
||||
// }
|
||||
// } catch (InterruptedException ignored) {
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private synchronized void stopModal() {
|
||||
// notifyAll();
|
||||
// }
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
btnRight = new javax.swing.JButton();
|
||||
btnLeft = new javax.swing.JButton();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
//lblMessage = new javax.swing.JTextArea();
|
||||
lblMessage = new MageTextArea();
|
||||
btnSpecial = new javax.swing.JButton();
|
||||
|
||||
setBackground(new java.awt.Color(255,255,255,200));
|
||||
|
||||
btnRight.setText("Cancel");
|
||||
btnRight.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnRightActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnLeft.setText("OK");
|
||||
btnLeft.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnLeftActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jScrollPane1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
//lblMessage.setBackground(new java.awt.Color(204, 204, 204));
|
||||
/*lblMessage.setColumns(20);
|
||||
lblMessage.setEditable(false);
|
||||
lblMessage.setLineWrap(true);
|
||||
lblMessage.setRows(2);
|
||||
lblMessage.setWrapStyleWord(true);*/
|
||||
|
||||
lblMessage.setBorder(null);
|
||||
jScrollPane1.setViewportView(lblMessage);
|
||||
jScrollPane1.setBorder(null);
|
||||
|
||||
btnSpecial.setText("Special");
|
||||
btnSpecial.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnSpecialActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(btnSpecial)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 31, Short.MAX_VALUE)
|
||||
.addComponent(btnLeft)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnRight))
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 224, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnRight)
|
||||
.addComponent(btnLeft)
|
||||
.addComponent(btnSpecial)))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
public void customInitComponents() {
|
||||
btnRight = new javax.swing.JButton();
|
||||
btnLeft = new javax.swing.JButton();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
lblMessage = new MageTextArea();
|
||||
btnSpecial = new javax.swing.JButton();
|
||||
btnUndo = new javax.swing.JButton();
|
||||
btnUndo.setVisible(true);
|
||||
|
||||
setBackground(new java.awt.Color(0,0,0,80));
|
||||
|
||||
|
@ -379,26 +254,18 @@ public class FeedbackPanel extends javax.swing.JPanel {
|
|||
}
|
||||
});
|
||||
|
||||
JLabel jlabel = new JLabel();
|
||||
jlabel.setLayout(new BorderLayout());
|
||||
jlabel.add(jScrollPane1, BorderLayout.CENTER);
|
||||
btnUndo.setText("Undo");
|
||||
btnUndo.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnUndoActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
JLabel jlabel2 = new JLabel();
|
||||
jlabel2.setLayout(new FlowLayout());
|
||||
jlabel2.add(btnSpecial);
|
||||
jlabel2.add(btnLeft);
|
||||
jlabel2.add(btnRight);
|
||||
jlabel2.setPreferredSize(new Dimension(0, 35));
|
||||
|
||||
add(jlabel, BorderLayout.CENTER);
|
||||
add(jlabel2, BorderLayout.PAGE_END);
|
||||
}
|
||||
|
||||
private void btnRightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRightActionPerformed
|
||||
this.selected = true;
|
||||
// clear0();
|
||||
if (connectedDialog != null) {
|
||||
connectedDialog.hideDialog();
|
||||
}
|
||||
|
@ -414,7 +281,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
|
|||
|
||||
private void btnLeftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLeftActionPerformed
|
||||
this.selected = true;
|
||||
// clear0();
|
||||
session.sendPlayerBoolean(gameId, true);
|
||||
AudioManager.playButtonCancel();
|
||||
}//GEN-LAST:event_btnLeftActionPerformed
|
||||
|
@ -423,6 +289,10 @@ public class FeedbackPanel extends javax.swing.JPanel {
|
|||
session.sendPlayerString(gameId, "special");
|
||||
}//GEN-LAST:event_btnSpecialActionPerformed
|
||||
|
||||
private void btnUndoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSpecialActionPerformed
|
||||
session.undo(gameId);
|
||||
}
|
||||
|
||||
public void setHelperPanel(HelperPanel helper) {
|
||||
this.helper = helper;
|
||||
}
|
||||
|
@ -443,9 +313,18 @@ public class FeedbackPanel extends javax.swing.JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
public void allowUndo(int bookmark) {
|
||||
this.helper.setUndoEnabled(true);
|
||||
}
|
||||
|
||||
public void disableUndo() {
|
||||
this.helper.setUndoEnabled(false);
|
||||
}
|
||||
|
||||
private javax.swing.JButton btnLeft;
|
||||
private javax.swing.JButton btnRight;
|
||||
private javax.swing.JButton btnSpecial;
|
||||
private javax.swing.JButton btnUndo;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
//private javax.swing.JTextArea lblMessage;
|
||||
private MageTextArea lblMessage;
|
||||
|
|
|
@ -490,6 +490,14 @@ public final class GamePanel extends javax.swing.JPanel {
|
|||
} else {
|
||||
CombatManager.getInstance().hideCombat(gameId);
|
||||
}
|
||||
|
||||
System.out.println("Size: " + game.getStatesSavedSize());
|
||||
if (game.getStatesSavedSize() > 0) {
|
||||
feedbackPanel.allowUndo(game.getStatesSavedSize());
|
||||
} else {
|
||||
feedbackPanel.disableUndo();
|
||||
}
|
||||
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
}
|
||||
|
|
|
@ -29,10 +29,11 @@
|
|||
package mage.client.game;
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import mage.client.components.MageTextArea;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Panel with buttons that copy the state of feedback panel.
|
||||
*
|
||||
|
@ -43,6 +44,7 @@ public class HelperPanel extends JPanel {
|
|||
private javax.swing.JButton btnLeft;
|
||||
private javax.swing.JButton btnRight;
|
||||
private javax.swing.JButton btnSpecial;
|
||||
private javax.swing.JButton btnUndo;
|
||||
//private javax.swing.JButton btnEndTurn;
|
||||
//private javax.swing.JButton btnStopTimer;
|
||||
|
||||
|
@ -52,6 +54,7 @@ public class HelperPanel extends JPanel {
|
|||
private javax.swing.JButton linkLeft;
|
||||
private javax.swing.JButton linkRight;
|
||||
private javax.swing.JButton linkSpecial;
|
||||
private javax.swing.JButton linkUndo;
|
||||
|
||||
public HelperPanel() {
|
||||
initComponents();
|
||||
|
@ -89,6 +92,9 @@ public class HelperPanel extends JPanel {
|
|||
btnRight = new JButton("Cancel");
|
||||
btnRight.setVisible(false);
|
||||
container.add(btnRight);
|
||||
btnUndo = new JButton("Undo");
|
||||
btnUndo.setVisible(false);
|
||||
container.add(btnUndo);
|
||||
|
||||
btnLeft.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
|
@ -122,6 +128,15 @@ public class HelperPanel extends JPanel {
|
|||
}}
|
||||
}
|
||||
});
|
||||
|
||||
btnUndo.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
if (linkUndo != null) {{
|
||||
linkUndo.doClick();
|
||||
}}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setState(String txtLeft, boolean leftVisible, String txtRight, boolean rightVisible) {
|
||||
|
@ -140,6 +155,10 @@ public class HelperPanel extends JPanel {
|
|||
this.btnSpecial.setText(txtSpecial);
|
||||
}
|
||||
|
||||
public void setUndoEnabled(boolean enabled) {
|
||||
this.btnUndo.setVisible(enabled);
|
||||
}
|
||||
|
||||
public void setRight(String txtRight, boolean rightVisible) {
|
||||
this.btnRight.setVisible(rightVisible);
|
||||
if (!txtRight.isEmpty()) {
|
||||
|
@ -147,10 +166,11 @@ public class HelperPanel extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
public void setLinks(JButton left, JButton right, JButton special) {
|
||||
public void setLinks(JButton left, JButton right, JButton special, JButton undo) {
|
||||
this.linkLeft = left;
|
||||
this.linkRight = right;
|
||||
this.linkSpecial = special;
|
||||
this.linkUndo = undo;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
|
|
|
@ -100,6 +100,7 @@ public interface MageServer {
|
|||
void sendPlayerBoolean(UUID gameId, String sessionId, Boolean data) throws MageException;
|
||||
void sendPlayerInteger(UUID gameId, String sessionId, Integer data) throws MageException;
|
||||
void concedeGame(UUID gameId, String sessionId) throws MageException;
|
||||
void undo(UUID gameId, String sessionId) throws MageException;
|
||||
GameView getGameView(UUID gameId, String sessionId, UUID playerId) throws MageException;
|
||||
|
||||
//priority methods
|
||||
|
|
|
@ -929,6 +929,21 @@ public class SessionImpl implements Session {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean undo(UUID gameId) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
server.undo(gameId, sessionId);
|
||||
return true;
|
||||
}
|
||||
} catch (MageException ex) {
|
||||
handleMageException(ex);
|
||||
} catch (Throwable t) {
|
||||
handleThrowable(t);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passPriorityUntilNextYourTurn(UUID gameId) {
|
||||
try {
|
||||
|
|
|
@ -59,6 +59,8 @@ public interface GamePlay {
|
|||
|
||||
DraftPickView sendCardPick(UUID draftId, UUID cardId);
|
||||
|
||||
boolean undo(UUID gameId);
|
||||
|
||||
/*** Separate methods for priority handling ***/
|
||||
/**
|
||||
* magenoxx:
|
||||
|
|
|
@ -74,10 +74,17 @@ public class GameView implements Serializable {
|
|||
private String priorityPlayerName = "";
|
||||
private int turn;
|
||||
private boolean special = false;
|
||||
private int statesSavedSize;
|
||||
|
||||
public GameView(GameState state, Game game) {
|
||||
for (Player player: state.getPlayers().values()) {
|
||||
players.add(new PlayerView(player, state, game));
|
||||
if (player.getStoredBookmark() > 0) {
|
||||
if (this.statesSavedSize > 0) {
|
||||
throw new IllegalStateException("This shouldn't happen");
|
||||
}
|
||||
this.statesSavedSize = player.getStoredBookmark();
|
||||
}
|
||||
}
|
||||
for (StackObject stackObject: state.getStack()) {
|
||||
if (stackObject instanceof StackAbility) {
|
||||
|
@ -254,7 +261,7 @@ public class GameView implements Serializable {
|
|||
return special;
|
||||
}
|
||||
|
||||
/*public List<UUID> getStackOrder() {
|
||||
return stackOrder;
|
||||
}*/
|
||||
public int getStatesSavedSize() {
|
||||
return statesSavedSize;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,9 +27,6 @@
|
|||
*/
|
||||
package mage.player.ai;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
|
@ -62,6 +59,10 @@ import mage.target.Target;
|
|||
import mage.target.TargetCard;
|
||||
import mage.target.Targets;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -132,7 +133,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
switch (game.getTurn().getStepType()) {
|
||||
case UPKEEP:
|
||||
case DRAW:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case PRECOMBAT_MAIN:
|
||||
case POSTCOMBAT_MAIN:
|
||||
|
@ -146,36 +147,36 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
act(game);
|
||||
return true;
|
||||
} else {
|
||||
pass();
|
||||
pass(game);
|
||||
}
|
||||
return false;
|
||||
case BEGIN_COMBAT:
|
||||
case FIRST_COMBAT_DAMAGE:
|
||||
case COMBAT_DAMAGE:
|
||||
case END_COMBAT:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case DECLARE_ATTACKERS:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
//declareAttackers(game, playerId);
|
||||
pass();
|
||||
pass(game);
|
||||
} else {
|
||||
pass();
|
||||
pass(game);
|
||||
}
|
||||
return false;
|
||||
case DECLARE_BLOCKERS:
|
||||
if (!game.getActivePlayerId().equals(playerId)) {
|
||||
declareBlockers(game, playerId);
|
||||
pass();
|
||||
pass(game);
|
||||
} else {
|
||||
pass();
|
||||
pass(game);
|
||||
}
|
||||
return false;
|
||||
case END_TURN:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case CLEANUP:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
@ -222,7 +223,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
|
||||
protected void act(Game game) {
|
||||
if (actions == null || actions.size() == 0) {
|
||||
pass();
|
||||
pass(game);
|
||||
} else {
|
||||
boolean usedStack = false;
|
||||
while (actions.peek() != null) {
|
||||
|
@ -257,7 +258,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
}
|
||||
}
|
||||
if (usedStack) {
|
||||
pass();
|
||||
pass(game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -536,7 +537,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
}
|
||||
if (!sim.isGameOver() && action.isUsesStack()) {
|
||||
// only pass if the last action uses the stack
|
||||
sim.getPlayer(currentPlayer.getId()).pass();
|
||||
sim.getPlayer(currentPlayer.getId()).pass(game);
|
||||
sim.getPlayerList().getNext();
|
||||
}
|
||||
SimulationNode2 newNode = new SimulationNode2(node, sim, action, depth, currentPlayer.getId());
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
package mage.player.ai;
|
||||
|
||||
import java.util.*;
|
||||
import mage.Constants;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -40,6 +39,10 @@ import mage.game.turn.*;
|
|||
import mage.players.Player;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -77,7 +80,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
switch (game.getTurn().getStepType()) {
|
||||
case UPKEEP:
|
||||
case DRAW:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case PRECOMBAT_MAIN:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
|
@ -89,11 +92,11 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
return true;
|
||||
}
|
||||
else {
|
||||
pass();
|
||||
pass(game);
|
||||
}
|
||||
return false;
|
||||
case BEGIN_COMBAT:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case DECLARE_ATTACKERS:
|
||||
if (!game.getActivePlayerId().equals(playerId)) {
|
||||
|
@ -105,14 +108,14 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
return true;
|
||||
}
|
||||
else {
|
||||
pass();
|
||||
pass(game);
|
||||
}
|
||||
return false;
|
||||
case DECLARE_BLOCKERS:
|
||||
case FIRST_COMBAT_DAMAGE:
|
||||
case COMBAT_DAMAGE:
|
||||
case END_COMBAT:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case POSTCOMBAT_MAIN:
|
||||
// if (game.getActivePlayerId().equals(playerId)) {
|
||||
|
@ -124,13 +127,13 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
return true;
|
||||
// }
|
||||
// else {
|
||||
// pass();
|
||||
// pass(game);
|
||||
// }
|
||||
// return false;
|
||||
case END_TURN:
|
||||
case CLEANUP:
|
||||
actionCache.clear();
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -721,7 +721,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
|
|||
break;
|
||||
}
|
||||
}
|
||||
pass();
|
||||
pass(game);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
switch (game.getTurn().getStepType()) {
|
||||
case UPKEEP:
|
||||
case DRAW:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case PRECOMBAT_MAIN:
|
||||
case BEGIN_COMBAT:
|
||||
|
@ -123,7 +123,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
return true;
|
||||
case END_TURN:
|
||||
case CLEANUP:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
@ -131,7 +131,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
|
||||
protected void act(Game game) {
|
||||
if (actions == null || actions.size() == 0)
|
||||
pass();
|
||||
pass(game);
|
||||
else {
|
||||
boolean usedStack = false;
|
||||
while (actions.peek() != null) {
|
||||
|
@ -143,7 +143,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
usedStack = true;
|
||||
}
|
||||
if (usedStack)
|
||||
pass();
|
||||
pass(game);
|
||||
}
|
||||
logger.info("Turn " + game.getTurnNum() + " Step " + game.getStep().toString() + " Player " + name + " Life " + life);
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
}
|
||||
if (!sim.isGameOver() && action.isUsesStack()) {
|
||||
// only pass if the last action uses the stack
|
||||
sim.getPlayer(currentPlayer.getId()).pass();
|
||||
sim.getPlayer(currentPlayer.getId()).pass(game);
|
||||
sim.getPlayerList().getNext();
|
||||
}
|
||||
SimulationNode newNode = new SimulationNode(node, sim, action, currentPlayer.getId());
|
||||
|
|
|
@ -74,7 +74,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
switch (game.getTurn().getStepType()) {
|
||||
case UPKEEP:
|
||||
case DRAW:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case PRECOMBAT_MAIN:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
|
@ -85,10 +85,10 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
return true;
|
||||
}
|
||||
else
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case BEGIN_COMBAT:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case DECLARE_ATTACKERS:
|
||||
if (!game.getActivePlayerId().equals(playerId)) {
|
||||
|
@ -99,13 +99,13 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
return true;
|
||||
}
|
||||
else
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case DECLARE_BLOCKERS:
|
||||
case FIRST_COMBAT_DAMAGE:
|
||||
case COMBAT_DAMAGE:
|
||||
case END_COMBAT:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case POSTCOMBAT_MAIN:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
|
@ -116,11 +116,11 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
return true;
|
||||
}
|
||||
else
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
case END_TURN:
|
||||
case CLEANUP:
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -391,24 +391,24 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
|||
passed = false;
|
||||
if (!abort) {
|
||||
if (passedAllTurns) {
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
}
|
||||
if (passedTurn && game.getStack().isEmpty()) {
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
}
|
||||
updateGameStatePriority("priority", game);
|
||||
game.firePriorityEvent(playerId);
|
||||
waitForResponse();
|
||||
if (response.getBoolean() != null) {
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
} else if (response.getInteger() != null) {
|
||||
/*if (response.getInteger() == -9999) {
|
||||
passedAllTurns = true;
|
||||
}*/
|
||||
pass();
|
||||
pass(game);
|
||||
//passedTurn = true;
|
||||
return false;
|
||||
} else if (response.getString() != null && response.getString().equals("special")) {
|
||||
|
|
|
@ -570,6 +570,17 @@ public class MageServerImpl implements MageServer {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undo(final UUID gameId, final String sessionId) throws MageException {
|
||||
execute("undo", sessionId, new Action() {
|
||||
@Override
|
||||
public void execute() {
|
||||
UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId();
|
||||
GameManager.getInstance().undo(gameId, userId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passPriorityUntilNextYourTurn(final UUID gameId, final String sessionId) throws MageException {
|
||||
execute("passPriorityUntilNextYourTurn", sessionId, new Action() {
|
||||
|
|
|
@ -255,6 +255,10 @@ public class GameController implements GameCallback {
|
|||
game.concede(getPlayerId(userId));
|
||||
}
|
||||
|
||||
public void undo(UUID userId) {
|
||||
game.undo(getPlayerId(userId));
|
||||
}
|
||||
|
||||
public void passPriorityUntilNextYourTurn(UUID userId) {
|
||||
game.passPriorityUntilNextYourTurn(getPlayerId(userId));
|
||||
}
|
||||
|
|
|
@ -96,6 +96,11 @@ public class GameManager {
|
|||
gameControllers.get(gameId).concede(userId);
|
||||
}
|
||||
|
||||
public void undo(UUID gameId, UUID userId) {
|
||||
if (gameControllers.containsKey(gameId))
|
||||
gameControllers.get(gameId).undo(userId);
|
||||
}
|
||||
|
||||
public void passPriorityUntilNextYourTurn(UUID gameId, UUID userId) {
|
||||
if (gameControllers.containsKey(gameId))
|
||||
gameControllers.get(gameId).passPriorityUntilNextYourTurn(userId);
|
||||
|
|
|
@ -45,6 +45,7 @@ import mage.player.ai.ComputerPlayer;
|
|||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanentAmount;
|
||||
import org.junit.Ignore;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -52,7 +53,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.target.common.TargetCreaturePermanentAmount;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -124,7 +124,7 @@ public class TestPlayer extends ComputerPlayer<TestPlayer> {
|
|||
}
|
||||
}
|
||||
}
|
||||
pass();
|
||||
pass(game);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public class PassEffect extends OneShotEffect<PassEffect> {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
player.pass();
|
||||
player.pass(game);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,7 @@ public interface Game extends MageItem, Serializable {
|
|||
void mulligan(UUID playerId);
|
||||
void quit(UUID playerId);
|
||||
void concede(UUID playerId);
|
||||
void undo(UUID playerId);
|
||||
void emptyManaPools();
|
||||
void addEffect(ContinuousEffect continuousEffect, Ability source);
|
||||
void addEmblem(Emblem emblem, Ability source);
|
||||
|
@ -200,6 +201,7 @@ public interface Game extends MageItem, Serializable {
|
|||
int bookmarkState();
|
||||
void restoreState(int bookmark);
|
||||
void removeBookmark(int bookmark);
|
||||
int getSavedStateSize();
|
||||
|
||||
// game options
|
||||
void setGameOptions(GameOptions options);
|
||||
|
|
|
@ -420,7 +420,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
savedStates.push(gameStates.getSize() - 1);
|
||||
return savedStates.size();
|
||||
}
|
||||
return 0;
|
||||
return savedStates.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -444,10 +444,31 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
while (savedStates.size() > bookmark) {
|
||||
savedStates.pop();
|
||||
}
|
||||
gameStates.remove(bookmark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearAllBookmarks() {
|
||||
if (!simulation) {
|
||||
while (!savedStates.isEmpty()) {
|
||||
savedStates.pop();
|
||||
}
|
||||
gameStates.remove(0);
|
||||
for (Player player : getPlayers().values()) {
|
||||
player.setStoredBookmark(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSavedStateSize() {
|
||||
if (!simulation) {
|
||||
return savedStates.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(UUID choosingPlayerId) {
|
||||
start(choosingPlayerId, this.gameOptions != null ? gameOptions : GameOptions.getDefault());
|
||||
|
@ -721,6 +742,19 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void undo(UUID playerId) {
|
||||
Player player = state.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
int bookmark = player.getStoredBookmark();
|
||||
if (bookmark != -1) {
|
||||
restoreState(bookmark);
|
||||
player.setStoredBookmark(-1);
|
||||
fireUpdatePlayersEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void passPriorityUntilNextYourTurn(UUID playerId) {
|
||||
Player player = state.getPlayer(playerId);
|
||||
|
@ -748,6 +782,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
@Override
|
||||
public void playPriority(UUID activePlayerId, boolean resuming) {
|
||||
int bookmark = 0;
|
||||
clearAllBookmarks();
|
||||
try {
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
if (!resuming) {
|
||||
|
|
|
@ -28,10 +28,11 @@
|
|||
|
||||
package mage.game;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -66,6 +67,15 @@ public class GameStates implements Serializable {
|
|||
return null;
|
||||
}
|
||||
|
||||
public int remove(int index) {
|
||||
if (states.size() > 0 && index < states.size()) {
|
||||
while (states.size() > index && states.size() > 0) {
|
||||
states.remove(states.size() - 1);
|
||||
}
|
||||
}
|
||||
return states.size();
|
||||
}
|
||||
|
||||
public GameState get(int index) {
|
||||
if (index < states.size())
|
||||
// return new Copier<GameState>().uncompressCopy(states.get(index));
|
||||
|
|
|
@ -28,17 +28,18 @@
|
|||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.Constants.TurnPhase;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -161,7 +162,7 @@ public class Turn implements Serializable {
|
|||
if (phase.resumePlay(game, stepType, wasPaused)) {
|
||||
//20091005 - 500.4/703.4n
|
||||
game.emptyManaPools();
|
||||
game.saveState();
|
||||
//game.saveState();
|
||||
//20091005 - 500.8
|
||||
playExtraPhases(game, phase.getType());
|
||||
}
|
||||
|
@ -175,7 +176,7 @@ public class Turn implements Serializable {
|
|||
if (phase.play(game, activePlayerId)) {
|
||||
//20091005 - 500.4/703.4n
|
||||
game.emptyManaPools();
|
||||
game.saveState();
|
||||
//game.saveState();
|
||||
//20091005 - 500.8
|
||||
playExtraPhases(game, phase.getType());
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
void setMaxHandSize(int maxHandSize);
|
||||
boolean isPassed();
|
||||
boolean isEmptyDraw();
|
||||
void pass();
|
||||
void pass(Game game);
|
||||
void resetPassed();
|
||||
boolean hasLost();
|
||||
boolean hasWon();
|
||||
|
@ -203,6 +203,10 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
void passTurnPriority(Game game);
|
||||
void restorePriority(Game game);
|
||||
|
||||
int getStoredBookmark();
|
||||
void setStoredBookmark(int bookmark);
|
||||
void resetStoredBookmark(Game game);
|
||||
|
||||
void revealCards(String name, Cards cards, Game game);
|
||||
void lookAtCards(String name, Cards cards, Game game);
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
protected boolean passed;
|
||||
protected boolean passedTurn;
|
||||
protected int turns;
|
||||
protected int storedBookmark = -1;
|
||||
|
||||
/**
|
||||
* This indicates that player passed all turns until his own turn starts.
|
||||
|
@ -175,6 +176,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
this.userData = player.userData;
|
||||
this.canPayLifeCost = player.canPayLifeCost;
|
||||
this.canPaySacrificeCost = player.canPaySacrificeCost;
|
||||
this.storedBookmark = player.storedBookmark;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -537,6 +539,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
game.fireEvent(event);
|
||||
game.fireInformEvent(name + spellAbility.getActivatedMessage(game));
|
||||
game.removeBookmark(bookmark);
|
||||
resetStoredBookmark(game);
|
||||
return true;
|
||||
}
|
||||
game.restoreState(bookmark);
|
||||
|
@ -556,6 +559,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), playerId));
|
||||
game.fireInformEvent(name + " plays " + card.getName());
|
||||
game.removeBookmark(bookmark);
|
||||
resetStoredBookmark(game);
|
||||
return true;
|
||||
}
|
||||
game.restoreState(bookmark);
|
||||
|
@ -568,7 +572,11 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
int bookmark = game.bookmarkState();
|
||||
if (ability.activate(game, false)) {
|
||||
ability.resolve(game);
|
||||
game.removeBookmark(bookmark);
|
||||
// #169
|
||||
if (storedBookmark == -1) {
|
||||
setStoredBookmark(bookmark);
|
||||
}
|
||||
//game.removeBookmark(bookmark);
|
||||
return true;
|
||||
}
|
||||
game.restoreState(bookmark);
|
||||
|
@ -587,6 +595,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATED_ABILITY, ability.getId(), ability.getSourceId(), playerId));
|
||||
game.fireInformEvent(name + ability.getActivatedMessage(game));
|
||||
game.removeBookmark(bookmark);
|
||||
resetStoredBookmark(game);
|
||||
return true;
|
||||
}
|
||||
game.restoreState(bookmark);
|
||||
|
@ -596,6 +605,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
if (ability.activate(game, false)) {
|
||||
ability.resolve(game);
|
||||
game.removeBookmark(bookmark);
|
||||
resetStoredBookmark(game);
|
||||
return true;
|
||||
}
|
||||
game.restoreState(bookmark);
|
||||
|
@ -612,6 +622,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
game.fireInformEvent(name + action.getActivatedMessage(game));
|
||||
if (action.resolve(game)) {
|
||||
game.removeBookmark(bookmark);
|
||||
resetStoredBookmark(game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -628,7 +639,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
}
|
||||
|
||||
if (ability instanceof PassAbility) {
|
||||
pass();
|
||||
pass(game);
|
||||
return true;
|
||||
}
|
||||
else if (ability instanceof PlayLandAbility) {
|
||||
|
@ -1055,8 +1066,9 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
}
|
||||
|
||||
@Override
|
||||
public void pass() {
|
||||
public void pass(Game game) {
|
||||
this.passed = true;
|
||||
resetStoredBookmark(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1598,4 +1610,21 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
return turns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStoredBookmark() {
|
||||
return storedBookmark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStoredBookmark(int storedBookmark) {
|
||||
this.storedBookmark = storedBookmark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void resetStoredBookmark(Game game) {
|
||||
if (this.storedBookmark != -1) {
|
||||
game.removeBookmark(this.storedBookmark);
|
||||
}
|
||||
setStoredBookmark(-1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue