diff --git a/Mage.Sets/src/mage/cards/g/GemstoneCaverns.java b/Mage.Sets/src/mage/cards/g/GemstoneCaverns.java index c461af2b965..aebc017e86e 100644 --- a/Mage.Sets/src/mage/cards/g/GemstoneCaverns.java +++ b/Mage.Sets/src/mage/cards/g/GemstoneCaverns.java @@ -30,18 +30,28 @@ package mage.cards.g; import java.util.UUID; import mage.Mana; import mage.abilities.Ability; -import mage.abilities.common.GemstoneCavernsAbility; +import mage.abilities.OpeningHandAction; +import mage.abilities.StaticAbility; import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.ExileFromHandCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalManaEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AddManaOfAnyColorEffect; import mage.abilities.effects.common.BasicManaEffect; import mage.abilities.mana.ConditionalManaAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInHand; /** * @@ -50,20 +60,20 @@ import mage.counters.CounterType; public class GemstoneCaverns extends CardImpl { public GemstoneCaverns(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.supertype.add("Legendary"); // If Gemstone Caverns is in your opening hand and you're not playing first, you may begin the game with Gemstone Caverns on the battlefield with a luck counter on it. If you do, exile a card from your hand. this.addAbility(new GemstoneCavernsAbility()); - + // {tap}: Add {C} to your mana pool. If Gemstone Caverns has a luck counter on it, instead add one mana of any color to your mana pool. Ability ability = new ConditionalManaAbility(Zone.BATTLEFIELD, new ConditionalManaEffect( - new AddManaOfAnyColorEffect(), - new BasicManaEffect(Mana.ColorlessMana(1)), - new SourceHasCounterCondition(CounterType.LUCK), - "Add {C} to your mana pool. If {this} has a luck counter on it, instead add one mana of any color to your mana pool."), - new TapSourceCost()); + new AddManaOfAnyColorEffect(), + new BasicManaEffect(Mana.ColorlessMana(1)), + new SourceHasCounterCondition(CounterType.LUCK), + "Add {C} to your mana pool. If {this} has a luck counter on it, instead add one mana of any color to your mana pool."), + new TapSourceCost()); this.addAbility(ability); } @@ -76,3 +86,78 @@ public class GemstoneCaverns extends CardImpl { return new GemstoneCaverns(this); } } + +class GemstoneCavernsAbility extends StaticAbility implements OpeningHandAction { + + public GemstoneCavernsAbility() { + super(Zone.HAND, new GemstoneCavernsEffect()); + } + + public GemstoneCavernsAbility(final GemstoneCavernsAbility ability) { + super(ability); + } + + @Override + public GemstoneCavernsAbility copy() { + return new GemstoneCavernsAbility(this); + } + + @Override + public String getRule() { + return "If {this} is in your opening hand and you're not playing first, you may begin the game with {this} on the battlefield with a luck counter on it. If you do, exile a card from your hand."; + } + + @Override + public boolean askUseOpeningHandAction(Card card, Player player, Game game) { + return player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getIdName() + " into play?", this, game); + } + + @Override + public boolean isOpeningHandActionAllowed(Card card, Player player, Game game) { + return !player.getId().equals(game.getStartingPlayerId()); + } + + @Override + public void doOpeningHandAction(Card card, Player player, Game game) { + this.resolve(game); + } + +} + +class GemstoneCavernsEffect extends OneShotEffect { + + GemstoneCavernsEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "you may begin the game with {this} on the battlefield with a luck counter on it. If you do, exile a card from your hand"; + } + + GemstoneCavernsEffect(final GemstoneCavernsEffect effect) { + super(effect); + } + + @Override + public GemstoneCavernsEffect copy() { + return new GemstoneCavernsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + Card card = game.getCard(source.getSourceId()); + if (card != null) { + if (card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId())) { + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + permanent.addCounters(CounterType.LUCK.createInstance(), game); + Cost cost = new ExileFromHandCost(new TargetCardInHand()); + if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game)) { + cost.pay(source, game, source.getSourceId(), source.getControllerId(), true, null); + } + } + } + } + } + return false; + } +} diff --git a/Mage/src/main/java/mage/abilities/OpeningHandAction.java b/Mage/src/main/java/mage/abilities/OpeningHandAction.java new file mode 100644 index 00000000000..6f7b2f8c433 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/OpeningHandAction.java @@ -0,0 +1,24 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities; + +import mage.cards.Card; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public interface OpeningHandAction { + + boolean askUseOpeningHandAction(Card card, Player player, Game game); + + boolean isOpeningHandActionAllowed(Card card, Player player, Game game); + + void doOpeningHandAction(Card card, Player player, Game game); + +} diff --git a/Mage/src/main/java/mage/abilities/common/ChancellorAbility.java b/Mage/src/main/java/mage/abilities/common/ChancellorAbility.java index b96049495dc..80e6c235b14 100644 --- a/Mage/src/main/java/mage/abilities/common/ChancellorAbility.java +++ b/Mage/src/main/java/mage/abilities/common/ChancellorAbility.java @@ -29,17 +29,22 @@ package mage.abilities.common; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.OpeningHandAction; import mage.abilities.StaticAbility; import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; +import mage.players.Player; /** * * @author BetaSteward_at_googlemail.com */ -public class ChancellorAbility extends StaticAbility { +public class ChancellorAbility extends StaticAbility implements OpeningHandAction { public ChancellorAbility(DelayedTriggeredAbility ability, String text) { super(Zone.HAND, new ChancellorEffect(ability, text)); @@ -63,6 +68,23 @@ public class ChancellorAbility extends StaticAbility { return "You may reveal this card from your opening hand. If you do, " + super.getRule(); } + @Override + public boolean askUseOpeningHandAction(Card card, Player player, Game game) { + return player.chooseUse(Outcome.PutCardInPlay, "Do you wish to reveal " + card.getIdName() + "?", this, game); + } + + @Override + public boolean isOpeningHandActionAllowed(Card card, Player player, Game game) { + return true; + } + + @Override + public void doOpeningHandAction(Card card, Player player, Game game) { + Cards cards = new CardsImpl(); + cards.add(card); + player.revealCards(card.getName(), cards, game); + this.resolve(game); + } } class ChancellorEffect extends OneShotEffect { diff --git a/Mage/src/main/java/mage/abilities/common/GemstoneCavernsAbility.java b/Mage/src/main/java/mage/abilities/common/GemstoneCavernsAbility.java deleted file mode 100644 index 3a7d91f5695..00000000000 --- a/Mage/src/main/java/mage/abilities/common/GemstoneCavernsAbility.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.abilities.common; - -/** - * - * @author emerald000 - */ -import mage.abilities.Ability; -import mage.abilities.StaticAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.common.ExileFromHandCost; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; - -public class GemstoneCavernsAbility extends StaticAbility { - public GemstoneCavernsAbility() { - super(Zone.HAND, new GemstoneCavernsEffect()); - } - - public GemstoneCavernsAbility(final GemstoneCavernsAbility ability) { - super(ability); - } - - @Override - public GemstoneCavernsAbility copy() { - return new GemstoneCavernsAbility(this); - } - - @Override - public String getRule() { - return "If {this} is in your opening hand and you're not playing first, you may begin the game with {this} on the battlefield with a luck counter on it. If you do, exile a card from your hand."; - } -} - -class GemstoneCavernsEffect extends OneShotEffect { - - GemstoneCavernsEffect() { - super(Outcome.PutCardInPlay); - this.staticText = "you may begin the game with {this} on the battlefield with a luck counter on it. If you do, exile a card from your hand."; - } - - GemstoneCavernsEffect(final GemstoneCavernsEffect effect) { - super(effect); - } - - @Override - public GemstoneCavernsEffect copy() { - return new GemstoneCavernsEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Card card = game.getCard(source.getSourceId()); - if (card != null) { - if (card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId())) { - Permanent permanent = game.getPermanent(card.getId()); - if (permanent != null) { - permanent.addCounters(CounterType.LUCK.createInstance(), game); - Cost cost = new ExileFromHandCost(new TargetCardInHand()); - if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game)) { - cost.pay(source, game, source.getSourceId(), source.getControllerId(), true, null); - } - } - } - } - } - return false; - } -} \ No newline at end of file diff --git a/Mage/src/main/java/mage/abilities/keyword/LeylineAbility.java b/Mage/src/main/java/mage/abilities/keyword/LeylineAbility.java index 3ac4e6a00e7..77d83180e13 100644 --- a/Mage/src/main/java/mage/abilities/keyword/LeylineAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/LeylineAbility.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,27 +20,30 @@ * 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.abilities.keyword; -import mage.constants.Zone; -import mage.abilities.MageSingleton; -import mage.abilities.StaticAbility; - import java.io.ObjectStreamException; +import mage.abilities.MageSingleton; +import mage.abilities.OpeningHandAction; +import mage.abilities.StaticAbility; +import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; /** * * @author BetaSteward_at_googlemail.com */ -public class LeylineAbility extends StaticAbility implements MageSingleton { +public class LeylineAbility extends StaticAbility implements MageSingleton, OpeningHandAction { - private static final LeylineAbility fINSTANCE = new LeylineAbility(); + private static final LeylineAbility fINSTANCE = new LeylineAbility(); private Object readResolve() throws ObjectStreamException { return fINSTANCE; @@ -64,4 +67,18 @@ public class LeylineAbility extends StaticAbility implements MageSingleton { return fINSTANCE; } + @Override + public boolean askUseOpeningHandAction(Card card, Player player, Game game) { + return player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", this, game); + } + + @Override + public boolean isOpeningHandActionAllowed(Card card, Player player, Game game) { + return true; + } + + @Override + public void doOpeningHandAction(Card card, Player player, Game game) { + player.moveCards(card, Zone.BATTLEFIELD, this, game); + } } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 380da80ec87..451f9bbb873 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -48,17 +48,15 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.OpeningHandAction; import mage.abilities.SpellAbility; import mage.abilities.TriggeredAbility; import mage.abilities.common.AttachableToRestrictedAbility; -import mage.abilities.common.ChancellorAbility; -import mage.abilities.common.GemstoneCavernsAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffects; import mage.abilities.effects.Effect; import mage.abilities.effects.PreventionEffectData; import mage.abilities.effects.common.CopyEffect; -import mage.abilities.keyword.LeylineAbility; import mage.abilities.keyword.MorphAbility; import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.DelayedTriggeredManaAbility; @@ -84,6 +82,7 @@ import mage.constants.Zone; import mage.counters.CounterType; import mage.counters.Counters; import mage.filter.Filter; +import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterPlaneswalkerPermanent; @@ -119,6 +118,7 @@ import mage.players.Player; import mage.players.PlayerList; import mage.players.Players; import mage.target.Target; +import mage.target.TargetCard; import mage.target.TargetPermanent; import mage.target.TargetPlayer; import mage.util.GameLog; @@ -1028,35 +1028,39 @@ public abstract class GameImpl implements Game, Serializable { //20100716 - 103.5 for (UUID playerId : state.getPlayerList(startingPlayerId)) { Player player = getPlayer(playerId); + Cards cardsWithOpeningAction = new CardsImpl(); for (Card card : player.getHand().getCards(this)) { - if (player.getHand().contains(card.getId())) { - if (card.getAbilities().containsKey(LeylineAbility.getInstance().getId())) { - if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", null, this)) { - card.putOntoBattlefield(this, Zone.HAND, null, player.getId()); - } - } - for (Ability ability : card.getAbilities()) { - if (ability instanceof ChancellorAbility) { - if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to reveal " + card.getName() + "?", ability, this)) { - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards("Revealed", cards, this); - ability.resolve(this); - } - } - if (ability instanceof GemstoneCavernsAbility) { - if (!playerId.equals(startingPlayerId)) { - if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " into play?", ability, this)) { - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards("Revealed", cards, this); - ability.resolve(this); - } - } + for (Ability ability : card.getAbilities()) { + if (ability instanceof OpeningHandAction) { + OpeningHandAction action = (OpeningHandAction) ability; + if (action.isOpeningHandActionAllowed(card, player, this)) { + cardsWithOpeningAction.add(card); } } } } + while (!cardsWithOpeningAction.isEmpty() && player.canRespond()) { + Card card; + if (cardsWithOpeningAction.size() > 1) { + TargetCard targetCard = new TargetCard(1, Zone.HAND, new FilterCard("card for opening hand action")); + player.chooseTarget(Outcome.Benefit, cardsWithOpeningAction, targetCard, null, this); + card = getCard(targetCard.getFirstTarget()); + } else { + card = cardsWithOpeningAction.getRandom(this); + } + if (card != null) { + for (Ability ability : card.getAbilities()) { + if (ability instanceof OpeningHandAction) { + OpeningHandAction action = (OpeningHandAction) ability; + if (action.askUseOpeningHandAction(card, player, this)) { + action.doOpeningHandAction(card, player, this); + } + } + + } + } + cardsWithOpeningAction.remove(card); + } } }