From 4f2671f47514637263c9f7e689b8078c865c46df Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 8 Feb 2022 08:43:47 -0500 Subject: [PATCH] [NEC] Implemented Aerial Surveyor --- .../src/mage/cards/a/AerialSurveyor.java | 115 ++++++++++++++++++ .../src/mage/sets/NeonDynastyCommander.java | 1 + .../filter/common/FilterBasicLandCard.java | 7 +- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/a/AerialSurveyor.java diff --git a/Mage.Sets/src/mage/cards/a/AerialSurveyor.java b/Mage.Sets/src/mage/cards/a/AerialSurveyor.java new file mode 100644 index 00000000000..9d733d7323e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AerialSurveyor.java @@ -0,0 +1,115 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.common.LandsYouControlHint; +import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterBasicLandCard; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate; +import mage.game.Controllable; +import mage.game.Game; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class AerialSurveyor extends CardImpl { + + private static final FilterCard filter = new FilterBasicLandCard(SubType.PLAINS); + + public AerialSurveyor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{W}"); + + this.subtype.add(SubType.VEHICLE); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever Aerial Surveyor attacks, if defending player controls more lands than you, search your library for a basic Plains card, put it onto the battlefield tapped, then shuffle. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new AttacksTriggeredAbility( + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), true) + ), AerialSurveyorCondition.instance, "Whenever {this} attacks, if defending player " + + "controls more lands than you, search your library for a basic Plains card, " + + "put it onto the battlefield tapped, then shuffle." + ).addHint(LandsYouControlHint.instance).addHint(AerialSurveyorHint.instance)); + + // Crew 2 + this.addAbility(new CrewAbility(2)); + } + + private AerialSurveyor(final AerialSurveyor card) { + super(card); + } + + @Override + public AerialSurveyor copy() { + return new AerialSurveyor(this); + } +} + +enum AerialSurveyorCondition implements Condition { + instance; + private static final FilterPermanent filter = new FilterLandPermanent(); + + static { + filter.add(DefendingPlayerControlsPredicate.instance); + } + + @Override + public boolean apply(Game game, Ability source) { + return game.getBattlefield().count( + filter, source.getControllerId(), source.getSourceId(), game + ) > game.getBattlefield().count( + StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, + source.getControllerId(), source.getSourceId(), game + ); + } +} + +enum AerialSurveyorHint implements Hint { + instance; + + @Override + public String getText(Game game, Ability ability) { + return game.getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_LAND, + ability.getControllerId(), + ability.getSourceId(), game + ).stream() + .map(Controllable::getControllerId) + .filter(game.getOpponents(ability.getControllerId())::contains) + .collect(Collectors.toMap(Function.identity(), u -> 1, Integer::sum)) + .entrySet() + .stream() + .filter(entry -> game.getPlayer(entry.getKey()) != null) + .map(entry -> "Lands " + game.getPlayer(entry.getKey()).getName() + " controls: " + entry.getValue()) + .collect(Collectors.joining("
")); + } + + @Override + public AerialSurveyorHint copy() { + return this; + } +} diff --git a/Mage.Sets/src/mage/sets/NeonDynastyCommander.java b/Mage.Sets/src/mage/sets/NeonDynastyCommander.java index 40ee615a79d..0cd3a66c0b1 100644 --- a/Mage.Sets/src/mage/sets/NeonDynastyCommander.java +++ b/Mage.Sets/src/mage/sets/NeonDynastyCommander.java @@ -19,6 +19,7 @@ public final class NeonDynastyCommander extends ExpansionSet { super("Neon Dynasty Commander", "NEC", ExpansionSet.buildDate(2022, 2, 18), SetType.SUPPLEMENTAL); this.hasBasicLands = false; + cards.add(new SetCardInfo("Aerial Surveyor", 5, Rarity.RARE, mage.cards.a.AerialSurveyor.class)); cards.add(new SetCardInfo("Chishiro, the Shattered Blade", 1, Rarity.MYTHIC, mage.cards.c.ChishiroTheShatteredBlade.class)); cards.add(new SetCardInfo("Kotori, Pilot Prodigy", 2, Rarity.MYTHIC, mage.cards.k.KotoriPilotProdigy.class)); cards.add(new SetCardInfo("Myojin of Blooming Dawn", 31, Rarity.RARE, mage.cards.m.MyojinOfBloomingDawn.class)); diff --git a/Mage/src/main/java/mage/filter/common/FilterBasicLandCard.java b/Mage/src/main/java/mage/filter/common/FilterBasicLandCard.java index 815419817c2..aa24dff0e5a 100644 --- a/Mage/src/main/java/mage/filter/common/FilterBasicLandCard.java +++ b/Mage/src/main/java/mage/filter/common/FilterBasicLandCard.java @@ -2,11 +2,11 @@ package mage.filter.common; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.FilterCard; /** - * * @author BetaSteward_at_googlemail.com */ public class FilterBasicLandCard extends FilterCard { @@ -15,6 +15,11 @@ public class FilterBasicLandCard extends FilterCard { this("basic land card"); } + public FilterBasicLandCard(SubType subType) { + this("basic " + subType + " card"); + this.add(subType.getPredicate()); + } + public FilterBasicLandCard(String name) { super(name); this.add(CardType.LAND.getPredicate());