diff --git a/AndorsTrail/AndroidManifest.xml b/AndorsTrail/AndroidManifest.xml index 6887dbfd9..dc3f10d77 100644 --- a/AndorsTrail/AndroidManifest.xml +++ b/AndorsTrail/AndroidManifest.xml @@ -62,6 +62,7 @@ + diff --git a/AndorsTrail/res/anim/hidetoolbox.xml b/AndorsTrail/res/anim/hidetoolbox.xml new file mode 100644 index 000000000..7ef0eee89 --- /dev/null +++ b/AndorsTrail/res/anim/hidetoolbox.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/AndorsTrail/res/anim/showtoolbox.xml b/AndorsTrail/res/anim/showtoolbox.xml new file mode 100644 index 000000000..f77856fb3 --- /dev/null +++ b/AndorsTrail/res/anim/showtoolbox.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/AndorsTrail/res/drawable/ui_icon_map.png b/AndorsTrail/res/drawable/ui_icon_map.png new file mode 100644 index 000000000..b49bbce3e Binary files /dev/null and b/AndorsTrail/res/drawable/ui_icon_map.png differ diff --git a/AndorsTrail/res/layout/displayworldmap.xml b/AndorsTrail/res/layout/displayworldmap.xml new file mode 100644 index 000000000..ea42a9203 --- /dev/null +++ b/AndorsTrail/res/layout/displayworldmap.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + diff --git a/AndorsTrail/res/layout/main.xml b/AndorsTrail/res/layout/main.xml index 9be5d0193..feb25065f 100644 --- a/AndorsTrail/res/layout/main.xml +++ b/AndorsTrail/res/layout/main.xml @@ -27,6 +27,15 @@ android:layout_alignParentTop="true" android:visibility="gone" /> + + + + + + + diff --git a/AndorsTrail/res/values/strings.xml b/AndorsTrail/res/values/strings.xml index c8a2de429..067a55646 100644 --- a/AndorsTrail/res/values/strings.xml +++ b/AndorsTrail/res/values/strings.xml @@ -507,5 +507,9 @@ Interface Enable animations Show animations for various interface elements, such as the combat bar. + Map + Map cannot be displayed. + The map cannot be displayed from this location. + Map diff --git a/AndorsTrail/res/values/ui_colors.xml b/AndorsTrail/res/values/ui_colors.xml index 5df4b03a2..7caaee8cf 100644 --- a/AndorsTrail/res/values/ui_colors.xml +++ b/AndorsTrail/res/values/ui_colors.xml @@ -1,4 +1,5 @@ #80000000 + #423921 diff --git a/AndorsTrail/res/values/ui_theme.xml b/AndorsTrail/res/values/ui_theme.xml index 0a2aba014..ebe0c7fef 100644 --- a/AndorsTrail/res/values/ui_theme.xml +++ b/AndorsTrail/res/values/ui_theme.xml @@ -29,4 +29,9 @@ wrap_content @dimen/smalltext_buttonheight + + \ No newline at end of file diff --git a/AndorsTrail/res/values/worldmap_template.xml b/AndorsTrail/res/values/worldmap_template.xml new file mode 100644 index 000000000..4ea5c1fa9 --- /dev/null +++ b/AndorsTrail/res/values/worldmap_template.xml @@ -0,0 +1,45 @@ + + +" + + + + + + + + + + +{{maps}} +{{areas}} + + x + + + + + + + +]]> diff --git a/AndorsTrail/res/xml/worldmap.xml b/AndorsTrail/res/xml/worldmap.xml new file mode 100644 index 000000000..7e394f863 --- /dev/null +++ b/AndorsTrail/res/xml/worldmap.xml @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index 6486784bd..761d80a39 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -16,7 +16,7 @@ public final class AndorsTrailApplication extends Application { public static final boolean DEVELOPMENT_DEBUGRESOURCES = false; public static final boolean DEVELOPMENT_FORCE_STARTNEWGAME = false; public static final boolean DEVELOPMENT_FORCE_CONTINUEGAME = false; - public static final boolean DEVELOPMENT_DEBUGBUTTONS = false; + public static final boolean DEVELOPMENT_DEBUGBUTTONS = true; public static final boolean DEVELOPMENT_VALIDATEDATA = false; public static final boolean DEVELOPMENT_DEBUGMESSAGES = false; public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES; 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 000000000..cfe9efae5 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java @@ -0,0 +1,86 @@ +package com.gpl.rpg.AndorsTrail.activity; + +import java.io.File; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.webkit.WebView; +import android.widget.Button; +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.model.map.WorldMapSegment; +import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.WorldMapSegmentMap; +import com.gpl.rpg.AndorsTrail.util.L; + +public class DisplayWorldMapActivity extends Activity { + private WorldContext world; + + private WebView displayworldmap_webview; + private String worldMapSegmentName; + + @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(R.color.displayworldmap_background)); + displayworldmap_webview.getSettings().setBuiltInZoomControls(true); + enableJavascript(); + + Button b = (Button) findViewById(R.id.displayworldmap_close); + b.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + DisplayWorldMapActivity.this.finish(); + } + }); + + worldMapSegmentName = getIntent().getStringExtra("worldMapSegmentName"); + } + + @SuppressLint("SetJavaScriptEnabled") + public void enableJavascript() { + displayworldmap_webview.getSettings().setJavaScriptEnabled(true); + } + + @Override + public void onResume() { + super.onResume(); + update(); + } + + private void update() { + File worldmap = WorldMapController.getCombinedWorldMapFile(worldMapSegmentName); + + if (!worldmap.exists()) { + Toast.makeText(this, getResources().getString(R.string.menu_button_worldmap_failed), Toast.LENGTH_LONG).show(); + this.finish(); + } + + WorldMapSegment segment = world.maps.worldMapSegments.get(worldMapSegmentName); + WorldMapSegmentMap map = segment.maps.get(world.model.currentMap.name); + if (map == null) this.finish(); + + String url = "file://" + worldmap.getAbsolutePath() + "?" + + (world.model.player.position.x + map.worldPosition.x) * WorldMapController.WORLDMAP_DISPLAY_TILESIZE + + "," + + (world.model.player.position.y + map.worldPosition.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 0f70c143d..e51f74adc 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -18,6 +18,7 @@ import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.view.CombatView; import com.gpl.rpg.AndorsTrail.view.DisplayActiveActorConditionIcons; import com.gpl.rpg.AndorsTrail.view.MainView; +import com.gpl.rpg.AndorsTrail.view.ToolboxView; import com.gpl.rpg.AndorsTrail.view.VirtualDpadView; import com.gpl.rpg.AndorsTrail.view.QuickButton.QuickButtonContextMenuInfo; import com.gpl.rpg.AndorsTrail.view.QuickitemView; @@ -40,7 +41,6 @@ import android.widget.Toast; public final class MainActivity extends Activity { - public static final int INTENTREQUEST_HEROINFO = 1; public static final int INTENTREQUEST_MONSTERENCOUNTER = 2; public static final int INTENTREQUEST_ITEMINFO = 3; public static final int INTENTREQUEST_CONVERSATION = 4; @@ -61,6 +61,7 @@ public final class MainActivity extends Activity { public CombatView combatview; public QuickitemView quickitemview; private DisplayActiveActorConditionIcons activeConditions; + private ToolboxView toolboxview; private VirtualDpadView dpad; private static final int NUM_MESSAGES = 3; @@ -87,6 +88,8 @@ public final class MainActivity extends Activity { quickitemview = (QuickitemView) findViewById(R.id.main_quickitemview); activeConditions = new DisplayActiveActorConditionIcons(app.preferences, world.tileManager, this, (RelativeLayout) findViewById(R.id.statusview_activeconditions)); dpad = (VirtualDpadView) findViewById(R.id.main_virtual_dpad); + toolboxview = (ToolboxView) findViewById(R.id.main_toolboxview); + statusview.registerToolboxViews(toolboxview, quickitemview); statusText = (TextView) findViewById(R.id.statusview_statustext); statusText.setOnClickListener(new OnClickListener() { @@ -97,22 +100,25 @@ public final class MainActivity extends Activity { }); clearMessages(); - if (AndorsTrailApplication.DEVELOPMENT_DEBUGBUTTONS) new DebugInterface(view).addDebugButtons(); + if (AndorsTrailApplication.DEVELOPMENT_DEBUGBUTTONS) new DebugInterface(view).addDebugButtons(); quickitemview.setVisibility(View.GONE); quickitemview.registerForContextMenu(this); - quickitemview.refreshQuickitems(); dpad.updateVisibility(app.preferences); + + // Define which views are in front of each other. + dpad.bringToFront(); + quickitemview.bringToFront(); + toolboxview.bringToFront(); + combatview.bringToFront(); + statusview.bringToFront(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { - case INTENTREQUEST_HEROINFO: - updateStatus(); - break; case INTENTREQUEST_MONSTERENCOUNTER: if (resultCode == Activity.RESULT_OK) { view.combatController.enterCombat(CombatController.BEGIN_TURN_PLAYER); @@ -264,6 +270,7 @@ public final class MainActivity extends Activity { statusview.updateStatus(); quickitemview.refreshQuickitems(); combatview.updateStatus(); + toolboxview.updateIcons(); } public void redrawAll(int why) { @@ -306,5 +313,4 @@ public final class MainActivity extends Activity { } t.show(); } - } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Constants.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Constants.java index ea0371ef2..66711501a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Constants.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Constants.java @@ -35,6 +35,9 @@ public final class Constants { public static final String PREFERENCE_MODEL_LASTRUNVERSION = "lastversion"; public static final String FILENAME_SAVEGAME_QUICKSAVE = "savegame"; public static final String FILENAME_SAVEGAME_DIRECTORY = "andors-trail"; + public static final String FILENAME_WORLDMAP_DIRECTORY = "worldmap"; + public static final String FILENAME_WORLDMAP_HTMLFILE_PREFIX = "worldmap_"; + public static final String FILENAME_WORLDMAP_HTMLFILE_SUFFIX = ".html"; public static final String FILENAME_SAVEGAME_FILENAME_PREFIX = "savegame"; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java index 3c27329d8..930434df2 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java @@ -3,7 +3,6 @@ package com.gpl.rpg.AndorsTrail.controller; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.ModelContainer; -import com.gpl.rpg.AndorsTrail.util.L; import com.gpl.rpg.AndorsTrail.util.TimedMessageTask; import com.gpl.rpg.AndorsTrail.view.MainView; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java index 8e1cea16b..b8f7c73f0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java @@ -2,8 +2,6 @@ package com.gpl.rpg.AndorsTrail.controller; import java.util.ArrayList; -import android.view.View; - import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; @@ -236,17 +234,6 @@ public final class ItemController { model.player.inventory.quickitem[quickSlotId] = itemType; view.mainActivity.updateStatus(); } - - public void toggleQuickItemView() { - if (view.mainActivity.quickitemview.getVisibility()==View.VISIBLE){ - view.mainActivity.quickitemview.setVisibility(View.GONE); - view.mainActivity.statusview.updateQuickItemImage(false); - } else { - view.mainActivity.quickitemview.setVisibility(View.VISIBLE); - view.mainActivity.quickitemview.bringToFront(); - view.mainActivity.statusview.updateQuickItemImage(true); - } - } public static void correctActorConditionsFromItemsPre0611b1(Player player, String conditionTypeID, WorldContext world, String itemTypeIDWithCondition) { if (!player.hasCondition(conditionTypeID)) return; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java index ce7fbe663..3e7684ced 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java @@ -272,6 +272,8 @@ public final class MovementController implements TimedMessageTask.Callback { world.model.currentTileMap = mapTiles; world.tileManager.currentMapTiles = cachedTiles; world.tileManager.cacheAdjacentMaps(res, world, nextMap); + + 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 new file mode 100644 index 000000000..c3ab96ee9 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/WorldMapController.java @@ -0,0 +1,280 @@ +package com.gpl.rpg.AndorsTrail.controller; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashSet; + +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.os.AsyncTask; +import android.os.Environment; +import android.widget.Toast; + +import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; +import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.activity.DisplayWorldMapActivity; +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.model.map.WorldMapSegment; +import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.NamedWorldMapArea; +import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.WorldMapSegmentMap; +import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection; +import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.CoordRect; +import com.gpl.rpg.AndorsTrail.util.L; +import com.gpl.rpg.AndorsTrail.util.Size; + +public final class WorldMapController { + + public static int WORLDMAP_SCREENSHOT_TILESIZE = 8; + 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) { + + final String worldMapSegmentName = world.maps.getWorldMapSegmentNameForMap(map.name); + if (worldMapSegmentName == null) return; + + if (!shouldUpdateWorldMap(map, worldMapSegmentName)) return; + + (new AsyncTask() { + @Override + protected Void doInBackground(Void... arg0) { + final MapRenderer renderer = new MapRenderer(world, map, mapTiles, cachedTiles); + try { + updateCachedBitmap(map, renderer); + updateWorldMapSegment(res, world, worldMapSegmentName); + } catch (IOException e) { + L.log("Error creating worldmap file for map " + map.name + " : " + e.toString()); + } + return null; + } + }).execute(); + } + + private static boolean shouldUpdateWorldMap(PredefinedMap map, String worldMapSegmentName) { + if (!map.visited) return true; + File file = getFileForMap(map); + if (!file.exists()) return true; + + if (map.lastVisitVersion < AndorsTrailApplication.CURRENT_VERSION) return true; + + file = getCombinedWorldMapFile(worldMapSegmentName); + if (!file.exists()) return true; + + return false; + } + + private static void updateCachedBitmap(PredefinedMap map, MapRenderer renderer) throws IOException { + ensureWorldmapDirectoryExists(); + + File file = getFileForMap(map); + if (file.exists()) { + if (map.lastVisitVersion == AndorsTrailApplication.CURRENT_VERSION) return; + } + + Bitmap image = renderer.drawMap(); + FileOutputStream fos = new FileOutputStream(file); + image.compress(Bitmap.CompressFormat.PNG, 70, fos); + fos.flush(); + fos.close(); + image.recycle(); + } + + private static final class MapRenderer { + private final PredefinedMap map; + private final LayeredTileMap mapTiles; + private final TileCollection cachedTiles; + private final int tileSize; + private final float scale; + private final Paint mPaint = new Paint(); + + public MapRenderer(final WorldContext world, final PredefinedMap map, final LayeredTileMap mapTiles, final TileCollection cachedTiles) { + this.map = map; + this.mapTiles = mapTiles; + this.cachedTiles = cachedTiles; + this.tileSize = world.tileManager.tileSize; + this.scale = (float) WORLDMAP_SCREENSHOT_TILESIZE / world.tileManager.tileSize; + } + + public Bitmap drawMap() { + 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); + + drawMapLayer(canvas, mapTiles.layers[LayeredTileMap.LAYER_GROUND]); + tryDrawMapLayer(canvas, LayeredTileMap.LAYER_OBJECTS); + tryDrawMapLayer(canvas, LayeredTileMap.LAYER_ABOVE); + + return image; + } + + private void tryDrawMapLayer(Canvas canvas, final int layerIndex) { + if (mapTiles.layers.length > layerIndex) drawMapLayer(canvas, mapTiles.layers[layerIndex]); + } + + private void drawMapLayer(Canvas canvas, final MapLayer layer) { + int py = 0; + for (int y = 0; y < map.size.height; ++y, py += tileSize) { + int px = 0; + for (int x = 0; x < map.size.width; ++x, px += tileSize) { + final int tile = layer.tiles[x][y]; + if (tile != 0) { + canvas.drawBitmap(cachedTiles.bitmaps[tile], px, py, mPaint); + } + } + } + } + } + + private static void ensureWorldmapDirectoryExists() throws IOException { + File root = Environment.getExternalStorageDirectory(); + File dir = new File(root, Constants.FILENAME_SAVEGAME_DIRECTORY); + if (!dir.exists()) dir.mkdir(); + dir = new File(dir, Constants.FILENAME_WORLDMAP_DIRECTORY); + if (!dir.exists()) dir.mkdir(); + + File noMediaFile = new File(dir, ".nomedia"); + if (!noMediaFile.exists()) noMediaFile.createNewFile(); + } + public static File getFileForMap(PredefinedMap map) { return getFileForMap(map.name); } + public static File getFileForMap(String mapName) { + return new File(getWorldmapDirectory(), mapName + ".png"); + } + 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(String segmentName) { + return new File(getWorldmapDirectory(), Constants.FILENAME_WORLDMAP_HTMLFILE_PREFIX + segmentName + Constants.FILENAME_WORLDMAP_HTMLFILE_SUFFIX); + } + + private static boolean shouldDisplayMapOnWorldmap(String mapName) { + File f = WorldMapController.getFileForMap(mapName); + return f.exists(); + } + private static String getWorldMapSegmentAsHtml(Resources res, WorldContext world, String segmentName) throws IOException { + WorldMapSegment segment = world.maps.worldMapSegments.get(segmentName); + + HashSet displayedMapNames = new HashSet(); + Coord offsetWorldmapTo = new Coord(999999, 999999); + for (WorldMapSegmentMap map : segment.maps.values()) { + if (!shouldDisplayMapOnWorldmap(map.mapName)) continue; + + displayedMapNames.add(map.mapName); + offsetWorldmapTo.x = Math.min(offsetWorldmapTo.x, map.worldPosition.x); + offsetWorldmapTo.y = Math.min(offsetWorldmapTo.y, map.worldPosition.y); + } + + StringBuffer mapsAsHtml = new StringBuffer(); + for (WorldMapSegmentMap segmentMap : segment.maps.values()) { + File f = WorldMapController.getFileForMap(segmentMap.mapName); + if (!f.exists()) continue; + + Size size = getMapSize(segmentMap, world); + mapsAsHtml + .append(""); + if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) mapsAsHtml.append("\n"); + } + + StringBuffer namedAreasAsHtml = new StringBuffer(); + for (NamedWorldMapArea area : segment.namedAreas.values()) { + CoordRect r = determineNamedAreaBoundary(area, segment, world, displayedMapNames); + if (r == null) continue; + namedAreasAsHtml + .append("") + .append(area.name) + .append(""); + if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) namedAreasAsHtml.append("\n"); + } + + return res.getString(R.string.worldmap_template) + .replace("{{maps}}", mapsAsHtml.toString()) + .replace("{{areas}}", namedAreasAsHtml.toString()) + .replace("{{offsetx}}", Integer.toString(offsetWorldmapTo.x * WorldMapController.WORLDMAP_DISPLAY_TILESIZE)) + .replace("{{offsety}}", Integer.toString(offsetWorldmapTo.y * WorldMapController.WORLDMAP_DISPLAY_TILESIZE)); + } + + private static Size getMapSize(WorldMapSegmentMap map, WorldContext world) { + return world.maps.findPredefinedMap(map.mapName).size; + } + + private static CoordRect determineNamedAreaBoundary(NamedWorldMapArea area, WorldMapSegment segment, WorldContext world, HashSet displayedMapNames) { + Coord topLeft = null; + Coord bottomRight = null; + + for (String mapName : area.mapNames) { + if (!displayedMapNames.contains(mapName)) continue; + WorldMapSegmentMap map = segment.maps.get(mapName); + Size size = getMapSize(map, world); + if (topLeft == null) { + topLeft = new Coord(map.worldPosition); + } else { + topLeft.x = Math.min(topLeft.x, map.worldPosition.x); + topLeft.y = Math.min(topLeft.y, map.worldPosition.y); + } + if (bottomRight == null) { + bottomRight = new Coord(map.worldPosition.x + size.width, map.worldPosition.y + size.height); + } else { + bottomRight.x = Math.max(bottomRight.x, map.worldPosition.x + size.width); + bottomRight.y = Math.max(bottomRight.y, map.worldPosition.y + size.height); + } + } + if (topLeft == null) return null; + return new CoordRect(topLeft, new Size(bottomRight.x - topLeft.x, bottomRight.y - topLeft.y)); + } + + private static void updateWorldMapSegment(Resources res, WorldContext world, String segmentName) throws IOException { + String mapAsHtml = getWorldMapSegmentAsHtml(res, world, segmentName); + File outputFile = getCombinedWorldMapFile(segmentName); + PrintWriter pw = new PrintWriter(outputFile); + pw.write(mapAsHtml); + pw.close(); + } + + public static boolean displayWorldMap(Context context, WorldContext world) { + String worldMapSegmentName = world.maps.getWorldMapSegmentNameForMap(world.model.currentMap.name); + if (worldMapSegmentName == null) { + Toast.makeText(context, context.getResources().getString(R.string.display_worldmap_not_available), Toast.LENGTH_LONG).show(); + return false; + } + + Intent intent = new Intent(context, DisplayWorldMapActivity.class); + intent.putExtra("worldMapSegmentName", worldMapSegmentName); + context.startActivity(intent); + + return true; + } +} 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 e442cec63..95a2dc4a8 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java @@ -4,6 +4,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.context.WorldContext; @@ -11,6 +12,7 @@ import com.gpl.rpg.AndorsTrail.util.L; public final class MapCollection { public final ArrayList predefinedMaps = new ArrayList(); + public final HashMap worldMapSegments = new HashMap(); public MapCollection() {} @@ -29,6 +31,13 @@ public final class MapCollection { m.reset(); } } + + public String getWorldMapSegmentNameForMap(String mapName) { + for (WorldMapSegment segment : worldMapSegments.values()) { + if (segment.containsMap(mapName)) return segment.name; + } + return null; + } // ====== PARCELABLE =================================================================== 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 7190746bb..50982e0ae 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java @@ -29,11 +29,13 @@ public final class PredefinedMap { 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 +46,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) { @@ -216,6 +219,7 @@ public final class PredefinedMap { } groundBags.clear(); visited = false; + lastVisitVersion = 0; } public boolean isRecentlyVisited() { @@ -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 2b309cc69..bbba42666 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapFileParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapFileParser.java @@ -10,6 +10,7 @@ import org.xmlpull.v1.XmlPullParserException; import com.gpl.rpg.AndorsTrail.util.Base64; import com.gpl.rpg.AndorsTrail.util.L; +import com.gpl.rpg.AndorsTrail.util.XmlResourceParserUtils; import android.content.res.Resources; import android.content.res.XmlResourceParser; @@ -41,7 +42,7 @@ public final class TMXMapFileParser { map.height = xrp.getAttributeIntValue(null, "height", -1); map.tilewidth = xrp.getAttributeIntValue(null, "tilewidth", -1); map.tileheight = xrp.getAttributeIntValue(null, "tileheight", -1); - readCurrentTagUntilEnd(xrp, new TagHandler() { + XmlResourceParserUtils.readCurrentTagUntilEnd(xrp, new XmlResourceParserUtils.TagHandler() { public void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException { if (tagName.equals("tileset")) { tileSets.add(readTMXTileSet(xrp)); @@ -49,6 +50,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)); } } }); @@ -79,7 +82,7 @@ public final class TMXMapFileParser { if (s.equals("map")) { map.width = xrp.getAttributeIntValue(null, "width", -1); map.height = xrp.getAttributeIntValue(null, "height", -1); - readCurrentTagUntilEnd(xrp, new TagHandler() { + XmlResourceParserUtils.readCurrentTagUntilEnd(xrp, new XmlResourceParserUtils.TagHandler() { public void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException { if (tagName.equals("tileset")) { tileSets.add(readTMXTileSet(xrp)); @@ -109,7 +112,7 @@ public final class TMXMapFileParser { ts.name = xrp.getAttributeValue(null, "name"); ts.tilewidth = xrp.getAttributeIntValue(null, "tilewidth", -1); ts.tileheight = xrp.getAttributeIntValue(null, "tileheight", -1); - readCurrentTagUntilEnd(xrp, new TagHandler() { + XmlResourceParserUtils.readCurrentTagUntilEnd(xrp, new XmlResourceParserUtils.TagHandler() { public void handleTag(XmlResourceParser xrp, String tagName) { if (tagName.equals("image")) { ts.imageSource = xrp.getAttributeValue(null, "source"); @@ -128,7 +131,7 @@ public final class TMXMapFileParser { group.name = xrp.getAttributeValue(null, "name"); group.width = xrp.getAttributeIntValue(null, "width", 1); group.height = xrp.getAttributeIntValue(null, "height", 1); - readCurrentTagUntilEnd(xrp, new TagHandler() { + XmlResourceParserUtils.readCurrentTagUntilEnd(xrp, new XmlResourceParserUtils.TagHandler() { public void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException { if (tagName.equals("object")) { group.objects.add(readTMXObject(xrp)); @@ -146,13 +149,10 @@ public final class TMXMapFileParser { object.y = xrp.getAttributeIntValue(null, "y", -1); 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) { + XmlResourceParserUtils.readCurrentTagUntilEnd(xrp, new XmlResourceParserUtils.TagHandler() { + 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)); } } }); @@ -165,7 +165,7 @@ public final class TMXMapFileParser { layer.width = xrp.getAttributeIntValue(null, "width", 1); layer.height = xrp.getAttributeIntValue(null, "height", 1); layer.gids = new int[layer.width][layer.height]; - readCurrentTagUntilEnd(xrp, new TagHandler() { + XmlResourceParserUtils.readCurrentTagUntilEnd(xrp, new XmlResourceParserUtils.TagHandler() { public void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException { if (tagName.equals("data")) { readTMXMapLayerData(xrp, layer); @@ -209,6 +209,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; @@ -220,23 +227,6 @@ public final class TMXMapFileParser { } } - private interface TagHandler { - void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException; - } - private static void readCurrentTagUntilEnd(XmlResourceParser xrp, TagHandler handler) throws XmlPullParserException, IOException { - String outerTagName = xrp.getName(); - String tagName; - int eventType; - while ((eventType = xrp.next()) != XmlResourceParser.END_DOCUMENT) { - if (eventType == XmlResourceParser.START_TAG) { - tagName = xrp.getName(); - handler.handleTag(xrp, tagName); - } else if (eventType == XmlResourceParser.END_TAG) { - tagName = xrp.getName(); - if (tagName.equals(outerTagName)) return; - } - } - } /* private static String getHexString(byte v) { String result = Integer.toHexString(v & 0xff); @@ -270,6 +260,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 +280,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 +289,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 62c82dbdd..e96515768 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/model/map/WorldMapSegment.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/WorldMapSegment.java new file mode 100644 index 000000000..8b1a084d6 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/WorldMapSegment.java @@ -0,0 +1,40 @@ +package com.gpl.rpg.AndorsTrail.model.map; + +import java.util.HashMap; +import java.util.HashSet; + +import com.gpl.rpg.AndorsTrail.util.Coord; + +public final class WorldMapSegment { + public final String name; + public final HashMap maps = new HashMap(); + public final HashMap namedAreas = new HashMap(); + + public WorldMapSegment(String name) { + this.name = name; + } + + public boolean containsMap(String mapName) { return maps.containsKey(mapName); } + + public static final class WorldMapSegmentMap { + public final String mapName; + public final Coord worldPosition; + public WorldMapSegmentMap(String mapName, Coord worldPosition) { + this.mapName = mapName; + this.worldPosition = worldPosition; + } + } + + // Towns, cities, villages, taverns, named dungeons + public static final class NamedWorldMapArea { + public final String id; + public final String name; + public final String type; // "settlement" or "other" + public final HashSet mapNames = new HashSet(); + public NamedWorldMapArea(String id, String name, String type) { + this.id = id; + this.name = name; + this.type = type; + } + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java index a96d825d5..fb4dc670b 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 000000000..18f30468b --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java @@ -0,0 +1,79 @@ +package com.gpl.rpg.AndorsTrail.resource.parsers; + +import java.io.IOException; +import java.util.ArrayList; + +import org.xmlpull.v1.XmlPullParserException; + +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.WorldMapSegment; +import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.NamedWorldMapArea; +import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.WorldMapSegmentMap; +import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.L; +import com.gpl.rpg.AndorsTrail.util.Pair; +import com.gpl.rpg.AndorsTrail.util.XmlResourceParserUtils; + +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("segment")) { + WorldMapSegment segment = parseSegment(xrp, maps); + maps.worldMapSegments.put(segment.name, segment); + } + } + } + xrp.close(); + } catch (Exception e) { + L.log("Error reading worldmap: " + e.toString()); + } + } + + private static WorldMapSegment parseSegment(XmlResourceParser xrp, final MapCollection maps) throws XmlPullParserException, IOException { + String segmentName = xrp.getAttributeValue(null, "id"); + final WorldMapSegment segment = new WorldMapSegment(segmentName); + + final ArrayList> mapsInNamedAreas = new ArrayList>(); + XmlResourceParserUtils.readCurrentTagUntilEnd(xrp, new XmlResourceParserUtils.TagHandler() { + @Override + public void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException { + if (tagName.equals("map")) { + String mapName = xrp.getAttributeValue(null, "id"); + if (maps.findPredefinedMap(mapName) == null) return; + Coord mapPosition = new Coord( + xrp.getAttributeIntValue(null, "x", -1), + xrp.getAttributeIntValue(null, "y", -1) + ); + WorldMapSegmentMap map = new WorldMapSegmentMap(mapName, mapPosition); + segment.maps.put(mapName, map); + + String namedArea = xrp.getAttributeValue(null, "area"); + if (namedArea != null) mapsInNamedAreas.add(new Pair(mapName, namedArea)); + } else if (tagName.equals("namedarea")) { + String id = xrp.getAttributeValue(null, "id"); + String name = xrp.getAttributeValue(null, "name"); + String type = xrp.getAttributeValue(null, "type"); + segment.namedAreas.put(id, new NamedWorldMapArea(id, name, type)); + } + } + }); + + for (Pair m : mapsInNamedAreas) { + segment.namedAreas.get(m.second).mapNames.add(m.first); + } + + return segment; + } + +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/XmlResourceParserUtils.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/XmlResourceParserUtils.java new file mode 100644 index 000000000..1eab988bf --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/XmlResourceParserUtils.java @@ -0,0 +1,29 @@ +package com.gpl.rpg.AndorsTrail.util; + +import java.io.IOException; + +import org.xmlpull.v1.XmlPullParserException; + +import android.content.res.XmlResourceParser; + +public final class XmlResourceParserUtils { + + public static interface TagHandler { + void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException; + } + + public static void readCurrentTagUntilEnd(XmlResourceParser xrp, TagHandler handler) throws XmlPullParserException, IOException { + String outerTagName = xrp.getName(); + String tagName; + int eventType; + while ((eventType = xrp.next()) != XmlResourceParser.END_DOCUMENT) { + if (eventType == XmlResourceParser.START_TAG) { + tagName = xrp.getName(); + handler.handleTag(xrp, tagName); + } else if (eventType == XmlResourceParser.END_TAG) { + tagName = xrp.getName(); + if (tagName.equals(outerTagName)) return; + } + } + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java index f2897c781..2a6201576 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java @@ -2,9 +2,7 @@ package com.gpl.rpg.AndorsTrail.view; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.R; -import com.gpl.rpg.AndorsTrail.activity.MainActivity; import com.gpl.rpg.AndorsTrail.activity.HeroinfoActivity; -import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; @@ -23,21 +21,20 @@ public final class StatusView extends RelativeLayout { private final WorldContext world; private final Player player; - private final ViewContext view; private final RangeBar healthBar; private final RangeBar expBar; private final ImageButton heroImage; - private final ImageButton quickToggle; + private final ImageButton toggleToolbox; private boolean showingLevelup; private final Drawable levelupDrawable; + private ToolboxView toolbox; public StatusView(final Context context, AttributeSet attr) { super(context, attr); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); this.world = app.world; this.player = app.world.model.player; - this.view = app.currentView.get(); setFocusable(false); inflate(context, R.layout.statusview, this); @@ -49,8 +46,7 @@ public final class StatusView extends RelativeLayout { heroImage.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - Intent intent = new Intent(context, HeroinfoActivity.class); - AndorsTrailApplication.getActivityFromActivityContext(context).startActivityForResult(intent, MainActivity.INTENTREQUEST_HEROINFO); + context.startActivity(new Intent(context, HeroinfoActivity.class)); } }); healthBar = (RangeBar) findViewById(R.id.statusview_health); @@ -64,18 +60,24 @@ public final class StatusView extends RelativeLayout { ,new BitmapDrawable(world.tileManager.preloadedTiles.getBitmap(TileManager.iconID_moveselect)) }); - quickToggle = (ImageButton) findViewById(R.id.quickitem_toggle); - world.tileManager.setImageViewTileForUIIcon(quickToggle, TileManager.iconID_boxclosed); - quickToggle.setOnClickListener(new OnClickListener() { + toggleToolbox = (ImageButton) findViewById(R.id.toolbox_toggle); + world.tileManager.setImageViewTileForUIIcon(toggleToolbox, TileManager.iconID_boxclosed); + toggleToolbox.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - view.itemController.toggleQuickItemView(); + toolbox.toggleVisibility(); } }); updateStatus(); updateIcon(player.canLevelup()); } + + public void registerToolboxViews(ToolboxView toolbox, QuickitemView quickitemView) { + this.toolbox = toolbox; + toolbox.registerToolboxViews(toggleToolbox, quickitemView); + toolbox.updateIcons(); + } public void updateStatus() { healthBar.update(player.health); @@ -94,12 +96,4 @@ public final class StatusView extends RelativeLayout { world.tileManager.setImageViewTile(heroImage, player); } } - - public void updateQuickItemImage(boolean visible){ - if(visible){ - world.tileManager.setImageViewTileForUIIcon(quickToggle, TileManager.iconID_boxopened); - } else { - world.tileManager.setImageViewTileForUIIcon(quickToggle, TileManager.iconID_boxclosed); - } - } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ToolboxView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ToolboxView.java new file mode 100644 index 000000000..b822330ee --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ToolboxView.java @@ -0,0 +1,97 @@ +package com.gpl.rpg.AndorsTrail.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.animation.Animation.AnimationListener; +import android.widget.ImageButton; +import android.widget.LinearLayout; + +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.resource.tiles.TileManager; + +public class ToolboxView extends LinearLayout implements OnClickListener { + private final WorldContext world; + private final Animation showAnimation; + private final Animation hideAnimation; + private final ImageButton toolbox_quickitems; + private final ImageButton toolbox_map; + private ImageButton toggleVisibility; + private QuickitemView quickitemView; + + public ToolboxView(final Context context, AttributeSet attrs) { + super(context, attrs); + AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); + this.world = app.world; + + inflate(context, R.layout.toolboxview, this); + + this.showAnimation = AnimationUtils.loadAnimation(context, R.anim.showtoolbox); + this.hideAnimation = AnimationUtils.loadAnimation(context, R.anim.hidetoolbox); + this.hideAnimation.setAnimationListener(new AnimationListener() { + @Override public void onAnimationStart(Animation animation) { } + @Override public void onAnimationRepeat(Animation animation) { } + @Override public void onAnimationEnd(Animation animation) { + ToolboxView.this.setVisibility(View.GONE); + } + }); + + toolbox_quickitems = (ImageButton)findViewById(R.id.toolbox_quickitems); + toolbox_quickitems.setOnClickListener(this); + toolbox_map = (ImageButton)findViewById(R.id.toolbox_map); + toolbox_map.setOnClickListener(this); + } + + public void registerToolboxViews(ImageButton toggleVisibility, QuickitemView quickitemView) { + this.toggleVisibility = toggleVisibility; + this.quickitemView = quickitemView; + } + + @Override + public void onClick(View btn) { + Context context = getContext(); + if (btn == toolbox_quickitems) { + toggleQuickItemView(); + } else if (btn == toolbox_map) { + if (!WorldMapController.displayWorldMap(context, world)) return; + setVisibility(View.GONE); + } + } + + private void toggleQuickItemView() { + if (quickitemView.getVisibility() == View.VISIBLE){ + quickitemView.setVisibility(View.GONE); + } else { + quickitemView.setVisibility(View.VISIBLE); + } + } + + public void toggleVisibility() { + if (getVisibility() == View.VISIBLE) { + startAnimation(hideAnimation); + setToolboxIcon(false); + } else { + setVisibility(View.VISIBLE); + startAnimation(showAnimation); + setToolboxIcon(true); + } + } + + public void updateIcons() { + setToolboxIcon(getVisibility() == View.VISIBLE); + } + + private void setToolboxIcon(boolean opened) { + if (opened) { + world.tileManager.setImageViewTileForUIIcon(toggleVisibility, TileManager.iconID_boxopened); + } else { + world.tileManager.setImageViewTileForUIIcon(toggleVisibility, TileManager.iconID_boxclosed); + } + } +}