mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28: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.Map.Entry;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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
|
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"),
|
CARDS("cards"),
|
||||||
PRECON_PRODUCT("precon product"),
|
PRECON_PRODUCT("precon product"),
|
||||||
BORDERLESS("borderless"),
|
BORDERLESS("borderless"),
|
||||||
@@ -85,11 +90,15 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
EditionSection(final String n) { this.name = n; }
|
EditionSectionWithCollectorNumbers(final String n) { this.name = n; }
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<String> getNames() {
|
||||||
|
return Arrays.stream(EditionSectionWithCollectorNumbers.values()).map(s -> s.getName()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CardInSet {
|
public static class CardInSet {
|
||||||
@@ -145,19 +154,23 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
private String doublePickDuringDraft = "";
|
private String doublePickDuringDraft = "";
|
||||||
private final ListMultimap<String, CardInSet> cardMap;
|
private final ListMultimap<String, CardInSet> cardMap;
|
||||||
private final Map<String, Integer> tokenNormalized;
|
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 int boosterArts = 1;
|
||||||
private SealedProduct.Template boosterTpl = null;
|
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.cardMap = cardMap;
|
||||||
this.tokenNormalized = tokens;
|
this.tokenNormalized = tokens;
|
||||||
|
this.customPrintSheetsToParse = customPrintSheetsToParse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CardEdition(CardInSet[] cards, Map<String, Integer> tokens) {
|
private CardEdition(CardInSet[] cards, Map<String, Integer> tokens) {
|
||||||
this.cardMap = ArrayListMultimap.create();
|
this.cardMap = ArrayListMultimap.create();
|
||||||
this.cardMap.replaceValues("cards", Arrays.asList(cards));
|
this.cardMap.replaceValues("cards", Arrays.asList(cards));
|
||||||
this.tokenNormalized = tokens;
|
this.tokenNormalized = tokens;
|
||||||
|
this.customPrintSheetsToParse = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,6 +322,14 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
|
|
||||||
sheets.add(sheet);
|
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;
|
return sheets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,15 +363,17 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
|
|
||||||
ListMultimap<String, CardInSet> cardMap = ArrayListMultimap.create();
|
ListMultimap<String, CardInSet> cardMap = ArrayListMultimap.create();
|
||||||
Map<String, Integer> tokenNormalized = new HashMap<>();
|
Map<String, Integer> tokenNormalized = new HashMap<>();
|
||||||
|
Map<String, List<String>> customPrintSheetsToParse = new HashMap<>();
|
||||||
|
List<String> editionSectionsWithCollectorNumbers = EditionSectionWithCollectorNumbers.getNames();
|
||||||
|
|
||||||
for(EditionSection section : EditionSection.values()) {
|
for (String sectionName : contents.keySet()) {
|
||||||
String name = section.getName();
|
// skip reserved section names like 'metadata' and 'tokens' that are handled separately
|
||||||
|
if (reservedSectionNames.contains(sectionName)) {
|
||||||
if (!contents.containsKey(name)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// parse sections of the format "<collector number> <rarity> <name>"
|
||||||
for(String line : contents.get(name)) {
|
if (editionSectionsWithCollectorNumbers.contains(sectionName)) {
|
||||||
|
for(String line : contents.get(sectionName)) {
|
||||||
Matcher matcher = pattern.matcher(line);
|
Matcher matcher = pattern.matcher(line);
|
||||||
|
|
||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
@@ -362,10 +385,17 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
String cardName = matcher.group(5);
|
String cardName = matcher.group(5);
|
||||||
CardInSet cis = new CardInSet(cardName, collectorNumber, r);
|
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")) {
|
if (contents.containsKey("tokens")) {
|
||||||
for(String line : contents.get("tokens")) {
|
for(String line : contents.get("tokens")) {
|
||||||
if (StringUtils.isBlank(line))
|
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);
|
FileSection section = FileSection.parse(contents.get("metadata"), FileSection.EQUALS_KV_SEPARATOR);
|
||||||
res.name = section.get("name");
|
res.name = section.get("name");
|
||||||
res.date = parseDate(section.get("date"));
|
res.date = parseDate(section.get("date"));
|
||||||
|
|||||||
@@ -6131,44 +6131,6 @@ Roil Eruption|ZNR|2
|
|||||||
Roiling Regrowth|ZNR|2
|
Roiling Regrowth|ZNR|2
|
||||||
Kargan Warleader|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]
|
[CMR Foils]
|
||||||
The Prismatic Piper+|CMR
|
The Prismatic Piper+|CMR
|
||||||
Akroma, Vision of Ixidor+|CMR
|
Akroma, Vision of Ixidor+|CMR
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ MciCode=znr
|
|||||||
Type=Expansion
|
Type=Expansion
|
||||||
BoosterCovers=3
|
BoosterCovers=3
|
||||||
Booster=10 Common:!dfc:fromSheet("ZNR cards"), 3 Uncommon:!dfc:fromSheet("ZNR cards"), 1 RareMythic:!dfc:fromSheet("ZNR cards"), 1 BasicLand
|
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+
|
Prerelease=6 Boosters, 1 RareMythic+
|
||||||
#BoosterBox=36 Boosters, 1 fromSheet('buy a box')+
|
#BoosterBox=36 Boosters, 1 fromSheet('buy a box')+
|
||||||
|
|
||||||
@@ -414,6 +414,44 @@ Prerelease=6 Boosters, 1 RareMythic+
|
|||||||
390 U Roiling Regrowth
|
390 U Roiling Regrowth
|
||||||
391 U Kargan Warleader
|
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]
|
[tokens]
|
||||||
w_4_4_angel_warrior_flying
|
w_4_4_angel_warrior_flying
|
||||||
w_1_1_cat
|
w_1_1_cat
|
||||||
|
|||||||
Reference in New Issue
Block a user