mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
* Performance: memory usage optimization for deck editor (part 2 of removed bloated usage of ManaCosts -> ManaColor objects, see #7515);
This commit is contained in:
parent
c1dea5b21e
commit
10e557b873
25 changed files with 164 additions and 113 deletions
|
|
@ -178,7 +178,7 @@ public class DeckGeneratorPool
|
||||||
* @return if all the mana symbols fit the chosen colors.
|
* @return if all the mana symbols fit the chosen colors.
|
||||||
*/
|
*/
|
||||||
private boolean cardFitsChosenColors(Card card) {
|
private boolean cardFitsChosenColors(Card card) {
|
||||||
for (String symbol : card.getManaCost().getSymbols()) {
|
for (String symbol : card.getManaCostSymbols()) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
symbol = symbol.replace("{", "").replace("}", "");
|
symbol = symbol.replace("{", "").replace("}", "");
|
||||||
if (isColoredManaSymbol(symbol)) {
|
if (isColoredManaSymbol(symbol)) {
|
||||||
|
|
@ -218,7 +218,7 @@ public class DeckGeneratorPool
|
||||||
|
|
||||||
List<Card> fixedSpells = getFixedSpells();
|
List<Card> fixedSpells = getFixedSpells();
|
||||||
for(Card spell: fixedSpells) {
|
for(Card spell: fixedSpells) {
|
||||||
for (String symbol : spell.getManaCost().getSymbols()) {
|
for (String symbol : spell.getManaCostSymbols()) {
|
||||||
symbol = symbol.replace("{", "").replace("}", "");
|
symbol = symbol.replace("{", "").replace("}", "");
|
||||||
if (isColoredManaSymbol(symbol)) {
|
if (isColoredManaSymbol(symbol)) {
|
||||||
for (ColoredManaSymbol allowed : allowedColors) {
|
for (ColoredManaSymbol allowed : allowedColors) {
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ public final class DeckBuilder {
|
||||||
final Map<String, Integer> colorCount = new HashMap<>();
|
final Map<String, Integer> colorCount = new HashMap<>();
|
||||||
for (final Card card : deck.getCards()) {
|
for (final Card card : deck.getCards()) {
|
||||||
|
|
||||||
for (String symbol : card.getManaCost().getSymbols()) {
|
for (String symbol : card.getManaCostSymbols()) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
symbol = symbol.replace("{", "").replace("}", "");
|
symbol = symbol.replace("{", "").replace("}", "");
|
||||||
if (isColoredMana(symbol)) {
|
if (isColoredMana(symbol)) {
|
||||||
|
|
@ -243,7 +243,7 @@ public final class DeckBuilder {
|
||||||
int maxSingleCount = 0;
|
int maxSingleCount = 0;
|
||||||
int multicolor = 0;
|
int multicolor = 0;
|
||||||
Set<String> colors = new HashSet<>();
|
Set<String> colors = new HashSet<>();
|
||||||
for (String symbol : card.getManaCost().getSymbols()) {
|
for (String symbol : card.getManaCostSymbols()) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
symbol = symbol.replace("{", "").replace("}", "");
|
symbol = symbol.replace("{", "").replace("}", "");
|
||||||
if (isColoredMana(symbol)) {
|
if (isColoredMana(symbol)) {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ public class AbilityView extends CardView {
|
||||||
this.subTypes = new SubTypes();
|
this.subTypes = new SubTypes();
|
||||||
this.superTypes = EnumSet.noneOf(SuperType.class);
|
this.superTypes = EnumSet.noneOf(SuperType.class);
|
||||||
this.color = new ObjectColor();
|
this.color = new ObjectColor();
|
||||||
this.manaCostLeftStr = String.join("", ability.getManaCosts().getSymbols());
|
this.manaCostLeftStr = String.join("", ability.getManaCostSymbols());
|
||||||
this.manaCostRightStr = "";
|
this.manaCostRightStr = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -347,29 +347,29 @@ public class CardView extends SimpleCardView {
|
||||||
if (splitCard != null) {
|
if (splitCard != null) {
|
||||||
this.isSplitCard = true;
|
this.isSplitCard = true;
|
||||||
leftSplitName = splitCard.getLeftHalfCard().getName();
|
leftSplitName = splitCard.getLeftHalfCard().getName();
|
||||||
leftSplitCostsStr = String.join("", splitCard.getLeftHalfCard().getManaCost().getSymbols());
|
leftSplitCostsStr = String.join("", splitCard.getLeftHalfCard().getManaCostSymbols());
|
||||||
leftSplitRules = splitCard.getLeftHalfCard().getRules(game);
|
leftSplitRules = splitCard.getLeftHalfCard().getRules(game);
|
||||||
leftSplitTypeLine = getCardTypeLine(game, splitCard.getLeftHalfCard());
|
leftSplitTypeLine = getCardTypeLine(game, splitCard.getLeftHalfCard());
|
||||||
rightSplitName = splitCard.getRightHalfCard().getName();
|
rightSplitName = splitCard.getRightHalfCard().getName();
|
||||||
rightSplitCostsStr = String.join("", splitCard.getRightHalfCard().getManaCost().getSymbols());
|
rightSplitCostsStr = String.join("", splitCard.getRightHalfCard().getManaCostSymbols());
|
||||||
rightSplitRules = splitCard.getRightHalfCard().getRules(game);
|
rightSplitRules = splitCard.getRightHalfCard().getRules(game);
|
||||||
rightSplitTypeLine = getCardTypeLine(game, splitCard.getRightHalfCard());
|
rightSplitTypeLine = getCardTypeLine(game, splitCard.getRightHalfCard());
|
||||||
|
|
||||||
fullCardName = card.getName(); // split card contains full name as normal
|
fullCardName = card.getName(); // split card contains full name as normal
|
||||||
this.manaCostLeftStr = String.join("", splitCard.getLeftHalfCard().getManaCost().getSymbols());
|
this.manaCostLeftStr = String.join("", splitCard.getLeftHalfCard().getManaCostSymbols());
|
||||||
this.manaCostRightStr = String.join("", splitCard.getRightHalfCard().getManaCost().getSymbols());
|
this.manaCostRightStr = String.join("", splitCard.getRightHalfCard().getManaCostSymbols());
|
||||||
} else if (card instanceof ModalDoubleFacesCard) {
|
} else if (card instanceof ModalDoubleFacesCard) {
|
||||||
this.isModalDoubleFacesCard = true;
|
this.isModalDoubleFacesCard = true;
|
||||||
ModalDoubleFacesCard mainCard = ((ModalDoubleFacesCard) card);
|
ModalDoubleFacesCard mainCard = ((ModalDoubleFacesCard) card);
|
||||||
fullCardName = mainCard.getLeftHalfCard().getName() + MockCard.MODAL_DOUBLE_FACES_NAME_SEPARATOR + mainCard.getRightHalfCard().getName();
|
fullCardName = mainCard.getLeftHalfCard().getName() + MockCard.MODAL_DOUBLE_FACES_NAME_SEPARATOR + mainCard.getRightHalfCard().getName();
|
||||||
this.manaCostLeftStr = String.join("", mainCard.getLeftHalfCard().getManaCost().getSymbols());
|
this.manaCostLeftStr = String.join("", mainCard.getLeftHalfCard().getManaCostSymbols());
|
||||||
this.manaCostRightStr = String.join("", mainCard.getRightHalfCard().getManaCost().getSymbols());
|
this.manaCostRightStr = String.join("", mainCard.getRightHalfCard().getManaCostSymbols());
|
||||||
} else if (card instanceof AdventureCard) {
|
} else if (card instanceof AdventureCard) {
|
||||||
AdventureCard adventureCard = ((AdventureCard) card);
|
AdventureCard adventureCard = ((AdventureCard) card);
|
||||||
AdventureCardSpell adventureCardSpell = ((AdventureCardSpell) adventureCard.getSpellCard());
|
AdventureCardSpell adventureCardSpell = ((AdventureCardSpell) adventureCard.getSpellCard());
|
||||||
fullCardName = adventureCard.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + adventureCardSpell.getName();
|
fullCardName = adventureCard.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + adventureCardSpell.getName();
|
||||||
this.manaCostLeftStr = String.join("", adventureCardSpell.getManaCost().getSymbols());
|
this.manaCostLeftStr = String.join("", adventureCardSpell.getManaCostSymbols());
|
||||||
this.manaCostRightStr = String.join("", adventureCard.getManaCost().getSymbols());
|
this.manaCostRightStr = String.join("", adventureCard.getManaCostSymbols());
|
||||||
} else if (card instanceof MockCard) {
|
} else if (card instanceof MockCard) {
|
||||||
// deck editor cards
|
// deck editor cards
|
||||||
fullCardName = ((MockCard) card).getFullName(true);
|
fullCardName = ((MockCard) card).getFullName(true);
|
||||||
|
|
@ -377,7 +377,7 @@ public class CardView extends SimpleCardView {
|
||||||
this.manaCostRightStr = String.join("", ((MockCard) card).getManaCostStr(CardInfo.ManaCostSide.RIGHT));
|
this.manaCostRightStr = String.join("", ((MockCard) card).getManaCostStr(CardInfo.ManaCostSide.RIGHT));
|
||||||
} else {
|
} else {
|
||||||
fullCardName = card.getName();
|
fullCardName = card.getName();
|
||||||
this.manaCostLeftStr = String.join("", card.getManaCost().getSymbols());
|
this.manaCostLeftStr = String.join("", card.getManaCostSymbols());
|
||||||
this.manaCostRightStr = "";
|
this.manaCostRightStr = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -389,7 +389,7 @@ public class CardView extends SimpleCardView {
|
||||||
} else {
|
} else {
|
||||||
this.rules = card.getRules(game);
|
this.rules = card.getRules(game);
|
||||||
}
|
}
|
||||||
this.convertedManaCost = card.getManaCost().convertedManaCost();
|
this.convertedManaCost = card.getConvertedManaCost();
|
||||||
|
|
||||||
if (card instanceof Permanent) {
|
if (card instanceof Permanent) {
|
||||||
this.mageObjectType = MageObjectType.PERMANENT;
|
this.mageObjectType = MageObjectType.PERMANENT;
|
||||||
|
|
@ -563,7 +563,7 @@ public class CardView extends SimpleCardView {
|
||||||
this.subTypes = object.getSubtype(game);
|
this.subTypes = object.getSubtype(game);
|
||||||
this.superTypes = object.getSuperType();
|
this.superTypes = object.getSuperType();
|
||||||
this.color = object.getColor(game);
|
this.color = object.getColor(game);
|
||||||
this.manaCostLeftStr = String.join("", object.getManaCost().getSymbols());
|
this.manaCostLeftStr = String.join("", object.getManaCostSymbols());
|
||||||
this.manaCostRightStr = "";
|
this.manaCostRightStr = "";
|
||||||
this.convertedManaCost = object.getManaCost().convertedManaCost();
|
this.convertedManaCost = object.getManaCost().convertedManaCost();
|
||||||
if (object instanceof PermanentToken) {
|
if (object instanceof PermanentToken) {
|
||||||
|
|
@ -733,7 +733,7 @@ public class CardView extends SimpleCardView {
|
||||||
this.color = token.getColor(game);
|
this.color = token.getColor(game);
|
||||||
this.frameColor = token.getFrameColor(game);
|
this.frameColor = token.getFrameColor(game);
|
||||||
this.frameStyle = token.getFrameStyle();
|
this.frameStyle = token.getFrameStyle();
|
||||||
this.manaCostLeftStr = String.join("", token.getManaCost().getSymbols());
|
this.manaCostLeftStr = String.join("", token.getManaCostSymbols());
|
||||||
this.manaCostRightStr = "";
|
this.manaCostRightStr = "";
|
||||||
this.rarity = Rarity.SPECIAL;
|
this.rarity = Rarity.SPECIAL;
|
||||||
this.type = token.getTokenType();
|
this.type = token.getTokenType();
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public class StackAbilityView extends CardView {
|
||||||
this.subTypes = ability.getSubtype(game);
|
this.subTypes = ability.getSubtype(game);
|
||||||
this.superTypes = ability.getSuperType();
|
this.superTypes = ability.getSuperType();
|
||||||
this.color = ability.getColor(game);
|
this.color = ability.getColor(game);
|
||||||
this.manaCostLeftStr = String.join("", ability.getManaCost().getSymbols());
|
this.manaCostLeftStr = String.join("", ability.getManaCostSymbols());
|
||||||
this.manaCostRightStr = "";
|
this.manaCostRightStr = "";
|
||||||
this.cardTypes = ability.getCardType();
|
this.cardTypes = ability.getCardType();
|
||||||
this.subTypes = ability.getSubtype(game);
|
this.subTypes = ability.getSubtype(game);
|
||||||
|
|
|
||||||
|
|
@ -2316,7 +2316,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
if (differentColorsInCost > 0 && differentColorsInCost < 3) {
|
if (differentColorsInCost > 0 && differentColorsInCost < 3) {
|
||||||
// if some colors were already chosen, total amount shouldn't be more than 3
|
// if some colors were already chosen, total amount shouldn't be more than 3
|
||||||
if (chosenSymbols.size() + differentColorsInCost < 4) {
|
if (chosenSymbols.size() + differentColorsInCost < 4) {
|
||||||
for (String symbol : picked.card.getManaCost().getSymbols()) {
|
for (String symbol : picked.card.getManaCostSymbols()) {
|
||||||
symbol = symbol.replace("{", "").replace("}", "");
|
symbol = symbol.replace("{", "").replace("}", "");
|
||||||
if (RateCard.isColoredMana(symbol)) {
|
if (RateCard.isColoredMana(symbol)) {
|
||||||
chosenSymbols.add(symbol);
|
chosenSymbols.add(symbol);
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ enum EmbodimentOfAgoniesValue implements DynamicValue {
|
||||||
.getCards(game)
|
.getCards(game)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(card -> !card.isLand())
|
.filter(card -> !card.isLand())
|
||||||
.forEach(card -> stringSet.add(getCosts(card.getManaCost())));
|
.forEach(card -> stringSet.add(getCosts(card.getManaCostSymbols())));
|
||||||
stringSet.removeIf(s -> s == null || s.equals(""));
|
stringSet.removeIf(s -> s == null || s.equals(""));
|
||||||
return stringSet.size();
|
return stringSet.size();
|
||||||
}
|
}
|
||||||
|
|
@ -83,11 +83,11 @@ enum EmbodimentOfAgoniesValue implements DynamicValue {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getCosts(ManaCosts<ManaCost> costs) {
|
private static String getCosts(List<String> manaCostSymbols) {
|
||||||
List<String> newList = new ArrayList();
|
List<String> newList = new ArrayList();
|
||||||
int generic = 0;
|
int generic = 0;
|
||||||
boolean hasGeneric = false;
|
boolean hasGeneric = false;
|
||||||
for (String s : costs.getSymbols()) {
|
for (String s : manaCostSymbols) {
|
||||||
if (s.matches("\\{\\d*\\}")) {
|
if (s.matches("\\{\\d*\\}")) {
|
||||||
generic += Integer.parseInt(s.substring(1, s.length() - 1));
|
generic += Integer.parseInt(s.substring(1, s.length() - 1));
|
||||||
hasGeneric = true;
|
hasGeneric = true;
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,7 @@ enum JeganthaTheWellspringCompanionCondition implements CompanionCondition {
|
||||||
|
|
||||||
private static boolean checkCard(Card card) {
|
private static boolean checkCard(Card card) {
|
||||||
Map<String, Integer> symbolMap = new HashMap();
|
Map<String, Integer> symbolMap = new HashMap();
|
||||||
return card.getManaCost()
|
return card.getManaCostSymbols()
|
||||||
.getSymbols()
|
|
||||||
.stream()
|
.stream()
|
||||||
.anyMatch(s -> symbolMap.compute(
|
.anyMatch(s -> symbolMap.compute(
|
||||||
s, (str, i) -> (i == null) ? 1 : i + 1
|
s, (str, i) -> (i == null) ? 1 : i + 1
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ public class CostReduceTest extends CardTestPlayerBase {
|
||||||
Assert.assertEquals("test mono hybrid have variant generic", "{1/R}", testCost.getText());
|
Assert.assertEquals("test mono hybrid have variant generic", "{1/R}", testCost.getText());
|
||||||
testReduce("{5/R}", 0, "{5/R}"); // ensure that mono hybrid in test mode
|
testReduce("{5/R}", 0, "{5/R}"); // ensure that mono hybrid in test mode
|
||||||
|
|
||||||
|
// mana order must be same (e.g. cost {R}{2}{G} must be reduced to {R}{1}{G})
|
||||||
|
|
||||||
// DECREASE COST
|
// DECREASE COST
|
||||||
|
|
||||||
// colorless is not reduce
|
// colorless is not reduce
|
||||||
|
|
@ -73,16 +75,29 @@ public class CostReduceTest extends CardTestPlayerBase {
|
||||||
testReduce("{R}{3}{G}", 2, "{R}{1}{G}");
|
testReduce("{R}{3}{G}", 2, "{R}{1}{G}");
|
||||||
testReduce("{R}{G}{3}", 2, "{R}{G}{1}");
|
testReduce("{R}{G}{3}", 2, "{R}{G}{1}");
|
||||||
|
|
||||||
|
// multi generics, decrease cost by 2 (you can't get multigeneric in real game example)
|
||||||
|
testReduce("{2}{2}", 2, "{2}");
|
||||||
|
testReduce("{3}{3}", 2, "{1}{3}");
|
||||||
|
testReduce("{3}{R}{3}", 2, "{1}{R}{3}");
|
||||||
|
testReduce("{3}{R}{3}{G}", 2, "{1}{R}{3}{G}");
|
||||||
|
testReduce("{R}{3}{G}{3}", 2, "{R}{1}{G}{3}");
|
||||||
|
//
|
||||||
|
testReduce("{2}{2}", 3, "{1}");
|
||||||
|
testReduce("{3}{3}", 3, "{3}");
|
||||||
|
testReduce("{3}{R}{3}", 5, "{R}{1}");
|
||||||
|
testReduce("{3}{R}{3}{G}", 5, "{R}{1}{G}");
|
||||||
|
testReduce("{R}{3}{G}{3}", 5, "{R}{G}{1}");
|
||||||
|
|
||||||
// INCREASE COST
|
// INCREASE COST
|
||||||
|
|
||||||
// colorless, increase cost by 1
|
// colorless, increase cost by 1
|
||||||
testReduce("{C}", -1, "{C}{1}");
|
testReduce("{C}", -1, "{1}{C}");
|
||||||
testReduce("{C}{G}", -1, "{C}{G}{1}");
|
testReduce("{C}{G}", -1, "{1}{C}{G}");
|
||||||
|
|
||||||
// 0 generic, increase cost by 1
|
// 0 generic, increase cost by 1
|
||||||
testReduce("", -1, "{1}");
|
testReduce("", -1, "{1}");
|
||||||
testReduce("{R}", -1, "{R}{1}");
|
testReduce("{R}", -1, "{1}{R}");
|
||||||
testReduce("{R}{G}", -1, "{R}{G}{1}");
|
testReduce("{R}{G}", -1, "{1}{R}{G}");
|
||||||
|
|
||||||
// 1 generic, increase cost by 1
|
// 1 generic, increase cost by 1
|
||||||
testReduce("{1}", -1, "{2}");
|
testReduce("{1}", -1, "{2}");
|
||||||
|
|
@ -123,8 +138,8 @@ public class CostReduceTest extends CardTestPlayerBase {
|
||||||
testReduce("{2/R}", 1, "{1/R}");
|
testReduce("{2/R}", 1, "{1/R}");
|
||||||
testReduce("{2/R}{2/G}", 1, "{1/R}{2/G}"); // TODO: add or/or reduction? (see https://github.com/magefree/mage/issues/6130 )
|
testReduce("{2/R}{2/G}", 1, "{1/R}{2/G}"); // TODO: add or/or reduction? (see https://github.com/magefree/mage/issues/6130 )
|
||||||
// mono hybrid, increase cost by 1
|
// mono hybrid, increase cost by 1
|
||||||
testReduce("{2/R}", -1, "{2/R}{1}");
|
testReduce("{2/R}", -1, "{1}{2/R}");
|
||||||
testReduce("{2/R}{2/G}", -1, "{2/R}{2/G}{1}");
|
testReduce("{2/R}{2/G}", -1, "{1}{2/R}{2/G}");
|
||||||
|
|
||||||
// generic, normal amount
|
// generic, normal amount
|
||||||
// mono hybrid + 1 generic, decrease cost by 1
|
// mono hybrid + 1 generic, decrease cost by 1
|
||||||
|
|
|
||||||
|
|
@ -1621,7 +1621,7 @@ public class VerifyCardDataTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
String expected = ref.manaCost;
|
String expected = ref.manaCost;
|
||||||
String cost = String.join("", card.getManaCost().getSymbols());
|
String cost = String.join("", card.getManaCostSymbols());
|
||||||
if (cost.isEmpty()) {
|
if (cost.isEmpty()) {
|
||||||
cost = null;
|
cost = null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,14 @@ public interface MageObject extends MageItem, Serializable {
|
||||||
|
|
||||||
ManaCosts<ManaCost> getManaCost();
|
ManaCosts<ManaCost> getManaCost();
|
||||||
|
|
||||||
|
default List<String> getManaCostSymbols() {
|
||||||
|
List<String> symbols = new ArrayList<>();
|
||||||
|
for (ManaCost cost : getManaCost()) {
|
||||||
|
symbols.add(cost.getText());
|
||||||
|
}
|
||||||
|
return symbols;
|
||||||
|
}
|
||||||
|
|
||||||
int getConvertedManaCost();
|
int getConvertedManaCost();
|
||||||
|
|
||||||
MageInt getPower();
|
MageInt getPower();
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import mage.target.targetadjustment.TargetAdjuster;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageIdentifier;
|
import mage.MageIdentifier;
|
||||||
|
|
@ -123,6 +124,14 @@ public interface Ability extends Controllable, Serializable {
|
||||||
*/
|
*/
|
||||||
ManaCosts<ManaCost> getManaCosts();
|
ManaCosts<ManaCost> getManaCosts();
|
||||||
|
|
||||||
|
default List<String> getManaCostSymbols() {
|
||||||
|
List<String> symbols = new ArrayList<>();
|
||||||
|
for (ManaCost cost : getManaCosts()) {
|
||||||
|
symbols.add(cost.getText());
|
||||||
|
}
|
||||||
|
return symbols;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all the {@link ManaCosts} that must be paid before activating this
|
* Gets all the {@link ManaCosts} that must be paid before activating this
|
||||||
* ability. These costs should be modified by any modification effects
|
* ability. These costs should be modified by any modification effects
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,6 @@ public interface ManaCosts<T extends ManaCost> extends List<T>, ManaCost {
|
||||||
*/
|
*/
|
||||||
void load(String mana, boolean extractMonoHybridGenericValue);
|
void load(String mana, boolean extractMonoHybridGenericValue);
|
||||||
|
|
||||||
List<String> getSymbols();
|
|
||||||
|
|
||||||
boolean payOrRollback(Ability ability, Game game, Ability source, UUID payingPlayerId);
|
boolean payOrRollback(Ability ability, Game game, Ability source, UUID payingPlayerId);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -505,15 +505,6 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getSymbols() {
|
|
||||||
List<String> symbols = new ArrayList<>();
|
|
||||||
for (ManaCost cost : this) {
|
|
||||||
symbols.add(cost.getText());
|
|
||||||
}
|
|
||||||
return symbols;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getId() {
|
public UUID getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,7 @@ public class SpellCostReductionForEachSourceEffect extends CostModificationEffec
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("this spell costs ");
|
sb.append("this spell costs ");
|
||||||
for (String manaSymbol : reduceManaCosts.getSymbols()) {
|
sb.append(reduceManaCosts.getText());
|
||||||
sb.append(manaSymbol);
|
|
||||||
}
|
|
||||||
sb.append(" less to cast for each ").append(this.eachAmount.getMessage());
|
sb.append(" less to cast for each ").append(this.eachAmount.getMessage());
|
||||||
this.staticText = sb.toString();
|
this.staticText = sb.toString();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,7 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl {
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("this spell costs ");
|
sb.append("this spell costs ");
|
||||||
for (String manaSymbol : manaCostsToReduce.getSymbols()) {
|
sb.append(manaCostsToReduce.getText());
|
||||||
sb.append(manaSymbol);
|
|
||||||
}
|
|
||||||
sb.append(" less to cast");
|
sb.append(" less to cast");
|
||||||
if (this.condition != null) {
|
if (this.condition != null) {
|
||||||
sb.append(" if ").append(this.condition.toString());
|
sb.append(" if ").append(this.condition.toString());
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,7 @@ public class SpellsCostIncreasingAllEffect extends CostModificationEffectImpl {
|
||||||
|
|
||||||
sb.append(" cost ");
|
sb.append(" cost ");
|
||||||
if (this.increaseManaCosts != null) {
|
if (this.increaseManaCosts != null) {
|
||||||
for (String manaSymbol : this.increaseManaCosts.getSymbols()) {
|
sb.append(this.increaseManaCosts.getText());
|
||||||
sb.append(manaSymbol);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sb.append("{").append(increaseGenericCost).append("}");
|
sb.append("{").append(increaseGenericCost).append("}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,7 @@ public class SpellsCostReductionControllerEffect extends CostModificationEffectI
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(filter.getMessage()).append(" you cast cost ");
|
sb.append(filter.getMessage()).append(" you cast cost ");
|
||||||
for (String manaSymbol : manaCostsToReduce.getSymbols()) {
|
sb.append(manaCostsToReduce.getText());
|
||||||
sb.append(manaSymbol);
|
|
||||||
}
|
|
||||||
sb.append(" less to cast. This effect reduces only the amount of colored mana you pay.");
|
sb.append(" less to cast. This effect reduces only the amount of colored mana you pay.");
|
||||||
this.staticText = sb.toString();
|
this.staticText = sb.toString();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.costs.mana.ManaCost;
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
import mage.abilities.costs.mana.ManaCosts;
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.ModalDoubleFacesCard;
|
import mage.cards.ModalDoubleFacesCard;
|
||||||
import mage.cards.repository.CardInfo;
|
import mage.cards.repository.CardInfo;
|
||||||
|
|
@ -35,6 +34,7 @@ public class MockCard extends CardImpl {
|
||||||
protected List<String> manaCostStr;
|
protected List<String> manaCostStr;
|
||||||
protected String adventureSpellName;
|
protected String adventureSpellName;
|
||||||
protected boolean isModalDoubleFacesCard;
|
protected boolean isModalDoubleFacesCard;
|
||||||
|
protected int convertedManaCost;
|
||||||
|
|
||||||
public MockCard(CardInfo card) {
|
public MockCard(CardInfo card) {
|
||||||
super(null, card.getName());
|
super(null, card.getName());
|
||||||
|
|
@ -49,10 +49,11 @@ public class MockCard extends CardImpl {
|
||||||
|
|
||||||
this.usesVariousArt = card.usesVariousArt();
|
this.usesVariousArt = card.usesVariousArt();
|
||||||
|
|
||||||
this.manaCost = new ManaCostsImpl(join(card.getManaCosts(CardInfo.ManaCostSide.ALL)));
|
//this.manaCost = new ManaCostsImpl(join(card.getManaCosts(CardInfo.ManaCostSide.ALL)));
|
||||||
this.manaCostLeftStr = card.getManaCosts(CardInfo.ManaCostSide.LEFT);
|
this.manaCostLeftStr = card.getManaCosts(CardInfo.ManaCostSide.LEFT);
|
||||||
this.manaCostRightStr = card.getManaCosts(CardInfo.ManaCostSide.RIGHT);
|
this.manaCostRightStr = card.getManaCosts(CardInfo.ManaCostSide.RIGHT);
|
||||||
this.manaCostStr = card.getManaCosts(CardInfo.ManaCostSide.ALL);
|
this.manaCostStr = card.getManaCosts(CardInfo.ManaCostSide.ALL);
|
||||||
|
this.convertedManaCost = card.getConvertedManaCost();
|
||||||
|
|
||||||
this.color = card.getColor();
|
this.color = card.getColor();
|
||||||
|
|
||||||
|
|
@ -112,21 +113,20 @@ public class MockCard extends CardImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ManaCosts<ManaCost> getManaCost() {
|
public ManaCosts<ManaCost> getManaCost() {
|
||||||
return manaCost;
|
// only split half cards can store mana cost in objects list instead strings (memory optimization)
|
||||||
|
// see https://github.com/magefree/mage/issues/7515
|
||||||
|
throw new IllegalArgumentException("Unsupport method call: getManaCost in " + this.getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
@Override
|
||||||
private ManaCosts<ManaCost> getManaCost(CardInfo.ManaCostSide manaCostSide) {
|
public List<String> getManaCostSymbols() {
|
||||||
switch (manaCostSide) {
|
return getManaCostStr(CardInfo.ManaCostSide.ALL);
|
||||||
case LEFT:
|
}
|
||||||
return manaCostLeft;
|
|
||||||
case RIGHT:
|
@Override
|
||||||
return manaCostRight;
|
public int getConvertedManaCost() {
|
||||||
default:
|
return this.convertedManaCost;
|
||||||
case ALL:
|
}
|
||||||
return manaCost;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public List<String> getManaCostStr(CardInfo.ManaCostSide manaCostSide) {
|
public List<String> getManaCostStr(CardInfo.ManaCostSide manaCostSide) {
|
||||||
switch (manaCostSide) {
|
switch (manaCostSide) {
|
||||||
|
|
@ -164,14 +164,6 @@ public class MockCard extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String join(List<String> strings) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (String string : strings) {
|
|
||||||
sb.append(string);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Ability textAbilityFromString(final String text) {
|
private Ability textAbilityFromString(final String text) {
|
||||||
return new MockAbility(text);
|
return new MockAbility(text);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
|
|
||||||
package mage.cards.mock;
|
package mage.cards.mock;
|
||||||
|
|
||||||
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.cards.SplitCard;
|
import mage.cards.SplitCard;
|
||||||
import mage.cards.SplitCardHalf;
|
import mage.cards.SplitCardHalf;
|
||||||
import mage.cards.repository.CardInfo;
|
import mage.cards.repository.CardInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
|
|
@ -12,9 +18,13 @@ import mage.cards.repository.CardInfo;
|
||||||
public class MockSplitCardHalf extends MockCard implements SplitCardHalf {
|
public class MockSplitCardHalf extends MockCard implements SplitCardHalf {
|
||||||
|
|
||||||
private SplitCard splitCardParent;
|
private SplitCard splitCardParent;
|
||||||
|
private ManaCosts<ManaCost> manaCosts;
|
||||||
|
private List<String> manaCostsSymbols;
|
||||||
|
|
||||||
public MockSplitCardHalf(CardInfo card) {
|
public MockSplitCardHalf(CardInfo card) {
|
||||||
super(card);
|
super(card);
|
||||||
|
this.manaCostsSymbols = card.getManaCosts(CardInfo.ManaCostSide.ALL);
|
||||||
|
this.manaCosts = new ManaCostsImpl<>(String.join("", this.manaCostsSymbols));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MockSplitCardHalf(final MockSplitCardHalf card) {
|
public MockSplitCardHalf(final MockSplitCardHalf card) {
|
||||||
|
|
@ -36,4 +46,15 @@ public class MockSplitCardHalf extends MockCard implements SplitCardHalf {
|
||||||
return splitCardParent;
|
return splitCardParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ManaCosts<ManaCost> getManaCost() {
|
||||||
|
// only split half cards can store mana cost in objects list instead strings (memory optimization)
|
||||||
|
return manaCosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getManaCostSymbols() {
|
||||||
|
// only split half cards can store mana cost in objects list instead strings (memory optimization)
|
||||||
|
return manaCostsSymbols;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,19 +167,19 @@ public class CardInfo {
|
||||||
|
|
||||||
// mana cost can contains multiple cards (split left/right, modal double faces, card/adventure)
|
// mana cost can contains multiple cards (split left/right, modal double faces, card/adventure)
|
||||||
if (card instanceof SplitCard) {
|
if (card instanceof SplitCard) {
|
||||||
List<String> manaCostLeft = ((SplitCard) card).getLeftHalfCard().getManaCost().getSymbols();
|
List<String> manaCostLeft = ((SplitCard) card).getLeftHalfCard().getManaCostSymbols();
|
||||||
List<String> manaCostRight = ((SplitCard) card).getRightHalfCard().getManaCost().getSymbols();
|
List<String> manaCostRight = ((SplitCard) card).getRightHalfCard().getManaCostSymbols();
|
||||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||||
} else if (card instanceof ModalDoubleFacesCard) {
|
} else if (card instanceof ModalDoubleFacesCard) {
|
||||||
List<String> manaCostLeft = ((ModalDoubleFacesCard) card).getLeftHalfCard().getManaCost().getSymbols();
|
List<String> manaCostLeft = ((ModalDoubleFacesCard) card).getLeftHalfCard().getManaCostSymbols();
|
||||||
List<String> manaCostRight = ((ModalDoubleFacesCard) card).getRightHalfCard().getManaCost().getSymbols();
|
List<String> manaCostRight = ((ModalDoubleFacesCard) card).getRightHalfCard().getManaCostSymbols();
|
||||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||||
} else if (card instanceof AdventureCard) {
|
} else if (card instanceof AdventureCard) {
|
||||||
List<String> manaCostLeft = ((AdventureCard) card).getSpellCard().getManaCost().getSymbols();
|
List<String> manaCostLeft = ((AdventureCard) card).getSpellCard().getManaCostSymbols();
|
||||||
List<String> manaCostRight = card.getManaCost().getSymbols();
|
List<String> manaCostRight = card.getManaCostSymbols();
|
||||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||||
} else {
|
} else {
|
||||||
this.setManaCosts(card.getManaCost().getSymbols());
|
this.setManaCosts(card.getManaCostSymbols());
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
|
|
||||||
|
|
@ -317,10 +317,10 @@ public final class RateCard {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static int getManaCostScore(Card card, List<ColoredManaSymbol> allowedColors) {
|
private static int getManaCostScore(Card card, List<ColoredManaSymbol> allowedColors) {
|
||||||
int converted = card.getManaCost().convertedManaCost();
|
int converted = card.getConvertedManaCost();
|
||||||
if (allowedColors == null) {
|
if (allowedColors == null) {
|
||||||
int colorPenalty = 0;
|
int colorPenalty = 0;
|
||||||
for (String symbol : card.getManaCost().getSymbols()) {
|
for (String symbol : card.getManaCostSymbols()) {
|
||||||
if (isColoredMana(symbol)) {
|
if (isColoredMana(symbol)) {
|
||||||
colorPenalty++;
|
colorPenalty++;
|
||||||
}
|
}
|
||||||
|
|
@ -329,7 +329,7 @@ public final class RateCard {
|
||||||
}
|
}
|
||||||
final Map<String, Integer> singleCount = new HashMap<>();
|
final Map<String, Integer> singleCount = new HashMap<>();
|
||||||
int maxSingleCount = 0;
|
int maxSingleCount = 0;
|
||||||
for (String symbol : card.getManaCost().getSymbols()) {
|
for (String symbol : card.getManaCostSymbols()) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
symbol = symbol.replace("{", "").replace("}", "");
|
symbol = symbol.replace("{", "").replace("}", "");
|
||||||
if (isColoredMana(symbol)) {
|
if (isColoredMana(symbol)) {
|
||||||
|
|
@ -385,7 +385,7 @@ public final class RateCard {
|
||||||
*/
|
*/
|
||||||
public static int getColorManaCount(Card card) {
|
public static int getColorManaCount(Card card) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (String symbol : card.getManaCost().getSymbols()) {
|
for (String symbol : card.getManaCostSymbols()) {
|
||||||
if (isColoredMana(symbol)) {
|
if (isColoredMana(symbol)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
@ -401,7 +401,7 @@ public final class RateCard {
|
||||||
*/
|
*/
|
||||||
public static int getDifferentColorManaCount(Card card) {
|
public static int getDifferentColorManaCount(Card card) {
|
||||||
Set<String> symbols = new HashSet<>();
|
Set<String> symbols = new HashSet<>();
|
||||||
for (String symbol : card.getManaCost().getSymbols()) {
|
for (String symbol : card.getManaCostSymbols()) {
|
||||||
if (isColoredMana(symbol)) {
|
if (isColoredMana(symbol)) {
|
||||||
symbols.add(symbol);
|
symbols.add(symbol);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package mage.game.stack;
|
package mage.game.stack;
|
||||||
|
|
||||||
import mage.MageIdentifier;
|
import mage.*;
|
||||||
import mage.MageInt;
|
|
||||||
import mage.MageObject;
|
|
||||||
import mage.ObjectColor;
|
|
||||||
import mage.abilities.*;
|
import mage.abilities.*;
|
||||||
import mage.abilities.costs.Cost;
|
import mage.abilities.costs.Cost;
|
||||||
import mage.abilities.costs.CostAdjuster;
|
import mage.abilities.costs.CostAdjuster;
|
||||||
|
|
@ -222,6 +219,11 @@ public class StackAbility extends StackObjImpl implements Ability {
|
||||||
return emptyCost;
|
return emptyCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getManaCostSymbols() {
|
||||||
|
return super.getManaCostSymbols();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MageInt getPower() {
|
public MageInt getPower() {
|
||||||
return MageInt.EmptyMageInt;
|
return MageInt.EmptyMageInt;
|
||||||
|
|
|
||||||
|
|
@ -133,29 +133,37 @@ public final class CardUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ManaCosts<ManaCost> adjustCost(ManaCosts<ManaCost> manaCosts, int reduceCount) {
|
private static ManaCosts<ManaCost> adjustCost(ManaCosts<ManaCost> manaCosts, int reduceCount) {
|
||||||
ManaCosts<ManaCost> adjustedCost = new ManaCostsImpl<>();
|
ManaCosts<ManaCost> newCost = new ManaCostsImpl<>();
|
||||||
|
|
||||||
// nothing to change
|
// nothing to change
|
||||||
if (reduceCount == 0) {
|
if (reduceCount == 0) {
|
||||||
for (ManaCost manaCost : manaCosts) {
|
for (ManaCost manaCost : manaCosts) {
|
||||||
adjustedCost.add(manaCost.copy());
|
newCost.add(manaCost.copy());
|
||||||
}
|
}
|
||||||
return adjustedCost;
|
return newCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep same order for costs
|
||||||
|
Map<ManaCost, ManaCost> changedCost = new LinkedHashMap<>(); // must be ordered
|
||||||
|
List<ManaCost> addedCost = new ArrayList<>();
|
||||||
|
manaCosts.forEach(manaCost -> {
|
||||||
|
changedCost.put(manaCost, manaCost);
|
||||||
|
});
|
||||||
|
|
||||||
// remove or save cost
|
// remove or save cost
|
||||||
if (reduceCount > 0) {
|
if (reduceCount > 0) {
|
||||||
int restToReduce = reduceCount;
|
int restToReduce = reduceCount;
|
||||||
|
|
||||||
// first run - priority for single option costs (generic)
|
// first run - priority for single option costs (generic)
|
||||||
for (ManaCost manaCost : manaCosts) {
|
for (ManaCost manaCost : manaCosts) {
|
||||||
|
|
||||||
|
// ignore snow mana
|
||||||
if (manaCost instanceof SnowManaCost) {
|
if (manaCost instanceof SnowManaCost) {
|
||||||
adjustedCost.add(manaCost);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore unknown mana
|
||||||
if (manaCost.getOptions().size() == 0) {
|
if (manaCost.getOptions().size() == 0) {
|
||||||
adjustedCost.add(manaCost);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,15 +179,15 @@ public final class CardUtil {
|
||||||
if ((colorless - restToReduce) > 0) {
|
if ((colorless - restToReduce) > 0) {
|
||||||
// partly reduce
|
// partly reduce
|
||||||
int newColorless = colorless - restToReduce;
|
int newColorless = colorless - restToReduce;
|
||||||
adjustedCost.add(new GenericManaCost(newColorless));
|
changedCost.put(manaCost, new GenericManaCost(newColorless));
|
||||||
restToReduce = 0;
|
restToReduce = 0;
|
||||||
} else {
|
} else {
|
||||||
// full reduce - ignore cost
|
// full reduce - ignore cost
|
||||||
|
changedCost.put(manaCost, null);
|
||||||
restToReduce -= colorless;
|
restToReduce -= colorless;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// nothing to reduce
|
// nothing to reduce
|
||||||
adjustedCost.add(manaCost.copy());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,22 +211,21 @@ public final class CardUtil {
|
||||||
if ((colorless - restToReduce) > 0) {
|
if ((colorless - restToReduce) > 0) {
|
||||||
// partly reduce
|
// partly reduce
|
||||||
int newColorless = colorless - restToReduce;
|
int newColorless = colorless - restToReduce;
|
||||||
adjustedCost.add(new MonoHybridManaCost(mono.getManaColor(), newColorless));
|
changedCost.put(manaCost, new MonoHybridManaCost(mono.getManaColor(), newColorless));
|
||||||
restToReduce = 0;
|
restToReduce = 0;
|
||||||
} else {
|
} else {
|
||||||
// full reduce
|
// full reduce
|
||||||
adjustedCost.add(new MonoHybridManaCost(mono.getManaColor(), 0));
|
changedCost.put(manaCost, new MonoHybridManaCost(mono.getManaColor(), 0));
|
||||||
restToReduce -= colorless;
|
restToReduce -= colorless;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// nothing to reduce
|
// nothing to reduce
|
||||||
adjustedCost.add(mono.copy());
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsupported multi-option mana types for reduce (like HybridManaCost)
|
// unsupported multi-option mana types for reduce (like HybridManaCost)
|
||||||
adjustedCost.add(manaCost.copy());
|
// nothing to do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,23 +233,39 @@ public final class CardUtil {
|
||||||
if (reduceCount < 0) {
|
if (reduceCount < 0) {
|
||||||
boolean added = false;
|
boolean added = false;
|
||||||
for (ManaCost manaCost : manaCosts) {
|
for (ManaCost manaCost : manaCosts) {
|
||||||
|
// ignore already reduced cost (add new cost to the start)
|
||||||
|
if (changedCost.get(manaCost) == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to existing cost
|
||||||
if (reduceCount != 0 && manaCost instanceof GenericManaCost) {
|
if (reduceCount != 0 && manaCost instanceof GenericManaCost) {
|
||||||
// add increase cost to existing generic
|
|
||||||
GenericManaCost gen = (GenericManaCost) manaCost;
|
GenericManaCost gen = (GenericManaCost) manaCost;
|
||||||
adjustedCost.add(new GenericManaCost(gen.getOptions().get(0).getGeneric() + -reduceCount));
|
changedCost.put(manaCost, new GenericManaCost(gen.getOptions().get(0).getGeneric() + -reduceCount));
|
||||||
reduceCount = 0;
|
reduceCount = 0;
|
||||||
added = true;
|
added = true;
|
||||||
} else {
|
} else {
|
||||||
// non-generic mana
|
// non-generic mana
|
||||||
adjustedCost.add(manaCost.copy());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add as new cost
|
||||||
if (!added) {
|
if (!added) {
|
||||||
// add increase cost as new
|
addedCost.add(new GenericManaCost(-reduceCount));
|
||||||
adjustedCost.add(new GenericManaCost(-reduceCount));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collect final result
|
||||||
|
addedCost.forEach(cost -> {
|
||||||
|
newCost.add(cost.copy());
|
||||||
|
});
|
||||||
|
changedCost.forEach((key, value) -> {
|
||||||
|
// ignore fully reduced and add changed
|
||||||
|
if (value != null) {
|
||||||
|
newCost.add(value.copy());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// cost modifying effects requiring snow mana unnecessarily (fixes #6000)
|
// cost modifying effects requiring snow mana unnecessarily (fixes #6000)
|
||||||
Filter filter = manaCosts.stream()
|
Filter filter = manaCosts.stream()
|
||||||
.filter(manaCost -> !(manaCost instanceof SnowManaCost))
|
.filter(manaCost -> !(manaCost instanceof SnowManaCost))
|
||||||
|
|
@ -251,9 +274,10 @@ public final class CardUtil {
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
adjustedCost.setSourceFilter(filter);
|
newCost.setSourceFilter(filter);
|
||||||
}
|
}
|
||||||
return adjustedCost;
|
|
||||||
|
return newCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reduceCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce) {
|
public static void reduceCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce) {
|
||||||
|
|
|
||||||
|
|
@ -576,7 +576,7 @@ public final class ManaUtil {
|
||||||
res.setWhite(res.isWhite() || secondColor.isWhite());
|
res.setWhite(res.isWhite() || secondColor.isWhite());
|
||||||
|
|
||||||
// from mana
|
// from mana
|
||||||
List<String> secondManaSymbols = secondSideCard.getManaCost().getSymbols();
|
List<String> secondManaSymbols = secondSideCard.getManaCostSymbols();
|
||||||
res.setWhite(res.isWhite() || containsManaSymbol(secondManaSymbols, "W"));
|
res.setWhite(res.isWhite() || containsManaSymbol(secondManaSymbols, "W"));
|
||||||
res.setBlue(res.isBlue() || containsManaSymbol(secondManaSymbols, "U"));
|
res.setBlue(res.isBlue() || containsManaSymbol(secondManaSymbols, "U"));
|
||||||
res.setBlack(res.isBlack() || containsManaSymbol(secondManaSymbols, "B"));
|
res.setBlack(res.isBlack() || containsManaSymbol(secondManaSymbols, "B"));
|
||||||
|
|
@ -628,7 +628,7 @@ public final class ManaUtil {
|
||||||
} else {
|
} else {
|
||||||
secondSide = card.getSecondCardFace();
|
secondSide = card.getSecondCardFace();
|
||||||
}
|
}
|
||||||
return getColorIdentity(card.getColor(), String.join("", card.getManaCost().getSymbols()), card.getRules(), secondSide);
|
return getColorIdentity(card.getColor(), String.join("", card.getManaCostSymbols()), card.getRules(), secondSide);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getColorIdentityHash(FilterMana colorIdentity) {
|
public static int getColorIdentityHash(FilterMana colorIdentity) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue