diff --git a/Mage.Sets/src/mage/cards/g/GargoyleFlock.java b/Mage.Sets/src/mage/cards/g/GargoyleFlock.java new file mode 100644 index 0000000000..27245eadbc --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GargoyleFlock.java @@ -0,0 +1,49 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.condition.common.CreatureEnteredUnderYourControlCondition; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.game.permanent.token.TyranidGargoyleToken; +import mage.watchers.common.CreatureEnteredControllerWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GargoyleFlock extends CardImpl { + + public GargoyleFlock(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); + + this.subtype.add(SubType.TYRANID); + this.subtype.add(SubType.GARGOYLE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Skyswarm -- At the beginning of your end step, if a creature entered the battlefield under your control this turn, create a 1/1 blue Tyranid Gargoyle creature token with flying. + this.addAbility(new BeginningOfEndStepTriggeredAbility( + new CreateTokenEffect(new TyranidGargoyleToken()), TargetController.YOU, + CreatureEnteredUnderYourControlCondition.instance, false + ).withFlavorWord("Skyswarm"), new CreatureEnteredControllerWatcher()); + } + + private GargoyleFlock(final GargoyleFlock card) { + super(card); + } + + @Override + public GargoyleFlock copy() { + return new GargoyleFlock(this); + } +} diff --git a/Mage.Sets/src/mage/cards/z/ZhalfirinDecoy.java b/Mage.Sets/src/mage/cards/z/ZhalfirinDecoy.java index e4047b37cc..9b7aa39653 100644 --- a/Mage.Sets/src/mage/cards/z/ZhalfirinDecoy.java +++ b/Mage.Sets/src/mage/cards/z/ZhalfirinDecoy.java @@ -10,16 +10,11 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.target.common.TargetCreaturePermanent; -import mage.watchers.Watcher; +import mage.watchers.common.CreatureEnteredControllerWatcher; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -37,10 +32,11 @@ public final class ZhalfirinDecoy extends CardImpl { // {T}: Tap target creature. Activate this ability only if you had a creature enter the battlefield under your control this turn. Ability ability = new ActivateIfConditionActivatedAbility( - Zone.BATTLEFIELD, new TapTargetEffect(), new TapSourceCost(), ZhalfirinDecoyCondition.instance + Zone.BATTLEFIELD, new TapTargetEffect(), + new TapSourceCost(), ZhalfirinDecoyCondition.instance ); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability, new ZhalfirinDecoyWatcher()); + this.addAbility(ability, new CreatureEnteredControllerWatcher()); } private ZhalfirinDecoy(final ZhalfirinDecoy card) { @@ -58,8 +54,7 @@ enum ZhalfirinDecoyCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - ZhalfirinDecoyWatcher watcher = game.getState().getWatcher(ZhalfirinDecoyWatcher.class); - return watcher != null && watcher.enteredCreatureForPlayer(source.getControllerId()); + return CreatureEnteredControllerWatcher.enteredCreatureForPlayer(source.getControllerId(), game); } @Override @@ -67,33 +62,3 @@ enum ZhalfirinDecoyCondition implements Condition { return "you had a creature enter the battlefield under your control this turn"; } } - -class ZhalfirinDecoyWatcher extends Watcher { - - private final Set players = new HashSet<>(); - - ZhalfirinDecoyWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getToZone() == Zone.BATTLEFIELD - && zEvent.getTarget().isCreature(game)) { - players.add(zEvent.getTarget().getControllerId()); - } - } - } - - @Override - public void reset() { - players.clear(); - } - - boolean enteredCreatureForPlayer(UUID playerId) { - return players.contains(playerId); - } - -} diff --git a/Mage.Sets/src/mage/sets/Warhammer40000.java b/Mage.Sets/src/mage/sets/Warhammer40000.java index ea983261c3..4a26ebaa7b 100644 --- a/Mage.Sets/src/mage/sets/Warhammer40000.java +++ b/Mage.Sets/src/mage/sets/Warhammer40000.java @@ -63,6 +63,7 @@ public final class Warhammer40000 extends ExpansionSet { cards.add(new SetCardInfo("Forgotten Cave", 280, Rarity.COMMON, mage.cards.f.ForgottenCave.class)); cards.add(new SetCardInfo("Frontier Bivouac", 281, Rarity.UNCOMMON, mage.cards.f.FrontierBivouac.class)); cards.add(new SetCardInfo("Game Trail", 282, Rarity.RARE, mage.cards.g.GameTrail.class)); + cards.add(new SetCardInfo("Gargoyle Flock", 123, Rarity.RARE, mage.cards.g.GargoyleFlock.class)); cards.add(new SetCardInfo("Goliath Truck", 158, Rarity.UNCOMMON, mage.cards.g.GoliathTruck.class)); cards.add(new SetCardInfo("Hardened Scales", 215, Rarity.RARE, mage.cards.h.HardenedScales.class)); cards.add(new SetCardInfo("Harrow", 216, Rarity.COMMON, mage.cards.h.Harrow.class)); diff --git a/Mage/src/main/java/mage/abilities/condition/common/CreatureEnteredUnderYourControlCondition.java b/Mage/src/main/java/mage/abilities/condition/common/CreatureEnteredUnderYourControlCondition.java new file mode 100644 index 0000000000..566804eacd --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/CreatureEnteredUnderYourControlCondition.java @@ -0,0 +1,23 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; +import mage.watchers.common.CreatureEnteredControllerWatcher; + +/** + * @author TheElk801 + */ +public enum CreatureEnteredUnderYourControlCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return CreatureEnteredControllerWatcher.enteredCreatureForPlayer(source.getControllerId(), game); + } + + @Override + public String toString() { + return "a creature entered the battlefield under your control this turn"; + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/TyranidGargoyleToken.java b/Mage/src/main/java/mage/game/permanent/token/TyranidGargoyleToken.java new file mode 100644 index 0000000000..86111bdf5d --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/TyranidGargoyleToken.java @@ -0,0 +1,37 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.Arrays; + +/** + * @author TheElk801 + */ +public final class TyranidGargoyleToken extends TokenImpl { + + public TyranidGargoyleToken() { + super("Tyranid Gargoyle Token", "1/1 blue Tyranid creature token with flying"); + cardType.add(CardType.CREATURE); + color.setBlue(true); + subtype.add(SubType.TYRANID); + subtype.add(SubType.GARGOYLE); + power = new MageInt(1); + toughness = new MageInt(1); + + addAbility(FlyingAbility.getInstance()); + + availableImageSetCodes.addAll(Arrays.asList("40K")); + } + + public TyranidGargoyleToken(final TyranidGargoyleToken token) { + super(token); + } + + @Override + public TyranidGargoyleToken copy() { + return new TyranidGargoyleToken(this); + } +} diff --git a/Mage/src/main/java/mage/watchers/common/CreatureEnteredControllerWatcher.java b/Mage/src/main/java/mage/watchers/common/CreatureEnteredControllerWatcher.java new file mode 100644 index 0000000000..e26d428c52 --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/CreatureEnteredControllerWatcher.java @@ -0,0 +1,48 @@ +package mage.watchers.common; + +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class CreatureEnteredControllerWatcher extends Watcher { + + private final Set players = new HashSet<>(); + + public CreatureEnteredControllerWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getToZone() == Zone.BATTLEFIELD + && zEvent.getTarget().isCreature(game)) { + players.add(zEvent.getTarget().getControllerId()); + } + } + } + + @Override + public void reset() { + players.clear(); + } + + public static boolean enteredCreatureForPlayer(UUID playerId, Game game) { + return game + .getState() + .getWatcher(CreatureEnteredControllerWatcher.class) + .players + .contains(playerId); + } +}