From fda5b59eb64b49951c82dda990598dcd0e2e4c21 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Fri, 9 Mar 2012 23:35:20 +0400 Subject: [PATCH] Feature #161 (In Progress) Load REC_PGRD records now using vector instead of C arrays fixed path grid edge loading added path grid to cell store implemented dedicated storage class for path grids --- components/esm/loadpgrd.cpp | 54 ++++++++++++--------- components/esm/loadpgrd.hpp | 14 ++---- components/esm_store/cell_store.hpp | 4 ++ components/esm_store/reclists.hpp | 74 +++++++++++++++++++++++++++++ components/esm_store/store.hpp | 3 +- 5 files changed, 115 insertions(+), 34 deletions(-) diff --git a/components/esm/loadpgrd.cpp b/components/esm/loadpgrd.cpp index 6787fab6ed..39684c0803 100644 --- a/components/esm/loadpgrd.cpp +++ b/components/esm/loadpgrd.cpp @@ -3,25 +3,14 @@ namespace ESM { -PathGrid::~PathGrid() { - if (points != NULL) { - delete[] points; - points = NULL; - } - if (edges != NULL) { - delete[] edges; - edges = NULL; - } -} - -void PathGrid::load(ESMReader &esm) +void Pathgrid::load(ESMReader &esm) { esm.getHNT(data, "DATA", 12); cell = esm.getHNString("NAME"); - //std::cout << "loading PGRD for " << cell << " x=" << data.x << " y=" << data.y << std::endl; - - // Remember this file position - context = esm.getContext(); +// std::cout << "loading PGRD for " << +// cell << " x=" << data.x << " y=" << data.y << +// " " << data.s1 +// << std::endl; // Check that the sizes match up. Size = 16 * s2 (path points?) if (esm.isNextSub("PGRP")) @@ -35,8 +24,13 @@ void PathGrid::load(ESMReader &esm) { pointCount = data.s2; //std::cout << "Path grid points count is " << data.s2 << std::endl; - points = new Point[pointCount]; - esm.getExact(points, size); + points.reserve(pointCount); + for (int i = 0; i < pointCount; ++i) + { + Point p; + esm.getExact(&p, sizeof(Point)); + points.push_back(p); + } // for (int i = 0; i < pointCount; ++i) // { // std::cout << i << "'s point: " << points[i].x; @@ -53,16 +47,30 @@ void PathGrid::load(ESMReader &esm) if (esm.isNextSub("PGRC")) { esm.getSubHeader(); + //esm.skipHSub(); int size = esm.getSubSize(); //std::cout << "PGRC size is " << size << std::endl; - if (size % 4 != 0) - esm.fail("PGRC size not a multiple of 4"); + if (size % sizeof(int) != 0) + esm.fail("PGRC size not a multiple of 8"); else { - edgeCount = size / sizeof(Edge); + edgeCount = size / sizeof(int) - 1; //std::cout << "Path grid edge count is " << edgeCount << std::endl; - edges = new Edge[edgeCount]; - esm.getExact(edges, size); + edges.reserve(edgeCount); + int prevValue; + esm.getT(prevValue); + //esm.getExact(&prevValue, sizeof(int)); + for (int i = 0; i < edgeCount; ++i) + { + int nextValue; + esm.getT(nextValue); + //esm.getExact(&nextValue, sizeof(int)); + Edge e; + e.v0 = prevValue; + e.v1 = nextValue; + edges.push_back(e); + prevValue = nextValue; + } // for (int i = 0; i < edgeCount; ++i) // { // std::cout << i << "'s edge: " << edges[i].v0 << " " diff --git a/components/esm/loadpgrd.hpp b/components/esm/loadpgrd.hpp index 6c7de919ca..da9fe33e3e 100644 --- a/components/esm/loadpgrd.hpp +++ b/components/esm/loadpgrd.hpp @@ -9,7 +9,7 @@ namespace ESM /* * Path grid. */ -struct PathGrid +struct Pathgrid { struct DATAstruct { @@ -19,7 +19,6 @@ struct PathGrid short s2; // Number of path points? Size of PGRP block is always 16 * s2; }; // 12 bytes -#pragma pack(push, 1) struct Point // path grid point { int x, y, z; // Location of point @@ -30,22 +29,17 @@ struct PathGrid { int v0, v1; // index of points connected with this edge }; // 8 bytes -#pragma pack(pop) std::string cell; // Cell name DATAstruct data; - Point *points; + std::vector points; int pointCount; - - Edge *edges; + + std::vector edges; int edgeCount; - ESM_Context context; // Context so we can return here later and - // finish the job void load(ESMReader &esm); - - ~PathGrid(); }; } #endif diff --git a/components/esm_store/cell_store.hpp b/components/esm_store/cell_store.hpp index c4bcf84d81..eae2bb7829 100644 --- a/components/esm_store/cell_store.hpp +++ b/components/esm_store/cell_store.hpp @@ -123,6 +123,8 @@ namespace ESMS CellRefList statics; CellRefList weapons; + ESM::Pathgrid *pathgrid; + void load (const ESMStore &store, ESMReader &esm) { if (mState!=State_Loaded) @@ -134,6 +136,8 @@ namespace ESMS loadRefs (store, esm); + pathgrid = store.pathgrids.search(cell->data.gridX, cell->data.gridY, cell->name); + mState = State_Loaded; } } diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 20a2e8ff95..91357286d9 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -390,6 +390,80 @@ namespace ESMS } }; + struct PathgridList : RecList + { + int count; + + // List of grids for interior cells. Indexed by cell name. + typedef std::map IntGrids; + IntGrids intGrids; + + // List of grids for exterior cells. Indexed as extCells[gridX][gridY]. + typedef std::map, ESM::Pathgrid*> ExtGrids; + ExtGrids extGrids; + + PathgridList() : count(0) {} + + ~PathgridList() + { + for (IntGrids::iterator it = intGrids.begin(); it!=intGrids.end(); ++it) + delete it->second; + + for (ExtGrids::iterator it = extGrids.begin(); it!=extGrids.end(); ++it) + delete it->second; + } + + int getSize() { return count; } + + virtual void listIdentifier (std::vector& identifier) const + { + // do nothing + } + + void load(ESMReader &esm, const std::string &id) + { + count++; + ESM::Pathgrid *grid = new ESM::Pathgrid; + grid->load(esm); + if (grid->data.x == 0 && grid->data.y) + { + intGrids[grid->cell] = grid; + } + else + { + extGrids[std::make_pair(grid->data.x, grid->data.y)] = grid; + } + } + + Pathgrid *find(int cellX, int cellY, std::string cellName) const + { + Pathgrid *result = search(cellX, cellY, cellName); + if (!result) + { + throw std::runtime_error("no pathgrid found for cell " + cellName); + } + return result; + } + + Pathgrid *search(int cellX, int cellY, std::string cellName) const + { + Pathgrid *result = NULL; + if (cellX == 0 && cellY == 0) // possibly interior + { + IntGrids::const_iterator it = intGrids.find(cellName); + if (it != intGrids.end()) + result = it->second; + } + else + { + ExtGrids::const_iterator it = extGrids.find(std::make_pair(cellX, cellY)); + if (it != extGrids.end()) + result = it->second; + } + return result; + } + }; + template struct ScriptListT : RecList { diff --git a/components/esm_store/store.hpp b/components/esm_store/store.hpp index e5d173cb8b..fab04d3e97 100644 --- a/components/esm_store/store.hpp +++ b/components/esm_store/store.hpp @@ -74,7 +74,8 @@ namespace ESMS ScriptListT