mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
- Refactored some cards to use the correct counter spell/ability method
This commit is contained in:
parent
f432365197
commit
070ba24e05
7 changed files with 93 additions and 49 deletions
|
@ -36,8 +36,10 @@ public final class BazaarOfWonders extends CardImpl {
|
|||
// When Bazaar of Wonders enters the battlefield, exile all cards from all graveyards.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new ExileGraveyardAllPlayersEffect()));
|
||||
|
||||
// Whenever a player casts a spell, counter it if a card with the same name is in a graveyard or a nontoken permanent with the same name is on the battlefield.
|
||||
this.addAbility(new SpellCastAllTriggeredAbility(new BazaarOfWondersEffect(), StaticFilters.FILTER_SPELL_A, false, SetTargetPointer.SPELL));
|
||||
// Whenever a player casts a spell, counter it if a card with the same name is in
|
||||
// a graveyard or a nontoken permanent with the same name is on the battlefield.
|
||||
this.addAbility(new SpellCastAllTriggeredAbility(new BazaarOfWondersEffect(),
|
||||
StaticFilters.FILTER_SPELL_A, false, SetTargetPointer.SPELL));
|
||||
}
|
||||
|
||||
public BazaarOfWonders(final BazaarOfWonders card) {
|
||||
|
@ -77,8 +79,9 @@ class BazaarOfWondersEffect extends OneShotEffect {
|
|||
FilterPermanent filter1 = new FilterPermanent();
|
||||
filter1.add(new NamePredicate(spellName));
|
||||
filter1.add(Predicates.not(TokenPredicate.instance));
|
||||
if (!game.getBattlefield().getActivePermanents(filter1, source.getControllerId(), game).isEmpty()) {
|
||||
spell.counter(source.getControllerId(), game);
|
||||
if (!game.getBattlefield().getActivePermanents(filter1,
|
||||
source.getControllerId(), game).isEmpty()) {
|
||||
game.getStack().counter(spell.getId(), source.getSourceId(), game);
|
||||
return true;
|
||||
}
|
||||
FilterCard filter2 = new FilterCard();
|
||||
|
|
|
@ -29,7 +29,8 @@ public final class CephalidShrine extends CardImpl {
|
|||
public CephalidShrine(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{U}");
|
||||
|
||||
// Whenever a player casts a spell, counter that spell unless that player pays {X}, where X is the number of cards in all graveyards with the same name as the spell.
|
||||
// Whenever a player casts a spell, counter that spell unless that player
|
||||
// pays {X}, where X is the number of cards in all graveyards with the same name as the spell.
|
||||
this.addAbility(new CephalidShrineTriggeredAbility());
|
||||
}
|
||||
|
||||
|
@ -67,7 +68,8 @@ class CephalidShrineTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
MageObject mageObject = game.getObject(sourceId);
|
||||
if (spell != null && mageObject != null) {
|
||||
if (spell != null
|
||||
&& mageObject != null) {
|
||||
game.getState().setValue("cephalidShrine" + mageObject, spell);
|
||||
return true;
|
||||
}
|
||||
|
@ -80,7 +82,10 @@ class CephalidShrineEffect extends OneShotEffect {
|
|||
|
||||
public CephalidShrineEffect() {
|
||||
super(Outcome.Detriment);
|
||||
staticText = "Whenever a player casts a spell, counter that spell unless that player pays {X}, where X is the number of cards in all graveyards with the same name as the spell";
|
||||
staticText = "Whenever a player casts a spell, counter that "
|
||||
+ "spell unless that player pays {X}, where X is the "
|
||||
+ "number of cards in all graveyards with the same name "
|
||||
+ "as the spell";
|
||||
}
|
||||
|
||||
public CephalidShrineEffect(final CephalidShrineEffect effect) {
|
||||
|
@ -109,13 +114,15 @@ class CephalidShrineEffect extends OneShotEffect {
|
|||
Cost cost = ManaUtil.createManaCost(count, true);
|
||||
if (game.getStack().contains(spell)
|
||||
&& cost.canPay(source, source.getSourceId(), controller.getId(), game)
|
||||
&& controller.chooseUse(outcome, "Pay " + cost.getText() + " to prevent countering " + spell.getName() + "?", source, game)
|
||||
&& controller.chooseUse(outcome, "Pay " + cost.getText()
|
||||
+ " to prevent countering " + spell.getName() + "?", source, game)
|
||||
&& cost.pay(source, game, source.getSourceId(), controller.getId(), false)
|
||||
&& cost.isPaid()) {
|
||||
return false;
|
||||
} else {
|
||||
spell.counter(source.getId(), game);
|
||||
game.informPlayers(spell.getName() + " has been countered due to " + controller.getName() + " not paying " + cost.getText());
|
||||
game.getStack().counter(spell.getId(), source.getSourceId(), game);
|
||||
game.informPlayers(spell.getName() + " has been countered due to "
|
||||
+ controller.getName() + " not paying " + cost.getText());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.f;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -27,7 +26,8 @@ public final class ForceChoke extends CardImpl {
|
|||
public ForceChoke(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{B}");
|
||||
|
||||
// Counter target spell. Its controller may pay life equal to that spell's cmc to return it to its owner's hand.
|
||||
// Counter target spell. Its controller may pay life equal to that
|
||||
// spell's cmc to return it to its owner's hand.
|
||||
this.getSpellAbility().addTarget(new TargetSpell());
|
||||
this.getSpellAbility().addEffect(new ForceChokeEffect());
|
||||
|
||||
|
@ -49,7 +49,8 @@ class ForceChokeEffect extends OneShotEffect {
|
|||
|
||||
public ForceChokeEffect() {
|
||||
super(Outcome.ReturnToHand);
|
||||
this.staticText = "Counter target spell. Its controller may pay life equal to that spell's converted mana cost to return it to its owner's hand";
|
||||
this.staticText = "Counter target spell. Its controller may pay life "
|
||||
+ "equal to that spell's converted mana cost to return it to its owner's hand";
|
||||
}
|
||||
|
||||
public ForceChokeEffect(final ForceChokeEffect effect) {
|
||||
|
@ -69,11 +70,12 @@ class ForceChokeEffect extends OneShotEffect {
|
|||
if (player != null) {
|
||||
Cost cost = new PayLifeCost(stackObject.getConvertedManaCost());
|
||||
if (cost.canPay(source, source.getSourceId(), objectController.getId(), game)
|
||||
&& objectController.chooseUse(Outcome.LoseLife, "Pay " + stackObject.getConvertedManaCost() + " life?", source, game)
|
||||
&& objectController.chooseUse(Outcome.LoseLife, "Pay "
|
||||
+ stackObject.getConvertedManaCost() + " life?", source, game)
|
||||
&& cost.pay(source, game, source.getSourceId(), objectController.getId(), false, null)) {
|
||||
objectController.moveCards((Card) stackObject, Zone.HAND, source, game);
|
||||
} else {
|
||||
stackObject.counter(source.getId(), game);
|
||||
game.getStack().counter(stackObject.getId(), source.getSourceId(), game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -34,22 +33,26 @@ public final class GrimoireThief extends CardImpl {
|
|||
protected static final String VALUE_PREFIX = "ExileZones";
|
||||
|
||||
public GrimoireThief(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}");
|
||||
this.subtype.add(SubType.MERFOLK);
|
||||
this.subtype.add(SubType.ROGUE);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// Whenever Grimoire Thief becomes tapped, exile the top three cards of target opponent's library face down.
|
||||
Ability ability = new BecomesTappedSourceTriggeredAbility(new GrimoireThiefExileEffect(), false);
|
||||
// Whenever Grimoire Thief becomes tapped, exile the top three
|
||||
// cards of target opponent's library face down.
|
||||
Ability ability = new BecomesTappedSourceTriggeredAbility(
|
||||
new GrimoireThiefExileEffect(), false);
|
||||
ability.addTarget(new TargetOpponent());
|
||||
this.addAbility(ability);
|
||||
|
||||
// You may look at cards exiled with Grimoire Thief.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new GrimoireThiefLookEffect()));
|
||||
|
||||
// {U}, Sacrifice Grimoire Thief: Turn all cards exiled with Grimoire Thief face up. Counter all spells with those names.
|
||||
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GrimoireThiefCounterspellEffect(), new ManaCostsImpl("{U}"));
|
||||
// {U}, Sacrifice Grimoire Thief: Turn all cards exiled with
|
||||
//Grimoire Thief face up. Counter all spells with those names.
|
||||
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD,
|
||||
new GrimoireThiefCounterspellEffect(), new ManaCostsImpl("{U}"));
|
||||
ability2.addCost(new SacrificeSourceCost());
|
||||
this.addAbility(ability2);
|
||||
|
||||
|
@ -86,15 +89,19 @@ class GrimoireThiefExileEffect extends OneShotEffect {
|
|||
for (Card card : cards) {
|
||||
card.setFaceDown(true, game);
|
||||
}
|
||||
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
targetOpponent.moveCardsToExile(cards, source, game, false, exileZoneId, sourceObject.getIdName());
|
||||
UUID exileZoneId = CardUtil.getExileZoneId(game,
|
||||
source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
targetOpponent.moveCardsToExile(cards, source, game, false,
|
||||
exileZoneId, sourceObject.getIdName());
|
||||
for (Card card : cards) {
|
||||
card.setFaceDown(true, game);
|
||||
}
|
||||
Set<UUID> exileZones = (Set<UUID>) game.getState().getValue(GrimoireThief.VALUE_PREFIX + source.getSourceId().toString());
|
||||
Set<UUID> exileZones = (Set<UUID>) game.getState().getValue(
|
||||
GrimoireThief.VALUE_PREFIX + source.getSourceId().toString());
|
||||
if (exileZones == null) {
|
||||
exileZones = new HashSet<>();
|
||||
game.getState().setValue(GrimoireThief.VALUE_PREFIX + source.getSourceId().toString(), exileZones);
|
||||
game.getState().setValue(GrimoireThief.VALUE_PREFIX
|
||||
+ source.getSourceId().toString(), exileZones);
|
||||
}
|
||||
exileZones.add(exileZoneId);
|
||||
return true;
|
||||
|
@ -132,13 +139,17 @@ class GrimoireThiefLookEffect extends AsThoughEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (affectedControllerId.equals(source.getControllerId()) && game.getState().getZone(objectId) == Zone.EXILED) {
|
||||
if (affectedControllerId.equals(source.getControllerId())
|
||||
&& game.getState().getZone(objectId) == Zone.EXILED) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (controller != null && sourceObject != null) {
|
||||
if (controller != null
|
||||
&& sourceObject != null) {
|
||||
Card card = game.getCard(objectId);
|
||||
if (card != null && card.isFaceDown(game)) {
|
||||
Set<UUID> exileZones = (Set<UUID>) game.getState().getValue(GrimoireThief.VALUE_PREFIX + source.getSourceId().toString());
|
||||
if (card != null
|
||||
&& card.isFaceDown(game)) {
|
||||
Set<UUID> exileZones = (Set<UUID>) game.getState().
|
||||
getValue(GrimoireThief.VALUE_PREFIX + source.getSourceId().toString());
|
||||
if (exileZones != null) {
|
||||
for (ExileZone exileZone : game.getExile().getExileZones()) {
|
||||
if (exileZone.contains(objectId)) {
|
||||
|
@ -160,7 +171,8 @@ class GrimoireThiefCounterspellEffect extends OneShotEffect {
|
|||
|
||||
public GrimoireThiefCounterspellEffect() {
|
||||
super(Outcome.Discard);
|
||||
staticText = "Turn all cards exiled with {this} face up. Counter all spells with those names";
|
||||
staticText = "Turn all cards exiled with {this} face up. "
|
||||
+ "Counter all spells with those names";
|
||||
}
|
||||
|
||||
public GrimoireThiefCounterspellEffect(final GrimoireThiefCounterspellEffect effect) {
|
||||
|
@ -171,7 +183,8 @@ class GrimoireThiefCounterspellEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Cards cards = new CardsImpl();
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
Set<UUID> exileZones = (Set<UUID>) game.getState().getValue(GrimoireThief.VALUE_PREFIX + source.getSourceId().toString());
|
||||
Set<UUID> exileZones = (Set<UUID>) game.getState().getValue(
|
||||
GrimoireThief.VALUE_PREFIX + source.getSourceId().toString());
|
||||
if (exileZones != null && sourceObject != null) {
|
||||
for (ExileZone exileZone : game.getExile().getExileZones()) {
|
||||
if (!exileZone.isEmpty()) {
|
||||
|
@ -190,18 +203,24 @@ class GrimoireThiefCounterspellEffect extends OneShotEffect {
|
|||
// handle split cards
|
||||
if (mageObject instanceof SplitCard) {
|
||||
if (stackObject instanceof Spell
|
||||
&& (stackObject.getName().contains(((SplitCard)mageObject).getLeftHalfCard().getName())
|
||||
|| stackObject.getName().contains(((SplitCard)mageObject).getRightHalfCard().getName()))) {
|
||||
&& (stackObject.getName().contains(((SplitCard) mageObject).getLeftHalfCard().getName())
|
||||
|| stackObject.getName().contains(((SplitCard) mageObject).getRightHalfCard().getName()))) {
|
||||
Spell spell = (Spell) stackObject;
|
||||
spell.counter(source.getSourceId(), game);
|
||||
game.informPlayers(sourceObject.getLogName() + ": the split-card spell named " + spell.getName() + " was countered.");
|
||||
game.getStack().counter(stackObject.getId(), source.getSourceId(), game);
|
||||
game.informPlayers(sourceObject.getLogName()
|
||||
+ ": the split-card spell named "
|
||||
+ spell.getName()
|
||||
+ " was countered.");
|
||||
}
|
||||
}
|
||||
if (stackObject instanceof Spell
|
||||
&& stackObject.getName().contains(card.getName())) {
|
||||
Spell spell = (Spell) stackObject;
|
||||
spell.counter(source.getSourceId(), game);
|
||||
game.informPlayers(sourceObject.getLogName() + ": the spell named " + spell.getName() + " was countered.");
|
||||
game.getStack().counter(spell.getId(), source.getSourceId(), game);
|
||||
game.informPlayers(sourceObject.getLogName()
|
||||
+ ": the spell named "
|
||||
+ spell.getName()
|
||||
+ " was countered.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -27,7 +26,9 @@ public final class Prohibit extends CardImpl {
|
|||
// Kicker {2}
|
||||
this.addAbility(new KickerAbility("{2}"));
|
||||
|
||||
// Counter target spell if its converted mana cost is 2 or less. If Prohibit was kicked, counter that spell if its converted mana cost is 4 or less instead.
|
||||
// Counter target spell if its converted mana cost is 2 or less.
|
||||
// If Prohibit was kicked, counter that spell if its
|
||||
// converted mana cost is 4 or less instead.
|
||||
this.getSpellAbility().addEffect(new ProhibitEffect());
|
||||
this.getSpellAbility().addTarget(new TargetSpell());
|
||||
}
|
||||
|
@ -46,7 +47,9 @@ class ProhibitEffect extends OneShotEffect {
|
|||
|
||||
ProhibitEffect() {
|
||||
super(Outcome.DestroyPermanent);
|
||||
this.staticText = "Counter target spell if its converted mana cost is 2 or less. if this spell was kicked, counter that spell if its converted mana cost is 4 or less instead.";
|
||||
this.staticText = "Counter target spell if its converted mana cost "
|
||||
+ "is 2 or less. if this spell was kicked, counter that "
|
||||
+ "spell if its converted mana cost is 4 or less instead.";
|
||||
}
|
||||
|
||||
ProhibitEffect(final ProhibitEffect effect) {
|
||||
|
@ -65,8 +68,9 @@ class ProhibitEffect extends OneShotEffect {
|
|||
Spell targetSpell = game.getSpell(this.getTargetPointer().getFirst(game, source));
|
||||
if (targetSpell != null) {
|
||||
int cmc = targetSpell.getConvertedManaCost();
|
||||
if (cmc <= 2 || (KickedCondition.instance.apply(game, source) && cmc <= 4)) {
|
||||
targetSpell.counter(source.getSourceId(), game);
|
||||
if (cmc <= 2
|
||||
|| (KickedCondition.instance.apply(game, source) && cmc <= 4)) {
|
||||
game.getStack().counter(targetSpell.getId(), source.getSourceId(), game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -24,7 +24,8 @@ public final class RitesOfRefusal extends CardImpl {
|
|||
public RitesOfRefusal(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
|
||||
|
||||
// Discard any number of cards. Counter target spell unless its controller pays {3} for each card discarded this way.
|
||||
// Discard any number of cards. Counter target spell unless its
|
||||
// controller pays {3} for each card discarded this way.
|
||||
this.getSpellAbility().addEffect(new RitesOfRefusalEffect());
|
||||
this.getSpellAbility().addTarget(new TargetSpell());
|
||||
|
||||
|
@ -44,7 +45,8 @@ class RitesOfRefusalEffect extends OneShotEffect {
|
|||
|
||||
RitesOfRefusalEffect() {
|
||||
super(Outcome.AIDontUseIt);
|
||||
this.staticText = "Discard any number of cards. Counter target spell unless its controller pays {3} for each card discarded this way";
|
||||
this.staticText = "Discard any number of cards. Counter target "
|
||||
+ "spell unless its controller pays {3} for each card discarded this way";
|
||||
}
|
||||
|
||||
RitesOfRefusalEffect(final RitesOfRefusalEffect effect) {
|
||||
|
@ -63,16 +65,23 @@ class RitesOfRefusalEffect extends OneShotEffect {
|
|||
if (targetSpell != null) {
|
||||
Player controllerOfTargetedSpell = game.getPlayer(targetSpell.getControllerId());
|
||||
if (controller != null && controllerOfTargetedSpell != null) {
|
||||
int numToDiscard = controller.getAmount(0, controller.getHand().size(), "How many cards do you want to discard?", game);
|
||||
int numToDiscard = controller.getAmount(0,
|
||||
controller.getHand().size(), "How many cards do you want to discard?", game);
|
||||
Cards discardedCards = controller.discard(numToDiscard, false, source, game);
|
||||
int actualNumberDiscarded = discardedCards.size();
|
||||
if (actualNumberDiscarded > 0) {
|
||||
Cost cost = ManaUtil.createManaCost(actualNumberDiscarded * 3, false);
|
||||
if (controllerOfTargetedSpell.chooseUse(Outcome.Benefit, "Do you want to pay " + cost.getText() + " to prevent " + targetSpell.getName() + " from gettting countered?", source, game)
|
||||
&& cost.pay(source, game, source.getSourceId(), controllerOfTargetedSpell.getId(), false)) {
|
||||
if (controllerOfTargetedSpell.chooseUse(Outcome.Benefit,
|
||||
"Do you want to pay "
|
||||
+ cost.getText()
|
||||
+ " to prevent "
|
||||
+ targetSpell.getName()
|
||||
+ " from gettting countered?", source, game)
|
||||
&& cost.pay(source, game, source.getSourceId(),
|
||||
controllerOfTargetedSpell.getId(), false)) {
|
||||
return true;
|
||||
}
|
||||
targetSpell.counter(source.getSourceId(), game);
|
||||
game.getStack().counter(targetSpell.getId(), source.getSourceId(), game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ class WhirlwindDenialEffect extends OneShotEffect {
|
|||
&& cost.pay(source, game, source.getSourceId(), stackObject.getControllerId(), false)) {
|
||||
return;
|
||||
}
|
||||
stackObject.counter(source.getSourceId(), game);
|
||||
game.getStack().counter(stackObject.getId(), source.getSourceId(), game);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue