diff --git a/Mage.Sets/src/mage/cards/a/AgelessEntity.java b/Mage.Sets/src/mage/cards/a/AgelessEntity.java index 5ebe3bb7ae6..106c1a901e1 100644 --- a/Mage.Sets/src/mage/cards/a/AgelessEntity.java +++ b/Mage.Sets/src/mage/cards/a/AgelessEntity.java @@ -1,35 +1,35 @@ package mage.cards.a; -import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.GainLifeControllerTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.counters.CounterType; -import mage.game.Game; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class AgelessEntity extends CardImpl { public AgelessEntity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); this.subtype.add(SubType.ELEMENTAL); this.power = new MageInt(4); this.toughness = new MageInt(4); // Whenever you gain life, put that many +1/+1 counters on Ageless Entity. - this.addAbility(new GainLifeControllerTriggeredAbility(new AgelessEntityEffect(), false, true)); + this.addAbility(new GainLifeControllerTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(), SavedGainedLifeValue.MANY), + false, true + )); } private AgelessEntity(final AgelessEntity card) { @@ -40,30 +40,4 @@ public final class AgelessEntity extends CardImpl { public AgelessEntity copy() { return new AgelessEntity(this); } -} - -class AgelessEntityEffect extends OneShotEffect { - - AgelessEntityEffect() { - super(Outcome.Benefit); - this.staticText = "put that many +1/+1 counters on {this}"; - } - - private AgelessEntityEffect(final AgelessEntityEffect effect) { - super(effect); - } - - @Override - public AgelessEntityEffect copy() { - return new AgelessEntityEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - int lifeGained = (Integer) this.getValue("gainedLife"); - if (lifeGained > 0) { - return new AddCountersSourceEffect(CounterType.P1P1.createInstance(lifeGained)).apply(game, source); - } - return false; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CradleOfVitality.java b/Mage.Sets/src/mage/cards/c/CradleOfVitality.java index fb56be6951c..9cf5689a0f6 100644 --- a/Mage.Sets/src/mage/cards/c/CradleOfVitality.java +++ b/Mage.Sets/src/mage/cards/c/CradleOfVitality.java @@ -3,15 +3,13 @@ package mage.cards.c; import mage.abilities.Ability; import mage.abilities.common.GainLifeControllerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -26,7 +24,9 @@ public final class CradleOfVitality extends CardImpl { // Whenever you gain life, you may pay {1}{W}. If you do, put a +1/+1 counter on target creature for each 1 life you gained. Ability ability = new GainLifeControllerTriggeredAbility(new DoIfCostPaid( - new CradleOfVitalityEffect(), new ManaCostsImpl<>("{1}{W}") + new AddCountersTargetEffect(CounterType.P1P1.createInstance(), SavedGainedLifeValue.MANY) + .setText("put a +1/+1 counter on target creature for each 1 life you gained"), + new ManaCostsImpl<>("{1}{W}") ), false, true); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -40,32 +40,4 @@ public final class CradleOfVitality extends CardImpl { public CradleOfVitality copy() { return new CradleOfVitality(this); } -} - -class CradleOfVitalityEffect extends OneShotEffect { - - CradleOfVitalityEffect() { - super(Outcome.Benefit); - staticText = "put a +1/+1 counter on target creature for each 1 life you gained"; - } - - private CradleOfVitalityEffect(final CradleOfVitalityEffect effect) { - super(effect); - } - - @Override - public CradleOfVitalityEffect copy() { - return new CradleOfVitalityEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - int lifeGained = 0; - if (this.getValue("gainedLife") != null) { - lifeGained = (Integer) this.getValue("gainedLife"); - } - return permanent != null && lifeGained > 0 - && permanent.addCounters(CounterType.P1P1.createInstance(lifeGained), source.getControllerId(), source, game); - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/f/FieldTestedFryingPan.java b/Mage.Sets/src/mage/cards/f/FieldTestedFryingPan.java index 24f14aff28b..6235df744d9 100644 --- a/Mage.Sets/src/mage/cards/f/FieldTestedFryingPan.java +++ b/Mage.Sets/src/mage/cards/f/FieldTestedFryingPan.java @@ -1,12 +1,10 @@ package mage.cards.f; -import mage.abilities.Ability; import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.GainLifeControllerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.common.CreateTokenAttachSourceEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; @@ -18,7 +16,6 @@ import mage.constants.AttachmentType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.game.Game; import mage.game.permanent.token.FoodToken; import mage.game.permanent.token.HalflingToken; @@ -42,8 +39,8 @@ public final class FieldTestedFryingPan extends CardImpl { // Equipped creature has "Whenever you gain life, this creature gets +X/+X until end of turn, where X is the amount of life you gained." TriggeredAbility equippedTrigger = new GainLifeControllerTriggeredAbility( new BoostSourceEffect( - FieldTestedFryingPanValue.instance, - FieldTestedFryingPanValue.instance, + SavedGainedLifeValue.MANY, + SavedGainedLifeValue.MANY, Duration.EndOfTurn ).setText("this creature gets +X/+X until end of turn, where X is the amount of life you gained.") ); @@ -63,28 +60,4 @@ public final class FieldTestedFryingPan extends CardImpl { public FieldTestedFryingPan copy() { return new FieldTestedFryingPan(this); } -} - -enum FieldTestedFryingPanValue implements DynamicValue { - instance; - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - return (Integer) effect.getValue("gainedLife"); - } - - @Override - public FieldTestedFryingPanValue copy() { - return this; - } - - @Override - public String getMessage() { - return ""; - } - - @Override - public String toString() { - return "X"; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/k/KavuPredator.java b/Mage.Sets/src/mage/cards/k/KavuPredator.java index ebd05f0e57c..234a56b0b11 100644 --- a/Mage.Sets/src/mage/cards/k/KavuPredator.java +++ b/Mage.Sets/src/mage/cards/k/KavuPredator.java @@ -1,32 +1,29 @@ package mage.cards.k; -import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class KavuPredator extends CardImpl { public KavuPredator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.KAVU); this.power = new MageInt(2); @@ -51,7 +48,7 @@ public final class KavuPredator extends CardImpl { class KavuPredatorTriggeredAbility extends TriggeredAbilityImpl { public KavuPredatorTriggeredAbility() { - super(Zone.BATTLEFIELD, new KavuPredatorEffect()); + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(), SavedGainedLifeValue.MANY)); setTriggerPhrase("Whenever an opponent gains life, "); } @@ -69,46 +66,13 @@ class KavuPredatorTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.GAINED_LIFE; } + @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getOpponents(this.controllerId).contains(event.getPlayerId())) { - this.getEffects().get(0).setValue("gainedLife", event.getAmount()); - return true; + if (!game.getOpponents(this.controllerId).contains(event.getPlayerId())) { + return false; } - return false; + this.getEffects().setValue(SavedGainedLifeValue.VALUE_KEY, event.getAmount()); + return true; } -} - -class KavuPredatorEffect extends OneShotEffect { - - KavuPredatorEffect() { - super(Outcome.BoostCreature); - this.staticText = "put that many +1/+1 counters on {this}"; - } - - private KavuPredatorEffect(final KavuPredatorEffect effect) { - super(effect); - } - - @Override - public KavuPredatorEffect copy() { - return new KavuPredatorEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { - Integer gainedLife = (Integer) this.getValue("gainedLife"); - if (gainedLife != null) { - permanent.addCounters(CounterType.P1P1.createInstance(gainedLife), source.getControllerId(), source, game); - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - game.informPlayers(player.getLogName() + " puts " + gainedLife + " +1/+1 counter on " + permanent.getName()); - } - } - return true; - } - return false; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/l/LichsMastery.java b/Mage.Sets/src/mage/cards/l/LichsMastery.java index 5a5bca91da7..516590290d2 100644 --- a/Mage.Sets/src/mage/cards/l/LichsMastery.java +++ b/Mage.Sets/src/mage/cards/l/LichsMastery.java @@ -1,27 +1,23 @@ package mage.cards.l; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.GainLifeControllerTriggeredAbility; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.LoseGameSourceControllerEffect; -import mage.constants.SuperType; import mage.abilities.keyword.HexproofAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; @@ -35,8 +31,9 @@ import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetControlledPermanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class LichsMastery extends CardImpl { @@ -53,7 +50,10 @@ public final class LichsMastery extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LichsMasteryCantLoseEffect())); // Whenever you gain life, draw that many cards. - this.addAbility(new GainLifeControllerTriggeredAbility(new LichsMasteryDrawCardsEffect(), false, true)); + this.addAbility(new GainLifeControllerTriggeredAbility( + new DrawCardSourceControllerEffect(SavedGainedLifeValue.MANY), + false, true + )); // Whenever you lose life, for each 1 life you lost, exile a permanent you control or a card from your hand or graveyard. this.addAbility(new LichsMasteryLoseLifeTriggeredAbility()); @@ -99,32 +99,6 @@ class LichsMasteryCantLoseEffect extends ContinuousRuleModifyingEffectImpl { } } -class LichsMasteryDrawCardsEffect extends OneShotEffect { - - LichsMasteryDrawCardsEffect() { - super(Outcome.Benefit); - this.staticText = "draw that many cards"; - } - - private LichsMasteryDrawCardsEffect(final LichsMasteryDrawCardsEffect effect) { - super(effect); - } - - @Override - public LichsMasteryDrawCardsEffect copy() { - return new LichsMasteryDrawCardsEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - int lifeGained = (Integer) this.getValue("gainedLife"); - if (lifeGained > 0) { - return new DrawCardSourceControllerEffect(lifeGained).apply(game, source); - } - return false; - } -} - class LichsMasteryLoseLifeTriggeredAbility extends TriggeredAbilityImpl { public LichsMasteryLoseLifeTriggeredAbility() { diff --git a/Mage.Sets/src/mage/cards/l/LightOfPromise.java b/Mage.Sets/src/mage/cards/l/LightOfPromise.java index 218fb31ec6a..36a65496f4b 100644 --- a/Mage.Sets/src/mage/cards/l/LightOfPromise.java +++ b/Mage.Sets/src/mage/cards/l/LightOfPromise.java @@ -3,20 +3,15 @@ package mage.cards.l; import mage.abilities.Ability; import mage.abilities.common.GainLifeControllerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; +import mage.constants.*; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -42,7 +37,8 @@ public final class LightOfPromise extends CardImpl { // Enchanted creature has "Whenever you gain life, put that many +1/+1 counters on this creature." this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( new GainLifeControllerTriggeredAbility( - new LightOfPromiseEffect(), false, true + new AddCountersSourceEffect(CounterType.P1P1.createInstance(), SavedGainedLifeValue.MANY), + false, true ), AttachmentType.AURA, Duration.WhileOnBattlefield, "Enchanted creature has \"Whenever you gain life, put that many +1/+1 counters on this creature.\"" ))); } @@ -55,31 +51,4 @@ public final class LightOfPromise extends CardImpl { public LightOfPromise copy() { return new LightOfPromise(this); } -} - -class LightOfPromiseEffect extends OneShotEffect { - - LightOfPromiseEffect() { - super(Outcome.Benefit); - staticText = "put that many +1/+1 counters on this creature"; - } - - private LightOfPromiseEffect(final LightOfPromiseEffect effect) { - super(effect); - } - - @Override - public LightOfPromiseEffect copy() { - return new LightOfPromiseEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - return false; - } - int gainedLife = (int) this.getValue("gainedLife"); - return permanent.addCounters(CounterType.P1P1.createInstance(gainedLife), source.getControllerId(), source, game); - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/n/NykthosParagon.java b/Mage.Sets/src/mage/cards/n/NykthosParagon.java index 57ed870888c..027d0139439 100644 --- a/Mage.Sets/src/mage/cards/n/NykthosParagon.java +++ b/Mage.Sets/src/mage/cards/n/NykthosParagon.java @@ -1,20 +1,15 @@ package mage.cards.n; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.GainLifeControllerTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; +import mage.abilities.effects.common.counter.AddCountersAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.util.CardUtil; import java.util.UUID; @@ -32,7 +27,13 @@ public final class NykthosParagon extends CardImpl { this.toughness = new MageInt(6); // Whenever you gain life, you may put that many +1/+1 counters on each creature you control. Do this only once each turn. - this.addAbility(new GainLifeControllerTriggeredAbility(new NykthosParagonEffect(), true, true).setDoOnlyOnceEachTurn(true)); + this.addAbility(new GainLifeControllerTriggeredAbility( + new AddCountersAllEffect( + CounterType.P1P1.createInstance(), + SavedGainedLifeValue.MANY, + StaticFilters.FILTER_CONTROLLED_CREATURE + ), true, true + ).setDoOnlyOnceEachTurn(true)); } private NykthosParagon(final NykthosParagon card) { @@ -43,45 +44,4 @@ public final class NykthosParagon extends CardImpl { public NykthosParagon copy() { return new NykthosParagon(this); } -} - -class NykthosParagonEffect extends OneShotEffect { - - NykthosParagonEffect() { - super(Outcome.BoostCreature); - staticText = "put that many +1/+1 counters on each creature you control"; - } - - private NykthosParagonEffect(final NykthosParagonEffect effect) { - super(effect); - } - - @Override - public NykthosParagonEffect copy() { - return new NykthosParagonEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Integer life = (Integer) this.getValue("gainedLife"); - if (controller == null || life == null || life < 1) { - return false; - } - for (Permanent permanent : game.getBattlefield().getActivePermanents( - StaticFilters.FILTER_CONTROLLED_CREATURES, - source.getControllerId(), source, game - )) { - permanent.addCounters( - CounterType.P1P1.createInstance(life), - source.getControllerId(), source, game - ); - game.informPlayers( - CardUtil.getSourceLogName(game, source) + ": " + - controller.getLogName() + " puts " + life + - " +1/+1 counters on " + permanent.getLogName() - ); - } - return true; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PrizePig.java b/Mage.Sets/src/mage/cards/p/PrizePig.java index 596ae5d4e0f..9c79d0032ca 100644 --- a/Mage.Sets/src/mage/cards/p/PrizePig.java +++ b/Mage.Sets/src/mage/cards/p/PrizePig.java @@ -3,7 +3,9 @@ package mage.cards.p; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.GainLifeControllerTriggeredAbility; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.mana.AnyColorManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -29,7 +31,11 @@ public final class PrizePig extends CardImpl { this.toughness = new MageInt(3); // Whenever you gain life, put that many ribbon counters on Prize Pig. Then if there are three or more ribbon counters on Prize Pig, remove those counters and untap it. - this.addAbility(new GainLifeControllerTriggeredAbility(new PrizePigEffect())); + Ability ability = new GainLifeControllerTriggeredAbility( + new AddCountersSourceEffect(CounterType.RIBBON.createInstance(), SavedGainedLifeValue.MANY) + ); + ability.addEffect(new PrizePigEffect()); + this.addAbility(ability); // {T}: Add one mana of any color. this.addAbility(new AnyColorManaAbility()); @@ -49,8 +55,7 @@ class PrizePigEffect extends OneShotEffect { PrizePigEffect() { super(Outcome.Benefit); - staticText = "put that many ribbon counters on {this}. Then if there are three " + - "or more ribbon counters on {this}, remove those counters and untap it"; + staticText = "Then if there are three or more ribbon counters on {this}, remove those counters and untap it"; } private PrizePigEffect(final PrizePigEffect effect) { @@ -65,11 +70,9 @@ class PrizePigEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = source.getSourcePermanentIfItStillExists(game); - int amount = (Integer) getValue("gainedLife"); - if (permanent == null || amount < 1) { + if (permanent == null) { return false; } - permanent.addCounters(CounterType.RIBBON.createInstance(amount), source, game); int count = permanent.getCounters(game).getCount(CounterType.RIBBON); if (count >= 3) { permanent.removeCounters(CounterType.RIBBON.createInstance(count), source, game); diff --git a/Mage.Sets/src/mage/cards/s/Sunbond.java b/Mage.Sets/src/mage/cards/s/Sunbond.java index 28665b369d4..c90bcac66ae 100644 --- a/Mage.Sets/src/mage/cards/s/Sunbond.java +++ b/Mage.Sets/src/mage/cards/s/Sunbond.java @@ -1,37 +1,31 @@ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.GainLifeControllerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; -import mage.game.Game; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class Sunbond extends CardImpl { public Sunbond(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); this.subtype.add(SubType.AURA); @@ -40,11 +34,17 @@ public final class Sunbond extends CardImpl { this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget); - this.addAbility(ability); + this.addAbility(ability); // Enchanted creature has "Whenever you gain life, put that many +1/+1 counters on this creature." - Effect effect = new GainAbilityAttachedEffect(new GainLifeControllerTriggeredAbility(new SunbondEffect(), false, true), AttachmentType.AURA, Duration.WhileOnBattlefield); + Effect effect = new GainAbilityAttachedEffect( + new GainLifeControllerTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(), SavedGainedLifeValue.MANY) + .setText("put that many +1/+1 counters on this creature"), + false, true + ), AttachmentType.AURA, Duration.WhileOnBattlefield + ); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - + } private Sunbond(final Sunbond card) { @@ -55,30 +55,4 @@ public final class Sunbond extends CardImpl { public Sunbond copy() { return new Sunbond(this); } -} - -class SunbondEffect extends OneShotEffect { - - public SunbondEffect() { - super(Outcome.Benefit); - this.staticText = "put that many +1/+1 counters on this creature"; - } - - private SunbondEffect(final SunbondEffect effect) { - super(effect); - } - - @Override - public SunbondEffect copy() { - return new SunbondEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - int lifeGained = (Integer) this.getValue("gainedLife"); - if (lifeGained > 0) { - return new AddCountersSourceEffect(CounterType.P1P1.createInstance(lifeGained)).apply(game, source); - } - return false; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/TheArchimandrite.java b/Mage.Sets/src/mage/cards/t/TheArchimandrite.java index af4366cd7d3..51425d58f0d 100644 --- a/Mage.Sets/src/mage/cards/t/TheArchimandrite.java +++ b/Mage.Sets/src/mage/cards/t/TheArchimandrite.java @@ -10,8 +10,8 @@ import mage.abilities.costs.common.TapTargetCost; import mage.abilities.dynamicvalue.AdditiveDynamicValue; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CardsInControllerHandCount; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; @@ -26,7 +26,6 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.TappedPredicate; -import mage.game.Game; import mage.target.common.TargetControlledPermanent; import java.util.UUID; @@ -77,7 +76,7 @@ public final class TheArchimandrite extends CardImpl { VigilanceAbility.getInstance(), Duration.EndOfTurn, filter ).setText("each Advisor, Artificer, and Monk you control gains vigilance")); ability.addEffect(new BoostControlledEffect( - TheArchimandriteValue.instance, StaticValue.get(0), Duration.EndOfTurn, + SavedGainedLifeValue.MANY, StaticValue.get(0), Duration.EndOfTurn, filter2, false ).setText("and gets +X/+0 until end of turn, where X is the amount of life you gained")); this.addAbility(ability); @@ -97,28 +96,4 @@ public final class TheArchimandrite extends CardImpl { public TheArchimandrite copy() { return new TheArchimandrite(this); } -} - -enum TheArchimandriteValue implements DynamicValue { - instance; - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - return (Integer) effect.getValue("gainedLife"); - } - - @Override - public TheArchimandriteValue copy() { - return this; - } - - @Override - public String getMessage() { - return ""; - } - - @Override - public String toString() { - return "X"; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/TreebeardGraciousHost.java b/Mage.Sets/src/mage/cards/t/TreebeardGraciousHost.java index e1b0f3acbbd..516d01912d8 100644 --- a/Mage.Sets/src/mage/cards/t/TreebeardGraciousHost.java +++ b/Mage.Sets/src/mage/cards/t/TreebeardGraciousHost.java @@ -5,21 +5,19 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.GainLifeControllerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.WardAbility; 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.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.game.permanent.token.FoodToken; import mage.target.TargetPermanent; @@ -57,7 +55,9 @@ public final class TreebeardGraciousHost extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken(), 2))); // Whenever you gain life, put that many +1/+1 counters on target Halfling or Treefolk. - Ability ability = new GainLifeControllerTriggeredAbility(new TreebeardGraciousHostEffect()); + Ability ability = new GainLifeControllerTriggeredAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance(), SavedGainedLifeValue.MANY) + ); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } @@ -70,29 +70,4 @@ public final class TreebeardGraciousHost extends CardImpl { public TreebeardGraciousHost copy() { return new TreebeardGraciousHost(this); } -} - -class TreebeardGraciousHostEffect extends OneShotEffect { - - TreebeardGraciousHostEffect() { - super(Outcome.Benefit); - staticText = "put that many +1/+1 counters on target Halfling or Treefolk"; - } - - private TreebeardGraciousHostEffect(final TreebeardGraciousHostEffect effect) { - super(effect); - } - - @Override - public TreebeardGraciousHostEffect copy() { - return new TreebeardGraciousHostEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - int amount = (Integer) getValue("gainedLife"); - return permanent != null && amount > 0 - && permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game); - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/w/WellOfLostDreams.java b/Mage.Sets/src/mage/cards/w/WellOfLostDreams.java index b2946974338..d21bdd918bd 100644 --- a/Mage.Sets/src/mage/cards/w/WellOfLostDreams.java +++ b/Mage.Sets/src/mage/cards/w/WellOfLostDreams.java @@ -1,10 +1,10 @@ package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.GainLifeControllerTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -13,14 +13,15 @@ import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class WellOfLostDreams extends CardImpl { public WellOfLostDreams(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // Whenever you gain life, you may pay {X}, where X is less than or equal to the amount of life you gained. If you do, draw X cards. this.addAbility(new GainLifeControllerTriggeredAbility(new WellOfLostDreamsEffect(), true, true)); @@ -56,7 +57,7 @@ class WellOfLostDreamsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - int amount = (Integer) getValue("gainedLife"); + int amount = SavedGainedLifeValue.MANY.calculate(game, source, this); if (amount > 0) { int xValue = controller.announceXMana(0, amount, "Announce X Value", game, source); if (xValue > 0) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/dst/AgelessEntityTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/dst/AgelessEntityTest.java new file mode 100644 index 00000000000..4b593682e18 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/dst/AgelessEntityTest.java @@ -0,0 +1,54 @@ +package org.mage.test.cards.single.dst; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class AgelessEntityTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.a.AgelessEntity Ageless Entity} {3}{G}{G} + * Creature — Elemental + * Whenever you gain life, put that many +1/+1 counters on Ageless Entity. + * 4/4 + */ + private static final String entity = "Ageless Entity"; + + @Test + public void test_Simple() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, entity); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 5); + addCard(Zone.HAND, playerA, "Dosan's Oldest Chant"); // You gain 6 life. Draw a card. + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dosan's Oldest Chant"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 20 + 6); + assertCounterCount(playerA, entity, CounterType.P1P1, 6); + } + + @Test + public void test_Lifelink() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, entity); + addCard(Zone.BATTLEFIELD, playerA, "Child of Night"); // 2/1 lifelink + + attack(1, playerA, "Child of Night", playerB); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20 + 2); + assertCounterCount(playerA, entity, CounterType.P1P1, 2); + } +} diff --git a/Mage/src/main/java/mage/abilities/common/GainLifeControllerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/GainLifeControllerTriggeredAbility.java index aad783c8d9a..638c519bdc5 100644 --- a/Mage/src/main/java/mage/abilities/common/GainLifeControllerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/GainLifeControllerTriggeredAbility.java @@ -1,6 +1,7 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.dynamicvalue.common.SavedGainedLifeValue; import mage.abilities.effects.Effect; import mage.constants.Zone; import mage.game.Game; @@ -46,7 +47,7 @@ public class GainLifeControllerTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getPlayerId().equals(this.getControllerId())) { - this.getEffects().setValue("gainedLife", event.getAmount()); + this.getEffects().setValue(SavedGainedLifeValue.VALUE_KEY, event.getAmount()); if (setTargetPointer) { this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId())); } diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/SavedGainedLifeValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/SavedGainedLifeValue.java new file mode 100644 index 00000000000..fea67a9837d --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/SavedGainedLifeValue.java @@ -0,0 +1,45 @@ +package mage.abilities.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.game.Game; + +import java.util.Optional; + +/** + * Stores gained life value in relevant triggers, to pass down on effects. + * + * @author Susucr + */ +public enum SavedGainedLifeValue implements DynamicValue { + MANY("many"), + MUCH("much"); + + private final String message; + public static final String VALUE_KEY = "gainedLife"; + + SavedGainedLifeValue(String message) { + this.message = "that " + message; + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return Optional.ofNullable((Integer) effect.getValue(VALUE_KEY)).orElse(0); + } + + @Override + public SavedGainedLifeValue copy() { + return this; + } + + @Override + public String toString() { + return message; + } + + @Override + public String getMessage() { + return ""; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java index 6fcf8c050d1..358be527915 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java @@ -35,6 +35,10 @@ public class AddCountersSourceEffect extends OneShotEffect { this(counter, StaticValue.get(0), informPlayers); } + public AddCountersSourceEffect(Counter counter, DynamicValue amount) { + this(counter, amount, true); + } + public AddCountersSourceEffect(Counter counter, DynamicValue amount, boolean informPlayers) { this(counter, amount, informPlayers, false); }