MapEnts Asset: Difference between revisions

From COD Engine Research
Kokole (talk | contribs)
No edit summary
 
(6 intermediate revisions by 2 users not shown)
Line 9: Line 9:
[[Category:BO1]]
[[Category:BO1]]
[[Category:BO2]]
[[Category:BO2]]
[[Category:BO3]]
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.
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 ==
== Call of Duty 4 & World at War & Black Ops 1 ==
Line 89: Line 90:
</syntaxhighlight>
</syntaxhighlight>
Keep in mind that the unknownInternalMapEnts1 is also used in the addon_map_ents and col_map_mp (clipMap) assets.
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 & 3 ==
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 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
struct MapTriggers
{
{
Line 110: Line 133:
};
};
</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
{
  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
{
{
   int unknownCount1;
   MapTriggers trigger;
   char * unknownData1; //size = unknownCount1 << 3
  unsigned __int16 numClientTriggerNodes;
   int unknownCount2;
   ClientTriggerAabbNode *clientTriggerAabbTree;
   char * unknownData2; //size = unknownCount2 << 5
   unsigned int triggerStringLength;
   int unknownCount3;
   char *triggerString;
   char * unknownData3; //size = ((unknownCount3 << 2) + unknownCount3) << 2
   __int16 *visionSetTriggers;
   char *triggerType;
  float (*origins)[3];
  float *scriptDelay;
  __int16 *audioTriggers;
  __int16 *blendLookup;
  __int16 *npcTriggers;
};
};


struct unknownInternalMapEnts2
struct ClientTriggerBlendNode
{
{
   unknownInternalMapEnts1 unknownStruct1;
   float pointA[3];
   short unknownCount1;
   float pointB[3];
   char * unknownData1; //size = unknownCount1 * 0x1C
   unsigned __int16 triggerA;
   int unknownCount2;
   unsigned __int16 triggerB;
  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 ClientTriggerBlend
{
{
   short unknownCount;
   unsigned __int16 numClientTriggerBlendNodes;
   char * unknownData; //size = unknownCount * 0x1C
   ClientTriggerBlendNode *blendNodes;
};
};


struct unknownInternalMapEnts4Internal1
struct SpawnPointEntityRecord
{
{
   short unknown1;
   unsigned __int16 index;
   ScriptString unknownScriptString1;
   scr_string_t name;
   ScriptString unknownScriptString2;
   scr_string_t target;
   ScriptString unknownScriptString2;
   scr_string_t script_noteworthy;
   char unknown2[0x18];
   float origin[3];
  float angles[3];
};
};


struct unknownInternalMapEnts4
struct SpawnPointRecordList
{
{
   short unknownCount;
   unsigned __int16 spawnsCount;
   unknownInternalMapEnts4Internal1 * unknownStruct; //Count = unknownCount
   SpawnPointEntityRecord *spawns;
};
};


struct unknownInternalMapEnts5Internal1Internal1
struct SplinePointEntityRecord
{
{
   char unknown1[8];
  int splineId;
   char (*unknown2)[0x40];
  int splineNodeId;
   char unknown3[0x28];
   char *splineNodeLabel;
   char (*unknown4)[0x30];
  float splineNodeTension;
   char (*unknown5)[0x24];
  float origin[3];
   float corridorDims[2];
   float tangent[3];
   float distToNextNode;
  float (*positionCubic)[3];
   float (*tangentQuadratic)[3];
};
};


struct unknownInternalMapEnts5Internal1
struct SplinePointRecordList
{
{
   short unknownCount;
   unsigned __int16 splinePointCount;
   int unknown;
   float splineLength;
   unknownInternalMapEnts5Internal1Internal1 * unknownStruct; //Count = unknownCount
   SplinePointEntityRecord *splinePoints;
};
};


struct unknownInternalMapEnts5
struct SplineRecordList
{
{
   short unknownCount;
   unsigned __int16 splineCount;
   unknownInternalMapEnts5Internal1 * unknownStruct; //Count = unknownCount
   SplinePointRecordList *splines;
};
};


Line 189: Line 260:
   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 357:
};
};
</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:05, 31 October 2015

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 & 3

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.