mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 21:12:04 -08:00
Merge origin/master
This commit is contained in:
commit
238152d6c4
8 changed files with 399 additions and 186 deletions
|
|
@ -110,11 +110,13 @@ public abstract class SplitCard extends CardImpl {
|
|||
public Abilities<Ability> getAbilities() {
|
||||
Abilities<Ability> allAbilites = new AbilitiesImpl<>();
|
||||
for (Ability ability : super.getAbilities()) {
|
||||
// ignore split abilities TODO: why it here, for GUI's cleanup in card texts? Maybe it can be removed
|
||||
if (ability instanceof SpellAbility
|
||||
&& ((SpellAbility) ability).getSpellAbilityType() != SpellAbilityType.SPLIT
|
||||
&& ((SpellAbility) ability).getSpellAbilityType() != SpellAbilityType.SPLIT_AFTERMATH) {
|
||||
allAbilites.add(ability);
|
||||
&& (((SpellAbility) ability).getSpellAbilityType() == SpellAbilityType.SPLIT
|
||||
|| ((SpellAbility) ability).getSpellAbilityType() == SpellAbilityType.SPLIT_AFTERMATH)) {
|
||||
continue;
|
||||
}
|
||||
allAbilites.add(ability);
|
||||
}
|
||||
allAbilites.addAll(leftHalfCard.getAbilities());
|
||||
allAbilites.addAll(rightHalfCard.getAbilities());
|
||||
|
|
|
|||
|
|
@ -246,7 +246,6 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
this.storedBookmark = player.storedBookmark;
|
||||
|
||||
this.topCardRevealed = player.topCardRevealed;
|
||||
this.playersUnderYourControl.clear();
|
||||
this.playersUnderYourControl.addAll(player.playersUnderYourControl);
|
||||
this.usersAllowedToSeeHandCards.addAll(player.usersAllowedToSeeHandCards);
|
||||
|
||||
|
|
@ -254,7 +253,6 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
this.isGameUnderControl = player.isGameUnderControl;
|
||||
|
||||
this.turnController = player.turnController;
|
||||
this.turnControllers.clear();
|
||||
this.turnControllers.addAll(player.turnControllers);
|
||||
|
||||
this.passed = player.passed;
|
||||
|
|
@ -1190,18 +1188,20 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return false;
|
||||
}
|
||||
ActivatedAbility playLandAbility = null;
|
||||
boolean found = false;
|
||||
boolean foundAlternative = false;
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if ((ability instanceof AlternativeSourceCosts)
|
||||
|| (ability instanceof OptionalAdditionalSourceCosts)) {
|
||||
found = true;
|
||||
foundAlternative = true;
|
||||
}
|
||||
if (ability instanceof PlayLandAbility) {
|
||||
playLandAbility = (ActivatedAbility) ability;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
|
||||
// try alternative cast (face down)
|
||||
if (foundAlternative) {
|
||||
SpellAbility spellAbility = new SpellAbility(null, "",
|
||||
game.getState().getZone(card.getId()), SpellAbilityType.FACE_DOWN_CREATURE);
|
||||
spellAbility.setControllerId(this.getId());
|
||||
|
|
@ -1210,9 +1210,11 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (playLandAbility == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//20091005 - 114.2a
|
||||
ActivationStatus activationStatus = playLandAbility.canActivate(this.playerId, game);
|
||||
if (ignoreTiming) {
|
||||
|
|
@ -1496,110 +1498,29 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return useable;
|
||||
}
|
||||
|
||||
// Get the usable activated abilities for a *single card object*, that is, either a card or half of a split card.
|
||||
// Also called on the whole split card but only passing the fuse ability and other whole-split-card shared abilities
|
||||
// as candidates.
|
||||
private void getUseableActivatedAbilitiesHalfImpl(MageObject object, Zone zone, Game game, Abilities<Ability> candidateAbilites,
|
||||
LinkedHashMap<UUID, ActivatedAbility> output) {
|
||||
boolean canUse = !(object instanceof Permanent) || ((Permanent) object).canUseActivatedAbilities(game);
|
||||
ManaOptions availableMana = null;
|
||||
// ManaOptions availableMana = getManaAvailable(game); // can only be activated if mana calculation works flawless otherwise player can't play spells they could play if calculation would work correctly
|
||||
// availableMana.addMana(manaPool.getMana());
|
||||
for (Ability ability : candidateAbilites) {
|
||||
if (canUse || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
|
||||
if (ability.getZone().match(zone)) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
if (ability instanceof ActivatedManaAbilityImpl) {
|
||||
if (((ActivatedAbility) ability).canActivate(playerId, game).canActivate()) {
|
||||
output.put(ability.getId(), (ActivatedAbility) ability);
|
||||
}
|
||||
} else if (canPlay(((ActivatedAbility) ability), availableMana, object, game)) {
|
||||
output.put(ability.getId(), (ActivatedAbility) ability);
|
||||
}
|
||||
} else if (ability instanceof AlternativeSourceCosts) {
|
||||
if (object.isLand()) {
|
||||
for (Ability ability2 : object.getAbilities().copy()) {
|
||||
if (ability2 instanceof PlayLandAbility) {
|
||||
output.put(ability2.getId(), (ActivatedAbility) ability2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (zone != Zone.HAND) {
|
||||
if (Zone.GRAVEYARD == zone && canPlayCardsFromGraveyard()) {
|
||||
for (ActivatedAbility ability : candidateAbilites.getPlayableAbilities(Zone.HAND)) {
|
||||
if (canUse
|
||||
|| ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
|
||||
if (ability.getZone().equals(zone) || ability.getZone().equals(Zone.HAND)) {
|
||||
if (ability.canActivate(playerId, game).canActivate()) {
|
||||
output.put(ability.getId(), ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (zone != Zone.BATTLEFIELD) {
|
||||
for (Ability ability : candidateAbilites) {
|
||||
if (ability.getZone().equals(zone) || ability.getZone().equals(Zone.HAND)) {
|
||||
if (game.getContinuousEffects().asThough(object.getId(),
|
||||
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE,
|
||||
null,
|
||||
this.getId(),
|
||||
game)
|
||||
!= null
|
||||
// if anyone sees an issue with this code, please report it. Worked in my testing. !
|
||||
|| game.getContinuousEffects().asThough(object.getId(),
|
||||
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE,
|
||||
ability,
|
||||
this.getId(),
|
||||
game)
|
||||
!= null) {
|
||||
if (canUse
|
||||
|| ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
|
||||
ability.setControllerId(this.getId());
|
||||
if (ability instanceof ActivatedAbility
|
||||
&& ability.getZone().match(Zone.HAND)
|
||||
&& ((ActivatedAbility) ability).canActivate(playerId, game).canActivate()) {
|
||||
output.put(ability.getId(), (ActivatedAbility) ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedHashMap<UUID, ActivatedAbility> getUseableActivatedAbilities(MageObject object, Zone zone, Game game) {
|
||||
// TODO: replace with getPlayableFromNonHandCardAll (uses for all tests)
|
||||
LinkedHashMap<UUID, ActivatedAbility> useable = new LinkedHashMap<>();
|
||||
boolean previousState = game.inCheckPlayableState();
|
||||
game.setCheckPlayableState(true);
|
||||
LinkedHashMap<UUID, ActivatedAbility> useable = new LinkedHashMap<>();
|
||||
if (object instanceof StackAbility) { // It may not be possible to activate abilities of stack abilities
|
||||
return useable;
|
||||
}
|
||||
if (object instanceof SplitCard) { // TODO: use of getAbilities(game)
|
||||
SplitCard splitCard = (SplitCard) object;
|
||||
getUseableActivatedAbilitiesHalfImpl(splitCard.getLeftHalfCard(),
|
||||
zone, game, splitCard.getLeftHalfCard().getAbilities(game), useable);
|
||||
getUseableActivatedAbilitiesHalfImpl(splitCard.getRightHalfCard(),
|
||||
zone, game, splitCard.getRightHalfCard().getAbilities(game), useable);
|
||||
getUseableActivatedAbilitiesHalfImpl(splitCard,
|
||||
zone, game, splitCard.getSharedAbilities(game), useable);
|
||||
} else if (object instanceof Card) {
|
||||
getUseableActivatedAbilitiesHalfImpl(object,
|
||||
zone, game, ((Card) object).getAbilities(game), useable);
|
||||
} else if (object != null) {
|
||||
getUseableActivatedAbilitiesHalfImpl(object,
|
||||
zone, game, object.getAbilities(), useable);
|
||||
getOtherUseableActivatedAbilities(object, zone, game, useable);
|
||||
}
|
||||
try {
|
||||
// It may not be possible to activate abilities of stack abilities
|
||||
if (object instanceof StackAbility) {
|
||||
return useable;
|
||||
}
|
||||
|
||||
game.setCheckPlayableState(previousState);
|
||||
// collect and filter playable activated abilities
|
||||
List<Ability> allPlayable = getPlayable(game, true, zone, false);
|
||||
for (Ability ability : allPlayable) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
if (object.hasAbility(ability, game)) {
|
||||
useable.putIfAbsent(ability.getId(), (ActivatedAbility) ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
game.setCheckPlayableState(previousState);
|
||||
}
|
||||
return useable;
|
||||
}
|
||||
|
||||
|
|
@ -3184,6 +3105,51 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected ActivatedAbility findActivatedAbilityFromPlayable(Card card, ManaOptions manaAvailable, Ability ability, Game game) {
|
||||
// replace alternative abilities by real play abilities (e.g. morph/facedown static ability by play land)
|
||||
|
||||
if (ability instanceof ActivatedManaAbilityImpl) {
|
||||
// mana ability
|
||||
if (((ActivatedManaAbilityImpl) ability).canActivate(this.getId(), game).canActivate()) {
|
||||
return (ActivatedManaAbilityImpl) ability;
|
||||
}
|
||||
} else if (ability instanceof AlternativeSourceCosts) {
|
||||
// alternative cost must be replaced by real play ability
|
||||
return findActivatedAbilityFromAlternativeSourceCost(card, manaAvailable, ability, game);
|
||||
} else if (ability instanceof ActivatedAbility) {
|
||||
// activated ability
|
||||
if (canPlay((ActivatedAbility) ability, manaAvailable, card, game)) {
|
||||
return (ActivatedAbility) ability;
|
||||
}
|
||||
}
|
||||
|
||||
// non playable abilities like static
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ActivatedAbility findActivatedAbilityFromAlternativeSourceCost(Card card, ManaOptions manaAvailable, Ability ability, Game game) {
|
||||
// alternative cost must be replaced by real play ability
|
||||
if (ability instanceof AlternativeSourceCosts) {
|
||||
AlternativeSourceCosts altAbility = (AlternativeSourceCosts) ability;
|
||||
if (card.isLand()) {
|
||||
// land
|
||||
// morph ability is static, so it must be replaced with play land ability (playLand search and try to use face down first)
|
||||
if (canLandPlayAlternateSourceCostsAbility(card, manaAvailable, ability, game)) { // e.g. Land with Morph
|
||||
Optional<Ability> landAbility = card.getAbilities(game).stream().filter(a -> a instanceof PlayLandAbility).findFirst();
|
||||
if (landAbility.isPresent()) {
|
||||
return (ActivatedAbility) landAbility.get();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// creature and other
|
||||
if (altAbility.isAvailable(card.getSpellAbility(), game)) {
|
||||
return card.getSpellAbility();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean canLandPlayAlternateSourceCostsAbility(Card sourceObject, ManaOptions available, Ability ability, Game game) {
|
||||
if (!(sourceObject instanceof Permanent)) {
|
||||
Ability sourceAbility = sourceObject.getAbilities().stream()
|
||||
|
|
@ -3216,27 +3182,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void getPlayableFromGraveyardCard(Game game, Card card, Abilities<Ability> candidateAbilities, ManaOptions availableMana, List<Ability> output) {
|
||||
MageObjectReference permittingObject = game.getContinuousEffects().asThough(card.getId(),
|
||||
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, card.getSpellAbility(), this.getId(), game);
|
||||
for (ActivatedAbility ability : candidateAbilities.getActivatedAbilities(Zone.ALL)) {
|
||||
boolean possible = false;
|
||||
if (ability.getZone().match(Zone.GRAVEYARD)) {
|
||||
possible = true;
|
||||
} else if (ability.getZone().match(Zone.HAND)
|
||||
&& (ability instanceof SpellAbility
|
||||
|| ability instanceof PlayLandAbility)) {
|
||||
if (permittingObject != null || canPlayCardsFromGraveyard()) {
|
||||
possible = true;
|
||||
}
|
||||
}
|
||||
if (possible && canPlay(ability, availableMana, card, game)) {
|
||||
output.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getPlayableFromNonHandCardAll(Game game, Zone fromZone, Card card, ManaOptions availableMana, List<Ability> output) {
|
||||
private void getPlayableFromCardAll(Game game, Zone fromZone, Card card, ManaOptions availableMana, List<Ability> output) {
|
||||
if (fromZone == null) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -3244,16 +3190,16 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
// BASIC abilities
|
||||
if (card instanceof SplitCard) {
|
||||
SplitCard splitCard = (SplitCard) card;
|
||||
getPlayableFromNonHandCardSingle(game, fromZone, splitCard.getLeftHalfCard(), splitCard.getLeftHalfCard().getAbilities(), availableMana, output);
|
||||
getPlayableFromNonHandCardSingle(game, fromZone, splitCard.getRightHalfCard(), splitCard.getRightHalfCard().getAbilities(), availableMana, output);
|
||||
getPlayableFromNonHandCardSingle(game, fromZone, splitCard, splitCard.getSharedAbilities(game), availableMana, output);
|
||||
getPlayableFromCardSingle(game, fromZone, splitCard.getLeftHalfCard(), splitCard.getLeftHalfCard().getAbilities(), availableMana, output);
|
||||
getPlayableFromCardSingle(game, fromZone, splitCard.getRightHalfCard(), splitCard.getRightHalfCard().getAbilities(), availableMana, output);
|
||||
getPlayableFromCardSingle(game, fromZone, splitCard, splitCard.getSharedAbilities(game), availableMana, output);
|
||||
} else if (card instanceof AdventureCard) {
|
||||
// adventure must use different card characteristics for different spells (main or adventure)
|
||||
AdventureCard adventureCard = (AdventureCard) card;
|
||||
getPlayableFromNonHandCardSingle(game, fromZone, adventureCard.getSpellCard(), adventureCard.getSpellCard().getAbilities(), availableMana, output);
|
||||
getPlayableFromNonHandCardSingle(game, fromZone, adventureCard, adventureCard.getSharedAbilities(game), availableMana, output);
|
||||
getPlayableFromCardSingle(game, fromZone, adventureCard.getSpellCard(), adventureCard.getSpellCard().getAbilities(), availableMana, output);
|
||||
getPlayableFromCardSingle(game, fromZone, adventureCard, adventureCard.getSharedAbilities(game), availableMana, output);
|
||||
} else {
|
||||
getPlayableFromNonHandCardSingle(game, fromZone, card, card.getAbilities(), availableMana, output);
|
||||
getPlayableFromCardSingle(game, fromZone, card, card.getAbilities(game), availableMana, output);
|
||||
}
|
||||
|
||||
// DYNAMIC ADDED abilities
|
||||
|
|
@ -3278,7 +3224,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private void getPlayableFromNonHandCardSingle(Game game, Zone fromZone, Card card, Abilities<Ability> candidateAbilities, ManaOptions availableMana, List<Ability> output) {
|
||||
private void getPlayableFromCardSingle(Game game, Zone fromZone, Card card, Abilities<Ability> candidateAbilities, ManaOptions availableMana, List<Ability> output) {
|
||||
// check "can play" condition as affected controller (BUT play from not own hand zone must be checked as original controller)
|
||||
for (ActivatedAbility ability : candidateAbilities.getActivatedAbilities(Zone.ALL)) {
|
||||
boolean isPlaySpell = (ability instanceof SpellAbility);
|
||||
|
|
@ -3339,8 +3285,13 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
possibleToPlay = true;
|
||||
}
|
||||
|
||||
if (possibleToPlay && canPlay(ability, availableMana, card, game)) {
|
||||
output.add(ability);
|
||||
if (!possibleToPlay) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ActivatedAbility playAbility = findActivatedAbilityFromPlayable(card, availableMana, ability, game);
|
||||
if (playAbility != null && !output.contains(playAbility)) {
|
||||
output.add(playAbility);
|
||||
}
|
||||
} finally {
|
||||
ability.setControllerId(savedControllerId);
|
||||
|
|
@ -3355,8 +3306,13 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
public List<Ability> getPlayable(Game game, boolean hidden, Zone fromZone, boolean hideDuplicatedAbilities) {
|
||||
List<Ability> playable = new ArrayList<>();
|
||||
if (shouldSkipGettingPlayable(game)) {
|
||||
return playable;
|
||||
}
|
||||
|
||||
boolean previousState = game.inCheckPlayableState();
|
||||
game.setCheckPlayableState(true);
|
||||
if (!shouldSkipGettingPlayable(game)) {
|
||||
try {
|
||||
ManaOptions availableMana = getManaAvailable(game);
|
||||
availableMana.addMana(manaPool.getMana());
|
||||
for (ConditionalMana conditionalMana : manaPool.getConditionalMana()) {
|
||||
|
|
@ -3390,26 +3346,9 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
continue;
|
||||
}
|
||||
|
||||
// if have alternative cost
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
// normal ability
|
||||
if (canPlay((ActivatedAbility) ability, availableMana, card, game)) {
|
||||
playable.add(ability);
|
||||
}
|
||||
} else if (ability instanceof AlternativeSourceCosts) {
|
||||
if (card.isLand()) {
|
||||
if (canLandPlayAlternateSourceCostsAbility(card, availableMana, ability, game)) { // e.g. Land with Morph
|
||||
playable.add(ability);
|
||||
}
|
||||
} else if (card.isCreature()) { // e.g. makes a card available for play by Morph if the card may not be cast normally
|
||||
if (!playable.contains(card.getSpellAbility())) {
|
||||
if (((AlternativeSourceCosts) ability).isAvailable(card.getSpellAbility(), game)) {
|
||||
playable.add(card.getSpellAbility());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// unknown type
|
||||
ActivatedAbility playAbility = findActivatedAbilityFromPlayable(card, availableMana, ability, game);
|
||||
if (playAbility != null && !playable.contains(playAbility)) {
|
||||
playable.add(playAbility);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3418,14 +3357,14 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
if (fromAll || fromZone == Zone.GRAVEYARD) {
|
||||
for (Card card : graveyard.getCards(game)) {
|
||||
getPlayableFromNonHandCardAll(game, Zone.GRAVEYARD, card, availableMana, playable);
|
||||
getPlayableFromCardAll(game, Zone.GRAVEYARD, card, availableMana, playable);
|
||||
}
|
||||
}
|
||||
|
||||
if (fromAll || fromZone == Zone.EXILED) {
|
||||
for (ExileZone exile : game.getExile().getExileZones()) {
|
||||
for (Card card : exile.getCards(game)) {
|
||||
getPlayableFromNonHandCardAll(game, Zone.EXILED, card, availableMana, playable);
|
||||
getPlayableFromCardAll(game, Zone.EXILED, card, availableMana, playable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3435,7 +3374,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
for (Cards revealedCards : game.getState().getRevealed().values()) {
|
||||
for (Card card : revealedCards.getCards(game)) {
|
||||
// revealed cards can be from any zones
|
||||
getPlayableFromNonHandCardAll(game, game.getState().getZone(card.getId()), card, availableMana, playable);
|
||||
getPlayableFromCardAll(game, game.getState().getZone(card.getId()), card, availableMana, playable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3444,7 +3383,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (fromAll || fromZone == Zone.OUTSIDE) {
|
||||
for (Cards companionCards : game.getState().getCompanion().values()) {
|
||||
for (Card card : companionCards.getCards(game)) {
|
||||
getPlayableFromNonHandCardAll(game, Zone.OUTSIDE, card, availableMana, playable);
|
||||
getPlayableFromCardAll(game, Zone.OUTSIDE, card, availableMana, playable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3453,12 +3392,10 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (fromAll || fromZone == Zone.LIBRARY) {
|
||||
for (UUID playerInRangeId : game.getState().getPlayersInRange(getId(), game)) {
|
||||
Player player = game.getPlayer(playerInRangeId);
|
||||
if (player != null) {
|
||||
if (/*player.isTopCardRevealed() &&*/player.getLibrary().hasCards()) {
|
||||
Card card = player.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
getPlayableFromNonHandCardAll(game, Zone.LIBRARY, card, availableMana, playable);
|
||||
}
|
||||
if (player != null && player.getLibrary().hasCards()) {
|
||||
Card card = player.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
getPlayableFromCardAll(game, Zone.LIBRARY, card, availableMana, playable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3471,10 +3408,13 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
// activated abilities from battlefield objects
|
||||
if (fromAll || fromZone == Zone.BATTLEFIELD) {
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
|
||||
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = getUseableActivatedAbilities(permanent, Zone.BATTLEFIELD, game);
|
||||
for (ActivatedAbility ability : useableAbilities.values()) {
|
||||
activatedUnique.putIfAbsent(ability.toString(), ability);
|
||||
activatedAll.add(ability);
|
||||
List<Ability> battlePlayable = new ArrayList<>();
|
||||
getPlayableFromCardAll(game, Zone.BATTLEFIELD, permanent, availableMana, battlePlayable);
|
||||
for (Ability ability : battlePlayable) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
activatedUnique.putIfAbsent(ability.toString(), ability);
|
||||
activatedAll.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3483,8 +3423,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (fromAll || fromZone == Zone.STACK) {
|
||||
for (StackObject stackObject : game.getState().getStack()) {
|
||||
for (ActivatedAbility ability : stackObject.getAbilities().getActivatedAbilities(Zone.STACK)) {
|
||||
if (ability != null
|
||||
&& canPlay(ability, availableMana, game.getObject(ability.getSourceId()), game)) {
|
||||
if (canPlay(ability, availableMana, game.getObject(ability.getSourceId()), game)) {
|
||||
activatedUnique.put(ability.toString(), ability);
|
||||
activatedAll.add(ability);
|
||||
}
|
||||
|
|
@ -3496,8 +3435,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (fromAll || fromZone == Zone.COMMAND) {
|
||||
for (CommandObject commandObject : game.getState().getCommand()) {
|
||||
for (ActivatedAbility ability : commandObject.getAbilities().getActivatedAbilities(Zone.COMMAND)) {
|
||||
if (ability.isControlledBy(getId())
|
||||
&& canPlay(ability, availableMana, game.getObject(ability.getSourceId()), game)) {
|
||||
if (canPlay(ability, availableMana, game.getObject(ability.getSourceId()), game)) {
|
||||
activatedUnique.put(ability.toString(), ability);
|
||||
activatedAll.add(ability);
|
||||
}
|
||||
|
|
@ -3510,8 +3448,10 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
} else {
|
||||
playable.addAll(activatedAll);
|
||||
}
|
||||
} finally {
|
||||
game.setCheckPlayableState(previousState);
|
||||
}
|
||||
game.setCheckPlayableState(false);
|
||||
|
||||
return playable;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue