Merge pull request #14078 from xenohedron/damagemulti

Rework effects that deal damage to multiple specific objects
This commit is contained in:
xenohedron 2025-11-13 00:35:06 -05:00 committed by GitHub
commit 1cb72d0efb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
86 changed files with 1200 additions and 844 deletions

View file

@ -1,21 +1,14 @@
package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.common.FilterAnyTarget;
import mage.filter.common.FilterPermanentOrPlayer;
import mage.filter.predicate.other.AnotherTargetPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetPermanentOrPlayer;
import java.io.ObjectStreamException;
import java.util.UUID;
/**
@ -34,10 +27,12 @@ public final class ArcTrail extends CardImpl {
public ArcTrail(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}");
// Arc Trail deals 2 damage to any target and 1 damage to another any target
this.getSpellAbility().addEffect(ArcTrailEffect.getInstance());
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter1).setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter2).setTargetTag(2));
// Arc Trail deals 2 damage to any target and 1 damage to another target
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(2, 1));
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter1)
.withChooseHint("to deal 2 damage").setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter2)
.withChooseHint("to deal 1 damage").setTargetTag(2));
}
private ArcTrail(final ArcTrail card) {
@ -50,54 +45,3 @@ public final class ArcTrail extends CardImpl {
}
}
class ArcTrailEffect extends OneShotEffect {
private static final ArcTrailEffect instance = new ArcTrailEffect();
private Object readResolve() throws ObjectStreamException {
return instance;
}
public static ArcTrailEffect getInstance() {
return instance;
}
private ArcTrailEffect() {
super(Outcome.Damage);
staticText = "{this} deals 2 damage to any target and 1 damage to another target";
}
@Override
public boolean apply(Game game, Ability source) {
boolean applied = false;
boolean twoDamageDone = false;
int damage = 2;
for (Target target : source.getTargets()) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (twoDamageDone) {
damage = 1;
}
if (permanent != null) {
applied |= (permanent.damage(damage, source.getSourceId(), source, game, false, true) > 0);
}
Player player = game.getPlayer(target.getFirstTarget());
if (player != null) {
applied |= (player.damage(damage, source.getSourceId(), source, game) > 0);
}
twoDamageDone = true;
}
return applied;
}
@Override
public ArcTrailEffect copy() {
return instance;
}
}

View file

@ -1,16 +1,14 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BlocksOrBlockedByCreatureSourceTriggeredAbility;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
@ -25,9 +23,8 @@ public final class AssembledAlphas extends CardImpl {
this.toughness = new MageInt(5);
// Whenever Assembled Alphas blocks or becomes blocked by a creature, Assembled Alphas deals 3 damage to that creature and 3 damage to that creature's controller.
Ability ability = new BlocksOrBlockedByCreatureSourceTriggeredAbility(new DamageTargetEffect(3, true, "that creature"));
ability.addEffect(new DamageTargetControllerEffect(3).setText("and 3 damage to that creature's controller"));
this.addAbility(ability);
this.addAbility(new BlocksOrBlockedByCreatureSourceTriggeredAbility(
new DamageTargetAndTargetControllerEffect(3, 3)));
}
private AssembledAlphas(final AssembledAlphas card) {

View file

@ -65,7 +65,7 @@ public final class AvalancheOfSector7 extends CardImpl {
class AvalancheOfSector7TriggeredAbility extends TriggeredAbilityImpl {
AvalancheOfSector7TriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(1, true, "that player", true));
super(Zone.BATTLEFIELD, new DamageTargetEffect(1, true, "that player"));
setTriggerPhrase("Whenever an opponent activates an ability of an artifact they control, ");
}

View file

@ -49,7 +49,7 @@ public final class BarretWallace extends CardImpl {
// Whenever Barret Wallace attacks, it deals damage equal to the number of equipped creatures you control to defending player.
this.addAbility(new AttacksTriggeredAbility(
new DamageTargetEffect(xValue, true, "it", true)
new DamageTargetEffect(xValue, true, "it")
.setText("it deals damage equal to the number of equipped creatures you control to defending player"),
false, null, SetTargetPointer.PLAYER
).withRuleTextReplacement(true).addHint(hint));

View file

@ -1,7 +1,6 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@ -75,7 +74,7 @@ class BedazzleEffect extends OneShotEffect {
if (permanent != null) {
permanent.destroy(source, game, false);
}
Effect effect = new DamageTargetEffect(StaticValue.get(2), true, "", true);
Effect effect = new DamageTargetEffect(2);
effect.setTargetPointer(new FixedTarget(source.getTargets().get(1).getFirstTarget(), game));
effect.apply(game, source);
return true;

View file

@ -3,9 +3,7 @@ package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsDamageToACreatureTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -31,12 +29,10 @@ public final class BellowingFiend extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever Bellowing Fiend deals damage to a creature, Bellowing Fiend deals 3 damage to that creature's controller and 3 damage to you.
Ability ability = new DealsDamageToACreatureTriggeredAbility(new BellowingFiendEffect(), false, false, true);
Effect effect = new DamageControllerEffect(3);
effect.setText("and 3 damage to you");
ability.addEffect(effect);
this.addAbility(ability);
this.addAbility(new DealsDamageToACreatureTriggeredAbility(
new BellowingFiendEffect(), false, false, true));
}
private BellowingFiend(final BellowingFiend card) {
@ -53,7 +49,7 @@ class BellowingFiendEffect extends OneShotEffect {
BellowingFiendEffect() {
super(Outcome.Detriment);
this.staticText = "{this} deals 3 damage to that creature's controller";
this.staticText = "{this} deals 3 damage to that creature's controller and 3 damage to you";
}
private BellowingFiendEffect(final BellowingFiendEffect effect) {
@ -67,15 +63,17 @@ class BellowingFiendEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
boolean applied = false;
Permanent damagedCreature = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
if (damagedCreature != null) {
Player controller = game.getPlayer(damagedCreature.getControllerId());
if (controller != null) {
controller.damage(3, source.getSourceId(), source, game);
applied = true;
}
}
return applied;
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
you.damage(3, source.getSourceId(), source, game);
}
return true;
}
}

View file

@ -1,21 +1,18 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author LoneFox
@ -29,10 +26,7 @@ public final class BrothersOfFire extends CardImpl {
this.toughness = new MageInt(2);
// {1}{R}{R}: Brothers of Fire deals 1 damage to any target and 1 damage to you.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new ManaCostsImpl<>("{1}{R}{R}"));
Effect effect = new DamageControllerEffect(1);
effect.setText("and 1 damage to you");
ability.addEffect(effect);
Ability ability = new SimpleActivatedAbility(new DamageTargetAndYouEffect(1), new ManaCostsImpl<>("{1}{R}{R}"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -1,12 +1,9 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -14,6 +11,8 @@ import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponentOrPlaneswalker;
import java.util.UUID;
/**
*
* @author TheElk801
@ -29,11 +28,9 @@ public final class BurningSunsAvatar extends CardImpl {
this.toughness = new MageInt(6);
// When Burning Sun's Avatar enters the battlefield, it deals 3 damage to target opponent and 3 damage to up to one target creature.
Effect effect = new DamageTargetEffect(3);
effect.setText("it deals 3 damage to target opponent or planeswalker and 3 damage to up to one target creature");
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
ability.addTarget(new TargetOpponentOrPlaneswalker());
ability.addTarget(new TargetCreaturePermanent(0, 1));
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetAndTargetEffect(3, 3));
ability.addTarget(new TargetOpponentOrPlaneswalker().setTargetTag(1));
ability.addTarget(new TargetCreaturePermanent(0, 1).setTargetTag(2));
this.addAbility(ability);
}

View file

@ -46,7 +46,7 @@ public final class BurningTreeShaman extends CardImpl {
class BurningTreeShamanTriggeredAbility extends TriggeredAbilityImpl {
BurningTreeShamanTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(1), true, "that player", true));
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(1), true, "that player"));
}
private BurningTreeShamanTriggeredAbility(final BurningTreeShamanTriggeredAbility ability) {

View file

@ -1,6 +1,6 @@
package mage.cards.c;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.cards.CardSetInfo;
@ -22,8 +22,7 @@ public final class CarnivalCarnage extends SplitCard {
// Carnival
// Carnival deals 1 damage to target creature or planeswalker and 1 damage to that permanent's controller.
this.getLeftHalfCard().getSpellAbility().addEffect(new DamageTargetEffect(1));
this.getLeftHalfCard().getSpellAbility().addEffect(new DamageTargetControllerEffect(1).setText("and 1 damage to that permanent's controller"));
this.getLeftHalfCard().getSpellAbility().addEffect(new DamageTargetAndTargetControllerEffect(1, 1));
this.getLeftHalfCard().getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
// Carnage

View file

@ -2,19 +2,14 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.effects.common.DamageTargetAndAllControlledEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
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 mage.target.TargetPlayer;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent;
@ -39,15 +34,12 @@ public final class ChandraFlamesFury extends CardImpl {
this.addAbility(ability);
// 2: Chandra, Flame's Fury deals 4 damage to target creature and 2 damage to that creature's controller.
ability = new LoyaltyAbility(new ChandraFlamesFuryEffect(), -2);
ability = new LoyaltyAbility(new DamageTargetAndTargetControllerEffect(4, 2), -2);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// 8: Chandra, Flame's Fury deals 10 damage to target player and each creature that player controls.
ability = new LoyaltyAbility(new DamageTargetEffect(10), -8);
ability.addEffect(new DamageAllControlledTargetEffect(
10, StaticFilters.FILTER_PERMANENT_CREATURE
).setText("and each creature that player controls"));
ability = new LoyaltyAbility(new DamageTargetAndAllControlledEffect(10), -8);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
@ -61,35 +53,3 @@ public final class ChandraFlamesFury extends CardImpl {
return new ChandraFlamesFury(this);
}
}
class ChandraFlamesFuryEffect extends OneShotEffect {
ChandraFlamesFuryEffect() {
super(Outcome.Benefit);
staticText = "{this} deals 4 damage to target creature and 2 damage to that creature's controller.";
}
private ChandraFlamesFuryEffect(final ChandraFlamesFuryEffect effect) {
super(effect);
}
@Override
public ChandraFlamesFuryEffect copy() {
return new ChandraFlamesFuryEffect(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;
}
permanent.damage(4, source.getSourceId(), source, game);
player.damage(2, source.getSourceId(), source, game);
return true;
}
}

View file

@ -36,8 +36,7 @@ public final class ChandraPyromaster extends CardImpl {
this.setStartingLoyalty(4);
// +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to
// up to one target creature that player controls. That creature can't block this turn.
// +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to up to one target creature that player controls. That creature can't block this turn.
LoyaltyAbility ability1 = new LoyaltyAbility(new ChandraPyromasterEffect1(), 1);
Target target1 = new TargetPlayerOrPlaneswalker();
ability1.addTarget(target1);
@ -68,7 +67,7 @@ public final class ChandraPyromaster extends CardImpl {
class ChandraPyromasterEffect1 extends OneShotEffect {
public ChandraPyromasterEffect1() {
ChandraPyromasterEffect1() {
super(Outcome.Damage);
staticText = "{this} deals 1 damage to target player or planeswalker "
+ "and 1 damage to up to one target creature that player or that "
@ -101,7 +100,7 @@ class ChandraPyromasterEffect1 extends OneShotEffect {
class ChandraPyromasterTarget extends TargetPermanent {
public ChandraPyromasterTarget() {
ChandraPyromasterTarget() {
super(0, 1, new FilterCreaturePermanent("creature that the targeted player "
+ "or planeswalker's controller controls"), false);
}
@ -138,7 +137,7 @@ class ChandraPyromasterTarget extends TargetPermanent {
class ChandraPyromasterEffect2 extends OneShotEffect {
public ChandraPyromasterEffect2() {
ChandraPyromasterEffect2() {
super(Outcome.Detriment);
this.staticText = "Exile the top card of your library. You may play it this turn";
}

View file

@ -1,14 +1,14 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndAllControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.common.TargetPlayerOrPlaneswalker;
import java.util.UUID;
/**
*
* @author North
@ -19,10 +19,8 @@ public final class ChandrasFury extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
// Chandra's Fury deals 4 damage to target player and 1 damage to each creature that player controls.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addEffect(new DamageAllControlledTargetEffect(1)
.setText("and 1 damage to each creature that player or that planeswalker's controller controls")
);
this.getSpellAbility().addEffect(new DamageTargetAndAllControlledEffect(4, 1,
StaticFilters.FILTER_PERMANENT_CREATURE));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
}

View file

@ -1,16 +1,13 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
@ -21,10 +18,7 @@ public final class ChandrasOutrage extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}{R}");
// Chandra's Outrage deals 4 damage to target creature and 2 damage to that creature's controller.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
Effect effect = new DamageTargetControllerEffect(2);
effect.setText("and 2 damage to that creature's controller");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addEffect(new DamageTargetAndTargetControllerEffect(4, 2));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}

View file

@ -1,15 +1,13 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author LevelX2
@ -19,13 +17,9 @@ public final class Char extends CardImpl {
public Char(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}");
// Char deals 4 damage to any target and 2 damage to you.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addEffect(new DamageTargetAndYouEffect(4, 2));
this.getSpellAbility().addTarget(new TargetAnyTarget());
Effect effect = new DamageControllerEffect(2);
effect.setText("and 2 damage to you");
this.getSpellAbility().addEffect(effect);
}
private Char(final Char card) {

View file

@ -1,13 +1,12 @@
package mage.cards.c;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
@ -20,16 +19,11 @@ public final class ConductElectricity extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
// Conduct Electricity deals 6 damage to target creature and 2 damage to up to one target creature token.
this.getSpellAbility().addEffect(new DamageTargetEffect(
6, true, "", true
));
this.getSpellAbility().addEffect(new DamageTargetEffect(
2, true, "", true
).setTargetPointer(new SecondTargetPointer()).setText("and 2 damage to up to one target creature token"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(6, 2));
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPermanent(
0, 1, StaticFilters.FILTER_CREATURE_TOKEN
));
).setTargetTag(2));
}
private ConductElectricity(final ConductElectricity card) {

View file

@ -1,17 +1,14 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlayerOrPlaneswalker;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
/**
*
@ -22,14 +19,11 @@ public final class CunningStrike extends CardImpl {
public CunningStrike(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{R}");
// Cunning Strike deals 2 damage to target creature and 2 damage to target player.
this.getSpellAbility().addEffect(new DamageTargetEffect(StaticValue.get(2), true, "", true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
Effect effect = new DamageTargetEffect(StaticValue.get(2), true, "", true);
effect.setTargetPointer(new SecondTargetPointer());
effect.setText("and 2 damage to target player or planeswalker");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
// Cunning Strike deals 2 damage to target creature and 2 damage to target player or planeswalker.
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(2, 2));
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker().setTargetTag(2));
// Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("<br>"));
}

View file

@ -1,4 +1,3 @@
package mage.cards.c;
import mage.MageInt;
@ -12,13 +11,13 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetOpponent;
import mage.target.targetadjustment.TargetAdjuster;
import mage.target.targetpointer.EachTargetPointer;
import java.util.UUID;
@ -35,7 +34,7 @@ public final class CuombajjWitches extends CardImpl {
this.toughness = new MageInt(3);
// {T}: Cuombajj Witches deals 1 damage to any target and 1 damage to any target of an opponent's choice.
Effect effect = new DamageTargetEffect(1);
Effect effect = new DamageTargetEffect(1).setTargetPointer(new EachTargetPointer());
effect.setText("{this} deals 1 damage to any target and 1 damage to any target of an opponent's choice");
Ability ability = new SimpleActivatedAbility(effect, new TapSourceCost());
ability.addTarget(new TargetAnyTarget());

View file

@ -22,11 +22,7 @@ public final class CutIn extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
// Cut In deals 4 damage to target creature.
this.getSpellAbility().addEffect(
new DamageTargetEffect(4)
.setUseOnlyTargetPointer(true)
.setTargetPointer(new FirstTargetPointer())
);
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Create a Young Hero Role token attached to up to one target creature you control.

View file

@ -3,14 +3,17 @@ package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllEffect;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
import mage.game.Game;
import java.util.UUID;
@ -28,14 +31,7 @@ public final class DaggerCaster extends CardImpl {
this.toughness = new MageInt(3);
// When Dagger Caster enters the battlefield, it deals 1 damage to each opponent and 1 damage to each creature your opponents control.
Ability ability = new EntersBattlefieldTriggeredAbility(new DamagePlayersEffect(
1, TargetController.OPPONENT, "it"
));
ability.addEffect(
new DamageAllEffect(1, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)
.setText("and 1 damage to each creature your opponents control")
);
this.addAbility(ability);
this.addAbility(new EntersBattlefieldTriggeredAbility(new DaggerCasterEffect()));
}
private DaggerCaster(final DaggerCaster card) {
@ -47,3 +43,29 @@ public final class DaggerCaster extends CardImpl {
return new DaggerCaster(this);
}
}
// needed for simultaneous damage
class DaggerCasterEffect extends OneShotEffect {
DaggerCasterEffect() {
super(Outcome.Damage);
staticText = "it deals 1 damage to each opponent and 1 damage to each creature your opponents control";
}
private DaggerCasterEffect(final DaggerCasterEffect effect) {
super(effect);
}
@Override
public DaggerCasterEffect copy() {
return new DaggerCasterEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
new DamagePlayersEffect(1, TargetController.OPPONENT, "it").apply(game, source);
new DamageAllEffect(1, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE).apply(game, source);
return true;
}
}

View file

@ -16,6 +16,7 @@ import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.EachTargetPointer;
import java.util.UUID;
@ -40,7 +41,7 @@ public final class DragonsparkReactor extends CardImpl {
new DamageTargetEffect(xValue).setText(
"it deals damage equal to the number of charge counters on it to target player " +
"and that much damage to up to one target creature"
), new GenericManaCost(4)
).setTargetPointer(new EachTargetPointer()), new GenericManaCost(4)
);
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPlayer());

View file

@ -3,20 +3,16 @@ package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.common.FilterAnyTarget;
import mage.filter.common.FilterPermanentOrPlayer;
import mage.filter.predicate.other.AnotherTargetPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetPermanentOrPlayer;
@ -26,6 +22,7 @@ import java.util.UUID;
* @author TheElk801
*/
public final class DrakusethMawOfFlames extends CardImpl {
private static final FilterPermanentOrPlayer filter = new FilterAnyTarget("any target");
static {
@ -45,7 +42,8 @@ public final class DrakusethMawOfFlames extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever Drakuseth, Maw of Flames attacks, it deals 4 damage to any target and 3 damage to each of up to two other targets.
Ability ability = new AttacksTriggeredAbility(new DrakusethMawOfFlamesEffect(), false);
Ability ability = new AttacksTriggeredAbility(new DamageTargetAndTargetEffect(4, 3)
.setText("it deals 4 damage to any target and 3 damage to each of up to two other targets"));
ability.addTarget(new TargetAnyTarget().withChooseHint("to deal 4 damage").setTargetTag(1));
ability.addTarget(new TargetPermanentOrPlayer(
0, 2, filter, false
@ -62,43 +60,3 @@ public final class DrakusethMawOfFlames extends CardImpl {
return new DrakusethMawOfFlames(this);
}
}
class DrakusethMawOfFlamesEffect extends OneShotEffect {
DrakusethMawOfFlamesEffect() {
super(Outcome.Damage);
staticText = "it deals 4 damage to any target and 3 damage to each of "
+ "up to two other targets.";
}
private DrakusethMawOfFlamesEffect(final DrakusethMawOfFlamesEffect effect) {
super(effect);
}
@Override
public DrakusethMawOfFlamesEffect copy() {
return new DrakusethMawOfFlamesEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
damage(4, source.getTargets().get(0).getFirstTarget(), game, source);
source.getTargets()
.get(1)
.getTargets()
.stream()
.forEach(targetId -> damage(3, targetId, game, source));
return true;
}
private static void damage(int damage, UUID targetId, Game game, Ability source) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(damage, source.getSourceId(), source, game, false, true);
}
Player player = game.getPlayer(targetId);
if (player != null) {
player.damage(damage, source.getSourceId(), source, game);
}
}
}

View file

@ -1,7 +1,6 @@
package mage.cards.e;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
@ -82,7 +81,7 @@ class ExplosionEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int xValue = CardUtil.getSourceCostsTag(game, source, "X", 0);
Effect effect = new DamageTargetEffect(StaticValue.get(xValue), true, "", true);
Effect effect = new DamageTargetEffect(xValue);
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
effect.apply(game, source);
Player player = game.getPlayer(source.getTargets().get(1).getFirstTarget());

View file

@ -1,8 +1,7 @@
package mage.cards.e;
import mage.Mana;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -11,10 +10,8 @@ import mage.constants.ManaType;
import mage.filter.common.FilterAnyTarget;
import mage.filter.common.FilterPermanentOrPlayer;
import mage.filter.predicate.other.AnotherTargetPredicate;
import mage.target.Target;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetPermanentOrPlayer;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
@ -34,19 +31,12 @@ public final class ExplosiveWelcome extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{7}{R}");
// Explosive Welcome deals 5 damage to any target and 3 damage to any other target. Add {R}{R}{R}.
this.getSpellAbility().addEffect(new DamageTargetEffect(StaticValue.get(5), true, "", true));
this.getSpellAbility().addEffect(
new DamageTargetEffect(StaticValue.get(3), true, "", true)
.setTargetPointer(new SecondTargetPointer())
.setText("and 3 damage to any other target.")
);
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(5, 3));
this.getSpellAbility().addEffect(new BasicManaEffect(new Mana(ManaType.RED, 3)));
Target target = new TargetAnyTarget();
target.setTargetTag(1);
this.getSpellAbility().addTarget(target);
target = new TargetPermanentOrPlayer(filter);
target.setTargetTag(2);
this.getSpellAbility().addTarget(target);
this.getSpellAbility().addTarget(new TargetAnyTarget()
.withChooseHint("to deal 5 damage").setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter)
.withChooseHint("to deal 3 damage").setTargetTag(2));
}
private ExplosiveWelcome(final ExplosiveWelcome card) {

View file

@ -34,7 +34,6 @@ public final class FearFireFoes extends CardImpl {
this.getSpellAbility().addEffect(new DamageCantBePreventedEffect(
Duration.EndOfTurn
));
this.getSpellAbility().addEffect(new DamageTargetEffect(GetXValue.instance));
this.getSpellAbility().addEffect(new FearFireFoesEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
@ -53,7 +52,8 @@ class FearFireFoesEffect extends OneShotEffect {
FearFireFoesEffect() {
super(Outcome.Benefit);
staticText = "and 1 damage to each other creature with the same controller";
staticText = "{this} deals X damage to target creature " +
"and 1 damage to each other creature with the same controller";
}
private FearFireFoesEffect(final FearFireFoesEffect effect) {
@ -67,6 +67,7 @@ class FearFireFoesEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
new DamageTargetEffect(GetXValue.instance).apply(game, source);
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent == null) {
return false;

View file

@ -37,7 +37,7 @@ public final class FieryAnnihilation extends CardImpl {
// Fiery Annihilation deals 5 damage to target creature. Exile up to one target Equipment attached to that creature. If that creature would die this turn, exile it instead.
this.getSpellAbility().addEffect(new DamageTargetEffect(
5, true, "target creature", true
5, true, "target creature"
));
this.getSpellAbility().addEffect(new ExileTargetEffect()
.setTargetPointer(new SecondTargetPointer())

View file

@ -1,7 +1,6 @@
package mage.cards.f;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -30,8 +29,7 @@ public final class FireAndBrimstone extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}{W}");
// Fire and Brimstone deals 4 damage to target player who attacked this turn and 4 damage to you.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addEffect(new DamageControllerEffect(4).setText("and 4 damage to you"));
this.getSpellAbility().addEffect(new DamageTargetAndYouEffect(4));
this.getSpellAbility().addTarget(new TargetPlayer(1, 1, false, filter));
}

View file

@ -4,8 +4,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -26,8 +25,7 @@ public final class Fireslinger extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(1);
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new TapSourceCost());
ability.addEffect(new DamageControllerEffect(1).setText("and 1 damage to you"));
Ability ability = new SimpleActivatedAbility(new DamageTargetAndYouEffect(1), new TapSourceCost());
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -1,17 +1,20 @@
package mage.cards.f;
import mage.abilities.Ability;
import mage.abilities.condition.common.ManaWasSpentCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import java.util.UUID;
@ -30,12 +33,8 @@ public final class Firespout extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R/G}");
// Firespout deals 3 damage to each creature without flying if {R} was spent to cast Firespout and 3 damage to each creature with flying if {G} was spent to cast it.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DamageAllEffect(3, filter1),
ManaWasSpentCondition.RED, "{this} deals 3 damage to each creature without flying if {R} was spent to cast this spell"));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DamageAllEffect(3, StaticFilters.FILTER_CREATURE_FLYING),
ManaWasSpentCondition.GREEN, "and 3 damage to each creature with flying if {G} was spent to cast this spell. <i>(Do both if {R}{G} was spent.)</i>"));
this.getSpellAbility().addEffect(new FirespoutEffect());
}
private Firespout(final Firespout card) {
@ -47,3 +46,37 @@ public final class Firespout extends CardImpl {
return new Firespout(this);
}
}
// needed for simultaneous damage
class FirespoutEffect extends OneShotEffect {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature without flying");
static {
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
}
FirespoutEffect() {
super(Outcome.Benefit);
staticText = "{this} deals 3 damage to each creature without flying if {R} was spent to cast this spell " +
"and 3 damage to each creature with flying if {G} was spent to cast this spell. " +
"<i>(Do both if {R}{G} was spent.)</i>";
}
private FirespoutEffect(final FirespoutEffect effect) {
super(effect);
}
@Override
public FirespoutEffect copy() {
return new FirespoutEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
new ConditionalOneShotEffect(new DamageAllEffect(3, filter),
ManaWasSpentCondition.RED).apply(game, source);
new ConditionalOneShotEffect(new DamageAllEffect(3, StaticFilters.FILTER_CREATURE_FLYING),
ManaWasSpentCondition.GREEN).apply(game, source);
return true;
}
}

View file

@ -1,9 +1,6 @@
package mage.cards.f;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -23,10 +20,7 @@ public final class FirstVolley extends CardImpl {
this.subtype.add(SubType.ARCANE);
// First Volley deals 1 damage to target creature and 1 damage to that creature's controller.
this.getSpellAbility().addEffect(new DamageTargetEffect(1));
Effect effect = new DamageTargetControllerEffect(1);
effect.setText("and 1 damage to that creature's controller");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addEffect(new DamageTargetAndTargetControllerEffect(1, 1));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}

View file

@ -73,7 +73,7 @@ public final class FlamescrollCelebrant extends ModalDoubleFacedCard {
class FlamescrollCelebrantTriggeredAbility extends TriggeredAbilityImpl {
FlamescrollCelebrantTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(1), true, "that player", true));
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(1), true, "that player"));
}
private FlamescrollCelebrantTriggeredAbility(final FlamescrollCelebrantTriggeredAbility ability) {

View file

@ -1,10 +1,9 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.DealsCombatDamageTriggeredAbility;
import mage.abilities.condition.common.ManaWasSpentCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
@ -13,15 +12,11 @@ import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.DamagedEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author LevelX2
@ -36,7 +31,10 @@ public final class FlashConscription extends CardImpl {
this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("That creature gains haste until end of turn"));
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new GainAbilityTargetEffect(new FlashConscriptionTriggeredAbility(), Duration.EndOfTurn),
new GainAbilityTargetEffect(
new DealsCombatDamageTriggeredAbility(new GainLifeEffect(SavedDamageValue.MUCH), false),
Duration.EndOfTurn
),
ManaWasSpentCondition.WHITE,
"If {W} was spent to cast this spell, the creature gains "
+ "\"Whenever this creature deals combat damage, you gain that much life\" until end of turn"
@ -54,43 +52,3 @@ public final class FlashConscription extends CardImpl {
return new FlashConscription(this);
}
}
class FlashConscriptionTriggeredAbility extends TriggeredAbilityImpl {
public FlashConscriptionTriggeredAbility() {
super(Zone.BATTLEFIELD, null);
}
private FlashConscriptionTriggeredAbility(final FlashConscriptionTriggeredAbility ability) {
super(ability);
}
@Override
public FlashConscriptionTriggeredAbility copy() {
return new FlashConscriptionTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PERMANENT
|| event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
DamagedEvent damageEvent = (DamagedEvent) event;
if (damageEvent.isCombatDamage()) {
if (event.getSourceId().equals(this.sourceId)) {
this.getEffects().clear();
this.getEffects().add(new GainLifeEffect(damageEvent.getAmount()));
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever {this} deals combat damage, you gain that much life.";
}
}

View file

@ -1,22 +1,20 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author anonymous
* @author xenohedron
*/
public final class ForgeDevil extends CardImpl {
@ -28,13 +26,8 @@ public final class ForgeDevil extends CardImpl {
this.toughness = new MageInt(1);
// When Forge Devil enters the battlefield, it deals 1 damage to target creature and 1 damage to you.
Effect effect = new DamageTargetEffect(1);
effect.setText("it deals 1 damage to target creature");
Ability ability = new EntersBattlefieldTriggeredAbility(effect);
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetAndYouEffect(1));
ability.addTarget(new TargetCreaturePermanent());
effect = new DamageControllerEffect(1);
effect.setText("and 1 damage to you");
ability.addEffect(effect);
this.addAbility(ability);
}

View file

@ -4,8 +4,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -26,8 +25,9 @@ public final class GoblinArtillery extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(3);
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new TapSourceCost());
ability.addEffect(new DamageControllerEffect(3).setText("and 3 damage to you"));
// {T}: This creature deals 2 damage to any target and 3 damage to you.
Ability ability = new SimpleActivatedAbility(new DamageTargetAndYouEffect(2, 3), new TapSourceCost());
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -1,25 +1,23 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.constants.SubType;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author fireshoes
@ -34,9 +32,8 @@ public final class GrangerGuildmage extends CardImpl {
this.toughness = new MageInt(1);
// {R}, {tap}: Granger Guildmage deals 1 damage to any target and 1 damage to you.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new ManaCostsImpl<>("{R}"));
Ability ability = new SimpleActivatedAbility(new DamageTargetAndYouEffect(1, 1), new ManaCostsImpl<>("{R}"));
ability.addCost(new TapSourceCost());
ability.addEffect(new DamageControllerEffect(1).setText("and 1 damage to you"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);

View file

@ -1,14 +1,18 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllEffect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.filter.common.FilterAttackingCreature;
import mage.game.Game;
import java.util.UUID;
/**
*
@ -20,9 +24,7 @@ public final class HailStorm extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}{G}");
// Hail Storm deals 2 damage to each attacking creature and 1 damage to you and each creature you control.
this.getSpellAbility().addEffect(new DamageAllEffect(2, new FilterAttackingCreature()));
this.getSpellAbility().addEffect(new DamageControllerEffect(1).setText("and 1 damage to you"));
this.getSpellAbility().addEffect(new DamageAllEffect(1, StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED).setText("and each creature you control."));
this.getSpellAbility().addEffect(new HailStormEffect());
}
private HailStorm(final HailStorm card) {
@ -34,3 +36,32 @@ public final class HailStorm extends CardImpl {
return new HailStorm(this);
}
}
// needed for simultaneous damage
class HailStormEffect extends OneShotEffect {
private static final FilterAttackingCreature filter = new FilterAttackingCreature();
HailStormEffect() {
super(Outcome.Benefit);
staticText = "{this} deals 2 damage to each attacking creature " +
"and 1 damage to you and each creature you control";
}
private HailStormEffect(final HailStormEffect effect) {
super(effect);
}
@Override
public HailStormEffect copy() {
return new HailStormEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
new DamageAllEffect(2, filter).apply(game, source);
new DamageControllerEffect(1).apply(game, source);
new DamageAllEffect(1, StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED).apply(game, source);
return true;
}
}

View file

@ -48,7 +48,7 @@ public final class HarshMentor extends CardImpl {
class HarshMentorTriggeredAbility extends TriggeredAbilityImpl {
HarshMentorTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(2), true, "that player", true));
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(2), true, "that player"));
}
private HarshMentorTriggeredAbility(final HarshMentorTriggeredAbility ability) {

View file

@ -1,14 +1,9 @@
package mage.cards.h;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
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 mage.target.common.TargetPlayerOrPlaneswalker;
@ -22,10 +17,10 @@ public final class HungryFlames extends CardImpl {
public HungryFlames(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}");
// Hungry Flames deals 3 damage to target creature and 2 damage to target player.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
this.getSpellAbility().addEffect(new HungryFlamesEffect());
// Hungry Flames deals 3 damage to target creature and 2 damage to target player or planeswalker.
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker().setTargetTag(2));
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(3, 2));
}
private HungryFlames(final HungryFlames card) {
@ -37,37 +32,4 @@ public final class HungryFlames extends CardImpl {
return new HungryFlames(this);
}
private static class HungryFlamesEffect extends OneShotEffect {
HungryFlamesEffect() {
super(Outcome.Damage);
this.staticText = "{this} deals 3 damage to target creature and 2 damage to target player or planeswalker";
}
private HungryFlamesEffect(final HungryFlamesEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getTargets().get(0).getFirstTarget());
Player player = game.getPlayer(source.getTargets().get(1).getFirstTarget());
if (permanent != null) {
permanent.damage(3, source.getSourceId(), source, game, false, true);
}
if (player != null) {
player.damage(2, source.getSourceId(), source, game);
}
return true;
}
@Override
public HungryFlamesEffect copy() {
return new HungryFlamesEffect(this);
}
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.i;
import java.util.HashMap;
@ -50,8 +49,8 @@ public final class IchneumonDruid extends CardImpl {
class IchneumonDruidAbility extends TriggeredAbilityImpl {
public IchneumonDruidAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(4), false, "that player", true));
IchneumonDruidAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(4), false, "that player"));
}
private IchneumonDruidAbility(final IchneumonDruidAbility ability) {
@ -95,7 +94,7 @@ class IchneumonDruidWatcher extends Watcher {
private final Map<UUID, Integer> playerInstantCount = new HashMap<>();
public IchneumonDruidWatcher() {
IchneumonDruidWatcher() {
super(WatcherScope.GAME);
}

View file

@ -67,7 +67,7 @@ public final class ImmolationShaman extends CardImpl {
class ImmolationShamanTriggeredAbility extends TriggeredAbilityImpl {
ImmolationShamanTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(1), true, "that player", true));
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(1), true, "that player"));
setTriggerPhrase("Whenever an opponent activates an ability of an artifact, creature, or land that isn't a mana ability, ");
}

View file

@ -1,8 +1,8 @@
package mage.cards.i;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.abilities.effects.common.continuous.DamageCantBePreventedEffect;
import mage.abilities.keyword.AftermathAbility;
import mage.cards.CardSetInfo;
@ -13,8 +13,6 @@ import mage.constants.Outcome;
import mage.constants.SpellAbilityType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlayerOrPlaneswalker;
import mage.util.CardUtil;
@ -39,9 +37,9 @@ public final class InsultInjury extends SplitCard {
// Injury
// Injury deals 2 damage to target creature and 2 damage to target player.
getRightHalfCard().addAbility(new AftermathAbility().setRuleAtTheTop(true));
getRightHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
getRightHalfCard().getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
getRightHalfCard().getSpellAbility().addEffect(new InjuryEffect());
getRightHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
getRightHalfCard().getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker().setTargetTag(2));
getRightHalfCard().getSpellAbility().addEffect(new DamageTargetAndTargetEffect(2, 2));
}
private InsultInjury(final InsultInjury card) {
@ -87,36 +85,3 @@ class InsultDoubleDamageEffect extends ReplacementEffectImpl {
return false;
}
}
class InjuryEffect extends OneShotEffect {
InjuryEffect() {
super(Outcome.Damage);
this.staticText = "{this} deals 2 damage to target creature and 2 damage to target player or planeswalker";
}
private InjuryEffect(final InjuryEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getTargets().get(0).getFirstTarget());
Player player = game.getPlayer(source.getTargets().get(1).getFirstTarget());
if (permanent != null) {
permanent.damage(2, source.getSourceId(), source, game, false, true);
}
if (player != null) {
player.damage(2, source.getSourceId(), source, game);
}
return true;
}
@Override
public InjuryEffect copy() {
return new InjuryEffect(this);
}
}

View file

@ -3,7 +3,7 @@ package mage.cards.i;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SiegeAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -14,7 +14,6 @@ import mage.filter.common.FilterPermanentOrPlayer;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPermanentOrPlayer;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
@ -43,19 +42,9 @@ public final class InvasionOfRegatha extends CardImpl {
this.addAbility(new SiegeAbility());
// When Invasion of Regatha enters the battlefield, it deals 4 damage to another target battle or opponent and 1 damage to up to one target creature.
Ability ability = new EntersBattlefieldTriggeredAbility(
new DamageTargetEffect(
4, true,
"another target battle or opponent", "it"
).setUseOnlyTargetPointer(true)
);
ability.addTarget(new TargetPermanentOrPlayer(filter));
ability.addEffect(new DamageTargetEffect(1)
.setUseOnlyTargetPointer(true)
.setTargetPointer(new SecondTargetPointer())
.setText("and 1 damage to up to one target creature"));
ability.addTarget(new TargetCreaturePermanent(0, 1));
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetAndTargetEffect(4, 1));
ability.addTarget(new TargetPermanentOrPlayer(filter).setTargetTag(1));
ability.addTarget(new TargetCreaturePermanent(0, 1).setTargetTag(2));
this.addAbility(ability);
}

View file

@ -23,7 +23,7 @@ public final class JeskaiRevelation extends CardImpl {
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetSpellOrPermanent());
this.getSpellAbility().addEffect(new DamageTargetEffect(
4, true, "any target", true
4, true, "any target"
).setTargetPointer(new SecondTargetPointer()));
this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addEffect(new CreateTokenEffect(new MonasteryMentorToken(), 2));

View file

@ -1,16 +1,19 @@
package mage.cards.j;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
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.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -20,16 +23,14 @@ import java.util.UUID;
*/
public final class JudgmentBolt extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.EQUIPMENT));
static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.EQUIPMENT));
private static final Hint hint = new ValueHint("Equipment you control", xValue);
public JudgmentBolt(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}");
// Judgment Bolt deals 5 damage to target creature and X damage to that creature's controller, where X is the number of Equipment you control.
this.getSpellAbility().addEffect(new DamageTargetEffect(5));
this.getSpellAbility().addEffect(new DamageTargetControllerEffect(xValue)
.setText("and X damage to that creature's controller, where X is the number of Equipment you control"));
this.getSpellAbility().addEffect(new JudgmentBoltEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addHint(hint);
}
@ -43,3 +44,28 @@ public final class JudgmentBolt extends CardImpl {
return new JudgmentBolt(this);
}
}
// too lazy to handle dynamic value properly in the common class
class JudgmentBoltEffect extends OneShotEffect {
JudgmentBoltEffect() {
super(Outcome.Benefit);
staticText = "{this} deals 5 damage to target creature and X damage to that creature's controller," +
" where X is the number of Equipment you control";
}
private JudgmentBoltEffect(final JudgmentBoltEffect effect) {
super(effect);
}
@Override
public JudgmentBoltEffect copy() {
return new JudgmentBoltEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return new DamageTargetAndTargetControllerEffect(5, JudgmentBolt.xValue.calculate(game, source, this))
.apply(game, source);
}
}

View file

@ -2,7 +2,7 @@ package mage.cards.k;
import mage.abilities.condition.common.ThresholdCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -21,15 +21,16 @@ public final class KamahlsSledge extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{R}{R}");
// Kamahl's Sledge deals 4 damage to target creature.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Threshold - If seven or more cards are in your graveyard, instead Kamahl's Sledge deals 4 damage to that creature and 4 damage to that creature's controller.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DamageTargetControllerEffect(4), ThresholdCondition.instance, "<br>" +
AbilityWord.THRESHOLD.formatWord() + "If seven or more cards are in your graveyard, " +
"instead {this} deals 4 damage to that creature and 4 damage to that creature's controller."
new DamageTargetAndTargetControllerEffect(4, 4),
new DamageTargetEffect(4),
ThresholdCondition.instance,
"{this} deals 4 damage to target creature. <br>" +
AbilityWord.THRESHOLD.formatWord() + "If seven or more cards are in your graveyard, " +
"instead {this} deals 4 damage to that creature and 4 damage to that creature's controller."
));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
private KamahlsSledge(final KamahlsSledge card) {

View file

@ -1,15 +1,13 @@
package mage.cards.l;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlayerOrPlaneswalker;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
/**
*
@ -21,14 +19,10 @@ public final class Lunge extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}");
// Lunge deals 2 damage to target creature and 2 damage to target player.
this.getSpellAbility().addEffect(new DamageTargetEffect(2).setUseOnlyTargetPointer(true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(2, 2));
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker().setTargetTag(2));
Effect effect = new DamageTargetEffect(2).setUseOnlyTargetPointer(true);
effect.setTargetPointer(new SecondTargetPointer());
effect.setText("and 2 damage to target player or planeswalker");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
}
private Lunge(final Lunge card) {

View file

@ -1,11 +1,9 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
@ -37,7 +35,7 @@ public final class ManticoreOfTheGauntlet extends CardImpl {
counters.setText("put a -1/-1 counter on target creature you control");
counters.setTargetPointer(new FirstTargetPointer());
Effect damage = new DamageTargetEffect(StaticValue.get(3), true, "", true);
Effect damage = new DamageTargetEffect(3);
damage.setText("{this} deals 3 damage to target opponent or planeswalker.");
damage.setTargetPointer(new SecondTargetPointer());

View file

@ -1,10 +1,9 @@
package mage.cards.n;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.abilities.hint.ConditionHint;
@ -12,13 +11,9 @@ import mage.abilities.hint.Hint;
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.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -42,7 +37,8 @@ public final class NeonatesRush extends CardImpl {
).addHint(hint).setRuleAtTheTop(true));
// Neonate's Rush deals 1 damage to target creature and 1 damage to its controller. Draw a card.
this.getSpellAbility().addEffect(new NeonatesRushEffect());
this.getSpellAbility().addEffect(new DamageTargetAndTargetControllerEffect(1, 1)
.setText("{this} deals 1 damage to target creature and 1 damage to its controller"));
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
@ -56,34 +52,3 @@ public final class NeonatesRush extends CardImpl {
return new NeonatesRush(this);
}
}
class NeonatesRushEffect extends OneShotEffect {
NeonatesRushEffect() {
super(Outcome.Benefit);
staticText = "{this} deals 1 damage to target creature and 1 damage to its controller.";
}
private NeonatesRushEffect(final NeonatesRushEffect effect) {
super(effect);
}
@Override
public NeonatesRushEffect copy() {
return new NeonatesRushEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent == null) {
return false;
}
permanent.damage(1, source.getSourceId(), source, game);
Player player = game.getPlayer(permanent.getControllerId());
if (player != null) {
player.damage(1, source.getSourceId(), source, game);
}
return true;
}
}

View file

@ -52,7 +52,6 @@ public final class NivMizzetGuildpact extends CardImpl {
// Whenever Niv-Mizzet, Guildpact deals combat damage to a player, it deals X damage to any target, target player draws X cards, and you gain X life, where X is the number of different color pairs among permanents you control that are exactly two colors.
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(
new DamageTargetEffect(NivMizzetGuildpactCount.instance)
.setUseOnlyTargetPointer(true)
.setText("it deals X damage to any target"), false);
ability.addTarget(new TargetAnyTarget());
ability.addEffect(new DrawCardTargetEffect(NivMizzetGuildpactCount.instance)

View file

@ -1,20 +1,18 @@
package mage.cards.o;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author Plopman
@ -30,9 +28,8 @@ public final class OrcishArtillery extends CardImpl {
this.toughness = new MageInt(3);
// {tap}: Orcish Artillery deals 2 damage to any target and 3 damage to you.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new TapSourceCost());
Ability ability = new SimpleActivatedAbility(new DamageTargetAndYouEffect(2, 3), new TapSourceCost());
ability.addTarget(new TargetAnyTarget());
ability.addEffect(new DamageControllerEffect(3).setText("and 3 damage to you"));
this.addAbility(ability);
}

View file

@ -1,16 +1,14 @@
package mage.cards.o;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author LevelX2
@ -21,11 +19,9 @@ public final class OrcishCannonade extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}{R}");
// Orcish Cannonade deals 2 damage to any target and 3 damage to you.
this.getSpellAbility().addEffect(new DamageTargetEffect(2));
this.getSpellAbility().addEffect(new DamageTargetAndYouEffect(2, 3));
this.getSpellAbility().addTarget(new TargetAnyTarget());
Effect effect = new DamageControllerEffect(3);
effect.setText("and 3 damage to you");
this.getSpellAbility().addEffect(effect);
// Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("<br>"));
}

View file

@ -1,21 +1,18 @@
package mage.cards.o;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author LoneFox
@ -31,10 +28,8 @@ public final class OrcishCannoneers extends CardImpl {
this.toughness = new MageInt(3);
// {tap}: Orcish Cannoneers deals 2 damage to any target and 3 damage to you.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new TapSourceCost()); ability.addTarget(new TargetAnyTarget());
Effect effect = new DamageControllerEffect(3);
effect.setText("and 3 damage to you");
ability.addEffect(effect);
Ability ability = new SimpleActivatedAbility(new DamageTargetAndYouEffect(2, 3), new TapSourceCost());
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -1,7 +1,6 @@
package mage.cards.p;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -18,8 +17,7 @@ public final class PsionicBlast extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}");
// Psionic Blast deals 4 damage to any target and 2 damage to you.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addEffect(new DamageControllerEffect(2).setText("and 2 damage to you"));
this.getSpellAbility().addEffect(new DamageTargetAndYouEffect(4, 2));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}

View file

@ -1,20 +1,18 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageSelfEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.constants.SubType;
import mage.abilities.effects.common.DamageTargetAndSelfEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.constants.SubType;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author TheElk801
@ -29,8 +27,7 @@ public final class PsionicEntity extends CardImpl {
this.toughness = new MageInt(2);
// {tap}: Psionic Entity deals 2 damage to any target and 3 damage to itself.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new TapSourceCost());
ability.addEffect(new DamageSelfEffect(3).setText("and 3 damage to itself"));
Ability ability = new SimpleActivatedAbility(new DamageTargetAndSelfEffect(2, 3), new TapSourceCost());
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -1,28 +1,24 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageSelfEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndSelfEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author anonymous
* @see mage.sets.seventhedition.RecklessEmbermage
* @author xenohedron
*/
public final class PsionicSliver extends CardImpl {
@ -35,11 +31,7 @@ public final class PsionicSliver extends CardImpl {
this.toughness = new MageInt(2);
// All Sliver creatures have "{T}: This creature deals 2 damage to any target and 3 damage to itself."
Ability ability = new SimpleActivatedAbility(
new DamageTargetEffect(2).setText("This creature deals 2 damage to any target"),
new TapSourceCost()
);
ability.addEffect(new DamageSelfEffect(3).setText("3 damage to itself."));
Ability ability = new SimpleActivatedAbility(new DamageTargetAndSelfEffect(2, 3), new TapSourceCost());
ability.addTarget(new TargetAnyTarget());
this.addAbility(
new SimpleStaticAbility(new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, filter,

View file

@ -1,15 +1,14 @@
package mage.cards.p;
import java.util.UUID;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.Target;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlayerOrPlaneswalker;
import java.util.UUID;
/**
*
* @author LevelX2
@ -20,11 +19,9 @@ public final class PunishTheEnemy extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
// Punish the Enemy deals 3 damage to target player and 3 damage to target creature.
this.getSpellAbility().addEffect(new DamageTargetEffect(3, true, "target player or planeswalker and 3 damage to target creature"));
Target target = new TargetPlayerOrPlaneswalker();
this.getSpellAbility().addTarget(target);
target = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(target);
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(3, 3));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(2));
}
private PunishTheEnemy(final PunishTheEnemy card) {

View file

@ -1,12 +1,10 @@
package mage.cards.r;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndAllControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.StaticFilters;
import mage.target.TargetPlayer;
import java.util.UUID;
@ -20,10 +18,9 @@ public final class RadiatingLightning extends CardImpl {
public RadiatingLightning(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R}");
// Radiating Lightning deals 3 damage to target player and 1 damage to each creature that player controls.
this.getSpellAbility().addEffect(new DamageTargetEffect(3));
this.getSpellAbility().addEffect(new DamageAllControlledTargetEffect(1, new FilterCreaturePermanent()).setText("and 1 damage to each creature that player controls"));
this.getSpellAbility().addEffect(new DamageTargetAndAllControlledEffect(
3, 1, StaticFilters.FILTER_PERMANENT_CREATURE));
this.getSpellAbility().addTarget(new TargetPlayer());
}

View file

@ -3,8 +3,7 @@ package mage.cards.r;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -29,11 +28,9 @@ public final class RakdosFirewheeler extends CardImpl {
this.toughness = new MageInt(3);
// When Rakdos Firewheeler enters the battlefield, it deals 2 damage to target opponent and 2 damage to up to one target creature or planeswalker.
Effect effect = new DamageTargetEffect(2);
effect.setText("it deals 2 damage to target opponent and 2 damage to up to one target creature or planeswalker");
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
ability.addTarget(new TargetOpponent());
ability.addTarget(new TargetCreatureOrPlaneswalker(0, 1));
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetAndTargetEffect(2, 2));
ability.addTarget(new TargetOpponent().setTargetTag(1));
ability.addTarget(new TargetCreatureOrPlaneswalker(0, 1).setTargetTag(2));
this.addAbility(ability);
}

View file

@ -1,20 +1,18 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamageSelfEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndSelfEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author Quercitron
@ -30,8 +28,7 @@ public final class RecklessEmbermage extends CardImpl {
this.toughness = new MageInt(2);
// {1}{R}: Reckless Embermage deals 1 damage to any target and 1 damage to itself.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new ManaCostsImpl<>("{1}{R}"));
ability.addEffect(new DamageSelfEffect(1).setText("and 1 damage to itself"));
Ability ability = new SimpleActivatedAbility(new DamageTargetAndSelfEffect(1), new ManaCostsImpl<>("{1}{R}"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -1,19 +1,15 @@
package mage.cards.r;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
import static mage.filter.StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL;
/**
* @author JayDi85
*/
@ -23,12 +19,9 @@ public final class RecklessRage extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
// Reckless Rage deals 4 damage to target creature you don't control and 2 damage to target creature you control.
this.getSpellAbility().addTarget(new TargetPermanent(FILTER_CREATURE_YOU_DONT_CONTROL));
this.getSpellAbility().addEffect(new DamageTargetEffect(4).setUseOnlyTargetPointer(true));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addEffect(new DamageTargetEffect(2).setUseOnlyTargetPointer(true)
.setText("and 2 damage to target creature you control")
.setTargetPointer(new SecondTargetPointer()));
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(4, 2));
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL).setTargetTag(1));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent().setTargetTag(2));
}
private RecklessRage(final RecklessRage card) {

View file

@ -28,8 +28,8 @@ public final class SeismicWave extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}");
// Seismic Wave deals 2 damage to any target and 1 damage to each nonartifact creature target opponent controls.
this.getSpellAbility().addTarget(new TargetAnyTarget().withChooseHint("2 damage"));
this.getSpellAbility().addTarget(new TargetOpponent().withChooseHint("1 damage to each nonartifact creature target opponent controls"));
this.getSpellAbility().addTarget(new TargetAnyTarget().withChooseHint("to deal 2 damage"));
this.getSpellAbility().addTarget(new TargetOpponent().withChooseHint("1 damage to each nonartifact creature they control"));
this.getSpellAbility().addEffect(new SeismicWaveEffect());
}
@ -51,7 +51,7 @@ class SeismicWaveEffect extends OneShotEffect {
filter.add(Predicates.not(CardType.ARTIFACT.getPredicate()));
}
public SeismicWaveEffect() {
SeismicWaveEffect() {
super(Outcome.Damage);
this.staticText = "{this} deals 2 damage to any target and 1 damage to each nonartifact creature target opponent controls";
}

View file

@ -89,7 +89,7 @@ class SelfDestructEffect extends OneShotEffect {
if (player != null) {
player.damage(power, creature.getId(), source, game);
}
permanent.damage(power, permanent.getId(), source, game);
creature.damage(power, creature.getId(), source, game);
return true;
}
}

View file

@ -1,21 +1,20 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
*
@ -37,9 +36,8 @@ public final class ShadowGuildmage extends CardImpl {
this.addAbility(ability);
// {R}, {tap}: Shadow Guildmage deals 1 damage to any target and 1 damage to you.
ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new ManaCostsImpl<>("{R}"));
ability = new SimpleActivatedAbility(new DamageTargetAndYouEffect(1, 1), new ManaCostsImpl<>("{R}"));
ability.addCost(new TapSourceCost());
ability.addEffect(new DamageControllerEffect(1).setText("and 1 damage to you"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -6,8 +6,7 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
@ -42,8 +41,7 @@ public final class ShockerUnshakable extends CardImpl {
)));
// Vibro-Shock Gauntlets -- When Shocker enters, he deals 2 damage to target creature and 2 damage to that creature's controller.
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2, "he"));
ability.addEffect(new DamageTargetControllerEffect(2).setText("and 2 damage to that creature's controller"));
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetAndTargetControllerEffect(2, 2));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability.withFlavorWord("Vibro-Shock Gauntlets"));
}

View file

@ -1,13 +1,14 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlayerOrPlaneswalker;
import java.util.UUID;
/**
*
* @author LevelX2
@ -17,10 +18,10 @@ public final class ShowerOfSparks extends CardImpl {
public ShowerOfSparks(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
// Shower of sparks deals 1 damage to target creature and 1 damage to target player.
this.getSpellAbility().addEffect(new DamageTargetEffect(1, true, "target creature and 1 damage to target player or planeswalker"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
// Shower of Sparks deals 1 damage to target creature and 1 damage to target player or planeswalker.
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(1, 1));
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker().setTargetTag(2));
}
private ShowerOfSparks(final ShowerOfSparks card) {

View file

@ -1,4 +1,3 @@
package mage.cards.s;
import java.util.UUID;
@ -27,7 +26,7 @@ public final class Simulacrum extends CardImpl {
// You gain life equal to the damage dealt to you this turn. Simulacrum deals damage to target creature you control equal to the damage dealt to you this turn.
this.getSpellAbility().addEffect(new GainLifeEffect(new SimulacrumAmount(), "You gain life equal to the damage dealt to you this turn."));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
Effect effect = new DamageTargetEffect(new SimulacrumAmount(), true, "target creature you control", true);
Effect effect = new DamageTargetEffect(new SimulacrumAmount(), true, "target creature you control");
effect.setText(" {this} deals damage to target creature you control equal to the damage dealt to you this turn.");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addWatcher(new AmountOfDamageAPlayerReceivedThisTurnWatcher());

View file

@ -1,4 +1,3 @@
package mage.cards.s;
import mage.MageInt;
@ -93,7 +92,7 @@ class SoulOfShandalarEffect extends OneShotEffect {
class SoulOfShandalarTarget extends TargetPermanent {
public SoulOfShandalarTarget() {
SoulOfShandalarTarget() {
super(0, 1, new FilterCreaturePermanent("creature that the targeted player or planeswalker's controller controls"));
}

View file

@ -1,35 +1,30 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
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.game.Game;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author Plopman
*/
public final class Sparksmith extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("Goblins on the battlefield");
static {
filter.add(SubType.GOBLIN.getPredicate());
}
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
public Sparksmith(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}");
this.subtype.add(SubType.GOBLIN);
@ -38,11 +33,8 @@ public final class Sparksmith extends CardImpl {
this.toughness = new MageInt(1);
// {tap}: Sparksmith deals X damage to target creature and X damage to you, where X is the number of Goblins on the battlefield.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(xValue)
.setText("{this} deals X damage to target creature"), new TapSourceCost());
Ability ability = new SimpleActivatedAbility(new SparksmithEffect(), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
ability.addEffect(new DamageControllerEffect(xValue)
.setText("and X damage to you, where X is the number of Goblins on the battlefield"));
this.addAbility(ability);
}
@ -55,3 +47,35 @@ public final class Sparksmith extends CardImpl {
return new Sparksmith(this);
}
}
// too lazy to handle dynamic value properly in the common class
class SparksmithEffect extends OneShotEffect {
private static final FilterPermanent filter = new FilterPermanent("Goblins on the battlefield");
static {
filter.add(SubType.GOBLIN.getPredicate());
}
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
SparksmithEffect() {
super(Outcome.Benefit);
staticText = "{this} deals X damage to target creature and X damage to you, " +
"where X is the number of Goblins on the battlefield";
}
private SparksmithEffect(final SparksmithEffect effect) {
super(effect);
}
@Override
public SparksmithEffect copy() {
return new SparksmithEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
int amount = xValue.calculate(game, source, this);
return new DamageTargetAndYouEffect(amount, amount).apply(game, source);
}
}

View file

@ -62,8 +62,7 @@ class SpiritualizeTriggeredAbility extends DelayedTriggeredAbility {
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER
|| event.getType() == GameEvent.EventType.DAMAGED_PERMANENT;
return event.getType() == GameEvent.EventType.DAMAGED_BATCH_BY_SOURCE;
}
@Override

View file

@ -1,26 +1,24 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageSelfEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndSelfEffect;
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.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author jeffwadsworth
@ -60,7 +58,7 @@ class SunflareShamanEffect extends OneShotEffect {
filter.add(SubType.ELEMENTAL.getPredicate());
}
public SunflareShamanEffect() {
SunflareShamanEffect() {
super(Outcome.Damage);
this.staticText = "{this} deals X damage to any target and X damage to itself, where X is the number of Elemental cards in your graveyard";
}
@ -78,9 +76,8 @@ class SunflareShamanEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
int ElementalsInYourGraveyard = controller.getGraveyard().count(filter, game);
new DamageTargetEffect(ElementalsInYourGraveyard).apply(game, source);
new DamageSelfEffect(ElementalsInYourGraveyard).apply(game, source);
int amount = controller.getGraveyard().count(filter, game);
new DamageTargetAndSelfEffect(amount, amount).apply(game, source);
return true;
}
return false;

View file

@ -3,15 +3,13 @@ package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.PartyCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.abilities.hint.common.PartyCountHint;
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;
@ -25,7 +23,6 @@ public final class SynchronizedSpellcraft extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
// Synchronized Spellcraft deals 4 damage to target creature and X damage to that creature's controller, where X is the number of creatures in your party.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addEffect(new SynchronizedSpellcraftEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addHint(PartyCountHint.instance);
@ -45,7 +42,8 @@ class SynchronizedSpellcraftEffect extends OneShotEffect {
SynchronizedSpellcraftEffect() {
super(Outcome.Benefit);
staticText = "and X damage to that creature's controller, " +
staticText = "{this} deals 4 damage to target creature " +
"and X damage to that creature's controller, " +
"where X is the number of creatures in your party. " + PartyCount.getReminder();
}
@ -60,18 +58,7 @@ class SynchronizedSpellcraftEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int partyCount = PartyCount.instance.calculate(game, source, this);
if (partyCount < 1) {
return false;
}
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget());
if (permanent == null) {
return false;
}
Player player = game.getPlayer(permanent.getControllerId());
if (player == null) {
return false;
}
return player.damage(partyCount, source.getSourceId(), source, game) > 0;
int amount = PartyCount.instance.calculate(game, source, this);
return new DamageTargetAndTargetControllerEffect(4, amount).apply(game, source);
}
}

View file

@ -2,8 +2,7 @@ package mage.cards.t;
import mage.MageItem;
import mage.abilities.Ability;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndAllControlledEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -32,12 +31,9 @@ public final class TheFallOfKroog extends CardImpl {
this.getSpellAbility().addEffect(new DestroyTargetEffect()
.setText("choose target opponent. Destroy target land that player controls")
.setTargetPointer(new SecondTargetPointer()));
this.getSpellAbility().addEffect(new DamageTargetEffect(
3, true, "that player"
));
this.getSpellAbility().addEffect(new DamageAllControlledTargetEffect(
1, StaticFilters.FILTER_PERMANENT_CREATURE
).setText("and 1 damage to each creature they control"));
this.getSpellAbility().addEffect(new DamageTargetAndAllControlledEffect(
3, 1, StaticFilters.FILTER_PERMANENT_CREATURE
).setText("{this} deals 3 damage to that player and 1 damage to each creature they control"));
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addTarget(new TheFallOfKroogTarget());
}

View file

@ -1,6 +1,6 @@
package mage.cards.t;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -9,7 +9,6 @@ import mage.filter.predicate.other.AnotherTargetPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
@ -31,12 +30,7 @@ public final class TrickShot extends CardImpl {
// Trick Shot deals 6 damage to target creature and 2 damage to up to one other target creature token.
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPermanent(0, 1, filter).setTargetTag(2));
this.getSpellAbility().addEffect(new DamageTargetEffect(6, true, "", true));
this.getSpellAbility().addEffect(
new DamageTargetEffect(2, true, "", true)
.setTargetPointer(new SecondTargetPointer())
.setText("and 2 damage to up to one other target creature token")
);
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(6, 2));
}
private TrickShot(final TrickShot card) {

View file

@ -1,14 +1,13 @@
package mage.cards.u;
import java.util.UUID;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreatureOrPlaneswalker;
import java.util.UUID;
/**
*
* @author weirddan455
@ -19,9 +18,8 @@ public final class UnleashShell extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}{R}");
// Unleash Shell deals 5 damage to target creature or planeswalker and 2 damage to that permanent's controller.
this.getSpellAbility().addEffect(new DamageTargetEffect(5));
this.getSpellAbility().addEffect(new DamageTargetControllerEffect(2).setText("and 2 damage to that permanent's controller"));
this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
this.getSpellAbility().addEffect(new DamageTargetAndTargetControllerEffect(5, 2));
}
private UnleashShell(final UnleashShell card) {

View file

@ -33,6 +33,8 @@ public final class WildfireHowl extends CardImpl {
GiftWasPromisedCondition.TRUE, "{this} deals 2 damage to each creature. " +
"If the gift was promised, instead {this} deals 1 damage to any target and 2 damage to each creature"
).addEffect(new DamageAllEffect(2, StaticFilters.FILTER_PERMANENT_CREATURE)));
// ConditionalOneShotEffect doesn't call processAction between effects, so currently works
// if that gets changed (which it perhaps should?) then need to make this a single effect
this.getSpellAbility().setTargetAdjuster(new ConditionalTargetAdjuster(
GiftWasPromisedCondition.TRUE, new TargetAnyTarget()
));

View file

@ -0,0 +1,191 @@
package org.mage.test.cards.triggers.damage;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author xenohedron
*/
public class DamageMultiLifelinkTriggerTest extends CardTestPlayerBase {
private static final String hatchling = "Kraken Hatchling"; // 0/4
private static final String wishcoin = "Wishcoin Crab"; // 2/5
private static final String devil = "Forge Devil"; // 1/1
// ETB 1 dmg to any target and 1 dmg to you
private static final String embermage = "Reckless Embermage"; // 2/2
// 1R: 1 dmg to any target and 1 dmg to itself
private static final String arc = "Arc Trail";
// Arc Trail deals 2 damage to any target and 1 damage to another target.
private static final String cone = "Cone of Flame";
// Cone of Flame deals 1 damage to any target, 2 damage to another target, and 3 damage to a third target.
private static final String chaar = "Char";
// Char deals 4 damage to any target and 2 damage to you.
private static final String outrage = "Chandra's Outrage";
// Chandra's Outrage deals 4 damage to target creature and 2 damage to that creature's controller.
private static final String fury = "Chandra's Fury";
// Chandra's Fury deals 4 damage to target player or planeswalker
// and 1 damage to each creature that player or that planeswalker's controller controls.
private static final String whip = "Whip of Erebos";
// Creatures you control have lifelink.
private static final String firesong = "Firesong and Sunspeaker";
// Red instant and sorcery spells you control have lifelink.
private static final String pridemate = "Ajani's Pridemate"; // 2/2
// Whenever you gain life, put a +1/+1 counter on this creature.
private void setupBattlefield() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
addCard(Zone.BATTLEFIELD, playerA, whip);
addCard(Zone.BATTLEFIELD, playerA, firesong);
addCard(Zone.BATTLEFIELD, playerA, pridemate);
addCard(Zone.BATTLEFIELD, playerA, hatchling);
addCard(Zone.BATTLEFIELD, playerB, wishcoin);
}
@Test
@Ignore
public void testCreatureDamageTargetAndYou() {
setupBattlefield();
addCard(Zone.HAND, playerA, devil);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, devil);
addTarget(playerA, wishcoin);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 - 1 + 2);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
@Ignore
public void testCreatureDamageTargetAndSelf() {
setupBattlefield();
addCard(Zone.BATTLEFIELD, playerA, embermage);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{R}: ");
addTarget(playerA, wishcoin);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 2);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 1);
assertDamageReceived(playerB, embermage, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
@Ignore
public void testSpellDamageTargetAndTarget() {
setupBattlefield();
addCard(Zone.HAND, playerA, arc);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arc);
addTarget(playerA, wishcoin);
addTarget(playerA, hatchling);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 3);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 2);
assertDamageReceived(playerA, hatchling, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
@Ignore
public void testSpellDamageThreeTargets() {
setupBattlefield();
addCard(Zone.HAND, playerA, cone);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cone);
addTarget(playerA, wishcoin);
addTarget(playerA, hatchling);
addTarget(playerA, firesong);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 6);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 3);
assertDamageReceived(playerA, hatchling, 2);
assertDamageReceived(playerA, firesong, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
@Ignore
public void testSpellDamageTargetAndYou() {
setupBattlefield();
addCard(Zone.HAND, playerA, chaar);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, chaar);
addTarget(playerA, wishcoin);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 - 2 + 6);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 4);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
@Ignore
public void testSpellDamageTargetAndController() {
setupBattlefield();
addCard(Zone.HAND, playerA, outrage);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, outrage);
addTarget(playerA, wishcoin);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 6);
assertLife(playerB, 20 - 2);
assertDamageReceived(playerB, wishcoin, 4);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
@Ignore
public void testSpellDamagePlayerAndControlled() {
setupBattlefield();
addCard(Zone.HAND, playerA, fury);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fury);
addTarget(playerA, playerB);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 5);
assertLife(playerB, 20 - 4);
assertDamageReceived(playerB, wishcoin, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
}

View file

@ -0,0 +1,188 @@
package org.mage.test.cards.triggers.damage;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author xenohedron
*/
public class DamageMultiTriggerTest extends CardTestPlayerBase {
private static final String hatchling = "Kraken Hatchling"; // 0/4
private static final String wishcoin = "Wishcoin Crab"; // 2/5
private static final String brothers = "Brothers of Fire"; // 2/2
// 1RR: 1 dmg to any target and 1 dmg to you
private static final String embermage = "Reckless Embermage"; // 2/2
// 1R: 1 dmg to any target and 1 dmg to itself
private static final String arc = "Arc Trail";
// Arc Trail deals 2 damage to any target and 1 damage to another target.
private static final String cone = "Cone of Flame";
// Cone of Flame deals 1 damage to any target, 2 damage to another target, and 3 damage to a third target.
private static final String chaar = "Char";
// Char deals 4 damage to any target and 2 damage to you.
private static final String outrage = "Chandra's Outrage";
// Chandra's Outrage deals 4 damage to target creature and 2 damage to that creature's controller.
private static final String fury = "Chandra's Fury";
// Chandra's Fury deals 4 damage to target player or planeswalker
// and 1 damage to each creature that player or that planeswalker's controller controls.
private static final String tamanoa = "Tamanoa"; // 2/4
// Whenever a noncreature source you control deals damage, you gain that much life.
private static final String spiritLink = "Spirit Link"; // 2/2
// Whenever enchanted creature deals damage, you gain that much life.
private static final String pridemate = "Ajani's Pridemate"; // 2/2
// Whenever you gain life, put a +1/+1 counter on this creature.
private void setupBattlefield() {
addCard(Zone.BATTLEFIELD, playerA, "Plateau", 5);
addCard(Zone.BATTLEFIELD, playerA, tamanoa);
addCard(Zone.HAND, playerA, spiritLink);
addCard(Zone.BATTLEFIELD, playerA, pridemate);
addCard(Zone.BATTLEFIELD, playerA, hatchling);
addCard(Zone.BATTLEFIELD, playerB, wishcoin);
}
@Test
public void testCreatureDamageTargetAndYou() {
setupBattlefield();
addCard(Zone.BATTLEFIELD, playerA, brothers);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, spiritLink, brothers);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{R}{R}: ");
addTarget(playerA, wishcoin);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 - 1 + 2);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
public void testCreatureDamageTargetAndSelf() {
setupBattlefield();
addCard(Zone.BATTLEFIELD, playerA, embermage);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, spiritLink, embermage);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{R}: ");
addTarget(playerA, wishcoin);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 2);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 1);
assertDamageReceived(playerA, embermage, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
public void testSpellDamageTargetAndTarget() {
setupBattlefield();
addCard(Zone.HAND, playerA, arc);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arc);
addTarget(playerA, wishcoin);
addTarget(playerA, hatchling);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 3);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 2);
assertDamageReceived(playerA, hatchling, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
public void testSpellDamageThreeTargets() {
setupBattlefield();
addCard(Zone.HAND, playerA, cone);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cone);
addTarget(playerA, wishcoin);
addTarget(playerA, hatchling);
addTarget(playerA, tamanoa);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 6);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 1);
assertDamageReceived(playerA, hatchling, 2);
assertDamageReceived(playerA, tamanoa, 3);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
public void testSpellDamageTargetAndYou() {
setupBattlefield();
addCard(Zone.HAND, playerA, chaar);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, chaar);
addTarget(playerA, wishcoin);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 - 2 + 6);
assertLife(playerB, 20);
assertDamageReceived(playerB, wishcoin, 4);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
public void testSpellDamageTargetAndController() {
setupBattlefield();
addCard(Zone.HAND, playerA, outrage);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, outrage);
addTarget(playerA, wishcoin);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 6);
assertLife(playerB, 20 - 2);
assertDamageReceived(playerB, wishcoin, 4);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
@Test
public void testSpellDamagePlayerAndControlled() {
setupBattlefield();
addCard(Zone.HAND, playerA, fury);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fury);
addTarget(playerA, playerB);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerA, 20 + 5);
assertLife(playerB, 20 - 4);
assertDamageReceived(playerB, wishcoin, 1);
assertCounterCount(pridemate, CounterType.P1P1, 1);
}
}

View file

@ -29,8 +29,7 @@ public class DealsDamageAttachedTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PERMANENT
|| event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
return event.getType() == GameEvent.EventType.DAMAGED_BATCH_BY_SOURCE;
}
@Override

View file

@ -0,0 +1,83 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
* @author xenohedron
*/
public class DamageTargetAndAllControlledEffect extends OneShotEffect {
private final int firstAmount;
private final int secondAmount;
private final FilterPermanent filter;
/**
* Deals simultaneous damage to the target and to each creature the target controls
*/
public DamageTargetAndAllControlledEffect(int amount) {
this(amount, amount, StaticFilters.FILTER_PERMANENT_CREATURE);
}
/**
* Deals simultaneous damage to the target and to each creature the target controls
*/
public DamageTargetAndAllControlledEffect(int firstAmount, int secondAmount, FilterPermanent filter) {
super(Outcome.Damage);
this.firstAmount = firstAmount;
this.secondAmount = secondAmount;
this.filter = filter;
}
protected DamageTargetAndAllControlledEffect(final DamageTargetAndAllControlledEffect effect) {
super(effect);
this.firstAmount = effect.firstAmount;
this.secondAmount = effect.secondAmount;
this.filter = effect.filter.copy();
}
@Override
public DamageTargetAndAllControlledEffect copy() {
return new DamageTargetAndAllControlledEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
permanent.damage(firstAmount, source.getSourceId(), source, game);
} else {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null) {
player.damage(firstAmount, source.getSourceId(), source, game);
}
}
Player controller = game.getPlayerOrPlaneswalkerController(getTargetPointer().getFirst(game, source));
if (controller != null) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
perm.damage(secondAmount, source.getSourceId(), source, game);
}
}
return true;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
String description = getTargetPointer().describeTargets(mode.getTargets(), "that player");
return "{this} deals " + firstAmount + "damage to " + description +
" and " + secondAmount + " damage to each " + filter.getMessage() +
" that player" +
(description.contains("planeswalker") ? " or that planeswalker's controller" : "") +
" controls";
}
}

View file

@ -0,0 +1,77 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
* @author xenohedron
*/
public class DamageTargetAndSelfEffect extends OneShotEffect {
private final int firstAmount;
private final int secondAmount;
/**
* Deals simultaneous damage to the target and to itself
*/
public DamageTargetAndSelfEffect(int amount) {
this(amount, amount);
}
/**
* Deals simultaneous damage to the target and to itself
*/
public DamageTargetAndSelfEffect(int firstAmount, int secondAmount) {
super(Outcome.Damage);
this.firstAmount = firstAmount;
this.secondAmount = secondAmount;
}
protected DamageTargetAndSelfEffect(final DamageTargetAndSelfEffect effect) {
super(effect);
this.firstAmount = effect.firstAmount;
this.secondAmount = effect.secondAmount;
}
@Override
public DamageTargetAndSelfEffect copy() {
return new DamageTargetAndSelfEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(firstAmount, source.getSourceId(), source, game);
} else {
Player player = game.getPlayer(targetId);
if (player != null) {
player.damage(firstAmount, source.getSourceId(), source, game);
}
}
}
Permanent itself = source.getSourcePermanentIfItStillExists(game);
if (itself != null) {
itself.damage(secondAmount, source.getSourceId(), source, game);
}
return true;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
return "{this} deals " + firstAmount + "damage to " +
getTargetPointer().describeTargets(mode.getTargets(), "that creature") +
" and " + secondAmount + "damage to itself";
}
}

View file

@ -0,0 +1,69 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
* @author xenohedron
*/
public class DamageTargetAndTargetControllerEffect extends OneShotEffect {
private final int firstAmount;
private final int secondAmount;
/**
* Deals simultaneous damage to the target and to the controller of the target
*/
public DamageTargetAndTargetControllerEffect(int firstAmount, int secondAmount) {
super(Outcome.Damage);
this.firstAmount = firstAmount;
this.secondAmount = secondAmount;
}
protected DamageTargetAndTargetControllerEffect(final DamageTargetAndTargetControllerEffect effect) {
super(effect);
this.firstAmount = effect.firstAmount;
this.secondAmount = effect.secondAmount;
}
@Override
public DamageTargetAndTargetControllerEffect copy() {
return new DamageTargetAndTargetControllerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(firstAmount, source.getSourceId(), source, game);
}
Permanent lki = game.getPermanentOrLKIBattlefield(targetId);
if (lki != null) {
Player player = game.getPlayer(lki.getControllerId());
if (player != null) {
player.damage(secondAmount, source.getSourceId(), source, game);
}
}
}
return true;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
String description = getTargetPointer().describeTargets(mode.getTargets(), "that creature");
return "{this} deals " + firstAmount + "damage to " + description +
" and " + secondAmount + "damage to that " +
(description.contains(" or ") ? "permanent's" : "creature's") + " controller";
}
}

View file

@ -0,0 +1,72 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
* @author xenohedron
*/
public class DamageTargetAndTargetEffect extends OneShotEffect {
private final int firstAmount;
private final int secondAmount;
/**
* Deals simultaneous damage to two targets. Must set target tag 1 and 2
*/
public DamageTargetAndTargetEffect(int firstAmount, int secondAmount) {
super(Outcome.Damage);
this.firstAmount = firstAmount;
this.secondAmount = secondAmount;
}
protected DamageTargetAndTargetEffect(final DamageTargetAndTargetEffect effect) {
super(effect);
this.firstAmount = effect.firstAmount;
this.secondAmount = effect.secondAmount;
}
@Override
public DamageTargetAndTargetEffect copy() {
return new DamageTargetAndTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
source.getTargets().getTargetsByTag(1).forEach(uuid -> damageTarget(uuid, firstAmount, source, game));
source.getTargets().getTargetsByTag(2).forEach(uuid -> damageTarget(uuid, secondAmount, source, game));
return true;
}
private void damageTarget(UUID targetId, int amount, Ability source, Game game) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(amount, source.getSourceId(), source, game) ;
} else {
Player player = game.getPlayer(targetId);
if (player != null) {
player.damage(amount, source.getSourceId(), source, game);
}
}
}
@Override
public String getText(Mode mode) {
// verify check that target tags are properly setup
if (mode.getTargets().getByTag(1) == null || mode.getTargets().getByTag(2) == null) {
throw new IllegalArgumentException("Wrong code usage: need to add tags to targets");
}
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
return "{this} deals " + firstAmount + "damage to " + mode.getTargets().getByTag(1).getDescription() +
" and " + secondAmount + "damage to " + mode.getTargets().getByTag(2).getDescription();
}
}

View file

@ -0,0 +1,77 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
* @author xenohedron
*/
public class DamageTargetAndYouEffect extends OneShotEffect {
private final int firstAmount;
private final int secondAmount;
/**
* Deals simultaneous damage to the target and the controller of the source
*/
public DamageTargetAndYouEffect(int amount) {
this(amount, amount);
}
/**
* Deals simultaneous damage to the target and the controller of the source
*/
public DamageTargetAndYouEffect(int firstAmount, int secondAmount) {
super(Outcome.Damage);
this.firstAmount = firstAmount;
this.secondAmount = secondAmount;
}
protected DamageTargetAndYouEffect(final DamageTargetAndYouEffect effect) {
super(effect);
this.firstAmount = effect.firstAmount;
this.secondAmount = effect.secondAmount;
}
@Override
public DamageTargetAndYouEffect copy() {
return new DamageTargetAndYouEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(firstAmount, source.getSourceId(), source, game);
} else {
Player player = game.getPlayer(targetId);
if (player != null) {
player.damage(firstAmount, source.getSourceId(), source, game);
}
}
}
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.damage(secondAmount, source.getSourceId(), source, game);
}
return true;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
return "{this} deals " + firstAmount + "damage to " +
getTargetPointer().describeTargets(mode.getTargets(), "that creature") +
" and " + secondAmount + "damage to you";
}
}

View file

@ -4,7 +4,6 @@ import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
@ -24,7 +23,6 @@ public class DamageTargetEffect extends OneShotEffect {
protected DynamicValue amount;
protected boolean preventable;
protected String targetDescription;
protected boolean useOnlyTargetPointer; // TODO: investigate why do we ignore targetPointer by default??
protected String sourceName = "{this}";
public DamageTargetEffect(int amount) {
@ -44,10 +42,6 @@ public class DamageTargetEffect extends OneShotEffect {
this(StaticValue.get(amount), preventable, targetDescription);
}
public DamageTargetEffect(int amount, boolean preventable, String targetDescription, boolean useOnlyTargetPointer) {
this(StaticValue.get(amount), preventable, targetDescription, useOnlyTargetPointer);
}
public DamageTargetEffect(int amount, boolean preventable, String targetDescription, String whoDealDamageName) {
this(StaticValue.get(amount), preventable, targetDescription);
this.sourceName = whoDealDamageName;
@ -67,15 +61,10 @@ public class DamageTargetEffect extends OneShotEffect {
}
public DamageTargetEffect(DynamicValue amount, boolean preventable, String targetDescription) {
this(amount, preventable, targetDescription, false);
}
public DamageTargetEffect(DynamicValue amount, boolean preventable, String targetDescription, boolean useOnlyTargetPointer) {
super(Outcome.Damage);
this.amount = amount;
this.preventable = preventable;
this.targetDescription = targetDescription;
this.useOnlyTargetPointer = useOnlyTargetPointer;
}
public int getAmount() {
@ -95,21 +84,15 @@ public class DamageTargetEffect extends OneShotEffect {
this.amount = effect.amount.copy();
this.preventable = effect.preventable;
this.targetDescription = effect.targetDescription;
this.useOnlyTargetPointer = effect.useOnlyTargetPointer;
this.sourceName = effect.sourceName;
}
@Override
public DamageTargetEffect withTargetDescription(String targetDescription) {
this.targetDescription = targetDescription;
return this;
}
// TODO: this should most likely be refactored to not be needed and always use target pointer.
public Effect setUseOnlyTargetPointer(boolean useOnlyTargetPointer) {
this.useOnlyTargetPointer = useOnlyTargetPointer;
return this;
}
@Override
public DamageTargetEffect copy() {
return new DamageTargetEffect(this);
@ -117,21 +100,6 @@ public class DamageTargetEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
if (!useOnlyTargetPointer && source.getTargets().size() > 1) {
for (Target target : source.getTargets()) {
for (UUID targetId : target.getTargets()) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(amount.calculate(game, source, this), source.getSourceId(), source, game, false, preventable);
}
Player player = game.getPlayer(targetId);
if (player != null) {
player.damage(amount.calculate(game, source, this), source.getSourceId(), source, game, false, preventable);
}
}
}
return true;
}
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
@ -154,7 +122,7 @@ public class DamageTargetEffect extends OneShotEffect {
StringBuilder sb = new StringBuilder();
String message = amount.getMessage();
sb.append(this.sourceName).append(" deals ");
if (message.isEmpty() || !message.equals("1")) {
if (!message.equals("1")) {
sb.append(amount);
}
if (!sb.toString().endsWith(" ")) {

View file

@ -6,7 +6,6 @@ import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import java.util.ArrayList;
import java.util.List;
@ -42,37 +41,26 @@ public class TargetsDamageTargetsEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
if (source.getTargets().size() < 2) {
return false;
}
Target damageTarget = source.getTargets().getByTag(1);
Target additionalDamageTarget = source.getTargets().getByTag(2);
Target destTarget = source.getTargets().getByTag(3);
List<Permanent> damagingPermanents = new ArrayList<>();
List<Permanent> receivingPermanents = new ArrayList<>();
for (UUID id : damageTarget.getTargets()) {
for (UUID id : source.getTargets().getTargetsByTag(1)) { // dealing damage
Permanent permanent = game.getPermanent(id);
if (permanent != null) {
damagingPermanents.add(permanent);
}
}
if (additionalDamageTarget != null) {
for (UUID id : additionalDamageTarget.getTargets()) {
Permanent permanent = game.getPermanent(id);
if (permanent != null) {
damagingPermanents.add(permanent);
}
for (UUID id : source.getTargets().getTargetsByTag(2)) { // additional dealing damage, if applicable
Permanent permanent = game.getPermanent(id);
if (permanent != null) {
damagingPermanents.add(permanent);
}
}
for (UUID id : destTarget.getTargets()) {
for (UUID id : source.getTargets().getTargetsByTag(3)) { // receiving damage
Permanent permanent = game.getPermanent(id);
if (permanent != null) {
receivingPermanents.add(permanent);
}
}
if (receivingPermanents.isEmpty() || damagingPermanents.isEmpty()) {
return false;
}
@ -86,6 +74,10 @@ public class TargetsDamageTargetsEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
// verify check that target tags are properly setup
if (mode.getTargets().getByTag(1) == null || mode.getTargets().getByTag(3) == null) {
throw new IllegalArgumentException("Wrong code usage: need to add tags to targets");
}
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}

View file

@ -1,13 +1,10 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.DealsCombatDamageTriggeredAbility;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
public final class VrondissRageOfAncientsToken extends TokenImpl {
@ -21,7 +18,7 @@ public final class VrondissRageOfAncientsToken extends TokenImpl {
power = new MageInt(5);
toughness = new MageInt(4);
this.addAbility(new VrondissRageOfAncientsTokenTriggeredAbility());
this.addAbility(new DealsCombatDamageTriggeredAbility(new SacrificeSourceEffect(), false));
}
private VrondissRageOfAncientsToken(final VrondissRageOfAncientsToken token) {
@ -32,35 +29,3 @@ public final class VrondissRageOfAncientsToken extends TokenImpl {
return new VrondissRageOfAncientsToken(this);
}
}
class VrondissRageOfAncientsTokenTriggeredAbility extends TriggeredAbilityImpl {
public VrondissRageOfAncientsTokenTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeSourceEffect(), false);
}
protected VrondissRageOfAncientsTokenTriggeredAbility(final VrondissRageOfAncientsTokenTriggeredAbility ability) {
super(ability);
}
@Override
public VrondissRageOfAncientsTokenTriggeredAbility copy() {
return new VrondissRageOfAncientsTokenTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER
|| event.getType() == GameEvent.EventType.DAMAGED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When this creature deals damage, sacrifice it.";
}
}