forked from External/mage
* Until your next turn effects - fixed that continuous effects of lost/leaved players can be discarded by combat or some cards before next turn starts;
This commit is contained in:
parent
a2e4e55811
commit
2460408da8
14 changed files with 147 additions and 93 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
|
@ -21,13 +20,12 @@ import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class Aetherspouts extends CardImpl {
|
public final class Aetherspouts extends CardImpl {
|
||||||
|
|
||||||
public Aetherspouts(UUID ownerId, CardSetInfo setInfo) {
|
public Aetherspouts(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}");
|
||||||
|
|
||||||
|
|
||||||
// For each attacking creature, its owner puts it on the top or bottom of their library.
|
// For each attacking creature, its owner puts it on the top or bottom of their library.
|
||||||
|
|
@ -73,14 +71,14 @@ class AetherspoutsEffect extends OneShotEffect {
|
||||||
game.getPlayerList();
|
game.getPlayerList();
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
PlayerList playerList = game.getPlayerList();
|
PlayerList playerList = game.getPlayerList().copy();
|
||||||
playerList.setCurrent(game.getActivePlayerId());
|
playerList.setCurrent(game.getActivePlayerId());
|
||||||
Player player = game.getPlayer(game.getActivePlayerId());
|
Player player = game.getPlayer(game.getActivePlayerId());
|
||||||
Player activePlayer = player;
|
Player activePlayer = player;
|
||||||
do {
|
do {
|
||||||
List<Permanent> permanentsToTop = new ArrayList<>();
|
List<Permanent> permanentsToTop = new ArrayList<>();
|
||||||
List<Permanent> permanentsToBottom = new ArrayList<>();
|
List<Permanent> permanentsToBottom = new ArrayList<>();
|
||||||
for (Permanent permanent:game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source.getSourceId(), game)) {
|
for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source.getSourceId(), game)) {
|
||||||
if (permanent.isOwnedBy(player.getId())) {
|
if (permanent.isOwnedBy(player.getId())) {
|
||||||
if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) {
|
if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) {
|
||||||
permanentsToTop.add(permanent);
|
permanentsToTop.add(permanent);
|
||||||
|
|
@ -94,7 +92,7 @@ class AetherspoutsEffect extends OneShotEffect {
|
||||||
// cards to top
|
// cards to top
|
||||||
Cards cards = new CardsImpl();
|
Cards cards = new CardsImpl();
|
||||||
List<Permanent> toLibrary = new ArrayList<>();
|
List<Permanent> toLibrary = new ArrayList<>();
|
||||||
for (Permanent permanent: permanentsToTop) {
|
for (Permanent permanent : permanentsToTop) {
|
||||||
if (permanent instanceof PermanentToken) {
|
if (permanent instanceof PermanentToken) {
|
||||||
toLibrary.add(permanent);
|
toLibrary.add(permanent);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -128,13 +126,13 @@ class AetherspoutsEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// move all permanents to lib at the same time
|
// move all permanents to lib at the same time
|
||||||
for(Permanent permanent: toLibrary) {
|
for (Permanent permanent : toLibrary) {
|
||||||
player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true, false);
|
player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true, false);
|
||||||
}
|
}
|
||||||
// cards to bottom
|
// cards to bottom
|
||||||
cards.clear();
|
cards.clear();
|
||||||
toLibrary.clear();
|
toLibrary.clear();
|
||||||
for (Permanent permanent: permanentsToBottom) {
|
for (Permanent permanent : permanentsToBottom) {
|
||||||
if (permanent instanceof PermanentToken) {
|
if (permanent instanceof PermanentToken) {
|
||||||
toLibrary.add(permanent);
|
toLibrary.add(permanent);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -161,15 +159,15 @@ class AetherspoutsEffect extends OneShotEffect {
|
||||||
if (cards.size() == 1) {
|
if (cards.size() == 1) {
|
||||||
Card card = cards.get(cards.iterator().next(), game);
|
Card card = cards.get(cards.iterator().next(), game);
|
||||||
Permanent permanent = game.getPermanent(card.getId());
|
Permanent permanent = game.getPermanent(card.getId());
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
toLibrary.add(permanent);
|
toLibrary.add(permanent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// move all permanents to lib at the same time
|
// move all permanents to lib at the same time
|
||||||
for(Permanent permanent: toLibrary) {
|
for (Permanent permanent : toLibrary) {
|
||||||
player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, false, false);
|
player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, false, false);
|
||||||
}
|
}
|
||||||
player = playerList.getNext(game);
|
player = playerList.getNext(game, false);
|
||||||
} while (player != null && !player.getId().equals(game.getActivePlayerId()) && activePlayer.canRespond());
|
} while (player != null && !player.getId().equals(game.getActivePlayerId()) && activePlayer.canRespond());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
|
|
||||||
package mage.cards.e;
|
package mage.cards.e;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
|
@ -27,21 +23,26 @@ import mage.players.PlayerList;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.common.TargetNonlandPermanent;
|
import mage.target.common.TargetNonlandPermanent;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class EyeOfDoom extends CardImpl {
|
public final class EyeOfDoom extends CardImpl {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterPermanent("permanent with a doom counter on it");
|
private static final FilterPermanent filter = new FilterPermanent("permanent with a doom counter on it");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(new CounterPredicate(CounterType.DOOM));
|
filter.add(new CounterPredicate(CounterType.DOOM));
|
||||||
}
|
}
|
||||||
|
|
||||||
public EyeOfDoom(UUID ownerId, CardSetInfo setInfo) {
|
public EyeOfDoom(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
|
||||||
|
|
||||||
// When Eye of Doom enters the battlefield, each player chooses a nonland permanent and puts a doom counter on it.
|
// When Eye of Doom enters the battlefield, each player chooses a nonland permanent and puts a doom counter on it.
|
||||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new EyeOfDoomEffect(),false));
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new EyeOfDoomEffect(), false));
|
||||||
|
|
||||||
// {2}, {tap}, Sacrifice Eye of Doom: Destroy each permanent with a doom counter on it.
|
// {2}, {tap}, Sacrifice Eye of Doom: Destroy each permanent with a doom counter on it.
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyAllEffect(filter), new GenericManaCost(2));
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyAllEffect(filter), new GenericManaCost(2));
|
||||||
|
|
@ -93,10 +94,10 @@ class EyeOfDoomEffect extends OneShotEffect {
|
||||||
game.informPlayers(player.getLogName() + " chooses " + permanent.getName());
|
game.informPlayers(player.getLogName() + " chooses " + permanent.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
player = playerList.getNext(game);
|
player = playerList.getNext(game, false);
|
||||||
} while (!player.getId().equals(game.getActivePlayerId()));
|
} while (!player.getId().equals(game.getActivePlayerId()));
|
||||||
|
|
||||||
for (Permanent permanent: permanents) {
|
for (Permanent permanent : permanents) {
|
||||||
permanent.addCounters(CounterType.DOOM.createInstance(), source, game);
|
permanent.addCounters(CounterType.DOOM.createInstance(), source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
|
|
||||||
package mage.cards.i;
|
package mage.cards.i;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.abilities.keyword.DoubleStrikeAbility;
|
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||||
|
|
@ -21,8 +17,12 @@ import mage.players.Player;
|
||||||
import mage.players.PlayerList;
|
import mage.players.PlayerList;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Quercitron
|
* @author Quercitron
|
||||||
*/
|
*/
|
||||||
public final class IllicitAuction extends CardImpl {
|
public final class IllicitAuction extends CardImpl {
|
||||||
|
|
@ -66,18 +66,17 @@ class IllicitAuctionEffect extends GainControlTargetEffect {
|
||||||
public void init(Ability source, Game game) {
|
public void init(Ability source, Game game) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
|
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
|
||||||
if (controller != null
|
if (controller != null && targetCreature != null) {
|
||||||
&& targetCreature != null) {
|
PlayerList playerList = game.getState().getPlayersInRange(controller.getId(), game);
|
||||||
PlayerList playerList = game.getPlayerList().copy();
|
Player winner = game.getPlayer(controller.getId());
|
||||||
playerList.setCurrent(game.getActivePlayerId());
|
|
||||||
|
|
||||||
Player winner = game.getPlayer(game.getActivePlayerId());
|
|
||||||
int highBid = 0;
|
int highBid = 0;
|
||||||
game.informPlayers(winner.getLogName() + " has bet 0 lifes");
|
game.informPlayers(winner.getLogName() + " has bet 0 lifes");
|
||||||
Player currentPlayer = playerList.getNextInRange(controller, game);
|
|
||||||
while (!Objects.equals(currentPlayer, winner)) {
|
Player currentPlayer = playerList.getNext(game, false);
|
||||||
|
while (currentPlayer != null && !Objects.equals(currentPlayer, winner)) {
|
||||||
String text = winner.getLogName() + " has bet " + highBid + " life" + (highBid > 1 ? "s" : "") + ". Top the bid?";
|
String text = winner.getLogName() + " has bet " + highBid + " life" + (highBid > 1 ? "s" : "") + ". Top the bid?";
|
||||||
if (currentPlayer.chooseUse(Outcome.GainControl, text, source, game)) {
|
if (currentPlayer.canRespond()
|
||||||
|
&& currentPlayer.chooseUse(Outcome.GainControl, text, source, game)) {
|
||||||
int newBid = 0;
|
int newBid = 0;
|
||||||
if (!currentPlayer.isHuman()) {//AI will evaluate the creature and bid
|
if (!currentPlayer.isHuman()) {//AI will evaluate the creature and bid
|
||||||
CreatureEvaluator eval = new CreatureEvaluator();
|
CreatureEvaluator eval = new CreatureEvaluator();
|
||||||
|
|
@ -85,7 +84,9 @@ class IllicitAuctionEffect extends GainControlTargetEffect {
|
||||||
int creatureValue = eval.evaluate(targetCreature, game);
|
int creatureValue = eval.evaluate(targetCreature, game);
|
||||||
newBid = Math.max(creatureValue % 2, computerLife - 100);
|
newBid = Math.max(creatureValue % 2, computerLife - 100);
|
||||||
} else {
|
} else {
|
||||||
newBid = currentPlayer.getAmount(highBid + 1, Integer.MAX_VALUE, "Choose bid", game);
|
if (currentPlayer.canRespond()) {
|
||||||
|
newBid = currentPlayer.getAmount(highBid + 1, Integer.MAX_VALUE, "Choose bid", game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (newBid > highBid) {
|
if (newBid > highBid) {
|
||||||
highBid = newBid;
|
highBid = newBid;
|
||||||
|
|
@ -93,7 +94,12 @@ class IllicitAuctionEffect extends GainControlTargetEffect {
|
||||||
game.informPlayers(currentPlayer.getLogName() + " bet " + newBid + " life" + (newBid > 1 ? "s" : ""));
|
game.informPlayers(currentPlayer.getLogName() + " bet " + newBid + " life" + (newBid > 1 ? "s" : ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentPlayer = playerList.getNextInRange(controller, game);
|
currentPlayer = playerList.getNext(game, false);
|
||||||
|
|
||||||
|
// stops loop on all players quite
|
||||||
|
if (game.getState().getPlayersInRange(controller.getId(), game).isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
game.informPlayers(winner.getLogName() + " won the auction with a bid of " + highBid + " life" + (highBid > 1 ? "s" : ""));
|
game.informPlayers(winner.getLogName() + " won the auction with a bid of " + highBid + " life" + (highBid > 1 ? "s" : ""));
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
package mage.cards.k;
|
package mage.cards.k;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.dynamicvalue.DynamicValue;
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
|
|
@ -16,8 +14,9 @@ import mage.players.Player;
|
||||||
import mage.players.PlayerList;
|
import mage.players.PlayerList;
|
||||||
import mage.target.common.TargetAnyTarget;
|
import mage.target.common.TargetAnyTarget;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class Kindle extends CardImpl {
|
public final class Kindle extends CardImpl {
|
||||||
|
|
@ -29,7 +28,7 @@ public final class Kindle extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Kindle(UUID ownerId, CardSetInfo setInfo) {
|
public Kindle(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
|
||||||
|
|
||||||
|
|
||||||
// Kindle deals X damage to any target, where X is 2 plus the number of cards named Kindle in all graveyards.
|
// Kindle deals X damage to any target, where X is 2 plus the number of cards named Kindle in all graveyards.
|
||||||
|
|
@ -64,7 +63,7 @@ class KindleCardsInAllGraveyardsCount implements DynamicValue {
|
||||||
@Override
|
@Override
|
||||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||||
int amount = 0;
|
int amount = 0;
|
||||||
PlayerList playerList = game.getPlayerList();
|
PlayerList playerList = game.getPlayerList().copy();
|
||||||
for (UUID playerUUID : playerList) {
|
for (UUID playerUUID : playerList) {
|
||||||
Player player = game.getPlayer(playerUUID);
|
Player player = game.getPlayer(playerUUID);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
|
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.costs.mana.ManaCosts;
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
|
|
@ -24,14 +20,17 @@ import mage.players.Player;
|
||||||
import mage.players.PlayerList;
|
import mage.players.PlayerList;
|
||||||
import mage.target.TargetCard;
|
import mage.target.TargetCard;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Quercitron
|
* @author Quercitron
|
||||||
*/
|
*/
|
||||||
public final class Tariff extends CardImpl {
|
public final class Tariff extends CardImpl {
|
||||||
|
|
||||||
public Tariff(UUID ownerId, CardSetInfo setInfo) {
|
public Tariff(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}");
|
||||||
|
|
||||||
|
|
||||||
// Each player sacrifices the creature they control with the highest converted mana cost unless they pay that creature's mana cost. If two or more creatures a player controls are tied for highest cost, that player chooses one.
|
// Each player sacrifices the creature they control with the highest converted mana cost unless they pay that creature's mana cost. If two or more creatures a player controls are tied for highest cost, that player chooses one.
|
||||||
|
|
@ -49,12 +48,12 @@ public final class Tariff extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
class TariffEffect extends OneShotEffect {
|
class TariffEffect extends OneShotEffect {
|
||||||
|
|
||||||
public TariffEffect() {
|
public TariffEffect() {
|
||||||
super(Outcome.DestroyPermanent);
|
super(Outcome.DestroyPermanent);
|
||||||
this.staticText = "Each player sacrifices the creature they control with the highest converted mana cost unless they pay that creature's mana cost. If two or more creatures a player controls are tied for highest cost, that player chooses one.";
|
this.staticText = "Each player sacrifices the creature they control with the highest converted mana cost unless they pay that creature's mana cost. If two or more creatures a player controls are tied for highest cost, that player chooses one.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public TariffEffect(final TariffEffect effect) {
|
public TariffEffect(final TariffEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
@ -63,21 +62,20 @@ class TariffEffect extends OneShotEffect {
|
||||||
public TariffEffect copy() {
|
public TariffEffect copy() {
|
||||||
return new TariffEffect(this);
|
return new TariffEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
PlayerList playerList = game.getPlayerList().copy();
|
PlayerList playerList = game.getPlayerList().copy();
|
||||||
playerList.setCurrent(game.getActivePlayerId());
|
playerList.setCurrent(game.getActivePlayerId());
|
||||||
Player player = game.getPlayer(game.getActivePlayerId());
|
Player player = game.getPlayer(game.getActivePlayerId());
|
||||||
|
|
||||||
do {
|
do {
|
||||||
processPlayer(game, source, player);
|
processPlayer(game, source, player);
|
||||||
player = playerList.getNext(game);
|
player = playerList.getNext(game, false);
|
||||||
} while (!player.getId().equals(game.getActivePlayerId()));
|
} while (!player.getId().equals(game.getActivePlayerId()));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processPlayer(Game game, Ability source, Player player) {
|
private void processPlayer(Game game, Ability source, Player player) {
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||||
|
|
||||||
|
|
@ -100,7 +98,7 @@ class TariffEffect extends OneShotEffect {
|
||||||
creatureToPayFor.sacrifice(source.getSourceId(), game);
|
creatureToPayFor.sacrifice(source.getSourceId(), game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Permanent> getPermanentsWithTheHighestCMC(Game game, UUID playerId, FilterPermanent filter) {
|
private List<Permanent> getPermanentsWithTheHighestCMC(Game game, UUID playerId, FilterPermanent filter) {
|
||||||
List<Permanent> permanents = game.getBattlefield().getAllActivePermanents(filter, playerId, game);
|
List<Permanent> permanents = game.getBattlefield().getAllActivePermanents(filter, playerId, game);
|
||||||
int highestCMC = -1;
|
int highestCMC = -1;
|
||||||
|
|
@ -135,5 +133,5 @@ class TariffEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
return permanent;
|
return permanent;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
|
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
|
@ -18,8 +14,11 @@ import mage.players.Player;
|
||||||
import mage.players.PlayerList;
|
import mage.players.PlayerList;
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class TemptWithReflections extends CardImpl {
|
public final class TemptWithReflections extends CardImpl {
|
||||||
|
|
@ -81,7 +80,7 @@ class TemptWithReflectionsEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
game.informPlayers((player.getLogName() + decision + permanent.getName()));
|
game.informPlayers((player.getLogName() + decision + permanent.getName()));
|
||||||
}
|
}
|
||||||
player = playerList.getNext(game);
|
player = playerList.getNext(game, false);
|
||||||
} while (!player.getId().equals(game.getActivePlayerId()));
|
} while (!player.getId().equals(game.getActivePlayerId()));
|
||||||
|
|
||||||
for (UUID playerId : playersSaidYes) {
|
for (UUID playerId : playersSaidYes) {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,8 @@
|
||||||
|
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.cards.Card;
|
import mage.cards.*;
|
||||||
import mage.cards.CardImpl;
|
|
||||||
import mage.cards.CardSetInfo;
|
|
||||||
import mage.cards.Cards;
|
|
||||||
import mage.cards.CardsImpl;
|
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
|
|
@ -24,14 +18,15 @@ import mage.target.TargetCard;
|
||||||
import mage.target.common.TargetCardInExile;
|
import mage.target.common.TargetCardInExile;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author emerald000
|
* @author emerald000
|
||||||
*/
|
*/
|
||||||
public final class ThievesAuction extends CardImpl {
|
public final class ThievesAuction extends CardImpl {
|
||||||
|
|
||||||
public ThievesAuction(UUID ownerId, CardSetInfo setInfo) {
|
public ThievesAuction(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{R}{R}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}{R}");
|
||||||
|
|
||||||
// Exile all nontoken permanents. Starting with you, each player chooses one of the exiled cards and puts it onto the battlefield tapped under their control. Repeat this process until all cards exiled this way have been chosen.
|
// Exile all nontoken permanents. Starting with you, each player chooses one of the exiled cards and puts it onto the battlefield tapped under their control. Repeat this process until all cards exiled this way have been chosen.
|
||||||
this.getSpellAbility().addEffect(new ThievesAuctionEffect());
|
this.getSpellAbility().addEffect(new ThievesAuctionEffect());
|
||||||
|
|
@ -98,7 +93,7 @@ class ThievesAuctionEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Repeat this process until all cards exiled this way have been chosen.
|
// Repeat this process until all cards exiled this way have been chosen.
|
||||||
player = playerList.getNext(game);
|
player = playerList.getNext(game, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,4 +153,58 @@ public class EndOfTurnMultiOpponentsTest extends CardTestMultiPlayerBaseWithRang
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// leaved players
|
||||||
|
// 800.4i When a player leaves the game, any continuous effects with durations that last until that player's next turn
|
||||||
|
// or until a specific point in that turn will last until that turn would have begun.
|
||||||
|
// They neither expire immediately nor last indefinitely.
|
||||||
|
@Test
|
||||||
|
public void test_UntilYourNextTurnMulti_Leaved() {
|
||||||
|
// Player order: A -> D -> C -> B
|
||||||
|
addCustomCardWithAbility("boost1", playerA, new SimpleStaticAbility(Zone.ALL, new BoostAllEffect(1, 1, Duration.UntilYourNextTurn)));
|
||||||
|
|
||||||
|
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 1, playerA, true, PhaseStep.END_TURN);
|
||||||
|
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 2, playerD, true, PhaseStep.END_TURN);
|
||||||
|
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 3, playerC, true, PhaseStep.END_TURN);
|
||||||
|
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 4, playerB, true, PhaseStep.END_TURN);
|
||||||
|
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 5, playerD, true, null);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, cardBear2, 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, cardBear2, 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerC, cardBear2, 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerD, cardBear2, 1);
|
||||||
|
//
|
||||||
|
// When Eye of Doom enters the battlefield, each player chooses a nonland permanent and puts a doom counter on it.
|
||||||
|
addCard(Zone.HAND, playerC, "Eye of Doom", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerC, "Forest", 4);
|
||||||
|
|
||||||
|
checkPlayerInGame("A must plays in 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerA, true);
|
||||||
|
attack(1, playerA, cardBear2);
|
||||||
|
|
||||||
|
checkPlayerInGame("A must plays in 2", 2, PhaseStep.PRECOMBAT_MAIN, playerD, playerA, true);
|
||||||
|
attack(2, playerD, cardBear2);
|
||||||
|
|
||||||
|
checkPlayerInGame("A must plays in 3 before", 3, PhaseStep.PRECOMBAT_MAIN, playerC, playerA, true);
|
||||||
|
attack(3, playerC, cardBear2);
|
||||||
|
concede(3, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||||
|
checkPlayerInGame("A must leaved in 3 after", 3, PhaseStep.POSTCOMBAT_MAIN, playerC, playerA, false);
|
||||||
|
|
||||||
|
// test PlayerList.getNext processing
|
||||||
|
// play Eye of Doom, ask all players to put doom counter
|
||||||
|
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerC, "Eye of Doom");
|
||||||
|
addTarget(playerC, cardBear2);
|
||||||
|
addTarget(playerB, cardBear2);
|
||||||
|
//addTarget(playerA, cardBear2); // leaved
|
||||||
|
addTarget(playerD, cardBear2);
|
||||||
|
|
||||||
|
checkPlayerInGame("A must leaved in 4", 4, PhaseStep.POSTCOMBAT_MAIN, playerB, playerA, false);
|
||||||
|
attack(4, playerB, cardBear2);
|
||||||
|
checkPlayerInGame("A must leaved in 5", 5, PhaseStep.POSTCOMBAT_MAIN, playerD, playerA, false);
|
||||||
|
attack(5, playerD, cardBear2);
|
||||||
|
|
||||||
|
setStopAt(5, PhaseStep.CLEANUP);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
||||||
boolean canDelete = false;
|
boolean canDelete = false;
|
||||||
Player player = game.getPlayer(startingControllerId);
|
Player player = game.getPlayer(startingControllerId);
|
||||||
|
|
||||||
// discard on start of turn for leave player
|
// discard on start of turn for leaved player
|
||||||
// 800.4i When a player leaves the game, any continuous effects with durations that last until that player's next turn
|
// 800.4i When a player leaves the game, any continuous effects with durations that last until that player's next turn
|
||||||
// or until a specific point in that turn will last until that turn would have begun.
|
// or until a specific point in that turn will last until that turn would have begun.
|
||||||
// They neither expire immediately nor last indefinitely.
|
// They neither expire immediately nor last indefinitely.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
package mage.abilities.effects.common;
|
package mage.abilities.effects.common;
|
||||||
|
|
||||||
import java.io.ObjectStreamException;
|
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.MageSingleton;
|
import mage.abilities.MageSingleton;
|
||||||
|
|
@ -20,6 +18,8 @@ import mage.players.PlayerList;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
|
|
||||||
|
import java.io.ObjectStreamException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. The controller of the spell or ability chooses an opponent. (This doesn't
|
* 1. The controller of the spell or ability chooses an opponent. (This doesn't
|
||||||
* target the opponent.) 2. Each player involved in the clash reveals the top
|
* target the opponent.) 2. Each player involved in the clash reveals the top
|
||||||
|
|
@ -36,7 +36,7 @@ import mage.target.common.TargetOpponent;
|
||||||
* 7. The clash spell or ability finishes resolving. That usually involves a
|
* 7. The clash spell or ability finishes resolving. That usually involves a
|
||||||
* bonus gained by the controller of the clash spell or ability if they won
|
* bonus gained by the controller of the clash spell or ability if they won
|
||||||
* the clash. 8. Abilities that triggered during the clash are put on the stack.
|
* the clash. 8. Abilities that triggered during the clash are put on the stack.
|
||||||
*
|
* <p>
|
||||||
* There are no draws or losses in a clash. Either you win it or you don't. Each
|
* There are no draws or losses in a clash. Either you win it or you don't. Each
|
||||||
* spell or ability with clash says what happens if you (the controller of that
|
* spell or ability with clash says what happens if you (the controller of that
|
||||||
* spell or ability) win the clash. Typically, if you don't win the clash,
|
* spell or ability) win the clash. Typically, if you don't win the clash,
|
||||||
|
|
@ -148,7 +148,7 @@ public class ClashEffect extends OneShotEffect implements MageSingleton {
|
||||||
if (cardOpponent != null && current.getId().equals(opponent.getId())) {
|
if (cardOpponent != null && current.getId().equals(opponent.getId())) {
|
||||||
topOpponent = current.chooseUse(Outcome.Detriment, "Put " + cardOpponent.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game);
|
topOpponent = current.chooseUse(Outcome.Detriment, "Put " + cardOpponent.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game);
|
||||||
}
|
}
|
||||||
nextPlayer = playerList.getNext(game);
|
nextPlayer = playerList.getNext(game, false);
|
||||||
} while (nextPlayer != null && !nextPlayer.getId().equals(game.getActivePlayerId()));
|
} while (nextPlayer != null && !nextPlayer.getId().equals(game.getActivePlayerId()));
|
||||||
// put the cards back to library
|
// put the cards back to library
|
||||||
if (cardController != null) {
|
if (cardController != null) {
|
||||||
|
|
|
||||||
|
|
@ -766,7 +766,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
state.getTurn().resumePlay(this, wasPaused);
|
state.getTurn().resumePlay(this, wasPaused);
|
||||||
if (!isPaused() && !checkIfGameIsOver()) {
|
if (!isPaused() && !checkIfGameIsOver()) {
|
||||||
endOfTurn();
|
endOfTurn();
|
||||||
player = playerList.getNext(this);
|
player = playerList.getNext(this, true);
|
||||||
state.setTurnNum(state.getTurnNum() + 1);
|
state.setTurnNum(state.getTurnNum() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -791,7 +791,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
if (!playExtraTurns()) {
|
if (!playExtraTurns()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
playerByOrder = playerList.getNext(this);
|
playerByOrder = playerList.getNext(this, true);
|
||||||
state.setPlayerByOrderId(playerByOrder.getId());
|
state.setPlayerByOrderId(playerByOrder.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2494,7 +2494,6 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
perm.removeFromCombat(this, true);
|
perm.removeFromCombat(this, true);
|
||||||
}
|
}
|
||||||
toOutside.add(perm);
|
toOutside.add(perm);
|
||||||
// it.remove();
|
|
||||||
} else if (perm.isControlledBy(player.getId())) {
|
} else if (perm.isControlledBy(player.getId())) {
|
||||||
// and any effects which give that player control of any objects or players end
|
// and any effects which give that player control of any objects or players end
|
||||||
Effects:
|
Effects:
|
||||||
|
|
@ -2591,7 +2590,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
if (!isActivePlayer(playerId)) {
|
if (!isActivePlayer(playerId)) {
|
||||||
setMonarchId(null, getActivePlayerId());
|
setMonarchId(null, getActivePlayerId());
|
||||||
} else {
|
} else {
|
||||||
Player nextPlayer = getPlayerList().getNext(this);
|
Player nextPlayer = getPlayerList().getNext(this, true);
|
||||||
if (nextPlayer != null) {
|
if (nextPlayer != null) {
|
||||||
setMonarchId(null, nextPlayer.getId());
|
setMonarchId(null, nextPlayer.getId());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1236,7 +1236,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
case LEFT:
|
case LEFT:
|
||||||
players = game.getState().getPlayerList(attackingPlayerId);
|
players = game.getState().getPlayerList(attackingPlayerId);
|
||||||
while (attackingPlayer.isInGame()) {
|
while (attackingPlayer.isInGame()) {
|
||||||
Player opponent = players.getNext(game);
|
Player opponent = players.getNext(game, false);
|
||||||
if (attackingPlayer.hasOpponent(opponent.getId(), game)) {
|
if (attackingPlayer.hasOpponent(opponent.getId(), game)) {
|
||||||
attackablePlayers.add(opponent.getId());
|
attackablePlayers.add(opponent.getId());
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -487,10 +487,10 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
inRange.add(playerId);
|
inRange.add(playerId);
|
||||||
PlayerList players = game.getState().getPlayerList(playerId);
|
PlayerList players = game.getState().getPlayerList(playerId);
|
||||||
for (int i = 0; i < range.getRange(); i++) {
|
for (int i = 0; i < range.getRange(); i++) {
|
||||||
Player player = players.getNext(game);
|
Player player = players.getNext(game, false);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
while (player.hasLeft()) {
|
while (player.hasLeft()) {
|
||||||
player = players.getNext(game);
|
player = players.getNext(game, false);
|
||||||
}
|
}
|
||||||
inRange.add(player.getId());
|
inRange.add(player.getId());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
|
|
||||||
package mage.players;
|
package mage.players;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.util.CircularList;
|
import mage.util.CircularList;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class PlayerList extends CircularList<UUID> {
|
public class PlayerList extends CircularList<UUID> {
|
||||||
|
|
@ -23,7 +22,7 @@ public class PlayerList extends CircularList<UUID> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getNextInRange(Player basePlayer, Game game) {
|
public Player getNextInRange(Player basePlayer, Game game) {
|
||||||
UUID currentPlayerBefore = get();
|
UUID currentPlayerBefore = this.get();
|
||||||
UUID nextPlayerId = super.getNext();
|
UUID nextPlayerId = super.getNext();
|
||||||
do {
|
do {
|
||||||
if (basePlayer.getInRange().contains(nextPlayerId)) {
|
if (basePlayer.getInRange().contains(nextPlayerId)) {
|
||||||
|
|
@ -34,7 +33,10 @@ public class PlayerList extends CircularList<UUID> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getNext(Game game) {
|
/**
|
||||||
|
* checkNextTurnReached - use it turns/priority code only to mark leaved player as "reached next turn end" (need for some continous effects)
|
||||||
|
*/
|
||||||
|
public Player getNext(Game game, boolean checkNextTurnReached) {
|
||||||
UUID start = this.get();
|
UUID start = this.get();
|
||||||
if (start == null) {
|
if (start == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -42,11 +44,14 @@ public class PlayerList extends CircularList<UUID> {
|
||||||
Player player;
|
Player player;
|
||||||
while (true) {
|
while (true) {
|
||||||
player = game.getPlayer(super.getNext());
|
player = game.getPlayer(super.getNext());
|
||||||
if (!player.hasLeft() && !player.hasLost()) {
|
if (player.isInGame()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!player.hasReachedNextTurnAfterLeaving()) {
|
|
||||||
player.setReachedNextTurnAfterLeaving(true);
|
if (checkNextTurnReached) {
|
||||||
|
if (!player.hasReachedNextTurnAfterLeaving()) {
|
||||||
|
player.setReachedNextTurnAfterLeaving(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (player.getId().equals(start)) {
|
if (player.getId().equals(start)) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -60,7 +65,7 @@ public class PlayerList extends CircularList<UUID> {
|
||||||
UUID start = this.get();
|
UUID start = this.get();
|
||||||
while (true) {
|
while (true) {
|
||||||
player = game.getPlayer(super.getPrevious());
|
player = game.getPlayer(super.getPrevious());
|
||||||
if (!player.hasLeft() && !player.hasLost()) {
|
if (player.isInGame()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (player.getId().equals(start)) {
|
if (player.getId().equals(start)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue