Create generic "Gains your choice of ability" effect, add [ACR] Assassin Initiate (#12619)

Create generic GainsChoiceOfAbilitiesEffect, covers both Target and Source cases.

Adds Assassin Initiate
This commit is contained in:
ssk97 2024-08-22 13:34:40 -07:00 committed by GitHub
parent b70638acc9
commit 00770646f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 381 additions and 1162 deletions

View file

@ -1,6 +1,5 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
@ -8,22 +7,24 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.common.FilterNonlandPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.permanent.token.BirdToken;
import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/**
*
* @author weirddan455
*/
public final class AetherChanneler extends CardImpl {
private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("another nonland permanent");
private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("another target nonland permanent");
static {
filter.add(AnotherPredicate.instance);
@ -42,8 +43,7 @@ public final class AetherChanneler extends CardImpl {
// * Return another target nonland permanent to its owner's hand.
// * Draw a card.
Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BirdToken()));
Mode mode = new Mode(new ReturnToHandTargetEffect()
.setText("Return another target nonland permanent to its owner's hand."));
Mode mode = new Mode(new ReturnToHandTargetEffect());
mode.addTarget(new TargetNonlandPermanent(filter));
ability.addMode(mode);
ability.addMode(new Mode(new DrawCardSourceControllerEffect(1)));

View file

@ -1,18 +1,12 @@
package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.LifelinkAbility;
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 mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -26,7 +20,9 @@ public final class AlchemistsGift extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}");
// Target creature gets +1/+1 and gains your choice of deathtouch or lifelink until end of turn.
this.getSpellAbility().addEffect(new AlchemistsGiftEffect());
this.getSpellAbility().addEffect(new BoostTargetEffect(1, 1).setText("Target creature gets +1/+1"));
this.getSpellAbility().addEffect(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Target, "", true,
DeathtouchAbility.getInstance(), LifelinkAbility.getInstance()).concatBy("and"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
@ -39,35 +35,3 @@ public final class AlchemistsGift extends CardImpl {
return new AlchemistsGift(this);
}
}
class AlchemistsGiftEffect extends OneShotEffect {
AlchemistsGiftEffect() {
super(Outcome.Benefit);
staticText = "Target creature gets +1/+1 and gains your choice of deathtouch or lifelink until end of turn.";
}
private AlchemistsGiftEffect(final AlchemistsGiftEffect effect) {
super(effect);
}
@Override
public AlchemistsGiftEffect copy() {
return new AlchemistsGiftEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Ability ability = player.chooseUse(
outcome, "Deathtouch or lifelink?", null,
"Deathtouch", "Lifelink", source, game
) ? DeathtouchAbility.getInstance() : LifelinkAbility.getInstance();
game.addEffect(new BoostTargetEffect(1, 1, Duration.EndOfTurn), source);
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn), source);
return true;
}
}

View file

@ -4,28 +4,17 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
/**
@ -41,7 +30,12 @@ public final class ArgivianAvenger extends CardImpl {
this.toughness = new MageInt(5);
// {1}: Until end of turn, Argivian Avenger gets -1/-1 and gains your choice of flying, vigilance, deathtouch, or haste.
this.addAbility(new SimpleActivatedAbility(new ArgivianAvengerEffect(), new GenericManaCost(1)));
Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(-1, -1)
.setText("Until end of turn, {this} gets -1/-1"), new GenericManaCost(1));
ability.addEffect(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source, "", false,
FlyingAbility.getInstance(), VigilanceAbility.getInstance(), DeathtouchAbility.getInstance(), HasteAbility.getInstance())
.concatBy("and"));
this.addAbility(ability);
}
private ArgivianAvenger(final ArgivianAvenger card) {
@ -53,49 +47,3 @@ public final class ArgivianAvenger extends CardImpl {
return new ArgivianAvenger(this);
}
}
class ArgivianAvengerEffect extends OneShotEffect {
private static final Map<String, Ability> abilityMap = new HashMap<>();
static {
abilityMap.put("Flying", FlyingAbility.getInstance());
abilityMap.put("Vigilance", VigilanceAbility.getInstance());
abilityMap.put("Deathtouch", DeathtouchAbility.getInstance());
abilityMap.put("Haste", HasteAbility.getInstance());
}
ArgivianAvengerEffect() {
super(Outcome.Benefit);
staticText = "until end of turn, {this} gets -1/-1 " +
"and gains your choice of flying, vigilance, deathtouch, or haste";
}
private ArgivianAvengerEffect(final ArgivianAvengerEffect effect) {
super(effect);
}
@Override
public ArgivianAvengerEffect copy() {
return new ArgivianAvengerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (player == null || permanent == null) {
return false;
}
game.addEffect(new BoostSourceEffect(-1, -1, Duration.EndOfTurn), source);
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose an ability");
choice.setChoices(new HashSet<>(abilityMap.keySet()));
player.choose(outcome, choice, game);
Ability ability = abilityMap.getOrDefault(choice.getChoice(), null);
if (ability != null) {
game.addEffect(new GainAbilitySourceEffect(ability, Duration.EndOfTurn), source);
}
return true;
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author notgreat
*/
public final class AssassinInitiate extends CardImpl {
public AssassinInitiate(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ASSASSIN);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {1}: Assassin Initiate gains your choice of flying, deathtouch, or lifelink until end of turn.
this.addAbility(new SimpleActivatedAbility(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source,
FlyingAbility.getInstance(), DeathtouchAbility.getInstance(), LifelinkAbility.getInstance()),
new GenericManaCost(1)));
}
private AssassinInitiate(final AssassinInitiate card) {
super(card);
}
@Override
public AssassinInitiate copy() {
return new AssassinInitiate(this);
}
}

View file

@ -1,14 +1,12 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlyingAbility;
@ -16,18 +14,12 @@ import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
/**
@ -50,7 +42,9 @@ public final class AtraxasSkitterfang extends CardImpl {
));
// At the beginning of combat on your turn, you may remove an oil counter from Atraxa's Skitterfang. When you do, target creature you control gains your choice of flying, vigilance, deathtouch, or lifelink until end of turn.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new AtraxasSkitterfangEffect(), false);
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new GainsChoiceOfAbilitiesEffect(
FlyingAbility.getInstance(), VigilanceAbility.getInstance(), DeathtouchAbility.getInstance(), LifelinkAbility.getInstance())
.concatBy("and"), false);
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(new BeginningOfCombatTriggeredAbility(new DoWhenCostPaid(
ability,
@ -68,48 +62,3 @@ public final class AtraxasSkitterfang extends CardImpl {
return new AtraxasSkitterfang(this);
}
}
class AtraxasSkitterfangEffect extends OneShotEffect {
private static final Map<String, Ability> abilityMap = new HashMap<>();
static {
abilityMap.put("Flying", FlyingAbility.getInstance());
abilityMap.put("Vigilance", VigilanceAbility.getInstance());
abilityMap.put("Deathtouch", DeathtouchAbility.getInstance());
abilityMap.put("Lifelink", LifelinkAbility.getInstance());
}
AtraxasSkitterfangEffect() {
super(Outcome.Benefit);
staticText = "target creature you control gains your choice " +
"of flying, vigilance, deathtouch, or lifelink until end of turn";
}
private AtraxasSkitterfangEffect(final AtraxasSkitterfangEffect effect) {
super(effect);
}
@Override
public AtraxasSkitterfangEffect copy() {
return new AtraxasSkitterfangEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (player == null || permanent == null) {
return false;
}
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose an ability");
choice.setChoices(new HashSet<>(abilityMap.keySet()));
player.choose(outcome, choice, game);
Ability ability = abilityMap.getOrDefault(choice.getChoice(), null);
if (ability != null) {
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn), source);
}
return true;
}
}

View file

@ -3,26 +3,16 @@ package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTargets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
@ -39,8 +29,9 @@ public final class BallroomBrawlers extends CardImpl {
this.toughness = new MageInt(5);
// Whenever Ballroom Brawlers attacks, Ballroom Brawlers and up to one other target creature you control each gain your choice of first strike or lifelink until end of turn.
Ability ability = new AttacksTriggeredAbility(new BallroomBrawlersEffect()).withRuleTextReplacement(false);
ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE));
Ability ability = new AttacksTriggeredAbility(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Both,
FirstStrikeAbility.getInstance(), LifelinkAbility.getInstance())).withRuleTextReplacement(false);
ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL));
this.addAbility(ability);
}
@ -53,43 +44,3 @@ public final class BallroomBrawlers extends CardImpl {
return new BallroomBrawlers(this);
}
}
class BallroomBrawlersEffect extends OneShotEffect {
BallroomBrawlersEffect() {
super(Outcome.Benefit);
staticText = "{this} and up to one other target creature you control " +
"both gain your choice of first strike or lifelink until end of turn";
}
private BallroomBrawlersEffect(final BallroomBrawlersEffect effect) {
super(effect);
}
@Override
public BallroomBrawlersEffect copy() {
return new BallroomBrawlersEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
List<Permanent> permanents = new ArrayList<>();
permanents.add(source.getSourcePermanentIfItStillExists(game));
permanents.add(game.getPermanent(getTargetPointer().getFirst(game, source)));
permanents.removeIf(Objects::isNull);
if (permanents.isEmpty()) {
return false;
}
Ability ability = player.chooseUse(
outcome, "Choose first strike or lifelink", null,
"First Strike", "Lifelink", source, game
) ? FirstStrikeAbility.getInstance() : LifelinkAbility.getInstance();
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn)
.setTargetPointer(new FixedTargets(permanents, game)), source);
return true;
}
}

View file

@ -1,28 +1,20 @@
package mage.cards.b;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
@ -39,9 +31,11 @@ public final class ButcherOfTheHorde extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Sacrifice another creature: Butcher of the Horde gains your choice of vigilance, lifelink, or haste until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
new ButcherOfTheHordeEffect(), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)));
this.addAbility(new SimpleActivatedAbility(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source,
VigilanceAbility.getInstance(), LifelinkAbility.getInstance(), HasteAbility.getInstance()),
new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)));
}
private ButcherOfTheHorde(final ButcherOfTheHorde card) {
@ -53,58 +47,3 @@ public final class ButcherOfTheHorde extends CardImpl {
return new ButcherOfTheHorde(this);
}
}
class ButcherOfTheHordeEffect extends OneShotEffect {
ButcherOfTheHordeEffect() {
super(Outcome.AddAbility);
staticText = "{this} gains your choice of vigilance, lifelink, or haste until end of turn";
}
private ButcherOfTheHordeEffect(final ButcherOfTheHordeEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source);
if (sourceObject != null && controller != null) {
Choice abilityChoice = new ChoiceImpl(true);
abilityChoice.setMessage("Choose an ability to add");
Set<String> abilities = new HashSet<>();
abilities.add(VigilanceAbility.getInstance().getRule());
abilities.add(LifelinkAbility.getInstance().getRule());
abilities.add(HasteAbility.getInstance().getRule());
abilityChoice.setChoices(abilities);
controller.choose(Outcome.AddAbility, abilityChoice, game);
if (!abilityChoice.isChosen()) {
return false;
}
String chosen = abilityChoice.getChoice();
Ability ability = null;
if (VigilanceAbility.getInstance().getRule().equals(chosen)) {
ability = VigilanceAbility.getInstance();
} else if (LifelinkAbility.getInstance().getRule().equals(chosen)) {
ability = LifelinkAbility.getInstance();
} else if (HasteAbility.getInstance().getRule().equals(chosen)) {
ability = HasteAbility.getInstance();
}
if (ability != null) {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " has chosen: " + chosen);
ContinuousEffect effect = new GainAbilitySourceEffect(ability, Duration.EndOfTurn);
game.addEffect(effect, source);
return true;
}
}
return false;
}
@Override
public ButcherOfTheHordeEffect copy() {
return new ButcherOfTheHordeEffect(this);
}
}

View file

@ -6,8 +6,7 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.keyword.InvestigateEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HexproofAbility;
@ -15,17 +14,11 @@ import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
/**
@ -49,7 +42,9 @@ public final class EzrimAgencyChief extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new InvestigateEffect(2)));
// {1}, Sacrifice an artifact: Ezrim gains your choice of vigilance, lifelink, or hexproof until end of turn.
Ability ability = new SimpleActivatedAbility(new EzrimAgencyChiefEffect(), new GenericManaCost(1));
Ability ability = new SimpleActivatedAbility(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source,
VigilanceAbility.getInstance(), LifelinkAbility.getInstance(), HexproofAbility.getInstance()),
new GenericManaCost(1));
ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN));
this.addAbility(ability);
}
@ -63,46 +58,3 @@ public final class EzrimAgencyChief extends CardImpl {
return new EzrimAgencyChief(this);
}
}
class EzrimAgencyChiefEffect extends OneShotEffect {
private static final Map<String, Ability> abilityMap = new HashMap<>();
static {
abilityMap.put("Vigilance", VigilanceAbility.getInstance());
abilityMap.put("Lifelink", LifelinkAbility.getInstance());
abilityMap.put("Hexproof", HexproofAbility.getInstance());
}
EzrimAgencyChiefEffect() {
super(Outcome.Benefit);
staticText = "{this} gains your choice of vigilance, lifelink, or hexproof until end of turn";
}
private EzrimAgencyChiefEffect(final EzrimAgencyChiefEffect effect) {
super(effect);
}
@Override
public EzrimAgencyChiefEffect copy() {
return new EzrimAgencyChiefEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (player == null || permanent == null) {
return false;
}
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose an ability");
choice.setChoices(new HashSet<>(abilityMap.keySet()));
player.choose(outcome, choice, game);
Ability ability = abilityMap.getOrDefault(choice.getChoice(), null);
if (ability != null) {
game.addEffect(new GainAbilitySourceEffect(ability, Duration.EndOfTurn), source);
}
return true;
}
}

View file

@ -1,7 +1,5 @@
package mage.cards.g;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.effects.common.GainLifeEffect;
@ -13,9 +11,9 @@ import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
@ -23,6 +21,8 @@ import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreatureOrPlaneswalker;
import java.util.UUID;
/**
*
* @author weirddan455
@ -30,7 +30,7 @@ import mage.target.common.TargetCreatureOrPlaneswalker;
public final class GeyadroneDihada extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("permanents with corruption counters on them");
private static final FilterPermanent filter2 = new FilterCreatureOrPlaneswalkerPermanent("other creature or planeswalker");
private static final FilterPermanent filter2 = new FilterCreatureOrPlaneswalkerPermanent("other target creature or planeswalker");
static {
filter.add(CounterType.CORRUPTION.getPredicate());
@ -50,8 +50,7 @@ public final class GeyadroneDihada extends CardImpl {
// +1: Each opponent loses 2 life and you gain 2 life. Put a corruption counter on up to one other target creature or planeswalker.
Ability ability = new LoyaltyAbility(new LoseLifeOpponentsEffect(2), 1);
ability.addEffect(new GainLifeEffect(2).concatBy("and"));
ability.addEffect(new AddCountersTargetEffect(CounterType.CORRUPTION.createInstance(), Outcome.Detriment)
.setText("Put a corruption counter on up to one other target creature or planeswalker"));
ability.addEffect(new AddCountersTargetEffect(CounterType.CORRUPTION.createInstance(), Outcome.Detriment));
ability.addTarget(new TargetPermanent(0, 1, filter2));
this.addAbility(ability);

View file

@ -7,33 +7,27 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.decorator.ConditionalPreventionEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.TokenImpl;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetNonlandPermanent;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -41,7 +35,7 @@ import java.util.UUID;
*/
public final class GideonBlackblade extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("another other creature you control");
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("other target creature you control");
static {
filter.add(AnotherPredicate.instance);
@ -69,7 +63,8 @@ public final class GideonBlackblade extends CardImpl {
)));
// +1: Up to one other target creature you control gains your choice of vigilance, lifelink, or indestructible until end of turn.
Ability ability = new LoyaltyAbility(new GideonBlackbladeEffect(), 1);
Ability ability = new LoyaltyAbility(new GainsChoiceOfAbilitiesEffect(
VigilanceAbility.getInstance(), LifelinkAbility.getInstance(), IndestructibleAbility.getInstance()), 1);
ability.addTarget(new TargetPermanent(0, 1, filter, false));
this.addAbility(ability);
@ -110,59 +105,3 @@ class GideonBlackbladeToken extends TokenImpl {
return new GideonBlackbladeToken(this);
}
}
class GideonBlackbladeEffect extends OneShotEffect {
private static final Set<String> choices = new LinkedHashSet<>();
static {
choices.add("Vigilance");
choices.add("Lifelink");
choices.add("Indestructible");
}
GideonBlackbladeEffect() {
super(Outcome.Benefit);
staticText = "Up to one other target creature you control gains your choice of " +
"vigilance, lifelink, or indestructible until end of turn.";
}
private GideonBlackbladeEffect(final GideonBlackbladeEffect effect) {
super(effect);
}
@Override
public GideonBlackbladeEffect copy() {
return new GideonBlackbladeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (player == null || permanent == null) {
return false;
}
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose an ability to give to " + permanent.getLogName());
choice.setChoices(choices);
if (!player.choose(outcome, choice, game)) {
return false;
}
Ability ability = null;
switch (choice.getChoice()) {
case "Vigilance":
ability = VigilanceAbility.getInstance();
break;
case "Lifelink":
ability = LifelinkAbility.getInstance();
break;
case "Indestructible":
ability = IndestructibleAbility.getInstance();
break;
}
if (ability != null) {
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn), source);
}
return true;
}
}

View file

@ -1,35 +1,26 @@
package mage.cards.g;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author nantuko
*/
@ -48,7 +39,8 @@ public final class GolemArtisan extends CardImpl {
this.addAbility(ability);
// {2}: Target artifact creature gains your choice of flying, trample, or haste until end of turn.
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GolemArtisanEffect(), new GenericManaCost(2));
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainsChoiceOfAbilitiesEffect(
FlyingAbility.getInstance(), TrampleAbility.getInstance(), HasteAbility.getInstance()), new GenericManaCost(2));
ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_CREATURE));
this.addAbility(ability);
@ -64,57 +56,3 @@ public final class GolemArtisan extends CardImpl {
}
}
class GolemArtisanEffect extends OneShotEffect {
GolemArtisanEffect() {
super(Outcome.AddAbility);
staticText = "Target artifact creature gains your choice of flying, trample, or haste until end of turn";
}
private GolemArtisanEffect(final GolemArtisanEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
Player playerControls = game.getPlayer(source.getControllerId());
if (permanent != null && playerControls != null) {
Choice abilityChoice = new ChoiceImpl(true);
abilityChoice.setMessage("Choose an ability to add");
Set<String> abilities = new HashSet<>();
abilities.add(FlyingAbility.getInstance().getRule());
abilities.add(TrampleAbility.getInstance().getRule());
abilities.add(HasteAbility.getInstance().getRule());
abilityChoice.setChoices(abilities);
if (!playerControls.choose(Outcome.AddAbility, abilityChoice, game)) {
return false;
}
String chosen = abilityChoice.getChoice();
Ability ability = null;
if (FlyingAbility.getInstance().getRule().equals(chosen)) {
ability = FlyingAbility.getInstance();
} else if (TrampleAbility.getInstance().getRule().equals(chosen)) {
ability = TrampleAbility.getInstance();
} else if (HasteAbility.getInstance().getRule().equals(chosen)) {
ability = HasteAbility.getInstance();
}
if (ability != null) {
ContinuousEffect effect = new GainAbilityTargetEffect(ability, Duration.EndOfTurn);
game.addEffect(effect, source);
return true;
}
}
return false;
}
@Override
public GolemArtisanEffect copy() {
return new GolemArtisanEffect(this);
}
}

View file

@ -6,23 +6,17 @@ import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.abilities.keyword.ShadowAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -39,7 +33,12 @@ public final class JodahsAvenger extends CardImpl {
this.toughness = new MageInt(4);
// {0}: Until end of turn, Jodah's Avenger gets -1/-1 and gains your choice of double strike, protection from red, vigilance, or shadow.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new JodahsAvengerEffect(), new ManaCostsImpl<>("{0}")));
Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(-1, -1)
.setText("Until end of turn, {this} gets -1/-1"), new ManaCostsImpl<>("{0}"));
ability.addEffect(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source, "", false,
DoubleStrikeAbility.getInstance(), ProtectionAbility.from(ObjectColor.RED), VigilanceAbility.getInstance(), ShadowAbility.getInstance())
.concatBy("and"));
this.addAbility(ability);
}
private JodahsAvenger(final JodahsAvenger card) {
@ -51,59 +50,3 @@ public final class JodahsAvenger extends CardImpl {
return new JodahsAvenger(this);
}
}
class JodahsAvengerEffect extends OneShotEffect {
private static final Set<String> choices = new LinkedHashSet<>();
static {
choices.add("Double strike");
choices.add("Protection from red");
choices.add("Vigilance");
choices.add("Shadow");
}
public JodahsAvengerEffect() {
super(Outcome.AddAbility);
this.staticText = "Until end of turn, {this} gets -1/-1 and gains your choice of double strike, protection from red, vigilance, or shadow";
}
private JodahsAvengerEffect(final JodahsAvengerEffect effect) {
super(effect);
}
@Override
public JodahsAvengerEffect copy() {
return new JodahsAvengerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose one");
choice.setChoices(choices);
if (controller.choose(outcome, choice, game)) {
Ability gainedAbility;
switch (choice.getChoice()) {
case "Double strike":
gainedAbility = DoubleStrikeAbility.getInstance();
break;
case "Vigilance":
gainedAbility = VigilanceAbility.getInstance();
break;
case "Shadow":
gainedAbility = ShadowAbility.getInstance();
break;
default:
gainedAbility = ProtectionAbility.from(ObjectColor.RED);
break;
}
game.addEffect(new GainAbilitySourceEffect(gainedAbility, Duration.EndOfTurn), source);
game.addEffect(new BoostSourceEffect(-1, -1, Duration.EndOfTurn), source);
return true;
}
}
return false;
}
}

View file

@ -1,32 +1,22 @@
package mage.cards.l;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.SunburstAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
@ -43,7 +33,8 @@ public final class LunarAvenger extends CardImpl {
// Sunburst
this.addAbility(new SunburstAbility(this));
// Remove a +1/+1 counter from Lunar Avenger: Lunar Avenger gains your choice of flying, first strike, or haste until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LunarAvengerEffect(),
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source,
FlyingAbility.getInstance(), FirstStrikeAbility.getInstance(), HasteAbility.getInstance()),
new RemoveCountersSourceCost(CounterType.P1P1.createInstance(1))));
}
@ -56,58 +47,3 @@ public final class LunarAvenger extends CardImpl {
return new LunarAvenger(this);
}
}
class LunarAvengerEffect extends OneShotEffect {
private static final Set<String> choices = new LinkedHashSet<>();
static {
choices.add("Flying");
choices.add("First Strike");
choices.add("Haste");
}
public LunarAvengerEffect() {
super(Outcome.AddAbility);
staticText = "{this} gains your choice of flying, first strike, or haste until end of turn";
}
private LunarAvengerEffect(final LunarAvengerEffect effect) {
super(effect);
}
@Override
public LunarAvengerEffect copy() {
return new LunarAvengerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose ability to add");
choice.setChoices(choices);
if (!controller.choose(outcome, choice, game)) {
return false;
}
Ability gainedAbility;
String chosen = choice.getChoice();
switch (chosen) {
case "Flying":
gainedAbility = FlyingAbility.getInstance();
break;
case "First strike":
gainedAbility = FirstStrikeAbility.getInstance();
break;
default:
gainedAbility = HasteAbility.getInstance();
break;
}
game.addEffect(new GainAbilitySourceEffect(gainedAbility, Duration.EndOfTurn), source);
return true;
}
return false;
}
}

View file

@ -1,16 +1,13 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.BattalionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
@ -28,7 +25,7 @@ public final class MakeshiftBattalion extends CardImpl {
this.toughness = new MageInt(2);
// Whenever Makeshift Battalion and at least two other creatures attack, put a +1/+1 counter on Makeshift Battalion.
this.addAbility(new MakeshiftBattalionTriggeredAbility());
this.addAbility(new BattalionAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())));
}
private MakeshiftBattalion(final MakeshiftBattalion card) {
@ -40,36 +37,3 @@ public final class MakeshiftBattalion extends CardImpl {
return new MakeshiftBattalion(this);
}
}
class MakeshiftBattalionTriggeredAbility extends TriggeredAbilityImpl {
MakeshiftBattalionTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
}
private MakeshiftBattalionTriggeredAbility(final MakeshiftBattalionTriggeredAbility ability) {
super(ability);
}
@Override
public MakeshiftBattalionTriggeredAbility copy() {
return new MakeshiftBattalionTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return game.getCombat().getAttackers().size() >= 3
&& game.getCombat().getAttackers().contains(this.sourceId);
}
@Override
public String getRule() {
return "Whenever {this} and at least two other creatures attack, "
+ "put a +1/+1 counter on {this}.";
}
}

View file

@ -3,18 +3,17 @@ package mage.cards.m;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.OffspringAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPermanent;
import java.util.UUID;
@ -38,7 +37,8 @@ public final class ManifoldMouse extends CardImpl {
this.addAbility(new OffspringAbility("{2}"));
// At the beginning of combat on your turn, target Mouse you control gains your choice of double strike or trample until end of turn.
Ability ability = new BeginningOfCombatTriggeredAbility(new ManifoldMouseEffect(), TargetController.YOU, false);
Ability ability = new BeginningOfCombatTriggeredAbility(new GainsChoiceOfAbilitiesEffect(
DoubleStrikeAbility.getInstance(), TrampleAbility.getInstance()), TargetController.YOU, false);
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
@ -52,34 +52,3 @@ public final class ManifoldMouse extends CardImpl {
return new ManifoldMouse(this);
}
}
class ManifoldMouseEffect extends OneShotEffect {
ManifoldMouseEffect() {
super(Outcome.Benefit);
staticText = "target Mouse you control gains your choice of double strike or trample until end of turn";
}
private ManifoldMouseEffect(final ManifoldMouseEffect effect) {
super(effect);
}
@Override
public ManifoldMouseEffect copy() {
return new ManifoldMouseEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Ability ability = player.chooseUse(
outcome, "Double strike or trample?", null,
"Double strike", "Trample", source, game
) ? DoubleStrikeAbility.getInstance() : TrampleAbility.getInstance();
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn), source);
return true;
}
}

View file

@ -8,22 +8,18 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.PayEnergyCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -42,7 +38,8 @@ public final class MultiformWonder extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(3), false));
// Pay {E}: Multiform Wonder gains your choice of flying, vigilance, or lifelink until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new MultiformWonderEffect(), new PayEnergyCost(1)));
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source,
FlyingAbility.getInstance(), VigilanceAbility.getInstance(), LifelinkAbility.getInstance()), new PayEnergyCost(1)));
// Pay {E}: Multiform Wonder gets +2/-2 or -2/+2 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new MultiformWonder2Effect(), new PayEnergyCost(1)));
@ -58,62 +55,6 @@ public final class MultiformWonder extends CardImpl {
}
}
class MultiformWonderEffect extends OneShotEffect {
private static final Set<String> choices = new LinkedHashSet<>();
static {
choices.add("Flying");
choices.add("Vigilance");
choices.add("Lifelink");
}
public MultiformWonderEffect() {
super(Outcome.AddAbility);
staticText = "{this} gains your choice of flying, vigilance, or lifelink until end of turn";
}
private MultiformWonderEffect(final MultiformWonderEffect effect) {
super(effect);
}
@Override
public MultiformWonderEffect copy() {
return new MultiformWonderEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose ability to add");
choice.setChoices(choices);
if (!controller.choose(outcome, choice, game)) {
return false;
}
Ability gainedAbility;
String chosen = choice.getChoice();
switch (chosen) {
case "Flying":
gainedAbility = FlyingAbility.getInstance();
break;
case "Vigilance":
gainedAbility = VigilanceAbility.getInstance();
break;
default:
gainedAbility = LifelinkAbility.getInstance();
break;
}
game.addEffect(new GainAbilitySourceEffect(gainedAbility, Duration.EndOfTurn), source);
return true;
}
return false;
}
}
class MultiformWonder2Effect extends OneShotEffect {
public MultiformWonder2Effect() {
super(Outcome.BoostCreature);

View file

@ -1,22 +1,14 @@
package mage.cards.o;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.keyword.AmassEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
@ -29,7 +21,8 @@ public final class OrcishMedicine extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}");
// Target creature gains your choice of lifelink or indestructible until end of turn.
this.getSpellAbility().addEffect(new OrcishMedicineEffect());
this.getSpellAbility().addEffect(new GainsChoiceOfAbilitiesEffect(
LifelinkAbility.getInstance(), IndestructibleAbility.getInstance()));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Amass Orcs 1.
@ -45,36 +38,3 @@ public final class OrcishMedicine extends CardImpl {
return new OrcishMedicine(this);
}
}
class OrcishMedicineEffect extends OneShotEffect {
OrcishMedicineEffect() {
super(Outcome.Benefit);
staticText = "target creature gains your choice of lifelink or indestructible until end of turn";
}
private OrcishMedicineEffect(final OrcishMedicineEffect effect) {
super(effect);
}
@Override
public OrcishMedicineEffect copy() {
return new OrcishMedicineEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (player == null || permanent == null) {
return false;
}
Ability ability = player.chooseUse(
outcome, "Choose lifelink or indestructible", null,
"Lifelink", "Indestructible", source, game
) ? LifelinkAbility.getInstance() : IndestructibleAbility.getInstance();
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn)
.setTargetPointer(new FixedTarget(permanent, game)), source);
return true;
}
}

View file

@ -3,19 +3,12 @@ package mage.cards.r;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.CommittedCrimeTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
@ -37,7 +30,8 @@ public final class RattlebackApothecary extends CardImpl {
this.addAbility(DeathtouchAbility.getInstance());
// Whenever you commit a crime, target creature you control gains your choice of menace or lifelink until end of turn.
Ability ability = new CommittedCrimeTriggeredAbility(new RattlebackApothecaryEffect());
Ability ability = new CommittedCrimeTriggeredAbility(new GainsChoiceOfAbilitiesEffect(
new MenaceAbility(false), LifelinkAbility.getInstance()));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
@ -51,35 +45,3 @@ public final class RattlebackApothecary extends CardImpl {
return new RattlebackApothecary(this);
}
}
class RattlebackApothecaryEffect extends OneShotEffect {
RattlebackApothecaryEffect() {
super(Outcome.Benefit);
staticText = "target creature you control gains your choice of menace or lifelink until end of turn";
}
private RattlebackApothecaryEffect(final RattlebackApothecaryEffect effect) {
super(effect);
}
@Override
public RattlebackApothecaryEffect copy() {
return new RattlebackApothecaryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Ability ability = player.chooseUse(
outcome, "Choose menace or lifelink", null,
"Menace", "Lifelink", source, game
) ? new MenaceAbility() : LifelinkAbility.getInstance();
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn)
.setTargetPointer(getTargetPointer().copy()), source);
return true;
}
}

View file

@ -2,30 +2,19 @@ package mage.cards.s;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.CantBeCounteredSourceAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -47,7 +36,8 @@ public final class ShiftingCeratops extends CardImpl {
this.addAbility(ProtectionAbility.from(ObjectColor.BLUE));
// {G}: Shifting Ceratops gains your choice of reach, trample, or haste until end of turn.
this.addAbility(new SimpleActivatedAbility(new ShiftingCeratopsEffect(), new ManaCostsImpl<>("{G}")));
this.addAbility(new SimpleActivatedAbility(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source,
ReachAbility.getInstance(), TrampleAbility.getInstance(), HasteAbility.getInstance()), new ManaCostsImpl<>("{G}")));
}
private ShiftingCeratops(final ShiftingCeratops card) {
@ -59,57 +49,3 @@ public final class ShiftingCeratops extends CardImpl {
return new ShiftingCeratops(this);
}
}
class ShiftingCeratopsEffect extends OneShotEffect {
private static final Set<String> choices = new LinkedHashSet();
static {
choices.add("Reach");
choices.add("Trample");
choices.add("Haste");
}
ShiftingCeratopsEffect() {
super(Outcome.Benefit);
staticText = "{this} gains your choice of reach, trample, or haste until end of turn.";
}
private ShiftingCeratopsEffect(final ShiftingCeratopsEffect effect) {
super(effect);
}
@Override
public ShiftingCeratopsEffect copy() {
return new ShiftingCeratopsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose an ability");
choice.setChoices(choices);
if (!player.choose(outcome, choice, game)) {
return false;
}
Ability ability = null;
switch (choice.getChoice()) {
case "Reach":
ability = ReachAbility.getInstance();
break;
case "Trample":
ability = TrampleAbility.getInstance();
break;
case "Haste":
ability = HasteAbility.getInstance();
break;
}
if (ability != null) {
game.addEffect(new GainAbilitySourceEffect(ability, Duration.EndOfTurn), source);
}
return true;
}
}

View file

@ -1,20 +1,14 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.MagecraftAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
@ -32,7 +26,8 @@ public final class SilverquillPledgemage extends CardImpl {
this.toughness = new MageInt(1);
// Magecraft Whenever you cast or copy an instant or sorcery spell, Silverquill Pledgemage gains your choice of flying or lifelink until end of turn.
this.addAbility(new MagecraftAbility(new SilverquillPledgemageEffect()));
this.addAbility(new MagecraftAbility(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source,
FlyingAbility.getInstance(), LifelinkAbility.getInstance())));
}
private SilverquillPledgemage(final SilverquillPledgemage card) {
@ -44,33 +39,3 @@ public final class SilverquillPledgemage extends CardImpl {
return new SilverquillPledgemage(this);
}
}
class SilverquillPledgemageEffect extends OneShotEffect {
SilverquillPledgemageEffect() {
super(Outcome.Benefit);
staticText = "{this} gains your choice of flying or lifelink until end of turn";
}
private SilverquillPledgemageEffect(final SilverquillPledgemageEffect effect) {
super(effect);
}
@Override
public SilverquillPledgemageEffect copy() {
return new SilverquillPledgemageEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
game.addEffect(new GainAbilitySourceEffect(player.chooseUse(
Outcome.Neutral, "Choose flying or lifelink", null,
"Flying", "Lifelink", source, game
) ? FlyingAbility.getInstance() : LifelinkAbility.getInstance(), Duration.EndOfTurn), source);
return true;
}
}

View file

@ -11,9 +11,9 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
@ -24,13 +24,6 @@ import java.util.UUID;
* @author TheElk801
*/
public final class SludgeMonster extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("other creature");
static {
filter.add(AnotherPredicate.instance);
}
public SludgeMonster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
@ -41,9 +34,8 @@ public final class SludgeMonster extends CardImpl {
// Whenever Sludge Monster enters the battlefield or attacks, put a slime counter on up to one other target creature.
Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(
new AddCountersTargetEffect(CounterType.SLIME.createInstance())
.setText("put a slime counter on up to one other target creature")
);
ability.addTarget(new TargetPermanent(0, 1, filter));
ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_ANOTHER_TARGET_CREATURE));
this.addAbility(ability);
// Non-Horror creatures with slime counters on them lose all abilities and have base power and toughness 2/2.

View file

@ -3,27 +3,18 @@ package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.PrototypeAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
/**
@ -45,8 +36,9 @@ public final class SteelSeraph extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// At the beginning of combat on your turn, target creature you control gains your choice of flying, vigilance, or lifelink until end of turn.
Ability ability = new BeginningOfCombatTriggeredAbility(
new SteelSeraphEffect(), TargetController.YOU, false
Ability ability = new BeginningOfCombatTriggeredAbility(new GainsChoiceOfAbilitiesEffect(
FlyingAbility.getInstance(), VigilanceAbility.getInstance(), LifelinkAbility.getInstance()),
TargetController.YOU, false
);
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
@ -61,46 +53,3 @@ public final class SteelSeraph extends CardImpl {
return new SteelSeraph(this);
}
}
class SteelSeraphEffect extends OneShotEffect {
private static final Map<String, Ability> map = new HashMap<>();
static {
map.put("Flying", FlyingAbility.getInstance());
map.put("Vigilance", VigilanceAbility.getInstance());
map.put("Lifelink", LifelinkAbility.getInstance());
}
SteelSeraphEffect() {
super(Outcome.Benefit);
staticText = "target creature you control gains your choice of flying, vigilance, or lifelink until end of turn";
}
private SteelSeraphEffect(final SteelSeraphEffect effect) {
super(effect);
}
@Override
public SteelSeraphEffect copy() {
return new SteelSeraphEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose an ability");
choice.setChoices(new HashSet<>(map.keySet()));
player.choose(outcome, choice, game);
Ability ability = map.getOrDefault(choice.getChoice(), null);
if (ability == null) {
return false;
}
game.addEffect(new GainAbilityTargetEffect(ability), source);
return true;
}
}

View file

@ -5,23 +5,17 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.BandingAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -31,14 +25,19 @@ import java.util.UUID;
public final class UrzasAvenger extends CardImpl {
public UrzasAvenger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT,CardType.CREATURE}, "{6}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}");
this.subtype.add(SubType.SHAPESHIFTER);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// {0}: Urza's Avenger gets -1/-1 and gains your choice of banding, flying, first strike, or trample until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UrzasAvengerEffect(), new ManaCostsImpl<>("{0}")));
Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(-1, -1)
.setText("{this} gets -1/-1"), new ManaCostsImpl<>("{0}"));
ability.addEffect(new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source, "", true,
BandingAbility.getInstance(), FlyingAbility.getInstance(), FirstStrikeAbility.getInstance(), TrampleAbility.getInstance())
.concatBy("and"));
this.addAbility(ability);
}
private UrzasAvenger(final UrzasAvenger card) {
@ -50,58 +49,3 @@ public final class UrzasAvenger extends CardImpl {
return new UrzasAvenger(this);
}
}
class UrzasAvengerEffect extends OneShotEffect {
private static final Set<String> choices = new LinkedHashSet<>();
static {
choices.add("Banding");
choices.add("Flying");
choices.add("First strike");
choices.add("Trample");
}
public UrzasAvengerEffect() {
super(Outcome.AddAbility);
this.staticText = "{this} gets -1/-1 and gains your choice of banding, flying, first strike, or trample until end of turn";
}
private UrzasAvengerEffect(final UrzasAvengerEffect effect) {
super(effect);
}
@Override
public UrzasAvengerEffect copy() {
return new UrzasAvengerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose one");
choice.setChoices(choices);
if (controller.choose(outcome, choice, game)) {
Ability gainedAbility;
switch (choice.getChoice()) {
case "Banding":
gainedAbility = BandingAbility.getInstance();
break;
case "Flying":
gainedAbility = FlyingAbility.getInstance();
break;
case "First strike":
gainedAbility = FirstStrikeAbility.getInstance();
break;
default:
gainedAbility = TrampleAbility.getInstance();
break;
}
game.addEffect(new GainAbilitySourceEffect(gainedAbility, Duration.EndOfTurn), source);
game.addEffect(new BoostSourceEffect(-1, -1, Duration.EndOfTurn), source);
return true;
}
}
return false;
}
}

View file

@ -1,15 +1,11 @@
package mage.cards.v;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.dynamicvalue.common.CreaturesYouControlCount;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.GainsChoiceOfAbilitiesEffect;
import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect;
import mage.abilities.hint.common.CreaturesYouControlHint;
import mage.abilities.keyword.FirstStrikeAbility;
@ -17,18 +13,14 @@ import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetControlledPermanent;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -58,8 +50,9 @@ public final class VeteranWarleader extends CardImpl {
.addHint(CreaturesYouControlHint.instance));
// Tap another untapped Ally you control: Veteran Warleader gains your choice of first strike, vigilance, or trample until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
new VeteranWarleaderEffect(), new TapTargetCost(new TargetControlledPermanent(1, 1, filter, true))));
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainsChoiceOfAbilitiesEffect(GainsChoiceOfAbilitiesEffect.TargetType.Source,
FirstStrikeAbility.getInstance(), VigilanceAbility.getInstance(), TrampleAbility.getInstance()),
new TapTargetCost(new TargetControlledPermanent(1, 1, filter, true))));
}
private VeteranWarleader(final VeteranWarleader card) {
@ -71,58 +64,3 @@ public final class VeteranWarleader extends CardImpl {
return new VeteranWarleader(this);
}
}
class VeteranWarleaderEffect extends OneShotEffect {
VeteranWarleaderEffect() {
super(Outcome.AddAbility);
staticText = "{this} gains your choice of first strike, vigilance, or trample until end of turn";
}
private VeteranWarleaderEffect(final VeteranWarleaderEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source);
if (sourceObject != null && controller != null) {
Choice abilityChoice = new ChoiceImpl(true);
abilityChoice.setMessage("Choose an ability to add");
Set<String> abilities = new HashSet<>();
abilities.add(FirstStrikeAbility.getInstance().getRule());
abilities.add(VigilanceAbility.getInstance().getRule());
abilities.add(TrampleAbility.getInstance().getRule());
abilityChoice.setChoices(abilities);
if (!controller.choose(Outcome.AddAbility, abilityChoice, game)) {
return false;
}
String chosen = abilityChoice.getChoice();
Ability ability = null;
if (FirstStrikeAbility.getInstance().getRule().equals(chosen)) {
ability = FirstStrikeAbility.getInstance();
} else if (VigilanceAbility.getInstance().getRule().equals(chosen)) {
ability = VigilanceAbility.getInstance();
} else if (TrampleAbility.getInstance().getRule().equals(chosen)) {
ability = TrampleAbility.getInstance();
}
if (ability != null) {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " has chosen: " + chosen);
ContinuousEffect effect = new GainAbilitySourceEffect(ability, Duration.EndOfTurn);
game.addEffect(effect, source);
return true;
}
}
return false;
}
@Override
public VeteranWarleaderEffect copy() {
return new VeteranWarleaderEffect(this);
}
}

View file

@ -27,6 +27,7 @@ public final class AssassinsCreed extends ExpansionSet {
cards.add(new SetCardInfo("Arno Dorian", 47, Rarity.UNCOMMON, mage.cards.a.ArnoDorian.class));
cards.add(new SetCardInfo("Assassin Den", 281, Rarity.UNCOMMON, mage.cards.a.AssassinDen.class));
cards.add(new SetCardInfo("Assassin Gauntlet", 12, Rarity.UNCOMMON, mage.cards.a.AssassinGauntlet.class));
cards.add(new SetCardInfo("Assassin Initiate", 22, Rarity.UNCOMMON, mage.cards.a.AssassinInitiate.class));
cards.add(new SetCardInfo("Assassin's Trophy", 95, Rarity.RARE, mage.cards.a.AssassinsTrophy.class));
cards.add(new SetCardInfo("Aya of Alexandria", 48, Rarity.RARE, mage.cards.a.AyaOfAlexandria.class));
cards.add(new SetCardInfo("Ballad of the Black Flag", 13, Rarity.UNCOMMON, mage.cards.b.BalladOfTheBlackFlag.class));

View file

@ -8,13 +8,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
public class AlchemistsGiftTest extends CardTestPlayerBase {
private final String deathtouch = "Yes";
private final String lifelink = "No";
@Test
public void giveDeathTouch(){
// Target creature gets +1/+1 and gains your choice of deathtouch or lifelink until end of turn.
@ -24,7 +17,7 @@ public class AlchemistsGiftTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Alchemist's Gift", "Adherent of Hope");
// give Deathtouch
setChoice(playerA, deathtouch);
setChoice(playerA, "deathtouch");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
@ -44,7 +37,7 @@ public class AlchemistsGiftTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Alchemist's Gift", "Adherent of Hope");
// give Lifelink
setChoice(playerA, lifelink);
setChoice(playerA, "lifelink");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);

View file

@ -0,0 +1,60 @@
package org.mage.test.cards.single.snc;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.b.BallroomBrawlers Ballroom Brawlers}
* Whenever Ballroom Brawlers attacks, Ballroom Brawlers and up to one other target creature you control
* both gain your choice of first strike or lifelink until end of turn.
*
* This tests an edge case of GainsChoiceOfAbilitiesEffect
*
* @author notgreat
*/
public class BallroomBrawlersTest extends CardTestPlayerBase {
@Test
public void testSoloFirstStrike() {
addCard(Zone.BATTLEFIELD, playerA, "Ballroom Brawlers");
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
attack(1, playerA, "Ballroom Brawlers");
attack(1, playerA, "Raging Goblin");
addTarget(playerA, TestPlayer.TARGET_SKIP );
setChoice(playerA, "first strike");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertAbility(playerA, "Ballroom Brawlers", LifelinkAbility.getInstance(), false);
assertAbility(playerA, "Raging Goblin", LifelinkAbility.getInstance(), false);
assertAbility(playerA, "Ballroom Brawlers", FirstStrikeAbility.getInstance(), true);
assertAbility(playerA, "Raging Goblin", FirstStrikeAbility.getInstance(), false);
}
@Test
public void testBothLifelink() {
addCard(Zone.BATTLEFIELD, playerA, "Ballroom Brawlers");
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
attack(1, playerA, "Ballroom Brawlers");
attack(1, playerA, "Raging Goblin");
addTarget(playerA, "Raging Goblin" );
setChoice(playerA, "lifelink");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertAbility(playerA, "Ballroom Brawlers", LifelinkAbility.getInstance(), true);
assertAbility(playerA, "Raging Goblin", LifelinkAbility.getInstance(), true);
assertAbility(playerA, "Ballroom Brawlers", FirstStrikeAbility.getInstance(), false);
assertAbility(playerA, "Raging Goblin", FirstStrikeAbility.getInstance(), false);
}
}

View file

@ -0,0 +1,141 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
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.FixedTargets;
import mage.util.CardUtil;
import java.util.*;
/**
* Something gains one ability of the player's choice from a list of abilities until end of turn.
* Affects any targets set and optionally the source as well. Have no targets to affect only the source.
*
* @author notgreat, TheElk801
*/
public class GainsChoiceOfAbilitiesEffect extends OneShotEffect {
public enum TargetType {
Source, Target, Both
}
private final Map<String, Ability> abilityMap;
private final boolean includeEnd;
private final TargetType affects;
private final String targetDescription;
public GainsChoiceOfAbilitiesEffect(Ability... abilities) {
this(TargetType.Target, null, true, abilities);
}
public GainsChoiceOfAbilitiesEffect(TargetType affects, Ability... abilities) {
this(affects, null, true, abilities);
}
public GainsChoiceOfAbilitiesEffect(TargetType affects, String targetDescription, boolean includeEnd, Ability... abilities) {
super(Outcome.AddAbility);
this.affects = affects;
this.targetDescription = targetDescription;
this.includeEnd = includeEnd;
this.abilityMap = new LinkedHashMap<>();
for (Ability ability : abilities) {
this.abilityMap.put(ability.getRule(), ability);
}
}
protected GainsChoiceOfAbilitiesEffect(final GainsChoiceOfAbilitiesEffect effect) {
super(effect);
this.affects = effect.affects;
this.abilityMap = CardUtil.deepCopyObject(effect.abilityMap);
this.targetDescription = effect.targetDescription;
this.includeEnd = effect.includeEnd;
}
@Override
public GainsChoiceOfAbilitiesEffect copy() {
return new GainsChoiceOfAbilitiesEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
List<Permanent> permanents = new ArrayList<>();
if (affects == TargetType.Source || affects == TargetType.Both) {
permanents.add(source.getSourcePermanentIfItStillExists(game));
}
if (affects == TargetType.Target || affects == TargetType.Both) {
for (UUID p : getTargetPointer().getTargets(game, source)) {
permanents.add(game.getPermanent(p));
}
}
permanents.removeIf(Objects::isNull);
if (player == null || permanents.isEmpty()) {
return false;
}
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose an ability to gain");
choice.setChoices(new HashSet<>(abilityMap.keySet()));
player.choose(outcome, choice, game);
Ability ability = abilityMap.get(choice.getChoice());
if (ability != null) {
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn)
.setTargetPointer(new FixedTargets(permanents, game)), source);
}
return true;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
StringBuilder sb = new StringBuilder();
if (targetDescription != null) {
if (targetDescription.isEmpty()){
sb.append("gains");
} else {
sb.append(targetDescription);
sb.append(" gains");
}
} else switch (affects) {
case Source:
sb.append("{this} gains");
break;
case Target:
sb.append(getTargetPointer().describeTargets(mode.getTargets(), "that creature"));
sb.append(" gains");
break;
case Both:
sb.append("{this} and ");
sb.append(getTargetPointer().describeTargets(mode.getTargets(), "that creature"));
sb.append(" both gain");
break;
}
sb.append(" your choice of ");
String[] abilitiesText = abilityMap.keySet().toArray(new String[0]);
if (abilityMap.size() == 2) {
sb.append(abilitiesText[0]).append(" or ").append(abilitiesText[1]);
} else if (abilityMap.size() > 2) {
for (int i = 0; i < abilityMap.size() - 1; i += 1) {
sb.append(abilitiesText[i]).append(", ");
}
sb.append("or ").append(abilitiesText[abilityMap.size()-1]);
} else {
throw new IllegalStateException("Not enough abilities for GainsChoiceOfAbilitiesEffect");
}
if (includeEnd) {
sb.append(" until end of turn");
}
return sb.toString();
}
}

View file

@ -103,10 +103,12 @@ public abstract class TargetImpl implements Target {
StringBuilder sb = new StringBuilder();
int min = getMinNumberOfTargets();
int max = getMaxNumberOfTargets();
String targetName = getTargetName();
if (min > 0 && max == Integer.MAX_VALUE) {
sb.append(CardUtil.numberToText(min));
sb.append(" or more ");
} else if (!getTargetName().startsWith("X ") && (min != 1 || max != 1)) {
} else if (!targetName.startsWith("X ") && (min != 1 || max != 1)) {
targetName = targetName.replace("another", "other"); //If non-singular, use "other" instead of "another"
if (min < max && max != Integer.MAX_VALUE) {
if (min == 1 && max == 2) {
sb.append("one or ");
@ -122,10 +124,10 @@ public abstract class TargetImpl implements Target {
boolean addTargetWord = false;
if (!isNotTarget()) {
addTargetWord = true;
if (getTargetName().contains("target ")) {
if (targetName.contains("target ")) {
addTargetWord = false;
} else if (getTargetName().endsWith("any target")
|| getTargetName().endsWith("any other target")) {
} else if (targetName.endsWith("any target")
|| targetName.endsWith("any other target")) {
addTargetWord = false;
}
// endsWith needs to be specific.
@ -135,9 +137,9 @@ public abstract class TargetImpl implements Target {
sb.append("target ");
}
if (isNotTarget() && min == 1 && max == 1) {
sb.append(CardUtil.addArticle(getTargetName()));
sb.append(CardUtil.addArticle(targetName));
} else {
sb.append(getTargetName());
sb.append(targetName);
}
return sb.toString();
}