Altered ego X value should be separate

This commit is contained in:
Steven Knipe 2023-11-16 18:21:02 -08:00
parent 18600a53a9
commit 177f72c8d8
4 changed files with 41 additions and 7 deletions

View file

@ -6,7 +6,7 @@ import mage.abilities.Ability;
import mage.abilities.common.CantBeCounteredSourceAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.CopyPermanentEffect;
import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -14,6 +14,7 @@ import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.util.CardUtil;
import mage.util.functions.CopyApplier;
import java.util.UUID;
@ -65,11 +66,14 @@ class AlteredEgoCopyApplier extends CopyApplier {
// effect is applied to that object after applying the copy effect with that exception, the
// exceptions effect doesnt happen.
if (!isCopyOfCopy(source, blueprint, copyToObjectId)) {
if (!isCopyOfCopy(source, blueprint, copyToObjectId) && CardUtil.checkSourceCostsTagExists(game, source, "X")) {
// except it enters with an additional X +1/+1 counters on it
blueprint.getAbilities().add(
new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance()))
new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(
(int)CardUtil.getSourceCostsTag(game, source, "X", 0)
)))
);
CardUtil.getSourceCostsTagsMap(game, source).remove("X"); //X value of Altered Ego is separate from the copied creature's X value
}
return true;

View file

@ -53,4 +53,34 @@ public class AlteredEgoTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Altered Ego", 1);
}
/**
* If the chosen creature has {X} in its mana cost, that X is considered to be 0.
* The value of X in Altered Egos last ability will be whatever value was chosen for X while casting Altered Ego.
* (2016-04-08)
*/
@Test
public void copyXCreature() {
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
addCard(Zone.BATTLEFIELD, playerB, "Tropical Island", 7);
addCard(Zone.HAND, playerA, "Endless One"); // {X}, ETB with X +1/+1 counters, 0/0
addCard(Zone.HAND, playerB, "Altered Ego"); // {X}{2}{G}{U}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Endless One");
setChoice(playerA, "X=2");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Altered Ego");
setChoice(playerB, "X=3");
setChoice(playerB, true); // use copy
setChoice(playerB, "Endless One"); // copy target
setChoice(playerB, ""); // Order place counters effects
setStrictChooseMode(true);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Endless One", 1);
assertPowerToughness(playerA, "Endless One", 2, 2);
assertPermanentCount(playerB, "Endless One", 1);
assertPowerToughness(playerB, "Endless One", 3, 3); //The X should not be copied
}
}

View file

@ -130,7 +130,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
* @return
*/
public static int getKickedCounterStrict(Game game, Ability source, String needKickerCost) {
Map<String, Object> costsTags = CardUtil.getSourceCostsTags(game, source);
Map<String, Object> costsTags = CardUtil.getSourceCostsTagsMap(game, source);
if (costsTags == null) {
return 0;
}

View file

@ -1687,7 +1687,7 @@ public final class CardUtil {
* @return the tag map (or null)
*/
//
public static Map<String, Object> getSourceCostsTags(Game game, Ability source) {
public static Map<String, Object> getSourceCostsTagsMap(Game game, Ability source) {
Map<String, Object> costTags;
costTags = source.getCostsTagMap();
if (costTags == null && source.getSourcePermanentOrLKI(game) != null) {
@ -1705,7 +1705,7 @@ public final class CardUtil {
* @return if the tag was found
*/
public static boolean checkSourceCostsTagExists(Game game, Ability source, String tag) {
Map<String, Object> costTags = getSourceCostsTags(game, source);
Map<String, Object> costTags = getSourceCostsTagsMap(game, source);
return costTags != null && costTags.containsKey(tag);
}
/**
@ -1719,7 +1719,7 @@ public final class CardUtil {
* @return The object stored by the tag if found, the default if not
*/
public static Object getSourceCostsTag(Game game, Ability source, String tag, Object defaultValue){
Map<String, Object> costTags = getSourceCostsTags(game, source);
Map<String, Object> costTags = getSourceCostsTagsMap(game, source);
if (costTags != null) {
return costTags.getOrDefault(tag, defaultValue);
}