mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 21:12:04 -08:00
* Added handling of triggered mana to available mana calculation (fixes #585).
This commit is contained in:
parent
5be6e9398a
commit
89249888b5
26 changed files with 544 additions and 96 deletions
|
|
@ -34,6 +34,7 @@ import java.util.ArrayList;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
|
@ -171,6 +172,9 @@ public abstract class AbilityImpl implements Ability {
|
|||
private boolean resolveMode(Game game) {
|
||||
boolean result = true;
|
||||
for (Effect effect : getEffects()) {
|
||||
if (game.inCheckPlayableState() && !(effect instanceof ManaEffect)) {
|
||||
continue; // Ignored non mana effects - see GameEvent.TAPPED_FOR_MANA
|
||||
}
|
||||
if (effect instanceof OneShotEffect) {
|
||||
boolean effectResult = effect.apply(game, this);
|
||||
result &= effectResult;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ public class TapForManaAllTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA
|
||||
return false;
|
||||
}
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
|
||||
if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) {
|
||||
ManaEvent mEvent = (ManaEvent) event;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ public class TapLandForManaAllTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA
|
||||
return false;
|
||||
}
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
|
||||
if (permanent != null && permanent.isLand()) {
|
||||
if (setTargetPointer) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class ReturnToHandChosenControlledPermanentCost extends CostImpl {
|
|||
target.setNotTarget(true);
|
||||
this.addTarget(target);
|
||||
if (target.getMaxNumberOfTargets() > 1 && target.getMaxNumberOfTargets() == target.getNumberOfTargets()) {
|
||||
this.text = "return " + CardUtil.numberToText(target.getMaxNumberOfTargets()) + ' '
|
||||
this.text = "Return " + CardUtil.numberToText(target.getMaxNumberOfTargets()) + ' '
|
||||
+ target.getTargetName()
|
||||
+ (target.getTargetName().endsWith(" you control") ? "" : " you control")
|
||||
+ " to their owner's hand";
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import mage.players.Player;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
|
@ -38,6 +39,15 @@ public abstract class ManaEffect extends OneShotEffect {
|
|||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (game.inCheckPlayableState()) {
|
||||
// During calculation of the available mana for a player the "TappedForMana" event is fired to simulate triggered mana production.
|
||||
// By checking the inCheckPlayableState these events are handled to give back only the available mana of instead really producing mana
|
||||
// So it's important if ManaEffects overwrite the apply method to take care for this.
|
||||
if (source instanceof TriggeredAbility) {
|
||||
player.addAvailableTriggeredMana(getNetMana(game, source));
|
||||
}
|
||||
return true; // No need to add mana to pool during checkPlayable
|
||||
}
|
||||
Mana manaToAdd = produceMana(game, source);
|
||||
if (manaToAdd != null && manaToAdd.count() > 0) {
|
||||
checkToFirePossibleEvents(manaToAdd, game, source);
|
||||
|
|
@ -72,11 +82,13 @@ public abstract class ManaEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
/**
|
||||
* Produced the mana the effect can produce (DO NOT add it to mana pool -- return all added as mana object to process by replace events)
|
||||
* Produced the mana the effect can produce (DO NOT add it to mana pool --
|
||||
* return all added as mana object to process by replace events)
|
||||
* <p>
|
||||
* WARNING, produceMana can be called multiple times for mana and spell available calculations
|
||||
* if you don't want it then overide getNetMana to return max possible mana values
|
||||
* (if you have choose dialogs or extra effects like new counters in produceMana)
|
||||
* WARNING, produceMana can be called multiple times for mana and spell
|
||||
* available calculations if you don't want it then overide getNetMana to
|
||||
* return max possible mana values (if you have choose dialogs or extra
|
||||
* effects like new counters in produceMana)
|
||||
*
|
||||
* @param game warning, can be NULL for AI score calcs (game == null)
|
||||
* @param source
|
||||
|
|
|
|||
|
|
@ -38,9 +38,26 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
|
|||
@Override
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
List<Mana> netMana = new ArrayList<>();
|
||||
Mana types = (Mana) this.getValue("mana"); // TODO: will not work until TriggeredManaAbility fix (see TriggeredManaAbilityMustGivesExtraManaOptions test)
|
||||
Mana types = (Mana) this.getValue("mana");
|
||||
if (types != null) {
|
||||
netMana.add(types.copy());
|
||||
if (types.getBlack() > 0) {
|
||||
netMana.add(Mana.BlackMana(1));
|
||||
}
|
||||
if (types.getRed() > 0) {
|
||||
netMana.add(Mana.RedMana(1));
|
||||
}
|
||||
if (types.getBlue() > 0) {
|
||||
netMana.add(Mana.BlueMana(1));
|
||||
}
|
||||
if (types.getGreen() > 0) {
|
||||
netMana.add(Mana.GreenMana(1));
|
||||
}
|
||||
if (types.getWhite() > 0) {
|
||||
netMana.add(Mana.WhiteMana(1));
|
||||
}
|
||||
if (types.getColorless() > 0) {
|
||||
netMana.add(Mana.ColorlessMana(1));
|
||||
}
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import mage.Mana;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
public class BasicManaEffect extends ManaEffect {
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import mage.abilities.costs.common.TapSourceCost;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ManaEvent;
|
||||
import mage.players.Player;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
|
|
@ -44,24 +45,11 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
//if there is only one mana option available add it to all the existing options
|
||||
List<Mana> netManas = abilities.get(0).getNetMana(game);
|
||||
if (netManas.size() == 1) {
|
||||
if (!hasTapCost(abilities.get(0)) || checkTappedForManaReplacement(abilities.get(0), game, netManas.get(0))) {
|
||||
addMana(netManas.get(0));
|
||||
}
|
||||
checkTappedForManaReplacement(abilities.get(0), game, netManas.get(0));
|
||||
addMana(netManas.get(0));
|
||||
addTriggeredMana(game, abilities.get(0));
|
||||
} else if (netManas.size() > 1) {
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
// boolean hasTapCost = hasTapCost(abilities.get(0)); // needed if checkTappedForManaReplacement is reactivated
|
||||
for (Mana netMana : netManas) {
|
||||
for (Mana mana : copy) {
|
||||
// checkTappedForManaReplacement seems in some situations to produce endless iterations so deactivated for now: https://github.com/magefree/mage/issues/5023
|
||||
if (true/* !hasTapCost || checkTappedForManaReplacement(abilities.get(0), game, netMana) */) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
addManaVariation(netManas, abilities.get(0), game);
|
||||
}
|
||||
|
||||
} else { // mana source has more than 1 ability
|
||||
|
|
@ -69,14 +57,14 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (ActivatedManaAbilityImpl ability : abilities) {
|
||||
boolean hasTapCost = hasTapCost(ability);
|
||||
for (Mana netMana : ability.getNetMana(game)) {
|
||||
if (!hasTapCost || checkTappedForManaReplacement(ability, game, netMana)) {
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
SkipAddMana:
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
newMana.add(triggeredManaVariation);
|
||||
for (Mana existingMana : this) {
|
||||
if (existingMana.equalManaValue(newMana)) {
|
||||
continue SkipAddMana;
|
||||
|
|
@ -91,18 +79,48 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkTappedForManaReplacement(Ability ability, Game game, Mana mana) {
|
||||
ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, ability.getSourceId(), ability.getSourceId(), ability.getControllerId(), mana);
|
||||
if (!game.replaceEvent(event)) {
|
||||
return true;
|
||||
private void addManaVariation(List<Mana> netManas, ActivatedManaAbilityImpl ability, Game game) {
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana netMana : netManas) {
|
||||
for (Mana mana : copy) {
|
||||
if (!hasTapCost(ability) || checkTappedForManaReplacement(ability, game, netMana)) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<List<Mana>> getSimulatedTriggeredManaFromPlayer(Game game, Ability ability) {
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
List<List<Mana>> newList = new ArrayList<>();
|
||||
if (player != null) {
|
||||
newList.addAll(player.getAvailableTriggeredMana());
|
||||
player.getAvailableTriggeredMana().clear();
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
|
||||
private boolean checkTappedForManaReplacement(Ability ability, Game game, Mana mana) {
|
||||
if (hasTapCost(ability)) {
|
||||
ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, ability.getSourceId(), ability.getSourceId(), ability.getControllerId(), mana);
|
||||
if (!game.replaceEvent(event)) {
|
||||
game.fireEvent(event);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasTapCost(Ability ability) {
|
||||
|
|
@ -127,31 +145,41 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
// no mana costs
|
||||
if (ability.getManaCosts().isEmpty()) {
|
||||
if (netManas.size() == 1) {
|
||||
checkTappedForManaReplacement(ability, game, netManas.get(0));
|
||||
addMana(netManas.get(0));
|
||||
addTriggeredMana(game, ability);
|
||||
} else {
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana netMana : netManas) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
this.add(newMana);
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(triggeredManaVariation);
|
||||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else // the ability has mana costs
|
||||
if (netManas.size() == 1) {
|
||||
checkTappedForManaReplacement(ability, game, netManas.get(0));
|
||||
subtractCostAddMana(ability.getManaCosts().getMana(), netManas.get(0), ability.getCosts().isEmpty());
|
||||
addTriggeredMana(game, ability);
|
||||
} else {
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana netMana : netManas) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
subtractCostAddMana(ability.getManaCosts().getMana(), netMana, ability.getCosts().isEmpty());
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(triggeredManaVariation);
|
||||
subtractCostAddMana(ability.getManaCosts().getMana(), netMana, ability.getCosts().isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -160,30 +188,30 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (ActivatedManaAbilityImpl ability : abilities) {
|
||||
boolean hasTapCost = hasTapCost(ability);
|
||||
List<Mana> netManas = ability.getNetMana(game);
|
||||
|
||||
if (ability.getManaCosts().isEmpty()) {
|
||||
for (Mana netMana : netManas) {
|
||||
if (!hasTapCost || checkTappedForManaReplacement(ability, game, netMana)) {
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
newMana.add(triggeredManaVariation);
|
||||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Mana netMana : netManas) {
|
||||
if (!hasTapCost || checkTappedForManaReplacement(ability, game, netMana)) {
|
||||
checkTappedForManaReplacement(ability, game, netMana);
|
||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||
for (Mana previousMana : copy) {
|
||||
CombineWithExisting:
|
||||
for (Mana manaOption : ability.getManaCosts().getManaOptions()) {
|
||||
Mana newMana = new Mana(previousMana);
|
||||
if (previousMana.includesMana(manaOption)) { // costs can be paid
|
||||
newMana.subtractCost(manaOption);
|
||||
newMana.add(netMana);
|
||||
newMana.add(triggeredManaVariation);
|
||||
// if the new mana is in all colors more than another already existing than replace
|
||||
for (Mana existingMana : this) {
|
||||
Mana moreValuable = Mana.getMoreValuableMana(newMana, existingMana);
|
||||
|
|
@ -211,6 +239,52 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
}
|
||||
}
|
||||
|
||||
private List<Mana> getTriggeredManaVariations(Game game, Ability ability, Mana baseMana) {
|
||||
List<Mana> baseManaPlusTriggeredMana = new ArrayList<>();
|
||||
baseManaPlusTriggeredMana.add(baseMana);
|
||||
List<List<Mana>> availableTriggeredManaList = getSimulatedTriggeredManaFromPlayer(game, ability);
|
||||
for (List<Mana> availableTriggeredMana : availableTriggeredManaList) {
|
||||
if (availableTriggeredMana.size() == 1) {
|
||||
for (Mana prevMana : baseManaPlusTriggeredMana) {
|
||||
prevMana.add(availableTriggeredMana.get(0));
|
||||
}
|
||||
} else if (availableTriggeredMana.size() > 1) {
|
||||
List<Mana> copy = new ArrayList<>(baseManaPlusTriggeredMana);
|
||||
baseManaPlusTriggeredMana.clear();
|
||||
for (Mana triggeredMana : availableTriggeredMana) {
|
||||
for (Mana prevMana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(prevMana);
|
||||
newMana.add(triggeredMana);
|
||||
baseManaPlusTriggeredMana.add(newMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return baseManaPlusTriggeredMana;
|
||||
}
|
||||
|
||||
private void addTriggeredMana(Game game, Ability ability) {
|
||||
List<List<Mana>> netManaList = getSimulatedTriggeredManaFromPlayer(game, ability);
|
||||
for (List<Mana> triggeredNetMana : netManaList) {
|
||||
if (triggeredNetMana.size() == 1) {
|
||||
addMana(triggeredNetMana.get(0));
|
||||
} else if (triggeredNetMana.size() > 1) {
|
||||
// Add variations
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
for (Mana triggeredMana : triggeredNetMana) {
|
||||
for (Mana mana : copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(triggeredMana);
|
||||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addMana(Mana addMana) {
|
||||
if (isEmpty()) {
|
||||
this.add(new Mana());
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public class GameEvent implements Serializable {
|
|||
targetId id of the spell that's cast
|
||||
playerId player that casts the spell or ability
|
||||
amount X multiplier to change X value, default 1
|
||||
*/
|
||||
*/
|
||||
CAST_SPELL,
|
||||
/* SPELL_CAST
|
||||
x-Costs are already defined
|
||||
|
|
@ -153,13 +153,13 @@ public class GameEvent implements Serializable {
|
|||
targetId id of the ability to activate / use
|
||||
sourceId sourceId of the object with that ability
|
||||
playerId player that tries to use this ability
|
||||
*/
|
||||
*/
|
||||
TAKE_SPECIAL_ACTION, TAKEN_SPECIAL_ACTION, // not used in implementation yet
|
||||
/* TAKE_SPECIAL_ACTION, TAKEN_SPECIAL_ACTION,
|
||||
targetId id of the ability to activate / use
|
||||
sourceId sourceId of the object with that ability
|
||||
playerId player that tries to use this ability
|
||||
*/
|
||||
*/
|
||||
TRIGGERED_ABILITY,
|
||||
RESOLVING_ABILITY,
|
||||
COPY_STACKOBJECT, COPIED_STACKOBJECT,
|
||||
|
|
@ -254,7 +254,13 @@ public class GameEvent implements Serializable {
|
|||
ENTERS_THE_BATTLEFIELD_CONTROL, // 616.1b
|
||||
ENTERS_THE_BATTLEFIELD_COPY, // 616.1c
|
||||
ENTERS_THE_BATTLEFIELD, // 616.1d
|
||||
TAP, TAPPED, TAPPED_FOR_MANA,
|
||||
TAP, TAPPED,
|
||||
TAPPED_FOR_MANA,
|
||||
/* TAPPED_FOR_MANA
|
||||
During calculation of the available mana for a player the "TappedForMana" event is fired to simulate triggered mana production.
|
||||
By checking the inCheckPlayableState these events are handled to give back only the available mana of instead really producing mana.
|
||||
IMPORTANT: Triggered non mana abilities have to ignore the event if game.inCheckPlayableState is true.
|
||||
*/
|
||||
UNTAP, UNTAPPED,
|
||||
FLIP, FLIPPED,
|
||||
UNFLIP, UNFLIPPED,
|
||||
|
|
@ -412,12 +418,12 @@ public class GameEvent implements Serializable {
|
|||
}
|
||||
|
||||
private GameEvent(EventType type, UUID customEventType,
|
||||
UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag) {
|
||||
UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag) {
|
||||
this(type, customEventType, targetId, sourceId, playerId, amount, flag, null);
|
||||
}
|
||||
|
||||
private GameEvent(EventType type, UUID customEventType,
|
||||
UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag, MageObjectReference reference) {
|
||||
UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag, MageObjectReference reference) {
|
||||
this.type = type;
|
||||
this.customEventType = customEventType;
|
||||
this.targetId = targetId;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import mage.util.Copyable;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import mage.Mana;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
|
@ -635,6 +636,10 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
void untap(Game game);
|
||||
|
||||
ManaOptions getManaAvailable(Game game);
|
||||
|
||||
void addAvailableTriggeredMana(List<Mana> netManaAvailable);
|
||||
|
||||
List<List<Mana>> getAvailableTriggeredMana();
|
||||
|
||||
List<ActivatedAbility> getPlayable(Game game, boolean hidden);
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,9 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
protected FilterMana phyrexianColors;
|
||||
|
||||
// Used during available mana calculation to give back possible available net mana from triggered mana abilities (No need to copy)
|
||||
protected final List<List<Mana>> availableTriggeredManaList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* During some steps we can't play anything
|
||||
*/
|
||||
|
|
@ -2848,8 +2851,18 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return game.getBattlefield().getAllActivePermanents(blockFilter, playerId, game);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mana options the player currently has. That means which combinations of
|
||||
* mana are available to cast spells or activate abilities etc.
|
||||
*
|
||||
* @param game
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ManaOptions getManaAvailable(Game game) {
|
||||
boolean oldState = game.inCheckPlayableState();
|
||||
game.setCheckPlayableState(true);
|
||||
|
||||
ManaOptions availableMana = new ManaOptions();
|
||||
|
||||
List<Abilities<ActivatedManaAbilityImpl>> sourceWithoutManaCosts = new ArrayList<>();
|
||||
|
|
@ -2891,10 +2904,34 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
// remove duplicated variants (see ManaOptionsTest for info - when that rises)
|
||||
availableMana.removeDuplicated();
|
||||
|
||||
|
||||
game.setCheckPlayableState(oldState);
|
||||
return availableMana;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used during calculation of available mana to gather the amount of producable triggered mana caused by using mana sources.
|
||||
* So the set value is only used during the calculation of the mana produced by one source and cleared thereafter
|
||||
*
|
||||
* @param netManaAvailable the net mana produced by the triggered mana abaility
|
||||
*/
|
||||
@Override
|
||||
public void addAvailableTriggeredMana(List<Mana> netManaAvailable) {
|
||||
this.availableTriggeredManaList.add(netManaAvailable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used during calculation of available mana to get the amount of producable triggered mana caused by using mana sources.
|
||||
* The list is cleared as soon the value is retrieved during available mana calculation.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<List<Mana>> getAvailableTriggeredMana() {
|
||||
return availableTriggeredManaList;
|
||||
}
|
||||
|
||||
|
||||
// returns only mana producers that don't require mana payment
|
||||
protected List<MageObject> getAvailableManaProducers(Game game) {
|
||||
List<MageObject> result = new ArrayList<>();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue