1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-04 17:00:13 -09:00

Merge branch 'master' into master

This commit is contained in:
theelk801 2018-12-19 23:41:02 -05:00 committed by GitHub
commit 6a77f8c430
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 755 additions and 4 deletions

View file

@ -0,0 +1,45 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.keyword.AdaptEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Aeromunculus extends CardImpl {
public Aeromunculus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}");
this.subtype.add(SubType.HOMUNCULUS);
this.subtype.add(SubType.MUTANT);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// {2}{G}{U}: Adapt 1.
this.addAbility(new SimpleActivatedAbility(
new AdaptEffect(1), new ManaCostsImpl("{2}{G}{U}")
));
}
public Aeromunculus(final Aeromunculus card) {
super(card);
}
@Override
public Aeromunculus copy() {
return new Aeromunculus(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.b;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Bedevil extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("artifact, creature, or planeswalker");
static {
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.PLANESWALKER)
));
}
public Bedevil(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{B}{R}");
// Destroy target artifact, creature, or planeswalker.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter));
}
public Bedevil(final Bedevil card) {
super(card);
}
@Override
public Bedevil copy() {
return new Bedevil(this);
}
}

View file

@ -1,7 +1,5 @@
package mage.cards.c;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect;
@ -15,6 +13,9 @@ import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import java.util.Set;
import java.util.UUID;
/**
*
* @author jeffwadsworth
@ -78,7 +79,7 @@ class CommuneWithLavaEffect extends OneShotEffect {
class CommuneWithLavaMayPlayEffect extends AsThoughEffectImpl {
int castOnTurn = 0;
private int castOnTurn = 0;
public CommuneWithLavaMayPlayEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);

View file

@ -0,0 +1,101 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.common.SimpleEvasionAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.PutOnLibrarySourceEffect;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GateColossus extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with power 2 or less");
static {
filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3));
}
public GateColossus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{8}");
this.subtype.add(SubType.CONSTRUCT);
this.power = new MageInt(8);
this.toughness = new MageInt(8);
// This spell costs {1} less to cast for each Gate you control.
this.addAbility(new SimpleStaticAbility(Zone.STACK, new GateColossusCostReductionEffect()));
// Gate Colossus can't be blocked by creatures with power 2 or less.
this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
// Whenever a Gate enters the battlefield under your control, you may put Gate Colossus from your graveyard on top of your library.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.GRAVEYARD,
new PutOnLibrarySourceEffect(
true, "put {this} from your graveyard on top of your library"
), GateColossusCostReductionEffect.filter, true
));
}
public GateColossus(final GateColossus card) {
super(card);
}
@Override
public GateColossus copy() {
return new GateColossus(this);
}
}
class GateColossusCostReductionEffect extends CostModificationEffectImpl {
static final FilterControlledPermanent filter = new FilterControlledPermanent();
static {
filter.add(new SubtypePredicate(SubType.GATE));
}
public GateColossusCostReductionEffect() {
super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "This spell costs {1} less to cast for each Gate you control";
}
protected GateColossusCostReductionEffect(final GateColossusCostReductionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
int count = game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game).size();
if (count > 0) {
CardUtil.reduceCost(abilityToModify, count);
}
return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
return abilityToModify.getSourceId().equals(source.getSourceId());
}
@Override
public GateColossusCostReductionEffect copy() {
return new GateColossusCostReductionEffect(this);
}
}

View file

@ -58,7 +58,7 @@ class GearseekerSerpentCostReductionEffect extends CostModificationEffectImpl {
public GearseekerSerpentCostReductionEffect() {
super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "{this} costs {1} less to cast for each artifact you control";
staticText = "This spell costs {1} less to cast for each artifact you control";
}
protected GearseekerSerpentCostReductionEffect(final GearseekerSerpentCostReductionEffect effect) {

View file

@ -0,0 +1,41 @@
package mage.cards.i;
import mage.MageInt;
import mage.abilities.keyword.AfterlifeAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ImperiousOligarch extends CardImpl {
public ImperiousOligarch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Afterlife 1
this.addAbility(new AfterlifeAbility(1));
}
public ImperiousOligarch(final ImperiousOligarch card) {
super(card);
}
@Override
public ImperiousOligarch copy() {
return new ImperiousOligarch(this);
}
}

View file

@ -0,0 +1,127 @@
package mage.cards.l;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.SpectacleAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import java.util.Set;
import java.util.UUID;
/**
* @author TheElk801 and jeffwadsworth
*/
public final class LightUpTheStage extends CardImpl {
public LightUpTheStage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
// Spectacle {R}
this.addAbility(new SpectacleAbility(this, new ManaCostsImpl("{R}")));
// Exile the top two cards of your library. Until the end of your next turn, you may play those cards.
this.getSpellAbility().addEffect(new LightUpTheStageEffect());
}
public LightUpTheStage(final LightUpTheStage card) {
super(card);
}
@Override
public LightUpTheStage copy() {
return new LightUpTheStage(this);
}
}
class LightUpTheStageEffect extends OneShotEffect {
public LightUpTheStageEffect() {
super(Outcome.PlayForFree);
this.staticText = "Exile the top two cards of your library. Until the end of your next turn, you may play those cards";
}
public LightUpTheStageEffect(final LightUpTheStageEffect effect) {
super(effect);
}
@Override
public LightUpTheStageEffect copy() {
return new LightUpTheStageEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId());
if (controller != null) {
Set<Card> cards = controller.getLibrary().getTopCards(game, 2);
controller.moveCardsToExile(cards, source, game, true, CardUtil.getCardExileZoneId(game, source), sourceCard.getIdName());
for (Card card : cards) {
ContinuousEffect effect = new LightUpTheStageMayPlayEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
}
return true;
}
return false;
}
}
class LightUpTheStageMayPlayEffect extends AsThoughEffectImpl {
private int castOnTurn = 0;
public LightUpTheStageMayPlayEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
this.staticText = "Until the end of your next turn, you may play that card.";
}
public LightUpTheStageMayPlayEffect(final LightUpTheStageMayPlayEffect effect) {
super(effect);
castOnTurn = effect.castOnTurn;
}
@Override
public LightUpTheStageMayPlayEffect copy() {
return new LightUpTheStageMayPlayEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
castOnTurn = game.getTurnNum();
}
@Override
public boolean isInactive(Ability source, Game game) {
if (castOnTurn != game.getTurnNum() && game.getPhase().getStep().getType() == PhaseStep.END_TURN) {
if (game.isActivePlayer(source.getControllerId())) {
return true;
}
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
return source.isControlledBy(affectedControllerId)
&& getTargetPointer().getTargets(game, source).contains(sourceId);
}
}

