[TLE] Implement Aang, Airbending Master

This commit is contained in:
theelk801 2025-08-14 17:23:26 -04:00
parent c5a52232d0
commit 2f85f46e32
3 changed files with 72 additions and 96 deletions

View file

@ -1,33 +1,30 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.BatchTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.OneOrMoreLeaveWithoutDyingTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CountersControllerCount; import mage.abilities.dynamicvalue.common.CountersControllerCount;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.counter.AddCountersPlayersEffect; import mage.abilities.effects.common.counter.AddCountersPlayersEffect;
import mage.abilities.effects.keyword.AirbendTargetEffect; import mage.abilities.effects.keyword.AirbendTargetEffect;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.constants.*;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeBatchEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.AllyToken; import mage.game.permanent.token.AllyToken;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import java.util.UUID;
/** /**
* * @author TheElk801
* @author Grath
*/ */
public final class AangAirbendingMaster extends CardImpl { public final class AangAirbendingMaster extends CardImpl {
@ -44,15 +41,19 @@ public final class AangAirbendingMaster extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// When Aang enters, airbend another target creature. // When Aang enters, airbend another target creature.
Ability ability = new EntersBattlefieldTriggeredAbility(new AirbendTargetEffect(), false); Ability ability = new EntersBattlefieldTriggeredAbility(new AirbendTargetEffect());
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE));
this.addAbility(ability); this.addAbility(ability);
// Whenever one or more creatures you control leave the battlefield without dying, you get an experience counter. // Whenever one or more creatures you control leave the battlefield without dying, you get an experience counter.
this.addAbility(new AangAirbendingMasterTriggeredAbility()); this.addAbility(new OneOrMoreLeaveWithoutDyingTriggeredAbility(
new AddCountersPlayersEffect(CounterType.EXPERIENCE.createInstance(), TargetController.YOU),
StaticFilters.FILTER_CONTROLLED_CREATURES
));
// At the beginning of your upkeep, create a 1/1 white Ally creature token for each experience counter you have. // At the beginning of your upkeep, create a 1/1 white Ally creature token for each experience counter you have.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new AllyToken(), xValue))); this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new AllyToken(), xValue)
.setText("create a 1/1 white Ally creature token for each experience counter you have")));
} }
private AangAirbendingMaster(final AangAirbendingMaster card) { private AangAirbendingMaster(final AangAirbendingMaster card) {
@ -64,39 +65,3 @@ public final class AangAirbendingMaster extends CardImpl {
return new AangAirbendingMaster(this); return new AangAirbendingMaster(this);
} }
} }
class AangAirbendingMasterTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility<ZoneChangeEvent> {
AangAirbendingMasterTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersPlayersEffect(CounterType.EXPERIENCE.createInstance(), TargetController.YOU));
setTriggerPhrase("Whenever one or more creatures you control leave the battlefield without dying, ");
}
private AangAirbendingMasterTriggeredAbility(final AangAirbendingMasterTriggeredAbility ability) {
super(ability);
}
@Override
public AangAirbendingMasterTriggeredAbility copy() {
return new AangAirbendingMasterTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH;
}
@Override
public boolean checkEvent(ZoneChangeEvent event, Game game) {
if (event.getFromZone() != Zone.BATTLEFIELD || event.getToZone() == Zone.GRAVEYARD) {
return false;
}
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
return permanent != null && permanent.isCreature(game) && permanent.isControlledBy(getControllerId());
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty();
}
}

View file

@ -2,8 +2,7 @@ package mage.cards.d;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.BatchTriggeredAbility; import mage.abilities.common.OneOrMoreLeaveWithoutDyingTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
@ -13,13 +12,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeBatchEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import java.util.UUID; import java.util.UUID;
@ -38,7 +31,9 @@ public final class DourPortMage extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// Whenever one or more other creatures you control leave the battlefield without dying, draw a card. // Whenever one or more other creatures you control leave the battlefield without dying, draw a card.
this.addAbility(new DourPortMageTriggeredAbility()); this.addAbility(new OneOrMoreLeaveWithoutDyingTriggeredAbility(
new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES
));
// {1}{U}, {T}: Return another target creature you control to its owner's hand. // {1}{U}, {T}: Return another target creature you control to its owner's hand.
Ability ability = new SimpleActivatedAbility(new ReturnToHandTargetEffect(), new ManaCostsImpl<>("{1}{U}")); Ability ability = new SimpleActivatedAbility(new ReturnToHandTargetEffect(), new ManaCostsImpl<>("{1}{U}"));
@ -56,39 +51,3 @@ public final class DourPortMage extends CardImpl {
return new DourPortMage(this); return new DourPortMage(this);
} }
} }
class DourPortMageTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility<ZoneChangeEvent> {
DourPortMageTriggeredAbility() {
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1));
setTriggerPhrase("Whenever one or more other creatures you control leave the battlefield without dying, ");
}
private DourPortMageTriggeredAbility(final DourPortMageTriggeredAbility ability) {
super(ability);
}
@Override
public DourPortMageTriggeredAbility copy() {
return new DourPortMageTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH;
}
@Override
public boolean checkEvent(ZoneChangeEvent event, Game game) {
if (event.getFromZone() != Zone.BATTLEFIELD || event.getToZone() == Zone.GRAVEYARD || event.getTargetId().equals(getSourceId())) {
return false;
}
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
return permanent != null && permanent.isCreature(game) && permanent.isControlledBy(getControllerId());
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty();
}
}

View file

@ -0,0 +1,52 @@
package mage.abilities.common;
import mage.abilities.BatchTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeBatchEvent;
import mage.game.events.ZoneChangeEvent;
/**
* @author TheElk801
*/
public class OneOrMoreLeaveWithoutDyingTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility<ZoneChangeEvent> {
private final FilterPermanent filter;
public OneOrMoreLeaveWithoutDyingTriggeredAbility(Effect effect, FilterPermanent filter) {
super(Zone.BATTLEFIELD, effect);
this.filter = filter;
setTriggerPhrase("Whenever one or more " + filter.getMessage() + " leave the battlefield without dying, ");
}
private OneOrMoreLeaveWithoutDyingTriggeredAbility(final OneOrMoreLeaveWithoutDyingTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
}
@Override
public OneOrMoreLeaveWithoutDyingTriggeredAbility copy() {
return new OneOrMoreLeaveWithoutDyingTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH;
}
@Override
public boolean checkEvent(ZoneChangeEvent event, Game game) {
return Zone.BATTLEFIELD.match(event.getFromZone())
&& !Zone.GRAVEYARD.match(event.getToZone())
&& filter.match(event.getTarget(), getControllerId(), this, game);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty();
}
}