From 51883dbdf54f4b52608a3dedbcac22d1352e78bf Mon Sep 17 00:00:00 2001 From: Oskar Wiksten Date: Fri, 20 Jul 2012 14:36:17 +0000 Subject: [PATCH] WIP on displaying an actual worldmap in-game. --- AndorsTrail/AndroidManifest.xml | 1 + AndorsTrail/res/layout/displayworldmap.xml | 9 + AndorsTrail/res/values/strings.xml | 2 + AndorsTrail/res/values/worldmap_template.xml | 39 ++ AndorsTrail/res/xml/worldmap.xml | 378 ++++++++++++++++++ .../activity/DisplayWorldMapActivity.java | 65 +++ .../AndorsTrail/activity/MainActivity.java | 9 + .../controller/MovementController.java | 2 +- .../controller/WorldMapController.java | 139 ++++++- .../AndorsTrail/model/map/PredefinedMap.java | 13 +- .../model/map/TMXMapFileParser.java | 21 +- .../model/map/TMXMapTranslator.java | 8 +- .../AndorsTrail/resource/ResourceLoader.java | 9 + .../resource/parsers/WorldMapParser.java | 36 ++ 14 files changed, 699 insertions(+), 32 deletions(-) create mode 100644 AndorsTrail/res/layout/displayworldmap.xml create mode 100644 AndorsTrail/res/values/worldmap_template.xml create mode 100644 AndorsTrail/res/xml/worldmap.xml create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java diff --git a/AndorsTrail/AndroidManifest.xml b/AndorsTrail/AndroidManifest.xml index 6887dbf..dc3f10d 100644 --- a/AndorsTrail/AndroidManifest.xml +++ b/AndorsTrail/AndroidManifest.xml @@ -62,6 +62,7 @@ + diff --git a/AndorsTrail/res/layout/displayworldmap.xml b/AndorsTrail/res/layout/displayworldmap.xml new file mode 100644 index 0000000..f796009 --- /dev/null +++ b/AndorsTrail/res/layout/displayworldmap.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/AndorsTrail/res/values/strings.xml b/AndorsTrail/res/values/strings.xml index 1fcb53d..4d0a2ad 100644 --- a/AndorsTrail/res/values/strings.xml +++ b/AndorsTrail/res/values/strings.xml @@ -504,5 +504,7 @@ When making an attack on a target whose block chance (BC) is at least %1$d lower than your attack chance (AC), there is a %2$d %% chance that the hit will cause a concussion on the target. A concussion will severely lower the target\'s offensive combat abilities, making the target less able to land successful attacks. About + Map + Map cannot be displayed. diff --git a/AndorsTrail/res/values/worldmap_template.xml b/AndorsTrail/res/values/worldmap_template.xml new file mode 100644 index 0000000..d4bdbd7 --- /dev/null +++ b/AndorsTrail/res/values/worldmap_template.xml @@ -0,0 +1,39 @@ + + +" + + + + + + + + +
+ +{{maps}} + +
x
+
+ + + + + + +]]>
diff --git a/AndorsTrail/res/xml/worldmap.xml b/AndorsTrail/res/xml/worldmap.xml new file mode 100644 index 0000000..bd6bb9f --- /dev/null +++ b/AndorsTrail/res/xml/worldmap.xml @@ -0,0 +1,378 @@ + + +
pwcave4
+
waytobrimhaven2
+
waytobrimhaven3
+
waytobrimhaven0
+
waytobrimhaven1
+
roadtocarntower1
+
roadtocarntower0
+
woodsettlement0
+
fallhaven_arcir_basement
+
roadtocarntower2
+
lodarcave7
+
lodarcave5
+
lodarcave6
+
lodarcave3
+
lodarcave4
+
lodarcave1
+
lodarcave2
+
fields9
+
lodarcave0
+
waterway9
+
fields6
+
waterway8
+
fields5
+
fields8
+
crossglen_cave
+
fields7
+
fields2
+
fields1
+
fields4
+
fields3
+
fields0
+
wild14_clearing
+
blackwater_mountain7
+
lodarhouse1
+
blackwater_mountain6
+
lodarhouse0
+
blackwater_mountain5
+
mountainlake10a
+
blackwater_mountain4
+
blackwater_mountain9
+
blackwater_mountain8
+
crossglen_farmhouse
+
fallhaven_storage
+
pwcave2
+
pwcave3
+
pwcave0
+
pwcave1
+
wild16_cave
+
lodarcave4a
+
wild3
+
wild2
+
wild5
+
wild4
+
wild7
+
wild6
+
remgard_weapon
+
wild9
+
clearing_level2
+
wild8
+
clearing_level1
+
blackwater_mountain0
+
blackwater_mountain1
+
blackwater_mountain2
+
blackwater_mountain3
+
vilegard_erttu
+
flagstone_upper
+
wild1
+
wild0
+
wild17
+
wild15
+
mountainlake13a
+
wild16
+
wild13
+
flagstone0
+
wild14
+
wild11
+
wild12
+
wild10
+
waterway6
+
waterway7
+
waterway4
+
waterway5
+
flagstone1
+
waterway2
+
flagstone2
+
loneford10
+
waterway3
+
woodhouse3
+
waterway0
+
lodar8cave0
+
flagstone3
+
waterway1
+
flagstone4
+
road4_gargoylecave
+
fallhaven_prison
+
lonelyhouse1
+
lonelyhouse0
+
minerhouse0
+
waytobrimhavencave3b
+
remgard_villager4
+
minerhouse4
+
remgard_villager3
+
minerhouse3
+
minerhouse2
+
minerhouse1
+
remgard_villager5
+
minerhouse8
+
fallhaven_nocmar
+
minerhouse7
+
remgard_villager2
+
minerhouse6
+
remgard_villager1
+
minerhouse5
+
waytobrimhavencave3a
+
lodar12cave0
+
crossglen_hall
+
lodar12cave1
+
vilegard_ogam
+
minerhouse9
+
fallhaven_church
+
vilegard_chapel
+
remgard_clothes
+
foaming_flask
+
remgard_tavern1
+
roadcave0
+
roadcave1
+
vilegard_sw
+
lostmine3
+
lostmine4
+
lostmine5
+
lostmine6
+
gapfiller1
+
gapfiller3
+
lostmine0
+
lostmine1
+
gapfiller4
+
lostmine2
+
waytolake0
+
lostmine9
+
fallhaven_farmer
+
vilegard_n
+
lostmine8
+
lostmine7
+
waytolostmine0
+
waytolake5
+
waytolake3
+
waytolake4
+
vilegard_s
+
waytolake1
+
waytolake2
+
road5_house
+
waytolostmine2
+
waytolostmine1
+
waytolostmine3
+
waytobrimhavencave1a
+
lostmine10
+
lostmine11
+
fallhaven_potions
+
remgard_armour
+
mountainlake13
+
mountainlake12
+
mountainlake11
+
loneford4
+
mountainlake10
+
loneford3
+
loneford2
+
loneford1
+
mountaincave3
+
mountaincave2
+
crossglen_farmhouse_basement
+
mountaincave1
+
mountaincave0
+
crossglen
+
fallhaven_clothes
+
loneford5
+
hauntedhouse2
+
loneford6
+
hauntedhouse1
+
loneford7
+
loneford8
+
loneford9
+
fallhaven_tavern
+
hauntedhouse4
+
hauntedhouse3
+
road1
+
road3
+
road2
+
road5
+
road4
+
jan_pitcave1
+
lodar5cave1
+
lodar5cave0
+
lodar21
+
jan_pitcave3
+
lodar5cave2
+
jan_pitcave2
+
fallhaven_gravedigger
+
lodar20
+
waterwayhouse
+
fallhaven_rigmor
+
waytominingtown1a
+
lostmine2a
+
wild6_house
+
lodar8
+
lodar9
+
lodar6
+
lodar7
+
lodar4
+
lodar5
+
lodar2
+
lodar3
+
lodar10
+
lodar12
+
lodar11
+
lodar14
+
lodar13
+
lodar16
+
lodar15
+
lodar18
+
woodcave1
+
lodar17
+
woodcave0
+
lostmine1a
+
lodar19
+
fallhaven_nw
+
waterway12
+
waterway11
+
waterway14
+
waterway13
+
waterway15
+
fallhaven_derelict
+
vilegard_armorer
+
remgard_school
+
remgard_farmer2
+
remgard_farmer3
+
waterway11_east
+
fallhaven_ne
+
remgard_farmer1
+
waterway10
+
oldcave0
+
oldcave1
+
home
+
roadbeforecrossroads
+
roadbeforecrossroads8
+
roadbeforecrossroads9
+
roadbeforecrossroads6
+
roadbeforecrossroads7
+
roadbeforecrossroads4
+
roadbeforecrossroads5
+
roadbeforecrossroads2
+
roadbeforecrossroads3
+
lodar1cave0
+
fallhaven_alaun
+
remgard_barn
+
lodar1
+
lodar0
+
remgard_tavern0
+
vilegard_wrye
+
waytomountaincave1
+
waytomountaincave0
+
waytomountaincave2
+
remgard_church
+
houseatcrossroads2
+
blackwater_mountain39
+
houseatcrossroads3
+
wild11_clearing
+
fallhaven_sw
+
blackwater_mountain37
+
houseatcrossroads4
+
waytobrimhavencave0
+
houseatcrossroads5
+
waterwayextention
+
blackwater_mountain38
+
waytominingtown0
+
mountainlake3
+
waytobrimhavencave1
+
mountainlake2
+
waytominingtown1
+
waytobrimhavencave2
+
mountainlake1
+
houseatcrossroads0
+
waytobrimhavencave3
+
waytominingtown2
+
mountainlake0
+
houseatcrossroads1
+
waytominingtown3
+
waytobrimhavencave4
+
blackwater_mountain31
+
mountainlake7
+
blackwater_mountain51
+
blackwater_mountain32
+
blackwater_mountain52
+
mountainlake6
+
mountainlake5
+
mountainlake4
+
blackwater_mountain30
+
fallhaven_lumberjack
+
blackwater_mountain35
+
blackwater_mountain36
+
mountainlake9
+
blackwater_mountain33
+
blackwater_mountain34
+
mountainlake8
+
blackwater_mountain50
+
woodhouse0
+
woodhouse2
+
woodhouse1
+
fallhaven_se
+
fields10
+
blackwater_mountain48
+
blackwater_mountain49
+
fields11
+
fallhaven_barn
+
fields12
+
vilegard_tavern
+
roadbeforecrossroads1
+
fallhaven_athamyr
+
blackwater_mountain40
+
blackwater_mountain41
+
blackwater_mountain42
+
blackwater_mountain43
+
blackwater_mountain44
+
blackwater_mountain45
+
blackwater_mountain46
+
blackwater_mountain47
+
crossglen_smith
+
pwcave2a
+
blackwater_mountain19
+
blackwater_mountain17
+
snakecave2
+
snakecave1
+
blackwater_mountain18
+
blackwater_mountain15
+
snakecave3
+
blackwater_mountain16
+
blackwater_mountain13
+
blackwater_mountain14
+
blackwater_mountain11
+
blackwater_mountain12
+
blackwater_mountain10
+
flagstone_inner
+
fallhaven_derelict2
+
vilegard_kaori
+
fallhaven_arcir
+
remgard_prison
+
catacombs1
+
catacombs2
+
vilegard_smith
+
waterwaycave
+
blackwater_mountain26
+
blackwater_mountain27
+
blackwater_mountain28
+
wild15_house
+
catacombs3
+
catacombs4
+
blackwater_mountain29
+
blackwater_mountain22
+
blackwater_mountain23
+
gargoylecave3
+
remgard1
+
blackwater_mountain24
+
remgard0
+
gargoylecave4
+
blackwater_mountain25
+
remgard3
+
gargoylecave1
+
remgard2
+
gargoylecave2
+
blackwater_mountain20
+
remgard4
+
blackwater_mountain21
+
wild14_cave
+
tradehouse0
+
tradehouse1
+
crossroads
+
\ No newline at end of file diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java new file mode 100644 index 0000000..b94f4e1 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java @@ -0,0 +1,65 @@ +package com.gpl.rpg.AndorsTrail.activity; + +import java.io.File; + +import android.app.Activity; +import android.os.Bundle; +import android.webkit.WebView; +import android.widget.Toast; + +import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; +import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.WorldMapController; +import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.L; + +public class DisplayWorldMapActivity extends Activity { + private WorldContext world; + + private WebView displayworldmap_webview; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); + if (!app.isInitialized()) { finish(); return; } + this.world = app.world; + + AndorsTrailApplication.setWindowParameters(this, app.preferences); + + setContentView(R.layout.displayworldmap); + + displayworldmap_webview = (WebView) findViewById(R.id.displayworldmap_webview); + displayworldmap_webview.setBackgroundColor(getResources().getColor(android.R.color.black)); + displayworldmap_webview.getSettings().setBuiltInZoomControls(true); + displayworldmap_webview.getSettings().setJavaScriptEnabled(true); + } + + @Override + public void onResume() { + super.onResume(); + update(); + } + + private void update() { + File worldmap = WorldMapController.getCombinedWorldMapFile(); + + if (!worldmap.exists()) { + Toast.makeText(this, getResources().getString(R.string.menu_button_worldmap_failed), Toast.LENGTH_LONG).show(); + this.finish(); + } + + String url = "file://" + worldmap.getAbsolutePath(); + Coord playerWorldPosition = WorldMapController.getPlayerWorldPosition(world); + if (playerWorldPosition != null) { + url += "?" + + playerWorldPosition.x * WorldMapController.WORLDMAP_DISPLAY_TILESIZE + + "," + + (playerWorldPosition.y-1) * WorldMapController.WORLDMAP_DISPLAY_TILESIZE; + } + L.log("Showing " + url); + displayworldmap_webview.loadUrl(url); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index badc06f..18d7d00 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -210,6 +210,15 @@ public final class MainActivity extends Activity { return true; } }); + menu.add(R.string.menu_button_worldmap) + .setIcon(android.R.drawable.ic_menu_mapmode) + .setOnMenuItemClickListener(new OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem arg0) { + startActivity(new Intent(MainActivity.this, DisplayWorldMapActivity.class)); + return true; + } + }); return true; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java index bd6dee1..dce246d 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java @@ -277,7 +277,7 @@ public final class MovementController implements TimedMessageTask.Callback { world.tileManager.currentMapTiles = cachedTiles; world.tileManager.cacheAdjacentMaps(res, world, nextMap); - WorldMapController.updateWorldMap(world, nextMap, mapTiles, cachedTiles); + WorldMapController.updateWorldMap(world, nextMap, mapTiles, cachedTiles, res); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/WorldMapController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/WorldMapController.java index 58f6517..eeeecf6 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/WorldMapController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/WorldMapController.java @@ -3,7 +3,9 @@ package com.gpl.rpg.AndorsTrail.controller; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.PrintWriter; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; @@ -11,44 +13,79 @@ import android.graphics.Paint; import android.os.AsyncTask; import android.os.Environment; +import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; +import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap; import com.gpl.rpg.AndorsTrail.model.map.MapLayer; import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection; +import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.L; public final class WorldMapController { - public static void updateWorldMap(final WorldContext world, final PredefinedMap map, final LayeredTileMap mapTiles, final TileCollection cachedTiles) { + + public static int WORLDMAP_SCREENSHOT_TILESIZE = 12; + public static int WORLDMAP_DISPLAY_TILESIZE = WORLDMAP_SCREENSHOT_TILESIZE; + + public static void updateWorldMap(final WorldContext world, final PredefinedMap map, final LayeredTileMap mapTiles, final TileCollection cachedTiles, final Resources res) { + + if (!shouldUpdateWorldMap(map)) return; + (new AsyncTask() { @Override protected Void doInBackground(Void... arg0) { - - File file = getFileForMap(map); - if (file.exists()) return null; - - try { - Bitmap image = new MapRenderer(world, map, mapTiles, cachedTiles).drawMap(); - ensureWorldmapDirectoryExists(); - FileOutputStream fos = new FileOutputStream(file); - image.compress(Bitmap.CompressFormat.PNG, 70, fos); - fos.flush(); - fos.close(); - image.recycle(); - } catch (IOException e) { - L.log("Error creating worldmap file for map " + map.name + " : " + e.toString()); - } + final MapRenderer renderer = new MapRenderer(world, map, mapTiles, cachedTiles); + updateCachedBitmap(map, renderer); + try { + updateCombinedWorldMap(res, world); + } catch (IOException e) {} return null; } }).execute(); } + + private static boolean isVisibleOnWorldMap(PredefinedMap map) { + return map.isOutdoors; + } + + private static boolean shouldUpdateWorldMap(PredefinedMap map) { + if (!isVisibleOnWorldMap(map)) return false; + if (!map.visited) return true; + File file = getFileForMap(map); + if (!file.exists()) return true; + + if (map.lastVisitVersion < AndorsTrailApplication.CURRENT_VERSION) return true; + + file = getCombinedWorldMapFile(); + if (!file.exists()) return true; + + return false; + } + + private static void updateCachedBitmap(PredefinedMap map, MapRenderer renderer) { + + File file = getFileForMap(map); + if (file.exists()) return; + + try { + Bitmap image = renderer.drawMap(); + ensureWorldmapDirectoryExists(); + FileOutputStream fos = new FileOutputStream(file); + image.compress(Bitmap.CompressFormat.PNG, 70, fos); + fos.flush(); + fos.close(); + image.recycle(); + } catch (IOException e) { + L.log("Error creating worldmap file for map " + map.name + " : " + e.toString()); + } + } private static final class MapRenderer { private final PredefinedMap map; private final LayeredTileMap mapTiles; private final TileCollection cachedTiles; private final int tileSize; - private static final int outputTileSize = 16; private final float scale; private final Paint mPaint = new Paint(); @@ -57,12 +94,11 @@ public final class WorldMapController { this.mapTiles = mapTiles; this.cachedTiles = cachedTiles; this.tileSize = world.tileManager.tileSize; - this.scale = (float) outputTileSize / world.tileManager.tileSize; - L.log("outputTileSize=" + outputTileSize + ", tileSize=" + tileSize + ", scale=" + scale); + this.scale = (float) WORLDMAP_SCREENSHOT_TILESIZE / world.tileManager.tileSize; } public Bitmap drawMap() { - Bitmap image = Bitmap.createBitmap(map.size.width * outputTileSize, map.size.height * outputTileSize, Config.RGB_565); + Bitmap image = Bitmap.createBitmap(map.size.width * WORLDMAP_SCREENSHOT_TILESIZE, map.size.height * WORLDMAP_SCREENSHOT_TILESIZE, Config.RGB_565); image.setDensity(Bitmap.DENSITY_NONE); Canvas canvas = new Canvas(image); canvas.scale(scale, scale); @@ -99,13 +135,72 @@ public final class WorldMapController { dir = new File(dir, Constants.FILENAME_WORLDMAP_DIRECTORY); if (!dir.exists()) dir.mkdir(); } - private static File getFileForMap(PredefinedMap map) { + public static File getFileForMap(PredefinedMap map) { File root = getWorldmapDirectory(); return new File(root, map.name + ".png"); } - private static File getWorldmapDirectory() { + public static File getWorldmapDirectory() { File dir = Environment.getExternalStorageDirectory(); dir = new File(dir, Constants.FILENAME_SAVEGAME_DIRECTORY); return new File(dir, Constants.FILENAME_WORLDMAP_DIRECTORY); } + public static File getCombinedWorldMapFile() { + return new File(getWorldmapDirectory(), Constants.FILENAME_WORLDMAP_HTMLFILE); + } + + private static String getCombinedWorldMapAsHtml(Resources res, WorldContext world) throws IOException { + StringBuffer sb = new StringBuffer(); + + Coord offsetWorldmapTo = new Coord(999999, 999999); + for (PredefinedMap map : world.maps.predefinedMaps) { + File f = WorldMapController.getFileForMap(map); + if (!f.exists()) continue; + + offsetWorldmapTo.x = Math.min(offsetWorldmapTo.x, map.worldMapPosition.x); + offsetWorldmapTo.y = Math.min(offsetWorldmapTo.y, map.worldMapPosition.y); + } + + for (PredefinedMap map : world.maps.predefinedMaps) { + File f = WorldMapController.getFileForMap(map); + if (!f.exists()) continue; + + sb + .append(""); + } + + return res.getString(R.string.worldmap_template) + .replace("{{maps}}", sb.toString()) + .replace("{{offsetx}}", Integer.toString(offsetWorldmapTo.x * WorldMapController.WORLDMAP_DISPLAY_TILESIZE)) + .replace("{{offsety}}", Integer.toString(offsetWorldmapTo.y * WorldMapController.WORLDMAP_DISPLAY_TILESIZE)); + } + + private static void updateCombinedWorldMap(Resources res, WorldContext world) throws IOException { + String mapAsHtml = getCombinedWorldMapAsHtml(res, world); + File outputFile = new File(WorldMapController.getWorldmapDirectory(), Constants.FILENAME_WORLDMAP_HTMLFILE); + PrintWriter pw = new PrintWriter(outputFile); + pw.write(mapAsHtml); + pw.close(); + } + + public static Coord getPlayerWorldPosition(WorldContext world) { + PredefinedMap map = world.model.currentMap; + if (!isVisibleOnWorldMap(map)) return null; + + return new Coord( + world.model.player.position.x + map.worldMapPosition.x, + world.model.player.position.y + map.worldMapPosition.y + ); + } } 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 7190746..eb2d0b6 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java @@ -24,16 +24,19 @@ public final class PredefinedMap { public final int xmlResourceId; public final String name; public final Size size; + public final Coord worldMapPosition = new Coord(); public final MapObject[] eventObjects; public final MonsterSpawnArea[] spawnAreas; public final ArrayList groundBags = new ArrayList(); public boolean visited = false; public long lastVisitTime = VISIT_RESET; + public int lastVisitVersion = 0; + public final boolean isOutdoors; public final boolean[][] isWalkable; public final ArrayList splatters = new ArrayList(); - public PredefinedMap(int xmlResourceId, String name, Size size, boolean[][] isWalkable, MapObject[] eventObjects, MonsterSpawnArea[] spawnAreas, boolean hasFOW) { + public PredefinedMap(int xmlResourceId, String name, Size size, boolean[][] isWalkable, MapObject[] eventObjects, MonsterSpawnArea[] spawnAreas, boolean hasFOW, boolean isOutdoors) { this.xmlResourceId = xmlResourceId; this.name = name; this.size = size; @@ -44,6 +47,7 @@ public final class PredefinedMap { assert(isWalkable.length == size.width); assert(isWalkable[0].length == size.height); this.isWalkable = isWalkable; + this.isOutdoors = isOutdoors; } public final boolean isWalkable(final Coord p) { @@ -224,6 +228,7 @@ public final class PredefinedMap { } public void updateLastVisitTime() { lastVisitTime = System.currentTimeMillis(); + lastVisitVersion = AndorsTrailApplication.CURRENT_VERSION; } public void resetTemporaryData() { for(MonsterSpawnArea a : spawnAreas) { @@ -277,6 +282,11 @@ public final class PredefinedMap { } lastVisitTime = src.readLong(); + if (visited) { + if (fileversion <= 30) lastVisitVersion = 30; + else lastVisitVersion = src.readInt(); + } + for(int i = loadedSpawnAreas; i < spawnAreas.length; ++i) { MonsterSpawnArea area = this.spawnAreas[i]; if (area.isUnique && visited) spawnAllInArea(world, area, true); @@ -295,5 +305,6 @@ public final class PredefinedMap { } dest.writeBoolean(visited); dest.writeLong(lastVisitTime); + if (visited) dest.writeInt(lastVisitVersion); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapFileParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapFileParser.java index 2b309cc..7633119 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapFileParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapFileParser.java @@ -49,6 +49,8 @@ public final class TMXMapFileParser { map.objectGroups.add(readTMXObjectGroup(xrp)); } else if (tagName.equals("layer")) { layers.add(readTMXMapLayer(xrp)); + } else if (tagName.equals("property")) { + map.properties.add(readTMXProperty(xrp)); } } }); @@ -147,12 +149,9 @@ public final class TMXMapFileParser { object.width = xrp.getAttributeIntValue(null, "width", -1); object.height = xrp.getAttributeIntValue(null, "height", -1); readCurrentTagUntilEnd(xrp, new TagHandler() { - public void handleTag(XmlResourceParser xrp, String tagName) { + public void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException { if (tagName.equals("property")) { - final TMXProperty property = new TMXProperty(); - object.properties.add(property); - property.name = xrp.getAttributeValue(null, "name"); - property.value = xrp.getAttributeValue(null, "value"); + object.properties.add(readTMXProperty(xrp)); } } }); @@ -209,6 +208,13 @@ public final class TMXMapFileParser { } } + private static TMXProperty readTMXProperty(XmlResourceParser xrp) throws XmlPullParserException, IOException { + final TMXProperty property = new TMXProperty(); + property.name = xrp.getAttributeValue(null, "name"); + property.value = xrp.getAttributeValue(null, "value"); + return property; + } + private static void copyStreamToBuffer(InflaterInputStream zi, byte[] buffer, int len) throws IOException { int offset = 0; int bytesToRead = len; @@ -270,6 +276,7 @@ public final class TMXMapFileParser { public int height; public TMXTileSet[] tileSets; public TMXLayer[] layers; + public final ArrayList properties = new ArrayList(); } public static final class TMXTileSet { public int firstgid; @@ -289,7 +296,7 @@ public final class TMXMapFileParser { public String name; public int width; public int height; - public ArrayList objects = new ArrayList(); + public final ArrayList objects = new ArrayList(); } public static final class TMXObject { public String name; @@ -298,7 +305,7 @@ public final class TMXMapFileParser { public int y; public int width; public int height; - public ArrayList properties = new ArrayList(); + public final ArrayList properties = new ArrayList(); } public static final class TMXProperty { public String name; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java index 62c82db..e965157 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java @@ -52,6 +52,12 @@ public final class TMXMapTranslator { assert(m.width > 0); assert(m.height > 0); + boolean isOutdoors = false; + for (TMXProperty p : m.properties) { + if(p.name.equalsIgnoreCase("outside")) isOutdoors = (Integer.parseInt(p.value) != 0); + else if(AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("OPTIMIZE: Map " + m.name + " has unrecognized property \"" + p.name + "\"."); + } + boolean[][] isWalkable = new boolean[m.width][m.height]; for (int y = 0; y < m.height; ++y) { for (int x = 0; x < m.width; ++x) { @@ -186,7 +192,7 @@ public final class TMXMapTranslator { MonsterSpawnArea[] _spawnAreas = new MonsterSpawnArea[spawnAreas.size()]; _spawnAreas = spawnAreas.toArray(_spawnAreas); - result.add(new PredefinedMap(m.xmlResourceId, m.name, mapSize, isWalkable, _eventObjects, _spawnAreas, false)); + result.add(new PredefinedMap(m.xmlResourceId, m.name, mapSize, isWalkable, _eventObjects, _spawnAreas, false, isOutdoors)); } return result; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java index a96d825..fb4dc67 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java @@ -13,6 +13,7 @@ import com.gpl.rpg.AndorsTrail.resource.parsers.DropListParser; import com.gpl.rpg.AndorsTrail.resource.parsers.ItemTypeParser; import com.gpl.rpg.AndorsTrail.resource.parsers.MonsterTypeParser; import com.gpl.rpg.AndorsTrail.resource.parsers.QuestParser; +import com.gpl.rpg.AndorsTrail.resource.parsers.WorldMapParser; import com.gpl.rpg.AndorsTrail.util.L; import com.gpl.rpg.AndorsTrail.util.Size; @@ -163,6 +164,14 @@ public final class ResourceLoader { if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("DynamicTileLoader"); // ======================================================================== + + // ======================================================================== + // Load worldmap coordinates + WorldMapParser.read(r, R.xml.worldmap, world.maps); + if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("WorldMapParser"); + // ======================================================================== + + if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) { long duration = System.currentTimeMillis() - start; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java new file mode 100644 index 0000000..24ea1ec --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java @@ -0,0 +1,36 @@ +package com.gpl.rpg.AndorsTrail.resource.parsers; + +import android.content.res.Resources; +import android.content.res.XmlResourceParser; + +import com.gpl.rpg.AndorsTrail.model.map.MapCollection; +import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; +import com.gpl.rpg.AndorsTrail.util.L; + +public final class WorldMapParser { + public static void read(Resources r, int xmlResourceId, final MapCollection maps) { + read(r.getXml(xmlResourceId), maps); + } + + private static void read(XmlResourceParser xrp, final MapCollection maps) { + try { + int eventType; + while ((eventType = xrp.next()) != XmlResourceParser.END_DOCUMENT) { + if (eventType == XmlResourceParser.START_TAG) { + String s = xrp.getName(); + if (s.equals("div")) { + String mapName = xrp.getAttributeValue(null, "id"); + PredefinedMap map = maps.findPredefinedMap(mapName); + if (map == null) continue; + map.worldMapPosition.x = xrp.getAttributeIntValue(null, "x-posx", -1); + map.worldMapPosition.y = xrp.getAttributeIntValue(null, "x-posy", -1); + } + } + } + xrp.close(); + } catch (Exception e) { + L.log("Error reading worldmap: " + e.toString()); + } + } + +} -- 2.49.0