mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
[SLD] Implemented Hawkins National Laboratory / The Upside Down
This commit is contained in:
parent
05222f3bdc
commit
5995dc2f7c
3 changed files with 289 additions and 0 deletions
110
Mage.Sets/src/mage/cards/h/HawkinsNationalLaboratory.java
Normal file
110
Mage.Sets/src/mage/cards/h/HawkinsNationalLaboratory.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
package mage.cards.h;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.effects.keyword.InvestigateEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class HawkinsNationalLaboratory extends CardImpl {
|
||||
|
||||
public HawkinsNationalLaboratory(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = mage.cards.t.TheUpsideDown.class;
|
||||
|
||||
// {T}: Add {C}.
|
||||
this.addAbility(new ColorlessManaAbility());
|
||||
|
||||
// {4}, {T}: Investigate.
|
||||
Ability ability = new SimpleActivatedAbility(new InvestigateEffect(), new GenericManaCost(4));
|
||||
ability.addCost(new TapSourceCost());
|
||||
this.addAbility(ability);
|
||||
|
||||
// At the beginning of your end step, if you sacrificed three or more Clues this turn, transform Hawkins National Laboratory.
|
||||
this.addAbility(new TransformAbility());
|
||||
this.addAbility(new BeginningOfEndStepTriggeredAbility(
|
||||
Zone.BATTLEFIELD, new TransformSourceEffect(true),
|
||||
TargetController.YOU, HawkinsNationalLaboratoryCondition.instance, false
|
||||
), new HawkinsNationalLaboratoryWatcher());
|
||||
}
|
||||
|
||||
private HawkinsNationalLaboratory(final HawkinsNationalLaboratory card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HawkinsNationalLaboratory copy() {
|
||||
return new HawkinsNationalLaboratory(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum HawkinsNationalLaboratoryCondition implements Condition {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return HawkinsNationalLaboratoryWatcher.checkPlayer(source.getControllerId(), game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "you sacrificed three or more Clues this turn";
|
||||
}
|
||||
}
|
||||
|
||||
class HawkinsNationalLaboratoryWatcher extends Watcher {
|
||||
|
||||
private final Map<UUID, Integer> playerMap = new HashMap<>();
|
||||
|
||||
HawkinsNationalLaboratoryWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() != GameEvent.EventType.SACRIFICED_PERMANENT) {
|
||||
return;
|
||||
}
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
|
||||
if (permanent == null || !permanent.hasSubtype(SubType.CLUE, game)) {
|
||||
return;
|
||||
}
|
||||
playerMap.compute(event.getPlayerId(), (u, i) -> i == null ? 1 : Integer.sum(i, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
playerMap.clear();
|
||||
super.reset();
|
||||
}
|
||||
|
||||
static boolean checkPlayer(UUID playerId, Game game) {
|
||||
return game
|
||||
.getState()
|
||||
.getWatcher(HawkinsNationalLaboratoryWatcher.class)
|
||||
.playerMap
|
||||
.getOrDefault(playerId, 0) >= 3;
|
||||
}
|
||||
}
|
177
Mage.Sets/src/mage/cards/t/TheUpsideDown.java
Normal file
177
Mage.Sets/src/mage/cards/t/TheUpsideDown.java
Normal file
|
@ -0,0 +1,177 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.mana.BlackManaAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TheUpsideDown extends CardImpl {
|
||||
|
||||
public TheUpsideDown(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.transformable = true;
|
||||
this.nightCard = true;
|
||||
|
||||
// When this land transforms into The Upside Down, return target creature card from your graveyard to the battlefield.
|
||||
this.addAbility(new TheUpsideDownTransformAbility());
|
||||
|
||||
// When the creature put onto the battlefield with The Upside Down leaves the battlefield, transform The Upside Down.
|
||||
this.addAbility(new TheUpsideDownLeavesAbility());
|
||||
|
||||
// {T}, Pay 1 life: Add {B}.
|
||||
Ability ability = new BlackManaAbility();
|
||||
ability.addCost(new PayLifeCost(1));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private TheUpsideDown(final TheUpsideDown card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheUpsideDown copy() {
|
||||
return new TheUpsideDown(this);
|
||||
}
|
||||
|
||||
static String makeKey(Ability source, Game game) {
|
||||
return "TheUpsideDown_" + source.getSourceId() + '_' + source.getSourceObjectZoneChangeCounter();
|
||||
}
|
||||
}
|
||||
|
||||
class TheUpsideDownTransformAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public TheUpsideDownTransformAbility() {
|
||||
super(Zone.BATTLEFIELD, new TheUpsideDownEffect(), false);
|
||||
this.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
|
||||
}
|
||||
|
||||
public TheUpsideDownTransformAbility(final TheUpsideDownTransformAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheUpsideDownTransformAbility copy() {
|
||||
return new TheUpsideDownTransformAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.TRANSFORMED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (!event.getTargetId().equals(this.getSourceId())) {
|
||||
return false;
|
||||
}
|
||||
Permanent permanent = getSourcePermanentIfItStillExists(game);
|
||||
return permanent != null && !permanent.isTransformed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When this land transforms into {this}, " +
|
||||
"return target creature card from your graveyard to the battlefield.";
|
||||
}
|
||||
}
|
||||
|
||||
class TheUpsideDownEffect extends OneShotEffect {
|
||||
|
||||
TheUpsideDownEffect() {
|
||||
super(Outcome.Benefit);
|
||||
}
|
||||
|
||||
private TheUpsideDownEffect(final TheUpsideDownEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheUpsideDownEffect copy() {
|
||||
return new TheUpsideDownEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
if (player == null || card == null) {
|
||||
return false;
|
||||
}
|
||||
player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
String key = TheUpsideDown.makeKey(source, game);
|
||||
Set<MageObjectReference> morSet;
|
||||
if (game.getState().getValue(key) != null) {
|
||||
morSet = (Set<MageObjectReference>) game.getState().getValue(key);
|
||||
} else {
|
||||
morSet = new HashSet<>();
|
||||
game.getState().setValue(key, morSet);
|
||||
}
|
||||
morSet.add(new MageObjectReference(permanent, game));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TheUpsideDownLeavesAbility extends TriggeredAbilityImpl {
|
||||
|
||||
TheUpsideDownLeavesAbility() {
|
||||
super(Zone.BATTLEFIELD, new TransformSourceEffect(false));
|
||||
}
|
||||
|
||||
private TheUpsideDownLeavesAbility(final TheUpsideDownLeavesAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheUpsideDownLeavesAbility copy() {
|
||||
return new TheUpsideDownLeavesAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
Set<MageObjectReference> morSet = (Set<MageObjectReference>) game.getState().getValue(TheUpsideDown.makeKey(this, game));
|
||||
return morSet != null
|
||||
&& !morSet.isEmpty()
|
||||
&& morSet.stream().anyMatch(mor -> mor.refersTo(zEvent.getTarget(), game));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When the creature put onto the battlefield with {this} leaves the battlefield, transform {this}.";
|
||||
}
|
||||
}
|
|
@ -380,5 +380,7 @@ public class SecretLairDrop extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Panharmonicon", 605, Rarity.RARE, mage.cards.p.Panharmonicon.class));
|
||||
cards.add(new SetCardInfo("Swiftfoot Boots", 606, Rarity.RARE, mage.cards.s.SwiftfootBoots.class));
|
||||
cards.add(new SetCardInfo("Rogue's Passage", 607, Rarity.RARE, mage.cards.r.RoguesPassage.class));
|
||||
cards.add(new SetCardInfo("Hawkins National Laboratory", 609, Rarity.RARE, mage.cards.h.HawkinsNationalLaboratory.class));
|
||||
cards.add(new SetCardInfo("The Upside Down", 609, Rarity.RARE, mage.cards.t.TheUpsideDown.class));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue