Update effects and abilities which involve tapping permanents for mana (#7679)

Abilities which use trigger from or replace tapping for mana now save the permanent in case it leaves the battlefield.
fixes #7671, fixes #7770
* Merge fix and additional comments, Winter's Night fixed

Co-authored-by: Oleg Agafonov <jaydi85@gmail.com>
This commit is contained in:
Evan Kranzler 2021-07-21 21:09:07 -04:00 committed by GitHub
parent 81193148e9
commit 214b688fdb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 884 additions and 1149 deletions

View file

@ -1,11 +1,8 @@
package mage.cards.b;
import java.util.UUID;
import mage.Mana;
import mage.abilities.effects.Effect;
import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect;
import mage.abilities.mana.DelayedTriggeredManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -13,21 +10,21 @@ import mage.constants.CardType;
import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author spjspj
*/
public final class BubblingMuck extends CardImpl {
public BubblingMuck(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
// Until end of turn, whenever a player taps a Swamp for mana, that player adds {B}.
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new BubblingMuckTriggeredAbility()));
@ -45,18 +42,12 @@ public final class BubblingMuck extends CardImpl {
class BubblingMuckTriggeredAbility extends DelayedTriggeredManaAbility {
private static final FilterLandPermanent filter = new FilterLandPermanent("Swamp");
static {
filter.add(SubType.SWAMP.getPredicate());
}
public BubblingMuckTriggeredAbility() {
BubblingMuckTriggeredAbility() {
super(new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.B), "their"), Duration.EndOfTurn, false);
this.usesStack = false;
}
public BubblingMuckTriggeredAbility(BubblingMuckTriggeredAbility ability) {
private BubblingMuckTriggeredAbility(BubblingMuckTriggeredAbility ability) {
super(ability);
}
@ -67,14 +58,12 @@ class BubblingMuckTriggeredAbility extends DelayedTriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId());
if (filter.match(land, getSourceId(), getControllerId(), game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(land.getControllerId()));
}
return true;
Permanent land = ((TappedForManaEvent) event).getPermanent();
if (land == null || !land.hasSubtype(SubType.SWAMP, game)) {
return false;
}
return false;
getEffects().setTargetPointer(new FixedTarget(land.getControllerId()));
return true;
}
@Override

View file

@ -1,35 +1,32 @@
package mage.cards.c;
import java.util.UUID;
import mage.Mana;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect;
import mage.abilities.mana.DelayedTriggeredManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class ChaosMoon extends CardImpl {
@ -38,7 +35,7 @@ public final class ChaosMoon extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
// At the beginning of each upkeep, count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ChaosMoonEffect(), TargetController.ANY, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ChaosMoonEffect(), TargetController.ANY, false));
}
private ChaosMoon(final ChaosMoon card) {
@ -59,12 +56,16 @@ class ChaosMoonEffect extends OneShotEffect {
filter.add(new ColorPredicate(ObjectColor.RED));
}
public ChaosMoonEffect() {
ChaosMoonEffect() {
super(Outcome.Neutral);
this.staticText = "count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type";
this.staticText = "count the number of permanents. If the number is odd, " +
"until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, " +
"that player adds {R} (in addition to the mana the land produces). If the number is even, " +
"until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, " +
"that Mountain produces colorless mana instead of any other type";
}
public ChaosMoonEffect(final ChaosMoonEffect effect) {
private ChaosMoonEffect(final ChaosMoonEffect effect) {
super(effect);
}
@ -76,37 +77,33 @@ class ChaosMoonEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
int permanentsInPlay = new PermanentsOnBattlefieldCount().calculate(game, source, null);
// Odd
if (permanentsInPlay % 2 != 0) {
game.addEffect(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), source);
new CreateDelayedTriggeredAbilityEffect(new ChaosMoonOddTriggeredAbility()).apply(game, source);
} // Even
else {
game.addEffect(new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter, false), source);
game.addEffect(new ChaosMoonEvenReplacementEffect(), source);
}
return true;
if (player == null) {
return false;
}
return false;
int permanentsInPlay = game.getBattlefield().count(
StaticFilters.FILTER_PERMANENT, source.getSourceId(), source.getControllerId(), game
);
// Odd
if (permanentsInPlay % 2 != 0) {
game.addEffect(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), source);
new CreateDelayedTriggeredAbilityEffect(new ChaosMoonOddTriggeredAbility()).apply(game, source);
} // Even
else {
game.addEffect(new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter, false), source);
game.addEffect(new ChaosMoonEvenReplacementEffect(), source);
}
return true;
}
}
class ChaosMoonOddTriggeredAbility extends DelayedTriggeredManaAbility {
private static final FilterLandPermanent filter = new FilterLandPermanent("Mountain");
static {
filter.add(SubType.MOUNTAIN.getPredicate());
}
public ChaosMoonOddTriggeredAbility() {
ChaosMoonOddTriggeredAbility() {
super(new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.R), "their"), Duration.EndOfTurn, false);
this.usesStack = false;
}
public ChaosMoonOddTriggeredAbility(ChaosMoonOddTriggeredAbility ability) {
private ChaosMoonOddTriggeredAbility(ChaosMoonOddTriggeredAbility ability) {
super(ability);
}
@ -117,14 +114,12 @@ class ChaosMoonOddTriggeredAbility extends DelayedTriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId());
if (filter.match(land, getSourceId(), getControllerId(), game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(land.getControllerId()));
}
return true;
Permanent land = ((TappedForManaEvent) event).getPermanent();
if (land == null || !land.hasSubtype(SubType.MOUNTAIN, game)) {
return false;
}
return false;
this.getEffects().setTargetPointer(new FixedTarget(land.getControllerId()));
return true;
}
@Override
@ -140,18 +135,12 @@ class ChaosMoonOddTriggeredAbility extends DelayedTriggeredManaAbility {
class ChaosMoonEvenReplacementEffect extends ReplacementEffectImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent("Mountain");
static {
filter.add(SubType.MOUNTAIN.getPredicate());
}
ChaosMoonEvenReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Neutral);
staticText = "Until end of turn, if a Mountain is tapped for mana, it produces colorless mana instead of any other type.";
}
ChaosMoonEvenReplacementEffect(final ChaosMoonEvenReplacementEffect effect) {
private ChaosMoonEvenReplacementEffect(final ChaosMoonEvenReplacementEffect effect) {
super(effect);
}
@ -180,10 +169,7 @@ class ChaosMoonEvenReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null && permanent.isLand(game)) {
return filter.match(permanent, game);
}
return false;
Permanent land = ((TappedForManaEvent) event).getPermanent();
return land != null && land.hasSubtype(SubType.MOUNTAIN, game);
}
}

View file

@ -1,8 +1,5 @@
package mage.cards.c;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@ -13,15 +10,18 @@ import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
/**
*
* @author emerald000
*/
public final class Contamination extends CardImpl {
@ -30,8 +30,11 @@ public final class Contamination extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
// At the beginning of your upkeep, sacrifice Contamination unless you sacrifice a creature.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(
new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT))), TargetController.YOU, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(
new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)
)), TargetController.YOU, false)
);
// If a land is tapped for mana, it produces {B} instead of any other type and amount.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ContaminationReplacementEffect()));
@ -54,7 +57,7 @@ class ContaminationReplacementEffect extends ReplacementEffectImpl {
staticText = "If a land is tapped for mana, it produces {B} instead of any other type and amount";
}
ContaminationReplacementEffect(final ContaminationReplacementEffect effect) {
private ContaminationReplacementEffect(final ContaminationReplacementEffect effect) {
super(effect);
}
@ -83,7 +86,7 @@ class ContaminationReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game);
}
}

View file

@ -1,6 +1,5 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.effects.mana.BasicManaEffect;
@ -11,14 +10,14 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author Plopman
*/
public final class CryptGhast extends CardImpl {
@ -49,18 +48,12 @@ public final class CryptGhast extends CardImpl {
class CryptGhastTriggeredAbility extends TriggeredManaAbility {
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("Swamp");
static {
filter.add(SubType.SWAMP.getPredicate());
}
public CryptGhastTriggeredAbility() {
CryptGhastTriggeredAbility() {
super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.BlackMana(1)), false);
this.usesStack = false;
}
public CryptGhastTriggeredAbility(CryptGhastTriggeredAbility ability) {
private CryptGhastTriggeredAbility(CryptGhastTriggeredAbility ability) {
super(ability);
}
@ -71,8 +64,8 @@ class CryptGhastTriggeredAbility extends TriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId());
return filter.match(land, this.getSourceId(), this.getControllerId(), game);
Permanent land = ((TappedForManaEvent) event).getPermanent();
return land != null && land.isControlledBy(getControllerId()) && land.hasSubtype(SubType.SWAMP, game);
}
@Override

View file

@ -1,6 +1,5 @@
package mage.cards.d;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -8,11 +7,16 @@ import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.cost.SpellsCostIncreasingAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import mage.watchers.common.CastSpellLastTurnWatcher;
@ -27,10 +31,10 @@ public final class DampingSphere extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// If a land is tapped for two or more mana, it produces {C} instead of any other type and amount.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DampingSphereReplacementEffect()));
this.addAbility(new SimpleStaticAbility(new DampingSphereReplacementEffect()));
// Each spell a player casts costs {1} more to cast for each other spell that player has cast this turn.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DampingSphereIncreasementAllEffect()), new CastSpellLastTurnWatcher());
this.addAbility(new SimpleStaticAbility(new DampingSphereIncreasementAllEffect()), new CastSpellLastTurnWatcher());
}
private DampingSphere(final DampingSphere card) {
@ -50,7 +54,7 @@ class DampingSphereReplacementEffect extends ReplacementEffectImpl {
staticText = "If a land is tapped for two or more mana, it produces {C} instead of any other type and amount";
}
DampingSphereReplacementEffect(final DampingSphereReplacementEffect effect) {
private DampingSphereReplacementEffect(final DampingSphereReplacementEffect effect) {
super(effect);
}
@ -79,10 +83,10 @@ class DampingSphereReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
MageObject mageObject = game.getPermanentOrLKIBattlefield(event.getSourceId());
ManaEvent manaEvent = (ManaEvent) event;
TappedForManaEvent manaEvent = (TappedForManaEvent) event;
Permanent land = manaEvent.getPermanent();
Mana mana = manaEvent.getMana();
return mageObject != null && mageObject.isLand(game) && mana.count() > 1;
return land != null && land.isLand(game) && mana.count() > 1;
}
}
@ -93,7 +97,7 @@ class DampingSphereIncreasementAllEffect extends SpellsCostIncreasingAllEffect {
this.staticText = "Each spell a player casts costs {1} more to cast for each other spell that player has cast this turn";
}
DampingSphereIncreasementAllEffect(DampingSphereIncreasementAllEffect effect) {
private DampingSphereIncreasementAllEffect(DampingSphereIncreasementAllEffect effect) {
super(effect);
}

View file

@ -1,8 +1,5 @@
package mage.cards.d;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -13,15 +10,15 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class DeepWater extends CardImpl {
@ -30,8 +27,7 @@ public final class DeepWater extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}");
// {U}: Until end of turn, if you tap a land you control for mana, it produces {U} instead of any other type.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DeepWaterReplacementEffect(), new ManaCostsImpl("{U}"));
this.addAbility(ability);
this.addAbility(new SimpleActivatedAbility(new DeepWaterReplacementEffect(), new ManaCostsImpl("{U}")));
}
private DeepWater(final DeepWater card) {
@ -46,14 +42,12 @@ public final class DeepWater extends CardImpl {
class DeepWaterReplacementEffect extends ReplacementEffectImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
DeepWaterReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Neutral);
staticText = "Until end of turn, if you tap a land you control for mana, it produces {U} instead of any other type";
}
DeepWaterReplacementEffect(final DeepWaterReplacementEffect effect) {
private DeepWaterReplacementEffect(final DeepWaterReplacementEffect effect) {
super(effect);
}
@ -82,10 +76,7 @@ class DeepWaterReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null && permanent.isLand(game)) {
return filter.match(permanent, game);
}
return false;
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game) && permanent.isControlledBy(source.getControllerId());
}
}

View file

@ -6,19 +6,17 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent;
import mage.watchers.Watcher;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.*;
/**
* @author L_J
@ -28,9 +26,11 @@ public final class Desolation extends CardImpl {
public Desolation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}");
// At the beginning of each end step, each player who tapped a land for mana this turn sacrifices a land. Desolation deals 2 damage to each player who sacrificed a Plains this way.
BeginningOfEndStepTriggeredAbility ability = new BeginningOfEndStepTriggeredAbility(new DesolationEffect(), TargetController.ANY, false);
this.addAbility(ability, new DesolationWatcher());
// At the beginning of each end step, each player who tapped a land for mana this
// turn sacrifices a land. Desolation deals 2 damage to each player who sacrificed a Plains this way.
this.addAbility(new BeginningOfEndStepTriggeredAbility(
new DesolationEffect(), TargetController.ANY, false
), new DesolationWatcher());
}
private Desolation(final Desolation card) {
@ -45,47 +45,49 @@ public final class Desolation extends CardImpl {
class DesolationEffect extends OneShotEffect {
private static final FilterPermanent filterPlains = new FilterPermanent();
static {
filterPlains.add(SubType.PLAINS.getPredicate());
}
public DesolationEffect() {
DesolationEffect() {
super(Outcome.Damage);
this.staticText = "each player who tapped a land for mana this turn sacrifices a land. {this} deals 2 damage to each player who sacrificed a Plains this way";
this.staticText = "each player who tapped a land for mana this turn sacrifices a land. " +
"{this} deals 2 damage to each player who sacrificed a Plains this way";
}
public DesolationEffect(DesolationEffect copy) {
private DesolationEffect(DesolationEffect copy) {
super(copy);
}
@Override
public boolean apply(Game game, Ability source) {
DesolationWatcher watcher = game.getState().getWatcher(DesolationWatcher.class);
if (watcher != null) {
for (UUID playerId : watcher.getPlayersTappedForMana()) {
Player player = game.getPlayer(playerId);
if (player != null) {
FilterControlledPermanent filter = new FilterControlledPermanent("land");
filter.add(CardType.LAND.getPredicate());
filter.add(new ControllerIdPredicate(playerId));
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true);
if (target.canChoose(source.getSourceId(), player.getId(), game)) {
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
permanent.sacrifice(source, game);
if (filterPlains.match(permanent, game)) {
player.damage(2, source.getSourceId(), source, game);
}
}
}
}
}
return true;
if (watcher == null) {
return false;
}
return false;
List<Permanent> permanents = new ArrayList<>();
for (UUID playerId : watcher.getPlayersTappedForMana()) {
Player player = game.getPlayer(playerId);
if (player == null) {
continue;
}
TargetPermanent target = new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND);
target.setNotTarget(true);
if (!target.canChoose(source.getSourceId(), player.getId(), game)) {
continue;
}
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
permanents.add(permanent);
}
}
for (Permanent permanent : permanents) {
Player player = game.getPlayer(permanent.getControllerId());
if (permanent != null
&& permanent.sacrifice(source, game)
&& permanent.hasSubtype(SubType.PLAINS, game)
&& player != null) {
player.damage(2, source.getSourceId(), source, game);
}
}
return true;
}
@Override
@ -98,25 +100,19 @@ class DesolationWatcher extends Watcher {
private final Set<UUID> tappedForManaThisTurnPlayers = new HashSet<>();
public DesolationWatcher() {
DesolationWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.UNTAP_STEP_PRE) {
reset();
if (event.getType() != GameEvent.EventType.TAPPED_FOR_MANA
&& !game.inCheckPlayableState()) {
return;
}
if (event.getType() == GameEvent.EventType.TAPPED_FOR_MANA
&& !game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA
UUID playerId = event.getPlayerId();
if (playerId != null) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); // need only info about permanent
if (permanent != null && permanent.isLand(game)) {
tappedForManaThisTurnPlayers.add(playerId);
}
}
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
if (permanent != null) {
tappedForManaThisTurnPlayers.add(permanent.getControllerId());
}
}
@ -129,5 +125,4 @@ class DesolationWatcher extends Watcher {
super.reset();
tappedForManaThisTurnPlayers.clear();
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.d;
import java.util.UUID;
@ -20,9 +19,9 @@ public final class DictateOfKarametra extends CardImpl {
public DictateOfKarametra(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}{G}");
// Flash
this.addAbility(FlashAbility.getInstance());
// Whenever a player taps a land for mana, that player adds one mana of any type that land produced.
this.addAbility(new TapForManaAllTriggeredManaAbility(
new AddManaOfAnyTypeProducedEffect(),

View file

@ -20,6 +20,7 @@ import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetLandPermanent;
@ -113,7 +114,7 @@ class ExtraplanarLensTriggeredAbility extends TriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent landTappedForMana = game.getPermanentOrLKIBattlefield(event.getSourceId()); // need only info about permanent
Permanent landTappedForMana = ((TappedForManaEvent) event).getPermanent(); // need only info about permanent
Permanent extraplanarLens = game.getPermanent(getSourceId());
if (extraplanarLens != null
&& landTappedForMana != null

View file

@ -1,35 +1,5 @@
/*
*
* 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.cards.f;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.CreateTokenTargetEffect;
import mage.abilities.mana.AnyColorManaAbility;
@ -39,11 +9,14 @@ import mage.constants.CardType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.SpiritToken;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class ForbiddenOrchard extends CardImpl {
@ -70,12 +43,12 @@ public final class ForbiddenOrchard extends CardImpl {
class ForbiddenOrchardTriggeredAbility extends TriggeredAbilityImpl {
public ForbiddenOrchardTriggeredAbility() {
ForbiddenOrchardTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenTargetEffect(new SpiritToken()));
this.addTarget(new TargetOpponent());
}
public ForbiddenOrchardTriggeredAbility(final ForbiddenOrchardTriggeredAbility ability) {
private ForbiddenOrchardTriggeredAbility(final ForbiddenOrchardTriggeredAbility ability) {
super(ability);
}
@ -86,10 +59,14 @@ class ForbiddenOrchardTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA
// it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA
if (game.inCheckPlayableState()) {
return false;
}
return event.getSourceId().equals(getSourceId());
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null
&& permanent == getSourcePermanentOrLKI(game)
&& isControlledBy(event.getPlayerId());
}
@Override
@ -101,5 +78,4 @@ class ForbiddenOrchardTriggeredAbility extends TriggeredAbilityImpl {
public ForbiddenOrchardTriggeredAbility copy() {
return new ForbiddenOrchardTriggeredAbility(this);
}
}

View file

@ -18,7 +18,7 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorlessPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
@ -80,12 +80,11 @@ class ForsakenMonumentTriggeredManaAbility extends TriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
ManaEvent mEvent = (ManaEvent) event;
if (permanent == null || !mEvent.getPlayerId().equals(getControllerId())) {
return false;
}
return mEvent.getMana().getColorless() > 0;
TappedForManaEvent mEvent = (TappedForManaEvent) event;
Permanent permanent = mEvent.getPermanent();
return permanent != null
&& isControlledBy(event.getPlayerId())
&& mEvent.getMana().getColorless() > 0;
}
@Override

View file

@ -5,20 +5,22 @@ import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ChooseColorEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.abilities.effects.mana.AddManaChosenColorEffect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.mana.TriggeredManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.mageobject.ChosenColorPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
@ -32,10 +34,11 @@ import java.util.UUID;
*/
public final class GauntletOfPower extends CardImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent("a basic land");
private static final FilterCreaturePermanent filter
= new FilterCreaturePermanent("creatures of the chosen color");
static {
filter.add(SuperType.BASIC.getPredicate());
filter.add(ChosenColorPredicate.TRUE);
}
public GauntletOfPower(UUID ownerId, CardSetInfo setInfo) {
@ -43,11 +46,14 @@ public final class GauntletOfPower extends CardImpl {
// As Gauntlet of Power enters the battlefield, choose a color.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral)));
// Creatures of the chosen color get +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GauntletOfPowerBoostEffect()));
this.addAbility(new SimpleStaticAbility(new BoostAllEffect(
1, 1, Duration.WhileOnBattlefield, filter, false
)));
// Whenever a basic land is tapped for mana of the chosen color, its controller adds one mana of that color.
this.addAbility(new GauntletOfPowerTapForManaAllTriggeredAbility(new GauntletOfPowerManaEffect2(), filter, SetTargetPointer.PERMANENT));
this.addAbility(new GauntletOfPowerTapForManaAllTriggeredAbility());
}
private GauntletOfPower(final GauntletOfPower card) {
@ -60,55 +66,14 @@ public final class GauntletOfPower extends CardImpl {
}
}
class GauntletOfPowerBoostEffect extends ContinuousEffectImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
public GauntletOfPowerBoostEffect() {
super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.BoostCreature);
staticText = "Creatures of the chosen color get +1/+1";
}
public GauntletOfPowerBoostEffect(final GauntletOfPowerBoostEffect effect) {
super(effect);
}
@Override
public GauntletOfPowerBoostEffect copy() {
return new GauntletOfPowerBoostEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
ObjectColor color = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color");
if (color != null) {
for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (perm.getColor(game).contains(color)) {
perm.addPower(1);
perm.addToughness(1);
}
}
}
return true;
}
}
class GauntletOfPowerTapForManaAllTriggeredAbility extends TriggeredManaAbility {
private final FilterPermanent filter;
private final SetTargetPointer setTargetPointer;
public GauntletOfPowerTapForManaAllTriggeredAbility(ManaEffect effect, FilterPermanent filter, SetTargetPointer setTargetPointer) {
super(Zone.BATTLEFIELD, effect, false);
this.filter = filter;
this.setTargetPointer = setTargetPointer;
GauntletOfPowerTapForManaAllTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddManaChosenColorEffect(), false);
}
public GauntletOfPowerTapForManaAllTriggeredAbility(GauntletOfPowerTapForManaAllTriggeredAbility ability) {
private GauntletOfPowerTapForManaAllTriggeredAbility(GauntletOfPowerTapForManaAllTriggeredAbility ability) {
super(ability);
this.filter = ability.filter.copy();
this.setTargetPointer = ability.setTargetPointer;
}
@Override
@ -118,42 +83,27 @@ class GauntletOfPowerTapForManaAllTriggeredAbility extends TriggeredManaAbility
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) {
ManaEvent mEvent = (ManaEvent) event;
ObjectColor color = (ObjectColor) game.getState().getValue(getSourceId() + "_color");
if (color != null) {
Mana mana = mEvent.getMana();
boolean colorFits = false;
if (color.isBlack() && mana.getBlack() > 0) {
colorFits = true;
} else if (color.isBlue() && mana.getBlue() > 0) {
colorFits = true;
} else if (color.isGreen() && mana.getGreen() > 0) {
colorFits = true;
} else if (color.isWhite() && mana.getWhite() > 0) {
colorFits = true;
} else if (color.isRed() && mana.getRed() > 0) {
colorFits = true;
}
if (colorFits) {
for (Effect effect : getEffects()) {
effect.setValue("mana", mEvent.getMana());
}
switch (setTargetPointer) {
case PERMANENT:
getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
break;
case PLAYER:
getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getControllerId()));
break;
}
return true;
}
}
TappedForManaEvent mEvent = (TappedForManaEvent) event;
Permanent permanent = mEvent.getPermanent();
if (permanent == null || !permanent.isLand() || !permanent.isBasic()) {
return false;
}
return false;
ObjectColor color = (ObjectColor) game.getState().getValue(getSourceId() + "_color");
if (color == null) {
return false;
}
Mana mana = mEvent.getMana();
if ((!color.isBlack() || mana.getBlack() < 1)
&& (!color.isBlue() || mana.getBlue() < 1)
&& (!color.isGreen() || mana.getGreen() < 1)
&& (!color.isWhite() || mana.getWhite() < 1)
&& (!color.isRed() || mana.getRed() < 1)) {
return false;
}
getEffects().setValue("mana", mEvent.getMana());
getEffects().setTargetPointer(new FixedTarget(permanent, game));
return true;
}
@Override
@ -170,12 +120,12 @@ class GauntletOfPowerTapForManaAllTriggeredAbility extends TriggeredManaAbility
class GauntletOfPowerManaEffect2 extends ManaEffect {
public GauntletOfPowerManaEffect2() {
GauntletOfPowerManaEffect2() {
super();
staticText = "its controller adds one additional mana of that color";
}
public GauntletOfPowerManaEffect2(final GauntletOfPowerManaEffect2 effect) {
private GauntletOfPowerManaEffect2(final GauntletOfPowerManaEffect2 effect) {
super(effect);
}
@ -191,27 +141,28 @@ class GauntletOfPowerManaEffect2 extends ManaEffect {
@Override
public List<Mana> getNetMana(Game game, Ability source) {
List<Mana> netMana = new ArrayList<>();
if (game != null) {
Mana mana = (Mana) getValue("mana");
if (mana != null) {
netMana.add(mana.copy());
}
if (game == null) {
return netMana;
}
Mana mana = (Mana) getValue("mana");
if (mana == null) {
return netMana;
}
netMana.add(mana.copy());
return netMana;
}
@Override
public Mana produceMana(Game game, Ability source) {
if (game != null) {
Permanent land = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
if (land != null) {
Mana mana = (Mana) getValue("mana");
if (mana != null) {
return mana.copy();
}
}
if (game == null) {
return new Mana();
}
return new Mana();
Permanent land = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
Mana mana = (Mana) getValue("mana");
if (land == null || mana == null) {
return new Mana();
}
return mana.copy();
}
@Override

View file

@ -12,6 +12,7 @@ import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
@ -30,7 +31,6 @@ public final class HallOfGemstone extends CardImpl {
// At the beginning of each player's upkeep, that player chooses a color. Until end of turn, lands tapped for mana produce mana of the chosen color instead of any other color.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new HallOfGemstoneEffect(), TargetController.ACTIVE, false));
}
private HallOfGemstone(final HallOfGemstone card) {
@ -50,7 +50,7 @@ class HallOfGemstoneEffect extends ReplacementEffectImpl {
staticText = "that player chooses a color. Until end of turn, lands tapped for mana produce mana of the chosen color instead of any other color";
}
HallOfGemstoneEffect(final HallOfGemstoneEffect effect) {
private HallOfGemstoneEffect(final HallOfGemstoneEffect effect) {
super(effect);
}
@ -69,50 +69,50 @@ class HallOfGemstoneEffect extends ReplacementEffectImpl {
super.init(source, game);
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
Permanent mageObject = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (player != null && mageObject != null) {
ChoiceColor choice = new ChoiceColor();
if (!player.choose(outcome, choice, game)) {
discard();
return;
}
if (!game.isSimulation()) {
game.informPlayers(mageObject.getLogName() + ": " + player.getLogName() + " has chosen " + choice.getChoice());
}
game.getState().setValue(mageObject.getId() + "_color", choice.getColor());
mageObject.addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen color: " + choice.getChoice()), game);
if (player == null || mageObject == null) {
return;
}
ChoiceColor choice = new ChoiceColor();
if (!player.choose(outcome, choice, game)) {
discard();
return;
}
game.informPlayers(mageObject.getLogName() + ": " + player.getLogName() + " has chosen " + choice.getChoice());
game.getState().setValue(mageObject.getId() + "_color", choice.getColor());
mageObject.addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen color: " + choice.getChoice()), game);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
ObjectColor colorChosen = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color");
if (colorChosen != null) {
ManaEvent manaEvent = (ManaEvent) event;
Mana mana = manaEvent.getMana();
// 8/23/2016 Colorless mana added to a player's mana pool isn't affected.
int genericAmount = mana.getGeneric();
int colorlessAmount = mana.getColorless();
int coloredAmount = mana.countColored();
switch (colorChosen.getOneColoredManaSymbol()) {
case W:
mana.setToMana(Mana.WhiteMana(coloredAmount));
break;
case U:
mana.setToMana(Mana.BlueMana(coloredAmount));
break;
case B:
mana.setToMana(Mana.BlackMana(coloredAmount));
break;
case R:
mana.setToMana(Mana.RedMana(coloredAmount));
break;
case G:
mana.setToMana(Mana.GreenMana(coloredAmount));
break;
}
mana.setGeneric(genericAmount);
mana.setColorless(colorlessAmount);
if (colorChosen == null) {
return false;
}
ManaEvent manaEvent = (ManaEvent) event;
Mana mana = manaEvent.getMana();
// 8/23/2016 Colorless mana added to a player's mana pool isn't affected.
int genericAmount = mana.getGeneric();
int colorlessAmount = mana.getColorless();
int coloredAmount = mana.countColored();
switch (colorChosen.getOneColoredManaSymbol()) {
case W:
mana.setToMana(Mana.WhiteMana(coloredAmount));
break;
case U:
mana.setToMana(Mana.BlueMana(coloredAmount));
break;
case B:
mana.setToMana(Mana.BlackMana(coloredAmount));
break;
case R:
mana.setToMana(Mana.RedMana(coloredAmount));
break;
case G:
mana.setToMana(Mana.GreenMana(coloredAmount));
break;
}
mana.setGeneric(genericAmount);
mana.setColorless(colorlessAmount);
return false;
}
@ -123,7 +123,7 @@ class HallOfGemstoneEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game);
}
}

View file

@ -1,11 +1,10 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ReplacementEffectImpl;
@ -13,19 +12,18 @@ import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCardInHand;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class HarvestMage extends CardImpl {
@ -38,9 +36,9 @@ public final class HarvestMage extends CardImpl {
this.toughness = new MageInt(1);
// {G}, {T}, Discard a card: Until end of turn, if you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HarvestMageReplacementEffect(), new ManaCostsImpl("{G}"));
SimpleActivatedAbility ability = new SimpleActivatedAbility(new HarvestMageReplacementEffect(), new ManaCostsImpl("{G}"));
ability.addCost(new TapSourceCost());
ability.addCost(new DiscardTargetCost(new TargetCardInHand()));
ability.addCost(new DiscardCardCost());
this.addAbility(ability);
}
@ -56,14 +54,12 @@ public final class HarvestMage extends CardImpl {
class HarvestMageReplacementEffect extends ReplacementEffectImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
HarvestMageReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Neutral);
staticText = "Until end of turn, if you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount";
}
HarvestMageReplacementEffect(final HarvestMageReplacementEffect effect) {
private HarvestMageReplacementEffect(final HarvestMageReplacementEffect effect) {
super(effect);
}
@ -84,11 +80,10 @@ class HarvestMageReplacementEffect extends ReplacementEffectImpl {
if (game != null && game.inCheckPlayableState()) {
mana.setToMana(new Mana(0, 0, 0, 0, 0, 0, 1, 0));
return false;
} else {
new AddManaOfAnyColorEffect().apply(game, source);
mana.setToMana(new Mana(0, 0, 0, 0, 0, 0, 0, 0));
return true;
}
new AddManaOfAnyColorEffect().apply(game, source);
mana.setToMana(new Mana(0, 0, 0, 0, 0, 0, 0, 0));
return true;
}
@Override
@ -98,10 +93,7 @@ class HarvestMageReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null && permanent.isLand(game)) {
return filter.match(permanent, game);
}
return false;
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game) && permanent.isControlledBy(source.getControllerId());
}
}

View file

@ -1,11 +1,8 @@
package mage.cards.h;
import java.util.UUID;
import mage.Mana;
import mage.abilities.effects.Effect;
import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect;
import mage.abilities.mana.DelayedTriggeredManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -13,25 +10,24 @@ import mage.constants.CardType;
import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author Plopman
*/
public final class HighTide extends CardImpl {
public HighTide(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
// Until end of turn, whenever a player taps an Island for mana, that player adds {U}.
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new HighTideTriggeredAbility()));
}
private HighTide(final HighTide card) {
@ -46,18 +42,12 @@ public final class HighTide extends CardImpl {
class HighTideTriggeredAbility extends DelayedTriggeredManaAbility {
private static final FilterLandPermanent filter = new FilterLandPermanent("Island");
static {
filter.add(SubType.ISLAND.getPredicate());
}
public HighTideTriggeredAbility() {
HighTideTriggeredAbility() {
super(new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.U), "their"), Duration.EndOfTurn, false);
this.usesStack = false;
}
public HighTideTriggeredAbility(HighTideTriggeredAbility ability) {
private HighTideTriggeredAbility(HighTideTriggeredAbility ability) {
super(ability);
}
@ -68,14 +58,12 @@ class HighTideTriggeredAbility extends DelayedTriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId());
if (land != null && filter.match(land, game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(land.getControllerId()));
}
return true;
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
if (permanent == null || !permanent.hasSubtype(SubType.ISLAND, game)) {
return false;
}
return false;
getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId()));
return true;
}
@Override

View file

@ -1,13 +1,9 @@
package mage.cards.i;
import java.util.UUID;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.CompositeCost;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ReplacementEffectImpl;
@ -17,14 +13,15 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.players.Player;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author spjspj
*/
public final class InfernalDarkness extends CardImpl {
@ -33,11 +30,12 @@ public final class InfernalDarkness extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
// Cumulative upkeep-Pay {B} and 1 life.
this.addAbility(new CumulativeUpkeepAbility(new InfernalDarknessCost()));
this.addAbility(new CumulativeUpkeepAbility(new CompositeCost(
new ManaCostsImpl<>("{B}"), new PayLifeCost(1), "pay {B} and 1 life"
)));
// If a land is tapped for mana, it produces {B} instead of any other type.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfernalDarknessReplacementEffect()));
this.addAbility(new SimpleStaticAbility(new InfernalDarknessReplacementEffect()));
}
private InfernalDarkness(final InfernalDarkness card) {
@ -50,59 +48,6 @@ public final class InfernalDarkness extends CardImpl {
}
}
class InfernalDarknessCost extends CostImpl {
ManaCostsImpl manaCost = new ManaCostsImpl("{B}");
Cost lifeCost = new PayLifeCost(1);
public InfernalDarknessCost() {
this.text = "Pay {B} and 1 life";
}
public InfernalDarknessCost(InfernalDarknessCost cost) {
super(cost);
this.manaCost = cost.manaCost;
this.lifeCost = cost.lifeCost;
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player player = game.getPlayer(controllerId);
if (player == null) {
return false;
}
paid = false;
manaCost.clearPaid();
if (manaCost.pay(ability, game, source, player.getId(), false)
&& player.canPayLifeCost(ability)
&& player.getLife() >= 1
&& lifeCost.pay(ability, game, source, player.getId(), false)) {
paid = true;
}
return paid;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
Player player = game.getPlayer(controllerId);
if (player != null
&& player.canPayLifeCost(ability)
&& player.getLife() >= 1) {
return true;
}
return false;
}
@Override
public InfernalDarknessCost copy() {
return new InfernalDarknessCost(this);
}
}
class InfernalDarknessReplacementEffect extends ReplacementEffectImpl {
InfernalDarknessReplacementEffect() {
@ -110,7 +55,7 @@ class InfernalDarknessReplacementEffect extends ReplacementEffectImpl {
staticText = "If a land is tapped for mana, it produces {B} instead of any other type";
}
InfernalDarknessReplacementEffect(final InfernalDarknessReplacementEffect effect) {
private InfernalDarknessReplacementEffect(final InfernalDarknessReplacementEffect effect) {
super(effect);
}
@ -139,7 +84,7 @@ class InfernalDarknessReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
MageObject mageObject = game.getPermanentOrLKIBattlefield(event.getSourceId());
return mageObject != null && mageObject.isLand(game);
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game);
}
}

View file

@ -6,7 +6,10 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
@ -23,7 +26,7 @@ public final class ManaReflection extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}{G}");
// If you tap a permanent for mana, it produces twice as much of that mana instead.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ManaReflectionReplacementEffect()));
this.addAbility(new SimpleStaticAbility(new ManaReflectionReplacementEffect()));
}
private ManaReflection(final ManaReflection card) {
@ -43,7 +46,7 @@ class ManaReflectionReplacementEffect extends ReplacementEffectImpl {
staticText = "If you tap a permanent for mana, it produces twice as much of that mana instead";
}
ManaReflectionReplacementEffect(ManaReflectionReplacementEffect effect) {
private ManaReflectionReplacementEffect(ManaReflectionReplacementEffect effect) {
super(effect);
}
@ -83,8 +86,7 @@ class ManaReflectionReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getPlayerId().equals(source.getControllerId())
&& game.getPermanentOrLKIBattlefield(event.getSourceId()) != null;
return source.isControlledBy(event.getPlayerId());
}
@Override

View file

@ -1,9 +1,5 @@
package mage.cards.m;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
@ -14,11 +10,15 @@ import mage.constants.CardType;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterLandPermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
import java.util.Collections;
import java.util.Set;
import java.util.UUID;
/**
* @author spjspj
@ -44,13 +44,14 @@ public final class ManaWeb extends CardImpl {
class ManaWebTriggeredAbility extends TriggeredAbilityImpl {
public ManaWebTriggeredAbility() {
ManaWebTriggeredAbility() {
super(Zone.BATTLEFIELD, new ManaWebeffect(), false);
}
private static final String staticText = "Whenever a land an opponent controls is tapped for mana, tap all lands that player controls that could produce any type of mana that land could produce.";
private static final String staticText = "Whenever a land an opponent controls is tapped for mana, " +
"tap all lands that player controls that could produce any type of mana that land could produce.";
public ManaWebTriggeredAbility(ManaWebTriggeredAbility ability) {
private ManaWebTriggeredAbility(ManaWebTriggeredAbility ability) {
super(ability);
}
@ -61,17 +62,18 @@ class ManaWebTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
// it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA
if (game.inCheckPlayableState()) {
return false;
}
if (game.getOpponents(controllerId).contains(event.getPlayerId())) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null && permanent.isLand(game)) {
this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getSourceId()));
return true;
}
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
if (permanent == null
|| !permanent.isLand(game)
|| !game.getOpponents(permanent.getControllerId()).contains(getControllerId())) {
return false;
}
return false;
this.getEffects().setValue("tappedPermanent", permanent);
return true;
}
@Override
@ -87,14 +89,11 @@ class ManaWebTriggeredAbility extends TriggeredAbilityImpl {
class ManaWebeffect extends OneShotEffect {
private static final FilterLandPermanent filter = new FilterLandPermanent("an opponent taps a land");
public ManaWebeffect() {
ManaWebeffect() {
super(Outcome.Tap);
staticText = "Whenever a land an opponent controls is tapped for mana, tap all lands that player controls that could produce any type of mana that land could produce.";
}
public ManaWebeffect(final ManaWebeffect effect) {
private ManaWebeffect(final ManaWebeffect effect) {
super(effect);
}
@ -105,23 +104,21 @@ class ManaWebeffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
Set<ManaType> manaTypesSource = AnyColorLandsProduceManaAbility.getManaTypesFromPermanent(permanent, game);
boolean tappedLands = false;
for (Permanent opponentPermanent : game.getBattlefield().getActivePermanents(filter, permanent.getControllerId(), game)) {
if (Objects.equals(opponentPermanent.getControllerId(), permanent.getControllerId())) {
Set<ManaType> manaTypes = AnyColorLandsProduceManaAbility.getManaTypesFromPermanent(opponentPermanent, game);
for (ManaType manaType : manaTypes) {
if (manaTypesSource.contains(manaType)) {
tappedLands = opponentPermanent.tap(source, game) || tappedLands;
break;
}
}
}
}
return tappedLands;
Permanent permanent = (Permanent) getValue("tappedPermanent");
if (permanent == null) {
return false;
}
return false;
Set<ManaType> manaTypesSource = AnyColorLandsProduceManaAbility.getManaTypesFromPermanent(permanent, game);
boolean tappedLands = false;
for (Permanent opponentPermanent : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
permanent.getControllerId(), source.getSourceId(), game
)) {
Set<ManaType> manaTypes = AnyColorLandsProduceManaAbility.getManaTypesFromPermanent(opponentPermanent, game);
if (!Collections.disjoint(manaTypes, manaTypesSource)) {
opponentPermanent.tap(source, game);
}
}
return tappedLands;
}
}

View file

@ -10,10 +10,13 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceColor;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -31,7 +34,7 @@ public final class NakedSingularity extends CardImpl {
this.addAbility(new CumulativeUpkeepAbility(new GenericManaCost(3)));
// If tapped for mana, Plains produce {R}, Islands produce {G}, Swamps produce {W}, Mountains produce {U}, and Forests produce {B} instead of any other type.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new NakedSingularityEffect()));
this.addAbility(new SimpleStaticAbility(new NakedSingularityEffect()));
}
private NakedSingularity(final NakedSingularity card) {
@ -48,10 +51,11 @@ class NakedSingularityEffect extends ReplacementEffectImpl {
NakedSingularityEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
staticText = "If tapped for mana, Plains produce {R}, Islands produce {G}, Swamps produce {W}, Mountains produce {U}, and Forests produce {B} instead of any other type";
staticText = "If tapped for mana, Plains produce {R}, Islands produce {G}, Swamps produce {W}, " +
"Mountains produce {U}, and Forests produce {B} instead of any other type";
}
NakedSingularityEffect(final NakedSingularityEffect effect) {
private NakedSingularityEffect(final NakedSingularityEffect effect) {
super(effect);
}
@ -67,57 +71,58 @@ class NakedSingularityEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
TappedForManaEvent manaEvent = (TappedForManaEvent) event;
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent permanent = game.getPermanent(event.getSourceId());
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
choice.setMessage("Pick a color to produce");
if (permanent.hasSubtype(SubType.PLAINS, game)) {
choice.getChoices().add("Red");
}
if (permanent.hasSubtype(SubType.ISLAND, game)) {
choice.getChoices().add("Green");
}
if (permanent.hasSubtype(SubType.SWAMP, game)) {
choice.getChoices().add("White");
}
if (permanent.hasSubtype(SubType.MOUNTAIN, game)) {
choice.getChoices().add("Blue");
}
if (permanent.hasSubtype(SubType.FOREST, game)) {
choice.getChoices().add("Black");
}
String chosenColor;
if (choice.getChoices().size() == 1) {
chosenColor = choice.getChoices().iterator().next();
} else {
controller.choose(Outcome.PutManaInPool, choice, game);
chosenColor = choice.getChoice();
}
if (chosenColor == null) {
return false;
}
ManaEvent manaEvent = (ManaEvent) event;
Mana mana = manaEvent.getMana();
int amount = mana.count();
switch (chosenColor) {
case "White":
mana.setToMana(Mana.WhiteMana(amount));
break;
case "Blue":
mana.setToMana(Mana.BlueMana(amount));
break;
case "Black":
mana.setToMana(Mana.BlackMana(amount));
break;
case "Red":
mana.setToMana(Mana.RedMana(amount));
break;
case "Green":
mana.setToMana(Mana.GreenMana(amount));
break;
}
Permanent permanent = manaEvent.getPermanent();
if (controller == null || permanent == null) {
return false;
}
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
choice.setMessage("Pick a color to produce");
if (permanent.hasSubtype(SubType.PLAINS, game)) {
choice.getChoices().add("Red");
}
if (permanent.hasSubtype(SubType.ISLAND, game)) {
choice.getChoices().add("Green");
}
if (permanent.hasSubtype(SubType.SWAMP, game)) {
choice.getChoices().add("White");
}
if (permanent.hasSubtype(SubType.MOUNTAIN, game)) {
choice.getChoices().add("Blue");
}
if (permanent.hasSubtype(SubType.FOREST, game)) {
choice.getChoices().add("Black");
}
String chosenColor;
if (choice.getChoices().size() == 1) {
chosenColor = choice.getChoices().iterator().next();
} else {
controller.choose(Outcome.PutManaInPool, choice, game);
chosenColor = choice.getChoice();
}
if (chosenColor == null) {
return false;
}
Mana mana = manaEvent.getMana();
int amount = mana.count();
switch (chosenColor) {
case "White":
mana.setToMana(Mana.WhiteMana(amount));
break;
case "Blue":
mana.setToMana(Mana.BlueMana(amount));
break;
case "Black":
mana.setToMana(Mana.BlackMana(amount));
break;
case "Red":
mana.setToMana(Mana.RedMana(amount));
break;
case "Green":
mana.setToMana(Mana.GreenMana(amount));
break;
}
return false;
}
@ -129,7 +134,7 @@ class NakedSingularityEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null
&& (permanent.hasSubtype(SubType.PLAINS, game)
|| permanent.hasSubtype(SubType.ISLAND, game)

View file

@ -1,13 +1,11 @@
package mage.cards.n;
import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.mana.TriggeredManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -15,20 +13,20 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class NirkanaRevenant extends CardImpl {
public NirkanaRevenant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
this.subtype.add(SubType.VAMPIRE);
this.subtype.add(SubType.SHADE);
@ -39,7 +37,9 @@ public final class NirkanaRevenant extends CardImpl {
this.addAbility(new NirkanaRevenantTriggeredAbility());
// {B}: Nirkana Revenant gets +1/+1 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{B}")));
this.addAbility(new SimpleActivatedAbility(
new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{B}")
));
}
private NirkanaRevenant(final NirkanaRevenant card) {
@ -53,18 +53,12 @@ public final class NirkanaRevenant extends CardImpl {
}
class NirkanaRevenantTriggeredAbility extends TriggeredManaAbility {
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("Swamp");
static {
filter.add(SubType.SWAMP.getPredicate());
}
public NirkanaRevenantTriggeredAbility() {
NirkanaRevenantTriggeredAbility() {
super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.BlackMana(1)), false);
this.usesStack = false;
}
public NirkanaRevenantTriggeredAbility(NirkanaRevenantTriggeredAbility ability) {
private NirkanaRevenantTriggeredAbility(final NirkanaRevenantTriggeredAbility ability) {
super(ability);
}
@ -75,8 +69,11 @@ class NirkanaRevenantTriggeredAbility extends TriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId());
return land != null && filter.match(land, this.getSourceId(), this.getControllerId(), game);
if (!isControlledBy(event.getPlayerId())) {
return false;
}
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.hasSubtype(SubType.SWAMP, game);
}
@Override
@ -86,6 +83,6 @@ class NirkanaRevenantTriggeredAbility extends TriggeredManaAbility {
@Override
public String getRule() {
return "Whenever you tap a Swamp for mana, add {B}.";
return "Whenever you tap a Swamp for mana, add an additional {B}.";
}
}

View file

@ -25,6 +25,7 @@ import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.command.emblems.NissaWhoShakesTheWorldEmblem;
import mage.game.events.GameEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.TokenImpl;
import mage.target.TargetPermanent;
@ -87,15 +88,8 @@ public final class NissaWhoShakesTheWorld extends CardImpl {
class NissaWhoShakesTheWorldTriggeredAbility extends TriggeredManaAbility {
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("Forest");
static {
filter.add(SubType.FOREST.getPredicate());
}
NissaWhoShakesTheWorldTriggeredAbility() {
super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.GreenMana(1)), false);
this.usesStack = false;
}
private NissaWhoShakesTheWorldTriggeredAbility(final NissaWhoShakesTheWorldTriggeredAbility ability) {
@ -109,8 +103,11 @@ class NissaWhoShakesTheWorldTriggeredAbility extends TriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId());
return land != null && filter.match(land, this.getSourceId(), this.getControllerId(), game);
if (!isControlledBy(event.getPlayerId())) {
return false;
}
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.hasSubtype(SubType.FOREST, game);
}
@Override

View file

@ -92,8 +92,7 @@ class NyxbloomAncientReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getPlayerId().equals(source.getControllerId())
&& game.getPermanentOrLKIBattlefield(event.getSourceId()) != null;
return source.isControlledBy(event.getPlayerId());
}
@Override

View file

@ -1,8 +1,5 @@
package mage.cards.p;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
@ -11,20 +8,21 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class PaleMoon extends CardImpl {
public PaleMoon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Until end of turn, if a player taps a nonbasic land for mana, it produces colorless mana instead of any other type.
this.getSpellAbility().addEffect(new PaleMoonReplacementEffect());
@ -42,14 +40,12 @@ public final class PaleMoon extends CardImpl {
class PaleMoonReplacementEffect extends ReplacementEffectImpl {
private static final FilterLandPermanent filter = FilterLandPermanent.nonbasicLands();
PaleMoonReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Neutral);
staticText = "Until end of turn, if a player taps a nonbasic land for mana, it produces colorless mana instead of any other type";
}
PaleMoonReplacementEffect(final PaleMoonReplacementEffect effect) {
private PaleMoonReplacementEffect(final PaleMoonReplacementEffect effect) {
super(effect);
}
@ -78,10 +74,7 @@ class PaleMoonReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null && permanent.isLand(game)) {
return filter.match(permanent, game);
}
return false;
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game) && !permanent.isBasic();
}
}

View file

@ -1,20 +1,19 @@
package mage.cards.p;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
* @author cbt33, Loki (Heartbeat of Spring)
*/
@ -39,37 +38,36 @@ public final class PriceOfGlory extends CardImpl {
class PriceOfGloryAbility extends TriggeredAbilityImpl {
private static final String staticText = "Whenever a player taps a land for mana, if it's not that player's turn, destroy that land.";
private static final String staticText = "Whenever a player taps a land for mana, " +
"if it's not that player's turn, destroy that land.";
public PriceOfGloryAbility() {
super(Zone.BATTLEFIELD, new PriceOfGloryEffect());
PriceOfGloryAbility() {
super(Zone.BATTLEFIELD, new DestroyTargetEffect());
}
public PriceOfGloryAbility(PriceOfGloryAbility ability) {
private PriceOfGloryAbility(final PriceOfGloryAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
if (game.inCheckPlayableState()) {
return false;
}
return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent == null) {
// it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA
if (game.inCheckPlayableState()) {
return false;
}
if (permanent.isLand(game)
&& game.getState().getPlayersInRange(controllerId, game).contains(permanent.getControllerId())
&& !permanent.isControlledBy(game.getActivePlayerId())) { // intervening if clause
getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
return true;
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
if (permanent == null
|| !permanent.isLand(game)
|| game.isActivePlayer(event.getPlayerId())) {
return false;
}
return false;
getEffects().setTargetPointer(new FixedTarget(permanent, game));
return true;
}
@Override
@ -82,33 +80,3 @@ class PriceOfGloryAbility extends TriggeredAbilityImpl {
return staticText;
}
}
class PriceOfGloryEffect extends OneShotEffect {
public PriceOfGloryEffect() {
super(Outcome.DestroyPermanent);
staticText = "if it's not that player's turn, destroy that land.";
}
public PriceOfGloryEffect(final PriceOfGloryEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent land = game.getPermanent(getTargetPointer().getFirst(game, source));
if (land != null && !land.isControlledBy(game.getActivePlayerId())) { // intervening if clause has to be checked again
land.destroy(source, game, false);
}
return true;
}
return false;
}
@Override
public PriceOfGloryEffect copy() {
return new PriceOfGloryEffect(this);
}
}

View file

@ -1,8 +1,5 @@
package mage.cards.p;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -11,18 +8,17 @@ import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class PulseOfLlanowar extends CardImpl {
@ -31,7 +27,7 @@ public final class PulseOfLlanowar extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}");
// If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PulseOfLlanowarReplacementEffect()));
this.addAbility(new SimpleStaticAbility(new PulseOfLlanowarReplacementEffect()));
}
private PulseOfLlanowar(final PulseOfLlanowar card) {
@ -46,17 +42,12 @@ public final class PulseOfLlanowar extends CardImpl {
class PulseOfLlanowarReplacementEffect extends ReplacementEffectImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
static {
filter.add(SuperType.BASIC.getPredicate());
}
PulseOfLlanowarReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
staticText = "If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type";
}
PulseOfLlanowarReplacementEffect(final PulseOfLlanowarReplacementEffect effect) {
private PulseOfLlanowarReplacementEffect(final PulseOfLlanowarReplacementEffect effect) {
super(effect);
}
@ -74,8 +65,8 @@ class PulseOfLlanowarReplacementEffect extends ReplacementEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
ManaEvent manaEvent = (ManaEvent) event;
Mana mana = manaEvent.getMana();
new AddManaOfAnyColorEffect(mana.count()).apply(game,source);
mana.setToMana(new Mana(0, 0, 0, 0,0, 0,0,0));
new AddManaOfAnyColorEffect(mana.count()).apply(game, source);
mana.setToMana(new Mana(0, 0, 0, 0, 0, 0, 0, 0));
return true;
}
@ -86,10 +77,7 @@ class PulseOfLlanowarReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null && permanent.isLand(game)) {
return filter.match(permanent, game);
}
return false;
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game) && permanent.isControlledBy(source.getControllerId());
}
}

View file

@ -10,10 +10,13 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceColor;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -31,7 +34,7 @@ public final class RealityTwist extends CardImpl {
this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}{U}{U}")));
// If tapped for mana, Plains produce {R}, Swamps produce {G}, Mountains produce {W}, and Forests produce {B} instead of any other type.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RealityTwistEffect()));
this.addAbility(new SimpleStaticAbility(new RealityTwistEffect()));
}
private RealityTwist(final RealityTwist card) {
@ -48,10 +51,11 @@ class RealityTwistEffect extends ReplacementEffectImpl {
RealityTwistEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
staticText = "If tapped for mana, Plains produce {R}, Swamps produce {G}, Mountains produce {W}, and Forests produce {B} instead of any other type";
staticText = "If tapped for mana, Plains produce {R}, Swamps produce {G}, " +
"Mountains produce {W}, and Forests produce {B} instead of any other type";
}
RealityTwistEffect(final RealityTwistEffect effect) {
private RealityTwistEffect(final RealityTwistEffect effect) {
super(effect);
}
@ -67,51 +71,52 @@ class RealityTwistEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
TappedForManaEvent manaEvent = (TappedForManaEvent) event;
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent permanent = game.getPermanent(event.getSourceId());
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
choice.setMessage("Pick a color to produce");
if (permanent.hasSubtype(SubType.PLAINS, game)) {
choice.getChoices().add("Red");
}
if (permanent.hasSubtype(SubType.SWAMP, game)) {
choice.getChoices().add("Green");
}
if (permanent.hasSubtype(SubType.MOUNTAIN, game)) {
choice.getChoices().add("White");
}
if (permanent.hasSubtype(SubType.FOREST, game)) {
choice.getChoices().add("Black");
}
String chosenColor;
if (choice.getChoices().size() == 1) {
chosenColor = choice.getChoices().iterator().next();
} else {
controller.choose(Outcome.PutManaInPool, choice, game);
chosenColor = choice.getChoice();
}
if (chosenColor == null) {
return false;
}
ManaEvent manaEvent = (ManaEvent) event;
Mana mana = manaEvent.getMana();
int amount = mana.count();
switch (chosenColor) {
case "White":
mana.setToMana(Mana.WhiteMana(amount));
break;
case "Black":
mana.setToMana(Mana.BlackMana(amount));
break;
case "Red":
mana.setToMana(Mana.RedMana(amount));
break;
case "Green":
mana.setToMana(Mana.GreenMana(amount));
break;
}
Permanent permanent = manaEvent.getPermanent();
if (controller == null || permanent == null) {
return false;
}
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
choice.setMessage("Pick a color to produce");
if (permanent.hasSubtype(SubType.PLAINS, game)) {
choice.getChoices().add("Red");
}
if (permanent.hasSubtype(SubType.SWAMP, game)) {
choice.getChoices().add("Green");
}
if (permanent.hasSubtype(SubType.MOUNTAIN, game)) {
choice.getChoices().add("White");
}
if (permanent.hasSubtype(SubType.FOREST, game)) {
choice.getChoices().add("Black");
}
String chosenColor;
if (choice.getChoices().size() == 1) {
chosenColor = choice.getChoices().iterator().next();
} else {
controller.choose(Outcome.PutManaInPool, choice, game);
chosenColor = choice.getChoice();
}
if (chosenColor == null) {
return false;
}
Mana mana = manaEvent.getMana();
int amount = mana.count();
switch (chosenColor) {
case "White":
mana.setToMana(Mana.WhiteMana(amount));
break;
case "Black":
mana.setToMana(Mana.BlackMana(amount));
break;
case "Red":
mana.setToMana(Mana.RedMana(amount));
break;
case "Green":
mana.setToMana(Mana.GreenMana(amount));
break;
}
return false;
}
@ -123,7 +128,7 @@ class RealityTwistEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null
&& (permanent.hasSubtype(SubType.PLAINS, game)
|| permanent.hasSubtype(SubType.SWAMP, game)

View file

@ -1,13 +1,9 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.abilities.effects.common.BecomesMonarchSourceEffect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.mana.TriggeredManaAbility;
import mage.cards.CardImpl;
@ -15,16 +11,14 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class RegalBehemoth extends CardImpl {
@ -38,15 +32,12 @@ public final class RegalBehemoth extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// When Regal Behemoth enters the battlefield, you become the monarch.
this.addAbility(new EntersBattlefieldTriggeredAbility(new BecomesMonarchSourceEffect(), false));
// Whenever you tap a land for mana while you're the monarch, add one mana of any color.
ManaEffect manaEffect = new AddManaOfAnyColorEffect();
manaEffect.setText("add one mana of any color <i>(in addition to the mana the land produces)</i>.");
ManaEffect effect = manaEffect;
this.addAbility(new RegalBehemothTriggeredManaAbility(
effect, new FilterControlledLandPermanent("you tap a land")));
this.addAbility(new RegalBehemothTriggeredManaAbility());
}
private RegalBehemoth(final RegalBehemoth card) {
@ -61,16 +52,12 @@ public final class RegalBehemoth extends CardImpl {
class RegalBehemothTriggeredManaAbility extends TriggeredManaAbility {
private final FilterPermanent filter;
public RegalBehemothTriggeredManaAbility(ManaEffect effect, FilterPermanent filter) {
super(Zone.BATTLEFIELD, effect);
this.filter = filter;
RegalBehemothTriggeredManaAbility() {
super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect());
}
public RegalBehemothTriggeredManaAbility(RegalBehemothTriggeredManaAbility ability) {
private RegalBehemothTriggeredManaAbility(RegalBehemothTriggeredManaAbility ability) {
super(ability);
this.filter = ability.filter.copy();
}
@Override
@ -80,21 +67,11 @@ class RegalBehemothTriggeredManaAbility extends TriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getMonarchId() != null
&& isControlledBy(game.getMonarchId())) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null
&& getControllerId() != null
&& filter.match(permanent, getSourceId(), getControllerId(), game)) {
ManaEvent mEvent = (ManaEvent) event;
for (Effect effect : getEffects()) {
effect.setValue("mana", mEvent.getMana());
effect.setTargetPointer(new FixedTarget(permanent, game));
}
return true;
}
if (!isControlledBy(game.getMonarchId()) || !isControlledBy(event.getPlayerId())) {
return false;
}
return false;
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game);
}
@Override
@ -103,7 +80,7 @@ class RegalBehemothTriggeredManaAbility extends TriggeredManaAbility {
}
@Override
public String getTriggerPhrase() {
return "Whenever you tap a land for mana while you're the monarch, " ;
public String getRule() {
return "Whenever you tap a land for mana while you're the monarch, add one mana of any color.";
}
}

View file

@ -1,8 +1,5 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -14,13 +11,15 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class RitualOfSubdual extends CardImpl {
@ -32,8 +31,7 @@ public final class RitualOfSubdual extends CardImpl {
this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{2}")));
// If a land is tapped for mana, it produces colorless mana instead of any other type.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RitualOfSubdualReplacementEffect()));
this.addAbility(new SimpleStaticAbility(new RitualOfSubdualReplacementEffect()));
}
private RitualOfSubdual(final RitualOfSubdual card) {
@ -53,7 +51,7 @@ class RitualOfSubdualReplacementEffect extends ReplacementEffectImpl {
staticText = "If a land is tapped for mana, it produces colorless mana instead of any other type.";
}
RitualOfSubdualReplacementEffect(final RitualOfSubdualReplacementEffect effect) {
private RitualOfSubdualReplacementEffect(final RitualOfSubdualReplacementEffect effect) {
super(effect);
}
@ -82,7 +80,7 @@ class RitualOfSubdualReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
MageObject mageObject = game.getPermanentOrLKIBattlefield(event.getSourceId());
return mageObject != null && mageObject.isLand(game);
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game);
}
}

View file

@ -1,11 +1,8 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
import mage.abilities.keyword.TrampleAbility;
@ -17,16 +14,18 @@ import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author cbt33
*/
public final class SavageFirecat extends CardImpl {
public SavageFirecat(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
this.subtype.add(SubType.ELEMENTAL);
this.subtype.add(SubType.CAT);
@ -37,11 +36,13 @@ public final class SavageFirecat extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// Savage Firecat enters the battlefield with seven +1/+1 counters on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(7))));
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(7)),
"with seven +1/+1 counters on it"
));
// Whenever you tap a land for mana, remove a +1/+1 counter from Savage Firecat.
this.addAbility(new SavageFirecatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P1.createInstance())));
this.addAbility(new SavageFirecatTriggeredAbility());
}
private SavageFirecat(final SavageFirecat card) {
@ -56,17 +57,17 @@ public final class SavageFirecat extends CardImpl {
class SavageFirecatTriggeredAbility extends TriggeredAbilityImpl {
public SavageFirecatTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect, false);
SavageFirecatTriggeredAbility() {
super(Zone.BATTLEFIELD, new RemoveCounterSourceEffect(CounterType.P1P1.createInstance()), false);
}
public SavageFirecatTriggeredAbility(final SavageFirecatTriggeredAbility ability) {
private SavageFirecatTriggeredAbility(final SavageFirecatTriggeredAbility ability) {
super(ability);
}
@Override
public SavageFirecatTriggeredAbility copy() {
return new SavageFirecatTriggeredAbility(this);
return new SavageFirecatTriggeredAbility(this);
}
@Override
@ -76,17 +77,16 @@ class SavageFirecatTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA
// it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA
if (game.inCheckPlayableState()) {
return false;
}
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
return permanent != null && permanent.isLand(game) && event.getPlayerId().equals(this.controllerId);
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null && permanent.isLand(game) && isControlledBy(event.getPlayerId());
}
@Override
public String getRule() {
return "Whenever you tap a land for mana, remove a +1/+1 counter from {this}";
}
}

View file

@ -1,33 +1,34 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.TapLandForManaAllTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.common.TapForManaAllTriggeredAbility;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.effects.common.continuous.PlayAdditionalLandsAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SetTargetPointer;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
* @author Quercitron
*/
public final class StormCauldron extends CardImpl {
public StormCauldron(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
// Each player may play an additional land during each of their turns.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayAdditionalLandsAllEffect()));
// Whenever a land is tapped for mana, return it to its owner's hand.
Effect effect = new ReturnToHandTargetEffect();
effect.setText("return it to its owner's hand");
this.addAbility(new TapLandForManaAllTriggeredAbility(effect, false, true, true));
this.addAbility(new TapForManaAllTriggeredAbility(
new ReturnToHandTargetEffect().setText("return it to its owner's hand"),
StaticFilters.FILTER_LAND_A, SetTargetPointer.PERMANENT
));
}
private StormCauldron(final StormCauldron card) {

View file

@ -9,6 +9,7 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
import mage.target.targetpointer.FixedTargets;
@ -45,32 +46,34 @@ public final class TreasureNabber extends CardImpl {
class TreasureNabberAbility extends TriggeredAbilityImpl {
public TreasureNabberAbility() {
TreasureNabberAbility() {
super(Zone.BATTLEFIELD, new TreasureNabberEffect());
}
public TreasureNabberAbility(TreasureNabberAbility ability) {
private TreasureNabberAbility(TreasureNabberAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
if (game.inCheckPlayableState()) {
return false;
}
return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getOpponents(controllerId).contains(event.getPlayerId())) {
Permanent permanent = game.getPermanent(event.getSourceId());
if (permanent != null && permanent.isArtifact(game)) {
getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
return true;
}
// it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA
if (game.inCheckPlayableState()) {
return false;
}
return false;
if (!game.getOpponents(controllerId).contains(event.getPlayerId())) {
return false;
}
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
if (permanent == null || !permanent.isArtifact(game)) {
return false;
}
getEffects().setTargetPointer(new FixedTarget(permanent, game));
return true;
}
@Override
@ -93,7 +96,7 @@ class TreasureNabberEffect extends ContinuousEffectImpl {
this.staticText = "gain control of that artifact until the end of your next turn";
}
TreasureNabberEffect(final TreasureNabberEffect effect) {
private TreasureNabberEffect(final TreasureNabberEffect effect) {
super(effect);
this.fixedTargets = effect.fixedTargets;
}

View file

@ -1,28 +1,25 @@
package mage.cards.v;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.TapForManaAllTriggeredManaAbility;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.effects.mana.AddManaOfAnyTypeProducedEffect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SetTargetPointer;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.constants.*;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public final class VorinclexVoiceOfHunger extends CardImpl {
@ -62,11 +59,11 @@ public final class VorinclexVoiceOfHunger extends CardImpl {
class VorinclexTriggeredAbility2 extends TriggeredAbilityImpl {
public VorinclexTriggeredAbility2() {
VorinclexTriggeredAbility2() {
super(Zone.BATTLEFIELD, new DontUntapInControllersNextUntapStepTargetEffect());
}
public VorinclexTriggeredAbility2(VorinclexTriggeredAbility2 ability) {
private VorinclexTriggeredAbility2(final VorinclexTriggeredAbility2 ability) {
super(ability);
}
@ -77,17 +74,19 @@ class VorinclexTriggeredAbility2 extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA
// it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA
if (game.inCheckPlayableState()) {
return false;
}
if (game.getOpponents(getControllerId()).contains(event.getPlayerId())) {
Permanent permanent = game.getPermanent(event.getSourceId());
if (permanent != null && permanent.isLand(game)) {
getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
return true;
}
}
return false;
if (!game.getOpponents(getControllerId()).contains(event.getPlayerId())) {
return false;
}
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
if (permanent == null || !permanent.isLand(game)) {
return false;
}
getEffects().setTargetPointer(new FixedTarget(permanent, game));
return true;
}
@Override

View file

@ -1,13 +1,9 @@
package mage.cards.w;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.TapForManaAllTriggeredAbility;
import mage.abilities.common.TapForManaAllTriggeredManaAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.mana.AddManaOfAnyTypeProducedEffect;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.effects.mana.AddManaOfAnyTypeProducedEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -15,31 +11,36 @@ import mage.constants.SetTargetPointer;
import mage.constants.SuperType;
import mage.filter.common.FilterLandPermanent;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class WintersNight extends CardImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent("a player taps a snow land");
static {
filter.add(SuperType.SNOW.getPredicate());
}
public WintersNight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}{G}{W}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{G}{W}");
addSuperType(SuperType.WORLD);
// Whenever a player taps a snow land for mana, that player adds one mana of any type that land produced.
// That land doesn't untap during its controller's next untap step.
ManaEffect effect = new AddManaOfAnyTypeProducedEffect();
effect.setText("that player adds one mana of any type that land produced");
Ability ability = new TapForManaAllTriggeredManaAbility(effect, filter, SetTargetPointer.PERMANENT);
Effect effect2 = new DontUntapInControllersNextUntapStepTargetEffect();
effect2.setText("That land doesn't untap during its controller's next untap step");
ability.addEffect(effect2);
this.addAbility(ability);
this.addAbility(new TapForManaAllTriggeredManaAbility(
new AddManaOfAnyTypeProducedEffect().setText("that player adds one mana of any type that land produced"),
filter,
SetTargetPointer.PERMANENT
));
this.addAbility(new TapForManaAllTriggeredAbility(
new DontUntapInControllersNextUntapStepTargetEffect().setText("that land doesn't untap during its controller's next untap step"),
filter,
SetTargetPointer.PERMANENT
));
}
private WintersNight(final WintersNight card) {

View file

@ -1,7 +1,5 @@
package mage.cards.z;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.DamagePlayersEffect;
@ -14,16 +12,18 @@ import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class ZhurTaaDruid extends CardImpl {
public ZhurTaaDruid(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}");
this.subtype.add(SubType.HUMAN, SubType.DRUID);
this.power = new MageInt(1);
@ -31,9 +31,9 @@ public final class ZhurTaaDruid extends CardImpl {
// {T}: Add {G}.
this.addAbility(new GreenManaAbility());
// Whenever you tap Zhur-Taa Druid for mana, it deals 1 damage to each opponent.
this.addAbility(new ZhurTaaDruidAbility());
}
private ZhurTaaDruid(final ZhurTaaDruid card) {
@ -48,25 +48,29 @@ public final class ZhurTaaDruid extends CardImpl {
class ZhurTaaDruidAbility extends TriggeredAbilityImpl {
public ZhurTaaDruidAbility() {
super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT, "it"));
ZhurTaaDruidAbility() {
super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT));
}
public ZhurTaaDruidAbility(final ZhurTaaDruidAbility ability) {
private ZhurTaaDruidAbility(final ZhurTaaDruidAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
if (game.inCheckPlayableState()) {
return false;
}
return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getSourceId().equals(getSourceId());
// it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA
if (game.inCheckPlayableState()) {
return false;
}
Permanent permanent = ((TappedForManaEvent) event).getPermanent();
return permanent != null
&& permanent == getSourcePermanentOrLKI(game)
&& isControlledBy(event.getPlayerId());
}
@Override
@ -78,5 +82,4 @@ class ZhurTaaDruidAbility extends TriggeredAbilityImpl {
public ZhurTaaDruidAbility copy() {
return new ZhurTaaDruidAbility(this);
}
}

View file

@ -8,6 +8,7 @@ import mage.counters.CounterType;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
@ -58,7 +59,7 @@ public class ManaReflectionTest extends CardTestPlayerBase {
assertManaPool(playerA, ManaType.GREEN, 2);
}
@Test
public void ManaReflectionWithGoblinClearcutterTest() {
// If you tap a permanent for mana, it produces twice as much of that mana instead.
@ -66,10 +67,10 @@ public class ManaReflectionTest extends CardTestPlayerBase {
// {T}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G}.
addCard(Zone.BATTLEFIELD, playerA, "Goblin Clearcutter");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
assertDuplicatedManaOptions(manaOptions);
@ -79,5 +80,20 @@ public class ManaReflectionTest extends CardTestPlayerBase {
assertManaOptions("{R}{R}{G}{G}{G}{G}{G}{G}", manaOptions);
assertManaOptions("{G}{G}{G}{G}{G}{G}{G}{G}", manaOptions);
}
@Test
public void ManaReflectionWithHavenwoodBattlegroundTest() {
// If you tap a permanent for mana, it produces twice as much of that mana instead.
addCard(Zone.BATTLEFIELD, playerA, "Mana Reflection");
// {T}, Sacrifice Havenwood Battleground: Add {G}{G}.
addCard(Zone.BATTLEFIELD, playerA, "Havenwood Battleground");
addCard(Zone.BATTLEFIELD, playerA, "Upwelling"); // Prevent mana from emptying before we can check it
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice");
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
assertManaPool(playerA, ManaType.GREEN, 4);
}
}

View file

@ -0,0 +1,35 @@
package org.mage.test.cards.single.iko;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author TheElk801
*/
public class KinnanBonderProdigyTest extends CardTestPlayerBase {
private static final String kinnan = "Kinnan, Bonder Prodigy";
private static final String egg = "Golden Egg";
private static final String hovermyr = "Hovermyr";
@Test
public void testSacrificedPermanent() {
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, kinnan);
addCard(Zone.BATTLEFIELD, playerA, egg);
addCard(Zone.HAND, playerA, hovermyr);
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hovermyr);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, hovermyr, 1);
assertPermanentCount(playerA, egg, 0);
assertGraveyardCount(playerA, egg, 1);
}
}

View file

@ -10,6 +10,22 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*/
public class StormCauldronTest extends CardTestPlayerBase {
@Test
public void testRegular() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Storm Cauldron", 1);
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, "Mountain", 1);
assertPermanentCount(playerA, "Mountain", 0);
}
/**
* With Storm Cauldron in play (owned by opponent), I sacced Crystal Vein
* for 2 mana... except it got returned to my hand, which shouldn't happen.

View file

@ -8,11 +8,12 @@ import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
* Non mana triggered ability (use case: you must apply non mana effects on mana taps like gain life)
*
* @author LevelX2
*/
@ -41,26 +42,26 @@ public class TapForManaAllTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA
// it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA
if (game.inCheckPlayableState()) {
return false;
}
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (filter.match(permanent, getSourceId(), getControllerId(), game)) {
ManaEvent mEvent = (ManaEvent) event;
for(Effect effect:getEffects()) {
effect.setValue("mana", mEvent.getMana());
}
switch(setTargetPointer) {
case PERMANENT:
getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
break;
case PLAYER:
getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getControllerId()));
break;
}
return true;
TappedForManaEvent manaEvent = ((TappedForManaEvent) event);
Permanent permanent = manaEvent.getPermanent();
if (permanent == null || !filter.match(permanent, getSourceId(), getControllerId(), game)) {
return false;
}
return false;
getEffects().setValue("mana", manaEvent.getMana());
getEffects().setValue("tappedPermanent", permanent);
switch (setTargetPointer) {
case PERMANENT:
getEffects().setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game)));
break;
case PLAYER:
getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId()));
break;
}
return true;
}
@Override

View file

@ -1,7 +1,5 @@
package mage.abilities.common;
import mage.abilities.effects.Effect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.mana.TriggeredManaAbility;
import mage.constants.SetTargetPointer;
@ -9,15 +7,15 @@ import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
* Mana triggered ability (use case: you must produce new mana on mana taps)
*
* @author LevelX2
*/
public class TapForManaAllTriggeredManaAbility extends TriggeredManaAbility {
private final FilterPermanent filter;
@ -42,23 +40,22 @@ public class TapForManaAllTriggeredManaAbility extends TriggeredManaAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (filter.match(permanent, getSourceId(), getControllerId(), game)) {
ManaEvent mEvent = (ManaEvent) event;
for(Effect effect:getEffects()) {
effect.setValue("mana", mEvent.getMana());
switch(setTargetPointer) {
case PERMANENT:
effect.setTargetPointer(new FixedTarget(permanent, game));
break;
case PLAYER:
effect.setTargetPointer(new FixedTarget(permanent.getControllerId()));
break;
}
}
return true;
TappedForManaEvent manaEvent = ((TappedForManaEvent) event);
Permanent permanent = manaEvent.getPermanent();
if (permanent == null || !filter.match(permanent, getSourceId(), getControllerId(), game)) {
return false;
}
return false;
getEffects().setValue("mana", manaEvent.getMana());
getEffects().setValue("tappedPermanent", permanent);
switch (setTargetPointer) {
case PERMANENT:
getEffects().setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game)));
break;
case PLAYER:
getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId()));
break;
}
return true;
}
@Override

View file

@ -1,69 +0,0 @@
package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author Quercitron
*/
public class TapLandForManaAllTriggeredAbility extends TriggeredAbilityImpl {
private final boolean setTargetPointer;
private final boolean landMustExists;
public TapLandForManaAllTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer, boolean landMustExists) {
super(Zone.BATTLEFIELD, effect, optional);
this.setTargetPointer = setTargetPointer;
this.landMustExists = landMustExists;
}
public TapLandForManaAllTriggeredAbility(final TapLandForManaAllTriggeredAbility ability) {
super(ability);
this.setTargetPointer = ability.setTargetPointer;
this.landMustExists = ability.landMustExists;
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA
return false;
}
Permanent permanent;
if (landMustExists) {
permanent = game.getPermanent(event.getSourceId());
} else {
permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
}
if (permanent != null && permanent.isLand(game)) {
if (setTargetPointer) {
getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
}
return true;
}
return false;
}
@Override
public TapLandForManaAllTriggeredAbility copy() {
return new TapLandForManaAllTriggeredAbility(this);
}
@Override
public String getTriggerPhrase() {
return "Whenever a land is tapped for mana, ";
}
}

View file

@ -1,57 +0,0 @@
package mage.abilities.common;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.mana.TriggeredManaAbility;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author LevelX2
*/
public class TapLandForManaAllTriggeredManaAbility extends TriggeredManaAbility {
private final boolean setTargetPointer;
public TapLandForManaAllTriggeredManaAbility(ManaEffect manaEffect, boolean optional, boolean setTargetPointer) {
super(Zone.BATTLEFIELD, manaEffect, optional);
this.setTargetPointer = setTargetPointer;
}
public TapLandForManaAllTriggeredManaAbility(final TapLandForManaAllTriggeredManaAbility ability) {
super(ability);
this.setTargetPointer = ability.setTargetPointer;
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent != null && permanent.isLand(game)) {
if (setTargetPointer) {
getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
}
return true;
}
return false;
}
@Override
public TapLandForManaAllTriggeredManaAbility copy() {
return new TapLandForManaAllTriggeredManaAbility(this);
}
@Override
public String getTriggerPhrase() {
return "Whenever a player taps a land for mana, ";
}
}

View file

@ -27,7 +27,7 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
@Override
public Player getPlayer(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
Permanent permanent = (Permanent) getValue("tappedPermanent");
if (permanent != null) {
return game.getPlayer(permanent.getControllerId());
}
@ -38,25 +38,26 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
public List<Mana> getNetMana(Game game, Ability source) {
List<Mana> netMana = new ArrayList<>();
Mana types = (Mana) this.getValue("mana");
if (types != null) {
if (types.getBlack() > 0) {
netMana.add(Mana.BlackMana(1));
}
if (types.getRed() > 0) {
netMana.add(Mana.RedMana(1));
}
if (types.getBlue() > 0) {
netMana.add(Mana.BlueMana(1));
}
if (types.getGreen() > 0) {
netMana.add(Mana.GreenMana(1));
}
if (types.getWhite() > 0) {
netMana.add(Mana.WhiteMana(1));
}
if (types.getColorless() > 0) {
netMana.add(Mana.ColorlessMana(1));
}
if (types == null) {
return netMana;
}
if (types.getBlack() > 0) {
netMana.add(Mana.BlackMana(1));
}
if (types.getRed() > 0) {
netMana.add(Mana.RedMana(1));
}
if (types.getBlue() > 0) {
netMana.add(Mana.BlueMana(1));
}
if (types.getGreen() > 0) {
netMana.add(Mana.GreenMana(1));
}
if (types.getWhite() > 0) {
netMana.add(Mana.WhiteMana(1));
}
if (types.getColorless() > 0) {
netMana.add(Mana.ColorlessMana(1));
}
return netMana;
}
@ -64,68 +65,69 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
@Override
public Mana produceMana(Game game, Ability source) {
Mana newMana = new Mana();
if (game != null) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
Player targetController = game.getPlayer(permanent.getControllerId());
Mana types = (Mana) this.getValue("mana");
if (targetController == null || types == null) {
return newMana;
}
if (game == null) {
return newMana;
}
Permanent permanent = (Permanent) this.getValue("tappedPermanent");
Mana types = (Mana) this.getValue("mana");
if (permanent == null || types == null) {
return newMana;
}
Player targetController = game.getPlayer(permanent.getControllerId());
if (targetController == null) {
return newMana;
}
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
choice.setMessage("Pick the type of mana to produce");
if (types.getBlack() > 0) {
choice.getChoices().add("Black");
}
if (types.getRed() > 0) {
choice.getChoices().add("Red");
}
if (types.getBlue() > 0) {
choice.getChoices().add("Blue");
}
if (types.getGreen() > 0) {
choice.getChoices().add("Green");
}
if (types.getWhite() > 0) {
choice.getChoices().add("White");
}
if (types.getColorless() > 0) {
choice.getChoices().add("Colorless");
}
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
choice.setMessage("Pick the type of mana to produce");
if (types.getWhite() > 0) {
choice.getChoices().add("White");
}
if (types.getBlue() > 0) {
choice.getChoices().add("Blue");
}
if (types.getBlack() > 0) {
choice.getChoices().add("Black");
}
if (types.getRed() > 0) {
choice.getChoices().add("Red");
}
if (types.getGreen() > 0) {
choice.getChoices().add("Green");
}
if (types.getColorless() > 0) {
choice.getChoices().add("Colorless");
}
if (!choice.getChoices().isEmpty()) {
if (choice.getChoices().size() == 1) {
choice.setChoice(choice.getChoices().iterator().next());
} else {
if (!targetController.choose(outcome, choice, game)) {
return newMana;
}
}
if (choice.getChoices().isEmpty()) {
return newMana;
}
if (choice.getChoices().size() != 1
&& !targetController.choose(outcome, choice, game)) {
return newMana;
}
choice.setChoice(choice.getChoices().iterator().next());
switch (choice.getChoice()) {
case "Black":
newMana.setBlack(1);
break;
case "Blue":
newMana.setBlue(1);
break;
case "Red":
newMana.setRed(1);
break;
case "Green":
newMana.setGreen(1);
break;
case "White":
newMana.setWhite(1);
break;
case "Colorless":
newMana.setColorless(1);
break;
}
}
}
switch (choice.getChoice()) {
case "White":
newMana.setWhite(1);
break;
case "Blue":
newMana.setBlue(1);
break;
case "Black":
newMana.setBlack(1);
break;
case "Red":
newMana.setRed(1);
break;
case "Green":
newMana.setGreen(1);
break;
case "Colorless":
newMana.setColorless(1);
break;
}
return newMana;
}
@ -134,5 +136,4 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
public AddManaOfAnyTypeProducedEffect copy() {
return new AddManaOfAnyTypeProducedEffect(this);
}
}

View file

@ -8,8 +8,8 @@ import mage.constants.AbilityType;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.players.Player;
import java.util.ArrayList;
@ -133,7 +133,7 @@ public abstract class ManaEffect extends OneShotEffect {
*/
public void checkToFirePossibleEvents(Mana mana, Game game, Ability source) {
if (source.getAbilityType() == AbilityType.MANA && source.hasTapCost()) {
ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, source.getSourceId(), source, source.getControllerId(), mana);
ManaEvent event = new TappedForManaEvent(source.getSourceId(), source, source.getControllerId(), mana, game);
if (!game.replaceEvent(event)) {
game.fireEvent(event);
}

View file

@ -1,19 +1,16 @@
package mage.abilities.mana;
import mage.ConditionalMana;
import mage.Mana;
import mage.abilities.Ability;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.game.events.TappedForManaEvent;
import mage.players.Player;
import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import mage.ConditionalMana;
import java.util.*;
/**
* @author BetaSteward_at_googlemail.com
@ -128,7 +125,7 @@ public class ManaOptions extends ArrayList<Mana> {
*/
private boolean checkManaReplacementAndTriggeredMana(Ability ability, Game game, Mana mana) {
if (ability.hasTapCost()) {
ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, ability.getSourceId(), ability, ability.getControllerId(), mana);
ManaEvent event = new TappedForManaEvent(ability.getSourceId(), ability, ability.getControllerId(), mana, game);
if (game.replaceEvent(event)) {
return false;
}
@ -415,7 +412,7 @@ public class ManaOptions extends ArrayList<Mana> {
if (manaToAdd != null && (manaToAdd.countColored() > 0 || manaToAdd.getAny() > 0) && manaToAdd.count() > 0 && onlyManaCosts) {
repeatable = true; // only replace to any with mana costs only will be repeated if able
}
for (Mana payCombination : ManaOptions.getPossiblePayCombinations(cost, currentMana)) {
Mana currentManaCopy = currentMana.copy(); // copy start mana because in iteration it will be updated
while (currentManaCopy.includesMana(payCombination)) { // loop for multiple usage if possible
@ -553,7 +550,7 @@ public class ManaOptions extends ArrayList<Mana> {
public boolean removeEqualMana(Mana manaToRemove) {
boolean result = false;
for (Iterator<Mana> iterator = this.iterator(); iterator.hasNext();) {
for (Iterator<Mana> iterator = this.iterator(); iterator.hasNext(); ) {
Mana next = iterator.next();
if (next.equalManaValue(manaToRemove)) {
iterator.remove();
@ -630,7 +627,7 @@ public class ManaOptions extends ArrayList<Mana> {
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
for (; ; ) {
Mana mana = it.next();
sb.append(mana.toString());
if (mana instanceof ConditionalMana) {

View file

@ -0,0 +1,31 @@
package mage.filter.predicate.mageobject;
import mage.MageObject;
import mage.ObjectColor;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
/**
* @author TheElk801
*/
public enum ChosenColorPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<MageObject>> {
TRUE(true), FALSE(false);
private final boolean value;
ChosenColorPredicate(boolean value) {
this.value = value;
}
@Override
public boolean apply(ObjectSourcePlayer<MageObject> input, Game game) {
ObjectColor color = (ObjectColor) game.getState().getValue(input.getSourceId() + "_color");
return color != null && input.getObject().getColor(game).shares(color) == value;
}
@Override
public String toString() {
return "Chosen subtype";
}
}

View file

@ -1,13 +1,11 @@
package mage.game.events;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class ManaEvent extends GameEvent {
@ -22,5 +20,4 @@ public class ManaEvent extends GameEvent {
public Mana getMana() {
return mana;
}
}

View file

@ -0,0 +1,25 @@
package mage.game.events;
import mage.Mana;
import mage.abilities.Ability;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public class TappedForManaEvent extends ManaEvent {
private final Permanent permanent;
public TappedForManaEvent(UUID targetId, Ability source, UUID playerId, Mana mana, Game game) {
super(EventType.TAPPED_FOR_MANA, targetId, source, playerId, mana);
this.permanent = source.getSourcePermanentOrLKI(game);
}
public Permanent getPermanent() {
return permanent;
}
}