[ECL] Implement Dose of Dawnglow

This commit is contained in:
theelk801 2025-12-16 15:30:53 -05:00
parent 0ef4695e29
commit acc180d1d4
11 changed files with 143 additions and 52 deletions

View file

@ -42,7 +42,7 @@ public final class AllOutAssault extends CardImpl {
extraCombatAbility.addEffect(new CreateDelayedTriggeredAbilityEffect(new WhenYouAttackDelayedTriggeredAbility( extraCombatAbility.addEffect(new CreateDelayedTriggeredAbilityEffect(new WhenYouAttackDelayedTriggeredAbility(
new UntapAllControllerEffect( new UntapAllControllerEffect(
StaticFilters.FILTER_CONTROLLED_CREATURE, "untap each creature you control"), Duration.EndOfTurn, true))); StaticFilters.FILTER_CONTROLLED_CREATURE, "untap each creature you control"), Duration.EndOfTurn, true)));
this.addAbility(extraCombatAbility.withInterveningIf(IsMainPhaseCondition.YOUR)); this.addAbility(extraCombatAbility.withInterveningIf(IsMainPhaseCondition.YOURS));
} }

View file

@ -0,0 +1,39 @@
package mage.cards.d;
import mage.abilities.condition.common.IsMainPhaseCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.keyword.BlightControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DoseOfDawnglow extends CardImpl {
public DoseOfDawnglow(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}");
// Return target creature card from your graveyard to the battlefield. Then if it isn't your main phase, blight 2.
this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new BlightControllerEffect(2), IsMainPhaseCondition.NOT_YOURS
).concatBy("Then"));
}
private DoseOfDawnglow(final DoseOfDawnglow card) {
super(card);
}
@Override
public DoseOfDawnglow copy() {
return new DoseOfDawnglow(this);
}
}

View file

@ -36,7 +36,7 @@ public final class DovinsAcuity extends CardImpl {
// Whenever you cast an instant spell during your main phase, you may return Dovin's Acuity to its owner's hand. // Whenever you cast an instant spell during your main phase, you may return Dovin's Acuity to its owner's hand.
this.addAbility(new SpellCastControllerTriggeredAbility( this.addAbility(new SpellCastControllerTriggeredAbility(
new ReturnToHandSourceEffect(true), filter, true new ReturnToHandSourceEffect(true), filter, true
).withTriggerCondition(IsMainPhaseCondition.YOUR).setTriggerPhrase("Whenever you cast an instant spell during your main phase, ")); ).withTriggerCondition(IsMainPhaseCondition.YOURS).setTriggerPhrase("Whenever you cast an instant spell during your main phase, "));
} }
private DovinsAcuity(final DovinsAcuity card) { private DovinsAcuity(final DovinsAcuity card) {

View file

@ -1,22 +1,25 @@
package mage.cards.f; package mage.cards.f;
import java.util.UUID; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.condition.common.IsMainPhaseCondition; import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.*; import mage.abilities.effects.common.AdditionalCombatPhaseEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.UntapAllEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AttackedThisTurnPredicate; import mage.filter.predicate.permanent.AttackedThisTurnPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.turn.Turn;
import java.util.UUID;
/** /**
*
* @author Jmlundeen * @author Jmlundeen
*/ */
public final class FullThrottle extends CardImpl { public final class FullThrottle extends CardImpl {
@ -24,16 +27,15 @@ public final class FullThrottle extends CardImpl {
public FullThrottle(UUID ownerId, CardSetInfo setInfo) { public FullThrottle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
// After this main phase, there are two additional combat phases. // After this main phase, there are two additional combat phases.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect( this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new AdditionalCombatPhaseEffect(2), new AdditionalCombatPhaseEffect(2), FullThrottleCondition.instance,
IsMainPhaseCondition.ANY,
"After this main phase, there are two additional combat phases." "After this main phase, there are two additional combat phases."
)); ));
// At the beginning of each combat this turn, untap all creatures that attacked this turn. // At the beginning of each combat this turn, untap all creatures that attacked this turn.
DelayedTriggeredAbility ability = new FullThrottleTriggeredAbility(); this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new FullThrottleTriggeredAbility())
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(ability).concatBy("<br>")); .concatBy("<br>"));
} }
private FullThrottle(final FullThrottle card) { private FullThrottle(final FullThrottle card) {
@ -46,14 +48,25 @@ public final class FullThrottle extends CardImpl {
} }
} }
enum FullThrottleCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
return game.getTurnPhaseType().isMain();
}
}
class FullThrottleTriggeredAbility extends DelayedTriggeredAbility { class FullThrottleTriggeredAbility extends DelayedTriggeredAbility {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures that attacked this turn");
private static final FilterPermanent filter = new FilterCreaturePermanent("creatures that attacked this turn");
static { static {
filter.add(AttackedThisTurnPredicate.instance); filter.add(AttackedThisTurnPredicate.instance);
} }
public FullThrottleTriggeredAbility() { public FullThrottleTriggeredAbility() {
super(new UntapAllEffect(filter), Duration.EndOfTurn, false); super(new UntapAllEffect(filter), Duration.EndOfTurn, false, false);
setTriggerPhrase("At the beginning of each combat this turn, "); setTriggerPhrase("At the beginning of each combat this turn, ");
} }
@ -73,7 +86,6 @@ class FullThrottleTriggeredAbility extends DelayedTriggeredAbility {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
Turn turn = game.getState().getTurn(); return true;
return turn.getPhase().getType() == TurnPhase.COMBAT;
} }
} }

View file

@ -59,7 +59,7 @@ public final class GrimReapersSprint extends CardImpl {
"untap each creature you control" "untap each creature you control"
), false ), false
); );
triggeredAbility.addEffect(new ConditionalOneShotEffect(new AdditionalCombatPhaseEffect(), IsMainPhaseCondition.YOUR, "If it's your main phase, there is an additional combat phase after this phase.")); triggeredAbility.addEffect(new ConditionalOneShotEffect(new AdditionalCombatPhaseEffect(), IsMainPhaseCondition.YOURS, "If it's your main phase, there is an additional combat phase after this phase."));
this.addAbility(triggeredAbility); this.addAbility(triggeredAbility);
// Enchanted creature gets +2/+2 and has haste. // Enchanted creature gets +2/+2 and has haste.
@ -110,4 +110,4 @@ class GrimReapersSprintCostModificationEffect extends CostModificationEffectImpl
public GrimReapersSprintCostModificationEffect copy() { public GrimReapersSprintCostModificationEffect copy() {
return new GrimReapersSprintCostModificationEffect(this); return new GrimReapersSprintCostModificationEffect(this);
} }
} }

View file

@ -7,23 +7,19 @@ import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility;
import mage.abilities.costs.common.TapTargetCost; import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.ProliferateEffect; import mage.abilities.effects.common.counter.ProliferateEffect;
import mage.abilities.effects.keyword.BlightControllerEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TappedPredicate; import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@ -87,24 +83,9 @@ class HighPerfectMorcantEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
// TODO: this will likely be refactored when we learn more about this mechanic
for (UUID opponentId : game.getOpponents(source.getControllerId())) { for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId); Player opponent = game.getPlayer(opponentId);
if (opponent == null || !game.getBattlefield().contains( BlightControllerEffect.doBlight(opponent, 1, game, source);
StaticFilters.FILTER_CONTROLLED_CREATURE, opponentId, source, game, 1
)) {
continue;
}
TargetPermanent target = new TargetControlledCreaturePermanent();
target.withNotTarget(true);
target.withChooseHint("to put a -1/-1 counter on");
opponent.choose(outcome, target, source, game);
Optional.ofNullable(target)
.map(TargetPermanent::getFirstTarget)
.map(game::getPermanent)
.ifPresent(permanent -> permanent.addCounters(
CounterType.M1M1.createInstance(), opponentId, source, game
));
} }
return true; return true;
} }

View file

@ -40,7 +40,7 @@ public final class MoraugFuryOfAkoum extends CardImpl {
this.addAbility(new SimpleStaticAbility(new MoraugFuryOfAkoumBoostEffect())); this.addAbility(new SimpleStaticAbility(new MoraugFuryOfAkoumBoostEffect()));
// Landfall Whenever a land you control enters, if it's your main phase, there's an additional combat phase after this phase. At the beginning of that combat, untap all creatures you control. // Landfall Whenever a land you control enters, if it's your main phase, there's an additional combat phase after this phase. At the beginning of that combat, untap all creatures you control.
this.addAbility(new LandfallAbility(new MoraugFuryOfAkoumCombatEffect()).withInterveningIf(IsMainPhaseCondition.YOUR), new MoraugFuryOfAkoumWatcher()); this.addAbility(new LandfallAbility(new MoraugFuryOfAkoumCombatEffect()).withInterveningIf(IsMainPhaseCondition.YOURS), new MoraugFuryOfAkoumWatcher());
} }
private MoraugFuryOfAkoum(final MoraugFuryOfAkoum card) { private MoraugFuryOfAkoum(final MoraugFuryOfAkoum card) {

View file

@ -32,6 +32,7 @@ public final class LorwynEclipsed extends ExpansionSet {
cards.add(new SetCardInfo("Blood Crypt", 349, Rarity.RARE, mage.cards.b.BloodCrypt.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Blood Crypt", 349, Rarity.RARE, mage.cards.b.BloodCrypt.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Deceit", 212, Rarity.MYTHIC, mage.cards.d.Deceit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Deceit", 212, Rarity.MYTHIC, mage.cards.d.Deceit.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Deceit", 293, Rarity.MYTHIC, mage.cards.d.Deceit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Deceit", 293, Rarity.MYTHIC, mage.cards.d.Deceit.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dose of Dawnglow", 100, Rarity.UNCOMMON, mage.cards.d.DoseOfDawnglow.class));
cards.add(new SetCardInfo("Eirdu, Carrier of Dawn", 13, Rarity.MYTHIC, mage.cards.e.EirduCarrierOfDawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Eirdu, Carrier of Dawn", 13, Rarity.MYTHIC, mage.cards.e.EirduCarrierOfDawn.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Eirdu, Carrier of Dawn", 286, Rarity.MYTHIC, mage.cards.e.EirduCarrierOfDawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Eirdu, Carrier of Dawn", 286, Rarity.MYTHIC, mage.cards.e.EirduCarrierOfDawn.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Emptiness", 222, Rarity.MYTHIC, mage.cards.e.Emptiness.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Emptiness", 222, Rarity.MYTHIC, mage.cards.e.Emptiness.class, NON_FULL_USE_VARIOUS));

View file

@ -1,4 +1,3 @@
package mage.abilities.condition.common; package mage.abilities.condition.common;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -10,23 +9,22 @@ import mage.game.Game;
*/ */
public enum IsMainPhaseCondition implements Condition { public enum IsMainPhaseCondition implements Condition {
YOUR(true), YOURS(true),
ANY(false); NOT_YOURS(false);
private final boolean yourMainPhaseOnly; private final boolean yours;
IsMainPhaseCondition(boolean yourMainPhaseOnly) { IsMainPhaseCondition(boolean yours) {
this.yourMainPhaseOnly = yourMainPhaseOnly; this.yours = yours;
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
return game.getTurnPhaseType().isMain() && return game.getTurnPhaseType().isMain() && yours == game.isActivePlayer(source.getControllerId());
(!yourMainPhaseOnly || game.getActivePlayerId().equals(source.getControllerId()));
} }
@Override @Override
public String toString() { public String toString() {
return "it's" + (yourMainPhaseOnly ? " your " : " ") + "main phase"; return "it" + (yours ? "'s" : " isn't") + " your main phase";
} }
} }

View file

@ -0,0 +1,59 @@
package mage.abilities.effects.keyword;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
/**
* @author TheElk801
*/
public class BlightControllerEffect extends OneShotEffect {
private final int amount;
public BlightControllerEffect(int amount) {
super(Outcome.Detriment);
this.amount = amount;
staticText = "blight " + amount;
}
private BlightControllerEffect(final BlightControllerEffect effect) {
super(effect);
this.amount = effect.amount;
}
@Override
public BlightControllerEffect copy() {
return new BlightControllerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
return doBlight(player, amount, game, source) != null;
}
public static Permanent doBlight(Player player, int amount, Game game, Ability source) {
if (player == null || amount < 1 || !game.getBattlefield().contains(
StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game, 1
)) {
return null;
}
TargetPermanent target = new TargetControlledCreaturePermanent();
target.withNotTarget(true);
target.withChooseHint("to put a -1/-1 counter on");
player.choose(Outcome.UnboostCreature, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
permanent.addCounters(CounterType.M1M1.createInstance(amount), source, game);
}
return permanent;
}
}

View file

@ -60825,6 +60825,7 @@ Sygg, Wanderwine Wisdom|Lorwyn Eclipsed|76|R|{1}{U}|Legendary Creature - Merfolk
Sygg, Wanderbrine Shield|Lorwyn Eclipsed|76|R||Legendary Creature - Merfolk Rogue|2|2|Sygg can't be blocked.$Whenever this creature transforms into Sygg, Wanderbrine Shield, target creature you control gains protection from each color until your next turn.$At the beginning of your first main phase, you may pay {U}. If you do, transform Sygg.| Sygg, Wanderbrine Shield|Lorwyn Eclipsed|76|R||Legendary Creature - Merfolk Rogue|2|2|Sygg can't be blocked.$Whenever this creature transforms into Sygg, Wanderbrine Shield, target creature you control gains protection from each color until your next turn.$At the beginning of your first main phase, you may pay {U}. If you do, transform Sygg.|
Unexpected Assistance|Lorwyn Eclipsed|80|C|{3}{U}{U}|Instant|||Convoke$Draw three cards, then discard a card.| Unexpected Assistance|Lorwyn Eclipsed|80|C|{3}{U}{U}|Instant|||Convoke$Draw three cards, then discard a card.|
Bitterbloom Bearer|Lorwyn Eclipsed|88|M|{B}{B}|Creature - Faerie Rogue|1|1|Flash$Flying$At the beginning of your upkeep, you lose 1 life and create a 1/1 blue and black Faerie creature token with flying.| Bitterbloom Bearer|Lorwyn Eclipsed|88|M|{B}{B}|Creature - Faerie Rogue|1|1|Flash$Flying$At the beginning of your upkeep, you lose 1 life and create a 1/1 blue and black Faerie creature token with flying.|
Dose of Dawnglow|Lorwyn Eclipsed|100|U|{4}{B}|Instant|||Return target creature card from your graveyard to the battlefield. Then if it isn't your main phase, blight 2.|
Perfect Intimidation|Lorwyn Eclipsed|115|U|{3}{B}|Sorcery|||Choose one or both --$* Target opponent exiles two cards from their hand.$* Remove all counters from target creature.| Perfect Intimidation|Lorwyn Eclipsed|115|U|{3}{B}|Sorcery|||Choose one or both --$* Target opponent exiles two cards from their hand.$* Remove all counters from target creature.|
Ashling, Rekindled|Lorwyn Eclipsed|124|R|{1}{R}|Legendary Creature - Elemental Sorcerer|1|3|Whenever this creature enters or transforms into Ashling, Rekindled, you may discard a card. If you do, draw a card.$At the beginning of your first main phase, you may pay {U}. If you do, transform Ashling.| Ashling, Rekindled|Lorwyn Eclipsed|124|R|{1}{R}|Legendary Creature - Elemental Sorcerer|1|3|Whenever this creature enters or transforms into Ashling, Rekindled, you may discard a card. If you do, draw a card.$At the beginning of your first main phase, you may pay {U}. If you do, transform Ashling.|
Ashling, Rimebound|Lorwyn Eclipsed|124|R||Legendary Creature - Elemental Wizard|1|3|Whenever this creature transforms into Ashling, Rimebound and at the beginning of your first main phase, add two mana of any one color. Spend this mana only to cast spells with mana value 4 or greater.$At the beginning of your first main phase, you may pay {R}. If you do, transform Ashling.| Ashling, Rimebound|Lorwyn Eclipsed|124|R||Legendary Creature - Elemental Wizard|1|3|Whenever this creature transforms into Ashling, Rimebound and at the beginning of your first main phase, add two mana of any one color. Spend this mana only to cast spells with mana value 4 or greater.$At the beginning of your first main phase, you may pay {R}. If you do, transform Ashling.|