Difference between revisions of "MapEnts Asset"

From COD Engine Research
Jump to: navigation, search
(Black Ops 2)
(Advanced Warfare)
 
(6 intermediate revisions by one user not shown)
Line 92: Line 92:
 
Black Ops 2 adds similar data to Modern Warfare 2 to the end of it's asset, believed to be buffer data.
 
Black Ops 2 adds similar data to Modern Warfare 2 to the end of it's asset, believed to be buffer data.
 
<syntaxhighlight lang="cpp">
 
<syntaxhighlight lang="cpp">
struct unknownInternalMapEnts1
+
struct TriggerModel
 
{
 
{
   int unknownCount1;
+
   int contents;
   char * unknownData1; //size = unknownCount1 << 3
+
   unsigned __int16 hullCount;
   int unknownCount2;
+
  unsigned __int16 firstHull;
   char * unknownData2; //size = unknownCount2 << 5
+
};
   int unknownCount3;
+
 
   BYTE * unknownData3; //size = ((unknownCount3 << 2) + unknownCount3) << 2
+
struct TriggerHull
 +
{
 +
  Bounds bounds;
 +
  int contents;
 +
  unsigned __int16 slabCount;
 +
  unsigned __int16 firstSlab;
 +
};
 +
 
 +
struct TriggerSlab
 +
{
 +
  vec3_t dir;
 +
  float midPoint;
 +
  float halfSize;
 +
};
 +
 
 +
struct MapTriggers
 +
{
 +
  unsigned int count;
 +
  TriggerModel *models;
 +
   unsigned int hullCount;
 +
   TriggerHull *hulls;
 +
   unsigned int slabCount;
 +
   TriggerSlab *slabs;
 
};
 
};
  
Line 110: Line 132:
 
};
 
};
 
</syntaxhighlight>
 
</syntaxhighlight>
Keep in mind that the unknownInternalMapEnts1 is also used in the addon_map_ents asset.
 
  
 
== Ghosts ==
 
== Ghosts ==
 
Ghosts provides a fundamental change to the way the map_ents asset works, because while the entityString still exists it goes unused.
 
Ghosts provides a fundamental change to the way the map_ents asset works, because while the entityString still exists it goes unused.
 
<syntaxhighlight lang="cpp">
 
<syntaxhighlight lang="cpp">
struct unknownInternalMapEnts1
+
struct Bounds
 
{
 
{
   int unknownCount1;
+
   float midPoint[3];
   char * unknownData1; //size = unknownCount1 << 3
+
   float halfSize[3];
  int unknownCount2;
+
  char * unknownData2; //size = unknownCount2 << 5
+
  int unknownCount3;
+
  char * unknownData3; //size = ((unknownCount3 << 2) + unknownCount3) << 2
+
 
};
 
};
  
struct unknownInternalMapEnts2
+
struct TriggerModel
 
{
 
{
  unknownInternalMapEnts1 unknownStruct1;
+
   int contents;
  short unknownCount1;
+
   unsigned __int16 hullCount;
  char * unknownData1; //size = unknownCount1 * 0x1C
+
   unsigned __int16 firstHull;
   int unknownCount2;
+
  char * unknownData2; //size = unknownCount2
+
  char * unknownData3; //size = unknownStruct1->unknownCount1 << 1
+
  char * unknownData4; //size = unknownStruct1->unknownCount1
+
  char * unknownData5; //size = ((unknownStruct1->unknownCount1 << 1) + unknownStruct1->unknownCount1) << 2
+
  char * unknownData6; //size = unknownStruct1->unknownCount1 << 2
+
  char * unknownData7; //size = unknownStruct1->unknownCount1 << 1
+
   char * unknownData8; //size = unknownStruct1->unknownCount1 << 1
+
   char * unknownData9; //size = unknownStruct1->unknownCount1 << 1
+
 
};
 
};
  
struct unknownInternalMapEnts3
+
struct TriggerHull
 
