mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-13 01:08:06 +00:00
Deck Importer support for Adventure, Quest, and Planar Conquest (#8681)
* Some cleanup. * Expanded/fixed basic land set functions for quest and adventure. * Get land sets from unlocked planes in conquest mode. * Add importer for Adventure, Quest, and Conquest. * Remove unused import * Remove redundant override * Deprecate hasBasicLands predicate. * Delete getManaNameAndSymbol --------- Co-authored-by: Jetz <Jetz722@gmail.com>
This commit is contained in:
@@ -1018,16 +1018,13 @@ public final class CardEdition implements Comparable<CardEdition> {
|
|||||||
|
|
||||||
public static final Predicate<CardEdition> HAS_BOOSTER_BOX = edition -> edition.getBoosterBoxCount() > 0;
|
public static final Predicate<CardEdition> HAS_BOOSTER_BOX = edition -> edition.getBoosterBoxCount() > 0;
|
||||||
|
|
||||||
|
@Deprecated //Use CardEdition::hasBasicLands and a nonnull test.
|
||||||
public static final Predicate<CardEdition> hasBasicLands = ed -> {
|
public static final Predicate<CardEdition> hasBasicLands = ed -> {
|
||||||
if (ed == null) {
|
if (ed == null) {
|
||||||
// Happens for new sets with "???" code
|
// Happens for new sets with "???" code
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for(String landName : MagicColor.Constant.BASIC_LANDS) {
|
return ed.hasBasicLands();
|
||||||
if (null == StaticData.instance().getCommonCards().getCard(landName, ed.getCode(), 0))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1048,7 +1045,7 @@ public final class CardEdition implements Comparable<CardEdition> {
|
|||||||
|
|
||||||
public boolean hasBasicLands() {
|
public boolean hasBasicLands() {
|
||||||
for(String landName : MagicColor.Constant.BASIC_LANDS) {
|
for(String landName : MagicColor.Constant.BASIC_LANDS) {
|
||||||
if (null == StaticData.instance().getCommonCards().getCard(landName, this.getCode(), 0))
|
if (this.getCardInSet(landName).isEmpty())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -49,6 +49,16 @@ public class DeckRecognizer {
|
|||||||
LIMITED_CARD,
|
LIMITED_CARD,
|
||||||
CARD_FROM_NOT_ALLOWED_SET,
|
CARD_FROM_NOT_ALLOWED_SET,
|
||||||
CARD_FROM_INVALID_SET,
|
CARD_FROM_INVALID_SET,
|
||||||
|
/**
|
||||||
|
* Valid card request, but can't be imported because the player does not have enough copies.
|
||||||
|
* Should be replaced with a different printing if possible.
|
||||||
|
*/
|
||||||
|
CARD_NOT_IN_INVENTORY,
|
||||||
|
/**
|
||||||
|
* Valid card request for a card that isn't in the player's inventory, but new copies can be acquired freely.
|
||||||
|
* Usually used for basic lands. Should be supplied to the import controller by the editor.
|
||||||
|
*/
|
||||||
|
FREE_CARD_NOT_IN_INVENTORY,
|
||||||
// Warning messages
|
// Warning messages
|
||||||
WARNING_MESSAGE,
|
WARNING_MESSAGE,
|
||||||
UNKNOWN_CARD,
|
UNKNOWN_CARD,
|
||||||
@@ -63,10 +73,14 @@ public class DeckRecognizer {
|
|||||||
CARD_TYPE,
|
CARD_TYPE,
|
||||||
CARD_RARITY,
|
CARD_RARITY,
|
||||||
CARD_CMC,
|
CARD_CMC,
|
||||||
MANA_COLOUR
|
MANA_COLOUR;
|
||||||
|
|
||||||
|
public static final EnumSet<TokenType> CARD_TOKEN_TYPES = EnumSet.of(LEGAL_CARD, LIMITED_CARD, CARD_FROM_NOT_ALLOWED_SET, CARD_FROM_INVALID_SET, CARD_NOT_IN_INVENTORY, FREE_CARD_NOT_IN_INVENTORY);
|
||||||
|
public static final EnumSet<TokenType> IN_DECK_TOKEN_TYPES = EnumSet.of(LEGAL_CARD, LIMITED_CARD, DECK_NAME, FREE_CARD_NOT_IN_INVENTORY);
|
||||||
|
public static final EnumSet<TokenType> CARD_PLACEHOLDER_TOKEN_TYPES = EnumSet.of(CARD_TYPE, CARD_RARITY, CARD_CMC, MANA_COLOUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LimitedCardType{
|
public enum LimitedCardType {
|
||||||
BANNED,
|
BANNED,
|
||||||
RESTRICTED,
|
RESTRICTED,
|
||||||
}
|
}
|
||||||
@@ -108,6 +122,10 @@ public class DeckRecognizer {
|
|||||||
return new Token(TokenType.CARD_FROM_INVALID_SET, count, card, cardRequestHasSetCode);
|
return new Token(TokenType.CARD_FROM_INVALID_SET, count, card, cardRequestHasSetCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Token NotInInventoryFree(final PaperCard card, final int count, final DeckSection section) {
|
||||||
|
return new Token(TokenType.FREE_CARD_NOT_IN_INVENTORY, count, card, section, true);
|
||||||
|
}
|
||||||
|
|
||||||
// WARNING MESSAGES
|
// WARNING MESSAGES
|
||||||
// ================
|
// ================
|
||||||
public static Token UnknownCard(final String cardName, final String setCode, final int count) {
|
public static Token UnknownCard(final String cardName, final String setCode, final int count) {
|
||||||
@@ -126,6 +144,10 @@ public class DeckRecognizer {
|
|||||||
return new Token(TokenType.WARNING_MESSAGE, msg);
|
return new Token(TokenType.WARNING_MESSAGE, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Token NotInInventory(final PaperCard card, final int count, final DeckSection section) {
|
||||||
|
return new Token(TokenType.CARD_NOT_IN_INVENTORY, count, card, section, false);
|
||||||
|
}
|
||||||
|
|
||||||
/* =================================
|
/* =================================
|
||||||
* DECK SECTIONS
|
* DECK SECTIONS
|
||||||
* ================================= */
|
* ================================= */
|
||||||
@@ -239,14 +261,11 @@ public class DeckRecognizer {
|
|||||||
/**
|
/**
|
||||||
* Filters all token types that have a PaperCard instance set (not null)
|
* Filters all token types that have a PaperCard instance set (not null)
|
||||||
* @return true for tokens of type:
|
* @return true for tokens of type:
|
||||||
* LEGAL_CARD, LIMITED_CARD, CARD_FROM_NOT_ALLOWED_SET and CARD_FROM_INVALID_SET.
|
* LEGAL_CARD, LIMITED_CARD, CARD_FROM_NOT_ALLOWED_SET and CARD_FROM_INVALID_SET, CARD_NOT_IN_INVENTORY, FREE_CARD_NOT_IN_INVENTORY.
|
||||||
* False otherwise.
|
* False otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isCardToken() {
|
public boolean isCardToken() {
|
||||||
return (this.type == TokenType.LEGAL_CARD ||
|
return TokenType.CARD_TOKEN_TYPES.contains(this.type);
|
||||||
this.type == TokenType.LIMITED_CARD ||
|
|
||||||
this.type == TokenType.CARD_FROM_NOT_ALLOWED_SET ||
|
|
||||||
this.type == TokenType.CARD_FROM_INVALID_SET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -255,9 +274,7 @@ public class DeckRecognizer {
|
|||||||
* LEGAL_CARD, LIMITED_CARD, DECK_NAME; false otherwise.
|
* LEGAL_CARD, LIMITED_CARD, DECK_NAME; false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isTokenForDeck() {
|
public boolean isTokenForDeck() {
|
||||||
return (this.type == TokenType.LEGAL_CARD ||
|
return TokenType.IN_DECK_TOKEN_TYPES.contains(this.type);
|
||||||
this.type == TokenType.LIMITED_CARD ||
|
|
||||||
this.type == TokenType.DECK_NAME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -266,7 +283,7 @@ public class DeckRecognizer {
|
|||||||
* False otherwise.
|
* False otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isCardTokenForDeck() {
|
public boolean isCardTokenForDeck() {
|
||||||
return (this.type == TokenType.LEGAL_CARD || this.type == TokenType.LIMITED_CARD);
|
return isCardToken() && isTokenForDeck();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -276,10 +293,7 @@ public class DeckRecognizer {
|
|||||||
* CARD_RARITY, CARD_CMC, CARD_TYPE, MANA_COLOUR
|
* CARD_RARITY, CARD_CMC, CARD_TYPE, MANA_COLOUR
|
||||||
*/
|
*/
|
||||||
public boolean isCardPlaceholder(){
|
public boolean isCardPlaceholder(){
|
||||||
return (this.type == TokenType.CARD_RARITY ||
|
return TokenType.CARD_PLACEHOLDER_TOKEN_TYPES.contains(this.type);
|
||||||
this.type == TokenType.CARD_CMC ||
|
|
||||||
this.type == TokenType.MANA_COLOUR ||
|
|
||||||
this.type == TokenType.CARD_TYPE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determines if current token is a Deck Section token
|
/** Determines if current token is a Deck Section token
|
||||||
@@ -536,7 +550,7 @@ public class DeckRecognizer {
|
|||||||
PaperCard tokenCard = token.getCard();
|
PaperCard tokenCard = token.getCard();
|
||||||
|
|
||||||
if (isAllowed(tokenSection)) {
|
if (isAllowed(tokenSection)) {
|
||||||
if (!tokenSection.equals(referenceDeckSectionInParsing)) {
|
if (tokenSection != referenceDeckSectionInParsing) {
|
||||||
Token sectionToken = Token.DeckSection(tokenSection.name(), this.allowedDeckSections);
|
Token sectionToken = Token.DeckSection(tokenSection.name(), this.allowedDeckSections);
|
||||||
// just check that last token is stack is a card placeholder.
|
// just check that last token is stack is a card placeholder.
|
||||||
// In that case, add the new section token before the placeholder
|
// In that case, add the new section token before the placeholder
|
||||||
@@ -575,7 +589,7 @@ public class DeckRecognizer {
|
|||||||
refLine = purgeAllLinks(refLine);
|
refLine = purgeAllLinks(refLine);
|
||||||
|
|
||||||
String line;
|
String line;
|
||||||
if (StringUtils.startsWith(refLine, LINE_COMMENT_DELIMITER_OR_MD_HEADER))
|
if (refLine.startsWith(LINE_COMMENT_DELIMITER_OR_MD_HEADER))
|
||||||
line = refLine.replaceAll(LINE_COMMENT_DELIMITER_OR_MD_HEADER, "");
|
line = refLine.replaceAll(LINE_COMMENT_DELIMITER_OR_MD_HEADER, "");
|
||||||
else
|
else
|
||||||
line = refLine.trim(); // Remove any trailing formatting
|
line = refLine.trim(); // Remove any trailing formatting
|
||||||
@@ -584,7 +598,7 @@ public class DeckRecognizer {
|
|||||||
// Final fantasy cards like Summon: Choco/Mog should be ommited to be recognized. TODO: fix maybe for future cards
|
// Final fantasy cards like Summon: Choco/Mog should be ommited to be recognized. TODO: fix maybe for future cards
|
||||||
if (!line.contains("Summon:"))
|
if (!line.contains("Summon:"))
|
||||||
line = SEARCH_SINGLE_SLASH.matcher(line).replaceFirst(" // ");
|
line = SEARCH_SINGLE_SLASH.matcher(line).replaceFirst(" // ");
|
||||||
if (StringUtils.startsWith(line, ASTERISK)) // markdown lists (tappedout md export)
|
if (line.startsWith(ASTERISK)) // Markdown lists (tappedout md export)
|
||||||
line = line.substring(2);
|
line = line.substring(2);
|
||||||
|
|
||||||
// == Patches to Corner Cases
|
// == Patches to Corner Cases
|
||||||
@@ -600,8 +614,8 @@ public class DeckRecognizer {
|
|||||||
Token result = recogniseCardToken(line, referenceSection);
|
Token result = recogniseCardToken(line, referenceSection);
|
||||||
if (result == null)
|
if (result == null)
|
||||||
result = recogniseNonCardToken(line);
|
result = recogniseNonCardToken(line);
|
||||||
return result != null ? result : StringUtils.startsWith(refLine, DOUBLE_SLASH) ||
|
return result != null ? result : refLine.startsWith(DOUBLE_SLASH) ||
|
||||||
StringUtils.startsWith(refLine, LINE_COMMENT_DELIMITER_OR_MD_HEADER) ?
|
refLine.startsWith(LINE_COMMENT_DELIMITER_OR_MD_HEADER) ?
|
||||||
new Token(TokenType.COMMENT, 0, refLine) : new Token(TokenType.UNKNOWN_TEXT, 0, refLine);
|
new Token(TokenType.COMMENT, 0, refLine) : new Token(TokenType.UNKNOWN_TEXT, 0, refLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,7 +627,7 @@ public class DeckRecognizer {
|
|||||||
while (m.find()) {
|
while (m.find()) {
|
||||||
line = line.replaceAll(m.group(), "").trim();
|
line = line.replaceAll(m.group(), "").trim();
|
||||||
}
|
}
|
||||||
if (StringUtils.endsWith(line, "()"))
|
if (line.endsWith("()"))
|
||||||
return line.substring(0, line.length()-2);
|
return line.substring(0, line.length()-2);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
@@ -741,21 +755,12 @@ public class DeckRecognizer {
|
|||||||
// This would save tons of time in parsing Input + would also allow to return UnsupportedCardTokens beforehand
|
// This would save tons of time in parsing Input + would also allow to return UnsupportedCardTokens beforehand
|
||||||
private DeckSection getTokenSection(String deckSec, DeckSection currentDeckSection, PaperCard card){
|
private DeckSection getTokenSection(String deckSec, DeckSection currentDeckSection, PaperCard card){
|
||||||
if (deckSec != null) {
|
if (deckSec != null) {
|
||||||
DeckSection cardSection;
|
DeckSection cardSection = switch (deckSec.toUpperCase().trim()) {
|
||||||
switch (deckSec.toUpperCase().trim()) {
|
case "MB" -> DeckSection.Main;
|
||||||
case "MB":
|
case "SB" -> DeckSection.Sideboard;
|
||||||
cardSection = DeckSection.Main;
|
case "CM" -> DeckSection.Commander;
|
||||||
break;
|
default -> DeckSection.matchingSection(card);
|
||||||
case "SB":
|
};
|
||||||
cardSection = DeckSection.Sideboard;
|
|
||||||
break;
|
|
||||||
case "CM":
|
|
||||||
cardSection = DeckSection.Commander;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cardSection = DeckSection.matchingSection(card);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (cardSection.validate(card))
|
if (cardSection.validate(card))
|
||||||
return cardSection;
|
return cardSection;
|
||||||
}
|
}
|
||||||
@@ -1017,51 +1022,21 @@ public class DeckRecognizer {
|
|||||||
private static MagicColor.Color getMagicColor(String colorName){
|
private static MagicColor.Color getMagicColor(String colorName){
|
||||||
if (colorName.toLowerCase().startsWith("multi") || colorName.equalsIgnoreCase("m"))
|
if (colorName.toLowerCase().startsWith("multi") || colorName.equalsIgnoreCase("m"))
|
||||||
return null; // will be handled separately
|
return null; // will be handled separately
|
||||||
|
return MagicColor.Color.fromByte(MagicColor.fromName(colorName.toLowerCase()));
|
||||||
byte color = MagicColor.fromName(colorName.toLowerCase());
|
|
||||||
switch (color) {
|
|
||||||
case MagicColor.WHITE:
|
|
||||||
return MagicColor.Color.WHITE;
|
|
||||||
case MagicColor.BLUE:
|
|
||||||
return MagicColor.Color.BLUE;
|
|
||||||
case MagicColor.BLACK:
|
|
||||||
return MagicColor.Color.BLACK;
|
|
||||||
case MagicColor.RED:
|
|
||||||
return MagicColor.Color.RED;
|
|
||||||
case MagicColor.GREEN:
|
|
||||||
return MagicColor.Color.GREEN;
|
|
||||||
default:
|
|
||||||
return MagicColor.Color.COLORLESS;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getLocalisedMagicColorName(String colorName){
|
public static String getLocalisedMagicColorName(String colorName){
|
||||||
Localizer localizer = Localizer.getInstance();
|
Localizer localizer = Localizer.getInstance();
|
||||||
switch(colorName.toLowerCase()){
|
return switch (colorName.toLowerCase()) {
|
||||||
case MagicColor.Constant.WHITE:
|
case MagicColor.Constant.WHITE -> localizer.getMessage("lblWhite");
|
||||||
return localizer.getMessage("lblWhite");
|
case MagicColor.Constant.BLUE -> localizer.getMessage("lblBlue");
|
||||||
|
case MagicColor.Constant.BLACK -> localizer.getMessage("lblBlack");
|
||||||
case MagicColor.Constant.BLUE:
|
case MagicColor.Constant.RED -> localizer.getMessage("lblRed");
|
||||||
return localizer.getMessage("lblBlue");
|
case MagicColor.Constant.GREEN -> localizer.getMessage("lblGreen");
|
||||||
|
case MagicColor.Constant.COLORLESS -> localizer.getMessage("lblColorless");
|
||||||
case MagicColor.Constant.BLACK:
|
case "multicolour", "multicolor" -> localizer.getMessage("lblMulticolor");
|
||||||
return localizer.getMessage("lblBlack");
|
default -> "";
|
||||||
|
};
|
||||||
case MagicColor.Constant.RED:
|
|
||||||
return localizer.getMessage("lblRed");
|
|
||||||
|
|
||||||
case MagicColor.Constant.GREEN:
|
|
||||||
return localizer.getMessage("lblGreen");
|
|
||||||
|
|
||||||
case MagicColor.Constant.COLORLESS:
|
|
||||||
return localizer.getMessage("lblColorless");
|
|
||||||
case "multicolour":
|
|
||||||
case "multicolor":
|
|
||||||
return localizer.getMessage("lblMulticolor");
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1080,37 +1055,6 @@ public class DeckRecognizer {
|
|||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Pair<String, String> getManaNameAndSymbol(String matchedMana) {
|
|
||||||
if (matchedMana == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Localizer localizer = Localizer.getInstance();
|
|
||||||
switch (matchedMana.toLowerCase()) {
|
|
||||||
case MagicColor.Constant.WHITE:
|
|
||||||
case "w":
|
|
||||||
return Pair.of(localizer.getMessage("lblWhite"), MagicColor.Color.WHITE.getSymbol());
|
|
||||||
case MagicColor.Constant.BLUE:
|
|
||||||
case "u":
|
|
||||||
return Pair.of(localizer.getMessage("lblBlue"), MagicColor.Color.BLUE.getSymbol());
|
|
||||||
case MagicColor.Constant.BLACK:
|
|
||||||
case "b":
|
|
||||||
return Pair.of(localizer.getMessage("lblBlack"), MagicColor.Color.BLACK.getSymbol());
|
|
||||||
case MagicColor.Constant.RED:
|
|
||||||
case "r":
|
|
||||||
return Pair.of(localizer.getMessage("lblRed"), MagicColor.Color.RED.getSymbol());
|
|
||||||
case MagicColor.Constant.GREEN:
|
|
||||||
case "g":
|
|
||||||
return Pair.of(localizer.getMessage("lblGreen"), MagicColor.Color.GREEN.getSymbol());
|
|
||||||
case MagicColor.Constant.COLORLESS:
|
|
||||||
case "c":
|
|
||||||
return Pair.of(localizer.getMessage("lblColorless"), MagicColor.Color.COLORLESS.getSymbol());
|
|
||||||
default: // Multicolour
|
|
||||||
return Pair.of(localizer.getMessage("lblMulticolor"), "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDeckName(final String lineAsIs) {
|
public static boolean isDeckName(final String lineAsIs) {
|
||||||
if (lineAsIs == null)
|
if (lineAsIs == null)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class AddBasicLandsDialog {
|
|||||||
private static final int LAND_PANEL_PADDING = 3;
|
private static final int LAND_PANEL_PADDING = 3;
|
||||||
|
|
||||||
private final FComboBoxPanel<CardEdition> cbLandSet = new FComboBoxPanel<>(Localizer.getInstance().getMessage("lblLandSet") + ":", FlowLayout.CENTER,
|
private final FComboBoxPanel<CardEdition> cbLandSet = new FComboBoxPanel<>(Localizer.getInstance().getMessage("lblLandSet") + ":", FlowLayout.CENTER,
|
||||||
IterableUtil.filter(StaticData.instance().getSortedEditions(), CardEdition.Predicates.hasBasicLands));
|
IterableUtil.filter(StaticData.instance().getSortedEditions(), CardEdition::hasBasicLands));
|
||||||
|
|
||||||
private final MainPanel panel = new MainPanel();
|
private final MainPanel panel = new MainPanel();
|
||||||
private final LandPanel pnlPlains = new LandPanel("Plains");
|
private final LandPanel pnlPlains = new LandPanel("Plains");
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ import forge.toolbox.*;
|
|||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
import forge.view.FDialog;
|
import forge.view.FDialog;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import static forge.deck.DeckRecognizer.TokenType.*;
|
import static forge.deck.DeckRecognizer.TokenType.*;
|
||||||
|
|
||||||
@@ -523,7 +522,7 @@ public class DeckImport<TModel extends DeckBase> extends FDialog {
|
|||||||
else
|
else
|
||||||
deck.setName(currentDeckName);
|
deck.setName(currentDeckName);
|
||||||
}
|
}
|
||||||
host.getDeckController().loadDeck(deck, controller.getCreateNewDeck());
|
host.getDeckController().loadDeck(deck, controller.getImportBehavior() != DeckImportController.ImportBehavior.MERGE);
|
||||||
processWindowEvent(new WindowEvent(DeckImport.this, WindowEvent.WINDOW_CLOSING));
|
processWindowEvent(new WindowEvent(DeckImport.this, WindowEvent.WINDOW_CLOSING));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -531,7 +530,7 @@ public class DeckImport<TModel extends DeckBase> extends FDialog {
|
|||||||
this.createNewDeckCheckbox.setSelected(false);
|
this.createNewDeckCheckbox.setSelected(false);
|
||||||
this.createNewDeckCheckbox.addActionListener(e -> {
|
this.createNewDeckCheckbox.addActionListener(e -> {
|
||||||
boolean createNewDeck = createNewDeckCheckbox.isSelected();
|
boolean createNewDeck = createNewDeckCheckbox.isSelected();
|
||||||
controller.setCreateNewDeck(createNewDeck);
|
controller.setImportBehavior(createNewDeck ? DeckImportController.ImportBehavior.CREATE_NEW : DeckImportController.ImportBehavior.MERGE);
|
||||||
String cmdAcceptLabel = createNewDeck ? CREATE_NEW_DECK_CMD_LABEL : IMPORT_CARDS_CMD_LABEL;
|
String cmdAcceptLabel = createNewDeck ? CREATE_NEW_DECK_CMD_LABEL : IMPORT_CARDS_CMD_LABEL;
|
||||||
cmdAcceptButton.setText(cmdAcceptLabel);
|
cmdAcceptButton.setText(cmdAcceptLabel);
|
||||||
String smartCardArtChboxTooltip = createNewDeck ? SMART_CARDART_TT_NO_DECK : SMART_CARDART_TT_WITH_DECK;
|
String smartCardArtChboxTooltip = createNewDeck ? SMART_CARDART_TT_NO_DECK : SMART_CARDART_TT_WITH_DECK;
|
||||||
@@ -600,7 +599,7 @@ public class DeckImport<TModel extends DeckBase> extends FDialog {
|
|||||||
if (token.getType() == LIMITED_CARD)
|
if (token.getType() == LIMITED_CARD)
|
||||||
cssClass = WARN_MSG_CLASS;
|
cssClass = WARN_MSG_CLASS;
|
||||||
String statusMsg = String.format("<span class=\"%s\" style=\"font-size: 9px;\">%s</span>", cssClass,
|
String statusMsg = String.format("<span class=\"%s\" style=\"font-size: 9px;\">%s</span>", cssClass,
|
||||||
getTokenStatusMessage(token));
|
controller.getTokenStatusMessage(token));
|
||||||
statusLbl.append(statusMsg);
|
statusLbl.append(statusMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,12 +739,12 @@ public class DeckImport<TModel extends DeckBase> extends FDialog {
|
|||||||
private String toHTML(final DeckRecognizer.Token token) {
|
private String toHTML(final DeckRecognizer.Token token) {
|
||||||
if (token == null)
|
if (token == null)
|
||||||
return "";
|
return "";
|
||||||
String tokenMsg = getTokenMessage(token);
|
String tokenMsg = controller.getTokenMessage(token);
|
||||||
if (tokenMsg == null)
|
if (tokenMsg == null)
|
||||||
return "";
|
return "";
|
||||||
String tokenStatus = getTokenStatusMessage(token);
|
String tokenStatus = controller.getTokenStatusMessage(token);
|
||||||
String cssClass = getTokenCSSClass(token.getType());
|
String cssClass = getTokenCSSClass(token.getType());
|
||||||
if (tokenStatus.length() == 0)
|
if (tokenStatus.isEmpty())
|
||||||
tokenMsg = padEndWithHTMLSpaces(tokenMsg, 2*PADDING_TOKEN_MSG_LENGTH+10);
|
tokenMsg = padEndWithHTMLSpaces(tokenMsg, 2*PADDING_TOKEN_MSG_LENGTH+10);
|
||||||
else {
|
else {
|
||||||
tokenMsg = padEndWithHTMLSpaces(tokenMsg, PADDING_TOKEN_MSG_LENGTH);
|
tokenMsg = padEndWithHTMLSpaces(tokenMsg, PADDING_TOKEN_MSG_LENGTH);
|
||||||
@@ -755,11 +754,6 @@ public class DeckImport<TModel extends DeckBase> extends FDialog {
|
|||||||
tokenMsg = String.format("<a class=\"%s\" href=\"%s\">%s</a>", cssClass,
|
tokenMsg = String.format("<a class=\"%s\" href=\"%s\">%s</a>", cssClass,
|
||||||
token.getKey().toString(), tokenMsg);
|
token.getKey().toString(), tokenMsg);
|
||||||
|
|
||||||
if (tokenStatus == null) {
|
|
||||||
String tokenTag = String.format("<td colspan=\"2\" class=\"%s\">%s</td>", cssClass, tokenMsg);
|
|
||||||
return String.format("<tr>%s</tr>", tokenTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
String tokenTag = "<td class=\"%s\">%s</td>";
|
String tokenTag = "<td class=\"%s\">%s</td>";
|
||||||
String tokenMsgTag = String.format(tokenTag, cssClass, tokenMsg);
|
String tokenMsgTag = String.format(tokenTag, cssClass, tokenMsg);
|
||||||
String tokenStatusTag;
|
String tokenStatusTag;
|
||||||
@@ -776,97 +770,6 @@ public class DeckImport<TModel extends DeckBase> extends FDialog {
|
|||||||
return String.format("%s%s", targetMsg, spacer);
|
return String.format("%s%s", targetMsg, spacer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTokenMessage(DeckRecognizer.Token token) {
|
|
||||||
switch (token.getType()) {
|
|
||||||
case LEGAL_CARD:
|
|
||||||
case LIMITED_CARD:
|
|
||||||
case CARD_FROM_NOT_ALLOWED_SET:
|
|
||||||
case CARD_FROM_INVALID_SET:
|
|
||||||
return String.format("%s x %s %s", token.getQuantity(), token.getText(), getTokenFoilLabel(token));
|
|
||||||
// Card Warning Msgs
|
|
||||||
case UNKNOWN_CARD:
|
|
||||||
case UNSUPPORTED_CARD:
|
|
||||||
return token.getQuantity() > 0 ? String.format("%s x %s", token.getQuantity(), token.getText())
|
|
||||||
: token.getText();
|
|
||||||
|
|
||||||
case UNSUPPORTED_DECK_SECTION:
|
|
||||||
return String.format("%s: %s", Localizer.getInstance().getMessage("lblWarningMsgPrefix"),
|
|
||||||
Localizer.getInstance()
|
|
||||||
.getMessage("lblWarnDeckSectionNotAllowedInEditor", token.getText(),
|
|
||||||
this.currentGameType));
|
|
||||||
|
|
||||||
// Special Case of Card moved into another section (e.g. Commander from Sideboard)
|
|
||||||
case WARNING_MESSAGE:
|
|
||||||
return String.format("%s: %s", Localizer.getInstance()
|
|
||||||
.getMessage("lblWarningMsgPrefix"), token.getText());
|
|
||||||
|
|
||||||
// Placeholders
|
|
||||||
case DECK_SECTION_NAME:
|
|
||||||
return String.format("%s: %s", Localizer.getInstance().getMessage("lblDeckSection"),
|
|
||||||
token.getText());
|
|
||||||
|
|
||||||
case CARD_RARITY:
|
|
||||||
return String.format("%s: %s", Localizer.getInstance().getMessage("lblRarity"),
|
|
||||||
token.getText());
|
|
||||||
|
|
||||||
case CARD_TYPE:
|
|
||||||
case CARD_CMC:
|
|
||||||
case MANA_COLOUR:
|
|
||||||
case COMMENT:
|
|
||||||
return token.getText();
|
|
||||||
|
|
||||||
case DECK_NAME:
|
|
||||||
return String.format("%s: %s", Localizer.getInstance().getMessage("lblDeckName"),
|
|
||||||
token.getText());
|
|
||||||
|
|
||||||
case UNKNOWN_TEXT:
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getTokenStatusMessage(DeckRecognizer.Token token){
|
|
||||||
if (token == null)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
switch (token.getType()) {
|
|
||||||
case LIMITED_CARD:
|
|
||||||
return String.format("%s: %s", Localizer.getInstance().getMessage("lblWarningMsgPrefix"),
|
|
||||||
Localizer.getInstance().getMessage("lblWarnLimitedCard",
|
|
||||||
StringUtils.capitalize(token.getLimitedCardType().name()), getGameFormatLabel()));
|
|
||||||
|
|
||||||
case CARD_FROM_NOT_ALLOWED_SET:
|
|
||||||
return Localizer.getInstance().getMessage("lblErrNotAllowedCard", getGameFormatLabel());
|
|
||||||
|
|
||||||
case CARD_FROM_INVALID_SET:
|
|
||||||
return Localizer.getInstance().getMessage("lblErrCardEditionDate");
|
|
||||||
|
|
||||||
case UNSUPPORTED_CARD:
|
|
||||||
return Localizer.getInstance().getMessage("lblErrUnsupportedCard", this.currentGameType);
|
|
||||||
|
|
||||||
case UNKNOWN_CARD:
|
|
||||||
return String.format("%s: %s", Localizer.getInstance().getMessage("lblWarningMsgPrefix"),
|
|
||||||
Localizer.getInstance().getMessage("lblWarnUnknownCardMsg"));
|
|
||||||
|
|
||||||
case UNSUPPORTED_DECK_SECTION:
|
|
||||||
case WARNING_MESSAGE:
|
|
||||||
case COMMENT:
|
|
||||||
case CARD_CMC:
|
|
||||||
case MANA_COLOUR:
|
|
||||||
case CARD_TYPE:
|
|
||||||
case DECK_SECTION_NAME:
|
|
||||||
case CARD_RARITY:
|
|
||||||
case DECK_NAME:
|
|
||||||
case LEGAL_CARD:
|
|
||||||
case UNKNOWN_TEXT:
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getTokenCSSClass(DeckRecognizer.TokenType tokenType){
|
private String getTokenCSSClass(DeckRecognizer.TokenType tokenType){
|
||||||
switch (tokenType){
|
switch (tokenType){
|
||||||
case LEGAL_CARD:
|
case LEGAL_CARD:
|
||||||
@@ -899,17 +802,6 @@ public class DeckImport<TModel extends DeckBase> extends FDialog {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTokenFoilLabel(DeckRecognizer.Token token) {
|
|
||||||
if (!token.isCardToken())
|
|
||||||
return "";
|
|
||||||
final String foilMarker = "- (Foil)";
|
|
||||||
return token.getCard().isFoil() ? foilMarker : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getGameFormatLabel() {
|
|
||||||
return String.format("\"%s\"", this.controller.getCurrentGameFormatName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class GameFormatDropdownRenderer extends JLabel implements ListCellRenderer<GameFormat> {
|
class GameFormatDropdownRenderer extends JLabel implements ListCellRenderer<GameFormat> {
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import forge.item.PaperCard;
|
|||||||
import forge.itemmanager.*;
|
import forge.itemmanager.*;
|
||||||
import forge.itemmanager.filters.CardColorFilter;
|
import forge.itemmanager.filters.CardColorFilter;
|
||||||
import forge.itemmanager.filters.CardTypeFilter;
|
import forge.itemmanager.filters.CardTypeFilter;
|
||||||
import forge.localinstance.properties.ForgePreferences;
|
|
||||||
import forge.menu.FCheckBoxMenuItem;
|
|
||||||
import forge.menu.FDropDownMenu;
|
import forge.menu.FDropDownMenu;
|
||||||
import forge.menu.FMenuItem;
|
import forge.menu.FMenuItem;
|
||||||
import forge.menu.FPopupMenu;
|
import forge.menu.FPopupMenu;
|
||||||
@@ -41,6 +39,7 @@ import forge.util.Utils;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class AdventureDeckEditor extends FDeckEditor {
|
public class AdventureDeckEditor extends FDeckEditor {
|
||||||
protected static class AdventureEditorConfig extends DeckEditorConfig {
|
protected static class AdventureEditorConfig extends DeckEditorConfig {
|
||||||
@@ -146,7 +145,8 @@ public class AdventureDeckEditor extends FDeckEditor {
|
|||||||
if(event.cardBlock != null) {
|
if(event.cardBlock != null) {
|
||||||
if(event.cardBlock.getLandSet() != null)
|
if(event.cardBlock.getLandSet() != null)
|
||||||
return List.of(event.cardBlock.getLandSet());
|
return List.of(event.cardBlock.getLandSet());
|
||||||
List<CardEdition> eventSets = event.cardBlock.getSets();
|
List<CardEdition> eventSets = new ArrayList<>(event.cardBlock.getSets());
|
||||||
|
eventSets.removeIf(Predicate.not(CardEdition::hasBasicLands));
|
||||||
if(!eventSets.isEmpty())
|
if(!eventSets.isEmpty())
|
||||||
return eventSets;
|
return eventSets;
|
||||||
}
|
}
|
||||||
@@ -558,7 +558,7 @@ public class AdventureDeckEditor extends FDeckEditor {
|
|||||||
currentEvent.participants[i].setDeck(opponentDecks[i]);
|
currentEvent.participants[i].setDeck(opponentDecks[i]);
|
||||||
}
|
}
|
||||||
currentEvent.draftedDeck = (Deck) currentEvent.registeredDeck.copyTo("Draft Deck");
|
currentEvent.draftedDeck = (Deck) currentEvent.registeredDeck.copyTo("Draft Deck");
|
||||||
if (allowsAddBasic()) {
|
if (allowAddBasic()) {
|
||||||
showAddBasicLandsDialog();
|
showAddBasicLandsDialog();
|
||||||
//Might be annoying if you haven't pruned your deck yet, but best to remind player that
|
//Might be annoying if you haven't pruned your deck yet, but best to remind player that
|
||||||
//this probably needs to be done since it's there since it's not normally part of Adventure
|
//this probably needs to be done since it's there since it's not normally part of Adventure
|
||||||
@@ -713,27 +713,6 @@ public class AdventureDeckEditor extends FDeckEditor {
|
|||||||
return this.deckHeader;
|
return this.deckHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected FPopupMenu createMoreOptionsMenu() {
|
|
||||||
return new FPopupMenu() {
|
|
||||||
@Override
|
|
||||||
protected void buildMenu() {
|
|
||||||
Localizer localizer = Forge.getLocalizer();
|
|
||||||
addItem(new FMenuItem(localizer.getMessage("btnCopyToClipboard"), Forge.hdbuttons ? FSkinImage.HDEXPORT : FSkinImage.BLANK, e1 -> FDeckViewer.copyDeckToClipboard(getDeck())));
|
|
||||||
if (allowsAddBasic()) {
|
|
||||||
FMenuItem addBasic = new FMenuItem(localizer.getMessage("lblAddBasicLands"), FSkinImage.LANDLOGO, e1 -> showAddBasicLandsDialog());
|
|
||||||
addItem(addBasic);
|
|
||||||
}
|
|
||||||
if(FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.DEV_MODE_ENABLED)) {
|
|
||||||
addItem(new FCheckBoxMenuItem(localizer.getMessage("cbEnforceDeckLegality"), shouldEnforceConformity(), e -> toggleConformity()));
|
|
||||||
String devSuffix = " (" + localizer.getMessage("lblDev") + ")";
|
|
||||||
addItem(new FMenuItem(localizer.getMessage("lblAddcard") + devSuffix, FSkinImage.HDPLUS, e -> showDevAddCardDialog()));
|
|
||||||
}
|
|
||||||
((DeckEditorPage) getSelectedPage()).buildDeckMenu(this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addChosenBasicLands(CardPool landsToAdd) {
|
protected void addChosenBasicLands(CardPool landsToAdd) {
|
||||||
if(isLimitedEditor())
|
if(isLimitedEditor())
|
||||||
@@ -765,6 +744,12 @@ public class AdventureDeckEditor extends FDeckEditor {
|
|||||||
catalog.moveCards(landsToMove, getMainDeckPage());
|
catalog.moveCards(landsToMove, getMainDeckPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PaperCard supplyPrintForImporter(PaperCard missingCard) {
|
||||||
|
PaperCard out = super.supplyPrintForImporter(missingCard);
|
||||||
|
return out == null ? null : out.getNoSellVersion();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void cacheTabPages() {
|
protected void cacheTabPages() {
|
||||||
super.cacheTabPages();
|
super.cacheTabPages();
|
||||||
@@ -775,7 +760,9 @@ public class AdventureDeckEditor extends FDeckEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean allowsAddBasic() {
|
protected boolean allowAddBasic() {
|
||||||
|
if(getEditorConfig() instanceof DeckPreviewConfig)
|
||||||
|
return false;
|
||||||
AdventureEventData currentEvent = getCurrentEvent();
|
AdventureEventData currentEvent = getCurrentEvent();
|
||||||
if (currentEvent == null)
|
if (currentEvent == null)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class AddBasicLandsDialog extends FDialog {
|
|||||||
private final Consumer<CardPool> callback;
|
private final Consumer<CardPool> callback;
|
||||||
|
|
||||||
private final FLabel lblLandSet = add(new FLabel.Builder().text(Forge.getLocalizer().getMessage("lblLandSet") + ":").font(FSkinFont.get(12)).textColor(FLabel.getInlineLabelColor()).build());
|
private final FLabel lblLandSet = add(new FLabel.Builder().text(Forge.getLocalizer().getMessage("lblLandSet") + ":").font(FSkinFont.get(12)).textColor(FLabel.getInlineLabelColor()).build());
|
||||||
private final FComboBox<CardEdition> cbLandSet = add(new FComboBox<>(IterableUtil.filter(StaticData.instance().getEditions(), CardEdition.Predicates.hasBasicLands)));
|
private final FComboBox<CardEdition> cbLandSet = add(new FComboBox<>(IterableUtil.filter(StaticData.instance().getSortedEditions(), CardEdition::hasBasicLands)));
|
||||||
|
|
||||||
private final FScrollPane scroller = add(new FScrollPane() {
|
private final FScrollPane scroller = add(new FScrollPane() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -81,13 +81,21 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
public boolean allowsCardReplacement() { return hasInfiniteCardPool() || usePlayerInventory(); }
|
public boolean allowsCardReplacement() { return hasInfiniteCardPool() || usePlayerInventory(); }
|
||||||
|
|
||||||
public List<CardEdition> getBasicLandSets(Deck currentDeck) {
|
public List<CardEdition> getBasicLandSets(Deck currentDeck) {
|
||||||
|
if(hasInfiniteCardPool())
|
||||||
|
return FModel.getMagicDb().getSortedEditions().stream().filter(CardEdition::hasBasicLands).collect(Collectors.toList());
|
||||||
return List.of(DeckProxy.getDefaultLandSet(currentDeck));
|
return List.of(DeckProxy.getDefaultLandSet(currentDeck));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IDeckController getController();
|
protected abstract IDeckController getController();
|
||||||
protected abstract DeckEditorPage[] getInitialPages();
|
protected abstract DeckEditorPage[] getInitialPages();
|
||||||
|
|
||||||
protected DeckSection[] getExtraSections() {
|
public DeckSection[] getPrimarySections() {
|
||||||
|
if(getGameType() != null)
|
||||||
|
return getGameType().getPrimaryDeckSections().toArray(new DeckSection[0]);
|
||||||
|
return new DeckSection[]{DeckSection.Main, DeckSection.Sideboard};
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeckSection[] getExtraSections() {
|
||||||
if(getGameType() != null)
|
if(getGameType() != null)
|
||||||
return getGameType().getSupplimentalDeckSections().toArray(new DeckSection[0]);
|
return getGameType().getSupplimentalDeckSections().toArray(new DeckSection[0]);
|
||||||
return new DeckSection[]{DeckSection.Attractions, DeckSection.Contraptions};
|
return new DeckSection[]{DeckSection.Attractions, DeckSection.Contraptions};
|
||||||
@@ -144,7 +152,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
ItemManagerConfig catalogConfig = null;
|
ItemManagerConfig catalogConfig = null;
|
||||||
ItemManagerConfig mainSectionConfig = null;
|
ItemManagerConfig mainSectionConfig = null;
|
||||||
ItemManagerConfig sideboardConfig = null;
|
ItemManagerConfig sideboardConfig = null;
|
||||||
Function<Deck, CardEdition> fnGetBasicLandSet = null;
|
Function<Deck, Collection<CardEdition>> fnGetBasicLandSet = null;
|
||||||
Supplier<ItemPool<PaperCard>> itemPoolSupplier = null;
|
Supplier<ItemPool<PaperCard>> itemPoolSupplier = null;
|
||||||
String catalogCaption = null;
|
String catalogCaption = null;
|
||||||
|
|
||||||
@@ -196,7 +204,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
this.sideboardConfig = sideboardConfig;
|
this.sideboardConfig = sideboardConfig;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public GameTypeDeckEditorConfig setBasicLandSetFunction(Function<Deck, CardEdition> fnGetBasicLandSet) {
|
public GameTypeDeckEditorConfig setBasicLandSetFunction(Function<Deck, Collection<CardEdition>> fnGetBasicLandSet) {
|
||||||
this.fnGetBasicLandSet = fnGetBasicLandSet;
|
this.fnGetBasicLandSet = fnGetBasicLandSet;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -296,9 +304,21 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DeckSection[] getExtraSections() {
|
public DeckSection[] getPrimarySections() {
|
||||||
|
return gameType.getPrimaryDeckSections().toArray(new DeckSection[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeckSection[] getExtraSections() {
|
||||||
return gameType.getSupplimentalDeckSections().toArray(new DeckSection[0]);
|
return gameType.getSupplimentalDeckSections().toArray(new DeckSection[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CardEdition> getBasicLandSets(Deck currentDeck) {
|
||||||
|
if(this.fnGetBasicLandSet != null)
|
||||||
|
return List.copyOf(fnGetBasicLandSet.apply(currentDeck));
|
||||||
|
return super.getBasicLandSets(currentDeck);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DeckEditorConfig EditorConfigConstructed = new GameTypeDeckEditorConfig(GameType.Constructed,
|
public static DeckEditorConfig EditorConfigConstructed = new GameTypeDeckEditorConfig(GameType.Constructed,
|
||||||
@@ -348,18 +368,19 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
.setMainSectionConfig(ItemManagerConfig.QUEST_DECK_EDITOR)
|
.setMainSectionConfig(ItemManagerConfig.QUEST_DECK_EDITOR)
|
||||||
.setSideboardConfig(ItemManagerConfig.QUEST_DECK_EDITOR)
|
.setSideboardConfig(ItemManagerConfig.QUEST_DECK_EDITOR)
|
||||||
.setPlayerInventorySupplier(() -> FModel.getQuest().getCards().getCardpool())
|
.setPlayerInventorySupplier(() -> FModel.getQuest().getCards().getCardpool())
|
||||||
.setBasicLandSetFunction(d -> FModel.getQuest().getDefaultLandSet());
|
.setBasicLandSetFunction(d -> FModel.getQuest().getAvailableLandSets());
|
||||||
public static DeckEditorConfig EditorConfigQuestCommander = new GameTypeDeckEditorConfig(GameType.QuestCommander, DECK_CONTROLLER_QUEST)
|
public static DeckEditorConfig EditorConfigQuestCommander = new GameTypeDeckEditorConfig(GameType.QuestCommander, DECK_CONTROLLER_QUEST)
|
||||||
.setCatalogConfig(ItemManagerConfig.QUEST_EDITOR_POOL)
|
.setCatalogConfig(ItemManagerConfig.QUEST_EDITOR_POOL)
|
||||||
.setMainSectionConfig(ItemManagerConfig.QUEST_DECK_EDITOR)
|
.setMainSectionConfig(ItemManagerConfig.QUEST_DECK_EDITOR)
|
||||||
.setSideboardConfig(ItemManagerConfig.QUEST_DECK_EDITOR)
|
.setSideboardConfig(ItemManagerConfig.QUEST_DECK_EDITOR)
|
||||||
.setPlayerInventorySupplier(() -> FModel.getQuest().getCards().getCardpool())
|
.setPlayerInventorySupplier(() -> FModel.getQuest().getCards().getCardpool())
|
||||||
.setBasicLandSetFunction(d -> FModel.getQuest().getDefaultLandSet());
|
.setBasicLandSetFunction(d -> FModel.getQuest().getAvailableLandSets());
|
||||||
public static DeckEditorConfig EditorConfigQuestDraft = new GameTypeDeckEditorConfig(GameType.QuestDraft, DECK_CONTROLLER_QUEST_DRAFT);
|
public static DeckEditorConfig EditorConfigQuestDraft = new GameTypeDeckEditorConfig(GameType.QuestDraft, DECK_CONTROLLER_QUEST_DRAFT);
|
||||||
public static DeckEditorConfig EditorConfigPlanarConquest = new GameTypeDeckEditorConfig(GameType.PlanarConquest, DECK_CONTROLLER_PLANAR_CONQUEST)
|
public static DeckEditorConfig EditorConfigPlanarConquest = new GameTypeDeckEditorConfig(GameType.PlanarConquest, DECK_CONTROLLER_PLANAR_CONQUEST)
|
||||||
.setCatalogConfig(ItemManagerConfig.CONQUEST_COLLECTION)
|
.setCatalogConfig(ItemManagerConfig.CONQUEST_COLLECTION)
|
||||||
.setMainSectionConfig(ItemManagerConfig.CONQUEST_DECK_EDITOR)
|
.setMainSectionConfig(ItemManagerConfig.CONQUEST_DECK_EDITOR)
|
||||||
.setPlayerInventorySupplier(ConquestUtil::getAvailablePool);
|
.setPlayerInventorySupplier(ConquestUtil::getAvailablePool)
|
||||||
|
.setBasicLandSetFunction(ConquestUtil::getBasicLandSets);
|
||||||
|
|
||||||
protected static DeckSectionPage createPageForExtraSection(DeckSection deckSection, DeckEditorConfig editorConfig) {
|
protected static DeckSectionPage createPageForExtraSection(DeckSection deckSection, DeckEditorConfig editorConfig) {
|
||||||
CardManager cm = new CardManager(false);
|
CardManager cm = new CardManager(false);
|
||||||
@@ -542,7 +563,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
@Override
|
@Override
|
||||||
protected void buildMenu() {
|
protected void buildMenu() {
|
||||||
final Localizer localizer = Forge.getLocalizer();
|
final Localizer localizer = Forge.getLocalizer();
|
||||||
if (allowsAddBasic())
|
if (allowAddBasic())
|
||||||
addItem(new FMenuItem(localizer.getMessage("lblAddBasicLands"), FSkinImage.LANDLOGO, e -> showAddBasicLandsDialog()));
|
addItem(new FMenuItem(localizer.getMessage("lblAddBasicLands"), FSkinImage.LANDLOGO, e -> showAddBasicLandsDialog()));
|
||||||
if (showAddExtraSectionOption()) {
|
if (showAddExtraSectionOption()) {
|
||||||
addItem(new FMenuItem(localizer.getMessage("lblAddDeckSection"), FSkinImage.CHAOS, e -> {
|
addItem(new FMenuItem(localizer.getMessage("lblAddDeckSection"), FSkinImage.CHAOS, e -> {
|
||||||
@@ -558,21 +579,33 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
if (editorConfig.getGameType() != null && editorConfig.hasInfiniteCardPool()) {
|
if (editorConfig.hasInfiniteCardPool() || editorConfig.usePlayerInventory()) {
|
||||||
addItem(new FMenuItem(localizer.getMessage("lblImportFromClipboard"), Forge.hdbuttons ? FSkinImage.HDIMPORT : FSkinImage.OPEN, e -> {
|
addItem(new FMenuItem(localizer.getMessage("lblImportFromClipboard"), Forge.hdbuttons ? FSkinImage.HDIMPORT : FSkinImage.OPEN, e -> {
|
||||||
FDeckImportDialog dialog = new FDeckImportDialog(!deck.isEmpty(), FDeckEditor.this.editorConfig);
|
FDeckImportDialog dialog = new FDeckImportDialog(deck, FDeckEditor.this.editorConfig);
|
||||||
|
if(editorConfig.usePlayerInventory())
|
||||||
|
dialog.setFreePrintConverter(FDeckEditor.this::supplyPrintForImporter);
|
||||||
|
dialog.setImportBannedCards(!FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY));
|
||||||
dialog.setCallback(importedDeck -> {
|
dialog.setCallback(importedDeck -> {
|
||||||
if (deck != null && importedDeck.hasName()) {
|
if (deck != null && importedDeck.hasName()) {
|
||||||
deck.setName(importedDeck.getName());
|
deck.setName(importedDeck.getName());
|
||||||
setHeaderText(importedDeck.getName());
|
setHeaderText(importedDeck.getName());
|
||||||
}
|
}
|
||||||
if (dialog.createNewDeck()) {
|
switch (dialog.getImportBehavior()) {
|
||||||
for (Entry<DeckSection, CardPool> section : importedDeck) {
|
case REPLACE_CURRENT:
|
||||||
DeckSectionPage page = getPageForSection(section.getKey());
|
for(DeckSectionPage page : pagesBySection.values()) {
|
||||||
if (page != null)
|
if(importedDeck.has(page.deckSection)) {
|
||||||
page.setCards(section.getValue());
|
page.setCards(importedDeck.get(page.deckSection));
|
||||||
|
if(hiddenExtraSections.contains(page.deckSection))
|
||||||
|
showExtraSectionTab(page.deckSection);
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
|
page.setCards(new CardPool());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CREATE_NEW:
|
||||||
|
deckController.setDeck(importedDeck);
|
||||||
|
break;
|
||||||
|
case MERGE:
|
||||||
for (Entry<DeckSection, CardPool> section : importedDeck) {
|
for (Entry<DeckSection, CardPool> section : importedDeck) {
|
||||||
DeckSectionPage page = getPageForSection(section.getKey());
|
DeckSectionPage page = getPageForSection(section.getKey());
|
||||||
if (page != null)
|
if (page != null)
|
||||||
@@ -580,6 +613,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
dialog.initParse();
|
||||||
dialog.show();
|
dialog.show();
|
||||||
setSelectedPage(getMainDeckPage()); //select main deck page if needed so main deck if visible below dialog
|
setSelectedPage(getMainDeckPage()); //select main deck page if needed so main deck if visible below dialog
|
||||||
}));
|
}));
|
||||||
@@ -643,6 +677,20 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
getMainDeckPage().addCards(landsToAdd);
|
getMainDeckPage().addCards(landsToAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a card is missing from a player's inventory while importing a deck, it gets run through here.
|
||||||
|
* Returning a PaperCard will let unlimited copies of that card be used as a substitute. Returning null
|
||||||
|
* will leave the card missing from the import.
|
||||||
|
*/
|
||||||
|
protected PaperCard supplyPrintForImporter(PaperCard missingCard) {
|
||||||
|
//Could support dungeons here too? Not that we really use them in the editor...
|
||||||
|
if(!missingCard.isVeryBasicLand())
|
||||||
|
return null;
|
||||||
|
List<CardEdition> basicSets = editorConfig.getBasicLandSets(deck);
|
||||||
|
String setCode = basicSets.isEmpty() ? "JMP" : basicSets.get(0).getCode();
|
||||||
|
return FModel.getMagicDb().fetchCard(missingCard.getCardName(), setCode, null);
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean shouldEnforceConformity() {
|
protected boolean shouldEnforceConformity() {
|
||||||
if(FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY))
|
if(FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY))
|
||||||
return true;
|
return true;
|
||||||
@@ -695,6 +743,9 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
showExtraSectionTab(section);
|
showExtraSectionTab(section);
|
||||||
if(pagesBySection.containsKey(section))
|
if(pagesBySection.containsKey(section))
|
||||||
setSelectedPage(pagesBySection.get(section));
|
setSelectedPage(pagesBySection.get(section));
|
||||||
|
else if(section == DeckSection.Main && pagesBySection.containsKey(mainDeckPage.deckSection))
|
||||||
|
//Tried to switch to the Main page in a Planar or Scheme deck.
|
||||||
|
setSelectedPage(pagesBySection.get(mainDeckPage.deckSection));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyNewControllerModel() {
|
public void notifyNewControllerModel() {
|
||||||
@@ -1027,7 +1078,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
protected boolean allowSaveAs() {
|
protected boolean allowSaveAs() {
|
||||||
return allowSave() && allowRename();
|
return allowSave() && allowRename();
|
||||||
}
|
}
|
||||||
protected boolean allowsAddBasic() {
|
protected boolean allowAddBasic() {
|
||||||
return !isDrafting();
|
return !isDrafting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,12 @@
|
|||||||
package forge.deck;
|
package forge.deck;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
@@ -31,11 +32,15 @@ import forge.deck.DeckRecognizer.TokenType;
|
|||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
import forge.gui.FThreads;
|
import forge.gui.FThreads;
|
||||||
import forge.gui.util.SOptionPane;
|
import forge.gui.util.SOptionPane;
|
||||||
|
import forge.item.PaperCard;
|
||||||
import forge.toolbox.FCheckBox;
|
import forge.toolbox.FCheckBox;
|
||||||
import forge.toolbox.FComboBox;
|
import forge.toolbox.FComboBox;
|
||||||
import forge.toolbox.FDialog;
|
import forge.toolbox.FDialog;
|
||||||
import forge.toolbox.FOptionPane;
|
import forge.toolbox.FOptionPane;
|
||||||
import forge.toolbox.FTextArea;
|
import forge.toolbox.FTextArea;
|
||||||
|
import forge.util.ItemPool;
|
||||||
|
import forge.util.Localizer;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
public class FDeckImportDialog extends FDialog {
|
public class FDeckImportDialog extends FDialog {
|
||||||
@@ -45,7 +50,7 @@ public class FDeckImportDialog extends FDialog {
|
|||||||
private final FCheckBox newEditionCheck = add(new FCheckBox(Forge.getLocalizer().getMessage("lblImportLatestVersionCard"), false));
|
private final FCheckBox newEditionCheck = add(new FCheckBox(Forge.getLocalizer().getMessage("lblImportLatestVersionCard"), false));
|
||||||
private final FCheckBox dateTimeCheck = add(new FCheckBox(Forge.getLocalizer().getMessage("lblUseOnlySetsReleasedBefore"), false));
|
private final FCheckBox dateTimeCheck = add(new FCheckBox(Forge.getLocalizer().getMessage("lblUseOnlySetsReleasedBefore"), false));
|
||||||
private final FCheckBox smartCardArtCheck = add(new FCheckBox(Forge.getLocalizer().getMessage("lblUseSmartCardArt"), false));
|
private final FCheckBox smartCardArtCheck = add(new FCheckBox(Forge.getLocalizer().getMessage("lblUseSmartCardArt"), false));
|
||||||
private final FCheckBox createNewDeckCheck = add(new FCheckBox(Forge.getLocalizer().getMessage("lblNewDeckCheckbox"), false));
|
private final FCheckBox createNewDeckCheck = add(new FCheckBox(Forge.getLocalizer().getMessage("lblReplaceDeckCheckbox"), false));
|
||||||
// private final FCheckBox importInDeck = add(new FCheckBox()
|
// private final FCheckBox importInDeck = add(new FCheckBox()
|
||||||
/*setting onlyCoreExpCheck to false allow the copied cards to pass the check of deck contents
|
/*setting onlyCoreExpCheck to false allow the copied cards to pass the check of deck contents
|
||||||
forge-core\src\main\java\forge\deck\Deck.javaDeck.java starting @ Line 320 which is called by
|
forge-core\src\main\java\forge\deck\Deck.javaDeck.java starting @ Line 320 which is called by
|
||||||
@@ -57,100 +62,60 @@ public class FDeckImportDialog extends FDialog {
|
|||||||
private final FComboBox<String> monthDropdown = add(new FComboBox<>()); //don't need wrappers since skin can't change while this dialog is open
|
private final FComboBox<String> monthDropdown = add(new FComboBox<>()); //don't need wrappers since skin can't change while this dialog is open
|
||||||
private final FComboBox<Integer> yearDropdown = add(new FComboBox<>());
|
private final FComboBox<Integer> yearDropdown = add(new FComboBox<>());
|
||||||
|
|
||||||
private final boolean showOptions;
|
private boolean showOptions;
|
||||||
private final boolean currentDeckIsEmpty;
|
private final Deck currentDeck;
|
||||||
private boolean createNewDeckControl;
|
private boolean createNewDeckControl;
|
||||||
private final DeckImportController controller;
|
private final DeckImportController controller;
|
||||||
|
private final FDeckEditor.DeckEditorConfig editorConfig;
|
||||||
|
|
||||||
private final static ImmutableList<String> importOrCancel = ImmutableList.of(Forge.getLocalizer().getMessage("lblImport"), Forge.getLocalizer().getMessage("lblCancel"));
|
private final static ImmutableList<String> importOrCancel = ImmutableList.of(Forge.getLocalizer().getMessage("lblImport"), Forge.getLocalizer().getMessage("lblCancel"));
|
||||||
|
|
||||||
public FDeckImportDialog(final boolean replacingDeck, final FDeckEditor.DeckEditorConfig editorConfig) {
|
public FDeckImportDialog(final Deck currentDeck, final FDeckEditor.DeckEditorConfig editorConfig) {
|
||||||
super(Forge.getLocalizer().getMessage("lblImportFromClipboard"), 2);
|
super(Forge.getLocalizer().getMessage("lblImportFromClipboard"), 2);
|
||||||
|
boolean usingInventory = editorConfig.usePlayerInventory();
|
||||||
|
boolean replacingDeck = !currentDeck.isEmpty() || usingInventory;
|
||||||
|
this.currentDeck = currentDeck;
|
||||||
|
this.editorConfig = editorConfig;
|
||||||
|
ItemPool<PaperCard> cardPool = editorConfig.getCardPool(false);
|
||||||
controller = new DeckImportController(dateTimeCheck, monthDropdown, yearDropdown, replacingDeck);
|
controller = new DeckImportController(dateTimeCheck, monthDropdown, yearDropdown, replacingDeck);
|
||||||
String contents = Forge.getClipboard().getContents();
|
String contents = Forge.getClipboard().getContents();
|
||||||
if (contents == null)
|
if (contents == null)
|
||||||
contents = ""; //prevent NPE
|
contents = ""; //prevent NPE
|
||||||
txtInput.setText(contents);
|
txtInput.setText(contents);
|
||||||
|
|
||||||
if (editorConfig.allowsCardReplacement()) {
|
|
||||||
GameType gameType = editorConfig.getGameType();
|
GameType gameType = editorConfig.getGameType();
|
||||||
controller.setGameFormat(gameType);
|
controller.setGameFormat(gameType);
|
||||||
List<DeckSection> supportedSections = new ArrayList<>();
|
List<DeckSection> supportedSections = new ArrayList<>();
|
||||||
supportedSections.add(DeckSection.Main);
|
supportedSections.addAll(List.of(editorConfig.getPrimarySections()));
|
||||||
supportedSections.add(DeckSection.Sideboard);
|
supportedSections.addAll(List.of(editorConfig.getExtraSections()));
|
||||||
if (editorConfig.hasCommander())
|
|
||||||
supportedSections.add(DeckSection.Commander);
|
|
||||||
supportedSections.addAll(Lists.newArrayList(editorConfig.getExtraSections()));
|
|
||||||
controller.setAllowedSections(supportedSections);
|
controller.setAllowedSections(supportedSections);
|
||||||
}
|
controller.setCurrentDeckInEditor(currentDeck);
|
||||||
|
if(usingInventory)
|
||||||
|
controller.setPlayerInventory(cardPool);
|
||||||
|
|
||||||
onlyCoreExpCheck.setSelected(StaticData.instance().isCoreExpansionOnlyFilterSet());
|
onlyCoreExpCheck.setSelected(StaticData.instance().isCoreExpansionOnlyFilterSet());
|
||||||
newEditionCheck.setSelected(StaticData.instance().cardArtPreferenceIsLatest());
|
newEditionCheck.setSelected(StaticData.instance().cardArtPreferenceIsLatest());
|
||||||
smartCardArtCheck.setSelected(StaticData.instance().isEnabledCardArtSmartSelection());
|
smartCardArtCheck.setSelected(StaticData.instance().isEnabledCardArtSmartSelection());
|
||||||
createNewDeckCheck.setSelected(replacingDeck);
|
createNewDeckCheck.setSelected(replacingDeck);
|
||||||
this.currentDeckIsEmpty = !replacingDeck;
|
|
||||||
this.createNewDeckControl = replacingDeck;
|
this.createNewDeckControl = replacingDeck;
|
||||||
|
|
||||||
initButton(0, Forge.getLocalizer().getMessage("lblImport"), e -> FThreads.invokeInBackgroundThread(() -> {
|
if(usingInventory)
|
||||||
List<DeckRecognizer.Token> tokens = controller.parseInput(txtInput.getText()); //ensure deck updated based on any changes to options
|
controller.setImportBehavior(DeckImportController.ImportBehavior.REPLACE_CURRENT);
|
||||||
|
else
|
||||||
|
controller.setImportBehavior(createNewDeckControl ? DeckImportController.ImportBehavior.CREATE_NEW : DeckImportController.ImportBehavior.MERGE);
|
||||||
|
|
||||||
if (controller.isSmartCardArtEnabled())
|
initButton(0, Forge.getLocalizer().getMessage("lblImport"), e -> FThreads.invokeInBackgroundThread(this::performImport));
|
||||||
tokens = controller.optimiseCardArtInTokens();
|
|
||||||
|
|
||||||
//if there are any cards that cannot be imported, let user know this and give them the option to cancel
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (DeckRecognizer.Token token : tokens) {
|
|
||||||
if (token.getType() == TokenType.CARD_FROM_NOT_ALLOWED_SET
|
|
||||||
|| token.getType() == TokenType.CARD_FROM_INVALID_SET
|
|
||||||
|| token.getType() == TokenType.UNKNOWN_CARD
|
|
||||||
|| token.getType() == TokenType.UNSUPPORTED_CARD) {
|
|
||||||
if (sb.length() > 0)
|
|
||||||
sb.append("\n");
|
|
||||||
sb.append(token.getQuantity()).append(" ").append(token.getText());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
if (SOptionPane.showOptionDialog(Forge.getLocalizer().getMessage("lblFollowingCardsCannotBeImported") + "\n\n" + sb, Forge.getLocalizer().getMessage("lblImportRemainingCards"), SOptionPane.INFORMATION_ICON, importOrCancel) == 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final Deck deck = controller.accept(); //must accept in background thread in case a dialog is shown
|
|
||||||
if (deck == null) { return; }
|
|
||||||
|
|
||||||
FThreads.invokeInEdtLater(() -> {
|
|
||||||
hide();
|
|
||||||
if (callback != null)
|
|
||||||
callback.accept(deck);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
initButton(1, Forge.getLocalizer().getMessage("lblCancel"), e -> hide());
|
initButton(1, Forge.getLocalizer().getMessage("lblCancel"), e -> hide());
|
||||||
|
|
||||||
List<DeckRecognizer.Token> tokens = controller.parseInput(txtInput.getText());
|
|
||||||
if (controller.isSmartCardArtEnabled())
|
|
||||||
tokens = controller.optimiseCardArtInTokens();
|
|
||||||
//ensure at least one known card found on clipboard
|
|
||||||
for (DeckRecognizer.Token token : tokens) {
|
|
||||||
if (token.getType() == TokenType.LEGAL_CARD) {
|
|
||||||
showOptions = true;
|
|
||||||
|
|
||||||
dateTimeCheck.setCommand(e -> updateDropDownEnabled());
|
dateTimeCheck.setCommand(e -> updateDropDownEnabled());
|
||||||
newEditionCheck.setCommand(e -> setArtPreferenceInController());
|
newEditionCheck.setCommand(e -> setArtPreferenceInController());
|
||||||
onlyCoreExpCheck.setCommand(e -> setArtPreferenceInController());
|
onlyCoreExpCheck.setCommand(e -> setArtPreferenceInController());
|
||||||
smartCardArtCheck.setCommand(e -> controller.setSmartCardArtOptimisation(smartCardArtCheck.isSelected()));
|
smartCardArtCheck.setCommand(e -> controller.setSmartCardArtOptimisation(smartCardArtCheck.isSelected()));
|
||||||
createNewDeckCheck.setCommand(e -> {
|
createNewDeckCheck.setCommand(e -> {
|
||||||
createNewDeckControl = createNewDeckCheck.isSelected();
|
createNewDeckControl = createNewDeckCheck.isSelected();
|
||||||
controller.setCreateNewDeck(createNewDeckControl);
|
controller.setImportBehavior(createNewDeckControl ? DeckImportController.ImportBehavior.CREATE_NEW : DeckImportController.ImportBehavior.MERGE);
|
||||||
});
|
});
|
||||||
updateDropDownEnabled();
|
setShowOptions(false);
|
||||||
setArtPreferenceInController();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showOptions = false;
|
|
||||||
setButtonEnabled(0, false);
|
|
||||||
txtInput.setText(Forge.getLocalizer().getMessage("lblNoKnownCardsOnClipboard"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setArtPreferenceInController() {
|
private void setArtPreferenceInController() {
|
||||||
@@ -160,16 +125,66 @@ public class FDeckImportDialog extends FDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateDropDownEnabled() {
|
private void updateDropDownEnabled() {
|
||||||
boolean enabled = dateTimeCheck.isSelected();
|
boolean enabled = dateTimeCheck.isSelected() && this.showOptions;
|
||||||
monthDropdown.setEnabled(enabled);
|
monthDropdown.setEnabled(enabled);
|
||||||
yearDropdown.setEnabled(enabled);
|
yearDropdown.setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setShowOptions(boolean showOptions) {
|
||||||
|
this.showOptions = showOptions;
|
||||||
|
dateTimeCheck.setEnabled(showOptions);
|
||||||
|
newEditionCheck.setEnabled(showOptions);
|
||||||
|
onlyCoreExpCheck.setEnabled(showOptions);
|
||||||
|
newEditionCheck.setEnabled(showOptions);
|
||||||
|
smartCardArtCheck.setEnabled(showOptions);
|
||||||
|
createNewDeckCheck.setEnabled(showOptions);
|
||||||
|
updateDropDownEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
public void setCallback(Consumer<Deck> callback0){
|
public void setCallback(Consumer<Deck> callback0){
|
||||||
callback = callback0;
|
callback = callback0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean createNewDeck(){ return this.createNewDeckControl; }
|
public void setFreePrintConverter(Function<PaperCard, PaperCard> freePrintConverter) {
|
||||||
|
this.controller.setFreePrintConverter(freePrintConverter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeckImportController.ImportBehavior getImportBehavior() {
|
||||||
|
return controller.getImportBehavior();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImportBannedCards(boolean importBannedCards) {
|
||||||
|
controller.importBannedAndRestrictedCards(importBannedCards);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initParse() {
|
||||||
|
boolean usingInventory = editorConfig.usePlayerInventory();
|
||||||
|
List<DeckRecognizer.Token> tokens = controller.parseInput(txtInput.getText());
|
||||||
|
if (usingInventory)
|
||||||
|
tokens = controller.constrainTokensToInventory();
|
||||||
|
else if (controller.isSmartCardArtEnabled())
|
||||||
|
tokens = controller.optimiseCardArtInTokens();
|
||||||
|
//ensure at least one known card found on clipboard
|
||||||
|
for (DeckRecognizer.Token token : tokens) {
|
||||||
|
if (token.getType() == TokenType.LEGAL_CARD || token.getType() == TokenType.FREE_CARD_NOT_IN_INVENTORY) {
|
||||||
|
|
||||||
|
if(usingInventory) {
|
||||||
|
//Settings aren't compatible with player inventories.
|
||||||
|
setShowOptions(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setShowOptions(true);
|
||||||
|
|
||||||
|
updateDropDownEnabled();
|
||||||
|
setArtPreferenceInController();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setButtonEnabled(0, false);
|
||||||
|
txtInput.setText(Forge.getLocalizer().getMessage("lblNoKnownCardsOnClipboard"));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawOverlay(Graphics g) {
|
public void drawOverlay(Graphics g) {
|
||||||
@@ -202,7 +217,7 @@ public class FDeckImportDialog extends FDialog {
|
|||||||
yearDropdown.setBounds(x + dropDownWidth + fieldPadding, y, dropDownWidth, h);
|
yearDropdown.setBounds(x + dropDownWidth + fieldPadding, y, dropDownWidth, h);
|
||||||
y += h + fieldPadding;
|
y += h + fieldPadding;
|
||||||
|
|
||||||
if (!this.currentDeckIsEmpty){
|
if (!this.currentDeck.isEmpty()){
|
||||||
smartCardArtCheck.setBounds(x, y, w/2, h);
|
smartCardArtCheck.setBounds(x, y, w/2, h);
|
||||||
createNewDeckCheck.setBounds(x + w/2, y, w/2, h);
|
createNewDeckCheck.setBounds(x + w/2, y, w/2, h);
|
||||||
} else
|
} else
|
||||||
@@ -222,4 +237,49 @@ public class FDeckImportDialog extends FDialog {
|
|||||||
}
|
}
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final EnumSet<TokenType> MISSING_TOKENS = EnumSet.of(TokenType.CARD_FROM_NOT_ALLOWED_SET,
|
||||||
|
TokenType.CARD_FROM_INVALID_SET, TokenType.UNKNOWN_CARD, TokenType.UNSUPPORTED_CARD,
|
||||||
|
TokenType.WARNING_MESSAGE, TokenType.CARD_NOT_IN_INVENTORY);
|
||||||
|
|
||||||
|
private void performImport() {
|
||||||
|
List<DeckRecognizer.Token> tokens = controller.parseInput(txtInput.getText()); //ensure deck updated based on any changes to options
|
||||||
|
|
||||||
|
if (editorConfig.usePlayerInventory())
|
||||||
|
tokens = controller.constrainTokensToInventory();
|
||||||
|
else if (controller.isSmartCardArtEnabled())
|
||||||
|
tokens = controller.optimiseCardArtInTokens();
|
||||||
|
|
||||||
|
//if there are any cards that cannot be imported, let user know this and give them the option to cancel
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (DeckRecognizer.Token token : tokens) {
|
||||||
|
if (MISSING_TOKENS.contains(token.getType())) {
|
||||||
|
if (!sb.isEmpty())
|
||||||
|
sb.append("\n");
|
||||||
|
String message = controller.getTokenMessage(token);
|
||||||
|
String statusMessage = controller.getTokenStatusMessage(token);
|
||||||
|
if(!StringUtils.isBlank(statusMessage))
|
||||||
|
sb.append(String.format("%s - (%s)", message, statusMessage));
|
||||||
|
else
|
||||||
|
sb.append(statusMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sb.isEmpty()) {
|
||||||
|
Localizer localizer = Forge.getLocalizer();
|
||||||
|
if (SOptionPane.showOptionDialog(localizer.getMessage("lblFollowingCardsCannotBeImported") + "\n\n" + sb, localizer.getMessage("lblImportRemainingCards"), SOptionPane.WARNING_ICON, importOrCancel) == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Deck deck = controller.accept(currentDeck.getName()); //must accept in background thread in case a dialog is shown
|
||||||
|
if (deck == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FThreads.invokeInEdtLater(() -> {
|
||||||
|
hide();
|
||||||
|
if (callback != null)
|
||||||
|
callback.accept(deck);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2838,6 +2838,7 @@ lblDecklistTitle=Deckliste
|
|||||||
lblSummaryStats=Gesamt-Statistik
|
lblSummaryStats=Gesamt-Statistik
|
||||||
lblDeckSection=Bereich
|
lblDeckSection=Bereich
|
||||||
lblNewDeckCheckbox=Erzeuge ein neues Deck
|
lblNewDeckCheckbox=Erzeuge ein neues Deck
|
||||||
|
lblReplaceDeckCheckbox=Replace Current Deck
|
||||||
lblImportCardsCmd=Importiere Karten
|
lblImportCardsCmd=Importiere Karten
|
||||||
lblCreateNewCmd=Neues Deck
|
lblCreateNewCmd=Neues Deck
|
||||||
lblErrNotAllowedCard=Set ist nicht erlaubt in {0}
|
lblErrNotAllowedCard=Set ist nicht erlaubt in {0}
|
||||||
@@ -2845,6 +2846,7 @@ lblWarnLimitedCard={0} in {1}
|
|||||||
lblErrCardEditionDate=Set verträgt sich nicht mit der Erscheinungsdatum-Option
|
lblErrCardEditionDate=Set verträgt sich nicht mit der Erscheinungsdatum-Option
|
||||||
lblErrUnsupportedCard=Ist nicht erlaubt in {0}
|
lblErrUnsupportedCard=Ist nicht erlaubt in {0}
|
||||||
lblWarnUnknownCardMsg=Unbekannte oder in Forge nicht unterstützte Karte
|
lblWarnUnknownCardMsg=Unbekannte oder in Forge nicht unterstützte Karte
|
||||||
|
lblWarnNotInInventory=Card not found in inventory
|
||||||
lblWarnTooManyCommanders=Aktueller {0}-Bereich enthält {1} mögliche Commander-Karten: {2}
|
lblWarnTooManyCommanders=Aktueller {0}-Bereich enthält {1} mögliche Commander-Karten: {2}
|
||||||
lblWarnCommandersInSideExtra=Bitte prüfen und, falls nötig, min. eine Karte in den Commander-Bereich verschieben.
|
lblWarnCommandersInSideExtra=Bitte prüfen und, falls nötig, min. eine Karte in den Commander-Bereich verschieben.
|
||||||
lblWarnDeckSectionNotAllowedInEditor=In {1} ist der {0}-Bereich nicht erlaubt.
|
lblWarnDeckSectionNotAllowedInEditor=In {1} ist der {0}-Bereich nicht erlaubt.
|
||||||
@@ -2936,6 +2938,7 @@ lblCardImportWarning=\nWarnung: Das Deck {0} wird umbenannt in {1}.
|
|||||||
lblConfirmCreateNewDeck=Du bist dabei das neue Deck {0} zu erzeugen. {1}\n\nWillst du fortfahren?\n\n Hinweis: \
|
lblConfirmCreateNewDeck=Du bist dabei das neue Deck {0} zu erzeugen. {1}\n\nWillst du fortfahren?\n\n Hinweis: \
|
||||||
Bitte denk daran den "Save"-Knopf im Deck-Editor zu klicken, um das neue Deck dem Deck-Katalog hinzuzufügen!
|
Bitte denk daran den "Save"-Knopf im Deck-Editor zu klicken, um das neue Deck dem Deck-Katalog hinzuzufügen!
|
||||||
lblNewDeckWarning=\nWarnung: Alle ungesicherten Änderungen am aktuellen Deck {0} werden verlorengehen.
|
lblNewDeckWarning=\nWarnung: Alle ungesicherten Änderungen am aktuellen Deck {0} werden verlorengehen.
|
||||||
|
lblConfirmReplaceDeck=This will replace the contents of the current deck ({0}) with the imported cards.\n\nWould you like to proceed?
|
||||||
lblImportCardsDialogTitle=Importiere Karten in aktuelles Deck
|
lblImportCardsDialogTitle=Importiere Karten in aktuelles Deck
|
||||||
lblNewDeckDialogTitle=Erzeuge neues Deck
|
lblNewDeckDialogTitle=Erzeuge neues Deck
|
||||||
#FNetOverlay.java
|
#FNetOverlay.java
|
||||||
|
|||||||
@@ -2898,6 +2898,7 @@ lblDecklistTitle=Decklist
|
|||||||
lblSummaryStats=Summary Statistics
|
lblSummaryStats=Summary Statistics
|
||||||
lblDeckSection=Section
|
lblDeckSection=Section
|
||||||
lblNewDeckCheckbox=Create a New Deck
|
lblNewDeckCheckbox=Create a New Deck
|
||||||
|
lblReplaceDeckCheckbox=Replace Current Deck
|
||||||
lblImportCardsCmd=Import Cards
|
lblImportCardsCmd=Import Cards
|
||||||
lblCreateNewCmd=New Deck
|
lblCreateNewCmd=New Deck
|
||||||
lblErrNotAllowedCard=Set not allowed in {0}
|
lblErrNotAllowedCard=Set not allowed in {0}
|
||||||
@@ -2905,6 +2906,7 @@ lblWarnLimitedCard={0} in {1}
|
|||||||
lblErrCardEditionDate=Set not compliant with Release Date option
|
lblErrCardEditionDate=Set not compliant with Release Date option
|
||||||
lblErrUnsupportedCard=Not allowed in {0}
|
lblErrUnsupportedCard=Not allowed in {0}
|
||||||
lblWarnUnknownCardMsg=Unknown Card or Unsupported in Forge
|
lblWarnUnknownCardMsg=Unknown Card or Unsupported in Forge
|
||||||
|
lblWarnNotInInventory=Card not found in inventory
|
||||||
lblWarnTooManyCommanders=Current {0} Section contains {1} potential Commander Cards: {2}
|
lblWarnTooManyCommanders=Current {0} Section contains {1} potential Commander Cards: {2}
|
||||||
lblWarnCommandersInSideExtra=Please check and move one to the Commander Section, in case.
|
lblWarnCommandersInSideExtra=Please check and move one to the Commander Section, in case.
|
||||||
lblWarnDeckSectionNotAllowedInEditor={0} Section is not allowed in {1}
|
lblWarnDeckSectionNotAllowedInEditor={0} Section is not allowed in {1}
|
||||||
@@ -3001,6 +3003,7 @@ lblCardImportWarning=\nWarning: The deck {0} will be renamed as {1}.
|
|||||||
lblConfirmCreateNewDeck=You are about to create a new deck {0}. {1}\n\nWould you like to proceed?\n\n Note: \
|
lblConfirmCreateNewDeck=You are about to create a new deck {0}. {1}\n\nWould you like to proceed?\n\n Note: \
|
||||||
Please remember to click on the "Save" button in the Deck Editor to add the new deck to the Catalog!
|
Please remember to click on the "Save" button in the Deck Editor to add the new deck to the Catalog!
|
||||||
lblNewDeckWarning=\nWarning: Any unsaved changes to the current deck {0} will be lost.
|
lblNewDeckWarning=\nWarning: Any unsaved changes to the current deck {0} will be lost.
|
||||||
|
lblConfirmReplaceDeck=This will replace the contents of the current deck ({0}) with the imported cards.\n\nWould you like to proceed?
|
||||||
lblImportCardsDialogTitle=Import cards in the Current Deck
|
lblImportCardsDialogTitle=Import cards in the Current Deck
|
||||||
lblNewDeckDialogTitle=Create a New Deck
|
lblNewDeckDialogTitle=Create a New Deck
|
||||||
#FNetOverlay.java
|
#FNetOverlay.java
|
||||||
|
|||||||
@@ -2847,6 +2847,7 @@ lblDecklistTitle=Decklist
|
|||||||
lblSummaryStats=Summary Statistics
|
lblSummaryStats=Summary Statistics
|
||||||
lblDeckSection=Section
|
lblDeckSection=Section
|
||||||
lblNewDeckCheckbox=Create a New Deck
|
lblNewDeckCheckbox=Create a New Deck
|
||||||
|
lblReplaceDeckCheckbox=Replace Current Deck
|
||||||
lblImportCardsCmd=Import Cards
|
lblImportCardsCmd=Import Cards
|
||||||
lblCreateNewCmd=New Deck
|
lblCreateNewCmd=New Deck
|
||||||
lblErrNotAllowedCard=Set not allowed in {0}
|
lblErrNotAllowedCard=Set not allowed in {0}
|
||||||
@@ -2854,6 +2855,7 @@ lblWarnLimitedCard={0} in {1}
|
|||||||
lblErrCardEditionDate=Set not compliant with Release Date option
|
lblErrCardEditionDate=Set not compliant with Release Date option
|
||||||
lblErrUnsupportedCard=Not allowed in {0}
|
lblErrUnsupportedCard=Not allowed in {0}
|
||||||
lblWarnUnknownCardMsg=Unknown Card or Unsupported in Forge
|
lblWarnUnknownCardMsg=Unknown Card or Unsupported in Forge
|
||||||
|
lblWarnNotInInventory=Card not found in inventory
|
||||||
lblWarnTooManyCommanders=Current {0} Section contains {1} potential Commander Cards: {2}
|
lblWarnTooManyCommanders=Current {0} Section contains {1} potential Commander Cards: {2}
|
||||||
lblWarnCommandersInSideExtra=Please check and move one to the Commander Section, in case.
|
lblWarnCommandersInSideExtra=Please check and move one to the Commander Section, in case.
|
||||||
lblWarnDeckSectionNotAllowedInEditor={0} Section is not allowed in {1}
|
lblWarnDeckSectionNotAllowedInEditor={0} Section is not allowed in {1}
|
||||||
@@ -2950,6 +2952,7 @@ lblCardImportWarning=\nWarning: The deck {0} will be renamed as {1}.
|
|||||||
lblConfirmCreateNewDeck=You are about to create a new deck {0}. {1}\n\nWould you like to proceed?\n\n Note: \
|
lblConfirmCreateNewDeck=You are about to create a new deck {0}. {1}\n\nWould you like to proceed?\n\n Note: \
|
||||||
Please remember to click on the "Save" button in the Deck Editor to add the new deck to the Catalog!
|
Please remember to click on the "Save" button in the Deck Editor to add the new deck to the Catalog!
|
||||||
lblNewDeckWarning=\nWarning: Any unsaved changes to the current deck {0} will be lost.
|
lblNewDeckWarning=\nWarning: Any unsaved changes to the current deck {0} will be lost.
|
||||||
|
lblConfirmReplaceDeck=This will replace the contents of the current deck ({0}) with the imported cards.\n\nWould you like to proceed?
|
||||||
lblImportCardsDialogTitle=Import cards in the Current Deck
|
lblImportCardsDialogTitle=Import cards in the Current Deck
|
||||||
lblNewDeckDialogTitle=Create a New Deck
|
lblNewDeckDialogTitle=Create a New Deck
|
||||||
#FNetOverlay.java
|
#FNetOverlay.java
|
||||||
|
|||||||
@@ -2840,6 +2840,7 @@ lblDecklistTitle=Liste de deck
|
|||||||
lblSummaryStats=Statistiques récapitulatives
|
lblSummaryStats=Statistiques récapitulatives
|
||||||
lblDeckSection=Section
|
lblDeckSection=Section
|
||||||
lblNewDeckCheckbox=Créer un nouveau deck
|
lblNewDeckCheckbox=Créer un nouveau deck
|
||||||
|
lblReplaceDeckCheckbox=Replace Current Deck
|
||||||
lblImportCardsCmd=Importer des cartes
|
lblImportCardsCmd=Importer des cartes
|
||||||
lblCreateNewCmd=Nouveau Deck
|
lblCreateNewCmd=Nouveau Deck
|
||||||
lblErrNotAllowedCard=Définir non autorisé dans {0}
|
lblErrNotAllowedCard=Définir non autorisé dans {0}
|
||||||
@@ -2847,6 +2848,7 @@ lblWarnLimitedCard={0} dans {1}
|
|||||||
lblErrCardEditionDate=Set non conforme avec l'option de date de sortie
|
lblErrCardEditionDate=Set non conforme avec l'option de date de sortie
|
||||||
lblErrUnsupportedCard=Non autorisé dans {0}
|
lblErrUnsupportedCard=Non autorisé dans {0}
|
||||||
lblWarnUnknownCardMsg=Carte inconnue ou non prise en charge dans Forge
|
lblWarnUnknownCardMsg=Carte inconnue ou non prise en charge dans Forge
|
||||||
|
lblWarnNotInInventory=Card not found in inventory
|
||||||
lblWarnTooManyCommanders=La section {0} actuelle contient {1} cartes de commandant potentielles : {2}
|
lblWarnTooManyCommanders=La section {0} actuelle contient {1} cartes de commandant potentielles : {2}
|
||||||
lblWarnCommandersInSideExtra=Veuillez vérifier et en déplacer un vers la section Commandant, au cas où.
|
lblWarnCommandersInSideExtra=Veuillez vérifier et en déplacer un vers la section Commandant, au cas où.
|
||||||
lblWarnDeckSectionNotAllowedInEditor={0} La section n'est pas autorisée dans {1}
|
lblWarnDeckSectionNotAllowedInEditor={0} La section n'est pas autorisée dans {1}
|
||||||
@@ -2944,6 +2946,7 @@ lblCardImportWarning=\nAttention : Le deck {0} sera renommé en {1}.
|
|||||||
lblConfirmCreateNewDeck=Vous êtes sur le point de créer un nouveau deck {0}. {1}\n\nVoulez-vous continuer ?\n\n Remarque : \
|
lblConfirmCreateNewDeck=Vous êtes sur le point de créer un nouveau deck {0}. {1}\n\nVoulez-vous continuer ?\n\n Remarque : \
|
||||||
N'oubliez pas de cliquer sur le bouton "Enregistrer" dans l'éditeur de deck pour ajouter le nouveau deck au catalogue !
|
N'oubliez pas de cliquer sur le bouton "Enregistrer" dans l'éditeur de deck pour ajouter le nouveau deck au catalogue !
|
||||||
lblNewDeckWarning=\nAttention : Toute modification non enregistrée dans le deck actuel {0} sera perdue.
|
lblNewDeckWarning=\nAttention : Toute modification non enregistrée dans le deck actuel {0} sera perdue.
|
||||||
|
lblConfirmReplaceDeck=This will replace the contents of the current deck ({0}) with the imported cards.\n\nWould you like to proceed?
|
||||||
lblImportCardsDialogTitle=Importer des cartes dans le Deck actuel
|
lblImportCardsDialogTitle=Importer des cartes dans le Deck actuel
|
||||||
lblNewDeckDialogTitle=Créer un nouveau deck
|
lblNewDeckDialogTitle=Créer un nouveau deck
|
||||||
#FNetOverlay.java
|
#FNetOverlay.java
|
||||||
|
|||||||
@@ -2836,6 +2836,7 @@ lblDecklistTitle=Lista delle Carte da Importare
|
|||||||
lblSummaryStats=Statistiche Generali
|
lblSummaryStats=Statistiche Generali
|
||||||
lblDeckSection=Sezione
|
lblDeckSection=Sezione
|
||||||
lblNewDeckCheckbox=Crea un nuovo mazzo
|
lblNewDeckCheckbox=Crea un nuovo mazzo
|
||||||
|
lblReplaceDeckCheckbox=Replace Current Deck
|
||||||
lblImportCardsCmd=Importa le carte
|
lblImportCardsCmd=Importa le carte
|
||||||
lblCreateNewCmd=Nuovo mazzo
|
lblCreateNewCmd=Nuovo mazzo
|
||||||
lblErrNotAllowedCard=Edizione non permessa in {0}
|
lblErrNotAllowedCard=Edizione non permessa in {0}
|
||||||
@@ -2843,6 +2844,7 @@ lblWarnLimitedCard={0} in {1}
|
|||||||
lblErrCardEditionDate=Edizione non valida secondo l'opzione sulla data di pubblicazione selezionata
|
lblErrCardEditionDate=Edizione non valida secondo l'opzione sulla data di pubblicazione selezionata
|
||||||
lblErrUnsupportedCard=Non Permesso in {0}
|
lblErrUnsupportedCard=Non Permesso in {0}
|
||||||
lblWarnUnknownCardMsg=Carta Sconosciuta, o non supportata in Forge
|
lblWarnUnknownCardMsg=Carta Sconosciuta, o non supportata in Forge
|
||||||
|
lblWarnNotInInventory=Card not found in inventory
|
||||||
lblWarnTooManyCommanders=La Sezione {0} contiene {1} potenziali carte Commander: {2}
|
lblWarnTooManyCommanders=La Sezione {0} contiene {1} potenziali carte Commander: {2}
|
||||||
lblWarnCommandersInSideExtra=Per favore, controlla e nel caso spostane una nella sezione Commander.
|
lblWarnCommandersInSideExtra=Per favore, controlla e nel caso spostane una nella sezione Commander.
|
||||||
lblWarnDeckSectionNotAllowedInEditor={0} Sezione non è permessa in {1}
|
lblWarnDeckSectionNotAllowedInEditor={0} Sezione non è permessa in {1}
|
||||||
@@ -2942,6 +2944,7 @@ lblCardImportWarning=\nAttenzione: Il mazzo {0} sarà rinominato come {1}.
|
|||||||
lblConfirmCreateNewDeck=Si sta per creare un nuovo mazzo {0}. {1}\n\nSi desidera procedere?\n\n Nota: \
|
lblConfirmCreateNewDeck=Si sta per creare un nuovo mazzo {0}. {1}\n\nSi desidera procedere?\n\n Nota: \
|
||||||
Non dimenticare di premere il tasto "Salva" una volta importate le carte per aggiungere il nuovo mazzo al catalogo!
|
Non dimenticare di premere il tasto "Salva" una volta importate le carte per aggiungere il nuovo mazzo al catalogo!
|
||||||
lblNewDeckWarning=\nAttenzione: Qualsiasi modifica non salvata al mazzo corrente {0} sarà persa.
|
lblNewDeckWarning=\nAttenzione: Qualsiasi modifica non salvata al mazzo corrente {0} sarà persa.
|
||||||
|
lblConfirmReplaceDeck=This will replace the contents of the current deck ({0}) with the imported cards.\n\nWould you like to proceed?
|
||||||
lblImportCardsDialogTitle=Importa le carte nel mazzo corrente
|
lblImportCardsDialogTitle=Importa le carte nel mazzo corrente
|
||||||
lblNewDeckDialogTitle=Crea un nuovo mazzo
|
lblNewDeckDialogTitle=Crea un nuovo mazzo
|
||||||
#FNetOverlay.java
|
#FNetOverlay.java
|
||||||
|
|||||||
@@ -2835,6 +2835,7 @@ lblDecklistTitle=Decklist
|
|||||||
lblSummaryStats=Summary Statistics
|
lblSummaryStats=Summary Statistics
|
||||||
lblDeckSection=Section
|
lblDeckSection=Section
|
||||||
lblNewDeckCheckbox=Create a New Deck
|
lblNewDeckCheckbox=Create a New Deck
|
||||||
|
lblReplaceDeckCheckbox=Replace Current Deck
|
||||||
lblImportCardsCmd=Import Cards
|
lblImportCardsCmd=Import Cards
|
||||||
lblCreateNewCmd=New Deck
|
lblCreateNewCmd=New Deck
|
||||||
lblErrNotAllowedCard=Set not allowed in {0}
|
lblErrNotAllowedCard=Set not allowed in {0}
|
||||||
@@ -2842,6 +2843,7 @@ lblWarnLimitedCard={0} in {1}
|
|||||||
lblErrCardEditionDate=Set not compliant with Release Date option
|
lblErrCardEditionDate=Set not compliant with Release Date option
|
||||||
lblErrUnsupportedCard=Not allowed in {0}
|
lblErrUnsupportedCard=Not allowed in {0}
|
||||||
lblWarnUnknownCardMsg=Unknown Card or Unsupported in Forge
|
lblWarnUnknownCardMsg=Unknown Card or Unsupported in Forge
|
||||||
|
lblWarnNotInInventory=Card not found in inventory
|
||||||
lblWarnTooManyCommanders=Current {0} Section contains {1} potential Commander Cards: {2}
|
lblWarnTooManyCommanders=Current {0} Section contains {1} potential Commander Cards: {2}
|
||||||
lblWarnCommandersInSideExtra=Please check and move one to the Commander Section, in case.
|
lblWarnCommandersInSideExtra=Please check and move one to the Commander Section, in case.
|
||||||
lblWarnDeckSectionNotAllowedInEditor={0} Section is not allowed in {1}
|
lblWarnDeckSectionNotAllowedInEditor={0} Section is not allowed in {1}
|
||||||
@@ -2938,6 +2940,7 @@ lblCardImportWarning=\nWarning: The deck {0} will be renamed as {1}.
|
|||||||
lblConfirmCreateNewDeck=You are about to create a new deck {0}. {1}\n\nWould you like to proceed?\n\n Note: \
|
lblConfirmCreateNewDeck=You are about to create a new deck {0}. {1}\n\nWould you like to proceed?\n\n Note: \
|
||||||
Please remember to click on the "Save" button in the Deck Editor to add the new deck to the Catalog!
|
Please remember to click on the "Save" button in the Deck Editor to add the new deck to the Catalog!
|
||||||
lblNewDeckWarning=\nWarning: Any unsaved changes to the current deck {0} will be lost.
|
lblNewDeckWarning=\nWarning: Any unsaved changes to the current deck {0} will be lost.
|
||||||
|
lblConfirmReplaceDeck=This will replace the contents of the current deck ({0}) with the imported cards.\n\nWould you like to proceed?
|
||||||
lblImportCardsDialogTitle=Import cards in the Current Deck
|
lblImportCardsDialogTitle=Import cards in the Current Deck
|
||||||
lblNewDeckDialogTitle=Create a New Deck
|
lblNewDeckDialogTitle=Create a New Deck
|
||||||
#FNetOverlay.java
|
#FNetOverlay.java
|
||||||
|
|||||||
@@ -2917,6 +2917,7 @@ lblDecklistTitle=Lista de decks
|
|||||||
lblSummaryStats=Estatísticas Resumidas
|
lblSummaryStats=Estatísticas Resumidas
|
||||||
lblDeckSection=Seção
|
lblDeckSection=Seção
|
||||||
lblNewDeckCheckbox=Criar um Novo deck
|
lblNewDeckCheckbox=Criar um Novo deck
|
||||||
|
lblReplaceDeckCheckbox=Replace Current Deck
|
||||||
lblImportCardsCmd=Importar Cartas
|
lblImportCardsCmd=Importar Cartas
|
||||||
lblCreateNewCmd=Novo Deck
|
lblCreateNewCmd=Novo Deck
|
||||||
lblErrNotAllowedCard=Coleção não permitida em {0}
|
lblErrNotAllowedCard=Coleção não permitida em {0}
|
||||||
@@ -2924,6 +2925,7 @@ lblWarnLimitedCard={0} em {1}
|
|||||||
lblErrCardEditionDate=Coleção não compatível com a opção de Data de Lançamento
|
lblErrCardEditionDate=Coleção não compatível com a opção de Data de Lançamento
|
||||||
lblErrUnsupportedCard=Não permitido em {0}
|
lblErrUnsupportedCard=Não permitido em {0}
|
||||||
lblWarnUnknownCardMsg=Carta desconhecida ou não suportada no Forge
|
lblWarnUnknownCardMsg=Carta desconhecida ou não suportada no Forge
|
||||||
|
lblWarnNotInInventory=Card not found in inventory
|
||||||
lblWarnTooManyCommanders=Seção {0} Atual contém {1} Cartas de Comandante em potencial\: {2}
|
lblWarnTooManyCommanders=Seção {0} Atual contém {1} Cartas de Comandante em potencial\: {2}
|
||||||
lblWarnCommandersInSideExtra=Verifique e mova um para a seção do Comandante.
|
lblWarnCommandersInSideExtra=Verifique e mova um para a seção do Comandante.
|
||||||
lblWarnDeckSectionNotAllowedInEditor=Seção {0} não é permitida em {1}
|
lblWarnDeckSectionNotAllowedInEditor=Seção {0} não é permitida em {1}
|
||||||
@@ -3012,6 +3014,7 @@ Deseja prosseguir?\n\
|
|||||||
Nota\: Por favor, lembre-se de clicar no botão "Salvar" no Editor do Deck para adicioná-lo ao Catálogo\!
|
Nota\: Por favor, lembre-se de clicar no botão "Salvar" no Editor do Deck para adicioná-lo ao Catálogo\!
|
||||||
lblNewDeckWarning=\n\
|
lblNewDeckWarning=\n\
|
||||||
Aviso\: Qualquer alteração não salva no deck atual {0} será perdida.
|
Aviso\: Qualquer alteração não salva no deck atual {0} será perdida.
|
||||||
|
lblConfirmReplaceDeck=This will replace the contents of the current deck ({0}) with the imported cards.\n\nWould you like to proceed?
|
||||||
lblImportCardsDialogTitle=Importar cartas no Deck Atual
|
lblImportCardsDialogTitle=Importar cartas no Deck Atual
|
||||||
lblNewDeckDialogTitle=Criar um Novo deck
|
lblNewDeckDialogTitle=Criar um Novo deck
|
||||||
#FNetOverlay.java
|
#FNetOverlay.java
|
||||||
|
|||||||
@@ -2844,6 +2844,7 @@ lblDecklistTitle=套牌列表
|
|||||||
lblSummaryStats=统计摘要
|
lblSummaryStats=统计摘要
|
||||||
lblDeckSection=部分
|
lblDeckSection=部分
|
||||||
lblNewDeckCheckbox=创建一个新套牌
|
lblNewDeckCheckbox=创建一个新套牌
|
||||||
|
lblReplaceDeckCheckbox=Replace Current Deck
|
||||||
lblImportCardsCmd=导入牌张
|
lblImportCardsCmd=导入牌张
|
||||||
lblCreateNewCmd=新建套牌
|
lblCreateNewCmd=新建套牌
|
||||||
lblErrNotAllowedCard=系列{0}不被允许
|
lblErrNotAllowedCard=系列{0}不被允许
|
||||||
@@ -2851,6 +2852,7 @@ lblWarnLimitedCard={0}中的{1}
|
|||||||
lblErrCardEditionDate=不符合上市日期选项
|
lblErrCardEditionDate=不符合上市日期选项
|
||||||
lblErrUnsupportedCard={0}不被允许
|
lblErrUnsupportedCard={0}不被允许
|
||||||
lblWarnUnknownCardMsg=未知的牌张或未被forge支持的牌张
|
lblWarnUnknownCardMsg=未知的牌张或未被forge支持的牌张
|
||||||
|
lblWarnNotInInventory=Card not found in inventory
|
||||||
lblWarnTooManyCommanders=现在{0}部分包含{1}张潜在的指挥官牌张: {2}
|
lblWarnTooManyCommanders=现在{0}部分包含{1}张潜在的指挥官牌张: {2}
|
||||||
lblWarnCommandersInSideExtra=如果确实是指挥官,请进行进行检查并将其中的一张移动到指挥官区。
|
lblWarnCommandersInSideExtra=如果确实是指挥官,请进行进行检查并将其中的一张移动到指挥官区。
|
||||||
lblWarnDeckSectionNotAllowedInEditor={0}部分中的{1}不被允许
|
lblWarnDeckSectionNotAllowedInEditor={0}部分中的{1}不被允许
|
||||||
@@ -2928,6 +2930,7 @@ lblCardImportWarning=\n警告:套牌{0}将被重命名为{1}。
|
|||||||
lblConfirmCreateNewDeck=你即将创建一个新套牌{0}。{1}\n\n你想要继续吗?\n\n 注意:请记得点击套牌编辑器中的\"保存按钮\"以\
|
lblConfirmCreateNewDeck=你即将创建一个新套牌{0}。{1}\n\n你想要继续吗?\n\n 注意:请记得点击套牌编辑器中的\"保存按钮\"以\
|
||||||
将新建的套牌保存到目录中!
|
将新建的套牌保存到目录中!
|
||||||
lblNewDeckWarning=\n警告:对于当前套牌{0}的任何未保存更改丢将被丢弃。
|
lblNewDeckWarning=\n警告:对于当前套牌{0}的任何未保存更改丢将被丢弃。
|
||||||
|
lblConfirmReplaceDeck=This will replace the contents of the current deck ({0}) with the imported cards.\n\nWould you like to proceed?
|
||||||
lblImportCardsDialogTitle=将牌张导入到当前套牌
|
lblImportCardsDialogTitle=将牌张导入到当前套牌
|
||||||
lblNewDeckDialogTitle=创建一个新套牌
|
lblNewDeckDialogTitle=创建一个新套牌
|
||||||
#FNetOverlay.java
|
#FNetOverlay.java
|
||||||
|
|||||||
@@ -13,15 +13,24 @@ import forge.gui.util.SOptionPane;
|
|||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.localinstance.properties.ForgePreferences;
|
import forge.localinstance.properties.ForgePreferences;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
|
import forge.util.ItemPool;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
import forge.util.StreamUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.text.DateFormatSymbols;
|
import java.text.DateFormatSymbols;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class DeckImportController {
|
public class DeckImportController {
|
||||||
private boolean createNewDeck;
|
public enum ImportBehavior {
|
||||||
|
MERGE,
|
||||||
|
CREATE_NEW,
|
||||||
|
REPLACE_CURRENT
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImportBehavior importBehavior;
|
||||||
// Date filter
|
// Date filter
|
||||||
private final ICheckBox dateTimeCheck;
|
private final ICheckBox dateTimeCheck;
|
||||||
private final IComboBox<String> monthDropdown;
|
private final IComboBox<String> monthDropdown;
|
||||||
@@ -30,7 +39,7 @@ public class DeckImportController {
|
|||||||
private CardDb.CardArtPreference artPreference;
|
private CardDb.CardArtPreference artPreference;
|
||||||
private boolean smartCardArt;
|
private boolean smartCardArt;
|
||||||
// Block Preference Filter
|
// Block Preference Filter
|
||||||
private boolean inlcludeBnRInDeck = false;
|
private boolean includeBnRInDeck = false;
|
||||||
|
|
||||||
private final List<Token> tokens = new ArrayList<>();
|
private final List<Token> tokens = new ArrayList<>();
|
||||||
private final Map<PaperCard, Token> cardsInTokens = new HashMap<>();
|
private final Map<PaperCard, Token> cardsInTokens = new HashMap<>();
|
||||||
@@ -38,7 +47,14 @@ public class DeckImportController {
|
|||||||
private Deck currentDeckInEditor = null;
|
private Deck currentDeckInEditor = null;
|
||||||
private DeckFormat currentDeckFormat;
|
private DeckFormat currentDeckFormat;
|
||||||
private GameFormat currentGameFormat;
|
private GameFormat currentGameFormat;
|
||||||
|
private GameType currentGameType;
|
||||||
private final List<DeckSection> allowedSections = new ArrayList<>();
|
private final List<DeckSection> allowedSections = new ArrayList<>();
|
||||||
|
private ItemPool<PaperCard> playerInventory;
|
||||||
|
/**
|
||||||
|
* If a free card is missing from a player's inventory (e.g. a basic land), it gets run through this function, which
|
||||||
|
* can handle creation of a usable print.
|
||||||
|
*/
|
||||||
|
private Function<PaperCard, PaperCard> freePrintSupplier;
|
||||||
|
|
||||||
public DeckImportController(ICheckBox dateTimeCheck0,
|
public DeckImportController(ICheckBox dateTimeCheck0,
|
||||||
IComboBox<String> monthDropdown0, IComboBox<Integer> yearDropdown0,
|
IComboBox<String> monthDropdown0, IComboBox<Integer> yearDropdown0,
|
||||||
@@ -54,13 +70,14 @@ public class DeckImportController {
|
|||||||
*/
|
*/
|
||||||
this.currentDeckNotEmpty = currentDeckNotEmpty;
|
this.currentDeckNotEmpty = currentDeckNotEmpty;
|
||||||
// this option will control the "new deck" action controlled by UI widget
|
// this option will control the "new deck" action controlled by UI widget
|
||||||
createNewDeck = false;
|
this.importBehavior = ImportBehavior.MERGE;
|
||||||
|
|
||||||
// Init default parameters
|
// Init default parameters
|
||||||
this.artPreference = StaticData.instance().getCardArtPreference(); // default
|
this.artPreference = StaticData.instance().getCardArtPreference(); // default
|
||||||
this.smartCardArt = StaticData.instance().isEnabledCardArtSmartSelection();
|
this.smartCardArt = StaticData.instance().isEnabledCardArtSmartSelection();
|
||||||
this.currentDeckFormat = null;
|
this.currentDeckFormat = null;
|
||||||
this.currentGameFormat = null;
|
this.currentGameFormat = null;
|
||||||
|
this.currentGameType = null;
|
||||||
fillDateDropdowns();
|
fillDateDropdowns();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,13 +85,23 @@ public class DeckImportController {
|
|||||||
if (gameType == null){
|
if (gameType == null){
|
||||||
this.currentGameFormat = null;
|
this.currentGameFormat = null;
|
||||||
this.currentDeckFormat = null;
|
this.currentDeckFormat = null;
|
||||||
|
this.currentGameType = null;
|
||||||
} else {
|
} else {
|
||||||
// get the game format with the same name of current game type (if any)
|
// get the game format with the same name of current game type (if any)
|
||||||
this.currentDeckFormat = gameType.getDeckFormat();
|
this.currentDeckFormat = gameType.getDeckFormat();
|
||||||
this.currentGameFormat = FModel.getFormats().get(gameType.name());
|
this.currentGameFormat = FModel.getFormats().get(gameType.name());
|
||||||
|
this.currentGameType = gameType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPlayerInventory(ItemPool<PaperCard> inventory) {
|
||||||
|
this.playerInventory = inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFreePrintConverter(Function<PaperCard, PaperCard> freePrintSupplier) {
|
||||||
|
this.freePrintSupplier = freePrintSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
public void setCurrentDeckInEditor(Deck deckInEditor){
|
public void setCurrentDeckInEditor(Deck deckInEditor){
|
||||||
this.currentDeckInEditor = deckInEditor;
|
this.currentDeckInEditor = deckInEditor;
|
||||||
}
|
}
|
||||||
@@ -105,11 +132,13 @@ public class DeckImportController {
|
|||||||
return this.smartCardArt;
|
return this.smartCardArt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCreateNewDeck(boolean createNewDeck){
|
public void setImportBehavior(ImportBehavior importBehavior) {
|
||||||
this.createNewDeck = createNewDeck;
|
this.importBehavior = importBehavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getCreateNewDeck() { return this.createNewDeck; }
|
public ImportBehavior getImportBehavior() {
|
||||||
|
return importBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
private void fillDateDropdowns() {
|
private void fillDateDropdowns() {
|
||||||
DateFormatSymbols dfs = new DateFormatSymbols();
|
DateFormatSymbols dfs = new DateFormatSymbols();
|
||||||
@@ -159,10 +188,10 @@ public class DeckImportController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void importBannedAndRestrictedCards(boolean includeBannedAndRestricted){
|
public void importBannedAndRestrictedCards(boolean includeBannedAndRestricted){
|
||||||
this.inlcludeBnRInDeck = includeBannedAndRestricted;
|
this.includeBnRInDeck = includeBannedAndRestricted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean importBannedAndRestrictedCards(){ return this.inlcludeBnRInDeck; }
|
public boolean importBannedAndRestrictedCards(){ return this.includeBnRInDeck; }
|
||||||
|
|
||||||
public List<Token> parseInput(String input) {
|
public List<Token> parseInput(String input) {
|
||||||
tokens.clear();
|
tokens.clear();
|
||||||
@@ -186,7 +215,7 @@ public class DeckImportController {
|
|||||||
if (!this.allowedSections.isEmpty())
|
if (!this.allowedSections.isEmpty())
|
||||||
recognizer.setAllowedDeckSections(this.allowedSections);
|
recognizer.setAllowedDeckSections(this.allowedSections);
|
||||||
// Banned and Restricted Card Policy
|
// Banned and Restricted Card Policy
|
||||||
if (this.inlcludeBnRInDeck)
|
if (this.includeBnRInDeck)
|
||||||
recognizer.forceImportBannedAndRestrictedCards();
|
recognizer.forceImportBannedAndRestrictedCards();
|
||||||
|
|
||||||
String[] lines = input.split("\n");
|
String[] lines = input.split("\n");
|
||||||
@@ -196,8 +225,13 @@ public class DeckImportController {
|
|||||||
|
|
||||||
if (this.currentGameFormatAllowsCommander()) {
|
if (this.currentGameFormatAllowsCommander()) {
|
||||||
List<Pair<Integer, Token>> commanderTokens = getTokensInSection(DeckSection.Commander);
|
List<Pair<Integer, Token>> commanderTokens = getTokensInSection(DeckSection.Commander);
|
||||||
if (commanderTokens.isEmpty()) // Check commanders in Sideboard only if the commander section is empty
|
if (commanderTokens.isEmpty()) {
|
||||||
|
// Check commanders in Sideboard only if the commander section is empty
|
||||||
|
if(!getTokensInSection(DeckSection.Sideboard).isEmpty())
|
||||||
checkAndFixCommanderIn(DeckSection.Sideboard);
|
checkAndFixCommanderIn(DeckSection.Sideboard);
|
||||||
|
else
|
||||||
|
checkAndFixCommanderIn(DeckSection.Main);
|
||||||
|
}
|
||||||
checkAndFixCommanderIn(DeckSection.Commander);
|
checkAndFixCommanderIn(DeckSection.Commander);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +343,7 @@ public class DeckImportController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean currentGameFormatAllowsCommander(){
|
public boolean currentGameFormatAllowsCommander(){
|
||||||
return this.allowedSections.contains(DeckSection.Commander);
|
return this.allowedSections.contains(DeckSection.Commander) || this.currentGameType == GameType.PlanarConquest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Token> optimiseCardArtInTokens(){
|
public List<Token> optimiseCardArtInTokens(){
|
||||||
@@ -332,12 +366,7 @@ public class DeckImportController {
|
|||||||
else
|
else
|
||||||
refTokenMap = tokensPerSectionWithSet;
|
refTokenMap = tokensPerSectionWithSet;
|
||||||
|
|
||||||
List<Token> tokensInSection = refTokenMap.getOrDefault(tokenSection, null);
|
List<Token> tokensInSection = refTokenMap.computeIfAbsent(tokenSection, e -> new ArrayList<>());
|
||||||
if (tokensInSection == null) {
|
|
||||||
tokensInSection = new ArrayList<>();
|
|
||||||
tokensInSection.add(token);
|
|
||||||
refTokenMap.put(tokenSection, tokensInSection);
|
|
||||||
} else
|
|
||||||
tokensInSection.add(token);
|
tokensInSection.add(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +385,7 @@ public class DeckImportController {
|
|||||||
|
|
||||||
Map<DeckSection, CardPool> referencePoolPerSection = new HashMap<>();
|
Map<DeckSection, CardPool> referencePoolPerSection = new HashMap<>();
|
||||||
|
|
||||||
if (this.currentDeckNotEmpty && !this.createNewDeck && this.currentDeckInEditor != null){
|
if (this.currentDeckNotEmpty && this.importBehavior == ImportBehavior.MERGE && this.currentDeckInEditor != null){
|
||||||
// We will always consider ONLY sections for cards needing art optimisation
|
// We will always consider ONLY sections for cards needing art optimisation
|
||||||
for (DeckSection section : tokensPerSectionWithNoSet.keySet()){
|
for (DeckSection section : tokensPerSectionWithNoSet.keySet()){
|
||||||
CardPool cardsInDeck = this.currentDeckInEditor.get(section);
|
CardPool cardsInDeck = this.currentDeckInEditor.get(section);
|
||||||
@@ -436,6 +465,100 @@ public class DeckImportController {
|
|||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Token> constrainTokensToInventory() {
|
||||||
|
if(this.playerInventory == null)
|
||||||
|
return tokens;
|
||||||
|
CardPool availableInventory = new CardPool(this.playerInventory);
|
||||||
|
//Map of tokens to the things we're gonna replace them with.
|
||||||
|
Map<Token, List<Token>> tokenReplacers = new LinkedHashMap<>();
|
||||||
|
//If we're adding to our existing deck, ensure we aren't counting the cards already in it.
|
||||||
|
if(this.importBehavior == ImportBehavior.MERGE && this.currentDeckInEditor != null)
|
||||||
|
availableInventory.removeAll(this.currentDeckInEditor.getAllCardsInASinglePool(true, true));
|
||||||
|
if(this.currentGameType == GameType.PlanarConquest && currentDeckInEditor != null)
|
||||||
|
availableInventory.removeAllFlat(this.currentDeckInEditor.getCommanders());
|
||||||
|
//Step 1: For each token, if it's asking for more copies of a print than we can supply, split the difference out
|
||||||
|
//into a token that's indifferent to the edition. Reduce available inventory accordingly.
|
||||||
|
for (Token token : this.tokens) {
|
||||||
|
if (!token.isCardToken())
|
||||||
|
continue;
|
||||||
|
PaperCard card = token.getCard();
|
||||||
|
int requestedAmount = token.getQuantity();
|
||||||
|
if (card == null)
|
||||||
|
continue;
|
||||||
|
if (token.cardRequestHasNoCode()) {
|
||||||
|
List<Token> list = new ArrayList<>();
|
||||||
|
tokenReplacers.put(token, list);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int available = availableInventory.count(card);
|
||||||
|
if (available <= 0) {
|
||||||
|
List<Token> list = new ArrayList<>();
|
||||||
|
tokenReplacers.put(token, list);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int numTaken = Math.min(requestedAmount, available);
|
||||||
|
availableInventory.remove(card, numTaken);
|
||||||
|
if (available >= requestedAmount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
List<Token> list = new ArrayList<>();
|
||||||
|
list.add(Token.LegalCard(card, numTaken, token.getTokenSection(), true));
|
||||||
|
tokenReplacers.put(token, list);
|
||||||
|
}
|
||||||
|
if(tokenReplacers.isEmpty())
|
||||||
|
return tokens; //We have every card that was requested.
|
||||||
|
//Step 2: Try to find alternative prints for the ones that do not request an edition.
|
||||||
|
int capacity = tokens.size();
|
||||||
|
for(Map.Entry<Token, List<Token>> tokenReplacer : tokenReplacers.entrySet()) {
|
||||||
|
Token token = tokenReplacer.getKey();
|
||||||
|
DeckSection tokenSection = token.getTokenSection();
|
||||||
|
List<Token> replacementList = tokenReplacer.getValue();
|
||||||
|
PaperCard card = token.getCard();
|
||||||
|
String cardName = card.getName();
|
||||||
|
CardPool substitutes = availableInventory.getFilteredPool(c -> c.getName().equals(cardName));
|
||||||
|
List<Map.Entry<PaperCard, Integer>> sortedSubstitutes = StreamUtil.stream(substitutes).sorted(Comparator.comparingInt(Map.Entry::getValue)).toList();
|
||||||
|
int neededQuantity = token.getQuantity();
|
||||||
|
for(Token found : replacementList) {
|
||||||
|
//If there's an item in the replacement list already it means we've already found some of the needed copies.
|
||||||
|
neededQuantity -= found.getQuantity();
|
||||||
|
}
|
||||||
|
for(int i = 0; i < sortedSubstitutes.size() && neededQuantity > 0; i++) {
|
||||||
|
Map.Entry<PaperCard, Integer> item = sortedSubstitutes.get(i);
|
||||||
|
PaperCard replacement = item.getKey();
|
||||||
|
int toMove = Math.min(neededQuantity, item.getValue());
|
||||||
|
replacementList.add(Token.LegalCard(replacement, toMove, tokenSection, true));
|
||||||
|
availableInventory.remove(replacement, toMove);
|
||||||
|
neededQuantity -= toMove;
|
||||||
|
capacity++;
|
||||||
|
}
|
||||||
|
if(neededQuantity > 0) {
|
||||||
|
PaperCard freePrint = getInfiniteSupplyPrinting(card);
|
||||||
|
if(freePrint != null)
|
||||||
|
replacementList.add(Token.NotInInventoryFree(freePrint, neededQuantity, tokenSection));
|
||||||
|
else
|
||||||
|
replacementList.add(Token.NotInInventory(card, neededQuantity, tokenSection));
|
||||||
|
capacity++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Step 3: Apply the replacement list.
|
||||||
|
List<Token> newList = new ArrayList<>(capacity);
|
||||||
|
for(Token t : this.tokens) {
|
||||||
|
if(tokenReplacers.containsKey(t))
|
||||||
|
newList.addAll(tokenReplacers.get(t));
|
||||||
|
else
|
||||||
|
newList.add(t);
|
||||||
|
}
|
||||||
|
this.tokens.clear();
|
||||||
|
this.tokens.addAll(newList);
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PaperCard getInfiniteSupplyPrinting(PaperCard card) {
|
||||||
|
if(this.freePrintSupplier == null)
|
||||||
|
return null;
|
||||||
|
return freePrintSupplier.apply(card);
|
||||||
|
}
|
||||||
|
|
||||||
private int countTokens(List<Token> tokensInSection){
|
private int countTokens(List<Token> tokensInSection){
|
||||||
if (tokensInSection == null || tokensInSection.isEmpty())
|
if (tokensInSection == null || tokensInSection.isEmpty())
|
||||||
return 0;
|
return 0;
|
||||||
@@ -487,27 +610,31 @@ public class DeckImportController {
|
|||||||
if (tokens.isEmpty()) { return null; }
|
if (tokens.isEmpty()) { return null; }
|
||||||
|
|
||||||
String deckName = "";
|
String deckName = "";
|
||||||
if (currentDeckName != null && currentDeckName.trim().length() > 0)
|
if (currentDeckName != null && !currentDeckName.trim().isEmpty())
|
||||||
deckName = String.format("\"%s\"", currentDeckName.trim());
|
deckName = String.format("\"%s\"", currentDeckName.trim());
|
||||||
|
|
||||||
String tokenDeckName = getTokenDeckNameIfAny();
|
String tokenDeckName = getTokenDeckNameIfAny();
|
||||||
if (tokenDeckName.length() > 0)
|
if (!tokenDeckName.isEmpty())
|
||||||
tokenDeckName = String.format("\"%s\"", tokenDeckName);
|
tokenDeckName = String.format("\"%s\"", tokenDeckName);
|
||||||
|
|
||||||
if (createNewDeck){
|
if(this.currentDeckNotEmpty) {
|
||||||
String extraWarning = currentDeckNotEmpty ? localizer.getMessage("lblNewDeckWarning", deckName) : "";
|
final String warning;
|
||||||
final String warning = localizer.getMessage("lblConfirmCreateNewDeck", tokenDeckName, extraWarning);
|
final String title;
|
||||||
if (!SOptionPane.showConfirmDialog(warning, localizer.getMessage("lblNewDeckDialogTitle"),
|
if (this.importBehavior == ImportBehavior.CREATE_NEW) {
|
||||||
localizer.getMessage("lblYes"), localizer.getMessage("lblNo"))) {
|
String extraWarning = localizer.getMessage("lblNewDeckWarning", deckName);
|
||||||
return null;
|
warning = localizer.getMessage("lblConfirmCreateNewDeck", tokenDeckName, extraWarning);
|
||||||
}
|
title = localizer.getMessage("lblNewDeckDialogTitle");
|
||||||
}
|
} else if (this.importBehavior == ImportBehavior.MERGE){
|
||||||
else if (this.currentDeckNotEmpty){
|
String extraWarning = (!tokenDeckName.isEmpty() && !tokenDeckName.equals(deckName)) ?
|
||||||
String extraWarning = (tokenDeckName.length() > 0 && !tokenDeckName.equals(deckName)) ?
|
|
||||||
localizer.getMessage("lblCardImportWarning", deckName, tokenDeckName) : "";
|
localizer.getMessage("lblCardImportWarning", deckName, tokenDeckName) : "";
|
||||||
final String warning = localizer.getMessage("lblConfirmCardImport", deckName, extraWarning);
|
warning = localizer.getMessage("lblConfirmCardImport", deckName, extraWarning);
|
||||||
if (!SOptionPane.showConfirmDialog(warning,
|
title = localizer.getMessage("lblImportCardsDialogTitle");
|
||||||
localizer.getMessage("lblImportCardsDialogTitle"),
|
}
|
||||||
|
else {
|
||||||
|
warning = localizer.getMessage("lblConfirmReplaceDeck", deckName);
|
||||||
|
title = localizer.getMessage("lblNewDeckDialogTitle");
|
||||||
|
}
|
||||||
|
if (!SOptionPane.showConfirmDialog(warning, title,
|
||||||
localizer.getMessage("lblYes"), localizer.getMessage("lblNo")))
|
localizer.getMessage("lblYes"), localizer.getMessage("lblNo")))
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -516,7 +643,7 @@ public class DeckImportController {
|
|||||||
final TokenType type = t.getType();
|
final TokenType type = t.getType();
|
||||||
// only Deck Name, legal card and limited card tokens will be analysed!
|
// only Deck Name, legal card and limited card tokens will be analysed!
|
||||||
if (!t.isTokenForDeck() ||
|
if (!t.isTokenForDeck() ||
|
||||||
(type == TokenType.LIMITED_CARD && !this.inlcludeBnRInDeck))
|
(type == TokenType.LIMITED_CARD && !this.includeBnRInDeck))
|
||||||
continue; // SKIP token
|
continue; // SKIP token
|
||||||
|
|
||||||
if (type == TokenType.DECK_NAME) {
|
if (type == TokenType.DECK_NAME) {
|
||||||
@@ -547,4 +674,66 @@ public class DeckImportController {
|
|||||||
}
|
}
|
||||||
return ""; // no deck name
|
return ""; // no deck name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTokenMessage(DeckRecognizer.Token token) {
|
||||||
|
return switch (token.getType()) {
|
||||||
|
case LEGAL_CARD, LIMITED_CARD, CARD_FROM_NOT_ALLOWED_SET, CARD_FROM_INVALID_SET,
|
||||||
|
CARD_NOT_IN_INVENTORY, FREE_CARD_NOT_IN_INVENTORY ->
|
||||||
|
String.format("%s x %s %s", token.getQuantity(), token.getText(), getTokenFoilLabel(token));
|
||||||
|
// Card Warning Msgs
|
||||||
|
case UNKNOWN_CARD, UNSUPPORTED_CARD ->
|
||||||
|
token.getQuantity() > 0 ? String.format("%s x %s", token.getQuantity(), token.getText())
|
||||||
|
: token.getText();
|
||||||
|
case UNSUPPORTED_DECK_SECTION ->
|
||||||
|
String.format("%s: %s", Localizer.getInstance().getMessage("lblWarningMsgPrefix"),
|
||||||
|
Localizer.getInstance()
|
||||||
|
.getMessage("lblWarnDeckSectionNotAllowedInEditor", token.getText(),
|
||||||
|
this.currentGameType.name()));
|
||||||
|
|
||||||
|
// Special Case of Card moved into another section (e.g. Commander from Sideboard)
|
||||||
|
case WARNING_MESSAGE -> String.format("%s: %s", Localizer.getInstance()
|
||||||
|
.getMessage("lblWarningMsgPrefix"), token.getText());
|
||||||
|
|
||||||
|
// Placeholders
|
||||||
|
case DECK_SECTION_NAME -> String.format("%s: %s", Localizer.getInstance().getMessage("lblDeckSection"),
|
||||||
|
token.getText());
|
||||||
|
case CARD_RARITY -> String.format("%s: %s", Localizer.getInstance().getMessage("lblRarity"),
|
||||||
|
token.getText());
|
||||||
|
case CARD_TYPE, CARD_CMC, MANA_COLOUR, COMMENT, UNKNOWN_TEXT -> token.getText();
|
||||||
|
case DECK_NAME -> String.format("%s: %s", Localizer.getInstance().getMessage("lblDeckName"),
|
||||||
|
token.getText());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTokenStatusMessage(DeckRecognizer.Token token) {
|
||||||
|
if (token == null)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
final Localizer localizer = Localizer.getInstance();
|
||||||
|
return switch (token.getType()) {
|
||||||
|
case LIMITED_CARD -> String.format("%s: %s", localizer.getMessage("lblWarningMsgPrefix"),
|
||||||
|
localizer.getMessage("lblWarnLimitedCard",
|
||||||
|
StringUtils.capitalize(token.getLimitedCardType().name()), getGameFormatLabel()));
|
||||||
|
case CARD_FROM_NOT_ALLOWED_SET ->
|
||||||
|
localizer.getMessage("lblErrNotAllowedCard", getGameFormatLabel());
|
||||||
|
case CARD_FROM_INVALID_SET -> localizer.getMessage("lblErrCardEditionDate");
|
||||||
|
case UNSUPPORTED_CARD -> localizer.getMessage("lblErrUnsupportedCard", this.currentGameType);
|
||||||
|
case UNKNOWN_CARD -> String.format("%s: %s", localizer.getMessage("lblWarningMsgPrefix"),
|
||||||
|
localizer.getMessage("lblWarnUnknownCardMsg"));
|
||||||
|
case CARD_NOT_IN_INVENTORY -> localizer.getMessage("lblWarnNotInInventory");
|
||||||
|
default -> "";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getTokenFoilLabel(DeckRecognizer.Token token) {
|
||||||
|
if (!token.isCardToken())
|
||||||
|
return "";
|
||||||
|
final String foilMarker = "- (Foil)";
|
||||||
|
return token.getCard().isFoil() ? foilMarker : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getGameFormatLabel() {
|
||||||
|
return String.format("\"%s\"", this.getCurrentGameFormatName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -774,7 +774,7 @@ public class DeckProxy implements InventoryItem {
|
|||||||
|
|
||||||
for (PaperCard c : deck.getAllCardsInASinglePool().toFlatList()) {
|
for (PaperCard c : deck.getAllCardsInASinglePool().toFlatList()) {
|
||||||
CardEdition edition = FModel.getMagicDb().getEditions().get(c.getEdition());
|
CardEdition edition = FModel.getMagicDb().getEditions().get(c.getEdition());
|
||||||
if (edition == null)
|
if (edition == null || !edition.hasBasicLands())
|
||||||
continue;
|
continue;
|
||||||
availableEditions.add(edition);
|
availableEditions.add(edition);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,11 @@
|
|||||||
package forge.gamemodes.planarconquest;
|
package forge.gamemodes.planarconquest;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import forge.card.CardDb;
|
import forge.card.CardDb;
|
||||||
import forge.gamemodes.planarconquest.ConquestPreferences.CQPref;
|
import forge.gamemodes.planarconquest.ConquestPreferences.CQPref;
|
||||||
@@ -199,14 +195,11 @@ public final class ConquestData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getAccessiblePlaneCount() {
|
public int getAccessiblePlaneCount() {
|
||||||
// TODO: Java 8 stream implementation of filtering
|
return (int) FModel.getPlanes().stream().filter(Predicate.not(ConquestPlane::isUnreachable)).count();
|
||||||
int i = 0;
|
|
||||||
for (ConquestPlane plane : FModel.getPlanes()) {
|
|
||||||
if (!plane.isUnreachable()) {
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return i;
|
public Set<ConquestPlane> getUnlockedPlanes() {
|
||||||
|
return planeDataMap.values().stream().map(ConquestPlaneData::getLocation).map(ConquestLocation::getPlane).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unlockPlane(ConquestPlane plane) {
|
public void unlockPlane(ConquestPlane plane) {
|
||||||
@@ -302,7 +295,7 @@ public final class ConquestData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commandersUsingCard.length() > 0) {
|
if (!commandersUsingCard.isEmpty()) {
|
||||||
SOptionPane.showMessageDialog(Localizer.getInstance().getMessage("lblCommandersCardCannotBeExiledByCard", CardTranslation.getTranslatedName(card.getName()), commandersUsingCard), title, SOptionPane.INFORMATION_ICON);
|
SOptionPane.showMessageDialog(Localizer.getInstance().getMessage("lblCommandersCardCannotBeExiledByCard", CardTranslation.getTranslatedName(card.getName()), commandersUsingCard), title, SOptionPane.INFORMATION_ICON);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public class ConquestPlane {
|
|||||||
private FCollection<PaperCard> commanders;
|
private FCollection<PaperCard> commanders;
|
||||||
private ConquestAwardPool awardPool;
|
private ConquestAwardPool awardPool;
|
||||||
private ConquestEvent[] events;
|
private ConquestEvent[] events;
|
||||||
|
private final Set<CardEdition> editions = new HashSet<>();
|
||||||
|
|
||||||
private ConquestPlane(String name0, String description0, int regionSize0, boolean unreachable0) {
|
private ConquestPlane(String name0, String description0, int regionSize0, boolean unreachable0) {
|
||||||
name = name0;
|
name = name0;
|
||||||
@@ -153,6 +154,10 @@ public class ConquestPlane {
|
|||||||
return planeCards;
|
return planeCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<CardEdition> getEditions() {
|
||||||
|
return editions;
|
||||||
|
}
|
||||||
|
|
||||||
private void ensureRegionsLoaded() {
|
private void ensureRegionsLoaded() {
|
||||||
if (regions != null) { return; }
|
if (regions != null) { return; }
|
||||||
|
|
||||||
@@ -193,6 +198,8 @@ public class ConquestPlane {
|
|||||||
if (edition == null)
|
if (edition == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
editions.add(edition);
|
||||||
|
|
||||||
for (EditionEntry card : edition.getObtainableCards()) {
|
for (EditionEntry card : edition.getObtainableCards()) {
|
||||||
if (bannedCardSet == null || !bannedCardSet.contains(card.name())) {
|
if (bannedCardSet == null || !bannedCardSet.contains(card.name())) {
|
||||||
addCard(commonCards.getCard(card.name(), setCode));
|
addCard(commonCards.getCard(card.name(), setCode));
|
||||||
|
|||||||
@@ -1,22 +1,16 @@
|
|||||||
package forge.gamemodes.planarconquest;
|
package forge.gamemodes.planarconquest;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
import forge.card.CardRarity;
|
import forge.card.*;
|
||||||
import forge.card.CardRules;
|
|
||||||
import forge.card.CardType;
|
|
||||||
import forge.card.CardType.CoreType;
|
import forge.card.CardType.CoreType;
|
||||||
import forge.card.ColorSet;
|
|
||||||
import forge.card.MagicColor;
|
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
@@ -143,6 +137,25 @@ public class ConquestUtil {
|
|||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<CardEdition> getBasicLandSets(Deck currentDeck) {
|
||||||
|
ConquestData model = FModel.getConquest().getModel();
|
||||||
|
List<ConquestPlane> planes = new ArrayList<>(model.getUnlockedPlanes());
|
||||||
|
ConquestPlane currentPlane = model.getCurrentPlane();
|
||||||
|
//Move the current plane to the front.
|
||||||
|
if(currentPlane != null && planes.contains(currentPlane)) {
|
||||||
|
planes.remove(currentPlane);
|
||||||
|
planes.add(0, currentPlane);
|
||||||
|
}
|
||||||
|
//Move editions of cards already in the deck to the front.
|
||||||
|
Map<CardEdition, Integer> editionStats = currentDeck.getAllCardsInASinglePool().getCardEditionStatistics(true);
|
||||||
|
List<CardEdition> out = planes.stream()
|
||||||
|
.<CardEdition>mapMulti((p, c) -> p.getEditions().forEach(c))
|
||||||
|
.filter(CardEdition::hasBasicLands)
|
||||||
|
.sorted(Comparator.comparing(e -> editionStats.getOrDefault(e, 0)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
public static ConquestPlane getPlaneByName(String planeName) {
|
public static ConquestPlane getPlaneByName(String planeName) {
|
||||||
for (ConquestPlane plane : FModel.getPlanes()) {
|
for (ConquestPlane plane : FModel.getPlanes()) {
|
||||||
if (plane.getName().equals(planeName)) {
|
if (plane.getName().equals(planeName)) {
|
||||||
@@ -189,19 +202,16 @@ public class ConquestUtil {
|
|||||||
public static int getShardValue(CardRarity rarity, CQPref baseValuePref) {
|
public static int getShardValue(CardRarity rarity, CQPref baseValuePref) {
|
||||||
ConquestPreferences prefs = FModel.getConquestPreferences();
|
ConquestPreferences prefs = FModel.getConquestPreferences();
|
||||||
int baseValue = prefs.getPrefInt(baseValuePref);
|
int baseValue = prefs.getPrefInt(baseValuePref);
|
||||||
switch (rarity) {
|
return switch (rarity) {
|
||||||
case Common:
|
case Common -> baseValue;
|
||||||
return baseValue;
|
case Uncommon ->
|
||||||
case Uncommon:
|
Math.round((float) baseValue * (float) prefs.getPrefInt(CQPref.AETHER_UNCOMMON_MULTIPLIER));
|
||||||
return Math.round((float)baseValue * (float)prefs.getPrefInt(CQPref.AETHER_UNCOMMON_MULTIPLIER));
|
case Rare, Special ->
|
||||||
case Rare:
|
Math.round((float) baseValue * (float) prefs.getPrefInt(CQPref.AETHER_RARE_MULTIPLIER));
|
||||||
case Special:
|
case MythicRare ->
|
||||||
return Math.round((float)baseValue * (float)prefs.getPrefInt(CQPref.AETHER_RARE_MULTIPLIER));
|
Math.round((float) baseValue * (float) prefs.getPrefInt(CQPref.AETHER_MYTHIC_MULTIPLIER));
|
||||||
case MythicRare:
|
default -> 0;
|
||||||
return Math.round((float)baseValue * (float)prefs.getPrefInt(CQPref.AETHER_MYTHIC_MULTIPLIER));
|
};
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AEtherFilter implements IHasSkinProp {
|
public enum AEtherFilter implements IHasSkinProp {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package forge.gamemodes.quest;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
@@ -620,17 +621,21 @@ public class QuestController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CardEdition getDefaultLandSet() {
|
public CardEdition getDefaultLandSet() {
|
||||||
List<String> availableEditionCodes = questFormat != null ? questFormat.getAllowedSetCodes() : Lists.newArrayList(FModel.getMagicDb().getEditions().getItemNames());
|
List<CardEdition> availableEditions = getAvailableLandSets();
|
||||||
List<CardEdition> availableEditions = new ArrayList<>();
|
|
||||||
|
|
||||||
for (String s : availableEditionCodes) {
|
|
||||||
availableEditions.add(FModel.getMagicDb().getEditions().get(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
CardEdition randomLandSet = CardEdition.Predicates.getRandomSetWithAllBasicLands(availableEditions);
|
CardEdition randomLandSet = CardEdition.Predicates.getRandomSetWithAllBasicLands(availableEditions);
|
||||||
return randomLandSet == null ? FModel.getMagicDb().getEditions().get("ZEN") : randomLandSet;
|
return randomLandSet == null ? FModel.getMagicDb().getEditions().get("ZEN") : randomLandSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<CardEdition> getAvailableLandSets() {
|
||||||
|
List<String> availableEditionCodes = questFormat != null ? questFormat.getAllowedSetCodes() : Lists.newArrayList(FModel.getMagicDb().getEditions().getItemNames());
|
||||||
|
CardEdition.Collection editions = FModel.getMagicDb().getEditions();
|
||||||
|
return availableEditionCodes.stream()
|
||||||
|
.map(editions::get)
|
||||||
|
.filter(CardEdition::hasBasicLands)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
public String getCurrentDeck() {
|
public String getCurrentDeck() {
|
||||||
return model.currentDeck;
|
return model.currentDeck;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user