Implemented Yorion, Sky Nomad (#6407)

* Implemented Yorion, Sky Nomad

* Implemented Yorion, Sky Nomad (but for real this time)

* updated game creation to use the correct deck size for limited
This commit is contained in:
Evan Kranzler 2020-04-16 08:10:18 -04:00 committed by GitHub
parent 378dfbf89a
commit 8494e98693
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 185 additions and 37 deletions

View file

@ -400,7 +400,7 @@ class TestGame extends GameImpl {
private int numPlayers; private int numPlayers;
public TestGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public TestGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public TestGame(final TestGame game) { public TestGame(final TestGame game) {

View file

@ -151,7 +151,7 @@ public class Brawl extends Constructed {
for (Ability ability : companion.getAbilities()) { for (Ability ability : companion.getAbilities()) {
if (ability instanceof CompanionAbility) { if (ability instanceof CompanionAbility) {
CompanionAbility companionAbility = (CompanionAbility) ability; CompanionAbility companionAbility = (CompanionAbility) ability;
if (!companionAbility.isLegal(cards)) { if (!companionAbility.isLegal(cards, getDeckMinSize())) {
invalid.put(companion.getName(), "Deck invalid for companion"); invalid.put(companion.getName(), "Deck invalid for companion");
valid = false; valid = false;
} }

View file

@ -234,7 +234,7 @@ public class Commander extends Constructed {
for (Ability ability : companion.getAbilities()) { for (Ability ability : companion.getAbilities()) {
if (ability instanceof CompanionAbility) { if (ability instanceof CompanionAbility) {
CompanionAbility companionAbility = (CompanionAbility) ability; CompanionAbility companionAbility = (CompanionAbility) ability;
if (!companionAbility.isLegal(cards)) { if (!companionAbility.isLegal(cards, getDeckMinSize())) {
invalid.put(companion.getName(), "Deck invalid for companion"); invalid.put(companion.getName(), "Deck invalid for companion");
valid = false; valid = false;
} }

View file

@ -158,7 +158,7 @@ public class FreeformCommander extends Constructed {
for (Ability ability : companion.getAbilities()) { for (Ability ability : companion.getAbilities()) {
if (ability instanceof CompanionAbility) { if (ability instanceof CompanionAbility) {
CompanionAbility companionAbility = (CompanionAbility) ability; CompanionAbility companionAbility = (CompanionAbility) ability;
if (!companionAbility.isLegal(cards)) { if (!companionAbility.isLegal(cards, getDeckMinSize())) {
invalid.put(companion.getName(), "Deck invalid for companion"); invalid.put(companion.getName(), "Deck invalid for companion");
valid = false; valid = false;
} }

View file

@ -189,7 +189,7 @@ public class PennyDreadfulCommander extends Constructed {
for (Ability ability : companion.getAbilities()) { for (Ability ability : companion.getAbilities()) {
if (ability instanceof CompanionAbility) { if (ability instanceof CompanionAbility) {
CompanionAbility companionAbility = (CompanionAbility) ability; CompanionAbility companionAbility = (CompanionAbility) ability;
if (!companionAbility.isLegal(cards)) { if (!companionAbility.isLegal(cards, getDeckMinSize())) {
invalid.put(companion.getName(), "Deck invalid for companion"); invalid.put(companion.getName(), "Deck invalid for companion");
valid = false; valid = false;
} }

View file

@ -10,7 +10,7 @@ import mage.game.mulligan.Mulligan;
public class BrawlDuel extends GameCommanderImpl { public class BrawlDuel extends GameCommanderImpl {
public BrawlDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public BrawlDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public BrawlDuel(final BrawlDuel game) { public BrawlDuel(final BrawlDuel game) {

View file

@ -17,7 +17,7 @@ public class BrawlFreeForAll extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public BrawlFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public BrawlFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public BrawlFreeForAll(final BrawlFreeForAll game) { public BrawlFreeForAll(final BrawlFreeForAll game) {

View file

@ -10,7 +10,7 @@ import mage.game.mulligan.Mulligan;
public class CommanderDuel extends GameCommanderImpl { public class CommanderDuel extends GameCommanderImpl {
public CommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public CommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 100);
} }
public CommanderDuel(final CommanderDuel game) { public CommanderDuel(final CommanderDuel game) {

View file

@ -2,14 +2,14 @@
package mage.game; package mage.game;
import java.util.UUID;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.game.match.MatchType; import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class CommanderFreeForAll extends GameCommanderImpl { public class CommanderFreeForAll extends GameCommanderImpl {
@ -17,7 +17,7 @@ public class CommanderFreeForAll extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public CommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public CommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 100);
} }
public CommanderFreeForAll(final CommanderFreeForAll game) { public CommanderFreeForAll(final CommanderFreeForAll game) {
@ -28,7 +28,7 @@ public class CommanderFreeForAll extends GameCommanderImpl {
@Override @Override
protected void init(UUID choosingPlayerId) { protected void init(UUID choosingPlayerId) {
startingPlayerSkipsDraw = false; startingPlayerSkipsDraw = false;
super.init(choosingPlayerId); super.init(choosingPlayerId);
} }
@Override @Override

View file

@ -15,7 +15,7 @@ public class FreeForAll extends GameImpl {
private int numPlayers; private int numPlayers;
public FreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public FreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public FreeForAll(final FreeForAll game) { public FreeForAll(final FreeForAll game) {

View file

@ -11,7 +11,7 @@ import mage.game.mulligan.Mulligan;
public class FreeformCommanderDuel extends GameCommanderImpl { public class FreeformCommanderDuel extends GameCommanderImpl {
public FreeformCommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public FreeformCommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public FreeformCommanderDuel(final FreeformCommanderDuel game) { public FreeformCommanderDuel(final FreeformCommanderDuel game) {

View file

@ -17,7 +17,7 @@ public class FreeformCommanderFreeForAll extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public FreeformCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public FreeformCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public FreeformCommanderFreeForAll(final FreeformCommanderFreeForAll game) { public FreeformCommanderFreeForAll(final FreeformCommanderFreeForAll game) {

View file

@ -24,7 +24,7 @@ import mage.players.Player;
public class MomirDuel extends GameImpl { public class MomirDuel extends GameImpl {
public MomirDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public MomirDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public MomirDuel(final MomirDuel game) { public MomirDuel(final MomirDuel game) {

View file

@ -26,7 +26,7 @@ public class MomirGame extends GameImpl {
private int numPlayers; private int numPlayers;
public MomirGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public MomirGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public MomirGame(final MomirGame game) { public MomirGame(final MomirGame game) {

View file

@ -32,7 +32,7 @@ public class OathbreakerFreeForAll extends GameCommanderImpl {
private static final String COMMANDER_NAME_SIGNATURE_SPELL = "Signature Spell"; private static final String COMMANDER_NAME_SIGNATURE_SPELL = "Signature Spell";
public OathbreakerFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public OathbreakerFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 100);
this.startingPlayerSkipsDraw = false; this.startingPlayerSkipsDraw = false;
} }

View file

@ -17,7 +17,7 @@ public class PennyDreadfulCommanderFreeForAll extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public PennyDreadfulCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public PennyDreadfulCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 60);
} }
public PennyDreadfulCommanderFreeForAll(final PennyDreadfulCommanderFreeForAll game) { public PennyDreadfulCommanderFreeForAll(final PennyDreadfulCommanderFreeForAll game) {

View file

@ -1,4 +1,3 @@
package mage.game; package mage.game;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
@ -13,7 +12,11 @@ import java.util.UUID;
public class TwoPlayerDuel extends GameImpl { public class TwoPlayerDuel extends GameImpl {
public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); this(attackOption, range, mulligan, startLife, 60);
}
public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startingSize) {
super(attackOption, range, mulligan, startLife, startingSize);
} }
public TwoPlayerDuel(final TwoPlayerDuel game) { public TwoPlayerDuel(final TwoPlayerDuel game) {

View file

@ -6,7 +6,6 @@ import mage.game.match.MatchOptions;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class TwoPlayerMatch extends MatchImpl { public class TwoPlayerMatch extends MatchImpl {
@ -18,7 +17,7 @@ public class TwoPlayerMatch extends MatchImpl {
@Override @Override
public void startGame() throws GameException { public void startGame() throws GameException {
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange(), mulligan, 20); TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange(), mulligan, 20, options.isLimited() ? 40 : 60);
// Sets a start message about the match score // Sets a start message about the match score
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);

View file

@ -96,7 +96,7 @@ enum KaheeraTheOrphanguardCompanionCondition implements CompanionCondition {
} }
@Override @Override
public boolean isLegal(Set<Card> deck) { public boolean isLegal(Set<Card> deck, int startingSize) {
return deck.stream() return deck.stream()
.filter(MageObject::isCreature) .filter(MageObject::isCreature)
.allMatch(KaheeraTheOrphanguardCompanionCondition::checkTypes); .allMatch(KaheeraTheOrphanguardCompanionCondition::checkTypes);

View file

@ -66,7 +66,7 @@ enum KerugaCondition implements CompanionCondition {
} }
@Override @Override
public boolean isLegal(Set<Card> deck) { public boolean isLegal(Set<Card> deck, int startingSize) {
return deck.stream().allMatch(card -> card.isLand() || card.getConvertedManaCost() >= 3); return deck.stream().allMatch(card -> card.isLand() || card.getConvertedManaCost() >= 3);
} }
} }

View file

@ -83,7 +83,7 @@ enum LutriTheSpellchaserCompanionCondition implements CompanionCondition {
} }
@Override @Override
public boolean isLegal(Set<Card> deck) { public boolean isLegal(Set<Card> deck, int startingSize) {
Map<String, Integer> cardMap = new HashMap(); Map<String, Integer> cardMap = new HashMap();
deck.stream() deck.stream()
.filter(card -> !card.isLand()) .filter(card -> !card.isLand())

View file

@ -58,7 +58,7 @@ enum OboshThePreypiercerCompanionCondition implements CompanionCondition {
} }
@Override @Override
public boolean isLegal(Set<Card> deck) { public boolean isLegal(Set<Card> deck, int startingSize) {
return deck return deck
.stream() .stream()
.filter(card -> !card.isLand()) .filter(card -> !card.isLand())

View file

@ -64,7 +64,7 @@ enum UmoriCondition implements CompanionCondition {
} }
@Override @Override
public boolean isLegal(Set<Card> deck) { public boolean isLegal(Set<Card> deck, int startingSize) {
Set<CardType> cardTypes = new HashSet<>(); Set<CardType> cardTypes = new HashSet<>();
for (Card card : deck) { for (Card card : deck) {
// Lands are fine. // Lands are fine.

View file

@ -0,0 +1,141 @@
package mage.cards.y;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.keyword.CompanionAbility;
import mage.abilities.keyword.CompanionCondition;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.*;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentMeld;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTargets;
import mage.util.CardUtil;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public final class YorionSkyNomad extends CardImpl {
public YorionSkyNomad(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W/U}{W/U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.BIRD);
this.subtype.add(SubType.SERPENT);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
// Companion Your starting deck contains at least twenty cards more than the minimum deck size.
this.addAbility(new CompanionAbility(YorionSkyNomadCompanionCondition.instance));
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Yorion enters the battlefield, exile any number of other nonland permanents you own and control. Return those cards to the battlefield at the beginning of the next end step.
this.addAbility(new EntersBattlefieldTriggeredAbility(new YorionSkyNomadEffect()));
}
private YorionSkyNomad(final YorionSkyNomad card) {
super(card);
}
@Override
public YorionSkyNomad copy() {
return new YorionSkyNomad(this);
}
}
enum YorionSkyNomadCompanionCondition implements CompanionCondition {
instance;
@Override
public String getRule() {
return "Your starting deck contains at least twenty cards more than the minimum deck size.";
}
@Override
public boolean isLegal(Set<Card> deck, int startingSize) {
return deck.size() >= startingSize + 20;
}
}
class YorionSkyNomadEffect extends OneShotEffect {
private static final FilterPermanent filter
= new FilterControlledPermanent("other nonland permanents you own and control");
static {
filter.add(Predicates.not(CardType.LAND.getPredicate()));
filter.add(TargetController.YOU.getOwnerPredicate());
filter.add(AnotherPredicate.instance);
}
YorionSkyNomadEffect() {
super(Outcome.Benefit);
staticText = "exile any number of other nonland permanents you own and control. " +
"Return those cards to the battlefield at the beginning of the next end step.";
}
private YorionSkyNomadEffect(final YorionSkyNomadEffect effect) {
super(effect);
}
@Override
public YorionSkyNomadEffect copy() {
return new YorionSkyNomadEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (sourceObject == null || controller == null) {
return false;
}
TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true);
controller.choose(outcome, target, source.getSourceId(), game);
Set<Card> toExile = target.getTargets().stream().map(game::getPermanent).collect(Collectors.toSet());
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
Cards cardsToReturn = new CardsImpl();
for (Card exiled : toExile) {
if (exiled instanceof PermanentMeld) {
MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
cardsToReturn.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
cardsToReturn.add(bottomCard);
}
} else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
cardsToReturn.add(exiled);
}
}
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
game.addDelayedTriggeredAbility(delayedAbility, source);
return true;
}
}

View file

@ -324,6 +324,7 @@ public final class IkoriaLairOfBehemoths extends ExpansionSet {
cards.add(new SetCardInfo("Wind-Scarred Crag", 258, Rarity.COMMON, mage.cards.w.WindScarredCrag.class)); cards.add(new SetCardInfo("Wind-Scarred Crag", 258, Rarity.COMMON, mage.cards.w.WindScarredCrag.class));
cards.add(new SetCardInfo("Wingfold Pteron", 71, Rarity.COMMON, mage.cards.w.WingfoldPteron.class)); cards.add(new SetCardInfo("Wingfold Pteron", 71, Rarity.COMMON, mage.cards.w.WingfoldPteron.class));
cards.add(new SetCardInfo("Wingspan Mentor", 72, Rarity.UNCOMMON, mage.cards.w.WingspanMentor.class)); cards.add(new SetCardInfo("Wingspan Mentor", 72, Rarity.UNCOMMON, mage.cards.w.WingspanMentor.class));
cards.add(new SetCardInfo("Yorion, Sky Nomad", 232, Rarity.RARE, mage.cards.y.YorionSkyNomad.class));
cards.add(new SetCardInfo("Winota, Joiner of Forces", 216, Rarity.MYTHIC, mage.cards.w.WinotaJoinerOfForces.class)); cards.add(new SetCardInfo("Winota, Joiner of Forces", 216, Rarity.MYTHIC, mage.cards.w.WinotaJoinerOfForces.class));
cards.add(new SetCardInfo("Yidaro, Wandering Monster", 141, Rarity.RARE, mage.cards.y.YidaroWanderingMonster.class)); cards.add(new SetCardInfo("Yidaro, Wandering Monster", 141, Rarity.RARE, mage.cards.y.YidaroWanderingMonster.class));
cards.add(new SetCardInfo("Zagoth Crystal", 242, Rarity.UNCOMMON, mage.cards.z.ZagothCrystal.class)); cards.add(new SetCardInfo("Zagoth Crystal", 242, Rarity.UNCOMMON, mage.cards.z.ZagothCrystal.class));

View file

@ -34,8 +34,8 @@ public class CompanionAbility extends StaticAbility {
return "Companion &mdash; " + condition.getRule(); return "Companion &mdash; " + condition.getRule();
} }
public boolean isLegal(Set<Card> cards) { public boolean isLegal(Set<Card> cards, int startingSize) {
return condition.isLegal(cards); return condition.isLegal(cards, startingSize);
} }
} }

View file

@ -17,7 +17,8 @@ public interface CompanionCondition extends Serializable {
/** /**
* @param deck The set of cards to check. * @param deck The set of cards to check.
* @param startingSize
* @return Whether the companion is valid for that deck. * @return Whether the companion is valid for that deck.
*/ */
boolean isLegal(Set<Card> deck); boolean isLegal(Set<Card> deck, int startingSize);
} }

View file

@ -12,7 +12,7 @@ import java.util.UUID;
public abstract class GameCanadianHighlanderImpl extends GameImpl { public abstract class GameCanadianHighlanderImpl extends GameImpl {
public GameCanadianHighlanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public GameCanadianHighlanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 100);
} }
public GameCanadianHighlanderImpl(final GameCanadianHighlanderImpl game) { public GameCanadianHighlanderImpl(final GameCanadianHighlanderImpl game) {

View file

@ -31,8 +31,8 @@ public abstract class GameCommanderImpl extends GameImpl {
protected boolean startingPlayerSkipsDraw = true; protected boolean startingPlayerSkipsDraw = true;
public GameCommanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public GameCommanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startingSize) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, startingSize);
} }
public GameCommanderImpl(final GameCommanderImpl game) { public GameCommanderImpl(final GameCommanderImpl game) {

View file

@ -130,6 +130,7 @@ public abstract class GameImpl implements Game, Serializable {
private int priorityTime; private int priorityTime;
private final int startLife; private final int startLife;
private final int startingSize;
protected PlayerList playerList; // auto-generated from state, don't copy protected PlayerList playerList; // auto-generated from state, don't copy
// infinite loop check (no copy of this attributes neccessary) // infinite loop check (no copy of this attributes neccessary)
@ -144,7 +145,7 @@ public abstract class GameImpl implements Game, Serializable {
// temporary store for income concede commands, don't copy // temporary store for income concede commands, don't copy
private final LinkedList<UUID> concedingPlayers = new LinkedList<>(); private final LinkedList<UUID> concedingPlayers = new LinkedList<>();
public GameImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public GameImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startingSize) {
this.id = UUID.randomUUID(); this.id = UUID.randomUUID();
this.range = range; this.range = range;
this.mulligan = mulligan; this.mulligan = mulligan;
@ -152,6 +153,7 @@ public abstract class GameImpl implements Game, Serializable {
this.state = new GameState(); this.state = new GameState();
this.startLife = startLife; this.startLife = startLife;
this.executingRollback = false; this.executingRollback = false;
this.startingSize = startingSize;
initGameDefaultWatchers(); initGameDefaultWatchers();
} }
@ -181,6 +183,7 @@ public abstract class GameImpl implements Game, Serializable {
this.saveGame = game.saveGame; this.saveGame = game.saveGame;
this.startLife = game.startLife; this.startLife = game.startLife;
this.enterWithCounters.putAll(game.enterWithCounters); this.enterWithCounters.putAll(game.enterWithCounters);
this.startingSize = game.startingSize;
} }
@Override @Override
@ -939,7 +942,7 @@ public abstract class GameImpl implements Game, Serializable {
for (Ability ability : card.getAbilities(this)) { for (Ability ability : card.getAbilities(this)) {
if (ability instanceof CompanionAbility) { if (ability instanceof CompanionAbility) {
CompanionAbility companionAbility = (CompanionAbility) ability; CompanionAbility companionAbility = (CompanionAbility) ability;
if (companionAbility.isLegal(new HashSet<>(player.getLibrary().getCards(this)))) { if (companionAbility.isLegal(new HashSet<>(player.getLibrary().getCards(this)), startingSize)) {
potentialCompanions.add(card); potentialCompanions.add(card);
break; break;
} }

View file

@ -32,7 +32,7 @@ public abstract class GameTinyLeadersImpl extends GameImpl {
protected boolean startingPlayerSkipsDraw = true; protected boolean startingPlayerSkipsDraw = true;
public GameTinyLeadersImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public GameTinyLeadersImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, 50);
} }
public GameTinyLeadersImpl(final GameTinyLeadersImpl game) { public GameTinyLeadersImpl(final GameTinyLeadersImpl game) {