mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
Cloud Key - fixed that it doesn't allow to cast cards without full mana available (#6698);
This commit is contained in:
parent
74ceac7322
commit
f9a9a55f7b
6 changed files with 87 additions and 211 deletions
|
@ -1,27 +1,22 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ChooseCardTypeEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
@ -46,7 +41,10 @@ public final class ArchonOfValorsReach extends CardImpl {
|
|||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// As Archon of Valor's Reach enters the battlefield, choose artifact, enchantment, instant, sorcery, or planeswalker.
|
||||
this.addAbility(new AsEntersBattlefieldAbility(new ArchonOfValorsReachChooseEffect()));
|
||||
this.addAbility(new AsEntersBattlefieldAbility(
|
||||
new ChooseCardTypeEffect(Outcome.Benefit, Arrays.asList(CardType.ARTIFACT, CardType.ENCHANTMENT, CardType.INSTANT, CardType.PLANESWALKER))
|
||||
.setText("choose artifact, enchantment, instant, sorcery, or planeswalker")
|
||||
));
|
||||
|
||||
// Players can't cast spells of the chosen type.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArchonOfValorsReachReplacementEffect()));
|
||||
|
@ -62,85 +60,6 @@ public final class ArchonOfValorsReach extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class ArchonOfValorsReachChooseEffect extends OneShotEffect {
|
||||
|
||||
ArchonOfValorsReachChooseEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "choose artifact, enchantment, instant, sorcery, or planeswalker";
|
||||
}
|
||||
|
||||
private ArchonOfValorsReachChooseEffect(final ArchonOfValorsReachChooseEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchonOfValorsReachChooseEffect copy() {
|
||||
return new ArchonOfValorsReachChooseEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
|
||||
if (mageObject == null) {
|
||||
mageObject = game.getObject(source.getSourceId());
|
||||
}
|
||||
if (controller != null && mageObject != null) {
|
||||
ArchonOfValorsReachChoice choices = new ArchonOfValorsReachChoice();
|
||||
if (controller.choose(Outcome.Neutral, choices, game)) {
|
||||
game.informPlayers(mageObject.getName() + ": Chosen card type is " + choices.getChoice());
|
||||
System.out.println(mageObject.getId());
|
||||
game.getState().setValue(mageObject.getId().toString() + "_cardtype", choices.getChoice());
|
||||
if (mageObject instanceof Permanent) {
|
||||
((Permanent) mageObject).addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen card type: " + choices.getChoice()), game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ArchonOfValorsReachChoice extends ChoiceImpl {
|
||||
|
||||
ArchonOfValorsReachChoice() {
|
||||
super(true);
|
||||
this.choices.add("Artifact");
|
||||
this.choices.add("Enchantment");
|
||||
this.choices.add("Instant");
|
||||
this.choices.add("Sorcery");
|
||||
this.choices.add("Planeswalker");
|
||||
this.message = "Choose artifact, enchantment, instant, sorcery, or planeswalker";
|
||||
}
|
||||
|
||||
private ArchonOfValorsReachChoice(final ArchonOfValorsReachChoice choice) {
|
||||
super(choice);
|
||||
}
|
||||
|
||||
public static CardType getType(String ch) {
|
||||
switch (ch) {
|
||||
case "Artifact":
|
||||
return CardType.ARTIFACT;
|
||||
case "Enchantment":
|
||||
return CardType.ENCHANTMENT;
|
||||
case "Instant":
|
||||
return CardType.INSTANT;
|
||||
case "Sorcery":
|
||||
return CardType.SORCERY;
|
||||
case "Planeswalker":
|
||||
return CardType.PLANESWALKER;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchonOfValorsReachChoice copy() {
|
||||
return new ArchonOfValorsReachChoice(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ArchonOfValorsReachReplacementEffect extends ContinuousRuleModifyingEffectImpl {
|
||||
|
||||
ArchonOfValorsReachReplacementEffect() {
|
||||
|
@ -154,10 +73,11 @@ class ArchonOfValorsReachReplacementEffect extends ContinuousRuleModifyingEffect
|
|||
|
||||
@Override
|
||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||
CardType cardType = (CardType) game.getState().getValue(source.getSourceId().toString() + "_cardtype");
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
if (mageObject != null && cardType != null) {
|
||||
return "You can't cast " + cardType.toString() + " spells (" + mageObject.getIdName() + ").";
|
||||
Object savedType = game.getState().getValue(source.getSourceId() + "_type");
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (savedType instanceof String && sourceCard != null) {
|
||||
CardType cardType = CardType.fromString((String) savedType);
|
||||
return "You can't cast " + cardType.toString() + " spells (" + sourceCard.getIdName() + ").";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -169,15 +89,13 @@ class ArchonOfValorsReachReplacementEffect extends ContinuousRuleModifyingEffect
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
|
||||
if ((String) game.getState().getValue(source.getSourceId().toString() + "_cardtype") == null){
|
||||
return false;
|
||||
Object savedType = game.getState().getValue(source.getSourceId() + "_type");
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (savedType instanceof String && sourceCard != null) {
|
||||
CardType cardType = CardType.fromString((String) savedType);
|
||||
return cardType != null && sourceCard != null && sourceCard.getCardType().contains(cardType);
|
||||
}
|
||||
|
||||
CardType cardType = ArchonOfValorsReachChoice.getType((String) game.getState().getValue(source.getSourceId().toString() + "_cardtype"));
|
||||
// spell is not on the stack yet, so we have to check the card
|
||||
Card card = game.getCard(event.getSourceId());
|
||||
return cardType != null && card != null && card.getCardType().contains(cardType);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,42 +1,37 @@
|
|||
/*
|
||||
* 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.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
|
||||
import mage.abilities.effects.common.ChooseCardTypeEffect;
|
||||
import mage.abilities.effects.common.cost.SpellsCostReductionAllOfChosenCardTypeEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author nick.myers
|
||||
*/
|
||||
public final class CloudKey extends CardImpl {
|
||||
|
||||
public CloudKey(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// As Cloud Key enters the battlefield, choose artifact, creature, enchantment, instant, or sorcery.
|
||||
this.addAbility(new AsEntersBattlefieldAbility(new CloudKeyChooseTypeEffect()));
|
||||
this.addAbility(new AsEntersBattlefieldAbility(
|
||||
new ChooseCardTypeEffect(Outcome.Benefit, Arrays.asList(CardType.ARTIFACT, CardType.CREATURE, CardType.ENCHANTMENT, CardType.INSTANT, CardType.SORCERY))
|
||||
.setText("choose artifact, creature, enchantment, instant, or sorcery")
|
||||
));
|
||||
|
||||
// Spells you cast of the chosen type cost {1} less to cast.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CloudKeyCostModificationEffect()));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||
new SpellsCostReductionAllOfChosenCardTypeEffect(new FilterCard("Spells you cast of the chosen type"), 1, true)
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,84 +43,3 @@ public final class CloudKey extends CardImpl {
|
|||
super(card);
|
||||
}
|
||||
}
|
||||
|
||||
class CloudKeyChooseTypeEffect extends OneShotEffect {
|
||||
|
||||
public CloudKeyChooseTypeEffect() {
|
||||
super(Outcome.Neutral);
|
||||
this.staticText = "choose artifact, creature, enchantment, instant, or sorcery.";
|
||||
}
|
||||
|
||||
public CloudKeyChooseTypeEffect(final CloudKeyChooseTypeEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudKeyChooseTypeEffect copy() {
|
||||
return new CloudKeyChooseTypeEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
|
||||
if (mageObject == null) {
|
||||
mageObject = game.getObject(source.getSourceId());
|
||||
}
|
||||
if (mageObject != null && controller != null) {
|
||||
ChoiceImpl choices = new ChoiceImpl(true);
|
||||
choices.setMessage("Choose a spell type");
|
||||
choices.getChoices().add(CardType.ARTIFACT.toString());
|
||||
choices.getChoices().add(CardType.CREATURE.toString());
|
||||
choices.getChoices().add(CardType.ENCHANTMENT.toString());
|
||||
choices.getChoices().add(CardType.INSTANT.toString());
|
||||
choices.getChoices().add(CardType.SORCERY.toString());
|
||||
if (controller.choose(Outcome.Neutral, choices, game)) {
|
||||
game.informPlayers(mageObject.getLogName() + ": chosen spell type is " + choices.getChoice());
|
||||
game.getState().setValue(source.getSourceId().toString() + "_CloudKey", choices.getChoice());
|
||||
if (mageObject instanceof Permanent) {
|
||||
((Permanent) mageObject).addInfo("chosenCardType", CardUtil.addToolTipMarkTags("Chosen card type: " + choices.getChoice()), game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CloudKeyCostModificationEffect extends CostModificationEffectImpl {
|
||||
|
||||
public CloudKeyCostModificationEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
|
||||
this.staticText = "Spells you cast of the chosen type cost {1} less to cast";
|
||||
}
|
||||
|
||||
public CloudKeyCostModificationEffect(final CloudKeyCostModificationEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudKeyCostModificationEffect copy() {
|
||||
return new CloudKeyCostModificationEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source, Ability abilityToModify) {
|
||||
SpellAbility spellAbility = (SpellAbility) abilityToModify;
|
||||
CardUtil.adjustCost(spellAbility, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (abilityToModify instanceof SpellAbility && abilityToModify.isControlledBy(source.getControllerId())) {
|
||||
Spell spell = game.getStack().getSpell(abilityToModify.getSourceId());
|
||||
if (spell != null && spell.getCardType().toString().contains((String) game.getState().getValue(source.getSourceId().toString() + "_CloudKey"))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.h;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.cost.SpellsCostReductionAllEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -9,15 +7,15 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class HelmOfAwakening extends CardImpl {
|
||||
|
||||
|
||||
public HelmOfAwakening(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
|
||||
|
||||
// Spells cost {1} less to cast.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionAllEffect(1)));
|
||||
|
|
|
@ -213,4 +213,35 @@ public class CostReduceForEachTest extends CardTestPlayerBaseWithAIHelps {
|
|||
|
||||
assertPermanentCount(playerA, "Balduvian Bears", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CloudKey_ChooseCardTypeForCostReduce() {
|
||||
// {3}
|
||||
// As Cloud Key enters the battlefield, choose artifact, creature, enchantment, instant, or sorcery.
|
||||
// Spells you cast of the chosen type cost {1} less to cast.
|
||||
addCard(Zone.HAND, playerA, "Cloud Key", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
|
||||
//
|
||||
addCard(Zone.HAND, playerA, "Balduvian Bears", 1); // {1}{G}
|
||||
addCard(Zone.HAND, playerA, "Forest", 1);
|
||||
|
||||
// prepare cloud key to reduce
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cloud Key");
|
||||
setChoice(playerA, "Creature");
|
||||
|
||||
// prepare lands
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPlayableAbility("can't with no mana", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Balduvian Bears", false);
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
|
||||
checkPlayableAbility("can play with mana and reduce", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Balduvian Bears", true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Balduvian Bears", 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,24 +5,38 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceCardType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author emerald000
|
||||
*/
|
||||
public class ChooseCardTypeEffect extends OneShotEffect {
|
||||
|
||||
List<CardType> cardTypes = Arrays.stream(CardType.values()).collect(Collectors.toList());
|
||||
|
||||
public ChooseCardTypeEffect(Outcome outcome) {
|
||||
this(outcome, Arrays.stream(CardType.values()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public ChooseCardTypeEffect(Outcome outcome, List<CardType> cardTypes) {
|
||||
super(outcome);
|
||||
staticText = "choose a card type";
|
||||
this.staticText = "choose a card type";
|
||||
this.cardTypes = new ArrayList<>(cardTypes);
|
||||
}
|
||||
|
||||
private ChooseCardTypeEffect(final ChooseCardTypeEffect effect) {
|
||||
super(effect);
|
||||
this.cardTypes = new ArrayList<>(effect.cardTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,6 +3,7 @@ package mage.choices;
|
|||
import mage.constants.CardType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -11,12 +12,12 @@ import java.util.stream.Collectors;
|
|||
public class ChoiceCardType extends ChoiceImpl {
|
||||
|
||||
public ChoiceCardType() {
|
||||
this(true);
|
||||
this(true, Arrays.stream(CardType.values()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public ChoiceCardType(boolean required) {
|
||||
public ChoiceCardType(boolean required, List<CardType> cardTypes) {
|
||||
super(required);
|
||||
this.choices.addAll(Arrays.stream(CardType.values()).map(CardType::toString).collect(Collectors.toList()));
|
||||
this.choices.addAll(cardTypes.stream().map(CardType::toString).collect(Collectors.toList()));
|
||||
this.message = "Choose a card type";
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue