Solve issue 1472 (#1528)

* ManaEffect.resolve add runTriggers boolean

* AbilityManaPart.produceMana incorporate runTriggers boolean

* caged_sun.txt refactor

* AbilityManaPart.produceMana split to add TriggerManaAdded

* TriggerManaAdded.java

* TriggerTapsForMana.java refactor out unneeded

* TriggerType.ManaAdded

* Adjust checks for new Trigger

* Caged Sun fix

* Fix False Dawn only affecting mana abilities

* Rework tapsForMana call

* Clean up

* Support default rules value

Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.59>
Co-authored-by: tool4ever <therealtoolkit@hotmail.com>
This commit is contained in:
Northmoc
2022-11-21 15:37:01 -05:00
committed by GitHub
parent d57794b31d
commit 35365c0893
29 changed files with 181 additions and 68 deletions

View File

@@ -514,10 +514,9 @@ public class ComputerUtilMana {
// Run triggers like Nissa
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(hostCard);
runParams.put(AbilityKey.Player, ai); // assuming AI would only ever gives itself mana
runParams.put(AbilityKey.Activator, ai); // assuming AI would only ever gives itself mana
runParams.put(AbilityKey.AbilityMana, saPayment);
runParams.put(AbilityKey.Produced, manaProduced);
runParams.put(AbilityKey.Activator, ai);
for (Trigger tr : ai.getGame().getTriggerHandler().getActiveTrigger(TriggerType.TapsForMana, runParams)) {
SpellAbility trSA = tr.ensureAbility();
if (trSA == null) {
@@ -529,7 +528,7 @@ public class ComputerUtilMana {
if (produced.equals("Chosen")) {
produced = MagicColor.toShortString(trSA.getHostCard().getChosenColor());
}
manaProduced += " " + StringUtils.repeat(produced, pAmount);
manaProduced += " " + StringUtils.repeat(produced, " ", pAmount);
} else if (ApiType.ManaReflected.equals(trSA.getApi())) {
final String colorOrType = trSA.getParamOrDefault("ColorOrType", "Color");
// currently Color or Type, Type is colors + colorless

View File

@@ -31,7 +31,6 @@ import forge.card.MagicColor;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostParser;
import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType;
import forge.game.card.CardPlayOption.PayManaCost;
import forge.game.cost.Cost;
@@ -834,12 +833,13 @@ public final class GameActionUtil {
}
public static String generatedMana(final SpellAbility sa) {
int amount = sa.amountOfManaGenerated(false);
AbilityManaPart abMana = sa.getManaPart();
if (abMana == null) {
return "";
}
String baseMana;
int amount = sa.amountOfManaGenerated(false);
if (abMana.isComboMana()) {
baseMana = abMana.getExpressChoice();
@@ -863,7 +863,7 @@ public final class GameActionUtil {
// Mark SAs with subAbilities as undoable. These are generally things like damage, and other stuff
// that's hard to track and remove
sa.setUndoable(false);
} else if (sa.getParam("Amount") != null && amount != AbilityUtils.calculateAmount(sa.getHostCard(),sa.getParam("Amount"), sa)) {
} else if (sa.hasParam("Amount") && !StringUtils.isNumeric(sa.getParam("Amount"))) {
sa.setUndoable(false);
}

View File

@@ -32,7 +32,7 @@ public class ManaEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {
final Card card = sa.getHostCard();
AbilityManaPart abMana = sa.getManaPart();
final AbilityManaPart abMana = sa.getManaPart();
final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa);
// Spells are not undoable
@@ -45,6 +45,8 @@ public class ManaEffect extends SpellAbilityEffect {
return;
}
final StringBuilder producedMana = new StringBuilder();
for (Player p : tgtPlayers) {
if (sa.usesTargeting() && !p.canBeTargetedBy(sa)) {
// Illegal target. Skip.
@@ -241,9 +243,11 @@ public class ManaEffect extends SpellAbilityEffect {
continue;
}
abMana.produceMana(mana, p, sa);
producedMana.append(abMana.produceMana(mana, p, sa));
}
abMana.tapsForMana(sa, producedMana.toString());
// Only clear express choice after mana has been produced
abMana.clearExpressChoice();
}

View File

@@ -21,18 +21,20 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
*/
@Override
public void resolve(SpellAbility sa) {
final Collection<String> colors = CardUtil.getReflectableManaColors(sa);
final AbilityManaPart ma = sa.getManaPart();
// Spells are not undoable
AbilityManaPart ma = sa.getManaPart();
sa.setUndoable(sa.isAbility() && sa.isUndoable() && sa.getSubAbility() == null);
final Collection<String> colors = CardUtil.getReflectableManaColors(sa);
final StringBuilder producedMana = new StringBuilder();
for (final Player player : getTargetPlayers(sa)) {
final String generated = generatedReflectedMana(sa, colors, player);
ma.produceMana(generated, player, sa);
}
producedMana.append(ma.produceMana(generated, player, sa));
}
ma.tapsForMana(sa, producedMana.toString());
}
// *************** Utility Functions **********************

View File

@@ -40,7 +40,7 @@ public class ReplaceProduceMana extends ReplacementEffect {
if (!matchesValidParam("ValidActivator", runParams.get(AbilityKey.Activator))) {
return false;
}
if (!matchesValidParam("ValidAbility", runParams.get(AbilityKey.AbilityMana))) {
if (!matchesValid(runParams.get(AbilityKey.AbilityMana), getParamOrDefault("ValidSA", "Activated.hasTapCost+ManaAbility").split(","), getHostCard())) {
return false;
}

View File

@@ -28,6 +28,7 @@ import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.card.mana.ManaAtom;
import forge.card.mana.ManaCostShard;
import forge.game.Game;
import forge.game.GameActionUtil;
import forge.game.IHasSVars;
import forge.game.ability.AbilityKey;
@@ -126,29 +127,31 @@ public class AbilityManaPart implements java.io.Serializable {
* @param player
* a {@link forge.game.player.Player} object.
* @param sa
*
*/
public final void produceMana(final String produced, final Player player, SpellAbility sa) {
public final String produceMana(final String produced, final Player player, SpellAbility sa) {
final Card source = this.getSourceCard();
final ManaPool manaPool = player.getManaPool();
final Game game = player.getGame();
String afterReplace = produced;
SpellAbility root = sa == null ? null : sa.getRootAbility();
if (root != null && root.isManaAbility()) {
if (root != null) {
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(source);
repParams.put(AbilityKey.Mana, afterReplace);
repParams.put(AbilityKey.Player, player);
repParams.put(AbilityKey.AbilityMana, root);
repParams.put(AbilityKey.Activator, root.getActivatingPlayer());
switch (player.getGame().getReplacementHandler().run(ReplacementType.ProduceMana, repParams)) {
switch (game.getReplacementHandler().run(ReplacementType.ProduceMana, repParams)) {
case NotReplaced:
break;
case Updated:
afterReplace = (String) repParams.get(AbilityKey.Mana);
break;
default:
return;
return "";
}
}
@@ -181,10 +184,25 @@ public class AbilityManaPart implements java.io.Serializable {
runParams.put(AbilityKey.AbilityMana, root);
runParams.put(AbilityKey.Activator, root == null ? null : root.getActivatingPlayer());
player.getGame().getTriggerHandler().runTrigger(TriggerType.TapsForMana, runParams, false);
if (source.isLand() && root.isManaAbility() && root.getPayCosts() != null && root.getPayCosts().hasTapCost()) {
game.getTriggerHandler().runTrigger(TriggerType.ManaAdded, runParams, false);
return afterReplace;
}
public void tapsForMana(final SpellAbility root, String mana) {
if (!root.isManaAbility() || root.getPayCosts() == null || !root.getPayCosts().hasTapCost()) {
return;
}
if (getSourceCard().isLand()) {
root.getActivatingPlayer().setTappedLandForManaThisTurn(true);
}
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(getSourceCard());
runParams.put(AbilityKey.Produced, mana);
runParams.put(AbilityKey.Activator, root.getActivatingPlayer());
getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.TapsForMana, runParams, false);
}
/**
@@ -529,7 +547,10 @@ public class AbilityManaPart implements java.io.Serializable {
* @return a boolean.
*/
public final boolean canProduce(final String s, final SpellAbility sa) {
// TODO: need to handle replacement effects like 106.7
// TODO: need to handle replacement effects like 106.7 before deciding no mana is produced
//if (sa.amountOfManaGenerated(false) == 0) {
// return false;
//}
// Any mana never means Colorless?
if (isAnyMana() && !s.equals("C")) {

View File

@@ -367,7 +367,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
return false; //Loyalty ability, not a mana ability.
}
// CR 605.1b
if (isTrigger() && this.getTrigger().getMode() != TriggerType.TapsForMana) {
if (isTrigger() && this.getTrigger().getMode() != TriggerType.TapsForMana && this.getTrigger().getMode() != TriggerType.ManaAdded) {
return false;
}

View File

@@ -503,7 +503,7 @@ public class TriggerHandler {
// Return true if the trigger went off, false otherwise.
private void runSingleTriggerInternal(final Trigger regtrig, final Map<AbilityKey, Object> runParams) {
// All tests passed, execute ability.
if (regtrig instanceof TriggerTapsForMana) {
if (regtrig instanceof TriggerTapsForMana || regtrig instanceof TriggerManaAdded) {
final SpellAbility abMana = (SpellAbility) runParams.get(AbilityKey.AbilityMana);
if (null != abMana && null != abMana.getManaPart()) {
abMana.setUndoable(false);

View File

@@ -0,0 +1,98 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.game.trigger;
import forge.card.MagicColor;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import forge.util.Localizer;
import java.util.Map;
import static forge.util.TextUtil.toManaString;
/**
* <p>
* Trigger_ManaAdded class.
* </p>
*
* @author Forge
* @version $Id$
*/
public class TriggerManaAdded extends Trigger {
/**
* <p>
* Constructor for Trigger_TapsForMana.
* </p>
*
* @param params
* a {@link java.util.HashMap} object.
* @param host
* a {@link forge.game.card.Card} object.
* @param intrinsic
* the intrinsic
*/
public TriggerManaAdded(final Map<String, String> params, final Card host, final boolean intrinsic) {
super(params, host, intrinsic);
}
/** {@inheritDoc}
* @param runParams*/
@Override
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.Card))) {
return false;
}
if (!matchesValidParam("ValidSA", runParams.get(AbilityKey.AbilityMana))) {
return false;
}
if (!matchesValidParam("Player", runParams.get(AbilityKey.Player))) {
return false;
}
if (hasParam("Produced")) {
Object prod = runParams.get(AbilityKey.Produced);
if (!(prod instanceof String)) {
return false;
}
String produced = (String) prod;
if ("ChosenColor".equals(getParam("Produced"))) {
if (!this.getHostCard().hasChosenColor() || !produced.contains(MagicColor.toShortString(this.getHostCard().getChosenColor()))) {
return false;
}
} else if (!produced.contains(MagicColor.toShortString(this.getParam("Produced")))) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
@Override
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card, AbilityKey.Player, AbilityKey.Produced);
}
@Override
public String getImportantStackObjects(SpellAbility sa) {
return Localizer.getInstance().getMessage("lblProduced") + ": " +
toManaString(sa.getTriggeringObject(AbilityKey.Produced).toString());
}
}

View File

@@ -57,28 +57,16 @@ public class TriggerTapsForMana extends Trigger {
* @param runParams*/
@Override
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
SpellAbility manaAbility = (SpellAbility) runParams.get(AbilityKey.AbilityMana);
// Caged Sun special case
if (!hasParam("NoTapCheck")) {
if (manaAbility == null || !manaAbility.isManaAbility() || !manaAbility.getPayCosts().hasTapCost()) {
return false;
}
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
return false;
}
if (!matchesValidParam("Player", runParams.get(AbilityKey.Player))) {
return false;
}
if (!matchesValidParam("Activator", runParams.get(AbilityKey.Activator))) {
return false;
}
if (hasParam("Produced")) {
Object prod = runParams.get(AbilityKey.Produced);
if (prod == null || !(prod instanceof String)) {
if (!(prod instanceof String)) {
return false;
}
String produced = (String) prod;
@@ -97,15 +85,14 @@ public class TriggerTapsForMana extends Trigger {
/** {@inheritDoc} */
@Override
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card, AbilityKey.Player, AbilityKey.Produced, AbilityKey.Activator);
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card, AbilityKey.Produced, AbilityKey.Activator);
}
@Override
public String getImportantStackObjects(SpellAbility sa) {
StringBuilder sb = new StringBuilder();
sb.append(Localizer.getInstance().getMessage("lblTappedForMana")).append(": ").append(sa.getTriggeringObject(AbilityKey.Card));
sb.append(Localizer.getInstance().getMessage("lblProduced")).append(": ").append(toManaString(sa.getTriggeringObject(AbilityKey.Produced).toString()));
return sb.toString();
return Localizer.getInstance().getMessage("lblTappedForMana") + ": " +
sa.getTriggeringObject(AbilityKey.Card) + Localizer.getInstance().getMessage("lblProduced") + ": "
+ toManaString(sa.getTriggeringObject(AbilityKey.Produced).toString());
}
}

View File

@@ -81,6 +81,7 @@ public enum TriggerType {
LifeGained(TriggerLifeGained.class),
LifeLost(TriggerLifeLost.class),
LosesGame(TriggerLosesGame.class),
ManaAdded(TriggerManaAdded.class),
MilledAll(TriggerMilledAll.class),
Mutates(TriggerMutates.class),
NewGame(TriggerNewGame.class),

View File

@@ -4,6 +4,7 @@ Types:Artifact
K:ETBReplacement:Other:ChooseColor
SVar:ChooseColor:DB$ ChooseColor | Defined$ You | AILogic$ MostProminentInComputerDeck | SpellDescription$ As CARDNAME enters the battlefield, choose a color.
S:Mode$ Continuous | Affected$ Creature.ChosenColor+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Creatures you control of the chosen color get +1/+1.
T:Mode$ TapsForMana | ValidCard$ Land | Produced$ ChosenColor | NoTapCheck$ True | Player$ You | Execute$ TrigMana | TriggerZones$ Battlefield | Static$ True | TriggerDescription$ Whenever a land's ability causes you to add one or more mana of the chosen color, add one additional mana of that color.
SVar:TrigMana:DB$ Mana | Produced$ Chosen | Amount$ 1 | Defined$ You
T:Mode$ ManaAdded | ValidSource$ Land | ValidSA$ SpellAbility.ManaAbility | Produced$ ChosenColor | Player$ You | Execute$ TrigMana | TriggerZones$ Battlefield | Static$ True | TriggerDescription$ Whenever a land's ability causes you to add one or more mana of the chosen color, add one additional mana of that color.
T:Mode$ ManaAdded | ValidSource$ Land | ValidSA$ SpellAbility.nonManaAbility | Produced$ ChosenColor | Player$ You | Execute$ TrigMana | TriggerZones$ Battlefield | TriggerDescription$ Whenever a land's ability causes you to add one or more mana of the chosen color, add one additional mana of that color.
SVar:TrigMana:DB$ Mana | Produced$ Chosen | Amount$ 1
Oracle:As Caged Sun enters the battlefield, choose a color.\nCreatures you control of the chosen color get +1/+1.\nWhenever a land's ability causes you to add one or more mana of the chosen color, add one additional mana of that color.

View File

@@ -5,9 +5,9 @@ T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigCount |
SVar:TrigCount:DB$ Effect | Triggers$ TrigRamp | StaticAbilities$ STPump | ConditionCheckSVar$ X | ConditionSVarCompare$ M21 | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | ReplacementEffects$ RepCurse | StaticAbilities$ STCurse | ConditionCheckSVar$ X | ConditionSVarCompare$ M20
SVar:TrigRamp:Mode$ TapsForMana | ValidCard$ Mountain | Execute$ TrigMana | Static$ True | TriggerZones$ Command | TriggerDescription$ Whenever a player taps a Mountain for mana, that player adds {R}.
SVar:TrigMana:DB$ Mana | Produced$ R | Amount$ 1 | Defined$ TriggeredCardController
SVar:TrigMana:DB$ Mana | Produced$ R | Amount$ 1 | Defined$ TriggeredActivator
SVar:STPump:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Battlefield | Affected$ Creature.Red | AddPower$ 1 | AddToughness$ 1
SVar:RepCurse:Event$ ProduceMana | ActiveZones$ Command | ValidCard$ Mountain | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceColorless | Description$ If a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type.
SVar:RepCurse:Event$ ProduceMana | ActiveZones$ Command | ValidCard$ Mountain | ReplaceWith$ ProduceColorless | Description$ If a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type.
SVar:ProduceColorless:DB$ ReplaceMana | ReplaceType$ C
SVar:STCurse:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Battlefield | Affected$ Creature.Red | AddPower$ -1 | AddToughness$ -1
SVar:X:Count$Valid Permanent

View File

@@ -2,7 +2,7 @@ Name:Contamination
ManaCost:2 B
Types:Enchantment
K:UpkeepCost:Sac<1/Creature>
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceB | Description$ If a land is tapped for mana, it produces {B} instead of any other type and amount.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land | ReplaceWith$ ProduceB | Description$ If a land is tapped for mana, it produces {B} instead of any other type and amount.
SVar:ProduceB:DB$ ReplaceMana | ReplaceMana$ B
AI:RemoveDeck:All
SVar:NonStackingEffect:True

View File

@@ -1,7 +1,7 @@
Name:Damping Sphere
ManaCost:2
Types:Artifact
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land | ValidAbility$ Activated.hasTapCost | ManaAmount$ GE2 | ReplaceWith$ ProduceC | Description$ If a land is tapped for two or more mana, it produces {C} instead of any other type and amount.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land | ManaAmount$ GE2 | ReplaceWith$ ProduceC | Description$ If a land is tapped for two or more mana, it produces {C} instead of any other type and amount.
SVar:ProduceC:DB$ ReplaceMana | ReplaceMana$ C
S:Mode$ RaiseCost | Activator$ Player | Type$ Spell | Amount$ X | Relative$ True | Description$ Each spell a player casts costs {1} more to cast for each other spell that player has cast this turn.
SVar:X:Count$ThisTurnCast_Card.YouCtrl

View File

@@ -2,7 +2,7 @@ Name:Deep Water
ManaCost:U U
Types:Enchantment
A:AB$ Effect | Cost$ U | ReplacementEffects$ ReplaceU | SpellDescription$ Until end of turn, if you tap a land you control for mana, it produces {U} instead of any other type.
SVar:ReplaceU:Event$ ProduceMana | ActiveZones$ Command | ValidActivator$ You | ValidCard$ Land.YouCtrl | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceU | Description$ If you tap a land you control for mana, it produces U instead of any other type.
SVar:ReplaceU:Event$ ProduceMana | ActiveZones$ Command | ValidActivator$ You | ValidCard$ Land.YouCtrl | ReplaceWith$ ProduceU | Description$ If you tap a land you control for mana, it produces U instead of any other type.
SVar:ProduceU:DB$ ReplaceMana | ReplaceType$ U
AI:RemoveDeck:All
AI:RemoveDeck:Random

View File

@@ -3,7 +3,7 @@ ManaCost:1 W
Types:Sorcery
A:SP$ Effect | Cost$ 1 W | ReplacementEffects$ FDRep | StaticAbilities$ FDManaConvertion | SubAbility$ DBDraw | SpellDescription$ Until end of turn, spells and abilities you control that would add colored mana instead add that much white mana. Until end of turn, you may spend white mana as though it were mana of any color. Draw a card.
SVar:DBDraw:DB$ Draw | NumCards$ 1
SVar:FDRep:Event$ ProduceMana | ActiveZones$ Command | ValidAbility$ SpellAbility.YouCtrl | ReplaceWith$ ProduceW | Description$ Spells and abilities you control that would add colored mana add that much white mana instead.
SVar:FDRep:Event$ ProduceMana | ActiveZones$ Command | ValidSA$ SpellAbility.YouCtrl | ReplaceWith$ ProduceW | Description$ Spells and abilities you control that would add colored mana add that much white mana instead.
SVar:ProduceW:DB$ ReplaceMana | ReplaceColor$ W
SVar:FDManaConvertion:Mode$ Continuous | EffectZone$ Command | Affected$ You | ManaConversion$ W->AnyColor | Description$ You may spend white mana as though it were mana of any color.
AI:RemoveDeck:All

View File

@@ -4,7 +4,7 @@ Types:World Enchantment
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player | Execute$ TrigChoose | TriggerZones$ Battlefield | TriggerDescription$ 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.
SVar:TrigChoose:DB$ ChooseColor | Defined$ TriggeredPlayer | AILogic$ MostProminentInActivePlayerHand | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | ReplacementEffects$ ReplaceChosen
SVar:ReplaceChosen:Event$ ProduceMana | ActiveZones$ Command | ValidCard$ Land | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceChosen | Description$ Lands tapped for mana produce mana of the chosen color instead of any other color.
SVar:ReplaceChosen:Event$ ProduceMana | ActiveZones$ Command | ValidCard$ Land | ReplaceWith$ ProduceChosen | Description$ Lands tapped for mana produce mana of the chosen color instead of any other color.
SVar:ProduceChosen:DB$ ReplaceMana | ReplaceColor$ Chosen
AI:RemoveDeck:Random
Oracle: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.

View File

@@ -3,7 +3,7 @@ ManaCost:G
Types:Creature Human Spellshaper
PT:1/1
A:AB$ Effect | Cost$ G T Discard<1/Card> | ReplacementEffects$ HarvestReplacement | AILogic$ Never | Stackable$ False | SpellDescription$ 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.
SVar:HarvestReplacement:Event$ ProduceMana | ActiveZones$ Command | ValidActivator$ You | ValidCard$ Land | ValidAbility$ Activated.hasTapCost | ReplaceWith$ HarvestProduce | Description$ If you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount.
SVar:HarvestReplacement:Event$ ProduceMana | ActiveZones$ Command | ValidActivator$ You | ValidCard$ Land | ReplaceWith$ HarvestProduce | Description$ If you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount.
SVar:HarvestProduce:DB$ ReplaceMana | ReplaceMana$ Any
AI:RemoveDeck:All
SVar:NonStackingEffect:True

View File

@@ -2,7 +2,7 @@ Name:Infernal Darkness
ManaCost:2 B B
Types:Enchantment
K:Cumulative upkeep:B PayLife<1>:Pay {B} and 1 life.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceB | Description$ If a land is tapped for mana, it produces {B} instead of any other type.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land | ReplaceWith$ ProduceB | Description$ If a land is tapped for mana, it produces {B} instead of any other type.
SVar:ProduceB:DB$ ReplaceMana | ReplaceType$ B
AI:RemoveDeck:All
AI:RemoveDeck:Random

View File

@@ -1,6 +1,6 @@
Name:Mana Reflection
ManaCost:4 G G
Types:Enchantment
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidActivator$ You | ValidCard$ Permanent | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceTwice | Description$ If you tap a permanent for mana, it produces twice as much of that mana instead.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidActivator$ You | ValidCard$ Permanent | ReplaceWith$ ProduceTwice | Description$ If you tap a permanent for mana, it produces twice as much of that mana instead.
SVar:ProduceTwice:DB$ ReplaceMana | ReplaceAmount$ 2
Oracle:If you tap a permanent for mana, it produces twice as much of that mana instead.

View File

@@ -2,7 +2,7 @@ Name:Mirri
ManaCost:no cost
Types:Vanguard
HandLifeModifier:+0/+5
R:Event$ ProduceMana | ActiveZones$ Command | ValidCard$ Land.Basic+YouCtrl | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceAny | Description$ If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type.
R:Event$ ProduceMana | ActiveZones$ Command | ValidCard$ Land.Basic+YouCtrl | ReplaceWith$ ProduceAny | Description$ If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type.
SVar:ProduceAny:DB$ ReplaceMana | ReplaceType$ Any
AI:RemoveDeck:All
Oracle:Hand +0, life +5\nIf a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type.

View File

@@ -3,15 +3,15 @@ ManaCost:5
Types:Artifact
Text: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.
K:Cumulative upkeep:3
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Plains | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceR | Secondary$ True | Description$ If tapped for mana, Plains produce R.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Plains | ReplaceWith$ ProduceR | Secondary$ True | Description$ If tapped for mana, Plains produce R.
SVar:ProduceR:DB$ ReplaceMana | ReplaceType$ R
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Island | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceG | Secondary$ True | Description$ If tapped for mana, Islands produce G.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Island | ReplaceWith$ ProduceG | Secondary$ True | Description$ If tapped for mana, Islands produce G.
SVar:ProduceG:DB$ ReplaceMana | ReplaceType$ G
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Swamp | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceW | Secondary$ True | Description$ If tapped for mana, Swamps produce W.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Swamp | ReplaceWith$ ProduceW | Secondary$ True | Description$ If tapped for mana, Swamps produce W.
SVar:ProduceW:DB$ ReplaceMana | ReplaceType$ W
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Mountain | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceU | Secondary$ True | Description$ If tapped for mana, Mountains produce U.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Mountain | ReplaceWith$ ProduceU | Secondary$ True | Description$ If tapped for mana, Mountains produce U.
SVar:ProduceU:DB$ ReplaceMana | ReplaceType$ U
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Forest | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceB | Secondary$ True | Description$ If tapped for mana, Forests produce B.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Forest | ReplaceWith$ ProduceB | Secondary$ True | Description$ If tapped for mana, Forests produce B.
SVar:ProduceB:DB$ ReplaceMana | ReplaceType$ B
AI:RemoveDeck:All
AI:RemoveDeck:Random

View File

@@ -3,6 +3,6 @@ ManaCost:4 G G G
Types:Enchantment Creature Elemental
PT:5/5
K:Trample
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidActivator$ You | ValidCard$ Permanent | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceThrice | Description$ If you tap a permanent for mana, it produces three times as much of that mana instead.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidActivator$ You | ValidCard$ Permanent | ReplaceWith$ ProduceThrice | Description$ If you tap a permanent for mana, it produces three times as much of that mana instead.
SVar:ProduceThrice:DB$ ReplaceMana | ReplaceAmount$ 3
Oracle:Trample\nIf you tap a permanent for mana, it produces three times as much of that mana instead.

View File

@@ -2,7 +2,7 @@ Name:Pale Moon
ManaCost:1 U
Types:Instant
A:SP$ Effect | Cost$ 1 U | ReplacementEffects$ ReplaceColorless | SpellDescription$ Until end of turn, if a player taps a nonbasic land for mana, it produces colorless mana instead of any other type.
SVar:ReplaceColorless:Event$ ProduceMana | ActiveZones$ Command | ValidCard$ Land.nonBasic | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceColorless | Description$ If a player taps a nonbasic land for mana, it produces colorless mana instead of any other type.
SVar:ReplaceColorless:Event$ ProduceMana | ActiveZones$ Command | ValidCard$ Land.nonBasic | ReplaceWith$ ProduceColorless | Description$ If a player taps a nonbasic land for mana, it produces colorless mana instead of any other type.
SVar:ProduceColorless:DB$ ReplaceMana | ReplaceType$ C
AI:RemoveDeck:All
AI:RemoveDeck:Random

View File

@@ -2,7 +2,7 @@ Name:Psionic Ritual
ManaCost:4 U U
Types:Sorcery
K:Replicate:tapXType<1/Horror>
A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Exile | TgtPrompt$ Choose target instant or sorcery card in your graveyard | ValidTgts$ Instant,Sorcery | RememberChanged$ True | SubAbility$ DBCopy | SpellDescription$ Exile target instant or sorcery card from a graveyard and copy it. You may cast the copy without paying its mana cost. Exile CARDNAME
A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Exile | TgtPrompt$ Choose target instant or sorcery card in your graveyard | ValidTgts$ Instant,Sorcery | RememberChanged$ True | SubAbility$ DBCopy | SpellDescription$ Exile target instant or sorcery card from a graveyard and copy it. You may cast the copy without paying its mana cost. Exile CARDNAME.
SVar:DBCopy:DB$ Play | Defined$ Remembered | Amount$ All | CopyCard$ True | WithoutManaCost$ True | Optional$ True | SubAbility$ ExileSelf
SVar:ExileSelf:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | Defined$ Self | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True

View File

@@ -1,7 +1,7 @@
Name:Pulse of Llanowar
ManaCost:3 G
Types:Enchantment
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land.Basic+YouCtrl | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceAny | Description$ If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land.Basic+YouCtrl | ReplaceWith$ ProduceAny | Description$ If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type.
SVar:ProduceAny:DB$ ReplaceMana | ReplaceType$ Any
AI:RemoveDeck:All
SVar:NonStackingEffect:True

View File

@@ -3,13 +3,13 @@ ManaCost:U U U
Types:Enchantment
Text:If tapped for mana, Plains produce {R}, Swamps produce {G}, Mountains produce {W}, and Forests produce {B} instead of any other type.
K:Cumulative upkeep:1 U U
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Plains | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceR | Secondary$ True | Description$ If tapped for mana, Plains produce R.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Plains | ReplaceWith$ ProduceR | Secondary$ True | Description$ If tapped for mana, Plains produce R.
SVar:ProduceR:DB$ ReplaceMana | ReplaceType$ R
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Swamp | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceG | Secondary$ True | Description$ If tapped for mana, Swamps produce G.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Swamp | ReplaceWith$ ProduceG | Secondary$ True | Description$ If tapped for mana, Swamps produce G.
SVar:ProduceG:DB$ ReplaceMana | ReplaceType$ G
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Mountain | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceW | Secondary$ True | Description$ If tapped for mana, Mountains produce U.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Mountain | ReplaceWith$ ProduceW | Secondary$ True | Description$ If tapped for mana, Mountains produce U.
SVar:ProduceW:DB$ ReplaceMana | ReplaceType$ W
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Forest | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceB | Secondary$ True | Description$ If tapped for mana, Forests produce B.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Forest | ReplaceWith$ ProduceB | Secondary$ True | Description$ If tapped for mana, Forests produce B.
SVar:ProduceB:DB$ ReplaceMana | ReplaceType$ B
AI:RemoveDeck:All
AI:RemoveDeck:Random

View File

@@ -2,7 +2,7 @@ Name:Ritual of Subdual
ManaCost:4 G G
Types:Enchantment
K:Cumulative upkeep:2
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land | ValidAbility$ Activated.hasTapCost | ReplaceWith$ ProduceColorless | Description$ If a land is tapped for mana, it produces colorless mana instead of any other type.
R:Event$ ProduceMana | ActiveZones$ Battlefield | ValidCard$ Land | ReplaceWith$ ProduceColorless | Description$ If a land is tapped for mana, it produces colorless mana instead of any other type.
SVar:ProduceColorless:DB$ ReplaceMana | ReplaceType$ C
AI:RemoveDeck:All
AI:RemoveDeck:Random