diff --git a/Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java b/Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java
index 2df6161f99f..a72bc6b9d80 100644
--- a/Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java
+++ b/Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java
@@ -7,17 +7,18 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.SuperType;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
import mage.game.Game;
-import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
-import mage.util.CardUtil;
import mage.util.functions.StackObjectCopyApplier;
import java.util.UUID;
@@ -27,6 +28,13 @@ import java.util.UUID;
*/
public class DonalHeraldOfWings extends CardImpl {
+ private static final FilterSpell filterSpell = new FilterSpell("a nonlegendary creature spell with flying");
+
+ static {
+ filterSpell.add(Predicates.not(SuperType.LEGENDARY.getPredicate()));
+ filterSpell.add(CardType.CREATURE.getPredicate());
+ }
+
public DonalHeraldOfWings(UUID ownderId, CardSetInfo setInfo) {
super(ownderId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
@@ -40,57 +48,18 @@ public class DonalHeraldOfWings extends CardImpl {
// Whenever you cast a nonlegendary creature spell with flying, you may copy it,
// except the copy is a 1/1 Spirit in addition to its other types.
// Do this only once each turn. (The copy becomes a token.)
- // TODO: This still triggers and asks if you wanna use it, even if you've used it once this turn.
- this.addAbility(new DonalHeraldOfWingsTriggeredAbility());
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new DonalHeraldOfWingsEffect(), filterSpell, true, true
+ ).setDoOnlyOnce(true));
}
- private DonalHeraldOfWings(final DonalHeraldOfWings card) { super(card); }
-
- @Override
- public DonalHeraldOfWings copy() { return new DonalHeraldOfWings(this); }
-}
-
-class DonalHeraldOfWingsTriggeredAbility extends SpellCastControllerTriggeredAbility {
-
- private static final FilterSpell filterSpell = new FilterSpell("a nonlegendary creature spell with flying");
- static {
- filterSpell.add(Predicates.not(SuperType.LEGENDARY.getPredicate()));
- filterSpell.add(CardType.CREATURE.getPredicate());
- }
-
- DonalHeraldOfWingsTriggeredAbility() {
- super(new DonalHeraldOfWingsEffect(), filterSpell, true, true);
- }
-
- private DonalHeraldOfWingsTriggeredAbility(final DonalHeraldOfWingsTriggeredAbility ability) { super(ability); }
-
- @Override
- public DonalHeraldOfWingsTriggeredAbility copy() {
- return new DonalHeraldOfWingsTriggeredAbility(this);
+ private DonalHeraldOfWings(final DonalHeraldOfWings card) {
+ super(card);
}
@Override
- public boolean checkTrigger(GameEvent event, Game game) {
- return abilityAvailableThisTurn(game) && super.checkTrigger(event, game);
- }
-
- @Override
- public boolean resolve(Game game) {
- if (!(abilityAvailableThisTurn(game) && super.resolve(game))) { return false; }
- game.getState().setValue(
- CardUtil.getCardZoneString("lastTurnResolved" + originalId, sourceId, game),
- game.getTurnNum()
- );
-
- return true;
- }
-
- private boolean abilityAvailableThisTurn(Game game) {
- Integer lastTurnResolved = (Integer) game.getState().getValue(
- CardUtil.getCardZoneString("lastTurnResolved" + originalId, sourceId, game)
- );
- // A null result is assumed to mean the this ability has not been used yet.
- return lastTurnResolved == null || lastTurnResolved != game.getTurnNum();
+ public DonalHeraldOfWings copy() {
+ return new DonalHeraldOfWings(this);
}
}
@@ -98,19 +67,24 @@ class DonalHeraldOfWingsEffect extends OneShotEffect {
DonalHeraldOfWingsEffect() {
super(Outcome.Copy);
- staticText = "you may copy it, except the copy is a 1/1 Spirit in addition to its other types. " +
- "Do this only once each turn. (The copy becomes a token.)";
+ staticText = "you may copy it, except the copy is a 1/1 Spirit in addition to its other types";
}
- private DonalHeraldOfWingsEffect(final DonalHeraldOfWingsEffect effect) { super(effect); }
+ private DonalHeraldOfWingsEffect(final DonalHeraldOfWingsEffect effect) {
+ super(effect);
+ }
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller == null) { return false; }
+ if (controller == null) {
+ return false;
+ }
// Get the card that was cast
- if (this.getTargetPointer() == null) { return false; }
+ if (this.getTargetPointer() == null) {
+ return false;
+ }
Spell originalSpell = game.getStack().getSpell(((FixedTarget) this.getTargetPointer()).getTarget());
// Create a token copy
@@ -120,7 +94,9 @@ class DonalHeraldOfWingsEffect extends OneShotEffect {
}
@Override
- public Effect copy() { return new DonalHeraldOfWingsEffect(this); }
+ public Effect copy() {
+ return new DonalHeraldOfWingsEffect(this);
+ }
}
enum DonalHeraldOfWingsApplier implements StackObjectCopyApplier {
@@ -134,5 +110,7 @@ enum DonalHeraldOfWingsApplier implements StackObjectCopyApplier {
}
@Override
- public MageObjectReferencePredicate getNextNewTargetType(int copyNumber) { return null; }
+ public MageObjectReferencePredicate getNextNewTargetType(int copyNumber) {
+ return null;
+ }
}
diff --git a/Mage.Sets/src/mage/cards/n/NykthosParagon.java b/Mage.Sets/src/mage/cards/n/NykthosParagon.java
index e2cae10701c..39160b8e5d6 100644
--- a/Mage.Sets/src/mage/cards/n/NykthosParagon.java
+++ b/Mage.Sets/src/mage/cards/n/NykthosParagon.java
@@ -1,27 +1,24 @@
package mage.cards.n;
-import java.util.UUID;
import mage.MageInt;
-import mage.MageObject;
import mage.abilities.Ability;
-import mage.abilities.TriggeredAbilityImpl;
-import mage.abilities.effects.Effect;
+import mage.abilities.common.GainLifeControllerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
-import mage.constants.Outcome;
-import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
+import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.counters.CounterType;
+import mage.filter.StaticFilters;
import mage.game.Game;
-import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
+import java.util.UUID;
+
/**
- *
* @author weirddan455
*/
public final class NykthosParagon extends CardImpl {
@@ -35,7 +32,7 @@ public final class NykthosParagon extends CardImpl {
this.toughness = new MageInt(6);
// Whenever you gain life, you may put that many +1/+1 counters on each creature you control. Do this only once each turn.
- this.addAbility(new NykthosParagonTriggeredAbility());
+ this.addAbility(new GainLifeControllerTriggeredAbility(new NykthosParagonEffect()).setDoOnlyOnce(true));
}
private NykthosParagon(final NykthosParagon card) {
@@ -48,65 +45,11 @@ public final class NykthosParagon extends CardImpl {
}
}
-class NykthosParagonTriggeredAbility extends TriggeredAbilityImpl {
-
- public NykthosParagonTriggeredAbility() {
- super(Zone.BATTLEFIELD, new NykthosParagonEffect(), true);
- }
-
- private NykthosParagonTriggeredAbility(final NykthosParagonTriggeredAbility ability) {
- super(ability);
- }
-
- @Override
- public NykthosParagonTriggeredAbility copy() {
- return new NykthosParagonTriggeredAbility(this);
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.GAINED_LIFE;
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- if (abilityAvailableThisTurn(game) && event.getPlayerId().equals(this.getControllerId())) {
- for (Effect effect : this.getEffects()) {
- effect.setValue("gainedLife", event.getAmount());
- }
- return true;
- }
- return false;
- }
-
- @Override
- public boolean resolve(Game game) {
- if (abilityAvailableThisTurn(game) && super.resolve(game)) {
- game.getState().setValue(CardUtil.getCardZoneString(
- "lastTurnResolved" + originalId, sourceId, game
- ), game.getTurnNum());
- return true;
- }
- return false;
- }
-
- private boolean abilityAvailableThisTurn(Game game) {
- Integer lastTurnResolved = (Integer) game.getState().getValue(
- CardUtil.getCardZoneString("lastTurnResolved" + originalId, sourceId, game)
- );
- return lastTurnResolved == null || lastTurnResolved != game.getTurnNum();
- }
-
- @Override
- public String getRule() {
- return "Whenever you gain life, you may put that many +1/+1 counters on each creature you control. Do this only once each turn.";
- }
-}
-
class NykthosParagonEffect extends OneShotEffect {
public NykthosParagonEffect() {
super(Outcome.BoostCreature);
+ staticText = "put that many +1/+1 counters on each creature you control";
}
private NykthosParagonEffect(final NykthosParagonEffect effect) {
@@ -119,22 +62,26 @@ class NykthosParagonEffect extends OneShotEffect {
}
@Override
- public boolean apply (Game game, Ability source) {
+ public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source);
Integer life = (Integer) this.getValue("gainedLife");
- if (controller != null && sourceObject != null && life != null) {
- for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) {
- if (permanent != null && permanent.isCreature(game)) {
- permanent.addCounters(CounterType.P1P1.createInstance(life), source.getControllerId(), source, game);
- if (!game.isSimulation()) {
- game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " puts " + life
- + " +1/+1 counters on " + permanent.getLogName());
- }
- }
- }
- return true;
+ if (controller == null || life == null || life < 1) {
+ return false;
}
- return false;
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(
+ StaticFilters.FILTER_CONTROLLED_CREATURES,
+ source.getControllerId(), source, game
+ )) {
+ permanent.addCounters(
+ CounterType.P1P1.createInstance(life),
+ source.getControllerId(), source, game
+ );
+ game.informPlayers(
+ CardUtil.getSourceLogName(game, source) + ": " +
+ controller.getLogName() + " puts " + life +
+ " +1/+1 counters on " + permanent.getLogName()
+ );
+ }
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/r/RiveteersAscendancy.java b/Mage.Sets/src/mage/cards/r/RiveteersAscendancy.java
new file mode 100644
index 00000000000..64d31061e6d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RiveteersAscendancy.java
@@ -0,0 +1,74 @@
+package mage.cards.r;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.SacrificePermanentTriggeredAbility;
+import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.FilterCard;
+import mage.filter.common.FilterCreatureCard;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RiveteersAscendancy extends CardImpl {
+
+ private static final FilterCard filter
+ = new FilterCreatureCard("creature card with lesser mana value from your graveyard ");
+
+ static {
+ filter.add(RiveteersAscendancyPredicate.instance);
+ }
+
+ public RiveteersAscendancy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}{R}{G}");
+
+ // Whenever you sacrifice a creature, you may return target creature card with lesser mana value from your graveyard to the battlefield tapped. Do this only once each turn.
+ Ability ability = new SacrificePermanentTriggeredAbility(
+ new ReturnFromGraveyardToBattlefieldTargetEffect(true)
+ ).setDoOnlyOnce(true);
+ ability.addTarget(new TargetCardInYourGraveyard(filter));
+ this.addAbility(ability);
+ }
+
+ private RiveteersAscendancy(final RiveteersAscendancy card) {
+ super(card);
+ }
+
+ @Override
+ public RiveteersAscendancy copy() {
+ return new RiveteersAscendancy(this);
+ }
+}
+
+enum RiveteersAscendancyPredicate implements ObjectSourcePlayerPredicate {
+ instance;
+
+ @Override
+ public boolean apply(ObjectSourcePlayer input, Game game) {
+ return input
+ .getObject()
+ .getManaValue()
+ < input
+ .getSource()
+ .getEffects()
+ .stream()
+ .map(effect -> effect.getValue("sacrificedPermanent"))
+ .filter(Objects::nonNull)
+ .map(Permanent.class::cast)
+ .mapToInt(MageObject::getManaValue)
+ .max()
+ .orElse(0);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/StreetsOfNewCapenna.java b/Mage.Sets/src/mage/sets/StreetsOfNewCapenna.java
index 630f56f2210..42e728cc529 100644
--- a/Mage.Sets/src/mage/sets/StreetsOfNewCapenna.java
+++ b/Mage.Sets/src/mage/sets/StreetsOfNewCapenna.java
@@ -210,6 +210,7 @@ public final class StreetsOfNewCapenna extends ExpansionSet {
cards.add(new SetCardInfo("Revelation of Power", 28, Rarity.COMMON, mage.cards.r.RevelationOfPower.class));
cards.add(new SetCardInfo("Rhox Pummeler", 155, Rarity.COMMON, mage.cards.r.RhoxPummeler.class));
cards.add(new SetCardInfo("Rigo, Streetwise Mentor", 215, Rarity.RARE, mage.cards.r.RigoStreetwiseMentor.class));
+ cards.add(new SetCardInfo("Riveteers Ascendancy", 216, Rarity.RARE, mage.cards.r.RiveteersAscendancy.class));
cards.add(new SetCardInfo("Riveteers Charm", 217, Rarity.UNCOMMON, mage.cards.r.RiveteersCharm.class));
cards.add(new SetCardInfo("Riveteers Decoy", 156, Rarity.UNCOMMON, mage.cards.r.RiveteersDecoy.class));
cards.add(new SetCardInfo("Riveteers Initiate", 120, Rarity.COMMON, mage.cards.r.RiveteersInitiate.class));
diff --git a/Mage/src/main/java/mage/abilities/TriggeredAbilities.java b/Mage/src/main/java/mage/abilities/TriggeredAbilities.java
index 644313f542d..199da56edc5 100644
--- a/Mage/src/main/java/mage/abilities/TriggeredAbilities.java
+++ b/Mage/src/main/java/mage/abilities/TriggeredAbilities.java
@@ -91,7 +91,7 @@ public class TriggeredAbilities extends ConcurrentHashMap