[FIN] Implement Sahagin

This commit is contained in:
theelk801 2025-05-14 21:59:11 -04:00
parent 181a3306a6
commit 34c4eebd44
10 changed files with 138 additions and 109 deletions

View file

@ -3,7 +3,7 @@ package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SpellCastOpponentNoManaSpentTriggeredAbility;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
@ -12,23 +12,19 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.*;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
* @author Susucr
*/
public final class BoromirWardenOfTheTower extends CardImpl {
public BoromirWardenOfTheTower(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
@ -39,12 +35,15 @@ public final class BoromirWardenOfTheTower extends CardImpl {
this.addAbility(VigilanceAbility.getInstance());
// Whenever an opponent casts a spell, if no mana was spent to cast it, counter that spell.
this.addAbility(new SpellCastOpponentNoManaSpentTriggeredAbility(new CounterTargetEffect().setText("counter that spell")));
this.addAbility(new SpellCastOpponentTriggeredAbility(
Zone.BATTLEFIELD, new CounterTargetEffect(),
StaticFilters.FILTER_SPELL_NO_MANA_SPENT, false, true
));
// Sacrifice Boromir, Warden of the Tower: Creatures you control gain indestructible until end of turn. The Ring tempts you.
Ability ability = new SimpleActivatedAbility(new GainAbilityAllEffect(
IndestructibleAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_CONTROLLED_CREATURES, false
IndestructibleAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_CONTROLLED_CREATURES, false
), new SacrificeSourceCost());
ability.addEffect(new TheRingTemptsYouEffect());
this.addAbility(ability);

View file

@ -1,11 +1,10 @@
package mage.cards.l;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastOpponentNoManaSpentTriggeredAbility;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.cards.Card;
@ -24,13 +23,12 @@ import java.util.List;
import java.util.UUID;
/**
*
* @author NinthWorld
*/
public final class LaviniaAzoriusRenegade extends CardImpl {
public LaviniaAzoriusRenegade(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.supertype.add(SuperType.LEGENDARY);
@ -42,7 +40,10 @@ public final class LaviniaAzoriusRenegade extends CardImpl {
this.addAbility(new SimpleStaticAbility(new LaviniaAzoriusRenegadeReplacementEffect()));
// Whenever an opponent casts a spell, if no mana was spent to cast it, counter that spell.
this.addAbility(new SpellCastOpponentNoManaSpentTriggeredAbility(new CounterTargetEffect().setText("counter that spell")));
this.addAbility(new SpellCastOpponentTriggeredAbility(
Zone.BATTLEFIELD, new CounterTargetEffect(),
StaticFilters.FILTER_SPELL_NO_MANA_SPENT, false, true
));
}
private LaviniaAzoriusRenegade(final LaviniaAzoriusRenegade card) {
@ -96,7 +97,7 @@ class LaviniaAzoriusRenegadeReplacementEffect extends ContinuousRuleModifyingEff
private int getLandCount(Ability source, GameEvent event, Game game) {
int landCount = 0;
UUID playerId = event.getPlayerId();
if(playerId != null) {
if (playerId != null) {
List<Permanent> permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, playerId, source, game);
for (Permanent permanent : permanents) {
if (permanent.isControlledBy(playerId)) {

View file

@ -1,49 +1,52 @@
package mage.cards.m;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastOpponentNoManaSpentTriggeredAbility;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.condition.common.OnOpponentsTurnCondition;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.CreateTokenAllEffect;
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.AddCardSubtypeAllEffect;
import mage.abilities.effects.common.continuous.SetBasePowerToughnessAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
import mage.game.permanent.token.ElephantToken;
import java.util.UUID;
/**
*
* @author Jmlundeen
*/
public final class MarchOfTheWorldOoze extends CardImpl {
public static final FilterSpell filter = new FilterSpell("a spell, if it's not their turn");
static {
filter.add(TargetController.INACTIVE.getControllerPredicate());
}
public MarchOfTheWorldOoze(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}{G}{G}");
// Creatures you control have base power and toughness 6/6 and are Oozes in addition to their other types.
Ability ability = new SimpleStaticAbility(new SetBasePowerToughnessAllEffect(
6, 6, Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURE));
ability.addEffect(new AddCardSubtypeAllEffect(StaticFilters.FILTER_CONTROLLED_CREATURE, SubType.OOZE, null)
.concatBy("and"));
6, 6, Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURE
));
ability.addEffect(new AddCardSubtypeAllEffect(
StaticFilters.FILTER_CONTROLLED_CREATURE, SubType.OOZE, null
).concatBy("and"));
this.addAbility(ability);
// Whenever an opponent casts a spell, if it's not their turn, you create a 3/3 green Elephant creature token.
Ability ability2 = new SpellCastOpponentTriggeredAbility(new CreateTokenEffect(new ElephantToken())
.setText("you create a 3/3 green Elephant creature token"),
filter, false);
Ability ability2 = new SpellCastOpponentTriggeredAbility(
new CreateTokenEffect(new ElephantToken())
.setText("you create a 3/3 green Elephant creature token"),
filter, false
);
this.addAbility(ability2);
}

View file

@ -17,11 +17,10 @@ import mage.constants.*;
import mage.filter.FilterSpell;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.mageobject.ManaSpentToCastPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.common.ManaPaidSourceWatcher;
import java.util.UUID;
@ -32,12 +31,12 @@ public final class RaggadraggaGoregutsBoss extends CardImpl {
private static final FilterCreaturePermanent filter
= new FilterCreaturePermanent("creature you control with a mana ability");
private static final FilterSpell filter2 = new FilterSpell();
private static final FilterSpell filter2 = new FilterSpell("a spell, if at least seven mana was spent to cast it");
static {
filter.add(TargetController.YOU.getOwnerPredicate());
filter.add(RaggadraggaGoregutsBossCreaturePredicate.instance);
filter2.add(RaggadraggaGoregutsBossSpellPredicate.instance);
filter2.add(new ManaSpentToCastPredicate(ComparisonType.MORE_THAN, 6));
}
public RaggadraggaGoregutsBoss(UUID ownerId, CardSetInfo setInfo) {
@ -61,9 +60,7 @@ public final class RaggadraggaGoregutsBoss extends CardImpl {
));
// Whenever you cast a spell, if at least seven mana was spent to cast it, untap target creature. It gets +7/+7 and gains trample until end of turn.
Ability ability = new SpellCastControllerTriggeredAbility(
new UntapTargetEffect(), filter2, false
).setTriggerPhrase("Whenever you cast a spell, if at least seven mana was spent to cast it, ");
Ability ability = new SpellCastControllerTriggeredAbility(new UntapTargetEffect(), filter2, false);
ability.addEffect(new BoostTargetEffect(7, 7).setText("It gets +7/+7"));
ability.addEffect(new GainAbilityTargetEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn
@ -90,12 +87,3 @@ enum RaggadraggaGoregutsBossCreaturePredicate implements Predicate<Permanent> {
return input.getAbilities(game).stream().anyMatch(ManaAbility.class::isInstance);
}
}
enum RaggadraggaGoregutsBossSpellPredicate implements Predicate<StackObject> {
instance;
@Override
public boolean apply(StackObject input, Game game) {
return ManaPaidSourceWatcher.getTotalPaid(input.getId(), game) >= 7;
}
}

View file

@ -0,0 +1,48 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Sahagin extends CardImpl {
public Sahagin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.MERFOLK);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
// Whenever you cast a noncreature spell, if at least four mana was spent to cast it, put a +1/+1 counter on this creature and it can't be blocked this turn.
Ability ability = new SpellCastControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
StaticFilters.FILTER_NONCREATURE_SPELL_FOUR_MANA_SPENT, false
);
ability.addEffect(new CantBeBlockedSourceEffect(Duration.EndOfTurn).setText("and it can't be blocked this turn"));
this.addAbility(ability);
}
private Sahagin(final Sahagin card) {
super(card);
}
@Override
public Sahagin copy() {
return new Sahagin(this);
}
}

View file

@ -1,10 +1,8 @@
package mage.cards.v;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SpellCastNoManaSpentTriggeredAbility;
import mage.abilities.common.SpellCastAllTriggeredAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
@ -13,20 +11,23 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.constants.SetTargetPointer;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
* @author grimreap124
*/
public final class VexingBauble extends CardImpl {
public VexingBauble(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[] { CardType.ARTIFACT }, "{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// Whenever a player casts a spell, if no mana was spent to cast it, counter that spell.
this.addAbility(new SpellCastNoManaSpentTriggeredAbility(
new CounterTargetEffect().setText("counter that spell")));
this.addAbility(new SpellCastAllTriggeredAbility(
new CounterTargetEffect(), StaticFilters.FILTER_SPELL_NO_MANA_SPENT, false, SetTargetPointer.SPELL
));
// {1}, {T}, Sacrifice Vexing Bauble: Draw a card.
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1),
@ -34,7 +35,6 @@ public final class VexingBauble extends CardImpl {
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
;
}
private VexingBauble(final VexingBauble card) {

View file

@ -180,6 +180,7 @@ public final class FinalFantasy extends ExpansionSet {
cards.add(new SetCardInfo("Rosa, Resolute White Mage", 555, Rarity.RARE, mage.cards.r.RosaResoluteWhiteMage.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sage's Nouliths", 582, Rarity.COMMON, mage.cards.s.SagesNouliths.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sage's Nouliths", 70, Rarity.COMMON, mage.cards.s.SagesNouliths.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sahagin", 71, Rarity.COMMON, mage.cards.s.Sahagin.class));
cards.add(new SetCardInfo("Samurai's Katana", 154, Rarity.UNCOMMON, mage.cards.s.SamuraisKatana.class));
cards.add(new SetCardInfo("Sazh's Chocobo", 200, Rarity.UNCOMMON, mage.cards.s.SazhsChocobo.class));
cards.add(new SetCardInfo("Sephiroth's Intervention", 116, Rarity.COMMON, mage.cards.s.SephirothsIntervention.class));

View file

@ -1,48 +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.stack.Spell;
import mage.target.targetpointer.FixedTarget;
/**
* @author Susucr
*/
public class SpellCastOpponentNoManaSpentTriggeredAbility extends TriggeredAbilityImpl {
public SpellCastOpponentNoManaSpentTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect, false);
this.setTriggerPhrase("Whenever an opponent casts a spell, if no mana was spent to cast it, ");
}
protected SpellCastOpponentNoManaSpentTriggeredAbility(final SpellCastOpponentNoManaSpentTriggeredAbility ability) {
super(ability);
}
@Override
public SpellCastOpponentNoManaSpentTriggeredAbility copy() {
return new SpellCastOpponentNoManaSpentTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && spell.getStackAbility().getManaCostsToPay().getUsedManaToPay().count() == 0) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
}
return true;
}
}
return false;
}
}

View file

@ -1,10 +1,7 @@
package mage.filter;
import mage.ObjectColor;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.common.*;
import mage.filter.predicate.Predicates;
@ -1045,6 +1042,21 @@ public final class StaticFilters {
FILTER_SPELL_KICKED_A.setLockedFilter(true);
}
public static final FilterSpell FILTER_SPELL_NO_MANA_SPENT = new FilterSpell("a spell, if no mana was spent to cast it");
static {
FILTER_SPELL_NO_MANA_SPENT.add(new ManaSpentToCastPredicate(ComparisonType.EQUAL_TO, 0));
FILTER_SPELL_NO_MANA_SPENT.setLockedFilter(true);
}
public static final FilterSpell FILTER_NONCREATURE_SPELL_FOUR_MANA_SPENT = new FilterSpell("a noncreature spell, if at least four mana was spent to cast it");
static {
FILTER_NONCREATURE_SPELL_FOUR_MANA_SPENT.add(Predicates.not(CardType.CREATURE.getPredicate()));
FILTER_NONCREATURE_SPELL_FOUR_MANA_SPENT.add(new ManaSpentToCastPredicate(ComparisonType.MORE_THAN, 3));
FILTER_NONCREATURE_SPELL_FOUR_MANA_SPENT.setLockedFilter(true);
}
public static final FilterPermanent FILTER_PERMANENT_TOKEN = new FilterPermanent("token");
static {

View file

@ -0,0 +1,25 @@
package mage.filter.predicate.mageobject;
import mage.constants.ComparisonType;
import mage.filter.predicate.IntComparePredicate;
import mage.game.stack.StackObject;
/**
* @author TheElk801
*/
public class ManaSpentToCastPredicate extends IntComparePredicate<StackObject> {
public ManaSpentToCastPredicate(ComparisonType type, int value) {
super(type, value);
}
@Override
protected int getInputValue(StackObject input) {
return input.getStackAbility().getManaCostsToPay().getUsedManaToPay().count();
}
@Override
public String toString() {
return "ManaSpent" + super.toString();
}
}