mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge branch 'allow-generic-edition-sections' into 'master'
Custom print sheets in edition files See merge request core-developers/forge!3442
This commit is contained in:
@@ -39,6 +39,7 @@ import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
@@ -74,7 +75,11 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
||||
MODERN // 8th Edition and newer
|
||||
}
|
||||
|
||||
public enum EditionSection {
|
||||
// reserved names of sections inside edition files, that are not parsed as cards
|
||||
private static final List<String> reservedSectionNames = ImmutableList.of("metadata", "tokens");
|
||||
|
||||
// commonly used printsheets with collector number
|
||||
public enum EditionSectionWithCollectorNumbers {
|
||||
CARDS("cards"),
|
||||
PRECON_PRODUCT("precon product"),
|
||||
BORDERLESS("borderless"),
|
||||
@@ -85,11 +90,15 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
||||
|
||||
private final String name;
|
||||
|
||||
EditionSection(final String n) { this.name = n; }
|
||||
EditionSectionWithCollectorNumbers(final String n) { this.name = n; }
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static List<String> getNames() {
|
||||
return Arrays.stream(EditionSectionWithCollectorNumbers.values()).map(s -> s.getName()).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
public static class CardInSet {
|
||||
@@ -145,19 +154,23 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
||||
private String doublePickDuringDraft = "";
|
||||
private final ListMultimap<String, CardInSet> cardMap;
|
||||
private final Map<String, Integer> tokenNormalized;
|
||||
// custom print sheets that will be loaded lazily
|
||||
private final Map<String, List<String>> customPrintSheetsToParse;
|
||||
|
||||
private int boosterArts = 1;
|
||||
private SealedProduct.Template boosterTpl = null;
|
||||
|
||||
private CardEdition(ListMultimap<String, CardInSet> cardMap, Map<String, Integer> tokens) {
|
||||
private CardEdition(ListMultimap<String, CardInSet> cardMap, Map<String, Integer> tokens, Map<String, List<String>> customPrintSheetsToParse) {
|
||||
this.cardMap = cardMap;
|
||||
this.tokenNormalized = tokens;
|
||||
this.customPrintSheetsToParse = customPrintSheetsToParse;
|
||||
}
|
||||
|
||||
private CardEdition(CardInSet[] cards, Map<String, Integer> tokens) {
|
||||
this.cardMap = ArrayListMultimap.create();
|
||||
this.cardMap.replaceValues("cards", Arrays.asList(cards));
|
||||
this.tokenNormalized = tokens;
|
||||
this.customPrintSheetsToParse = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,6 +322,14 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
||||
|
||||
sheets.add(sheet);
|
||||
}
|
||||
|
||||
for(String sheetName : customPrintSheetsToParse.keySet()) {
|
||||
List<String> sheetToParse = customPrintSheetsToParse.get(sheetName);
|
||||
CardPool sheetPool = CardPool.fromCardList(sheetToParse);
|
||||
PrintSheet sheet = new PrintSheet(String.format("%s %s", this.getCode(), sheetName), sheetPool);
|
||||
sheets.add(sheet);
|
||||
}
|
||||
|
||||
return sheets;
|
||||
}
|
||||
|
||||
@@ -342,15 +363,17 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
||||
|
||||
ListMultimap<String, CardInSet> cardMap = ArrayListMultimap.create();
|
||||
Map<String, Integer> tokenNormalized = new HashMap<>();
|
||||
Map<String, List<String>> customPrintSheetsToParse = new HashMap<>();
|
||||
List<String> editionSectionsWithCollectorNumbers = EditionSectionWithCollectorNumbers.getNames();
|
||||
|
||||
for(EditionSection section : EditionSection.values()) {
|
||||
String name = section.getName();
|
||||
|
||||
if (!contents.containsKey(name)) {
|
||||
for (String sectionName : contents.keySet()) {
|
||||
// skip reserved section names like 'metadata' and 'tokens' that are handled separately
|
||||
if (reservedSectionNames.contains(sectionName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(String line : contents.get(name)) {
|
||||
// parse sections of the format "<collector number> <rarity> <name>"
|
||||
if (editionSectionsWithCollectorNumbers.contains(sectionName)) {
|
||||
for(String line : contents.get(sectionName)) {
|
||||
Matcher matcher = pattern.matcher(line);
|
||||
|
||||
if (!matcher.matches()) {
|
||||
@@ -362,10 +385,17 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
||||
String cardName = matcher.group(5);
|
||||
CardInSet cis = new CardInSet(cardName, collectorNumber, r);
|
||||
|
||||
cardMap.put(name, cis);
|
||||
cardMap.put(sectionName, cis);
|
||||
}
|
||||
}
|
||||
// save custom print sheets of the format "<amount> <name>|<setcode>|<art index>"
|
||||
// to parse later when printsheets are loaded lazily (and the cardpool is already initialized)
|
||||
else {
|
||||
customPrintSheetsToParse.put(sectionName, contents.get(sectionName));
|
||||
}
|
||||
}
|
||||
|
||||
// parse tokens section
|
||||
if (contents.containsKey("tokens")) {
|
||||
for(String line : contents.get("tokens")) {
|
||||
if (StringUtils.isBlank(line))
|
||||
@@ -379,8 +409,9 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
||||
}
|
||||
}
|
||||
|
||||
CardEdition res = new CardEdition(cardMap, tokenNormalized);
|
||||
CardEdition res = new CardEdition(cardMap, tokenNormalized, customPrintSheetsToParse);
|
||||
|
||||
// parse metadata section
|
||||
FileSection section = FileSection.parse(contents.get("metadata"), FileSection.EQUALS_KV_SEPARATOR);
|
||||
res.name = section.get("name");
|
||||
res.date = parseDate(section.get("date"));
|
||||
|
||||
@@ -6131,44 +6131,6 @@ Roil Eruption|ZNR|2
|
||||
Roiling Regrowth|ZNR|2
|
||||
Kargan Warleader|ZNR|2
|
||||
|
||||
[ZNRModalDoubleFaceCards]
|
||||
1 Agadeem's Awakening|ZNR
|
||||
1 Emeria's Call|ZNR
|
||||
1 Sea Gate Restoration|ZNR
|
||||
1 Shatterskull Smashing|ZNR
|
||||
1 Turntimber Symbiosis|ZNR
|
||||
2 Branchloft Pathway|ZNR
|
||||
2 Brightclimb Pathway|ZNR
|
||||
2 Clearwater Pathway|ZNR
|
||||
2 Cragcrown Pathway|ZNR
|
||||
2 Glasspool Mimic|ZNR
|
||||
2 Hagra Mauling|ZNR
|
||||
2 Kazandu Mammoth|ZNR
|
||||
2 Needleverge Pathway|ZNR
|
||||
2 Ondu Inversion|ZNR
|
||||
2 Riverglide Pathway|ZNR
|
||||
2 Valakut Awakening|ZNR
|
||||
6 Akoum Warrior|ZNR
|
||||
6 Bala Ged Recovery|ZNR
|
||||
6 Beyeen Veil|ZNR
|
||||
6 Blackbloom Rogue|ZNR
|
||||
6 Jwari Disruption|ZNR
|
||||
6 Kabira Takedown|ZNR
|
||||
6 Kazuul's Fury|ZNR
|
||||
6 Khalni Ambush|ZNR
|
||||
6 Makindi Stampede|ZNR
|
||||
6 Malakir Rebirth|ZNR
|
||||
6 Pelakka Predation|ZNR
|
||||
6 Sejiri Shelter|ZNR
|
||||
6 Silundi Vision|ZNR
|
||||
6 Skyclave Cleric|ZNR
|
||||
6 Song-Mad Treachery|ZNR
|
||||
6 Spikefield Hazard|ZNR
|
||||
6 Tangled Florahedron|ZNR
|
||||
6 Umara Wizard|ZNR
|
||||
6 Vastwood Fortification|ZNR
|
||||
6 Zof Consumption|ZNR
|
||||
|
||||
[CMR Foils]
|
||||
The Prismatic Piper+|CMR
|
||||
Akroma, Vision of Ixidor+|CMR
|
||||
|
||||
@@ -7,7 +7,7 @@ MciCode=znr
|
||||
Type=Expansion
|
||||
BoosterCovers=3
|
||||
Booster=10 Common:!dfc:fromSheet("ZNR cards"), 3 Uncommon:!dfc:fromSheet("ZNR cards"), 1 RareMythic:!dfc:fromSheet("ZNR cards"), 1 BasicLand
|
||||
BoosterReplaceSlotFromPrintSheet=ZNRModalDoubleFaceCards
|
||||
BoosterReplaceSlotFromPrintSheet=ZNR ModalDoubleFaceCards
|
||||
Prerelease=6 Boosters, 1 RareMythic+
|
||||
#BoosterBox=36 Boosters, 1 fromSheet('buy a box')+
|
||||
|
||||
@@ -414,6 +414,44 @@ Prerelease=6 Boosters, 1 RareMythic+
|
||||
390 U Roiling Regrowth
|
||||
391 U Kargan Warleader
|
||||
|
||||
[ModalDoubleFaceCards]
|
||||
1 Agadeem's Awakening|ZNR
|
||||
1 Emeria's Call|ZNR
|
||||
1 Sea Gate Restoration|ZNR
|
||||
1 Shatterskull Smashing|ZNR
|
||||
1 Turntimber Symbiosis|ZNR
|
||||
2 Branchloft Pathway|ZNR
|
||||
2 Brightclimb Pathway|ZNR
|
||||
2 Clearwater Pathway|ZNR
|
||||
2 Cragcrown Pathway|ZNR
|
||||
2 Glasspool Mimic|ZNR
|
||||
2 Hagra Mauling|ZNR
|
||||
2 Kazandu Mammoth|ZNR
|
||||
2 Needleverge Pathway|ZNR
|
||||
2 Ondu Inversion|ZNR
|
||||
2 Riverglide Pathway|ZNR
|
||||
2 Valakut Awakening|ZNR
|
||||
6 Akoum Warrior|ZNR
|
||||
6 Bala Ged Recovery|ZNR
|
||||
6 Beyeen Veil|ZNR
|
||||
6 Blackbloom Rogue|ZNR
|
||||
6 Jwari Disruption|ZNR
|
||||
6 Kabira Takedown|ZNR
|
||||
6 Kazuul's Fury|ZNR
|
||||
6 Khalni Ambush|ZNR
|
||||
6 Makindi Stampede|ZNR
|
||||
6 Malakir Rebirth|ZNR
|
||||
6 Pelakka Predation|ZNR
|
||||
6 Sejiri Shelter|ZNR
|
||||
6 Silundi Vision|ZNR
|
||||
6 Skyclave Cleric|ZNR
|
||||
6 Song-Mad Treachery|ZNR
|
||||
6 Spikefield Hazard|ZNR
|
||||
6 Tangled Florahedron|ZNR
|
||||
6 Umara Wizard|ZNR
|
||||
6 Vastwood Fortification|ZNR
|
||||
6 Zof Consumption|ZNR
|
||||
|
||||
[tokens]
|
||||
w_4_4_angel_warrior_flying
|
||||
w_1_1_cat
|
||||
|
||||
Reference in New Issue
Block a user