mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
Improved freeze checks and canRespond/isInGame usage
This commit is contained in:
parent
3b19e3db35
commit
adbe84c540
17 changed files with 54 additions and 77 deletions
|
@ -1964,7 +1964,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
waitForResponse(game);
|
waitForResponse(game);
|
||||||
|
|
||||||
if (response.getUUID() != null && isInGame()) {
|
if (response.getUUID() != null) {
|
||||||
if (abilities.containsKey(response.getUUID())) {
|
if (abilities.containsKey(response.getUUID())) {
|
||||||
activateAbility(abilities.get(response.getUUID()), game);
|
activateAbility(abilities.get(response.getUUID()), game);
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,7 +326,7 @@ public class GameController implements GameCallback {
|
||||||
private void sendInfoAboutPlayersNotJoinedYetAndTryToFixIt() {
|
private void sendInfoAboutPlayersNotJoinedYetAndTryToFixIt() {
|
||||||
// runs every 5 secs untill all players join
|
// runs every 5 secs untill all players join
|
||||||
for (Player player : game.getPlayers().values()) {
|
for (Player player : game.getPlayers().values()) {
|
||||||
if (player.isInGame() && player.isHuman()) {
|
if (player.canRespond() && player.isHuman()) {
|
||||||
Optional<User> requestedUser = getUserByPlayerId(player.getId());
|
Optional<User> requestedUser = getUserByPlayerId(player.getId());
|
||||||
if (requestedUser.isPresent()) {
|
if (requestedUser.isPresent()) {
|
||||||
User user = requestedUser.get();
|
User user = requestedUser.get();
|
||||||
|
|
|
@ -123,7 +123,7 @@ class CovetedJewelControlEffect extends ContinuousEffectImpl {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
Player newControllingPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
Player newControllingPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||||
if (permanent == null || newControllingPlayer == null || !newControllingPlayer.isInGame()) {
|
if (permanent == null || newControllingPlayer == null || !newControllingPlayer.canRespond()) {
|
||||||
this.discard();
|
this.discard();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
|
|
||||||
package mage.cards.c;
|
package mage.cards.c;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -18,8 +12,9 @@ import mage.players.Player;
|
||||||
import mage.target.TargetCard;
|
import mage.target.TargetCard;
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author TheElk801 & L_J
|
* @author TheElk801 & L_J
|
||||||
*/
|
*/
|
||||||
public final class CruelFate extends CardImpl {
|
public final class CruelFate extends CardImpl {
|
||||||
|
@ -71,7 +66,7 @@ class CruelFateEffect extends OneShotEffect {
|
||||||
|
|
||||||
// card to put into opponent's graveyard
|
// card to put into opponent's graveyard
|
||||||
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into target opponent's graveyard"));
|
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into target opponent's graveyard"));
|
||||||
if (targetOpponent.isInGame()) {
|
if (targetOpponent.canRespond()) {
|
||||||
if (cards.size() > 1) {
|
if (cards.size() > 1) {
|
||||||
controller.choose(Outcome.Detriment, cards, target, game);
|
controller.choose(Outcome.Detriment, cards, target, game);
|
||||||
Card card = cards.get(target.getFirstTarget(), game);
|
Card card = cards.get(target.getFirstTarget(), game);
|
||||||
|
|
|
@ -137,7 +137,7 @@ class EyeOfTheStormEffect1 extends OneShotEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean continueCasting = true;
|
boolean continueCasting = true;
|
||||||
while (spellController.isInGame() && continueCasting) {
|
while (spellController.canRespond() && continueCasting) {
|
||||||
continueCasting = copiedCards.size() > 1 && spellController.chooseUse(outcome, "Cast one of the copied cards without paying its mana cost?", source, game);
|
continueCasting = copiedCards.size() > 1 && spellController.chooseUse(outcome, "Cast one of the copied cards without paying its mana cost?", source, game);
|
||||||
|
|
||||||
Card cardToCopy;
|
Card cardToCopy;
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package mage.cards.k;
|
package mage.cards.k;
|
||||||
|
|
||||||
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.DelayedTriggeredAbility;
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
|
@ -26,6 +23,10 @@ import mage.target.TargetPlayer;
|
||||||
import mage.target.common.TargetCardInHand;
|
import mage.target.common.TargetCardInHand;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author bunchOfDevs
|
* @author bunchOfDevs
|
||||||
*/
|
*/
|
||||||
|
@ -100,7 +101,7 @@ class KarnLiberatedEffect extends OneShotEffect {
|
||||||
game.getState().addCard(card);
|
game.getState().addCard(card);
|
||||||
}
|
}
|
||||||
for (Player player : game.getPlayers().values()) {
|
for (Player player : game.getPlayers().values()) {
|
||||||
if (player.isInGame()) { // only players alive are in the restarted game
|
if (player.canRespond()) { // only players alive are in the restarted game
|
||||||
player.getGraveyard().clear();
|
player.getGraveyard().clear();
|
||||||
player.getHand().clear();
|
player.getHand().clear();
|
||||||
player.getLibrary().clear();
|
player.getLibrary().clear();
|
||||||
|
|
|
@ -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.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DamageAllEffect;
|
import mage.abilities.effects.common.DamageAllEffect;
|
||||||
|
@ -15,8 +13,9 @@ import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
public final class KindleTheCarnage extends CardImpl {
|
public final class KindleTheCarnage extends CardImpl {
|
||||||
|
@ -62,7 +61,6 @@ class KindleTheCarnageEffect extends OneShotEffect {
|
||||||
Cards hand = controller.getHand();
|
Cards hand = controller.getHand();
|
||||||
while (hand != null
|
while (hand != null
|
||||||
&& hand.size() > 0
|
&& hand.size() > 0
|
||||||
&& controller.isInGame()
|
|
||||||
&& controller.chooseUse(Outcome.AIDontUseIt, "Discard a card randomly from your hand?", source, game)) {
|
&& controller.chooseUse(Outcome.AIDontUseIt, "Discard a card randomly from your hand?", source, game)) {
|
||||||
Card discardedCard = controller.discardOne(true, source, game);
|
Card discardedCard = controller.discardOne(true, source, game);
|
||||||
if (discardedCard != null) {
|
if (discardedCard != null) {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.n;
|
package mage.cards.n;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
@ -24,7 +23,6 @@ import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Rene - bugisemail at gmail dot com
|
* @author Rene - bugisemail at gmail dot com
|
||||||
*/
|
*/
|
||||||
public final class NaturalBalance extends CardImpl {
|
public final class NaturalBalance extends CardImpl {
|
||||||
|
@ -100,9 +98,7 @@ public final class NaturalBalance extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Player player : toShuffle) {
|
for (Player player : toShuffle) {
|
||||||
if (player.isInGame()) {
|
player.shuffleLibrary(source, game);
|
||||||
player.shuffleLibrary(source, game);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,8 +96,7 @@ class ScourgeOfValkasDamageEffect extends OneShotEffect {
|
||||||
permanent.damage(dragons, enteringDragon.getId(), game, false, true);
|
permanent.damage(dragons, enteringDragon.getId(), game, false, true);
|
||||||
} else {
|
} else {
|
||||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||||
if (player != null
|
if (player != null) {
|
||||||
&& player.isInGame()) {
|
|
||||||
player.damage(dragons, enteringDragon.getId(), game);
|
player.damage(dragons, enteringDragon.getId(), game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.Mode;
|
import mage.abilities.Mode;
|
||||||
|
@ -17,15 +15,16 @@ import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author ciaccona007
|
* @author ciaccona007
|
||||||
*/
|
*/
|
||||||
public final class SkySwallower extends CardImpl {
|
public final class SkySwallower extends CardImpl {
|
||||||
|
|
||||||
public SkySwallower(UUID ownerId, CardSetInfo setInfo) {
|
public SkySwallower(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
|
||||||
|
|
||||||
this.subtype.add(SubType.LEVIATHAN);
|
this.subtype.add(SubType.LEVIATHAN);
|
||||||
this.power = new MageInt(8);
|
this.power = new MageInt(8);
|
||||||
this.toughness = new MageInt(8);
|
this.toughness = new MageInt(8);
|
||||||
|
@ -68,7 +67,7 @@ class GainControlAllPermanentsEffect extends ContinuousEffectImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
|
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
|
||||||
if (targetPlayer != null && targetPlayer.isInGame()) {
|
if (targetPlayer != null) {
|
||||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
|
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
|
||||||
if (permanent != null && !permanent.getId().equals(source.getSourceId())) {
|
if (permanent != null && !permanent.getId().equals(source.getSourceId())) {
|
||||||
permanent.changeControllerId(targetPlayer.getId(), game);
|
permanent.changeControllerId(targetPlayer.getId(), game);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
@ -70,7 +69,7 @@ class SlaughterTheStrongEffect extends OneShotEffect {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
boolean selectionDone = false;
|
boolean selectionDone = false;
|
||||||
Set<UUID> selectedCreatures = new HashSet<>();
|
Set<UUID> selectedCreatures = new HashSet<>();
|
||||||
while (selectionDone == false && player.isInGame()) {
|
while (player.canRespond() && selectionDone == false) {
|
||||||
int powerSum = 0;
|
int powerSum = 0;
|
||||||
for (UUID creatureId : selectedCreatures) {
|
for (UUID creatureId : selectedCreatures) {
|
||||||
Permanent creature = game.getPermanent(creatureId);
|
Permanent creature = game.getPermanent(creatureId);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package mage.cards.u;
|
package mage.cards.u;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DamageTargetEffect;
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
|
@ -15,10 +14,10 @@ import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetAnyTarget;
|
import mage.target.common.TargetAnyTarget;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class UndyingFlames extends CardImpl {
|
public final class UndyingFlames extends CardImpl {
|
||||||
|
|
||||||
|
@ -60,7 +59,7 @@ class UndyingFlamesEffect extends OneShotEffect {
|
||||||
|
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
while (controller.getLibrary().hasCards() && controller.isInGame()) {
|
while (controller.canRespond() && controller.getLibrary().hasCards()) {
|
||||||
Card card = controller.getLibrary().getFromTop(game);
|
Card card = controller.getLibrary().getFromTop(game);
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
controller.moveCards(card, Zone.EXILED, source, game);
|
controller.moveCards(card, Zone.EXILED, source, game);
|
||||||
|
|
|
@ -122,8 +122,7 @@ public class DamageTargetEffect extends OneShotEffect {
|
||||||
permanent.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, preventable);
|
permanent.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, preventable);
|
||||||
}
|
}
|
||||||
Player player = game.getPlayer(targetId);
|
Player player = game.getPlayer(targetId);
|
||||||
if (player != null
|
if (player != null) {
|
||||||
&& player.isInGame()) {
|
|
||||||
player.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, preventable);
|
player.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, preventable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,8 +135,7 @@ public class DamageTargetEffect extends OneShotEffect {
|
||||||
permanent.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, preventable);
|
permanent.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, preventable);
|
||||||
} else {
|
} else {
|
||||||
Player player = game.getPlayer(targetId);
|
Player player = game.getPlayer(targetId);
|
||||||
if (player != null
|
if (player != null) {
|
||||||
&& player.isInGame()) {
|
|
||||||
player.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, preventable);
|
player.damage(amount.calculate(game, source, this), source.getSourceId(), game, false, preventable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package mage.abilities.effects.common.continuous;
|
package mage.abilities.effects.common.continuous;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.ActivatedAbility;
|
import mage.abilities.ActivatedAbility;
|
||||||
import mage.abilities.Mode;
|
import mage.abilities.Mode;
|
||||||
|
@ -16,8 +15,9 @@ import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class GainControlTargetEffect extends ContinuousEffectImpl {
|
public class GainControlTargetEffect extends ContinuousEffectImpl {
|
||||||
|
@ -31,17 +31,15 @@ public class GainControlTargetEffect extends ContinuousEffectImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param duration
|
* @param duration
|
||||||
* @param fixedControl Controlling player is fixed even if the controller of
|
* @param fixedControl Controlling player is fixed even if the controller of
|
||||||
* the ability changes later
|
* the ability changes later
|
||||||
*/
|
*/
|
||||||
public GainControlTargetEffect(Duration duration, boolean fixedControl) {
|
public GainControlTargetEffect(Duration duration, boolean fixedControl) {
|
||||||
this(duration, fixedControl, null);
|
this(duration, fixedControl, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param duration
|
* @param duration
|
||||||
* @param controllingPlayerId Player that controls the target creature
|
* @param controllingPlayerId Player that controls the target creature
|
||||||
*/
|
*/
|
||||||
|
@ -112,8 +110,7 @@ public class GainControlTargetEffect extends ContinuousEffectImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// no valid target exists and the controller is no longer in the game, effect can be discarded
|
// no valid target exists and the controller is no longer in the game, effect can be discarded
|
||||||
if (!oneTargetStillExists
|
if (!oneTargetStillExists || !controller.isInGame()) {
|
||||||
|| !controller.isInGame()) {
|
|
||||||
discard();
|
discard();
|
||||||
}
|
}
|
||||||
firstControlChange = false;
|
firstControlChange = false;
|
||||||
|
|
|
@ -982,7 +982,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
targetPlayer.setTargetName("starting player");
|
targetPlayer.setTargetName("starting player");
|
||||||
if (choosingPlayerId != null) {
|
if (choosingPlayerId != null) {
|
||||||
choosingPlayer = this.getPlayer(choosingPlayerId);
|
choosingPlayer = this.getPlayer(choosingPlayerId);
|
||||||
if (choosingPlayer != null && !choosingPlayer.isInGame()) {
|
if (choosingPlayer != null && !choosingPlayer.canRespond()) {
|
||||||
choosingPlayer = null;
|
choosingPlayer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1007,7 +1007,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
if (startingPlayerId == null) {
|
if (startingPlayerId == null) {
|
||||||
// choose any available player as starting player
|
// choose any available player as starting player
|
||||||
for (Player player : state.getPlayers().values()) {
|
for (Player player : state.getPlayers().values()) {
|
||||||
if (player.isInGame()) {
|
if (player.canRespond()) {
|
||||||
startingPlayerId = player.getId();
|
startingPlayerId = player.getId();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1161,7 +1161,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
while (!hasEnded()) {
|
while (!hasEnded()) {
|
||||||
playerId = players[RandomUtil.nextInt(players.length)];
|
playerId = players[RandomUtil.nextInt(players.length)];
|
||||||
Player player = getPlayer(playerId);
|
Player player = getPlayer(playerId);
|
||||||
if (player != null && player.isInGame()) {
|
if (player != null && player.canRespond()) {
|
||||||
fireInformEvent(state.getPlayer(playerId).getLogName() + " won the toss");
|
fireInformEvent(state.getPlayer(playerId).getLogName() + " won the toss");
|
||||||
return player.getId();
|
return player.getId();
|
||||||
}
|
}
|
||||||
|
@ -3281,7 +3281,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
gameStatesRollBack.put(getTurnNum(), state.copy());
|
gameStatesRollBack.put(getTurnNum(), state.copy());
|
||||||
executingRollback = true;
|
executingRollback = true;
|
||||||
for (Player playerObject : getPlayers().values()) {
|
for (Player playerObject : getPlayers().values()) {
|
||||||
if (playerObject.isHuman() && playerObject.isInGame()) {
|
if (playerObject.isHuman() && playerObject.canRespond()) {
|
||||||
playerObject.resetStoredBookmark(this);
|
playerObject.resetStoredBookmark(this);
|
||||||
playerObject.abort();
|
playerObject.abort();
|
||||||
playerObject.resetPlayerPassedActions();
|
playerObject.resetPlayerPassedActions();
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
|
|
||||||
package mage.game.combat;
|
package mage.game.combat;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.ControllerAssignCombatDamageToBlockersAbility;
|
import mage.abilities.common.ControllerAssignCombatDamageToBlockersAbility;
|
||||||
import mage.abilities.common.ControllerDivideCombatDamageAbility;
|
import mage.abilities.common.ControllerDivideCombatDamageAbility;
|
||||||
import mage.abilities.common.DamageAsThoughNotBlockedAbility;
|
import mage.abilities.common.DamageAsThoughNotBlockedAbility;
|
||||||
import mage.abilities.keyword.BandingAbility;
|
import mage.abilities.keyword.*;
|
||||||
import mage.abilities.keyword.BandsWithOtherAbility;
|
|
||||||
import mage.abilities.keyword.CantBlockAloneAbility;
|
|
||||||
import mage.abilities.keyword.DeathtouchAbility;
|
|
||||||
import mage.abilities.keyword.DoubleStrikeAbility;
|
|
||||||
import mage.abilities.keyword.FirstStrikeAbility;
|
|
||||||
import mage.abilities.keyword.TrampleAbility;
|
|
||||||
import mage.constants.AsThoughEffectType;
|
import mage.constants.AsThoughEffectType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
|
@ -27,7 +20,6 @@ import java.util.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
|
@ -43,9 +35,9 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
protected boolean defenderIsPlaneswalker;
|
protected boolean defenderIsPlaneswalker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param defenderId the player that controls the defending permanents
|
* @param defenderId the player that controls the defending permanents
|
||||||
* @param defenderIsPlaneswalker is the defending permanent a planeswalker
|
* @param defenderIsPlaneswalker is the defending permanent a planeswalker
|
||||||
* @param defendingPlayerId regular controller of the defending permanents
|
* @param defendingPlayerId regular controller of the defending permanents
|
||||||
*/
|
*/
|
||||||
public CombatGroup(UUID defenderId, boolean defenderIsPlaneswalker, UUID defendingPlayerId) {
|
public CombatGroup(UUID defenderId, boolean defenderIsPlaneswalker, UUID defendingPlayerId) {
|
||||||
this.defenderId = defenderId;
|
this.defenderId = defenderId;
|
||||||
|
@ -174,7 +166,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
Player player = game.getPlayer(defenderAssignsCombatDamage(game) ? defendingPlayerId : attacker.getControllerId());
|
Player player = game.getPlayer(defenderAssignsCombatDamage(game) ? defendingPlayerId : attacker.getControllerId());
|
||||||
if ((attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId()) &&
|
if ((attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId()) &&
|
||||||
player.chooseUse(Outcome.Damage, "Do you wish to assign damage for "
|
player.chooseUse(Outcome.Damage, "Do you wish to assign damage for "
|
||||||
+ attacker.getLogName() + " as though it weren't blocked?", null, game)) ||
|
+ attacker.getLogName() + " as though it weren't blocked?", null, game)) ||
|
||||||
game.getContinuousEffects().asThough(attacker.getId(), AsThoughEffectType.DAMAGE_NOT_BLOCKED
|
game.getContinuousEffects().asThough(attacker.getId(), AsThoughEffectType.DAMAGE_NOT_BLOCKED
|
||||||
, null, attacker.getControllerId(), game) != null) {
|
, null, attacker.getControllerId(), game) != null) {
|
||||||
// for handling creatures like Thorn Elemental
|
// for handling creatures like Thorn Elemental
|
||||||
|
@ -227,7 +219,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
* Determines if permanent can damage in current (First Strike or not)
|
* Determines if permanent can damage in current (First Strike or not)
|
||||||
* combat damage step
|
* combat damage step
|
||||||
*
|
*
|
||||||
* @param perm Permanent to check
|
* @param perm Permanent to check
|
||||||
* @param first First strike or common combat damage step
|
* @param first First strike or common combat damage step
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -409,7 +401,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
}
|
}
|
||||||
if (damage > 0) {
|
if (damage > 0) {
|
||||||
Player defendingPlayer = game.getPlayer(defendingPlayerId);
|
Player defendingPlayer = game.getPlayer(defendingPlayerId);
|
||||||
if (defendingPlayer.isInGame()) {
|
if (defendingPlayer != null) {
|
||||||
defendingPlayer.damage(damage, attacker.getId(), game, true, true);
|
defendingPlayer.damage(damage, attacker.getId(), game, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,9 +458,9 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
* Damages attacking creatures by a creature that blocked several ones
|
* Damages attacking creatures by a creature that blocked several ones
|
||||||
* Damages only attackers as blocker was damage in
|
* Damages only attackers as blocker was damage in
|
||||||
* {@link #singleBlockerDamage}.
|
* {@link #singleBlockerDamage}.
|
||||||
*
|
* <p>
|
||||||
* Handles abilities like "{this} an block any number of creatures.".
|
* Handles abilities like "{this} an block any number of creatures.".
|
||||||
*
|
* <p>
|
||||||
* Blocker damage for blockers blocking single creatures is handled in the
|
* Blocker damage for blockers blocking single creatures is handled in the
|
||||||
* single/multi blocker methods, so this shouldn't be used anymore.
|
* single/multi blocker methods, so this shouldn't be used anymore.
|
||||||
*
|
*
|
||||||
|
@ -492,7 +484,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
* Damages attacking creatures by a creature that blocked several ones
|
* Damages attacking creatures by a creature that blocked several ones
|
||||||
* Damages only attackers as blocker was damage in either
|
* Damages only attackers as blocker was damage in either
|
||||||
* {@link #singleBlockerDamage} or {@link #multiBlockerDamage}.
|
* {@link #singleBlockerDamage} or {@link #multiBlockerDamage}.
|
||||||
*
|
* <p>
|
||||||
* Handles abilities like "{this} an block any number of creatures.".
|
* Handles abilities like "{this} an block any number of creatures.".
|
||||||
*
|
*
|
||||||
* @param first
|
* @param first
|
||||||
|
@ -552,7 +544,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Player defender = game.getPlayer(defenderId);
|
Player defender = game.getPlayer(defenderId);
|
||||||
if (defender.isInGame()) {
|
if (defender != null) {
|
||||||
defender.damage(amount, attacker.getId(), game, true, true);
|
defender.damage(amount, attacker.getId(), game, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,9 +564,8 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param blockerId
|
* @param blockerId
|
||||||
* @param playerId controller of the blocking creature
|
* @param playerId controller of the blocking creature
|
||||||
* @param game
|
* @param game
|
||||||
*/
|
*/
|
||||||
public void addBlocker(UUID blockerId, UUID playerId, Game game) {
|
public void addBlocker(UUID blockerId, UUID playerId, Game game) {
|
||||||
|
@ -591,7 +582,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
* event.
|
* event.
|
||||||
*
|
*
|
||||||
* @param blockerId
|
* @param blockerId
|
||||||
* @param playerId controller of the blocking creature
|
* @param playerId controller of the blocking creature
|
||||||
* @param game
|
* @param game
|
||||||
*/
|
*/
|
||||||
public void addBlockerToGroup(UUID blockerId, UUID playerId, Game game) {
|
public void addBlockerToGroup(UUID blockerId, UUID playerId, Game game) {
|
||||||
|
@ -645,7 +636,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
attackerPerms.add(game.getPermanent(attackerId));
|
attackerPerms.add(game.getPermanent(attackerId));
|
||||||
}
|
}
|
||||||
UUID attackerId = player.chooseAttackerOrder(attackerPerms, game);
|
UUID attackerId = player.chooseAttackerOrder(attackerPerms, game);
|
||||||
if (!player.isInGame()) {
|
if (attackerId == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
attackerOrder.add(attackerId);
|
attackerOrder.add(attackerId);
|
||||||
|
@ -791,7 +782,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
||||||
/**
|
/**
|
||||||
* There are effects, that set an attacker to be blocked. Therefore this
|
* There are effects, that set an attacker to be blocked. Therefore this
|
||||||
* setter can be used.
|
* setter can be used.
|
||||||
*
|
* <p>
|
||||||
* This method lacks a band check, use setBlocked(blocked, game) instead.
|
* This method lacks a band check, use setBlocked(blocked, game) instead.
|
||||||
*
|
*
|
||||||
* @param blocked
|
* @param blocked
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class PlayerList extends CircularList<UUID> {
|
||||||
player.setReachedNextTurnAfterLeaving(true);
|
player.setReachedNextTurnAfterLeaving(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.getId().equals(start)) {
|
if (player.getId().equals(start)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -63,11 +64,15 @@ public class PlayerList extends CircularList<UUID> {
|
||||||
public Player getPrevious(Game game) {
|
public Player getPrevious(Game game) {
|
||||||
Player player;
|
Player player;
|
||||||
UUID start = this.get();
|
UUID start = this.get();
|
||||||
|
if (start == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
player = game.getPlayer(super.getPrevious());
|
player = game.getPlayer(super.getPrevious());
|
||||||
if (player.isInGame()) {
|
if (player.isInGame()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.getId().equals(start)) {
|
if (player.getId().equals(start)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue