mirror of
https://github.com/magefree/mage.git
synced 2026-01-23 19:59:54 -08:00
Merge branch 'master' into master
This commit is contained in:
commit
659e3d7015
27 changed files with 764 additions and 187 deletions
|
|
@ -40,6 +40,7 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.TargetAdjustment;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
|
|
@ -65,6 +66,7 @@ public class AlexiZephyrMage extends CardImpl {
|
|||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new DiscardTargetCost(new TargetCardInHand(2, new FilterCard("two cards"))));
|
||||
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURES));
|
||||
ability.setTargetAdjustment(TargetAdjustment.X_TARGETS);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ class CurtainOfLightEffect extends OneShotEffect {
|
|||
CombatGroup combatGroup = game.getCombat().findGroup(permanent.getId());
|
||||
if (combatGroup != null) {
|
||||
combatGroup.setBlocked(true);
|
||||
game.informPlayers(permanent.getLogName() + " has become blocked");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ class DazzlingBeautyEffect extends OneShotEffect {
|
|||
CombatGroup combatGroup = game.getCombat().findGroup(permanent.getId());
|
||||
if (combatGroup != null) {
|
||||
combatGroup.setBlocked(true);
|
||||
game.informPlayers(permanent.getLogName() + " has become blocked");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,34 +34,41 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.costs.common.DiscardCardCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetAdjustment;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class DeepwoodElder extends CardImpl {
|
||||
|
||||
public DeepwoodElder(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}{G}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}");
|
||||
|
||||
this.subtype.add(SubType.DRYAD);
|
||||
this.subtype.add(SubType.SPELLSHAPER);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// {X}{G}{G}, {T}, Discard a card: X target lands become Forests until end of turn.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesBasicLandTargetEffect(Duration.EndOfTurn, SubType.FOREST).setText("X target lands become Forests until end of turn"), new ManaCostsImpl("{X}{G}{G}"));
|
||||
// {X}{G}{G}, {tap}, Discard a card: X target lands become Forests until end of turn.
|
||||
Ability ability = new SimpleActivatedAbility(new DeepwoodElderEffect(), new ManaCostsImpl("{X}{G}{G}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new DiscardCardCost());
|
||||
ability.addCost(new DiscardCardCost());
|
||||
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_LANDS));
|
||||
ability.setTargetAdjustment(TargetAdjustment.X_TARGETS);
|
||||
this.addAbility(ability);
|
||||
|
|
@ -76,3 +83,35 @@ public class DeepwoodElder extends CardImpl {
|
|||
return new DeepwoodElder(this);
|
||||
}
|
||||
}
|
||||
|
||||
class DeepwoodElderEffect extends OneShotEffect {
|
||||
|
||||
DeepwoodElderEffect() {
|
||||
super(Outcome.LoseAbility);
|
||||
this.staticText = "X target lands become Forests until end of turn";
|
||||
}
|
||||
|
||||
DeepwoodElderEffect(final DeepwoodElderEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeepwoodElderEffect copy() {
|
||||
return new DeepwoodElderEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
for (Target target : source.getTargets()) {
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
ContinuousEffect effect = new BecomesBasicLandTargetEffect(Duration.EndOfTurn, SubType.FOREST);
|
||||
effect.setTargetPointer(new FixedTarget(permanent, game));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.target.TargetPlayer;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -54,6 +55,7 @@ public class OrcishSpy extends CardImpl {
|
|||
|
||||
// {T}: Look at the top three cards of target player's library.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryTopCardTargetPlayerEffect(3), new TapSourceCost());
|
||||
ability.addTarget(new TargetPlayer());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,26 +30,20 @@ package mage.cards.s;
|
|||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||
import mage.abilities.keyword.EvolveAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubLayer;
|
||||
import mage.constants.TargetAdjustment;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
|
|
@ -69,7 +63,7 @@ public class SimicManipulator extends CardImpl {
|
|||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power less than or equal to the number of +1/+1 counters removed this way");
|
||||
|
||||
public SimicManipulator(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
|
||||
this.subtype.add(SubType.MUTANT);
|
||||
this.subtype.add(SubType.WIZARD);
|
||||
|
||||
|
|
@ -80,11 +74,10 @@ public class SimicManipulator extends CardImpl {
|
|||
this.addAbility(new EvolveAbility());
|
||||
|
||||
// {T}, Remove one or more +1/+1 counters from Simic Manipulator: Gain control of target creature with power less than or equal to the number of +1/+1 counters removed this way.
|
||||
// TODO: Improve targeting, that only valid targets (power <= removed counters) can be choosen
|
||||
// Disadvantage now is, that a creature can be targeted that couldn't be targeted by rules.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SimicManipulatorGainControlTargetEffect(Duration.Custom), new TapSourceCost());
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainControlTargetEffect(Duration.Custom, true), new TapSourceCost());
|
||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.P1P1.createInstance(), 1, "Remove one or more +1/+1 counters from {this}"));
|
||||
ability.setTargetAdjustment(TargetAdjustment.SIMIC_MANIPULATOR);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -97,53 +90,3 @@ public class SimicManipulator extends CardImpl {
|
|||
return new SimicManipulator(this);
|
||||
}
|
||||
}
|
||||
|
||||
class SimicManipulatorGainControlTargetEffect extends ContinuousEffectImpl {
|
||||
|
||||
private boolean valid;
|
||||
|
||||
public SimicManipulatorGainControlTargetEffect(Duration duration) {
|
||||
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
|
||||
}
|
||||
|
||||
public SimicManipulatorGainControlTargetEffect(final SimicManipulatorGainControlTargetEffect effect) {
|
||||
super(effect);
|
||||
this.valid = effect.valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
int maxPower = 0;
|
||||
for (Cost cost : source.getCosts()) {
|
||||
if (cost instanceof RemoveVariableCountersSourceCost) {
|
||||
maxPower = ((RemoveVariableCountersSourceCost) cost).getAmount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (permanent.getPower().getValue() <= maxPower) {
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimicManipulatorGainControlTargetEffect copy() {
|
||||
return new SimicManipulatorGainControlTargetEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent != null && valid) {
|
||||
return permanent.changeControllerId(source.getControllerId(), game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "Gain control of target " + mode.getTargets().get(0).getTargetName() + ' ' + duration.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,50 +29,49 @@ package mage.cards.s;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.common.ChooseOpponentEffect;
|
||||
import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubLayer;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.SupertypePredicate;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth, fireshoes & L_J
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class SkyshroudWarBeast extends CardImpl {
|
||||
|
||||
public SkyshroudWarBeast(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
||||
|
||||
this.subtype.add(SubType.BEAST);
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(0);
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
|
||||
// As Skyshroud War Beast enters the battlefield, choose an opponent.
|
||||
this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponentEffect(Outcome.Detriment)));
|
||||
|
||||
// Skyshroud War Beast's power is equal to the number of tapped lands the chosen player controls.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new SkyshroudWarBeastCount(), Duration.WhileOnBattlefield, SubLayer.CharacteristicDefining_7a)));
|
||||
this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponentEffect(Outcome.BoostCreature)));
|
||||
|
||||
// Skyshroud War Beast's power and toughness are each equal to the number of nonbasic lands the chosen player controls.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SkyshroudWarBeastEffect()));
|
||||
}
|
||||
|
||||
public SkyshroudWarBeast(final SkyshroudWarBeast card) {
|
||||
|
|
@ -85,35 +84,37 @@ public class SkyshroudWarBeast extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class SkyshroudWarBeastCount implements DynamicValue {
|
||||
class SkyshroudWarBeastEffect extends ContinuousEffectImpl {
|
||||
|
||||
public SkyshroudWarBeastEffect() {
|
||||
super(Duration.EndOfGame, Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, Outcome.BoostCreature);
|
||||
staticText = "{this}'s power and toughness are each equal to the number of nonbasic lands the chosen player controls";
|
||||
}
|
||||
|
||||
public SkyshroudWarBeastEffect(final SkyshroudWarBeastEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
if (sourceAbility != null) {
|
||||
UUID playerId = (UUID) game.getState().getValue(sourceAbility.getSourceId() + ChooseOpponentEffect.VALUE_KEY);
|
||||
Player chosenPlayer = game.getPlayer(playerId);
|
||||
if (chosenPlayer != null) {
|
||||
FilterLandPermanent filter = new FilterLandPermanent("nonbasic lands the chosen player controls");
|
||||
filter.add(Predicates.not(new SupertypePredicate(SuperType.BASIC)));
|
||||
public SkyshroudWarBeastEffect copy() {
|
||||
return new SkyshroudWarBeastEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
MageObject target = game.getObject(source.getSourceId());
|
||||
if (target != null) {
|
||||
UUID playerId = (UUID) game.getState().getValue(source.getSourceId().toString() + ChooseOpponentEffect.VALUE_KEY);
|
||||
FilterLandPermanent filter = new FilterLandPermanent();
|
||||
filter.add(new ControllerIdPredicate(playerId));
|
||||
return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game);
|
||||
int number = new PermanentsOnBattlefieldCount(filter).calculate(game, source, this);
|
||||
target.getPower().setValue(number);
|
||||
target.getToughness().setValue(number);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
return new SkyshroudWarBeastCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "nonbasic lands the chosen player controls";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,19 +28,23 @@
|
|||
package mage.cards.v;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CipherEffect;
|
||||
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlSourceEffect;
|
||||
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -49,7 +53,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public class Voidwalk extends CardImpl {
|
||||
|
||||
public Voidwalk(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}");
|
||||
|
||||
// Exile target creature. Return it to the battlefield under its owner's control at the beginning of the next end step.
|
||||
this.getSpellAbility().addEffect(new VoidwalkEffect());
|
||||
|
|
@ -71,32 +75,29 @@ public class Voidwalk extends CardImpl {
|
|||
|
||||
class VoidwalkEffect extends OneShotEffect {
|
||||
|
||||
private static final String effectText = "Exile target creature. Return it to the battlefield under its owner's control at the beginning of the next end step";
|
||||
|
||||
VoidwalkEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = effectText;
|
||||
public VoidwalkEffect() {
|
||||
super(Outcome.Detriment);
|
||||
staticText = "Exile target creature. Return it to the battlefield under its owner's control at the beginning of the next end step";
|
||||
}
|
||||
|
||||
VoidwalkEffect(VoidwalkEffect effect) {
|
||||
public VoidwalkEffect(final VoidwalkEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
if (getTargetPointer().getFirst(game, source) != null) {
|
||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (permanent != null) {
|
||||
int zcc = game.getState().getZoneChangeCounter(permanent.getId());
|
||||
if (permanent.moveToExile(null, "", source.getSourceId(), game)) {
|
||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
|
||||
new ReturnToBattlefieldUnderOwnerControlSourceEffect(false, zcc + 1)), source);
|
||||
}
|
||||
}
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (controller != null && permanent != null && sourceObject != null) {
|
||||
if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true)) {
|
||||
//create delayed triggered ability
|
||||
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
|
||||
effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step");
|
||||
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
|
||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue