From abc0d0b68f7c7105f8bdd00cdf6999903d9156b1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 15 Sep 2018 19:29:19 +0200 Subject: [PATCH] [GRN] Added Venerated Loxodon. --- .../src/mage/cards/v/VeneratedLoxodon.java | 145 ++++++++++++++++++ Mage.Sets/src/mage/sets/GuildsOfRavnica.java | 1 + .../abilities/keyword/ConvokeAbility.java | 3 +- .../main/java/mage/game/events/GameEvent.java | 6 + 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/v/VeneratedLoxodon.java diff --git a/Mage.Sets/src/mage/cards/v/VeneratedLoxodon.java b/Mage.Sets/src/mage/cards/v/VeneratedLoxodon.java new file mode 100644 index 00000000000..34a41b9ab46 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeneratedLoxodon.java @@ -0,0 +1,145 @@ +package mage.cards.v; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.ConvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.WatcherScope; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.watchers.Watcher; + +/** + * + * @author LevelX2 + */ +public final class VeneratedLoxodon extends CardImpl { + + public VeneratedLoxodon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.subtype.add(SubType.ELEPHANT); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Convoke + this.addAbility(new ConvokeAbility()); + + // When Venerated Loxodon enters the battlefield, put a +1/+1 counter on each creature that convoked it. + this.addAbility(new EntersBattlefieldTriggeredAbility(new VeneratedLoxodonEffect(), false), new VeneratedLoxodonWatcher()); + } + + public VeneratedLoxodon(final VeneratedLoxodon card) { + super(card); + } + + @Override + public VeneratedLoxodon copy() { + return new VeneratedLoxodon(this); + } +} + +class VeneratedLoxodonEffect extends OneShotEffect { + + public VeneratedLoxodonEffect() { + super(Outcome.BoostCreature); + this.staticText = "put a +1/+1 counter on each creature that convoked it"; + } + + public VeneratedLoxodonEffect(final VeneratedLoxodonEffect effect) { + super(effect); + } + + @Override + public VeneratedLoxodonEffect copy() { + return new VeneratedLoxodonEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + VeneratedLoxodonWatcher watcher = (VeneratedLoxodonWatcher) game.getState().getWatchers().get(VeneratedLoxodonWatcher.class.getSimpleName()); + if (watcher != null) { + MageObjectReference mor = new MageObjectReference(source.getSourceId(), source.getSourceObjectZoneChangeCounter() - 1, game); // -1 because of spell on the stack + Set creatures = watcher.getConvokingCreatures(mor); + if (creatures != null) { + for (MageObjectReference creatureMOR : creatures) { + Permanent creature = creatureMOR.getPermanent(game); + if (creature != null) { + creature.addCounters(CounterType.P1P1.createInstance(), source, game); + } + } + } + return true; + } + return false; + } +} + +class VeneratedLoxodonWatcher extends Watcher { + + private final Map> convokingCreatures = new HashMap<>(); + + public VeneratedLoxodonWatcher() { + super(VeneratedLoxodonWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public VeneratedLoxodonWatcher(final VeneratedLoxodonWatcher watcher) { + super(watcher); + for (Entry> entry : watcher.convokingCreatures.entrySet()) { + Set creatures = new HashSet<>(); + creatures.addAll(entry.getValue()); + convokingCreatures.put(entry.getKey(), creatures); + } + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.CONVOKED) { + Spell spell = game.getSpell(event.getSourceId()); + Permanent tappedCreature = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (spell != null && tappedCreature != null) { + MageObjectReference convokedSpell = new MageObjectReference(spell.getSourceId(), game); + Set creatures; + if (convokingCreatures.containsKey(convokedSpell)) { + creatures = convokingCreatures.get(convokedSpell); + } else { + creatures = new HashSet<>(); + convokingCreatures.put(convokedSpell, creatures); + } + creatures.add(new MageObjectReference(tappedCreature, game)); + } + } + } + + public Set getConvokingCreatures(MageObjectReference mor) { + return convokingCreatures.get(mor); + } + + @Override + public void reset() { + super.reset(); + convokingCreatures.clear(); + } + + @Override + public VeneratedLoxodonWatcher copy() { + return new VeneratedLoxodonWatcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/GuildsOfRavnica.java b/Mage.Sets/src/mage/sets/GuildsOfRavnica.java index 6279463cb34..f6b44056c2a 100644 --- a/Mage.Sets/src/mage/sets/GuildsOfRavnica.java +++ b/Mage.Sets/src/mage/sets/GuildsOfRavnica.java @@ -163,6 +163,7 @@ public final class GuildsOfRavnica extends ExpansionSet { cards.add(new SetCardInfo("Truefire Captain", 209, Rarity.UNCOMMON, mage.cards.t.TruefireCaptain.class)); cards.add(new SetCardInfo("Underrealm Lich", 211, Rarity.MYTHIC, mage.cards.u.UnderrealmLich.class)); cards.add(new SetCardInfo("Unexplained Disappearance", 56, Rarity.COMMON, mage.cards.u.UnexplainedDisappearance.class)); + cards.add(new SetCardInfo("Venerated Loxodon", 30, Rarity.RARE, mage.cards.v.VeneratedLoxodon.class)); cards.add(new SetCardInfo("Vivid Revival", 148, Rarity.RARE, mage.cards.v.VividRevival.class)); cards.add(new SetCardInfo("Vraska's Stoneglare", 272, Rarity.RARE, mage.cards.v.VraskasStoneglare.class)); cards.add(new SetCardInfo("Vraska, Golgari Queen", 213, Rarity.MYTHIC, mage.cards.v.VraskaGolgariQueen.class)); diff --git a/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java b/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java index a863da01c28..afba2dcd995 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.keyword; import java.util.ArrayList; @@ -25,6 +24,7 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.filter.predicate.permanent.TappedPredicate; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.ManaPool; import mage.players.Player; @@ -223,6 +223,7 @@ class ConvokeEffect extends OneShotEffect { manaPool.unlockManaType(ManaType.COLORLESS); manaName = "colorless"; } + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CONVOKED, perm.getId(), source.getSourceId(), source.getControllerId())); game.informPlayers("Convoke: " + controller.getLogName() + " taps " + perm.getLogName() + " to pay one " + manaName + " mana"); } diff --git a/Mage/src/main/java/mage/game/events/GameEvent.java b/Mage/src/main/java/mage/game/events/GameEvent.java index 6678cd8fdfb..eeb746ce952 100644 --- a/Mage/src/main/java/mage/game/events/GameEvent.java +++ b/Mage/src/main/java/mage/game/events/GameEvent.java @@ -72,6 +72,12 @@ public class GameEvent implements Serializable { MADNESS_CARD_EXILED, INVESTIGATED, KICKED, + /* CONVOKED + targetId id of the creature that was taped to convoke the sourceId + sourceId sourceId of the convoked spell + playerId controller of the convoked spell + */ + CONVOKED, DISCARD_CARD, DISCARDED_CARD, CYCLE_CARD, CYCLED_CARD,