{
 
{
   short unknownCount;
+
   Bounds bounds;
   char * unknownData; //size = unknownCount * 0x1C
+
   int contents;
 +
  unsigned __int16 slabCount;
 +
  unsigned __int16 firstSlab;
 
};
 
};
  
struct unknownInternalMapEnts4Internal1
+
struct TriggerSlab
 
{
 
{
   short unknown1;
+
   float dir[3];
   ScriptString unknownScriptString1;
+
   float midPoint;
   ScriptString unknownScriptString2;
+
   float halfSize;
  ScriptString unknownScriptString2;
+
  char unknown2[0x18];
+
 
};
 
};
  
struct unknownInternalMapEnts4
+
struct MapTriggers
 
{
 
{
   short unknownCount;
+
   unsigned int count;
   unknownInternalMapEnts4Internal1 * unknownStruct; //Count = unknownCount
+
   TriggerModel *models;
 +
  unsigned int hullCount;
 +
  TriggerHull *hulls;
 +
  unsigned int slabCount;
 +
  TriggerSlab *slabs;
 
};
 
};
  
struct unknownInternalMapEnts5Internal1Internal1
+
struct ClientTriggerAabbNode
 
{
 
{
   char unknown1[8];
+
   Bounds bounds;
   char (*unknown2)[0x40];
+
   unsigned __int16 firstChild;
   char unknown3[0x28];
+
   unsigned __int16 childCount;
  char (*unknown4)[0x30];
+
  char (*unknown5)[0x24];
+
 
};
 
};
  
struct unknownInternalMapEnts5Internal1
+
struct ClientTriggers
 
{
 
{
   short unknownCount;
+
   MapTriggers trigger;
   int unknown;
+
   unsigned __int16 numClientTriggerNodes;
   unknownInternalMapEnts5Internal1Internal1 * unknownStruct; //Count = unknownCount
+
  ClientTriggerAabbNode *clientTriggerAabbTree;
 +
  unsigned int triggerStringLength;
 +
  char *triggerString;
 +
  __int16 *visionSetTriggers;
 +
  char *triggerType;
 +
  float (*origins)[3];
 +
  float *scriptDelay;
 +
  __int16 *audioTriggers;
 +
  __int16 *blendLookup;
 +
   __int16 *npcTriggers;
 
};
 
};
  
struct unknownInternalMapEnts5
+
struct ClientTriggerBlendNode
 
{
 
{
   short unknownCount;
+
   float pointA[3];
   unknownInternalMapEnts5Internal1 * unknownStruct; //Count = unknownCount
+
   float pointB[3];
 +
  unsigned __int16 triggerA;
 +
  unsigned __int16 triggerB;
 +
};
 +
 
 +
struct ClientTriggerBlend
 +
{
 +
  unsigned __int16 numClientTriggerBlendNodes;
 +
  ClientTriggerBlendNode *blendNodes;
 +
};
 +
 
 +
struct SpawnPointEntityRecord
 +
{
 +
  unsigned __int16 index;
 +
  scr_string_t name;
 +
  scr_string_t target;
 +
  scr_string_t script_noteworthy;
 +
  float origin[3];
 +
  float angles[3];
 +
};
 +
 
 +
struct SpawnPointRecordList
 +
{
 +
  unsigned __int16 spawnsCount;
 +
  SpawnPointEntityRecord *spawns;
 +
};
 +
 
 +
struct SplinePointEntityRecord
 +
{
 +
  int splineId;
 +
  int splineNodeId;
 +
  char *splineNodeLabel;
 +
  float splineNodeTension;
 +
  float origin[3];
 +
  float corridorDims[2];
 +
  float tangent[3];
 +
  float distToNextNode;
 +
  float (*positionCubic)[3];
 +
  float (*tangentQuadratic)[3];
 +
};
 +
 
 +
struct SplinePointRecordList
 +
{
 +
  unsigned __int16 splinePointCount;
 +
  float splineLength;
 +
  SplinePointEntityRecord *splinePoints;
 +
};
 +
 
 +
struct SplineRecordList
 +
{
 +
  unsigned __int16 splineCount;
 +
  SplinePointRecordList *splines;
 
};
 
};
  
Line 189: Line 259:
 
   char *entityString;
 
   char *entityString;
 
   int numEntityChars;
 
   int numEntityChars;
      unknownInternalMapEnts1 unknownStruct1;
+
  MapTriggers trigger;
      unknownInternalMapEnts2 unknownStruct2;
+
  ClientTriggers clientTrigger;
      unknownInternalMapEnts3 unknownStruct3;
+
  ClientTriggerBlend clientTriggerBlend;
      unknownInternalMapEnts4 unknownStruct4;
+
  SpawnPointRecordList spawnList;
      unknownInternalMapEnts5 unknownStruct5;
+
  SplineRecordList splineList;
 
};
 
};
 
</syntaxhighlight>
 
</syntaxhighlight>
Keep in mind that the unknownInternalMapEnts1 is also used in the addon_map_ents and col_map_mp (clipMap) assets.
+
 
 
== Advanced Warfare ==
 
== Advanced Warfare ==
Ghosts provides a fundamental change to the way the map_ents asset works, because while the entityString still exists it goes unused.
+
Advanced Warfare provides a fundamental change to the way the map_ents asset works, because while the entityString still exists it goes unused.
 
<syntaxhighlight lang="cpp">
 
<syntaxhighlight lang="cpp">
 
struct unknownInternalMapEnts1
 
struct unknownInternalMapEnts1
Line 286: Line 356:
 
};
 
};
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 
== Source Format ==
 
== Source Format ==
 
The source format must work in tandem with the other D3DBSP assets. Currently the used the source format is simply a text file with the entityString located at "raw/maps/(MAPNAME).d3dbsp" for SP maps and at "raw/maps/mp/(MAPNAME).d3dbsp" for MP maps.
 
The source format must work in tandem with the other D3DBSP assets. Currently the used the source format is simply a text file with the entityString located at "raw/maps/(MAPNAME).d3dbsp" for SP maps and at "raw/maps/mp/(MAPNAME).d3dbsp" for MP maps.

Latest revision as of 07:33, 24 December 2014

The map_ents asset is part of the D3DBSP system used that is produced by Radiant. This is used to define any entities in the map particularly spawn points, helicopter path points, physable entities, and destructible entities. Although the entity string itself is quite easy to understand, some unknown structures have been added on later Call of Duty games.

Call of Duty 4 & World at War & Black Ops 1

This is the simplest map_ents.

struct MapEnts
{
  const char *name;
  char *entityString;
  int numEntityChars;
};

The entityString is simply a string that defines different entitys, and it's length is numEntityChars. This is a simple as it gets.

Modern Warfare 2

Modern Warfare 2 adds some extra data to the end, believed to be buffer data and Stage data.

struct unknownInternalMapEnts1
{
  int unknownCount1;
  char * unknownData1;			//size = unknownCount1 << 3
  int unknownCount2;
  char * unknownData2;			//size = unknownCount2 << 5
  int unknownCount3;
  char * unknownData3;			//size = ((unknownCount3 << 2) + unknownCount3) << 2
};
 
struct Stage
{
  char * stageName;
  float offset[3];
  int flags;
};
 
struct MapEnts
{
  const char *name;
  char *entityString;
  int numEntityChars;
       unknownInternalMapEnts1 unknownStruct1;
  Stage * stages;
  byte stageCount;
};

Keep in mind that the unknownInternalMapEnts1 is also used in the addon_map_ents asset, despite one of those never actually having been found.

Modern Warfare 3

Modern Warfare 3 adds even more extra data to the end, believed to be buffer data.

struct unknownInternalMapEnts1
{
  int unknownCount1;
  char * unknownData1;			//size = unknownCount1 << 3
  int unknownCount2;
  char * unknownData2;			//size = unknownCount2 << 5
  int unknownCount3;
  char * unknownData3;			//size = ((unknownCount3 << 2) + unknownCount3) << 2
};
 
