mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-07-03 22:44:32 +00:00
Added support for world maps in mods.
Mods with a <Properties hasWorldMap="1"> 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.
This commit is contained in:
parent
e7c8b0093b
commit
b250d4c1bd
9 changed files with 155 additions and 66 deletions
|
@ -3207,12 +3207,12 @@ void Continuity::reset()
|
||||||
|
|
||||||
loadTreasureData();
|
loadTreasureData();
|
||||||
|
|
||||||
stringBank.load("data/stringbank.txt");
|
stringBank.load();
|
||||||
|
|
||||||
gems.clear();
|
gems.clear();
|
||||||
beacons.clear();
|
beacons.clear();
|
||||||
|
|
||||||
worldMap.load("data/worldmap.txt");
|
worldMap.load();
|
||||||
|
|
||||||
ingredients.clear();
|
ingredients.clear();
|
||||||
|
|
||||||
|
|
|
@ -206,10 +206,11 @@ class StringBank
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StringBank();
|
StringBank();
|
||||||
void load(const std::string &file);
|
void load();
|
||||||
|
|
||||||
std::string get(int idx);
|
std::string get(int idx);
|
||||||
protected:
|
protected:
|
||||||
|
void _load(const std::string &file);
|
||||||
|
|
||||||
typedef std::map<int, std::string> StringMap;
|
typedef std::map<int, std::string> StringMap;
|
||||||
StringMap stringMap;
|
StringMap stringMap;
|
||||||
|
@ -260,6 +261,7 @@ public:
|
||||||
|
|
||||||
bool isActive();
|
bool isActive();
|
||||||
bool isDebugMenu();
|
bool isDebugMenu();
|
||||||
|
bool hasWorldMap();
|
||||||
|
|
||||||
std::string getPath();
|
std::string getPath();
|
||||||
std::string getName();
|
std::string getName();
|
||||||
|
@ -269,6 +271,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
bool shuttingDown;
|
bool shuttingDown;
|
||||||
bool active;
|
bool active;
|
||||||
|
bool hasMap;
|
||||||
int doRecache;
|
int doRecache;
|
||||||
int debugMenu;
|
int debugMenu;
|
||||||
int enqueueModStart;
|
int enqueueModStart;
|
||||||
|
@ -581,8 +584,8 @@ protected:
|
||||||
struct WorldMap
|
struct WorldMap
|
||||||
{
|
{
|
||||||
WorldMap();
|
WorldMap();
|
||||||
void load(const std::string &file);
|
void load();
|
||||||
void save(const std::string &file);
|
void save();
|
||||||
void hideMap();
|
void hideMap();
|
||||||
void revealMap(const std::string &name);
|
void revealMap(const std::string &name);
|
||||||
WorldMapTile *getWorldMapTile(const std::string &name);
|
WorldMapTile *getWorldMapTile(const std::string &name);
|
||||||
|
@ -595,6 +598,9 @@ struct WorldMap
|
||||||
int gw, gh;
|
int gw, gh;
|
||||||
typedef std::vector<WorldMapTile> WorldMapTiles;
|
typedef std::vector<WorldMapTile> WorldMapTiles;
|
||||||
WorldMapTiles worldMapTiles;
|
WorldMapTiles worldMapTiles;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _load(const std::string &file);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Path;
|
class Path;
|
||||||
|
|
|
@ -6983,8 +6983,10 @@ void Game::applyState()
|
||||||
|
|
||||||
core->sort();
|
core->sort();
|
||||||
|
|
||||||
|
if (dsq->mod.isActive())
|
||||||
dsq->runScript("scripts/maps/premap_"+sceneName+".lua", "init", true);
|
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;
|
std::string musicToPlay = this->musicToPlay;
|
||||||
if (!overrideMusic.empty())
|
if (!overrideMusic.empty())
|
||||||
|
@ -7076,7 +7078,10 @@ void Game::applyState()
|
||||||
dsq->subtitlePlayer.show(0.25);
|
dsq->subtitlePlayer.show(0.25);
|
||||||
|
|
||||||
if (verbose) debugLog("loading map init script");
|
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()))
|
if (!dsq->doScreenTrans && (dsq->overlay->alpha != 0 && !dsq->overlay->alpha.isInterpolating()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,6 +102,7 @@ protected:
|
||||||
unsigned char *savedTexData;
|
unsigned char *savedTexData;
|
||||||
bool mb;
|
bool mb;
|
||||||
Vector lastMousePosition; // See FIXME in WorldMapRender.cpp --achurch
|
Vector lastMousePosition; // See FIXME in WorldMapRender.cpp --achurch
|
||||||
|
void updateEditor();
|
||||||
};
|
};
|
||||||
|
|
||||||
class PathRender : public RenderObject
|
class PathRender : public RenderObject
|
||||||
|
|
|
@ -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())
|
if (dsq->game->worldMapRender->isOn())
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,6 +58,7 @@ void Mod::clear()
|
||||||
active = false;
|
active = false;
|
||||||
doRecache = 0;
|
doRecache = 0;
|
||||||
debugMenu = false;
|
debugMenu = false;
|
||||||
|
hasMap = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mod::isDebugMenu()
|
bool Mod::isDebugMenu()
|
||||||
|
@ -65,6 +66,11 @@ bool Mod::isDebugMenu()
|
||||||
return debugMenu;
|
return debugMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Mod::hasWorldMap()
|
||||||
|
{
|
||||||
|
return hasMap;
|
||||||
|
}
|
||||||
|
|
||||||
void Mod::loadModXML(TiXmlDocument *d, std::string modName)
|
void Mod::loadModXML(TiXmlDocument *d, std::string modName)
|
||||||
{
|
{
|
||||||
d->LoadFile(baseModPath + modName + ".xml");
|
d->LoadFile(baseModPath + modName + ".xml");
|
||||||
|
@ -112,6 +118,12 @@ void Mod::load(const std::string &p)
|
||||||
if (props->Attribute("debugMenu")) {
|
if (props->Attribute("debugMenu")) {
|
||||||
props->Attribute("debugMenu", &debugMenu);
|
props->Attribute("debugMenu", &debugMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props->Attribute("hasWorldMap")) {
|
||||||
|
int t;
|
||||||
|
props->Attribute("hasWorldMap", &t);
|
||||||
|
hasMap = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,19 @@ StringBank::StringBank()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringBank::load(const std::string &file)
|
void StringBank::load()
|
||||||
{
|
{
|
||||||
//debugLog("StringBank::load("+file+")");
|
|
||||||
stringMap.clear();
|
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::ifstream in(file.c_str());
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
|
@ -1029,57 +1029,59 @@ void WorldMapRender::onUpdate(float dt)
|
||||||
internalOffset += mouseChange / scale.x;
|
internalOffset += mouseChange / scale.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!editorActive)
|
||||||
|
{
|
||||||
|
float scrollSpeed = 2.0f;
|
||||||
|
float amt = (400*dt)/scale.x;
|
||||||
|
if (isActing(ACTION_SWIMLEFT))
|
||||||
|
{
|
||||||
|
internalOffset += Vector(amt, 0);
|
||||||
|
}
|
||||||
|
if (isActing(ACTION_SWIMRIGHT))
|
||||||
|
{
|
||||||
|
internalOffset += Vector(-amt, 0);
|
||||||
|
}
|
||||||
|
if (isActing(ACTION_SWIMDOWN))
|
||||||
|
{
|
||||||
|
if (core->getShiftState())
|
||||||
|
{
|
||||||
|
scale.stop();
|
||||||
|
scale -= Vector(scrollSpeed*dt, scrollSpeed*dt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
internalOffset += Vector(0, -amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isActing(ACTION_SWIMUP))
|
||||||
|
{
|
||||||
|
if (core->getShiftState())
|
||||||
|
{
|
||||||
|
scale.stop();
|
||||||
|
scale += Vector(scrollSpeed*dt, scrollSpeed*dt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
internalOffset += Vector(0, amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float scrollSpeed = 2.0f;
|
if (core->joystickEnabled)
|
||||||
float amt = (400*dt)/scale.x;
|
|
||||||
if (isActing(ACTION_SWIMLEFT))
|
|
||||||
{
|
|
||||||
internalOffset += Vector(amt, 0);
|
|
||||||
}
|
|
||||||
if (isActing(ACTION_SWIMRIGHT))
|
|
||||||
{
|
|
||||||
internalOffset += Vector(-amt, 0);
|
|
||||||
}
|
|
||||||
if (isActing(ACTION_SWIMDOWN))
|
|
||||||
{
|
|
||||||
if (core->getShiftState())
|
|
||||||
{
|
{
|
||||||
scale.stop();
|
if (isActing(ACTION_SECONDARY))
|
||||||
scale -= Vector(scrollSpeed*dt, scrollSpeed*dt);
|
{
|
||||||
}
|
if (core->joystick.position.y >= 0.6f)
|
||||||
else
|
scale.interpolateTo(scale / 1.2f, 0.1f);
|
||||||
{
|
else if (core->joystick.position.y <= -0.6f)
|
||||||
internalOffset += Vector(0, -amt);
|
scale.interpolateTo(scale * 1.2f, 0.1f);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
if (isActing(ACTION_SWIMUP))
|
{
|
||||||
{
|
// The negative multiplier is deliberate -- it makes the
|
||||||
if (core->getShiftState())
|
// map scroll as though the joystick was controlling the
|
||||||
{
|
// cursor (which is fixed in the center of the screen).
|
||||||
scale.stop();
|
internalOffset += core->joystick.position * (-400*dt / scale.x);
|
||||||
scale += Vector(scrollSpeed*dt, scrollSpeed*dt);
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
internalOffset += Vector(0, amt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (core->joystickEnabled)
|
|
||||||
{
|
|
||||||
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->getShiftState())
|
||||||
{
|
{
|
||||||
|
if (core->getCtrlState())
|
||||||
|
a2 *= 10.0f;
|
||||||
if (core->getKeyState(KEY_UP))
|
if (core->getKeyState(KEY_UP))
|
||||||
activeTile->scale2 += -a2;
|
activeTile->scale2 += -a2;
|
||||||
if (core->getKeyState(KEY_DOWN))
|
if (core->getKeyState(KEY_DOWN))
|
||||||
activeTile->scale2 += a2;
|
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
|
else
|
||||||
{
|
{
|
||||||
if (core->getCtrlState())
|
if (core->getCtrlState())
|
||||||
|
@ -1159,19 +1172,23 @@ void WorldMapRender::onUpdate(float dt)
|
||||||
|
|
||||||
if (core->getKeyState(KEY_F2))
|
if (core->getKeyState(KEY_F2))
|
||||||
{
|
{
|
||||||
dsq->continuity.worldMap.save("data/WorldMap.txt");
|
dsq->continuity.worldMap.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
activeQuad->position = activeTile->gridPos;
|
activeQuad->position = activeTile->gridPos;
|
||||||
activeQuad->scale = Vector(0.25f*activeTile->scale2, 0.25f*activeTile->scale2);
|
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
|
else
|
||||||
{
|
{
|
||||||
#ifdef AQUARIA_BUILD_MAPVIS
|
#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 screenWidth = core->getVirtualWidth() * core->invGlobalScale;
|
||||||
const float screenHeight = core->getVirtualHeight() * 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)
|
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;
|
Vector p;
|
||||||
p = (position/TILE_SIZE) / (256*tile->scale);
|
p = Vector((position.x/TILE_SIZE) / (sizew*tile->scale), (position.y/TILE_SIZE) / (sizeh*tile->scale));
|
||||||
p *= 256*tile->scale*0.25f*tile->scale2;
|
p.x *= sizew*tile->scale*0.25f*tile->scale2;
|
||||||
|
p.y *= sizeh*tile->scale*0.25f*tile->scale2;
|
||||||
if (fromCenter)
|
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)
|
if (tilePos)
|
||||||
p += tile->gridPos;
|
p += tile->gridPos;
|
||||||
return p;
|
return p;
|
||||||
|
@ -1298,7 +1320,7 @@ void WorldMapRender::toggle(bool turnON)
|
||||||
if (dsq->game->miniMapRender->isRadarHide()) return;
|
if (dsq->game->miniMapRender->isRadarHide()) return;
|
||||||
if (alpha.isInterpolating()) return;
|
if (alpha.isInterpolating()) return;
|
||||||
|
|
||||||
if (dsq->mod.isActive()) return;
|
if (dsq->mod.isActive() && !dsq->mod.hasWorldMap()) return;
|
||||||
|
|
||||||
if (dsq->isNested()) 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)
|
void WorldMapRender::action (int id, int state)
|
||||||
{
|
{
|
||||||
if (isOn())
|
if (isOn())
|
||||||
|
@ -1505,7 +1539,7 @@ void WorldMapRender::action (int id, int state)
|
||||||
|
|
||||||
if (editorActive)
|
if (editorActive)
|
||||||
{
|
{
|
||||||
areaLabel->setText("EDITING...");
|
updateEditor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,15 @@ WorldMap::WorldMap()
|
||||||
gw=gh=0;
|
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();
|
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());
|
std::string fn;
|
||||||
|
|
||||||
for (int i = 0; i < worldMapTiles.size(); i++)
|
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];
|
for (int i = 0; i < worldMapTiles.size(); i++)
|
||||||
out << t->index << " " << t->name << " " << t->layer << " " << t->scale << " " << t->gridPos.x << " " << t->gridPos.y << " " << t->prerevealed << " " << t->scale2 << std::endl;
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue