refactor: new GainLifeTargetControllerEffect

This commit is contained in:
xenohedron 2024-06-01 16:57:27 -04:00
parent af89fd80ee
commit 058ae26de7
7 changed files with 136 additions and 191 deletions

View file

@ -2,8 +2,9 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.GainLifeTargetControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
@ -13,9 +14,6 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
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;
@ -39,8 +37,9 @@ public final class AjaniInspiringLeader extends CardImpl {
this.addAbility(ability);
// 3: Exile target creature. Its controller gains 2 life.
ability = new LoyaltyAbility(new AjaniInspiringLeaderEffect(), -3);
ability = new LoyaltyAbility(new ExileTargetEffect(), -3);
ability.addTarget(new TargetCreaturePermanent());
ability.addEffect(new GainLifeTargetControllerEffect(2));
this.addAbility(ability);
// 10: Creatures you control gain flying and double strike until end of turn.
@ -64,34 +63,3 @@ public final class AjaniInspiringLeader extends CardImpl {
return new AjaniInspiringLeader(this);
}
}
class AjaniInspiringLeaderEffect extends OneShotEffect {
AjaniInspiringLeaderEffect() {
super(Outcome.Benefit);
staticText = "Exile target creature. Its controller gains 2 life.";
}
private AjaniInspiringLeaderEffect(final AjaniInspiringLeaderEffect effect) {
super(effect);
}
@Override
public AjaniInspiringLeaderEffect copy() {
return new AjaniInspiringLeaderEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent == null) {
return false;
}
Player player = game.getPlayer(permanent.getControllerId());
if (player == null) {
return false;
}
player.gainLife(2, game, source);
return player.moveCards(permanent, Zone.EXILED, source, game);
}
}

View file

@ -1,21 +1,17 @@
package mage.cards.l;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.GainLifeTargetControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author LevelX2
@ -33,7 +29,7 @@ public final class LastBreath extends CardImpl {
// Exile target creature with power 2 or less. Its controller gains 4 life.
this.getSpellAbility().addEffect(new ExileTargetEffect());
this.getSpellAbility().addEffect(new LastBreathEffect());
this.getSpellAbility().addEffect(new GainLifeTargetControllerEffect(4));
this.getSpellAbility().addTarget(new TargetPermanent(filter));
}
@ -47,34 +43,3 @@ public final class LastBreath extends CardImpl {
return new LastBreath(this);
}
}
class LastBreathEffect extends OneShotEffect {
LastBreathEffect() {
super(Outcome.GainLife);
staticText = "Its controller gains 4 life";
}
private LastBreathEffect(final LastBreathEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent target = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
if (target != null) {
Player player = game.getPlayer(target.getControllerId());
if (player != null) {
player.gainLife(4, game, source);
return true;
}
}
return false;
}
@Override
public LastBreathEffect copy() {
return new LastBreathEffect(this);
}
}

View file

@ -1,17 +1,15 @@
package mage.cards.l;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.GainLifeTargetControllerEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
@ -19,10 +17,8 @@ import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import java.util.Optional;
import java.util.UUID;
/**
@ -42,8 +38,9 @@ public final class LayDownArms extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}");
// Exile target creature with mana value less than or equal to the number of Plains you control. Its controller gains 3 life.
this.getSpellAbility().addEffect(new LayDownArmsEffect());
this.getSpellAbility().addEffect(new ExileTargetEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter));
this.getSpellAbility().addEffect(new GainLifeTargetControllerEffect(3));
this.getSpellAbility().addHint(LayDownArmsPredicate.getHint());
}
@ -72,34 +69,3 @@ enum LayDownArmsPredicate implements ObjectSourcePlayerPredicate<Permanent> {
return hint;
}
}
class LayDownArmsEffect extends OneShotEffect {
LayDownArmsEffect() {
super(Outcome.Benefit);
staticText = "exile target creature with mana value less than or equal " +
"to the number of Plains you control. Its controller gains 3 life";
}
private LayDownArmsEffect(final LayDownArmsEffect effect) {
super(effect);
}
@Override
public LayDownArmsEffect copy() {
return new LayDownArmsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller == null || permanent == null) {
return false;
}
controller.moveCards(permanent, Zone.EXILED, source, game);
Optional.ofNullable(game.getPlayer(permanent.getControllerId()))
.ifPresent(player -> player.gainLife(3, game, source));
return true;
}
}

View file

@ -1,17 +1,11 @@
package mage.cards.n;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.GainLifeTargetControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import java.util.UUID;
@ -27,7 +21,7 @@ public final class NaturesClaim extends CardImpl {
// Destroy target artifact or enchantment. Its controller gains 4 life.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addEffect(new NaturesClaimEffect());
this.getSpellAbility().addEffect(new GainLifeTargetControllerEffect(4));
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
}
@ -40,33 +34,3 @@ public final class NaturesClaim extends CardImpl {
return new NaturesClaim(this);
}
}
class NaturesClaimEffect extends OneShotEffect {
NaturesClaimEffect() {
super(Outcome.GainLife);
staticText = "Its controller gains 4 life";
}
private NaturesClaimEffect(final NaturesClaimEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent target = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
if (target != null) {
Player player = game.getPlayer(target.getControllerId());
if (player != null) {
player.gainLife(4, game, source);
return true;
}
}
return false;
}
@Override
public NaturesClaimEffect copy() {
return new NaturesClaimEffect(this);
}
}

View file

@ -1,17 +1,14 @@
package mage.cards.o;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GainLifeTargetControllerEffect;
import mage.abilities.effects.common.PutIntoLibraryNFromTopTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author North
@ -22,7 +19,8 @@ public final class Oust extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}");
// Put target creature into its owner's library second from the top. Its controller gains 3 life.
this.getSpellAbility().addEffect(new OustEffect());
this.getSpellAbility().addEffect(new PutIntoLibraryNFromTopTargetEffect(2));
this.getSpellAbility().addEffect(new GainLifeTargetControllerEffect(3));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
@ -35,35 +33,3 @@ public final class Oust extends CardImpl {
return new Oust(this);
}
}
class OustEffect extends OneShotEffect {
OustEffect() {
super(Outcome.Benefit);
this.staticText = "Put target creature into its owner's library second from the top. Its controller gains 3 life";
}
private OustEffect(final OustEffect effect) {
super(effect);
}
@Override
public OustEffect copy() {
return new OustEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
Player owner = game.getPlayer(permanent.getOwnerId());
Player controller = game.getPlayer(permanent.getControllerId());
if (owner == null || controller == null) {
return false;
}
owner.putCardOnTopXOfLibrary(permanent, game, source, 2, true);
controller.gainLife(3, game, source);
}
return true;
}
}

View file

@ -0,0 +1,57 @@
package org.mage.test.cards.single.mmq;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author xenohedron
*/
public class LastBreathTest extends CardTestPlayerBase {
// Exile target creature with power 2 or less. Its controller gains 4 life.
private static final String lastBreath = "Last Breath"; // 1W Instant
private static final String drake = "Wind Drake";
@Test
public void testControllerGains() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.HAND, playerA, lastBreath);
addCard(Zone.BATTLEFIELD, playerB, drake);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lastBreath, drake);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertGraveyardCount(playerA, lastBreath, 1);
assertExileCount(playerB, drake, 1);
assertLife(playerA, 20);
assertLife(playerB, 24);
}
@Test
public void testControllerChanged() {
String threaten = "Act of Treason";
addCard(Zone.HAND, playerA, lastBreath);
addCard(Zone.BATTLEFIELD, playerB, drake);
addCard(Zone.BATTLEFIELD, playerA, "Plateau", 5);
addCard(Zone.HAND, playerA, threaten);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, threaten, drake);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, lastBreath, drake);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertGraveyardCount(playerA, lastBreath, 1);
assertExileCount(playerB, drake, 1);
assertLife(playerA, 24);
assertLife(playerB, 20);
}
}

View file

@ -0,0 +1,59 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
/**
* @author xenohedron
*/
public class GainLifeTargetControllerEffect extends OneShotEffect {
protected DynamicValue amount;
public GainLifeTargetControllerEffect(int amount) {
this(StaticValue.get(amount));
this.staticText = "its controller gains " + amount + " life";
}
public GainLifeTargetControllerEffect(DynamicValue amount) {
super(Outcome.GainLife);
this.amount = amount;
}
protected GainLifeTargetControllerEffect(final GainLifeTargetControllerEffect effect) {
super(effect);
amount = effect.amount.copy();
}
@Override
public GainLifeTargetControllerEffect copy() {
return new GainLifeTargetControllerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetController = null;
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
if (permanent != null) {
targetController = game.getPlayer(permanent.getControllerId());
} else {
Spell spell = game.getSpellOrLKIStack(getTargetPointer().getFirst(game, source));
if (spell != null) {
targetController = game.getPlayer(spell.getControllerId());
}
}
if (targetController != null) {
targetController.gainLife(amount.calculate(game, source, this), game, source);
return true;
}
return false;
}
}