diff --git a/.gitattributes b/.gitattributes index 09871121c6f..77a25a95bed 100644 --- a/.gitattributes +++ b/.gitattributes @@ -18561,6 +18561,7 @@ forge-gui/src/main/java/forge/net/server/NetGuiGame.java -text forge-gui/src/main/java/forge/net/server/RemoteClient.java -text forge-gui/src/main/java/forge/net/server/ServerGameLobby.java -text forge-gui/src/main/java/forge/net/server/package-info.java -text +forge-gui/src/main/java/forge/planarconquest/ConquestAwardPool.java -text forge-gui/src/main/java/forge/planarconquest/ConquestChaosBattle.java -text forge-gui/src/main/java/forge/planarconquest/ConquestCommander.java -text forge-gui/src/main/java/forge/planarconquest/ConquestController.java -text @@ -18572,6 +18573,7 @@ forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java -text forge-gui/src/main/java/forge/planarconquest/ConquestPlaneData.java -text forge-gui/src/main/java/forge/planarconquest/ConquestPreferences.java -text forge-gui/src/main/java/forge/planarconquest/ConquestRecord.java -text +forge-gui/src/main/java/forge/planarconquest/ConquestRegion.java -text forge-gui/src/main/java/forge/planarconquest/ConquestReward.java -text forge-gui/src/main/java/forge/planarconquest/ConquestUtil.java -text forge-gui/src/main/java/forge/player/GamePlayerUtil.java -text diff --git a/forge-core/src/main/java/forge/card/ColorSet.java b/forge-core/src/main/java/forge/card/ColorSet.java index d0a93ce7b44..685d25f8b99 100644 --- a/forge-core/src/main/java/forge/card/ColorSet.java +++ b/forge-core/src/main/java/forge/card/ColorSet.java @@ -77,6 +77,14 @@ public final class ColorSet implements Comparable, Iterable, Ser return fromMask(mask); } + public static ColorSet fromNames(final char[] colors) { + byte mask = 0; + for (final char s : colors) { + mask |= MagicColor.fromName(s); + } + return fromMask(mask); + } + public static ColorSet fromManaCost(final ManaCost mana) { return fromMask(mana.getColorProfile()); } diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCollectionScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCollectionScreen.java index 434ea99685e..d7e0659e334 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCollectionScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCollectionScreen.java @@ -62,7 +62,7 @@ public class ConquestCollectionScreen extends FScreen { private static class CardOriginFilter extends ComboBoxFilter { public CardOriginFilter(ItemManager itemManager0) { - super("All Planes", ConquestPlane.values(), itemManager0); + super("All Planes", FModel.getPlanes(), itemManager0); } @Override diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCommandersScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCommandersScreen.java index 7e6efa31e1b..51f3690f6b4 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCommandersScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCommandersScreen.java @@ -213,7 +213,7 @@ public class ConquestCommandersScreen extends FScreen { private static class CommanderOriginFilter extends ComboBoxFilter { public CommanderOriginFilter(ItemManager itemManager0) { - super("All Planes", ConquestPlane.values(), itemManager0); + super("All Planes", FModel.getPlanes(), itemManager0); } @Override diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMultiverseScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMultiverseScreen.java index 5560e044a0c..b24ac4c33ad 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMultiverseScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMultiverseScreen.java @@ -18,6 +18,7 @@ import forge.card.CardDetailUtil; import forge.card.CardRenderer; import forge.card.CardDetailUtil.DetailColors; import forge.model.FModel; +import forge.planarconquest.ConquestAwardPool; import forge.planarconquest.ConquestData; import forge.planarconquest.ConquestEvent.ChaosWheelOutcome; import forge.planarconquest.ConquestEvent.ConquestEventRecord; @@ -25,11 +26,10 @@ import forge.planarconquest.ConquestChaosBattle; import forge.planarconquest.ConquestEvent; import forge.planarconquest.ConquestLocation; import forge.planarconquest.ConquestPlane; -import forge.planarconquest.ConquestPlane.AwardPool; -import forge.planarconquest.ConquestPlane.Region; import forge.planarconquest.ConquestPreferences.CQPref; import forge.planarconquest.ConquestPlaneData; import forge.planarconquest.ConquestReward; +import forge.planarconquest.ConquestRegion; import forge.screens.FScreen; import forge.screens.LoadingOverlay; import forge.toolbox.FDisplayObject; @@ -131,18 +131,18 @@ public class ConquestMultiverseScreen extends FScreen { }); } - private void awardBoosters(AwardPool pool, int totalCount) { + private void awardBoosters(ConquestAwardPool pool, int totalCount) { AwardBoosterHelper helper = new AwardBoosterHelper(pool, totalCount); helper.run(); } private class AwardBoosterHelper implements Runnable { - private final AwardPool pool; + private final ConquestAwardPool pool; private final int totalCount; private final int shardsBefore; private int number; - private AwardBoosterHelper(AwardPool pool0, int totalCount0) { + private AwardBoosterHelper(ConquestAwardPool pool0, int totalCount0) { pool = pool0; number = 1; totalCount = totalCount0; @@ -256,15 +256,15 @@ public class ConquestMultiverseScreen extends FScreen { float w = getWidth(); float h = getHeight(); float regionHeight = w / CardRenderer.CARD_ART_RATIO; - int cols = Region.COLS_PER_REGION; - int rows = Region.ROWS_PER_REGION; + int cols = ConquestRegion.COLS_PER_REGION; + int rows = ConquestRegion.ROWS_PER_REGION; float colWidth = w / cols; float rowHeight = regionHeight / rows; float eventIconSize = Math.min(colWidth, rowHeight) / 3; float eventIconOffset = Math.round(eventIconSize * 0.1f); ConquestPlane plane = model.getCurrentPlane(); - FCollectionView regions = plane.getRegions(); + FCollectionView regions = plane.getRegions(); int regionCount = regions.size(); ConquestPlaneData planeData = model.getCurrentPlaneData(); ConquestLocation currentLocation = model.getCurrentLocation(); @@ -286,7 +286,7 @@ public class ConquestMultiverseScreen extends FScreen { if (y > h) { break; } //draw background art - Region region = regions.get(i); + ConquestRegion region = regions.get(i); FImage art = (FImage)region.getArt(); if (art != null) { g.drawImage(art, x, y, w, regionHeight); @@ -346,7 +346,7 @@ public class ConquestMultiverseScreen extends FScreen { color = FOG_OF_WAR_COLOR; //if any bordering grid square has been conquered, instead show unconquered color - if (i == 0 && r == 0 && c == Region.START_COL) { + if (i == 0 && r == 0 && c == ConquestRegion.START_COL) { color = UNCONQUERED_COLOR; //show unconquered color for starting square of plane } else { @@ -410,20 +410,20 @@ public class ConquestMultiverseScreen extends FScreen { float w = getWidth(); float h = getScrollHeight(); float regionHeight = w / CardRenderer.CARD_ART_RATIO; - float colWidth = w / Region.COLS_PER_REGION; - float rowHeight = regionHeight / Region.ROWS_PER_REGION; + float colWidth = w / ConquestRegion.COLS_PER_REGION; + float rowHeight = regionHeight / ConquestRegion.ROWS_PER_REGION; int rowIndex = (int)((h - y) / rowHeight); //flip axis since locations go bottom to top ConquestPlane plane = model.getCurrentPlane(); - int regionIndex = rowIndex / Region.ROWS_PER_REGION; - int row = rowIndex % Region.ROWS_PER_REGION; + int regionIndex = rowIndex / ConquestRegion.ROWS_PER_REGION; + int row = rowIndex % ConquestRegion.ROWS_PER_REGION; int col = (int)(x / colWidth); if (col < 0) { col = 0; } - else if (col > Region.COLS_PER_REGION - 1) { - col = Region.COLS_PER_REGION - 1; + else if (col > ConquestRegion.COLS_PER_REGION - 1) { + col = ConquestRegion.COLS_PER_REGION - 1; } return new ConquestLocation(plane, regionIndex, row, col); @@ -433,8 +433,8 @@ public class ConquestMultiverseScreen extends FScreen { float w = getWidth(); float h = getScrollHeight(); float regionHeight = w / CardRenderer.CARD_ART_RATIO; - float colWidth = w / Region.COLS_PER_REGION; - float rowHeight = regionHeight / Region.ROWS_PER_REGION; + float colWidth = w / ConquestRegion.COLS_PER_REGION; + float rowHeight = regionHeight / ConquestRegion.ROWS_PER_REGION; float x = loc.getCol() * colWidth + colWidth / 2; float y = h - (loc.getRegionIndex() * regionHeight + loc.getRow() * rowHeight + rowHeight / 2); diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneSelector.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneSelector.java index 9292280f6d0..cd750650304 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneSelector.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneSelector.java @@ -1,8 +1,11 @@ package forge.screens.planarconquest; +import java.util.List; + import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; import com.badlogic.gdx.math.Rectangle; +import com.google.common.collect.ImmutableList; import forge.Graphics; import forge.assets.FImage; @@ -12,6 +15,7 @@ import forge.assets.FSkinImage; import forge.assets.FSkinTexture; import forge.card.CardRenderer; import forge.item.PaperCard; +import forge.model.FModel; import forge.planarconquest.ConquestPlane; import forge.toolbox.FDisplayObject; import forge.toolbox.FOptionPane; @@ -27,7 +31,7 @@ public class ConquestPlaneSelector extends FDisplayObject { private static final float MONITOR_LEFT_MULTIPLIER = 19f / 443f; private static final float ARROW_THICKNESS = Utils.scale(3); - private static final ConquestPlane[] planes = ConquestPlane.values(); + private static final List planes = ImmutableList.copyOf(FModel.getPlanes()); private final FTimer timer = new FTimer(2.5f) { @Override @@ -48,7 +52,7 @@ public class ConquestPlaneSelector extends FDisplayObject { } public ConquestPlane getSelectedPlane() { - return planes[selectedIndex]; + return planes.get(selectedIndex); } public void activate() { @@ -74,9 +78,9 @@ public class ConquestPlaneSelector extends FDisplayObject { private void incrementSelectedIndex(int dir) { int newIndex = selectedIndex + dir; if (newIndex < 0) { - newIndex = planes.length - 1; + newIndex = planes.size() - 1; } - else if (newIndex >= planes.length) { + else if (newIndex >= planes.size()) { newIndex = 0; } setSelectedIndex(newIndex); diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/NewConquestScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/NewConquestScreen.java index 7ffe5cd9e0d..72d49857b68 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/NewConquestScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/NewConquestScreen.java @@ -12,7 +12,6 @@ import forge.item.PaperCard; import forge.model.FModel; import forge.planarconquest.ConquestController; import forge.planarconquest.ConquestData; -import forge.planarconquest.ConquestPlane; import forge.planarconquest.ConquestPreferences.CQPref; import forge.planarconquest.ConquestUtil; import forge.screens.LoadingOverlay; @@ -168,7 +167,7 @@ public class NewConquestScreen extends MultiStepWizardScreen { - private final FChoiceList lstCommanders = add(new FChoiceList(ConquestPlane.Alara.getCommanders()) { + private final FChoiceList lstCommanders = add(new FChoiceList(FModel.getPlanes().iterator().next().getCommanders()) { @Override protected void onItemActivate(Integer index, PaperCard value) { advance(); diff --git a/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java b/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java index 87bfc3417f2..052af02e996 100644 --- a/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java +++ b/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java @@ -29,6 +29,7 @@ import forge.item.PaperCard; import forge.model.FModel; import forge.planarconquest.ConquestCommander; import forge.planarconquest.ConquestPlane; +import forge.planarconquest.ConquestRegion; import forge.quest.QuestWorld; import forge.util.gui.SGuiChoose; import forge.util.gui.SOptionPane; @@ -74,7 +75,7 @@ public class AdvancedSearch { return FModel.getFormats().getAllFormatsOfCard(input); } }), - CARD_PLANE("Plane", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(ImmutableList.copyOf(ConquestPlane.values())) { + CARD_PLANE("Plane", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(ImmutableList.copyOf(FModel.getPlanes())) { @Override protected ConquestPlane getItemValue(PaperCard input) { throw new RuntimeException("getItemValues should be called instead"); @@ -84,14 +85,14 @@ public class AdvancedSearch { return ConquestPlane.getAllPlanesOfCard(input); } }), - CARD_REGION("Region", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(ConquestPlane.getAllRegions()) { + CARD_REGION("Region", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(ConquestRegion.getAllRegions()) { @Override - protected ConquestPlane.Region getItemValue(PaperCard input) { + protected ConquestRegion getItemValue(PaperCard input) { throw new RuntimeException("getItemValues should be called instead"); } @Override - protected Set getItemValues(PaperCard input) { - return ConquestPlane.getAllRegionsOfCard(input); + protected Set getItemValues(PaperCard input) { + return ConquestRegion.getAllRegionsOfCard(input); } }), CARD_QUEST_WORLD("Quest World", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(ImmutableList.copyOf(FModel.getWorlds())) { @@ -316,7 +317,7 @@ public class AdvancedSearch { return input.getName(); } }), - COMMANDER_ORIGIN("Origin", ConquestCommander.class, FilterOperator.SINGLE_LIST_OPS, new CustomListEvaluator(Arrays.asList(ConquestPlane.values())) { + COMMANDER_ORIGIN("Origin", ConquestCommander.class, FilterOperator.SINGLE_LIST_OPS, new CustomListEvaluator(ImmutableList.copyOf(FModel.getPlanes())) { @Override protected ConquestPlane getItemValue(ConquestCommander input) { return input.getOriginPlane(); diff --git a/forge-gui/src/main/java/forge/model/FModel.java b/forge-gui/src/main/java/forge/model/FModel.java index ed881c01267..dcc046abe89 100644 --- a/forge-gui/src/main/java/forge/model/FModel.java +++ b/forge-gui/src/main/java/forge/model/FModel.java @@ -35,6 +35,7 @@ import forge.interfaces.IProgressBar; import forge.itemmanager.ItemManagerConfig; import forge.limited.GauntletMini; import forge.planarconquest.ConquestController; +import forge.planarconquest.ConquestPlane; import forge.planarconquest.ConquestPreferences; import forge.player.GamePlayerUtil; import forge.properties.ForgeConstants; @@ -83,6 +84,7 @@ public final class FModel { private static IStorage blocks; private static IStorage fantasyBlocks; + private static IStorage planes; private static IStorage worlds; private static GameFormat.Collection formats; @@ -155,6 +157,7 @@ public final class FModel { questPreferences = new QuestPreferences(); conquestPreferences = new ConquestPreferences(); fantasyBlocks = new StorageBase<>("Custom blocks", new CardBlock.Reader(ForgeConstants.BLOCK_DATA_DIR + "fantasyblocks.txt", magicDb.getEditions())); + planes = new StorageBase<>("Conquest planes", new ConquestPlane.Reader(ForgeConstants.CONQUEST_PLANES_DIR + "planes.txt")); worlds = new StorageBase<>("Quest worlds", new QuestWorld.Reader(ForgeConstants.QUEST_WORLD_DIR + "worlds.txt")); loadDynamicGamedata(); @@ -301,6 +304,10 @@ public final class FModel { return decks; } + public static IStorage getPlanes() { + return planes; + } + public static IStorage getWorlds() { return worlds; } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestAwardPool.java b/forge-gui/src/main/java/forge/planarconquest/ConquestAwardPool.java new file mode 100644 index 00000000000..057db215fb5 --- /dev/null +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestAwardPool.java @@ -0,0 +1,113 @@ +package forge.planarconquest; + +import java.util.ArrayList; +import java.util.List; + +import forge.item.PaperCard; +import forge.model.FModel; +import forge.planarconquest.ConquestPreferences.CQPref; +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(); + + commons = new BoosterPool(); + uncommons = new BoosterPool(); + rares = new BoosterPool(); + mythics = new BoosterPool(); + + for (PaperCard c : cards) { + switch (c.getRarity()) { + case Common: + commons.add(c); + break; + case Uncommon: + uncommons.add(c); + break; + case Rare: + case Special: //lump special cards in with rares for simplicity + rares.add(c); + break; + case MythicRare: + mythics.add(c); + break; + default: + break; + } + } + + //calculate odds of each rarity + float commonOdds = commons.getOdds(prefs.getPrefInt(CQPref.BOOSTER_COMMONS)); + float uncommonOdds = uncommons.getOdds(prefs.getPrefInt(CQPref.BOOSTER_UNCOMMONS)); + int raresPerBooster = prefs.getPrefInt(CQPref.BOOSTER_RARES); + 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)); + } + + public int getShardValue(PaperCard card) { + switch (card.getRarity()) { + case Common: + return commonValue; + case Uncommon: + return uncommonValue; + case Rare: + case Special: + return rareValue; + case MythicRare: + return mythicValue; + default: + return 0; + } + } + + public BoosterPool getCommons() { + return commons; + } + public BoosterPool getUncommons() { + return uncommons; + } + public BoosterPool getRares() { + return rares; + } + public BoosterPool getMythics() { + return mythics; + } + + public class BoosterPool { + private final List cards = new ArrayList(); + + private BoosterPool() { + } + + public boolean isEmpty() { + return cards.isEmpty(); + } + + private float getOdds(float perBoosterCount) { + int count = cards.size(); + if (count == 0) { return 0; } + return (float)perBoosterCount / (float)count; + } + + private void add(PaperCard c) { + cards.add(c); + } + + public void rewardCard(List rewards) { + int index = Aggregates.randomInt(0, cards.size() - 1); + PaperCard c = cards.get(index); + cards.remove(index); + rewards.add(c); + } + } +} \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestChaosBattle.java b/forge-gui/src/main/java/forge/planarconquest/ConquestChaosBattle.java index a619da479b0..dd1a914aee0 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestChaosBattle.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestChaosBattle.java @@ -11,7 +11,6 @@ import forge.interfaces.IButton; import forge.interfaces.IGuiGame; import forge.interfaces.IWinLoseView; import forge.model.FModel; -import forge.planarconquest.ConquestPlane.AwardPool; import forge.planarconquest.ConquestPreferences.CQPref; import forge.properties.ForgeConstants; import forge.quest.QuestEventDifficulty; @@ -23,7 +22,7 @@ import forge.util.Aggregates; public class ConquestChaosBattle extends ConquestEvent { private final QuestWorld world; private final QuestEventDuel duel; - private AwardPool awardPool; + private ConquestAwardPool awardPool; private boolean finished; public ConquestChaosBattle() { @@ -114,9 +113,9 @@ public class ConquestChaosBattle extends ConquestEvent { finished = true; } - public AwardPool getAwardPool() { + public ConquestAwardPool getAwardPool() { if (awardPool == null) { //delay initializing until needed - awardPool = new AwardPool(world.getAllCards()); + awardPool = new ConquestAwardPool(world.getAllCards()); } return awardPool; } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestCommander.java b/forge-gui/src/main/java/forge/planarconquest/ConquestCommander.java index edf9572d46d..808fe100e8a 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestCommander.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestCommander.java @@ -5,7 +5,6 @@ import forge.deck.generation.DeckGenPool; import forge.item.InventoryItem; import forge.item.PaperCard; import forge.model.FModel; -import forge.planarconquest.ConquestPlane.Region; import forge.util.XmlReader; import forge.util.XmlWriter; import forge.util.XmlWriter.IXmlWritable; @@ -35,11 +34,11 @@ public class ConquestCommander implements InventoryItem, IXmlWritable { //determine origin of commander ConquestPlane originPlane0 = null; String originRegionName0 = null; - for (ConquestPlane plane : ConquestPlane.values()) { + for (ConquestPlane plane : FModel.getPlanes()) { if (plane.getCommanders().contains(card)) { originPlane0 = plane; - for (Region region : plane.getRegions()) { - if (region.getCommanders().contains(card)) { + for (ConquestRegion region : plane.getRegions()) { + if (region.getCardPool().contains(card)) { originRegionName0 = region.getName(); break; } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestController.java b/forge-gui/src/main/java/forge/planarconquest/ConquestController.java index 783a40f66cb..18c65e8fae9 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestController.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestController.java @@ -40,7 +40,6 @@ import forge.interfaces.IWinLoseView; import forge.item.PaperCard; import forge.match.HostedMatch; import forge.model.FModel; -import forge.planarconquest.ConquestPlane.AwardPool; import forge.planarconquest.ConquestPreferences.CQPref; import forge.player.GamePlayerUtil; import forge.player.LobbyPlayerHuman; @@ -183,7 +182,7 @@ public class ConquestController { activeEvent = null; } - public List awardBooster(AwardPool pool) { + public List awardBooster(ConquestAwardPool pool) { ConquestPreferences prefs = FModel.getConquestPreferences(); List rewards = new ArrayList(); int boostersPerMythic = prefs.getPrefInt(CQPref.BOOSTERS_PER_MYTHIC); @@ -233,7 +232,7 @@ public class ConquestController { public int calculateShardCost(ItemPool filteredCards, int unfilteredCount) { if (filteredCards.isEmpty()) { return 0; } - AwardPool pool = FModel.getConquest().getModel().getCurrentPlane().getAwardPool(); + ConquestAwardPool pool = FModel.getConquest().getModel().getCurrentPlane().getAwardPool(); //determine average value of filtered cards int totalValue = 0; diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestData.java b/forge-gui/src/main/java/forge/planarconquest/ConquestData.java index 58b1f7629d6..3f7f3ff0ede 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestData.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestData.java @@ -26,7 +26,6 @@ import forge.itemmanager.ColumnDef; import forge.itemmanager.ItemColumn; import forge.itemmanager.ItemManagerConfig; import forge.model.FModel; -import forge.planarconquest.ConquestPlane.Region; import forge.planarconquest.ConquestPreferences.CQPref; import forge.properties.ForgeConstants; import forge.util.FileUtil; @@ -36,7 +35,6 @@ import forge.util.XmlWriter; import java.io.File; import java.util.ArrayList; import java.util.Collections; -import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -58,7 +56,7 @@ public final class ConquestData { private final File directory; private final String xmlFilename; private final ConquestRecord chaosBattleRecord; - private final EnumMap planeDataMap = new EnumMap(ConquestPlane.class); + private final Map planeDataMap = new HashMap(); private final HashSet unlockedCards = new HashSet(); private final List commanders = new ArrayList(); private final HashSet newCards = new HashSet(); @@ -68,7 +66,7 @@ public final class ConquestData { directory = new File(ForgeConstants.CONQUEST_SAVE_DIR, name); xmlFilename = directory.getPath() + ForgeConstants.PATH_SEPARATOR + XML_FILE; aetherShards = FModel.getConquestPreferences().getPrefInt(CQPref.AETHER_START_SHARDS); - currentLocation = new ConquestLocation(startingPlane0, 0, 0, Region.START_COL); + currentLocation = new ConquestLocation(startingPlane0, 0, 0, ConquestRegion.START_COL); setPlaneswalker(startingPlaneswalker0); unlockCard(startingPlaneswalker0); @@ -102,7 +100,7 @@ public final class ConquestData { xml.read("unlockedCards", unlockedCards, cardDb); xml.read("newCards", newCards, cardDb); xml.read("commanders", commanders, ConquestCommander.class); - xml.read("planeDataMap", planeDataMap, ConquestPlane.class, ConquestPlaneData.class); + xml.read("planeDataMap", planeDataMap, ConquestPlaneData.class); } catch (Exception e) { e.printStackTrace(); @@ -149,7 +147,7 @@ public final class ConquestData { ConquestPlaneData planeData = planeDataMap.get(plane); if (planeData == null) { planeData = new ConquestPlaneData(plane); - planeDataMap.put(plane, planeData); + planeDataMap.put(plane.getName(), planeData); } return planeData; } @@ -221,8 +219,8 @@ public final class ConquestData { int conquered = 0; int total = 0; - for (ConquestPlane plane : ConquestPlane.values()) { - ConquestPlaneData planeData = planeDataMap.get(plane); + for (ConquestPlane plane : FModel.getPlanes()) { + ConquestPlaneData planeData = planeDataMap.get(plane.getName()); if (planeData != null) { conquered += planeData.getConqueredCount(); } @@ -299,8 +297,8 @@ public final class ConquestData { private PathFinder() { ConquestPlane plane = getCurrentPlane(); - int xMax = Region.COLS_PER_REGION; - int yMax = plane.getRegions().size() * Region.ROWS_PER_REGION; + int xMax = ConquestRegion.COLS_PER_REGION; + int yMax = plane.getRegions().size() * ConquestRegion.ROWS_PER_REGION; map = new Node[xMax][yMax]; for (int x = 0; x < xMax; x++) { for (int y = 0; y < yMax; y++) { @@ -380,7 +378,7 @@ public final class ConquestData { private Node getNode(ConquestLocation loc) { int x = loc.getCol(); - int y = loc.getRegionIndex() * Region.ROWS_PER_REGION + loc.getRow(); + int y = loc.getRegionIndex() * ConquestRegion.ROWS_PER_REGION + loc.getRow(); return map[x][y]; } @@ -396,9 +394,9 @@ public final class ConquestData { x = x0; y = y0; - int regionIndex = y / Region.ROWS_PER_REGION; + int regionIndex = y / ConquestRegion.ROWS_PER_REGION; int col = x; - int row = y % Region.ROWS_PER_REGION; + int row = y % ConquestRegion.ROWS_PER_REGION; loc = new ConquestLocation(plane, regionIndex, row, col); } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestLocation.java b/forge-gui/src/main/java/forge/planarconquest/ConquestLocation.java index 94df69b420b..0b4cab540c1 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestLocation.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestLocation.java @@ -11,7 +11,6 @@ import forge.interfaces.IGuiGame; import forge.item.PaperCard; import forge.model.FModel; import forge.planarconquest.ConquestEvent.ConquestEventRecord; -import forge.planarconquest.ConquestPlane.Region; import forge.util.Aggregates; import forge.util.XmlReader; import forge.util.XmlWriter; @@ -31,14 +30,14 @@ public class ConquestLocation implements IXmlWritable { } public ConquestLocation(XmlReader xml) { - plane = xml.read("plane", ConquestPlane.Alara); + plane = FModel.getPlanes().get(xml.read("plane", "Alara")); regionIndex = xml.read("regionIndex", 0); row = xml.read("row", 0); col = xml.read("col", 0); } @Override public void saveToXml(XmlWriter xml) { - xml.write("plane", plane); + xml.write("plane", plane.getName()); xml.write("regionIndex", regionIndex); xml.write("row", row); xml.write("col", col); @@ -48,7 +47,7 @@ public class ConquestLocation implements IXmlWritable { return plane; } - public Region getRegion() { + public ConquestRegion getRegion() { if (regionIndex == -1 || regionIndex == plane.getRegions().size()) { return null; //indicates we're on portal row } @@ -83,7 +82,7 @@ public class ConquestLocation implements IXmlWritable { List locations = new ArrayList(); //add location above - if (row0 < Region.ROWS_PER_REGION - 1) { + if (row0 < ConquestRegion.ROWS_PER_REGION - 1) { locations.add(new ConquestLocation(plane0, regionIndex0, row0 + 1, col0)); } else if (regionIndex0 < regionCount - 1) { @@ -95,7 +94,7 @@ public class ConquestLocation implements IXmlWritable { locations.add(new ConquestLocation(plane0, regionIndex0, row0 - 1, col0)); } else if (regionIndex0 > 0) { - locations.add(new ConquestLocation(plane0, regionIndex0 - 1, Region.ROWS_PER_REGION - 1, col0)); + locations.add(new ConquestLocation(plane0, regionIndex0 - 1, ConquestRegion.ROWS_PER_REGION - 1, col0)); } //add location to left @@ -104,7 +103,7 @@ public class ConquestLocation implements IXmlWritable { } //add location to right - if (col0 < Region.COLS_PER_REGION - 1) { + if (col0 < ConquestRegion.COLS_PER_REGION - 1) { locations.add(new ConquestLocation(plane0, regionIndex0, row0, col0 + 1)); } @@ -125,7 +124,7 @@ public class ConquestLocation implements IXmlWritable { //TODO: Make this pull from predefined events ConquestEventRecord record = FModel.getConquest().getModel().getCurrentPlaneData().getEventRecord(this); return new ConquestEvent(this, record == null ? 0 : Math.min(record.getHighestConqueredTier() + 1, 3)) { - private final PaperCard commander = Aggregates.random(getRegion().getCommanders()); + private final PaperCard commander = Aggregates.random(plane.getCommanders()); @Override protected Deck buildOpponentDeck() { diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java b/forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java index 4f335253c90..9e01240d6ab 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java @@ -17,381 +17,118 @@ */ package forge.planarconquest; -import java.util.ArrayList; import java.util.Collections; -import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; -import com.google.common.base.Predicate; +import com.google.common.base.Function; -import forge.GuiBase; -import forge.assets.ISkinImage; import forge.card.CardDb; import forge.card.CardEdition; import forge.card.CardEdition.CardInSet; import forge.card.CardRules; -import forge.card.ColorSet; -import forge.card.MagicColor; import forge.deck.generation.DeckGenPool; import forge.item.PaperCard; import forge.model.FModel; -import forge.planarconquest.ConquestPreferences.CQPref; -import forge.util.Aggregates; +import forge.properties.ForgeConstants; +import forge.util.FileUtil; import forge.util.collect.FCollection; import forge.util.collect.FCollectionView; +import forge.util.storage.StorageBase; +import forge.util.storage.StorageReaderFile; -public enum ConquestPlane { - Alara("Alara", new String[] { - "ALA", "CON", "ARB" - }, new String[] { - "Bant", "Grixis", "Jund", "Naya", "The Maelstrom" - }, new String[] { - "Unstable Obelisk", "Baleful Strix", "Shardless Agent", "Etherium-Horn Sorcerer", - "Patron of the Valiant", "Sublime Archangel", "Naya Soulbeast", "Stalwart Aven", - "Citadel Castellan", "Ajani's Mantra", "Topan Freeblade", "Valeron Wardens", - "Honored Hierarch", "Knight of the Pilgrim's Road", "Relic Seeker", "War Oracle", - "Derevi, Empyrial Tactician", "Kaalia of the Vast", "Bloodspore Thrinax", - "Duskmantle Prowler", "Duty-Bound Dead", "Knight of Glory", "Knight of Infamy", - "Nefarox, Overlord of Grixis", "Servant of Nefarox", "Cathedral of War", - "Meren of Clan Nel Toth", "Jazal Goldmane", "Jhessian Thief", "Maelstrom Wanderer", - "Preyseizer Dragon", "Thromok the Insatiable", "Restore", "Rhox Faithmender", - "Rhox Pikemaster", "Roon of the Hidden Realm", "Scourge of Nel Toth" - }, new Region[] { - new Region("Bant", "Bant Panorama", MagicColor.GREEN | MagicColor.WHITE | MagicColor.BLUE), - new Region("Esper", "Esper Panorama", MagicColor.WHITE | MagicColor.BLUE | MagicColor.BLACK), - new Region("Grixis", "Grixis Panorama", MagicColor.BLUE | MagicColor.BLACK | MagicColor.RED), - new Region("Jund", "Jund Panorama", MagicColor.BLACK | MagicColor.RED | MagicColor.GREEN), - new Region("Naya", "Naya Panorama", MagicColor.RED | MagicColor.GREEN | MagicColor.WHITE), - new Region("Maelstrom", "Rupture Spire", ColorSet.ALL_COLORS.getColor()) - }), - Dominaria("Dominaria", new String[] { - "ICE", "ALL", "CSP", - "MIR", "VIS", "WTH", - "USG", "ULG", "UDS", - "INV", "PLS", "APC", - "ODY", "TOR", "JUD", - "ONS", "LGN", "SCG", - "TSP", "PLC", "FUT" - }, new String[] { - "Academy at Tolaria West", "Isle of Vesuva", "Krosa", "Llanowar", "Otaria", "Shiv", "Talon Gates" - }, new String[] { - "Crown of Empires", "Scepter of Empires", "Throne of Empires", "Roc Egg", "Brindle Boar", - "Armored Cancrix", "Academy Raider", "Alaborn Cavalier", "Prossh, Skyraider of Kher", - "Balance of Power", "Beetleback Chief", "Crimson Mage", "Cruel Edict", "Dakmor Lancer", - "Famine", "Firewing Phoenix", "Flesh to Dust", "Flusterstorm", "Freyalise, Llanowar's Fury", - "Gaea's Revenge", "Ice Cage", "Liliana, Heretical Healer", "Mwonvuli Beast Tracker", - "Teferi, Temporal Archmage", "Titania, Protector of Argoth", "Onyx Mage" - }, new Region[] { - new Region("Ice Age", "Dark Depths", inSet("ICE", "ALL", "CSP")), - new Region("Mirage", "Teferi's Isle", inSet("MIR", "VIS", "WTH")), - new Region("Urza's Saga", "Tolarian Academy", inSet("USG", "ULG", "UDS")), - new Region("Invasion", "Legacy Weapon", inSet("INV", "PLS", "APC")), - new Region("Odyssey", "Cabal Coffers", inSet("ODY", "TOR", "JUD")), - new Region("Onslaught", "Grand Coliseum", inSet("ONS", "LGN", "SCG")), - new Region("Time Spiral", "Vesuva", inSet("TSP", "TSB", "PLC", "FUT")) - }), - Innistrad("Innistrad", new String[] { - "ISD", "DKA", "AVR" - }, new String[] { - "Gavony", "Kessig", "Nephalia" - }, new String[] { - "Profane Memento", "Strionic Resonator", "Guardian Seraph", "Seraph of the Sword", - "Soul of Innistrad", "Ajani's Pridemate", "Jeleva, Nephalia's Scourge", "Blood Bairn", - "Blood Host", "Call of the Full Moon", "Captivating Vampire", "Child of Night", - "Jeleva, Nephalia's Scourge", "Vampire Nocturnus", "Crusader of Odric", "Odric, Master Tactician", - "Curse of Chaos", "Curse of Inertia", "Curse of Predation", "Curse of Shallow Graves", - "Curse of the Forsaken", "Deathreap Ritual", "Malicious Affliction", "Predator's Howl", - "Geist of the Moors", "Ghoulcaller Gisa", "Hushwing Gryff", "Possessed Skaab", "Predator's Howl", - "Sign in Blood", "Stitcher Geralf" - }, new Region[] { - new Region("Moorland", "Moorland Haunt", MagicColor.WHITE | MagicColor.BLUE), - new Region("Nephalia", "Nephalia Drownyard", MagicColor.BLUE | MagicColor.BLACK), - new Region("Stensia", "Stensia Bloodhall", MagicColor.BLACK | MagicColor.RED), - new Region("Kessig", "Kessig Wolf Run", MagicColor.RED | MagicColor.GREEN), - new Region("Gavony", "Gavony Township", MagicColor.GREEN | MagicColor.WHITE), - }), - Kaladesh("Kaladesh", new String[] { - - }, new String[] { - "Immersturm" //TODO: Replace with proper plane when one created - }, new String[] { - "Consul's Lieutenant" - }, new Region[] { - new Region("", "", ColorSet.ALL_COLORS.getColor()) - }), - Kamigawa("Kamigawa", new String[] { - "CHK", "BOK", "SOK" - }, new String[] { - "Minamo", "Orochi Colony", "Sokenzan", "Takenuma" - }, new String[] { - "Champion's Helm", "Haunted Plate Mail", "Sai of the Shinobi", "Kaseto, Orochi Archmage", - "Gahiji, Honored One", "Kurkesh, Onakke Ancient", "Sakashima's Student", "Silent-Blade Oni", - "Vela the Night-Clad" - }, new Region[] { - new Region("Towabara", "Eiganjo Castle", MagicColor.WHITE), - new Region("Minamo Academy", "Minamo, School at Water's Edge", MagicColor.BLUE), - new Region("Takenuma", "Shizo, Death's Storehouse", MagicColor.BLACK), - new Region("Sokenzan Mountains", "Shinka, the Bloodsoaked Keep", MagicColor.RED), - new Region("Jukai Forest", "Okina, Temple to the Grandfathers", MagicColor.GREEN), - }), - LorwynShadowmoor("Lorwyn-Shadowmoor", new String[] { - "LRW", "MOR", "SHM", "EVE" - }, new String[] { - "Goldmeadow", "The Great Forest", "Velis Vel", "Raven's Run", - }, new String[] { - "Throwing Knife", "Awakener Druid", "Boonweaver Giant", "Cruel Sadist", "Dungrove Elder", - "Great Oak Guardian", "Dwynen's Elite", "Dwynen, Gilt-Leaf Daen", "Eyeblight Assassin", - "Eyeblight Massacre", "Flamekin Village", "Fleshpulper Giant", "Gilt-Leaf Winnower", - "Gnarlroot Trapper", "Harbinger of the Tides", "Marath, Will of the Wild", "Shaman of the Pack", - "Thornbow Archer", "Outland Colossus" - }, new Region[] { - new Region("Wanderwine Hub", "Wanderwine Hub", MagicColor.WHITE | MagicColor.BLUE), - new Region("Secluded Glen", "Secluded Glen", MagicColor.BLUE | MagicColor.BLACK), - new Region("Auntie's Hovel", "Auntie's Hovel", MagicColor.BLACK | MagicColor.RED), - new Region("Rustic Clachan", "Rustic Clachan", MagicColor.GREEN | MagicColor.WHITE), - new Region("Gilt-Leaf Palace", "Gilt-Leaf Palace", MagicColor.BLACK | MagicColor.GREEN), - new Region("Ancient Amphitheater", "Ancient Amphitheater", MagicColor.RED | MagicColor.WHITE), - new Region("Murmuring Bosk", "Murmuring Bosk", MagicColor.WHITE | MagicColor.BLACK | MagicColor.GREEN), - new Region("Primal Beyond", "Primal Beyond", ColorSet.ALL_COLORS.getColor()) - }), - Mercadia("Mercadia", new String[] { - "MMQ", "NEM", "PCY" - }, new String[] { - "Cliffside Market" - }, new String[] { - - }, new Region[] { - new Region("Fountain of Cho", "Fountain of Cho", MagicColor.WHITE), - new Region("Saprazzan Cove", "Saprazzan Cove", MagicColor.BLUE), - new Region("Subterranean Hangar", "Subterranean Hangar", MagicColor.BLACK), - new Region("Mercadian Bazaar", "Mercadian Bazaar", MagicColor.RED), - new Region("Rushwood Grove", "Rushwood Grove", MagicColor.GREEN) - }), - Mirrodin("Mirrodin", new String[] { - "MRD", "DST", "5DN", "SOM", "MBS", "NPH" - }, new String[] { - "Panopticon", "Quicksilver Sea", "Furnace Layer", "Norn's Dominion" - }, new String[] { - "Crystal Ball", "Vial of Poison", "Avarice Amulet", "Masterwork of Ingenuity", "Scytheclaw", - "Soul of New Phyrexia", "Adaptive Automaton", "Bonded Construct", "Chief of the Foundry", - "Guardian Automaton", "Hangarback Walker", "Scuttling Doom Engine", "Steel Overseer", - "Chronomaton", "Ramroller", "Augury Owl", "Healer of the Pride", "Aeronaut Tinkerer", - "Aspiring Aeronaut", "Foundry of the Consuls", "Ghirapur Gearcrafter", "Pia and Kiran Nalaar", - "Thopter Engineer", "Thopter Spy Network", "Whirler Rogue", "Ajani, Caller of the Pride", - "Blastfire Bolt", "Buried Ruin", "Chief Engineer", "Artificer's Hex", "Artificer's Epiphany", - "Feldon of the Third Path", "Flamewright", "Muzzio, Visionary Architect", "Reclusive Artificer", - "Sydri, Galvanic Genius", "Darksteel Mutation", "Ensoul Artifact", "Ezuri, Claw of Progress", - "Ghirapur AEther Grid", "Hoarding Dragon", "Manic Vandal", "Molten Birth", "Phylactery Lich", - "Preordain", "Scrap Mastery", "Scrapyard Mongrel", "Smelt" - }, new Region[] { - new Region("Panopticon", "Darksteel Citadel", MagicColor.COLORLESS), - new Region("Taj-Nar", "Ancient Den", MagicColor.WHITE), - new Region("Lumengrid", "Seat of the Synod", MagicColor.BLUE), - new Region("Ish Sah", "Vault of Whispers", MagicColor.BLACK), - new Region("Kuldotha", "Great Furnace", MagicColor.RED), - new Region("Tel-Jilad", "Tree of Tales", MagicColor.GREEN), - new Region("Glimmervoid", "Glimmervoid", ColorSet.ALL_COLORS.getColor()) - }), - Rath("Rath", new String[] { - "TMP", "STH", "EXO" - }, new String[] { - "Stronghold Furnace" - }, new String[] { - "Battle Sliver", "Belligerent Sliver", "Blur Sliver", "Bonescythe Sliver", "Constricting Sliver", - "Diffusion Sliver", "Galerider Sliver", "Groundshaker Sliver", "Hive Stirrings", "Leeching Sliver", - "Manaweft Sliver", "Megantic Sliver", "Predatory Sliver", "Sentinel Sliver", "Sliver Construct", - "Sliver Hive", "Sliver Hivelord", "Steelform Sliver", "Striking Sliver", "Syphon Sliver", - "Thorncaster Sliver", "Venom Sliver" - }, new Region[] { - new Region("Caldera Lake", "Caldera Lake", MagicColor.BLUE | MagicColor.RED), - new Region("Cinder Marsh", "Cinder Marsh", MagicColor.BLACK | MagicColor.RED), - new Region("Mogg Hollows", "Mogg Hollows", MagicColor.RED | MagicColor.GREEN), - new Region("Pine Barrens", "Pine Barrens", MagicColor.BLACK | MagicColor.GREEN), - new Region("Rootwater Depths", "Rootwater Depths", MagicColor.BLUE | MagicColor.BLACK), - new Region("Salt Flats", "Salt Flats", MagicColor.WHITE | MagicColor.BLACK), - new Region("Scabland", "Scabland", MagicColor.RED | MagicColor.WHITE), - new Region("Skyshroud Forest", "Skyshroud Forest", MagicColor.GREEN | MagicColor.BLUE), - new Region("Thalakos Lowlands", "Thalakos Lowlands", MagicColor.WHITE | MagicColor.BLUE), - new Region("Vec Townships", "Vec Townships", MagicColor.GREEN | MagicColor.WHITE) - }), - Ravnica("Ravnica", new String[] { - "RAV", "GPT", "DIS", "RTR", "GTC", "DGM" - }, new String[] { - "Agyrem", "Grand Ossuary", "Izzet Steam Maze", "Orzhova", "Prahv", "Selesnya Loft Gardens", "Undercity Reaches" - }, new String[] { - "Druidic Satchel", "Gem of Becoming", "Obelisk of Urd", "Will-Forged Golem", "Seraph of the Masses", - "Avatar of Slaughter", "Basandra, Battle Seraph", "Soul of Ravnica", "Duskhunter Bat", - "Shattergang Brothers", "Blood Ogre", "Bloodlord of Vaasgoth", "Bloodrage Vampire", "Carnage Wurm", - "Furyborn Hellkite", "Gorehorn Minotaurs", "Lurking Crocodile", "Stormblood Berserker", - "Vampire Outcasts", "Bounding Krasis", "Conclave Naturalists", "Covenant of Blood", - "Crowd's Favor", "Endless Obedience", "Ephemeral Shields", "Feral Incarnation", "Living Totem", - "Meditation Puzzle", "Return to the Ranks", "Stain the Mind", "Stoke the Flames", "Triplicate Spirits", - "Unmake the Graves", "Deadbridge Shaman", "Extract from Darkness", "Mizzium Meddler", "Mizzix of the Izmagnus", - "Karlov of the Ghost Council", "Mazirek, Kraul Death Priest", "Fungal Sprouting", "Ghave, Guru of Spores", - "Jade Mage", "Sporemound", "Jace, the Living Guildpact", "Krenko's Command", "Krenko's Enforcer", "Krenko, Mob Boss", - "Leyline of Anticipation", "Leyline of Punishment", "Leyline of Sanctity", "Leyline of Vitality", "Mantle of Webs", - "Nightsnare", "Shattergang Brothers", "Yeva's Forcemage", "Yeva, Nature's Herald", "Rhox Maulers", - "Goblin Glory Chaser", "Scab-Clan Berserker", "Undercity Troll" - }, new Region[] { - new Region("Azorius Chancery", "Azorius Chancery", MagicColor.WHITE | MagicColor.BLUE), - new Region("Boros Garrison", "Boros Garrison", MagicColor.RED | MagicColor.WHITE), - new Region("Dimir Aqueduct", "Dimir Aqueduct", MagicColor.BLUE | MagicColor.BLACK), - new Region("Golgari Rot Farm", "Golgari Rot Farm", MagicColor.BLACK | MagicColor.GREEN), - new Region("Gruul Turf", "Gruul Turf", MagicColor.RED | MagicColor.GREEN), - new Region("Izzet Boilerworks", "Izzet Boilerworks", MagicColor.BLUE | MagicColor.RED), - new Region("Orzhov Basilica", "Orzhov Basilica", MagicColor.WHITE | MagicColor.BLACK), - new Region("Rakdos Carnarium", "Rakdos Carnarium", MagicColor.BLACK | MagicColor.RED), - new Region("Selesnya Sanctuary", "Selesnya Sanctuary", MagicColor.GREEN | MagicColor.WHITE), - new Region("Simic Growth Chamber", "Simic Growth Chamber", MagicColor.GREEN | MagicColor.BLUE) - }), - Regatha("Regatha", new String[] { - - }, new String[] { - "Mount Keralia" - }, new String[] { - "Firefiend Elemental", "Acolyte of the Inferno" - }, new Region[] { - new Region("", "", ColorSet.ALL_COLORS.getColor()) - }), - Shandalar("Shandalar", new String[] { - "2ED", "3ED", "4ED", "ARN", "ATQ", "LEG", "DRK", "FEM" - }, new String[] { - "Eloren Wilds", "Onakke Catacomb" - }, new String[] { - "Acorn Catapult", "Tyrant's Machine", "Brittle Effigy", "Kird Chieftain", "Soul of Shandalar", - "Ring of Evos Isle", "Ring of Kalonia", "Ring of Thune", "Ring of Valkas", "Ring of Xathrid", - "Kalonian Behemoth", "Kalonian Tusker", "Kalonian Hydra", "Kalonian Twingrove", "Roaring Primadox", - "Thragtusk", "Warden of Evos Isle", "Initiates of the Ebon Hand", "Deathgaze Cockatrice", - "Acolyte of Xathrid", "Xathrid Demon", "Xathrid Gorgon", "Xathrid Necromancer", "Xathrid Slyblade", - "Downpour", "Talrand's Invocation", "Talrand, Sky Summoner", "Encrust", "Sentinel Spider", - "Faith's Reward", "Garruk, Apex Predator", "Garruk, Primal Hunter", "Griffin Rider", - "Hunter's Insight", "In Garruk's Wake", "Jalira, Master Polymorphist", "Kothophed, Soul Hoarder", - "Magmatic Force", "Master of the Pearl Trident", "Polymorphist's Jest", "Scroll Thief", - "The Chain Veil", "Yisan, the Wanderer Bard" - }, new Region[] { - new Region("Core", "Black Lotus", inSet("2ED", "3ED", "4ED")), - new Region("Arabian Nights", "Library of Alexandria", inSet("ARN")), - new Region("Antiquities", "Mishra's Workshop", inSet("ATQ")), - new Region("Legends", "Karakas", inSet("LEG")), - new Region("The Dark", "City of Shadows", inSet("DRK")), - new Region("Fallen Empires", "Ruins of Trokair", inSet("FEM")) - }), - Tarkir("Tarkir", new String[] { - "KTK", "FRF", "DTK" - }, new String[] { - "Kharasha Foothills" - }, new String[] { - "Ringwarden Owl", "Aven Battle Priest", "Abbot of Keral Keep", "Mage-Ring Bully" - }, new Region[] { - new Region("Abzan Houses", "Sandsteppe Citadel", MagicColor.WHITE | MagicColor.BLACK | MagicColor.GREEN), - new Region("Jeskai Way", "Mystic Monastery", MagicColor.BLUE | MagicColor.RED | MagicColor.WHITE), - new Region("Mardu Horde", "Nomad Outpost", MagicColor.RED | MagicColor.WHITE | MagicColor.BLACK), - new Region("Sultai Brood", "Opulent Palace", MagicColor.BLACK | MagicColor.GREEN | MagicColor.BLUE), - new Region("Temur Frontier", "Frontier Bivouac", MagicColor.GREEN | MagicColor.BLUE | MagicColor.RED) - }), - Theros("Theros", new String[] { - "THS", "BNG", "JOU" - }, new String[] { - "Lethe Lake" - }, new String[] { - "Gorgon Flail", "Helm of the Gods", "Sigil of Valor", "Aegis Angel", "Soul of Theros", - "Enlightened Ascetic", "Ajani's Chosen", "Herald of the Pantheon", "Ajani Steadfast", - "Ajani's Sunstriker", "Akroan Jailer", "Akroan Sergeant", "Anchor to the AEther", - "Blood-Cursed Knight", "Daxos the Returned", "Daxos's Torment", "Kalemne, Disciple of Iroas", - "Gideon's Avenger", "Gideon's Lawkeeper", "Gideon's Phalanx", "Grasp of the Hieromancer", - "Kytheon's Irregulars", "Kytheon's Tactics", "Kytheon, Hero of Akros", "Hixus, Prison Warden", - "Iroas's Champion", "Kalemne's Captain", "Magmatic Insight", "Oath of the Ancient Wood", - "Prickleboar", "Shadows of the Past", "Starfield of Nyx", "Suppression Bonds", "Valor in Akros", - "Pharika's Disciple", "Celestial Flare" - }, new Region[] { - new Region("Oreskos", "Temple of Plenty", MagicColor.WHITE), - new Region("Meletis", "Temple of Enlightenment", MagicColor.BLUE), - new Region("Asphodel", "Temple of Silence", MagicColor.BLACK), - new Region("Akros", "Temple of Malice", MagicColor.RED), - new Region("Setessa", "Temple of Mystery", MagicColor.GREEN), - }), - Ulgrotha("Ulgrotha", new String[] { - "HML" - }, new String[] { - "The Dark Barony" - }, new String[] { - "Elixir of Immortality", "Viscera Seer" - }, new Region[] { - new Region("", "", inSet("HML")) - }), - Zendikar("Zendikar", new String[] { - "ZEN", "WWK", "ROE", "BFZ", "OGW" - }, new String[] { - "Akoum", "Hedron Fields of Agadeem", "Murasa", "Tazeem" - }, new String[] { - "Perilous Vault", "Archangel of Thune", "Soul of Zendikar", "Boundless Realms", "Malakir Cullblade", - "Nissa's Expedition", "Dismiss into Dream", "Elemental Bond", "Elvish Archdruid", "Elvish Mystic", - "Nahiri, the Lithomancer", "Felidar Umbra", "Indrik Umbra", "Into the Wilds", "Joraga Invocation", - "Mind Control", "Nissa's Pilgrimage", "Nissa's Revelation", "Nissa, Vastwood Seer", "Nissa, Worldwaker", - "Ob Nixilis of the Black Oath", "Ob Nixilis, Unshackled", "Sword of the Animist", "Vastwood Hydra", - "Wild Instincts", "Woodborn Behemoth", "Zendikar Incarnate", "Zendikar's Roil" - }, new Region[] { - new Region("Kazandu", "Kazandu Refuge", MagicColor.RED | MagicColor.GREEN), - new Region("Graypelt", "Graypelt Refuge", MagicColor.GREEN | MagicColor.WHITE), - new Region("Sejiri", "Sejiri Refuge", MagicColor.WHITE | MagicColor.BLUE), - new Region("Jwar Isle", "Jwar Isle Refuge", MagicColor.BLUE | MagicColor.BLACK), - new Region("Akoum", "Akoum Refuge", MagicColor.BLACK | MagicColor.RED), - new Region("Blind Eternities", "Eldrazi Temple", MagicColor.COLORLESS) - }); - +public class ConquestPlane { private final String name; - private final FCollection editions = new FCollection(); - private final FCollection regions; - private final FCollection bannedCards = new FCollection(); - private final DeckGenPool cardPool = new DeckGenPool(); - private final FCollection planeCards = new FCollection(); - private final FCollection commanders = new FCollection(); - private AwardPool awardPool; + private final String directory; + private FCollection regions; + private DeckGenPool cardPool; + private FCollection planeCards; + private FCollection commanders; + private ConquestAwardPool awardPool; - private ConquestPlane(String name0, String[] setCodes0, String[] planeCards0, String[] additionalCards0, Region[] regions0) { - this(name0, setCodes0, planeCards0, additionalCards0, regions0, null); - } - private ConquestPlane(String name0, String[] setCodes0, String[] planeCards0, String[] additionalCards0, Region[] regions0, String[] bannedCards0) { + private ConquestPlane(String name0) { name = name0; - regions = new FCollection(regions0); - if (bannedCards0 != null) { - bannedCards.addAll(bannedCards0); - } + directory = ForgeConstants.CONQUEST_PLANES_DIR + name + ForgeConstants.PATH_SEPARATOR; + } - for (Region region : regions) { - region.plane = this; + public String getName() { + return name; + } + + public String getDirectory() { + return directory; + } + + public FCollectionView getRegions() { + ensureRegionsLoaded(); + return regions; + } + + public int getEventCount() { + ensureRegionsLoaded(); + return regions.size() * ConquestRegion.ROWS_PER_REGION * ConquestRegion.COLS_PER_REGION; + } + + public DeckGenPool getCardPool() { + ensureRegionsLoaded(); + return cardPool; + } + + public FCollectionView getCommanders() { + ensureRegionsLoaded(); + return commanders; + } + + public FCollectionView getPlaneCards() { + if (planeCards == null) { + planeCards = new FCollection(); + + CardDb variantCards = FModel.getMagicDb().getVariantCards(); + List planeCardNames = FileUtil.readFile(directory + "plane_cards.txt"); + for (String name : planeCardNames) { + PaperCard pc = variantCards.getCard(name); + if (pc == null) { + System.out.println("\"" + name + "\" does not correspond to a valid Plane card"); + continue; + } + planeCards.add(pc); + } } + return planeCards; + } + + private void ensureRegionsLoaded() { + if (regions != null) { return; } + + regions = new FCollection(new StorageBase("Conquest regions", new ConquestRegion.Reader(this))); + + //must initialize card pool when regions loaded + cardPool = new DeckGenPool(); + commanders = new FCollection(); CardDb commonCards = FModel.getMagicDb().getCommonCards(); - for (String setCode : setCodes0) { + List bannedCards = FileUtil.readFile(directory + "banned_cards.txt"); + Set bannedCardSet = bannedCards.isEmpty() ? null : new HashSet(bannedCards); + + List setCodes = FileUtil.readFile(directory + "sets.txt"); + for (String setCode : setCodes) { CardEdition edition = FModel.getMagicDb().getEditions().get(setCode); if (edition != null) { - editions.add(edition); for (CardInSet card : edition.getCards()) { - if (!bannedCards.contains(card.name)) { + if (bannedCardSet == null || !bannedCardSet.contains(card.name)) { addCard(commonCards.getCard(card.name, setCode)); } } } } - for (String cardName : additionalCards0) { + List additionalCards = FileUtil.readFile(directory + "cards.txt"); + for (String cardName : additionalCards) { addCard(commonCards.getCard(cardName)); } - CardDb variantCards = FModel.getMagicDb().getVariantCards(); - for (String planeCard : planeCards0) { - PaperCard pc = variantCards.getCard(planeCard); - if (pc == null) { - System.out.println("\"" + planeCard + "\" does not correspond to a valid Plane card"); - continue; - } - planeCards.add(pc); - } - //sort commanders by name Collections.sort(commanders); } @@ -400,291 +137,53 @@ public enum ConquestPlane { if (pc == null) { return; } CardRules rules = pc.getRules(); - boolean isCommander = pc.getRules().canBeCommander(); + if (rules.getType().isBasicLand()) { return; } //ignore basic lands + cardPool.add(pc); - if (isCommander) { + + if (rules.canBeCommander()) { commanders.add(pc); } - int count = 0; - if (!rules.getType().isBasicLand()) { //add all basic lands to all regions below - for (Region region : regions) { - if (region.pred.apply(pc)) { - region.cardPool.add(pc); - if (isCommander) { - region.commanders.add(pc); - } - count++; - } - } - } - //if card doesn't match any region's predicate, - //make card available to all regions - if (count == 0) { - for (Region region : regions) { - region.cardPool.add(pc); - if (isCommander) { - region.commanders.add(pc); - } - } - } - } - public String getName() { - return name; - } - - public FCollectionView getEditions() { - return editions; - } - - public FCollectionView getBannedCards() { - return bannedCards; - } - - public FCollectionView getRegions() { - return regions; - } - - public DeckGenPool getCardPool() { - return cardPool; - } - - public FCollectionView getCommanders() { - return commanders; - } - - public FCollectionView getPlaneCards() { - return planeCards; - } - - public int getEventCount() { - return regions.size() * Region.ROWS_PER_REGION * Region.COLS_PER_REGION; + ConquestRegion.addCard(pc, regions); } public String toString() { return name; } - public static class Region { - public static final int ROWS_PER_REGION = 3; - public static final int COLS_PER_REGION = 3; - public static final int START_COL = (COLS_PER_REGION - 1) / 2; - - private final String name, artCardName; - private final ColorSet colorSet; - private final Predicate pred; - private final DeckGenPool cardPool = new DeckGenPool(); - private final FCollection commanders = new FCollection(); - - private ConquestPlane plane; - private ISkinImage art; - - private Region(String name0, String artCardName0, final int colorMask) { - name = name0; - artCardName = artCardName0; - pred = new Predicate() { - @Override - public boolean apply(PaperCard pc) { - return pc.getRules().getColorIdentity().hasNoColorsExcept(colorMask); - } - }; - colorSet = ColorSet.fromMask(colorMask); - } - private Region(String name0, String artCardName0, Predicate pred0) { - name = name0; - artCardName = artCardName0; - pred = pred0; - colorSet = ColorSet.fromMask(ColorSet.ALL_COLORS.getColor()); + public static final Function FN_GET_NAME = new Function() { + @Override + public String apply(ConquestPlane plane) { + return plane.getName(); } + }; - public String getName() { - return name; - } - - public ISkinImage getArt() { - if (art == null) { - art = GuiBase.getInterface().getCardArt(cardPool.getCard(artCardName)); - } - return art; - } - - public ColorSet getColorSet() { - return colorSet; - } - - public DeckGenPool getCardPool() { - return cardPool; - } - - public FCollectionView getCommanders() { - return commanders; - } - - public ConquestPlane getPlane() { - return plane; - } - - public String toString() { - return plane.name + " - " + name; - } - } - - private static Predicate inSet(final String... sets) { - return new Predicate() { - @Override - public boolean apply(PaperCard pc) { - for (String set : sets) { - if (pc.getEdition().equals(set)) { - return true; - } - } - return false; - } - }; - } - - public AwardPool getAwardPool() { + public ConquestAwardPool getAwardPool() { if (awardPool == null) { //delay initializing until needed - awardPool = new AwardPool(cardPool.getAllCards()); + awardPool = new ConquestAwardPool(cardPool.getAllCards()); } return awardPool; } - public static class AwardPool { - private final BoosterPool commons, uncommons, rares, mythics; - private final int commonValue, uncommonValue, rareValue, mythicValue; - - public AwardPool(Iterable cards) { - ConquestPreferences prefs = FModel.getConquestPreferences(); - - commons = new BoosterPool(); - uncommons = new BoosterPool(); - rares = new BoosterPool(); - mythics = new BoosterPool(); - - for (PaperCard c : cards) { - switch (c.getRarity()) { - case Common: - commons.add(c); - break; - case Uncommon: - uncommons.add(c); - break; - case Rare: - case Special: //lump special cards in with rares for simplicity - rares.add(c); - break; - case MythicRare: - mythics.add(c); - break; - default: - break; - } - } - - //calculate odds of each rarity - float commonOdds = commons.getOdds(prefs.getPrefInt(CQPref.BOOSTER_COMMONS)); - float uncommonOdds = uncommons.getOdds(prefs.getPrefInt(CQPref.BOOSTER_UNCOMMONS)); - int raresPerBooster = prefs.getPrefInt(CQPref.BOOSTER_RARES); - 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)); + public static class Reader extends StorageReaderFile { + public Reader(String file0) { + super(file0, ConquestPlane.FN_GET_NAME); } - public int getShardValue(PaperCard card) { - switch (card.getRarity()) { - case Common: - return commonValue; - case Uncommon: - return uncommonValue; - case Rare: - case Special: - return rareValue; - case MythicRare: - return mythicValue; - default: - return 0; - } - } - - public BoosterPool getCommons() { - return commons; - } - public BoosterPool getUncommons() { - return uncommons; - } - public BoosterPool getRares() { - return rares; - } - public BoosterPool getMythics() { - return mythics; - } - - public class BoosterPool { - private final List cards = new ArrayList(); - - private BoosterPool() { - } - - public boolean isEmpty() { - return cards.isEmpty(); - } - - private float getOdds(float perBoosterCount) { - int count = cards.size(); - if (count == 0) { return 0; } - return (float)perBoosterCount / (float)count; - } - - private void add(PaperCard c) { - cards.add(c); - } - - public void rewardCard(List rewards) { - int index = Aggregates.randomInt(0, cards.size() - 1); - PaperCard c = cards.get(index); - cards.remove(index); - rewards.add(c); - } + @Override + protected ConquestPlane read(String line, int i) { + return new ConquestPlane(line); } } public static Set getAllPlanesOfCard(PaperCard card) { - EnumSet planes = EnumSet.noneOf(ConquestPlane.class); - for (ConquestPlane plane : values()) { + Set planes = new HashSet(); + for (ConquestPlane plane : FModel.getPlanes()) { if (plane.cardPool.contains(card)) { planes.add(plane); } } return planes; } - - public static Set getAllRegionsOfCard(PaperCard card) { - Set regions = new HashSet(); - for (ConquestPlane plane : values()) { - if (plane.cardPool.contains(card)) { - for (Region region : plane.getRegions()) { - if (region.cardPool.contains(card)) { - regions.add(region); - } - } - } - } - return regions; - } - - public static List getAllRegions() { - List regions = new ArrayList(); - for (ConquestPlane plane : values()) { - for (Region region : plane.getRegions()) { - regions.add(region); - } - } - return regions; - } } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestPlaneData.java b/forge-gui/src/main/java/forge/planarconquest/ConquestPlaneData.java index 5f704379aec..1cce9914ad8 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestPlaneData.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestPlaneData.java @@ -3,7 +3,6 @@ package forge.planarconquest; import forge.item.PaperCard; import forge.model.FModel; import forge.planarconquest.ConquestEvent.ConquestEventRecord; -import forge.planarconquest.ConquestPlane.Region; import forge.util.XmlReader; import forge.util.XmlWriter; import forge.util.XmlWriter.IXmlWritable; @@ -32,7 +31,7 @@ public class ConquestPlaneData implements IXmlWritable { return hasConquered(loc.getRegionIndex(), loc.getRow(), loc.getCol()); } public boolean hasConquered(int regionIndex, int row, int col) { - return hasConquered(regionIndex * Region.ROWS_PER_REGION * Region.COLS_PER_REGION + row * Region.COLS_PER_REGION + col); + return hasConquered(regionIndex * ConquestRegion.ROWS_PER_REGION * ConquestRegion.COLS_PER_REGION + row * ConquestRegion.COLS_PER_REGION + col); } private boolean hasConquered(int index) { ConquestEventRecord result = eventResults[index]; @@ -43,12 +42,12 @@ public class ConquestPlaneData implements IXmlWritable { return getEventRecord(loc.getRegionIndex(), loc.getRow(), loc.getCol()); } public ConquestEventRecord getEventRecord(int regionIndex, int row, int col) { - return eventResults[regionIndex * Region.ROWS_PER_REGION * Region.COLS_PER_REGION + row * Region.COLS_PER_REGION + col]; + return eventResults[regionIndex * ConquestRegion.ROWS_PER_REGION * ConquestRegion.COLS_PER_REGION + row * ConquestRegion.COLS_PER_REGION + col]; } private ConquestEventRecord getOrCreateResult(ConquestEvent event) { ConquestLocation loc = event.getLocation(); - int index = loc.getRegionIndex() * Region.ROWS_PER_REGION * Region.COLS_PER_REGION + loc.getRow() * Region.COLS_PER_REGION + loc.getCol(); + int index = loc.getRegionIndex() * ConquestRegion.ROWS_PER_REGION * ConquestRegion.COLS_PER_REGION + loc.getRow() * ConquestRegion.COLS_PER_REGION + loc.getCol(); ConquestEventRecord result = eventResults[index]; if (result == null) { result = new ConquestEventRecord(); diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestRegion.java b/forge-gui/src/main/java/forge/planarconquest/ConquestRegion.java new file mode 100644 index 00000000000..6b7387b0a1c --- /dev/null +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestRegion.java @@ -0,0 +1,174 @@ +package forge.planarconquest; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; + +import forge.GuiBase; +import forge.assets.ISkinImage; +import forge.card.ColorSet; +import forge.deck.generation.DeckGenPool; +import forge.item.PaperCard; +import forge.model.FModel; +import forge.util.storage.StorageReaderFile; + +public class ConquestRegion { + public static final int ROWS_PER_REGION = 3; + public static final int COLS_PER_REGION = 3; + public static final int START_COL = (COLS_PER_REGION - 1) / 2; + + private final ConquestPlane plane; + private final String name, artCardName; + private final ColorSet colorSet; + private final Predicate pred; + private final DeckGenPool cardPool = new DeckGenPool(); + + private ISkinImage art; + + private ConquestRegion(ConquestPlane plane0, String name0, String artCardName0, ColorSet colorSet0, Predicate pred0) { + plane = plane0; + name = name0; + artCardName = artCardName0; + pred = pred0; + colorSet = colorSet0; + } + + public ConquestPlane getPlane() { + return plane; + } + + public String getName() { + return name; + } + + public ISkinImage getArt() { + if (art == null) { + art = GuiBase.getInterface().getCardArt(cardPool.getCard(artCardName)); + } + return art; + } + + public ColorSet getColorSet() { + return colorSet; + } + + public DeckGenPool getCardPool() { + return cardPool; + } + + public String toString() { + return plane.getName() + " - " + name; + } + + public static final Function FN_GET_NAME = new Function() { + @Override + public String apply(ConquestRegion region) { + return region.getName(); + } + }; + + public static class Reader extends StorageReaderFile { + private final ConquestPlane plane; + + public Reader(ConquestPlane plane0) { + super(plane0.getDirectory() + "regions.txt", ConquestRegion.FN_GET_NAME); + plane = plane0; + } + + @Override + protected ConquestRegion read(String line, int index) { + String name = null; + String artCardName = null; + ColorSet colorSet = ColorSet.ALL_COLORS; + Predicate pred = null; + + String[] pieces = line.trim().split("\\|"); + for (String piece : pieces) { + String[] kv = piece.split(":", 2); + String key = kv[0].trim().toLowerCase(); + String value = kv[1].trim(); + switch(key) { + case "name": + name = value; + break; + case "art": + artCardName = value; + break; + case "colors": + colorSet = ColorSet.fromNames(value.toCharArray()); + final int colorMask = colorSet.getColor(); + pred = new Predicate() { + @Override + public boolean apply(PaperCard pc) { + return pc.getRules().getColorIdentity().hasNoColorsExcept(colorMask); + } + }; + break; + case "sets": + final String[] sets = value.split(","); + for (int i = 0; i < sets.length; i++) { + sets[i] = sets[i].trim(); + } + pred = new Predicate() { + @Override + public boolean apply(PaperCard pc) { + for (String set : sets) { + if (pc.getEdition().equals(set)) { + return true; + } + } + return false; + } + }; + break; + } + } + return new ConquestRegion(plane, name, artCardName, colorSet, pred); + } + } + + static void addCard(PaperCard pc, Iterable regions) { + boolean foundRegion = false; + for (ConquestRegion region : regions) { + if (region.pred.apply(pc)) { + region.cardPool.add(pc); + foundRegion = true; + } + } + + if (foundRegion) { return; } + + //if card doesn't match any region's predicate, make card available to all regions + for (ConquestRegion region : regions) { + region.cardPool.add(pc); + } + } + + public static Set getAllRegionsOfCard(PaperCard card) { + Set regions = new HashSet(); + for (ConquestPlane plane : FModel.getPlanes()) { + if (plane.getCardPool().contains(card)) { + for (ConquestRegion region : plane.getRegions()) { + if (region.getCardPool().contains(card)) { + regions.add(region); + } + } + } + } + return regions; + } + + public static List getAllRegions() { + List regions = new ArrayList(); + for (ConquestPlane plane : FModel.getPlanes()) { + for (ConquestRegion region : plane.getRegions()) { + regions.add(region); + } + } + return regions; + } +} \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/properties/ForgeConstants.java b/forge-gui/src/main/java/forge/properties/ForgeConstants.java index a6c93451655..c3993c14a95 100644 --- a/forge-gui/src/main/java/forge/properties/ForgeConstants.java +++ b/forge-gui/src/main/java/forge/properties/ForgeConstants.java @@ -73,6 +73,9 @@ public final class ForgeConstants { public static final String DEFAULT_CHALLENGES_DIR = QUEST_DIR + "challenges"; public static final String THEMES_DIR = QUEST_DIR + "themes"; + private static final String CONQUEST_DIR = RES_DIR + "conquest" + PATH_SEPARATOR; + public static final String CONQUEST_PLANES_DIR = CONQUEST_DIR + "planes" + PATH_SEPARATOR; + public static final String SKINS_DIR = RES_DIR + "skins" + PATH_SEPARATOR; public static final String DEFAULT_SKINS_DIR = SKINS_DIR + "default" + PATH_SEPARATOR; //don't associate these skin files with a directory since skin directory will be determined later diff --git a/forge-gui/src/main/java/forge/quest/QuestWorld.java b/forge-gui/src/main/java/forge/quest/QuestWorld.java index 02379282382..be009346f65 100644 --- a/forge-gui/src/main/java/forge/quest/QuestWorld.java +++ b/forge-gui/src/main/java/forge/quest/QuestWorld.java @@ -99,7 +99,6 @@ public class QuestWorld implements Comparable{ } public static final Function FN_GET_NAME = new Function() { - @Override public String apply(QuestWorld arg1) { return arg1.getName(); diff --git a/forge-gui/src/main/java/forge/util/XmlReader.java b/forge-gui/src/main/java/forge/util/XmlReader.java index 97c1eda823f..0b498c7c920 100644 --- a/forge-gui/src/main/java/forge/util/XmlReader.java +++ b/forge-gui/src/main/java/forge/util/XmlReader.java @@ -3,6 +3,7 @@ package forge.util; import java.io.File; import java.util.Collection; import java.util.EnumMap; +import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -102,6 +103,30 @@ public class XmlReader { } }); } + public void read(final String key, final Map enumMap, final Class valueType) { + parseChildElements(key, new Evaluator() { + @Override + public Void evaluate() { + final GenericBuilder builder = new GenericBuilder(valueType); + return parseChildElements(null, new Evaluator() { + @Override + public Void evaluate() { + try { + String key = currentElement.getTagName(); + V value = builder.evaluate(); + if (value != null) { + enumMap.put(key, value); + } + } + catch (Exception e) { + e.printStackTrace(); + } + return null; + } + }); + } + }); + } public , V extends IXmlWritable> void read(final String key, final EnumMap enumMap, final Class enumType, final Class valueType) { parseChildElements(key, new Evaluator() { @Override diff --git a/forge-gui/src/main/java/forge/util/XmlWriter.java b/forge-gui/src/main/java/forge/util/XmlWriter.java index cb80e37e2a4..b8e955cd53b 100644 --- a/forge-gui/src/main/java/forge/util/XmlWriter.java +++ b/forge-gui/src/main/java/forge/util/XmlWriter.java @@ -2,6 +2,7 @@ package forge.util; import java.util.EnumMap; import java.util.HashSet; +import java.util.Map; import java.util.Map.Entry; import java.util.Stack; @@ -92,6 +93,13 @@ public class XmlWriter { } endElement(); } + public void write(String key, Map value) { + startElement(key); + for (Entry entry : value.entrySet()) { + write(entry.getKey(), entry.getValue()); + } + endElement(); + } public void write(String key, EnumMap, ? extends IXmlWritable> value) { startElement(key); for (Entry, ? extends IXmlWritable> entry : value.entrySet()) {