mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-12-25 14:15:46 +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
c78d4d7a11
commit
b20ae992a6
9 changed files with 169 additions and 80 deletions
|
@ -3203,12 +3203,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();
|
||||
|
||||
|
|
|
@ -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<int, std::string> 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<WorldMapTile> WorldMapTiles;
|
||||
WorldMapTiles worldMapTiles;
|
||||
|
||||
private:
|
||||
void _load(const std::string &file);
|
||||
};
|
||||
|
||||
class Path;
|
||||
|
|
|
@ -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()))
|
||||
{
|
||||
|
|
|
@ -102,6 +102,7 @@ protected:
|
|||
unsigned char *savedTexData;
|
||||
bool mb;
|
||||
Vector lastMousePosition; // See FIXME in WorldMapRender.cpp --achurch
|
||||
void updateEditor();
|
||||
};
|
||||
|
||||
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())
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,10 +24,18 @@ StringBank::StringBank()
|
|||
{
|
||||
}
|
||||
|
||||
void StringBank::load(const std::string &file)
|
||||
void StringBank::load()
|
||||
{
|
||||
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+")");
|
||||
stringMap.clear();
|
||||
|
||||
std::ifstream in(file.c_str());
|
||||
|
||||
|
|
|
@ -1029,59 +1029,61 @@ void WorldMapRender::onUpdate(float dt)
|
|||
internalOffset += mouseChange / scale.x;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (activeTile && activeTile->layer == 1)
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,13 +240,21 @@ 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();
|
||||
|
||||
std::string line;
|
||||
|
||||
std::ifstream in(file.c_str());
|
||||
std::ifstream in(file.c_str());
|
||||
|
||||
while (std::getline(in, line))
|
||||
{
|
||||
|
@ -259,15 +267,30 @@ 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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldMap::revealMap(const std::string &name)
|
||||
|
|
Loading…
Reference in a new issue