mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
[KHM] Implemented Cosima, God of the Voyage
This commit is contained in:
parent
af5331a9e4
commit
d056f6cec2
4 changed files with 317 additions and 22 deletions
295
Mage.Sets/src/mage/cards/c/CosimaGodOfTheVoyage.java
Normal file
295
Mage.Sets/src/mage/cards/c/CosimaGodOfTheVoyage.java
Normal file
|
@ -0,0 +1,295 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.CrewAbility;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class CosimaGodOfTheVoyage extends ModalDoubleFacesCard {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.VEHICLE, "a Vehicle you control");
|
||||
|
||||
public CosimaGodOfTheVoyage(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo,
|
||||
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{2}{U}",
|
||||
"The Omenkeel", new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "{1}{U}"
|
||||
);
|
||||
|
||||
// 1.
|
||||
// Cosima, God of the Voyage
|
||||
// Legendary Creature - God
|
||||
this.getLeftHalfCard().addSuperType(SuperType.LEGENDARY);
|
||||
this.getLeftHalfCard().setPT(new MageInt(2), new MageInt(4));
|
||||
|
||||
// At the beginning of your upkeep, you may exile Cosima. If you do, it gains "Whenever a land enters the battlefield under your control, if Cosima is exiled, you may put a voyage counter on it. If you don't, return Cosima to the battlefield with X +1/+1 counters on it and draw X cards, where X is the number of voyage counters on it.
|
||||
this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(
|
||||
new CosimaGodOfTheVoyageEffect(), TargetController.YOU, true
|
||||
));
|
||||
|
||||
// 2.
|
||||
// The Omenkeel
|
||||
// Legendary Artifact - Vehicle
|
||||
this.getRightHalfCard().addSuperType(SuperType.LEGENDARY);
|
||||
this.getRightHalfCard().setPT(new MageInt(3), new MageInt(3));
|
||||
|
||||
// Whenever a Vehicle you control deals combat damage to a player, that player exiles that many cards from the top of their library. You may play lands from among those cards for as long as they remain exiled.
|
||||
this.getRightHalfCard().addAbility(new DealsDamageToAPlayerAllTriggeredAbility(
|
||||
new TheOmenkeelEffect(), filter, false,
|
||||
SetTargetPointer.PLAYER, true, true
|
||||
));
|
||||
|
||||
// Crew 1
|
||||
this.getRightHalfCard().addAbility(new CrewAbility(1));
|
||||
}
|
||||
|
||||
private CosimaGodOfTheVoyage(final CosimaGodOfTheVoyage card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CosimaGodOfTheVoyage copy() {
|
||||
return new CosimaGodOfTheVoyage(this);
|
||||
}
|
||||
}
|
||||
|
||||
class CosimaGodOfTheVoyageEffect extends OneShotEffect {
|
||||
|
||||
CosimaGodOfTheVoyageEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "exile {this}. If you do, it gains " +
|
||||
"\"Whenever a land enters the battlefield under your control, if {this} is exiled, " +
|
||||
"you may put a voyage counter on it. If you don't, return {this} to the battlefield " +
|
||||
"with X +1/+1 counters on it and draw X cards, where X is the number of voyage counters on it.\"";
|
||||
}
|
||||
|
||||
private CosimaGodOfTheVoyageEffect(final CosimaGodOfTheVoyageEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CosimaGodOfTheVoyageEffect copy() {
|
||||
return new CosimaGodOfTheVoyageEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (player == null || permanent == null) {
|
||||
return false;
|
||||
}
|
||||
Card card = game.getCard(permanent.getId());
|
||||
player.moveCards(permanent, Zone.EXILED, source, game);
|
||||
if (card == null || game.getState().getZone(card.getId()) != Zone.EXILED) {
|
||||
return true;
|
||||
}
|
||||
game.addEffect(new CosimaGodOfTheVoyageGainAbilityEffect(new MageObjectReference(card, game)), source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CosimaGodOfTheVoyageGainAbilityEffect extends ContinuousEffectImpl {
|
||||
|
||||
private final MageObjectReference mor;
|
||||
|
||||
CosimaGodOfTheVoyageGainAbilityEffect(MageObjectReference mor) {
|
||||
super(Duration.Custom, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||
this.mor = mor;
|
||||
}
|
||||
|
||||
private CosimaGodOfTheVoyageGainAbilityEffect(final CosimaGodOfTheVoyageGainAbilityEffect effect) {
|
||||
super(effect);
|
||||
this.mor = effect.mor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CosimaGodOfTheVoyageGainAbilityEffect copy() {
|
||||
return new CosimaGodOfTheVoyageGainAbilityEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card card = mor.getCard(game);
|
||||
if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
||||
Ability ability = new CosimaGodOfTheVoyageTriggeredAbility();
|
||||
ability.setSourceId(card.getId());
|
||||
ability.setControllerId(source.getSourceId());
|
||||
game.getState().addAbility(ability, card);
|
||||
game.getState().addOtherAbility(card, ability);
|
||||
} else {
|
||||
discard();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CosimaGodOfTheVoyageTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
CosimaGodOfTheVoyageTriggeredAbility() {
|
||||
super(Zone.EXILED, new CosimaGodOfTheVoyageReturnEffect());
|
||||
}
|
||||
|
||||
private CosimaGodOfTheVoyageTriggeredAbility(final CosimaGodOfTheVoyageTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
return permanent != null && permanent.isLand() && permanent.isControlledBy(getControllerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkInterveningIfClause(Game game) {
|
||||
return game.getState().getZone(getSourceId()) == Zone.EXILED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CosimaGodOfTheVoyageTriggeredAbility copy() {
|
||||
return new CosimaGodOfTheVoyageTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a land enters the battlefield under your control, if {this} is exiled, " +
|
||||
"you may put a voyage counter on it. If you don't, return {this} to the battlefield " +
|
||||
"with X +1/+1 counters on it and draw X cards, where X is the number of voyage counters on it.";
|
||||
}
|
||||
}
|
||||
|
||||
class CosimaGodOfTheVoyageReturnEffect extends OneShotEffect {
|
||||
|
||||
CosimaGodOfTheVoyageReturnEffect() {
|
||||
super(Outcome.Benefit);
|
||||
}
|
||||
|
||||
private CosimaGodOfTheVoyageReturnEffect(final CosimaGodOfTheVoyageReturnEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CosimaGodOfTheVoyageReturnEffect copy() {
|
||||
return new CosimaGodOfTheVoyageReturnEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (player == null || card == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(outcome, "Add a voyage counter?", source, game)
|
||||
&& card.addCounters(CounterType.VOYAGE.createInstance(), player.getId(), source, game)) {
|
||||
return true;
|
||||
}
|
||||
int counterCount = card.getCounters(game).getCount(CounterType.VOYAGE);
|
||||
player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
if (counterCount < 1) {
|
||||
return true;
|
||||
}
|
||||
player.drawCards(counterCount, source, game);
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(counterCount), player.getId(), source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TheOmenkeelEffect extends OneShotEffect {
|
||||
|
||||
TheOmenkeelEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "that player exiles that many cards from the top of their library. " +
|
||||
"You may play lands from among those cards for as long as they remain exiled.";
|
||||
}
|
||||
|
||||
private TheOmenkeelEffect(final TheOmenkeelEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheOmenkeelEffect copy() {
|
||||
return new TheOmenkeelEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getFirstTarget());
|
||||
int damage = (Integer) getValue("damage");
|
||||
if (player == null || damage < 1) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, damage));
|
||||
player.moveCards(cards, Zone.EXILED, source, game);
|
||||
cards.removeIf(uuid -> game.getState().getZone(uuid) != Zone.EXILED);
|
||||
cards.removeIf(uuid -> !game.getCard(uuid).isLand());
|
||||
game.addEffect(new TheOmenkeelPlayFromExileEffect(cards, game), source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TheOmenkeelPlayFromExileEffect extends AsThoughEffectImpl {
|
||||
|
||||
private final Set<MageObjectReference> morSet = new HashSet<>();
|
||||
|
||||
TheOmenkeelPlayFromExileEffect(Cards cards, Game game) {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
this.morSet.addAll(cards.stream().map(uuid -> new MageObjectReference(uuid, game)).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
private TheOmenkeelPlayFromExileEffect(final TheOmenkeelPlayFromExileEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheOmenkeelPlayFromExileEffect copy() {
|
||||
return new TheOmenkeelPlayFromExileEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (!source.isControlledBy(affectedControllerId)
|
||||
|| game.getState().getZone(sourceId) != Zone.EXILED) {
|
||||
return false;
|
||||
}
|
||||
Card card = game.getCard(sourceId);
|
||||
return card != null
|
||||
&& card.isLand()
|
||||
&& morSet.stream().anyMatch(mor -> mor.refersTo(card, game));
|
||||
}
|
||||
}
|
|
@ -91,6 +91,7 @@ public final class Kaldheim extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Cleaving Reaper", 376, Rarity.RARE, mage.cards.c.CleavingReaper.class));
|
||||
cards.add(new SetCardInfo("Codespell Cleric", 7, Rarity.COMMON, mage.cards.c.CodespellCleric.class));
|
||||
cards.add(new SetCardInfo("Colossal Plow", 236, Rarity.UNCOMMON, mage.cards.c.ColossalPlow.class));
|
||||
cards.add(new SetCardInfo("Cosima, God of the Voyage", 50, Rarity.RARE, mage.cards.c.CosimaGodOfTheVoyage.class));
|
||||
cards.add(new SetCardInfo("Cosmos Elixir", 237, Rarity.RARE, mage.cards.c.CosmosElixir.class));
|
||||
cards.add(new SetCardInfo("Craven Hulk", 127, Rarity.COMMON, mage.cards.c.CravenHulk.class));
|
||||
cards.add(new SetCardInfo("Crippling Fear", 82, Rarity.RARE, mage.cards.c.CripplingFear.class));
|
||||
|
|
|
@ -58,30 +58,28 @@ public class DealsDamageToAPlayerAllTriggeredAbility extends TriggeredAbilityImp
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (!onlyCombat || ((DamagedPlayerEvent) event).isCombatDamage()) {
|
||||
Permanent permanent = game.getPermanent(event.getSourceId());
|
||||
if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setValue("damage", event.getAmount());
|
||||
effect.setValue("sourceId", event.getSourceId());
|
||||
if (affectsDefendingPlayer) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
continue;
|
||||
}
|
||||
switch (setTargetPointer) {
|
||||
case PLAYER:
|
||||
effect.setTargetPointer(new FixedTarget(permanent.getControllerId()));
|
||||
break;
|
||||
case PERMANENT:
|
||||
effect.setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game)));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
if (onlyCombat && !((DamagedPlayerEvent) event).isCombatDamage()) {
|
||||
return false;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(event.getSourceId());
|
||||
if (permanent == null || !filter.match(permanent, getSourceId(), getControllerId(), game)) {
|
||||
return false;
|
||||
}
|
||||
this.getEffects().setValue("damage", event.getAmount());
|
||||
this.getEffects().setValue("sourceId", event.getSourceId());
|
||||
if (affectsDefendingPlayer) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
} else {
|
||||
switch (setTargetPointer) {
|
||||
case PLAYER:
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId()));
|
||||
break;
|
||||
case PERMANENT:
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -164,6 +164,7 @@ public enum CounterType {
|
|||
VIGILANCE("vigilance"),
|
||||
VITALITY("vitality"),
|
||||
VORTEX("vortex"),
|
||||
VOYAGE("voyage"),
|
||||
WAGE("wage"),
|
||||
WINCH("winch"),
|
||||
WIND("wind"),
|
||||
|
|
Loading…
Reference in a new issue