From eaab0bdd7d6897559d54cc7c0d9795e87e852263 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 12 Nov 2024 21:21:49 +0800 Subject: [PATCH 01/16] fix Cryptic Spire --- .../src/main/java/forge/game/GameAction.java | 8 ++++++-- .../src/main/java/forge/game/card/Card.java | 15 ++++++++++++++- .../main/java/forge/game/card/CardView.java | 7 ++++++- .../game/spellability/AbilityManaPart.java | 19 +++++++++++++++++++ .../forge/trackable/TrackableProperty.java | 1 + .../res/cardsfolder/c/cryptic_spires.txt | 2 +- .../java/forge/gui/card/CardDetailUtil.java | 10 ++++++++++ 7 files changed, 57 insertions(+), 5 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index e1ccedf9df1..d583954a67b 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -572,6 +572,10 @@ public class GameAction { game.getTriggerHandler().registerActiveTrigger(copied, false); } + if (c.hasChosenColorSpire()) { + copied.setChosenColorSpire(ImmutableList.copyOf(c.getChosenColorSpire())); + } + // update state for view copied.updateStateForView(); @@ -2223,14 +2227,14 @@ public class GameAction { c.setChosenNumber(chosen); } for (Card c : spires) { - if (!c.hasChosenColor()) { + if (!c.hasChosenColorSpire()) { List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); String prompt = CardTranslation.getTranslatedName(c.getName()) + ": " + Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(2)); SpellAbility sa = new SpellAbility.EmptySa(ApiType.ChooseColor, c, takesAction); sa.putParam("AILogic", "MostProminentInComputerDeck"); List chosenColors = takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices); - c.setChosenColors(chosenColors); + c.setChosenColorSpire(chosenColors); } } takesAction = game.getNextPlayerAfter(takesAction); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index b8d7e07a2d7..7350fe5adcd 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -293,6 +293,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr private String chosenType2 = ""; private List notedTypes = new ArrayList<>(); private List chosenColors; + private List chosenColorSpire; private List chosenName = new ArrayList<>(); private Integer chosenNumber; private Player chosenPlayer; @@ -2118,7 +2119,19 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr public boolean hasChosenColor(String s) { return chosenColors != null && chosenColors.contains(s); } - + public final Iterable getChosenColorSpire() { + if (chosenColorSpire == null) { + return Lists.newArrayList(); + } + return chosenColorSpire; + } + public final void setChosenColorSpire(final List s) { + chosenColorSpire = s; + view.updateChosenColorSpire(this); + } + public boolean hasChosenColorSpire() { + return chosenColorSpire != null && !chosenColorSpire.isEmpty(); + } public final Card getChosenCard() { return getChosenCards().getFirst(); } diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index 1f25f0380d2..9325bbd2896 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -433,7 +433,12 @@ public class CardView extends GameEntityView { void updateChosenColors(Card c) { set(TrackableProperty.ChosenColors, c.getChosenColors()); } - + public List getChosenColorSpire() { + return get(TrackableProperty.ChosenColorSpire); + } + void updateChosenColorSpire(Card c) { + set(TrackableProperty.ChosenColorSpire, c.getChosenColorSpire()); + } public FCollectionView getMergedCardsCollection() { return get(TrackableProperty.MergedCardsCollection); } diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java index 8fd49d86057..5c357ad9721 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -654,6 +654,10 @@ public class AbilityManaPart implements java.io.Serializable { if (origProduced.contains("Chosen")) { origProduced = origProduced.replace("Chosen", getChosenColor(sa)); } + // replace Chosen for Spire colors + if (origProduced.contains("Spire")) { + origProduced = origProduced.replace("Spire", getChosenSpireColor(sa)); + } if (origProduced.contains("NotedColors")) { // Should only be used for Paliano, the High City if (sa.getActivatingPlayer() == null) { @@ -697,6 +701,21 @@ public class AbilityManaPart implements java.io.Serializable { return sb.length() == 0 ? "" : sb.substring(0, sb.length() - 1); } + public String getChosenSpireColor(SpellAbility sa) { + if (sa == null) { + return ""; + } + Card card = sa.getHostCard(); + if (card != null && card.hasChosenColorSpire()) { + StringBuilder values = new StringBuilder(); + for (String s : card.getChosenColorSpire()) { + values.append(MagicColor.toShortString(MagicColor.fromName(s))).append(" "); + } + return values.toString(); + } + return ""; + } + public String getChosenColor(SpellAbility sa) { if (sa == null) { return ""; diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index 58481162c46..638c8694c94 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -67,6 +67,7 @@ public enum TrackableProperty { ChosenType2(TrackableTypes.StringType), NotedTypes(TrackableTypes.StringListType), ChosenColors(TrackableTypes.StringListType), + ChosenColorSpire(TrackableTypes.StringListType), ChosenCards(TrackableTypes.CardViewCollectionType), ChosenNumber(TrackableTypes.StringType), StoredRolls(TrackableTypes.StringListType), diff --git a/forge-gui/res/cardsfolder/c/cryptic_spires.txt b/forge-gui/res/cardsfolder/c/cryptic_spires.txt index 9bcbec5ba29..2f7aafde128 100644 --- a/forge-gui/res/cardsfolder/c/cryptic_spires.txt +++ b/forge-gui/res/cardsfolder/c/cryptic_spires.txt @@ -4,5 +4,5 @@ Types:Land Text:As you create your deck, circle two of the colors below. R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True -A:AB$ Mana | Cost$ T | Produced$ Combo Chosen | SpellDescription$ Add one mana of either of the circled colors. +A:AB$ Mana | Cost$ T | Produced$ Combo Spire | SpellDescription$ Add one mana of either of the circled colors. Oracle:As you create your deck, circle two of the colors below.\nCryptic Spires enters tapped.\n{T}: Add one mana of either of the circled colors. diff --git a/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java b/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java index 59ebe64a76c..87ec9d6fb70 100644 --- a/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java +++ b/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java @@ -487,6 +487,16 @@ public class CardDetailUtil { area.append(")"); } + // chosen spire + if (card.getChosenColorSpire() != null && !card.getChosenColorSpire().isEmpty()) { + if (area.length() != 0) { + area.append("\n"); + } + area.append("(").append(Localizer.getInstance().getMessage("lblSelected")).append(": "); + area.append(Lang.joinHomogenous(card.getChosenColorSpire().stream().map(DeckRecognizer::getLocalisedMagicColorName).collect(Collectors.toList()))); + area.append(")"); + } + // chosen color if (card.getChosenColors() != null && !card.getChosenColors().isEmpty()) { if (area.length() != 0) { From 65c5985281656440290f34cc9f124c0e991317d9 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 12 Nov 2024 22:14:11 +0800 Subject: [PATCH 02/16] add TODO --- forge-game/src/main/java/forge/game/GameAction.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index d583954a67b..974f28f63c9 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -2227,6 +2227,8 @@ public class GameAction { c.setChosenNumber(chosen); } for (Card c : spires) { + // TODO: only do this for the AI, for the player part, get the encoded color from the deck file and pass + // it to either player or the papercard object so it feels like rule based for the player side.. if (!c.hasChosenColorSpire()) { List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); String prompt = CardTranslation.getTranslatedName(c.getName()) + ": " + From 5afaff814a3800657cb8613044a15710388a7dd1 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 13 Nov 2024 10:29:18 +0800 Subject: [PATCH 03/16] update deck editor for spire --- .../src/main/java/forge/item/IPaperCard.java | 1 + .../src/main/java/forge/item/PaperCard.java | 24 ++++++++++++++--- .../src/main/java/forge/item/PaperToken.java | 6 +++++ .../src/main/java/forge/game/GameAction.java | 20 +++++++++----- .../game/ability/effects/ManaEffect.java | 2 +- .../src/forge/deck/FDeckEditor.java | 27 +++++++++++++++++++ .../forge/itemmanager/views/ImageView.java | 22 +++++++++++++++ 7 files changed, 91 insertions(+), 11 deletions(-) diff --git a/forge-core/src/main/java/forge/item/IPaperCard.java b/forge-core/src/main/java/forge/item/IPaperCard.java index 72d2f9b6b8b..fef8216208f 100644 --- a/forge-core/src/main/java/forge/item/IPaperCard.java +++ b/forge-core/src/main/java/forge/item/IPaperCard.java @@ -234,6 +234,7 @@ public interface IPaperCard extends InventoryItem, Serializable { String getEdition(); String getCollectorNumber(); String getFunctionalVariant(); + List getSpireColors(); int getArtIndex(); boolean isFoil(); boolean isToken(); diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index 02116812ec6..c2462b7bf12 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.io.ObjectInputStream; +import java.util.List; /** * A lightweight version of a card that matches real-world cards, to use outside of games (eg. inventory, decks, trade). @@ -55,6 +56,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, private final boolean foil; private Boolean hasImage; private final boolean noSell; + private List spireColors; private String sortableName; private final String functionalVariant; @@ -85,6 +87,11 @@ public class PaperCard implements Comparable, InventoryItemFromSet, return functionalVariant; } + @Override + public List getSpireColors() { + return spireColors; + } + @Override public int getArtIndex() { return artIndex; @@ -156,7 +163,10 @@ public class PaperCard implements Comparable, InventoryItemFromSet, this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, false); return sellable; } - + public PaperCard getSpireVersion(List colors) { + return new PaperCard(this.rules, this.edition, this.rarity, + this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, false, colors); + } @Override public String getItemType() { final Localizer localizer = Localizer.getInstance(); @@ -190,6 +200,12 @@ public class PaperCard implements Comparable, InventoryItemFromSet, public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, final int artIndex0, final boolean foil0, final String collectorNumber0, final String artist0, final String functionalVariant, final boolean noSell0) { + this(rules0, edition0, rarity0, artIndex0, foil0, collectorNumber0, artist0, functionalVariant, noSell0, null); + } + + public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, + final int artIndex0, final boolean foil0, final String collectorNumber0, + final String artist0, final String functionalVariant, final boolean noSell0, final List spires) { if (rules0 == null || edition0 == null || rarity0 == null) { throw new IllegalArgumentException("Cannot create card without rules, edition or rarity"); } @@ -206,6 +222,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, sortableName = TextUtil.toSortableName(CardTranslation.getTranslatedName(rules0.getName())); this.functionalVariant = functionalVariant != null ? functionalVariant : IPaperCard.NO_FUNCTIONAL_VARIANT; noSell = noSell0; + spireColors = spires; } public static PaperCard FAKE_CARD = new PaperCard(CardRules.getUnsupportedCardNamed("Fake Card"), "Fake Edition", CardRarity.Common); @@ -244,10 +261,11 @@ public class PaperCard implements Comparable, InventoryItemFromSet, public int hashCode() { final int code = (name.hashCode() * 11) + (edition.hashCode() * 59) + (artIndex * 2) + (getCollectorNumber().hashCode() * 383); + final int id = spireColors == null ? 0 : spireColors.hashCode(); if (foil) { - return code + 1; + return code + id + 1; } - return code; + return code + id; } // FIXME: Check diff --git a/forge-core/src/main/java/forge/item/PaperToken.java b/forge-core/src/main/java/forge/item/PaperToken.java index c13b0435880..1eea87d50e8 100644 --- a/forge-core/src/main/java/forge/item/PaperToken.java +++ b/forge-core/src/main/java/forge/item/PaperToken.java @@ -1,6 +1,7 @@ package forge.item; import java.util.ArrayList; +import java.util.List; import java.util.Locale; import forge.card.*; @@ -152,6 +153,11 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard { return IPaperCard.NO_FUNCTIONAL_VARIANT; } + @Override + public List getSpireColors() { + return null; + } + @Override public int getArtIndex() { return artIndex; diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 974f28f63c9..c8da2085d42 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -2230,13 +2230,19 @@ public class GameAction { // TODO: only do this for the AI, for the player part, get the encoded color from the deck file and pass // it to either player or the papercard object so it feels like rule based for the player side.. if (!c.hasChosenColorSpire()) { - List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); - String prompt = CardTranslation.getTranslatedName(c.getName()) + ": " + - Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(2)); - SpellAbility sa = new SpellAbility.EmptySa(ApiType.ChooseColor, c, takesAction); - sa.putParam("AILogic", "MostProminentInComputerDeck"); - List chosenColors = takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices); - c.setChosenColorSpire(chosenColors); + if (takesAction.isAI()) { + List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); + String prompt = CardTranslation.getTranslatedName(c.getName()) + ": " + + Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(2)); + SpellAbility sa = new SpellAbility.EmptySa(ApiType.ChooseColor, c, takesAction); + sa.putParam("AILogic", "MostProminentInComputerDeck"); + List chosenColors = takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices); + c.setChosenColorSpire(chosenColors); + } else { + if (c.getPaperCard().getSpireColors() != null) { + c.setChosenColorSpire(c.getPaperCard().getSpireColors()); + } + } } } takesAction = game.getNextPlayerAfter(takesAction); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java index 5d393c39783..50b209c4cfe 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java @@ -119,7 +119,7 @@ public class ManaEffect extends SpellAbilityEffect { } } - if (choiceString.toString().isEmpty() && "Combo ColorIdentity".equals(abMana.getOrigProduced())) { + if (choiceString.toString().isEmpty() && ("Combo ColorIdentity".equals(abMana.getOrigProduced()) || "Combo Spire".equals(abMana.getOrigProduced()))) { // No mana could be produced here (non-EDH match?), so cut short continue; } diff --git a/forge-gui-mobile/src/forge/deck/FDeckEditor.java b/forge-gui-mobile/src/forge/deck/FDeckEditor.java index 3a2abbc3234..388d27833e2 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckEditor.java +++ b/forge-gui-mobile/src/forge/deck/FDeckEditor.java @@ -12,6 +12,7 @@ import forge.Forge.KeyInputAdapter; import forge.Graphics; import forge.assets.*; import forge.card.CardEdition; +import forge.card.MagicColor; import forge.deck.io.DeckPreferences; import forge.gamemodes.limited.BoosterDraft; import forge.gamemodes.planarconquest.ConquestUtil; @@ -1841,6 +1842,19 @@ public class FDeckEditor extends TabPageScreen { } } addCommanderItems(menu, card); + if ("Cryptic Spires".equalsIgnoreCase(card.getCardName())) { + menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> { + //sort options so current option is on top and selected by default + List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); + GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { + @Override + public void run(List result) { + addCard(card.getSpireVersion(result)); + removeCard(card); + } + }); + })); + } break; case Sideboard: cardSourceSection = parentScreen.isLimitedEditor() ? parentScreen.getMainDeckPage() : parentScreen.getCatalogPage(); @@ -1880,6 +1894,19 @@ public class FDeckEditor extends TabPageScreen { } } addCommanderItems(menu, card); + if ("Cryptic Spires".equalsIgnoreCase(card.getCardName())) { + menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> { + //sort options so current option is on top and selected by default + List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); + GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { + @Override + public void run(List result) { + addCard(card.getSpireVersion(result)); + removeCard(card); + } + }); + })); + } break; case Commander: if (parentScreen.editorType != EditorType.PlanarConquest || isPartnerCommander(card)) { diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index 60097618cc1..5618dfe2e99 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -1029,6 +1029,8 @@ public class ImageView extends ItemView { private boolean selected, deckSelectMode, showRanking; private final float IMAGE_SIZE = CardRenderer.MANA_SYMBOL_SIZE; private DeckProxy deckProxy = null; + private StringBuffer spireColor = new StringBuffer(); + private TextRenderer textRenderer; private FImageComplex deckCover = null; private Texture dpImg = null; //private TextureRegion tr; @@ -1055,6 +1057,21 @@ public class ImageView extends ItemView { draftRankImage = FSkinImage.DRAFTRANK_C; } } + if (((PaperCard) item).getSpireColors() != null) { + for (String s : ((PaperCard) item).getSpireColors()) { + if ("white".equalsIgnoreCase(s)) + spireColor.append("{W}"); + if ("green".equalsIgnoreCase(s)) + spireColor.append("{G}"); + if ("red".equalsIgnoreCase(s)) + spireColor.append("{R}"); + if ("blue".equalsIgnoreCase(s)) + spireColor.append("{U}"); + if ("black".equalsIgnoreCase(s)) + spireColor.append("{B}"); + } + textRenderer = new TextRenderer(true); + } } } @@ -1136,6 +1153,11 @@ public class ImageView extends ItemView { } } } + // spire colors + if (!spireColor.isEmpty()) { + drawCardLabel(g,"", Color.GRAY, x, y, w, h); + textRenderer.drawText(g, spireColor.toString(), FSkinFont.forHeight(w / 7), Color.WHITE, x, y, w, h, y, h, false, Align.center, true); + } } else if (item instanceof ConquestCommander) { CardRenderer.drawCard(g, ((ConquestCommander) item).getCard(), x, y, w, h, pos); } else if (deckSelectMode) { From 31abd61a3f97595d3aebc5551a5d9b24151f1618 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 13 Nov 2024 11:10:27 +0800 Subject: [PATCH 04/16] fix render for ImageView --- forge-gui-mobile/src/forge/itemmanager/views/ImageView.java | 6 ++---- forge-gui/src/main/java/forge/itemmanager/ColumnDef.java | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index 5618dfe2e99..47f5ca39ed1 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -44,6 +44,7 @@ public class ImageView extends ItemView { private static final float PADDING = Utils.scale(5); private static final float PILE_SPACING_Y = 0.1f; private static final FSkinFont LABEL_FONT = FSkinFont.get(12); + private TextRenderer textRenderer = new TextRenderer(true); private static FSkinColor getGroupHeaderForeColor() { if (Forge.isMobileAdventureMode) @@ -1030,7 +1031,6 @@ public class ImageView extends ItemView { private final float IMAGE_SIZE = CardRenderer.MANA_SYMBOL_SIZE; private DeckProxy deckProxy = null; private StringBuffer spireColor = new StringBuffer(); - private TextRenderer textRenderer; private FImageComplex deckCover = null; private Texture dpImg = null; //private TextureRegion tr; @@ -1070,7 +1070,6 @@ public class ImageView extends ItemView { if ("black".equalsIgnoreCase(s)) spireColor.append("{B}"); } - textRenderer = new TextRenderer(true); } } } @@ -1155,8 +1154,7 @@ public class ImageView extends ItemView { } // spire colors if (!spireColor.isEmpty()) { - drawCardLabel(g,"", Color.GRAY, x, y, w, h); - textRenderer.drawText(g, spireColor.toString(), FSkinFont.forHeight(w / 7), Color.WHITE, x, y, w, h, y, h, false, Align.center, true); + textRenderer.drawText(g, spireColor.toString(), FSkinFont.forHeight(w / 5), Color.WHITE, x, y, w, h, y, h, false, Align.center, true); } } else if (item instanceof ConquestCommander) { CardRenderer.drawCard(g, ((ConquestCommander) item).getCard(), x, y, w, h, pos); diff --git a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java index 77e25d479b6..671c243d53e 100644 --- a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java +++ b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java @@ -57,8 +57,9 @@ public enum ColumnDef { NAME("lblName", "lblName", 180, false, SortState.ASC, from -> { if (from.getKey() instanceof PaperCard) { + String spire = ((PaperCard) from.getKey()).getSpireColors() == null ? "" : ((PaperCard) from.getKey()).getSpireColors().toString(); String sortableName = ((PaperCard)from.getKey()).getSortableName(); - return sortableName == null ? TextUtil.toSortableName(from.getKey().getName()) : sortableName; + return sortableName == null ? TextUtil.toSortableName(from.getKey().getName() + spire) : sortableName + spire; } return TextUtil.toSortableName(from.getKey().getName()); }, From 8fd521b949f3f67b19e68eb34908f1d7355cdbab Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 13 Nov 2024 13:43:47 +0800 Subject: [PATCH 05/16] update desktop editor --- .../main/java/forge/game/card/CardView.java | 3 +++ .../deckeditor/controllers/ACEditorBase.java | 20 +++++++++++++++++++ .../controllers/CEditorConstructed.java | 1 + .../match/controllers/CDetailPicture.java | 2 ++ .../forge/itemmanager/views/ImageView.java | 2 +- 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index 9325bbd2896..c7b741590db 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -436,6 +436,9 @@ public class CardView extends GameEntityView { public List getChosenColorSpire() { return get(TrackableProperty.ChosenColorSpire); } + public void updateChosenColorSpire(List chosen) { + set(TrackableProperty.ChosenColorSpire, chosen); + } void updateChosenColorSpire(Card c) { set(TrackableProperty.ChosenColorSpire, c.getChosenColorSpire()); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java index 6c5dbc3dc0d..49ce9bb32e4 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java @@ -30,6 +30,7 @@ import javax.swing.SwingUtilities; import com.google.common.collect.Iterables; +import forge.card.MagicColor; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckBase; @@ -65,6 +66,7 @@ import forge.toolbox.FLabel; import forge.toolbox.FSkin; import forge.util.Aggregates; import forge.util.ItemPool; +import forge.util.Lang; import forge.util.Localizer; import forge.view.FView; @@ -576,5 +578,23 @@ public abstract class ACEditorBase { + List colors = GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, MagicColor.Constant.ONLY_COLORS); + // make a foiled version based on the original + PaperCard updated = existingCard.getSpireVersion(colors); + // remove *quantity* instances of existing card + CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 1); + // add *quantity* into the deck and set them as selected + cardManager.addItem(updated, 1); + cardManager.setSelectedItem(updated); + }, true, true); + } } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java index be000243440..8d5c7080d04 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java @@ -375,6 +375,7 @@ public final class CEditorConstructed extends CDeckEditor { if (foilAvailable) { cmb.addMakeFoils(); } + cmb.addSetColorSpire(); } /* (non-Javadoc) diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java index a2619254602..46bebcab791 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java @@ -69,6 +69,8 @@ public class CDetailPicture { c.getCurrentState().setFoilIndexOverride(1); } } + if (paperCard.getSpireColors() != null && c.getChosenColorSpire() == null) + c.updateChosenColorSpire(paperCard.getSpireColors()); showCard(c, isDisplayAlt); } else { currentView = null; diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index 47f5ca39ed1..3d67741fc40 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -1154,7 +1154,7 @@ public class ImageView extends ItemView { } // spire colors if (!spireColor.isEmpty()) { - textRenderer.drawText(g, spireColor.toString(), FSkinFont.forHeight(w / 5), Color.WHITE, x, y, w, h, y, h, false, Align.center, true); + textRenderer.drawText(g, spireColor.toString(), FSkinFont.forHeight(w / 5), Color.WHITE, x, y + h / 4, w, h, y, h, false, Align.center, true); } } else if (item instanceof ConquestCommander) { CardRenderer.drawCard(g, ((ConquestCommander) item).getCard(), x, y, w, h, pos); From f814292de741b2a2eca1c2e4693024b67ef9bd9c Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 13 Nov 2024 13:45:09 +0800 Subject: [PATCH 06/16] update comment --- .../java/forge/screens/deckeditor/controllers/ACEditorBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java index 49ce9bb32e4..4069cb2f3a8 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java @@ -587,7 +587,7 @@ public abstract class ACEditorBase { List colors = GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, MagicColor.Constant.ONLY_COLORS); - // make a foiled version based on the original + // make an updated version PaperCard updated = existingCard.getSpireVersion(colors); // remove *quantity* instances of existing card CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 1); From f7dfdea36142ea86a6d7cd76619d21c464b8dd6e Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 13 Nov 2024 14:13:16 +0800 Subject: [PATCH 07/16] update clone and copy effect --- .../src/main/java/forge/game/ability/effects/CloneEffect.java | 2 ++ .../java/forge/game/ability/effects/CopyPermanentEffect.java | 2 ++ forge-game/src/main/java/forge/game/card/Card.java | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java index 7b5750284d5..9a7a17f216e 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java @@ -199,6 +199,8 @@ public class CloneEffect extends SpellAbilityEffect { if (sa.hasParam("RememberCloneOrigin")) { tgtCard.addRemembered(cardToCopy); } + // spire + tgtCard.setChosenColorSpire(cardToCopy.getChosenColorSpire()); game.fireEvent(new GameEventCardStatsChanged(tgtCard)); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java index 08ac7418f67..93c138e9a28 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java @@ -318,6 +318,8 @@ public class CopyPermanentEffect extends TokenEffectBase { copy.setState(copy.getCurrentStateName(), true, true); } } + // spire + copy.setChosenColorSpire(original.getChosenColorSpire()); copy.setTokenSpawningAbility(sa); copy.setGamePieceType(GamePieceType.TOKEN); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 7350fe5adcd..4be24e98ae8 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -2119,7 +2119,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr public boolean hasChosenColor(String s) { return chosenColors != null && chosenColors.contains(s); } - public final Iterable getChosenColorSpire() { + public final List getChosenColorSpire() { if (chosenColorSpire == null) { return Lists.newArrayList(); } From 4012469910be0fbbe1a9586f8e76018146f33c2a Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 13 Nov 2024 19:12:34 +0800 Subject: [PATCH 08/16] refactor var name --- .../src/main/java/forge/game/GameAction.java | 8 ++------ .../game/ability/effects/CloneEffect.java | 2 +- .../ability/effects/CopyPermanentEffect.java | 2 +- .../src/main/java/forge/game/card/Card.java | 18 ++++++++++-------- .../main/java/forge/game/card/CardView.java | 11 ++++------- .../game/spellability/AbilityManaPart.java | 8 ++++---- .../forge/trackable/TrackableProperty.java | 2 +- .../match/controllers/CDetailPicture.java | 2 -- .../src/forge/itemmanager/views/ImageView.java | 16 ++++++++-------- forge-gui/res/cardsfolder/c/cryptic_spires.txt | 2 +- .../java/forge/gui/card/CardDetailUtil.java | 4 ++-- 11 files changed, 34 insertions(+), 41 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index c8da2085d42..acab924969a 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -573,7 +573,7 @@ public class GameAction { } if (c.hasChosenColorSpire()) { - copied.setChosenColorSpire(ImmutableList.copyOf(c.getChosenColorSpire())); + copied.setChosenColorID(ImmutableList.copyOf(c.getChosenColorID())); } // update state for view @@ -2237,11 +2237,7 @@ public class GameAction { SpellAbility sa = new SpellAbility.EmptySa(ApiType.ChooseColor, c, takesAction); sa.putParam("AILogic", "MostProminentInComputerDeck"); List chosenColors = takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices); - c.setChosenColorSpire(chosenColors); - } else { - if (c.getPaperCard().getSpireColors() != null) { - c.setChosenColorSpire(c.getPaperCard().getSpireColors()); - } + c.setChosenColorID(chosenColors); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java index 9a7a17f216e..170c07fcfee 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java @@ -200,7 +200,7 @@ public class CloneEffect extends SpellAbilityEffect { tgtCard.addRemembered(cardToCopy); } // spire - tgtCard.setChosenColorSpire(cardToCopy.getChosenColorSpire()); + tgtCard.setChosenColorID(cardToCopy.getChosenColorID()); game.fireEvent(new GameEventCardStatsChanged(tgtCard)); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java index 93c138e9a28..17ee13acdb4 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java @@ -319,7 +319,7 @@ public class CopyPermanentEffect extends TokenEffectBase { } } // spire - copy.setChosenColorSpire(original.getChosenColorSpire()); + copy.setChosenColorID(original.getChosenColorID()); copy.setTokenSpawningAbility(sa); copy.setGamePieceType(GamePieceType.TOKEN); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 4be24e98ae8..c7f74613245 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -293,7 +293,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr private String chosenType2 = ""; private List notedTypes = new ArrayList<>(); private List chosenColors; - private List chosenColorSpire; + private List chosenColorID; private List chosenName = new ArrayList<>(); private Integer chosenNumber; private Player chosenPlayer; @@ -400,6 +400,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr view.updateSickness(this); view.updateClassLevel(this); view.updateDraftAction(this); + if (paperCard != null) + setChosenColorID(paperCard.getSpireColors()); } public boolean changeToState(final CardStateName state) { @@ -2119,18 +2121,18 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr public boolean hasChosenColor(String s) { return chosenColors != null && chosenColors.contains(s); } - public final List getChosenColorSpire() { - if (chosenColorSpire == null) { + public final List getChosenColorID() { + if (chosenColorID == null) { return Lists.newArrayList(); } - return chosenColorSpire; + return chosenColorID; } - public final void setChosenColorSpire(final List s) { - chosenColorSpire = s; - view.updateChosenColorSpire(this); + public final void setChosenColorID(final List s) { + chosenColorID = s; + view.updateChosenColorID(this); } public boolean hasChosenColorSpire() { - return chosenColorSpire != null && !chosenColorSpire.isEmpty(); + return chosenColorID != null && !chosenColorID.isEmpty(); } public final Card getChosenCard() { return getChosenCards().getFirst(); diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index c7b741590db..8553614719d 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -433,14 +433,11 @@ public class CardView extends GameEntityView { void updateChosenColors(Card c) { set(TrackableProperty.ChosenColors, c.getChosenColors()); } - public List getChosenColorSpire() { - return get(TrackableProperty.ChosenColorSpire); + public List getChosenColorID() { + return get(TrackableProperty.ChosenColorID); } - public void updateChosenColorSpire(List chosen) { - set(TrackableProperty.ChosenColorSpire, chosen); - } - void updateChosenColorSpire(Card c) { - set(TrackableProperty.ChosenColorSpire, c.getChosenColorSpire()); + void updateChosenColorID(Card c) { + set(TrackableProperty.ChosenColorID, c.getChosenColorID()); } public FCollectionView getMergedCardsCollection() { return get(TrackableProperty.MergedCardsCollection); diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java index 5c357ad9721..742a5dc318d 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -655,8 +655,8 @@ public class AbilityManaPart implements java.io.Serializable { origProduced = origProduced.replace("Chosen", getChosenColor(sa)); } // replace Chosen for Spire colors - if (origProduced.contains("Spire")) { - origProduced = origProduced.replace("Spire", getChosenSpireColor(sa)); + if (origProduced.contains("ColorID")) { + origProduced = origProduced.replace("ColorID", getChosenColorID(sa)); } if (origProduced.contains("NotedColors")) { // Should only be used for Paliano, the High City @@ -701,14 +701,14 @@ public class AbilityManaPart implements java.io.Serializable { return sb.length() == 0 ? "" : sb.substring(0, sb.length() - 1); } - public String getChosenSpireColor(SpellAbility sa) { + public String getChosenColorID(SpellAbility sa) { if (sa == null) { return ""; } Card card = sa.getHostCard(); if (card != null && card.hasChosenColorSpire()) { StringBuilder values = new StringBuilder(); - for (String s : card.getChosenColorSpire()) { + for (String s : card.getChosenColorID()) { values.append(MagicColor.toShortString(MagicColor.fromName(s))).append(" "); } return values.toString(); diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index 638c8694c94..a02db4eee41 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -67,7 +67,7 @@ public enum TrackableProperty { ChosenType2(TrackableTypes.StringType), NotedTypes(TrackableTypes.StringListType), ChosenColors(TrackableTypes.StringListType), - ChosenColorSpire(TrackableTypes.StringListType), + ChosenColorID(TrackableTypes.StringListType), ChosenCards(TrackableTypes.CardViewCollectionType), ChosenNumber(TrackableTypes.StringType), StoredRolls(TrackableTypes.StringListType), diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java index 46bebcab791..a2619254602 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java @@ -69,8 +69,6 @@ public class CDetailPicture { c.getCurrentState().setFoilIndexOverride(1); } } - if (paperCard.getSpireColors() != null && c.getChosenColorSpire() == null) - c.updateChosenColorSpire(paperCard.getSpireColors()); showCard(c, isDisplayAlt); } else { currentView = null; diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index 3d67741fc40..5f7d82c48b4 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -1030,7 +1030,7 @@ public class ImageView extends ItemView { private boolean selected, deckSelectMode, showRanking; private final float IMAGE_SIZE = CardRenderer.MANA_SYMBOL_SIZE; private DeckProxy deckProxy = null; - private StringBuffer spireColor = new StringBuffer(); + private StringBuffer colorID = new StringBuffer(); private FImageComplex deckCover = null; private Texture dpImg = null; //private TextureRegion tr; @@ -1060,15 +1060,15 @@ public class ImageView extends ItemView { if (((PaperCard) item).getSpireColors() != null) { for (String s : ((PaperCard) item).getSpireColors()) { if ("white".equalsIgnoreCase(s)) - spireColor.append("{W}"); + colorID.append("{W}"); if ("green".equalsIgnoreCase(s)) - spireColor.append("{G}"); + colorID.append("{G}"); if ("red".equalsIgnoreCase(s)) - spireColor.append("{R}"); + colorID.append("{R}"); if ("blue".equalsIgnoreCase(s)) - spireColor.append("{U}"); + colorID.append("{U}"); if ("black".equalsIgnoreCase(s)) - spireColor.append("{B}"); + colorID.append("{B}"); } } } @@ -1153,8 +1153,8 @@ public class ImageView extends ItemView { } } // spire colors - if (!spireColor.isEmpty()) { - textRenderer.drawText(g, spireColor.toString(), FSkinFont.forHeight(w / 5), Color.WHITE, x, y + h / 4, w, h, y, h, false, Align.center, true); + if (!colorID.isEmpty()) { + textRenderer.drawText(g, colorID.toString(), FSkinFont.forHeight(w / 5), Color.WHITE, x, y + h / 4, w, h, y, h, false, Align.center, true); } } else if (item instanceof ConquestCommander) { CardRenderer.drawCard(g, ((ConquestCommander) item).getCard(), x, y, w, h, pos); diff --git a/forge-gui/res/cardsfolder/c/cryptic_spires.txt b/forge-gui/res/cardsfolder/c/cryptic_spires.txt index 2f7aafde128..aff3fb69fe0 100644 --- a/forge-gui/res/cardsfolder/c/cryptic_spires.txt +++ b/forge-gui/res/cardsfolder/c/cryptic_spires.txt @@ -4,5 +4,5 @@ Types:Land Text:As you create your deck, circle two of the colors below. R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True -A:AB$ Mana | Cost$ T | Produced$ Combo Spire | SpellDescription$ Add one mana of either of the circled colors. +A:AB$ Mana | Cost$ T | Produced$ Combo ColorID | SpellDescription$ Add one mana of either of the circled colors. Oracle:As you create your deck, circle two of the colors below.\nCryptic Spires enters tapped.\n{T}: Add one mana of either of the circled colors. diff --git a/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java b/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java index 87ec9d6fb70..76cc1c0dcdc 100644 --- a/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java +++ b/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java @@ -488,12 +488,12 @@ public class CardDetailUtil { } // chosen spire - if (card.getChosenColorSpire() != null && !card.getChosenColorSpire().isEmpty()) { + if (card.getChosenColorID() != null && !card.getChosenColorID().isEmpty()) { if (area.length() != 0) { area.append("\n"); } area.append("(").append(Localizer.getInstance().getMessage("lblSelected")).append(": "); - area.append(Lang.joinHomogenous(card.getChosenColorSpire().stream().map(DeckRecognizer::getLocalisedMagicColorName).collect(Collectors.toList()))); + area.append(Lang.joinHomogenous(card.getChosenColorID().stream().map(DeckRecognizer::getLocalisedMagicColorName).collect(Collectors.toList()))); area.append(")"); } From 88613c555a278345862a1f8aa1b30befbd0d94c3 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 13 Nov 2024 22:13:18 +0800 Subject: [PATCH 09/16] refactor some vars, and save to deck file todo validate --- .../src/main/java/forge/card/CardDb.java | 43 ++++++++++++++++++- .../main/java/forge/card/ICardDatabase.java | 1 + .../src/main/java/forge/deck/CardPool.java | 12 +++--- forge-core/src/main/java/forge/deck/Deck.java | 2 +- .../src/main/java/forge/item/IPaperCard.java | 2 +- .../src/main/java/forge/item/PaperCard.java | 10 ++--- .../src/main/java/forge/item/PaperToken.java | 2 +- .../src/main/java/forge/game/card/Card.java | 2 +- .../src/forge/deck/FDeckEditor.java | 4 +- .../forge/itemmanager/views/ImageView.java | 4 +- .../java/forge/itemmanager/ColumnDef.java | 2 +- 11 files changed, 62 insertions(+), 22 deletions(-) diff --git a/forge-core/src/main/java/forge/card/CardDb.java b/forge-core/src/main/java/forge/card/CardDb.java index ae928fee725..8672ef475e2 100644 --- a/forge-core/src/main/java/forge/card/CardDb.java +++ b/forge-core/src/main/java/forge/card/CardDb.java @@ -42,6 +42,7 @@ import java.util.stream.Collectors; public final class CardDb implements ICardDatabase, IDeckGenPool { public final static String foilSuffix = "+"; public final static char NameSetSeparator = '|'; + public final static String colorIDPrefix = "#"; private final String exlcudedCardName = "Concentrate"; private final String exlcudedCardSet = "DS0"; @@ -90,13 +91,19 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { public int artIndex; public boolean isFoil; public String collectorNumber; + public List colorID; private CardRequest(String name, String edition, int artIndex, boolean isFoil, String collectorNumber) { + this(name, edition, artIndex, isFoil, collectorNumber, null); + } + + private CardRequest(String name, String edition, int artIndex, boolean isFoil, String collectorNumber, List colorID) { cardName = name; this.edition = edition; this.artIndex = artIndex; this.isFoil = isFoil; this.collectorNumber = collectorNumber; + this.colorID = colorID; } public static boolean isFoilCardName(final String cardName){ @@ -125,6 +132,14 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { return requestInfo + NameSetSeparator + artIndex; } + public static String compose(String cardName, String setCode, int artIndex, List colorID) { + String requestInfo = compose(cardName, setCode); + artIndex = Math.max(artIndex, IPaperCard.DEFAULT_ART_INDEX); + String cid = colorID == null ? "" : NameSetSeparator + + colorID.toString().replace("[", colorIDPrefix).replace(", ", colorIDPrefix).replace("]", ""); + return requestInfo + NameSetSeparator + artIndex + cid; + } + public static String compose(String cardName, String setCode, String collectorNumber) { String requestInfo = compose(cardName, setCode); // CollectorNumber will be wrapped in square brackets @@ -154,6 +169,10 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { return s.startsWith("[") && s.endsWith("]"); } + private static boolean isColorIDString(String s) { + return s.startsWith(colorIDPrefix); + } + private static boolean isArtIndex(String s) { return StringUtils.isNumeric(s) && s.length() <= 2 ; // only artIndex between 1-99 } @@ -171,7 +190,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { String cardName = info[0]; String setCode = info[1]; int artIndex = Integer.parseInt(info[2]); - return new CardRequest(cardName, setCode, artIndex, isFoil, IPaperCard.NO_COLLECTOR_NUMBER); + return new CardRequest(cardName, setCode, artIndex, isFoil, IPaperCard.NO_COLLECTOR_NUMBER, null); } catch (NumberFormatException ex){ return null; } } @@ -183,22 +202,29 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { int setPos; int artPos; int cNrPos; + int clrPos; if (info.length >= 4) { // name|set|artIndex|[collNr] setPos = isSetCode(info[1]) ? 1 : -1; artPos = isArtIndex(info[2]) ? 2 : -1; cNrPos = isCollectorNumber(info[3]) ? 3 : -1; + int pos = cNrPos > 0 ? 4 : 3; + clrPos = isColorIDString(info[pos]) ? pos : -1; } else if (info.length == 3) { // name|set|artIndex (or CollNr) setPos = isSetCode(info[1]) ? 1 : -1; artPos = isArtIndex(info[2]) ? 2 : -1; cNrPos = isCollectorNumber(info[2]) ? 2 : -1; + int pos = cNrPos > 0 ? 3 : 2; + clrPos = isColorIDString(info[pos]) ? pos : -1; } else if (info.length == 2) { // name|set (or artIndex, even if not possible via compose) setPos = isSetCode(info[1]) ? 1 : -1; artPos = isArtIndex(info[1]) ? 1 : -1; cNrPos = -1; + clrPos = -1; } else { setPos = -1; artPos = -1; cNrPos = -1; + clrPos = -1; } String cardName = info[0]; boolean isFoil = false; @@ -209,6 +235,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { int artIndex = artPos > 0 ? Integer.parseInt(info[artPos]) : IPaperCard.NO_ART_INDEX; // default: no art index String collectorNumber = cNrPos > 0 ? info[cNrPos].substring(1, info[cNrPos].length() - 1) : IPaperCard.NO_COLLECTOR_NUMBER; String setCode = setPos > 0 ? info[setPos] : null; + List colorID = clrPos > 0 ? Arrays.stream(info[clrPos].substring(1).split(colorIDPrefix)).collect(Collectors.toList()) : null; if (setCode != null && setCode.equals(CardEdition.UNKNOWN.getCode())) { // ??? setCode = null; } @@ -224,7 +251,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { // finally, check whether any between artIndex and CollectorNumber has been set if (collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER) && artIndex == IPaperCard.NO_ART_INDEX) artIndex = IPaperCard.DEFAULT_ART_INDEX; - return new CardRequest(cardName, setCode, artIndex, isFoil, collectorNumber); + return new CardRequest(cardName, setCode, artIndex, isFoil, collectorNumber, colorID); } } @@ -569,6 +596,13 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { return tryGetCard(request); } + @Override + public PaperCard getCard(final String cardName, String setCode, int artIndex, List colorID) { + String reqInfo = CardRequest.compose(cardName, setCode, artIndex, colorID); + CardRequest request = CardRequest.fromString(reqInfo); + return tryGetCard(request); + } + private PaperCard tryGetCard(CardRequest request) { // Before doing anything, check that a non-null request has been provided if (request == null) @@ -1128,6 +1162,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { if (artCount >= IPaperCard.DEFAULT_ART_INDEX) { sb.append(CardDb.NameSetSeparator).append(card.getArtIndex()); // indexes start at 1 to match image file name conventions } + if (card.getColorID() != null) { + sb.append(CardDb.NameSetSeparator); + for (String color : card.getColorID()) + sb.append(CardDb.colorIDPrefix).append(color); + } } return sb; diff --git a/forge-core/src/main/java/forge/card/ICardDatabase.java b/forge-core/src/main/java/forge/card/ICardDatabase.java index 4618e78f83f..b5984abb741 100644 --- a/forge-core/src/main/java/forge/card/ICardDatabase.java +++ b/forge-core/src/main/java/forge/card/ICardDatabase.java @@ -50,6 +50,7 @@ public interface ICardDatabase extends Iterable { // [NEW Methods] Including the card CollectorNumber as criterion for DB lookup PaperCard getCard(String cardName, String edition, String collectorNumber); PaperCard getCard(String cardName, String edition, int artIndex, String collectorNumber); + PaperCard getCard(String cardName, String edition, int artIndex, List colorID); // 2. Card Lookup from a single Expansion Set PaperCard getCardFromSet(String cardName, CardEdition edition, boolean isFoil); // NOT yet used, included for API symmetry diff --git a/forge-core/src/main/java/forge/deck/CardPool.java b/forge-core/src/main/java/forge/deck/CardPool.java index 0846ae7ed49..6696253b2b5 100644 --- a/forge-core/src/main/java/forge/deck/CardPool.java +++ b/forge-core/src/main/java/forge/deck/CardPool.java @@ -53,7 +53,7 @@ public class CardPool extends ItemPool { public void add(final String cardRequest, final int amount) { CardDb.CardRequest request = CardDb.CardRequest.fromString(cardRequest); - this.add(CardDb.CardRequest.compose(request.cardName, request.isFoil), request.edition, request.artIndex, amount); + this.add(CardDb.CardRequest.compose(request.cardName, request.isFoil), request.edition, request.artIndex, amount, false, request.colorID); } public void add(final String cardName, final String setCode) { @@ -65,14 +65,14 @@ public class CardPool extends ItemPool { } public void add(final String cardName, final String setCode, final int amount, boolean addAny) { - this.add(cardName, setCode, IPaperCard.NO_ART_INDEX, amount, addAny); + this.add(cardName, setCode, IPaperCard.NO_ART_INDEX, amount, addAny, null); } // NOTE: ART indices are "1" -based public void add(String cardName, String setCode, int artIndex, final int amount) { - this.add(cardName, setCode, artIndex, amount, false); + this.add(cardName, setCode, artIndex, amount, false, null); } - public void add(String cardName, String setCode, int artIndex, final int amount, boolean addAny) { + public void add(String cardName, String setCode, int artIndex, final int amount, boolean addAny, List colorID) { Map dbs = StaticData.instance().getAvailableDatabases(); PaperCard paperCard = null; String selectedDbName = ""; @@ -82,7 +82,7 @@ public class CardPool extends ItemPool { for (Map.Entry entry: dbs.entrySet()){ String dbName = entry.getKey(); CardDb db = entry.getValue(); - paperCard = db.getCard(cardName, setCode, artIndex); + paperCard = db.getCard(cardName, setCode, artIndex, colorID); if (paperCard != null) { selectedDbName = dbName; break; @@ -124,7 +124,7 @@ public class CardPool extends ItemPool { int cnt = artGroups[i - 1]; if (cnt <= 0) continue; - PaperCard randomCard = cardDb.getCard(cardName, setCode, i); + PaperCard randomCard = cardDb.getCard(cardName, setCode, i, colorID); this.add(randomCard, cnt); } } diff --git a/forge-core/src/main/java/forge/deck/Deck.java b/forge-core/src/main/java/forge/deck/Deck.java index 8cbbcbcc3b9..974bd4592d1 100644 --- a/forge-core/src/main/java/forge/deck/Deck.java +++ b/forge-core/src/main/java/forge/deck/Deck.java @@ -337,7 +337,7 @@ public class Deck extends DeckBase implements Iterable originalRequest : originalCardRequests){ String cardRequest = originalRequest.getLeft(); diff --git a/forge-core/src/main/java/forge/item/IPaperCard.java b/forge-core/src/main/java/forge/item/IPaperCard.java index fef8216208f..b9694e083d2 100644 --- a/forge-core/src/main/java/forge/item/IPaperCard.java +++ b/forge-core/src/main/java/forge/item/IPaperCard.java @@ -234,7 +234,7 @@ public interface IPaperCard extends InventoryItem, Serializable { String getEdition(); String getCollectorNumber(); String getFunctionalVariant(); - List getSpireColors(); + List getColorID(); int getArtIndex(); boolean isFoil(); boolean isToken(); diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index c2462b7bf12..2da629bdc02 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -56,7 +56,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, private final boolean foil; private Boolean hasImage; private final boolean noSell; - private List spireColors; + private List colorID; private String sortableName; private final String functionalVariant; @@ -88,8 +88,8 @@ public class PaperCard implements Comparable, InventoryItemFromSet, } @Override - public List getSpireColors() { - return spireColors; + public List getColorID() { + return colorID; } @Override @@ -222,7 +222,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, sortableName = TextUtil.toSortableName(CardTranslation.getTranslatedName(rules0.getName())); this.functionalVariant = functionalVariant != null ? functionalVariant : IPaperCard.NO_FUNCTIONAL_VARIANT; noSell = noSell0; - spireColors = spires; + colorID = spires; } public static PaperCard FAKE_CARD = new PaperCard(CardRules.getUnsupportedCardNamed("Fake Card"), "Fake Edition", CardRarity.Common); @@ -261,7 +261,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, public int hashCode() { final int code = (name.hashCode() * 11) + (edition.hashCode() * 59) + (artIndex * 2) + (getCollectorNumber().hashCode() * 383); - final int id = spireColors == null ? 0 : spireColors.hashCode(); + final int id = colorID == null ? 0 : colorID.hashCode(); if (foil) { return code + id + 1; } diff --git a/forge-core/src/main/java/forge/item/PaperToken.java b/forge-core/src/main/java/forge/item/PaperToken.java index 1eea87d50e8..b4a2411897e 100644 --- a/forge-core/src/main/java/forge/item/PaperToken.java +++ b/forge-core/src/main/java/forge/item/PaperToken.java @@ -154,7 +154,7 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard { } @Override - public List getSpireColors() { + public List getColorID() { return null; } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index c7f74613245..45616ce4850 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -401,7 +401,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr view.updateClassLevel(this); view.updateDraftAction(this); if (paperCard != null) - setChosenColorID(paperCard.getSpireColors()); + setChosenColorID(paperCard.getColorID()); } public boolean changeToState(final CardStateName state) { diff --git a/forge-gui-mobile/src/forge/deck/FDeckEditor.java b/forge-gui-mobile/src/forge/deck/FDeckEditor.java index 388d27833e2..020c706925a 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckEditor.java +++ b/forge-gui-mobile/src/forge/deck/FDeckEditor.java @@ -1846,7 +1846,7 @@ public class FDeckEditor extends TabPageScreen { menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> { //sort options so current option is on top and selected by default List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); - GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { + GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { @Override public void run(List result) { addCard(card.getSpireVersion(result)); @@ -1898,7 +1898,7 @@ public class FDeckEditor extends TabPageScreen { menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> { //sort options so current option is on top and selected by default List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); - GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { + GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { @Override public void run(List result) { addCard(card.getSpireVersion(result)); diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index 5f7d82c48b4..1c6d0d26b2d 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -1057,8 +1057,8 @@ public class ImageView extends ItemView { draftRankImage = FSkinImage.DRAFTRANK_C; } } - if (((PaperCard) item).getSpireColors() != null) { - for (String s : ((PaperCard) item).getSpireColors()) { + if (((PaperCard) item).getColorID() != null) { + for (String s : ((PaperCard) item).getColorID()) { if ("white".equalsIgnoreCase(s)) colorID.append("{W}"); if ("green".equalsIgnoreCase(s)) diff --git a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java index 671c243d53e..2f910ef7ecc 100644 --- a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java +++ b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java @@ -57,7 +57,7 @@ public enum ColumnDef { NAME("lblName", "lblName", 180, false, SortState.ASC, from -> { if (from.getKey() instanceof PaperCard) { - String spire = ((PaperCard) from.getKey()).getSpireColors() == null ? "" : ((PaperCard) from.getKey()).getSpireColors().toString(); + String spire = ((PaperCard) from.getKey()).getColorID() == null ? "" : ((PaperCard) from.getKey()).getColorID().toString(); String sortableName = ((PaperCard)from.getKey()).getSortableName(); return sortableName == null ? TextUtil.toSortableName(from.getKey().getName() + spire) : sortableName + spire; } From 85913a3d6c89c4ffd76c939d06522663a8162b29 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 13 Nov 2024 23:42:08 +0800 Subject: [PATCH 10/16] load from deck --- .../src/main/java/forge/card/CardDb.java | 33 ++++++++++++++----- .../main/java/forge/card/ICardDatabase.java | 2 ++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/forge-core/src/main/java/forge/card/CardDb.java b/forge-core/src/main/java/forge/card/CardDb.java index 8672ef475e2..e9e1e1890c3 100644 --- a/forge-core/src/main/java/forge/card/CardDb.java +++ b/forge-core/src/main/java/forge/card/CardDb.java @@ -207,14 +207,14 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { setPos = isSetCode(info[1]) ? 1 : -1; artPos = isArtIndex(info[2]) ? 2 : -1; cNrPos = isCollectorNumber(info[3]) ? 3 : -1; - int pos = cNrPos > 0 ? 4 : 3; - clrPos = isColorIDString(info[pos]) ? pos : -1; + int pos = cNrPos > 0 ? -1 : 3; + clrPos = pos > 0 ? isColorIDString(info[pos]) ? pos : -1 : -1; } else if (info.length == 3) { // name|set|artIndex (or CollNr) setPos = isSetCode(info[1]) ? 1 : -1; artPos = isArtIndex(info[2]) ? 2 : -1; cNrPos = isCollectorNumber(info[2]) ? 2 : -1; - int pos = cNrPos > 0 ? 3 : 2; - clrPos = isColorIDString(info[pos]) ? pos : -1; + int pos = cNrPos > 0 ? -1 : 2; + clrPos = pos > 0 ? isColorIDString(info[pos]) ? pos : -1 : -1; } else if (info.length == 2) { // name|set (or artIndex, even if not possible via compose) setPos = isSetCode(info[1]) ? 1 : -1; artPos = isArtIndex(info[1]) ? 1 : -1; @@ -614,8 +614,9 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { // MOST of the extensions have two short codes, 141 out of 221 (so far) // ALSO: Set Code are always UpperCase CardEdition edition = editions.get(reqEditionCode.toUpperCase()); + return this.getCardFromSet(request.cardName, edition, request.artIndex, - request.collectorNumber, request.isFoil); + request.collectorNumber, request.isFoil, request.colorID); } // 2. Card lookup in edition with specified filter didn't work. @@ -657,8 +658,12 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } @Override - public PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, - String collectorNumber, boolean isFoil) { + public PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil) { + return getCardFromSet(cardName, edition, artIndex, collectorNumber, isFoil, null); + } + + @Override + public PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil, List colorID) { if (edition == null || cardName == null) // preview cards return null; // No cards will be returned @@ -692,7 +697,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { while (!candidate.hasImage() && candidatesIterator.hasNext()) candidate = candidatesIterator.next(); candidate = candidate.hasImage() ? candidate : firstCandidate; - return isFoil ? candidate.getFoiled() : candidate; + return isFoil ? candidate.getFoiled().getSpireVersion(colorID) : candidate.getSpireVersion(colorID); } /* @@ -735,6 +740,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex, filter); } + @Override + public PaperCard getCardFromEditions(final String cardInfo, final CardArtPreference artPreference, int artIndex, List colorID) { + return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex, null, false, null, colorID); + } + /* * =============================================== * 4. SPECIALISED CARD LOOKUP BASED ON @@ -809,6 +819,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { private PaperCard tryToGetCardFromEditions(String cardInfo, CardArtPreference artPreference, int artIndex, Date releaseDate, boolean releasedBeforeFlag, Predicate filter){ + return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex, releaseDate, releasedBeforeFlag, filter, null); + } + + private PaperCard tryToGetCardFromEditions(String cardInfo, CardArtPreference artPreference, int artIndex, + Date releaseDate, boolean releasedBeforeFlag, Predicate filter, List colorID){ if (cardInfo == null) return null; final CardRequest cr = CardRequest.fromString(cardInfo); @@ -889,7 +904,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } candidate = candidate.hasImage() ? candidate : firstCandidate; //If any, we're sure that at least one candidate is always returned despite it having any image - return cr.isFoil ? candidate.getFoiled() : candidate; + return cr.isFoil ? candidate.getFoiled().getSpireVersion(colorID) : candidate.getSpireVersion(colorID); } @Override diff --git a/forge-core/src/main/java/forge/card/ICardDatabase.java b/forge-core/src/main/java/forge/card/ICardDatabase.java index b5984abb741..a8165dff000 100644 --- a/forge-core/src/main/java/forge/card/ICardDatabase.java +++ b/forge-core/src/main/java/forge/card/ICardDatabase.java @@ -57,12 +57,14 @@ public interface ICardDatabase extends Iterable { PaperCard getCardFromSet(String cardName, CardEdition edition, String collectorNumber, boolean isFoil); PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, boolean isFoil); PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil); + PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil, List colorID); // 3. Card lookup based on CardArtPreference Selection Policy PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference); PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, Predicate filter); PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex); PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex, Predicate filter); + PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex, List colorID); // 4. Specialised Card Lookup on CardArtPreference Selection and Release Date PaperCard getCardFromEditionsReleasedBefore(String cardName, CardArtPreference artPreference, Date releaseDate); From 71ecf91bb5a74d27df41b7716b7f2daa19e00c58 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 14 Nov 2024 06:00:02 +0800 Subject: [PATCH 11/16] from list to set --- .../src/main/java/forge/card/CardDb.java | 19 ++++++++++--------- .../main/java/forge/card/ICardDatabase.java | 7 ++++--- .../src/main/java/forge/deck/CardPool.java | 2 +- .../src/main/java/forge/item/IPaperCard.java | 2 +- .../src/main/java/forge/item/PaperCard.java | 17 +++++++++++------ .../src/main/java/forge/item/PaperToken.java | 3 ++- .../src/main/java/forge/game/GameAction.java | 4 ++-- .../src/main/java/forge/game/card/Card.java | 8 ++++---- .../main/java/forge/game/card/CardView.java | 2 +- .../forge/trackable/TrackableProperty.java | 2 +- .../deckeditor/controllers/ACEditorBase.java | 5 ++++- .../src/forge/deck/FDeckEditor.java | 8 ++++---- 12 files changed, 45 insertions(+), 34 deletions(-) diff --git a/forge-core/src/main/java/forge/card/CardDb.java b/forge-core/src/main/java/forge/card/CardDb.java index e9e1e1890c3..4dcd013be60 100644 --- a/forge-core/src/main/java/forge/card/CardDb.java +++ b/forge-core/src/main/java/forge/card/CardDb.java @@ -28,6 +28,7 @@ import forge.deck.generation.IDeckGenPool; import forge.item.IPaperCard; import forge.item.PaperCard; import forge.util.CollectionSuppliers; +import forge.util.CollectionUtil; import forge.util.Lang; import forge.util.TextUtil; import forge.util.lang.LangEnglish; @@ -91,13 +92,13 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { public int artIndex; public boolean isFoil; public String collectorNumber; - public List colorID; + public Set colorID; private CardRequest(String name, String edition, int artIndex, boolean isFoil, String collectorNumber) { this(name, edition, artIndex, isFoil, collectorNumber, null); } - private CardRequest(String name, String edition, int artIndex, boolean isFoil, String collectorNumber, List colorID) { + private CardRequest(String name, String edition, int artIndex, boolean isFoil, String collectorNumber, Set colorID) { cardName = name; this.edition = edition; this.artIndex = artIndex; @@ -132,7 +133,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { return requestInfo + NameSetSeparator + artIndex; } - public static String compose(String cardName, String setCode, int artIndex, List colorID) { + public static String compose(String cardName, String setCode, int artIndex, Set colorID) { String requestInfo = compose(cardName, setCode); artIndex = Math.max(artIndex, IPaperCard.DEFAULT_ART_INDEX); String cid = colorID == null ? "" : NameSetSeparator + @@ -235,7 +236,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { int artIndex = artPos > 0 ? Integer.parseInt(info[artPos]) : IPaperCard.NO_ART_INDEX; // default: no art index String collectorNumber = cNrPos > 0 ? info[cNrPos].substring(1, info[cNrPos].length() - 1) : IPaperCard.NO_COLLECTOR_NUMBER; String setCode = setPos > 0 ? info[setPos] : null; - List colorID = clrPos > 0 ? Arrays.stream(info[clrPos].substring(1).split(colorIDPrefix)).collect(Collectors.toList()) : null; + Set colorID = clrPos > 0 ? Arrays.stream(info[clrPos].substring(1).split(colorIDPrefix)).collect(Collectors.toSet()) : null; if (setCode != null && setCode.equals(CardEdition.UNKNOWN.getCode())) { // ??? setCode = null; } @@ -597,7 +598,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } @Override - public PaperCard getCard(final String cardName, String setCode, int artIndex, List colorID) { + public PaperCard getCard(final String cardName, String setCode, int artIndex, Set colorID) { String reqInfo = CardRequest.compose(cardName, setCode, artIndex, colorID); CardRequest request = CardRequest.fromString(reqInfo); return tryGetCard(request); @@ -663,7 +664,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } @Override - public PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil, List colorID) { + public PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil, Set colorID) { if (edition == null || cardName == null) // preview cards return null; // No cards will be returned @@ -741,7 +742,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } @Override - public PaperCard getCardFromEditions(final String cardInfo, final CardArtPreference artPreference, int artIndex, List colorID) { + public PaperCard getCardFromEditions(final String cardInfo, final CardArtPreference artPreference, int artIndex, Set colorID) { return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex, null, false, null, colorID); } @@ -823,7 +824,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } private PaperCard tryToGetCardFromEditions(String cardInfo, CardArtPreference artPreference, int artIndex, - Date releaseDate, boolean releasedBeforeFlag, Predicate filter, List colorID){ + Date releaseDate, boolean releasedBeforeFlag, Predicate filter, Set colorID){ if (cardInfo == null) return null; final CardRequest cr = CardRequest.fromString(cardInfo); @@ -891,7 +892,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { if (acceptedEditions.size() > 1) { Collections.sort(acceptedEditions); // CardEdition correctly sort by (release) date if (artPref.latestFirst) - Collections.reverse(acceptedEditions); // newest editions first + CollectionUtil.reverse(acceptedEditions); // newest editions first } final Iterator editionIterator = acceptedEditions.iterator(); diff --git a/forge-core/src/main/java/forge/card/ICardDatabase.java b/forge-core/src/main/java/forge/card/ICardDatabase.java index a8165dff000..15761b234fa 100644 --- a/forge-core/src/main/java/forge/card/ICardDatabase.java +++ b/forge-core/src/main/java/forge/card/ICardDatabase.java @@ -7,6 +7,7 @@ import forge.item.PaperCard; import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.Set; public interface ICardDatabase extends Iterable { /** @@ -50,21 +51,21 @@ public interface ICardDatabase extends Iterable { // [NEW Methods] Including the card CollectorNumber as criterion for DB lookup PaperCard getCard(String cardName, String edition, String collectorNumber); PaperCard getCard(String cardName, String edition, int artIndex, String collectorNumber); - PaperCard getCard(String cardName, String edition, int artIndex, List colorID); + PaperCard getCard(String cardName, String edition, int artIndex, Set colorID); // 2. Card Lookup from a single Expansion Set PaperCard getCardFromSet(String cardName, CardEdition edition, boolean isFoil); // NOT yet used, included for API symmetry PaperCard getCardFromSet(String cardName, CardEdition edition, String collectorNumber, boolean isFoil); PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, boolean isFoil); PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil); - PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil, List colorID); + PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil, Set colorID); // 3. Card lookup based on CardArtPreference Selection Policy PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference); PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, Predicate filter); PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex); PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex, Predicate filter); - PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex, List colorID); + PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex, Set colorID); // 4. Specialised Card Lookup on CardArtPreference Selection and Release Date PaperCard getCardFromEditionsReleasedBefore(String cardName, CardArtPreference artPreference, Date releaseDate); diff --git a/forge-core/src/main/java/forge/deck/CardPool.java b/forge-core/src/main/java/forge/deck/CardPool.java index 6696253b2b5..5b9d3d2c98a 100644 --- a/forge-core/src/main/java/forge/deck/CardPool.java +++ b/forge-core/src/main/java/forge/deck/CardPool.java @@ -72,7 +72,7 @@ public class CardPool extends ItemPool { public void add(String cardName, String setCode, int artIndex, final int amount) { this.add(cardName, setCode, artIndex, amount, false, null); } - public void add(String cardName, String setCode, int artIndex, final int amount, boolean addAny, List colorID) { + public void add(String cardName, String setCode, int artIndex, final int amount, boolean addAny, Set colorID) { Map dbs = StaticData.instance().getAvailableDatabases(); PaperCard paperCard = null; String selectedDbName = ""; diff --git a/forge-core/src/main/java/forge/item/IPaperCard.java b/forge-core/src/main/java/forge/item/IPaperCard.java index b9694e083d2..51cf00fe92f 100644 --- a/forge-core/src/main/java/forge/item/IPaperCard.java +++ b/forge-core/src/main/java/forge/item/IPaperCard.java @@ -234,7 +234,7 @@ public interface IPaperCard extends InventoryItem, Serializable { String getEdition(); String getCollectorNumber(); String getFunctionalVariant(); - List getColorID(); + Set getColorID(); int getArtIndex(); boolean isFoil(); boolean isToken(); diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index 2da629bdc02..17cdaab38ac 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -29,6 +29,8 @@ import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.io.ObjectInputStream; import java.util.List; +import java.util.Optional; +import java.util.Set; /** * A lightweight version of a card that matches real-world cards, to use outside of games (eg. inventory, decks, trade). @@ -56,7 +58,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, private final boolean foil; private Boolean hasImage; private final boolean noSell; - private List colorID; + private Set colorID; private String sortableName; private final String functionalVariant; @@ -88,7 +90,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, } @Override - public List getColorID() { + public Set getColorID() { return colorID; } @@ -163,7 +165,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, false); return sellable; } - public PaperCard getSpireVersion(List colors) { + public PaperCard getSpireVersion(Set colors) { return new PaperCard(this.rules, this.edition, this.rarity, this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, false, colors); } @@ -205,7 +207,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, final int artIndex0, final boolean foil0, final String collectorNumber0, - final String artist0, final String functionalVariant, final boolean noSell0, final List spires) { + final String artist0, final String functionalVariant, final boolean noSell0, final Set colorID0) { if (rules0 == null || edition0 == null || rarity0 == null) { throw new IllegalArgumentException("Cannot create card without rules, edition or rarity"); } @@ -222,7 +224,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, sortableName = TextUtil.toSortableName(CardTranslation.getTranslatedName(rules0.getName())); this.functionalVariant = functionalVariant != null ? functionalVariant : IPaperCard.NO_FUNCTIONAL_VARIANT; noSell = noSell0; - colorID = spires; + colorID = colorID0; } public static PaperCard FAKE_CARD = new PaperCard(CardRules.getUnsupportedCardNamed("Fake Card"), "Fake Edition", CardRarity.Common); @@ -249,6 +251,9 @@ public class PaperCard implements Comparable, InventoryItemFromSet, } if (!getCollectorNumber().equals(other.getCollectorNumber())) return false; + // colorID can be NULL + if (getColorID() != other.getColorID()) + return false; return (other.foil == foil) && (other.artIndex == artIndex); } @@ -261,7 +266,7 @@ public class PaperCard implements Comparable, InventoryItemFromSet, public int hashCode() { final int code = (name.hashCode() * 11) + (edition.hashCode() * 59) + (artIndex * 2) + (getCollectorNumber().hashCode() * 383); - final int id = colorID == null ? 0 : colorID.hashCode(); + final int id = Optional.ofNullable(colorID).map(Set::hashCode).orElse(0); if (foil) { return code + id + 1; } diff --git a/forge-core/src/main/java/forge/item/PaperToken.java b/forge-core/src/main/java/forge/item/PaperToken.java index b4a2411897e..cbabd12bfa9 100644 --- a/forge-core/src/main/java/forge/item/PaperToken.java +++ b/forge-core/src/main/java/forge/item/PaperToken.java @@ -3,6 +3,7 @@ package forge.item; import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.Set; import forge.card.*; import org.apache.commons.lang3.StringUtils; @@ -154,7 +155,7 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard { } @Override - public List getColorID() { + public Set getColorID() { return null; } diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index acab924969a..d9e52576309 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -573,7 +573,7 @@ public class GameAction { } if (c.hasChosenColorSpire()) { - copied.setChosenColorID(ImmutableList.copyOf(c.getChosenColorID())); + copied.setChosenColorID(ImmutableSet.copyOf(c.getChosenColorID())); } // update state for view @@ -2236,7 +2236,7 @@ public class GameAction { Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(2)); SpellAbility sa = new SpellAbility.EmptySa(ApiType.ChooseColor, c, takesAction); sa.putParam("AILogic", "MostProminentInComputerDeck"); - List chosenColors = takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices); + Set chosenColors = new HashSet<>(takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices)); c.setChosenColorID(chosenColors); } } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 45616ce4850..2d00f281ea6 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -293,7 +293,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr private String chosenType2 = ""; private List notedTypes = new ArrayList<>(); private List chosenColors; - private List chosenColorID; + private Set chosenColorID; private List chosenName = new ArrayList<>(); private Integer chosenNumber; private Player chosenPlayer; @@ -2121,13 +2121,13 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr public boolean hasChosenColor(String s) { return chosenColors != null && chosenColors.contains(s); } - public final List getChosenColorID() { + public final Set getChosenColorID() { if (chosenColorID == null) { - return Lists.newArrayList(); + return Sets.newHashSet(); } return chosenColorID; } - public final void setChosenColorID(final List s) { + public final void setChosenColorID(final Set s) { chosenColorID = s; view.updateChosenColorID(this); } diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index 8553614719d..5ce321d5fac 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -433,7 +433,7 @@ public class CardView extends GameEntityView { void updateChosenColors(Card c) { set(TrackableProperty.ChosenColors, c.getChosenColors()); } - public List getChosenColorID() { + public Set getChosenColorID() { return get(TrackableProperty.ChosenColorID); } void updateChosenColorID(Card c) { diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index a02db4eee41..9ce53471afb 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -67,7 +67,7 @@ public enum TrackableProperty { ChosenType2(TrackableTypes.StringType), NotedTypes(TrackableTypes.StringListType), ChosenColors(TrackableTypes.StringListType), - ChosenColorID(TrackableTypes.StringListType), + ChosenColorID(TrackableTypes.StringSetType), ChosenCards(TrackableTypes.CardViewCollectionType), ChosenNumber(TrackableTypes.StringType), StoredRolls(TrackableTypes.StringListType), diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java index 4069cb2f3a8..5fc72473d1c 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java @@ -20,8 +20,11 @@ package forge.screens.deckeditor.controllers; import java.awt.Toolkit; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import java.util.HashSet; import java.util.List; import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Collectors; import javax.swing.JMenu; import javax.swing.JPopupMenu; @@ -586,7 +589,7 @@ public abstract class ACEditorBase { - List colors = GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, MagicColor.Constant.ONLY_COLORS); + Set colors = new HashSet<>(GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, MagicColor.Constant.ONLY_COLORS)); // make an updated version PaperCard updated = existingCard.getSpireVersion(colors); // remove *quantity* instances of existing card diff --git a/forge-gui-mobile/src/forge/deck/FDeckEditor.java b/forge-gui-mobile/src/forge/deck/FDeckEditor.java index 020c706925a..1b4c58df7b9 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckEditor.java +++ b/forge-gui-mobile/src/forge/deck/FDeckEditor.java @@ -1845,11 +1845,11 @@ public class FDeckEditor extends TabPageScreen { if ("Cryptic Spires".equalsIgnoreCase(card.getCardName())) { menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> { //sort options so current option is on top and selected by default - List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); + Set colorChoices = new HashSet<>(MagicColor.Constant.ONLY_COLORS); GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { @Override public void run(List result) { - addCard(card.getSpireVersion(result)); + addCard(card.getSpireVersion(new HashSet<>(result))); removeCard(card); } }); @@ -1897,11 +1897,11 @@ public class FDeckEditor extends TabPageScreen { if ("Cryptic Spires".equalsIgnoreCase(card.getCardName())) { menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> { //sort options so current option is on top and selected by default - List colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS); + Set colorChoices = new HashSet<>(MagicColor.Constant.ONLY_COLORS); GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { @Override public void run(List result) { - addCard(card.getSpireVersion(result)); + addCard(card.getSpireVersion(new HashSet<>(result))); removeCard(card); } }); From 60cfd971625e68e7c4034185d20e542927177982 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 14 Nov 2024 06:02:38 +0800 Subject: [PATCH 12/16] remove unused imports --- forge-core/src/main/java/forge/item/PaperCard.java | 1 - forge-core/src/main/java/forge/item/PaperToken.java | 1 - .../java/forge/screens/deckeditor/controllers/ACEditorBase.java | 1 - 3 files changed, 3 deletions(-) diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index 17cdaab38ac..24e7939df0b 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -28,7 +28,6 @@ import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.io.ObjectInputStream; -import java.util.List; import java.util.Optional; import java.util.Set; diff --git a/forge-core/src/main/java/forge/item/PaperToken.java b/forge-core/src/main/java/forge/item/PaperToken.java index cbabd12bfa9..4f96abee9e0 100644 --- a/forge-core/src/main/java/forge/item/PaperToken.java +++ b/forge-core/src/main/java/forge/item/PaperToken.java @@ -1,7 +1,6 @@ package forge.item; import java.util.ArrayList; -import java.util.List; import java.util.Locale; import java.util.Set; diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java index 5fc72473d1c..9771ac7bf1b 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java @@ -24,7 +24,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map.Entry; import java.util.Set; -import java.util.stream.Collectors; import javax.swing.JMenu; import javax.swing.JPopupMenu; From 8d9dabf7d70e630dc89baa6a6604334c67dab8eb Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 14 Nov 2024 06:06:26 +0800 Subject: [PATCH 13/16] remove uncommited changes --- forge-core/src/main/java/forge/card/CardDb.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/forge-core/src/main/java/forge/card/CardDb.java b/forge-core/src/main/java/forge/card/CardDb.java index 4dcd013be60..b781ae6c641 100644 --- a/forge-core/src/main/java/forge/card/CardDb.java +++ b/forge-core/src/main/java/forge/card/CardDb.java @@ -28,7 +28,6 @@ import forge.deck.generation.IDeckGenPool; import forge.item.IPaperCard; import forge.item.PaperCard; import forge.util.CollectionSuppliers; -import forge.util.CollectionUtil; import forge.util.Lang; import forge.util.TextUtil; import forge.util.lang.LangEnglish; @@ -892,7 +891,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { if (acceptedEditions.size() > 1) { Collections.sort(acceptedEditions); // CardEdition correctly sort by (release) date if (artPref.latestFirst) - CollectionUtil.reverse(acceptedEditions); // newest editions first + Collections.reverse(acceptedEditions); // newest editions first } final Iterator editionIterator = acceptedEditions.iterator(); From b1615025954a6d954f999cf4b602e99ff1f5a150 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 14 Nov 2024 10:30:33 +0800 Subject: [PATCH 14/16] update setting colorID --- forge-core/src/main/java/forge/card/CardDb.java | 4 ++-- forge-core/src/main/java/forge/card/CardRules.java | 12 ++++++++++++ forge-core/src/main/java/forge/item/PaperCard.java | 4 ++-- .../deckeditor/controllers/ACEditorBase.java | 9 +++++---- .../deckeditor/controllers/CEditorConstructed.java | 2 +- forge-gui-mobile/src/forge/deck/FDeckEditor.java | 14 ++++++++------ forge-gui/res/cardsfolder/c/cryptic_spires.txt | 1 + 7 files changed, 31 insertions(+), 15 deletions(-) diff --git a/forge-core/src/main/java/forge/card/CardDb.java b/forge-core/src/main/java/forge/card/CardDb.java index b781ae6c641..db7718b875f 100644 --- a/forge-core/src/main/java/forge/card/CardDb.java +++ b/forge-core/src/main/java/forge/card/CardDb.java @@ -697,7 +697,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { while (!candidate.hasImage() && candidatesIterator.hasNext()) candidate = candidatesIterator.next(); candidate = candidate.hasImage() ? candidate : firstCandidate; - return isFoil ? candidate.getFoiled().getSpireVersion(colorID) : candidate.getSpireVersion(colorID); + return isFoil ? candidate.getFoiled().getColorIDVersion(colorID) : candidate.getColorIDVersion(colorID); } /* @@ -904,7 +904,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } candidate = candidate.hasImage() ? candidate : firstCandidate; //If any, we're sure that at least one candidate is always returned despite it having any image - return cr.isFoil ? candidate.getFoiled().getSpireVersion(colorID) : candidate.getSpireVersion(colorID); + return cr.isFoil ? candidate.getFoiled().getColorIDVersion(colorID) : candidate.getColorIDVersion(colorID); } @Override diff --git a/forge-core/src/main/java/forge/card/CardRules.java b/forge-core/src/main/java/forge/card/CardRules.java index c6e8cdc29c7..3811eeb3ded 100644 --- a/forge-core/src/main/java/forge/card/CardRules.java +++ b/forge-core/src/main/java/forge/card/CardRules.java @@ -53,6 +53,7 @@ public final class CardRules implements ICardCharacteristics { private String meldWith; private String partnerWith; private boolean addsWildCardColor; + private int setColorID; private boolean custom; public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah) { @@ -72,6 +73,8 @@ public final class CardRules implements ICardCharacteristics { meldWith = ""; partnerWith = ""; addsWildCardColor = false; + setColorID = 0; + //calculate color identity byte colMask = calculateColorIdentity(mainPart); @@ -95,6 +98,7 @@ public final class CardRules implements ICardCharacteristics { meldWith = newRules.meldWith; partnerWith = newRules.partnerWith; addsWildCardColor = newRules.addsWildCardColor; + setColorID = newRules.setColorID; tokens = newRules.tokens; } @@ -397,6 +401,10 @@ public final class CardRules implements ICardCharacteristics { return addsWildCardColor; } + public int getSetColorID() { + return setColorID; + } + // vanguard card fields, they don't use sides. private int deltaHand; private int deltaLife; @@ -448,6 +456,7 @@ public final class CardRules implements ICardCharacteristics { private String meldWith = ""; private String partnerWith = ""; private boolean addsWildCardColor = false; + private int setColorID = 0; private String handLife = null; private String normalizedName = ""; private Set supportedFunctionalVariants = null; @@ -512,6 +521,7 @@ public final class CardRules implements ICardCharacteristics { result.meldWith = this.meldWith; result.partnerWith = this.partnerWith; result.addsWildCardColor = this.addsWildCardColor; + result.setColorID = this.setColorID; if (!tokens.isEmpty()) { result.tokens = tokens; } @@ -687,6 +697,8 @@ public final class CardRules implements ICardCharacteristics { value = colonPos > 0 ? value.substring(1+colonPos) : null; face.addSVar(variable, value); + } else if (key.startsWith("SETCOLORID")) { + this.setColorID = Integer.parseInt(value); } break; diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index 24e7939df0b..b81f3825266 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -164,9 +164,9 @@ public class PaperCard implements Comparable, InventoryItemFromSet, this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, false); return sellable; } - public PaperCard getSpireVersion(Set colors) { + public PaperCard getColorIDVersion(Set colors) { return new PaperCard(this.rules, this.edition, this.rarity, - this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, false, colors); + this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, this.noSell, colors); } @Override public String getItemType() { diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java index 9771ac7bf1b..4f966a099cc 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java @@ -580,17 +580,18 @@ public abstract class ACEditorBase 0) return; GuiUtils.addMenuItem(menu, label, null, () -> { - Set colors = new HashSet<>(GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(2)), 2, 2, MagicColor.Constant.ONLY_COLORS)); + Set colors = new HashSet<>(GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(val)), val, val, MagicColor.Constant.ONLY_COLORS)); // make an updated version - PaperCard updated = existingCard.getSpireVersion(colors); + PaperCard updated = existingCard.getColorIDVersion(colors); // remove *quantity* instances of existing card CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 1); // add *quantity* into the deck and set them as selected diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java index 8d5c7080d04..f3be724aab0 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java @@ -375,7 +375,7 @@ public final class CEditorConstructed extends CDeckEditor { if (foilAvailable) { cmb.addMakeFoils(); } - cmb.addSetColorSpire(); + cmb.addSetColorID(); } /* (non-Javadoc) diff --git a/forge-gui-mobile/src/forge/deck/FDeckEditor.java b/forge-gui-mobile/src/forge/deck/FDeckEditor.java index 1b4c58df7b9..8578e757cd5 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckEditor.java +++ b/forge-gui-mobile/src/forge/deck/FDeckEditor.java @@ -1800,6 +1800,8 @@ public class FDeckEditor extends TabPageScreen { CardManagerPage cardSourceSection; DeckSection destination = DeckSection.matchingSection(card); final DeckSectionPage destinationPage = parentScreen.getPageForSection(destination); + // val for colorID setup + int val; switch (deckSection) { default: case Main: @@ -1842,14 +1844,14 @@ public class FDeckEditor extends TabPageScreen { } } addCommanderItems(menu, card); - if ("Cryptic Spires".equalsIgnoreCase(card.getCardName())) { + if ((val = card.getRules().getSetColorID()) > 0) { menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> { //sort options so current option is on top and selected by default Set colorChoices = new HashSet<>(MagicColor.Constant.ONLY_COLORS); - GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { + GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(val)), val, val, colorChoices, new Callback<>() { @Override public void run(List result) { - addCard(card.getSpireVersion(new HashSet<>(result))); + addCard(card.getColorIDVersion(new HashSet<>(result))); removeCard(card); } }); @@ -1894,14 +1896,14 @@ public class FDeckEditor extends TabPageScreen { } } addCommanderItems(menu, card); - if ("Cryptic Spires".equalsIgnoreCase(card.getCardName())) { + if ((val = card.getRules().getSetColorID()) > 0) { menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> { //sort options so current option is on top and selected by default Set colorChoices = new HashSet<>(MagicColor.Constant.ONLY_COLORS); - GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(2)), 2, 2, colorChoices, new Callback<>() { + GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(val)), val, val, colorChoices, new Callback<>() { @Override public void run(List result) { - addCard(card.getSpireVersion(new HashSet<>(result))); + addCard(card.getColorIDVersion(new HashSet<>(result))); removeCard(card); } }); diff --git a/forge-gui/res/cardsfolder/c/cryptic_spires.txt b/forge-gui/res/cardsfolder/c/cryptic_spires.txt index aff3fb69fe0..d7031b33257 100644 --- a/forge-gui/res/cardsfolder/c/cryptic_spires.txt +++ b/forge-gui/res/cardsfolder/c/cryptic_spires.txt @@ -6,3 +6,4 @@ R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementRe SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True A:AB$ Mana | Cost$ T | Produced$ Combo ColorID | SpellDescription$ Add one mana of either of the circled colors. Oracle:As you create your deck, circle two of the colors below.\nCryptic Spires enters tapped.\n{T}: Add one mana of either of the circled colors. +SETCOLORID:2 From dcd4fac927404de3384cbbbb78504e22397c9e77 Mon Sep 17 00:00:00 2001 From: kevlahnota Date: Fri, 15 Nov 2024 09:51:04 +0800 Subject: [PATCH 15/16] update desktop logic --- .../deckeditor/controllers/ACEditorBase.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java index 4f966a099cc..853c5af9df9 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java @@ -585,19 +585,18 @@ public abstract class ACEditorBase 0) - return; - - GuiUtils.addMenuItem(menu, label, null, () -> { - Set colors = new HashSet<>(GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(val)), val, val, MagicColor.Constant.ONLY_COLORS)); - // make an updated version - PaperCard updated = existingCard.getColorIDVersion(colors); - // remove *quantity* instances of existing card - CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 1); - // add *quantity* into the deck and set them as selected - cardManager.addItem(updated, 1); - cardManager.setSelectedItem(updated); - }, true, true); + if ((val = existingCard.getRules().getSetColorID()) > 0) { + GuiUtils.addMenuItem(menu, label, null, () -> { + Set colors = new HashSet<>(GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(val)), val, val, MagicColor.Constant.ONLY_COLORS)); + // make an updated version + PaperCard updated = existingCard.getColorIDVersion(colors); + // remove *quantity* instances of existing card + CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 1); + // add *quantity* into the deck and set them as selected + cardManager.addItem(updated, 1); + cardManager.setSelectedItem(updated); + }, true, true); + } } } } From 95e33049483fe1173f14e18fa462b827a3e71539 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sat, 16 Nov 2024 18:24:22 +0800 Subject: [PATCH 16/16] add coloridversion check --- forge-core/src/main/java/forge/item/PaperCard.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index b81f3825266..7ecbce6c09b 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -165,6 +165,12 @@ public class PaperCard implements Comparable, InventoryItemFromSet, return sellable; } public PaperCard getColorIDVersion(Set colors) { + if (colors == null && this.colorID == null) + return this; + if (this.colorID != null && this.colorID.equals(colors)) + return this; + if (colors != null && colors.equals(this.colorID)) + return this; return new PaperCard(this.rules, this.edition, this.rarity, this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, this.noSell, colors); }