diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index 1844eef90..2bb46e9c3 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -18,7 +18,7 @@ public final class AndorsTrailApplication extends Application { public static final boolean DEVELOPMENT_VALIDATEDATA = true; public static final boolean DEVELOPMENT_DEBUGMESSAGES = true; public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES; - public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? 999 : 34; + public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? 999 : 35; public static final String CURRENT_VERSION_DISPLAY = "0.7.0dev"; private final AndorsTrailPreferences preferences = new AndorsTrailPreferences(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java index 074da6c02..4d9e7b062 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java @@ -117,7 +117,7 @@ public final class DebugInterface { ,new DebugButton("reset", new OnClickListener() { @Override public void onClick(View arg0) { - for(PredefinedMap map : world.maps.predefinedMaps) { + for(PredefinedMap map : world.maps.getAllMaps()) { map.resetTemporaryData(); } mainActivity.showToast("DEBUG: maps respawned", Toast.LENGTH_SHORT); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java index ed36dc482..736e2bae3 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java @@ -80,9 +80,9 @@ public final class MapController { controllers.actorStatsController.recalculatePlayerStats(player); controllers.actorStatsController.setActorMaxAP(player); controllers.actorStatsController.setActorMaxHealth(player); - for (PredefinedMap m : world.maps.predefinedMaps) { + for (PredefinedMap m : world.maps.getAllMaps()) { m.resetTemporaryData(); - } + } controllers.monsterSpawnController.spawnAll(world.model.currentMap); } @@ -99,7 +99,7 @@ public final class MapController { } public void resetMapsNotRecentlyVisited() { - for (PredefinedMap m : world.maps.predefinedMaps) { + for (PredefinedMap m : world.maps.getAllMaps()) { if (m == world.model.currentMap) continue; if (m.isRecentlyVisited()) continue; if (m.hasResetTemporaryData()) continue; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java index 7c4370a8e..3a801db5f 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java @@ -255,7 +255,7 @@ public final class MovementController implements TimedMessageTask.Callback { // If any monsters somehow spawned on an unwalkable tile, we move the monster to a new position on the spawnarea // This could happen if we change some tile to non-walkable in a future version. - for (PredefinedMap map : world.maps.predefinedMaps) { + for (PredefinedMap map : world.maps.getAllMaps()) { Coord playerPosition = null; if (map == model.currentMap) playerPosition = model.player.position; for (MonsterSpawnArea a : map.spawnAreas) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java index eef5fa9f8..d56649a8a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java @@ -1,34 +1,46 @@ package com.gpl.rpg.AndorsTrail.model.map; +import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; +import com.gpl.rpg.AndorsTrail.context.ControllerContext; +import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForMap; +import com.gpl.rpg.AndorsTrail.util.L; + import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; - -import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; -import com.gpl.rpg.AndorsTrail.context.ControllerContext; -import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.util.L; +import java.util.List; public final class MapCollection { - public final ArrayList predefinedMaps = new ArrayList(); + private final HashMap predefinedMaps = new HashMap(); public final HashMap worldMapSegments = new HashMap(); public MapCollection() {} - - public PredefinedMap findPredefinedMap(String name) { - for (PredefinedMap m : predefinedMaps) { - if (m.name.equals(name)) return m; - } - if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { - L.log("WARNING: Cannot find LayeredWorldMap for name \"" + name + "\"."); + + public void addAll(ArrayList mapsToAdd) { + for (PredefinedMap map : mapsToAdd) { + predefinedMaps.put(map.name, map); } - return null; + } + + public Collection getAllMaps() { + return predefinedMaps.values(); + } + + public PredefinedMap findPredefinedMap(String name) { + if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { + if (!predefinedMaps.containsKey(name)) { + L.log("WARNING: Cannot find PredefinedMap for name \"" + name + "\"."); + } + } + return predefinedMaps.get(name); } public void reset() { - for (PredefinedMap m : predefinedMaps) { + for (PredefinedMap m : getAllMaps()) { m.reset(); } } @@ -48,18 +60,42 @@ public final class MapCollection { if (fileversion == 5) size = 11; else size = src.readInt(); for(int i = 0; i < size; ++i) { - predefinedMaps.get(i).readFromParcel(src, world, controllers, fileversion); + String name; + if (fileversion >= 35) { + name = src.readUTF(); + } else { + name = LegacySavegameFormatReaderForMap.getMapnameFromIndex(i); + } + PredefinedMap map = predefinedMaps.get(name); + if (map == null) { + if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { + L.log("WARNING: Tried to load savegame with map \"" + name + "\", but no such map exists."); + } + continue; + } + map.readFromParcel(src, world, controllers, fileversion); if (i >= 40) { - if (fileversion < 15) predefinedMaps.get(i).visited = false; + if (fileversion < 15) map.visited = false; } } } - - public void writeToParcel(DataOutputStream dest, int flags) throws IOException { - final int size = predefinedMaps.size(); - dest.writeInt(size); - for(int i = 0; i < size; ++i) { - predefinedMaps.get(i).writeToParcel(dest, flags); + + private static boolean shouldSaveMap(WorldContext world, PredefinedMap map) { + if (map == world.model.currentMap) return true; + if (!map.visited) return false; + if (map.hasPersistentData()) return true; + return false; + } + + public void writeToParcel(DataOutputStream dest, WorldContext world, int flags) throws IOException { + List mapsToExport = new ArrayList(); + for(PredefinedMap map : getAllMaps()) { + if (shouldSaveMap(world, map)) mapsToExport.add(map); + } + dest.writeInt(mapsToExport.size()); + for(PredefinedMap map : mapsToExport) { + dest.writeUTF(map.name); + map.writeToParcel(dest, flags); } } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java index 4013fdf10..991c8761b 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java @@ -178,6 +178,14 @@ public final class PredefinedMap { public boolean hasResetTemporaryData() { return lastVisitTime == VISIT_RESET; } + public boolean hasPersistentData() { + if (!hasResetTemporaryData()) return true; + if (!groundBags.isEmpty()) return true; + for (MonsterSpawnArea a : spawnAreas) { + if (a.isUnique) return true; + } + return false; + } public void createAllContainerLoot() { for (MapObject o : eventObjects) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java index a0fe44e3a..6c31c6324 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java @@ -159,7 +159,7 @@ public final class ResourceLoader { mapReader.read(r, mapResourceId, mapName); } if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("TMXMapReader"); - world.maps.predefinedMaps.addAll(mapReader.transformMaps(loader, world.monsterTypes, world.dropLists)); + world.maps.addAll(mapReader.transformMaps(loader, world.monsterTypes, world.dropLists)); mapReader = null; if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("mapReader.transformMaps"); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMap.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMap.java new file mode 100644 index 000000000..9c16165e4 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMap.java @@ -0,0 +1,299 @@ +package com.gpl.rpg.AndorsTrail.savegames; + +public final class LegacySavegameFormatReaderForMap { + public static String getMapnameFromIndex(int index) { + /* + * Before v0.7.0 (before fileversion 35), all maps were stored in the savegame file + * in a specific order, one after the other. Because of that, the ordering had significance + * when loading the files ("home.tmx" was expected to come first, for example. + * We've now moved away from that ordering, but still need to be able to load old savegame files + * that still use that ordering. Hence this list of mapping indexes to which map it means. + */ + switch (index) { + case 0: return "home"; + case 1: return "crossglen"; + case 2: return "crossglen_farmhouse"; + case 3: return "crossglen_farmhouse_basement"; + case 4: return "crossglen_hall"; + case 5: return "crossglen_smith"; + case 6: return "crossglen_cave"; + case 7: return "wild1"; + case 8: return "wild2"; + case 9: return "wild3"; + case 10: return "jan_pitcave1"; + case 11: return "jan_pitcave2"; + case 12: return "jan_pitcave3"; + case 13: return "fallhaven_nw"; + case 14: return "snakecave1"; + case 15: return "snakecave2"; + case 16: return "snakecave3"; + case 17: return "wild4"; + case 18: return "hauntedhouse1"; + case 19: return "hauntedhouse2"; + case 20: return "fallhaven_ne"; + case 21: return "fallhaven_church"; + case 22: return "fallhaven_barn"; + case 23: return "fallhaven_potions"; + case 24: return "fallhaven_gravedigger"; + case 25: return "fallhaven_clothes"; + case 26: return "fallhaven_arcir"; + case 27: return "fallhaven_arcir_basement"; + case 28: return "fallhaven_athamyr"; + case 29: return "fallhaven_rigmor"; + case 30: return "fallhaven_tavern"; + case 31: return "fallhaven_prison"; + case 32: return "fallhaven_derelict"; + case 33: return "fallhaven_nocmar"; + case 34: return "catacombs1"; + case 35: return "catacombs2"; + case 36: return "catacombs3"; + case 37: return "catacombs4"; + case 38: return "hauntedhouse3"; + case 39: return "hauntedhouse4"; + case 40: return "fallhaven_sw"; + case 41: return "wild5"; + case 42: return "wild6"; + case 43: return "wild6_house"; + case 44: return "wild7"; + case 45: return "wild8"; + case 46: return "wild9"; + case 47: return "wild10"; + case 48: return "flagstone0"; + case 49: return "flagstone_inner"; + case 50: return "flagstone_upper"; + case 51: return "flagstone1"; + case 52: return "flagstone2"; + case 53: return "flagstone3"; + case 54: return "flagstone4"; + case 55: return "wild11"; + case 56: return "wild12"; + case 57: return "wild11_clearing"; + case 58: return "clearing_level1"; + case 59: return "clearing_level2"; + case 60: return "fallhaven_se"; + case 61: return "fallhaven_lumberjack"; + case 62: return "fallhaven_alaun"; + case 63: return "fallhaven_storage"; + case 64: return "fallhaven_farmer"; + case 65: return "wild13"; + case 66: return "wild14"; + case 67: return "wild14_cave"; + case 68: return "wild14_clearing"; + case 69: return "wild15"; + case 70: return "wild15_house"; + case 71: return "road1"; + case 72: return "foaming_flask"; + case 73: return "fallhaven_derelict2"; + case 74: return "vilegard_n"; + case 75: return "vilegard_s"; + case 76: return "vilegard_sw"; + case 77: return "vilegard_ogam"; + case 78: return "vilegard_chapel"; + case 79: return "vilegard_tavern"; + case 80: return "vilegard_armorer"; + case 81: return "vilegard_smith"; + case 82: return "vilegard_wrye"; + case 83: return "vilegard_kaori"; + case 84: return "vilegard_erttu"; + case 85: return "road2"; + case 86: return "road3"; + case 87: return "road4"; + case 88: return "road4_gargoylecave"; + case 89: return "road5"; + case 90: return "road5_house"; + case 91: return "gargoylecave1"; + case 92: return "gargoylecave2"; + case 93: return "gargoylecave3"; + case 94: return "gargoylecave4"; + case 95: return "blackwater_mountain0"; + case 96: return "blackwater_mountain1"; + case 97: return "blackwater_mountain2"; + case 98: return "blackwater_mountain3"; + case 99: return "blackwater_mountain4"; + case 100: return "blackwater_mountain5"; + case 101: return "blackwater_mountain6"; + case 102: return "blackwater_mountain7"; + case 103: return "blackwater_mountain8"; + case 104: return "blackwater_mountain9"; + case 105: return "blackwater_mountain10"; + case 106: return "blackwater_mountain11"; + case 107: return "blackwater_mountain12"; + case 108: return "blackwater_mountain13"; + case 109: return "blackwater_mountain14"; + case 110: return "blackwater_mountain15"; + case 111: return "blackwater_mountain16"; + case 112: return "blackwater_mountain17"; + case 113: return "blackwater_mountain18"; + case 114: return "blackwater_mountain19"; + case 115: return "blackwater_mountain20"; + case 116: return "blackwater_mountain21"; + case 117: return "blackwater_mountain22"; + case 118: return "blackwater_mountain23"; + case 119: return "blackwater_mountain24"; + case 120: return "blackwater_mountain25"; + case 121: return "blackwater_mountain26"; + case 122: return "blackwater_mountain27"; + case 123: return "blackwater_mountain28"; + case 124: return "blackwater_mountain29"; + case 125: return "blackwater_mountain30"; + case 126: return "blackwater_mountain31"; + case 127: return "blackwater_mountain32"; + case 128: return "blackwater_mountain33"; + case 129: return "blackwater_mountain34"; + case 130: return "blackwater_mountain35"; + case 131: return "blackwater_mountain36"; + case 132: return "blackwater_mountain37"; + case 133: return "blackwater_mountain38"; + case 134: return "blackwater_mountain39"; + case 135: return "blackwater_mountain40"; + case 136: return "blackwater_mountain41"; + case 137: return "blackwater_mountain42"; + case 138: return "blackwater_mountain43"; + case 139: return "blackwater_mountain44"; + case 140: return "blackwater_mountain45"; + case 141: return "blackwater_mountain46"; + case 142: return "blackwater_mountain47"; + case 143: return "blackwater_mountain48"; + case 144: return "blackwater_mountain49"; + case 145: return "blackwater_mountain50"; + case 146: return "blackwater_mountain51"; + case 147: return "blackwater_mountain52"; + case 148: return "wild0"; + case 149: return "crossroads"; + case 150: return "fields0"; + case 151: return "fields1"; + case 152: return "fields2"; + case 153: return "fields3"; + case 154: return "fields4"; + case 155: return "fields5"; + case 156: return "fields6"; + case 157: return "fields7"; + case 158: return "fields8"; + case 159: return "fields9"; + case 160: return "fields10"; + case 161: return "fields11"; + case 162: return "fields12"; + case 163: return "houseatcrossroads0"; + case 164: return "houseatcrossroads1"; + case 165: return "houseatcrossroads2"; + case 166: return "houseatcrossroads3"; + case 167: return "houseatcrossroads4"; + case 168: return "houseatcrossroads5"; + case 169: return "loneford1"; + case 170: return "loneford2"; + case 171: return "loneford3"; + case 172: return "loneford4"; + case 173: return "loneford5"; + case 174: return "loneford6"; + case 175: return "loneford7"; + case 176: return "loneford8"; + case 177: return "loneford9"; + case 178: return "loneford10"; + case 179: return "roadbeforecrossroads"; + case 180: return "roadtocarntower0"; + case 181: return "roadtocarntower1"; + case 182: return "roadtocarntower2"; + case 183: return "woodcave0"; + case 184: return "woodcave1"; + case 185: return "wild16"; + case 186: return "wild17"; + case 187: return "gapfiller1"; + case 188: return "gapfiller3"; + case 189: return "gapfiller4"; + case 190: return "waterway0"; + case 191: return "waterway1"; + case 192: return "waterway2"; + case 193: return "waterway3"; + case 194: return "waterwayhouse"; + case 195: return "waterwayextention"; + case 196: return "pwcave0"; + case 197: return "pwcave1"; + case 198: return "pwcave2"; + case 199: return "pwcave2a"; + case 200: return "pwcave3"; + case 201: return "pwcave4"; + case 202: return "waterway4"; + case 203: return "waterway5"; + case 204: return "waterway6"; + case 205: return "waterway7"; + case 206: return "waterway8"; + case 207: return "waterway9"; + case 208: return "waterway10"; + case 209: return "waterway11_east"; + case 210: return "waterway11"; + case 211: return "waterway12"; + case 212: return "waterway13"; + case 213: return "waterway14"; + case 214: return "waterway15"; + case 215: return "waterwaycave"; + case 216: return "mountaincave0"; + case 217: return "mountaincave1"; + case 218: return "mountaincave2"; + case 219: return "mountaincave3"; + case 220: return "mountainlake0"; + case 221: return "mountainlake1"; + case 222: return "mountainlake2"; + case 223: return "mountainlake3"; + case 224: return "mountainlake4"; + case 225: return "mountainlake5"; + case 226: return "mountainlake6"; + case 227: return "mountainlake7"; + case 228: return "mountainlake8"; + case 229: return "mountainlake9"; + case 230: return "mountainlake10"; + case 231: return "mountainlake10a"; + case 232: return "mountainlake11"; + case 233: return "mountainlake12"; + case 234: return "mountainlake13"; + case 235: return "mountainlake13a"; + case 236: return "remgard0"; + case 237: return "remgard1"; + case 238: return "remgard2"; + case 239: return "remgard3"; + case 240: return "remgard4"; + case 241: return "remgard_armour"; + case 242: return "remgard_barn"; + case 243: return "remgard_church"; + case 244: return "remgard_clothes"; + case 245: return "remgard_farmer1"; + case 246: return "remgard_farmer2"; + case 247: return "remgard_farmer3"; + case 248: return "remgard_prison"; + case 249: return "remgard_school"; + case 250: return "remgard_tavern0"; + case 251: return "remgard_tavern1"; + case 252: return "remgard_villager1"; + case 253: return "remgard_villager2"; + case 254: return "remgard_villager3"; + case 255: return "remgard_villager4"; + case 256: return "remgard_villager5"; + case 257: return "remgard_weapon"; + case 258: return "waytobrimhaven0"; + case 259: return "waytobrimhaven1"; + case 260: return "waytobrimhaven2"; + case 261: return "waytobrimhaven3"; + case 262: return "waytobrimhavencave0"; + case 263: return "waytobrimhavencave1a"; + case 264: return "waytobrimhavencave1"; + case 265: return "waytobrimhavencave2"; + case 266: return "waytobrimhavencave3a"; + case 267: return "waytobrimhavencave3b"; + case 268: return "waytobrimhavencave3"; + case 269: return "waytobrimhavencave4"; + case 270: return "waytolake0"; + case 271: return "waytolake1"; + case 272: return "waytolake2"; + case 273: return "waytolake3"; + case 274: return "waytolake4"; + case 275: return "waytolake5"; + case 276: return "waytomountaincave0"; + case 277: return "waytomountaincave1"; + case 278: return "waytomountaincave2"; + case 279: return "lonelyhouse0"; + case 280: return "lonelyhouse1"; + case 281: return "wild16_cave"; + case 282: return "gapfiller2"; + } + return null; + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/Savegames.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/Savegames.java index 38152e3ed..d6e178a22 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/Savegames.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/Savegames.java @@ -105,7 +105,7 @@ public final class Savegames { DataOutputStream dest = new DataOutputStream(outStream); final int flags = 0; FileHeader.writeToParcel(dest, world.model.player.getName(), displayInfo); - world.maps.writeToParcel(dest, flags); + world.maps.writeToParcel(dest, world, flags); world.model.writeToParcel(dest, flags); dest.close(); }