diff --git a/Mage.Client/src/main/java/mage/client/cards/CardGrid.java b/Mage.Client/src/main/java/mage/client/cards/CardGrid.java index a602188b04..7a5b34b0f5 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardGrid.java @@ -75,7 +75,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener setOpaque(false); } - public void loadCards(CardsView showCards, SortBy sortBy, BigCard bigCard, UUID gameId) { + public void loadCards(CardsView showCards, SortBy sortBy, boolean piles, BigCard bigCard, UUID gameId) { this.bigCard = bigCard; this.gameId = gameId; for (CardView card: showCards.values()) { @@ -90,7 +90,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener i.remove(); } } - drawCards(sortBy); + drawCards(sortBy, piles); this.setVisible(true); } @@ -106,7 +106,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener cards.put(card.getId(), cardImg); } - public void drawCards(SortBy sortBy) { + public void drawCards(SortBy sortBy, boolean piles) { int maxWidth = this.getParent().getWidth(); int numColumns = maxWidth / Config.dimensions.frameWidth; int curColumn = 0; @@ -128,15 +128,54 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener Collections.sort(sortedCards, new CardCostComparator()); break; } + MageCard lastCard = null; for (MageCard cardImg: sortedCards) { - rectangle.setLocation(curColumn * Config.dimensions.frameWidth, curRow * 20); - cardImg.setBounds(rectangle); - cardImg.setCardBounds(rectangle.x, rectangle.y, Config.dimensions.frameWidth, Config.dimensions.frameHeight); - moveToFront(cardImg); - curColumn++; - if (curColumn == numColumns) { - curColumn = 0; + if (piles) { + if (lastCard == null) + lastCard = cardImg; + switch (sortBy) { + case NAME: + if (!cardImg.getOriginal().getName().equals(lastCard.getOriginal().getName())) { + curColumn++; + curRow = 0; + } + break; + case RARITY: + if (!cardImg.getOriginal().getRarity().equals(lastCard.getOriginal().getRarity())) { + curColumn++; + curRow = 0; + } + break; + case COLOR: + if (cardImg.getOriginal().getColor().compareTo(lastCard.getOriginal().getColor()) != 0) { + curColumn++; + curRow = 0; + } + break; + case CASTING_COST: + if (cardImg.getOriginal().getConvertedManaCost() != lastCard.getOriginal().getConvertedManaCost()) { + curColumn++; + curRow = 0; + } + break; + } + rectangle.setLocation(curColumn * Config.dimensions.frameWidth, curRow * 20); + cardImg.setBounds(rectangle); + cardImg.setCardBounds(rectangle.x, rectangle.y, Config.dimensions.frameWidth, Config.dimensions.frameHeight); + moveToFront(cardImg); curRow++; + lastCard = cardImg; + } + else { + rectangle.setLocation(curColumn * Config.dimensions.frameWidth, curRow * 20); + cardImg.setBounds(rectangle); + cardImg.setCardBounds(rectangle.x, rectangle.y, Config.dimensions.frameWidth, Config.dimensions.frameHeight); + moveToFront(cardImg); + curColumn++; + if (curColumn == numColumns) { + curColumn = 0; + curRow++; + } } } } diff --git a/Mage.Client/src/main/java/mage/client/cards/CardsList.form b/Mage.Client/src/main/java/mage/client/cards/CardsList.form index 85696ffe74..3046438e2e 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsList.form +++ b/Mage.Client/src/main/java/mage/client/cards/CardsList.form @@ -27,7 +27,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -58,12 +58,14 @@ - + - - + + + + @@ -74,6 +76,7 @@ + @@ -109,6 +112,14 @@ + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/cards/CardsList.java b/Mage.Client/src/main/java/mage/client/cards/CardsList.java index 413b1b5201..2d003a03ee 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsList.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardsList.java @@ -46,6 +46,7 @@ import java.util.List; import java.util.UUID; import javax.swing.DefaultComboBoxModel; import mage.Constants.CardType; +import mage.ObjectColor; import mage.cards.MageCard; import mage.client.constants.Constants.SortBy; @@ -115,17 +116,58 @@ public class CardsList extends javax.swing.JPanel implements MouseListener { Collections.sort(sortedCards, new CardViewCostComparator()); break; } + CardView lastCard = null; for (CardView card: sortedCards) { - rectangle.setLocation(curColumn * Config.dimensions.frameWidth, curRow * 20); - addCard(card, bigCard, gameId, rectangle); - if (card.getCardTypes().contains(CardType.LAND)) - landCount++; - if (card.getCardTypes().contains(CardType.CREATURE)) - creatureCount++; - curColumn++; - if (curColumn == numColumns) { - curColumn = 0; + if (chkPiles.isSelected()) { + if (lastCard == null) + lastCard = card; + switch (sortBy) { + case NAME: + if (!card.getName().equals(lastCard.getName())) { + curColumn++; + curRow = 0; + } + break; + case RARITY: + if (!card.getRarity().equals(lastCard.getRarity())) { + curColumn++; + curRow = 0; + } + break; + case COLOR: + if (card.getColor().compareTo(lastCard.getColor()) != 0) { + curColumn++; + curRow = 0; + } + break; + case CASTING_COST: + if (card.getConvertedManaCost() != lastCard.getConvertedManaCost()) { + curColumn++; + curRow = 0; + } + break; + } + rectangle.setLocation(curColumn * Config.dimensions.frameWidth, curRow * 20); + addCard(card, bigCard, gameId, rectangle); + if (card.getCardTypes().contains(CardType.LAND)) + landCount++; + if (card.getCardTypes().contains(CardType.CREATURE)) + creatureCount++; curRow++; + lastCard = card; + } + else { + rectangle.setLocation(curColumn * Config.dimensions.frameWidth, curRow * 20); + addCard(card, bigCard, gameId, rectangle); + if (card.getCardTypes().contains(CardType.LAND)) + landCount++; + if (card.getCardTypes().contains(CardType.CREATURE)) + creatureCount++; + curColumn++; + if (curColumn == numColumns) { + curColumn = 0; + curRow++; + } } } } @@ -176,6 +218,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener { lblCount = new javax.swing.JLabel(); lblCreatureCount = new javax.swing.JLabel(); lblLandCount = new javax.swing.JLabel(); + chkPiles = new javax.swing.JCheckBox(); setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); setPreferredSize((!Beans.isDesignTime())?(new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight)):(new Dimension(100, 100))); @@ -195,6 +238,13 @@ public class CardsList extends javax.swing.JPanel implements MouseListener { lblLandCount.setText("Land Count"); + chkPiles.setText("Piles"); + chkPiles.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + chkPilesActionPerformed(evt); + } + }); + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( @@ -205,8 +255,10 @@ public class CardsList extends javax.swing.JPanel implements MouseListener { .addComponent(lblCreatureCount, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(lblLandCount, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(cbSortBy, 0, 353, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkPiles) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbSortBy, 0, 300, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -214,7 +266,8 @@ public class CardsList extends javax.swing.JPanel implements MouseListener { .addComponent(cbSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblCount) .addComponent(lblCreatureCount) - .addComponent(lblLandCount)) + .addComponent(lblLandCount) + .addComponent(chkPiles)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -222,14 +275,14 @@ public class CardsList extends javax.swing.JPanel implements MouseListener { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 639, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 625, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 397, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -237,10 +290,15 @@ public class CardsList extends javax.swing.JPanel implements MouseListener { drawCards((SortBy) cbSortBy.getSelectedItem()); }//GEN-LAST:event_cbSortByActionPerformed + private void chkPilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkPilesActionPerformed + drawCards((SortBy) cbSortBy.getSelectedItem()); + }//GEN-LAST:event_chkPilesActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLayeredPane cardArea; private javax.swing.JComboBox cbSortBy; + private javax.swing.JCheckBox chkPiles; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel lblCount; diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form index a317ec55e0..64253dc584 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form +++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form @@ -255,6 +255,17 @@ + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java index 7ad58865f3..760f1c9b61 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java @@ -142,7 +142,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene filteredCards.add(card); } } - this.cardGrid.loadCards(new CardsView(filteredCards), (SortBy) cbSortBy.getSelectedItem(), bigCard, null); + this.cardGrid.loadCards(new CardsView(filteredCards), (SortBy) cbSortBy.getSelectedItem(), chkPiles.isSelected(), bigCard, null); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); @@ -198,6 +198,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene rdoInstants = new javax.swing.JRadioButton(); rdoSorceries = new javax.swing.JRadioButton(); rdoPlaneswalkers = new javax.swing.JRadioButton(); + chkPiles = new javax.swing.JCheckBox(); cbSortBy = new javax.swing.JComboBox(); tbColor.setFloatable(false); @@ -394,6 +395,17 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene }); tbTypes.add(rdoPlaneswalkers); + chkPiles.setText("Piles"); + chkPiles.setFocusable(false); + chkPiles.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + chkPiles.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + chkPiles.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + chkPilesActionPerformed(evt); + } + }); + tbTypes.add(chkPiles); + cbSortBy.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); cbSortBy.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -530,9 +542,14 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene private void cbSortByActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbSortByActionPerformed if (cbSortBy.getSelectedItem() instanceof SortBy) - this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem()); + this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem(), chkPiles.isSelected()); }//GEN-LAST:event_cbSortByActionPerformed + private void chkPilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkPilesActionPerformed + if (cbSortBy.getSelectedItem() instanceof SortBy) + this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem(), chkPiles.isSelected()); + }//GEN-LAST:event_chkPilesActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnBooster; @@ -540,6 +557,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene private mage.client.cards.CardGrid cardGrid; private javax.swing.JComboBox cbExpansionSet; private javax.swing.JComboBox cbSortBy; + private javax.swing.JCheckBox chkPiles; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JRadioButton rdoArtifacts; private javax.swing.JRadioButton rdoBlack; @@ -561,25 +579,25 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene @Override public void componentResized(ComponentEvent e) { if (cbSortBy.getSelectedItem() instanceof SortBy) - this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem()); + this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem(), chkPiles.isSelected()); } @Override public void componentMoved(ComponentEvent e) { if (cbSortBy.getSelectedItem() instanceof SortBy) - this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem()); + this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem(), chkPiles.isSelected()); } @Override public void componentShown(ComponentEvent e) { if (cbSortBy.getSelectedItem() instanceof SortBy) - this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem()); + this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem(), chkPiles.isSelected()); } @Override public void componentHidden(ComponentEvent e) { if (cbSortBy.getSelectedItem() instanceof SortBy) - this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem()); + this.cardGrid.drawCards((SortBy) cbSortBy.getSelectedItem(), chkPiles.isSelected()); } } diff --git a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java index 9bd5c9d9df..4d3c3e775d 100644 --- a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java +++ b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java @@ -98,7 +98,7 @@ public class DraftPanel extends javax.swing.JPanel { public void loadBooster(DraftPickView draftPickView) { draftBooster.loadBooster(draftPickView.getBooster(), bigCard); - draftPicks.loadCards(draftPickView.getPicks(), SortBy.NAME, bigCard, null); + draftPicks.loadCards(draftPickView.getPicks(), SortBy.NAME, false, bigCard, null); this.draftBooster.clearCardEventListeners(); this.draftBooster.addCardEventListener( new Listener () { @@ -108,7 +108,7 @@ public class DraftPanel extends javax.swing.JPanel { DraftPickView view = session.sendCardPick(draftId, (UUID)event.getSource()); if (view != null) { draftBooster.loadBooster(view.getBooster(), bigCard); - draftPicks.loadCards(view.getPicks(), SortBy.NAME, bigCard, null); + draftPicks.loadCards(view.getPicks(), SortBy.NAME, false, bigCard, null); setMessage("Waiting for other players"); } } diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 8ee7bc1e90..ec056f11d8 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -44,6 +44,7 @@ import mage.MageObject; import mage.Mana; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; +import mage.abilities.SpellAbility; import mage.abilities.TriggeredAbilities; import mage.abilities.TriggeredAbility; import mage.abilities.costs.mana.ColoredManaCost; @@ -225,7 +226,8 @@ public class ComputerPlayer> extends PlayerImpl i return true; } } - return false; + if (!target.isRequired()) + return false; } if (target instanceof TargetDiscard) { findPlayables(game); @@ -243,7 +245,8 @@ public class ComputerPlayer> extends PlayerImpl i return true; } } - return false; + if (!target.isRequired()) + return false; } if (target instanceof TargetControlledPermanent) { List targets; @@ -271,7 +274,8 @@ public class ComputerPlayer> extends PlayerImpl i return true; } } - return false; + if (!target.isRequired()) + return false; } if (target instanceof TargetCreatureOrPlayer) { List targets; @@ -300,7 +304,8 @@ public class ComputerPlayer> extends PlayerImpl i return true; } } - return false; + if (!target.isRequired()) + return false; } throw new IllegalStateException("Target wasn't handled. class:" + target.getClass().toString()); } @@ -484,10 +489,13 @@ public class ComputerPlayer> extends PlayerImpl i for (Mana mana: options) { for (Mana avail: available) { if (mana.enough(avail)) { - if (card.getCardType().contains(CardType.INSTANT)) - playableInstant.add(card); - else - playableNonInstant.add(card); + SpellAbility ability = card.getSpellAbility(); + if (ability != null && ability.canActivate(playerId, game)) { + if (card.getCardType().contains(CardType.INSTANT)) + playableInstant.add(card); + else + playableNonInstant.add(card); + } } else { if (!playableInstant.contains(card) && !playableNonInstant.contains(card)) diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java index 5400751b70..67ec0288cb 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java @@ -160,6 +160,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { logger.debug("simulating pre combat actions -----------------------------------------------------------------------------------------"); addActionsTimed(new FilterAbility()); +// addActions(root, new FilterAbility(), maxDepth, Integer.MIN_VALUE, Integer.MAX_VALUE); if (root.children.size() > 0) { root = root.children.get(0); actions = new LinkedList(root.abilities); @@ -176,6 +177,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { root = new SimulationNode(null, sim, maxDepth, playerId); logger.debug("simulating post combat actions ----------------------------------------------------------------------------------------"); addActionsTimed(new FilterAbility()); +// addActions(root, new FilterAbility(), maxDepth, Integer.MIN_VALUE, Integer.MAX_VALUE); if (root.children.size() > 0) { root = root.children.get(0); actions = new LinkedList(root.abilities); @@ -296,8 +298,8 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { } else if (!counter) { finishCombat(game); - val = GameStateEvaluator.evaluate(playerId, game); -// val = simulateCounterAttack(game, node, depth, alpha, beta); +// val = GameStateEvaluator.evaluate(playerId, game); + val = simulateCounterAttack(game, node, depth, alpha, beta); } } if (val == null) @@ -326,16 +328,16 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { break; } Game sim = game.copy(); - UUID defenderId = game.getOpponents(playerId).iterator().next(); + UUID defenderId = game.getOpponents(attackerId).iterator().next(); for (CombatGroup group: engagement.getGroups()) { for (UUID attackId: group.getAttackers()) { sim.getPlayer(attackerId).declareAttacker(attackId, defenderId, sim); } } - sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId)); + sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, attackerId, attackerId)); SimulationNode newNode = new SimulationNode(node, sim, depth, attackerId); if (logger.isDebugEnabled()) - logger.debug("simulating attack for player:" + game.getPlayer(newNode.getPlayerId()).getName()); + logger.debug("simulating attack for player:" + game.getPlayer(attackerId).getName()); sim.checkStateAndTriggered(); while (!sim.getStack().isEmpty()) { sim.getStack().resolve(sim); @@ -399,10 +401,10 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { } } } - sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId)); + sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId)); SimulationNode newNode = new SimulationNode(node, sim, depth, defenderId); if (logger.isDebugEnabled()) - logger.debug("simulating block for player:" + game.getPlayer(newNode.getPlayerId()).getName()); + logger.debug("simulating block for player:" + game.getPlayer(defenderId).getName()); sim.checkStateAndTriggered(); while (!sim.getStack().isEmpty()) { sim.getStack().resolve(sim); @@ -455,9 +457,9 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { } Integer val = null; if (!game.isGameOver()) { - logger.debug("simulating -- counter attack"); simulateToEnd(game); game.getState().setActivePlayerId(game.getState().getPlayerList(game.getActivePlayerId()).getNext()); + logger.debug("simulating -- counter attack for player " + game.getPlayer(game.getActivePlayerId()).getName()); game.getTurn().setPhase(new BeginningPhase()); if (game.getPhase().beginPhase(game, game.getActivePlayerId())) { simulateStep(game, new UntapStep()); diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java index 90a8b0ec58..5e02552540 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java @@ -59,7 +59,7 @@ public class GameStateEvaluator { int score = lifeScore + permanentScore + handScore; if (logger.isDebugEnabled()) - logger.debug("game state evaluated to- lifeScore:" + lifeScore + " permanentScore:" + permanentScore + " handScore:" + handScore + " total:" + score); + logger.debug("game state for player " + player.getName() + " evaluated to- lifeScore:" + lifeScore + " permanentScore:" + permanentScore + " handScore:" + handScore + " total:" + score); return score; } diff --git a/Mage.Server/plugins/mage-player-ai.jar b/Mage.Server/plugins/mage-player-ai.jar index 45016d5014..1e7af9d1ad 100644 Binary files a/Mage.Server/plugins/mage-player-ai.jar and b/Mage.Server/plugins/mage-player-ai.jar differ diff --git a/Mage.Server/plugins/mage-player-aiminimax.jar b/Mage.Server/plugins/mage-player-aiminimax.jar index 72624ad402..cbb118befe 100644 Binary files a/Mage.Server/plugins/mage-player-aiminimax.jar and b/Mage.Server/plugins/mage-player-aiminimax.jar differ diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 1b596b3549..849d5fc582 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -36,8 +36,6 @@ import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -56,11 +54,11 @@ import mage.players.Player; import mage.server.ChatManager; import mage.server.util.ThreadExecutor; import mage.sets.Sets; -import mage.util.Logging; import mage.view.AbilityPickerView; import mage.view.CardsView; import mage.view.GameView; import mage.view.ChatMessage.MessageColor; +import org.apache.log4j.Logger; /** * @@ -69,7 +67,7 @@ import mage.view.ChatMessage.MessageColor; public class GameController implements GameCallback { private static ExecutorService gameExecutor = ThreadExecutor.getInstance().getGameExecutor(); - private final static Logger logger = Logging.getLogger(GameController.class.getName()); + private final static Logger logger = Logger.getLogger(GameController.class); public static final String INIT_FILE_PATH = "config" + File.separator + "init.txt"; private ConcurrentHashMap gameSessions = new ConcurrentHashMap(); @@ -104,7 +102,7 @@ public class GameController implements GameCallback { break; case INFO: ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK); - logger.finest(game.getId() + " " + event.getMessage()); + logger.debug(game.getId() + " " + event.getMessage()); break; case REVEAL: revealCards(event.getMessage(), event.getCards()); @@ -178,7 +176,7 @@ public class GameController implements GameCallback { if (gameFuture == null) { for (final Entry entry: gameSessions.entrySet()) { if (!entry.getValue().init(getGameView(entry.getKey()))) { - logger.severe("Unable to initialize client"); + logger.fatal("Unable to initialize client"); //TODO: generate client error message return; } @@ -238,7 +236,7 @@ public class GameController implements GameCallback { card.putOntoBattlefield(game, Zone.OUTSIDE, null, playerId); } } catch (GameException ex) { - logger.warning(ex.getMessage()); + logger.warn(ex.getMessage()); } addCardsForTesting(game); updateGame(); @@ -434,7 +432,7 @@ public class GameController implements GameCallback { File f = new File(INIT_FILE_PATH); Pattern pattern = Pattern.compile("([a-zA-Z]*):([\\w]*):([a-zA-Z ,\\-.!'\\d]*):([\\d]*)"); if (!f.exists()) { - logger.warning("Couldn't find init file: " + INIT_FILE_PATH); + logger.warn("Couldn't find init file: " + INIT_FILE_PATH); return; } @@ -444,7 +442,7 @@ public class GameController implements GameCallback { try { while (scanner.hasNextLine()) { String line = scanner.nextLine().trim(); - if (line.startsWith("#")) continue; + if (line.trim().length() == 0 || line.startsWith("#")) continue; Matcher m = pattern.matcher(line); if (m.matches()) { @@ -476,14 +474,14 @@ public class GameController implements GameCallback { game.loadCards(cards, player.getId()); swapWithAnyCard(game, player, card, gameZone); } else { - logger.severe("Couldn't find a card: " + cardName); + logger.fatal("Couldn't find a card: " + cardName); } } } else { - logger.warning("Was skipped: " + line); + logger.warn("Was skipped: " + line); } } else { - logger.warning("Init string wasn't parsed: " + line); + logger.warn("Init string wasn't parsed: " + line); } } } @@ -491,7 +489,7 @@ public class GameController implements GameCallback { scanner.close(); } } catch (Exception e) { - logger.log(Level.SEVERE, "", e); + logger.fatal("", e); } } diff --git a/Mage.Sets/src/mage/sets/conflux/MartialCoup.java b/Mage.Sets/src/mage/sets/conflux/MartialCoup.java index c34dd17e61..25fe18615e 100644 --- a/Mage.Sets/src/mage/sets/conflux/MartialCoup.java +++ b/Mage.Sets/src/mage/sets/conflux/MartialCoup.java @@ -90,8 +90,8 @@ class MartialCoupEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int amount = 0; - if (source.getManaCosts().getVariableCosts().size() > 0) { - amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); + if (source.getManaCostsToPay().getVariableCosts().size() > 0) { + amount = source.getManaCostsToPay().getVariableCosts().get(0).getAmount(); } if (amount > 4) { diff --git a/Mage.Sets/src/mage/sets/magic2010/Earthquake.java b/Mage.Sets/src/mage/sets/magic2010/Earthquake.java index 81423c5d42..e361e1a1a0 100644 --- a/Mage.Sets/src/mage/sets/magic2010/Earthquake.java +++ b/Mage.Sets/src/mage/sets/magic2010/Earthquake.java @@ -93,7 +93,7 @@ class EarthquakeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - int amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); + int amount = source.getManaCostsToPay().getVariableCosts().get(0).getAmount(); for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { permanent.damage(amount, source.getId(), game, true, false); diff --git a/Mage.Sets/src/mage/sets/magic2010/Fireball.java b/Mage.Sets/src/mage/sets/magic2010/Fireball.java index 3b6f8ab590..fe6e07fa27 100644 --- a/Mage.Sets/src/mage/sets/magic2010/Fireball.java +++ b/Mage.Sets/src/mage/sets/magic2010/Fireball.java @@ -91,7 +91,7 @@ class FireballEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int numTargets = source.getTargets().get(0).getTargets().size(); - int damage = source.getManaCosts().getVariableCosts().get(0).getAmount(); + int damage = source.getManaCostsToPay().getVariableCosts().get(0).getAmount(); if (numTargets > 0) { int damagePer = damage/numTargets; if (damagePer > 0) { diff --git a/Mage.Sets/src/mage/sets/magic2010/MindSpring.java b/Mage.Sets/src/mage/sets/magic2010/MindSpring.java index b63406a77e..17d3d4d541 100644 --- a/Mage.Sets/src/mage/sets/magic2010/MindSpring.java +++ b/Mage.Sets/src/mage/sets/magic2010/MindSpring.java @@ -84,7 +84,7 @@ class MindSpringEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - int amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); + int amount = source.getManaCostsToPay().getVariableCosts().get(0).getAmount(); Player player = game.getPlayer(source.getControllerId()); if (player != null) { player.drawCards(amount, game); diff --git a/Mage.Sets/src/mage/sets/magic2010/ProteanHydra.java b/Mage.Sets/src/mage/sets/magic2010/ProteanHydra.java index 3577003801..c6765dacbc 100644 --- a/Mage.Sets/src/mage/sets/magic2010/ProteanHydra.java +++ b/Mage.Sets/src/mage/sets/magic2010/ProteanHydra.java @@ -99,7 +99,7 @@ public class ProteanHydra extends CardImpl { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { - int amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); + int amount = source.getManaCostsToPay().getVariableCosts().get(0).getAmount(); permanent.addCounters(new PlusOneCounter(amount)); } return true; diff --git a/Mage.Sets/src/mage/sets/magic2011/VengefulArchon.java b/Mage.Sets/src/mage/sets/magic2011/VengefulArchon.java index c2474954af..facf503bf0 100644 --- a/Mage.Sets/src/mage/sets/magic2011/VengefulArchon.java +++ b/Mage.Sets/src/mage/sets/magic2011/VengefulArchon.java @@ -102,8 +102,8 @@ class VengefulArchonEffect extends PreventionEffectImpl { @Override public void init(Ability source, Game game) { super.init(source, game); - if (source.getManaCosts().getVariableCosts().size() > 0) - amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); + if (source.getManaCostsToPay().getVariableCosts().size() > 0) + amount = source.getManaCostsToPay().getVariableCosts().get(0).getAmount(); } @Override diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/AccorderPaladin.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/AccorderPaladin.java new file mode 100644 index 0000000000..bcccaf8bdb --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/AccorderPaladin.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.mirrodinbesieged; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.keyword.BattleCryAbility; +import mage.cards.CardImpl; + +/** + * + * @author Loki + */ +public class AccorderPaladin extends CardImpl { + + public AccorderPaladin (UUID ownerId) { + super(ownerId, 1, "Accorder Paladin", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "MBS"; + this.subtype.add("Human"); + this.subtype.add("Knight"); + this.color.setWhite(true); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + this.addAbility(new BattleCryAbility()); + } + + public AccorderPaladin (final AccorderPaladin card) { + super(card); + } + + @Override + public AccorderPaladin copy() { + return new AccorderPaladin(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/ArdentRecruit.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/ArdentRecruit.java new file mode 100644 index 0000000000..d4dbba3450 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/ArdentRecruit.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.mirrodinbesieged; + +import java.util.UUID; + +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.Metalcraft; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.common.continious.BoostSourceEffect; +import mage.cards.CardImpl; + +/** + * @author Loki + */ +public class ArdentRecruit extends CardImpl { + + private final String myText = "Metalcraft - Ardent Recruit gets +2/+2 as long as you control three or more artifacts"; + + public ArdentRecruit(UUID ownerId) { + super(ownerId, 2, "Ardent Recruit", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{W}"); + this.expansionSetCode = "MBS"; + this.subtype.add("Human"); + this.subtype.add("Soldier"); + this.color.setWhite(true); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + ContinuousEffect boostSource = new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield); + ConditionalContinousEffect effect = new ConditionalContinousEffect(boostSource, Metalcraft.getInstance(), myText); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + } + + public ArdentRecruit(final ArdentRecruit card) { + super(card); + } + + @Override + public ArdentRecruit copy() { + return new ArdentRecruit(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/Flensermite.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/Flensermite.java new file mode 100644 index 0000000000..1d93cbd14a --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/Flensermite.java @@ -0,0 +1,67 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.mirrodinbesieged; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.keyword.InfectAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; + +/** + * + * @author Loki + */ +public class Flensermite extends CardImpl { + + public Flensermite (UUID ownerId) { + super(ownerId, 41, "Flensermite", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.expansionSetCode = "MBS"; + this.subtype.add("Gremlin"); + this.color.setBlack(true); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + this.addAbility(InfectAbility.getInstance()); + this.addAbility(LifelinkAbility.getInstance()); + } + + public Flensermite (final Flensermite card) { + super(card); + } + + @Override + public Flensermite copy() { + return new Flensermite(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/GoblinWardriver.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/GoblinWardriver.java new file mode 100644 index 0000000000..af579fe061 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/GoblinWardriver.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.mirrodinbesieged; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.keyword.BattleCryAbility; +import mage.cards.CardImpl; + +/** + * + * @author Loki + */ +public class GoblinWardriver extends CardImpl { + + public GoblinWardriver (UUID ownerId) { + super(ownerId, 64, "Goblin Wardriver", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{R}{R}"); + this.expansionSetCode = "MBS"; + this.subtype.add("Goblin"); + this.subtype.add("Warrior"); + this.color.setRed(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + this.addAbility(new BattleCryAbility()); + } + + public GoblinWardriver (final GoblinWardriver card) { + super(card); + } + + @Override + public GoblinWardriver copy() { + return new GoblinWardriver(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/GustSkimmer.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/GustSkimmer.java new file mode 100644 index 0000000000..ed2e057b54 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/GustSkimmer.java @@ -0,0 +1,67 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.mirrodinbesieged; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; + +/** + * + * @author Loki + */ +public class GustSkimmer extends CardImpl { + + public GustSkimmer (UUID ownerId) { + super(ownerId, 108, "Gust-Skimmer", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); + this.expansionSetCode = "MBS"; + this.subtype.add("Insect"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{U}"))); + } + + public GustSkimmer (final GustSkimmer card) { + super(card); + } + + @Override + public GustSkimmer copy() { + return new GustSkimmer(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/LoxodonPartisan.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/LoxodonPartisan.java new file mode 100644 index 0000000000..d02632fbca --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/LoxodonPartisan.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.mirrodinbesieged; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.keyword.BattleCryAbility; +import mage.cards.CardImpl; + +/** + * + * @author Loki + */ +public class LoxodonPartisan extends CardImpl { + + public LoxodonPartisan (UUID ownerId) { + super(ownerId, 12, "Loxodon Partisan", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{W}"); + this.expansionSetCode = "MBS"; + this.subtype.add("Elephant"); + this.subtype.add("Soldier"); + this.color.setWhite(true); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + this.addAbility(new BattleCryAbility()); + } + + public LoxodonPartisan (final LoxodonPartisan card) { + super(card); + } + + @Override + public LoxodonPartisan copy() { + return new LoxodonPartisan(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/ViridianClaw.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/ViridianClaw.java new file mode 100644 index 0000000000..8355c2f35b --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/ViridianClaw.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR P N CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.mirrodinbesieged; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continious.BoostEquippedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; + +/** + * + * @author Loki + */ +public class ViridianClaw extends CardImpl { + + public ViridianClaw (UUID ownerId) { + super(ownerId, 143, "Viridian Claw", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "MBS"; + this.subtype.add("Equipment"); + this.addAbility(new EquipAbility(Constants.Outcome.AddAbility, new GenericManaCost(3))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), Constants.AttachmentType.EQUIPMENT))); + } + + public ViridianClaw (final ViridianClaw card) { + super(card); + } + + @Override + public ViridianClaw copy() { + return new ViridianClaw(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/Exsanguinate.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/Exsanguinate.java index 5332ac3aaa..b60d402655 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/Exsanguinate.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/Exsanguinate.java @@ -76,7 +76,7 @@ class ExsanguinateEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int loseLife = 0; - int damage = source.getManaCosts().getVariableCosts().get(0).getAmount(); + int damage = source.getManaCostsToPay().getVariableCosts().get(0).getAmount(); for (UUID opponentId : game.getOpponents(source.getControllerId())) { loseLife += game.getPlayer(opponentId).loseLife(damage, game); } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/SigilofDistinction.java b/Mage.Sets/src/mage/sets/shardsofalara/SigilofDistinction.java index 2d524a64d0..98e3cac478 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/SigilofDistinction.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/SigilofDistinction.java @@ -85,7 +85,7 @@ class SigilofDistinctionEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - int amount = source.getManaCosts().getVariableCosts().get(0).getAmount(); + int amount = source.getManaCostsToPay().getVariableCosts().get(0).getAmount(); Permanent p = game.getPermanent(source.getSourceId()); if (p != null) { p.addCounters(CounterType.CHARGE.createInstance(amount)); diff --git a/Mage.Tests/plugins/mage-player-aiminimax.jar b/Mage.Tests/plugins/mage-player-aiminimax.jar index bcc39cedd2..cbb118befe 100644 Binary files a/Mage.Tests/plugins/mage-player-aiminimax.jar and b/Mage.Tests/plugins/mage-player-aiminimax.jar differ diff --git a/Mage/src/mage/abilities/keyword/BattleCryAbility.java b/Mage/src/mage/abilities/keyword/BattleCryAbility.java new file mode 100644 index 0000000000..e3a8d2e960 --- /dev/null +++ b/Mage/src/mage/abilities/keyword/BattleCryAbility.java @@ -0,0 +1,26 @@ +package mage.abilities.keyword; + +import mage.Constants; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.continious.BoostControlledEffect; +import mage.filter.common.FilterAttackingCreature; + +public class BattleCryAbility extends AttacksTriggeredAbility { + public BattleCryAbility() { + super(new BoostControlledEffect(1, 0, Constants.Duration.EndOfTurn, new FilterAttackingCreature(), true), false); + } + + public BattleCryAbility(final BattleCryAbility ability) { + super(ability); + } + + @Override + public String getRule() { + return "Battle cry (Whenever this creature attacks, each other attacking creature gets +1/+0 until end of turn.)"; + } + + @Override + public BattleCryAbility copy() { + return new BattleCryAbility(this); + } +} diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 5833e957d9..e02ccec4ed 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -325,6 +325,9 @@ public abstract class GameImpl> implements Game, Serializa for (Player player: state.getPlayers().values()) { player.init(this, testMode); } + for (Player player: state.getPlayers().values()) { + player.beginTurn(this); + } fireInformEvent("game has started"); saveState(); @@ -344,7 +347,7 @@ public abstract class GameImpl> implements Game, Serializa else { choosingPlayer = this.getPlayer(choosingPlayerId); } - if (choosingPlayer.chooseTarget(Outcome.Benefit, targetPlayer, null, this)) { + if (choosingPlayer.choose(Outcome.Benefit, targetPlayer, this)) { startingPlayerId = ((List)targetPlayer.getTargets()).get(0); fireInformEvent(state.getPlayer(startingPlayerId).getName() + " will start"); } diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index f1b12a0adb..2138df47df 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -168,7 +168,6 @@ public abstract class PlayerImpl> implements Player, Ser this.left = false; this.passed = false; this.passedTurn = false; - findRange(game); } @Override diff --git a/pom.xml b/pom.xml index b259abec65..c387f129bb 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ mage.googlecode.com - http://mage.googlecode.com/svn/trunk/repository + https://mage.googlecode.com/hg/repository/ jetlang.googlecode.com