* Gain cost modification abilities - fixed that commanders can't be played without full mana (example: gained Affinity by Mycosynth Golem, gained Convoke by Chief Engineer, see #7249 #7171, #6698);

This commit is contained in:
Oleg Agafonov 2020-12-18 18:33:44 +04:00
parent 53c5abea14
commit 384ff2e7ac
8 changed files with 145 additions and 28 deletions

View file

@ -60,6 +60,14 @@ public class GainAbilitySpellsEffect extends ContinuousEffectImpl {
game.getState().addOtherAbility(card, ability);
}
}
// workaround to gain cost reduction abilities to commanders before cast (make it playable)
game.getCommanderCardsFromCommandZone(player).stream()
.filter(card -> filter.match(card, game))
.forEach(card -> {
game.getState().addOtherAbility(card, ability);
});
for (StackObject stackObject : game.getStack()) {
if (stackObject.isControlledBy(source.getControllerId())) {
Card card = game.getCard(stackObject.getSourceId());

View file

@ -44,8 +44,7 @@ public class GainAbilityControlledSpellsEffect extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null
&& permanent != null) {
if (player != null && permanent != null) {
for (Card card : game.getExile().getAllCards(game)) {
if (card.isOwnedBy(source.getControllerId())
&& filter.match(card, game)) {
@ -67,6 +66,14 @@ public class GainAbilityControlledSpellsEffect extends ContinuousEffectImpl {
game.getState().addOtherAbility(card, ability);
}
}
// workaround to gain cost reduction abilities to commanders before cast (make it playable)
game.getCommanderCardsFromCommandZone(player).stream()
.filter(card -> filter.match(card, game))
.forEach(card -> {
game.getState().addOtherAbility(card, ability);
});
for (StackObject stackObject : game.getStack()) {
// only spells cast, so no copies of spells
if ((stackObject instanceof Spell)

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;
@ -45,6 +42,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();
@ -503,6 +504,21 @@ public interface Game extends MageItem, Serializable {
return getCommandersIds(player, CommanderCardType.ANY);
}
/**
* Return not played commander cards from command zone
*
* @param player
* @return
*/
default Set<Card> getCommanderCardsFromCommandZone(Player player) {
// commanders in command zone aren't cards so you must call getCard instead getObject
return getCommandersIds(player).stream()
.map(this::getCard)
.filter(Objects::nonNull)
.filter(card -> Zone.COMMAND.equals(this.getState().getZone(card.getId())))
.collect(Collectors.toSet());
}
void setGameStopped(boolean gameStopped);
boolean isGameStopped();

View file

@ -23,6 +23,7 @@ import mage.filter.Filter;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.CardState;
import mage.game.Game;
import mage.game.command.Commander;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
@ -815,6 +816,15 @@ public final class CardUtil {
public static Abilities<Ability> getAbilities(MageObject object, Game game) {
if (object instanceof Card) {
return ((Card) object).getAbilities(game);
} else if (object instanceof Commander && Zone.COMMAND.equals(game.getState().getZone(object.getId()))) {
// Commanders in command zone must gain cost related abilities for playable
// calculation (affinity, convoke; example: Chief Engineer). So you must use card object here
Card card = game.getCard(object.getId());
if (card != null) {
return card.getAbilities(game);
} else {
return object.getAbilities();
}
} else {
return object.getAbilities();
}