mirror of
https://github.com/magefree/mage.git
synced 2025-12-21 02:52:02 -08:00
properly implement WaterbendXCost
This commit is contained in:
parent
f007ebb289
commit
4480dbdf4d
9 changed files with 90 additions and 72 deletions
|
|
@ -33,7 +33,7 @@ public final class BenevolentRiverSpirit extends CardImpl {
|
||||||
this.getSpellAbility().addCost(new WaterbendCost(5));
|
this.getSpellAbility().addCost(new WaterbendCost(5));
|
||||||
this.addAbility(new SimpleStaticAbility(
|
this.addAbility(new SimpleStaticAbility(
|
||||||
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {5}")
|
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {5}")
|
||||||
));
|
).setRuleAtTheTop(true));
|
||||||
|
|
||||||
// Flying
|
// Flying
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
package mage.cards.c;
|
package mage.cards.c;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.costs.common.WaterbendXCost;
|
import mage.abilities.costs.common.WaterbendXCost;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.InfoEffect;
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Zone;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterOpponentsCreaturePermanent;
|
import mage.filter.common.FilterOpponentsCreaturePermanent;
|
||||||
|
|
@ -31,6 +34,9 @@ public final class CrashingWave extends CardImpl {
|
||||||
|
|
||||||
// As an additional cost to cast this spell, waterbend {X}.
|
// As an additional cost to cast this spell, waterbend {X}.
|
||||||
this.getSpellAbility().addCost(new WaterbendXCost());
|
this.getSpellAbility().addCost(new WaterbendXCost());
|
||||||
|
this.addAbility(new SimpleStaticAbility(
|
||||||
|
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {X}")
|
||||||
|
).setRuleAtTheTop(true));
|
||||||
|
|
||||||
// Tap up to X target creatures, then distribute three stun counters among tapped creatures your opponents control.
|
// Tap up to X target creatures, then distribute three stun counters among tapped creatures your opponents control.
|
||||||
this.getSpellAbility().addEffect(new TapTargetEffect("tap up to X target creatures"));
|
this.getSpellAbility().addEffect(new TapTargetEffect("tap up to X target creatures"));
|
||||||
|
|
@ -79,7 +85,7 @@ class CrashingWaveEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
TargetPermanentAmount target = new TargetPermanentAmount(3, 1, filter);
|
TargetPermanentAmount target = new TargetPermanentAmount(3, 1, filter);
|
||||||
target.withNotTarget(true);
|
target.withNotTarget(true);
|
||||||
player.chooseTarget(outcome, target, source, game);
|
target.chooseTarget(outcome, player.getId(), source, game);
|
||||||
for (UUID targetId : target.getTargets()) {
|
for (UUID targetId : target.getTargets()) {
|
||||||
Optional.ofNullable(targetId)
|
Optional.ofNullable(targetId)
|
||||||
.map(game::getPermanent)
|
.map(game::getPermanent)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
package mage.cards.f;
|
package mage.cards.f;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||||
import mage.abilities.costs.common.WaterbendCost;
|
|
||||||
import mage.abilities.costs.common.WaterbendXCost;
|
import mage.abilities.costs.common.WaterbendXCost;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
||||||
|
import mage.abilities.effects.common.InfoEffect;
|
||||||
import mage.abilities.effects.common.SacrificeTargetEffect;
|
import mage.abilities.effects.common.SacrificeTargetEffect;
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
|
@ -35,6 +36,9 @@ public final class FoggySwampVisions extends CardImpl {
|
||||||
|
|
||||||
// As an additional cost to cast this spell, waterbend {X}.
|
// As an additional cost to cast this spell, waterbend {X}.
|
||||||
this.getSpellAbility().addCost(new WaterbendXCost());
|
this.getSpellAbility().addCost(new WaterbendXCost());
|
||||||
|
this.addAbility(new SimpleStaticAbility(
|
||||||
|
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {X}")
|
||||||
|
).setRuleAtTheTop(true));
|
||||||
|
|
||||||
// Exile X target creature cards from graveyards. For each creature card exiled this way, create a token that's a copy of it. At the beginning of your next end step, sacrifice those tokens.
|
// Exile X target creature cards from graveyards. For each creature card exiled this way, create a token that's a copy of it. At the beginning of your next end step, sacrifice those tokens.
|
||||||
this.getSpellAbility().addEffect(new FoggySwampVisionsEffect());
|
this.getSpellAbility().addEffect(new FoggySwampVisionsEffect());
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import mage.abilities.common.ActivateIfConditionActivatedAbility;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.MyTurnCondition;
|
import mage.abilities.condition.common.MyTurnCondition;
|
||||||
import mage.abilities.costs.common.WaterbendXCost;
|
import mage.abilities.costs.common.WaterbendXCost;
|
||||||
import mage.abilities.costs.mana.VariableManaCost;
|
|
||||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.abilities.effects.common.InfoEffect;
|
import mage.abilities.effects.common.InfoEffect;
|
||||||
|
|
@ -20,7 +19,6 @@ import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.permanent.token.AllyToken;
|
import mage.game.permanent.token.AllyToken;
|
||||||
import mage.util.CardUtil;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -49,9 +47,8 @@ public final class KataraWaterTribesHope extends CardImpl {
|
||||||
Ability ability = new ActivateIfConditionActivatedAbility(new SetBasePowerToughnessAllEffect(
|
Ability ability = new ActivateIfConditionActivatedAbility(new SetBasePowerToughnessAllEffect(
|
||||||
GetXValue.instance, GetXValue.instance, Duration.EndOfTurn,
|
GetXValue.instance, GetXValue.instance, Duration.EndOfTurn,
|
||||||
StaticFilters.FILTER_CONTROLLED_CREATURES
|
StaticFilters.FILTER_CONTROLLED_CREATURES
|
||||||
), new WaterbendXCost(), MyTurnCondition.instance);
|
), new WaterbendXCost(1), MyTurnCondition.instance);
|
||||||
ability.addEffect(new InfoEffect("X can't be 0"));
|
ability.addEffect(new InfoEffect("X can't be 0"));
|
||||||
CardUtil.castStream(ability.getCosts(), VariableManaCost.class).forEach(cost -> cost.setMinX(1));
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ public final class WaterWhip extends CardImpl {
|
||||||
this.getSpellAbility().addCost(new WaterbendCost(5));
|
this.getSpellAbility().addCost(new WaterbendCost(5));
|
||||||
this.addAbility(new SimpleStaticAbility(
|
this.addAbility(new SimpleStaticAbility(
|
||||||
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {5}")
|
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {5}")
|
||||||
));
|
).setRuleAtTheTop(true));
|
||||||
|
|
||||||
// Return up to two target creatures to their owners' hands. Draw two cards.
|
// Return up to two target creatures to their owners' hands. Draw two cards.
|
||||||
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
|
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
package mage.cards.w;
|
package mage.cards.w;
|
||||||
|
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.costs.common.WaterbendXCost;
|
import mage.abilities.costs.common.WaterbendXCost;
|
||||||
import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect;
|
import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect;
|
||||||
|
import mage.abilities.effects.common.InfoEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
import mage.target.targetadjustment.XTargetsCountAdjuster;
|
import mage.target.targetadjustment.XTargetsCountAdjuster;
|
||||||
|
|
||||||
|
|
@ -23,6 +26,9 @@ public final class WaterbendersRestoration extends CardImpl {
|
||||||
|
|
||||||
// As an additional cost to cast this spell, waterbend {X}.
|
// As an additional cost to cast this spell, waterbend {X}.
|
||||||
this.getSpellAbility().addCost(new WaterbendXCost());
|
this.getSpellAbility().addCost(new WaterbendXCost());
|
||||||
|
this.addAbility(new SimpleStaticAbility(
|
||||||
|
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {X}")
|
||||||
|
).setRuleAtTheTop(true));
|
||||||
|
|
||||||
// Exile X target creatures you control. Return those cards to the battlefield under their owner's control at the beginning of the next end step.
|
// Exile X target creatures you control. Return those cards to the battlefield under their owner's control at the beginning of the next end step.
|
||||||
this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect()
|
this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect()
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.costs.*;
|
import mage.abilities.costs.*;
|
||||||
import mage.abilities.costs.common.PayLifeCost;
|
import mage.abilities.costs.common.PayLifeCost;
|
||||||
import mage.abilities.costs.common.WaterbendCost;
|
import mage.abilities.costs.common.WaterbendCost;
|
||||||
|
import mage.abilities.costs.common.WaterbendXCost;
|
||||||
import mage.abilities.costs.mana.*;
|
import mage.abilities.costs.mana.*;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
|
|
@ -814,54 +815,59 @@ public abstract class AbilityImpl implements Ability {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (variableManaCost != null) {
|
if (variableManaCost == null) {
|
||||||
if (!variableManaCost.isPaid()) { // should only happen for human players
|
return variableManaCost;
|
||||||
int xValue;
|
|
||||||
if (!noMana || variableManaCost.getCostType().canUseAnnounceOnFreeCast()) {
|
|
||||||
if (variableManaCost.wasAnnounced()) {
|
|
||||||
// announce by rules
|
|
||||||
xValue = variableManaCost.getAmount();
|
|
||||||
} else {
|
|
||||||
// announce by player
|
|
||||||
xValue = controller.announceX(variableManaCost.getMinX(), variableManaCost.getMaxX(),
|
|
||||||
"Announce the value for " + variableManaCost.getText(), game, this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int amountMana = xValue * variableManaCost.getXInstancesCount();
|
|
||||||
StringBuilder manaString = threadLocalBuilder.get();
|
|
||||||
if (variableManaCost.getFilter() == null || variableManaCost.getFilter().isGeneric()) {
|
|
||||||
manaString.append('{').append(amountMana).append('}');
|
|
||||||
} else {
|
|
||||||
String manaSymbol = null;
|
|
||||||
if (variableManaCost.getFilter().isBlack()) {
|
|
||||||
if (variableManaCost.getFilter().isRed()) {
|
|
||||||
manaSymbol = "B/R";
|
|
||||||
} else {
|
|
||||||
manaSymbol = "B";
|
|
||||||
}
|
|
||||||
} else if (variableManaCost.getFilter().isRed()) {
|
|
||||||
manaSymbol = "R";
|
|
||||||
} else if (variableManaCost.getFilter().isBlue()) {
|
|
||||||
manaSymbol = "U";
|
|
||||||
} else if (variableManaCost.getFilter().isGreen()) {
|
|
||||||
manaSymbol = "G";
|
|
||||||
} else if (variableManaCost.getFilter().isWhite()) {
|
|
||||||
manaSymbol = "W";
|
|
||||||
}
|
|
||||||
if (manaSymbol == null) {
|
|
||||||
throw new UnsupportedOperationException("ManaFilter is not supported: " + this);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < amountMana; i++) {
|
|
||||||
manaString.append('{').append(manaSymbol).append('}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addManaCostsToPay(new ManaCostsImpl<>(manaString.toString()));
|
|
||||||
getManaCostsToPay().setX(xValue, amountMana);
|
|
||||||
setCostsTag("X", xValue);
|
|
||||||
}
|
|
||||||
variableManaCost.setPaid();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (variableManaCost.isPaid()) {
|
||||||
|
return variableManaCost;
|
||||||
|
} // should only happen for human players
|
||||||
|
int xValue;
|
||||||
|
if (!noMana || variableManaCost.getCostType().canUseAnnounceOnFreeCast()) {
|
||||||
|
if (variableManaCost.wasAnnounced()) {
|
||||||
|
// announce by rules
|
||||||
|
xValue = variableManaCost.getAmount();
|
||||||
|
} else {
|
||||||
|
// announce by player
|
||||||
|
xValue = controller.announceX(variableManaCost.getMinX(), variableManaCost.getMaxX(),
|
||||||
|
"Announce the value for " + variableManaCost.getText(), game, this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int amountMana = xValue * variableManaCost.getXInstancesCount();
|
||||||
|
StringBuilder manaString = threadLocalBuilder.get();
|
||||||
|
if (!(variableManaCost instanceof WaterbendXCost)) {
|
||||||
|
if (variableManaCost.getFilter() == null || variableManaCost.getFilter().isGeneric()) {
|
||||||
|
manaString.append('{').append(amountMana).append('}');
|
||||||
|
} else {
|
||||||
|
String manaSymbol;
|
||||||
|
if (variableManaCost.getFilter().isBlack()) {
|
||||||
|
if (variableManaCost.getFilter().isRed()) {
|
||||||
|
manaSymbol = "B/R";
|
||||||
|
} else {
|
||||||
|
manaSymbol = "B";
|
||||||
|
}
|
||||||
|
} else if (variableManaCost.getFilter().isRed()) {
|
||||||
|
manaSymbol = "R";
|
||||||
|
} else if (variableManaCost.getFilter().isBlue()) {
|
||||||
|
manaSymbol = "U";
|
||||||
|
} else if (variableManaCost.getFilter().isGreen()) {
|
||||||
|
manaSymbol = "G";
|
||||||
|
} else if (variableManaCost.getFilter().isWhite()) {
|
||||||
|
manaSymbol = "W";
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("ManaFilter is not supported: " + this);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < amountMana; i++) {
|
||||||
|
manaString.append('{').append(manaSymbol).append('}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addManaCostsToPay(new ManaCostsImpl<>(manaString.toString()));
|
||||||
|
} else {
|
||||||
|
addManaCostsToPay(new WaterbendCost(amountMana));
|
||||||
|
}
|
||||||
|
getManaCostsToPay().setX(xValue, amountMana);
|
||||||
|
setCostsTag("X", xValue);
|
||||||
|
}
|
||||||
|
variableManaCost.setPaid();
|
||||||
|
|
||||||
return variableManaCost;
|
return variableManaCost;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ import mage.abilities.costs.mana.GenericManaCost;
|
||||||
* (usually because the waterbend cost itself is an additional cost), the alternate method to pay for mana
|
* (usually because the waterbend cost itself is an additional cost), the alternate method to pay for mana
|
||||||
* described in rule 701.67a may be used only to pay for the amount of generic mana in the waterbend cost,
|
* described in rule 701.67a may be used only to pay for the amount of generic mana in the waterbend cost,
|
||||||
* even if the total cost to cast that spell or activate that ability includes other generic mana components.
|
* even if the total cost to cast that spell or activate that ability includes other generic mana components.
|
||||||
|
* <p>
|
||||||
|
* If you need Waterbend {X} then use {@link WaterbendXCost}
|
||||||
|
* If using as an additional cost for a spell, add an ability with an InfoEffect for proper text generation (see WaterWhip)
|
||||||
*
|
*
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,23 @@
|
||||||
package mage.abilities.costs.common;
|
package mage.abilities.costs.common;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.costs.VariableCostType;
|
||||||
import mage.abilities.costs.Cost;
|
import mage.abilities.costs.mana.VariableManaCost;
|
||||||
import mage.abilities.costs.CostImpl;
|
|
||||||
import mage.game.Game;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Implement properly
|
* Used for Waterbend {X} costs, otherwise use {@link WaterbendCost}
|
||||||
|
* If using as an additional cost for a spell, add an ability with an InfoEffect for proper text generation (see WaterbendersRestoration)
|
||||||
*
|
*
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public class WaterbendXCost extends CostImpl {
|
public class WaterbendXCost extends VariableManaCost {
|
||||||
|
|
||||||
public WaterbendXCost() {
|
public WaterbendXCost() {
|
||||||
super();
|
this(0);
|
||||||
this.text = "waterbend {X}";
|
}
|
||||||
|
|
||||||
|
public WaterbendXCost(int minX) {
|
||||||
|
super(VariableCostType.NORMAL);
|
||||||
|
this.setMinX(minX);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WaterbendXCost(final WaterbendXCost cost) {
|
private WaterbendXCost(final WaterbendXCost cost) {
|
||||||
|
|
@ -29,12 +30,7 @@ public class WaterbendXCost extends CostImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
public String getText() {
|
||||||
return false;
|
return "waterbend {X}";
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue