Merge branch 'magefree:master' into github-actions

This commit is contained in:
Phred Lane 2024-02-17 04:03:58 -06:00 committed by GitHub
commit dfd7e94e64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 544 additions and 578 deletions

View file

@ -208,7 +208,7 @@ class AKillerAmongUsEffect extends OneShotEffect {
class AKillerAmongUsCost extends CostImpl {
AKillerAmongUsCost() {
this.text = "Reveal the chosen creature type";
this.text = "Reveal the creature type you chose";
}
private AKillerAmongUsCost(final AKillerAmongUsCost cost) {

View file

@ -31,7 +31,7 @@ public final class AkromasWill extends CardImpl {
// Choose one. If you control a commander as you cast this spell, you may choose both.
this.getSpellAbility().getModes().setChooseText(
"Choose one. If you control a commander as you cast this spell, you may choose both."
"Choose one. If you control a commander as you cast this spell, you may choose both instead."
);
this.getSpellAbility().getModes().setMoreCondition(ControlACommanderCondition.instance);

View file

@ -27,7 +27,7 @@ import java.util.UUID;
*/
public final class AmaliaBenavidesAguirre extends CardImpl {
private final static FilterPermanent filter = new FilterCreaturePermanent("other creatures");
private static final FilterPermanent filter = new FilterCreaturePermanent("other creatures");
static {
filter.add(AnotherPredicate.instance);
@ -50,7 +50,7 @@ public final class AmaliaBenavidesAguirre extends CardImpl {
ability.addEffect(new ConditionalOneShotEffect(
new DestroyAllEffect(filter),
AmaliaBenavidesAguirreCondition.instance
).setText("Then, destroy all other creatures if its power is exactly 20"));
).setText("Then destroy all other creatures if its power is exactly 20"));
this.addAbility(ability);
}

View file

@ -40,8 +40,7 @@ public final class AnzragTheQuakeMole extends CardImpl {
Ability ability = new BecomesBlockedSourceTriggeredAbility(
new UntapAllEffect(filter), false
);
ability.addEffect(new AdditionalCombatPhaseEffect()
.setText("After this combat phase, there is an additional combat phase"));
ability.addEffect(new AdditionalCombatPhaseEffect());
this.addAbility(ability);
// {3}{R}{R}{G}{G}: Anzrag must be blocked each combat this turn if able.

View file

@ -90,7 +90,7 @@ class AzraBladeseekerEffect extends OneShotEffect {
return true;
}
class PlayerCard {
static class PlayerCard {
private final Player player;
private final Card card;

View file

@ -1,24 +1,22 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.TargetPlayerGainControlTargetPermanentEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
/**
*
* @author North
@ -42,7 +40,7 @@ public final class BazaarTrader extends CardImpl {
this.toughness = new MageInt(1);
// {tap}: Target player gains control of target artifact, creature, or land you control.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BazaarTraderEffect(), new TapSourceCost());
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TargetPlayerGainControlTargetPermanentEffect(), new TapSourceCost());
ability.addTarget(new TargetPlayer());
ability.addTarget(new TargetControlledPermanent(filter));
this.addAbility(ability);
@ -57,41 +55,3 @@ public final class BazaarTrader extends CardImpl {
return new BazaarTrader(this);
}
}
class BazaarTraderEffect extends ContinuousEffectImpl {
MageObjectReference targetPermanentReference;
public BazaarTraderEffect() {
super(Duration.Custom, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.staticText = "Target player gains control of target artifact, creature, or land you control";
}
private BazaarTraderEffect(final BazaarTraderEffect effect) {
super(effect);
this.targetPermanentReference = effect.targetPermanentReference;
}
@Override
public BazaarTraderEffect copy() {
return new BazaarTraderEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
targetPermanentReference = new MageObjectReference(source.getTargets().get(1).getFirstTarget(), game);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
Permanent permanent = targetPermanentReference.getPermanent(game);
if (player != null && permanent != null) {
return permanent.changeControllerId(player.getId(), game, source);
} else {
discard();
}
return false;
}
}

View file

@ -68,7 +68,7 @@ class BillFernyEffect extends OneShotEffect {
private static final Effect create3TreasureTokens = new CreateTokenEffect(new TreasureToken(), 3);
private static final Effect removeFromCombat = new RemoveFromCombatSourceEffect();
public BillFernyEffect() {
BillFernyEffect() {
super(Outcome.Benefit);
this.staticText = "Target opponent gains control of target Horse you control. If they do, remove Bill Ferny from combat and create three Treasure tokens.";
}

View file

@ -1,16 +1,11 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.AddCardSubtypeAllEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.effects.common.continuous.AddBasicLandTypeAllLandsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterLandPermanent;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
@ -22,13 +17,9 @@ public final class BlanketOfNight extends CardImpl {
public BlanketOfNight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}");
// Each land is a Swamp in addition to its other land types.
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new BlackManaAbility(), Duration.WhileOnBattlefield, new FilterLandPermanent(),
"Each land is a Swamp in addition to its other land types"));
ability.addEffect(new AddCardSubtypeAllEffect(StaticFilters.FILTER_LAND, SubType.SWAMP, DependencyType.BecomeSwamp));
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(new AddBasicLandTypeAllLandsEffect(SubType.SWAMP)));
}
private BlanketOfNight(final BlanketOfNight card) {

View file

@ -84,8 +84,8 @@ class FetchQuestEffect extends OneShotEffect {
FetchQuestEffect() {
super(Outcome.Benefit);
staticText = "mill seven cards, then put a creature, enchantment, or land card "
+ "from among cards milled this way onto the battlefield";
staticText = "mill seven cards. Then put a creature, enchantment, or land card "
+ "from among the milled cards onto the battlefield";
}
private FetchQuestEffect(final FetchQuestEffect effect) {
@ -115,4 +115,4 @@ class FetchQuestEffect extends OneShotEffect {
return true;
}
}
}

View file

@ -22,7 +22,7 @@ public final class CrystalGrotto extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// When Crystal Grotto enters the battlefield, scry 1.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(1)));
this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(1, false)));
// {T}: Add {C}.
this.addAbility(new ColorlessManaAbility());

View file

@ -43,7 +43,8 @@ public final class DavrosDalekCreator extends CardImpl {
Ability ability = new BeginningOfEndStepTriggeredAbility(
new ConditionalOneShotEffect(
new CreateTokenEffect(new DalekToken()),
new OpponentLostLifeCondition(ComparisonType.OR_GREATER, 3)
new OpponentLostLifeCondition(ComparisonType.OR_GREATER, 3),
"create a 3/3 black Dalek artifact creature token with menace if an opponent lost 3 or more life this turn"
),
TargetController.YOU, false
);

View file

@ -1,4 +1,3 @@
package mage.cards.d;
import java.util.UUID;
@ -39,39 +38,40 @@ public final class Disarm extends CardImpl {
return new Disarm(this);
}
class DisarmEffect extends OneShotEffect {
}
public DisarmEffect() {
super(Outcome.UnboostCreature);
this.staticText = "Unattach all Equipment from target creature";
}
class DisarmEffect extends OneShotEffect {
private DisarmEffect(final DisarmEffect effect) {
super(effect);
}
DisarmEffect() {
super(Outcome.UnboostCreature);
this.staticText = "Unattach all Equipment from target creature";
}
@Override
public DisarmEffect copy() {
return new DisarmEffect(this);
}
private DisarmEffect(final DisarmEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(targetPointer.getFirst(game, source));
if (creature != null) {
FilterPermanent creatureFilter = new FilterPermanent();
creatureFilter.add(new PermanentIdPredicate(creature.getId()));
@Override
public DisarmEffect copy() {
return new DisarmEffect(this);
}
FilterPermanent equipmentFilter = new FilterPermanent();
equipmentFilter.add(new AttachedToPredicate(creatureFilter));
equipmentFilter.add(SubType.EQUIPMENT.getPredicate());
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (creature != null) {
FilterPermanent creatureFilter = new FilterPermanent();
creatureFilter.add(new PermanentIdPredicate(creature.getId()));
for (Permanent equipment : game.getBattlefield().getAllActivePermanents(equipmentFilter, game)) {
creature.removeAttachment(equipment.getId(), source, game);
}
return true;
FilterPermanent equipmentFilter = new FilterPermanent();
equipmentFilter.add(new AttachedToPredicate(creatureFilter));
equipmentFilter.add(SubType.EQUIPMENT.getPredicate());
for (Permanent equipment : game.getBattlefield().getAllActivePermanents(equipmentFilter, game)) {
creature.removeAttachment(equipment.getId(), source, game);
}
return false;
return true;
}
return false;
}
}

View file

@ -66,7 +66,7 @@ public final class DiscerningFinancier extends CardImpl {
// {2}{W}: Choose another player. That player gains control of target Treasure you control. You draw a card.
Ability ability = new SimpleActivatedAbility(
new DiscerningFinancierEffect(),
new ManaCostsImpl("{2}{W}")
new ManaCostsImpl<>("{2}{W}")
);
ability.addTarget(new TargetControlledPermanent(filter));
ability.addEffect(new DrawCardSourceControllerEffect(1, "you"));
@ -126,4 +126,4 @@ class DiscerningFinancierEffect extends OneShotEffect {
return true;
}
}
}

View file

@ -1,22 +1,13 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.abilities.effects.common.TargetPlayerGainControlTargetPermanentEffect;
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.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetControlledPermanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
@ -28,7 +19,7 @@ public final class Donate extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}");
// Target player gains control of target permanent you control.
this.getSpellAbility().addEffect(new DonateEffect());
this.getSpellAbility().addEffect(new TargetPlayerGainControlTargetPermanentEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addTarget(new TargetControlledPermanent());
}
@ -42,33 +33,3 @@ public final class Donate extends CardImpl {
return new Donate(this);
}
}
class DonateEffect extends OneShotEffect {
DonateEffect() {
super(Outcome.Detriment);
this.staticText = "Target player gains control of target permanent you control";
}
private DonateEffect(final DonateEffect effect) {
super(effect);
}
@Override
public DonateEffect copy() {
return new DonateEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (targetPlayer != null && permanent != null) {
ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, true, targetPlayer.getId());
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
}
return true;
}
}

View file

@ -49,7 +49,7 @@ public final class EdgewallInn extends CardImpl {
// {3}, {T}, Sacrifice Edgewall Inn: Return target card that has an Adventure from your graveyard to your hand.
Ability ability = new SimpleActivatedAbility(
new ReturnFromGraveyardToHandTargetEffect(),
new ManaCostsImpl("{3}")
new ManaCostsImpl<>("{3}")
);
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());

View file

@ -31,7 +31,7 @@ public final class FallOfCairAndros extends CardImpl {
this.addAbility(new FallOfCairAndrosTriggeredAbility());
// {7}{R}: Fall of Cair Andros deals 7 damage to target creature.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(7), new ManaCostsImpl("{7}{R}"));
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(7), new ManaCostsImpl<>("{7}{R}"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}

View file

@ -1,4 +1,3 @@
package mage.cards.f;
import java.util.UUID;
@ -34,51 +33,54 @@ public final class FathomTrawl extends CardImpl {
return new FathomTrawl(this);
}
class FathomTrawlEffect extends OneShotEffect {
}
public FathomTrawlEffect() {
super(Outcome.DrawCard);
this.staticText = "Reveal cards from the top of your library until you reveal three nonland cards. Put the nonland cards revealed this way into your hand, then put the rest of the revealed cards on the bottom of your library in any order";
class FathomTrawlEffect extends OneShotEffect {
FathomTrawlEffect() {
super(Outcome.DrawCard);
this.staticText = "Reveal cards from the top of your library until you reveal three nonland cards. " +
"Put the nonland cards revealed this way into your hand, then put the rest of the revealed " +
"cards on the bottom of your library in any order";
}
private FathomTrawlEffect(final FathomTrawlEffect effect) {
super(effect);
}
@Override
public FathomTrawlEffect copy() {
return new FathomTrawlEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
MageObject sourceObject = game.getObject(source);
Player controller = game.getPlayer(source.getControllerId());
if (controller == null || sourceObject == null) {
return false;
}
private FathomTrawlEffect(final FathomTrawlEffect effect) {
super(effect);
}
@Override
public FathomTrawlEffect copy() {
return new FathomTrawlEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
MageObject sourceObject = game.getObject(source);
Player controller = game.getPlayer(source.getControllerId());
if (controller == null || sourceObject == null) {
return false;
}
Cards cards = new CardsImpl();
Cards nonlandCards = new CardsImpl();
Cards landCards = new CardsImpl();
for (Card card : controller.getLibrary().getCards(game)) {
if (card != null) {
cards.add(card);
if (!card.isLand(game)) {
nonlandCards.add(card);
if (nonlandCards.size() == 3) {
break;
}
} else {
landCards.add(card);
Cards cards = new CardsImpl();
Cards nonlandCards = new CardsImpl();
Cards landCards = new CardsImpl();
for (Card card : controller.getLibrary().getCards(game)) {
if (card != null) {
cards.add(card);
if (!card.isLand(game)) {
nonlandCards.add(card);
if (nonlandCards.size() == 3) {
break;
}
} else {
break;
landCards.add(card);
}
} else {
break;
}
controller.revealCards(sourceObject.getName(), cards, game);
controller.moveCards(nonlandCards, Zone.HAND, source, game);
controller.putCardsOnBottomOfLibrary(landCards, game, source, true);
return true;
}
controller.revealCards(sourceObject.getName(), cards, game);
controller.moveCards(nonlandCards, Zone.HAND, source, game);
controller.putCardsOnBottomOfLibrary(landCards, game, source, true);
return true;
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.f;
import mage.MageInt;
@ -28,11 +27,6 @@ import java.util.UUID;
* @author Blinke
*/
public final class ForgottenAncient extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature");
static {
filter.add(AnotherPredicate.instance);
}
public ForgottenAncient(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
@ -58,82 +52,89 @@ public final class ForgottenAncient extends CardImpl {
return new ForgottenAncient(this);
}
class CounterMovement {
}
class ForgottenAncientEffect extends OneShotEffect {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature");
static {
filter.add(AnotherPredicate.instance);
}
ForgottenAncientEffect() {
super(Outcome.Benefit);
this.staticText = "you may move any number of +1/+1 counters from {this} onto other creatures.";
}
private ForgottenAncientEffect(final ForgottenAncientEffect effect) {
super(effect);
}
@Override
public ForgottenAncientEffect copy() {
return new ForgottenAncientEffect(this);
}
static class CounterMovement {
public UUID target;
public int counters;
}
class ForgottenAncientEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
public ForgottenAncientEffect() {
super(Outcome.Benefit);
this.staticText = "you may move any number of +1/+1 counters from {this} onto other creatures.";
if (controller == null || sourcePermanent == null) {
return false;
}
private ForgottenAncientEffect(final ForgottenAncientEffect effect) {
super(effect);
int numCounters = sourcePermanent.getCounters(game).getCount(CounterType.P1P1);
if (numCounters == 0) {
return false;
}
@Override
public ForgottenAncientEffect copy() {
return new ForgottenAncientEffect(this);
}
List<CounterMovement> counterMovements = new ArrayList<>();
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (controller == null || sourcePermanent == null) {
return false;
do {
Target target = new TargetCreaturePermanent(1, 1, filter, true);
if (!target.canChoose(controller.getId(), source, game)) {
break;
}
int numCounters = sourcePermanent.getCounters(game).getCount(CounterType.P1P1);
if (numCounters == 0) {
return false;
if (!target.choose(Outcome.BoostCreature, source.getControllerId(), source.getSourceId(), source, game)) {
break;
}
List<CounterMovement> counterMovements = new ArrayList<>();
int amountToMove = controller.getAmount(0, numCounters, "Choose how many counters to move (" + numCounters + " counters remaining.)", game);
if (amountToMove == 0) {
break;
}
do {
Target target = new TargetCreaturePermanent(1, 1, filter, true);
if (!target.canChoose(controller.getId(), source, game)) {
break;
}
if (!target.choose(Outcome.BoostCreature, source.getControllerId(), source.getSourceId(), source, game)) {
break;
}
int amountToMove = controller.getAmount(0, numCounters, "Choose how many counters to move (" + numCounters + " counters remaining.)", game);
if (amountToMove == 0) {
break;
}
boolean previouslyChosen = false;
for (CounterMovement cm : counterMovements) {
if (cm.target.equals(target.getFirstTarget())) {
cm.counters += amountToMove;
previouslyChosen = true;
}
}
if (!previouslyChosen) {
CounterMovement cm = new CounterMovement();
cm.target = target.getFirstTarget();
cm.counters = amountToMove;
counterMovements.add(cm);
}
numCounters -= amountToMove;
} while (numCounters > 0 && controller.chooseUse(Outcome.Benefit, "Move additional counters?", source, game));
//Move all the counters for each chosen creature
boolean previouslyChosen = false;
for (CounterMovement cm : counterMovements) {
sourcePermanent.removeCounters(CounterType.P1P1.createInstance(cm.counters), source, game);
game.getPermanent(cm.target).addCounters(CounterType.P1P1.createInstance(cm.counters), source.getControllerId(), source, game);
if (cm.target.equals(target.getFirstTarget())) {
cm.counters += amountToMove;
previouslyChosen = true;
}
}
return true;
if (!previouslyChosen) {
CounterMovement cm = new CounterMovement();
cm.target = target.getFirstTarget();
cm.counters = amountToMove;
counterMovements.add(cm);
}
numCounters -= amountToMove;
} while (numCounters > 0 && controller.chooseUse(Outcome.Benefit, "Move additional counters?", source, game));
//Move all the counters for each chosen creature
for (CounterMovement cm : counterMovements) {
sourcePermanent.removeCounters(CounterType.P1P1.createInstance(cm.counters), source, game);
game.getPermanent(cm.target).addCounters(CounterType.P1P1.createInstance(cm.counters), source.getControllerId(), source, game);
}
return true;
}
}

View file

@ -1,5 +1,3 @@
package mage.cards.f;
import java.util.ArrayList;
@ -42,14 +40,12 @@ public final class FulgentDistraction extends CardImpl {
class FulgentDistractionEffect extends OneShotEffect {
private static String text = "Choose two target creatures. Tap those creatures, then unattach all Equipment from them";
FulgentDistractionEffect ( ) {
FulgentDistractionEffect() {
super(Outcome.Tap);
staticText = text;
staticText = "Choose two target creatures. Tap those creatures, then unattach all Equipment from them";
}
FulgentDistractionEffect ( FulgentDistractionEffect effect ) {
private FulgentDistractionEffect(FulgentDistractionEffect effect) {
super(effect);
}
@ -63,13 +59,14 @@ class FulgentDistractionEffect extends OneShotEffect {
Permanent equipment = game.getPermanent(equipmentId);
boolean isEquipment = false;
for ( Ability ability : equipment.getAbilities() ) {
if ( ability instanceof EquipAbility ) {
for (Ability ability : equipment.getAbilities()) {
if (ability instanceof EquipAbility) {
isEquipment = true;
break;
}
}
if ( isEquipment ) {
if (isEquipment) {
creature.removeAttachment(equipmentId, source, game);
}
}

View file

@ -46,7 +46,7 @@ public final class GoddricCloakedReveler extends CardImpl {
// Celebration -- As long as two or more nonland permanents entered the battlefield under your control this turn, Goddric, Cloaked Reveler is a Dragon with base power and toughness 4/4, flying, and "{R}: Dragons you control get +1/+0 until end of turn."
Ability dragonFirebreath = new SimpleActivatedAbility(
new BoostAllEffect(1, 0, Duration.EndOfTurn, filter, false),
new ManaCostsImpl("{R}")
new ManaCostsImpl<>("{R}")
);
Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect(

View file

@ -1,22 +1,14 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.TargetPlayerGainControlTargetPermanentEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
*
* @author fireshoes
@ -27,7 +19,7 @@ public final class HarmlessOffering extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}");
// Target opponent gains control of target permanent you control.
this.getSpellAbility().addEffect(new HarmlessOfferingEffect());
this.getSpellAbility().addEffect(new TargetPlayerGainControlTargetPermanentEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addTarget(new TargetControlledPermanent());
}
@ -41,34 +33,3 @@ public final class HarmlessOffering extends CardImpl {
return new HarmlessOffering(this);
}
}
class HarmlessOfferingEffect extends ContinuousEffectImpl {
HarmlessOfferingEffect() {
super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.Benefit);
this.staticText = "Target opponent gains control of target permanent you control";
}
private HarmlessOfferingEffect(final HarmlessOfferingEffect effect) {
super(effect);
}
@Override
public HarmlessOfferingEffect copy() {
return new HarmlessOfferingEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
UUID controllerId = source.getTargets().get(0).getFirstTarget();
Player controller = game.getPlayer(controllerId);
Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (controller != null && permanent != null) {
permanent.changeControllerId(controllerId, game, source);
} else {
this.discard();
}
return true;
}
}

View file

@ -34,7 +34,7 @@ public final class HopelessNightmare extends CardImpl {
this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new ScryEffect(2, false)));
// {2}{B}: Sacrifice Hopeless Nightmare.
this.addAbility(new SimpleActivatedAbility(new SacrificeSourceEffect(), new ManaCostsImpl("{2}{B}")));
this.addAbility(new SimpleActivatedAbility(new SacrificeSourceEffect(), new ManaCostsImpl<>("{2}{B}")));
}
private HopelessNightmare(final HopelessNightmare card) {

View file

@ -62,7 +62,8 @@ public final class IntiSeneschalOfTheSun extends CardImpl {
class IntiSeneschalOfTheSunTriggeredAbility extends TriggeredAbilityImpl {
IntiSeneschalOfTheSunTriggeredAbility() {
super(Zone.BATTLEFIELD, new ExileTopXMayPlayUntilEffect(1, Duration.UntilYourNextEndStep));
super(Zone.BATTLEFIELD, new ExileTopXMayPlayUntilEffect(1, Duration.UntilYourNextEndStep)
.withTextOptions("that card", true));
this.setTriggerPhrase("Whenever you discard one or more cards, ");
}

View file

@ -27,7 +27,7 @@ public final class JeskasWill extends CardImpl {
// Choose one. If you control a commander as you cast this spell, you may choose both.
this.getSpellAbility().getModes().setChooseText(
"Choose one. If you control a commander as you cast this spell, you may choose both."
"Choose one. If you control a commander as you cast this spell, you may choose both instead."
);
this.getSpellAbility().getModes().setMoreCondition(ControlACommanderCondition.instance);
@ -70,7 +70,7 @@ class JeskasWillEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player player = game.getPlayer(source.getFirstTarget());
if (controller == null || player == null || player.getHand().size() < 1) {
if (controller == null || player == null || player.getHand().isEmpty()) {
return false;
}
controller.getManaPool().addMana(Mana.RedMana(player.getHand().size()), game, source);

View file

@ -0,0 +1,132 @@
package mage.cards.k;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author DominionSpy
*/
public final class KrenkosBuzzcrusher extends CardImpl {
public KrenkosBuzzcrusher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{R}{R}");
this.subtype.add(SubType.INSECT);
this.subtype.add(SubType.THOPTER);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// When Krenko's Buzzcrusher enters the battlefield, for each player, destroy up to one nonbasic land that player controls. For each land destroyed this way, its controller may search their library for a basic land card, put it onto the battlefield tapped, then shuffle.
this.addAbility(new EntersBattlefieldTriggeredAbility(new KrenkosBuzzcrusherEffect()));
}
private KrenkosBuzzcrusher(final KrenkosBuzzcrusher card) {
super(card);
}
@Override
public KrenkosBuzzcrusher copy() {
return new KrenkosBuzzcrusher(this);
}
}
class KrenkosBuzzcrusherEffect extends OneShotEffect {
KrenkosBuzzcrusherEffect() {
super(Outcome.DestroyPermanent);
staticText = "for each player, destroy up to one nonbasic land that player controls. " +
"For each land destroyed this way, its controller may search their library for a basic land card, " +
"put it onto the battlefield tapped, then shuffle";
}
private KrenkosBuzzcrusherEffect(final KrenkosBuzzcrusherEffect effect) {
super(effect);
}
@Override
public KrenkosBuzzcrusherEffect copy() {
return new KrenkosBuzzcrusherEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
List<Permanent> chosenLands = new ArrayList<>();
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player == null) {
continue;
}
FilterLandPermanent filter = new FilterLandPermanent("nonbasic land " + player.getName() + " controls");
filter.add(new ControllerIdPredicate(playerId));
filter.add(Predicates.not(SuperType.BASIC.getPredicate()));
TargetPermanent target = new TargetPermanent(0, 1, filter);
target.withNotTarget(true);
controller.chooseTarget(outcome, target, source, game);
Permanent land = game.getPermanent(target.getFirstTarget());
if (land != null) {
chosenLands.add(land);
}
}
List<Permanent> destroyedLands = new ArrayList<>();
for (Permanent land : chosenLands) {
if (land.destroy(source, game)) {
destroyedLands.add(land);
}
}
for (Permanent land : destroyedLands) {
Player player = game.getPlayer(land.getControllerId());
if (player == null) {
continue;
}
TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND_A);
if (!player.chooseUse(Outcome.PutLandInPlay, "Search your library for " + target.getDescription() + "?", source, game)) {
continue;
}
if (player.searchLibrary(target, source, game)) {
player.moveCards(game.getCard(target.getFirstTarget()), Zone.BATTLEFIELD,
source, game, true, false, false, null);
player.shuffleLibrary(source, game);
}
}
return true;
}
}

View file

@ -6,7 +6,7 @@ import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterLandPermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -36,9 +36,7 @@ public final class Melting extends CardImpl {
class MeltingEffect extends ContinuousEffectImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent();
public MeltingEffect() {
MeltingEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
this.staticText = "All lands are no longer snow";
}
@ -54,7 +52,7 @@ class MeltingEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source, game)) {
permanent.removeSuperType(game, SuperType.SNOW);
}
return true;

View file

@ -41,8 +41,7 @@ public final class PortRazer extends CardImpl {
"untap each creature you control"
), false
);
ability.addEffect(new AdditionalCombatPhaseEffect()
.setText("After this combat phase, there is an additional combat phase."));
ability.addEffect(new AdditionalCombatPhaseEffect());
this.addAbility(ability);
// Port Razer can't attack a player it has already attacked this turn.

View file

@ -1,4 +1,3 @@
package mage.cards.p;
import java.util.UUID;
@ -53,67 +52,68 @@ public final class ProteanHydra extends CardImpl {
return new ProteanHydra(this);
}
class ProteanHydraAbility extends TriggeredAbilityImpl {
public ProteanHydraAbility() {
super(Zone.BATTLEFIELD, new CreateDelayedTriggeredAbilityEffect(new ProteanHydraDelayedTriggeredAbility()), false);
}
private ProteanHydraAbility(final ProteanHydraAbility ability) {
super(ability);
}
@Override
public ProteanHydraAbility copy() {
return new ProteanHydraAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.COUNTER_REMOVED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getData().equals(CounterType.P1P1.getName()) && event.getTargetId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "Whenever a +1/+1 counter is removed from {this}, put two +1/+1 counters on it at the beginning of the next end step.";
}
}
static class ProteanHydraDelayedTriggeredAbility extends DelayedTriggeredAbility {
public ProteanHydraDelayedTriggeredAbility() {
super(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)));
}
private ProteanHydraDelayedTriggeredAbility(final ProteanHydraDelayedTriggeredAbility ability) {
super(ability);
}
@Override
public ProteanHydraDelayedTriggeredAbility copy() {
return new ProteanHydraDelayedTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.END_TURN_STEP_PRE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return true;
}
@Override
public String getRule() {
return "Put two +1/+1 counters on {this} at the beginning of the next end step";
}
}
}
class ProteanHydraAbility extends TriggeredAbilityImpl {
ProteanHydraAbility() {
super(Zone.BATTLEFIELD, new CreateDelayedTriggeredAbilityEffect(new ProteanHydraDelayedTriggeredAbility()), false);
}
private ProteanHydraAbility(final ProteanHydraAbility ability) {
super(ability);
}
@Override
public ProteanHydraAbility copy() {
return new ProteanHydraAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.COUNTER_REMOVED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getData().equals(CounterType.P1P1.getName()) && event.getTargetId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "Whenever a +1/+1 counter is removed from {this}, put two +1/+1 counters on it at the beginning of the next end step.";
}
}
class ProteanHydraDelayedTriggeredAbility extends DelayedTriggeredAbility {
ProteanHydraDelayedTriggeredAbility() {
super(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)));
}
private ProteanHydraDelayedTriggeredAbility(final ProteanHydraDelayedTriggeredAbility ability) {
super(ability);
}
@Override
public ProteanHydraDelayedTriggeredAbility copy() {
return new ProteanHydraDelayedTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.END_TURN_STEP_PRE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return true;
}
@Override
public String getRule() {
return "Put two +1/+1 counters on {this} at the beginning of the next end step";
}
}

View file

@ -47,7 +47,7 @@ public final class RampagingRaptor extends CardImpl {
// {2}{R}: Rampaging Raptor gets +2/+0 until end of turn.
this.addAbility(new SimpleActivatedAbility(
new BoostSourceEffect(2, 0, Duration.EndOfTurn), new ManaCostsImpl("{2}{R}")
new BoostSourceEffect(2, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{2}{R}")
));
// Whenever Rampaging Raptor deals combat damage to an opponent, it deals that much damage to target planeswalker that player controls or battle that player protects.

View file

@ -1,5 +1,3 @@
package mage.cards.r;
import java.util.UUID;
@ -15,6 +13,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -45,42 +44,40 @@ public final class RatchetBomb extends CardImpl {
return new RatchetBomb(this);
}
class RatchetBombEffect extends OneShotEffect {
}
public RatchetBombEffect() {
super(Outcome.DestroyPermanent);
staticText = "Destroy each nonland permanent with mana value equal to the number of charge counters on {this}";
}
class RatchetBombEffect extends OneShotEffect {
private RatchetBombEffect(final RatchetBombEffect effect) {
super(effect);
}
RatchetBombEffect() {
super(Outcome.DestroyPermanent);
staticText = "Destroy each nonland permanent with mana value equal to the number of charge counters on {this}";
}
@Override
public boolean apply(Game game, Ability source) {
Permanent p = game.getBattlefield().getPermanent(source.getSourceId());
private RatchetBombEffect(final RatchetBombEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent p = game.getBattlefield().getPermanent(source.getSourceId());
if (p == null) {
p = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
if (p == null) {
p = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
if (p == null) {
return false;
}
return false;
}
int count = p.getCounters(game).getCount(CounterType.CHARGE);
for (Permanent perm: game.getBattlefield().getAllActivePermanents()) {
if (perm.getManaValue() == count && !(perm.isLand(game))) {
perm.destroy(source, game, false);
}
}
int count = p.getCounters(game).getCount(CounterType.CHARGE);
for (Permanent perm : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_NON_LAND, source.getControllerId(), source, game)) {
if (perm.getManaValue() == count) {
perm.destroy(source, game, false);
}
return true;
}
@Override
public RatchetBombEffect copy() {
return new RatchetBombEffect(this);
}
return true;
}
@Override
public RatchetBombEffect copy() {
return new RatchetBombEffect(this);
}
}

View file

@ -34,7 +34,7 @@ public final class RuinsRecluse extends CardImpl {
// {3}{G}: Put a +1/+1 counter on Ruins Recluse.
this.addAbility(new SimpleActivatedAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl("{3}{G}")
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{3}{G}")
));
}

View file

@ -1,22 +1,19 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect;
import mage.abilities.effects.common.continuous.AddBasicLandTypeAllLandsEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.IslandwalkAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
@ -44,7 +41,8 @@ public final class StormtideLeviathan extends CardImpl {
this.addAbility(new IslandwalkAbility());
// All lands are Islands in addition to their other types.
this.addAbility(new SimpleStaticAbility(new StormtideLeviathanEffect()));
this.addAbility(new SimpleStaticAbility(new AddBasicLandTypeAllLandsEffect(SubType.ISLAND)
.setText("all lands are Islands in addition to their other types")));
// Creatures without flying or islandwalk can't attack.
this.addAbility(new SimpleStaticAbility(new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, filter)));
@ -59,35 +57,4 @@ public final class StormtideLeviathan extends CardImpl {
return new StormtideLeviathan(this);
}
class StormtideLeviathanEffect extends ContinuousEffectImpl {
private StormtideLeviathanEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "All lands are Islands in addition to their other types";
this.dependencyTypes.add(DependencyType.BecomeIsland);
}
private StormtideLeviathanEffect(final StormtideLeviathanEffect effect) {
super(effect);
}
@Override
public StormtideLeviathanEffect copy() {
return new StormtideLeviathanEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent land : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_LAND, source.getControllerId(), game
)) {
// land abilities are intrinsic, so add them here, not in layer 6
land.addSubType(game, SubType.ISLAND);
if (!land.getAbilities(game).containsClass(BlueManaAbility.class)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
}
return true;
}
}
}

View file

@ -35,7 +35,7 @@ public final class TempleOfCivilization extends CardImpl {
Ability ability = new ActivateIfConditionActivatedAbility(
Zone.BATTLEFIELD,
new TransformSourceEffect(),
new ManaCostsImpl("{2}{W}"),
new ManaCostsImpl<>("{2}{W}"),
TempleOfCivilizationCondition.instance,
TimingRule.SORCERY
);

View file

@ -37,7 +37,7 @@ public final class TempleOfCultivation extends CardImpl {
Ability ability = new ActivateIfConditionActivatedAbility(
Zone.BATTLEFIELD,
new TransformSourceEffect(),
new ManaCostsImpl("{2}{G}"),
new ManaCostsImpl<>("{2}{G}"),
new TempleOfCultivationCondition(),
TimingRule.SORCERY
);

View file

@ -35,7 +35,7 @@ public final class TempleOfTheDead extends CardImpl {
Ability ability = new ActivateIfConditionActivatedAbility(
Zone.BATTLEFIELD,
new TransformSourceEffect(),
new ManaCostsImpl("{2}{B}"),
new ManaCostsImpl<>("{2}{B}"),
TempleOfTheDeadCondition.instance,
TimingRule.SORCERY
);

View file

@ -53,7 +53,7 @@ public final class TheBlackGate extends CardImpl {
// {1}{B}, {T}: Choose a player with the most life or tied for most life. Target creature can't be blocked by creatures that player controls this turn.
ActivatedAbility ability = new SimpleActivatedAbility(
new BlackGateEffect(),
new ManaCostsImpl("{1}{B}")
new ManaCostsImpl<>("{1}{B}")
);
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
@ -148,4 +148,4 @@ class BlackGateEffect extends OneShotEffect {
return true;
}
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.t;
import java.util.UUID;
@ -14,7 +13,6 @@ import mage.constants.SubType;
import mage.constants.Duration;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
/**
*
@ -42,34 +40,35 @@ public final class TolarianEntrancer extends CardImpl {
return new TolarianEntrancer(this);
}
class TolarianEntrancerDelayedTriggeredAbility extends DelayedTriggeredAbility {
}
public TolarianEntrancerDelayedTriggeredAbility() {
super(new GainControlTargetEffect(Duration.EndOfGame));
}
class TolarianEntrancerDelayedTriggeredAbility extends DelayedTriggeredAbility {
private TolarianEntrancerDelayedTriggeredAbility(final TolarianEntrancerDelayedTriggeredAbility ability) {
super(ability);
}
TolarianEntrancerDelayedTriggeredAbility() {
super(new GainControlTargetEffect(Duration.EndOfGame));
}
@Override
public TolarianEntrancerDelayedTriggeredAbility copy() {
return new TolarianEntrancerDelayedTriggeredAbility(this);
}
private TolarianEntrancerDelayedTriggeredAbility(final TolarianEntrancerDelayedTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.END_COMBAT_STEP_POST;
}
@Override
public TolarianEntrancerDelayedTriggeredAbility copy() {
return new TolarianEntrancerDelayedTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return true;
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.END_COMBAT_STEP_POST;
}
@Override
public String getRule() {
return "gain control of that creature at end of combat";
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return true;
}
@Override
public String getRule() {
return "gain control of that creature at end of combat";
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.w;
import java.util.UUID;
@ -57,22 +56,24 @@ public final class WindZendikon extends CardImpl {
return new WindZendikon(this);
}
class WindZendikonElementalToken extends TokenImpl {
WindZendikonElementalToken() {
super("", "2/2 blue Elemental creature with flying");
cardType.add(CardType.CREATURE);
color.setBlue(true);
subtype.add(SubType.ELEMENTAL);
power = new MageInt(2);
toughness = new MageInt(2);
addAbility(FlyingAbility.getInstance());
}
private WindZendikonElementalToken(final WindZendikonElementalToken token) {
super(token);
}
}
public WindZendikonElementalToken copy() {
return new WindZendikonElementalToken(this);
}
class WindZendikonElementalToken extends TokenImpl {
WindZendikonElementalToken() {
super("", "2/2 blue Elemental creature with flying");
cardType.add(CardType.CREATURE);
color.setBlue(true);
subtype.add(SubType.ELEMENTAL);
power = new MageInt(2);
toughness = new MageInt(2);
addAbility(FlyingAbility.getInstance());
}
private WindZendikonElementalToken(final WindZendikonElementalToken token) {
super(token);
}
public WindZendikonElementalToken copy() {
return new WindZendikonElementalToken(this);
}
}

View file

@ -1,17 +1,11 @@
package mage.cards.w;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.abilities.effects.common.TargetPlayerGainControlTargetPermanentEffect;
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.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
@ -24,7 +18,7 @@ public final class WrongTurn extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}");
// Target opponent gains control of target creature.
this.getSpellAbility().addEffect(new WrongTurnEffect());
this.getSpellAbility().addEffect(new TargetPlayerGainControlTargetPermanentEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
@ -38,28 +32,3 @@ public final class WrongTurn extends CardImpl {
return new WrongTurn(this);
}
}
class WrongTurnEffect extends OneShotEffect {
WrongTurnEffect() {
super(Outcome.Benefit);
staticText = "target opponent gains control of target creature";
}
private WrongTurnEffect(final WrongTurnEffect effect) {
super(effect);
}
@Override
public WrongTurnEffect copy() {
return new WrongTurnEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addEffect(new GainControlTargetEffect(
Duration.Custom, true, source.getFirstTarget()
).setTargetPointer(new FixedTarget(source.getTargets().get(1).getFirstTarget(), game)), source);
return true;
}
}

View file

@ -31,7 +31,7 @@ public final class YasminKhan extends CardImpl {
// {T}: Exile the top card of your library. Until your next end step, you may play it.
this.addAbility(new SimpleActivatedAbility(new ExileTopXMayPlayUntilEffect(
1, Duration.UntilYourNextEndStep
), new TapSourceCost()));
).withTextOptions("it", false), new TapSourceCost()));
// Doctor's companion
this.addAbility(DoctorsCompanionAbility.getInstance());

View file

@ -1,26 +1,23 @@
package mage.cards.z;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.PermanentsYouOwnThatOpponentsControlCount;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.TargetPlayerGainControlTargetPermanentEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
*
* @author andyfries
@ -44,7 +41,7 @@ public final class ZedruuTheGreathearted extends CardImpl {
this.addAbility(ability);
// {R}{W}{U}: Target opponent gains control of target permanent you control.
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ZedruuTheGreatheartedEffect(), new ManaCostsImpl<>("{U}{R}{W}"));
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TargetPlayerGainControlTargetPermanentEffect(), new ManaCostsImpl<>("{U}{R}{W}"));
ability.addTarget(new TargetOpponent());
ability.addTarget(new TargetControlledPermanent());
this.addAbility(ability);
@ -59,40 +56,4 @@ public final class ZedruuTheGreathearted extends CardImpl {
return new ZedruuTheGreathearted(this);
}
class ZedruuTheGreatheartedEffect extends ContinuousEffectImpl {
private MageObjectReference targetPermanentReference;
public ZedruuTheGreatheartedEffect() {
super(Duration.Custom, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.staticText = "Target opponent gains control of target permanent you control";
}
private ZedruuTheGreatheartedEffect(final ZedruuTheGreatheartedEffect effect) {
super(effect);
this.targetPermanentReference = effect.targetPermanentReference;
}
@Override
public ZedruuTheGreatheartedEffect copy() {
return new ZedruuTheGreatheartedEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
targetPermanentReference = new MageObjectReference(source.getTargets().get(1).getFirstTarget(), game);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = targetPermanentReference.getPermanent(game);
if (permanent != null) {
return permanent.changeControllerId(source.getFirstTarget(), game, source);
} else {
discard();
}
return false;
}
}
}

View file

@ -139,6 +139,7 @@ public final class MurdersAtKarlovManor extends ExpansionSet {
cards.add(new SetCardInfo("Jaded Analyst", 62, Rarity.COMMON, mage.cards.j.JadedAnalyst.class));
cards.add(new SetCardInfo("Knife", 134, Rarity.UNCOMMON, mage.cards.k.Knife.class));
cards.add(new SetCardInfo("Kraul Whipcracker", 213, Rarity.UNCOMMON, mage.cards.k.KraulWhipcracker.class));
cards.add(new SetCardInfo("Krenko's Buzzcrusher", 136, Rarity.RARE, mage.cards.k.KrenkosBuzzcrusher.class));
cards.add(new SetCardInfo("Krenko, Baron of Tin Street", 135, Rarity.RARE, mage.cards.k.KrenkoBaronOfTinStreet.class));
cards.add(new SetCardInfo("Krovod Haunch", 21, Rarity.UNCOMMON, mage.cards.k.KrovodHaunch.class));
cards.add(new SetCardInfo("Kylox, Visionary Inventor", 214, Rarity.RARE, mage.cards.k.KyloxVisionaryInventor.class));

View file

@ -133,7 +133,7 @@ public final class MurdersAtKarlovManorCommander extends ExpansionSet {
cards.add(new SetCardInfo("Krosan Colossus", 176, Rarity.RARE, mage.cards.k.KrosanColossus.class));
cards.add(new SetCardInfo("Krosan Verge", 271, Rarity.UNCOMMON, mage.cards.k.KrosanVerge.class));
cards.add(new SetCardInfo("Labyrinth of Skophos", 272, Rarity.RARE, mage.cards.l.LabyrinthOfSkophos.class));
cards.add(new SetCardInfo("Lazav, the Multifarious", 214, Rarity.RARE, mage.cards.l.LazavTheMultifarious.class));
cards.add(new SetCardInfo("Lazav, the Multifarious", 214, Rarity.MYTHIC, mage.cards.l.LazavTheMultifarious.class));
cards.add(new SetCardInfo("Lifecrafter's Bestiary", 231, Rarity.RARE, mage.cards.l.LifecraftersBestiary.class));
cards.add(new SetCardInfo("Lonely Sandbar", 273, Rarity.UNCOMMON, mage.cards.l.LonelySandbar.class));
cards.add(new SetCardInfo("Lonis, Cryptozoologist", 215, Rarity.RARE, mage.cards.l.LonisCryptozoologist.class));

View file

@ -0,0 +1,67 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
/**
* @author xenohedron
*/
public class TargetPlayerGainControlTargetPermanentEffect extends OneShotEffect {
private final String playerDescription;
public TargetPlayerGainControlTargetPermanentEffect() {
this("");
}
public TargetPlayerGainControlTargetPermanentEffect(String playerDescription) {
super(Outcome.Benefit);
this.playerDescription = playerDescription;
}
protected TargetPlayerGainControlTargetPermanentEffect(final TargetPlayerGainControlTargetPermanentEffect effect) {
super(effect);
this.playerDescription = effect.playerDescription;
}
@Override
public boolean apply(Game game, Ability source) {
if (source.getTargets().size() != 2) {
throw new IllegalStateException("It must have two targets, but found " + source.getTargets().size());
}
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (player == null || permanent == null) {
return false;
}
game.addEffect(new GainControlTargetEffect(
Duration.Custom, true, player.getId()
).setTargetPointer(new FixedTarget(permanent, game)), source);
return true;
}
@Override
public TargetPlayerGainControlTargetPermanentEffect copy() {
return new TargetPlayerGainControlTargetPermanentEffect(this);
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
if (mode.getTargets().size() != 2) {
throw new IllegalStateException("It must have two targets, but found " + mode.getTargets().size());
}
return (playerDescription.isEmpty() ? mode.getTargets().get(0).getDescription() : playerDescription) +
" gains control of " + mode.getTargets().get(1).getDescription();
}
}

View file

@ -21,7 +21,7 @@ import java.util.UUID;
public class GainControlTargetEffect extends ContinuousEffectImpl {
protected UUID controllingPlayerId;
private boolean fixedControl;
private final boolean fixedControl;
private boolean firstControlChange = true;
private final Condition condition;
@ -63,6 +63,7 @@ public class GainControlTargetEffect extends ContinuousEffectImpl {
this.controllingPlayerId = effect.controllingPlayerId;
this.fixedControl = effect.fixedControl;
this.condition = effect.condition;
this.firstControlChange = effect.firstControlChange;
}
@Override