View file

@ -0,0 +1,53 @@
package mage.cards.r;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.SpectacleCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
import mage.abilities.keyword.SpectacleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RafterDemon extends CardImpl {
public RafterDemon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
this.subtype.add(SubType.DEMON);
this.power = new MageInt(4);
this.toughness = new MageInt(2);
// Spectacle {3}{B}{R}
this.addAbility(new SpectacleAbility(this, new ManaCostsImpl("{3}{B}{R}")));
// When Rafter Demon enters the battlefield, if its spectacle cost was paid, each opponent discards a card.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect(
new StaticValue(1), false, TargetController.OPPONENT
)), SpectacleCondition.instance,
"When {this} enters the battlefield, " +
"if its spectacle cost was paid, " +
"each opponent discards a card."
));
}
public RafterDemon(final RafterDemon card) {
super(card);
}
@Override
public RafterDemon copy() {
return new RafterDemon(this);
}
}

View file

@ -0,0 +1,83 @@
package mage.cards.r;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.SpectacleCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.SpectacleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RixMaadiReveler extends CardImpl {
public RixMaadiReveler(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SHAMAN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Spectacle {2}{B}{R}
this.addAbility(new SpectacleAbility(this, new ManaCostsImpl("{2}{B}{R}")));
// When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.
this.addAbility(new EntersBattlefieldTriggeredAbility(new RixMaadiRevelerEffect(), false));
}
public RixMaadiReveler(final RixMaadiReveler card) {
super(card);
}
@Override
public RixMaadiReveler copy() {
return new RixMaadiReveler(this);
}
}
class RixMaadiRevelerEffect extends OneShotEffect {
RixMaadiRevelerEffect() {
super(Outcome.Benefit);
staticText = "discard a card, then draw a card. " +
"If {this}'s spectacle cost was paid, " +
"instead discard your hand, then draw three cards.";
}
private RixMaadiRevelerEffect(final RixMaadiRevelerEffect effect) {
super(effect);
}
@Override
public RixMaadiRevelerEffect copy() {
return new RixMaadiRevelerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
if (SpectacleCondition.instance.apply(game, source)) {
player.discard(player.getHand().size(), false, source, game);
player.drawCards(3, game);
} else {
player.discard(1, false, source, game);
player.drawCards(1, game);
}
return true;
}
}

