mirror of
https://github.com/magefree/mage.git
synced 2025-12-23 12:02:01 -08:00
refactor: new GainLifeTargetControllerEffect
This commit is contained in:
parent
af89fd80ee
commit
058ae26de7
7 changed files with 136 additions and 191 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue