[VOW] Implemented Jacob Hauken, Inspector / Hauken's Insight

This commit is contained in:
Daniel Bomar 2021-11-11 10:48:33 -06:00
parent 8716ecdb3d
commit 24fab24440
No known key found for this signature in database
GPG key ID: C86C8658F4023918
4 changed files with 340 additions and 0 deletions

View file

@ -0,0 +1,201 @@
package mage.cards.h;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageIdentifier;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import mage.watchers.Watcher;
/**
*
* @author weirddan455
*/
public final class HaukensInsight extends CardImpl {
public HaukensInsight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "");
this.addSuperType(SuperType.LEGENDARY);
this.color.setBlue(true);
// Back half of Jacob Hauken, Inspector
this.nightCard = true;
// At the beginning of your upkeep, exile the top card of your library face down. You may look at that card for as long as it remains exiled.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new HaukensInsightExileEffect(), TargetController.YOU, false));
// Once during each of your turns, you may play a land or cast a spell from among the cards exiled with this permanent without paying its mana cost.
this.addAbility(new SimpleStaticAbility(new HaukensInsightPlayEffect())
.setIdentifier(MageIdentifier.HaukensInsightWatcher),
new HaukensInsightWatcher());
}
private HaukensInsight(final HaukensInsight card) {
super(card);
}
@Override
public HaukensInsight copy() {
return new HaukensInsight(this);
}
}
class HaukensInsightExileEffect extends OneShotEffect {
public HaukensInsightExileEffect() {
super(Outcome.Benefit);
staticText = "exile the top card of your library face down. You may look at that card for as long as it remains exiled";
}
private HaukensInsightExileEffect(final HaukensInsightExileEffect effect) {
super(effect);
}
@Override
public HaukensInsightExileEffect copy() {
return new HaukensInsightExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = controller.getLibrary().getFromTop(game);
if (card != null) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
MageObject sourceObject = source.getSourceObject(game);
String exileName = sourceObject == null ? null : sourceObject.getIdName();
controller.moveCardsToExile(card, source, game, true, exileId, exileName);
if (game.getState().getZone(card.getId()) == Zone.EXILED) {
card.setFaceDown(true, game);
HaukensInsightLookEffect effect = new HaukensInsightLookEffect(controller.getId());
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
return true;
}
}
}
return false;
}
}
class HaukensInsightLookEffect extends AsThoughEffectImpl {
private final UUID authorizedPlayerId;
public HaukensInsightLookEffect(UUID authorizedPlayerId) {
super(AsThoughEffectType.LOOK_AT_FACE_DOWN, Duration.EndOfGame, Outcome.Benefit);
this.authorizedPlayerId = authorizedPlayerId;
}
private HaukensInsightLookEffect(final HaukensInsightLookEffect effect) {
super(effect);
this.authorizedPlayerId = effect.authorizedPlayerId;
}
@Override
public HaukensInsightLookEffect copy() {
return new HaukensInsightLookEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
UUID cardId = getTargetPointer().getFirst(game, source);
if (cardId == null) {
this.discard(); // card is no longer in the origin zone, effect can be discarded
}
return affectedControllerId.equals(authorizedPlayerId)
&& objectId.equals(cardId);
}
}
class HaukensInsightPlayEffect extends AsThoughEffectImpl {
public HaukensInsightPlayEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.PlayForFree, true);
staticText = "Once during each of your turns, you may play a land or cast a spell from among the cards exiled with this permanent without paying its mana cost";
}
private HaukensInsightPlayEffect(final HaukensInsightPlayEffect effect) {
super(effect);
}
@Override
public HaukensInsightPlayEffect copy() {
return new HaukensInsightPlayEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (affectedControllerId.equals(source.getControllerId()) && game.isActivePlayer(source.getControllerId())) {
Player controller = game.getPlayer(source.getControllerId());
HaukensInsightWatcher watcher = game.getState().getWatcher(HaukensInsightWatcher.class);
Permanent sourceObject = game.getPermanent(source.getSourceId());
if (controller != null && watcher != null && sourceObject != null && !watcher.isAbilityUsed(new MageObjectReference(sourceObject, game))) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()));
ExileZone exileZone = game.getExile().getExileZone(exileId);
if (exileZone != null && exileZone.contains(CardUtil.getMainCardId(game, objectId))) {
allowCardToPlayWithoutMana(objectId, source, affectedControllerId, game);
return true;
}
}
}
return false;
}
}
class HaukensInsightWatcher extends Watcher {
private final Set<MageObjectReference> usedFrom = new HashSet<>();
public HaukensInsightWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.LAND_PLAYED) {
if (event.hasApprovingIdentifier(MageIdentifier.HaukensInsightWatcher)) {
usedFrom.add(event.getAdditionalReference().getApprovingMageObjectReference());
}
}
}
@Override
public void reset() {
super.reset();
usedFrom.clear();
}
public boolean isAbilityUsed(MageObjectReference mor) {
return usedFrom.contains(mor);
}
}

View file

@ -0,0 +1,136 @@
package mage.cards.j;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.Card;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
*
* @author weirddan455
*/
public final class JacobHaukenInspector extends CardImpl {
public JacobHaukenInspector(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ADVISOR);
this.power = new MageInt(0);
this.toughness = new MageInt(2);
this.secondSideCardClazz = mage.cards.h.HaukensInsight.class;
// {T}: Draw a card, then exile a card from your hand face down. You may look at that card for as long as it remains exiled. You may pay {4}{U}{U}. If you do, transform Jacob Hauken, Inspector.
this.addAbility(new TransformAbility());
Ability ability = new SimpleActivatedAbility(new JacobHaukenInspectorExileEffect(), new TapSourceCost());
ability.addEffect(new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{U}{U}")));
this.addAbility(ability);
}
private JacobHaukenInspector(final JacobHaukenInspector card) {
super(card);
}
@Override
public JacobHaukenInspector copy() {
return new JacobHaukenInspector(this);
}
}
class JacobHaukenInspectorExileEffect extends OneShotEffect {
public JacobHaukenInspectorExileEffect() {
super(Outcome.Benefit);
staticText = "Draw a card, then exile a card from your hand face down. You may look at that card for as long as it remains exiled";
}
private JacobHaukenInspectorExileEffect(final JacobHaukenInspectorExileEffect effect) {
super(effect);
}
@Override
public JacobHaukenInspectorExileEffect copy() {
return new JacobHaukenInspectorExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
controller.drawCards(1, source, game);
if (!controller.getHand().isEmpty()) {
TargetCardInHand target = new TargetCardInHand().withChooseHint("to exile");
controller.chooseTarget(outcome, controller.getHand(), target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
MageObject sourceObject = source.getSourceObject(game);
String exileName = sourceObject == null ? null : sourceObject.getIdName();
controller.moveCardsToExile(card, source, game, true, exileId, exileName);
if (game.getState().getZone(card.getId()) == Zone.EXILED) {
card.setFaceDown(true, game);
JacobHaukenInspectorLookEffect effect = new JacobHaukenInspectorLookEffect(controller.getId());
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
}
}
}
return true;
}
}
class JacobHaukenInspectorLookEffect extends AsThoughEffectImpl {
private final UUID authorizedPlayerId;
public JacobHaukenInspectorLookEffect(UUID authorizedPlayerId) {
super(AsThoughEffectType.LOOK_AT_FACE_DOWN, Duration.EndOfGame, Outcome.Benefit);
this.authorizedPlayerId = authorizedPlayerId;
}
private JacobHaukenInspectorLookEffect(final JacobHaukenInspectorLookEffect effect) {
super(effect);
this.authorizedPlayerId = effect.authorizedPlayerId;
}
@Override
public JacobHaukenInspectorLookEffect copy() {
return new JacobHaukenInspectorLookEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
UUID cardId = getTargetPointer().getFirst(game, source);
if (cardId == null) {
this.discard(); // card is no longer in the origin zone, effect can be discarded
}
return affectedControllerId.equals(authorizedPlayerId)
&& objectId.equals(cardId);
}
}

View file

@ -171,6 +171,7 @@ public final class InnistradCrimsonVow extends ExpansionSet {
cards.add(new SetCardInfo("Halana and Alena, Partners", 239, Rarity.RARE, mage.cards.h.HalanaAndAlenaPartners.class));
cards.add(new SetCardInfo("Hallowed Haunting", 17, Rarity.MYTHIC, mage.cards.h.HallowedHaunting.class));
cards.add(new SetCardInfo("Hamlet Vanguard", 201, Rarity.RARE, mage.cards.h.HamletVanguard.class));
cards.add(new SetCardInfo("Hauken's Insight", 65, Rarity.MYTHIC, mage.cards.h.HaukensInsight.class));
cards.add(new SetCardInfo("Headless Rider", 118, Rarity.RARE, mage.cards.h.HeadlessRider.class));
cards.add(new SetCardInfo("Henrika Domnathi", 119, Rarity.MYTHIC, mage.cards.h.HenrikaDomnathi.class));
cards.add(new SetCardInfo("Henrika, Infernal Seer", 119, Rarity.MYTHIC, mage.cards.h.HenrikaInfernalSeer.class));
@ -194,6 +195,7 @@ public final class InnistradCrimsonVow extends ExpansionSet {
cards.add(new SetCardInfo("Into the Night", 163, Rarity.UNCOMMON, mage.cards.i.IntoTheNight.class));
cards.add(new SetCardInfo("Investigator's Journal", 258, Rarity.RARE, mage.cards.i.InvestigatorsJournal.class));
cards.add(new SetCardInfo("Island", 399, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Jacob Hauken, Inspector", 65, Rarity.MYTHIC, mage.cards.j.JacobHaukenInspector.class));
cards.add(new SetCardInfo("Katilda's Rising Dawn", 21, Rarity.RARE, mage.cards.k.KatildasRisingDawn.class));
cards.add(new SetCardInfo("Katilda, Dawnhart Martyr", 21, Rarity.RARE, mage.cards.k.KatildaDawnhartMartyr.class));
cards.add(new SetCardInfo("Kaya, Geist Hunter", 240, Rarity.MYTHIC, mage.cards.k.KayaGeistHunter.class));

View file

@ -9,6 +9,7 @@ package mage;
public enum MageIdentifier {
CemeteryIlluminatorWatcher,
GisaAndGeralfWatcher,
HaukensInsightWatcher,
KaradorGhostChieftainWatcher,
KessDissidentMageWatcher,
LurrusOfTheDreamDenWatcher,