Difference between revisions of "MapEnts Asset"

From COD Engine Research
Jump to: navigation, search
(Advanced Warfare)
 
(8 intermediate revisions by 2 users not shown)
Line 5: Line 5:
 
[[Category:MW3]]
 
[[Category:MW3]]
 
[[Category:Ghosts]]
 
[[Category:Ghosts]]
 +
[[Category:AW]]
 
[[Category:WaW]]
 
[[Category:WaW]]
 
[[Category:BO1]]
 
[[Category:BO1]]
Line 91: 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 106: Line 129:
 
   char *entityString;
 
   char *entityString;
 
   int numEntityChars;
 
   int numEntityChars;
      unknownInternalMapEnts1 unknownStruct1;
+
  MapTriggers trigger;
 
};
 
};
 
</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">
 +
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;
 +
};
 +
</syntaxhighlight>
 +
 +
== 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.
 
<syntaxhighlight lang="cpp">
 
<syntaxhighlight lang="cpp">
 
struct unknownInternalMapEnts1
 
struct unknownInternalMapEnts1
Line 120: Line 277:
 
   char * unknownData2; //size = unknownCount2 << 5
 
   char * unknownData2; //size = unknownCount2 << 5
 
   int unknownCount3;
 
   int unknownCount3;
   char * unknownData3; //size = ((unknownCount3 << 2) + unknownCount3) << 2
+
   char * unknownData3; //size = (unknownCount3 << 4) + (unknownCount3 << 2)
 
};
 
};
  
Line 131: Line 288:
 
   char * unknownData2; //size = unknownCount2
 
   char * unknownData2; //size = unknownCount2
 
   char * unknownData3; //size = unknownStruct1->unknownCount1 << 1
 
   char * unknownData3; //size = unknownStruct1->unknownCount1 << 1
   char * unknownData4; //size = unknownStruct1->unknownCount1
+
   char * unknownData4; //size = unknownStruct1->unknownCount1 << 1
   char * unknownData5; //size = ((unknownStruct1->unknownCount1 << 1) + unknownStruct1->unknownCount1) << 2
+
   char * unknownData5; //size = unknownStruct1->unknownCount1 << 1
   char * unknownData6; //size = unknownStruct1->unknownCount1 << 2
+
   char * unknownData6; //size = unknownStruct1->unknownCount1 << 1
   char * unknownData7; //size = unknownStruct1->unknownCount1 << 1
+
   char * unknownData7; //size = ((unknownStruct1->unknownCount1 + unknownStruct1->unknownCount1) + unknownStruct1->unknownCount1) << 2
   char * unknownData8; //size = unknownStruct1->unknownCount1 << 1
+
   char * unknownData8; //size = unknownStruct1->unknownCount1 << 2
 
   char * unknownData9; //size = unknownStruct1->unknownCount1 << 1
 
   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
 
};
 
};
  
Line 150: Line 311:
 
   ScriptString unknownScriptString1;
 
   ScriptString unknownScriptString1;
 
   ScriptString unknownScriptString2;
 
   ScriptString unknownScriptString2;
   ScriptString unknownScriptString2;
+
   ScriptString unknownScriptString3;
   char unknown2[0x18];
+
  ScriptString unknownScriptString4;
 +
   char unknown2[0x12];
 
};
 
};
  
Line 194: Line 356:
 
};
 
};
 
</syntaxhighlight>
 
</syntaxhighlight>
Keep in mind that the unknownInternalMapEnts1 is also used in the addon_map_ents and col_map_mp (clipMap) assets.
+
 
 
== 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 05: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.