[M3C] Implement Rampant Frogantua

This commit is contained in:
theelk801 2025-04-29 11:42:20 -04:00
parent bcfc84f360
commit 8f472a13b8
4 changed files with 172 additions and 42 deletions

View file

@ -1,30 +1,25 @@
package mage.cards.h;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.SuspectTargetEffect;
import mage.abilities.effects.common.combat.GoadTargetEffect;
import mage.abilities.effects.common.continuous.GainControlAllUntapGainHasteEffect;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.WatcherScope;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.GoadedPredicate;
import mage.filter.predicate.permanent.SuspectedPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.watchers.Watcher;
import mage.watchers.common.PlayerLostGameWatcher;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -52,13 +47,8 @@ public final class HotPursuit extends CardImpl {
this.addAbility(ability);
// At the beginning of combat on your turn, if two or more players have lost the game, gain control of all goaded and/or suspected creatures until end of turn. Untap them. They gain haste until end of turn.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new BeginningOfCombatTriggeredAbility(
new GainControlAllUntapGainHasteEffect(filter)
), HotPursuitCondition.instance, "At the beginning of combat on your turn, " +
"if two or more players have lost the game, gain control of all goaded and/or " +
"suspected creatures until end of turn. Untap them. They gain haste until end of turn."
), new HotPursuitWatcher());
this.addAbility(new BeginningOfCombatTriggeredAbility(new GainControlAllUntapGainHasteEffect(filter))
.withInterveningIf(HotPursuitCondition.instance), new PlayerLostGameWatcher());
}
private HotPursuit(final HotPursuit card) {
@ -76,36 +66,11 @@ enum HotPursuitCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
return HotPursuitWatcher.checkCondition(game);
}
}
class HotPursuitWatcher extends Watcher {
private final Set<UUID> players = new HashSet<>();
HotPursuitWatcher() {
super(WatcherScope.GAME);
return PlayerLostGameWatcher.getCount(game) >= 2;
}
@Override
public void watch(GameEvent event, Game game) {
switch (event.getType()) {
case BEGINNING_PHASE_PRE:
if (game.getTurnNum() == 1) {
players.clear();
}
return;
case LOST:
players.add(event.getPlayerId());
}
}
static boolean checkCondition(Game game) {
return game
.getState()
.getWatcher(HotPursuitWatcher.class)
.players
.size() >= 2;
public String toString() {
return "two or more players have lost the game";
}
}

View file

@ -0,0 +1,121 @@
package mage.cards.r;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.watchers.common.PlayerLostGameWatcher;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RampantFrogantua extends CardImpl {
public RampantFrogantua(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.subtype.add(SubType.FROG);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Rampant Frogantua gets +10/+10 for each player who has lost the game.
this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(
RampantFrogantuaValue.instance, RampantFrogantuaValue.instance, Duration.WhileOnBattlefield
)), new PlayerLostGameWatcher());
// Whenever Rampant Frogantua deals combat damage to a player, you may mill that many cards. Put any number of land cards from among them onto the battlefield tapped.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new RampantFrogantuaEffect(), true));
}
private RampantFrogantua(final RampantFrogantua card) {
super(card);
}
@Override
public RampantFrogantua copy() {
return new RampantFrogantua(this);
}
}
class RampantFrogantuaEffect extends OneShotEffect {
RampantFrogantuaEffect() {
super(Outcome.Benefit);
staticText = "mill that many cards. Put any number of land cards from among them onto the battlefield tapped";
}
private RampantFrogantuaEffect(final RampantFrogantuaEffect effect) {
super(effect);
}
@Override
public RampantFrogantuaEffect copy() {
return new RampantFrogantuaEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
int amount = SavedDamageValue.MANY.calculate(game, source, this);
if (player == null || amount < 1) {
return false;
}
Cards cards = player.millCards(amount, source, game);
if (cards.isEmpty()) {
return true;
}
TargetCard target = new TargetCard(0, Integer.MAX_VALUE, Zone.ALL, StaticFilters.FILTER_CARD_LANDS);
target.withNotTarget(true);
player.choose(Outcome.DrawCard, cards, target, source, game);
player.moveCards(
new CardsImpl(target.getTargets()).getCards(game),
Zone.BATTLEFIELD, source, game, true,
false, false, null
);
return true;
}
}
enum RampantFrogantuaValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return 10 * PlayerLostGameWatcher.getCount(game);
}
@Override
public RampantFrogantuaValue copy() {
return this;
}
@Override
public String getMessage() {
return "player who has lost the game";
}
@Override
public String toString() {
return "10";
}
}

View file

@ -219,6 +219,7 @@ public final class ModernHorizons3Commander extends ExpansionSet {
cards.add(new SetCardInfo("Quandrix Campus", 366, Rarity.COMMON, mage.cards.q.QuandrixCampus.class));
cards.add(new SetCardInfo("Raging Ravine", 367, Rarity.RARE, mage.cards.r.RagingRavine.class));
cards.add(new SetCardInfo("Rampaging Baloths", 239, Rarity.MYTHIC, mage.cards.r.RampagingBaloths.class));
cards.add(new SetCardInfo("Rampant Frogantua", 66, Rarity.RARE, mage.cards.r.RampantFrogantua.class));
cards.add(new SetCardInfo("Rampant Growth", 240, Rarity.COMMON, mage.cards.r.RampantGrowth.class));
cards.add(new SetCardInfo("Ramunap Excavator", 241, Rarity.RARE, mage.cards.r.RamunapExcavator.class));
cards.add(new SetCardInfo("Razorfield Ripper", 42, Rarity.RARE, mage.cards.r.RazorfieldRipper.class));

View file

@ -0,0 +1,43 @@
package mage.watchers.common;
import mage.constants.WatcherScope;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.watchers.Watcher;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* @author TheElk801
*/
public class PlayerLostGameWatcher extends Watcher {
private final Set<UUID> players = new HashSet<>();
public PlayerLostGameWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
switch (event.getType()) {
case BEGINNING_PHASE_PRE:
if (game.getTurnNum() == 1) {
players.clear();
}
return;
case LOST:
players.add(event.getPlayerId());
}
}
public static int getCount(Game game) {
return game
.getState()
.getWatcher(PlayerLostGameWatcher.class)
.players
.size();
}
}