From 5d0c1c96c8c97d27b4e3e6eedd5c3f77ce9db75d Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sat, 26 Aug 2023 00:26:25 -0400 Subject: [PATCH 01/10] remove sublayer parameter in SetBasePowerToughnessSourceEffect --- Mage.Sets/src/mage/cards/a/Amplifire.java | 3 +-- Mage.Sets/src/mage/cards/a/AquamorphEntity.java | 2 +- Mage.Sets/src/mage/cards/a/AscendantSpirit.java | 5 ++--- Mage.Sets/src/mage/cards/b/BattlegateMimic.java | 3 +-- Mage.Sets/src/mage/cards/b/BramblefortFink.java | 2 +- Mage.Sets/src/mage/cards/b/BrokersInitiate.java | 3 +-- Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java | 2 +- Mage.Sets/src/mage/cards/d/Dracoplasm.java | 2 +- Mage.Sets/src/mage/cards/e/ElvishImpersonators.java | 2 +- Mage.Sets/src/mage/cards/e/EvolvedSleeper.java | 4 ++-- Mage.Sets/src/mage/cards/f/FigureOfDestiny.java | 6 +++--- Mage.Sets/src/mage/cards/f/FrodoSauronsBane.java | 2 +- Mage.Sets/src/mage/cards/g/Gigantiform.java | 2 +- Mage.Sets/src/mage/cards/h/Halfdane.java | 6 +++--- Mage.Sets/src/mage/cards/m/MarshFlitter.java | 2 +- Mage.Sets/src/mage/cards/m/MasterOfWinds.java | 2 +- Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java | 2 +- Mage.Sets/src/mage/cards/m/MoltenSentry.java | 2 +- Mage.Sets/src/mage/cards/n/NamelessRace.java | 2 +- Mage.Sets/src/mage/cards/n/NightskyMimic.java | 3 +-- Mage.Sets/src/mage/cards/p/PrimalClay.java | 2 +- Mage.Sets/src/mage/cards/p/PrimalPlasma.java | 2 +- Mage.Sets/src/mage/cards/r/RisenRiptide.java | 3 +-- Mage.Sets/src/mage/cards/r/RiverfallMimic.java | 3 +-- Mage.Sets/src/mage/cards/s/ShapeStealer.java | 3 +-- Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java | 3 +-- Mage.Sets/src/mage/cards/s/SurgeEngine.java | 2 +- Mage.Sets/src/mage/cards/s/SwornDefender.java | 2 +- Mage.Sets/src/mage/cards/t/TimberPaladin.java | 9 ++++----- Mage.Sets/src/mage/cards/t/TrenchGorger.java | 2 +- Mage.Sets/src/mage/cards/w/WardenOfTheFirstTree.java | 2 +- Mage.Sets/src/mage/cards/w/WoodElemental.java | 3 +-- Mage.Sets/src/mage/cards/w/WoodlurkerMimic.java | 3 +-- .../continuous/SetBasePowerToughnessSourceEffect.java | 4 ++-- .../java/mage/abilities/keyword/LevelerCardBuilder.java | 3 +-- 35 files changed, 45 insertions(+), 58 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/Amplifire.java b/Mage.Sets/src/mage/cards/a/Amplifire.java index d7a3c643e36..1919bd1e3a1 100644 --- a/Mage.Sets/src/mage/cards/a/Amplifire.java +++ b/Mage.Sets/src/mage/cards/a/Amplifire.java @@ -83,8 +83,7 @@ class AmplifireEffect extends OneShotEffect { SetBasePowerToughnessSourceEffect setBasePowerToughnessSourceEffect = new SetBasePowerToughnessSourceEffect( 2*lastCard.getPower().getValue(), 2*lastCard.getToughness().getValue(), - Duration.UntilYourNextTurn, - SubLayer.SetPT_7b + Duration.UntilYourNextTurn ); game.addEffect(setBasePowerToughnessSourceEffect, source); } diff --git a/Mage.Sets/src/mage/cards/a/AquamorphEntity.java b/Mage.Sets/src/mage/cards/a/AquamorphEntity.java index 09156b6ba28..b4075b0fe3f 100644 --- a/Mage.Sets/src/mage/cards/a/AquamorphEntity.java +++ b/Mage.Sets/src/mage/cards/a/AquamorphEntity.java @@ -124,7 +124,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { toughness = 5; break; } - game.addEffect(new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield, SubLayer.CharacteristicDefining_7a), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield), source); return false; } diff --git a/Mage.Sets/src/mage/cards/a/AscendantSpirit.java b/Mage.Sets/src/mage/cards/a/AscendantSpirit.java index a414df1ad2b..c70ec869315 100644 --- a/Mage.Sets/src/mage/cards/a/AscendantSpirit.java +++ b/Mage.Sets/src/mage/cards/a/AscendantSpirit.java @@ -39,8 +39,7 @@ public final class AscendantSpirit extends CardImpl { ability.addEffect(new SetBasePowerToughnessSourceEffect( 2, 3, - Duration.WhileOnBattlefield, - SubLayer.SetPT_7b + Duration.WhileOnBattlefield ).setText("with base power and toughness 2/3")); this.addAbility(ability); @@ -93,7 +92,7 @@ class AscendantSpiritWarriorEffect extends OneShotEffect { Duration.Custom, SubType.SPIRIT, SubType.WARRIOR, SubType.ANGEL ), source); game.addEffect(new SetBasePowerToughnessSourceEffect( - 4, 4, Duration.Custom, SubLayer.SetPT_7b + 4, 4, Duration.Custom ), source); return true; } diff --git a/Mage.Sets/src/mage/cards/b/BattlegateMimic.java b/Mage.Sets/src/mage/cards/b/BattlegateMimic.java index 43beaa70e8e..d4655b7fa10 100644 --- a/Mage.Sets/src/mage/cards/b/BattlegateMimic.java +++ b/Mage.Sets/src/mage/cards/b/BattlegateMimic.java @@ -12,7 +12,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; @@ -41,7 +40,7 @@ public final class BattlegateMimic extends CardImpl { this.toughness = new MageInt(1); // Whenever you cast a spell that's both red and white, Battlegate Mimic has base power and toughness 4/2 and gains first strike until end of turn. - SetBasePowerToughnessSourceEffect baseToughnessSourceEffect = new SetBasePowerToughnessSourceEffect(4, 2, Duration.EndOfTurn, SubLayer.SetPT_7b); + SetBasePowerToughnessSourceEffect baseToughnessSourceEffect = new SetBasePowerToughnessSourceEffect(4, 2, Duration.EndOfTurn); Ability ability = SpellCastControllerTriggeredAbility.createWithRule(baseToughnessSourceEffect, filter, false, rule); ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, false, true)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/b/BramblefortFink.java b/Mage.Sets/src/mage/cards/b/BramblefortFink.java index 9a1ad980931..c7f7eca5764 100644 --- a/Mage.Sets/src/mage/cards/b/BramblefortFink.java +++ b/Mage.Sets/src/mage/cards/b/BramblefortFink.java @@ -34,7 +34,7 @@ public final class BramblefortFink extends CardImpl { this.addAbility(new ActivateIfConditionActivatedAbility( Zone.BATTLEFIELD, new SetBasePowerToughnessSourceEffect( - 10, 10, Duration.EndOfTurn, SubLayer.SetPT_7b + 10, 10, Duration.EndOfTurn ).setText("{this} has base power and toughness 10/10 until end of turn"), new GenericManaCost(8), condition)); diff --git a/Mage.Sets/src/mage/cards/b/BrokersInitiate.java b/Mage.Sets/src/mage/cards/b/BrokersInitiate.java index 99ff6178c6a..085f1ce4943 100644 --- a/Mage.Sets/src/mage/cards/b/BrokersInitiate.java +++ b/Mage.Sets/src/mage/cards/b/BrokersInitiate.java @@ -8,7 +8,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.SubType; import java.util.UUID; @@ -28,7 +27,7 @@ public final class BrokersInitiate extends CardImpl { // {4}{G/U}: Brokers Initiate has base power and toughness 5/5 until end of turn. this.addAbility(new SimpleActivatedAbility( - new SetBasePowerToughnessSourceEffect(5, 5, Duration.EndOfTurn, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(5, 5, Duration.EndOfTurn), new ManaCostsImpl<>("{4}{G/U}") )); } diff --git a/Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java b/Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java index ab54c8e0b9c..eaff66a9962 100644 --- a/Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java +++ b/Mage.Sets/src/mage/cards/d/DonalHeraldOfWings.java @@ -103,7 +103,7 @@ enum DonalHeraldOfWingsApplier implements StackObjectCopyApplier { copiedSpell.addSubType(SubType.SPIRIT); copiedSpell.getPower().setModifiedBaseValue(1); copiedSpell.getToughness().setModifiedBaseValue(1); - Ability ability = new SimpleStaticAbility(new SetBasePowerToughnessSourceEffect(1,1, Duration.Custom, SubLayer.SetPT_7b)); + Ability ability = new SimpleStaticAbility(new SetBasePowerToughnessSourceEffect(1,1, Duration.Custom)); ability.setRuleVisible(false); copiedSpell.getAbilities().add(ability); } diff --git a/Mage.Sets/src/mage/cards/d/Dracoplasm.java b/Mage.Sets/src/mage/cards/d/Dracoplasm.java index 35fa182e4a2..c0971d5dc88 100644 --- a/Mage.Sets/src/mage/cards/d/Dracoplasm.java +++ b/Mage.Sets/src/mage/cards/d/Dracoplasm.java @@ -117,7 +117,7 @@ class DracoplasmEffect extends ReplacementEffectImpl { toughness = CardUtil.overflowInc(toughness, targetCreature.getToughness().getValue()); } } - ContinuousEffect effect = new SetBasePowerToughnessSourceEffect(power, toughness, Duration.Custom, SubLayer.SetPT_7b); + ContinuousEffect effect = new SetBasePowerToughnessSourceEffect(power, toughness, Duration.Custom); game.addEffect(effect, source); return false; } diff --git a/Mage.Sets/src/mage/cards/e/ElvishImpersonators.java b/Mage.Sets/src/mage/cards/e/ElvishImpersonators.java index e83b05cf75b..7270a5e6b39 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishImpersonators.java +++ b/Mage.Sets/src/mage/cards/e/ElvishImpersonators.java @@ -65,7 +65,7 @@ class ElvishImpersonatorsEffect extends OneShotEffect { List results = controller.rollDice(outcome, source, game, 6, 2, 0); int firstRoll = results.get(0); int secondRoll = results.get(1); - game.addEffect(new SetBasePowerToughnessSourceEffect(firstRoll, secondRoll, Duration.WhileOnBattlefield, SubLayer.SetPT_7b), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(firstRoll, secondRoll, Duration.WhileOnBattlefield), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/e/EvolvedSleeper.java b/Mage.Sets/src/mage/cards/e/EvolvedSleeper.java index 2f5df81a307..26fe6d8e53d 100644 --- a/Mage.Sets/src/mage/cards/e/EvolvedSleeper.java +++ b/Mage.Sets/src/mage/cards/e/EvolvedSleeper.java @@ -34,7 +34,7 @@ public final class EvolvedSleeper extends CardImpl { Duration.Custom, SubType.HUMAN, SubType.CLERIC ).setText("{this} becomes a Human Cleric"), new ManaCostsImpl<>("{B}")); ability.addEffect(new SetBasePowerToughnessSourceEffect( - 2, 2, Duration.Custom, SubLayer.SetPT_7b + 2, 2, Duration.Custom ).setText("with base power and toughness 2/2")); this.addAbility(ability); @@ -87,7 +87,7 @@ class EvolvedSleeperClericEffect extends OneShotEffect { Duration.Custom, SubType.PHYREXIAN, SubType.HUMAN, SubType.CLERIC ), source); game.addEffect(new SetBasePowerToughnessSourceEffect( - 3, 3, Duration.Custom, SubLayer.SetPT_7b + 3, 3, Duration.Custom ), source); return true; } diff --git a/Mage.Sets/src/mage/cards/f/FigureOfDestiny.java b/Mage.Sets/src/mage/cards/f/FigureOfDestiny.java index 19cf8b538fd..8c7e9f56e2e 100644 --- a/Mage.Sets/src/mage/cards/f/FigureOfDestiny.java +++ b/Mage.Sets/src/mage/cards/f/FigureOfDestiny.java @@ -35,7 +35,7 @@ public final class FigureOfDestiny extends CardImpl { Duration.Custom, SubType.KITHKIN, SubType.SPIRIT ).setText("{this} becomes a Kithkin Spirit"), new ManaCostsImpl<>("{R/W}")); ability.addEffect(new SetBasePowerToughnessSourceEffect( - 2, 2, Duration.Custom, SubLayer.SetPT_7b + 2, 2, Duration.Custom ).setText("with base power and toughness 2/2")); this.addAbility(ability); @@ -86,7 +86,7 @@ class FigureOfDestinySpiritEffect extends OneShotEffect { Duration.Custom, SubType.KITHKIN, SubType.SPIRIT, SubType.WARRIOR ), source); game.addEffect(new SetBasePowerToughnessSourceEffect( - 4, 4, Duration.Custom, SubLayer.SetPT_7b + 4, 4, Duration.Custom ), source); return true; } @@ -119,7 +119,7 @@ class FigureOfDestinyWarriorEffect extends OneShotEffect { Duration.Custom, SubType.KITHKIN, SubType.SPIRIT, SubType.WARRIOR, SubType.AVATAR ), source); game.addEffect(new SetBasePowerToughnessSourceEffect( - 8, 8, Duration.Custom, SubLayer.SetPT_7b + 8, 8, Duration.Custom ), source); game.addEffect(new GainAbilitySourceEffect( FlyingAbility.getInstance(), Duration.Custom diff --git a/Mage.Sets/src/mage/cards/f/FrodoSauronsBane.java b/Mage.Sets/src/mage/cards/f/FrodoSauronsBane.java index 5e6e1e640e5..e4843b0e83d 100644 --- a/Mage.Sets/src/mage/cards/f/FrodoSauronsBane.java +++ b/Mage.Sets/src/mage/cards/f/FrodoSauronsBane.java @@ -44,7 +44,7 @@ public final class FrodoSauronsBane extends CardImpl { this.addAbility(new SimpleActivatedAbility( new ConditionalOneShotEffect(new AddContinuousEffectToGame( new AddCardSubTypeSourceEffect(Duration.Custom, SubType.HALFLING, SubType.SCOUT), - new SetBasePowerToughnessSourceEffect(2, 3, Duration.Custom, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(2, 3, Duration.Custom), new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.Custom) ), condition1, "if {this} is a Citizen, it becomes a Halfling Scout with base power and toughness 2/3 and lifelink"), new ManaCostsImpl<>("{W/B}{W/B}") diff --git a/Mage.Sets/src/mage/cards/g/Gigantiform.java b/Mage.Sets/src/mage/cards/g/Gigantiform.java index 90fc0d36393..12daf2b3088 100644 --- a/Mage.Sets/src/mage/cards/g/Gigantiform.java +++ b/Mage.Sets/src/mage/cards/g/Gigantiform.java @@ -71,7 +71,7 @@ class GigantiformAbility extends StaticAbility { super(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA)); Ability ability = new SimpleStaticAbility( Zone.BATTLEFIELD, - new SetBasePowerToughnessSourceEffect(8, 8, Duration.WhileOnBattlefield, SubLayer.SetPT_7b) + new SetBasePowerToughnessSourceEffect(8, 8, Duration.WhileOnBattlefield) ); this.addEffect(new GainAbilityAttachedEffect(ability, AttachmentType.AURA)); } diff --git a/Mage.Sets/src/mage/cards/h/Halfdane.java b/Mage.Sets/src/mage/cards/h/Halfdane.java index 210408bdb50..b3e421f1706 100644 --- a/Mage.Sets/src/mage/cards/h/Halfdane.java +++ b/Mage.Sets/src/mage/cards/h/Halfdane.java @@ -81,9 +81,9 @@ class HalfdaneUpkeepEffect extends OneShotEffect { ContinuousEffect effect = new SetBasePowerToughnessSourceEffect( permanent.getPower().getValue(), permanent.getToughness().getValue(), - Duration.UntilYourNextUpkeepStep, - SubLayer.SetPT_7b); + Duration.UntilYourNextUpkeepStep + ); game.addEffect(effect, source); return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MarshFlitter.java b/Mage.Sets/src/mage/cards/m/MarshFlitter.java index bea9a8ac24c..641acb0a167 100644 --- a/Mage.Sets/src/mage/cards/m/MarshFlitter.java +++ b/Mage.Sets/src/mage/cards/m/MarshFlitter.java @@ -44,7 +44,7 @@ public final class MarshFlitter extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoblinRogueToken(), 2), false)); // Sacrifice a Goblin: Marsh Flitter has base power and toughness 3/3 until end of turn. - Effect effect = new SetBasePowerToughnessSourceEffect(3, 3, Duration.EndOfTurn, SubLayer.SetPT_7b); + Effect effect = new SetBasePowerToughnessSourceEffect(3, 3, Duration.EndOfTurn); effect.setText("{this} has base power and toughness 3/3 until end of turn"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new SacrificeTargetCost(new TargetControlledPermanent(filter))); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/m/MasterOfWinds.java b/Mage.Sets/src/mage/cards/m/MasterOfWinds.java index 575085000c9..13385ec7c5d 100644 --- a/Mage.Sets/src/mage/cards/m/MasterOfWinds.java +++ b/Mage.Sets/src/mage/cards/m/MasterOfWinds.java @@ -79,7 +79,7 @@ class MasterOfWindsEffect extends OneShotEffect { null, "4/1", "1/4", source, game ) ? 4 : 1; game.addEffect(new SetBasePowerToughnessSourceEffect( - power, 5 - power, Duration.EndOfTurn, SubLayer.SetPT_7b + power, 5 - power, Duration.EndOfTurn ), source); return true; } diff --git a/Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java b/Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java index 4fa6df8ea6b..1f621495cb3 100644 --- a/Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java +++ b/Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java @@ -84,7 +84,7 @@ class MinionOfTheWastesEffect extends OneShotEffect { game.informPlayers((sourceCard != null ? sourceCard.getLogName() : "") + ": " + controller.getLogName() + " pays " + payAmount + " life"); game.addEffect(new SetBasePowerToughnessSourceEffect( - payAmount, payAmount, Duration.Custom, SubLayer.CharacteristicDefining_7a + payAmount, payAmount, Duration.Custom ), source); permanent.addInfo("life paid", CardUtil.addToolTipMarkTags("Life paid: " + payAmount), game); return true; diff --git a/Mage.Sets/src/mage/cards/m/MoltenSentry.java b/Mage.Sets/src/mage/cards/m/MoltenSentry.java index 4f64c0bdd42..d90a32bf91b 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenSentry.java +++ b/Mage.Sets/src/mage/cards/m/MoltenSentry.java @@ -79,7 +79,7 @@ class MoltenSentryEffect extends OneShotEffect { toughness = 5; gainedAbility = DefenderAbility.getInstance(); } - game.addEffect(new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield, SubLayer.CharacteristicDefining_7a), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield), source); game.addEffect(new GainAbilitySourceEffect(gainedAbility, Duration.WhileOnBattlefield), source); return true; } diff --git a/Mage.Sets/src/mage/cards/n/NamelessRace.java b/Mage.Sets/src/mage/cards/n/NamelessRace.java index eeebb2285cb..94ea4af158e 100644 --- a/Mage.Sets/src/mage/cards/n/NamelessRace.java +++ b/Mage.Sets/src/mage/cards/n/NamelessRace.java @@ -108,7 +108,7 @@ class NamelessRaceEffect extends OneShotEffect { game.informPlayers((sourceCard != null ? sourceCard.getLogName() : "") + ": " + controller.getLogName() + " pays " + payAmount + " life"); game.addEffect(new SetBasePowerToughnessSourceEffect( - payAmount, payAmount, Duration.Custom, SubLayer.CharacteristicDefining_7a + payAmount, payAmount, Duration.Custom ), source); permanent.addInfo("life paid", CardUtil.addToolTipMarkTags("Life paid: " + payAmount), game); return true; diff --git a/Mage.Sets/src/mage/cards/n/NightskyMimic.java b/Mage.Sets/src/mage/cards/n/NightskyMimic.java index 59b97067f75..34f00cb3569 100644 --- a/Mage.Sets/src/mage/cards/n/NightskyMimic.java +++ b/Mage.Sets/src/mage/cards/n/NightskyMimic.java @@ -12,7 +12,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; @@ -44,7 +43,7 @@ public final class NightskyMimic extends CardImpl { // Whenever you cast a spell that's both white and black, Nightsky Mimic has base power and toughness 4/4 until end of turn and gains flying until end of turn. Ability ability = SpellCastControllerTriggeredAbility.createWithRule( - new SetBasePowerToughnessSourceEffect(4, 4, Duration.EndOfTurn, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(4, 4, Duration.EndOfTurn), filter, false, rule ); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, false, true)); diff --git a/Mage.Sets/src/mage/cards/p/PrimalClay.java b/Mage.Sets/src/mage/cards/p/PrimalClay.java index 4b8f234833c..0570212a95f 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalClay.java +++ b/Mage.Sets/src/mage/cards/p/PrimalClay.java @@ -114,7 +114,7 @@ public final class PrimalClay extends CardImpl { game.addEffect(new GainAbilitySourceEffect(DefenderAbility.getInstance(), Duration.Custom), source); break; } - game.addEffect(new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield, SubLayer.CharacteristicDefining_7a), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield), source); return false; } diff --git a/Mage.Sets/src/mage/cards/p/PrimalPlasma.java b/Mage.Sets/src/mage/cards/p/PrimalPlasma.java index 426e414eb1f..b3dba1d1023 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalPlasma.java +++ b/Mage.Sets/src/mage/cards/p/PrimalPlasma.java @@ -113,7 +113,7 @@ public final class PrimalPlasma extends CardImpl { game.addEffect(new GainAbilitySourceEffect(DefenderAbility.getInstance(), Duration.Custom), source); break; } - game.addEffect(new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield, SubLayer.CharacteristicDefining_7a), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield), source); } return false; diff --git a/Mage.Sets/src/mage/cards/r/RisenRiptide.java b/Mage.Sets/src/mage/cards/r/RisenRiptide.java index a120990bec5..976e4c45ccd 100644 --- a/Mage.Sets/src/mage/cards/r/RisenRiptide.java +++ b/Mage.Sets/src/mage/cards/r/RisenRiptide.java @@ -7,7 +7,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.filter.StaticFilters; @@ -27,7 +26,7 @@ public final class RisenRiptide extends CardImpl { // Whenever you cast a kicked spell, Risen Riptide has base power and toughness 5/5 until end of turn. this.addAbility(new SpellCastControllerTriggeredAbility( - new SetBasePowerToughnessSourceEffect(5, 5, Duration.EndOfTurn, SubLayer.SetPT_7b) + new SetBasePowerToughnessSourceEffect(5, 5, Duration.EndOfTurn) .setText("{this} has base power and toughness 5/5 until end of turn"), StaticFilters.FILTER_SPELL_KICKED_A, false) diff --git a/Mage.Sets/src/mage/cards/r/RiverfallMimic.java b/Mage.Sets/src/mage/cards/r/RiverfallMimic.java index 5721668acfc..4d3c3341a77 100644 --- a/Mage.Sets/src/mage/cards/r/RiverfallMimic.java +++ b/Mage.Sets/src/mage/cards/r/RiverfallMimic.java @@ -12,7 +12,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; @@ -44,7 +43,7 @@ public final class RiverfallMimic extends CardImpl { // Whenever you cast a spell that's both blue and red, Riverfall Mimic has base power and toughness 3/3 until end of turn and can't be blocked this turn. Ability ability = SpellCastControllerTriggeredAbility.createWithRule( - new SetBasePowerToughnessSourceEffect(3, 3, Duration.EndOfTurn, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(3, 3, Duration.EndOfTurn), filter, false, rule ); ability.addEffect(new GainAbilitySourceEffect(new CantBeBlockedSourceAbility(), Duration.EndOfTurn, false, true)); diff --git a/Mage.Sets/src/mage/cards/s/ShapeStealer.java b/Mage.Sets/src/mage/cards/s/ShapeStealer.java index 33b94100771..402fdbde6fb 100644 --- a/Mage.Sets/src/mage/cards/s/ShapeStealer.java +++ b/Mage.Sets/src/mage/cards/s/ShapeStealer.java @@ -14,7 +14,6 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -74,7 +73,7 @@ class ShapeStealerEffect extends OneShotEffect { return false; } - ContinuousEffect effect = new SetBasePowerToughnessSourceEffect(permanent.getPower().getValue(), permanent.getToughness().getValue(), Duration.EndOfTurn, SubLayer.SetPT_7b); + ContinuousEffect effect = new SetBasePowerToughnessSourceEffect(permanent.getPower().getValue(), permanent.getToughness().getValue(), Duration.EndOfTurn); game.addEffect(effect, source); return true; } diff --git a/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java b/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java index cd5fbe562c1..37e5c2c347b 100644 --- a/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java +++ b/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java @@ -12,7 +12,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; @@ -44,7 +43,7 @@ public final class ShorecrasherMimic extends CardImpl { // Whenever you cast a spell that's both green and blue, Shorecrasher Mimic has base power and toughness 5/3 until end of turn and gains trample until end of turn. Ability ability = SpellCastControllerTriggeredAbility.createWithRule( - new SetBasePowerToughnessSourceEffect(5, 3, Duration.EndOfTurn, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(5, 3, Duration.EndOfTurn), filter, false, rule ); ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, false, true)); diff --git a/Mage.Sets/src/mage/cards/s/SurgeEngine.java b/Mage.Sets/src/mage/cards/s/SurgeEngine.java index b87378e9563..a230a0b0b65 100644 --- a/Mage.Sets/src/mage/cards/s/SurgeEngine.java +++ b/Mage.Sets/src/mage/cards/s/SurgeEngine.java @@ -54,7 +54,7 @@ public final class SurgeEngine extends CardImpl { new ManaCostsImpl<>("{2}{U}"), SurgeEngineCondition.instance ); ability.addEffect(new SetBasePowerToughnessSourceEffect( - 5, 4, Duration.Custom, SubLayer.SetPT_7b + 5, 4, Duration.Custom ).setText("and has base power and toughness 5/4")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/SwornDefender.java b/Mage.Sets/src/mage/cards/s/SwornDefender.java index 02a3aa63e9f..a22492ef37f 100644 --- a/Mage.Sets/src/mage/cards/s/SwornDefender.java +++ b/Mage.Sets/src/mage/cards/s/SwornDefender.java @@ -78,7 +78,7 @@ class SwornDefenderEffect extends OneShotEffect { if (controller != null && targetPermanent != null) { int newPower = CardUtil.overflowDec(targetPermanent.getToughness().getValue(), 1); int newToughness = CardUtil.overflowInc(targetPermanent.getPower().getValue(), 1); - game.addEffect(new SetBasePowerToughnessSourceEffect(newPower, newToughness, Duration.EndOfTurn, SubLayer.SetPT_7b), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(newPower, newToughness, Duration.EndOfTurn), source); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/t/TimberPaladin.java b/Mage.Sets/src/mage/cards/t/TimberPaladin.java index 7c239ba1071..e29954dd081 100644 --- a/Mage.Sets/src/mage/cards/t/TimberPaladin.java +++ b/Mage.Sets/src/mage/cards/t/TimberPaladin.java @@ -17,7 +17,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.Duration; -import mage.constants.SubLayer; /** * @@ -38,7 +37,7 @@ public final class TimberPaladin extends CardImpl { // As long as Timber Paladin is enchanted by exactly one Aura, it has base power and toughness 3/3. Ability ability1 = new SimpleStaticAbility(new ConditionalContinuousEffect( - new SetBasePowerToughnessSourceEffect(3, 3, Duration.WhileOnBattlefield, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(3, 3, Duration.WhileOnBattlefield), exactlyOne, "As long as {this} is enchanted by exactly one Aura, it has base power and toughness 3/3." )); @@ -47,7 +46,7 @@ public final class TimberPaladin extends CardImpl { // As long as Timber Paladin is enchanted by exactly two Auras, it has base power and toughness 5/5 and vigilance. Ability ability2 = new SimpleStaticAbility(new ConditionalContinuousEffect( - new SetBasePowerToughnessSourceEffect(5, 5, Duration.WhileOnBattlefield, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(5, 5, Duration.WhileOnBattlefield), exactlyTwo, "As long as {this} is enchanted by exactly two Auras, it has base power and toughness 5/5" )); @@ -57,7 +56,7 @@ public final class TimberPaladin extends CardImpl { // As long as Timber Paladin is enchanted by three or more Auras, it has base power and toughness 10/10, vigilance, and trample. Ability ability3 = new SimpleStaticAbility(new ConditionalContinuousEffect( - new SetBasePowerToughnessSourceEffect(10, 10, Duration.WhileOnBattlefield, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(10, 10, Duration.WhileOnBattlefield), threeOrMore, "As long as {this} is enchanted by three or more Auras, it has base power and toughness 10/10" )); @@ -74,4 +73,4 @@ public final class TimberPaladin extends CardImpl { public TimberPaladin copy() { return new TimberPaladin(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/t/TrenchGorger.java b/Mage.Sets/src/mage/cards/t/TrenchGorger.java index 2c0d2be4f88..ef0420943ff 100644 --- a/Mage.Sets/src/mage/cards/t/TrenchGorger.java +++ b/Mage.Sets/src/mage/cards/t/TrenchGorger.java @@ -86,7 +86,7 @@ class TrenchGorgerEffect extends OneShotEffect { } } controller.shuffleLibrary(source, game); - game.addEffect(new SetBasePowerToughnessSourceEffect(count, count, Duration.WhileOnBattlefield, SubLayer.SetPT_7b), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(count, count, Duration.WhileOnBattlefield), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/w/WardenOfTheFirstTree.java b/Mage.Sets/src/mage/cards/w/WardenOfTheFirstTree.java index 49fb66d8140..53c2588fe1a 100644 --- a/Mage.Sets/src/mage/cards/w/WardenOfTheFirstTree.java +++ b/Mage.Sets/src/mage/cards/w/WardenOfTheFirstTree.java @@ -43,7 +43,7 @@ public final class WardenOfTheFirstTree extends CardImpl { Duration.Custom, SubType.HUMAN, SubType.WARRIOR ).setText("{this} becomes a Human Warrior"), new ManaCostsImpl<>("{1}{W/B}")); ability.addEffect(new SetBasePowerToughnessSourceEffect( - 3, 3, Duration.Custom, SubLayer.SetPT_7b + 3, 3, Duration.Custom ).setText("with base power and toughness 3/3")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/w/WoodElemental.java b/Mage.Sets/src/mage/cards/w/WoodElemental.java index abfa7bf1e98..056ee32ceb0 100644 --- a/Mage.Sets/src/mage/cards/w/WoodElemental.java +++ b/Mage.Sets/src/mage/cards/w/WoodElemental.java @@ -16,7 +16,6 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.SubLayer; import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.permanent.TappedPredicate; @@ -95,7 +94,7 @@ class WoodElementalEffect extends OneShotEffect { targetPermanent.sacrifice(source, game); } } - game.addEffect(new SetBasePowerToughnessSourceEffect(sacrificedForests, sacrificedForests, Duration.Custom, SubLayer.SetPT_7b), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(sacrificedForests, sacrificedForests, Duration.Custom), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/w/WoodlurkerMimic.java b/Mage.Sets/src/mage/cards/w/WoodlurkerMimic.java index b2fe7cccb8a..c166fbfe989 100644 --- a/Mage.Sets/src/mage/cards/w/WoodlurkerMimic.java +++ b/Mage.Sets/src/mage/cards/w/WoodlurkerMimic.java @@ -12,7 +12,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; @@ -44,7 +43,7 @@ public final class WoodlurkerMimic extends CardImpl { // Whenever you cast a spell that's both black and green, Woodlurker Mimic has base power and toughness 4/5 until end of turn and gains wither until end of turn. Ability ability = SpellCastControllerTriggeredAbility.createWithRule( - new SetBasePowerToughnessSourceEffect(4, 5, Duration.EndOfTurn, SubLayer.SetPT_7b), + new SetBasePowerToughnessSourceEffect(4, 5, Duration.EndOfTurn), filter, false, rule ); ability.addEffect(new GainAbilitySourceEffect(WitherAbility.getInstance(), Duration.EndOfTurn, false, true)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java index 488144005df..d95f8b80afc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java @@ -42,8 +42,8 @@ public class SetBasePowerToughnessSourceEffect extends ContinuousEffectImpl { this.staticText = "{this}'s power and toughness are each equal to the number of " + amount.getMessage(); } - public SetBasePowerToughnessSourceEffect(int power, int toughness, Duration duration, SubLayer subLayer) { - this(StaticValue.get(power), StaticValue.get(toughness), duration, subLayer); + public SetBasePowerToughnessSourceEffect(int power, int toughness, Duration duration) { + this(StaticValue.get(power), StaticValue.get(toughness), duration, SubLayer.SetPT_7b); this.staticText = "{this} has base power and toughness " + power + '/' + toughness + ' ' + duration.toString(); } diff --git a/Mage/src/main/java/mage/abilities/keyword/LevelerCardBuilder.java b/Mage/src/main/java/mage/abilities/keyword/LevelerCardBuilder.java index 80acc591b5f..e84a97f6d4a 100644 --- a/Mage/src/main/java/mage/abilities/keyword/LevelerCardBuilder.java +++ b/Mage/src/main/java/mage/abilities/keyword/LevelerCardBuilder.java @@ -11,7 +11,6 @@ import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.Zone; import mage.counters.CounterType; @@ -55,7 +54,7 @@ public class LevelerCardBuilder { staticAbility.setRuleVisible(false); constructed.add(staticAbility); } - ContinuousEffect effect = new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield, SubLayer.SetPT_7b); + ContinuousEffect effect = new SetBasePowerToughnessSourceEffect(power, toughness, Duration.WhileOnBattlefield); ConditionalContinuousEffect ptEffect = new ConditionalContinuousEffect(effect, condition, rule); constructed.add(new SimpleStaticAbility(Zone.BATTLEFIELD, ptEffect)); From c84fbfd00e127b0c91cb54366e94396699337bdb Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sat, 26 Aug 2023 00:51:20 -0400 Subject: [PATCH 02/10] new SetBasePowerToughnessPlusOneSourceEffect --- Mage.Sets/src/mage/cards/c/ConsumingBlob.java | 16 ++++------ Mage.Sets/src/mage/cards/l/Lhurgoyf.java | 18 ++++------- Mage.Sets/src/mage/cards/t/Tarmogoyf.java | 15 ++++------ .../src/mage/cards/u/UrborgLhurgoyf.java | 16 ++++------ ...BasePowerToughnessPlusOneSourceEffect.java | 30 +++++++++++++++++++ .../SetBasePowerToughnessSourceEffect.java | 11 ++----- .../token/ConsumingBlobOozeToken.java | 15 ++++------ 7 files changed, 59 insertions(+), 62 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessPlusOneSourceEffect.java diff --git a/Mage.Sets/src/mage/cards/c/ConsumingBlob.java b/Mage.Sets/src/mage/cards/c/ConsumingBlob.java index 72a18f5c659..e74cd19321f 100644 --- a/Mage.Sets/src/mage/cards/c/ConsumingBlob.java +++ b/Mage.Sets/src/mage/cards/c/ConsumingBlob.java @@ -3,15 +3,16 @@ package mage.cards.c; import mage.MageInt; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.AdditiveDynamicValue; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessPlusOneSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; import mage.game.permanent.token.ConsumingBlobOozeToken; import java.util.UUID; @@ -22,7 +23,6 @@ import java.util.UUID; public final class ConsumingBlob extends CardImpl { private static final DynamicValue powerValue = CardTypesInGraveyardCount.YOU; - private static final DynamicValue toughnessValue = new AdditiveDynamicValue(powerValue, StaticValue.get(1)); public ConsumingBlob(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); @@ -32,11 +32,7 @@ public final class ConsumingBlob extends CardImpl { this.toughness = new MageInt(1); // Consuming Blob's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, - new SetBasePowerToughnessSourceEffect(powerValue, toughnessValue, Duration.EndOfGame, SubLayer.CharacteristicDefining_7a) - .setText("{this}'s power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1") - )); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue))); // At the beginning of your end step, create a green Ooze creature token with "This creature's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1". this.addAbility(new BeginningOfEndStepTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/l/Lhurgoyf.java b/Mage.Sets/src/mage/cards/l/Lhurgoyf.java index da9c3611368..8787c128f77 100644 --- a/Mage.Sets/src/mage/cards/l/Lhurgoyf.java +++ b/Mage.Sets/src/mage/cards/l/Lhurgoyf.java @@ -1,30 +1,26 @@ package mage.cards.l; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.AdditiveDynamicValue; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessPlusOneSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.StaticFilters; +import java.util.UUID; + /** * * @author Plopman */ public final class Lhurgoyf extends CardImpl { - private static final DynamicValue powerValue = new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE); - private static final DynamicValue toughnessValue = new AdditiveDynamicValue(powerValue, StaticValue.get(1)); + private static final DynamicValue powerValue = new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURES); public Lhurgoyf(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); @@ -34,11 +30,7 @@ public final class Lhurgoyf extends CardImpl { this.toughness = new MageInt(0); // Lhurgoyf's power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, - new SetBasePowerToughnessSourceEffect(powerValue, toughnessValue, Duration.EndOfGame, SubLayer.CharacteristicDefining_7a) - .setText("{this}'s power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1") - )); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue))); } private Lhurgoyf(final Lhurgoyf card) { diff --git a/Mage.Sets/src/mage/cards/t/Tarmogoyf.java b/Mage.Sets/src/mage/cards/t/Tarmogoyf.java index 71030665f96..f0d292c4318 100644 --- a/Mage.Sets/src/mage/cards/t/Tarmogoyf.java +++ b/Mage.Sets/src/mage/cards/t/Tarmogoyf.java @@ -2,14 +2,14 @@ package mage.cards.t; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.AdditiveDynamicValue; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessPlusOneSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; import java.util.UUID; @@ -19,7 +19,6 @@ import java.util.UUID; public final class Tarmogoyf extends CardImpl { private static final DynamicValue powerValue = CardTypesInGraveyardCount.ALL; - private static final DynamicValue toughnessValue = new AdditiveDynamicValue(powerValue, StaticValue.get(1)); public Tarmogoyf(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); @@ -29,11 +28,7 @@ public final class Tarmogoyf extends CardImpl { this.toughness = new MageInt(1); // Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, - new SetBasePowerToughnessSourceEffect(powerValue, toughnessValue, Duration.EndOfGame, SubLayer.CharacteristicDefining_7a) - .setText("{this}'s power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1") - )); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue))); } private Tarmogoyf(final Tarmogoyf card) { diff --git a/Mage.Sets/src/mage/cards/u/UrborgLhurgoyf.java b/Mage.Sets/src/mage/cards/u/UrborgLhurgoyf.java index cae5121a1da..d25cb2e8fb2 100644 --- a/Mage.Sets/src/mage/cards/u/UrborgLhurgoyf.java +++ b/Mage.Sets/src/mage/cards/u/UrborgLhurgoyf.java @@ -3,17 +3,18 @@ package mage.cards.u; import mage.MageInt; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.IntPlusDynamicValue; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.MultipliedValue; import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; import mage.abilities.dynamicvalue.common.MultikickerCount; import mage.abilities.effects.common.MillCardsControllerEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessPlusOneSourceEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; import mage.filter.StaticFilters; import java.util.UUID; @@ -23,8 +24,7 @@ import java.util.UUID; */ public final class UrborgLhurgoyf extends CardImpl { - private static final DynamicValue powerValue = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE); - private static final DynamicValue toughnessValue = new IntPlusDynamicValue(1, powerValue); + private static final DynamicValue powerValue = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURES); private static final DynamicValue millValue = new MultipliedValue(MultikickerCount.instance, 3); public UrborgLhurgoyf(UUID ownerId, CardSetInfo setInfo) { @@ -43,11 +43,7 @@ public final class UrborgLhurgoyf extends CardImpl { this.addAbility(new AsEntersBattlefieldAbility(new MillCardsControllerEffect(millValue))); // Urborg Lhurgoyf's power is equal to the number of creature cards in your graveyard and its toughness is equal to that number plus 1. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, - new SetBasePowerToughnessSourceEffect(powerValue, toughnessValue, Duration.EndOfGame, SubLayer.CharacteristicDefining_7a) - .setText("{this}'s power is equal to the number of creature cards in your graveyard and its toughness is equal to that number plus 1") - )); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue))); } private UrborgLhurgoyf(final UrborgLhurgoyf card) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessPlusOneSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessPlusOneSourceEffect.java new file mode 100644 index 00000000000..de6fafeedd8 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessPlusOneSourceEffect.java @@ -0,0 +1,30 @@ +package mage.abilities.effects.common.continuous; + +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.IntPlusDynamicValue; +import mage.constants.Duration; +import mage.constants.SubLayer; + +/** + * @author xenohedron + */ +public class SetBasePowerToughnessPlusOneSourceEffect extends SetBasePowerToughnessSourceEffect { + + /** + * @param amount Power to set as a characteristic-defining ability; toughness is that value plus 1 + */ + public SetBasePowerToughnessPlusOneSourceEffect(DynamicValue amount) { + super(amount, new IntPlusDynamicValue(1, amount), Duration.EndOfGame, SubLayer.CharacteristicDefining_7a); + this.staticText = "{this}'s power is equal to the number of " + amount.getMessage() + " and its toughness is equal to that number plus 1"; + } + + protected SetBasePowerToughnessPlusOneSourceEffect(final SetBasePowerToughnessPlusOneSourceEffect effect) { + super(effect); + } + + @Override + public SetBasePowerToughnessPlusOneSourceEffect copy() { + return new SetBasePowerToughnessPlusOneSourceEffect(this); + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java index d95f8b80afc..b11a81cddde 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common.continuous; import mage.MageObject; @@ -13,8 +12,6 @@ import mage.constants.SubLayer; import mage.game.Game; /** - * RENAME - * * @author BetaSteward_at_googlemail.com, North, Alex-Vasile, xenohedron */ public class SetBasePowerToughnessSourceEffect extends ContinuousEffectImpl { @@ -72,15 +69,11 @@ public class SetBasePowerToughnessSourceEffect extends ContinuousEffectImpl { discard(); return false; } - if (this.power != null) { - int power = this.power.calculate(game, source, this); - mageObject.getPower().setModifiedBaseValue(power); + mageObject.getPower().setModifiedBaseValue(this.power.calculate(game, source, this)); } - if (this.toughness != null) { - int toughness = this.toughness.calculate(game, source, this); - mageObject.getToughness().setModifiedBaseValue(toughness); + mageObject.getToughness().setModifiedBaseValue(this.toughness.calculate(game, source, this)); } return true; } diff --git a/Mage/src/main/java/mage/game/permanent/token/ConsumingBlobOozeToken.java b/Mage/src/main/java/mage/game/permanent/token/ConsumingBlobOozeToken.java index 6f39c1ed03f..42a7f067a44 100644 --- a/Mage/src/main/java/mage/game/permanent/token/ConsumingBlobOozeToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/ConsumingBlobOozeToken.java @@ -2,12 +2,12 @@ package mage.game.permanent.token; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.AdditiveDynamicValue; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -import mage.constants.*; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessPlusOneSourceEffect; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; /** * @author ciaccona007 @@ -15,7 +15,6 @@ import mage.constants.*; public final class ConsumingBlobOozeToken extends TokenImpl { private static final DynamicValue powerValue = CardTypesInGraveyardCount.YOU; - private static final DynamicValue toughnessValue = new AdditiveDynamicValue(powerValue, StaticValue.get(1)); public ConsumingBlobOozeToken() { super("Ooze Token", "green Ooze creature token with \"This creature's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1.\""); @@ -27,11 +26,7 @@ public final class ConsumingBlobOozeToken extends TokenImpl { toughness = new MageInt(1); // This creature's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, - new SetBasePowerToughnessSourceEffect(powerValue, toughnessValue, Duration.EndOfGame, SubLayer.CharacteristicDefining_7a) - .setText("{this}'s power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1") - )); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue))); } private ConsumingBlobOozeToken(final ConsumingBlobOozeToken token) { From 33a859cb68905c41e7b62581dd7b48a90fa4cdac Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sat, 26 Aug 2023 01:01:48 -0400 Subject: [PATCH 03/10] simplify SetBasePowerSourceEffect --- .../src/mage/cards/a/ArniBrokenbrow.java | 5 +-- .../src/mage/cards/c/CraterElemental.java | 6 +-- .../src/mage/cards/e/EvraHalcyonWitness.java | 16 +++----- .../src/mage/cards/r/RiptideMangler.java | 12 +++--- .../continuous/SetBasePowerSourceEffect.java | 39 +++++++------------ 5 files changed, 27 insertions(+), 51 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/ArniBrokenbrow.java b/Mage.Sets/src/mage/cards/a/ArniBrokenbrow.java index 4941b8742f9..eda3f368e66 100644 --- a/Mage.Sets/src/mage/cards/a/ArniBrokenbrow.java +++ b/Mage.Sets/src/mage/cards/a/ArniBrokenbrow.java @@ -4,9 +4,8 @@ import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; import mage.abilities.keyword.BoastAbility; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; @@ -88,7 +87,7 @@ class ArniBrokenbrowEffect extends OneShotEffect { if (controller.chooseUse(outcome, "Change base power of " + mageObject.getLogName() + " to " + power + " until end of turn?", source, game )) { - game.addEffect(new SetBasePowerToughnessSourceEffect(StaticValue.get(power), null, Duration.EndOfTurn, SubLayer.SetPT_7b), source); + game.addEffect(new SetBasePowerSourceEffect(power, Duration.EndOfTurn), source); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CraterElemental.java b/Mage.Sets/src/mage/cards/c/CraterElemental.java index 1508e44040c..aa0bea29657 100644 --- a/Mage.Sets/src/mage/cards/c/CraterElemental.java +++ b/Mage.Sets/src/mage/cards/c/CraterElemental.java @@ -8,9 +8,8 @@ import mage.abilities.condition.common.FormidableCondition; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -41,8 +40,7 @@ public final class CraterElemental extends CardImpl { // Formidable — {2}{R}: Crater Elemental has base power 8 until end of turn. Activate this ability only if creatures you control have total power 8 or greater. ability = new ActivateIfConditionActivatedAbility( Zone.BATTLEFIELD, - new SetBasePowerToughnessSourceEffect(StaticValue.get(8), null, Duration.EndOfTurn, SubLayer.SetPT_7b) - .setText("{this} has base power 8 until end of turn"), + new SetBasePowerSourceEffect(8, Duration.EndOfTurn), new ManaCostsImpl<>("{2}{R}"), FormidableCondition.instance ); diff --git a/Mage.Sets/src/mage/cards/e/EvraHalcyonWitness.java b/Mage.Sets/src/mage/cards/e/EvraHalcyonWitness.java index a6c0d8ba6c1..244a821c08a 100644 --- a/Mage.Sets/src/mage/cards/e/EvraHalcyonWitness.java +++ b/Mage.Sets/src/mage/cards/e/EvraHalcyonWitness.java @@ -1,28 +1,22 @@ package mage.cards.e; -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.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.UUID; + /** * * @author TheElk801 @@ -88,7 +82,7 @@ class EvraHalcyonWitnessEffect extends OneShotEffect { // For example, say Evra is enchanted with Dub (which makes it 6/6) and your life total is 7. // After the exchange, Evra would be a 9/6 creature (its power became 7, which was then modified by Dub) and your life total would be 6. // (2018-04-27) - game.addEffect(new SetBasePowerToughnessSourceEffect(StaticValue.get(life), null, Duration.Custom, SubLayer.SetPT_7b), source); + game.addEffect(new SetBasePowerSourceEffect(life, Duration.Custom), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/r/RiptideMangler.java b/Mage.Sets/src/mage/cards/r/RiptideMangler.java index 55950bae181..9e3164389d8 100644 --- a/Mage.Sets/src/mage/cards/r/RiptideMangler.java +++ b/Mage.Sets/src/mage/cards/r/RiptideMangler.java @@ -1,25 +1,23 @@ - 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.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -import mage.constants.SubType; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author TheElk801 @@ -71,7 +69,7 @@ class RiptideManglerEffect extends OneShotEffect { if (permanent == null) { return false; } - game.addEffect(new SetBasePowerToughnessSourceEffect(StaticValue.get(permanent.getPower().getValue()), null, Duration.WhileOnBattlefield, SubLayer.SetPT_7b), source); + game.addEffect(new SetBasePowerSourceEffect(permanent.getPower().getValue(), Duration.WhileOnBattlefield), source); return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerSourceEffect.java index 43c3b08c40c..65b1e247033 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerSourceEffect.java @@ -1,36 +1,34 @@ - package mage.abilities.effects.common.continuous; -import mage.MageObject; -import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.game.Game; /** - * @author LevelX2 + * @author xenohedron */ -public class SetBasePowerSourceEffect extends ContinuousEffectImpl { - - private final DynamicValue amount; +public class SetBasePowerSourceEffect extends SetBasePowerToughnessSourceEffect { /** * @param amount Power to set as a characteristic-defining ability */ public SetBasePowerSourceEffect(DynamicValue amount) { - super(Duration.EndOfGame, Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, Outcome.BoostCreature); - setCharacterDefining(true); - this.amount = amount; + super(amount, null, Duration.EndOfGame, SubLayer.CharacteristicDefining_7a); staticText = "{this}'s power is equal to the number of " + amount.getMessage(); } + /** + * @param amount Power to set in layer 7b + * @param duration Duration for the effect + */ + public SetBasePowerSourceEffect(int amount, Duration duration) { + super(StaticValue.get(amount), null, duration, SubLayer.SetPT_7b); + staticText = "{this} has base power " + amount + ' ' + duration.toString(); + } + protected SetBasePowerSourceEffect(final SetBasePowerSourceEffect effect) { super(effect); - this.amount = effect.amount; } @Override @@ -38,15 +36,4 @@ public class SetBasePowerSourceEffect extends ContinuousEffectImpl { return new SetBasePowerSourceEffect(this); } - @Override - public boolean apply(Game game, Ability source) { - MageObject mageObject = game.getObject(source); - if (mageObject == null) { - return false; - } - int value = amount.calculate(game, source, this); - mageObject.getPower().setModifiedBaseValue(value); - return true; - } - } From ab0abcfd2258ed49a0a4f858915ace706e581dcb Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sat, 26 Aug 2023 01:06:56 -0400 Subject: [PATCH 04/10] simplify SetBaseToughnessSourceEffect fix Duration.WhileOnBattlefield -> Duration.Custom in some effects --- Mage.Sets/src/mage/cards/s/Sentinel.java | 5 +-- .../src/mage/cards/t/TreeOfPerdition.java | 14 ++----- .../src/mage/cards/t/TreeOfRedemption.java | 7 +--- .../src/mage/cards/w/WallOfTombstones.java | 5 +-- .../SetBaseToughnessSourceEffect.java | 41 ++++++------------- 5 files changed, 23 insertions(+), 49 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/Sentinel.java b/Mage.Sets/src/mage/cards/s/Sentinel.java index 0a7df439e21..a76c0cdb24b 100644 --- a/Mage.Sets/src/mage/cards/s/Sentinel.java +++ b/Mage.Sets/src/mage/cards/s/Sentinel.java @@ -4,9 +4,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBaseToughnessSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -77,7 +76,7 @@ class SentinelEffect extends OneShotEffect { Permanent targetPermanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); if (controller != null && targetPermanent != null) { int newToughness = CardUtil.overflowInc(targetPermanent.getPower().getValue(), 1); - game.addEffect(new SetBasePowerToughnessSourceEffect(null, StaticValue.get(newToughness), Duration.WhileOnBattlefield, SubLayer.SetPT_7b), source); + game.addEffect(new SetBaseToughnessSourceEffect(newToughness, Duration.WhileOnBattlefield), source); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/t/TreeOfPerdition.java b/Mage.Sets/src/mage/cards/t/TreeOfPerdition.java index be473c5011d..b478a50c00c 100644 --- a/Mage.Sets/src/mage/cards/t/TreeOfPerdition.java +++ b/Mage.Sets/src/mage/cards/t/TreeOfPerdition.java @@ -1,16 +1,11 @@ - package mage.cards.t; -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.common.StaticValue; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessTargetEffect; +import mage.abilities.effects.common.continuous.SetBaseToughnessSourceEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -19,7 +14,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetOpponent; -import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** * @@ -88,9 +84,7 @@ class TreeOfPerditionEffect extends OneShotEffect { // For example, say Tree of Perdition is equipped with Cultist’s Staff (which makes it 2/15) and the player’s life total is 7. // After the exchange, Tree of Perdition would be a 2/9 creature (its toughness became 7, which was then modified by Cultist’s Staff) and the player’s life total would be 15. // (2016-07-13) - ContinuousEffect powerToughnessEffect = new SetBasePowerToughnessTargetEffect(null, StaticValue.get(life), Duration.Custom); - powerToughnessEffect.setTargetPointer(new FixedTarget(perm.getId())); - game.addEffect(powerToughnessEffect, source); + game.addEffect(new SetBaseToughnessSourceEffect(life, Duration.Custom), source); return true; } diff --git a/Mage.Sets/src/mage/cards/t/TreeOfRedemption.java b/Mage.Sets/src/mage/cards/t/TreeOfRedemption.java index ee93f9e21c1..aefc01504ac 100644 --- a/Mage.Sets/src/mage/cards/t/TreeOfRedemption.java +++ b/Mage.Sets/src/mage/cards/t/TreeOfRedemption.java @@ -1,13 +1,11 @@ - package mage.cards.t; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBaseToughnessSourceEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -65,7 +63,6 @@ class TreeOfRedemptionEffect extends OneShotEffect { return false; } - int amount = perm.getToughness().getValue(); int life = player.getLife(); if (life == amount) { @@ -78,7 +75,7 @@ class TreeOfRedemptionEffect extends OneShotEffect { return false; } player.setLife(amount, game, source); - game.addEffect(new SetBasePowerToughnessSourceEffect(null, StaticValue.get(life), Duration.WhileOnBattlefield, SubLayer.SetPT_7b), source); + game.addEffect(new SetBaseToughnessSourceEffect(life, Duration.Custom), source); return true; } diff --git a/Mage.Sets/src/mage/cards/w/WallOfTombstones.java b/Mage.Sets/src/mage/cards/w/WallOfTombstones.java index 2114624b09a..51ab1d0c411 100644 --- a/Mage.Sets/src/mage/cards/w/WallOfTombstones.java +++ b/Mage.Sets/src/mage/cards/w/WallOfTombstones.java @@ -4,9 +4,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.common.continuous.SetBaseToughnessSourceEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -65,7 +64,7 @@ class WallOfTombstonesEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int newToughness = CardUtil.overflowInc(1, new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE).calculate(game, source, this)); - game.addEffect(new SetBasePowerToughnessSourceEffect(null, StaticValue.get(newToughness), Duration.WhileOnBattlefield, SubLayer.SetPT_7b), source); + game.addEffect(new SetBaseToughnessSourceEffect(newToughness, Duration.WhileOnBattlefield), source); return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBaseToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBaseToughnessSourceEffect.java index cbe57b62c56..f203194bd1d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBaseToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBaseToughnessSourceEffect.java @@ -1,38 +1,34 @@ - package mage.abilities.effects.common.continuous; -import mage.MageObject; -import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.game.Game; /** - * RENAME - * - * @author Backfir3, noxx + * @author xenohedron */ -public class SetBaseToughnessSourceEffect extends ContinuousEffectImpl { - - private final DynamicValue amount; +public class SetBaseToughnessSourceEffect extends SetBasePowerToughnessSourceEffect { /** * @param amount Toughness to set as a characteristic-defining ability */ public SetBaseToughnessSourceEffect(DynamicValue amount) { - super(Duration.EndOfGame, Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, Outcome.BoostCreature); - setCharacterDefining(true); - this.amount = amount; + super(null, amount, Duration.EndOfGame, SubLayer.CharacteristicDefining_7a); staticText = "{this}'s toughness is equal to the number of " + amount.getMessage(); } + /** + * @param amount Toughness to set in layer 7b + * @param duration Duration for the effect + */ + public SetBaseToughnessSourceEffect(int amount, Duration duration) { + super(null, StaticValue.get(amount), duration, SubLayer.SetPT_7b); + staticText = "{this} has base toughness " + amount + ' ' + duration.toString(); + } + protected SetBaseToughnessSourceEffect(final SetBaseToughnessSourceEffect effect) { super(effect); - this.amount = effect.amount; } @Override @@ -40,15 +36,4 @@ public class SetBaseToughnessSourceEffect extends ContinuousEffectImpl { return new SetBaseToughnessSourceEffect(this); } - @Override - public boolean apply(Game game, Ability source) { - MageObject mageObject = game.getObject(source); - if (mageObject != null) { - int value = amount.calculate(game, source, this); - mageObject.getToughness().setModifiedBaseValue(value); - return true; - } - return false; - } - } From 2eab7836f66169588e3c16a9b213780d23d63011 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sat, 26 Aug 2023 01:22:49 -0400 Subject: [PATCH 05/10] cleanup SetBasePowerToughnessSourceEffect usages --- .../src/mage/cards/b/BramblefortFink.java | 4 +--- Mage.Sets/src/mage/cards/c/ChimericMass.java | 2 +- Mage.Sets/src/mage/cards/d/DruidClass.java | 2 +- .../src/mage/cards/e/EntropicSpecter.java | 5 +---- Mage.Sets/src/mage/cards/g/Gigantoplasm.java | 6 +----- .../src/mage/cards/m/MinionOfTheWastes.java | 2 +- Mage.Sets/src/mage/cards/m/MythRealized.java | 3 ++- .../mage/cards/s/SvogthosTheRestlessTomb.java | 2 +- .../src/mage/cards/t/TestamentOfFaith.java | 2 +- .../SetBasePowerToughnessSourceEffect.java | 21 +++++++++++++++---- 10 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BramblefortFink.java b/Mage.Sets/src/mage/cards/b/BramblefortFink.java index c7f7eca5764..dfb393b5f22 100644 --- a/Mage.Sets/src/mage/cards/b/BramblefortFink.java +++ b/Mage.Sets/src/mage/cards/b/BramblefortFink.java @@ -33,9 +33,7 @@ public final class BramblefortFink extends CardImpl { // {8}: Bramblefort Fink has base power and toughness 10/10 until end of turn. Activate this ability only if you control an Oko planeswalker. this.addAbility(new ActivateIfConditionActivatedAbility( Zone.BATTLEFIELD, - new SetBasePowerToughnessSourceEffect( - 10, 10, Duration.EndOfTurn - ).setText("{this} has base power and toughness 10/10 until end of turn"), + new SetBasePowerToughnessSourceEffect(10, 10, Duration.EndOfTurn), new GenericManaCost(8), condition)); } diff --git a/Mage.Sets/src/mage/cards/c/ChimericMass.java b/Mage.Sets/src/mage/cards/c/ChimericMass.java index 9774cf47941..76aabe80a40 100644 --- a/Mage.Sets/src/mage/cards/c/ChimericMass.java +++ b/Mage.Sets/src/mage/cards/c/ChimericMass.java @@ -34,7 +34,7 @@ public final class ChimericMass extends CardImpl { new CreatureToken(0, 0, "Construct artifact creature with \"This creature's power and toughness are each equal to the number of charge counters on it.\"") .withType(CardType.ARTIFACT) .withSubType(SubType.CONSTRUCT) - .withAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetBasePowerToughnessSourceEffect(count, count, Duration.WhileOnBattlefield, SubLayer.SetPT_7b))), + .withAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetBasePowerToughnessSourceEffect(count, Duration.WhileOnBattlefield))), CardType.ARTIFACT, Duration.EndOfTurn).withDurationRuleAtStart(true), new GenericManaCost(1))); } diff --git a/Mage.Sets/src/mage/cards/d/DruidClass.java b/Mage.Sets/src/mage/cards/d/DruidClass.java index 04c24492394..48a54994abf 100644 --- a/Mage.Sets/src/mage/cards/d/DruidClass.java +++ b/Mage.Sets/src/mage/cards/d/DruidClass.java @@ -78,7 +78,7 @@ class DruidClassToken extends TokenImpl { this.addAbility(HasteAbility.getInstance()); this.addAbility(new SimpleStaticAbility(new SetBasePowerToughnessSourceEffect( - LandsYouControlCount.instance, LandsYouControlCount.instance, Duration.EndOfGame, SubLayer.SetPT_7b + LandsYouControlCount.instance, Duration.EndOfGame ).setText("this creature's power and toughness are each equal to the number of lands you control"))); } diff --git a/Mage.Sets/src/mage/cards/e/EntropicSpecter.java b/Mage.Sets/src/mage/cards/e/EntropicSpecter.java index 8814a842773..747ea0ef1c6 100644 --- a/Mage.Sets/src/mage/cards/e/EntropicSpecter.java +++ b/Mage.Sets/src/mage/cards/e/EntropicSpecter.java @@ -1,4 +1,3 @@ - package mage.cards.e; import mage.MageInt; @@ -42,9 +41,7 @@ public final class EntropicSpecter extends CardImpl { // Entropic Specter's power and toughness are each equal to the number of cards in the chosen player's hand. this.addAbility(new SimpleStaticAbility(Zone.ALL, // back to the graveyard or if the chosen player left the game it's again a 0/0 - new SetBasePowerToughnessSourceEffect(CardsInTargetPlayerHandCount.instance, CardsInTargetPlayerHandCount.instance, - Duration.WhileOnBattlefield, SubLayer.SetPT_7b) - .setText("{this}'s power and toughness are each equal to the number of cards in the chosen player's hand"))); + new SetBasePowerToughnessSourceEffect(CardsInTargetPlayerHandCount.instance, Duration.WhileOnBattlefield))); // Whenever Entropic Specter deals damage to a player, that player discards a card. this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new DiscardTargetEffect(1, false), false, true)); diff --git a/Mage.Sets/src/mage/cards/g/Gigantoplasm.java b/Mage.Sets/src/mage/cards/g/Gigantoplasm.java index 485f95d4f93..c7e57502f06 100644 --- a/Mage.Sets/src/mage/cards/g/Gigantoplasm.java +++ b/Mage.Sets/src/mage/cards/g/Gigantoplasm.java @@ -1,4 +1,3 @@ - package mage.cards.g; import java.util.UUID; @@ -8,7 +7,6 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; @@ -18,7 +16,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; -import mage.constants.SubLayer; import mage.constants.Zone; import mage.filter.StaticFilters; import mage.game.Game; @@ -56,8 +53,7 @@ class GigantoplasmCopyApplier extends CopyApplier { @Override public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) { - DynamicValue variableMana = ManacostVariableValue.REGULAR; - Effect effect = new SetBasePowerToughnessSourceEffect(variableMana, variableMana, Duration.WhileOnBattlefield, SubLayer.SetPT_7b); + Effect effect = new SetBasePowerToughnessSourceEffect(ManacostVariableValue.REGULAR, Duration.WhileOnBattlefield); effect.setText("This creature has base power and toughness X/X"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{X}")); blueprint.getAbilities().add(ability); diff --git a/Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java b/Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java index 1f621495cb3..159d5b78b4d 100644 --- a/Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java +++ b/Mage.Sets/src/mage/cards/m/MinionOfTheWastes.java @@ -35,7 +35,7 @@ public final class MinionOfTheWastes extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); - // As Minion of the Wastes enters the battlefield, pay any amount of life. The amount you pay can't be more than the total number of white nontoken permanents your opponents control plus the total number of white cards in their graveyards. + // As Minion of the Wastes enters the battlefield, pay any amount of life. this.addAbility(new AsEntersBattlefieldAbility(new MinionOfTheWastesEffect())); // Minion of the Wastes's power and toughness are each equal to the life paid as it entered the battlefield. diff --git a/Mage.Sets/src/mage/cards/m/MythRealized.java b/Mage.Sets/src/mage/cards/m/MythRealized.java index c87dd76f304..430e3df8fa4 100644 --- a/Mage.Sets/src/mage/cards/m/MythRealized.java +++ b/Mage.Sets/src/mage/cards/m/MythRealized.java @@ -40,7 +40,8 @@ public final class MythRealized extends CardImpl { // {W}: Until end of turn, Myth Realized becomes a Monk Avatar creature in addition to its other types and gains "This creature's power and toughness are each equal to the number of lore counters on it." Effect effect = new BecomesCreatureSourceEffect(new MythRealizedToken(), CardType.ENCHANTMENT, Duration.EndOfTurn).withDurationRuleAtStart(true); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{W}")); - ability.addEffect(new SetBasePowerToughnessSourceEffect(loreCounterCount, loreCounterCount, Duration.EndOfTurn, SubLayer.SetPT_7b).setText("and gains \"This creature's power and toughness are each equal to the number of lore counters on it.\"")); + ability.addEffect(new SetBasePowerToughnessSourceEffect(loreCounterCount, Duration.EndOfTurn) + .setText("and gains \"This creature's power and toughness are each equal to the number of lore counters on it.\"")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SvogthosTheRestlessTomb.java b/Mage.Sets/src/mage/cards/s/SvogthosTheRestlessTomb.java index 59d9ca960d2..7d369e51159 100644 --- a/Mage.Sets/src/mage/cards/s/SvogthosTheRestlessTomb.java +++ b/Mage.Sets/src/mage/cards/s/SvogthosTheRestlessTomb.java @@ -55,7 +55,7 @@ class SvogthosToken extends TokenImpl { power = new MageInt(0); toughness = new MageInt(0); CardsInControllerGraveyardCount count = new CardsInControllerGraveyardCount(new FilterCreatureCard("creature cards")); - this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(count, count, Duration.WhileOnBattlefield, SubLayer.SetPT_7b))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(count, Duration.WhileOnBattlefield))); } public SvogthosToken(final SvogthosToken token) { super(token); diff --git a/Mage.Sets/src/mage/cards/t/TestamentOfFaith.java b/Mage.Sets/src/mage/cards/t/TestamentOfFaith.java index 38010f817b0..e51181c82e0 100644 --- a/Mage.Sets/src/mage/cards/t/TestamentOfFaith.java +++ b/Mage.Sets/src/mage/cards/t/TestamentOfFaith.java @@ -27,7 +27,7 @@ public final class TestamentOfFaith extends CardImpl { // {X}: Testament of Faith becomes an X/X Wall creature with defender in addition to its other types until end of turn. Ability ability = new SimpleActivatedAbility(new SetBasePowerToughnessSourceEffect( - ManacostVariableValue.REGULAR, ManacostVariableValue.REGULAR, Duration.EndOfTurn, SubLayer.SetPT_7b + ManacostVariableValue.REGULAR, Duration.EndOfTurn ).setText("{this} becomes an X/X"), new VariableManaCost(VariableCostType.NORMAL)); ability.addEffect(new TestamentOfFaithEffect()); ability.addEffect(new GainAbilitySourceEffect( diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java index b11a81cddde..72eed3ff1a8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java @@ -20,11 +20,11 @@ public class SetBasePowerToughnessSourceEffect extends ContinuousEffectImpl { private final DynamicValue toughness; /** - * Note: Need to set text manually if calling this constructor directly. - *

- * It is possible to have power or toughness to null, in which case only the other is modified. + * This constructor is called by the other more specific constructors which set text for appropriate usages. + * @param power can be null, if only toughness is to be modified + * @param toughness can be null, if only power is to be modified */ - public SetBasePowerToughnessSourceEffect(DynamicValue power, DynamicValue toughness, Duration duration, SubLayer subLayer) { + protected SetBasePowerToughnessSourceEffect(DynamicValue power, DynamicValue toughness, Duration duration, SubLayer subLayer) { super(duration, Layer.PTChangingEffects_7, subLayer, Outcome.BoostCreature); setCharacterDefining(subLayer == SubLayer.CharacteristicDefining_7a); this.power = power; @@ -39,6 +39,19 @@ public class SetBasePowerToughnessSourceEffect extends ContinuousEffectImpl { this.staticText = "{this}'s power and toughness are each equal to the number of " + amount.getMessage(); } + /** + * @param amount Power and toughness to set in layer 7b + * @param duration Duration for the effect + */ + public SetBasePowerToughnessSourceEffect(DynamicValue amount, Duration duration) { + this(amount, amount, duration, SubLayer.SetPT_7b); + if (duration.toString().isEmpty()) { + staticText = "{this}'s power and toughness are each equal to the number of " + amount.getMessage(); + } else { + staticText = "{this} has base power and toughness each equal to the number of " + amount.getMessage() + " " + duration; + } + } + public SetBasePowerToughnessSourceEffect(int power, int toughness, Duration duration) { this(StaticValue.get(power), StaticValue.get(toughness), duration, SubLayer.SetPT_7b); this.staticText = "{this} has base power and toughness " + power + '/' + toughness + ' ' + duration.toString(); From 76eb8882b0c1485b8c91e122cb509ec4cb81bb01 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sun, 27 Aug 2023 00:06:13 -0400 Subject: [PATCH 06/10] fix some Duration.WhileOnBattlefield -> Duration.Custom --- Mage.Sets/src/mage/cards/a/AscendantSpirit.java | 2 +- Mage.Sets/src/mage/cards/e/ElvishImpersonators.java | 2 +- Mage.Sets/src/mage/cards/g/Gigantoplasm.java | 2 +- Mage.Sets/src/mage/cards/r/RiptideMangler.java | 2 +- Mage.Sets/src/mage/cards/s/Sentinel.java | 2 +- Mage.Sets/src/mage/cards/w/WallOfTombstones.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AscendantSpirit.java b/Mage.Sets/src/mage/cards/a/AscendantSpirit.java index c70ec869315..1276c73dbf7 100644 --- a/Mage.Sets/src/mage/cards/a/AscendantSpirit.java +++ b/Mage.Sets/src/mage/cards/a/AscendantSpirit.java @@ -39,7 +39,7 @@ public final class AscendantSpirit extends CardImpl { ability.addEffect(new SetBasePowerToughnessSourceEffect( 2, 3, - Duration.WhileOnBattlefield + Duration.Custom ).setText("with base power and toughness 2/3")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/e/ElvishImpersonators.java b/Mage.Sets/src/mage/cards/e/ElvishImpersonators.java index 7270a5e6b39..1d86986889f 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishImpersonators.java +++ b/Mage.Sets/src/mage/cards/e/ElvishImpersonators.java @@ -65,7 +65,7 @@ class ElvishImpersonatorsEffect extends OneShotEffect { List results = controller.rollDice(outcome, source, game, 6, 2, 0); int firstRoll = results.get(0); int secondRoll = results.get(1); - game.addEffect(new SetBasePowerToughnessSourceEffect(firstRoll, secondRoll, Duration.WhileOnBattlefield), source); + game.addEffect(new SetBasePowerToughnessSourceEffect(firstRoll, secondRoll, Duration.Custom), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/g/Gigantoplasm.java b/Mage.Sets/src/mage/cards/g/Gigantoplasm.java index c7e57502f06..185895b6cfc 100644 --- a/Mage.Sets/src/mage/cards/g/Gigantoplasm.java +++ b/Mage.Sets/src/mage/cards/g/Gigantoplasm.java @@ -53,7 +53,7 @@ class GigantoplasmCopyApplier extends CopyApplier { @Override public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) { - Effect effect = new SetBasePowerToughnessSourceEffect(ManacostVariableValue.REGULAR, Duration.WhileOnBattlefield); + Effect effect = new SetBasePowerToughnessSourceEffect(ManacostVariableValue.REGULAR, Duration.Custom); effect.setText("This creature has base power and toughness X/X"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{X}")); blueprint.getAbilities().add(ability); diff --git a/Mage.Sets/src/mage/cards/r/RiptideMangler.java b/Mage.Sets/src/mage/cards/r/RiptideMangler.java index 9e3164389d8..943f2c3046f 100644 --- a/Mage.Sets/src/mage/cards/r/RiptideMangler.java +++ b/Mage.Sets/src/mage/cards/r/RiptideMangler.java @@ -69,7 +69,7 @@ class RiptideManglerEffect extends OneShotEffect { if (permanent == null) { return false; } - game.addEffect(new SetBasePowerSourceEffect(permanent.getPower().getValue(), Duration.WhileOnBattlefield), source); + game.addEffect(new SetBasePowerSourceEffect(permanent.getPower().getValue(), Duration.Custom), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/s/Sentinel.java b/Mage.Sets/src/mage/cards/s/Sentinel.java index a76c0cdb24b..7d4bb421f18 100644 --- a/Mage.Sets/src/mage/cards/s/Sentinel.java +++ b/Mage.Sets/src/mage/cards/s/Sentinel.java @@ -76,7 +76,7 @@ class SentinelEffect extends OneShotEffect { Permanent targetPermanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); if (controller != null && targetPermanent != null) { int newToughness = CardUtil.overflowInc(targetPermanent.getPower().getValue(), 1); - game.addEffect(new SetBaseToughnessSourceEffect(newToughness, Duration.WhileOnBattlefield), source); + game.addEffect(new SetBaseToughnessSourceEffect(newToughness, Duration.Custom), source); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/w/WallOfTombstones.java b/Mage.Sets/src/mage/cards/w/WallOfTombstones.java index 51ab1d0c411..865ba548cc1 100644 --- a/Mage.Sets/src/mage/cards/w/WallOfTombstones.java +++ b/Mage.Sets/src/mage/cards/w/WallOfTombstones.java @@ -64,7 +64,7 @@ class WallOfTombstonesEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int newToughness = CardUtil.overflowInc(1, new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE).calculate(game, source, this)); - game.addEffect(new SetBaseToughnessSourceEffect(newToughness, Duration.WhileOnBattlefield), source); + game.addEffect(new SetBaseToughnessSourceEffect(newToughness, Duration.Custom), source); return true; } } From f72f88cb3502e9c7d757d4d6c7dde0a2ab232282 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sun, 23 Jul 2023 19:09:14 -0400 Subject: [PATCH 07/10] tests for Primal Clay and friends (current implementation is workaround) --- .../entersBattlefield/PrimalClayTest.java | 287 ++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/replacement/entersBattlefield/PrimalClayTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/entersBattlefield/PrimalClayTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/entersBattlefield/PrimalClayTest.java new file mode 100644 index 00000000000..5a7851df73e --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/entersBattlefield/PrimalClayTest.java @@ -0,0 +1,287 @@ +package org.mage.test.cards.replacement.entersBattlefield; + +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.constants.PhaseStep; +import mage.constants.SubType; +import mage.constants.Zone; +import org.junit.Ignore; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author xenohedron + */ +public class PrimalClayTest extends CardTestPlayerBase { + + private static final String clay = "Primal Clay"; + // As Primal Clay enters the battlefield, it becomes your choice of a 3/3 artifact creature, a 2/2 artifact creature + // with flying, or a 1/6 Wall artifact creature with defender in addition to its other types. + private static final String plasma = "Primal Plasma"; + // As Primal Plasma enters the battlefield, it becomes your choice of a 3/3 creature, a 2/2 creature with flying, + // or a 1/6 creature with defender. + private static final String sentry = "Molten Sentry"; + // As Molten Sentry enters the battlefield, flip a coin. If the coin comes up heads, Molten Sentry enters the battlefield + // as a 5/2 creature with haste. If it comes up tails, Molten Sentry enters the battlefield as a 2/5 creature with defender. + private static final String aquamorph = "Aquamorph Entity"; + // As Aquamorph Entity enters the battlefield or is turned face up, it becomes your choice of 5/1 or 1/5. + private static final String tunnel = "Tunnel"; + // Destroy target Wall. It can't be regenerated. + private static final String clone = "Clone"; + // You may have Clone enter the battlefield as a copy of any creature on the battlefield. + private static final String cryptoplasm = "Cryptoplasm"; + // At the beginning of your upkeep, you may have Cryptoplasm become a copy of another target creature, except it has this ability. + private static final String cloudshift = "Cloudshift"; + // Exile target creature you control, then return that card to the battlefield under your control. + + @Test + public void testClayPTSet() { + addCard(Zone.HAND, playerA, clay); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, clay); + setChoice(playerA, "a 3/3 artifact creature"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, clay, 3, 3); + } + + @Test + public void testClayAbilityGained() { + addCard(Zone.HAND, playerA, clay); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, clay); + setChoice(playerA, "a 2/2 artifact creature with flying"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, clay, 2, 2); + assertAbility(playerA, clay, FlyingAbility.getInstance(), true); + } + + @Test + @Ignore("current workaround implementation doesn't account for this") + public void testClaySubtypeGained() { + addCard(Zone.HAND, playerA, clay); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, clay); + setChoice(playerA, "a 1/6 Wall artifact creature with defender"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, clay, 1, 6); + assertAbility(playerA, clay, DefenderAbility.getInstance(), true); + assertSubtype(clay, SubType.WALL); + } + + @Test + public void testClayCopyPTOnBattlefield() { + addCard(Zone.HAND, playerA, clay); + addCard(Zone.HAND, playerA, cryptoplasm); + addCard(Zone.BATTLEFIELD, playerA, "Island", 7); + addCard(Zone.BATTLEFIELD, playerB, "Plains", 3); + addCard(Zone.HAND, playerB, "The Battle of Bywater", 1); + // Destroy all creatures with power 3 or greater. Then create a Food token for each creature you control. + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, clay); + setChoice(playerA, "a 3/3 artifact creature"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cryptoplasm); + + // cryptoplasm trigger at next upkeep + setChoice(playerA, true); // whether to copy + addTarget(playerA, clay); // what to copy + + castSpell(4, PhaseStep.PRECOMBAT_MAIN, playerB, "The Battle of Bywater"); + // since cryptoplasm now a 3/3, both are destroyed + + setStrictChooseMode(true); + setStopAt(4, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertGraveyardCount(playerA, clay, 1); + assertGraveyardCount(playerA, cryptoplasm, 1); + } + + @Ignore("Chosen characteristics of Primal Clay should be copiable values") + @Test + public void testClayCopySubtypeOnBattlefield() { + addCard(Zone.HAND, playerA, clay); + addCard(Zone.HAND, playerA, cryptoplasm); + addCard(Zone.BATTLEFIELD, playerA, "Island", 7); + addCard(Zone.HAND, playerB, tunnel, 2); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, clay); + setChoice(playerA, "a 1/6 Wall artifact creature with defender"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cryptoplasm); + + // cryptoplasm trigger at next upkeep + setChoice(playerA, true); // whether to copy + addTarget(playerA, clay); // what to copy + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerB, tunnel, clay); + waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN); + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerB, tunnel, clay); + + setStrictChooseMode(true); + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, clay, 1); + assertGraveyardCount(playerA, cryptoplasm, 1); + } + + @Test + public void testPlasmaClone() { + addCard(Zone.HAND, playerA, plasma); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.HAND, playerB, clone); + addCard(Zone.BATTLEFIELD, playerB, "Island", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, plasma); + setChoice(playerA, "a 1/6 creature with defender"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, clone); + setChoice(playerB, true); // whether to copy + setChoice(playerB, plasma); // what to copy + setChoice(playerB, "a 2/2 creature with flying"); // new choice as ETB + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, plasma, 1, 6); + assertPowerToughness(playerB, plasma, 2, 2); + assertAbility(playerB, plasma, FlyingAbility.getInstance(), true); + //assertAbility(playerB, plasma, DefenderAbility.getInstance(), true); TODO: this is a copiable value + } + + @Test + public void testMoltenSentryClone() { + addCard(Zone.HAND, playerA, sentry); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); + addCard(Zone.HAND, playerB, clone); + addCard(Zone.BATTLEFIELD, playerB, "Island", 4); + + setFlipCoinResult(playerA, true); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sentry); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, clone); + setChoice(playerB, true); // whether to copy + setFlipCoinResult(playerB, false); + setChoice(playerB, sentry); // what to copy + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, sentry, 5, 2); + assertAbility(playerA, sentry, HasteAbility.getInstance(), true); + assertPowerToughness(playerB, sentry, 2, 5); + assertAbility(playerB, sentry, DefenderAbility.getInstance(), true); + } + + @Test + public void testAquamorphEntityETB() { + addCard(Zone.HAND, playerA, aquamorph); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aquamorph); + setChoice(playerA, false); // not using morph + setChoice(playerA, "a 5/1 creature"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, aquamorph, 5, 1); + } + + @Test + public void testAquamorphEntityUnmorph() { + addCard(Zone.HAND, playerA, aquamorph); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 6); + addCard(Zone.HAND, playerA, "Island"); + addCard(Zone.HAND, playerA, "Savage Swipe", 1); + // Target creature you control gets +2/+2 until end of turn if its power is 2. Then it fights target creature you don’t control. + addCard(Zone.BATTLEFIELD, playerB, "Siege Mastodon", 1); // 3/5 creature for fighting + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aquamorph); + setChoice(playerA, true); // cast facedown as 2/2 + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Savage Swipe"); + addTarget(playerA, ""); // morph + addTarget(playerA, "Siege Mastodon"); + // 2/2 becomes 4/4, fights 3/5, neither dies + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Island"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}{U}: Turn"); // unmorph + setChoice(playerA, "a 1/5 creature"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, aquamorph, 1 + 2, 5 + 2); + assertDamageReceived(playerA, aquamorph, 3); + assertDamageReceived(playerB, "Siege Mastodon", 4); + } + + @Test + public void testClayFlicker() { + addCard(Zone.HAND, playerA, clay); + addCard(Zone.HAND, playerA, cloudshift); + addCard(Zone.BATTLEFIELD, playerA, "Waterkin Shaman"); + // 2/1; Whenever a creature with flying enters the battlefield under your control, Waterkin Shaman gets +1/+1 until end of turn. + addCard(Zone.BATTLEFIELD, playerA, "Plains", 5); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, clay); + setChoice(playerA, "a 2/2 artifact creature with flying"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cloudshift, clay); + setChoice(playerA, "a 3/3 artifact creature"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, clay, 3, 3); + assertPowerToughness(playerA, "Waterkin Shaman", 2 + 1, 1 + 1); + assertAbility(playerA, clay, FlyingAbility.getInstance(), false); + } + + @Test + public void testClayFlickerWall() { + addCard(Zone.HAND, playerA, clay); + addCard(Zone.HAND, playerA, cloudshift); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 5); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, clay); + setChoice(playerA, "a 1/6 artifact creature with defender"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cloudshift, clay); + setChoice(playerA, "a 3/3 artifact creature"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, clay, 3, 3); + assertNotSubtype(clay, SubType.WALL); + } + +} From 476136b7661b6f57dfc9203ddc3e4a21d0d4fd92 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sun, 27 Aug 2023 00:28:37 -0400 Subject: [PATCH 08/10] add logic to check zcc --- .../continuous/SetBasePowerToughnessSourceEffect.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java index 72eed3ff1a8..24970e7b122 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java @@ -72,13 +72,14 @@ public class SetBasePowerToughnessSourceEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { - if (duration == Duration.Custom || isTemporary()) { - mageObject = game.getPermanent(source.getSourceId()); - } else { + if (this.characterDefining || this.duration == Duration.WhileOnBattlefield) { + // Duration is a workaround for Primal Clay and similar which are incorrectly implemented mageObject = game.getObject(source); + } else { + mageObject = source.getSourcePermanentIfItStillExists(game); } } - if (mageObject == null || (power == null && toughness == null)) { + if (mageObject == null) { discard(); return false; } From a427406d5fc5c0927b48ce6761ceb14e0181381f Mon Sep 17 00:00:00 2001 From: xenohedron Date: Tue, 29 Aug 2023 23:33:59 -0400 Subject: [PATCH 09/10] fix Sutured Ghoul --- Mage.Sets/src/mage/cards/s/SuturedGhoul.java | 19 ++++++++----------- .../SetBasePowerToughnessSourceEffect.java | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SuturedGhoul.java b/Mage.Sets/src/mage/cards/s/SuturedGhoul.java index a910577a8f8..888c9eb249b 100644 --- a/Mage.Sets/src/mage/cards/s/SuturedGhoul.java +++ b/Mage.Sets/src/mage/cards/s/SuturedGhoul.java @@ -8,7 +8,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -27,13 +27,10 @@ import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; /** - * @author nantuko + * @author nantuko, xenohedron */ public final class SuturedGhoul extends CardImpl { - private static final String staticText = "exile any number of creature cards from your graveyard"; - private static final String staticText2 = "Sutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness"; - public SuturedGhoul(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}{B}"); this.subtype.add(SubType.ZOMBIE); @@ -44,12 +41,12 @@ public final class SuturedGhoul extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // As Sutured Ghoul enters the battlefield, exile any number of creature cards from your graveyard. - this.addAbility(new AsEntersBattlefieldAbility(new SuturedGhoulEffect(), staticText)); + this.addAbility(new AsEntersBattlefieldAbility(new SuturedGhoulEffect())); // Sutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. - BoostSourceEffect effect = new BoostSourceEffect(SuturedGhoulPowerCount.instance, SuturedGhoulToughnessCount.instance, Duration.WhileOnBattlefield); - effect.setText(staticText2); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + this.addAbility(new SimpleStaticAbility(new SetBasePowerToughnessSourceEffect( + SuturedGhoulPowerCount.instance, SuturedGhoulToughnessCount.instance, Duration.WhileOnBattlefield, + "{this}'s power is equal to the total power of the exiled cards and its toughness is equal to their total toughness"))); } private SuturedGhoul(final SuturedGhoul card) { @@ -64,12 +61,12 @@ public final class SuturedGhoul extends CardImpl { class SuturedGhoulEffect extends OneShotEffect { - public SuturedGhoulEffect() { + SuturedGhoulEffect() { super(Outcome.Benefit); staticText = "exile any number of creature cards from your graveyard"; } - public SuturedGhoulEffect(SuturedGhoulEffect effect) { + private SuturedGhoulEffect(final SuturedGhoulEffect effect) { super(effect); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java index 24970e7b122..b6e2803ac1f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetBasePowerToughnessSourceEffect.java @@ -52,6 +52,22 @@ public class SetBasePowerToughnessSourceEffect extends ContinuousEffectImpl { } } + /** + * @param power set in layer 7b + * @param toughness set in layer 7b + * @param duration Duration for the effect + * @param text Text to set as staticText + */ + public SetBasePowerToughnessSourceEffect(DynamicValue power, DynamicValue toughness, Duration duration, String text) { + this(power, toughness, duration, SubLayer.SetPT_7b); + this.staticText = text; + } + + /** + * @param power set in layer 7b + * @param toughness set in layer 7b + * @param duration Duration for the effect + */ public SetBasePowerToughnessSourceEffect(int power, int toughness, Duration duration) { this(StaticValue.get(power), StaticValue.get(toughness), duration, SubLayer.SetPT_7b); this.staticText = "{this} has base power and toughness " + power + '/' + toughness + ' ' + duration.toString(); From d0d708ba52d5222ced41c8c504f834004faa07d0 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Wed, 30 Aug 2023 19:52:44 -0400 Subject: [PATCH 10/10] Add tests --- .../cards/continuous/SetBasePTSourceTest.java | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/continuous/SetBasePTSourceTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SetBasePTSourceTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SetBasePTSourceTest.java new file mode 100644 index 00000000000..49538f0ce72 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SetBasePTSourceTest.java @@ -0,0 +1,161 @@ +package org.mage.test.cards.continuous; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * Check that effects setting base power/toughness work properly, including CDA and 7b with duration + * + * @author xenohedron + */ +public class SetBasePTSourceTest extends CardTestPlayerBase { + + @Test + public void testCDAsetPT() { + String rootless = "Rootless Yew"; // 3GG 5/4 + // When Rootless Yew dies, search your library for a creature card with power or toughness 6 or greater, + // reveal it, put it into your hand, then shuffle. + String enigma = "Enigma Drake"; // 1UR */4 + // Enigma Drake's power is equal to the number of instant and sorcery cards in your graveyard. + String kami = "Traproot Kami"; // G 0/* + // Traproot Kami’s toughness is equal to the number of Forests on the battlefield. + + setStrictChooseMode(true); + addCard(Zone.LIBRARY, playerA, enigma); + addCard(Zone.GRAVEYARD, playerA, "Shock", 6); + addCard(Zone.BATTLEFIELD, playerA, rootless); + addCard(Zone.BATTLEFIELD, playerA, "Tarmogoyf"); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + addCard(Zone.BATTLEFIELD, playerA, kami); + addCard(Zone.BATTLEFIELD, playerA, "Visara the Dreadful"); + + // Activate Visara to trigger dies ability and search. CDA must apply in all zones. + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Destroy target", rootless); + addTarget(playerA, enigma); // power 6 due to 6 instants in graveyard + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertHandCount(playerA, enigma, 1); + assertGraveyardCount(playerA, rootless, 1); + assertPowerToughness(playerA, kami, 0, 3); // 3 forests + assertPowerToughness(playerA, "Tarmogoyf", 2, 3); // Instant and creature + } + + @Test + public void testLayer7b() { + String mimic = "Battlegate Mimic"; // {1}{R/W} 2/1 + // Whenever you cast a spell that’s both red and white, Battlegate Mimic has base power and toughness 4/2 + // until end of turn and gains first strike until end of turn. + String figure = "Figure of Destiny"; // {R/W} 1/1 + // {R/W}: Figure of Destiny becomes a Kithkin Spirit with base power and toughness 2/2. + // {R/W}{R/W}{R/W}: If Figure of Destiny is a Spirit, it becomes a Kithkin Spirit Warrior with base power and toughness 4/4. + // {R/W}{R/W}{R/W}{R/W}{R/W}{R/W}: If Figure of Destiny is a Warrior, it becomes a Kithkin Spirit Warrior Avatar + // with base power and toughness 8/8, flying, and first strike. + String cloudshift = "Cloudshift"; // {W} Instant + // Exile target creature you control, then return that card to the battlefield under your control. + + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 10); + addCard(Zone.BATTLEFIELD, playerA, mimic); + addCard(Zone.HAND, playerA, figure); + addCard(Zone.HAND, playerA, cloudshift, 2); + addCard(Zone.HAND, playerA, "Double Cleave"); // {1}{R/W} Instant + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, figure); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, mimic, 4, 2); + assertPowerToughness(playerA, figure,1, 1); + + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R/W}: "); + waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R/W}{R/W}{R/W}: "); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPowerToughness(playerA, mimic, 4, 2); + assertPowerToughness(playerA, figure,4, 4); + + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertPowerToughness(playerA, mimic, 2, 1); + assertPowerToughness(playerA, figure,4, 4); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Double Cleave", mimic); + waitStackResolved(2, PhaseStep.PRECOMBAT_MAIN); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, cloudshift, figure); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, mimic, 4, 2); + assertPowerToughness(playerA, figure, 1, 1); + + castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, cloudshift, mimic); + waitStackResolved(2, PhaseStep.POSTCOMBAT_MAIN); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R/W}: "); + + setStopAt(2, PhaseStep.END_TURN); + execute(); + + assertPowerToughness(playerA, mimic, 2, 1); + assertPowerToughness(playerA, figure, 2, 2); + } + + @Test + public void testSvogthos() { + String svogthos = "Svogthos, the Restless Tomb"; // Land + // {3}{B}{G}: Until end of turn, Svogthos, the Restless Tomb becomes a black and green Plant Zombie creature with + // "This creature’s power and toughness are each equal to the number of creature cards in your graveyard." It’s still a land. + + setStrictChooseMode(true); + addCard(Zone.GRAVEYARD, playerA, "Walking Corpse", 5); + addCard(Zone.BATTLEFIELD, playerA, svogthos); + addCard(Zone.BATTLEFIELD, playerA, "Bayou", 5); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}{B}{G}: "); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, svogthos, 5, 5); + } + + @Test + public void testSuturedGhoul() { + String ghoul = "Sutured Ghoul"; // 4BBB */* Trample + // As Sutured Ghoul enters the battlefield, exile any number of creature cards from your graveyard. + // Sutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. + String tymaret = "Tymaret, Chosen from Death"; // BB 2/* + // Tymaret's toughness is equal to your devotion to black. + String corpse = "Walking Corpse"; // 1B 2/2 + String bogstomper = "Bogstomper"; // 4BB 6/5 + + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, corpse); + addCard(Zone.GRAVEYARD, playerA, tymaret, 1); + addCard(Zone.GRAVEYARD, playerA, bogstomper, 1); + addCard(Zone.HAND, playerA, ghoul); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ghoul); + addTarget(playerA, tymaret + "^" + bogstomper); + // Total devotion is 3 + 1 so Tymaret has toughness 4 in all zones + // Therefore Sutured Ghoul exiling Tymaret and Bogstomper should have power 2+6 and toughness 4+5 + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerA, tymaret, 1); + assertExileCount(playerA, bogstomper, 1); + assertPowerToughness(playerA, ghoul, 8, 9); + + } + +}