diff --git a/forge-core/src/main/java/forge/deck/Deck.java b/forge-core/src/main/java/forge/deck/Deck.java index 25f3f94723b..cecdd712e8d 100644 --- a/forge-core/src/main/java/forge/deck/Deck.java +++ b/forge-core/src/main/java/forge/deck/Deck.java @@ -51,6 +51,7 @@ public class Deck extends DeckBase implements Iterable> unplayable = new HashMap<>(); + public final int inMainDeck; + + private UnplayableAICards(Deck myDeck) { + int mainDeck = 0; + for (Entry ds : myDeck) { + List result = Lists.newArrayList(); + for (Entry cp : ds.getValue()) { + if (cp.getKey().getRules().getAiHints().getRemAIDecks()) { + result.add(cp.getKey()); + } + } + if (ds.getKey().equals(DeckSection.Main)) { + mainDeck = result.size(); + } + if (!result.isEmpty()) { + unplayable.put(ds.getKey(), result); + } + } + inMainDeck = mainDeck; + } + } + @Override public boolean isEmpty() { loadDeferredSections(); diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/views/DeckAIRenderer.java b/forge-gui-desktop/src/main/java/forge/itemmanager/views/DeckAIRenderer.java new file mode 100644 index 00000000000..09d4403e60a --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/views/DeckAIRenderer.java @@ -0,0 +1,56 @@ + +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.itemmanager.views; + +import java.awt.Component; +import java.util.TreeSet; + +import javax.swing.JTable; + +import forge.deck.Deck; +import forge.deck.DeckSection; +import forge.util.DeckAIUtils; +import forge.util.Localizer; + + +public class DeckAIRenderer extends ItemCellRenderer { + + private final Localizer localizer = Localizer.getInstance(); + + @Override + public boolean alwaysShowTooltip() { + return false; + } + + @Override + public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) { + final StringBuilder label = new StringBuilder(""); + final StringBuilder tooltip = new StringBuilder(""); + if (value instanceof Deck.UnplayableAICards) { + final Deck.UnplayableAICards removedUnplayableCards = ((Deck.UnplayableAICards) value); + for (final DeckSection s: new TreeSet<>(removedUnplayableCards.unplayable.keySet())) { + int unplayableSize = removedUnplayableCards.unplayable.get(s).size(); + tooltip.append("[" + DeckAIUtils.getLocalizedDeckSection(localizer, s) + ":" + unplayableSize + "]"); + } + label.append(removedUnplayableCards.inMainDeck > 0 ? "" + removedUnplayableCards.inMainDeck : ""); + } + setToolTipText(tooltip.toString()); + return super.getTableCellRendererComponent(table, label.toString(), isSelected, hasFocus, row, row); + } +} \ No newline at end of file diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/views/ItemCellRenderer.java b/forge-gui-desktop/src/main/java/forge/itemmanager/views/ItemCellRenderer.java index 7da3727fbfd..93ea8eaf42c 100644 --- a/forge-gui-desktop/src/main/java/forge/itemmanager/views/ItemCellRenderer.java +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/views/ItemCellRenderer.java @@ -58,6 +58,8 @@ public class ItemCellRenderer extends DefaultTableCellRenderer { return new DeckStarRenderer(); case DECK_QUANTITY: return new DeckQuantityRenderer(); + case DECK_AI: + return new DeckAIRenderer(); default: return new ItemCellRenderer(); } diff --git a/forge-gui-mobile/src/forge/itemmanager/DeckManager.java b/forge-gui-mobile/src/forge/itemmanager/DeckManager.java index 536ea5cbebc..f0523edca1c 100644 --- a/forge-gui-mobile/src/forge/itemmanager/DeckManager.java +++ b/forge-gui-mobile/src/forge/itemmanager/DeckManager.java @@ -134,7 +134,7 @@ public final class DeckManager extends ItemManager implements IHasGam x += IMAGE_SIZE + FList.PADDING; ColorSet deckColor = deck.getColor(); float availableNameWidth = w - CardFaceSymbols.getWidth(deckColor, IMAGE_SIZE) - IMAGE_SIZE - 2 * FList.PADDING; - if (deck.getAI()) { + if (deck.getAI().inMainDeck == 0) { g.drawOutlinedText("AI", font, Color.GREEN, Color.BLACK, x, y, w, IMAGE_SIZE, true, Align.left, true, false); x += IMAGE_SIZE + FList.PADDING; } diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index d5b5ea3bf49..ca8984bbef6 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -1065,7 +1065,7 @@ public class ImageView extends ItemView { g.drawImage(DeckPreferences.getPrefs(dp).getStarCount() > 0 ? FSkinImage.HDSTAR_FILLED : FSkinImage.HDSTAR_OUTLINE, x, y, symbolSize, symbolSize); else g.drawImage(DeckPreferences.getPrefs(dp).getStarCount() > 0 ? FSkinImage.STAR_FILLED : FSkinImage.STAR_OUTLINE, x, y, symbolSize, symbolSize); - if (dp.getAI()) { + if (dp.getAI().inMainDeck == 0) { g.drawOutlinedText("AI", GROUP_HEADER_FONT, Color.GREEN, Color.BLACK, x+PADDING, y+symbolSize+PADDING, w, h, true, Align.left, false, false); } } diff --git a/forge-gui/src/main/java/forge/deck/DeckProxy.java b/forge-gui/src/main/java/forge/deck/DeckProxy.java index 12c5e6cd7ea..750b16579c1 100644 --- a/forge-gui/src/main/java/forge/deck/DeckProxy.java +++ b/forge-gui/src/main/java/forge/deck/DeckProxy.java @@ -42,7 +42,6 @@ public class DeckProxy implements InventoryItem { // cached values protected ColorSet color; protected ColorSet colorIdentity; - protected Boolean ai; protected Set formats; protected Set exhaustiveFormats; private Integer mainSize = null; @@ -141,7 +140,6 @@ public class DeckProxy implements InventoryItem { edition = null; mainSize = null; sbSize = null; - ai = null; } public ColorSet getColor() { @@ -213,32 +211,8 @@ public class DeckProxy implements InventoryItem { return colorIdentity; } - public boolean getAI() { - if (ai == null) { - boolean hasAi = true; - for (final Entry deckEntry : getDeck()) { - switch (deckEntry.getKey()) { - case Main: - case Commander: - for (final Entry poolEntry : deckEntry.getValue()) { - CardAiHints ai = poolEntry.getKey().getRules().getAiHints(); - if (ai.getRemAIDecks()) { - hasAi = false; - break; - } - } - break; - case Sideboard: // Let's pretend the sideboard doesn't matter - default: - break; //ignore other sections - } - if (hasAi == false) { - break; - } - } - ai = hasAi; - } - return ai; + public Deck.UnplayableAICards getAI() { + return getDeck().getUnplayableAICards(); } diff --git a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java index 5d337c6c2fa..fce43bc1f8c 100644 --- a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java +++ b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java @@ -463,13 +463,13 @@ public enum ColumnDef { new Function, Comparable>() { @Override public Comparable apply(final Entry from) { - return toDeck(from.getKey()).getAI() ? Integer.valueOf(1) : Integer.valueOf(-1); + return toDeck(from.getKey()).getAI().inMainDeck; } }, new Function, Object>() { @Override public Object apply(final Entry from) { - return toDeck(from.getKey()).getAI()? "" : "X"; + return toDeck(from.getKey()).getAI(); } }), /** diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 74fa37f7205..e5b8f11f894 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -17,6 +17,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.TreeSet; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.Range; @@ -133,6 +134,7 @@ import forge.localinstance.properties.ForgePreferences.FPref; import forge.localinstance.skin.FSkinProp; import forge.model.FModel; import forge.util.CardTranslation; +import forge.util.DeckAIUtils; import forge.util.ITriggerEvent; import forge.util.Lang; import forge.util.Localizer; @@ -2093,8 +2095,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont for (Player p : unplayable.keySet()) { final Map> removedUnplayableCards = unplayable.get(p); final List labels = new ArrayList<>(); - for (final DeckSection s: removedUnplayableCards.keySet()) { - labels.add("=== " + getLocalizedDeckSection(s) + " ==="); + for (final DeckSection s: new TreeSet<>(removedUnplayableCards.keySet())) { + labels.add("=== " + DeckAIUtils.getLocalizedDeckSection(localizer, s) + " ==="); for (PaperCard c: removedUnplayableCards.get(s)) { labels.add(c.toString()); } @@ -2104,20 +2106,6 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont } } - private String getLocalizedDeckSection(DeckSection d) { - switch (d) { - case Avatar: return localizer.getMessage("lblAvatar"); - case Commander: return localizer.getMessage("lblCommanderDeck"); - case Main: return localizer.getMessage("lblMainDeck"); - case Sideboard: return localizer.getMessage("lblSideboard"); - case Planes: return localizer.getMessage("lblPlanarDeck"); - case Schemes: return localizer.getMessage("lblSchemeDeck"); - case Conspiracy: return /* TODO localise */ "Conspiracy"; - case Dungeon: return /* TODO localise */ "Dungeon"; - default: return /* TODO better handling */ "UNKNOWN"; - } - } - @Override public List chooseCardsYouWonToAddToDeck(final List losses) { return getGui().many(localizer.getMessage("lblSelectCardstoAddtoYourDeck"), localizer.getMessage("lblAddTheseToMyDeck"), 0, losses.size(), losses, null); diff --git a/forge-gui/src/main/java/forge/util/DeckAIUtils.java b/forge-gui/src/main/java/forge/util/DeckAIUtils.java new file mode 100644 index 00000000000..31548edd400 --- /dev/null +++ b/forge-gui/src/main/java/forge/util/DeckAIUtils.java @@ -0,0 +1,39 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.util; + +import forge.deck.DeckSection; + +public class DeckAIUtils { + private DeckAIUtils() { + } + + public static String getLocalizedDeckSection(Localizer localizer, DeckSection d) { + switch (d) { + case Avatar: return localizer.getMessage("lblAvatar"); + case Commander: return localizer.getMessage("lblCommanderDeck"); + case Main: return localizer.getMessage("lblMainDeck"); + case Sideboard: return localizer.getMessage("lblSideboard"); + case Planes: return localizer.getMessage("lblPlanarDeck"); + case Schemes: return localizer.getMessage("lblSchemeDeck"); + case Conspiracy: return /* TODO localise */ "Conspiracy"; + case Dungeon: return /* TODO localise */ "Dungeon"; + default: return /* TODO better handling */ "UNKNOWN"; + } + } +} \ No newline at end of file