mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
refactor methods to find cards in exile (#13967)
* refactor exile method names, add comments * fix card effects checking exile with filter to process ObjectSourcePlayerPredicates * fix card effects checking exile to respect range of influence
This commit is contained in:
parent
32af4a0671
commit
34c26f09c8
60 changed files with 183 additions and 195 deletions
|
|
@ -74,8 +74,8 @@ public enum CardsInExileCount implements DynamicValue {
|
|||
return playerIds.stream()
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.map(player -> game.getExile().getAllCards(game, player.getId()))
|
||||
.map(player -> game.getExile().getCardsOwned(game, player.getId()))
|
||||
.flatMap(Collection::stream)
|
||||
.filter(Objects::nonNull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package mage.abilities.dynamicvalue.common;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.cards.Card;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
|
@ -17,18 +16,11 @@ public enum InstantSorceryExileGraveyardCount implements DynamicValue {
|
|||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
Player player = game.getPlayer(sourceAbility.getControllerId());
|
||||
if (player != null) {
|
||||
int exileCount = 0;
|
||||
for (Card exiledCard : game.getExile().getAllCards(game)) {
|
||||
if (exiledCard.getOwnerId().equals(player.getId()) && exiledCard.isInstantOrSorcery(game)) {
|
||||
exileCount++;
|
||||
}
|
||||
}
|
||||
return player.getGraveyard().count(
|
||||
StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, game
|
||||
) + exileCount;
|
||||
if (player == null) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return game.getExile().getCardsOwned(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, player.getId(), sourceAbility, game).size()
|
||||
+ player.getGraveyard().count(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, player.getId(), sourceAbility, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public enum TotalCardsExiledOwnedManaValue implements DynamicValue {
|
|||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
int totalCMC = 0;
|
||||
List<Card> cards = game.getExile().getAllCards(
|
||||
List<Card> cards = game.getExile().getCardsOwned(
|
||||
game,
|
||||
sourceAbility.getControllerId()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public class WishEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
Cards cards = controller.getSideboard();
|
||||
List<Card> exile = game.getExile().getAllCards(game);
|
||||
List<Card> exile = game.getExile().getCardsOwned(game, controller.getId());
|
||||
boolean noTargets = cards.isEmpty() && (!alsoFromExile || exile.isEmpty());
|
||||
if (noTargets) {
|
||||
game.informPlayer(controller, "You have no cards outside the game" + (alsoFromExile ? " or in exile" : "") + '.');
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public class AddCreatureSubTypeAllMultiZoneEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
}
|
||||
// in Exile
|
||||
for (Card card : game.getState().getExile().getAllCards(game, controllerId)) {
|
||||
for (Card card : game.getState().getExile().getCardsOwned(game, controllerId)) {
|
||||
if (filterCard.match(card, controllerId, source, game) && !card.hasSubtype(subType, game)) {
|
||||
game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class GainAbilityControlledSpellsEffect extends ContinuousEffectImpl {
|
|||
return false;
|
||||
}
|
||||
|
||||
for (Card card : game.getExile().getAllCardsByRange(game, source.getControllerId())) {
|
||||
for (Card card : game.getExile().getCardsInRange(game, source.getControllerId())) {
|
||||
if (filter.match(card, player.getId(), source, game)) {
|
||||
game.getState().addOtherAbility(card, ability);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public class NextSpellCastHasAbilityEffect extends ContinuousEffectImpl {
|
|||
discard(); // only one use
|
||||
return false;
|
||||
}
|
||||
for (Card card : game.getExile().getAllCardsByRange(game, playerId)) {
|
||||
for (Card card : game.getExile().getCardsInRange(game, playerId)) {
|
||||
if (filter.match(card, playerId, source, game)) {
|
||||
game.getState().addOtherAbility(card, ability);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public class ChoiceCreatureType extends ChoiceImpl {
|
|||
});
|
||||
|
||||
// exile
|
||||
game.getExile().getAllCards(game, playerId).forEach(card -> {
|
||||
game.getExile().getCardsOwned(game, playerId).forEach(card -> {
|
||||
list.addAll(card.getSubtype(game).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package mage.game;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.cards.Card;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.util.Copyable;
|
||||
|
|
@ -61,24 +62,33 @@ public class Exile implements Serializable, Copyable<Exile> {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all cards in exile matching the filter. Use only for test framework.
|
||||
* For card effects, instead use a method that checks owner or range of influence.
|
||||
*/
|
||||
@Deprecated
|
||||
public List<Card> getCards(FilterCard filter, Game game) {
|
||||
List<Card> allCards = getAllCards(game);
|
||||
return allCards.stream().filter(card -> filter.match(card, game)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Deprecated // TODO: must use related request due game range like getAllCardsByRange
|
||||
/**
|
||||
* Returns all cards in exile. Use only for test framework.
|
||||
* For card effects, instead use a method that checks owner or range of influence.
|
||||
*/
|
||||
@Deprecated
|
||||
public List<Card> getAllCards(Game game) {
|
||||
return getAllCards(game, null);
|
||||
return getCardsOwned(game, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return exiled cards owned by a specific player. Use it in effects to find all cards in range.
|
||||
* Returns all cards in exile owned by the specified player
|
||||
*/
|
||||
public List<Card> getAllCards(Game game, UUID fromPlayerId) {
|
||||
public List<Card> getCardsOwned(Game game, UUID ownerId) {
|
||||
List<Card> res = new ArrayList<>();
|
||||
for (ExileZone exile : exileZones.values()) {
|
||||
for (Card card : exile.getCards(game)) {
|
||||
if (fromPlayerId == null || card.isOwnedBy(fromPlayerId)) {
|
||||
if (ownerId == null || card.isOwnedBy(ownerId)) {
|
||||
res.add(card);
|
||||
}
|
||||
}
|
||||
|
|
@ -86,14 +96,37 @@ public class Exile implements Serializable, Copyable<Exile> {
|
|||
return res;
|
||||
}
|
||||
|
||||
public List<Card> getAllCardsByRange(Game game, UUID controllerId) {
|
||||
/**
|
||||
* Returns all cards in exile matching the filter, owned by the specified player
|
||||
*/
|
||||
public Set<Card> getCardsOwned(FilterCard filter, UUID playerId, Ability source, Game game) {
|
||||
return getCardsOwned(game, playerId)
|
||||
.stream()
|
||||
.filter(card -> filter.match(card, playerId, source, game))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all cards in exile in range of the specified player
|
||||
*/
|
||||
public List<Card> getCardsInRange(Game game, UUID controllerId) {
|
||||
List<Card> res = new ArrayList<>();
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controllerId, game)) {
|
||||
res.addAll(getAllCards(game, playerId));
|
||||
res.addAll(getCardsOwned(game, playerId));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all cards in exile matching the filter, in range of the specified player
|
||||
*/
|
||||
public Set<Card> getCardsInRange(FilterCard filter, UUID playerId, Ability source, Game game) {
|
||||
return getCardsInRange(game, playerId)
|
||||
.stream()
|
||||
.filter(card -> filter.match(card, playerId, source, game))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
}
|
||||
|
||||
public boolean removeCard(Card card) {
|
||||
for (ExileZone exile : exileZones.values()) {
|
||||
if (exile.contains(card.getId())) {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ public class KayaTheInexorableEmblem extends Emblem {
|
|||
|
||||
class KayaTheInexorableEmblemEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterCard filter = new FilterOwnedCard();
|
||||
private static final FilterCard filter2 = new FilterCard();
|
||||
private static final Set<String> choices = new LinkedHashSet<>();
|
||||
|
||||
|
|
@ -94,7 +93,7 @@ class KayaTheInexorableEmblemEffect extends OneShotEffect {
|
|||
cards.addAll(player.getGraveyard());
|
||||
break;
|
||||
case "Exile":
|
||||
cards.addAllCards(game.getExile().getCards(filter, game));
|
||||
cards.addAllCards(game.getExile().getCardsOwned(game, player.getId()));
|
||||
break;
|
||||
}
|
||||
return CardUtil.castSpellWithAttributesForFree(player, source, game, cards, filter2);
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ public class TargetCard extends TargetObject {
|
|||
protected static Set<UUID> getAllPossibleTargetInExile(Game game, Player player, UUID sourceControllerId, Ability source, FilterCard filter, boolean isNotTarget) {
|
||||
Set<UUID> possibleTargets = new HashSet<>();
|
||||
UUID sourceId = source != null ? source.getSourceId() : null;
|
||||
for (Card card : game.getExile().getAllCardsByRange(game, sourceControllerId)) {
|
||||
for (Card card : game.getExile().getCardsInRange(game, sourceControllerId)) {
|
||||
if (filter.match(card, sourceControllerId, source, game)) {
|
||||
possibleTargets.add(card.getId());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ public class TargetSource extends TargetObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (Card card : game.getExile().getAllCards(game)) {
|
||||
for (Card card : game.getExile().getCardsInRange(game, sourceControllerId)) {
|
||||
if (filter.match(card, sourceControllerId, source, game)) {
|
||||
possibleTargets.add(card.getId());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class TargetCardInExile extends TargetCard {
|
|||
Set<UUID> possibleTargets = new HashSet<>();
|
||||
|
||||
if (zoneId == null) { // no specific exile zone
|
||||
for (Card card : game.getExile().getAllCardsByRange(game, sourceControllerId)) {
|
||||
for (Card card : game.getExile().getCardsInRange(game, sourceControllerId)) {
|
||||
if (filter.match(card, sourceControllerId, source, game)) {
|
||||
possibleTargets.add(card.getId());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class TargetPermanentOrSuspendedCard extends TargetImpl {
|
|||
possibleTargets.add(permanent.getId());
|
||||
}
|
||||
}
|
||||
for (Card card : game.getExile().getAllCards(game)) {
|
||||
for (Card card : game.getExile().getCardsInRange(game, sourceControllerId)) {
|
||||
if (filter.match(card, sourceControllerId, source, game)) {
|
||||
possibleTargets.add(card.getId());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue