This commit is contained in:
jeffwadsworth 2019-12-30 16:24:55 -06:00
parent be9e43ffd8
commit 174f38d589
6 changed files with 113 additions and 66 deletions

View file

@ -38,7 +38,8 @@ public final class GeodeGolem extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever Geode Golem deals combat damage to a player, you may cast your commander from the command zone without paying its mana cost.
// Whenever Geode Golem deals combat damage to a player, you may
// cast your commander from the command zone without paying its mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new GeodeGolemEffect(), true));
}
@ -56,7 +57,8 @@ class GeodeGolemEffect extends OneShotEffect {
public GeodeGolemEffect() {
super(Outcome.PlayForFree);
staticText = "you may cast your commander from the command zone without paying its mana cost";
staticText = "you may cast your commander from the command zone "
+ "without paying its mana cost";
}
public GeodeGolemEffect(final GeodeGolemEffect effect) {
@ -83,10 +85,12 @@ class GeodeGolemEffect extends OneShotEffect {
if (possibleCommanders.size() == 1) {
selectedCommanderId = possibleCommanders.iterator().next();
} else {
TargetCard target = new TargetCard(Zone.COMMAND, new FilterCard("commander to cast without mana cost"));
TargetCard target = new TargetCard(Zone.COMMAND, new FilterCard(
"commander to cast without mana cost"));
Cards cards = new CardsImpl(possibleCommanders);
target.setNotTarget(true);
if (controller.canRespond() && controller.choose(Outcome.Benefit, cards, target, game)) {
if (controller.canRespond()
&& controller.choose(Outcome.PlayForFree, cards, target, game)) {
if (target.getFirstTarget() != null) {
selectedCommanderId = target.getFirstTarget();
}
@ -99,7 +103,7 @@ class GeodeGolemEffect extends OneShotEffect {
}
// PAY
// TODO: it's can be broken with commander cost reduction effect
// TODO: this is broken with the commander cost reduction effect
ManaCost cost = null;
CommanderPlaysCountWatcher watcher = game.getState().getWatcher(CommanderPlaysCountWatcher.class);
int castCount = watcher.getPlaysCount(commander.getId());
@ -108,9 +112,14 @@ class GeodeGolemEffect extends OneShotEffect {
}
// CAST: as spell or as land
if (cost == null || cost.pay(source, game, source.getSourceId(), controller.getId(), false, null)) {
if (cost == null
|| cost.pay(source, game, source.getSourceId(), controller.getId(), false, null)) {
if (commander.getSpellAbility() != null) {
return controller.cast(commander.getSpellAbility().copy(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + commander.getId(), Boolean.TRUE);
Boolean commanderWasCast = controller.cast(controller.chooseAbilityForCast(commander, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + commander.getId(), null);
return commanderWasCast;
} else {
return controller.playLand(commander, game, true);
}

View file

@ -1,4 +1,3 @@
package mage.cards.h;
import java.util.UUID;
@ -44,7 +43,8 @@ public final class HazoretsUndyingFury extends CardImpl {
//Land you control don't untap during your next untap step.
this.getSpellAbility().addEffect(new DontUntapInControllersUntapStepAllEffect(
Duration.UntilYourNextTurn, TargetController.YOU, new FilterControlledLandPermanent("Lands you control"))
Duration.UntilYourNextTurn, TargetController.YOU,
new FilterControlledLandPermanent("Lands you control"))
.setText("Lands you control don't untap during your next untap phase"));
}
@ -60,7 +60,8 @@ public final class HazoretsUndyingFury extends CardImpl {
class HazoretsUndyingFuryEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("nonland cards with converted mana cost 5 or less");
private static final FilterCard filter = new FilterCard(
"nonland cards with converted mana cost 5 or less");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
@ -68,8 +69,10 @@ class HazoretsUndyingFuryEffect extends OneShotEffect {
}
public HazoretsUndyingFuryEffect() {
super(Outcome.Benefit);
this.staticText = "Shuffle your library, then exile the top four cards. You may cast any number of nonland cards with converted mana cost 5 or less from among them without paying their mana costs";
super(Outcome.PlayForFree);
this.staticText = "Shuffle your library, then exile the top four cards. "
+ "You may cast any number of nonland cards with converted mana "
+ "cost 5 or less from among them without paying their mana costs";
}
public HazoretsUndyingFuryEffect(final HazoretsUndyingFuryEffect effect) {
@ -85,29 +88,40 @@ class HazoretsUndyingFuryEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) {
if (controller != null
&& sourceObject != null) {
controller.shuffleLibrary(source, game);
// move cards from library to exile
controller.moveCardsToExile(controller.getLibrary().getTopCards(game, 4), source, game, true, source.getSourceId(), sourceObject.getIdName());
controller.moveCardsToExile(controller.getLibrary().getTopCards(game, 4),
source, game, true, source.getSourceId(), sourceObject.getIdName());
// cast the possible cards without paying the mana
ExileZone hazoretsUndyingFuryExileZone = game.getExile().getExileZone(source.getSourceId());
Cards cardsToCast = new CardsImpl();
if (hazoretsUndyingFuryExileZone == null) {
return true;
}
cardsToCast.addAll(hazoretsUndyingFuryExileZone.getCards(filter, source.getSourceId(), source.getControllerId(), game));
cardsToCast.addAll(hazoretsUndyingFuryExileZone.getCards(filter,
source.getSourceId(), source.getControllerId(), game));
while (!cardsToCast.isEmpty()) {
if (!controller.chooseUse(Outcome.PlayForFree, "Cast (another) a card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
if (!controller.chooseUse(Outcome.PlayForFree,
"Cast (another) a card exiled with "
+ sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
break;
}
TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("nonland card to cast for free"));
TargetCard targetCard = new TargetCard(1, Zone.EXILED,
new FilterCard("nonland card to cast for free"));
if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) {
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (cardWasCast) {
cardsToCast.remove(card);
} else {
game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");
game.informPlayer(controller, "You're not able to cast "
+ card.getIdName() + " or you canceled the casting.");
}
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.r;
import java.util.UUID;
@ -28,7 +27,8 @@ public final class ReversalOfFortune extends CardImpl {
public ReversalOfFortune(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
// Target opponent reveals their hand. You may copy an instant or sorcery card in it. If you do, you may cast the copy without paying its mana cost.
// Target opponent reveals their hand. You may copy an instant or sorcery
// card in it. If you do, you may cast the copy without paying its mana cost.
this.getSpellAbility().addEffect(new ReversalOfFortuneEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@ -47,7 +47,9 @@ class ReversalOfFortuneEffect extends OneShotEffect {
public ReversalOfFortuneEffect() {
super(Outcome.Copy);
this.staticText = "Target opponent reveals their hand. You may copy an instant or sorcery card in it. If you do, you may cast the copy without paying its mana cost";
this.staticText = "Target opponent reveals their hand. You may copy an "
+ "instant or sorcery card in it. If you do, you may cast the "
+ "copy without paying its mana cost";
}
public ReversalOfFortuneEffect(final ReversalOfFortuneEffect effect) {
@ -64,7 +66,8 @@ class ReversalOfFortuneEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getFirstTarget());
if (controller != null && opponent != null) {
if (controller != null
&& opponent != null) {
// Target opponent reveals their hand
Cards revealedCards = new CardsImpl();
revealedCards.addAll(opponent.getHand());
@ -73,13 +76,16 @@ class ReversalOfFortuneEffect extends OneShotEffect {
//You may copy an instant or sorcery card in it
TargetCard target = new TargetCard(1, Zone.HAND, new FilterInstantOrSorceryCard());
target.setRequired(false);
if (controller.choose(outcome, revealedCards, target, game)) {
if (controller.choose(Outcome.PlayForFree, revealedCards, target, game)) {
Card card = revealedCards.get(target.getFirstTarget(), game);
//If you do, you may cast the copy without paying its mana cost
if (card != null) {
Card copiedCard = game.copyCard(card, source, source.getControllerId());
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
if (controller.chooseUse(Outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(copiedCard, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
}
} else {
return false;

View file

@ -1,4 +1,3 @@
package mage.cards.s;
import java.util.UUID;
@ -43,8 +42,10 @@ public final class SpellweaverVolute extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Whenever you cast a sorcery spell, copy the enchanted instant card. You may cast the copy without paying its mana cost.
// If you do, exile the enchanted card and attach Spellweaver Volute to another instant card in a graveyard.
// Whenever you cast a sorcery spell, copy the enchanted instant card.
// You may cast the copy without paying its mana cost.
// If you do, exile the enchanted card and attach Spellweaver Volute
// to another instant card in a graveyard.
FilterSpell filterSpell = new FilterSpell("a sorcery spell");
filterSpell.add(new CardTypePredicate(CardType.SORCERY));
this.addAbility(new SpellCastControllerTriggeredAbility(new SpellweaverVoluteEffect(), filterSpell, false));
@ -63,7 +64,7 @@ public final class SpellweaverVolute extends CardImpl {
class SpellweaverVoluteEffect extends OneShotEffect {
public SpellweaverVoluteEffect() {
super(Outcome.Benefit);
super(Outcome.PlayForFree);
this.staticText = "copy the enchanted instant card. You may cast the copy without paying its mana cost. \n"
+ "If you do, exile the enchanted card and attach {this} to another instant card in a graveyard";
}
@ -87,21 +88,24 @@ class SpellweaverVoluteEffect extends OneShotEffect {
if (enchantedCard != null && game.getState().getZone(enchantedCard.getId()) == Zone.GRAVEYARD) {
Player ownerEnchanted = game.getPlayer(enchantedCard.getOwnerId());
if (ownerEnchanted != null
&& controller.chooseUse(outcome, "Create a copy of " + enchantedCard.getName() + '?', source, game)) {
&& controller.chooseUse(Outcome.Copy, "Create a copy of " + enchantedCard.getName() + '?', source, game)) {
Card copiedCard = game.copyCard(enchantedCard, source, source.getControllerId());
if (copiedCard != null) {
ownerEnchanted.getGraveyard().add(copiedCard);
game.getState().setZone(copiedCard.getId(), Zone.GRAVEYARD);
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
if (controller.chooseUse(Outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
if (copiedCard.getSpellAbility() != null) {
controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(copiedCard, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
}
if (controller.moveCards(enchantedCard, Zone.EXILED, source, game)) {
FilterCard filter = new FilterCard("instant card in a graveyard");
filter.add(new CardTypePredicate(CardType.INSTANT));
TargetCardInGraveyard auraTarget = new TargetCardInGraveyard(filter);
if (auraTarget.canChoose(source.getSourceId(), controller.getId(), game)) {
controller.choose(outcome, auraTarget, source.getSourceId(), game);
controller.choose(Outcome.Benefit, auraTarget, source.getSourceId(), game);
Card newAuraTarget = game.getCard(auraTarget.getFirstTarget());
if (newAuraTarget != null) {
if (enchantedCard.getId().equals(newAuraTarget.getId())) {

View file

@ -1,4 +1,3 @@
package mage.cards.t;
import java.util.UUID;
@ -31,37 +30,40 @@ import mage.target.common.TargetCardInYourGraveyard;
* @author LevelX2
*/
public final class ToshiroUmezawa extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature an opponent controls");
private static final FilterCreaturePermanent filter
= new FilterCreaturePermanent("a creature an opponent controls");
private static final FilterCard filterInstant = new FilterCard("instant card from your graveyard");
static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));
filterInstant.add(new CardTypePredicate(CardType.INSTANT));
}
public ToshiroUmezawa(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SAMURAI);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Bushido 1
this.addAbility(new BushidoAbility(1));
// Whenever a creature an opponent controls dies, you may cast target instant card from your graveyard. If that card would be put into a graveyard this turn, exile it instead.
// Whenever a creature an opponent controls dies, you may cast target
// instant card from your graveyard. If that card would be put into a
// graveyard this turn, exile it instead.
Ability ability = new DiesCreatureTriggeredAbility(new ToshiroUmezawaEffect(), true, filter);
ability.addTarget(new TargetCardInYourGraveyard(1, 1, filterInstant));
this.addAbility(ability);
}
public ToshiroUmezawa(final ToshiroUmezawa card) {
super(card);
}
@Override
public ToshiroUmezawa copy() {
return new ToshiroUmezawa(this);
@ -69,28 +71,33 @@ public final class ToshiroUmezawa extends CardImpl {
}
class ToshiroUmezawaEffect extends OneShotEffect {
public ToshiroUmezawaEffect() {
super(Outcome.Benefit);
this.staticText = "cast target instant card from your graveyard. If that card would be put into a graveyard this turn, exile it instead";
this.staticText = "cast target instant card from your graveyard. "
+ "If that card would be put into a graveyard this turn, exile it instead";
}
public ToshiroUmezawaEffect(final ToshiroUmezawaEffect effect) {
super(effect);
}
@Override
public ToshiroUmezawaEffect copy() {
return new ToshiroUmezawaEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card != null) {
controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game));
if (card != null
&& controller.getGraveyard().contains(card.getId())) { // must be in graveyard
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, false),
game, false, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
game.addEffect(new ToshiroUmezawaReplacementEffect(card.getId()), source);
}
}
@ -99,24 +106,24 @@ class ToshiroUmezawaEffect extends OneShotEffect {
}
class ToshiroUmezawaReplacementEffect extends ReplacementEffectImpl {
private final UUID cardId;
public ToshiroUmezawaReplacementEffect(UUID cardId) {
super(Duration.EndOfTurn, Outcome.Exile);
this.cardId = cardId;
}
public ToshiroUmezawaReplacementEffect(final ToshiroUmezawaReplacementEffect effect) {
super(effect);
this.cardId = effect.cardId;
}
@Override
public ToshiroUmezawaReplacementEffect copy() {
return new ToshiroUmezawaReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
UUID eventObject = event.getTargetId();
@ -132,12 +139,12 @@ class ToshiroUmezawaReplacementEffect extends ReplacementEffectImpl {
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;

View file

@ -1,4 +1,3 @@
package mage.cards.t;
import java.util.List;
@ -35,8 +34,10 @@ public final class TwinningGlass extends CardImpl {
public TwinningGlass(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// {1}, {tap}: You may cast a nonland card from your hand without paying its mana cost if it has the same name as a spell that was cast this turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TwinningGlassEffect(), new ManaCostsImpl("{1}"));
// {1}, {tap}: You may cast a nonland card from your hand without paying
// its mana cost if it has the same name as a spell that was cast this turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new TwinningGlassEffect(), new ManaCostsImpl("{1}"));
ability.addWatcher(new SpellsCastWatcher());
ability.addCost(new TapSourceCost());
this.addAbility(ability);
@ -56,8 +57,10 @@ public final class TwinningGlass extends CardImpl {
class TwinningGlassEffect extends OneShotEffect {
public TwinningGlassEffect() {
super(Outcome.PutCardInPlay);
this.staticText = "You may cast a nonland card from your hand without paying its mana cost if it has the same name as a spell that was cast this turn";
super(Outcome.PlayForFree);
this.staticText = "You may cast a nonland card from your hand "
+ "without paying its mana cost if it has the same name "
+ "as a spell that was cast this turn";
}
public TwinningGlassEffect(final TwinningGlassEffect effect) {
@ -92,11 +95,15 @@ class TwinningGlassEffect extends OneShotEffect {
}
}
TargetCardInHand target = new TargetCardInHand(0, 1, filterCard);
if (controller.choose(Outcome.Benefit, controller.getHand(), target, game)) {
if (controller.choose(Outcome.PlayForFree, controller.getHand(), target, game)) {
Card chosenCard = game.getCard(target.getFirstTarget());
if (chosenCard != null) {
if (controller.chooseUse(outcome, "Cast the card without paying mana cost?", source, game)) {
return controller.cast(chosenCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
if (controller.chooseUse(Outcome.PlayForFree, "Cast the card without paying mana cost?", source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(chosenCard, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), null);
return cardWasCast;
}
}
}