diff --git a/forge-core/src/main/java/forge/card/CardRules.java b/forge-core/src/main/java/forge/card/CardRules.java index db8e4bc5ec6..1989d7c284d 100644 --- a/forge-core/src/main/java/forge/card/CardRules.java +++ b/forge-core/src/main/java/forge/card/CardRules.java @@ -17,14 +17,14 @@ */ package forge.card; -import java.util.StringTokenizer; - -import forge.util.TextUtil; -import org.apache.commons.lang3.StringUtils; - +import com.google.common.collect.Iterables; import forge.card.mana.IParserManaCost; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostShard; +import forge.util.TextUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.StringTokenizer; /** * A collection of methods containing full @@ -199,6 +199,10 @@ public final class CardRules implements ICardCharacteristics { return mainPart.getOracleText().contains("can be your commander"); } + public boolean canBePartnerCommander() { + return canBeCommander() && Iterables.contains(mainPart.getKeywords(), "Partner"); + } + public String getMeldWith() { return meldWith; } diff --git a/forge-core/src/main/java/forge/deck/DeckFormat.java b/forge-core/src/main/java/forge/deck/DeckFormat.java index bed900e77c2..0d26abb8146 100644 --- a/forge-core/src/main/java/forge/deck/DeckFormat.java +++ b/forge-core/src/main/java/forge/deck/DeckFormat.java @@ -17,21 +17,9 @@ */ package forge.deck; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; - -import forge.util.TextUtil; -import org.apache.commons.lang3.Range; -import org.apache.commons.lang3.tuple.ImmutablePair; - import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableSet; - import forge.StaticData; import forge.card.CardRules; import forge.card.CardRulesPredicates; @@ -43,6 +31,12 @@ import forge.deck.generation.IDeckGenPool; import forge.item.IPaperCard; import forge.item.PaperCard; import forge.util.Aggregates; +import forge.util.TextUtil; +import org.apache.commons.lang3.Range; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.Map.Entry; /** * GameType is an enum to determine the type of current game. :) @@ -428,4 +422,12 @@ public enum DeckFormat { } return Predicates.compose(CardRulesPredicates.hasColorIdentity(cmdCI), PaperCard.FN_GET_RULES); } + + public Predicate isLegalCardForCommanderOrLegalPartnerPredicate(List commanders) { + byte cmdCI = 0; + for (final PaperCard p : commanders) { + cmdCI |= p.getRules().getColorIdentity().getColor(); + } + return Predicates.compose(Predicates.or(CardRulesPredicates.hasColorIdentity(cmdCI), CardRulesPredicates.hasKeyword("Partner")), PaperCard.FN_GET_RULES); + } } diff --git a/forge-gui-mobile/src/forge/deck/FDeckEditor.java b/forge-gui-mobile/src/forge/deck/FDeckEditor.java index 72c4ac74395..a98f99dbcc0 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckEditor.java +++ b/forge-gui-mobile/src/forge/deck/FDeckEditor.java @@ -7,10 +7,9 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; - import forge.Forge; -import forge.Graphics; import forge.Forge.KeyInputAdapter; +import forge.Graphics; import forge.assets.*; import forge.card.CardDb; import forge.card.CardEdition; @@ -43,16 +42,10 @@ import forge.util.ItemPool; import forge.util.Lang; import forge.util.Utils; import forge.util.storage.IStorage; - import org.apache.commons.lang3.StringUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; public class FDeckEditor extends TabPageScreen { public static FSkinImage MAIN_DECK_ICON = FSkinImage.DECKLIST; @@ -214,7 +207,8 @@ public class FDeckEditor extends TabPageScreen { case PlanarConquest: return new DeckEditorPage[] { new CatalogPage(ItemManagerConfig.CONQUEST_COLLECTION, "Collection", FSkinImage.SPELLBOOK), - new DeckSectionPage(DeckSection.Main, ItemManagerConfig.CONQUEST_DECK_EDITOR, "Deck", FSkinImage.DECKLIST) + new DeckSectionPage(DeckSection.Main, ItemManagerConfig.CONQUEST_DECK_EDITOR, "Deck", FSkinImage.DECKLIST), + new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION) }; } } @@ -924,7 +918,7 @@ public class FDeckEditor extends TabPageScreen { } else { //if a commander has been set, only show cards that match its color identity - additionalFilter = DeckFormat.Commander.isLegalCardForCommanderPredicate(commanders); + additionalFilter = DeckFormat.Commander.isLegalCardForCommanderOrLegalPartnerPredicate(commanders); cardManager.setCaption("Cards"); } //fall through to below @@ -941,6 +935,9 @@ public class FDeckEditor extends TabPageScreen { @Override protected void onCardActivated(PaperCard card) { + if (canOnlyBePartnerCommander(card)) { + return; // don't auto-change commander unexpectedly + } if (needsCommander()) { setCommander(card); //handle special case of setting commander return; @@ -955,6 +952,24 @@ public class FDeckEditor extends TabPageScreen { return parentScreen.getCommanderPage() != null && parentScreen.getDeck().getCommanders().isEmpty(); } + private boolean canHavePartnerCommander() { + return parentScreen.getCommanderPage() != null && parentScreen.getDeck().getCommanders().size() == 1 + && parentScreen.getDeck().getCommanders().get(0).getRules().canBePartnerCommander(); + } + + private boolean canOnlyBePartnerCommander(final PaperCard card) { + if (parentScreen.getCommanderPage() == null) { + return false; + } + + byte cmdCI = 0; + for (final PaperCard p : parentScreen.getDeck().getCommanders()) { + cmdCI |= p.getRules().getColorIdentity().getColor(); + } + + return !card.getRules().getColorIdentity().hasNoColorsExcept(cmdCI); + } + private void setCommander(PaperCard card) { if (!cardManager.isInfinite()) { removeCard(card); @@ -965,9 +980,17 @@ public class FDeckEditor extends TabPageScreen { refresh(); //refresh so cards shown that match commander's color identity } + private void setPartnerCommander(PaperCard card) { + if (!cardManager.isInfinite()) { + removeCard(card); + } + parentScreen.getCommanderPage().addCard(card, 1); + refresh(); //refresh so cards shown that match commander's color identity + } + @Override protected void buildMenu(final FDropDownMenu menu, final PaperCard card) { - if (!needsCommander()) { + if (!needsCommander() && !canOnlyBePartnerCommander(card)) { addItem(menu, "Add", "to " + parentScreen.getMainDeckPage().cardManager.getCaption(), parentScreen.getMainDeckPage().getIcon(), true, true, new Callback() { @Override public void run(Integer result) { @@ -994,7 +1017,7 @@ public class FDeckEditor extends TabPageScreen { } } if (parentScreen.getCommanderPage() != null) { - if (DeckFormat.Commander.isLegalCommander(card.getRules()) && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) { + if (parentScreen.editorType != EditorType.PlanarConquest && DeckFormat.Commander.isLegalCommander(card.getRules()) && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) { addItem(menu, "Set", "as Commander", parentScreen.getCommanderPage().getIcon(), true, true, new Callback() { @Override public void run(Integer result) { @@ -1003,6 +1026,15 @@ public class FDeckEditor extends TabPageScreen { } }); } + if (canHavePartnerCommander() && card.getRules().canBePartnerCommander()) { + addItem(menu, "Set", "as Partner Commander", parentScreen.getCommanderPage().getIcon(), true, true, new Callback() { + @Override + public void run(Integer result) { + if (result == null || result <= 0) { return; } + setPartnerCommander(card); + } + }); + } } if (parentScreen.getEditorType() == EditorType.Constructed) { @@ -1257,16 +1289,20 @@ public class FDeckEditor extends TabPageScreen { }); break; case Commander: - addItem(menu, "Remove", null, FSkinImage.MINUS, false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } + if (parentScreen.editorType != EditorType.PlanarConquest || isPartnerCommander(card)) { + addItem(menu, "Remove", null, FSkinImage.MINUS, false, false, new Callback() { + @Override + public void run(Integer result) { + if (result == null || result <= 0) { + return; + } - removeCard(card, result); - parentScreen.getCatalogPage().refresh(); //refresh so commander options shown again - parentScreen.setSelectedPage(parentScreen.getCatalogPage()); - } - }); + removeCard(card, result); + parentScreen.getCatalogPage().refresh(); //refresh so commander options shown again + parentScreen.setSelectedPage(parentScreen.getCatalogPage()); + } + }); + } break; case Avatar: addItem(menu, "Remove", null, FSkinImage.MINUS, false, false, new Callback() { @@ -1316,7 +1352,7 @@ public class FDeckEditor extends TabPageScreen { break; } - if (parentScreen.getCommanderPage() != null && deckSection != DeckSection.Commander) { + if (parentScreen.editorType != EditorType.PlanarConquest && parentScreen.getCommanderPage() != null && deckSection != DeckSection.Commander) { if (card.getRules().getType().isLegendary() && card.getRules().getType().isCreature() && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) { addItem(menu, "Set", "as Commander", parentScreen.getCommanderPage().getIcon(), false, false, new Callback() { @Override @@ -1334,6 +1370,16 @@ public class FDeckEditor extends TabPageScreen { } } } + + private boolean isPartnerCommander(final PaperCard card) { + if (parentScreen.getCommanderPage() == null || parentScreen.getDeck().getCommanders().isEmpty()) { + return false; + } + + PaperCard firstCmdr = parentScreen.getDeck().getCommanders().get(0); + return !card.getName().equals(firstCmdr.getName()); + } + } private static class DraftPackPage extends CatalogPage { diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestUtil.java b/forge-gui/src/main/java/forge/planarconquest/ConquestUtil.java index 665c3c9dedb..0d9c09fdaa9 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestUtil.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestUtil.java @@ -1,36 +1,20 @@ package forge.planarconquest; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; - import forge.assets.FSkinProp; import forge.assets.IHasSkinProp; -import forge.card.CardRarity; -import forge.card.CardRules; -import forge.card.CardType; +import forge.card.*; import forge.card.CardType.CoreType; import forge.card.mana.ManaCostShard; -import forge.card.ColorSet; -import forge.card.MagicColor; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckFormat; import forge.deck.DeckSection; -import forge.deck.generation.DeckGenerator2Color; -import forge.deck.generation.DeckGenerator3Color; -import forge.deck.generation.DeckGenerator5Color; -import forge.deck.generation.DeckGeneratorBase; -import forge.deck.generation.DeckGeneratorMonoColor; -import forge.deck.generation.IDeckGenPool; +import forge.deck.generation.*; import forge.item.PaperCard; import forge.model.FModel; import forge.planarconquest.ConquestPreferences.CQPref; @@ -40,6 +24,12 @@ import forge.util.FileUtil; import forge.util.MyRandom; import forge.util.gui.SOptionPane; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + public class ConquestUtil { private ConquestUtil() {} @@ -153,7 +143,7 @@ public class ConquestUtil { //remove any cards that aren't allowed in deck due to color identity if (colorIdentity != MagicColor.ALL_COLORS) { - Predicate pred = DeckFormat.Commander.isLegalCardForCommanderPredicate(deck.getCommanders()); + Predicate pred = DeckFormat.Commander.isLegalCardForCommanderOrLegalPartnerPredicate(deck.getCommanders()); availableCards.retainAll(Lists.newArrayList(Iterables.filter(availableCards, pred))); }