View file

@ -0,0 +1,81 @@
package mage.cards.z;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.effects.keyword.AdaptEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.filter.predicate.permanent.CounterPredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ZeganaUtopianSpeaker extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent();
private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent();
static {
filter.add(new CounterPredicate(CounterType.P1P1));
filter.add(new AnotherPredicate());
filter2.add(new CounterPredicate(CounterType.P1P1));
}
public ZeganaUtopianSpeaker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.MERFOLK);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// When Zegana, Utopian Speaker enters the battlefield, if you control another creature with a +1/+1 counter on it, draw a card.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new EntersBattlefieldTriggeredAbility(
new DrawCardSourceControllerEffect(1), false
), new PermanentsOnTheBattlefieldCondition(filter),
"When {this} enters the battlefield, " +
"if you control another creature " +
"with a +1/+1 counter on it, draw a card."
));
// {4}{G}{U}: Adapt 4.
this.addAbility(new SimpleActivatedAbility(
new AdaptEffect(4), new ManaCostsImpl("{4}{G}{U}")
));
// Each creature you control with a +1/+1 counter on it has trample.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD,
new GainAbilityAllEffect(
TrampleAbility.getInstance(), Duration.WhileOnBattlefield,
filter2, "Each creature you control with a +1/+1 counter on it has trample"
)
));
}
public ZeganaUtopianSpeaker(final ZeganaUtopianSpeaker card) {
super(card);
}
@Override
public ZeganaUtopianSpeaker copy() {
return new ZeganaUtopianSpeaker(this);
}
}

View file

@ -32,10 +32,18 @@ public final class RavnicaAllegiance extends ExpansionSet {
this.ratioBoosterMythic = 8;
this.maxCardNumberInBooster = 259;
cards.add(new SetCardInfo("Aeromunculus", 152, Rarity.COMMON, mage.cards.a.Aeromunculus.class));
cards.add(new SetCardInfo("Bedevil", 157, Rarity.RARE, mage.cards.b.Bedevil.class));
cards.add(new SetCardInfo("Gate Colossus", 232, Rarity.UNCOMMON, mage.cards.g.GateColossus.class));
cards.add(new SetCardInfo("Growth Spiral", 178, Rarity.COMMON, mage.cards.g.GrowthSpiral.class));
cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class));
cards.add(new SetCardInfo("Light Up the Stage", 107, Rarity.UNCOMMON, mage.cards.l.LightUpTheStage.class));
cards.add(new SetCardInfo("Mortify", 192, Rarity.UNCOMMON, mage.cards.m.Mortify.class));
cards.add(new SetCardInfo("Rafter Demon", 196, Rarity.COMMON, mage.cards.r.RafterDemon.class));
cards.add(new SetCardInfo("Rakdos Firewheeler", Rarity.UNCOMMON, mage.cards.r.RakdosFirewheeler.class));
cards.add(new SetCardInfo("Rix Maadi Reveler", 109, Rarity.RARE, mage.cards.r.RixMaadiReveler.class));
cards.add(new SetCardInfo("The Haunt of Hightower", 273, Rarity.MYTHIC, mage.cards.t.TheHauntOfHightower.class));
cards.add(new SetCardInfo("Zegana, Utopian Speaker", 214, Rarity.RARE, mage.cards.z.ZeganaUtopianSpeaker.class));
}
@Override

View file

@ -0,0 +1,33 @@
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.keyword.SpectacleAbility;
import mage.constants.AbilityType;
import mage.game.Game;
import java.util.ArrayList;
import java.util.List;
/**
* @author TheElk801
*/
public enum SpectacleCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
if (source.getAbilityType() == AbilityType.TRIGGERED) {
@SuppressWarnings("unchecked")
List<Integer> spectacleActivations = (ArrayList) game.getState().getValue(SpectacleAbility.SPECTACLE_ACTIVATION_VALUE_KEY + source.getSourceId());
if (spectacleActivations != null) {
return spectacleActivations.contains(game.getState().getZoneChangeCounter(source.getSourceId()) - 1);
}
return false;
} else {
return source instanceof SpectacleAbility;
}
}
}

View file

@ -0,0 +1,48 @@
package mage.abilities.effects.keyword;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
/**
* @author TheElk801
*/
public class AdaptEffect extends OneShotEffect {
private final int adaptNumber;
public AdaptEffect(int adaptNumber) {
super(Outcome.BoostCreature);
this.adaptNumber = adaptNumber;
staticText = "Adapt " + adaptNumber +
" <i>(If this creature has no +1/+1 counters on it, put " +
CardUtil.numberToText(adaptNumber) + " +1/+1 counter" +
(adaptNumber > 1 ? "s" : "") + " on it.)</i>";
}
private AdaptEffect(final AdaptEffect effect) {
super(effect);
this.adaptNumber = effect.adaptNumber;
}
@Override
public AdaptEffect copy() {
return new AdaptEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) {
return false;
}
if (permanent.getCounters(game).getCount(CounterType.P1P1) == 0) {
permanent.addCounters(CounterType.P1P1.createInstance(adaptNumber), source, game);
}
return true;
}
}

View file

@ -0,0 +1,80 @@
package mage.abilities.keyword;
import mage.abilities.SpellAbility;
import mage.abilities.costs.mana.ManaCost;
import mage.cards.Card;
import mage.constants.SpellAbilityType;
import mage.constants.Zone;
import mage.game.Game;
import mage.watchers.common.PlayerLostLifeWatcher;
import java.util.ArrayList;
import java.util.UUID;
/**
* @author TheElk801
*/
public class SpectacleAbility extends SpellAbility {
public static final String SPECTACLE_ACTIVATION_VALUE_KEY = "spectacleActivation";
private String rule;
public SpectacleAbility(Card card, ManaCost spectacleCosts) {
super(spectacleCosts, card.getName() + " with spectacle", Zone.HAND, SpellAbilityType.BASE_ALTERNATE);
this.getCosts().addAll(card.getSpellAbility().getCosts().copy());
this.getEffects().addAll(card.getSpellAbility().getEffects().copy());
this.getTargets().addAll(card.getSpellAbility().getTargets().copy());
this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
this.timing = card.getSpellAbility().getTiming();
this.setRuleAtTheTop(true);
this.rule = "Spectacle " + spectacleCosts.getText()
+ " <i>(You may cast this spell for its spectacle cost rather than its mana cost if an opponent lost life this turn.)</i>";
}
public SpectacleAbility(final SpectacleAbility ability) {
super(ability);
this.rule = ability.rule;
}
@Override
public ActivationStatus canActivate(UUID playerId, Game game) {
PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName());
if (watcher != null && watcher.getAllOppLifeLost(playerId, game) > 0) {
return super.canActivate(playerId, game);
}
return ActivationStatus.getFalse();
}
@Override
@SuppressWarnings("unchecked")
public boolean activate(Game game, boolean noMana) {
if (super.activate(game, noMana)) {
ArrayList<Integer> spectacleActivations = (ArrayList) game.getState().getValue(SPECTACLE_ACTIVATION_VALUE_KEY + getSourceId());
if (spectacleActivations == null) {
spectacleActivations = new ArrayList<>(); // zoneChangeCounter
game.getState().setValue(SPECTACLE_ACTIVATION_VALUE_KEY + getSourceId(), spectacleActivations);
}
spectacleActivations.add(game.getState().getZoneChangeCounter(getSourceId()));
return true;
}
return false;
}
@Override
public SpectacleAbility copy() {
return new SpectacleAbility(this);
}
@Override
public String getRule(boolean all) {
return getRule();
}
@Override
public String getRule() {
return rule;
}
}

View file

@ -82,6 +82,7 @@ Shroud|instance|
Soulbond|instance|
Soulshift|number|
Skulk|new|
Spectacle|card, cost|
Storm|new|
Sunburst|new|
Swampcycling|cost|

View file

@ -34579,11 +34579,15 @@ Impervious Greatwurm|Guilds of Ravnica|273|M|{7}{G}{G}{G}|Creature - Wurm|16|16|
Tithe Taker|Ravnica Allegiance|27|R|{1}{W}|Creature - Human Soldier|2|1|During your turn, spells your opponents cast cost {1} more to cast and abilities your opponents activate cost {1} more to activate unless they're mana abilities.$Afterlife 1|
Light Up the Stage|Ravnica Allegiance|107|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.|
Rix Maadi Reveler|Ravnica Allegiance|109|R|{1}{R}|Creature - Human Shaman|2|2|Spectacle {2}{B}{R}$When Rix Maadi Reveler enters the battlefield, discard a card, then draw a card. If Rix Maadi Reveler's spectacle cost was paid, instead discard your hand, then draw three cards.|
Aeromunculus|Ravnica Allegiance|152|C|{1}{G}{U}|Creature - Homunculus Mutant|2|3|Flying${2}{G}{U}: Adapt 1.|
Bedevil|Ravnica Allegiance|157|R|{B}{B}{R}|Instant|||Destroy target artifact, creature, or planeswalker.|
Growth Spiral|Ravnica Allegiance|178|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.|
Imperious Oligarch|Ravnica Allegiance|184|C|{W}{B}|Creature - Human Cleric|2|1|Vigilance$Afterlife 1|
Lavinia, Azorius Renegade|Ravnica Allegiance|189|R|{W}{U}|Legendary Creature - Human Soldier|2|2|Each opponent can't cast noncreature spells with converted mana cost greater than the number of lands that player controls.$Whenever an opponent casts a spell, if no mana was spent to cast it, counter that spell.|
Mortify|Ravnica Allegiance|192|U|{1}{W}{B}|Instant|||Destroy target creature or enchantment.|
Rafter Demon|Ravnica Allegiance|196|C|{2}{B}{R}|Creature - Demon|4|2|Spectacle {3}{B}{R}$When Rafter Demon enters the battlefield, if its spectacle cost was paid, each opponent discards a card.|
Rakdos Firewheeler|Ravnica Allegiance|197|U|{B}{B}{R}{R}|Creature - Human Rogue|4|3|When Rakdos Firewheeler enters the battlefield, it deals 2 damage to target opponent and 2 damage to up to one target creature or planeswalker.|
Simic Ascendancy|Ravnica Allegiance|207|R|{G}{U}|Enchantment|||{1}{G}{U}: Put a +1/+1 counter on target creature you control.$Whenever one or more +1/+1 counters are put on a creature you control, put that many growth counters on Simic Ascendancy.$At the beginning of your upkeep, if Simic Ascendancy has twenty or more growth counters on it, you win the game.|
Zegana, Utopian Speaker|Ravnica Allegiance|214|R|{2}{G}{U}|Legendary Creature - Merfolk Wizard|4|4|When Zegana, Utopian Speaker enters the battlefield, if you control another creature with a +1/+1 counter on it, draw a card.${4}{G}{U}: Adapt 4.$Each creature you control with a +1/+1 counter on it has trample.|
Gate Colossus|Ravnica Allegiance|232|U|{8}|Artifact Creature - Construct|8|8|This spell costs {1} less to cast for each Gate you control.$Gate Colossus can't be blocked by creatures with power 2 or less.$Whenever a Gate enters the battlefield under your control, you may put Gate Colossus from your graveyard on top of your library.|
The Haunt of Hightower|Ravnica Allegiance|273|M|{4}{B}{B}|Legendary Creature - Vampire|3|3|Flying, lifelink$Whenever The Haunt of Hightower attacks, defending player discards a card.$Whenever a card is put into an opponent's graveyard from anywhere, put a +1/+1 counter on The Haunt of Hightower.|