diff --git a/forge-core/src/main/java/forge/StaticData.java b/forge-core/src/main/java/forge/StaticData.java index c30ab9f96a5..157dd6ba897 100644 --- a/forge-core/src/main/java/forge/StaticData.java +++ b/forge-core/src/main/java/forge/StaticData.java @@ -13,14 +13,10 @@ import forge.util.storage.IStorage; import forge.util.storage.StorageBase; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; - /** +/** * The class holding game invariants, such as cards, editions, game formats. All that data, which is not supposed to be changed by player * * @author Max @@ -165,4 +161,28 @@ public class StaticData { public CardDb getVariantCards() { return variantCards; } + + public PaperCard getCardByEditionDate(PaperCard card, Date editionDate) { + + PaperCard c = this.getCommonCards().getCardFromEdition(card.getName(), editionDate, CardDb.SetPreference.LatestCoreExp, card.getArtIndex()); + + if (null != c) { + return c; + } + + c = this.getCommonCards().getCardFromEdition(card.getName(), editionDate, CardDb.SetPreference.LatestCoreExp, -1); + + if (null != c) { + return c; + } + + c = this.getCommonCards().getCardFromEdition(card.getName(), editionDate, CardDb.SetPreference.Latest, -1); + + if (null != c) { + return c; + } + + // I give up! + return card; + } } diff --git a/forge-core/src/main/java/forge/card/CardEdition.java b/forge-core/src/main/java/forge/card/CardEdition.java index bf8c0b58189..0b7558cb3a1 100644 --- a/forge-core/src/main/java/forge/card/CardEdition.java +++ b/forge-core/src/main/java/forge/card/CardEdition.java @@ -469,6 +469,15 @@ public final class CardEdition implements Comparable { // immutable } return UNKNOWN; } + + public Date getEarliestDateWithAllCards(CardPool cardPool) { + CardEdition earliestSet = StaticData.instance().getEditions().getEarliestEditionWithAllCards(cardPool); + + Calendar cal = Calendar.getInstance(); + cal.setTime(earliestSet.getDate()); + cal.add(Calendar.DATE, 1); + return cal.getTime(); + } } public static class Predicates { diff --git a/forge-core/src/main/java/forge/deck/Deck.java b/forge-core/src/main/java/forge/deck/Deck.java index 35f5299bbe5..832afddc05f 100644 --- a/forge-core/src/main/java/forge/deck/Deck.java +++ b/forge-core/src/main/java/forge/deck/Deck.java @@ -23,7 +23,6 @@ import com.google.common.collect.Lists; import forge.StaticData; import forge.card.CardDb.SetPreference; import forge.card.CardDb; -import forge.card.CardEdition; import forge.item.IPaperCard; import forge.item.PaperCard; @@ -218,36 +217,27 @@ public class Deck extends DeckBase implements Iterable p : parts.entrySet()) { if( p.getKey() == DeckSection.Planes || p.getKey() == DeckSection.Schemes || p.getKey() == DeckSection.Avatar) continue; - + CardPool newPool = new CardPool(); - + for(Entry cp : p.getValue()){ - String cardName = cp.getKey().getName(); - int artIndex = cp.getKey().getArtIndex(); - - PaperCard c = StaticData.instance().getCommonCards().getCardFromEdition(cardName, dayAfterNewestSetRelease, SetPreference.LatestCoreExp, artIndex); - if( null == c ) { - c = StaticData.instance().getCommonCards().getCardFromEdition(cardName, dayAfterNewestSetRelease, SetPreference.LatestCoreExp, -1); - if( c == null) - c = StaticData.instance().getCommonCards().getCardFromEdition(cardName, dayAfterNewestSetRelease, SetPreference.Latest, -1); - - if( c != null ) { - newPool.add(cardName, c.getEdition(), cp.getValue()); // this is to randomize art of all those cards - } else // I give up! - newPool.add(cp.getKey(), cp.getValue()); - } else - newPool.add(c, cp.getValue()); + PaperCard card = cp.getKey(); + int count = cp.getValue(); + + PaperCard replacementCard = StaticData.instance().getCardByEditionDate(card, dateWithAllCards); + + if (replacementCard.getArtIndex() == card.getArtIndex()) { + newPool.add(card, count); + } else { + newPool.add(card.getName(), card.getEdition(), count); // this is to randomize art + } } + parts.put(p.getKey(), newPool); } } @@ -302,6 +292,14 @@ public class Deck extends DeckBase implements Iterable, In /** * Sets the comment. * - * @param comment the new comment + * @param comment0 the new comment */ public void setComment(final String comment0) { comment = comment0; @@ -148,4 +148,6 @@ public abstract class DeckBase implements Serializable, Comparable, In } public abstract boolean isEmpty(); + + public abstract void importDeck(Deck deck); } diff --git a/forge-core/src/main/java/forge/deck/DeckGroup.java b/forge-core/src/main/java/forge/deck/DeckGroup.java index cdb869613f1..599449d69a2 100644 --- a/forge-core/src/main/java/forge/deck/DeckGroup.java +++ b/forge-core/src/main/java/forge/deck/DeckGroup.java @@ -18,11 +18,10 @@ package forge.deck; import com.google.common.base.Function; +import forge.StaticData; +import forge.item.PaperCard; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.*; /** * TODO: Write javadoc for this type. @@ -143,7 +142,7 @@ public class DeckGroup extends DeckBase { return arg1.getName(); } }; - + public static final Function FN_HUMAN_DECK = new Function() { @Override @@ -161,4 +160,100 @@ public class DeckGroup extends DeckBase { public String getImageKey(boolean altState) { return null; } + + + @Override + public void importDeck(Deck deck) { + CardPool draftedCards = this.getHumanDeck().getAllCardsInASinglePool(false); + + this.getHumanDeck().putSection(DeckSection.Main, new CardPool()); + this.getHumanDeck().putSection(DeckSection.Sideboard, new CardPool()); + + HashMap countByName = getCountByName(deck); + + addFromDraftedCardPool(countByName, draftedCards); + addBasicLands(deck, countByName, draftedCards); + } + + private HashMap getCountByName(Deck deck) { + HashMap result = new HashMap(); + + for (Map.Entry entry: deck.getMain()) { + PaperCard importedCard = entry.getKey(); + + Integer previousCount = result.getOrDefault(importedCard.getName(), 0); + int countToAdd = entry.getValue(); + + result.put(importedCard.getName(), countToAdd + previousCount); + } + + return result; + } + + private void addFromDraftedCardPool(HashMap countByName, CardPool availableCards) { + for (Map.Entry entry: availableCards) { + + PaperCard availableCard = entry.getKey(); + Integer availableCount = entry.getValue(); + int countToAdd = countByName.getOrDefault(availableCard.getName(), 0); + + if (availableCard.getRules().getType().isBasicLand()) { + // basic lands are added regardless from drafted cards + continue; + } + + int countMain = Math.min(availableCount, countToAdd); + + if (countMain > 0) { + this.getHumanDeck().getMain().add(availableCard, countMain); + countByName.put(availableCard.getName(), countToAdd - countMain); + } + + int countSideboard = availableCount - countMain; + + if (countSideboard > 0) { + CardPool sideboard = this.getHumanDeck().getOrCreate(DeckSection.Sideboard); + sideboard.add(availableCard, countSideboard); + } + } + } + + private void addBasicLands(Deck deck, HashMap countByName, CardPool availableCards) { + HashMap basicLandsByName = getBasicLandsByName(deck, countByName); + + Date dateWithAllCards = StaticData.instance().getEditions().getEarliestDateWithAllCards(availableCards); + for (String cardName: countByName.keySet()) { + + PaperCard card = basicLandsByName.getOrDefault(cardName, null); + + if (card == null) { + continue; + } + + int countToAdd = countByName.get(cardName); + + card = StaticData.instance().getCardByEditionDate(card, dateWithAllCards); + this.getHumanDeck().getMain().add(card.getName(), card.getEdition(), countToAdd); + } + } + + private HashMap getBasicLandsByName(Deck deck, HashMap countByName) { + HashMap result = new HashMap(); + + for (Map.Entry entry: deck.getMain()) { + PaperCard card = entry.getKey(); + + if (!card.getRules().getType().isBasicLand()) { + continue; + } + + if (result.containsKey(card.getName())) { + continue; + } + + result.put(card.getName(), card); + } + + return result; + } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/DeckImport.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/DeckImport.java index 4552e7a9f62..bef0304d2f6 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/DeckImport.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/DeckImport.java @@ -33,6 +33,7 @@ import forge.deck.DeckRecognizer; import forge.deck.DeckRecognizer.TokenType; import forge.item.InventoryItem; import forge.screens.deckeditor.controllers.ACEditorBase; +import forge.screens.deckeditor.controllers.DeckController; import forge.toolbox.FButton; import forge.toolbox.FCheckBox; import forge.toolbox.FComboBox; @@ -144,10 +145,15 @@ public class DeckImport ex @SuppressWarnings("unchecked") @Override public void actionPerformed(final ActionEvent e) { - final Deck toSet = controller.accept(); - if (toSet == null) { return; } + final Deck deck = controller.accept(); + if (deck == null) { return; } + + DeckController controller = DeckImport.this.host.getDeckController(); + TModel model = controller.getModel(); + + model.importDeck(deck); + controller.setModel(model); - DeckImport.this.host.getDeckController().setModel((TModel) toSet); DeckImport.this.processWindowEvent(new WindowEvent(DeckImport.this, WindowEvent.WINDOW_CLOSING)); } }); diff --git a/forge-gui/src/main/java/forge/limited/CustomLimited.java b/forge-gui/src/main/java/forge/limited/CustomLimited.java index 68a6c326c99..5cecbfc5fd1 100644 --- a/forge-gui/src/main/java/forge/limited/CustomLimited.java +++ b/forge-gui/src/main/java/forge/limited/CustomLimited.java @@ -188,6 +188,11 @@ public class CustomLimited extends DeckBase { return cardPool.isEmpty(); } + @Override + public void importDeck(Deck deck) { + throw new UnsupportedOperationException("CustomDraft does not support deck import"); + } + @Override public String getImageKey(boolean altState) { return null;