Merge branch 'master' into 'master'

Refactor carddb for Deck Editor/Workshop Catalog

Closes #1436

See merge request core-developers/forge!4298
This commit is contained in:
Anthony Calosa
2021-03-29 13:44:55 +00:00
8 changed files with 108 additions and 43 deletions

View File

@@ -37,7 +37,6 @@ public class StaticData {
private final String blockDataFolder;
private final CardDb commonCards;
private final CardDb commonCardsforDeckEditor;
private final CardDb variantCards;
private final CardDb customCards;
private final TokenDb allTokens;
@@ -109,14 +108,11 @@ public class StaticData {
commonCards = new CardDb(regularCards, editions);
variantCards = new CardDb(variantsCards, editions);
customCards = new CardDb(customizedCards, customEditions);
commonCardsforDeckEditor = new CardDb(regularCards, editions);
//must initialize after establish field values for the sake of card image logic
commonCards.initialize(false, false, enableUnknownCards, loadNonLegalCards, false);
variantCards.initialize(false, false, enableUnknownCards, loadNonLegalCards, false);
customCards.initialize(false, false, enableUnknownCards, loadNonLegalCards, false);
//cannot filter commonCards unless we don't allow to put duplicate parts on database, commonCardsforDeckEditor is strictly for Deck Editor use
commonCardsforDeckEditor.initialize(false, false, enableUnknownCards, loadNonLegalCards, true);
commonCards.initialize(false, false, enableUnknownCards, loadNonLegalCards);
variantCards.initialize(false, false, enableUnknownCards, loadNonLegalCards);
customCards.initialize(false, false, enableUnknownCards, loadNonLegalCards);
}
{
@@ -135,7 +131,6 @@ public class StaticData {
Collection<PaperCard> paperCards = customCards.getAllCards();
for(PaperCard p: paperCards) {
commonCards.addCard(p);
commonCardsforDeckEditor.addCard(p, true);
}
}
}
@@ -245,13 +240,7 @@ public class StaticData {
}
public CardDb getCommonCards() {
return getCommonCards(true);
}
public CardDb getCommonCards(boolean includeBackSides) {
if (includeBackSides)
return commonCards;
return commonCardsforDeckEditor;
return commonCards;
}
public CardDb getCustomCards() {

View File

@@ -56,6 +56,9 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
public final static String foilSuffix = "+";
public final static char NameSetSeparator = '|';
// for deck editor only
private final ListMultimap<String, PaperCard> allCardsByNameNoAlt = Multimaps.newListMultimap(new TreeMap<>(String.CASE_INSENSITIVE_ORDER), CollectionSuppliers.arrayLists());
private final Map<String, PaperCard> uniqueCardsByNameNoAlt = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
// need this to obtain cardReference by name+set+artindex
private final ListMultimap<String, PaperCard> allCardsByName = Multimaps.newListMultimap(new TreeMap<>(String.CASE_INSENSITIVE_ORDER), CollectionSuppliers.arrayLists());
private final Map<String, PaperCard> uniqueCardsByName = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
@@ -67,6 +70,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
private final Map<String, Integer> artIds = new HashMap<>();
private final Collection<PaperCard> roAllCards = Collections.unmodifiableCollection(allCardsByName.values());
private final Collection<PaperCard> roAllCardsNoAlt = Collections.unmodifiableCollection(allCardsByNameNoAlt.values());
private final CardEdition.Collection editions;
public enum SetPreference {
@@ -156,9 +160,6 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
}
private void addSetCard(CardEdition e, CardInSet cis, CardRules cr) {
addSetCard(e, cis, cr, false);
}
private void addSetCard(CardEdition e, CardInSet cis, CardRules cr, boolean noSplitTypesNames) {
int artIdx = 1;
String key = e.getCode() + "/" + cis.name;
if (artIds.containsKey(key)) {
@@ -166,7 +167,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
}
artIds.put(key, artIdx);
addCard(new PaperCard(cr, e.getCode(), cis.rarity, artIdx), noSplitTypesNames);
addCard(new PaperCard(cr, e.getCode(), cis.rarity, artIdx));
}
public void loadCard(String cardName, CardRules cr) {
@@ -185,7 +186,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
reIndex();
}
public void initialize(boolean logMissingPerEdition, boolean logMissingSummary, boolean enableUnknownCards, boolean loadNonLegalCards, boolean noSplitTypesNames) {
public void initialize(boolean logMissingPerEdition, boolean logMissingSummary, boolean enableUnknownCards, boolean loadNonLegalCards) {
Set<String> allMissingCards = new LinkedHashSet<>();
List<String> missingCards = new ArrayList<>();
CardEdition upcomingSet = null;
@@ -213,7 +214,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
}
if (cr != null) {
addSetCard(e, cis, cr, noSplitTypesNames);
addSetCard(e, cis, cr);
}
else {
missingCards.add(cis.name);
@@ -258,12 +259,8 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
}
public void addCard(PaperCard paperCard) {
addCard(paperCard, false);
}
public void addCard(PaperCard paperCard, boolean noSplitTypesNames) {
allCardsByName.put(paperCard.getName(), paperCard);
if (noSplitTypesNames) { return; }
allCardsByNameNoAlt.put(paperCard.getName(), paperCard);
if (paperCard.getRules().getSplitType() == CardSplitType.None) { return; }
@@ -279,9 +276,13 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
private void reIndex() {
uniqueCardsByName.clear();
uniqueCardsByNameNoAlt.clear();
for (Entry<String, Collection<PaperCard>> kv : allCardsByName.asMap().entrySet()) {
uniqueCardsByName.put(kv.getKey(), getFirstWithImage(kv.getValue()));
}
for (Entry<String, Collection<PaperCard>> kv : allCardsByNameNoAlt.asMap().entrySet()) {
uniqueCardsByNameNoAlt.put(kv.getKey(), getFirstWithImage(kv.getValue()));
}
}
private static PaperCard getFirstWithImage(final Collection<PaperCard> cards) {
@@ -569,6 +570,10 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
return uniqueCardsByName.values();
}
public Collection<PaperCard> getUniqueCardsNoAlt() {
return uniqueCardsByNameNoAlt.values();
}
public PaperCard getUniqueByName(final String name) {
return uniqueCardsByName.get(getName(name));
}
@@ -586,6 +591,10 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
return roAllCards;
}
public Collection<PaperCard> getAllCardsNoAlt() {
return roAllCardsNoAlt;
}
public Collection<PaperCard> getAllNonPromoCards() {
return Lists.newArrayList(Iterables.filter(this.roAllCards, new Predicate<PaperCard>() {
@Override
@@ -613,12 +622,21 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
return allCardsByName.get(getName(cardName));
}
public List<PaperCard> getAllCardsNoAlt(String cardName) {
return allCardsByNameNoAlt.get(getName(cardName));
}
/** Returns a modifiable list of cards matching the given predicate */
@Override
public List<PaperCard> getAllCards(Predicate<PaperCard> predicate) {
return Lists.newArrayList(Iterables.filter(this.roAllCards, predicate));
}
/** Returns a modifiable list of cards matching the given predicate */
public List<PaperCard> getAllCardsNoAlt(Predicate<PaperCard> predicate) {
return Lists.newArrayList(Iterables.filter(this.roAllCardsNoAlt, predicate));
}
// Do I want a foiled version of these cards?
@Override
public List<PaperCard> getAllCardsFromEdition(CardEdition edition) {

View File

@@ -82,11 +82,11 @@ public final class CEditorCommander extends CDeckEditor<Deck> {
allSections.add(DeckSection.Sideboard);
allSections.add(DeckSection.Commander);
CardDb commonCards = FModel.getMagicDb().getCommonCards(false);
CardDb commonCards = FModel.getMagicDb().getCommonCards();
if (gameType == GameType.Brawl){
GameFormat format = FModel.getFormats().get("Brawl");
Predicate<CardRules> commanderFilter = CardRulesPredicates.Presets.CAN_BE_BRAWL_COMMANDER;
commanderPool = ItemPool.createFrom(commonCards.getAllCards(Predicates.and(
commanderPool = ItemPool.createFrom(commonCards.getAllCardsNoAlt(Predicates.and(
format.getFilterPrinted(), Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES))), PaperCard.class);
normalPool = ItemPool.createFrom(format.getAllCards(), PaperCard.class);
}
@@ -94,8 +94,8 @@ public final class CEditorCommander extends CDeckEditor<Deck> {
Predicate<CardRules> commanderFilter = gameType == GameType.Oathbreaker
? Predicates.or(CardRulesPredicates.Presets.CAN_BE_OATHBREAKER, CardRulesPredicates.Presets.CAN_BE_SIGNATURE_SPELL)
: CardRulesPredicates.Presets.CAN_BE_COMMANDER;
commanderPool = ItemPool.createFrom(commonCards.getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)),PaperCard.class);
normalPool = ItemPool.createFrom(commonCards.getAllCards(), PaperCard.class);
commanderPool = ItemPool.createFrom(commonCards.getAllCardsNoAlt(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)),PaperCard.class);
normalPool = ItemPool.createFrom(commonCards.getAllCardsNoAlt(), PaperCard.class);
}
CardManager catalogManager = new CardManager(getCDetailPicture(), true, false);

View File

@@ -93,7 +93,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
allSections.add(DeckSection.Planes);
allSections.add(DeckSection.Conspiracy);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(), PaperCard.class);
avatarPool = ItemPool.createFrom(FModel.getMagicDb().getVariantCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_VANGUARD, PaperCard.FN_GET_RULES)), PaperCard.class);
planePool = ItemPool.createFrom(FModel.getMagicDb().getVariantCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_PLANE_OR_PHENOMENON, PaperCard.FN_GET_RULES)), PaperCard.class);
schemePool = ItemPool.createFrom(FModel.getMagicDb().getVariantCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_SCHEME, PaperCard.FN_GET_RULES)), PaperCard.class);
@@ -104,8 +104,8 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
allSections.add(DeckSection.Commander);
commanderFilter = CardRulesPredicates.Presets.CAN_BE_COMMANDER;
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(), PaperCard.class);
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(), PaperCard.class);
wantUnique = true;
break;
@@ -113,8 +113,8 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
allSections.add(DeckSection.Commander);
commanderFilter = CardRulesPredicates.Presets.CAN_BE_TINY_LEADERS_COMMANDER;
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(), PaperCard.class);
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(), PaperCard.class);
wantUnique = true;
break;
@@ -122,8 +122,8 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
allSections.add(DeckSection.Commander);
commanderFilter = Predicates.or(CardRulesPredicates.Presets.CAN_BE_OATHBREAKER, CardRulesPredicates.Presets.CAN_BE_SIGNATURE_SPELL);
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(), PaperCard.class);
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(), PaperCard.class);
wantUnique = true;
break;
@@ -131,7 +131,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
allSections.add(DeckSection.Commander);
commanderFilter = CardRulesPredicates.Presets.CAN_BE_BRAWL_COMMANDER;
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(Predicates.and(
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(Predicates.and(
FModel.getFormats().get("Brawl").getFilterPrinted(), Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES))), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getFormats().get("Brawl").getAllCards(), PaperCard.class);

