mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 21:02:08 -08:00
implement waterbending mechanic
This commit is contained in:
parent
6906072ec4
commit
f007ebb289
14 changed files with 170 additions and 55 deletions
|
|
@ -2,8 +2,10 @@ package mage.cards.b;
|
|||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.abilities.effects.keyword.ScryEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.WardAbility;
|
||||
|
|
@ -11,6 +13,7 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -28,6 +31,9 @@ public final class BenevolentRiverSpirit extends CardImpl {
|
|||
|
||||
// As an additional cost to cast this spell, waterbend {5}.
|
||||
this.getSpellAbility().addCost(new WaterbendCost(5));
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {5}")
|
||||
));
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.costs.common.WaterbendXCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.TapTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -30,7 +30,7 @@ public final class CrashingWave extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{U}");
|
||||
|
||||
// As an additional cost to cast this spell, waterbend {X}.
|
||||
this.getSpellAbility().addCost(new WaterbendCost("{X}"));
|
||||
this.getSpellAbility().addCost(new WaterbendXCost());
|
||||
|
||||
// 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"));
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package mage.cards.f;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.costs.common.WaterbendXCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
||||
import mage.abilities.effects.common.SacrificeTargetEffect;
|
||||
|
|
@ -33,7 +34,7 @@ public final class FoggySwampVisions extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{B}");
|
||||
|
||||
// As an additional cost to cast this spell, waterbend {X}.
|
||||
this.getSpellAbility().addCost(new WaterbendCost("{X}"));
|
||||
this.getSpellAbility().addCost(new WaterbendXCost());
|
||||
|
||||
// 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());
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ package mage.cards.h;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.CostsImpl;
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.MillCardsTargetEffect;
|
||||
|
|
@ -20,6 +20,7 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.target.common.TargetOpponent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ public final class HamaTheBloodbender extends CardImpl {
|
|||
// When Hama enters, target opponent mills three cards. Exile up to one noncreature, nonland card from that player's graveyard. For as long as you control Hama, you may cast the exiled card during your turn by waterbending {X} rather than paying its mana cost, where X is its mana value.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new MillCardsTargetEffect(3));
|
||||
ability.addEffect(new HamaTheBloodbenderExileEffect());
|
||||
ability.addTarget(new TargetOpponent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -143,10 +145,9 @@ class HamaTheBloodbenderCastEffect extends AsThoughEffectImpl {
|
|||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Costs<Cost> newCosts = new CostsImpl<>();
|
||||
newCosts.add(new WaterbendCost(card.getManaValue()));
|
||||
newCosts.addAll(card.getSpellAbility().getCosts());
|
||||
player.setCastSourceIdWithAlternateMana(card.getId(), null, newCosts);
|
||||
ManaCosts<ManaCost> manaCosts = new ManaCostsImpl<>("{0}");
|
||||
manaCosts.add(new WaterbendCost(card.getManaValue()));
|
||||
player.setCastSourceIdWithAlternateMana(card.getId(), manaCosts, card.getSpellAbility().getCosts());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.ActivateIfConditionActivatedAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.MyTurnCondition;
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.costs.common.WaterbendXCost;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
|
|
@ -49,7 +49,7 @@ public final class KataraWaterTribesHope extends CardImpl {
|
|||
Ability ability = new ActivateIfConditionActivatedAbility(new SetBasePowerToughnessAllEffect(
|
||||
GetXValue.instance, GetXValue.instance, Duration.EndOfTurn,
|
||||
StaticFilters.FILTER_CONTROLLED_CREATURES
|
||||
), new WaterbendCost("{X}"), MyTurnCondition.instance);
|
||||
), new WaterbendXCost(), MyTurnCondition.instance);
|
||||
ability.addEffect(new InfoEffect("X can't be 0"));
|
||||
CardUtil.castStream(ability.getCosts(), VariableManaCost.class).forEach(cost -> cost.setMinX(1));
|
||||
this.addAbility(ability);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
package mage.cards.w;
|
||||
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -23,6 +26,9 @@ public final class WaterWhip extends CardImpl {
|
|||
|
||||
// As an additional cost to cast this spell, waterbend {5}.
|
||||
this.getSpellAbility().addCost(new WaterbendCost(5));
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {5}")
|
||||
));
|
||||
|
||||
// Return up to two target creatures to their owners' hands. Draw two cards.
|
||||
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.w;
|
||||
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.costs.common.WaterbendXCost;
|
||||
import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -22,7 +22,7 @@ public final class WaterbendersRestoration extends CardImpl {
|
|||
this.subtype.add(SubType.LESSON);
|
||||
|
||||
// As an additional cost to cast this spell, waterbend {X}.
|
||||
this.getSpellAbility().addCost(new WaterbendCost("{X}"));
|
||||
this.getSpellAbility().addCost(new WaterbendXCost());
|
||||
|
||||
// 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()
|
||||
|
|
|
|||
|
|
@ -4,15 +4,11 @@ import mage.cards.ExpansionSet;
|
|||
import mage.constants.Rarity;
|
||||
import mage.constants.SetType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class AvatarTheLastAirbender extends ExpansionSet {
|
||||
|
||||
private static final List<String> unfinished = Arrays.asList("Aang's Iceberg", "Aang, Swift Savior", "Avatar Aang", "Benevolent River Spirit", "Crashing Wave", "Flexible Waterbender", "Foggy Swamp Vinebender", "Foggy Swamp Visions", "Geyser Leaper", "Giant Koi", "Hama, the Bloodbender", "Invasion Submersible", "Katara, Bending Prodigy", "Katara, Water Tribe's Hope", "North Pole Patrol", "Ruinous Waterbending", "Secret of Bloodbending", "Spirit Water Revival", "The Legend of Kuruk", "The Unagi of Kyoshi Island", "Waterbender Ascension", "Waterbending Lesson", "Water Tribe Rallier", "Watery Grasp", "Yue, the Moon Spirit");
|
||||
private static final AvatarTheLastAirbender instance = new AvatarTheLastAirbender();
|
||||
|
||||
public static AvatarTheLastAirbender getInstance() {
|
||||
|
|
@ -430,7 +426,5 @@ public final class AvatarTheLastAirbender extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Zuko, Conflicted", 253, Rarity.RARE, mage.cards.z.ZukoConflicted.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Zuko, Conflicted", 302, Rarity.RARE, mage.cards.z.ZukoConflicted.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Zuko, Exiled Prince", 163, Rarity.UNCOMMON, mage.cards.z.ZukoExiledPrince.class));
|
||||
|
||||
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,11 @@ import mage.cards.ExpansionSet;
|
|||
import mage.constants.Rarity;
|
||||
import mage.constants.SetType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class AvatarTheLastAirbenderEternal extends ExpansionSet {
|
||||
|
||||
private static final List<String> unfinished = Arrays.asList("Katara, Seeking Revenge", "Ruthless Waterbender", "Waterbender's Restoration", "Water Whip");
|
||||
|
||||
private static final AvatarTheLastAirbenderEternal instance = new AvatarTheLastAirbenderEternal();
|
||||
|
||||
public static AvatarTheLastAirbenderEternal getInstance() {
|
||||
|
|
@ -342,7 +337,5 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Zuko, Firebending Master", 127, Rarity.MYTHIC, mage.cards.z.ZukoFirebendingMaster.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Zuko, Firebending Master", 200, Rarity.MYTHIC, mage.cards.z.ZukoFirebendingMaster.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Zuko, Seeking Honor", 150, Rarity.UNCOMMON, mage.cards.z.ZukoSeekingHonor.class));
|
||||
|
||||
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ import mage.abilities.common.EntersBattlefieldAbility;
|
|||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.costs.*;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.costs.mana.*;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
|
|
@ -25,6 +23,7 @@ import mage.choices.ChoiceHintType;
|
|||
import mage.choices.ChoiceImpl;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.command.Dungeon;
|
||||
import mage.game.command.Emblem;
|
||||
|
|
@ -39,8 +38,10 @@ import mage.game.stack.StackAbility;
|
|||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.Targets;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.targetadjustment.GenericTargetAdjuster;
|
||||
import mage.target.targetadjustment.TargetAdjuster;
|
||||
import mage.util.CardUtil;
|
||||
|
|
@ -50,6 +51,7 @@ import mage.watchers.Watcher;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
|
@ -349,6 +351,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
// Phyrexian mana symbols, the player announces whether they intend to pay 2
|
||||
// life or the corresponding colored mana cost for each of those symbols.
|
||||
AbilityImpl.handlePhyrexianCosts(game, this, this, this.getManaCostsToPay());
|
||||
AbilityImpl.handleWaterbendingCosts(game, this, this, this.getManaCostsToPay());
|
||||
|
||||
// 20241022 - 601.2b
|
||||
// Not yet included in 601.2b but this is where it will be
|
||||
|
|
@ -687,6 +690,38 @@ public abstract class AbilityImpl implements Ability {
|
|||
}
|
||||
}
|
||||
|
||||
public static void handleWaterbendingCosts(Game game, Ability source, Ability abilityToPay, ManaCosts manaCostsToPay) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int total = CardUtil
|
||||
.castStream(manaCostsToPay, WaterbendCost.class)
|
||||
.mapToInt(WaterbendCost::manaValue)
|
||||
.sum();
|
||||
if (total < 1) {
|
||||
return;
|
||||
}
|
||||
TargetPermanent target = new TargetControlledPermanent(
|
||||
0, total, StaticFilters.FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE, true
|
||||
);
|
||||
target.withChooseHint("to tap for waterbending");
|
||||
controller.choose(Outcome.Tap, target, source, game);
|
||||
Set<Permanent> permanents = target
|
||||
.getTargets()
|
||||
.stream()
|
||||
.map(game::getPermanent)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
for (Permanent permanent : permanents) {
|
||||
permanent.tap(source, game);
|
||||
}
|
||||
manaCostsToPay.removeIf(WaterbendCost.class::isInstance);
|
||||
abilityToPay.addCost(new GenericManaCost(total - permanents.size()));
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.WATERBENDED, source.getSourceId(), source, controller.getId(), total));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and pay Phyrexian style effects like replace mana by life
|
||||
* Must be called after original Phyrexian mana processing and after cost modifications, e.g. on payment
|
||||
|
|
@ -1701,15 +1736,15 @@ public abstract class AbilityImpl implements Ability {
|
|||
|
||||
@Override
|
||||
public void initSourceObjectZoneChangeCounter(Game game, boolean force) {
|
||||
if (!(this instanceof MageSingleton) && (force || sourceObjectZoneChangeCounter == 0 )) {
|
||||
if (!(this instanceof MageSingleton) && (force || sourceObjectZoneChangeCounter == 0)) {
|
||||
setSourceObjectZoneChangeCounter(getCurrentSourceObjectZoneChangeCounter(game));
|
||||
}
|
||||
}
|
||||
|
||||
private int getCurrentSourceObjectZoneChangeCounter(Game game){
|
||||
private int getCurrentSourceObjectZoneChangeCounter(Game game) {
|
||||
int zcc = game.getState().getZoneChangeCounter(getSourceId());
|
||||
Permanent p = game.getPermanentEntering(getSourceId());
|
||||
if (p != null && !(p instanceof PermanentToken)){
|
||||
if (p != null && !(p instanceof PermanentToken)) {
|
||||
// If the triggered ability triggered while the permanent is entering the battlefield
|
||||
// then add 1 zcc so that it triggers as if the permanent was already on the battlefield
|
||||
// So "Enters with counters" causes "Whenever counters are placed" to trigger with battlefield zcc
|
||||
|
|
|
|||
|
|
@ -1,26 +1,24 @@
|
|||
package mage.abilities.costs.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
|
||||
/**
|
||||
* TODO: Implement properly
|
||||
* 701.67. Waterbend
|
||||
* <p>
|
||||
* 701.67a “Waterbend [cost]” means “Pay [cost]. For each generic mana in that cost,
|
||||
* you may tap an untapped artifact or creature you control rather than pay that mana.”
|
||||
* <p>
|
||||
* 701.67b If a waterbend cost is part of the total cost to cast a spell or activate an ability
|
||||
* (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,
|
||||
* even if the total cost to cast that spell or activate that ability includes other generic mana components.
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class WaterbendCost extends CostImpl {
|
||||
public class WaterbendCost extends GenericManaCost {
|
||||
|
||||
public WaterbendCost(int amount) {
|
||||
this("{" + amount + '}');
|
||||
}
|
||||
|
||||
public WaterbendCost(String mana) {
|
||||
super();
|
||||
this.text = "waterbend " + mana;
|
||||
super(amount);
|
||||
}
|
||||
|
||||
private WaterbendCost(final WaterbendCost cost) {
|
||||
|
|
@ -33,12 +31,7 @@ public class WaterbendCost extends CostImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
return false;
|
||||
public String getText() {
|
||||
return "waterbend " + super.getText();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package mage.abilities.costs.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* TODO: Implement properly
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class WaterbendXCost extends CostImpl {
|
||||
|
||||
public WaterbendXCost() {
|
||||
super();
|
||||
this.text = "waterbend {X}";
|
||||
}
|
||||
|
||||
private WaterbendXCost(final WaterbendXCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WaterbendXCost copy() {
|
||||
return new WaterbendXCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,20 +5,27 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.AbilityImpl;
|
||||
import mage.abilities.costs.*;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.costs.common.WaterbendCost;
|
||||
import mage.abilities.mana.ManaOptions;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.constants.ManaType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.ManaPool;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.Targets;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.ManaUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @param <T>
|
||||
|
|
@ -162,6 +169,7 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
|||
if (payingPlayer != null) {
|
||||
int bookmark = game.bookmarkState();
|
||||
handlePhyrexianManaCosts(ability, payingPlayer, source, game);
|
||||
handleWaterbendingCosts(ability, payingPlayer, source, game);
|
||||
if (pay(ability, game, source, payingPlayerId, false, null)) {
|
||||
game.removeBookmark(bookmark);
|
||||
return true;
|
||||
|
|
@ -195,6 +203,33 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
|||
tempCosts.pay(source, game, source, payingPlayer.getId(), false, null);
|
||||
}
|
||||
|
||||
private void handleWaterbendingCosts(Ability abilityToPay, Player payingPlayer, Ability source, Game game) {
|
||||
int total = CardUtil
|
||||
.castStream(this, WaterbendCost.class)
|
||||
.mapToInt(WaterbendCost::manaValue)
|
||||
.sum();
|
||||
if (total < 1) {
|
||||
return;
|
||||
}
|
||||
TargetPermanent target = new TargetControlledPermanent(
|
||||
0, total, StaticFilters.FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE, true
|
||||
);
|
||||
target.withChooseHint("to tap for waterbending");
|
||||
payingPlayer.choose(Outcome.Tap, target, source, game);
|
||||
Set<Permanent> permanents = target
|
||||
.getTargets()
|
||||
.stream()
|
||||
.map(game::getPermanent)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
for (Permanent permanent : permanents) {
|
||||
permanent.tap(source, game);
|
||||
}
|
||||
this.removeIf(WaterbendCost.class::isInstance);
|
||||
this.add(new GenericManaCost(total - permanents.size()));
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.WATERBENDED, source.getSourceId(), source, payingPlayer.getId(), total));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaCosts<T> getUnpaid() {
|
||||
ManaCosts<T> unpaid = new ManaCostsImpl<>();
|
||||
|
|
|
|||
|
|
@ -477,6 +477,17 @@ public final class StaticFilters {
|
|||
FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterControlledPermanent FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE = new FilterControlledPermanent("untapped artifact or creature you control");
|
||||
|
||||
static {
|
||||
FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE.add(TappedPredicate.UNTAPPED);
|
||||
FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE.add(Predicates.or(
|
||||
CardType.ARTIFACT.getPredicate(),
|
||||
CardType.CREATURE.getPredicate()
|
||||
));
|
||||
FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterControlledPermanent FILTER_CONTROLLED_ARTIFACT_OR_OTHER_CREATURE = new FilterControlledPermanent("another creature or an artifact");
|
||||
|
||||
static {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue