mirror of https://github.com/OpenMW/openmw.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
7.0 KiB
C++
155 lines
7.0 KiB
C++
/*
|
|
Copyright (C) 2016, 2018, 2020 cc9cii
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
cc9cii cc9c@iinet.net.au
|
|
|
|
Much of the information on the data structures are based on the information
|
|
from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
|
|
trial & error. See http://en.uesp.net/wiki for details.
|
|
|
|
*/
|
|
#ifndef ESM4_GRUP_H
|
|
#define ESM4_GRUP_H
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
#include "common.hpp" // GroupLabel
|
|
|
|
namespace ESM4
|
|
{
|
|
// http://www.uesp.net/wiki/Tes4Mod:Mod_File_Format#Hierarchical_Top_Groups
|
|
//
|
|
// Type | Info |
|
|
// ------+--------------------------------------+-------------------
|
|
// 2 | Interior Cell Block |
|
|
// 3 | Interior Cell Sub-Block |
|
|
// R | CELL |
|
|
// 6 | Cell Childen |
|
|
// 8 | Persistent children |
|
|
// R | REFR, ACHR, ACRE |
|
|
// 10 | Visible distant children |
|
|
// R | REFR, ACHR, ACRE |
|
|
// 9 | Temp Children |
|
|
// R | PGRD |
|
|
// R | REFR, ACHR, ACRE |
|
|
// | |
|
|
// 0 | Top (Type) |
|
|
// R | WRLD |
|
|
// 1 | World Children |
|
|
// R | ROAD |
|
|
// R | CELL |
|
|
// 6 | Cell Childen |
|
|
// 8 | Persistent children |
|
|
// R | REFR, ACHR, ACRE |
|
|
// 10 | Visible distant children |
|
|
// R | REFR, ACHR, ACRE |
|
|
// 9 | Temp Children |
|
|
// R | PGRD |
|
|
// R | REFR, ACHR, ACRE |
|
|
// 4 | Exterior World Block |
|
|
// 5 | Exterior World Sub-block |
|
|
// R | CELL |
|
|
// 6 | Cell Childen |
|
|
// 8 | Persistent children |
|
|
// R | REFR, ACHR, ACRE |
|
|
// 10 | Visible distant children |
|
|
// R | REFR, ACHR, ACRE |
|
|
// 9 | Temp Children |
|
|
// R | LAND |
|
|
// R | PGRD |
|
|
// R | REFR, ACHR, ACRE |
|
|
//
|
|
struct WorldGroup
|
|
{
|
|
FormId mWorld; // WRLD record for this group
|
|
|
|
// occurs only after World Child (type 1)
|
|
// since GRUP label may not be reliable, need to keep the formid of the current WRLD in
|
|
// the reader's context
|
|
FormId mRoad;
|
|
|
|
std::vector<FormId> mCells; // FIXME should this be CellGroup* instead?
|
|
};
|
|
|
|
// http://www.uesp.net/wiki/Tes4Mod:Mod_File_Format/CELL
|
|
//
|
|
// The block and subblock groups for an interior cell are determined by the last two decimal
|
|
// digits of the lower 3 bytes of the cell form ID (the modindex is not included in the
|
|
// calculation). For example, for form ID 0x000CF2=3314, the block is 4 and the subblock is 1.
|
|
//
|
|
// The block and subblock groups for an exterior cell are determined by the X-Y coordinates of
|
|
// the cell. Each block contains 16 subblocks (4x4) and each subblock contains 64 cells (8x8).
|
|
// So each block contains 1024 cells (32x32).
|
|
//
|
|
// NOTE: There may be many CELL records in one subblock
|
|
struct CellGroup
|
|
{
|
|
FormId mCell; // CELL record for this cell group
|
|
int mCellModIndex; // from which file to get the CELL record (e.g. may have been updated)
|
|
|
|
// For retrieving parent group size (for lazy loading or skipping) and sub-block number / grid
|
|
// NOTE: There can be more than one file that adds/modifies records to this cell group
|
|
//
|
|
// Use Case 1: To quickly get only the visble when distant records:
|
|
//
|
|
// - Find the FormId of the CELL (maybe WRLD/X/Y grid lookup or from XTEL of a REFR)
|
|
// - search a map of CELL FormId to CellGroup
|
|
// - load CELL and its child groups (or load the visible distant only, or whatever)
|
|
//
|
|
// Use Case 2: Scan the files but don't load CELL or cell group
|
|
//
|
|
// - Load referenceables and other records up front, updating them as required
|
|
// - Don't load CELL, LAND, PGRD or ROAD (keep FormId's and file index, and file
|
|
// context then skip the rest of the group)
|
|
//
|
|
std::vector<GroupTypeHeader> mHeaders; // FIXME: is this needed?
|
|
|
|
// FIXME: should these be pairs? i.e. <FormId, modindex> so that we know from which file
|
|
// the formid came (it may have been updated by a mod)
|
|
// but does it matter? the record itself keeps track of whether it is base,
|
|
// added or modified anyway
|
|
// FIXME: should these be maps? e.g. std::map<FormId, std::uint8_t>
|
|
// or vector for storage with a corresponding map of index?
|
|
|
|
// cache (modindex adjusted) formId's of children
|
|
// FIXME: also need file index + file context of all those that has type 8 GRUP
|
|
GroupTypeHeader mHdrPersist;
|
|
std::vector<FormId> mPersistent; // REFR, ACHR, ACRE
|
|
std::vector<FormId> mdelPersistent;
|
|
|
|
// FIXME: also need file index + file context of all those that has type 10 GRUP
|
|
GroupTypeHeader mHdrVisDist;
|
|
std::vector<FormId> mVisibleDist; // REFR, ACHR, ACRE
|
|
std::vector<FormId> mdelVisibleDist;
|
|
|
|
// FIXME: also need file index + file context of all those that has type 9 GRUP
|
|
GroupTypeHeader mHdrTemp;
|
|
FormId mLand; // if present, assume only one LAND per exterior CELL
|
|
FormId mPgrd; // if present, seems to be the first record after LAND in Temp Cell Child GRUP
|
|
std::vector<FormId> mTemporary; // REFR, ACHR, ACRE
|
|
std::vector<FormId> mdelTemporary;
|
|
|
|
// need to keep modindex and context for lazy loading (of all the files that contribute
|
|
// to this group)
|
|
};
|
|
}
|
|
|
|
#endif // ESM4_GRUP_H
|