View File

@@ -80,7 +80,7 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
private ItemPool<InventoryItem> cardsForSale;
private final ItemPool<InventoryItem> fullCatalogCards =
ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(), InventoryItem.class);
ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(), InventoryItem.class);
private boolean showingFullCatalog = false;
private DragCell allDecksParent = null;
private DragCell deckGenParent = null;

View File

@@ -41,7 +41,7 @@ public enum VWorkshopCatalog implements IVDoc<CWorkshopCatalog> {
VWorkshopCatalog() {
this.cardManager = new CardManager(cDetailPicture, true, false);
this.cardManager.setCaption(localizer.getMessage("lblCatalog"));
final Iterable<PaperCard> allCards = Iterables.concat(FModel.getMagicDb().getCommonCards(false), FModel.getMagicDb().getVariantCards());
final Iterable<PaperCard> allCards = Iterables.concat(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(), FModel.getMagicDb().getVariantCards().getAllCards());
this.cardManager.setPool(ItemPool.createFrom(allCards, PaperCard.class), true);
this.cardManagerContainer.setItemManager(this.cardManager);

View File

@@ -1156,10 +1156,10 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
// fall through to below
default:
if (cardManager.getWantUnique()) {
cardManager.setPool(editorType.applyCardFilter(ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getUniqueCards(), PaperCard.class), additionalFilter), true);
cardManager.setPool(editorType.applyCardFilter(ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getUniqueCardsNoAlt(), PaperCard.class), additionalFilter), true);
}
else {
cardManager.setPool(editorType.applyCardFilter(ItemPool.createFrom(FModel.getMagicDb().getCommonCards(false).getAllCards(), PaperCard.class), additionalFilter), true);
cardManager.setPool(editorType.applyCardFilter(ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(), PaperCard.class), additionalFilter), true);
}
break;
}
@@ -1243,7 +1243,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
}
//if card has more than one art option, add item to change user's preferred art
final List<PaperCard> artOptions = FModel.getMagicDb().getCommonCards(false).getAllCards(card.getName());
final List<PaperCard> artOptions = FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(card.getName());
if (artOptions != null && artOptions.size() > 1) {
menu.addItem(new FMenuItem(localizer.getMessage("lblChangePreferredArt"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, new FEventHandler() {
@Override

View File

@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableList;
import forge.card.CardEdition;
import forge.card.CardRarity;
import forge.card.CardRules;
import forge.card.CardSplitType;
import forge.card.CardType;
import forge.card.CardType.CoreType;
import forge.card.CardType.Supertype;
@@ -60,6 +61,13 @@ public class AdvancedSearch {
Set<String> names = new HashSet<>();
names.add(input.getName());
names.add(CardTranslation.getTranslatedName(input.getName()));
CardSplitType cardSplitType = input.getRules().getSplitType();
if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) {
if (input.getRules().getOtherPart() != null) {
names.add(input.getRules().getOtherPart().getName());
names.add(CardTranslation.getTranslatedName(input.getRules().getOtherPart().getName()));
}
}
return names;
}
}),
@@ -73,6 +81,13 @@ public class AdvancedSearch {
Set<String> names = new HashSet<>();
names.add(input.getRules().getOracleText());
names.add(CardTranslation.getTranslatedOracle(input.getName()));
CardSplitType cardSplitType = input.getRules().getSplitType();
if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) {
if (input.getRules().getOtherPart() != null) {
names.add(input.getRules().getOtherPart().getOracleText());
names.add(CardTranslation.getTranslatedOracle(input.getRules().getOtherPart().getName()));
}
}
return names;
}
}),
@@ -83,6 +98,18 @@ public class AdvancedSearch {
}
@Override
protected Set<Keyword> getItemValues(PaperCard input) {
CardSplitType cardSplitType = input.getRules().getSplitType();
if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) {
Set<Keyword> keywords = new HashSet<>();
if (input.getRules().getOtherPart() != null) {
PaperCard otherPart = FModel.getMagicDb().getCommonCards().getCard(input.getRules().getOtherPart().getName());
if (otherPart != null) {
keywords.addAll(Keyword.getKeywordSet(otherPart));
keywords.addAll(Keyword.getKeywordSet(input));
}
}
return keywords;
}
return Keyword.getKeywordSet(input);
}
}),
@@ -167,6 +194,24 @@ public class AdvancedSearch {
protected Set<String> getItemValues(PaperCard input) {
final CardType type = input.getRules().getType();
final Set<String> types = new HashSet<>();
CardSplitType cardSplitType = input.getRules().getSplitType();
if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) {
if (input.getRules().getOtherPart() != null) {
for (Supertype supertype : input.getRules().getOtherPart().getType().getSupertypes()) {
types.add(supertype.name());
}
for (CoreType coreType : input.getRules().getOtherPart().getType().getCoreTypes()) {
types.add(coreType.name());
}
for (Supertype supertype : input.getRules().getMainPart().getType().getSupertypes()) {
types.add(supertype.name());
}
for (CoreType coreType : input.getRules().getMainPart().getType().getCoreTypes()) {
types.add(coreType.name());
}
return types;
}
}
for (Supertype t : type.getSupertypes()) {
types.add(t.name());
}
@@ -183,6 +228,19 @@ public class AdvancedSearch {
}
@Override
protected Set<String> getItemValues(PaperCard input) {
CardSplitType cardSplitType = input.getRules().getSplitType();
if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) {
if (input.getRules().getOtherPart() != null) {
Set<String> subtypes = new HashSet<>();
for (String subs : input.getRules().getOtherPart().getType().getSubtypes()) {
subtypes.add(subs);
}
for (String subs : input.getRules().getMainPart().getType().getSubtypes()) {
subtypes.add(subs);
}
return subtypes;
}
}
return (Set<String>)input.getRules().getType().getSubtypes();
}
}),