diff --git a/Mage.Sets/src/mage/cards/i/InspiredSphinx.java b/Mage.Sets/src/mage/cards/i/InspiredSphinx.java index 2fe8e4e7a7..f3e793d77e 100644 --- a/Mage.Sets/src/mage/cards/i/InspiredSphinx.java +++ b/Mage.Sets/src/mage/cards/i/InspiredSphinx.java @@ -7,15 +7,12 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.OpponentsCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.FilterSpell; -import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.permanent.token.ThopterColorlessToken; import java.util.UUID; @@ -25,12 +22,6 @@ import java.util.UUID; */ public final class InspiredSphinx extends CardImpl { - private static final FilterSpell filter = new FilterSpell("Wizard"); - - static { - filter.add(new SubtypePredicate(SubType.WIZARD)); - } - public InspiredSphinx(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); this.subtype.add(SubType.SPHINX); diff --git a/Mage.Sets/src/mage/cards/m/MilitantAngel.java b/Mage.Sets/src/mage/cards/m/MilitantAngel.java new file mode 100644 index 0000000000..790f1e62c1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MilitantAngel.java @@ -0,0 +1,49 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.AttackedThisTurnOpponentsCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.KnightToken; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class MilitantAngel extends CardImpl { + + public MilitantAngel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); + this.subtype.add(SubType.ANGEL); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // When Militant Angel enters the battlefield, create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn. + Effect effect = new CreateTokenEffect(new KnightToken(), new AttackedThisTurnOpponentsCount()); + effect.setText("create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn"); + this.addAbility(new EntersBattlefieldTriggeredAbility(effect)); + } + + public MilitantAngel(final MilitantAngel card) { + super(card); + } + + @Override + public MilitantAngel copy() { + return new MilitantAngel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/GameNight.java b/Mage.Sets/src/mage/sets/GameNight.java index 1a69efd0e5..cfb9b33749 100644 --- a/Mage.Sets/src/mage/sets/GameNight.java +++ b/Mage.Sets/src/mage/sets/GameNight.java @@ -59,7 +59,7 @@ public final class GameNight extends ExpansionSet { cards.add(new SetCardInfo("Lord of the Accursed", 33, Rarity.UNCOMMON, mage.cards.l.LordOfTheAccursed.class)); cards.add(new SetCardInfo("Manalith", 54, Rarity.COMMON, mage.cards.m.Manalith.class)); cards.add(new SetCardInfo("Mesa Unicorn", 15, Rarity.COMMON, mage.cards.m.MesaUnicorn.class)); - // TODO: cards.add(new SetCardInfo("Militant Angel", 1, Rarity.MYTHIC, mage.cards.m.MilitantAngel.class)); + cards.add(new SetCardInfo("Militant Angel", 1, Rarity.MYTHIC, mage.cards.m.MilitantAngel.class)); cards.add(new SetCardInfo("Mountain", 65, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 66, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nissa's Revelation", 47, Rarity.RARE, mage.cards.n.NissasRevelation.class)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java new file mode 100644 index 0000000000..69a12d8c92 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java @@ -0,0 +1,44 @@ + +package mage.abilities.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.game.Game; +import mage.watchers.common.PlayersAttackedThisTurnWatcher; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public class AttackedThisTurnOpponentsCount implements DynamicValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return this.calculate(game, sourceAbility.getControllerId()); + } + + public int calculate(Game game, UUID controllerId) { + PlayersAttackedThisTurnWatcher watcher = (PlayersAttackedThisTurnWatcher) game.getState().getWatchers().get(PlayersAttackedThisTurnWatcher.class.getSimpleName()); + if (watcher != null) { + return watcher.getAttackedOpponentsCount(controllerId); + } + return 0; + } + + @Override + public AttackedThisTurnOpponentsCount copy() { + return new AttackedThisTurnOpponentsCount(); + } + + @Override + public String toString() { + return "1"; + } + + @Override + public String getMessage() { + return "the number of opponents you attacked this turn"; + } +} diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index be845c2c26..c0fa488e20 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -1026,6 +1026,7 @@ public abstract class GameImpl implements Game, Serializable { watchers.add(new BlockedAttackerWatcher()); watchers.add(new DamageDoneWatcher()); watchers.add(new PlanarRollWatcher()); + watchers.add(new PlayersAttackedThisTurnWatcher()); //20100716 - 103.5 for (UUID playerId : state.getPlayerList(startingPlayerId)) { diff --git a/Mage/src/main/java/mage/watchers/common/PlayersAttackedThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/PlayersAttackedThisTurnWatcher.java new file mode 100644 index 0000000000..0099fb1267 --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/PlayersAttackedThisTurnWatcher.java @@ -0,0 +1,91 @@ +package mage.watchers.common; + +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.PlayerList; +import mage.watchers.Watcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @author JayDi85 + */ +public class PlayersAttackedThisTurnWatcher extends Watcher { + + // how many players or opponents each player attacked this turn + private final Map playersAttackedThisTurn = new HashMap<>(); + private final Map opponentsAttackedThisTurn = new HashMap<>(); + + public PlayersAttackedThisTurnWatcher() { + super(PlayersAttackedThisTurnWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public PlayersAttackedThisTurnWatcher(final PlayersAttackedThisTurnWatcher watcher) { + super(watcher); + + for (Map.Entry entry : watcher.playersAttackedThisTurn.entrySet()) { + this.playersAttackedThisTurn.put(entry.getKey(), entry.getValue()); + } + + for (Map.Entry entry : watcher.opponentsAttackedThisTurn.entrySet()) { + this.opponentsAttackedThisTurn.put(entry.getKey(), entry.getValue()); + } + } + + @Override + public PlayersAttackedThisTurnWatcher copy() { + return new PlayersAttackedThisTurnWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.BEGINNING_PHASE_PRE) { + playersAttackedThisTurn.clear(); + opponentsAttackedThisTurn.clear(); + } + + if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) { + + // players + PlayerList playersAttacked = playersAttackedThisTurn.get(event.getPlayerId()); + if (playersAttacked == null) { + playersAttacked = new PlayerList(); + } + UUID playerDefender = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); + if (playerDefender != null) { + playersAttacked.add(playerDefender); + } + playersAttackedThisTurn.put(event.getPlayerId(), playersAttacked); + + // opponents + PlayerList opponentsAttacked = opponentsAttackedThisTurn.get(event.getPlayerId()); + if (opponentsAttacked == null) { + opponentsAttacked = new PlayerList(); + } + UUID opponentDefender = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); + if (opponentDefender != null && game.getOpponents(event.getPlayerId()).contains(opponentDefender)) { + opponentsAttacked.add(opponentDefender); + } + opponentsAttackedThisTurn.put(event.getPlayerId(), opponentsAttacked); + } + } + + public int getAttackedPlayersCount(UUID playerID) { + PlayerList defendersList = playersAttackedThisTurn.getOrDefault(playerID, null); + if (defendersList != null) { + return defendersList.size(); + } + return 0; + } + + public int getAttackedOpponentsCount(UUID playerID) { + PlayerList defendersList = opponentsAttackedThisTurn.getOrDefault(playerID, null); + if (defendersList != null) { + return defendersList.size(); + } + return 0; + } +}