mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
[BRO] Implement The Temporal Anchor
This commit is contained in:
parent
accc5d2d0b
commit
4cb8466d07
4 changed files with 174 additions and 1 deletions
166
Mage.Sets/src/mage/cards/t/TheTemporalAnchor.java
Normal file
166
Mage.Sets/src/mage/cards/t/TheTemporalAnchor.java
Normal file
|
@ -0,0 +1,166 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.keyword.ScryEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TheTemporalAnchor extends CardImpl {
|
||||
|
||||
public TheTemporalAnchor(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{U}{U}{U}");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
|
||||
// At the beginning of your upkeep, scry 2.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
|
||||
new ScryEffect(2), TargetController.YOU, false
|
||||
));
|
||||
|
||||
// Whenever you choose to put one or more cards on the bottom of your library while scrying, exile that many cards from the bottom of your library.
|
||||
this.addAbility(new TheTemporalAnchorTriggeredAbility());
|
||||
|
||||
// During your turn, you may play cards exiled with The Temporal Anchor.
|
||||
this.addAbility(new SimpleStaticAbility(new TheTemporalAnchorPlayEffect()));
|
||||
}
|
||||
|
||||
private TheTemporalAnchor(final TheTemporalAnchor card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheTemporalAnchor copy() {
|
||||
return new TheTemporalAnchor(this);
|
||||
}
|
||||
}
|
||||
|
||||
class TheTemporalAnchorTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
TheTemporalAnchorTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new TheTemporalAnchorExileEffect());
|
||||
}
|
||||
|
||||
private TheTemporalAnchorTriggeredAbility(final TheTemporalAnchorTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheTemporalAnchorTriggeredAbility copy() {
|
||||
return new TheTemporalAnchorTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.SCRY_TO_BOTTOM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (isControlledBy(event.getPlayerId()) && event.getAmount() > 0) {
|
||||
this.getEffects().setValue("amount", event.getAmount());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever you choose to put one or more cards on the bottom of your library while scrying, " +
|
||||
"exile that many cards from the bottom of your library.";
|
||||
}
|
||||
}
|
||||
|
||||
class TheTemporalAnchorExileEffect extends OneShotEffect {
|
||||
|
||||
TheTemporalAnchorExileEffect() {
|
||||
super(Outcome.Benefit);
|
||||
}
|
||||
|
||||
private TheTemporalAnchorExileEffect(final TheTemporalAnchorExileEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheTemporalAnchorExileEffect copy() {
|
||||
return new TheTemporalAnchorExileEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
int amount = (Integer) getValue("amount");
|
||||
if (player == null || amount < 1) {
|
||||
return false;
|
||||
}
|
||||
int toSkip = Math.max(player.getLibrary().size() - amount, 0);
|
||||
Set<Card> cards = player
|
||||
.getLibrary()
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.skip(toSkip)
|
||||
.collect(Collectors.toSet());
|
||||
return !cards.isEmpty() && player.moveCardsToExile(
|
||||
cards, source, game, true,
|
||||
CardUtil.getExileZoneId(game, source),
|
||||
CardUtil.getSourceName(game, source)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TheTemporalAnchorPlayEffect extends AsThoughEffectImpl {
|
||||
|
||||
TheTemporalAnchorPlayEffect() {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "during your turn, you may play cards exiled with {this}";
|
||||
}
|
||||
|
||||
private TheTemporalAnchorPlayEffect(final TheTemporalAnchorPlayEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheTemporalAnchorPlayEffect copy() {
|
||||
return new TheTemporalAnchorPlayEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (!source.isControlledBy(affectedControllerId) || !game.isActivePlayer(affectedControllerId)) {
|
||||
return false;
|
||||
}
|
||||
Card card = game.getCard(objectId);
|
||||
if (card == null) {
|
||||
return false;
|
||||
}
|
||||
UUID mainId = card.getMainCard().getId(); // for split cards
|
||||
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source));
|
||||
return exileZone != null
|
||||
&& exileZone.contains(mainId)
|
||||
&& game.getCard(mainId) != null;
|
||||
}
|
||||
}
|
|
@ -249,6 +249,7 @@ public final class TheBrothersWar extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Terror Ballista", 290, Rarity.RARE, mage.cards.t.TerrorBallista.class));
|
||||
cards.add(new SetCardInfo("The Mightstone and Weakstone", "238a", Rarity.RARE, mage.cards.t.TheMightstoneAndWeakstone.class));
|
||||
cards.add(new SetCardInfo("The Stasis Coffin", 245, Rarity.RARE, mage.cards.t.TheStasisCoffin.class));
|
||||
cards.add(new SetCardInfo("The Temporal Anchor", 82, Rarity.RARE, mage.cards.t.TheTemporalAnchor.class));
|
||||
cards.add(new SetCardInfo("Third Path Iconoclast", 223, Rarity.UNCOMMON, mage.cards.t.ThirdPathIconoclast.class));
|
||||
cards.add(new SetCardInfo("Third Path Savant", 67, Rarity.COMMON, mage.cards.t.ThirdPathSavant.class));
|
||||
cards.add(new SetCardInfo("Thopter Architect", 29, Rarity.UNCOMMON, mage.cards.t.ThopterArchitect.class));
|
||||
|
|
|
@ -305,7 +305,7 @@ public class GameEvent implements Serializable {
|
|||
SHUFFLE_LIBRARY, LIBRARY_SHUFFLED,
|
||||
ENCHANT_PLAYER, ENCHANTED_PLAYER,
|
||||
CAN_TAKE_MULLIGAN,
|
||||
SCRY, SCRIED,
|
||||
SCRY, SCRIED, SCRY_TO_BOTTOM,
|
||||
SURVEIL, SURVEILED,
|
||||
FATESEALED,
|
||||
FLIP_COIN, COIN_FLIPPED,
|
||||
|
|
|
@ -4989,6 +4989,12 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
+ " to PUT on the BOTTOM of your library (Scry)"));
|
||||
chooseTarget(Outcome.Benefit, cards, target, source, game);
|
||||
putCardsOnBottomOfLibrary(new CardsImpl(target.getTargets()), game, source, true);
|
||||
if (!target.getTargets().isEmpty()) {
|
||||
game.fireEvent(GameEvent.getEvent(
|
||||
GameEvent.EventType.SCRY_TO_BOTTOM, getId(),
|
||||
source, getId(), target.getTargets().size()
|
||||
));
|
||||
}
|
||||
cards.removeIf(target.getTargets()::contains);
|
||||
putCardsOnTopOfLibrary(cards, game, source, true);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue