mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00: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.
|
||||
*/
|
||||
private boolean cardFitsChosenColors(Card card) {
|
||||
for (String symbol : card.getManaCost().getSymbols()) {
|
||||
for (String symbol : card.getManaCostSymbols()) {
|
||||
boolean found = false;
|
||||
symbol = symbol.replace("{", "").replace("}", "");
|
||||
if (isColoredManaSymbol(symbol)) {
|
||||
|
@ -218,7 +218,7 @@ public class DeckGeneratorPool
|
|||
|
||||
List<Card> fixedSpells = getFixedSpells();
|
||||
for(Card spell: fixedSpells) {
|
||||
for (String symbol : spell.getManaCost().getSymbols()) {
|
||||
for (String symbol : spell.getManaCostSymbols()) {
|
||||
symbol = symbol.replace("{", "").replace("}", "");
|
||||
if (isColoredManaSymbol(symbol)) {
|
||||
for (ColoredManaSymbol allowed : allowedColors) {
|
||||
|
|
|
@ -134,7 +134,7 @@ public final class DeckBuilder {
|
|||
final Map<String, Integer> colorCount = new HashMap<>();
|
||||
for (final Card card : deck.getCards()) {
|
||||
|
||||
for (String symbol : card.getManaCost().getSymbols()) {
|
||||
for (String symbol : card.getManaCostSymbols()) {
|
||||
int count = 0;
|
||||
symbol = symbol.replace("{", "").replace("}", "");
|
||||
if (isColoredMana(symbol)) {
|
||||
|
@ -243,7 +243,7 @@ public final class DeckBuilder {
|
|||
int maxSingleCount = 0;
|
||||
int multicolor = 0;
|
||||
Set<String> colors = new HashSet<>();
|
||||
for (String symbol : card.getManaCost().getSymbols()) {
|
||||
for (String symbol : card.getManaCostSymbols()) {
|
||||
int count = 0;
|
||||
symbol = symbol.replace("{", "").replace("}", "");
|
||||
if (isColoredMana(symbol)) {
|
||||
|
|
|
@ -31,7 +31,7 @@ public class AbilityView extends CardView {
|
|||
this.subTypes = new SubTypes();
|
||||
this.superTypes = EnumSet.noneOf(SuperType.class);
|
||||
this.color = new ObjectColor();
|
||||
this.manaCostLeftStr = String.join("", ability.getManaCosts().getSymbols());
|
||||
this.manaCostLeftStr = String.join("", ability.getManaCostSymbols());
|
||||
this.manaCostRightStr = "";
|
||||
}
|
||||
|
||||
|
|
|
@ -347,29 +347,29 @@ public class CardView extends SimpleCardView {
|
|||
if (splitCard != null) {
|
||||
this.isSplitCard = true;
|
||||
leftSplitName = splitCard.getLeftHalfCard().getName();
|
||||
leftSplitCostsStr = String.join("", splitCard.getLeftHalfCard().getManaCost().getSymbols());
|
||||
leftSplitCostsStr = String.join("", splitCard.getLeftHalfCard().getManaCostSymbols());
|
||||
leftSplitRules = splitCard.getLeftHalfCard().getRules(game);
|
||||
leftSplitTypeLine = getCardTypeLine(game, splitCard.getLeftHalfCard());
|
||||
rightSplitName = splitCard.getRightHalfCard().getName();
|
||||
rightSplitCostsStr = String.join("", splitCard.getRightHalfCard().getManaCost().getSymbols());
|
||||
rightSplitCostsStr = String.join("", splitCard.getRightHalfCard().getManaCostSymbols());
|
||||
rightSplitRules = splitCard.getRightHalfCard().getRules(game);
|
||||
rightSplitTypeLine = getCardTypeLine(game, splitCard.getRightHalfCard());
|
||||
|
||||
fullCardName = card.getName(); // split card contains full name as normal
|
||||
this.manaCostLeftStr = String.join("", splitCard.getLeftHalfCard().getManaCost().getSymbols());
|
||||
this.manaCostRightStr = String.join("", splitCard.getRightHalfCard().getManaCost().getSymbols());
|
||||
this.manaCostLeftStr = String.join("", splitCard.getLeftHalfCard().getManaCostSymbols());
|
||||
this.manaCostRightStr = String.join("", splitCard.getRightHalfCard().getManaCostSymbols());
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
this.isModalDoubleFacesCard = true;
|
||||
ModalDoubleFacesCard mainCard = ((ModalDoubleFacesCard) card);
|
||||
fullCardName = mainCard.getLeftHalfCard().getName() + MockCard.MODAL_DOUBLE_FACES_NAME_SEPARATOR + mainCard.getRightHalfCard().getName();
|
||||
this.manaCostLeftStr = String.join("", mainCard.getLeftHalfCard().getManaCost().getSymbols());
|
||||
this.manaCostRightStr = String.join("", mainCard.getRightHalfCard().getManaCost().getSymbols());
|
||||
this.manaCostLeftStr = String.join("", mainCard.getLeftHalfCard().getManaCostSymbols());
|
||||
this.manaCostRightStr = String.join("", mainCard.getRightHalfCard().getManaCostSymbols());
|
||||
} else if (card instanceof AdventureCard) {
|
||||
AdventureCard adventureCard = ((AdventureCard) card);
|
||||
AdventureCardSpell adventureCardSpell = ((AdventureCardSpell) adventureCard.getSpellCard());
|
||||
fullCardName = adventureCard.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + adventureCardSpell.getName();
|
||||
this.manaCostLeftStr = String.join("", adventureCardSpell.getManaCost().getSymbols());
|
||||
this.manaCostRightStr = String.join("", adventureCard.getManaCost().getSymbols());
|
||||
this.manaCostLeftStr = String.join("", adventureCardSpell.getManaCostSymbols());
|
||||
this.manaCostRightStr = String.join("", adventureCard.getManaCostSymbols());
|
||||
} else if (card instanceof MockCard) {
|
||||
// deck editor cards
|
||||
fullCardName = ((MockCard) card).getFullName(true);
|
||||
|
@ -377,7 +377,7 @@ public class CardView extends SimpleCardView {
|
|||
this.manaCostRightStr = String.join("", ((MockCard) card).getManaCostStr(CardInfo.ManaCostSide.RIGHT));
|
||||
} else {
|
||||
fullCardName = card.getName();
|
||||
this.manaCostLeftStr = String.join("", card.getManaCost().getSymbols());
|
||||
this.manaCostLeftStr = String.join("", card.getManaCostSymbols());
|
||||
this.manaCostRightStr = "";
|
||||
}
|
||||
|
||||
|
@ -389,7 +389,7 @@ public class CardView extends SimpleCardView {
|
|||
} else {
|
||||
this.rules = card.getRules(game);
|
||||
}
|
||||
this.convertedManaCost = card.getManaCost().convertedManaCost();
|
||||
this.convertedManaCost = card.getConvertedManaCost();
|
||||
|
||||
if (card instanceof Permanent) {
|
||||
this.mageObjectType = MageObjectType.PERMANENT;
|
||||
|
@ -563,7 +563,7 @@ public class CardView extends SimpleCardView {
|
|||
this.subTypes = object.getSubtype(game);
|
||||
this.superTypes = object.getSuperType();
|
||||
this.color = object.getColor(game);
|
||||
this.manaCostLeftStr = String.join("", object.getManaCost().getSymbols());
|
||||
this.manaCostLeftStr = String.join("", object.getManaCostSymbols());
|
||||
this.manaCostRightStr = "";
|
||||
this.convertedManaCost = object.getManaCost().convertedManaCost();
|
||||
if (object instanceof PermanentToken) {
|
||||
|
@ -733,7 +733,7 @@ public class CardView extends SimpleCardView {
|
|||
this.color = token.getColor(game);
|
||||
this.frameColor = token.getFrameColor(game);
|
||||
this.frameStyle = token.getFrameStyle();
|
||||
this.manaCostLeftStr = String.join("", token.getManaCost().getSymbols());
|
||||
this.manaCostLeftStr = String.join("", token.getManaCostSymbols());
|
||||
this.manaCostRightStr = "";
|
||||
this.rarity = Rarity.SPECIAL;
|
||||
this.type = token.getTokenType();
|
||||
|
|
|
@ -44,7 +44,7 @@ public class StackAbilityView extends CardView {
|
|||
this.subTypes = ability.getSubtype(game);
|
||||
this.superTypes = ability.getSuperType();
|
||||
this.color = ability.getColor(game);
|
||||
this.manaCostLeftStr = String.join("", ability.getManaCost().getSymbols());
|
||||
this.manaCostLeftStr = String.join("", ability.getManaCostSymbols());
|
||||
this.manaCostRightStr = "";
|
||||
this.cardTypes = ability.getCardType();
|
||||
this.subTypes = ability.getSubtype(game);
|
||||
|
|
|
@ -2316,7 +2316,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
if (differentColorsInCost > 0 && differentColorsInCost < 3) {
|
||||
// if some colors were already chosen, total amount shouldn't be more than 3
|
||||
if (chosenSymbols.size() + differentColorsInCost < 4) {
|
||||
for (String symbol : picked.card.getManaCost().getSymbols()) {
|
||||
for (String symbol : picked.card.getManaCostSymbols()) {
|
||||
symbol = symbol.replace("{", "").replace("}", "");
|
||||
if (RateCard.isColoredMana(symbol)) {
|
||||
chosenSymbols.add(symbol);
|
||||
|
|
|
@ -68,7 +68,7 @@ enum EmbodimentOfAgoniesValue implements DynamicValue {
|
|||
.getCards(game)
|
||||
.stream()
|
||||
.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(""));
|
||||
return stringSet.size();
|
||||
}
|
||||
|
@ -83,11 +83,11 @@ enum EmbodimentOfAgoniesValue implements DynamicValue {
|
|||
return "";
|
||||
}
|
||||
|
||||
private static String getCosts(ManaCosts<ManaCost> costs) {
|
||||
private static String getCosts(List<String> manaCostSymbols) {
|
||||
List<String> newList = new ArrayList();
|
||||
int generic = 0;
|
||||
boolean hasGeneric = false;
|
||||
for (String s : costs.getSymbols()) {
|
||||
for (String s : manaCostSymbols) {
|
||||
if (s.matches("\\{\\d*\\}")) {
|
||||
generic += Integer.parseInt(s.substring(1, s.length() - 1));
|
||||
hasGeneric = true;
|
||||
|
|
|
@ -69,8 +69,7 @@ enum JeganthaTheWellspringCompanionCondition implements CompanionCondition {
|
|||
|
||||
private static boolean checkCard(Card card) {
|
||||
Map<String, Integer> symbolMap = new HashMap();
|
||||
return card.getManaCost()
|
||||
.getSymbols()
|
||||
return card.getManaCostSymbols()
|
||||
.stream()
|
||||
.anyMatch(s -> symbolMap.compute(
|
||||
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());
|
||||
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
|
||||
|
||||
// colorless is not reduce
|
||||
|
@ -73,16 +75,29 @@ public class CostReduceTest extends CardTestPlayerBase {
|
|||
testReduce("{R}{3}{G}", 2, "{R}{1}{G}");
|
||||
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
|
||||
|
||||
// colorless, increase cost by 1
|
||||
testReduce("{C}", -1, "{C}{1}");
|
||||
testReduce("{C}{G}", -1, "{C}{G}{1}");
|
||||
testReduce("{C}", -1, "{1}{C}");
|
||||
testReduce("{C}{G}", -1, "{1}{C}{G}");
|
||||
|
||||
// 0 generic, increase cost by 1
|
||||
testReduce("", -1, "{1}");
|
||||
testReduce("{R}", -1, "{R}{1}");
|
||||
testReduce("{R}{G}", -1, "{R}{G}{1}");
|
||||
testReduce("{R}", -1, "{1}{R}");
|
||||
testReduce("{R}{G}", -1, "{1}{R}{G}");
|
||||
|
||||
// 1 generic, increase cost by 1
|
||||
testReduce("{1}", -1, "{2}");
|
||||
|
@ -123,8 +138,8 @@ public class CostReduceTest extends CardTestPlayerBase {
|
|||
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 )
|
||||
// mono hybrid, increase cost by 1
|
||||
testReduce("{2/R}", -1, "{2/R}{1}");
|
||||
testReduce("{2/R}{2/G}", -1, "{2/R}{2/G}{1}");
|
||||
testReduce("{2/R}", -1, "{1}{2/R}");
|
||||
testReduce("{2/R}{2/G}", -1, "{1}{2/R}{2/G}");
|
||||
|
||||
// generic, normal amount
|
||||
// mono hybrid + 1 generic, decrease cost by 1
|
||||
|
|
|
@ -1621,7 +1621,7 @@ public class VerifyCardDataTest {
|
|||
}
|
||||
|
||||
String expected = ref.manaCost;
|
||||
String cost = String.join("", card.getManaCost().getSymbols());
|
||||
String cost = String.join("", card.getManaCostSymbols());
|
||||
if (cost.isEmpty()) {
|
||||
cost = null;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,14 @@ public interface MageObject extends MageItem, Serializable {
|
|||
|
||||
ManaCosts<ManaCost> getManaCost();
|
||||
|
||||
default List<String> getManaCostSymbols() {
|
||||
List<String> symbols = new ArrayList<>();
|
||||
for (ManaCost cost : getManaCost()) {
|
||||
symbols.add(cost.getText());
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
int getConvertedManaCost();
|
||||
|
||||
MageInt getPower();
|
||||
|
|
|
@ -22,6 +22,7 @@ import mage.target.targetadjustment.TargetAdjuster;
|
|||
import mage.watchers.Watcher;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageIdentifier;
|
||||
|
@ -123,6 +124,14 @@ public interface Ability extends Controllable, Serializable {
|
|||
*/
|
||||
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
|
||||
* 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);
|
||||
|
||||
List<String> getSymbols();
|
||||
|
||||
boolean payOrRollback(Ability ability, Game game, Ability source, UUID payingPlayerId);
|
||||
|
||||
@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
|
||||
public UUID getId() {
|
||||
return this.id;
|
||||
|
|
|
@ -43,9 +43,7 @@ public class SpellCostReductionForEachSourceEffect extends CostModificationEffec
|
|||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("this spell costs ");
|
||||
for (String manaSymbol : reduceManaCosts.getSymbols()) {
|
||||
sb.append(manaSymbol);
|
||||
}
|
||||
sb.append(reduceManaCosts.getText());
|
||||
sb.append(" less to cast for each ").append(this.eachAmount.getMessage());
|
||||
this.staticText = sb.toString();
|
||||
}
|
||||
|
|
|
@ -34,9 +34,7 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl {
|
|||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("this spell costs ");
|
||||
for (String manaSymbol : manaCostsToReduce.getSymbols()) {
|
||||
sb.append(manaSymbol);
|
||||
}
|
||||
sb.append(manaCostsToReduce.getText());
|
||||
sb.append(" less to cast");
|
||||
if (this.condition != null) {
|
||||
sb.append(" if ").append(this.condition.toString());
|
||||
|
|
|
@ -63,9 +63,7 @@ public class SpellsCostIncreasingAllEffect extends CostModificationEffectImpl {
|
|||
|
||||
sb.append(" cost ");
|
||||
if (this.increaseManaCosts != null) {
|
||||
for (String manaSymbol : this.increaseManaCosts.getSymbols()) {
|
||||
sb.append(manaSymbol);
|
||||
}
|
||||
sb.append(this.increaseManaCosts.getText());
|
||||
} else {
|
||||
sb.append("{").append(increaseGenericCost).append("}");
|
||||
}
|
||||
|
|
|
@ -37,9 +37,7 @@ public class SpellsCostReductionControllerEffect extends CostModificationEffectI
|
|||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(filter.getMessage()).append(" you cast cost ");
|
||||
for (String manaSymbol : manaCostsToReduce.getSymbols()) {
|
||||
sb.append(manaSymbol);
|
||||
}
|
||||
sb.append(manaCostsToReduce.getText());
|
||||
sb.append(" less to cast. This effect reduces only the amount of colored mana you pay.");
|
||||
this.staticText = sb.toString();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.cards.repository.CardInfo;
|
||||
|
@ -35,6 +34,7 @@ public class MockCard extends CardImpl {
|
|||
protected List<String> manaCostStr;
|
||||
protected String adventureSpellName;
|
||||
protected boolean isModalDoubleFacesCard;
|
||||
protected int convertedManaCost;
|
||||
|
||||
public MockCard(CardInfo card) {
|
||||
super(null, card.getName());
|
||||
|
@ -49,10 +49,11 @@ public class MockCard extends CardImpl {
|
|||
|
||||
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.manaCostRightStr = card.getManaCosts(CardInfo.ManaCostSide.RIGHT);
|
||||
this.manaCostStr = card.getManaCosts(CardInfo.ManaCostSide.ALL);
|
||||
this.convertedManaCost = card.getConvertedManaCost();
|
||||
|
||||
this.color = card.getColor();
|
||||
|
||||
|
@ -112,21 +113,20 @@ public class MockCard extends CardImpl {
|
|||
|
||||
@Override
|
||||
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());
|
||||
}
|
||||
|
||||
/*
|
||||
private ManaCosts<ManaCost> getManaCost(CardInfo.ManaCostSide manaCostSide) {
|
||||
switch (manaCostSide) {
|
||||
case LEFT:
|
||||
return manaCostLeft;
|
||||
case RIGHT:
|
||||
return manaCostRight;
|
||||
default:
|
||||
case ALL:
|
||||
return manaCost;
|
||||
}
|
||||
}*/
|
||||
@Override
|
||||
public List<String> getManaCostSymbols() {
|
||||
return getManaCostStr(CardInfo.ManaCostSide.ALL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConvertedManaCost() {
|
||||
return this.convertedManaCost;
|
||||
}
|
||||
|
||||
public List<String> getManaCostStr(CardInfo.ManaCostSide 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) {
|
||||
return new MockAbility(text);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
|
||||
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.SplitCardHalf;
|
||||
import mage.cards.repository.CardInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
@ -12,9 +18,13 @@ import mage.cards.repository.CardInfo;
|
|||
public class MockSplitCardHalf extends MockCard implements SplitCardHalf {
|
||||
|
||||
private SplitCard splitCardParent;
|
||||
private ManaCosts<ManaCost> manaCosts;
|
||||
private List<String> manaCostsSymbols;
|
||||
|
||||
public MockSplitCardHalf(CardInfo card) {
|
||||
super(card);
|
||||
this.manaCostsSymbols = card.getManaCosts(CardInfo.ManaCostSide.ALL);
|
||||
this.manaCosts = new ManaCostsImpl<>(String.join("", this.manaCostsSymbols));
|
||||
}
|
||||
|
||||
public MockSplitCardHalf(final MockSplitCardHalf card) {
|
||||
|
@ -36,4 +46,15 @@ public class MockSplitCardHalf extends MockCard implements SplitCardHalf {
|
|||
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)
|
||||
if (card instanceof SplitCard) {
|
||||
List<String> manaCostLeft = ((SplitCard) card).getLeftHalfCard().getManaCost().getSymbols();
|
||||
List<String> manaCostRight = ((SplitCard) card).getRightHalfCard().getManaCost().getSymbols();
|
||||
List<String> manaCostLeft = ((SplitCard) card).getLeftHalfCard().getManaCostSymbols();
|
||||
List<String> manaCostRight = ((SplitCard) card).getRightHalfCard().getManaCostSymbols();
|
||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
List<String> manaCostLeft = ((ModalDoubleFacesCard) card).getLeftHalfCard().getManaCost().getSymbols();
|
||||
List<String> manaCostRight = ((ModalDoubleFacesCard) card).getRightHalfCard().getManaCost().getSymbols();
|
||||
List<String> manaCostLeft = ((ModalDoubleFacesCard) card).getLeftHalfCard().getManaCostSymbols();
|
||||
List<String> manaCostRight = ((ModalDoubleFacesCard) card).getRightHalfCard().getManaCostSymbols();
|
||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||
} else if (card instanceof AdventureCard) {
|
||||
List<String> manaCostLeft = ((AdventureCard) card).getSpellCard().getManaCost().getSymbols();
|
||||
List<String> manaCostRight = card.getManaCost().getSymbols();
|
||||
List<String> manaCostLeft = ((AdventureCard) card).getSpellCard().getManaCostSymbols();
|
||||
List<String> manaCostRight = card.getManaCostSymbols();
|
||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||
} else {
|
||||
this.setManaCosts(card.getManaCost().getSymbols());
|
||||
this.setManaCosts(card.getManaCostSymbols());
|
||||
}
|
||||
|
||||
int length = 0;
|
||||
|
|
|
@ -317,10 +317,10 @@ public final class RateCard {
|
|||
* @return
|
||||
*/
|
||||
private static int getManaCostScore(Card card, List<ColoredManaSymbol> allowedColors) {
|
||||
int converted = card.getManaCost().convertedManaCost();
|
||||
int converted = card.getConvertedManaCost();
|
||||
if (allowedColors == null) {
|
||||
int colorPenalty = 0;
|
||||
for (String symbol : card.getManaCost().getSymbols()) {
|
||||
for (String symbol : card.getManaCostSymbols()) {
|
||||
if (isColoredMana(symbol)) {
|
||||
colorPenalty++;
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ public final class RateCard {
|
|||
}
|
||||
final Map<String, Integer> singleCount = new HashMap<>();
|
||||
int maxSingleCount = 0;
|
||||
for (String symbol : card.getManaCost().getSymbols()) {
|
||||
for (String symbol : card.getManaCostSymbols()) {
|
||||
int count = 0;
|
||||
symbol = symbol.replace("{", "").replace("}", "");
|
||||
if (isColoredMana(symbol)) {
|
||||
|
@ -385,7 +385,7 @@ public final class RateCard {
|
|||
*/
|
||||
public static int getColorManaCount(Card card) {
|
||||
int count = 0;
|
||||
for (String symbol : card.getManaCost().getSymbols()) {
|
||||
for (String symbol : card.getManaCostSymbols()) {
|
||||
if (isColoredMana(symbol)) {
|
||||
count++;
|
||||
}
|
||||
|
@ -401,7 +401,7 @@ public final class RateCard {
|
|||
*/
|
||||
public static int getDifferentColorManaCount(Card card) {
|
||||
Set<String> symbols = new HashSet<>();
|
||||
for (String symbol : card.getManaCost().getSymbols()) {
|
||||
for (String symbol : card.getManaCostSymbols()) {
|
||||
if (isColoredMana(symbol)) {
|
||||
symbols.add(symbol);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package mage.game.stack;
|
||||
|
||||
import mage.MageIdentifier;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
import mage.*;
|
||||
import mage.abilities.*;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
|
@ -222,6 +219,11 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
return emptyCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getManaCostSymbols() {
|
||||
return super.getManaCostSymbols();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageInt getPower() {
|
||||
return MageInt.EmptyMageInt;
|
||||
|
|
|
@ -133,29 +133,37 @@ public final class CardUtil {
|
|||
}
|
||||
|
||||
private static ManaCosts<ManaCost> adjustCost(ManaCosts<ManaCost> manaCosts, int reduceCount) {
|
||||
ManaCosts<ManaCost> adjustedCost = new ManaCostsImpl<>();
|
||||
ManaCosts<ManaCost> newCost = new ManaCostsImpl<>();
|
||||
|
||||
// nothing to change
|
||||
if (reduceCount == 0) {
|
||||
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
|
||||
if (reduceCount > 0) {
|
||||
int restToReduce = reduceCount;
|
||||
|
||||
// first run - priority for single option costs (generic)
|
||||
for (ManaCost manaCost : manaCosts) {
|
||||
|
||||
// ignore snow mana
|
||||
if (manaCost instanceof SnowManaCost) {
|
||||
adjustedCost.add(manaCost);
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignore unknown mana
|
||||
if (manaCost.getOptions().size() == 0) {
|
||||
adjustedCost.add(manaCost);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -171,15 +179,15 @@ public final class CardUtil {
|
|||
if ((colorless - restToReduce) > 0) {
|
||||
// partly reduce
|
||||
int newColorless = colorless - restToReduce;
|
||||
adjustedCost.add(new GenericManaCost(newColorless));
|
||||
changedCost.put(manaCost, new GenericManaCost(newColorless));
|
||||
restToReduce = 0;
|
||||
} else {
|
||||
// full reduce - ignore cost
|
||||
changedCost.put(manaCost, null);
|
||||
restToReduce -= colorless;
|
||||
}
|
||||
} else {
|
||||
// nothing to reduce
|
||||
adjustedCost.add(manaCost.copy());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,22 +211,21 @@ public final class CardUtil {
|
|||
if ((colorless - restToReduce) > 0) {
|
||||
// partly reduce
|
||||
int newColorless = colorless - restToReduce;
|
||||
adjustedCost.add(new MonoHybridManaCost(mono.getManaColor(), newColorless));
|
||||
changedCost.put(manaCost, new MonoHybridManaCost(mono.getManaColor(), newColorless));
|
||||
restToReduce = 0;
|
||||
} else {
|
||||
// full reduce
|
||||
adjustedCost.add(new MonoHybridManaCost(mono.getManaColor(), 0));
|
||||
changedCost.put(manaCost, new MonoHybridManaCost(mono.getManaColor(), 0));
|
||||
restToReduce -= colorless;
|
||||
}
|
||||
} else {
|
||||
// nothing to reduce
|
||||
adjustedCost.add(mono.copy());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
boolean added = false;
|
||||
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) {
|
||||
// add increase cost to existing generic
|
||||
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;
|
||||
added = true;
|
||||
} else {
|
||||
// non-generic mana
|
||||
adjustedCost.add(manaCost.copy());
|
||||
}
|
||||
}
|
||||
|
||||
// add as new cost
|
||||
if (!added) {
|
||||
// add increase cost as new
|
||||
adjustedCost.add(new GenericManaCost(-reduceCount));
|
||||
addedCost.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)
|
||||
Filter filter = manaCosts.stream()
|
||||
.filter(manaCost -> !(manaCost instanceof SnowManaCost))
|
||||
|
@ -251,9 +274,10 @@ public final class CardUtil {
|
|||
.findFirst()
|
||||
.orElse(null);
|
||||
if (filter != null) {
|
||||
adjustedCost.setSourceFilter(filter);
|
||||
newCost.setSourceFilter(filter);
|
||||
}
|
||||
return adjustedCost;
|
||||
|
||||
return newCost;
|
||||
}
|
||||
|
||||
public static void reduceCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce) {
|
||||
|
|
|
@ -576,7 +576,7 @@ public final class ManaUtil {
|
|||
res.setWhite(res.isWhite() || secondColor.isWhite());
|
||||
|
||||
// from mana
|
||||
List<String> secondManaSymbols = secondSideCard.getManaCost().getSymbols();
|
||||
List<String> secondManaSymbols = secondSideCard.getManaCostSymbols();
|
||||
res.setWhite(res.isWhite() || containsManaSymbol(secondManaSymbols, "W"));
|
||||
res.setBlue(res.isBlue() || containsManaSymbol(secondManaSymbols, "U"));
|
||||
res.setBlack(res.isBlack() || containsManaSymbol(secondManaSymbols, "B"));
|
||||
|
@ -628,7 +628,7 @@ public final class ManaUtil {
|
|||
} else {
|
||||
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) {
|
||||
|
|
Loading…
Reference in a new issue