diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index de56a98fef..f7420e2613 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -81,7 +81,7 @@ import org.apache.log4j.Logger; */ public class DeckEditorPanel extends javax.swing.JPanel { - private static final Logger LOGGER = Logger.getLogger(DeckEditorPanel.class); + private static final Logger logger = Logger.getLogger(DeckEditorPanel.class); private final JFileChooser fcSelectDeck; private final JFileChooser fcImportDeck; private Deck deck = new Deck(); @@ -690,7 +690,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } catch (GameException ex) { JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); } catch (Exception ex) { - LOGGER.fatal(ex); + logger.fatal(ex); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } @@ -722,7 +722,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { setCursor(new Cursor(Cursor.WAIT_CURSOR)); Sets.saveDeck(fileName, deck.getDeckCardLists()); } catch (Exception ex) { - LOGGER.fatal(ex); + logger.fatal(ex); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } @@ -771,7 +771,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Unknown deck format", "Error importing deck", JOptionPane.ERROR_MESSAGE); } } catch (Exception ex) { - LOGGER.fatal(ex); + logger.fatal(ex); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } @@ -877,7 +877,7 @@ class ImportFilter extends FileFilter { class UpdateDeckTask extends SwingWorker { - private static final Logger LOGGER = Logger.getLogger(UpdateDeckTask.class); + private static final Logger logger = Logger.getLogger(UpdateDeckTask.class); private final Session session; private final UUID tableId; private final Deck deck; @@ -902,7 +902,7 @@ class UpdateDeckTask extends SwingWorker { try { get(); } catch (InterruptedException | ExecutionException ex) { - LOGGER.fatal("Update Matches Task error", ex); + logger.fatal("Update Matches Task error", ex); } catch (CancellationException ex) { } } diff --git a/Mage.Client/src/main/java/mage/client/util/stats/UpdateMemUsageTask.java b/Mage.Client/src/main/java/mage/client/util/stats/UpdateMemUsageTask.java index 8851fd7d7c..b3c6366b56 100644 --- a/Mage.Client/src/main/java/mage/client/util/stats/UpdateMemUsageTask.java +++ b/Mage.Client/src/main/java/mage/client/util/stats/UpdateMemUsageTask.java @@ -18,7 +18,7 @@ public class UpdateMemUsageTask extends SwingWorker { private final JLabel jLabelToDisplayInfo; - private static final Logger LOGGER = Logger.getLogger(UpdateMemUsageTask.class); + private static final Logger logger = Logger.getLogger(UpdateMemUsageTask.class); public UpdateMemUsageTask(JLabel jLabelToDisplayInfo) { this.jLabelToDisplayInfo = jLabelToDisplayInfo; @@ -51,7 +51,7 @@ public class UpdateMemUsageTask extends SwingWorker { try { get(); } catch (InterruptedException | ExecutionException ex) { - LOGGER.fatal("Update Memory Usage error", ex); + logger.fatal("Update Memory Usage error", ex); } catch (CancellationException ex) { } } diff --git a/Mage.Sets/src/mage/sets/magicorigins/MageRingNetwork.java b/Mage.Sets/src/mage/sets/magicorigins/MageRingNetwork.java index efab88d84d..f901d201cd 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/MageRingNetwork.java +++ b/Mage.Sets/src/mage/sets/magicorigins/MageRingNetwork.java @@ -63,12 +63,12 @@ public class MageRingNetwork extends CardImpl { new ManaCostsImpl("{1}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); - // {T}, Remove X storage counters from Mage-Ring Network: Add {x} to your mana pool. + // {T}, Remove any number of storage counters from Mage-Ring Network: Add {C} to your mana pool for each storage counter removed this way. ability = new DynamicManaAbility( Mana.ColorlessMana(1), new RemovedCountersForCostValue(), new TapSourceCost(), - "Add {X} to your mana pool", + "Add {C} to your mana pool for each storage counter removed this way", true, new CountersCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), "Remove X storage counters from {this}")); diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/LeoninArbiter.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/LeoninArbiter.java index e86bc9a5e1..2ca7d97385 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/LeoninArbiter.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/LeoninArbiter.java @@ -57,7 +57,7 @@ import mage.game.permanent.Permanent; */ public class LeoninArbiter extends CardImpl { - private static final String keyString = "_ignoreEffectForTurn"; + private static final String KEY_STRING = "_ignoreEffectForTurn"; public LeoninArbiter(UUID ownerId) { super(ownerId, 14, "Leonin Arbiter", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}"); @@ -69,10 +69,10 @@ public class LeoninArbiter extends CardImpl { this.toughness = new MageInt(2); // Players can't search libraries. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LeoninArbiterCantSearchEffect(keyString))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LeoninArbiterCantSearchEffect(KEY_STRING))); // Any player may pay {2} for that player to ignore this effect until end of turn. - this.addAbility(new LeoninArbiterSpecialAction(keyString)); + this.addAbility(new LeoninArbiterSpecialAction(KEY_STRING)); } public LeoninArbiter(final LeoninArbiter card) { @@ -132,7 +132,7 @@ class LeoninArbiterIgnoreEffect extends OneShotEffect { // Using a Map.Entry since there is no pair class long zoneChangeCount = permanent.getZoneChangeCounter(game); long turnNum = game.getTurnNum(); - Long activationState = zoneChangeCount << 32 | turnNum & 0xFFFFFFFFL; + Long activationState = zoneChangeCount << 32 | turnNum & 0xFFFFFFFFL; Map.Entry> turnIgnoringPlayersPair = (Map.Entry>) game.getState().getValue(key); if (turnIgnoringPlayersPair == null || !activationState.equals(turnIgnoringPlayersPair.getKey())) { @@ -169,13 +169,13 @@ class LeoninArbiterCantSearchEffect extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { - boolean applies = true; + boolean applies = true; String key = permanent.getId() + keyString; Map.Entry> turnIgnoringPlayersPair = (Map.Entry>) game.getState().getValue(key); if (turnIgnoringPlayersPair != null) { long zoneChangeCount = permanent.getZoneChangeCounter(game); long turnNum = game.getTurnNum(); - Long activationState = zoneChangeCount << 32 | turnNum & 0xFFFFFFFFL; + Long activationState = zoneChangeCount << 32 | turnNum & 0xFFFFFFFFL; if (activationState.equals(turnIgnoringPlayersPair.getKey())) { applies = !turnIgnoringPlayersPair.getValue().contains(event.getPlayerId()); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/DrawTriggeredTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/DrawTriggeredTest.java index ce6196e749..b4a5e27bb6 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/DrawTriggeredTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/DrawTriggeredTest.java @@ -90,4 +90,47 @@ public class DrawTriggeredTest extends CardTestPlayerBase { assertHandCount(playerA, 4); // 2 * 2 from Sphinx = 4 } + + /** + * two consecrated sphinxes do not work properly, only gives one player + * additional draw + * + */ + @Test + public void TwoConsecratedSphinxDifferentPlayers() { + // Flying + // Whenever an opponent draws a card, you may draw two cards. + addCard(Zone.BATTLEFIELD, playerA, "Consecrated Sphinx", 1); + + // Flying + // Whenever an opponent draws a card, you may draw two cards. + addCard(Zone.BATTLEFIELD, playerB, "Consecrated Sphinx", 1); + + setChoice(playerA, "Yes"); + setChoice(playerA, "No"); + setChoice(playerA, "No"); + + setChoice(playerB, "Yes"); + setChoice(playerB, "No"); + setStopAt(2, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertHandCount(playerB, 3); // 1 from start of turn 1 and 4 from Opponents draw of 2 cards + assertHandCount(playerA, 2); // 2 from Sphinx triggered by the normal draw + + } + + @Test + public void TwoConsecratedSphinxSamePlayer() { + // Flying + // Whenever an opponent draws a card, you may draw two cards. + addCard(Zone.BATTLEFIELD, playerA, "Consecrated Sphinx", 2); + + setStopAt(2, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertHandCount(playerB, 1); // 1 from start of turn 1 and 4 from Opponents draw of 2 cards + assertHandCount(playerA, 4); // 2 from Sphinx triggered by the normal draw + + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/HeartbeatOfSpringTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/HeartbeatOfSpringTest.java new file mode 100644 index 0000000000..7993861ed5 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/HeartbeatOfSpringTest.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 org.mage.test.cards.triggers; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class HeartbeatOfSpringTest extends CardTestPlayerBase { + + /** + * Heartbeat of Spring does not function on urza's + */ + @Test + public void testWorksForUrzasLand() { + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + // {T}: Add {C} to your mana pool. If you control an Urza's Power-Plant and an Urza's Tower, add {C}{C} to your mana pool instead. + addCard(Zone.HAND, playerA, "Urza's Mine", 1); + // Whenever a player taps a land for mana, that player adds one mana to his or her mana pool of any type that land produced. + addCard(Zone.HAND, playerA, "Heartbeat of Spring"); // {2}{G} + // Whenever a player casts a white spell, you may gain 1 life. + addCard(Zone.HAND, playerA, "Angel's Feather"); // {2} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Heartbeat of Spring"); + playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Urza's Mine"); + + activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}:"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Angel's Feather"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Heartbeat of Spring", 1); + assertPermanentCount(playerA, "Angel's Feather", 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 6ba7999fe6..8618a73267 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -393,6 +393,7 @@ public class TestPlayer implements Player { command = command.substring(command.indexOf("manaActivate:") + 13); String[] groups = command.split("\\$"); List manaObjects = computerPlayer.getAvailableManaProducers(game); + for (MageObject mageObject : manaObjects) { if (mageObject instanceof Permanent) { for (Ability manaAbility : ((Permanent) mageObject).getAbilities(game).getAvailableManaAbilities(Zone.BATTLEFIELD, game)) { diff --git a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java index f6b6e8b7ac..0f45a8e717 100644 --- a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java @@ -321,7 +321,7 @@ public class ManaOptionsTest extends CardTestPlayerBase { public void testMageRingNetwork2() { // {T}: Add {C} to your mana pool. // {T}, {1} : Put a storage counter on Mage-Ring Network. - // {T}, Remove X storage counters from Mage-Ring Network: Add {X} to your mana pool. + // {T}, Remove any number of storage counters from Mage-Ring Network: Add {C} to your mana pool for each storage counter removed this way. addCard(Zone.BATTLEFIELD, playerA, "Mage-Ring Network", 1); addCounters(1, PhaseStep.UPKEEP, playerA, "Mage-Ring Network", CounterType.STORAGE, 4); addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); @@ -332,9 +332,8 @@ public class ManaOptionsTest extends CardTestPlayerBase { ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); - Assert.assertEquals("mana variations don't fit", 2, manaOptions.size()); - Assert.assertEquals("{C}{W}{B}", getManaOption(0, manaOptions)); - Assert.assertEquals("{4}{W}{B}", getManaOption(1, manaOptions)); + Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); + Assert.assertEquals("{C}{C}{C}{C}{W}{B}", getManaOption(0, manaOptions)); } @Test diff --git a/Mage/src/main/java/mage/Mana.java b/Mage/src/main/java/mage/Mana.java index f4abecd691..be05bf6f82 100644 --- a/Mage/src/main/java/mage/Mana.java +++ b/Mage/src/main/java/mage/Mana.java @@ -347,14 +347,17 @@ public class Mana implements Comparable, Serializable, Copyable { if (black > 0) { black--; generic++; + continue; } if (colorless > 0) { colorless--; generic++; + continue; } if (any > 0) { any--; generic++; + continue; } if (oldColorless == generic) { throw new ArithmeticException("Not enough mana to pay colorless"); diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 5ec8c1a88c..4440f5b458 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -426,10 +426,10 @@ public abstract class AbilityImpl implements Ability { if (cost instanceof TapSourceCost) { Mana mana = null; Effect effect = getEffects().get(0); - if (effect instanceof BasicManaEffect) { - mana = ((BasicManaEffect) effect).getMana(game, this); - } else if (effect instanceof DynamicManaEffect) { + if (effect instanceof DynamicManaEffect) { mana = ((DynamicManaEffect) effect).getMana(game, this); + } else if (effect instanceof BasicManaEffect) { + mana = ((BasicManaEffect) effect).getMana(game, this); } if (mana != null && mana.getAny() == 0) { // if mana == null or Any > 0 the event has to be fired in the mana effect to know which mana was produced ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, sourceId, sourceId, controllerId, mana); diff --git a/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java b/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java index 309414d42d..016369ac85 100644 --- a/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java @@ -85,7 +85,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge if (isOptional()) { MageObject object = game.getObject(getSourceId()); Player player = game.getPlayer(this.getControllerId()); - if (player != null) { + if (player != null && object != null) { if (!player.chooseUse(getEffects().get(0).getOutcome(), (object != null ? this.getRule(object.getLogName()) : this.getRule()), this, game)) { return false; } @@ -129,22 +129,18 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge newRule.insert(4, "may "); superRule = newRule.toString(); } - } else { - if (this.getTargets().isEmpty() - || ruleLow.startsWith("exile") - || ruleLow.startsWith("destroy") - || ruleLow.startsWith("return") - || ruleLow.startsWith("tap") - || ruleLow.startsWith("untap") - || ruleLow.startsWith("put") - || ruleLow.startsWith("remove") - || ruleLow.startsWith("counter")) { - sb.append("you may "); - } else { - if (!ruleLow.startsWith("its controller may")) { - sb.append("you may have "); - } - } + } else if (this.getTargets().isEmpty() + || ruleLow.startsWith("exile") + || ruleLow.startsWith("destroy") + || ruleLow.startsWith("return") + || ruleLow.startsWith("tap") + || ruleLow.startsWith("untap") + || ruleLow.startsWith("put") + || ruleLow.startsWith("remove") + || ruleLow.startsWith("counter")) { + sb.append("you may "); + } else if (!ruleLow.startsWith("its controller may")) { + sb.append("you may have "); } } @@ -191,12 +187,10 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge if (isLeavesTheBattlefieldTrigger()) { if (event.getType().equals(EventType.DESTROYED_PERMANENT)) { source = game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD); + } else if (((ZoneChangeEvent) event).getTarget() != null) { + source = ((ZoneChangeEvent) event).getTarget(); } else { - if (((ZoneChangeEvent) event).getTarget() != null) { - source = ((ZoneChangeEvent) event).getTarget(); - } else { - source = game.getLastKnownInformation(getSourceId(), ((ZoneChangeEvent) event).getZone()); - } + source = game.getLastKnownInformation(getSourceId(), ((ZoneChangeEvent) event).getZone()); } } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index d693b46363..f2bb07819d 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -83,7 +83,7 @@ import org.apache.log4j.Logger; */ public class ContinuousEffects implements Serializable { - private static final Logger LOGGER = Logger.getLogger(ContinuousEffects.class); + private static final Logger logger = Logger.getLogger(ContinuousEffects.class); private long order = 0; @@ -227,7 +227,7 @@ public class ContinuousEffects implements Serializable { } } } else { - LOGGER.error("No abilities for continuous effect: " + effect.toString()); + logger.error("No abilities for continuous effect: " + effect.toString()); } break; default: @@ -1095,10 +1095,10 @@ public class ContinuousEffects implements Serializable { public void addEffect(ContinuousEffect effect, Ability source) { if (effect == null) { - LOGGER.error("Effect is null: " + source.toString()); + logger.error("Effect is null: " + source.toString()); return; } else if (source == null) { - LOGGER.warn("Adding effect without ability : " + effect.toString()); + logger.warn("Adding effect without ability : " + effect.toString()); } switch (effect.getEffectType()) { case REPLACEMENT: @@ -1165,7 +1165,7 @@ public class ContinuousEffects implements Serializable { ability.setControllerId(controllerId); } } else if (!ability.getZone().equals(Zone.COMMAND)) { - LOGGER.fatal("Continuous effect for ability with no sourceId Ability: " + ability); + logger.fatal("Continuous effect for ability with no sourceId Ability: " + ability); } } } @@ -1236,7 +1236,7 @@ public class ContinuousEffects implements Serializable { } } } else { - LOGGER.error("Replacement effect without ability: " + entry.getKey().toString()); + logger.error("Replacement effect without ability: " + entry.getKey().toString()); } } return texts; @@ -1274,7 +1274,7 @@ public class ContinuousEffects implements Serializable { } } } else { - LOGGER.warn("Ability without sourceId:" + ability.getRule()); + logger.warn("Ability without sourceId:" + ability.getRule()); } } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DynamicManaEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DynamicManaEffect.java index 8dcdda4aa6..3ab765c7cc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DynamicManaEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DynamicManaEffect.java @@ -138,6 +138,8 @@ public class DynamicManaEffect extends BasicManaEffect { computedMana.setRed(count); } else if (mana.getWhite() > 0) { computedMana.setWhite(count); + } else if (mana.getColorless() > 0) { + computedMana.setColorless(count); } else if (mana.getAny() > 0) { if (netMana) { computedMana.setAny(count); diff --git a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java index 0dfc4b5540..56b416f212 100644 --- a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java +++ b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java @@ -1,4 +1,4 @@ - /* +/* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are @@ -132,20 +132,18 @@ public class ManaOptions extends ArrayList { } } } + } else // the ability has mana costs + if (netManas.size() == 1) { + subtractCostAddMana(ability.getManaCosts().getMana(), netManas.get(0), ability.getCosts().isEmpty()); } else { - // the ability has mana costs - if (netManas.size() == 1) { - subtractCostAddMana(ability.getManaCosts().getMana(), netManas.get(0), ability.getCosts().isEmpty()); - } else { - List copy = copy(); - this.clear(); - for (Mana netMana : netManas) { - for (Mana mana : copy) { - Mana newMana = new Mana(); - newMana.add(mana); - newMana.add(netMana); - subtractCostAddMana(ability.getManaCosts().getMana(), netMana, ability.getCosts().isEmpty()); - } + List copy = copy(); + this.clear(); + for (Mana netMana : netManas) { + for (Mana mana : copy) { + Mana newMana = new Mana(); + newMana.add(mana); + newMana.add(netMana); + subtractCostAddMana(ability.getManaCosts().getMana(), netMana, ability.getCosts().isEmpty()); } } } @@ -248,7 +246,7 @@ public class ManaOptions extends ArrayList { Mana oldMan = mana.copy(); if (mana.includesMana(cost)) { // colorless costs can be paid with different colored mana, can lead to different color combinations - if (cost.getGeneric() > 0 && cost.getGeneric() > mana.getGeneric()) { + if (cost.getGeneric() > 0 && cost.getGeneric() > (mana.getGeneric() + mana.getColorless())) { Mana coloredCost = cost.copy(); coloredCost.setGeneric(0); mana.subtract(coloredCost); diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 89872ea178..2b63c50aff 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -138,7 +138,7 @@ public abstract class GameImpl implements Game, Serializable { private static final int ROLLBACK_TURNS_MAX = 4; - private static final Logger LOGGER = Logger.getLogger(GameImpl.class); + private static final Logger logger = Logger.getLogger(GameImpl.class); private static final FilterPermanent FILTER_AURA = new FilterPermanent(); private static final FilterPermanent FILTER_EQUIPMENT = new FilterPermanent(); @@ -230,7 +230,7 @@ public abstract class GameImpl implements Game, Serializable { public GameImpl(final GameImpl game) { long t1 = 0; - if (LOGGER.isDebugEnabled()) { + if (logger.isDebugEnabled()) { t1 = System.currentTimeMillis(); } this.id = game.id; @@ -248,7 +248,7 @@ public abstract class GameImpl implements Game, Serializable { this.lkiExtended.putAll(game.lkiExtended); this.shortLivingLKI.putAll(game.shortLivingLKI); this.permanentsEntering.putAll(game.permanentsEntering); - if (LOGGER.isDebugEnabled()) { + if (logger.isDebugEnabled()) { copyCount++; copyTime += (System.currentTimeMillis() - t1); } @@ -577,7 +577,7 @@ public abstract class GameImpl implements Game, Serializable { boolean result = checkIfGameIsOver(); return result; } else { - LOGGER.debug("Game over for player Id: " + playerId + " gameId " + getId()); + logger.debug("Game over for player Id: " + playerId + " gameId " + getId()); leave(playerId); return true; } @@ -599,15 +599,15 @@ public abstract class GameImpl implements Game, Serializable { } if (remainingPlayers <= 1 || numLosers >= state.getPlayers().size() - 1) { end(); - if (remainingPlayers == 0 && LOGGER.isDebugEnabled()) { - LOGGER.debug("DRAW for gameId: " + getId()); + if (remainingPlayers == 0 && logger.isDebugEnabled()) { + logger.debug("DRAW for gameId: " + getId()); for (Player player : state.getPlayers().values()) { - LOGGER.debug("-- " + player.getName() + " left: " + (player.hasLeft() ? "Y" : "N") + " lost: " + (player.hasLost() ? "Y" : "N")); + logger.debug("-- " + player.getName() + " left: " + (player.hasLeft() ? "Y" : "N") + " lost: " + (player.hasLost() ? "Y" : "N")); } } for (Player player : state.getPlayers().values()) { if (!player.hasLeft() && !player.hasLost()) { - LOGGER.debug(new StringBuilder("Player ").append(player.getName()).append(" has won gameId: ").append(this.getId())); + logger.debug(new StringBuilder("Player ").append(player.getName()).append(" has won gameId: ").append(this.getId())); player.won(this); } } @@ -643,8 +643,8 @@ public abstract class GameImpl implements Game, Serializable { public int bookmarkState() { if (!simulation) { saveState(true); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Bookmarking state: " + gameStates.getSize()); + if (logger.isTraceEnabled()) { + logger.trace("Bookmarking state: " + gameStates.getSize()); } savedStates.push(gameStates.getSize() - 1); return savedStates.size(); @@ -772,7 +772,7 @@ public abstract class GameImpl implements Game, Serializable { sb.append("]"); count++; } - LOGGER.info(sb.toString()); + logger.info(sb.toString()); } } @@ -926,7 +926,7 @@ public abstract class GameImpl implements Game, Serializable { } Player startingPlayer = state.getPlayer(startingPlayerId); if (startingPlayer == null) { - LOGGER.debug("Starting player not found. playerId:" + startingPlayerId); + logger.debug("Starting player not found. playerId:" + startingPlayerId); return; } StringBuilder message = new StringBuilder(choosingPlayer.getLogName()).append(" chooses that "); @@ -1052,12 +1052,12 @@ public abstract class GameImpl implements Game, Serializable { UUID winnerIdFound = null; for (Player player : state.getPlayers().values()) { if (player.hasWon()) { - LOGGER.debug(player.getName() + " has won gameId: " + getId()); + logger.debug(player.getName() + " has won gameId: " + getId()); winnerIdFound = player.getId(); break; } if (!player.hasLost() && !player.hasLeft()) { - LOGGER.debug(player.getName() + " has not lost so he won gameId: " + this.getId()); + logger.debug(player.getName() + " has not lost so he won gameId: " + this.getId()); player.won(this); winnerIdFound = player.getId(); break; @@ -1089,7 +1089,7 @@ public abstract class GameImpl implements Game, Serializable { return player.getId(); } } - LOGGER.debug("Game was not possible to pick a choosing player. GameId:" + getId()); + logger.debug("Game was not possible to pick a choosing player. GameId:" + getId()); return null; } @@ -1106,7 +1106,7 @@ public abstract class GameImpl implements Game, Serializable { @Override public void end() { if (!state.isGameOver()) { - LOGGER.debug("END of gameId: " + this.getId()); + logger.debug("END of gameId: " + this.getId()); endTime = new Date(); state.endGame(); for (Player player : state.getPlayers().values()) { @@ -1175,7 +1175,7 @@ public abstract class GameImpl implements Game, Serializable { if (player != null) { player.timerTimeout(this); } else { - LOGGER.error(new StringBuilder("timerTimeout - player not found - playerId: ").append(playerId)); + logger.error(new StringBuilder("timerTimeout - player not found - playerId: ").append(playerId)); } } @@ -1185,7 +1185,7 @@ public abstract class GameImpl implements Game, Serializable { if (player != null) { player.idleTimeout(this); } else { - LOGGER.error(new StringBuilder("idleTimeout - player not found - playerId: ").append(playerId)); + logger.error(new StringBuilder("idleTimeout - player not found - playerId: ").append(playerId)); } } @@ -1193,7 +1193,7 @@ public abstract class GameImpl implements Game, Serializable { public synchronized void concede(UUID playerId) { Player player = state.getPlayer(playerId); if (player != null) { - LOGGER.debug("Player " + player.getName() + " concedes game " + this.getId()); + logger.debug("Player " + player.getName() + " concedes game " + this.getId()); fireInformEvent(player.getLogName() + " has conceded."); player.concede(this); } @@ -1306,10 +1306,10 @@ public abstract class GameImpl implements Game, Serializable { } } } catch (Exception ex) { - LOGGER.fatal("Game exception gameId: " + getId(), ex); + logger.fatal("Game exception gameId: " + getId(), ex); if ((ex instanceof NullPointerException) && errorContinueCounter == 1 && ex.getStackTrace() != null) { - LOGGER.fatal(ex.getStackTrace()); + logger.fatal(ex.getStackTrace()); } this.fireErrorEvent("Game exception occurred: ", ex); restoreState(bookmark, ""); @@ -1329,7 +1329,7 @@ public abstract class GameImpl implements Game, Serializable { } } } catch (Exception ex) { - LOGGER.fatal("Game exception ", ex); + logger.fatal("Game exception ", ex); this.fireErrorEvent("Game exception occurred: ", ex); this.end(); } finally { @@ -1736,7 +1736,7 @@ public abstract class GameImpl implements Game, Serializable { } if (spellAbility.getTargets().isEmpty()) { Permanent enchanted = this.getPermanent(perm.getAttachedTo()); - LOGGER.error("Aura without target: " + perm.getName() + " attached to " + (enchanted == null ? " null" : enchanted.getName())); + logger.error("Aura without target: " + perm.getName() + " attached to " + (enchanted == null ? " null" : enchanted.getName())); } else { Target target = spellAbility.getTargets().get(0); if (target instanceof TargetPermanent) { @@ -2091,7 +2091,7 @@ public abstract class GameImpl implements Game, Serializable { @Override public void debugMessage(String message) { - LOGGER.warn(message); + logger.warn(message); } @Override @@ -2115,7 +2115,7 @@ public abstract class GameImpl implements Game, Serializable { if (simulation) { return; } - LOGGER.trace("fireUpdatePlayersEvent"); + logger.trace("fireUpdatePlayersEvent"); tableEventSource.fireTableEvent(EventType.UPDATE, null, this); getState().clearLookedAt(); getState().clearRevealed(); @@ -2126,7 +2126,7 @@ public abstract class GameImpl implements Game, Serializable { if (simulation) { return; } - LOGGER.trace("fireGameEndIfo"); + logger.trace("fireGameEndIfo"); tableEventSource.fireTableEvent(EventType.END_GAME_INFO, null, this); } @@ -2212,10 +2212,10 @@ public abstract class GameImpl implements Game, Serializable { Player player = getPlayer(playerId); if (player == null || player.hasLeft()) { - LOGGER.debug("Player already left " + (player != null ? player.getName() : playerId)); + logger.debug("Player already left " + (player != null ? player.getName() : playerId)); return; } - LOGGER.debug("Start leave game: " + player.getName()); + logger.debug("Start leave game: " + player.getName()); player.leave(); if (checkIfGameIsOver()) { // no need to remove objects if only one player is left so the game is over @@ -2530,9 +2530,9 @@ public abstract class GameImpl implements Game, Serializable { try { Integer amount = Integer.parseInt(s[1]); player.setLife(amount, this); - LOGGER.info("Setting player's life: "); + logger.info("Setting player's life: "); } catch (NumberFormatException e) { - LOGGER.fatal("error setting life", e); + logger.fatal("error setting life", e); } }