forked from External/mage
Improved and fixed X mana cost and pays, mana pool:
* Pay X abilities - fixed that it spends all available mana pool instead only needed; * Pay X abilities - added support of interactions with other X effects like Rosheen Meanderer's mana usage for "pay X to prevent"; * Rosheen Meanderer - fixed that it can't use mana for "you may pay X" like Flameblast Dragon's effect (#5206); * Devs: added support to use VariableManaCost to pay X in code (without generic's workaround, use ManaUtil.createManaCost to generate cost to pay);
This commit is contained in:
parent
500fc935e4
commit
437861ec20
20 changed files with 675 additions and 192 deletions
|
|
@ -1,12 +1,5 @@
|
|||
package mage.players;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.ConditionalMana;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -22,8 +15,10 @@ import mage.game.events.GameEvent.EventType;
|
|||
import mage.game.events.ManaEvent;
|
||||
import mage.game.stack.Spell;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class ManaPool implements Serializable {
|
||||
|
|
@ -84,25 +79,24 @@ public class ManaPool implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param manaType the mana type that should be paid
|
||||
* @param manaType the mana type that should be paid
|
||||
* @param ability
|
||||
* @param filter
|
||||
* @param game
|
||||
* @param costToPay complete costs to pay (needed to check conditional mana)
|
||||
* @param costToPay complete costs to pay (needed to check conditional mana)
|
||||
* @param usedManaToPay the information about what mana was paid
|
||||
* @return
|
||||
*/
|
||||
public boolean pay(ManaType manaType, Ability ability, Filter filter, Game game, Cost costToPay, Mana usedManaToPay) {
|
||||
if (!isAutoPayment()
|
||||
if (!isAutoPayment()
|
||||
&& manaType != unlockedManaType) {
|
||||
// if manual payment and the needed mana type was not unlocked, nothing will be paid
|
||||
return false;
|
||||
}
|
||||
ManaType possibleAsThoughPoolManaType = null;
|
||||
if (isAutoPayment()
|
||||
&& isAutoPaymentRestricted()
|
||||
&& !wasManaAddedBeyondStock()
|
||||
if (isAutoPayment()
|
||||
&& isAutoPaymentRestricted()
|
||||
&& !wasManaAddedBeyondStock()
|
||||
&& manaType != unlockedManaType) {
|
||||
// if automatic restricted payment and there is already mana in the pool
|
||||
// and the needed mana type was not unlocked, nothing will be paid
|
||||
|
|
@ -112,7 +106,7 @@ public class ManaPool implements Serializable {
|
|||
possibleAsThoughPoolManaType = game.getContinuousEffects().asThoughMana(manaType, checkItem, ability.getSourceId(), ability, ability.getControllerId(), game);
|
||||
}
|
||||
// Check if it's possible to use mana as thought for the unlocked manatype in the mana pool for this ability
|
||||
if (possibleAsThoughPoolManaType == null
|
||||
if (possibleAsThoughPoolManaType == null
|
||||
|| possibleAsThoughPoolManaType != unlockedManaType) {
|
||||
return false; // if it's not possible return
|
||||
}
|
||||
|
|
@ -123,21 +117,21 @@ public class ManaPool implements Serializable {
|
|||
lockManaType(); // pay only one mana if mana payment is set to manually
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
for (ManaPoolItem mana : manaItems) {
|
||||
if (filter != null) {
|
||||
if (!filter.match(mana.getSourceObject(), game)) {
|
||||
// Prevent that cost reduction by convoke is filtered out
|
||||
if (!(mana.getSourceObject() instanceof Spell)
|
||||
if (!(mana.getSourceObject() instanceof Spell)
|
||||
|| ability.getSourceId().equals(mana.getSourceId())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (possibleAsThoughPoolManaType == null
|
||||
&& manaType != unlockedManaType
|
||||
&& isAutoPayment()
|
||||
&& isAutoPaymentRestricted()
|
||||
if (possibleAsThoughPoolManaType == null
|
||||
&& manaType != unlockedManaType
|
||||
&& isAutoPayment()
|
||||
&& isAutoPaymentRestricted()
|
||||
&& mana.count() == mana.getStock()) {
|
||||
// no mana added beyond the stock so don't auto pay this
|
||||
continue;
|
||||
|
|
@ -174,7 +168,7 @@ public class ManaPool implements Serializable {
|
|||
if (mana.isConditional()
|
||||
&& mana.getConditionalMana().get(manaType) > 0
|
||||
&& mana.getConditionalMana().apply(ability, game, mana.getSourceId(), costToPay)) {
|
||||
if (filter == null
|
||||
if (filter == null
|
||||
|| filter.match(mana.getSourceObject(), game)) {
|
||||
return mana.getConditionalMana().get(manaType);
|
||||
}
|
||||
|
|
@ -184,7 +178,7 @@ public class ManaPool implements Serializable {
|
|||
}
|
||||
|
||||
public int getConditionalCount(Ability ability, Game game, FilterMana filter, Cost costToPay) {
|
||||
if (ability == null
|
||||
if (ability == null
|
||||
|| getConditionalMana().isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -222,7 +216,7 @@ public class ManaPool implements Serializable {
|
|||
for (ManaType manaType : ManaType.values()) {
|
||||
if (!doNotEmptyManaTypes.contains(manaType)) {
|
||||
if (item.get(manaType) > 0) {
|
||||
if (item.getDuration() != Duration.EndOfTurn
|
||||
if (item.getDuration() != Duration.EndOfTurn
|
||||
|| game.getPhase().getType() == TurnPhase.END) {
|
||||
if (game.replaceEvent(new GameEvent(GameEvent.EventType.EMPTY_MANA_POOL, playerId, null, playerId))) {
|
||||
int amount = item.get(manaType);
|
||||
|
|
@ -236,7 +230,7 @@ public class ManaPool implements Serializable {
|
|||
}
|
||||
if (conditionalItem != null) {
|
||||
if (conditionalItem.get(manaType) > 0) {
|
||||
if (item.getDuration() != Duration.EndOfTurn
|
||||
if (item.getDuration() != Duration.EndOfTurn
|
||||
|| game.getPhase().getType() == TurnPhase.END) {
|
||||
if (game.replaceEvent(new GameEvent(GameEvent.EventType.EMPTY_MANA_POOL, playerId, null, playerId))) {
|
||||
int amount = conditionalItem.get(manaType);
|
||||
|
|
@ -258,86 +252,6 @@ public class ManaPool implements Serializable {
|
|||
return total;
|
||||
}
|
||||
|
||||
private int payX(Ability ability, Game game) {
|
||||
int total = 0;
|
||||
Iterator<ManaPoolItem> it = manaItems.iterator();
|
||||
while (it.hasNext()) {
|
||||
ManaPoolItem item = it.next();
|
||||
if (item.isConditional()) {
|
||||
ConditionalMana cm = item.getConditionalMana();
|
||||
if (cm.apply(ability, game, cm.getManaProducerId(), null)) {
|
||||
total += item.count();
|
||||
it.remove();
|
||||
}
|
||||
} else {
|
||||
total += item.count();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all mana from pool that applies and that matches filter
|
||||
*
|
||||
* @param ability
|
||||
* @param game
|
||||
* @param filter
|
||||
* @return
|
||||
*/
|
||||
public int payX(Ability ability, Game game, FilterMana filter) {
|
||||
if (filter == null) {
|
||||
return payX(ability, game);
|
||||
}
|
||||
int total = 0;
|
||||
Iterator<ManaPoolItem> it = manaItems.iterator();
|
||||
while (it.hasNext()) {
|
||||
ManaPoolItem item = it.next();
|
||||
if (item.isConditional()) {
|
||||
ConditionalMana c = item.getConditionalMana();
|
||||
if (c.apply(ability, game, c.getManaProducerId(), null)) {
|
||||
int count = c.count(filter);
|
||||
if (count > 0) {
|
||||
total += count;
|
||||
c.removeAll(filter);
|
||||
if (c.count() == 0) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (filter.isBlack()) {
|
||||
total += item.getBlack();
|
||||
item.removeBlack();
|
||||
}
|
||||
if (filter.isBlue()) {
|
||||
total += item.getBlue();
|
||||
item.removeBlue();
|
||||
}
|
||||
if (filter.isWhite()) {
|
||||
total += item.getWhite();
|
||||
item.removeWhite();
|
||||
}
|
||||
if (filter.isRed()) {
|
||||
total += item.getRed();
|
||||
item.removeRed();
|
||||
}
|
||||
if (filter.isGreen()) {
|
||||
total += item.getGreen();
|
||||
item.removeGreen();
|
||||
}
|
||||
if (filter.isGeneric()) {
|
||||
total += item.getColorless();
|
||||
item.removeColorless();
|
||||
}
|
||||
if (item.count() == 0) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public Mana getMana() {
|
||||
Mana m = new Mana();
|
||||
for (ManaPoolItem item : manaItems) {
|
||||
|
|
@ -376,12 +290,6 @@ public class ManaPool implements Serializable {
|
|||
return m;
|
||||
}
|
||||
|
||||
public Mana getAllConditionalMana(Ability ability, Game game, FilterMana filter) {
|
||||
Mana m = new Mana();
|
||||
m.setGeneric(getConditionalCount(ability, game, filter, null));
|
||||
return m;
|
||||
}
|
||||
|
||||
public void addMana(Mana manaToAdd, Game game, Ability source) {
|
||||
addMana(manaToAdd, game, source, false);
|
||||
}
|
||||
|
|
@ -392,7 +300,7 @@ public class ManaPool implements Serializable {
|
|||
if (!game.replaceEvent(new ManaEvent(EventType.ADD_MANA, source.getId(), source.getSourceId(), playerId, mana))) {
|
||||
if (mana instanceof ConditionalMana) {
|
||||
ManaPoolItem item = new ManaPoolItem((ConditionalMana) mana, source.getSourceObject(game),
|
||||
((ConditionalMana) mana).getManaProducerOriginalId() != null
|
||||
((ConditionalMana) mana).getManaProducerOriginalId() != null
|
||||
? ((ConditionalMana) mana).getManaProducerOriginalId() : source.getOriginalId());
|
||||
if (emptyOnTurnsEnd) {
|
||||
item.setDuration(Duration.EndOfTurn);
|
||||
|
|
@ -524,12 +432,12 @@ public class ManaPool implements Serializable {
|
|||
public UUID getPlayerId() {
|
||||
return playerId;
|
||||
}
|
||||
|
||||
|
||||
public void storeMana() {
|
||||
poolBookmark.clear();
|
||||
poolBookmark.addAll(getManaItems());
|
||||
}
|
||||
|
||||
|
||||
public List<ManaPoolItem> getPoolBookmark() {
|
||||
List<ManaPoolItem> itemsCopy = new ArrayList<>();
|
||||
for (ManaPoolItem manaItem : poolBookmark) {
|
||||
|
|
@ -537,7 +445,7 @@ public class ManaPool implements Serializable {
|
|||
}
|
||||
return itemsCopy;
|
||||
}
|
||||
|
||||
|
||||
public void restoreMana(List<ManaPoolItem> manaList) {
|
||||
manaItems.clear();
|
||||
if (!manaList.isEmpty()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue