Merge pull request #11430 from ssk97/VariedCardImprovements

fix Cosmium Confluence bug, other varied card improvements
This commit is contained in:
xenohedron 2023-11-19 14:47:33 -05:00 committed by GitHub
commit 0a86a4473d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 48 additions and 280 deletions

View file

@ -2,6 +2,7 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect;
@ -107,12 +108,13 @@ class CosmiumConfluenceEffect extends OneShotEffect {
new AddCountersTargetEffect(CounterType.P1P1.createInstance(3))
.setTargetPointer(fixedTarget)
.apply(game, source);
new BecomesCreatureTargetEffect(
ContinuousEffect effect = new BecomesCreatureTargetEffect(
new CreatureToken(0, 0, "0/0 Elemental creature with haste", SubType.ELEMENTAL)
.withAbility(HasteAbility.getInstance()),
false, true, Duration.Custom
).setTargetPointer(fixedTarget)
.apply(game, source);
);
effect.setTargetPointer(fixedTarget);
game.addEffect(effect, source);
return true;
}

View file

@ -3,20 +3,19 @@ package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.MayCastTargetThenExileEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.card.OwnerIdPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetCardInOpponentsGraveyard;
@ -24,7 +23,6 @@ import mage.target.targetadjustment.TargetAdjuster;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
import mage.ApprovingObject;
/**
* @author LevelX2
@ -108,17 +106,7 @@ class DiluvianPrimordialEffect extends OneShotEffect {
if (target instanceof TargetCardInOpponentsGraveyard) {
Card targetCard = game.getCard(target.getFirstTarget());
if (targetCard != null) {
if (controller.chooseUse(Outcome.PlayForFree, "Cast " + targetCard.getLogName() + '?', source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + targetCard.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(targetCard, game, true),
game, true, new ApprovingObject(source, game));
game.getState().setValue("PlayFromNotOwnHandZone" + targetCard.getId(), null);
if (cardWasCast) {
ContinuousEffect effect = new DiluvianPrimordialReplacementEffect();
effect.setTargetPointer(new FixedTarget(targetCard.getId(), game.getState().getZoneChangeCounter(targetCard.getId())));
game.addEffect(effect, source);
}
}
new MayCastTargetThenExileEffect(true).setTargetPointer(new FixedTarget(targetCard, game)).apply(game, source);
}
}
}
@ -127,43 +115,3 @@ class DiluvianPrimordialEffect extends OneShotEffect {
return false;
}
}
class DiluvianPrimordialReplacementEffect extends ReplacementEffectImpl {
public DiluvianPrimordialReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Exile);
staticText = "If a card cast this way would be put into a graveyard this turn, exile it instead";
}
private DiluvianPrimordialReplacementEffect(final DiluvianPrimordialReplacementEffect effect) {
super(effect);
}
@Override
public DiluvianPrimordialReplacementEffect copy() {
return new DiluvianPrimordialReplacementEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
return zEvent.getToZone() == Zone.GRAVEYARD
&& event.getTargetId().equals(getTargetPointer().getFirst(game, source));
}
}

View file

@ -66,11 +66,7 @@ class FieryEmancipationEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmount(CardUtil.overflowInc(
CardUtil.overflowInc(
event.getAmount(), event.getAmount()
), event.getAmount()
));
event.setAmount(CardUtil.overflowMultiply(event.getAmount(), 3));
return false;
}
}

View file

@ -1,20 +1,18 @@
package mage.cards.f;
import mage.ApprovingObject;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.MayCastTargetThenExileEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.Target;
@ -118,7 +116,7 @@ class FinaleOfPromiseEffect extends OneShotEffect {
}
// ask to cast order
if (!cardsToCast.isEmpty()) {
if (cardsToCast.size() > 1) {
String cardsOrder = cardsToCast.stream()
.map(game::getCard)
.filter(Objects::nonNull)
@ -135,13 +133,7 @@ class FinaleOfPromiseEffect extends OneShotEffect {
for (UUID id : cardsToCast) {
Card card = game.getCard(id);
if (card != null) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new ApprovingObject(source, game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
ContinuousEffect effect = new FinaleOfPromiseReplacementEffect();
effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId())));
game.addEffect(effect, source);
new MayCastTargetThenExileEffect(true).setTargetPointer(new FixedTarget(card, game)).apply(game, source);
}
}
@ -162,49 +154,3 @@ class FinaleOfPromiseEffect extends OneShotEffect {
return true;
}
}
class FinaleOfPromiseReplacementEffect extends ReplacementEffectImpl {
public FinaleOfPromiseReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Exile);
staticText = "If a card cast this way would be put into your graveyard this turn, exile it instead";
}
private FinaleOfPromiseReplacementEffect(final FinaleOfPromiseReplacementEffect effect) {
super(effect);
}
@Override
public FinaleOfPromiseReplacementEffect copy() {
return new FinaleOfPromiseReplacementEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card != null) {
return controller.moveCards(card, Zone.EXILED, source, game);
}
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
return zEvent.getToZone() == Zone.GRAVEYARD
&& event.getTargetId().equals(getTargetPointer().getFirst(game, source));
}
}

View file

@ -7,22 +7,22 @@ import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.MayCastTargetThenExileEffect;
import mage.abilities.effects.common.replacement.ThatSpellGraveyardExileReplacementEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInGraveyard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import java.util.UUID;
@ -90,40 +90,9 @@ class HaloForagerPayEffect extends OneShotEffect {
"instant or sorcery card with mana value " + costX + " from a graveyard"
);
filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, costX));
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new HaloForagerCastEffect(costX), false);
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new MayCastTargetThenExileEffect(true), false);
ability.addTarget(new TargetCardInGraveyard(filter));
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
}
class HaloForagerCastEffect extends OneShotEffect {
HaloForagerCastEffect(int costX) {
super(Outcome.Benefit);
staticText = "You may cast target instant or sorcery card with mana value " + costX + " from a graveyard " +
"without paying its mana cost. " + ThatSpellGraveyardExileReplacementEffect.RULE_A;
}
private HaloForagerCastEffect(final HaloForagerCastEffect effect) {
super(effect);
}
@Override
public HaloForagerCastEffect copy() {
return new HaloForagerCastEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (player == null || card == null) {
return false;
}
ContinuousEffect effect = new ThatSpellGraveyardExileReplacementEffect(false);
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
return CardUtil.castSpellWithAttributesForFree(player, source, game, card);
}
}

View file

@ -150,9 +150,7 @@ class JeskaThriceRebornEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
int amount = event.getAmount();
event.setAmount(CardUtil.overflowInc(amount, event.getAmount()));
event.setAmount(CardUtil.overflowInc(amount, event.getAmount()));
event.setAmount(CardUtil.overflowMultiply(event.getAmount(), 3));
return false;
}
}

View file

@ -13,8 +13,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
@ -27,13 +26,6 @@ import java.util.UUID;
*/
public final class KrosDefenseContractor extends CardImpl {
private static final FilterPermanent filter
= new FilterCreaturePermanent("creature you don't control");
static {
filter.add(TargetController.NOT_YOU.getControllerPredicate());
}
public KrosDefenseContractor(UUID ownerID, CardSetInfo setInfo) {
super(ownerID, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}{U}");
@ -50,7 +42,7 @@ public final class KrosDefenseContractor extends CardImpl {
this.addAbility(ability);
// Whenever you put one or more counters on a creature you don't control, tap that creature and goad it. It gains trample until your next turn.
this.addAbility(new PutCounterOnCreatureTriggeredAbility(new KrosDefenseContractorEffect(), null, filter, true));
this.addAbility(new PutCounterOnCreatureTriggeredAbility(new KrosDefenseContractorEffect(), null, StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, true));
}
private KrosDefenseContractor(final KrosDefenseContractor card) {

View file

@ -12,22 +12,13 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.StaticFilters;
/**
*
* @author LevelX2
*/
public final class OrzhovPontiff extends CardImpl {
private static final FilterCreaturePermanent filterControlled = new FilterCreaturePermanent("Creatures you control");
private static final FilterCreaturePermanent filterNotControlled = new FilterCreaturePermanent("creatures you don't control");
static {
filterControlled.add(TargetController.YOU.getControllerPredicate());
filterNotControlled.add((TargetController.NOT_YOU.getControllerPredicate()));
}
public OrzhovPontiff(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{B}");
this.subtype.add(SubType.HUMAN);
@ -38,8 +29,8 @@ public final class OrzhovPontiff extends CardImpl {
// Haunt
// When Orzhov Pontiff enters the battlefield or the creature it haunts dies, choose one - Creatures you control get +1/+1 until end of turn; or creatures you don't control get -1/-1 until end of turn.
Ability ability = new HauntAbility(this, new BoostAllEffect(1,1, Duration.EndOfTurn, filterControlled, false));
Mode mode = new Mode(new BoostAllEffect(-1,-1, Duration.EndOfTurn, filterNotControlled, false));
Ability ability = new HauntAbility(this, new BoostAllEffect(1,1, Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES_CONTROLLED, false));
Mode mode = new Mode(new BoostAllEffect(-1,-1, Duration.EndOfTurn, StaticFilters.FILTER_CREATURES_YOU_DONT_CONTROL, false));
ability.addMode(mode);
this.addAbility(ability);

View file

@ -1,27 +1,27 @@
package mage.cards.s;
import mage.ApprovingObject;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.replacement.ThatSpellGraveyardExileReplacementEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
import mage.ApprovingObject;
/**
* @author TheElk801
@ -96,59 +96,16 @@ class ScholarOfTheLostTroveEffect extends OneShotEffect {
return true;
}
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new ApprovingObject(source, game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (!cardWasCast || !card.isInstantOrSorcery(game)) {
return true;
}
ContinuousEffect effect = new ScholarOfTheLostTroveReplacementEffect(card.getId());
ContinuousEffect effect = new ThatSpellGraveyardExileReplacementEffect(true);
effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId())));
effect.setText("If an instant or sorcery spell cast this way would be put into your graveyard this turn, exile it instead");
game.addEffect(effect, source);
return true;
}
}
class ScholarOfTheLostTroveReplacementEffect extends ReplacementEffectImpl {
private final UUID cardId;
ScholarOfTheLostTroveReplacementEffect(UUID cardId) {
super(Duration.EndOfTurn, Outcome.Exile);
this.cardId = cardId;
staticText = "If an instant or sorcery spell cast this way would be put into your graveyard this turn, exile it instead";
}
private ScholarOfTheLostTroveReplacementEffect(final ScholarOfTheLostTroveReplacementEffect effect) {
super(effect);
this.cardId = effect.cardId;
}
@Override
public ScholarOfTheLostTroveReplacementEffect copy() {
return new ScholarOfTheLostTroveReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
Card card = game.getCard(this.cardId);
if (controller == null || card == null) {
return false;
}
controller.moveCards(card, Zone.EXILED, source, game);
return true;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
return zEvent.getToZone() == Zone.GRAVEYARD
&& zEvent.getTargetId().equals(this.cardId);
}
}

View file

@ -5,8 +5,9 @@ import mage.abilities.effects.common.counter.ProliferateEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -26,7 +27,7 @@ public final class SmellFear extends CardImpl {
"<br>Target creature you control fights up to one target creature you don't control"
));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1, StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, false));
}
private SmellFear(final SmellFear card) {

View file

@ -1,20 +1,18 @@
package mage.cards.v;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.Ability;
import mage.abilities.common.ExertCreatureControllerTriggeredAbility;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.keyword.ExertAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
*
@ -34,7 +32,9 @@ public final class VizierOfTheTrue extends CardImpl {
this.addAbility(new ExertAbility(null, false));
// Whenever you exert a creature, tap target creature an opponent controls.
this.addAbility(new VizierOfTheTrueAbility());
Ability ability = new ExertCreatureControllerTriggeredAbility(new TapTargetEffect());
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
}
private VizierOfTheTrue(final VizierOfTheTrue card) {
@ -46,35 +46,3 @@ public final class VizierOfTheTrue extends CardImpl {
return new VizierOfTheTrue(this);
}
}
class VizierOfTheTrueAbility extends TriggeredAbilityImpl {
public VizierOfTheTrueAbility() {
super(Zone.BATTLEFIELD, new TapTargetEffect());
addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE));
}
private VizierOfTheTrueAbility(final VizierOfTheTrueAbility ability) {
super(ability);
}
@Override
public VizierOfTheTrueAbility copy() {
return new VizierOfTheTrueAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.BECOMES_EXERTED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(getControllerId());
}
@Override
public String getRule() {
return "Whenever you exert a creature, tap target creature an opponent controls.";
}
}