/* * Map.java * * Created on January 26, 2007, 6:31 PM */ package editor; import eug.parser.EUGFileIO; import eug.parser.ParserSettings; import eug.shared.GenericList; import eug.shared.GenericObject; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; /** * * @author Michael Myers */ public final class Map { private static final String MAP_DIR_NAME = "/map"; private GenericObject mapData; private GenericObject continents; private java.util.Map<String, List<String>> contList = null; private GenericObject climates; private java.util.Map<String, List<String>> climateList = null; private GenericObject natives; private java.util.Map<String, List<String>> nativeList = null; private GenericObject regions; private java.util.Map<String, List<String>> regionList = null; private boolean[] isLand = null; // for In Nomine mainly private boolean isInNomine; /** * Creates a new instance of Map. */ public Map() { try { loadData(); } catch (FileNotFoundException ex) { ex.printStackTrace(); } } private void loadData() throws FileNotFoundException { System.out.println("Map file is " + Main.filenameResolver.resolveFilename(MAP_DIR_NAME + "/default.map")); mapData = EUGFileIO.load(Main.filenameResolver.resolveFilename(MAP_DIR_NAME + "/default.map")); // System.out.println("default.map:"); // System.out.println(mapData); if (mapData == null) { throw new RuntimeException("Failed to load map file"); } isInNomine = mapData.getString("sea_starts").length() == 0; System.out.println(isInNomine ? "In Nomine" : "Not In Nomine"); String contFilename = mapData.getString("continent").replace('\\', '/'); if (!contFilename.contains("/")) contFilename = MAP_DIR_NAME + '/' + contFilename; continents = EUGFileIO.load( Main.filenameResolver.resolveFilename(contFilename), ParserSettings.getNoCommentSettings().setPrintTimingInfo(false) ); String climateFilename = mapData.getString("climate").replace('\\', '/'); if (!climateFilename.contains("/")) climateFilename = MAP_DIR_NAME + '/' + climateFilename; climates = EUGFileIO.load( Main.filenameResolver.resolveFilename(climateFilename), ParserSettings.getNoCommentSettings().setPrintTimingInfo(false) ); String nativesFilename = "common/natives.txt"; natives = EUGFileIO.load( Main.filenameResolver.resolveFilename(nativesFilename), ParserSettings.getNoCommentSettings().setPrintTimingInfo(false) ); if (isInNomine) { String regFilename = mapData.getString("region").replace('\\', '/'); if (!regFilename.contains("/")) regFilename = MAP_DIR_NAME + '/' + regFilename; regions = EUGFileIO.load( Main.filenameResolver.resolveFilename(regFilename), ParserSettings.getNoCommentSettings().setPrintTimingInfo(false) ); } if (isInNomine) { // Initialize boolean array isLand = new boolean[mapData.getInt("max_provinces")]; for (int i = 1; i < isLand.length; i++) { isLand[i] = true; // unfortunately, the default is false } GenericList seaProvs = mapData.getList("sea_starts"); if (seaProvs == null) { System.err.println("No sea_starts found in default.map; weird things might start happening now"); } else { for (String provId : seaProvs) { int id = Integer.parseInt(provId); isLand[id] = false; } } } } public java.util.Map<String, List<String>> getContinents() { if (contList == null) { contList = new HashMap<String, List<String>>(continents.size()); for (GenericList cont : continents.lists) { contList.put(cont.getName(), cont.getList()); } } return contList; } public List<String> getContinent(String name) { return getContinents().get(name); } public String getContinentOfProv(String provId) { for (java.util.Map.Entry<String, List<String>> entry : getContinents().entrySet()) { if (entry.getValue().contains(provId)) { return entry.getKey(); } } return "(none)"; } public String getContinentOfProv(int provId) { return getContinentOfProv(Integer.toString(provId)); } public java.util.Map<String, List<String>> getClimates() { if (climateList == null) { climateList = new HashMap<String, List<String>>(climates.size()+1); final List<String> usedIds = new ArrayList<String>(1000); for (GenericList climate : climates.lists) { final List<String> ids = climate.getList(); usedIds.addAll(ids); climateList.put(climate.getName(), ids); } Collections.sort(usedIds); final List<String> unusedIds = new ArrayList<String>(); for (int i : getLandProvs()) { final String sid = Integer.toString(i); final int idx = Collections.binarySearch(usedIds, sid); if (idx < 0) { unusedIds.add(sid); } } climateList.put("normal", unusedIds); } return climateList; } public List<String> getClimate(String name) { return getClimates().get(name); } public String getClimateOfProv(String provId) { for (java.util.Map.Entry<String, List<String>> entry : getClimates().entrySet()) { if (entry.getValue().contains(provId)) { return entry.getKey(); } } return "(none)"; } public String getClimateOfProv(int provId) { return getClimateOfProv(Integer.toString(provId)); } public boolean hasRegions() { return regions != null; } public java.util.Map<String, List<String>> getRegions() { if (regionList == null) { regionList = new HashMap<String, List<String>>(regions.size()); for (GenericList cont : regions.lists) { regionList.put(cont.getName(), cont.getList()); } } return regionList; } public List<String> getRegion(String name) { return getRegions().get(name); } public List<String> getRegionsOfProv(String provId) { List<String> ret = new ArrayList<String>(); for (java.util.Map.Entry<String, List<String>> entry : getRegions().entrySet()) { if (entry.getValue().contains(provId)) { ret.add(entry.getKey()); } } if (ret.size() == 0) ret.add("(none)"); return ret; } public List<String> getRegionsOfProv(int provId) { return getRegionsOfProv(Integer.toString(provId)); } public java.util.Map<String, List<String>> getNatives() { if (nativeList == null) { nativeList = new HashMap<String, List<String>>(natives.size()+1); final List<String> usedIds = new ArrayList<String>(1000); for (GenericObject nativeGroup : natives.children) { final List<String> ids = nativeGroup.getList("provinces").getList(); usedIds.addAll(ids); nativeList.put(nativeGroup.name, ids); } Collections.sort(usedIds); final List<String> unusedIds = new ArrayList<String>(); for (int i : getLandProvs()) { final String sid = Integer.toString(i); final int idx = Collections.binarySearch(usedIds, sid); if (idx < 0) { unusedIds.add(sid); } } nativeList.put("normal", unusedIds); } return nativeList; } public List<String> getNatives(String name) { return getNatives().get(name); } public String getNativeTypeOfProv(String provId) { for (java.util.Map.Entry<String, List<String>> entry : getNatives().entrySet()) { if (entry.getValue().contains(provId)) { return entry.getKey(); } } return "(none)"; } public String getNativeTypeOfProv(int provId) { return getNativeTypeOfProv(Integer.toString(provId)); } public String getString(String key) { return mapData.getString(key); } public Iterable<Integer> getLandProvs() { if (isInNomine) return new INLandProvIterator(); return new LandProvIterator(mapData.getInt("sea_starts")); } public boolean isLand(int provId) { if (provId <= 0) return false; if (isInNomine) return isLand[provId]; return provId < mapData.getInt("sea_starts"); } public boolean isInNomine() { return isInNomine; } public int getFirstSeaProv() { if (isInNomine) { for (int i = 1; i < isLand.length; i++) { if (!isLand[i]) return i; } return isLand.length; } else { return Integer.parseInt(mapData.getString("sea_starts")); } } private final class INLandProvIterator implements Iterable<Integer>, Iterator<Integer> { private final int numProvs; private int index; public INLandProvIterator() { this.numProvs = mapData.getInt("max_provinces"); index = 1; } public Iterator<Integer> iterator() { return this; } public boolean hasNext() { while (++index < numProvs) { if (isLand[index]) return true; } return false; } public Integer next() { return index++; } public void remove() { throw new UnsupportedOperationException(); } } private static final class LandProvIterator implements Iterable<Integer>, Iterator<Integer> { private final int seaStarts; private int index; public LandProvIterator(int seaStarts) { // requires a parameter so we can make this class static this.seaStarts = seaStarts; index = 1; } public Iterator<Integer> iterator() { return this; } public boolean hasNext() { return index < seaStarts; } public Integer next() { return index++; } public void remove() { throw new UnsupportedOperationException(); } } }