struct unknownInternalMapEnts2
{
  unknownInternalMapEnts1 unknownStruct1;
  short unknownCount1;
  char * unknownData1;			//size = unknownCount1 * 0x1C
  int unknownCount2;
  char * unknownData2;			//size = unknownCount2
  char * unknownData3;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData4;			//size = unknownStruct1->unknownCount1
  char * unknownData5;			//size = ((unknownStruct1->unknownCount1 << 1) + unknownStruct1->unknownCount1) << 2
  char * unknownData6;			//size = unknownStruct1->unknownCount1 << 2
  char * unknownData7;			//size = unknownStruct1->unknownCount1 << 1
};
 
struct MapEnts
{
  const char *name;
  char *entityString;
  int numEntityChars;
       unknownInternalMapEnts1 unknownStruct1;
       unknownInternalMapEnts2 unknownStruct2;
};

Keep in mind that the unknownInternalMapEnts1 is also used in the addon_map_ents and col_map_mp (clipMap) assets.

Black Ops 2

Black Ops 2 adds similar data to Modern Warfare 2 to the end of it's asset, believed to be buffer data.

struct TriggerModel
{
  int contents;
  unsigned __int16 hullCount;
  unsigned __int16 firstHull;
};
 
struct TriggerHull
{
  Bounds bounds;
  int contents;
  unsigned __int16 slabCount;
  unsigned __int16 firstSlab;
};
 
struct TriggerSlab
{
  vec3_t dir;
  float midPoint;
  float halfSize;
};
 
struct MapTriggers
{
  unsigned int count;
  TriggerModel *models;
  unsigned int hullCount;
  TriggerHull *hulls;
  unsigned int slabCount;
  TriggerSlab *slabs;
};
 
struct MapEnts
{
  const char *name;
  char *entityString;
  int numEntityChars;
  MapTriggers trigger;
};

Ghosts

Ghosts provides a fundamental change to the way the map_ents asset works, because while the entityString still exists it goes unused.

struct Bounds
{
  float midPoint[3];
  float halfSize[3];
};
 
struct TriggerModel
{
  int contents;
  unsigned __int16 hullCount;
  unsigned __int16 firstHull;
};
 
struct TriggerHull
{
  Bounds bounds;
  int contents;
  unsigned __int16 slabCount;
  unsigned __int16 firstSlab;
};
 
struct TriggerSlab
{
  float dir[3];
  float midPoint;
  float halfSize;
};
 
struct MapTriggers
{
  unsigned int count;
  TriggerModel *models;
  unsigned int hullCount;
  TriggerHull *hulls;
  unsigned int slabCount;
  TriggerSlab *slabs;
};
 
struct ClientTriggerAabbNode
{
  Bounds bounds;
  unsigned __int16 firstChild;
  unsigned __int16 childCount;
};
 
struct ClientTriggers
{
  MapTriggers trigger;
  unsigned __int16 numClientTriggerNodes;
  ClientTriggerAabbNode *clientTriggerAabbTree;
  unsigned int triggerStringLength;
  char *triggerString;
  __int16 *visionSetTriggers;
  char *triggerType;
  float (*origins)[3];
  float *scriptDelay;
  __int16 *audioTriggers;
  __int16 *blendLookup;
  __int16 *npcTriggers;
};
 
struct ClientTriggerBlendNode
{
  float pointA[3];
  float pointB[3];
  unsigned __int16 triggerA;
  unsigned __int16 triggerB;
};
 
struct ClientTriggerBlend
{
  unsigned __int16 numClientTriggerBlendNodes;
  ClientTriggerBlendNode *blendNodes;
};
 
struct SpawnPointEntityRecord
{
  unsigned __int16 index;
  scr_string_t name;
  scr_string_t target;
  scr_string_t script_noteworthy;
  float origin[3];
  float angles[3];
};
 
struct SpawnPointRecordList
{
  unsigned __int16 spawnsCount;
  SpawnPointEntityRecord *spawns;
};
 
struct SplinePointEntityRecord
{
  int splineId;
  int splineNodeId;
  char *splineNodeLabel;
  float splineNodeTension;
  float origin[3];
  float corridorDims[2];
  float tangent[3];
  float distToNextNode;
  float (*positionCubic)[3];
  float (*tangentQuadratic)[3];
};
 
struct SplinePointRecordList
{
  unsigned __int16 splinePointCount;
  float splineLength;
  SplinePointEntityRecord *splinePoints;
};
 
struct SplineRecordList
{
  unsigned __int16 splineCount;
  SplinePointRecordList *splines;
};
 
struct MapEnts
{
  const char *name;
  char *entityString;
  int numEntityChars;
  MapTriggers trigger;
  ClientTriggers clientTrigger;
  ClientTriggerBlend clientTriggerBlend;
  SpawnPointRecordList spawnList;
  SplineRecordList splineList;
};

Advanced Warfare

Advanced Warfare provides a fundamental change to the way the map_ents asset works, because while the entityString still exists it goes unused.

struct unknownInternalMapEnts1
{
  int unknownCount1;
  char * unknownData1;			//size = unknownCount1 << 3
  int unknownCount2;
  char * unknownData2;			//size = unknownCount2 << 5
  int unknownCount3;
  char * unknownData3;			//size = (unknownCount3 << 4) + (unknownCount3 << 2)
};
 
struct unknownInternalMapEnts2
{
  unknownInternalMapEnts1 unknownStruct1;
  short unknownCount1;
  char * unknownData1;			//size = unknownCount1 * 0x1C
  int unknownCount2;
  char * unknownData2;			//size = unknownCount2
  char * unknownData3;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData4;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData5;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData6;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData7;			//size = ((unknownStruct1->unknownCount1 + unknownStruct1->unknownCount1) + unknownStruct1->unknownCount1) << 2
  char * unknownData8;			//size = unknownStruct1->unknownCount1 << 2
  char * unknownData9;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData10;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData11;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData12;			//size = unknownStruct1->unknownCount1 << 1
  char * unknownData13;			//size = unknownStruct1->unknownCount1 << 1
};
 
struct unknownInternalMapEnts3
{
  short unknownCount;
  char * unknownData;			//size = unknownCount * 0x1C
};
 
struct unknownInternalMapEnts4Internal1
{
  short unknown1;
  ScriptString unknownScriptString1;
  ScriptString unknownScriptString2;
  ScriptString unknownScriptString3;
  ScriptString unknownScriptString4;
  char unknown2[0x12];
};
 
struct unknownInternalMapEnts4
{
  short unknownCount;
  unknownInternalMapEnts4Internal1 * unknownStruct;			//Count = unknownCount
};
 
struct unknownInternalMapEnts5Internal1Internal1
{
  char unknown1[8];
  char (*unknown2)[0x40];
  char unknown3[0x28];
  char (*unknown4)[0x30];
  char (*unknown5)[0x24];
};
 
struct unknownInternalMapEnts5Internal1
{
  short unknownCount;
  int unknown;
  unknownInternalMapEnts5Internal1Internal1 * unknownStruct;			//Count = unknownCount
};
 
struct unknownInternalMapEnts5
{
  short unknownCount;
  unknownInternalMapEnts5Internal1 * unknownStruct;			//Count = unknownCount
};
 
struct MapEnts
{
  const char *name;
  char *entityString;
  int numEntityChars;
       unknownInternalMapEnts1 unknownStruct1;
       unknownInternalMapEnts2 unknownStruct2;
       unknownInternalMapEnts3 unknownStruct3;
       unknownInternalMapEnts4 unknownStruct4;
       unknownInternalMapEnts5 unknownStruct5;
};

Source Format

The source format must work in tandem with the other D3DBSP assets. Currently the used the source format is simply a text file with the entityString located at "raw/maps/(MAPNAME).d3dbsp" for SP maps and at "raw/maps/mp/(MAPNAME).d3dbsp" for MP maps.