From 50172a3be698b2d30c8bff7d7da5b501c60bbfc3 Mon Sep 17 00:00:00 2001 From: drdev Date: Sat, 19 Mar 2016 22:52:30 +0000 Subject: [PATCH] Refactor conquest AEther reward structure and filters --- .../src/forge/card/CardFaceSymbols.java | 1 - .../planarconquest/ConquestAEtherScreen.java | 54 +++++-- .../planarconquest/ConquestPrefsScreen.java | 9 +- .../src/forge/toolbox/FChoiceList.java | 4 +- .../src/forge/toolbox/FLabel.java | 4 + .../planarconquest/ConquestAwardPool.java | 26 ++-- .../planarconquest/ConquestController.java | 33 +---- .../planarconquest/ConquestPreferences.java | 9 +- .../forge/planarconquest/ConquestUtil.java | 135 +++++++++++++----- 9 files changed, 171 insertions(+), 104 deletions(-) diff --git a/forge-gui-mobile/src/forge/card/CardFaceSymbols.java b/forge-gui-mobile/src/forge/card/CardFaceSymbols.java index 7076b759338..646411558f2 100644 --- a/forge-gui-mobile/src/forge/card/CardFaceSymbols.java +++ b/forge-gui-mobile/src/forge/card/CardFaceSymbols.java @@ -22,7 +22,6 @@ import forge.assets.FSkinImage; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostShard; import forge.error.BugReporter; - import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestAEtherScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestAEtherScreen.java index 0d90c63c909..b8c40562bbe 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestAEtherScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestAEtherScreen.java @@ -16,15 +16,21 @@ import forge.animation.ForgeAnimation; import forge.assets.FSkin; import forge.assets.FSkinColor; import forge.assets.FSkinFont; +import forge.assets.FSkinProp; import forge.assets.FSkinTexture; import forge.assets.TextRenderer; import forge.card.CardRenderer; import forge.card.CardZoom; +import forge.card.ColorSet; import forge.card.CardRenderer.CardStackPosition; +import forge.card.ColorSetImage; import forge.item.PaperCard; import forge.model.FModel; +import forge.planarconquest.ConquestAwardPool; +import forge.planarconquest.ConquestCommander; import forge.planarconquest.ConquestData; import forge.planarconquest.ConquestPlane; +import forge.planarconquest.ConquestPreferences.CQPref; import forge.planarconquest.ConquestUtil; import forge.planarconquest.ConquestUtil.AEtherFilter; import forge.screens.FScreen; @@ -59,6 +65,7 @@ public class ConquestAEtherScreen extends FScreen { private PullAnimation activePullAnimation; private int shardCost; + private ConquestCommander commander; public ConquestAEtherScreen() { super("", ConquestMenu.getMenu()); @@ -71,6 +78,12 @@ public class ConquestAEtherScreen extends FScreen { setHeaderCaption(model.getName()); + ConquestCommander commander0 = model.getSelectedCommander(); + if (commander != commander0) { + commander = commander0; + resetFilters(); //reset filters if commander changed since the last time this screen was opened + } + pool.clear(); for (PaperCard card : plane.getCardPool().getAllCards()) { if (!model.hasUnlockedCard(card)) { @@ -81,6 +94,13 @@ public class ConquestAEtherScreen extends FScreen { updateAvailableShards(); } + private void resetFilters() { + btnColorFilter.setSelectedOption(ConquestUtil.getColorFilter(commander.getCard().getRules().getColorIdentity())); + btnTypeFilter.setSelectedOption(AEtherFilter.CREATURE); + btnRarityFilter.setSelectedOption(AEtherFilter.COMMON); + btnCMCFilter.setSelectedOption(AEtherFilter.CMC_LOW_MID); + } + private void updateFilteredPool() { Predicate predicate = btnColorFilter.buildFilterPredicate(null); predicate = btnTypeFilter.buildFilterPredicate(predicate); @@ -102,8 +122,13 @@ public class ConquestAEtherScreen extends FScreen { } private void updateShardCost() { - shardCost = FModel.getConquest().calculateShardCost(filteredPool, pool.size(), - btnColorFilter.selectedOption, btnTypeFilter.selectedOption, btnCMCFilter.selectedOption); + ConquestAwardPool pool = FModel.getConquest().getModel().getCurrentPlane().getAwardPool(); + if (filteredPool.isEmpty()) { + shardCost = 0; + } + else { + shardCost = pool.getShardValue(btnRarityFilter.selectedOption.getRarity(), FModel.getConquestPreferences().getPrefInt(CQPref.AETHER_BASE_PULL_COST)); + } display.updateMessage(); } @@ -306,24 +331,27 @@ public class ConquestAEtherScreen extends FScreen { if (selectedOption == selectedOption0) { return; } selectedOption = selectedOption0; - if (selectedOption == AEtherFilter.NONE) { - setIcon(null); - setText("Filter\n" + caption); + FSkinProp skinProp = selectedOption.skinProp; + if (skinProp != null) { + setIcon(FSkin.getImages().get(skinProp)); } else { - setIcon(FSkin.getImages().get(selectedOption.skinProp)); - setText(""); + ColorSet color = selectedOption.getColor(); + if (color != null) { + setIcon(new ColorSetImage(color)); + } + else { + System.out.println("No icon for filter " + selectedOption.name()); + setIcon(null); + } } } private Predicate buildFilterPredicate(Predicate predicate) { - if (selectedOption != AEtherFilter.NONE) { - if (predicate == null) { - return selectedOption.predicate; - } - return Predicates.and(predicate, selectedOption.predicate); + if (predicate == null) { + return selectedOption.predicate; } - return predicate; + return Predicates.and(predicate, selectedOption.predicate); } @Override diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPrefsScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPrefsScreen.java index 7fd915f31d3..1bd9fc54392 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPrefsScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPrefsScreen.java @@ -52,11 +52,10 @@ public class ConquestPrefsScreen extends FScreen { super("Conquest Preferences", ConquestMenu.getMenu()); scroller.add(new PrefsHeader("AEther Shards", FSkinImage.AETHER_SHARD, PrefsGroup.BOOSTER)); - scroller.add(new PrefsOption("Base Card Value", CQPref.AETHER_BASE_VALUE, PrefsGroup.AETHER)); - scroller.add(new PrefsOption("Markup Percentage", CQPref.AETHER_MARKUP, PrefsGroup.AETHER)); - scroller.add(new PrefsOption("Color Filter Markup", CQPref.AETHER_COLOR_FILTER_MARKUP, PrefsGroup.AETHER)); - scroller.add(new PrefsOption("Type Filter Markup", CQPref.AETHER_TYPE_FILTER_MARKUP, PrefsGroup.AETHER)); - scroller.add(new PrefsOption("CMC Filter Markup", CQPref.AETHER_CMC_FILTER_MARKUP, PrefsGroup.AETHER)); + scroller.add(new PrefsOption("Base Duplicate Value", CQPref.AETHER_BASE_DUPLICATE_VALUE, PrefsGroup.AETHER)); + scroller.add(new PrefsOption("Base Exile Value", CQPref.AETHER_BASE_EXILE_VALUE, PrefsGroup.AETHER)); + scroller.add(new PrefsOption("Base Retrieve Cost", CQPref.AETHER_BASE_RETRIEVE_COST, PrefsGroup.AETHER)); + scroller.add(new PrefsOption("Base Pull Cost", CQPref.AETHER_BASE_PULL_COST, PrefsGroup.AETHER)); scroller.add(new PrefsOption("Starting Shards", CQPref.AETHER_START_SHARDS, PrefsGroup.AETHER)); scroller.add(new PrefsOption("Chaos Wheel Shard Value", CQPref.AETHER_WHEEL_SHARDS, PrefsGroup.AETHER)); diff --git a/forge-gui-mobile/src/forge/toolbox/FChoiceList.java b/forge-gui-mobile/src/forge/toolbox/FChoiceList.java index b5e496f8d62..39dd99e3249 100644 --- a/forge-gui-mobile/src/forge/toolbox/FChoiceList.java +++ b/forge-gui-mobile/src/forge/toolbox/FChoiceList.java @@ -518,6 +518,8 @@ public class FChoiceList extends FList implements ActivateHandler { } } protected class IHasSkinPropRenderer extends DefaultItemRenderer { + private final TextRenderer textRenderer = new TextRenderer(true); + @Override public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { FSkinProp skinProp = ((IHasSkinProp)value).getSkinProp(); @@ -531,7 +533,7 @@ public class FChoiceList extends FList implements ActivateHandler { x += dx; w -= dx; } - super.drawValue(g, value, font, foreColor, pressed, x, y, w, h); + textRenderer.drawText(g, value.toString(), font, foreColor, x, y, w, h, y, h, true, HAlignment.LEFT, true); } } diff --git a/forge-gui-mobile/src/forge/toolbox/FLabel.java b/forge-gui-mobile/src/forge/toolbox/FLabel.java index 671e42e53e7..7642a4a93a2 100644 --- a/forge-gui-mobile/src/forge/toolbox/FLabel.java +++ b/forge-gui-mobile/src/forge/toolbox/FLabel.java @@ -333,6 +333,10 @@ public class FLabel extends FDisplayObject implements IButton { else if (iconInBackground || iconScaleAuto) { iconHeight = h * iconScaleFactor; iconWidth = iconHeight * aspectRatio; + if (iconWidth > w && iconInBackground) { //ensure background icon stays with label bounds + iconWidth = w; + iconHeight = iconWidth / aspectRatio; + } } float iconOffset = iconWidth + insets.x + getExtraGapBetweenIconAndText(); diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestAwardPool.java b/forge-gui/src/main/java/forge/planarconquest/ConquestAwardPool.java index 057db215fb5..ec29b0db22e 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestAwardPool.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestAwardPool.java @@ -2,7 +2,7 @@ package forge.planarconquest; import java.util.ArrayList; import java.util.List; - +import forge.card.CardRarity; import forge.item.PaperCard; import forge.model.FModel; import forge.planarconquest.ConquestPreferences.CQPref; @@ -10,7 +10,6 @@ import forge.util.Aggregates; public class ConquestAwardPool { private final BoosterPool commons, uncommons, rares, mythics; - private final int commonValue, uncommonValue, rareValue, mythicValue; public ConquestAwardPool(Iterable cards) { ConquestPreferences prefs = FModel.getConquestPreferences(); @@ -47,24 +46,24 @@ public class ConquestAwardPool { float rareOdds = rares.getOdds(raresPerBooster); float mythicOdds = mythics.getOdds((float)raresPerBooster / (float)prefs.getPrefInt(CQPref.BOOSTERS_PER_MYTHIC)); - //determine value of each rarity based on the base value of a common - commonValue = prefs.getPrefInt(CQPref.AETHER_BASE_VALUE); - uncommonValue = Math.round(commonValue / (uncommonOdds / commonOdds)); - rareValue = Math.round(commonValue / (rareOdds / commonOdds)); - mythicValue = mythics.isEmpty() ? 0 : Math.round(commonValue / (mythicOdds / commonOdds)); + //determine multipliers for each rarity based on ratio of odds + commons.multiplier = 1; + uncommons.multiplier = commonOdds / uncommonOdds; + rares.multiplier = commonOdds / rareOdds; + mythics.multiplier = mythics.isEmpty() ? 0 : commonOdds / mythicOdds; } - public int getShardValue(PaperCard card) { - switch (card.getRarity()) { + public int getShardValue(CardRarity rarity, int baseValue) { + switch (rarity) { case Common: - return commonValue; + return baseValue; case Uncommon: - return uncommonValue; + return Math.round(baseValue * uncommons.multiplier); case Rare: case Special: - return rareValue; + return Math.round(baseValue * rares.multiplier); case MythicRare: - return mythicValue; + return Math.round(baseValue * mythics.multiplier); default: return 0; } @@ -85,6 +84,7 @@ public class ConquestAwardPool { public class BoosterPool { private final List cards = new ArrayList(); + private float multiplier; private BoosterPool() { } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestController.java b/forge-gui/src/main/java/forge/planarconquest/ConquestController.java index 03354e9c963..04663e0ef1d 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestController.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestController.java @@ -41,7 +41,6 @@ import forge.item.PaperCard; import forge.match.HostedMatch; import forge.model.FModel; import forge.planarconquest.ConquestPreferences.CQPref; -import forge.planarconquest.ConquestUtil.AEtherFilter; import forge.player.GamePlayerUtil; import forge.player.LobbyPlayerHuman; import forge.properties.ForgeConstants; @@ -221,13 +220,14 @@ public class ConquestController { //also build list of all rewards including replacement shards for each duplicate card //build this list in reverse order so commons appear first int shards = 0; + int baseDuplicateValue = prefs.getPrefInt(CQPref.AETHER_BASE_DUPLICATE_VALUE); final List allRewards = new ArrayList(); for (int i = rewards.size() - 1; i >= 0; i--) { int replacementShards = 0; PaperCard card = rewards.get(i); if (model.hasUnlockedCard(card)) { rewards.remove(i); - replacementShards = pool.getShardValue(card); + replacementShards = pool.getShardValue(card.getRarity(), baseDuplicateValue); shards += replacementShards; } allRewards.add(new ConquestReward(card, replacementShards)); @@ -237,33 +237,4 @@ public class ConquestController { model.rewardAEtherShards(shards); return allRewards; } - - public int calculateShardCost(Set filteredCards, int unfilteredCount, AEtherFilter colorFilter, AEtherFilter typeFilter, AEtherFilter cmcFilter) { - if (filteredCards.isEmpty()) { return 0; } - - ConquestAwardPool pool = FModel.getConquest().getModel().getCurrentPlane().getAwardPool(); - - //determine average value of filtered cards - int totalValue = 0; - for (PaperCard card : filteredCards) { - totalValue += pool.getShardValue(card); - } - - ConquestPreferences prefs = FModel.getConquestPreferences(); - float averageValue = totalValue / filteredCards.size(); - float multiplier = 1f + (float)prefs.getPrefInt(CQPref.AETHER_MARKUP) / 100f; - - //increase multipliers based on applied filters - if (colorFilter != AEtherFilter.NONE) { - multiplier += (float)prefs.getPrefInt(CQPref.AETHER_COLOR_FILTER_MARKUP) / 100f; - } - if (typeFilter != AEtherFilter.NONE) { - multiplier += (float)prefs.getPrefInt(CQPref.AETHER_TYPE_FILTER_MARKUP) / 100f; - } - if (cmcFilter != AEtherFilter.NONE) { - multiplier += (float)prefs.getPrefInt(CQPref.AETHER_CMC_FILTER_MARKUP) / 100f; - } - - return Math.round(averageValue * multiplier); - } } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestPreferences.java b/forge-gui/src/main/java/forge/planarconquest/ConquestPreferences.java index d146aedd6c9..502a4749cb6 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestPreferences.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestPreferences.java @@ -29,11 +29,10 @@ public class ConquestPreferences extends PreferencesStore getTypes() { + if (predicate instanceof ColorFilter) { + return ((TypeFilter)predicate).types; + } + return null; + } + + public CardRarity getRarity() { + if (predicate instanceof RarityFilter) { + return ((RarityFilter)predicate).rarity; + } + return null; + } + @Override public String toString() { return caption; } } + public static AEtherFilter getColorFilter(ColorSet color) { + String name = ""; + for (ManaCostShard s : color.getOrderedShards()) { + name += s.toString(); + } + name = name.replaceAll("[{}]", ""); //remove all brackets + try { + return AEtherFilter.valueOf(name); + } + catch (Exception e) { + System.err.println("No color filter with name " + name); + return AEtherFilter.WUBRG; //return 5-color filter as fallback + } + } + public static final AEtherFilter[] COLOR_FILTERS = new AEtherFilter[] { - AEtherFilter.NONE, - AEtherFilter.WHITE, - AEtherFilter.BLUE, - AEtherFilter.BLACK, - AEtherFilter.RED, - AEtherFilter.GREEN, - AEtherFilter.COLORLESS }; + AEtherFilter.W, + AEtherFilter.U, + AEtherFilter.B, + AEtherFilter.R, + AEtherFilter.G, + AEtherFilter.WU, + AEtherFilter.WB, + AEtherFilter.UB, + AEtherFilter.UR, + AEtherFilter.BR, + AEtherFilter.BG, + AEtherFilter.RG, + AEtherFilter.RW, + AEtherFilter.GW, + AEtherFilter.GU, + AEtherFilter.WUB, + AEtherFilter.WBG, + AEtherFilter.UBR, + AEtherFilter.URW, + AEtherFilter.BRG, + AEtherFilter.BGU, + AEtherFilter.RGW, + AEtherFilter.RWB, + AEtherFilter.GWU, + AEtherFilter.GUR, + AEtherFilter.WUBRG }; public static final AEtherFilter[] TYPE_FILTERS = new AEtherFilter[] { - AEtherFilter.NONE, AEtherFilter.CREATURE, - AEtherFilter.ARTIFACT_ENCHANTMENT, - AEtherFilter.INSTANT_SORCERY, - AEtherFilter.LAND }; + AEtherFilter.NONCREATURE_PERMANENT, + AEtherFilter.INSTANT_SORCERY }; public static final AEtherFilter[] RARITY_FILTERS = new AEtherFilter[] { - AEtherFilter.NONE, AEtherFilter.COMMON, AEtherFilter.UNCOMMON, AEtherFilter.RARE, AEtherFilter.MYTHIC }; public static final AEtherFilter[] CMC_FILTERS = new AEtherFilter[] { - AEtherFilter.NONE, AEtherFilter.CMC_LOW, AEtherFilter.CMC_LOW_MID, AEtherFilter.CMC_MID_HIGH, AEtherFilter.CMC_HIGH }; private static class ColorFilter implements Predicate { - private final byte color; + private final ColorSet color; - private ColorFilter(byte color0) { - color = color0; + private ColorFilter(int colorMask0) { + color = ColorSet.fromMask(colorMask0); } @Override public boolean apply(PaperCard card) { - //use color identity for lands and color for other cards - CardRules cardRules = card.getRules(); - ColorSet cardColor = cardRules.getType().isLand() ? cardRules.getColorIdentity() : cardRules.getColor(); - - if (color == MagicColor.COLORLESS) { - return cardColor.isColorless(); - } - return cardColor.hasAllColors(color); + return card.getRules().getColorIdentity().hasNoColorsExcept(color); } }