From d515496b6e0cc925af9c4402caaabd7dfb9d854a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 12 Jan 2021 17:28:52 -0500 Subject: [PATCH] [KHM] Implemented Skemfar Shadowsage --- .../src/mage/cards/l/LittjaraKinseekers.java | 32 ++------ .../src/mage/cards/s/SkemfarShadowsage.java | 54 +++++++++++++ Mage.Sets/src/mage/sets/Kaldheim.java | 1 + .../GreatestSharedCreatureTypeCount.java | 75 +++++++++++++++++++ 4 files changed, 135 insertions(+), 27 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SkemfarShadowsage.java create mode 100644 Mage/src/main/java/mage/abilities/dynamicvalue/common/GreatestSharedCreatureTypeCount.java diff --git a/Mage.Sets/src/mage/cards/l/LittjaraKinseekers.java b/Mage.Sets/src/mage/cards/l/LittjaraKinseekers.java index 928b0edfb4..7e48a21e79 100644 --- a/Mage.Sets/src/mage/cards/l/LittjaraKinseekers.java +++ b/Mage.Sets/src/mage/cards/l/LittjaraKinseekers.java @@ -1,11 +1,11 @@ package mage.cards.l; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.dynamicvalue.common.GreatestSharedCreatureTypeCount; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.keyword.ChangelingAbility; @@ -14,11 +14,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.counters.CounterType; -import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.permanent.Permanent; -import java.util.*; +import java.util.UUID; /** * @author TheElk801 @@ -45,7 +43,7 @@ public final class LittjaraKinseekers extends CardImpl { "put a +1/+1 counter on {this}, then scry 1." ); ability.addEffect(new ScryEffect(1)); - this.addAbility(ability); + this.addAbility(ability.addHint(GreatestSharedCreatureTypeCount.getHint())); } private LittjaraKinseekers(final LittjaraKinseekers card) { @@ -63,26 +61,6 @@ enum LittjaraKinseekersCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - List permanentList = game.getBattlefield().getActivePermanents( - StaticFilters.FILTER_CONTROLLED_CREATURE, - source.getControllerId(), source.getSourceId(), game - ); - permanentList.removeIf(Objects::isNull); - long changelings = permanentList - .stream() - .filter(Objects::nonNull) - .filter(MageObject::isAllCreatureTypes) - .count(); - if (changelings > 2) { - return true; - } - permanentList.removeIf(MageObject::isAllCreatureTypes); - Map typeMap = new HashMap<>(); - return permanentList - .stream() - .map(permanent -> permanent.getSubtype(game)) - .flatMap(Collection::stream) - .mapToInt(subType -> typeMap.compute(subType, (s, i) -> i == null ? 1 : Integer.sum(i, 1))) - .anyMatch(x -> x + changelings > 2); + return GreatestSharedCreatureTypeCount.instance.calculate(game, source, null) >= 3; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SkemfarShadowsage.java b/Mage.Sets/src/mage/cards/s/SkemfarShadowsage.java new file mode 100644 index 0000000000..4eeeccda43 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SkemfarShadowsage.java @@ -0,0 +1,54 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.GreatestSharedCreatureTypeCount; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SkemfarShadowsage extends CardImpl { + + public SkemfarShadowsage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // When Skemfar Shadowsage enters the battlefield, choose one — + // • Each opponent loses X life, where X is the greatest number of creatures you control that have a creature type in common. + Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeOpponentsEffect( + GreatestSharedCreatureTypeCount.instance + ).setText("each opponent loses X life, where X is the greatest number " + + "of creatures you control that have a creature type in common")); + + // • You gain X life, where X is the greatest number of creatures you control that have a creature type in common. + ability.addMode(new Mode(new GainLifeEffect( + GreatestSharedCreatureTypeCount.instance + ).setText("you gain X life, where X is the greatest number " + + "of creatures you control that have a creature type in common"))); + + this.addAbility(ability.addHint(GreatestSharedCreatureTypeCount.getHint())); + } + + private SkemfarShadowsage(final SkemfarShadowsage card) { + super(card); + } + + @Override + public SkemfarShadowsage copy() { + return new SkemfarShadowsage(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Kaldheim.java b/Mage.Sets/src/mage/sets/Kaldheim.java index 3e2a8f23fd..15944f57b5 100644 --- a/Mage.Sets/src/mage/sets/Kaldheim.java +++ b/Mage.Sets/src/mage/sets/Kaldheim.java @@ -133,6 +133,7 @@ public final class Kaldheim extends ExpansionSet { cards.add(new SetCardInfo("Seize the Spoils", 149, Rarity.COMMON, mage.cards.s.SeizeTheSpoils.class)); cards.add(new SetCardInfo("Showdown of the Skalds", 229, Rarity.RARE, mage.cards.s.ShowdownOfTheSkalds.class)); cards.add(new SetCardInfo("Sigrid, God-Favored", 29, Rarity.RARE, mage.cards.s.SigridGodFavored.class)); + cards.add(new SetCardInfo("Skemfar Shadowsage", 110, Rarity.UNCOMMON, mage.cards.s.SkemfarShadowsage.class)); cards.add(new SetCardInfo("Snakeskin Veil", 194, Rarity.COMMON, mage.cards.s.SnakeskinVeil.class)); cards.add(new SetCardInfo("Snow-Covered Forest", 284, Rarity.LAND, mage.cards.s.SnowCoveredForest.class)); cards.add(new SetCardInfo("Snow-Covered Island", 278, Rarity.LAND, mage.cards.s.SnowCoveredIsland.class)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/GreatestSharedCreatureTypeCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/GreatestSharedCreatureTypeCount.java new file mode 100644 index 0000000000..b2571d27ac --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/GreatestSharedCreatureTypeCount.java @@ -0,0 +1,75 @@ +package mage.abilities.dynamicvalue.common; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.constants.SubType; +import mage.constants.SubTypeSet; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.*; + +/** + * @author TheElk801 + */ +public enum GreatestSharedCreatureTypeCount implements DynamicValue { + instance; + + private static final Hint hint = new ValueHint( + "Greatest number of creatures you control that share a creature type", instance + ); + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + List permanentList = game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, + sourceAbility.getControllerId(), sourceAbility.getSourceId(), game + ); + permanentList.removeIf(Objects::isNull); + int changelings = permanentList + .stream() + .filter(Objects::nonNull) + .filter(MageObject::isAllCreatureTypes) + .mapToInt(x -> 1) + .sum(); + permanentList.removeIf(MageObject::isAllCreatureTypes); + Map typeMap = new HashMap<>(); + permanentList + .stream() + .map(permanent -> permanent.getSubtype(game)) + .flatMap(Collection::stream) + .filter(subType -> subType.getSubTypeSet() == SubTypeSet.CreatureType) + .forEach(subType -> typeMap.compute(subType, (s, i) -> i == null ? 1 : Integer.sum(i, 1))); + return changelings + + typeMap + .values() + .stream() + .mapToInt(x -> x) + .max() + .getAsInt(); + } + + @Override + public GreatestSharedCreatureTypeCount copy() { + return instance; + } + + @Override + public String toString() { + return "X"; + } + + @Override + public String getMessage() { + return "greatest number of creatures you control that have a creature type in common"; + } + + public static Hint getHint() { + return hint; + } +}