diff --git a/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java index ad92e560e6..25a5da5b83 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java @@ -400,7 +400,7 @@ class TestGame extends GameImpl { private int numPlayers; 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) { diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java index f62801a02f..e656b53d87 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java @@ -151,7 +151,7 @@ public class Brawl extends Constructed { for (Ability ability : companion.getAbilities()) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (!companionAbility.isLegal(cards)) { + if (!companionAbility.isLegal(cards, getDeckMinSize())) { invalid.put(companion.getName(), "Deck invalid for companion"); valid = false; } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java index 8836549e40..3a9b104f3a 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java @@ -234,7 +234,7 @@ public class Commander extends Constructed { for (Ability ability : companion.getAbilities()) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (!companionAbility.isLegal(cards)) { + if (!companionAbility.isLegal(cards, getDeckMinSize())) { invalid.put(companion.getName(), "Deck invalid for companion"); valid = false; } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java index d53dd54dd6..f66405d36b 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java @@ -158,7 +158,7 @@ public class FreeformCommander extends Constructed { for (Ability ability : companion.getAbilities()) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (!companionAbility.isLegal(cards)) { + if (!companionAbility.isLegal(cards, getDeckMinSize())) { invalid.put(companion.getName(), "Deck invalid for companion"); valid = false; } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java index 967578f66b..ceff69fd1f 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java @@ -189,7 +189,7 @@ public class PennyDreadfulCommander extends Constructed { for (Ability ability : companion.getAbilities()) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (!companionAbility.isLegal(cards)) { + if (!companionAbility.isLegal(cards, getDeckMinSize())) { invalid.put(companion.getName(), "Deck invalid for companion"); valid = false; } diff --git a/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuel.java b/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuel.java index 8aa8ba425e..50ef2e4dab 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuel.java +++ b/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuel.java @@ -10,7 +10,7 @@ import mage.game.mulligan.Mulligan; public class BrawlDuel extends GameCommanderImpl { 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) { diff --git a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/src/mage/game/BrawlFreeForAll.java b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/src/mage/game/BrawlFreeForAll.java index 29cc7f22e0..6b5f1db755 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/src/mage/game/BrawlFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/src/mage/game/BrawlFreeForAll.java @@ -17,7 +17,7 @@ public class BrawlFreeForAll extends GameCommanderImpl { private int numPlayers; 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) { diff --git a/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java b/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java index 6e5df00b82..f8afcb93df 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java +++ b/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java @@ -10,7 +10,7 @@ import mage.game.mulligan.Mulligan; public class CommanderDuel extends GameCommanderImpl { 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) { diff --git a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/src/mage/game/CommanderFreeForAll.java b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/src/mage/game/CommanderFreeForAll.java index 2c1a9e7d18..0192a2c0ad 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/src/mage/game/CommanderFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/src/mage/game/CommanderFreeForAll.java @@ -2,14 +2,14 @@ package mage.game; -import java.util.UUID; import mage.constants.MultiplayerAttackOption; import mage.constants.RangeOfInfluence; import mage.game.match.MatchType; import mage.game.mulligan.Mulligan; +import java.util.UUID; + /** - * * @author LevelX2 */ public class CommanderFreeForAll extends GameCommanderImpl { @@ -17,7 +17,7 @@ public class CommanderFreeForAll extends GameCommanderImpl { private int numPlayers; 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) { @@ -28,7 +28,7 @@ public class CommanderFreeForAll extends GameCommanderImpl { @Override protected void init(UUID choosingPlayerId) { startingPlayerSkipsDraw = false; - super.init(choosingPlayerId); + super.init(choosingPlayerId); } @Override diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java index 44209f3388..2d6b1ab80b 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java @@ -15,7 +15,7 @@ public class FreeForAll extends GameImpl { private int numPlayers; 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) { diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/src/mage/game/FreeformCommanderDuel.java b/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/src/mage/game/FreeformCommanderDuel.java index d57f520f07..eccf1bfcd7 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/src/mage/game/FreeformCommanderDuel.java +++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/src/mage/game/FreeformCommanderDuel.java @@ -11,7 +11,7 @@ import mage.game.mulligan.Mulligan; public class FreeformCommanderDuel extends GameCommanderImpl { 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) { diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/src/mage/game/FreeformCommanderFreeForAll.java b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/src/mage/game/FreeformCommanderFreeForAll.java index 2f9aa0e29f..7638fbe59e 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/src/mage/game/FreeformCommanderFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/src/mage/game/FreeformCommanderFreeForAll.java @@ -17,7 +17,7 @@ public class FreeformCommanderFreeForAll extends GameCommanderImpl { private int numPlayers; 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) { diff --git a/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java b/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java index ac51137df9..cc66fc51df 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java +++ b/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java @@ -24,7 +24,7 @@ import mage.players.Player; public class MomirDuel extends GameImpl { 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) { diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java index 0750d4d7cb..efa5ee8b89 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java @@ -26,7 +26,7 @@ public class MomirGame extends GameImpl { private int numPlayers; 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) { diff --git a/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java b/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java index 7e068208e2..90f673c200 100644 --- a/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java @@ -32,7 +32,7 @@ public class OathbreakerFreeForAll extends GameCommanderImpl { private static final String COMMANDER_NAME_SIGNATURE_SPELL = "Signature Spell"; public OathbreakerFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 100); this.startingPlayerSkipsDraw = false; } diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/src/mage/game/PennyDreadfulCommanderFreeForAll.java b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/src/mage/game/PennyDreadfulCommanderFreeForAll.java index add9c578a9..0f6ea01fae 100644 --- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/src/mage/game/PennyDreadfulCommanderFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/src/mage/game/PennyDreadfulCommanderFreeForAll.java @@ -17,7 +17,7 @@ public class PennyDreadfulCommanderFreeForAll extends GameCommanderImpl { private int numPlayers; 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) { diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java index b5e7f2b334..21f3a61a60 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java @@ -1,4 +1,3 @@ - package mage.game; import mage.constants.MultiplayerAttackOption; @@ -13,7 +12,11 @@ import java.util.UUID; public class TwoPlayerDuel extends GameImpl { 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) { diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java index 9705f03e5d..720ae4fd24 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java @@ -6,7 +6,6 @@ import mage.game.match.MatchOptions; import mage.game.mulligan.Mulligan; /** - * * @author BetaSteward_at_googlemail.com */ public class TwoPlayerMatch extends MatchImpl { @@ -18,7 +17,7 @@ public class TwoPlayerMatch extends MatchImpl { @Override public void startGame() throws GameException { 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 game.setStartMessage(this.createGameStartMessage()); initGame(game); diff --git a/Mage.Sets/src/mage/cards/k/KaheeraTheOrphanguard.java b/Mage.Sets/src/mage/cards/k/KaheeraTheOrphanguard.java index 0fa1715734..d8762ae5f0 100644 --- a/Mage.Sets/src/mage/cards/k/KaheeraTheOrphanguard.java +++ b/Mage.Sets/src/mage/cards/k/KaheeraTheOrphanguard.java @@ -96,7 +96,7 @@ enum KaheeraTheOrphanguardCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck.stream() .filter(MageObject::isCreature) .allMatch(KaheeraTheOrphanguardCompanionCondition::checkTypes); diff --git a/Mage.Sets/src/mage/cards/k/KerugaTheMacrosage.java b/Mage.Sets/src/mage/cards/k/KerugaTheMacrosage.java index 6594ce24a9..a9373bc5b7 100644 --- a/Mage.Sets/src/mage/cards/k/KerugaTheMacrosage.java +++ b/Mage.Sets/src/mage/cards/k/KerugaTheMacrosage.java @@ -66,7 +66,7 @@ enum KerugaCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck.stream().allMatch(card -> card.isLand() || card.getConvertedManaCost() >= 3); } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java b/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java index d0a33d48bf..b1d9545da6 100644 --- a/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java +++ b/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java @@ -83,7 +83,7 @@ enum LutriTheSpellchaserCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { Map cardMap = new HashMap(); deck.stream() .filter(card -> !card.isLand()) diff --git a/Mage.Sets/src/mage/cards/o/OboshThePreypiercer.java b/Mage.Sets/src/mage/cards/o/OboshThePreypiercer.java index da92f2651a..012eb183e0 100644 --- a/Mage.Sets/src/mage/cards/o/OboshThePreypiercer.java +++ b/Mage.Sets/src/mage/cards/o/OboshThePreypiercer.java @@ -58,7 +58,7 @@ enum OboshThePreypiercerCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck .stream() .filter(card -> !card.isLand()) diff --git a/Mage.Sets/src/mage/cards/u/UmoriTheCollector.java b/Mage.Sets/src/mage/cards/u/UmoriTheCollector.java index 7943a5c430..a56cab1d0a 100644 --- a/Mage.Sets/src/mage/cards/u/UmoriTheCollector.java +++ b/Mage.Sets/src/mage/cards/u/UmoriTheCollector.java @@ -64,7 +64,7 @@ enum UmoriCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { Set cardTypes = new HashSet<>(); for (Card card : deck) { // Lands are fine. diff --git a/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java b/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java new file mode 100644 index 0000000000..c7cb415a8b --- /dev/null +++ b/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java @@ -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 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 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; + } +} diff --git a/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java b/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java index 4a1e426d63..3479c3d8a8 100644 --- a/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java +++ b/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java @@ -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("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("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("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)); diff --git a/Mage/src/main/java/mage/abilities/keyword/CompanionAbility.java b/Mage/src/main/java/mage/abilities/keyword/CompanionAbility.java index b4f6ff5eba..cbf32664aa 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CompanionAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CompanionAbility.java @@ -34,8 +34,8 @@ public class CompanionAbility extends StaticAbility { return "Companion — " + condition.getRule(); } - public boolean isLegal(Set cards) { - return condition.isLegal(cards); + public boolean isLegal(Set cards, int startingSize) { + return condition.isLegal(cards, startingSize); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/CompanionCondition.java b/Mage/src/main/java/mage/abilities/keyword/CompanionCondition.java index ce43630cc2..161bd2aad9 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CompanionCondition.java +++ b/Mage/src/main/java/mage/abilities/keyword/CompanionCondition.java @@ -17,7 +17,8 @@ public interface CompanionCondition extends Serializable { /** * @param deck The set of cards to check. + * @param startingSize * @return Whether the companion is valid for that deck. */ - boolean isLegal(Set deck); + boolean isLegal(Set deck, int startingSize); } diff --git a/Mage/src/main/java/mage/game/GameCanadianHighlanderImpl.java b/Mage/src/main/java/mage/game/GameCanadianHighlanderImpl.java index ab7408114a..f306f4cf20 100644 --- a/Mage/src/main/java/mage/game/GameCanadianHighlanderImpl.java +++ b/Mage/src/main/java/mage/game/GameCanadianHighlanderImpl.java @@ -12,7 +12,7 @@ import java.util.UUID; public abstract class GameCanadianHighlanderImpl extends GameImpl { 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) { diff --git a/Mage/src/main/java/mage/game/GameCommanderImpl.java b/Mage/src/main/java/mage/game/GameCommanderImpl.java index 36af5d30f8..31709e2965 100644 --- a/Mage/src/main/java/mage/game/GameCommanderImpl.java +++ b/Mage/src/main/java/mage/game/GameCommanderImpl.java @@ -31,8 +31,8 @@ public abstract class GameCommanderImpl extends GameImpl { protected boolean startingPlayerSkipsDraw = true; - public GameCommanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + public GameCommanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startingSize) { + super(attackOption, range, mulligan, startLife, startingSize); } public GameCommanderImpl(final GameCommanderImpl game) { diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index aa142061b0..96e5059948 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -130,6 +130,7 @@ public abstract class GameImpl implements Game, Serializable { private int priorityTime; private final int startLife; + private final int startingSize; protected PlayerList playerList; // auto-generated from state, don't copy // 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 private final LinkedList 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.range = range; this.mulligan = mulligan; @@ -152,6 +153,7 @@ public abstract class GameImpl implements Game, Serializable { this.state = new GameState(); this.startLife = startLife; this.executingRollback = false; + this.startingSize = startingSize; initGameDefaultWatchers(); } @@ -181,6 +183,7 @@ public abstract class GameImpl implements Game, Serializable { this.saveGame = game.saveGame; this.startLife = game.startLife; this.enterWithCounters.putAll(game.enterWithCounters); + this.startingSize = game.startingSize; } @Override @@ -939,7 +942,7 @@ public abstract class GameImpl implements Game, Serializable { for (Ability ability : card.getAbilities(this)) { if (ability instanceof CompanionAbility) { 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); break; } diff --git a/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java b/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java index 0a64d1b381..97bccb6b1a 100644 --- a/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java +++ b/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java @@ -32,7 +32,7 @@ public abstract class GameTinyLeadersImpl extends GameImpl { protected boolean startingPlayerSkipsDraw = true; 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) {