Refactor: added missing getPlayersInRange in cards code (to ignore leaved/lost players);

This commit is contained in:
Oleg Agafonov 2019-12-26 05:24:44 +04:00
parent 04cceb9b62
commit 61a58d36c2
15 changed files with 75 additions and 110 deletions

View file

@ -10,11 +10,9 @@ import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author Jeff
*/
public class BeginningOfUntapTriggeredAbility extends TriggeredAbilityImpl {
@ -59,8 +57,8 @@ public class BeginningOfUntapTriggeredAbility extends TriggeredAbilityImpl {
}
return yours;
case NOT_YOU:
Player controller = game.getPlayer(this.getControllerId());
if (controller != null && controller.getInRange().contains(event.getPlayerId()) && !event.getPlayerId().equals(this.getControllerId())) {
if (game.getState().getPlayersInRange(this.getControllerId(), game).contains(event.getPlayerId())
&& !event.getPlayerId().equals(this.getControllerId())) {
if (getTargets().isEmpty()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
@ -80,8 +78,7 @@ public class BeginningOfUntapTriggeredAbility extends TriggeredAbilityImpl {
}
break;
case ANY:
controller = game.getPlayer(this.getControllerId());
if (controller != null && controller.getInRange().contains(event.getPlayerId())) {
if (game.getState().getPlayersInRange(this.getControllerId(), game).contains(event.getPlayerId())) {
if (getTargets().isEmpty()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
@ -89,6 +86,7 @@ public class BeginningOfUntapTriggeredAbility extends TriggeredAbilityImpl {
}
return true;
}
break;
}
return false;
}

View file

@ -1,8 +1,5 @@
package mage.game;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import mage.MageItem;
import mage.MageObject;
import mage.abilities.Ability;
@ -44,6 +41,10 @@ import mage.players.Players;
import mage.util.MessageToClient;
import mage.util.functions.ApplyToPermanent;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
public interface Game extends MageItem, Serializable {
MatchType getGameType();
@ -127,7 +128,6 @@ public interface Game extends MageItem, Serializable {
return player.getInRange().stream()
.filter(opponentId -> !opponentId.equals(playerId))
.collect(Collectors.toSet());
}
default boolean isActivePlayer(UUID playerId) {
@ -298,9 +298,9 @@ public interface Game extends MageItem, Serializable {
/**
* Creates and fires an damage prevention event
*
* @param damageEvent damage event that will be replaced (instanceof check
* will be done)
* @param source ability that's the source of the prevention effect
* @param damageEvent damage event that will be replaced (instanceof check
* will be done)
* @param source ability that's the source of the prevention effect
* @param game
* @param amountToPrevent max preventable amount
* @return true prevention was successfull / false prevention was replaced
@ -310,12 +310,12 @@ public interface Game extends MageItem, Serializable {
/**
* Creates and fires an damage prevention event
*
* @param event damage event that will be replaced (instanceof check will be
* done)
* @param source ability that's the source of the prevention effect
* @param event damage event that will be replaced (instanceof check will be
* done)
* @param source ability that's the source of the prevention effect
* @param game
* @param preventAllDamage true if there is no limit to the damage that can
* be prevented
* be prevented
* @return true prevention was successfull / false prevention was replaced
*/
PreventionEffectData preventDamage(GameEvent event, Ability source, Game game, boolean preventAllDamage);

View file

@ -635,6 +635,9 @@ public class GameState implements Serializable, Copyable<GameState> {
* Returns a list of all active players of the game in range of playerId,
* also setting the playerId to the first/current player of the list. Also
* returning the other players in turn order.
* <p>
* Not safe for continuous effects, see rule 800.4k (effects must work until end of turn even after player leaves)
* Use Player.InRange() to find active players list at the start of the turn
*
* @param playerId
* @param game
@ -645,7 +648,7 @@ public class GameState implements Serializable, Copyable<GameState> {
Player currentPlayer = game.getPlayer(playerId);
if (currentPlayer != null) {
for (Player player : players.values()) {
if (!player.hasLeft() && !player.hasLost() && currentPlayer.getInRange().contains(player.getId())) {
if (player.isInGame() && currentPlayer.getInRange().contains(player.getId())) {
newPlayerList.add(player.getId());
}
}

View file

@ -1,4 +1,3 @@
package mage.game.permanent;
import mage.abilities.keyword.PhasingAbility;
@ -6,7 +5,6 @@ import mage.constants.CardType;
import mage.constants.RangeOfInfluence;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.players.Player;
import java.io.Serializable;
import java.util.*;
@ -85,8 +83,8 @@ public class Battlefield implements Serializable {
&& permanent.isPhasedIn())
.count();
} else {
Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange();
return (int) field.values()
List<UUID> range = game.getState().getPlayersInRange(sourcePlayerId, game);
return (int) field.values()
.stream()
.filter(permanent -> range.contains(permanent.getControllerId())
&& filter.match(permanent, sourceId, sourcePlayerId, game)
@ -150,7 +148,7 @@ public class Battlefield implements Serializable {
&& permanent.isPhasedIn()).count() >= num;
} else {
Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange();
List<UUID> range = game.getState().getPlayersInRange(sourcePlayerId, game);
return field.values().stream()
.filter(permanent -> range.contains(permanent.getControllerId())
&& filter.match(permanent, null, sourcePlayerId, game)
@ -298,12 +296,8 @@ public class Battlefield implements Serializable {
.filter(perm -> perm.isPhasedIn() && filter.match(perm, sourceId, sourcePlayerId, game))
.collect(Collectors.toList());
} else {
Player player = game.getPlayer(sourcePlayerId);
if(player == null){
return Collections.emptyList();
}
Set<UUID> range = player.getInRange();
return field.values()
List<UUID> range = game.getState().getPlayersInRange(sourcePlayerId, game);
return field.values()
.stream()
.filter(perm -> perm.isPhasedIn() && range.contains(perm.getControllerId())
&& filter.match(perm, sourceId, sourcePlayerId, game)).collect(Collectors.toList());
@ -323,7 +317,7 @@ public class Battlefield implements Serializable {
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
return getAllActivePermanents();
} else {
Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange();
List<UUID> range = game.getState().getPlayersInRange(sourcePlayerId, game);
return field.values()
.stream()
.filter(perm -> perm.isPhasedIn()

View file

@ -211,13 +211,6 @@ public interface Player extends MageItem, Copyable<Player> {
*/
boolean canRespond();
/**
* Called if other player left the game
*
* @param game
*/
void otherPlayerLeftGame(Game game);
ManaPool getManaPool();
Set<UUID> getInRange();

View file

@ -457,11 +457,6 @@ public abstract class PlayerImpl implements Player, Serializable {
return counters;
}
@Override
public void otherPlayerLeftGame(Game game) {
findRange(game);
}
@Override
public void beginTurn(Game game) {
this.landsPlayed = 0;