Ghostfire Blade - fixed that it can't be played without full available mana (#6698);

This commit is contained in:
Oleg Agafonov 2020-07-02 20:37:59 +04:00
parent 2a31e8063b
commit 6dccaee9a4
7 changed files with 127 additions and 48 deletions

View file

@ -1226,6 +1226,14 @@ public abstract class AbilityImpl implements Ability {
}
}
/**
* Dynamic cost modification for ability.
* Example: if it need stack related info (like real targets) then must check two states (game.inCheckPlayableState):
* 1. In playable state it must check all possible use cases (e.g. allow to reduce on any available target and modes)
* 2. In real cast state it must check current use case (e.g. real selected targets and modes)
*
* @param costAdjuster
*/
@Override
public void setCostAdjuster(CostAdjuster costAdjuster) {
this.costAdjuster = costAdjuster;

View file

@ -8,5 +8,14 @@ import mage.game.Game;
*/
public interface CostAdjuster {
/**
* Must check playable and real cast states.
* Example: if it need stack related info (like real targets) then must check two states (game.inCheckPlayableState):
* 1. In playable state it must check all possible use cases (e.g. allow to reduce on any available target and modes)
* 2. In real cast state it must check current use case (e.g. real selected targets and modes)
*
* @param ability
* @param game
*/
void adjustCosts(Ability ability, Game game);
}

View file

@ -1,7 +1,6 @@
package mage.abilities.effects.common.cost;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.SpellAbility;
import mage.constants.CostModificationType;
import mage.constants.Duration;
@ -11,13 +10,10 @@ import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.Target;
import mage.util.CardUtil;
import java.util.Collection;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author JayDi85
@ -119,12 +115,12 @@ public class SpellsCostModificationThatTargetSourceEffect extends CostModificati
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
if (spell != null && this.spellFilter.match(spell, game)) {
// real cast with put on stack
Set<UUID> allTargets = getAllSelectedTargets(abilityToModify, source, game);
Set<UUID> allTargets = CardUtil.getAllSelectedTargets(abilityToModify, game);
return allTargets.contains(source.getSourceId());
} else {
// get playable and other staff without put on stack
// used at least for flashback ability because Flashback ability doesn't use stack
Set<UUID> allTargets = getAllPossibleTargets(abilityToModify, source, game);
Set<UUID> allTargets = CardUtil.getAllPossibleTargets(abilityToModify, game);
switch (this.getModificationType()) {
case REDUCE_COST:
// reduce all the time
@ -137,27 +133,6 @@ public class SpellsCostModificationThatTargetSourceEffect extends CostModificati
return false;
}
private Set<UUID> getAllSelectedTargets(Ability abilityToModify, Ability source, Game game) {
return abilityToModify.getModes().getSelectedModes()
.stream()
.map(abilityToModify.getModes()::get)
.map(Mode::getTargets)
.flatMap(Collection::stream)
.map(Target::getTargets)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
}
private Set<UUID> getAllPossibleTargets(Ability abilityToModify, Ability source, Game game) {
return abilityToModify.getModes().values()
.stream()
.map(Mode::getTargets)
.flatMap(Collection::stream)
.map(t -> t.possibleTargets(abilityToModify.getSourceId(), abilityToModify.getControllerId(), game))
.flatMap(Collection::stream)
.collect(Collectors.toSet());
}
public SpellsCostModificationThatTargetSourceEffect withTargetName(String targetName) {
this.targetName = targetName;
setText();