[BLB] Implement Ruthless Negotiation

This commit is contained in:
theelk801 2024-07-19 16:15:02 -04:00
parent 25f27fe7f4
commit b92c22d602
9 changed files with 136 additions and 225 deletions

View file

@ -1,7 +1,6 @@
package mage.cards.i;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.CastFromGraveyardSourceCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
@ -9,10 +8,7 @@ import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
@ -29,7 +25,7 @@ public final class IncreasingAmbition extends CardImpl {
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(2, StaticFilters.FILTER_CARD), false),
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(), false),
IncreasingAmbitionCondition.instance, "Search your library for a card " +
CastFromGraveyardSourceCondition.instance, "Search your library for a card " +
"and put that card into your hand. If this spell was cast from a graveyard, " +
"instead search your library for two cards and put those cards into your hand. " +
"Then shuffle."
@ -48,13 +44,3 @@ public final class IncreasingAmbition extends CardImpl {
return new IncreasingAmbition(this);
}
}
enum IncreasingAmbitionCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
Spell spell = game.getSpell(source.getSourceId());
return spell != null && spell.getFromZone() == Zone.GRAVEYARD;
}
}

View file

@ -1,31 +1,36 @@
package mage.cards.i;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.condition.common.CastFromGraveyardSourceCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.MultipliedValue;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.MillCardsTargetEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.constants.CardType;
import mage.target.TargetPlayer;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public final class IncreasingConfusion extends CardImpl {
public IncreasingConfusion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}");
private static final DynamicValue xValue = new MultipliedValue(ManacostVariableValue.REGULAR, 2);
public IncreasingConfusion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}");
// Target player puts the top X cards of their library into their graveyard. If this spell was cast from a graveyard, that player puts twice that many cards into their graveyard instead.
this.getSpellAbility().addEffect(new IncreasingConfusionEffect());
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new MillCardsTargetEffect(xValue), new MillCardsTargetEffect(ManacostVariableValue.REGULAR),
CastFromGraveyardSourceCondition.instance, "target player mills X cards. " +
"If this spell was cast from a graveyard, that player mills twice that many cards"
));
this.getSpellAbility().addTarget(new TargetPlayer());
// Flashback {X}{U}
@ -41,38 +46,3 @@ public final class IncreasingConfusion extends CardImpl {
return new IncreasingConfusion(this);
}
}
class IncreasingConfusionEffect extends OneShotEffect {
IncreasingConfusionEffect() {
super(Outcome.Detriment);
staticText = "Target player mills X cards. If this spell was cast from a graveyard, that player mills twice that many cards";
}
private IncreasingConfusionEffect(final IncreasingConfusionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
int amount = source.getManaCostsToPay().getX();
Spell spell = (Spell) game.getStack().getStackObject(source.getSourceId());
if (spell != null) {
if (spell.getFromZone() == Zone.GRAVEYARD) {
amount *= 2;
}
player.millCards(amount, source, game);
return true;
}
}
return false;
}
@Override
public IncreasingConfusionEffect copy() {
return new IncreasingConfusionEffect(this);
}
}

View file

@ -1,23 +1,18 @@
package mage.cards.i;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.condition.common.CastFromGraveyardSourceCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.token.HumanToken;
import mage.game.stack.Spell;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public final class IncreasingDevotion extends CardImpl {
@ -26,7 +21,11 @@ public final class IncreasingDevotion extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}{W}");
// Create five 1/1 white Human creature tokens. If this spell was cast from a graveyard, create ten of those tokens instead.
this.getSpellAbility().addEffect(new IncreasingDevotionEffect());
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new CreateTokenEffect(new HumanToken(), 10), new CreateTokenEffect(new HumanToken(), 5),
CastFromGraveyardSourceCondition.instance, "create five 1/1 white Human creature tokens. " +
"If this spell was cast from a graveyard, create ten of those tokens instead"
));
// Flashback {7}{W}{W}
this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{7}{W}{W}")));
@ -41,37 +40,3 @@ public final class IncreasingDevotion extends CardImpl {
return new IncreasingDevotion(this);
}
}
class IncreasingDevotionEffect extends OneShotEffect {
private static HumanToken token = new HumanToken();
public IncreasingDevotionEffect() {
super(Outcome.PutCreatureInPlay);
staticText = "Create five 1/1 white Human creature tokens. If this spell was cast from a graveyard, create ten of those tokens instead";
}
private IncreasingDevotionEffect(final IncreasingDevotionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int amount = 5;
Spell spell = (Spell) game.getStack().getStackObject(source.getSourceId());
if (spell != null) {
if (spell.getFromZone() == Zone.GRAVEYARD) {
amount = 10;
}
token.putOntoBattlefield(amount, game, source, source.getControllerId());
return true;
}
return false;
}
@Override
public IncreasingDevotionEffect copy() {
return new IncreasingDevotionEffect(this);
}
}

View file

@ -1,32 +1,33 @@
package mage.cards.i;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.condition.common.CastFromGraveyardSourceCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public final class IncreasingSavagery extends CardImpl {
public IncreasingSavagery(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}{G}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}");
// Put five +1/+1 counters on target creature. If this spell was cast from a graveyard, put ten +1/+1 counters on that creature instead.
this.getSpellAbility().addEffect(new IncreasingSavageryEffect());
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new AddCountersTargetEffect(CounterType.P1P1.createInstance(10)),
new AddCountersTargetEffect(CounterType.P1P1.createInstance(5)),
CastFromGraveyardSourceCondition.instance, "put five +1/+1 counters on target creature. " +
"If this spell was cast from a graveyard, put ten +1/+1 counters on that creature instead"
));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Flashback {5}{G}{G}
@ -42,38 +43,3 @@ public final class IncreasingSavagery extends CardImpl {
return new IncreasingSavagery(this);
}
}
class IncreasingSavageryEffect extends OneShotEffect {
IncreasingSavageryEffect() {
super(Outcome.BoostCreature);
staticText = "Put five +1/+1 counters on target creature. If this spell was cast from a graveyard, put ten +1/+1 counters on that creature instead";
}
private IncreasingSavageryEffect(final IncreasingSavageryEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int amount = 5;
Spell spell = (Spell) game.getStack().getStackObject(source.getSourceId());
if (spell != null) {
if (spell.getFromZone() == Zone.GRAVEYARD) {
amount = 10;
}
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
permanent.addCounters(CounterType.P1P1.createInstance(amount), source.getControllerId(), source, game);
}
return true;
}
return false;
}
@Override
public IncreasingSavageryEffect copy() {
return new IncreasingSavageryEffect(this);
}
}

View file

@ -1,19 +1,16 @@
package mage.cards.i;
import mage.abilities.Ability;
import mage.abilities.condition.common.CastFromGraveyardSourceCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.Target;
import mage.filter.common.FilterInstantOrSorcerySpell;
import mage.target.TargetSpell;
import java.util.UUID;
@ -23,12 +20,9 @@ import java.util.UUID;
*/
public final class IncreasingVengeance extends CardImpl {
private static final FilterSpell filter = new FilterSpell("instant or sorcery spell");
private static final FilterSpell filter = new FilterInstantOrSorcerySpell("instant or sorcery spell you control");
static {
filter.add(Predicates.or(
CardType.INSTANT.getPredicate(),
CardType.SORCERY.getPredicate()));
filter.add(TargetController.YOU.getControllerPredicate());
}
@ -36,9 +30,13 @@ public final class IncreasingVengeance extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{R}");
// Copy target instant or sorcery spell you control. If this spell was cast from a graveyard, copy that spell twice instead. You may choose new targets for the copies.
this.getSpellAbility().addEffect(new IncreasingVengeanceEffect());
Target target = new TargetSpell(filter);
this.getSpellAbility().addTarget(target);
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new CopyTargetStackObjectEffect(false, false, true, 2, null),
new CopyTargetStackObjectEffect(), CastFromGraveyardSourceCondition.instance, "copy target " +
"instant or sorcery spell you control. If this spell was cast from a graveyard, " +
"copy that spell twice instead. You may choose new targets for the copies"
));
this.getSpellAbility().addTarget(new TargetSpell(filter));
// Flashback {3}{R}{R}
this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{3}{R}{R}")));
@ -53,40 +51,3 @@ public final class IncreasingVengeance extends CardImpl {
return new IncreasingVengeance(this);
}
}
class IncreasingVengeanceEffect extends OneShotEffect {
IncreasingVengeanceEffect() {
super(Outcome.BoostCreature);
staticText = "Copy target instant or sorcery spell you control. If this spell was cast from a graveyard, copy that spell twice instead. You may choose new targets for the copies";
}
private IncreasingVengeanceEffect(final IncreasingVengeanceEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Spell spell = game.getStack().getSpell(getTargetPointer().getFirst(game, source));
if (spell == null) {
return false;
}
Spell sourceSpell = (Spell) game.getSpell(source.getSourceId());
int copies = 1;
if (sourceSpell != null && sourceSpell.getFromZone() == Zone.GRAVEYARD) {
copies++;
}
spell.createCopyOnStack(game, source, source.getControllerId(), true, copies);
return true;
}
@Override
public IncreasingVengeanceEffect copy() {
return new IncreasingVengeanceEffect(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.r;
import mage.abilities.condition.common.CastFromGraveyardSourceCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.ExileFromZoneTargetEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RuthlessNegotiation extends CardImpl {
public RuthlessNegotiation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
// Target opponent exiles a card from their hand. If this spell was cast from a graveyard, draw a card.
this.getSpellAbility().addEffect(new ExileFromZoneTargetEffect(Zone.HAND, false));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1), CastFromGraveyardSourceCondition.instance,
"if this spell was cast from a graveyard, draw a card"
));
this.getSpellAbility().addTarget(new TargetOpponent());
// Flashback {4}{B}
this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{4}{B}")));
}
private RuthlessNegotiation(final RuthlessNegotiation card) {
super(card);
}
@Override
public RuthlessNegotiation copy() {
return new RuthlessNegotiation(this);
}
}

View file

@ -1,7 +1,6 @@
package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.CastFromGraveyardSourceCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.keyword.InvestigateEffect;
@ -9,10 +8,6 @@ import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.stack.Spell;
import java.util.UUID;
@ -26,7 +21,7 @@ public final class SecretsOfTheKey extends CardImpl {
// Investigate. If this spell was cast from a graveyard, investigate twice instead.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new InvestigateEffect(2), new InvestigateEffect(), SecretsOfTheKeyCondition.instance,
new InvestigateEffect(2), new InvestigateEffect(), CastFromGraveyardSourceCondition.instance,
"Investigate. If this spell was cast from a graveyard, investigate twice instead."
));
@ -43,13 +38,3 @@ public final class SecretsOfTheKey extends CardImpl {
return new SecretsOfTheKey(this);
}
}
enum SecretsOfTheKeyCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
Spell spell = game.getSpell(source.getSourceId());
return spell != null && spell.getFromZone() == Zone.GRAVEYARD;
}
}

View file

@ -162,6 +162,7 @@ public final class Bloomburrow extends ExpansionSet {
cards.add(new SetCardInfo("Rockface Village", 259, Rarity.UNCOMMON, mage.cards.r.RockfaceVillage.class));
cards.add(new SetCardInfo("Run Away Together", 67, Rarity.COMMON, mage.cards.r.RunAwayTogether.class));
cards.add(new SetCardInfo("Rust-Shield Rampager", 190, Rarity.COMMON, mage.cards.r.RustShieldRampager.class));
cards.add(new SetCardInfo("Ruthless Negotiation", 108, Rarity.UNCOMMON, mage.cards.r.RuthlessNegotiation.class));
cards.add(new SetCardInfo("Salvation Swan", 28, Rarity.RARE, mage.cards.s.SalvationSwan.class));
cards.add(new SetCardInfo("Savor", 109, Rarity.COMMON, mage.cards.s.Savor.class));
cards.add(new SetCardInfo("Scales of Shale", 110, Rarity.COMMON, mage.cards.s.ScalesOfShale.class));

View file

@ -0,0 +1,32 @@
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.stack.Spell;
import java.util.Optional;
/**
* @author TheElk801
*/
public enum CastFromGraveyardSourceCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
return Optional
.ofNullable(source)
.map(Ability::getSourceId)
.map(game::getSpell)
.map(Spell::getFromZone)
.map(Zone.GRAVEYARD::match)
.orElse(false);
}
@Override
public String toString() {
return "this spell was cast from a graveyard";
}
}