* Fixed available mana calculation for Cryptic Trilobite and Titans' Nest. Added some improvements for available mana calculation of conditional mana.

This commit is contained in:
LevelX2 2020-08-16 01:16:52 +02:00
parent 3d989b24ac
commit 768f1bec4f
100 changed files with 507 additions and 144 deletions

View file

@ -1,130 +0,0 @@
package mage.abilities.effects.common;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.constants.AbilityType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ManaEvent;
import mage.players.Player;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import mage.abilities.TriggeredAbility;
import mage.constants.ManaType;
/**
* @author BetaSteward_at_googlemail.com
*/
public abstract class ManaEffect extends OneShotEffect {
public ManaEffect() {
super(Outcome.PutManaInPool);
}
public ManaEffect(final ManaEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = getPlayer(game, source);
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);
addManaToPool(player, manaToAdd, game, source);
}
return true;
}
protected Player getPlayer(Game game, Ability source) {
return game.getPlayer(source.getControllerId());
}
protected void addManaToPool(Player player, Mana manaToAdd, Game game, Ability source) {
player.getManaPool().addMana(manaToAdd, game, source);
}
/**
* Returns the currently available max mana variations the effect can
* produce
*
* @param game warning, can be NULL for card score calcs (AI games)
* @param source
* @return
*/
public List<Mana> getNetMana(Game game, Ability source) {
List<Mana> netMana = new ArrayList<>();
Mana mana = produceMana(game, source);
if (mana != null && mana.count() > 0) {
netMana.add(mana);
}
return netMana;
}
/**
* The type of mana a permanent "could produce" is the type of mana that any
* ability of that permanent can generate, taking into account any
* applicable replacement effects. If the type of mana cant be defined,
* theres no type of mana that that permanent could produce. The "type" of
* mana is its color, or lack thereof (for colorless mana).
*
* @param game
* @param source
* @return
*/
public Set<ManaType> getProducableManaTypes(Game game, Ability source) {
return ManaType.getManaTypesFromManaList(getNetMana(game, source));
}
/**
* 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)
*
* @param game warning, can be NULL for AI score calcs (game == null)
* @param source
* @return can return null or empty mana
*/
public abstract Mana produceMana(Game game, Ability source);
/**
* Only used for mana effects that decide which kind of mana is produced
* during resolution of the effect.
*
* @param mana
* @param game
* @param source
*/
public void checkToFirePossibleEvents(Mana mana, Game game, Ability source) {
if (source.getAbilityType() == AbilityType.MANA && source.hasTapCost()) {
ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, source.getSourceId(), source.getSourceId(), source.getControllerId(), mana);
if (!game.replaceEvent(event)) {
game.fireEvent(event);
}
}
}
}