mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	Finished cell loading code in esm/loadcell.hpp
This commit is contained in:
		
							parent
							
								
									7238847b8b
								
							
						
					
					
						commit
						5d2394a78b
					
				
					 2 changed files with 184 additions and 14 deletions
				
			
		
							
								
								
									
										11
									
								
								esm/defs.hpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								esm/defs.hpp
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -5,6 +5,9 @@
 | 
			
		|||
 | 
			
		||||
namespace ESM {
 | 
			
		||||
 | 
			
		||||
// Pixel color value. Standard four-byte rr,gg,bb,aa format.
 | 
			
		||||
typedef int32_t Color;
 | 
			
		||||
 | 
			
		||||
enum VarType
 | 
			
		||||
  {
 | 
			
		||||
    VT_Unknown,
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +46,14 @@ struct SpellList
 | 
			
		|||
*/
 | 
			
		||||
#pragma pack(push)
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
 | 
			
		||||
// Position and rotation
 | 
			
		||||
struct Position
 | 
			
		||||
{
 | 
			
		||||
  float pos[3];
 | 
			
		||||
  float rot[3];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ENAMstruct
 | 
			
		||||
{
 | 
			
		||||
  // Magical effect, hard-coded ID
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										187
									
								
								esm/loadcell.hpp
									
									
									
									
									
								
							
							
						
						
									
										187
									
								
								esm/loadcell.hpp
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -2,9 +2,77 @@
 | 
			
		|||
#define _ESM_CELL_H
 | 
			
		||||
 | 
			
		||||
#include "esm_reader.hpp"
 | 
			
		||||
#include "defs.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM {
 | 
			
		||||
 | 
			
		||||
/* Cell reference. This represents ONE object (of many) inside the
 | 
			
		||||
   cell. The cell references are not loaded as part of the normal
 | 
			
		||||
   loading process, but are rather loaded later on demand when we are
 | 
			
		||||
   setting up a specific cell.
 | 
			
		||||
 */
 | 
			
		||||
struct CellRef
 | 
			
		||||
{
 | 
			
		||||
  int refnum;           // Reference number
 | 
			
		||||
  std::string refID;    // ID of object being referenced
 | 
			
		||||
 | 
			
		||||
  float scale;          // Scale applied to mesh
 | 
			
		||||
 | 
			
		||||
  // The NPC that owns this object (and will get angry if you steal
 | 
			
		||||
  // it)
 | 
			
		||||
  std::string owner;
 | 
			
		||||
 | 
			
		||||
  // I have no idea, looks like a link to a global variable?
 | 
			
		||||
  std::string glob;
 | 
			
		||||
 | 
			
		||||
  // ID of creature trapped in this soul gem (?)
 | 
			
		||||
  std::string soul;
 | 
			
		||||
 | 
			
		||||
  // ?? CNAM has a faction name, might be for objects/beds etc
 | 
			
		||||
  // belonging to a faction.
 | 
			
		||||
  std::string faction;
 | 
			
		||||
 | 
			
		||||
  // INDX might be PC faction rank required to use the item? Sometimes
 | 
			
		||||
  // is -1, which I assume means "any rank".
 | 
			
		||||
  int factIndex;
 | 
			
		||||
 | 
			
		||||
  // Depends on context - possibly weapon health, number of uses left
 | 
			
		||||
  // or weapon magic charge?
 | 
			
		||||
  float charge;
 | 
			
		||||
 | 
			
		||||
  // I have no idea, these are present some times, often along with
 | 
			
		||||
  // owner (ANAM) and sometimes otherwise. Is NAM9 is always 1?  INTV
 | 
			
		||||
  // is usually one, but big for lights. Perhaps something to do with
 | 
			
		||||
  // remaining light "charge". I haven't tried reading it as a float
 | 
			
		||||
  // in those cases.
 | 
			
		||||
  int intv, nam9;
 | 
			
		||||
 | 
			
		||||
  // For doors - true if this door teleports to somewhere else, false
 | 
			
		||||
  // if it should open through animation.
 | 
			
		||||
  bool teleport;
 | 
			
		||||
 | 
			
		||||
  // Teleport location for the door, if this is a teleporting door.
 | 
			
		||||
  Position doorDest;
 | 
			
		||||
 | 
			
		||||
  // Destination cell for doors (optional)
 | 
			
		||||
  std::string destCell;
 | 
			
		||||
 | 
			
		||||
  // Lock level for doors and containers
 | 
			
		||||
  int lockLevel;
 | 
			
		||||
  std::string key, trap; // Key and trap ID names, if any
 | 
			
		||||
 | 
			
		||||
  // No idea - occurs ONCE in Morrowind.esm, for an activator
 | 
			
		||||
  char unam;
 | 
			
		||||
 | 
			
		||||
  // Occurs in Tribunal.esm, eg. in the cell "Mournhold, Plaza
 | 
			
		||||
  // Brindisi Dorom", where it has the value 100. Also only for
 | 
			
		||||
  // activators.
 | 
			
		||||
  int fltv;
 | 
			
		||||
 | 
			
		||||
  // Position and rotation of this object within the cell
 | 
			
		||||
  Position pos;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Cells hold data about objects, creatures, statics (rocks, walls,
 | 
			
		||||
   buildings) and landscape (for exterior cells). Cells frequently
 | 
			
		||||
   also has other associated LAND and PGRD records. Combined, all this
 | 
			
		||||
| 
						 | 
				
			
			@ -12,12 +80,7 @@ namespace ESM {
 | 
			
		|||
   the strategy we use is to remember the file position of each cell
 | 
			
		||||
   (using ESMReader::getContext()) and jumping back into place
 | 
			
		||||
   whenever we need to load a given cell.
 | 
			
		||||
 | 
			
		||||
   TODO: We should handle the actual cell content loading in this file
 | 
			
		||||
   too, although the solution should be as open as possible and let
 | 
			
		||||
   the user handle all data storage.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct Cell
 | 
			
		||||
{
 | 
			
		||||
  enum Flags
 | 
			
		||||
| 
						 | 
				
			
			@ -35,34 +98,130 @@ struct Cell
 | 
			
		|||
    int gridX, gridY;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct AMBIstruct
 | 
			
		||||
  {
 | 
			
		||||
    Color ambient, sunlight, fog;
 | 
			
		||||
    float fogDensity;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Interior cells are indexed by this (it's the 'id'), for exterior
 | 
			
		||||
  // cells it is optional.
 | 
			
		||||
  std::string name,
 | 
			
		||||
 | 
			
		||||
  // Optional region name for exterior cells.
 | 
			
		||||
  // Optional region name for exterior and quasi-exterior cells.
 | 
			
		||||
    region;
 | 
			
		||||
 | 
			
		||||
  // File position
 | 
			
		||||
  ESM_Context context;
 | 
			
		||||
 | 
			
		||||
  ESM_Context context; // File position
 | 
			
		||||
  DATAstruct data;
 | 
			
		||||
  AMBIstruct ambi;
 | 
			
		||||
  int water; // Water level
 | 
			
		||||
  int mapColor;
 | 
			
		||||
 | 
			
		||||
  void load(ESMReader &esm)
 | 
			
		||||
  {
 | 
			
		||||
    // This is implicit?
 | 
			
		||||
    //name = esm.getHNString("NAME");
 | 
			
		||||
 | 
			
		||||
    // Ignore this for now, it might mean we should delete the entire
 | 
			
		||||
    // cell?
 | 
			
		||||
    if(esm.isNextSub("DELE")) esm.skipHSub();
 | 
			
		||||
 | 
			
		||||
    esm.getHNT(data, "DATA", 12);
 | 
			
		||||
    region = esm.getHNOString("RGNN");
 | 
			
		||||
 | 
			
		||||
    // Save position and move on
 | 
			
		||||
    // Water level
 | 
			
		||||
    water = 0;
 | 
			
		||||
 | 
			
		||||
    if(data.flags & Interior)
 | 
			
		||||
      {
 | 
			
		||||
        // Interior cells
 | 
			
		||||
 | 
			
		||||
        if(esm.isNextSub("INTV") || esm.isNextSub("WHGT"))
 | 
			
		||||
          esm.getHT(water);
 | 
			
		||||
 | 
			
		||||
        // Quasi-exterior cells have a region (which determines the
 | 
			
		||||
        // weather), pure interior cells have ambient lighting
 | 
			
		||||
        // instead.
 | 
			
		||||
        if(data.flags & QuasiEx)
 | 
			
		||||
          region = esm.getHNOString("RGNN");
 | 
			
		||||
        else
 | 
			
		||||
          esm.getHNT(ambi, "AMBI", 16);
 | 
			
		||||
      }
 | 
			
		||||
    else
 | 
			
		||||
      {
 | 
			
		||||
        // Exterior cells
 | 
			
		||||
        region = esm.getHNOString("RGNN");
 | 
			
		||||
        esm.getHNOT(mapColor, "NAM5");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    // Save position of the cell references and move on
 | 
			
		||||
    context = esm.getContext();
 | 
			
		||||
    esm.skipRecord();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Restore the given reader to the stored position. Will try to open
 | 
			
		||||
  // the file matching the stored file name. If you want to read from
 | 
			
		||||
  // somewhere other than the file system, you need to pre-open the
 | 
			
		||||
  // ESMReader, and the filename must match the stored filename
 | 
			
		||||
  // exactly.
 | 
			
		||||
  void restore(ESMReader &esm)
 | 
			
		||||
  { esm.restoreContext(context); }
 | 
			
		||||
 | 
			
		||||
  // Get the next reference in this cell, if any. Returns false when
 | 
			
		||||
  // there are no more references in the cell.
 | 
			
		||||
  bool getNextRef(ESMReader &esm, CellRef &ref)
 | 
			
		||||
  {
 | 
			
		||||
    if(!esm.hasMoreSubs()) return false;
 | 
			
		||||
 | 
			
		||||
    // Number of references in the cell? Maximum once in each cell,
 | 
			
		||||
    // but not always at the beginning, and not always right. In other
 | 
			
		||||
    // words, completely useless.
 | 
			
		||||
    {
 | 
			
		||||
      int i;
 | 
			
		||||
      esm.getHNOT(i, "NAM0");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    esm.getHNT(ref.refnum, "FRMR");
 | 
			
		||||
    ref.refID = esm.getHNString("NAME");
 | 
			
		||||
 | 
			
		||||
    // getHNOT will not change the existing value (1.0) if the
 | 
			
		||||
    // subrecord is missing
 | 
			
		||||
    ref.scale = 1.0;
 | 
			
		||||
    esm.getHNOT(ref.scale, "XSCL");
 | 
			
		||||
 | 
			
		||||
    ref.owner = esm.getHNOString("ANAM");
 | 
			
		||||
    ref.glob = esm.getHNOString("BNAM");
 | 
			
		||||
    ref.soul = esm.getHNOString("XSOL");
 | 
			
		||||
 | 
			
		||||
    ref.faction = esm.getHNOString("CNAM");
 | 
			
		||||
    esm.getHNOT(ref.factIndex, "INDX");
 | 
			
		||||
 | 
			
		||||
    ref.charge = 0.0;
 | 
			
		||||
    esm.getHNOT(ref.charge, "XCHG");
 | 
			
		||||
 | 
			
		||||
    ref.intv = 0;
 | 
			
		||||
    ref.nam9 = 0;
 | 
			
		||||
    esm.getHNOT(ref.intv, "INTV");
 | 
			
		||||
    esm.getHNOT(ref.nam9, "NAM9");
 | 
			
		||||
 | 
			
		||||
    // Present for doors that teleport you to another cell.
 | 
			
		||||
    if(esm.isNextSub("DODT"))
 | 
			
		||||
      {
 | 
			
		||||
        ref.teleport = true;
 | 
			
		||||
        esm.getHT(ref.doorDest);
 | 
			
		||||
        ref.destCell = esm.getHNOString("DNAM");
 | 
			
		||||
      }
 | 
			
		||||
    else ref.teleport = false;
 | 
			
		||||
 | 
			
		||||
    esm.getHNOT(ref.lockLevel, "FLTV"); // int, despite the name
 | 
			
		||||
    ref.key = esm.getHNOString("KNAM");
 | 
			
		||||
    ref.trap = esm.getHNOString("TNAM");
 | 
			
		||||
 | 
			
		||||
    ref.unam = 0;
 | 
			
		||||
    ref.fltv = 0;
 | 
			
		||||
    esm.getHNOT(ref.unam, "UNAM");
 | 
			
		||||
    esm.getHNOT(ref.fltv, "FLTV");
 | 
			
		||||
 | 
			
		||||
    esm.getHNT(ref.pos, "DATA", 24);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue