From ca8721e4f986742c29c46063c4f4861f256a3124 Mon Sep 17 00:00:00 2001 From: Noah Gleason Date: Fri, 22 Jun 2018 00:09:32 -0400 Subject: [PATCH 1/4] Implement Giant Albatross --- .../src/mage/cards/g/GiantAlbatross.java | 110 ++++++++++++++++++ Mage.Sets/src/mage/sets/Homelands.java | 2 + .../watchers/common/DealtDamageToWatcher.java | 64 ++++++++++ 3 files changed, 176 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GiantAlbatross.java create mode 100644 Mage/src/main/java/mage/watchers/common/DealtDamageToWatcher.java diff --git a/Mage.Sets/src/mage/cards/g/GiantAlbatross.java b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java new file mode 100644 index 00000000000..33e3ec355d2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java @@ -0,0 +1,110 @@ +package mage.cards.g; + +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.watchers.Watcher; +import mage.watchers.common.DealtDamageToWatcher; +import mage.watchers.common.PlayerDamagedBySourceWatcher; + +/** + * + * @author noahg + */ +public final class GiantAlbatross extends CardImpl { + + public GiantAlbatross(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.BIRD); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Giant Albatross dies, you may pay {1}{U}. If you do, for each creature that dealt damage to Giant Albatross this turn, destroy that creature unless its controller pays 2 life. A creature destroyed this way can't be regenerated. + Ability ability = new DiesTriggeredAbility(new DoIfCostPaid(new GiantAlbatrossEffect(), new ManaCostsImpl("{1}{U}"))); + DealtDamageToWatcher watcher = new DealtDamageToWatcher(); + watcher.setSourceId(this.objectId); + ability.addWatcher(watcher); + this.addAbility(ability); + } + + public GiantAlbatross(final GiantAlbatross card) { + super(card); + } + + @Override + public GiantAlbatross copy() { + return new GiantAlbatross(this); + } +} + +class GiantAlbatrossEffect extends OneShotEffect { + + public GiantAlbatrossEffect() { + super(Outcome.Detriment); + this.staticText = "for each creature that dealt damage to {this} this turn, destroy that creature unless its controller pays 2 life. A creature destroyed this way can’t be regenerated"; + } + + public GiantAlbatrossEffect(final GiantAlbatrossEffect effect) { + super(effect); + } + + @Override + public GiantAlbatrossEffect copy() { + return new GiantAlbatrossEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + DealtDamageToWatcher watcher = (DealtDamageToWatcher) game.getState().getWatchers().get(DealtDamageToWatcher.class.getSimpleName(), source.getSourceId()); + System.out.println("Dealt damage: "+watcher.dealtDamageToSource); + for (MageObjectReference mageObjectReference : watcher.dealtDamageToSource){ + System.out.println(mageObjectReference.getCard(game).getName()); + System.out.println(mageObjectReference.getCard(game).getLogName()); + } + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + List creatures = game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game); + + Cost cost = new PayLifeCost(2); + for (Permanent creature : creatures) { + if (watcher.didDamage(creature, game)) { + final StringBuilder sb = new StringBuilder("Pay 2 life? (Otherwise ").append(creature.getName()).append(" will be destroyed)"); + if (cost.canPay(source, creature.getControllerId(), creature.getControllerId(), game) && player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { + cost.pay(source, game, creature.getControllerId(), creature.getControllerId(), true, null); + } + if (!cost.isPaid()) { + creature.destroy(source.getSourceId(), game, true); + } + } + } + } + } + + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index 5de1fb7d4e6..f867f332d38 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -103,6 +103,8 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Forget", 26, Rarity.RARE, mage.cards.f.Forget.class)); cards.add(new SetCardInfo("Funeral March", 48, Rarity.UNCOMMON, mage.cards.f.FuneralMarch.class)); cards.add(new SetCardInfo("Ghost Hounds", 49, Rarity.UNCOMMON, mage.cards.g.GhostHounds.class)); + cards.add(new SetCardInfo("Giant Albatross", "34a", Rarity.COMMON, mage.cards.g.GiantAlbatross.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Giant Albatross", "34b", Rarity.COMMON, mage.cards.g.GiantAlbatross.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grandmother Sengir", 50, Rarity.RARE, mage.cards.g.GrandmotherSengir.class)); cards.add(new SetCardInfo("Greater Werewolf", 51, Rarity.UNCOMMON, mage.cards.g.GreaterWerewolf.class)); cards.add(new SetCardInfo("Hazduhr the Abbot", 8, Rarity.RARE, mage.cards.h.HazduhrTheAbbot.class)); diff --git a/Mage/src/main/java/mage/watchers/common/DealtDamageToWatcher.java b/Mage/src/main/java/mage/watchers/common/DealtDamageToWatcher.java new file mode 100644 index 00000000000..3862841bb7f --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/DealtDamageToWatcher.java @@ -0,0 +1,64 @@ +package mage.watchers.common; + +import mage.MageObject; +import mage.MageObjectReference; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public class DealtDamageToWatcher extends Watcher { + + public final Set dealtDamageToSource = new HashSet<>(); + + public DealtDamageToWatcher() { + super(DealtDamageToWatcher.class.getSimpleName(), WatcherScope.CARD); + } + + public DealtDamageToWatcher(final DealtDamageToWatcher watcher) { + super(watcher); + this.dealtDamageToSource.addAll(watcher.dealtDamageToSource); + } + + @Override + public DealtDamageToWatcher copy() { + return new DealtDamageToWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + boolean eventHasAppropriateType = event.getType() == GameEvent.EventType.DAMAGED_CREATURE || + event.getType() == GameEvent.EventType.DAMAGED_PLANESWALKER; + if (eventHasAppropriateType && sourceId.equals(event.getTargetId())) { + MageObjectReference mor = new MageObjectReference(event.getSourceId(), game); + dealtDamageToSource.add(mor); + } + } + + @Override + public void reset() { + super.reset(); + dealtDamageToSource.clear(); + } + + public boolean didDamage(UUID sourceId, Game game) { + MageObject mageObject = game.getObject(sourceId); + if (mageObject != null) { + return didDamage(new MageObjectReference(mageObject, game)); + } + return false; + } + + private boolean didDamage(MageObjectReference objectReference) { + return dealtDamageToSource.contains(objectReference); + } + + public boolean didDamage(Permanent permanent, Game game) { + return dealtDamageToSource.contains(new MageObjectReference(permanent, game)); + } +} From d1192661bc7ea3e7bf9f0fb9efdd3ec36241bc3e Mon Sep 17 00:00:00 2001 From: Noah Gleason Date: Fri, 22 Jun 2018 12:17:24 -0400 Subject: [PATCH 2/4] Remove debug logging --- Mage.Sets/src/mage/cards/g/GiantAlbatross.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GiantAlbatross.java b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java index 33e3ec355d2..93abfbfc03d 100644 --- a/Mage.Sets/src/mage/cards/g/GiantAlbatross.java +++ b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java @@ -80,11 +80,6 @@ class GiantAlbatrossEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); DealtDamageToWatcher watcher = (DealtDamageToWatcher) game.getState().getWatchers().get(DealtDamageToWatcher.class.getSimpleName(), source.getSourceId()); - System.out.println("Dealt damage: "+watcher.dealtDamageToSource); - for (MageObjectReference mageObjectReference : watcher.dealtDamageToSource){ - System.out.println(mageObjectReference.getCard(game).getName()); - System.out.println(mageObjectReference.getCard(game).getLogName()); - } for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { From a1bfe071c80109394bb1f2bb9d042aca17a35e75 Mon Sep 17 00:00:00 2001 From: Noah Gleason Date: Sat, 23 Jun 2018 14:41:14 -0400 Subject: [PATCH 3/4] Switch from Watcher to getDealtDamageByThisTurn() --- .../src/mage/cards/g/GiantAlbatross.java | 33 +++++++++---------- Mage.Sets/src/mage/sets/Homelands.java | 4 +-- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GiantAlbatross.java b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java index 93abfbfc03d..b9ec60ce36a 100644 --- a/Mage.Sets/src/mage/cards/g/GiantAlbatross.java +++ b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java @@ -44,9 +44,6 @@ public final class GiantAlbatross extends CardImpl { // When Giant Albatross dies, you may pay {1}{U}. If you do, for each creature that dealt damage to Giant Albatross this turn, destroy that creature unless its controller pays 2 life. A creature destroyed this way can't be regenerated. Ability ability = new DiesTriggeredAbility(new DoIfCostPaid(new GiantAlbatrossEffect(), new ManaCostsImpl("{1}{U}"))); - DealtDamageToWatcher watcher = new DealtDamageToWatcher(); - watcher.setSourceId(this.objectId); - ability.addWatcher(watcher); this.addAbility(ability); } @@ -79,21 +76,23 @@ class GiantAlbatrossEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - DealtDamageToWatcher watcher = (DealtDamageToWatcher) game.getState().getWatchers().get(DealtDamageToWatcher.class.getSimpleName(), source.getSourceId()); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - List creatures = game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourcePermanent != null) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + List creatures = game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game); - Cost cost = new PayLifeCost(2); - for (Permanent creature : creatures) { - if (watcher.didDamage(creature, game)) { - final StringBuilder sb = new StringBuilder("Pay 2 life? (Otherwise ").append(creature.getName()).append(" will be destroyed)"); - if (cost.canPay(source, creature.getControllerId(), creature.getControllerId(), game) && player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { - cost.pay(source, game, creature.getControllerId(), creature.getControllerId(), true, null); - } - if (!cost.isPaid()) { - creature.destroy(source.getSourceId(), game, true); + Cost cost = new PayLifeCost(2); + for (Permanent creature : creatures) { + if (sourcePermanent.getDealtDamageByThisTurn().contains(new MageObjectReference(creature.getId(), game))) { + final StringBuilder sb = new StringBuilder("Pay 2 life? (Otherwise ").append(creature.getName()).append(" will be destroyed)"); + if (cost.canPay(source, creature.getControllerId(), creature.getControllerId(), game) && player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { + cost.pay(source, game, creature.getControllerId(), creature.getControllerId(), true, null); + } + if (!cost.isPaid()) { + creature.destroy(source.getSourceId(), game, true); + } } } } diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index f867f332d38..2b22d743b6d 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -103,8 +103,8 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Forget", 26, Rarity.RARE, mage.cards.f.Forget.class)); cards.add(new SetCardInfo("Funeral March", 48, Rarity.UNCOMMON, mage.cards.f.FuneralMarch.class)); cards.add(new SetCardInfo("Ghost Hounds", 49, Rarity.UNCOMMON, mage.cards.g.GhostHounds.class)); - cards.add(new SetCardInfo("Giant Albatross", "34a", Rarity.COMMON, mage.cards.g.GiantAlbatross.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Giant Albatross", "34b", Rarity.COMMON, mage.cards.g.GiantAlbatross.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Giant Albatross", "27a", Rarity.COMMON, mage.cards.g.GiantAlbatross.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Giant Albatross", "27b", Rarity.COMMON, mage.cards.g.GiantAlbatross.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grandmother Sengir", 50, Rarity.RARE, mage.cards.g.GrandmotherSengir.class)); cards.add(new SetCardInfo("Greater Werewolf", 51, Rarity.UNCOMMON, mage.cards.g.GreaterWerewolf.class)); cards.add(new SetCardInfo("Hazduhr the Abbot", 8, Rarity.RARE, mage.cards.h.HazduhrTheAbbot.class)); From 2f936c7c7896e126573b3d4abe68c8a008e1a452 Mon Sep 17 00:00:00 2001 From: Noah Gleason Date: Sun, 24 Jun 2018 21:55:15 -0400 Subject: [PATCH 4/4] Remove useless watcher --- .../src/mage/cards/g/GiantAlbatross.java | 13 ++-- .../watchers/common/DealtDamageToWatcher.java | 64 ------------------- 2 files changed, 5 insertions(+), 72 deletions(-) delete mode 100644 Mage/src/main/java/mage/watchers/common/DealtDamageToWatcher.java diff --git a/Mage.Sets/src/mage/cards/g/GiantAlbatross.java b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java index b9ec60ce36a..d2c05f3e8cd 100644 --- a/Mage.Sets/src/mage/cards/g/GiantAlbatross.java +++ b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java @@ -1,7 +1,5 @@ package mage.cards.g; -import java.util.List; -import java.util.UUID; import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; @@ -11,20 +9,19 @@ import mage.abilities.costs.common.PayLifeCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.cards.Card; -import mage.constants.Outcome; -import mage.constants.SubType; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.watchers.Watcher; -import mage.watchers.common.DealtDamageToWatcher; -import mage.watchers.common.PlayerDamagedBySourceWatcher; + +import java.util.List; +import java.util.UUID; /** * diff --git a/Mage/src/main/java/mage/watchers/common/DealtDamageToWatcher.java b/Mage/src/main/java/mage/watchers/common/DealtDamageToWatcher.java deleted file mode 100644 index 3862841bb7f..00000000000 --- a/Mage/src/main/java/mage/watchers/common/DealtDamageToWatcher.java +++ /dev/null @@ -1,64 +0,0 @@ -package mage.watchers.common; - -import mage.MageObject; -import mage.MageObjectReference; -import mage.constants.WatcherScope; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.watchers.Watcher; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -public class DealtDamageToWatcher extends Watcher { - - public final Set dealtDamageToSource = new HashSet<>(); - - public DealtDamageToWatcher() { - super(DealtDamageToWatcher.class.getSimpleName(), WatcherScope.CARD); - } - - public DealtDamageToWatcher(final DealtDamageToWatcher watcher) { - super(watcher); - this.dealtDamageToSource.addAll(watcher.dealtDamageToSource); - } - - @Override - public DealtDamageToWatcher copy() { - return new DealtDamageToWatcher(this); - } - - @Override - public void watch(GameEvent event, Game game) { - boolean eventHasAppropriateType = event.getType() == GameEvent.EventType.DAMAGED_CREATURE || - event.getType() == GameEvent.EventType.DAMAGED_PLANESWALKER; - if (eventHasAppropriateType && sourceId.equals(event.getTargetId())) { - MageObjectReference mor = new MageObjectReference(event.getSourceId(), game); - dealtDamageToSource.add(mor); - } - } - - @Override - public void reset() { - super.reset(); - dealtDamageToSource.clear(); - } - - public boolean didDamage(UUID sourceId, Game game) { - MageObject mageObject = game.getObject(sourceId); - if (mageObject != null) { - return didDamage(new MageObjectReference(mageObject, game)); - } - return false; - } - - private boolean didDamage(MageObjectReference objectReference) { - return dealtDamageToSource.contains(objectReference); - } - - public boolean didDamage(Permanent permanent, Game game) { - return dealtDamageToSource.contains(new MageObjectReference(permanent, game)); - } -}