mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 21:02:08 -08:00
Merge branch 'magefree:master' into case-of-the-pilfered-proof
This commit is contained in:
commit
e79bab6520
12 changed files with 540 additions and 3 deletions
|
|
@ -55,6 +55,16 @@ public final class Main {
|
|||
private static final Logger logger = Logger.getLogger(Main.class);
|
||||
private static final MageVersion version = new MageVersion(Main.class);
|
||||
|
||||
// Server threads:
|
||||
// - worker threads: creates for each connection, controls by maxPoolSize;
|
||||
// - acceptor threads: processing requests to start a new connection, controls by numAcceptThreads;
|
||||
// - backlog threads: processing waiting queue if maxPoolSize reached, controls by backlogSize;
|
||||
// Usage hints:
|
||||
// - if maxPoolSize reached then new clients will freeze in connection dialog until backlog queue overflow;
|
||||
// - so for active server must increase maxPoolSize to big value like "max online * 10" or enable worker idle timeout
|
||||
// - worker idle time will free unused worker thread, so new client can connect;
|
||||
private static final int SERVER_WORKER_THREAD_IDLE_TIMEOUT_SECS = 5 * 60; // no needs to config, must be enabled for all
|
||||
|
||||
// arg settings can be setup by run script or IDE's program arguments like -xxx=yyy
|
||||
// prop settings can be setup by -Dxxx=yyy in the launcher
|
||||
// priority: default setting -> prop setting -> arg setting
|
||||
|
|
@ -432,6 +442,7 @@ public final class Main {
|
|||
((BisocketServerInvoker) invoker).setSecondaryBindPort(managerFactory.configSettings().getSecondaryBindPort());
|
||||
((BisocketServerInvoker) invoker).setBacklog(managerFactory.configSettings().getBacklogSize());
|
||||
((BisocketServerInvoker) invoker).setNumAcceptThreads(managerFactory.configSettings().getNumAcceptThreads());
|
||||
((BisocketServerInvoker) invoker).setIdleTimeout(SERVER_WORKER_THREAD_IDLE_TIMEOUT_SECS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
101
Mage.Sets/src/mage/cards/b/BountyBoard.java
Normal file
101
Mage.Sets/src/mage/cards/b/BountyBoard.java
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
|
||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||
import mage.abilities.mana.AnyColorManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Controllable;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class BountyBoard extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter
|
||||
= new FilterCreaturePermanent("a creature with a bounty counter on it");
|
||||
|
||||
static {
|
||||
filter.add(CounterType.BOUNTY.getPredicate());
|
||||
}
|
||||
|
||||
public BountyBoard(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// {T}: Add one mana of any color.
|
||||
this.addAbility(new AnyColorManaAbility());
|
||||
|
||||
// {1}, {T}: Put a bounty counter on target creature. Activate only as a sorcery.
|
||||
Ability ability = new ActivateAsSorceryActivatedAbility(
|
||||
new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()), new GenericManaCost(1)
|
||||
);
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
this.addAbility(ability);
|
||||
|
||||
// Whenever a creature with a bounty counter on it dies, each of its controller's opponents draws a card and gains 2 life.
|
||||
this.addAbility(new DiesCreatureTriggeredAbility(new BountyBoardEffect(), false, filter));
|
||||
}
|
||||
|
||||
private BountyBoard(final BountyBoard card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BountyBoard copy() {
|
||||
return new BountyBoard(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BountyBoardEffect extends OneShotEffect {
|
||||
|
||||
BountyBoardEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "each of its controller's opponents draws a card and gains 2 life";
|
||||
}
|
||||
|
||||
private BountyBoardEffect(final BountyBoardEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BountyBoardEffect copy() {
|
||||
return new BountyBoardEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Optional.ofNullable(getValue("creatureDied"))
|
||||
.map(Permanent.class::cast)
|
||||
.map(Controllable::getControllerId)
|
||||
.map(game::getOpponents)
|
||||
.map(Collection::stream)
|
||||
.orElseGet(Stream::empty)
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(player -> {
|
||||
player.drawCards(1, source, game);
|
||||
player.gainLife(2, game, source);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
54
Mage.Sets/src/mage/cards/d/DeadBeforeSunrise.java
Normal file
54
Mage.Sets/src/mage/cards/d/DeadBeforeSunrise.java
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
package mage.cards.d;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.common.DamageWithPowerFromSourceToAnotherTargetEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.OutlawPredicate;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class DeadBeforeSunrise extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
|
||||
static {
|
||||
filter.add(OutlawPredicate.instance);
|
||||
}
|
||||
|
||||
public DeadBeforeSunrise(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}");
|
||||
|
||||
// Until end of turn, outlaw creatures you control get +1/+0 and gain "{T}: This creature deals damage equal to its power to target creature."
|
||||
this.getSpellAbility().addEffect(new BoostControlledEffect(
|
||||
1, 0, Duration.EndOfTurn, filter
|
||||
).setText("until end of turn, outlaw creatures you control get +1/+0"));
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new DamageWithPowerFromSourceToAnotherTargetEffect("this creature"), new TapSourceCost()
|
||||
);
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(
|
||||
ability, Duration.EndOfTurn, filter
|
||||
).setText("and gain \"{T}: This creature deals damage equal to its power to target creature.\""));
|
||||
}
|
||||
|
||||
private DeadBeforeSunrise(final DeadBeforeSunrise card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeadBeforeSunrise copy() {
|
||||
return new DeadBeforeSunrise(this);
|
||||
}
|
||||
}
|
||||
77
Mage.Sets/src/mage/cards/g/GraywatersFixer.java
Normal file
77
Mage.Sets/src/mage/cards/g/GraywatersFixer.java
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.keyword.UnearthAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class GraywatersFixer extends CardImpl {
|
||||
|
||||
public GraywatersFixer(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
|
||||
|
||||
this.subtype.add(SubType.LIZARD);
|
||||
this.subtype.add(SubType.MERCENARY);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Each outlaw creature card in your graveyard has encore {X}, where X is its mana value.
|
||||
this.addAbility(new SimpleStaticAbility(new GraywatersFixerEffect()));
|
||||
}
|
||||
|
||||
private GraywatersFixer(final GraywatersFixer card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraywatersFixer copy() {
|
||||
return new GraywatersFixer(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GraywatersFixerEffect extends ContinuousEffectImpl {
|
||||
GraywatersFixerEffect() {
|
||||
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||
staticText = "each outlaw creature card in your graveyard has encore {X}, where X is its mana value";
|
||||
}
|
||||
|
||||
private GraywatersFixerEffect(final GraywatersFixerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
for (Card card : controller.getGraveyard().getCards(game)) {
|
||||
if (!card.isCreature(game) || !card.isOutlaw(game)) {
|
||||
continue;
|
||||
}
|
||||
UnearthAbility ability = new UnearthAbility(new GenericManaCost(card.getManaValue()));
|
||||
ability.setSourceId(card.getId());
|
||||
ability.setControllerId(card.getOwnerId());
|
||||
game.getState().addOtherAbility(card, ability);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraywatersFixerEffect copy() {
|
||||
return new GraywatersFixerEffect(this);
|
||||
}
|
||||
}
|
||||
102
Mage.Sets/src/mage/cards/p/PreWarFormalwear.java
Normal file
102
Mage.Sets/src/mage/cards/p/PreWarFormalwear.java
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package mage.cards.p;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||
import mage.abilities.keyword.EquipAbility;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class PreWarFormalwear extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCreatureCard("creature card with mana value 3 or less from your graveyard");
|
||||
|
||||
static {
|
||||
filter.add(new ManaValuePredicate(ComparisonType.OR_LESS, 3));
|
||||
filter.add(CardType.CREATURE.getPredicate());
|
||||
}
|
||||
|
||||
public PreWarFormalwear(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{W}");
|
||||
|
||||
this.subtype.add(SubType.EQUIPMENT);
|
||||
|
||||
// When Pre-War Formalwear enters the battlefield, return target creature card with mana value 3 or less from your graveyard to the battlefield and attach Pre-War Formalwear to it.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new PreWarFormalwerEffect());
|
||||
ability.addTarget(new TargetCardInYourGraveyard(filter));
|
||||
this.addAbility(ability);
|
||||
|
||||
// Equipped creature gets +2/+2 and has vigilance.
|
||||
ability = new SimpleStaticAbility(new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield));
|
||||
ability.addEffect(new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA).setText("and has vigilance"));
|
||||
this.addAbility(ability);
|
||||
|
||||
// Equip {3}
|
||||
this.addAbility(new EquipAbility(3));
|
||||
}
|
||||
|
||||
private PreWarFormalwear(final PreWarFormalwear card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreWarFormalwear copy() {
|
||||
return new PreWarFormalwear(this);
|
||||
}
|
||||
}
|
||||
|
||||
class PreWarFormalwerEffect extends OneShotEffect {
|
||||
|
||||
PreWarFormalwerEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "return target creature card with mana value 3 or less from your graveyard "
|
||||
+ "to the battlefield and attach Pre-War Formalwear to it";
|
||||
}
|
||||
|
||||
private PreWarFormalwerEffect(final PreWarFormalwerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreWarFormalwerEffect copy() {
|
||||
return new PreWarFormalwerEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card card = game.getCard(source.getFirstTarget());
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (card == null || player == null) {
|
||||
return false;
|
||||
}
|
||||
player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
new AttachEffect(Outcome.BoostCreature)
|
||||
.setTargetPointer(new FixedTarget(permanent.getId()))
|
||||
.apply(game, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
71
Mage.Sets/src/mage/cards/p/PyreticCharge.java
Normal file
71
Mage.Sets/src/mage/cards/p/PyreticCharge.java
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
package mage.cards.p;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.abilities.keyword.PlotAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class PyreticCharge extends CardImpl {
|
||||
|
||||
public PyreticCharge(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}");
|
||||
|
||||
// Discard your hand, then draw four cards. For each card discarded this way, creatures you control get +1/+0 until end of turn.
|
||||
this.getSpellAbility().addEffect(new PyreticChargeEffect());
|
||||
|
||||
// Plot {3}{R}
|
||||
this.addAbility(new PlotAbility("{3}{R}"));
|
||||
}
|
||||
|
||||
private PyreticCharge(final PyreticCharge card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyreticCharge copy() {
|
||||
return new PyreticCharge(this);
|
||||
}
|
||||
}
|
||||
|
||||
class PyreticChargeEffect extends OneShotEffect {
|
||||
|
||||
PyreticChargeEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "discard your hand, then draw four cards. For each card discarded this way, " +
|
||||
"creatures you control get +1/+0 until end of turn";
|
||||
}
|
||||
|
||||
private PyreticChargeEffect(final PyreticChargeEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyreticChargeEffect copy() {
|
||||
return new PyreticChargeEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
int count = player.getHand().size();
|
||||
player.discard(count, false, false, source, game);
|
||||
player.drawCards(4, source, game);
|
||||
game.addEffect(new BoostControlledEffect(count, 0, Duration.EndOfTurn), source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -80,6 +80,7 @@ class SigardasVanguardEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
TargetPermanent target = new TargetCreaturesWithDifferentPowers();
|
||||
target.withNotTarget(true);
|
||||
player.choose(outcome, target, source, game);
|
||||
if (target.getTargets().isEmpty()) {
|
||||
return false;
|
||||
|
|
|
|||
61
Mage.Sets/src/mage/cards/t/ThievingVarmint.java
Normal file
61
Mage.Sets/src/mage/cards/t/ThievingVarmint.java
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.keyword.DeathtouchAbility;
|
||||
import mage.abilities.keyword.LifelinkAbility;
|
||||
import mage.abilities.mana.ConditionalAnyColorManaAbility;
|
||||
import mage.abilities.mana.conditional.ConditionalSpellManaBuilder;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterSpell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class ThievingVarmint extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell("spells you don't own");
|
||||
|
||||
static {
|
||||
filter.add(TargetController.NOT_YOU.getOwnerPredicate());
|
||||
}
|
||||
|
||||
public ThievingVarmint(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
|
||||
|
||||
this.subtype.add(SubType.VARMINT);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// Deathtouch
|
||||
this.addAbility(DeathtouchAbility.getInstance());
|
||||
|
||||
// Lifelink
|
||||
this.addAbility(LifelinkAbility.getInstance());
|
||||
|
||||
// {T}, Pay 1 life: Add two mana of any one color. Spend this mana only to cast spells you don't own.
|
||||
Ability ability = new ConditionalAnyColorManaAbility(
|
||||
new TapSourceCost(), 2,
|
||||
new ConditionalSpellManaBuilder(filter), true
|
||||
);
|
||||
ability.addCost(new PayLifeCost(1));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private ThievingVarmint(final ThievingVarmint card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThievingVarmint copy() {
|
||||
return new ThievingVarmint(this);
|
||||
}
|
||||
}
|
||||
53
Mage.Sets/src/mage/cards/t/TowerWinder.java
Normal file
53
Mage.Sets/src/mage/cards/t/TowerWinder.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect;
|
||||
import mage.abilities.keyword.DeathtouchAbility;
|
||||
import mage.abilities.keyword.ReachAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TowerWinder extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("Command Tower");
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Command Tower"));
|
||||
}
|
||||
|
||||
public TowerWinder(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
||||
|
||||
this.subtype.add(SubType.SNAKE);
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// Reach
|
||||
this.addAbility(ReachAbility.getInstance());
|
||||
|
||||
// Deathtouch
|
||||
this.addAbility(DeathtouchAbility.getInstance());
|
||||
|
||||
// When Tower Winder enters the battlefield, search your library and/or graveyard for a card named Command Tower, reveal it, and put it into your hand. If you search your library this way, shuffle.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryGraveyardPutInHandEffect(filter)));
|
||||
}
|
||||
|
||||
private TowerWinder(final TowerWinder card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TowerWinder copy() {
|
||||
return new TowerWinder(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -220,6 +220,7 @@ public final class Fallout extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Plains", 317, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Powder Ganger", 65, Rarity.RARE, mage.cards.p.PowderGanger.class));
|
||||
cards.add(new SetCardInfo("Prairie Stream", 280, Rarity.RARE, mage.cards.p.PrairieStream.class));
|
||||
cards.add(new SetCardInfo("Pre-War Formalwear", 21, Rarity.RARE, mage.cards.p.PreWarFormalwear.class));
|
||||
cards.add(new SetCardInfo("Puresteel Paladin", 170, Rarity.RARE, mage.cards.p.PuresteelPaladin.class));
|
||||
cards.add(new SetCardInfo("Putrefy", 219, Rarity.UNCOMMON, mage.cards.p.Putrefy.class));
|
||||
cards.add(new SetCardInfo("Radstorm", 37, Rarity.RARE, mage.cards.r.Radstorm.class));
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public final class OutlawsOfThunderJunctionCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Bojuka Bog", 273, Rarity.COMMON, mage.cards.b.BojukaBog.class));
|
||||
cards.add(new SetCardInfo("Bonders' Enclave", 274, Rarity.RARE, mage.cards.b.BondersEnclave.class));
|
||||
cards.add(new SetCardInfo("Boros Charm", 216, Rarity.UNCOMMON, mage.cards.b.BorosCharm.class));
|
||||
cards.add(new SetCardInfo("Bounty Board", 37, Rarity.RARE, mage.cards.b.BountyBoard.class));
|
||||
cards.add(new SetCardInfo("Brainstealer Dragon", 127, Rarity.RARE, mage.cards.b.BrainstealerDragon.class));
|
||||
cards.add(new SetCardInfo("Breena, the Demagogue", 217, Rarity.MYTHIC, mage.cards.b.BreenaTheDemagogue.class));
|
||||
cards.add(new SetCardInfo("Cactus Preserve", 40, Rarity.RARE, mage.cards.c.CactusPreserve.class));
|
||||
|
|
@ -77,6 +78,7 @@ public final class OutlawsOfThunderJunctionCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Darksteel Ingot", 256, Rarity.UNCOMMON, mage.cards.d.DarksteelIngot.class));
|
||||
cards.add(new SetCardInfo("Darkwater Catacombs", 282, Rarity.RARE, mage.cards.d.DarkwaterCatacombs.class));
|
||||
cards.add(new SetCardInfo("Dazzling Sphinx", 93, Rarity.RARE, mage.cards.d.DazzlingSphinx.class));
|
||||
cards.add(new SetCardInfo("Dead Before Sunrise", 26, Rarity.RARE, mage.cards.d.DeadBeforeSunrise.class));
|
||||
cards.add(new SetCardInfo("Deadly Dispute", 131, Rarity.COMMON, mage.cards.d.DeadlyDispute.class));
|
||||
cards.add(new SetCardInfo("Decimate", 220, Rarity.RARE, mage.cards.d.Decimate.class));
|
||||
cards.add(new SetCardInfo("Deep Analysis", 94, Rarity.COMMON, mage.cards.d.DeepAnalysis.class));
|
||||
|
|
@ -128,6 +130,7 @@ public final class OutlawsOfThunderJunctionCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Glittering Stockpile", 167, Rarity.UNCOMMON, mage.cards.g.GlitteringStockpile.class));
|
||||
cards.add(new SetCardInfo("Goblin Electromancer", 228, Rarity.COMMON, mage.cards.g.GoblinElectromancer.class));
|
||||
cards.add(new SetCardInfo("Gonti, Lord of Luxury", 135, Rarity.RARE, mage.cards.g.GontiLordOfLuxury.class));
|
||||
cards.add(new SetCardInfo("Graywater's Fixer", 36, Rarity.RARE, mage.cards.g.GraywatersFixer.class));
|
||||
cards.add(new SetCardInfo("Grenzo, Havoc Raiser", 168, Rarity.RARE, mage.cards.g.GrenzoHavocRaiser.class));
|
||||
cards.add(new SetCardInfo("Guttersnipe", 169, Rarity.COMMON, mage.cards.g.Guttersnipe.class));
|
||||
cards.add(new SetCardInfo("Harrow", 194, Rarity.COMMON, mage.cards.h.Harrow.class));
|
||||
|
|
@ -203,6 +206,7 @@ public final class OutlawsOfThunderJunctionCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Propaganda", 108, Rarity.UNCOMMON, mage.cards.p.Propaganda.class));
|
||||
cards.add(new SetCardInfo("Pteramander", 109, Rarity.UNCOMMON, mage.cards.p.Pteramander.class));
|
||||
cards.add(new SetCardInfo("Putrefy", 238, Rarity.UNCOMMON, mage.cards.p.Putrefy.class));
|
||||
cards.add(new SetCardInfo("Pyretic Charge", 29, Rarity.RARE, mage.cards.p.PyreticCharge.class));
|
||||
cards.add(new SetCardInfo("Queen Marchesa", 239, Rarity.RARE, mage.cards.q.QueenMarchesa.class));
|
||||
cards.add(new SetCardInfo("Radical Idea", 110, Rarity.COMMON, mage.cards.r.RadicalIdea.class));
|
||||
cards.add(new SetCardInfo("Rain of Riches", 177, Rarity.RARE, mage.cards.r.RainOfRiches.class));
|
||||
|
|
@ -272,11 +276,13 @@ public final class OutlawsOfThunderJunctionCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Thief of Sanity", 243, Rarity.RARE, mage.cards.t.ThiefOfSanity.class));
|
||||
cards.add(new SetCardInfo("Thieving Amalgam", 150, Rarity.RARE, mage.cards.t.ThievingAmalgam.class));
|
||||
cards.add(new SetCardInfo("Thieving Skydiver", 118, Rarity.RARE, mage.cards.t.ThievingSkydiver.class));
|
||||
cards.add(new SetCardInfo("Thieving Varmint", 23, Rarity.RARE, mage.cards.t.ThievingVarmint.class));
|
||||
cards.add(new SetCardInfo("Think Twice", 119, Rarity.COMMON, mage.cards.t.ThinkTwice.class));
|
||||
cards.add(new SetCardInfo("Third Path Iconoclast", 244, Rarity.UNCOMMON, mage.cards.t.ThirdPathIconoclast.class));
|
||||
cards.add(new SetCardInfo("Three Visits", 209, Rarity.UNCOMMON, mage.cards.t.ThreeVisits.class));
|
||||
cards.add(new SetCardInfo("Thrilling Discovery", 245, Rarity.COMMON, mage.cards.t.ThrillingDiscovery.class));
|
||||
cards.add(new SetCardInfo("Titania, Protector of Argoth", 210, Rarity.MYTHIC, mage.cards.t.TitaniaProtectorOfArgoth.class));
|
||||
cards.add(new SetCardInfo("Tower Winder", 34, Rarity.RARE, mage.cards.t.TowerWinder.class));
|
||||
cards.add(new SetCardInfo("Trailblazer's Boots", 269, Rarity.UNCOMMON, mage.cards.t.TrailblazersBoots.class));
|
||||
cards.add(new SetCardInfo("Treasure Cruise", 120, Rarity.COMMON, mage.cards.t.TreasureCruise.class));
|
||||
cards.add(new SetCardInfo("Triton Shorestalker", 121, Rarity.COMMON, mage.cards.t.TritonShorestalker.class));
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package mage.abilities.keyword;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.ActivatedAbilityImpl;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileSourceEffect;
|
||||
|
|
@ -14,7 +14,6 @@ import mage.constants.TimingRule;
|
|||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
|
||||
/**
|
||||
|
|
@ -32,7 +31,7 @@ import mage.game.events.ZoneChangeEvent;
|
|||
*/
|
||||
public class UnearthAbility extends ActivatedAbilityImpl {
|
||||
|
||||
public UnearthAbility(ManaCosts costs) {
|
||||
public UnearthAbility(Cost costs) {
|
||||
super(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(false, true, true), costs);
|
||||
this.timing = TimingRule.SORCERY;
|
||||
this.addEffect(new CreateDelayedTriggeredAbilityEffect(new UnearthDelayedTriggeredAbility()));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue