rework partner variants, add tests

This commit is contained in:
theelk801 2025-10-10 13:56:39 -04:00
parent fec3599b73
commit 8375d6b606
13 changed files with 128 additions and 128 deletions

View file

@ -27,8 +27,7 @@ public abstract class AbstractCommander extends Constructed {
private static List<CommanderValidator> validators = Arrays.asList( private static List<CommanderValidator> validators = Arrays.asList(
PartnerValidator.instance, PartnerValidator.instance,
PartnerSurvivorsValidator.instance, PartnerVariantValidator.instance,
PartnerFatherAndSonValidator.instance,
FriendsForeverValidator.instance, FriendsForeverValidator.instance,
PartnerWithValidator.instance, PartnerWithValidator.instance,
ChooseABackgroundValidator.instance, ChooseABackgroundValidator.instance,

View file

@ -6,10 +6,10 @@ import mage.abilities.dynamicvalue.common.ManaSpentToCastCount;
import mage.abilities.effects.common.CastSourceTriggeredAbility; import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.EntersBattlefieldUnderControlOfOpponentOfChoiceEffect; import mage.abilities.effects.common.EntersBattlefieldUnderControlOfOpponentOfChoiceEffect;
import mage.abilities.keyword.PartnerSurvivorsAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.PartnerVariantType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.game.permanent.token.CordycepsInfectedToken; import mage.game.permanent.token.CordycepsInfectedToken;
@ -41,7 +41,7 @@ public final class AbbyMercilessSoldier extends CardImpl {
this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldUnderControlOfOpponentOfChoiceEffect())); this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldUnderControlOfOpponentOfChoiceEffect()));
// Partner--Survivors // Partner--Survivors
this.addAbility(PartnerSurvivorsAbility.getInstance()); this.addAbility(PartnerVariantType.SURVIVORS.makeAbility());
} }
private AbbyMercilessSoldier(final AbbyMercilessSoldier card) { private AbbyMercilessSoldier(final AbbyMercilessSoldier card) {

View file

@ -10,14 +10,10 @@ import mage.abilities.dynamicvalue.common.CountersControllerCount;
import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.discard.DiscardControllerEffect; import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.abilities.keyword.PartnerFatherAndSonAbility;
import mage.abilities.keyword.ReachAbility; import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.counters.CounterType; import mage.counters.CounterType;
import java.util.UUID; import java.util.UUID;
@ -50,7 +46,7 @@ public final class AtreusImpulsiveSon extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// Partner--Father & son // Partner--Father & son
this.addAbility(PartnerFatherAndSonAbility.getInstance()); this.addAbility(PartnerVariantType.FATHER_AND_SON.makeAbility());
} }
private AtreusImpulsiveSon(final AtreusImpulsiveSon card) { private AtreusImpulsiveSon(final AtreusImpulsiveSon card) {

View file

@ -4,7 +4,6 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.PartnerSurvivorsAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
@ -34,7 +33,7 @@ public final class EllieBrickMaster extends CardImpl {
this.addAbility(new EllieBrickMasterTriggeredAbility()); this.addAbility(new EllieBrickMasterTriggeredAbility());
// Partner--Survivors // Partner--Survivors
this.addAbility(PartnerSurvivorsAbility.getInstance()); this.addAbility(PartnerVariantType.SURVIVORS.makeAbility());
} }
private EllieBrickMaster(final EllieBrickMaster card) { private EllieBrickMaster(final EllieBrickMaster card) {

View file

@ -8,13 +8,9 @@ import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.IndestructibleAbility; import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.PartnerSurvivorsAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
@ -44,7 +40,7 @@ public final class EllieVengefulHunter extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// Partner--Survivors // Partner--Survivors
this.addAbility(PartnerSurvivorsAbility.getInstance()); this.addAbility(PartnerVariantType.SURVIVORS.makeAbility());
} }
private EllieVengefulHunter(final EllieVengefulHunter card) { private EllieVengefulHunter(final EllieVengefulHunter card) {

View file

@ -6,10 +6,10 @@ import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.MenaceAbility; import mage.abilities.keyword.MenaceAbility;
import mage.abilities.keyword.PartnerSurvivorsAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.PartnerVariantType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.counters.CounterType; import mage.counters.CounterType;
@ -43,7 +43,7 @@ public final class JoelResoluteSurvivor extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// Partner--Survivors // Partner--Survivors
this.addAbility(PartnerSurvivorsAbility.getInstance()); this.addAbility(PartnerVariantType.SURVIVORS.makeAbility());
} }
private JoelResoluteSurvivor(final JoelResoluteSurvivor card) { private JoelResoluteSurvivor(final JoelResoluteSurvivor card) {

View file

@ -143,6 +143,28 @@ public class CommanderDeckValidationTest extends MageTestPlayerBase {
); );
} }
@Test
public void testPartnerVariants() {
DeckTester deckTester = new DeckTester(new Commander());
deckTester.addMaindeck("Swamp", 98);
deckTester.addSideboard("Ellie, Vengeful Hunter", 1);
deckTester.addSideboard("Joel, Resolute Survivor", 1);
deckTester.validate("You can have two commanders if they both have the same Partner variant");
}
@Test(expected = AssertionError.class)
public void testPartnerVariants2() {
DeckTester deckTester = new DeckTester(new Commander());
deckTester.addMaindeck("Mountain", 98);
deckTester.addSideboard("Ellie, Vengeful Hunter", 1);
deckTester.addSideboard("Atreus, Impulsive Son", 1);
deckTester.validate("You can't have two commanders if they don't have the same Partner variant");
}
@Test() @Test()
public void testVehicles1() { public void testVehicles1() {
DeckTester deckTester = new DeckTester(new Commander()); DeckTester deckTester = new DeckTester(new Commander());

View file

@ -1,38 +0,0 @@
package mage.abilities.keyword;
import mage.abilities.MageSingleton;
import mage.abilities.StaticAbility;
import mage.constants.Zone;
import java.io.ObjectStreamException;
/**
* @author LevelX2
*/
public class PartnerFatherAndSonAbility extends StaticAbility implements MageSingleton {
private static final PartnerFatherAndSonAbility instance = new PartnerFatherAndSonAbility();
private Object readResolve() throws ObjectStreamException {
return instance;
}
public static PartnerFatherAndSonAbility getInstance() {
return instance;
}
private PartnerFatherAndSonAbility() {
super(Zone.BATTLEFIELD, null);
}
@Override
public String getRule() {
return "Partner&mdash;Father & son <i>(You can have two commanders if both have this ability.)</i>";
}
@Override
public PartnerFatherAndSonAbility copy() {
return instance;
}
}

View file

@ -1,38 +0,0 @@
package mage.abilities.keyword;
import mage.abilities.MageSingleton;
import mage.abilities.StaticAbility;
import mage.constants.Zone;
import java.io.ObjectStreamException;
/**
* @author LevelX2
*/
public class PartnerSurvivorsAbility extends StaticAbility implements MageSingleton {
private static final PartnerSurvivorsAbility instance = new PartnerSurvivorsAbility();
private Object readResolve() throws ObjectStreamException {
return instance;
}
public static PartnerSurvivorsAbility getInstance() {
return instance;
}
private PartnerSurvivorsAbility() {
super(Zone.BATTLEFIELD, null);
}
@Override
public String getRule() {
return "Partner&mdash;Survivors <i>(You can have two commanders if both have this ability.)</i>";
}
@Override
public PartnerSurvivorsAbility copy() {
return instance;
}
}

View file

@ -0,0 +1,80 @@
package mage.constants;
import mage.abilities.StaticAbility;
import mage.cards.Card;
import mage.util.CardUtil;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public enum PartnerVariantType {
FATHER_AND_SON("Father & son"),
SURVIVORS("Survivors");
private final String name;
PartnerVariantType(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
public PartnerVariantAbility makeAbility() {
return new PartnerVariantAbility(this);
}
private static Set<PartnerVariantType> getTypes(Card card) {
return CardUtil
.castStream(card.getAbilities(), PartnerVariantAbility.class)
.map(PartnerVariantAbility::getType)
.collect(Collectors.toSet());
}
public static boolean checkCommanders(Card commander1, Card commander2) {
Set<PartnerVariantType> types1 = getTypes(commander1);
if (types1.isEmpty()) {
return false;
}
Set<PartnerVariantType> types2 = getTypes(commander2);
if (types2.isEmpty()) {
return false;
}
types1.retainAll(types2);
return !types1.isEmpty();
}
}
class PartnerVariantAbility extends StaticAbility {
private final PartnerVariantType type;
PartnerVariantAbility(PartnerVariantType type) {
super(Zone.BATTLEFIELD, null);
this.type = type;
}
private PartnerVariantAbility(final PartnerVariantAbility ability) {
super(ability);
this.type = ability.type;
}
@Override
public PartnerVariantAbility copy() {
return new PartnerVariantAbility(this);
}
public PartnerVariantType getType() {
return type;
}
@Override
public String getRule() {
return "Partner&mdash;" + type + " <i>(You can have two commanders if both have this ability.)</i>";
}
}

View file

@ -1,16 +0,0 @@
package mage.util.validation;
import mage.abilities.keyword.PartnerFatherAndSonAbility;
import mage.cards.Card;
/**
* @author TheElk801
*/
public enum PartnerFatherAndSonValidator implements CommanderValidator {
instance;
@Override
public boolean checkPartner(Card commander1, Card commander2) {
return commander1.getAbilities().containsClass(PartnerFatherAndSonAbility.class);
}
}

View file

@ -1,16 +0,0 @@
package mage.util.validation;
import mage.abilities.keyword.PartnerSurvivorsAbility;
import mage.cards.Card;
/**
* @author TheElk801
*/
public enum PartnerSurvivorsValidator implements CommanderValidator {
instance;
@Override
public boolean checkPartner(Card commander1, Card commander2) {
return commander1.getAbilities().containsClass(PartnerSurvivorsAbility.class);
}
}

View file

@ -0,0 +1,16 @@
package mage.util.validation;
import mage.cards.Card;
import mage.constants.PartnerVariantType;
/**
* @author TheElk801
*/
public enum PartnerVariantValidator implements CommanderValidator {
instance;
@Override
public boolean checkPartner(Card commander1, Card commander2) {
return PartnerVariantType.checkCommanders(commander1, commander2);
}
}