From 5f84b680afaf8b7b69ab2b9623f8356dd2b72393 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 Sep 2010 11:55:28 +0200 Subject: [PATCH 1/7] implemented exterior coc --- apps/openmw/mwscript/cellextensions.cpp | 15 +++++++++++-- apps/openmw/mwworld/world.cpp | 14 ++++++++++++ apps/openmw/mwworld/world.hpp | 3 +++ components/esm_store/reclists.hpp | 30 +++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index 93e77ee48..cf0f02a93 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -41,9 +41,20 @@ namespace MWScript runtime.pop(); ESM::Position pos; - pos.pos[0] = pos.pos[1] = pos.pos[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; - context.getWorld().changeCell (cell, pos); + pos.pos[2] = 0; + + if (const ESM::Cell *exterior = context.getWorld().getExterior (cell)) + { + context.getWorld().indexToPosition (exterior->data.gridX, exterior->data.gridY, + pos.pos[0], pos.pos[1]); + context.getWorld().changeToExteriorCell (pos); + } + else + { + pos.pos[0] = pos.pos[1] = 0; + context.getWorld().changeCell (cell, pos); + } } }; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 496da44ef..056d33c6b 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -691,6 +691,20 @@ namespace MWWorld changeCell (x, y, position); } + const ESM::Cell *World::getExterior (const std::string& cellName) const + { + // first try named cells + if (const ESM::Cell *cell = mStore.cells.searchExtByName (cellName)) + return cell; + + // didn't work -> now check for regions + if (mStore.regions.search (cellName)) + if (const ESM::Cell *cell = mStore.cells.searchExtByRegion (cellName)) + return cell; + + return 0; + } + void World::markCellAsUnchanged() { mCellChanged = false; diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 2ff2d3ccc..395b279d7 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -145,6 +145,9 @@ namespace MWWorld void changeToExteriorCell (const ESM::Position& position); + const ESM::Cell *getExterior (const std::string& cellName) const; + ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. + void markCellAsUnchanged(); std::string getFacedHandle(); diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 3711a20b1..823433f56 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -209,6 +209,36 @@ namespace ESMS return it2->second; } + const Cell *searchExtByName (const std::string& id) const + { + for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter) + { + const ExtCellsCol& column = iter->second; + for (ExtCellsCol::const_iterator iter = column.begin(); iter!=column.end(); ++iter) + { + if (iter->second->name==id) + return iter->second; + } + } + + return 0; + } + + const Cell *searchExtByRegion (const std::string& id) const + { + for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter) + { + const ExtCellsCol& column = iter->second; + for (ExtCellsCol::const_iterator iter = column.begin(); iter!=column.end(); ++iter) + { + if (iter->second->region==id) + return iter->second; + } + } + + return 0; + } + void load(ESMReader &esm, const std::string &id) { using namespace std; From db2b23832809651ff757b66037ab29d123a94ab2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 Sep 2010 12:21:55 +0200 Subject: [PATCH 2/7] adjusted coordinates for coc/coe for exteriors (place player in the middle of the cell instead of at the border) --- apps/openmw/mwscript/cellextensions.cpp | 4 ++-- apps/openmw/mwworld/world.cpp | 8 +++++++- apps/openmw/mwworld/world.hpp | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index cf0f02a93..4d3025469 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -47,7 +47,7 @@ namespace MWScript if (const ESM::Cell *exterior = context.getWorld().getExterior (cell)) { context.getWorld().indexToPosition (exterior->data.gridX, exterior->data.gridY, - pos.pos[0], pos.pos[1]); + pos.pos[0], pos.pos[1], true); context.getWorld().changeToExteriorCell (pos); } else @@ -75,7 +75,7 @@ namespace MWScript ESM::Position pos; - context.getWorld().indexToPosition (x, y, pos.pos[0], pos.pos[1]); + context.getWorld().indexToPosition (x, y, pos.pos[0], pos.pos[1], true); pos.pos[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 056d33c6b..de3c1ab5c 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -770,12 +770,18 @@ namespace MWWorld // TODO cell change for non-player ref } - void World::indexToPosition (int cellX, int cellY, float &x, float &y) const + void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const { const int cellSize = 8192; x = cellSize * cellX; y = cellSize * cellY; + + if (centre) + { + x += cellSize/2; + y += cellSize/2; + } } void World::positionToIndex (float x, float y, int &cellX, int &cellY) const diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 395b279d7..832c90bf0 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -157,7 +157,7 @@ namespace MWWorld void moveObject (Ptr ptr, float x, float y, float z); - void indexToPosition (int cellX, int cellY, float &x, float &y) const; + void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) const; ///< Convert cell numbers to position. void positionToIndex (float x, float y, int &cellX, int &cellY) const; From 814d721e33d7914648b51be62b7d3a75402d52ca Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 Sep 2010 15:12:42 +0200 Subject: [PATCH 3/7] build external cell names from name of region instead of from internal region id --- apps/openmw/mwworld/world.cpp | 16 +++++++++++++--- components/esm_store/reclists.hpp | 4 +++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index de3c1ab5c..ca29facfd 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -698,9 +698,19 @@ namespace MWWorld return cell; // didn't work -> now check for regions - if (mStore.regions.search (cellName)) - if (const ESM::Cell *cell = mStore.cells.searchExtByRegion (cellName)) - return cell; + std::string cellName2 = ESMS::RecListT::toLower (cellName); + + for (ESMS::RecListT::MapType::const_iterator iter (mStore.regions.list.begin()); + iter!=mStore.regions.list.end(); ++iter) + { + if (ESMS::RecListT::toLower (iter->second.name)==cellName2) + { + if (const ESM::Cell *cell = mStore.cells.searchExtByRegion (iter->first)) + return cell; + + break; + } + } return 0; } diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 823433f56..81b0d6054 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -226,12 +226,14 @@ namespace ESMS const Cell *searchExtByRegion (const std::string& id) const { + std::string id2 = toLower (id); + for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter) { const ExtCellsCol& column = iter->second; for (ExtCellsCol::const_iterator iter = column.begin(); iter!=column.end(); ++iter) { - if (iter->second->region==id) + if (toLower (iter->second->region)==id) return iter->second; } } From 0414d7f862951924d37599b0bee788439f061f02 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 12 Sep 2010 09:34:45 +0200 Subject: [PATCH 4/7] load skill and magic effect records --- components/esm/loadskil.hpp | 1 + components/esm_store/reclists.hpp | 49 ++++++++++++++++++++++++++++--- components/esm_store/store.cpp | 10 +++++-- components/esm_store/store.hpp | 6 ++-- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/components/esm/loadskil.hpp b/components/esm/loadskil.hpp index 0e5585ac6..9ccde237d 100644 --- a/components/esm/loadskil.hpp +++ b/components/esm/loadskil.hpp @@ -32,6 +32,7 @@ struct Skill void load(ESMReader &esm) { + esm.getHNT(index, "INDX"); esm.getHNT(data, "SKDT", 24); description = esm.getHNOString("DESC"); } diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 81b0d6054..8b19b0cf1 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -308,12 +308,53 @@ namespace ESMS int getSize() { return list.size(); } }; + template + struct IndexListT + { + typedef std::map MapType; + + MapType list; + + void load(ESMReader &esm) + { + X ref; + ref.load (esm); + int index = ref.index; + list[index] = ref; + } + + int getSize() + { + return list.size(); + } + + // Find the given object ID, or return NULL if not found. + const X* search (int id) const + { + if (list.find (id) == list.end()) + return NULL; + + return &list.find(id)->second; + } + + // Find the given object ID (throws an exception if not found) + const X* find (int id) const + { + const X *object = search (id); + + if (!object) + { + std::ostringstream error; + error << "object " << id << " not found"; + throw std::runtime_error (error.str()); + } + + return object; + } + }; + /* We need special lists for: - Magic effects - Skills - Dialog / Info combo - Scripts Land Path grids Land textures diff --git a/components/esm_store/store.cpp b/components/esm_store/store.cpp index c43855873..8204c6304 100644 --- a/components/esm_store/store.cpp +++ b/components/esm_store/store.cpp @@ -46,15 +46,21 @@ void ESMStore::load(ESMReader &esm) { std::cerr << "error: info record without dialog" << std::endl; esm.skipRecord(); - continue; } } + else if (n.val==ESM::REC_MGEF) + { + magicEffects.load (esm); + } + else if (n.val==ESM::REC_SKIL) + { + skills.load (esm); + } else { // Not found (this would be an error later) esm.skipRecord(); missing.insert(n.toString()); - continue; } } else diff --git a/components/esm_store/store.hpp b/components/esm_store/store.hpp index 1b9184aa6..b0f75785d 100644 --- a/components/esm_store/store.hpp +++ b/components/esm_store/store.hpp @@ -71,9 +71,9 @@ namespace ESMS RecIDListT gameSettings; //RecListT lands; //RecListT landTexts; - //RecListT magicEffects; + IndexListT magicEffects; ScriptListT