mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 12:52:06 -08:00
Merge branch 'master' of https://github.com/magefree/mage
This commit is contained in:
commit
28d9d64112
55 changed files with 1136 additions and 217 deletions
|
|
@ -30,7 +30,6 @@ import mage.target.targetpointer.FixedTarget;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Colin Redman
|
||||
*/
|
||||
public class AminatouTheFateshifter extends CardImpl {
|
||||
|
|
@ -53,9 +52,9 @@ public class AminatouTheFateshifter extends CardImpl {
|
|||
Ability ability = new LoyaltyAbility(new AminatouPlusEffect(), +1);
|
||||
this.addAbility(ability);
|
||||
|
||||
// -1: Exile another target permanent you own, then return it to the battlefield under your control.
|
||||
// −1: Exile another target permanent you own, then return it to the battlefield under your control.
|
||||
ability = new LoyaltyAbility(new ExileTargetForSourceEffect(), -1);
|
||||
ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect(true));
|
||||
ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect(false));
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public final class ArlinnVoiceOfThePack extends CardImpl {
|
|||
this.addAbility(new SimpleStaticAbility(new ArlinnVoiceOfThePackReplacementEffect()));
|
||||
|
||||
// -2: Create a 2/2 green Wolf creature token.
|
||||
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new WolfToken("WAR")), -2));
|
||||
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new WolfToken()), -2));
|
||||
}
|
||||
|
||||
private ArlinnVoiceOfThePack(final ArlinnVoiceOfThePack card) {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public final class BagOfDevouring extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{B}");
|
||||
|
||||
// Whenever you sacrifice another nontoken artifact or creature, exile it.
|
||||
this.addAbility(new SacrificePermanentTriggeredAbility(new ExileTargetForSourceEffect(), filter, true));
|
||||
this.addAbility(new SacrificePermanentTriggeredAbility(new ExileTargetForSourceEffect().setText("exile it"), filter, true));
|
||||
|
||||
// {2}, {T}, Sacrifice another artifact or creature: Draw a card.
|
||||
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(2));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
|
|
@ -11,7 +7,6 @@ import mage.abilities.effects.Effect;
|
|||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
|
|
@ -20,10 +15,12 @@ import mage.constants.TargetController;
|
|||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class CelestialConvergence extends CardImpl {
|
||||
|
|
@ -70,49 +67,42 @@ class CelestialConvergenceEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card sourceObject = game.getCard(source.getSourceId());
|
||||
Permanent sourcePermanent = source.getSourcePermanentOrLKI(game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (sourceObject != null
|
||||
&& controller != null
|
||||
&& sourceObject.getCounters(game).getCount(CounterType.OMEN) == 0) {
|
||||
if (sourcePermanent == null || controller == null
|
||||
|| sourcePermanent.getCounters(game).getCount(CounterType.OMEN) > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 801.14. If an effect states that a player wins the game, all of
|
||||
* that player's opponents within their range of influence lose the
|
||||
* game instead. #
|
||||
*
|
||||
* 801.15. If the effect of a spell or ability states that the game
|
||||
* is a draw, the game is a draw for that spell or ability's
|
||||
* controller and all players within their range of influence. They
|
||||
* leave the game. All remaining players continue to play the game.
|
||||
*
|
||||
*/
|
||||
List<UUID> highestLifePlayers = new ArrayList<>();
|
||||
int highLife = Integer.MIN_VALUE;
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
if (player.getLife() > highLife) {
|
||||
highestLifePlayers.clear();
|
||||
highestLifePlayers.add(player.getId());
|
||||
} else if (player.getLife() == highLife) {
|
||||
highestLifePlayers.add(player.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (highestLifePlayers.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (highestLifePlayers.size() > 1) {
|
||||
game.setDraw(controller.getId());
|
||||
} else {
|
||||
Player winner = game.getPlayer(highestLifePlayers.iterator().next());
|
||||
if (winner != null) {
|
||||
winner.won(game);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 801.14. If an effect states that a player wins the game, all of
|
||||
* that player's opponents within their range of influence lose the
|
||||
* game instead. #
|
||||
*
|
||||
* 801.15. If the effect of a spell or ability states that the game
|
||||
* is a draw, the game is a draw for that spell or ability's
|
||||
* controller and all players within their range of influence. They
|
||||
* leave the game. All remaining players continue to play the game.
|
||||
*
|
||||
*/
|
||||
Map<Integer, Set<UUID>> playerMap = new HashMap<>();
|
||||
game.getState()
|
||||
.getPlayersInRange(controller.getId(), game)
|
||||
.stream()
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(player -> playerMap.computeIfAbsent(
|
||||
player.getLife(), x -> new HashSet<>()
|
||||
).add(player.getId()));
|
||||
int highLife = playerMap.keySet().stream().mapToInt(x -> x).max().orElse(Integer.MIN_VALUE);
|
||||
if (playerMap.get(highLife).size() > 1) {
|
||||
game.setDraw(controller.getId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
Player winner = game.getPlayer(playerMap.get(highLife).iterator().next());
|
||||
if (winner != null) {
|
||||
winner.won(game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
123
Mage.Sets/src/mage/cards/h/HellishRebuke.java
Normal file
123
Mage.Sets/src/mage/cards/h/HellishRebuke.java
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package mage.cards.h;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
|
||||
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.watchers.common.SpellsCastWatcher;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class HellishRebuke extends CardImpl {
|
||||
|
||||
public HellishRebuke(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}");
|
||||
|
||||
// Until end of turn, permanents your opponents control gain "When this permanent deals damage to the player who cast Hellish Rebuke, sacrifice this permanent. You lose 2 life."
|
||||
this.getSpellAbility().addEffect(new HellishRebukeEffect());
|
||||
this.getSpellAbility().addWatcher(new SpellsCastWatcher());
|
||||
}
|
||||
|
||||
private HellishRebuke(final HellishRebuke card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HellishRebuke copy() {
|
||||
return new HellishRebuke(this);
|
||||
}
|
||||
}
|
||||
|
||||
class HellishRebukeEffect extends OneShotEffect {
|
||||
|
||||
HellishRebukeEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "until end of turn, permanents your opponents control gain " +
|
||||
"\"When this permanent deals damage to the player who cast {this}, " +
|
||||
"sacrifice this permanent. You lose 2 life.\"";
|
||||
}
|
||||
|
||||
private HellishRebukeEffect(final HellishRebukeEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HellishRebukeEffect copy() {
|
||||
return new HellishRebukeEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
MageObject mageObject = source.getSourceObject(game);
|
||||
game.addEffect(new GainAbilityAllEffect(
|
||||
new HellishRebukeTriggeredAbility(source, game),
|
||||
Duration.EndOfTurn, StaticFilters.FILTER_OPPONENTS_PERMANENT
|
||||
), source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class HellishRebukeTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
private final String sourceName;
|
||||
private final UUID casterId;
|
||||
|
||||
HellishRebukeTriggeredAbility(Ability source, Game game) {
|
||||
super(Zone.BATTLEFIELD, new SacrificeSourceEffect());
|
||||
this.addEffect(new LoseLifeSourceControllerEffect(2));
|
||||
this.sourceName = getSourceName(source, game);
|
||||
this.casterId = getCasterId(source, game);
|
||||
}
|
||||
|
||||
private HellishRebukeTriggeredAbility(final HellishRebukeTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.sourceName = ability.sourceName;
|
||||
this.casterId = ability.casterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return event.getSourceId().equals(getSourceId()) && event.getPlayerId().equals(casterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HellishRebukeTriggeredAbility copy() {
|
||||
return new HellishRebukeTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When this permanent deals damage to the player who cast "
|
||||
+ sourceName + ", sacrifice this permanent. You lose 2 life.";
|
||||
}
|
||||
|
||||
private static final String getSourceName(Ability source, Game game) {
|
||||
MageObject object = source.getSourceObject(game);
|
||||
return object != null ? object.getName() : "Hellish Rebuke";
|
||||
}
|
||||
|
||||
private static final UUID getCasterId(Ability source, Game game) {
|
||||
SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
|
||||
return watcher.getCasterId(source, game);
|
||||
}
|
||||
}
|
||||
136
Mage.Sets/src/mage/cards/k/KarazikarTheEyeTyrant.java
Normal file
136
Mage.Sets/src/mage/cards/k/KarazikarTheEyeTyrant.java
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.common.*;
|
||||
import mage.abilities.effects.common.combat.GoadTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class KarazikarTheEyeTyrant extends CardImpl {
|
||||
|
||||
public KarazikarTheEyeTyrant(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{R}");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.BEHOLDER);
|
||||
this.power = new MageInt(5);
|
||||
this.toughness = new MageInt(5);
|
||||
|
||||
// Whenever you attack a player, tap target creature that player controls and goad it.
|
||||
this.addAbility(new KarazikarTheEyeTyrantFirstTriggeredAbility());
|
||||
|
||||
// Whenever an opponent attacks another one of your opponents, you and the attacking player each draw a card and lose 1 life.
|
||||
this.addAbility(new KarazikarTheEyeTyrantSecondTriggeredAbility());
|
||||
}
|
||||
|
||||
private KarazikarTheEyeTyrant(final KarazikarTheEyeTyrant card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KarazikarTheEyeTyrant copy() {
|
||||
return new KarazikarTheEyeTyrant(this);
|
||||
}
|
||||
}
|
||||
|
||||
class KarazikarTheEyeTyrantFirstTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
KarazikarTheEyeTyrantFirstTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new TapTargetEffect(), false);
|
||||
this.addEffect(new GoadTargetEffect());
|
||||
}
|
||||
|
||||
private KarazikarTheEyeTyrantFirstTriggeredAbility(final KarazikarTheEyeTyrantFirstTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KarazikarTheEyeTyrantFirstTriggeredAbility copy() {
|
||||
return new KarazikarTheEyeTyrantFirstTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (!isControlledBy(event.getPlayerId())) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(event.getTargetId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
FilterPermanent filter = new FilterCreaturePermanent("creature controlled by " + player.getName());
|
||||
filter.add(new ControllerIdPredicate(player.getId()));
|
||||
this.getTargets().clear();
|
||||
this.addTarget(new TargetPermanent(filter));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever you attack a player, tap target creature that player controls and goad it.";
|
||||
}
|
||||
}
|
||||
|
||||
class KarazikarTheEyeTyrantSecondTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
KarazikarTheEyeTyrantSecondTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false);
|
||||
this.addEffect(new LoseLifeSourceControllerEffect(1));
|
||||
this.addEffect(new DrawCardTargetEffect(1));
|
||||
this.addEffect(new LoseLifeTargetEffect(1));
|
||||
}
|
||||
|
||||
private KarazikarTheEyeTyrantSecondTriggeredAbility(final KarazikarTheEyeTyrantSecondTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KarazikarTheEyeTyrantSecondTriggeredAbility copy() {
|
||||
return new KarazikarTheEyeTyrantSecondTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DEFENDER_ATTACKED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Set<UUID> opponents = game.getOpponents(getControllerId());
|
||||
if (!opponents.contains(event.getPlayerId()) || !opponents.contains(event.getTargetId())) {
|
||||
return false;
|
||||
}
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever an opponent attacks another one of your opponents, " +
|
||||
"you and the attacking player each draw a card and lose 1 life.";
|
||||
}
|
||||
}
|
||||
78
Mage.Sets/src/mage/cards/k/KlauthsWill.java
Normal file
78
Mage.Sets/src/mage/cards/k/KlauthsWill.java
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.condition.common.ControlACommanderCondition;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
import mage.abilities.effects.common.DamageAllEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.AbilityPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.targetadjustment.TargetAdjuster;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class KlauthsWill extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterCreaturePermanent("creature without flying");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
|
||||
}
|
||||
|
||||
public KlauthsWill(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{R}{G}");
|
||||
|
||||
// Choose one. If you control a commander as you cast this spell, you may choose both.
|
||||
this.getSpellAbility().getModes().setChooseText(
|
||||
"Choose one. If you control a commander as you cast this spell, you may choose both."
|
||||
);
|
||||
this.getSpellAbility().getModes().setMoreCondition(ControlACommanderCondition.instance);
|
||||
|
||||
// • Breathe Flame — Klauth's Will deals X damage to each creature without flying.
|
||||
this.getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.REGULAR, filter));
|
||||
this.getSpellAbility().withFirstModeFlavorWord("Breathe Flame");
|
||||
|
||||
// • Smash Relics — Destroy up to X target artifacts and/or enchantments.
|
||||
this.getSpellAbility().addMode(new Mode(
|
||||
new DestroyTargetEffect().setText("destroy up to X target artifacts and/or enchantments")
|
||||
).withFlavorWord("Smash Relics"));
|
||||
this.getSpellAbility().setTargetAdjuster(KlauthsWillAdjuster.instance);
|
||||
}
|
||||
|
||||
private KlauthsWill(final KlauthsWill card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KlauthsWill copy() {
|
||||
return new KlauthsWill(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum KlauthsWillAdjuster implements TargetAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustTargets(Ability ability, Game game) {
|
||||
if (ability.getEffects().stream().anyMatch(DestroyTargetEffect.class::isInstance)) {
|
||||
ability.getTargets().clear();
|
||||
ability.addTarget(new TargetPermanent(
|
||||
0, ability.getManaCostsToPay().getX(),
|
||||
StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ class MaddeningHexEffect extends OneShotEffect {
|
|||
opponents.remove(player.getId());
|
||||
}
|
||||
if (!opponents.isEmpty()) {
|
||||
permanent.attachTo(RandomUtil.randomFromSet(opponents), source, game);
|
||||
permanent.attachTo(RandomUtil.randomFromCollection(opponents), source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ import mage.abilities.effects.mana.BasicManaEffect;
|
|||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
|
|
@ -94,6 +91,7 @@ class ManaCacheManaAbility extends ActivatedManaAbilityImpl {
|
|||
super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.ColorlessMana(1), new CountersSourceCount(CounterType.CHARGE)),
|
||||
new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(1)));
|
||||
this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, 0, 1));
|
||||
this.setMayActivate(TargetController.ANY);
|
||||
}
|
||||
|
||||
public ManaCacheManaAbility(final ManaCacheManaAbility ability) {
|
||||
|
|
@ -102,17 +100,15 @@ class ManaCacheManaAbility extends ActivatedManaAbilityImpl {
|
|||
|
||||
@Override
|
||||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||
if (!super.hasMoreActivationsThisTurn(game) || !(condition == null || condition.apply(game, this))) {
|
||||
// any player, but only during their turn before the end step
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null
|
||||
|| !playerId.equals(game.getActivePlayerId())
|
||||
|| !game.getStep().getType().isBefore(PhaseStep.END_TURN)) {
|
||||
return ActivationStatus.getFalse();
|
||||
}
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null && playerId.equals(game.getActivePlayerId()) && game.getStep().getType().isBefore(PhaseStep.END_TURN)) {
|
||||
if (costs.canPay(this, this, playerId, game)) {
|
||||
this.setControllerId(playerId);
|
||||
return ActivationStatus.getTrue(this, game);
|
||||
}
|
||||
}
|
||||
return ActivationStatus.getFalse();
|
||||
|
||||
return super.canActivate(playerId, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
165
Mage.Sets/src/mage/cards/n/Nihiloor.java
Normal file
165
Mage.Sets/src/mage/cards/n/Nihiloor.java
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
package mage.cards.n;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksAllTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.permanent.TappedPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class Nihiloor extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
|
||||
static {
|
||||
filter.add(TargetController.OPPONENT.getOwnerPredicate());
|
||||
}
|
||||
|
||||
public Nihiloor(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}{B}");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HORROR);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(5);
|
||||
|
||||
// When Nihiloor enters the battlefield, for each opponent, tap up to one untapped creature you control. When you do, gain control of target creature that player controls with power less than or equal to the tapped creature's power for as long as you control Nihiloor.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new NihiloorControlEffect()));
|
||||
|
||||
// Whenever you attack with a creature an opponent owns, you gain 2 life and that player loses 2 life.
|
||||
Ability ability = new AttacksAllTriggeredAbility(
|
||||
new GainLifeEffect(1), false, filter,
|
||||
SetTargetPointer.PERMANENT, false
|
||||
).setTriggerPhrase("Whenever you attack with a creature an opponent owns, ");
|
||||
ability.addEffect(new NihiloorLoseLifeEffect());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private Nihiloor(final Nihiloor card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nihiloor copy() {
|
||||
return new Nihiloor(this);
|
||||
}
|
||||
}
|
||||
|
||||
class NihiloorControlEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterPermanent filter
|
||||
= new FilterControlledCreaturePermanent("untapped creatured you control");
|
||||
|
||||
static {
|
||||
filter.add(TappedPredicate.UNTAPPED);
|
||||
}
|
||||
|
||||
private static final class NihiloorPredicate implements Predicate<Permanent> {
|
||||
private final Permanent permanent;
|
||||
private final UUID playerId;
|
||||
|
||||
private NihiloorPredicate(Permanent permanent, UUID playerId) {
|
||||
this.permanent = permanent;
|
||||
this.playerId = playerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Permanent input, Game game) {
|
||||
return input.isControlledBy(playerId)
|
||||
&& input.getPower().getValue() <= permanent.getPower().getValue();
|
||||
}
|
||||
}
|
||||
|
||||
NihiloorControlEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "for each opponent, tap up to one untapped creature you control. When you do, " +
|
||||
"gain control of target creature that player controls with power less than " +
|
||||
"or equal to the tapped creature's power for as long as you control {this}";
|
||||
}
|
||||
|
||||
private NihiloorControlEffect(final NihiloorControlEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NihiloorControlEffect copy() {
|
||||
return new NihiloorControlEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
for (UUID playerId : game.getOpponents(source.getControllerId())) {
|
||||
Player opponent = game.getPlayer(playerId);
|
||||
if (opponent == null) {
|
||||
continue;
|
||||
}
|
||||
TargetPermanent target = new TargetPermanent(0, 1, filter, true);
|
||||
target.withChooseHint("tapping a creature controlled by " + opponent.getName());
|
||||
controller.choose(outcome, target, source.getControllerId(), game);
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
if (permanent == null || !permanent.tap(source, game)) {
|
||||
continue;
|
||||
}
|
||||
FilterPermanent filter2 = new FilterPermanent(
|
||||
"creature controlled by " + opponent.getName()
|
||||
+ " with power " + permanent.getPower().getValue() + " or less"
|
||||
);
|
||||
filter2.add(new NihiloorPredicate(permanent, playerId));
|
||||
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
|
||||
new GainControlTargetEffect(Duration.Custom, true),
|
||||
false, "gain control of target creature that player controls with " +
|
||||
"power less than or equal to the tapped creature's power for as long as you control {this}"
|
||||
);
|
||||
ability.addTarget(new TargetPermanent(filter2));
|
||||
game.fireReflexiveTriggeredAbility(ability, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NihiloorLoseLifeEffect extends OneShotEffect {
|
||||
|
||||
NihiloorLoseLifeEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "you gain 2 life and that player loses 2 life";
|
||||
}
|
||||
|
||||
private NihiloorLoseLifeEffect(final NihiloorLoseLifeEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NihiloorLoseLifeEffect copy() {
|
||||
return new NihiloorLoseLifeEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getControllerId(getTargetPointer().getFirst(game, source)));
|
||||
return player != null && player.loseLife(2, game, source, false) > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -187,7 +187,10 @@ class TheBookOfVileDarknessEffect extends OneShotEffect {
|
|||
}
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (ability instanceof TriggeredAbility) {
|
||||
token.addAbility(ability.copy());
|
||||
Ability copyAbility = ability.copy();
|
||||
copyAbility.newId();
|
||||
copyAbility.setControllerId(source.getControllerId());
|
||||
token.addAbility(copyAbility);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public final class WolfSkullShaman extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// Kinship - At the beginning of your upkeep, you may look at the top card of your library. If it shares a creature type with Wolf-Skull Shaman, you may reveal it. If you do, create a 2/2 green Wolf creature token.
|
||||
this.addAbility(new KinshipAbility(new CreateTokenEffect(new WolfToken("LRW"))));
|
||||
this.addAbility(new KinshipAbility(new CreateTokenEffect(new WolfToken())));
|
||||
}
|
||||
|
||||
private WolfSkullShaman(final WolfSkullShaman card) {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class WolfcallersHowlEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
return new CreateTokenEffect(new WolfToken("C14"), count).apply(game, source);
|
||||
return new CreateTokenEffect(new WolfToken(), count).apply(game, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public final class WrensRunPackmaster extends CardImpl {
|
|||
this.addAbility(new ChampionAbility(this, SubType.ELF, false));
|
||||
|
||||
// {2}{G}: Create a 2/2 green Wolf creature token.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new WolfToken("LRW")), new ManaCostsImpl<>("{2}{G}")));
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new WolfToken()), new ManaCostsImpl<>("{2}{G}")));
|
||||
|
||||
// Each Wolf you control has deathtouch.
|
||||
Effect effect = new GainAbilityAllEffect(DeathtouchAbility.getInstance(), Duration.WhileOnBattlefield, filter);
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ public final class ForgottenRealmsCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Halimar Depths", 244, Rarity.COMMON, mage.cards.h.HalimarDepths.class));
|
||||
cards.add(new SetCardInfo("Haven of the Spirit Dragon", 245, Rarity.RARE, mage.cards.h.HavenOfTheSpiritDragon.class));
|
||||
cards.add(new SetCardInfo("Heirloom Blade", 208, Rarity.UNCOMMON, mage.cards.h.HeirloomBlade.class));
|
||||
cards.add(new SetCardInfo("Hellish Rebuke", 26, Rarity.RARE, mage.cards.h.HellishRebuke.class));
|
||||
cards.add(new SetCardInfo("Heroic Intervention", 161, Rarity.RARE, mage.cards.h.HeroicIntervention.class));
|
||||
cards.add(new SetCardInfo("Hex", 101, Rarity.RARE, mage.cards.h.Hex.class));
|
||||
cards.add(new SetCardInfo("High Market", 246, Rarity.RARE, mage.cards.h.HighMarket.class));
|
||||
|
|
@ -136,9 +137,11 @@ public final class ForgottenRealmsCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Imprisoned in the Moon", 85, Rarity.RARE, mage.cards.i.ImprisonedInTheMoon.class));
|
||||
cards.add(new SetCardInfo("Indomitable Might", 40, Rarity.RARE, mage.cards.i.IndomitableMight.class));
|
||||
cards.add(new SetCardInfo("Izzet Chemister", 130, Rarity.RARE, mage.cards.i.IzzetChemister.class));
|
||||
cards.add(new SetCardInfo("Karazikar, the Eye Tyrant", 49, Rarity.MYTHIC, mage.cards.k.KarazikarTheEyeTyrant.class));
|
||||
cards.add(new SetCardInfo("Karmic Guide", 68, Rarity.RARE, mage.cards.k.KarmicGuide.class));
|
||||
cards.add(new SetCardInfo("Kenrith's Transformation", 162, Rarity.UNCOMMON, mage.cards.k.KenrithsTransformation.class));
|
||||
cards.add(new SetCardInfo("Kindred Summons", 163, Rarity.RARE, mage.cards.k.KindredSummons.class));
|
||||
cards.add(new SetCardInfo("Klauth's Will", 51, Rarity.RARE, mage.cards.k.KlauthsWill.class));
|
||||
cards.add(new SetCardInfo("Klauth, Unrivaled Ancient", 50, Rarity.MYTHIC, mage.cards.k.KlauthUnrivaledAncient.class));
|
||||
cards.add(new SetCardInfo("Knight of Autumn", 187, Rarity.RARE, mage.cards.k.KnightOfAutumn.class));
|
||||
cards.add(new SetCardInfo("Light Up the Stage", 131, Rarity.UNCOMMON, mage.cards.l.LightUpTheStage.class));
|
||||
|
|
@ -165,6 +168,7 @@ public final class ForgottenRealmsCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Nature's Lore", 164, Rarity.COMMON, mage.cards.n.NaturesLore.class));
|
||||
cards.add(new SetCardInfo("Necromantic Selection", 103, Rarity.RARE, mage.cards.n.NecromanticSelection.class));
|
||||
cards.add(new SetCardInfo("Necrotic Sliver", 188, Rarity.UNCOMMON, mage.cards.n.NecroticSliver.class));
|
||||
cards.add(new SetCardInfo("Nihiloor", 53, Rarity.MYTHIC, mage.cards.n.Nihiloor.class));
|
||||
cards.add(new SetCardInfo("Nimbus Maze", 252, Rarity.RARE, mage.cards.n.NimbusMaze.class));
|
||||
cards.add(new SetCardInfo("Obsessive Stitcher", 189, Rarity.UNCOMMON, mage.cards.o.ObsessiveStitcher.class));
|
||||
cards.add(new SetCardInfo("Ogre Slumlord", 104, Rarity.RARE, mage.cards.o.OgreSlumlord.class));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue