From b250d4c1bd0e3c3f9bba660bf30c12b14e2a38bc Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sun, 20 Nov 2011 17:16:48 +0100 Subject: [PATCH] Added support for world maps in mods. Mods with a tag in their XML definition can now open a native world map like the original game. Fixed an oversight that the world map visited area was updated while the editor was open. Fixed missing field in worldmap.txt saving. Removed the limitation that world map tiles had to be 256x256 - all tile sizes work now. The game does now read _mods/#/data/stringbank.txt from a mod and merges it with the main stringbank.txt, and uses _mods/#/data/worldmap.txt as a full replacement. Load _mods/#/[map|premap]_mapname.lua scripts to properly initialize the Naija map token. Improved the builtin worldmap editor a little. --- Aquaria/Continuity.cpp | 4 +- Aquaria/DSQ.h | 12 +++- Aquaria/Game.cpp | 11 +++- Aquaria/GridRender.h | 1 + Aquaria/MiniMapRender.cpp | 2 +- Aquaria/Mod.cpp | 12 ++++ Aquaria/StringBank.cpp | 12 +++- Aquaria/WorldMapRender.cpp | 130 +++++++++++++++++++++++-------------- Aquaria/WorldMapTiles.cpp | 37 +++++++++-- 9 files changed, 155 insertions(+), 66 deletions(-) diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index bfd00f3..dbcf072 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -3207,12 +3207,12 @@ void Continuity::reset() loadTreasureData(); - stringBank.load("data/stringbank.txt"); + stringBank.load(); gems.clear(); beacons.clear(); - worldMap.load("data/worldmap.txt"); + worldMap.load(); ingredients.clear(); diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 53dd33a..d647ed8 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -206,10 +206,11 @@ class StringBank { public: StringBank(); - void load(const std::string &file); + void load(); std::string get(int idx); protected: + void _load(const std::string &file); typedef std::map StringMap; StringMap stringMap; @@ -260,6 +261,7 @@ public: bool isActive(); bool isDebugMenu(); + bool hasWorldMap(); std::string getPath(); std::string getName(); @@ -269,6 +271,7 @@ public: protected: bool shuttingDown; bool active; + bool hasMap; int doRecache; int debugMenu; int enqueueModStart; @@ -581,8 +584,8 @@ protected: struct WorldMap { WorldMap(); - void load(const std::string &file); - void save(const std::string &file); + void load(); + void save(); void hideMap(); void revealMap(const std::string &name); WorldMapTile *getWorldMapTile(const std::string &name); @@ -595,6 +598,9 @@ struct WorldMap int gw, gh; typedef std::vector WorldMapTiles; WorldMapTiles worldMapTiles; + +private: + void _load(const std::string &file); }; class Path; diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index b6c2370..d9c4fa9 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -6983,8 +6983,10 @@ void Game::applyState() core->sort(); - - dsq->runScript("scripts/maps/premap_"+sceneName+".lua", "init", true); + if (dsq->mod.isActive()) + dsq->runScript(dsq->mod.getPath() + "scripts/premap_" + sceneName + ".lua", "init", true); + else + dsq->runScript("scripts/maps/premap_"+sceneName+".lua", "init", true); std::string musicToPlay = this->musicToPlay; if (!overrideMusic.empty()) @@ -7076,7 +7078,10 @@ void Game::applyState() dsq->subtitlePlayer.show(0.25); if (verbose) debugLog("loading map init script"); - dsq->runScript("scripts/maps/map_"+sceneName+".lua", "init", true); + if (dsq->mod.isActive()) + dsq->runScript(dsq->mod.getPath() + "scripts/map_" + sceneName + ".lua", "init", true); + else + dsq->runScript("scripts/maps/map_"+sceneName+".lua", "init", true); if (!dsq->doScreenTrans && (dsq->overlay->alpha != 0 && !dsq->overlay->alpha.isInterpolating())) { diff --git a/Aquaria/GridRender.h b/Aquaria/GridRender.h index 4ec88ac..4fed0e1 100644 --- a/Aquaria/GridRender.h +++ b/Aquaria/GridRender.h @@ -102,6 +102,7 @@ protected: unsigned char *savedTexData; bool mb; Vector lastMousePosition; // See FIXME in WorldMapRender.cpp --achurch + void updateEditor(); }; class PathRender : public RenderObject diff --git a/Aquaria/MiniMapRender.cpp b/Aquaria/MiniMapRender.cpp index a0760f5..095db91 100644 --- a/Aquaria/MiniMapRender.cpp +++ b/Aquaria/MiniMapRender.cpp @@ -359,7 +359,7 @@ void MiniMapRender::onUpdate(float dt) } } - if (!btn && !dsq->mod.isActive() && !radarHide) + if (!btn && !radarHide && (!dsq->mod.isActive() || dsq->mod.hasWorldMap())) { if (dsq->game->worldMapRender->isOn()) { diff --git a/Aquaria/Mod.cpp b/Aquaria/Mod.cpp index 82b5d50..d3c93e0 100644 --- a/Aquaria/Mod.cpp +++ b/Aquaria/Mod.cpp @@ -58,6 +58,7 @@ void Mod::clear() active = false; doRecache = 0; debugMenu = false; + hasMap = false; } bool Mod::isDebugMenu() @@ -65,6 +66,11 @@ bool Mod::isDebugMenu() return debugMenu; } +bool Mod::hasWorldMap() +{ + return hasMap; +} + void Mod::loadModXML(TiXmlDocument *d, std::string modName) { d->LoadFile(baseModPath + modName + ".xml"); @@ -112,6 +118,12 @@ void Mod::load(const std::string &p) if (props->Attribute("debugMenu")) { props->Attribute("debugMenu", &debugMenu); } + + if (props->Attribute("hasWorldMap")) { + int t; + props->Attribute("hasWorldMap", &t); + hasMap = t; + } } } diff --git a/Aquaria/StringBank.cpp b/Aquaria/StringBank.cpp index a37cb5b..9e842db 100644 --- a/Aquaria/StringBank.cpp +++ b/Aquaria/StringBank.cpp @@ -24,11 +24,19 @@ StringBank::StringBank() { } -void StringBank::load(const std::string &file) +void StringBank::load() { - //debugLog("StringBank::load("+file+")"); stringMap.clear(); + _load("data/stringbank.txt"); + if (dsq->mod.isActive()) + _load(dsq->mod.getPath() + "data/stringbank.txt"); +} + +void StringBank::_load(const std::string &file) +{ + //debugLog("StringBank::load("+file+")"); + std::ifstream in(file.c_str()); std::string line; diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index 8ba2a1a..bc0d99a 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -1029,57 +1029,59 @@ void WorldMapRender::onUpdate(float dt) internalOffset += mouseChange / scale.x; } - - float scrollSpeed = 2.0f; - float amt = (400*dt)/scale.x; - if (isActing(ACTION_SWIMLEFT)) + if(!editorActive) { - internalOffset += Vector(amt, 0); - } - if (isActing(ACTION_SWIMRIGHT)) - { - internalOffset += Vector(-amt, 0); - } - if (isActing(ACTION_SWIMDOWN)) - { - if (core->getShiftState()) + float scrollSpeed = 2.0f; + float amt = (400*dt)/scale.x; + if (isActing(ACTION_SWIMLEFT)) { - scale.stop(); - scale -= Vector(scrollSpeed*dt, scrollSpeed*dt); + internalOffset += Vector(amt, 0); } - else + if (isActing(ACTION_SWIMRIGHT)) { - internalOffset += Vector(0, -amt); + internalOffset += Vector(-amt, 0); } - } - if (isActing(ACTION_SWIMUP)) - { - if (core->getShiftState()) + if (isActing(ACTION_SWIMDOWN)) { - scale.stop(); - scale += Vector(scrollSpeed*dt, scrollSpeed*dt); + if (core->getShiftState()) + { + scale.stop(); + scale -= Vector(scrollSpeed*dt, scrollSpeed*dt); + } + else + { + internalOffset += Vector(0, -amt); + } } - else + if (isActing(ACTION_SWIMUP)) { - internalOffset += Vector(0, amt); - } - } + if (core->getShiftState()) + { + scale.stop(); + scale += Vector(scrollSpeed*dt, scrollSpeed*dt); + } + else + { + internalOffset += Vector(0, amt); + } + } - if (core->joystickEnabled) - { - if (isActing(ACTION_SECONDARY)) + if (core->joystickEnabled) { - if (core->joystick.position.y >= 0.6f) - scale.interpolateTo(scale / 1.2f, 0.1f); - else if (core->joystick.position.y <= -0.6f) - scale.interpolateTo(scale * 1.2f, 0.1f); - } - else - { - // The negative multiplier is deliberate -- it makes the - // map scroll as though the joystick was controlling the - // cursor (which is fixed in the center of the screen). - internalOffset += core->joystick.position * (-400*dt / scale.x); + if (isActing(ACTION_SECONDARY)) + { + if (core->joystick.position.y >= 0.6f) + scale.interpolateTo(scale / 1.2f, 0.1f); + else if (core->joystick.position.y <= -0.6f) + scale.interpolateTo(scale * 1.2f, 0.1f); + } + else + { + // The negative multiplier is deliberate -- it makes the + // map scroll as though the joystick was controlling the + // cursor (which is fixed in the center of the screen). + internalOffset += core->joystick.position * (-400*dt / scale.x); + } } } @@ -1136,11 +1138,22 @@ void WorldMapRender::onUpdate(float dt) if (core->getShiftState()) { + if (core->getCtrlState()) + a2 *= 10.0f; if (core->getKeyState(KEY_UP)) activeTile->scale2 += -a2; if (core->getKeyState(KEY_DOWN)) activeTile->scale2 += a2; } + else if (core->getAltState()) + { + if (core->getCtrlState()) + a2 *= 10.0f; + if (core->getKeyState(KEY_UP)) + activeTile->scale += -a2; + if (core->getKeyState(KEY_DOWN)) + activeTile->scale += a2; + } else { if (core->getCtrlState()) @@ -1159,19 +1172,23 @@ void WorldMapRender::onUpdate(float dt) if (core->getKeyState(KEY_F2)) { - dsq->continuity.worldMap.save("data/WorldMap.txt"); + dsq->continuity.worldMap.save(); } activeQuad->position = activeTile->gridPos; activeQuad->scale = Vector(0.25f*activeTile->scale2, 0.25f*activeTile->scale2); + if(activeQuad->texture) + activeQuad->setWidthHeight(activeQuad->texture->width*activeTile->scale, // FG: HACK force resize proper + activeQuad->texture->height*activeTile->scale); } + updateEditor(); } } } else { #ifdef AQUARIA_BUILD_MAPVIS - if (!dsq->isInCutscene() && dsq->game->avatar && activeTile) + if (!dsq->isInCutscene() && dsq->game->avatar && activeTile && !dsq->game->sceneEditor.isOn()) { const float screenWidth = core->getVirtualWidth() * core->invGlobalScale; const float screenHeight = core->getVirtualHeight() * core->invGlobalScale; @@ -1231,11 +1248,16 @@ Vector WorldMapRender::getAvatarWorldMapPosition() Vector WorldMapRender::getWorldToTile(WorldMapTile *tile, Vector position, bool fromCenter, bool tilePos) { + const float sizew = (float)tile->q->texture->width; + const float halfw = sizew / 2.0f; + const float sizeh = (float)tile->q->texture->height; + const float halfh = sizeh / 2.0f; Vector p; - p = (position/TILE_SIZE) / (256*tile->scale); - p *= 256*tile->scale*0.25f*tile->scale2; + p = Vector((position.x/TILE_SIZE) / (sizew*tile->scale), (position.y/TILE_SIZE) / (sizeh*tile->scale)); + p.x *= sizew*tile->scale*0.25f*tile->scale2; + p.y *= sizeh*tile->scale*0.25f*tile->scale2; if (fromCenter) - p -= Vector((128*tile->scale)*(0.25f*tile->scale2), (128*tile->scale)*(0.25f*tile->scale2)); + p -= Vector((halfw*tile->scale)*(0.25f*tile->scale2), (halfh*tile->scale)*(0.25f*tile->scale2)); if (tilePos) p += tile->gridPos; return p; @@ -1298,7 +1320,7 @@ void WorldMapRender::toggle(bool turnON) if (dsq->game->miniMapRender->isRadarHide()) return; if (alpha.isInterpolating()) return; - if (dsq->mod.isActive()) return; + if (dsq->mod.isActive() && !dsq->mod.hasWorldMap()) return; if (dsq->isNested()) return; @@ -1489,6 +1511,18 @@ void WorldMapRender::createGemHint(const std::string &gfx) } } +void WorldMapRender::updateEditor() +{ + std::ostringstream os; + os << "EDITING... "; + if(activeTile) + { + os << "x=" << activeTile->gridPos.x << "; y=" << activeTile->gridPos.y << std::endl; + os << "scale=" << activeTile->scale << "; scale2=" << activeTile->scale2; + } + areaLabel->setText(os.str()); +} + void WorldMapRender::action (int id, int state) { if (isOn()) @@ -1505,7 +1539,7 @@ void WorldMapRender::action (int id, int state) if (editorActive) { - areaLabel->setText("EDITING..."); + updateEditor(); } } } diff --git a/Aquaria/WorldMapTiles.cpp b/Aquaria/WorldMapTiles.cpp index f535a44..fb646d7 100644 --- a/Aquaria/WorldMapTiles.cpp +++ b/Aquaria/WorldMapTiles.cpp @@ -240,7 +240,15 @@ WorldMap::WorldMap() gw=gh=0; } -void WorldMap::load(const std::string &file) +void WorldMap::load() +{ + if (!dsq->mod.isActive()) + _load("data/worldmap.txt"); + else + _load(dsq->mod.getPath() + "data/worldmap.txt"); +} + +void WorldMap::_load(const std::string &file) { worldMapTiles.clear(); @@ -259,14 +267,29 @@ void WorldMap::load(const std::string &file) } } -void WorldMap::save(const std::string &file) +void WorldMap::save() { - std::ofstream out(file.c_str()); - - for (int i = 0; i < worldMapTiles.size(); i++) + std::string fn; + + if (dsq->mod.isActive()) + fn = dsq->mod.getPath() + "data/worldmap.txt"; + else + fn = "data/worldmap.txt"; + + std::ofstream out(fn.c_str()); + + if (out) { - WorldMapTile *t = &worldMapTiles[i]; - out << t->index << " " << t->name << " " << t->layer << " " << t->scale << " " << t->gridPos.x << " " << t->gridPos.y << " " << t->prerevealed << " " << t->scale2 << std::endl; + for (int i = 0; i < worldMapTiles.size(); i++) + { + WorldMapTile *t = &worldMapTiles[i]; + out << t->index << " " << t->stringIndex << " " << t->name << " " << t->layer << " " << t->scale << " " << t->gridPos.x << " " << t->gridPos.y << " " << t->prerevealed << " " << t->scale2 << std::endl; + } + dsq->screenMessage("Saved worldmap data to " + fn); + } + else + { + dsq->screenMessage("Unable to save worldmap to " + fn); } }