[STX] Implemented Professor Onyx

This commit is contained in:
Evan Kranzler 2021-03-22 19:25:55 -04:00
parent aa527ea8b2
commit df866f858e
4 changed files with 192 additions and 0 deletions

View file

@ -0,0 +1,146 @@
package mage.cards.p;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.MagecraftAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.*;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetDiscard;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ProfessorOnyx extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent(
"a creature with the greatest power among creatures that player controls"
);
static {
filter.add(ProfessorOnyxPredicate.instance);
}
public ProfessorOnyx(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{B}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.LILIANA);
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// Magecraft Whenever you cast or copy an instant or sorcery spell, each opponent loses 2 life and you gain 2 life.
Ability ability = new MagecraftAbility(new LoseLifeOpponentsEffect(2), false);
ability.addEffect(new GainLifeEffect(2).concatBy("and"));
this.addAbility(ability);
// +1: You lose 1 life. Look at the top three cards of your library. Put one of them into your hand and the rest into your graveyard.
ability = new LoyaltyAbility(new LoseLifeSourceControllerEffect(1), 1);
ability.addEffect(new LookLibraryAndPickControllerEffect(
StaticValue.get(3), false, StaticValue.get(1), StaticFilters.FILTER_CARD,
Zone.GRAVEYARD, false, false, false, Zone.HAND, false
).setText("Look at the top three cards of your library. Put one of them into your hand and the rest into your graveyard"));
this.addAbility(ability);
// 3: Each opponent sacrifices a creature with the greatest power among creatures that player controls.
this.addAbility(new LoyaltyAbility(new SacrificeOpponentsEffect(filter), -3));
// 8: Each opponent may discard a card. If they don't, they lose 3 life. Repeat this process six more times.
this.addAbility(new LoyaltyAbility(new ProfessorOnyxEffect(), -8));
}
private ProfessorOnyx(final ProfessorOnyx card) {
super(card);
}
@Override
public ProfessorOnyx copy() {
return new ProfessorOnyx(this);
}
}
enum ProfessorOnyxPredicate implements Predicate<Permanent> {
instance;
@Override
public boolean apply(Permanent input, Game game) {
return input.getPower().getValue()
>= game
.getBattlefield()
.getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE,
input.getControllerId(), game
)
.stream()
.filter(Objects::nonNull)
.map(MageObject::getPower)
.mapToInt(MageInt::getValue)
.max()
.orElse(Integer.MIN_VALUE);
}
}
class ProfessorOnyxEffect extends OneShotEffect {
ProfessorOnyxEffect() {
super(Outcome.Benefit);
staticText = "each opponent may discard a card. If they don't, " +
"they lose 3 life. Repeat this process six more times";
}
private ProfessorOnyxEffect(final ProfessorOnyxEffect effect) {
super(effect);
}
@Override
public ProfessorOnyxEffect copy() {
return new ProfessorOnyxEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (int i = 0; i < 6; i++) {
Map<UUID, Card> playerMap = new HashMap<>();
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player player = game.getPlayer(playerId);
if (player == null) {
continue;
}
TargetDiscard target = new TargetDiscard(
0, 1, StaticFilters.FILTER_CARD, playerId
);
player.choose(Outcome.Discard, target, source.getSourceId(), game);
playerMap.put(playerId, game.getCard(target.getFirstTarget()));
}
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player player = game.getPlayer(playerId);
if (player == null) {
continue;
}
if (playerMap.get(playerId) == null
|| !player.discard(playerMap.get(playerId), false, source, game)) {
player.loseLife(3, game, source, false);
}
}
}
return true;
}
}

View file

@ -30,6 +30,7 @@ public final class StrixhavenSchoolOfMages extends ExpansionSet {
cards.add(new SetCardInfo("Kasmina, Enigma Sage", 196, Rarity.MYTHIC, mage.cards.k.KasminaEnigmaSage.class)); cards.add(new SetCardInfo("Kasmina, Enigma Sage", 196, Rarity.MYTHIC, mage.cards.k.KasminaEnigmaSage.class));
cards.add(new SetCardInfo("Lorehold Command", 199, Rarity.RARE, mage.cards.l.LoreholdCommand.class)); cards.add(new SetCardInfo("Lorehold Command", 199, Rarity.RARE, mage.cards.l.LoreholdCommand.class));
cards.add(new SetCardInfo("Prismari Command", 214, Rarity.RARE, mage.cards.p.PrismariCommand.class)); cards.add(new SetCardInfo("Prismari Command", 214, Rarity.RARE, mage.cards.p.PrismariCommand.class));
cards.add(new SetCardInfo("Professor Onyx", 83, Rarity.MYTHIC, mage.cards.p.ProfessorOnyx.class));
cards.add(new SetCardInfo("Quandrix Command", 217, Rarity.RARE, mage.cards.q.QuandrixCommand.class)); cards.add(new SetCardInfo("Quandrix Command", 217, Rarity.RARE, mage.cards.q.QuandrixCommand.class));
cards.add(new SetCardInfo("Silverquill Command", 232, Rarity.RARE, mage.cards.s.SilverquillCommand.class)); cards.add(new SetCardInfo("Silverquill Command", 232, Rarity.RARE, mage.cards.s.SilverquillCommand.class));
cards.add(new SetCardInfo("Witherbloom Command", 248, Rarity.RARE, mage.cards.w.WitherbloomCommand.class)); cards.add(new SetCardInfo("Witherbloom Command", 248, Rarity.RARE, mage.cards.w.WitherbloomCommand.class));

View file

@ -0,0 +1,44 @@
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;
/**
* @author TheElk801
*/
public class MagecraftAbility extends TriggeredAbilityImpl {
public MagecraftAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
}
private MagecraftAbility(final MagecraftAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.COPIED_STACKOBJECT
|| event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Spell spell = game.getSpell(event.getTargetId());
return spell != null && spell.isControlledBy(getControllerId()) && spell.isInstantOrSorcery();
}
@Override
public String getRule() {
return "<i>Magecraft</i> &mdash; Whenever you cast or copy an instant or sorcery spell, " + super.getRule();
}
@Override
public MagecraftAbility copy() {
return new MagecraftAbility(this);
}
}

View file

@ -32,6 +32,7 @@ public enum AbilityWord {
LANDFALL("Landfall"), LANDFALL("Landfall"),
LIEUTENANT("Lieutenant"), LIEUTENANT("Lieutenant"),
METALCRAFT("Metalcraft"), METALCRAFT("Metalcraft"),
MAGECRAFT("Magecraft"),
MORBID("Morbid"), MORBID("Morbid"),
PARLEY("Parley"), PARLEY("Parley"),
RADIANCE("Radiance"), RADIANCE("Radiance"),