Game Map Asset: Difference between revisions

From COD Engine Research
Jakes625 (talk | contribs)
Jakes625 (talk | contribs)
 
Line 454: Line 454:
</syntaxhighlight>
</syntaxhighlight>
=== Multiplayer ===
=== Multiplayer ===
<code>unknownGameWorldStruct2 = GGlassData</code>
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
struct GGlassPiece // len: 0x0C
struct GGlassPiece // len: 0x0C
Line 500: Line 499:
     GGlassName* GlassNames;
     GGlassName* GlassNames;


     // 0x14..0x7F: PS3 copies these bytes as part of the fixed 0x80 root;  
     // 0x14..0x7F: PS3 copies these bytes as part of the fixed 0x80 root;
     // no consumer semantics proven yet.
     unsigned char padding[108]; // seriously, this is how the loader does it
    uint32_t unknown[0x1A];
};
};



Latest revision as of 02:32, 30 June 2026

The game map (or game world) is part of the D3DBSP system produced by Radiant, and is on every Call of Duty game except for Modern Warfare 3 and Ghosts. This contains scripting information for the map, such as AI pathing information.

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

For World at War and Black Ops 1, the MP and SP assets are identical.

enum nodeType
{
  NODE_BADNODE = 0x0,
  NODE_PATHNODE = 0x1,
  NODE_COVER_STAND = 0x2,
  NODE_COVER_CROUCH = 0x3,
  NODE_COVER_CROUCH_WINDOW = 0x4,
  NODE_COVER_PRONE = 0x5,
  NODE_COVER_RIGHT = 0x6,
  NODE_COVER_LEFT = 0x7,
  NODE_COVER_WIDE_RIGHT = 0x8,
  NODE_COVER_WIDE_LEFT = 0x9,
  NODE_CONCEALMENT_STAND = 0xA,
  NODE_CONCEALMENT_CROUCH = 0xB,
  NODE_CONCEALMENT_PRONE = 0xC,
  NODE_REACQUIRE = 0xD,
  NODE_BALCONY = 0xE,
  NODE_SCRIPTED = 0xF,
  NODE_NEGOTIATION_BEGIN = 0x10,
  NODE_NEGOTIATION_END = 0x11,
  NODE_TURRET = 0x12,
  NODE_GUARD = 0x13,
  NODE_NUMTYPES = 0x14,
};

struct pathlink_s
{
  float fDist;
  unsigned __int16 nodeNum;
  char disconnectCount;
  char negotiationLink;
  char ubBadPlaceCount[4];
};

struct pathnode_constant_t
{
  nodeType type;
  unsigned __int16 spawnflags;
  ScriptString targetname;
  ScriptString script_linkName;
  ScriptString script_noteworthy;
  ScriptString target;
  ScriptString animscript;
  int animscriptfunc;
  float vOrigin[3];
  float fAngle;
  float forward[2];
  float fRadius;
  float minUseDistSq;
  __int16 wOverlapNode[2];
  __int16 wChainId;
  __int16 wChainDepth;
  __int16 wChainParent;
  unsigned __int16 totalLinkCount;
  pathlink_s *Links;
};

struct pathnode_dynamic_t
{
  struct sentient_s *pOwner;
  int iFreeTime;
  int iValidTime[3];
  int inPlayerLOSTime;
  __int16 wLinkCount;
  __int16 wOverlapCount;
  __int16 turretEntNumber;
  __int16 userCount;
};

struct pathnode_t
{
  pathnode_constant_t constant;
  pathnode_dynamic_t dynamic;
  pathnode_transient_t transient;
};

struct pathnode_transient_t
{
  int iSearchFrame;
  pathnode_t *pNextOpen;
  pathnode_t *pPrevOpen;
  pathnode_t *pParent;
  float fCost;
  float fHeuristic;
  float costFactor;
};

struct pathnode_tree_t
{
  int axis;
  float dist;
  pathnode_tree_info_t u;
};

struct pathnode_tree_nodes_t
{
  int nodeCount;
  unsigned short **nodes;
};

union pathnode_tree_info_t
{
  pathnode_tree_t *child[2];
  pathnode_tree_nodes_t s;
};

typdef char pathbasenode_t[0x10];

struct PathData
{
  unsigned int nodeCount;
  pathnode_t *nodes;
  pathbasenode_t *nodeBases;
  unsigned int chainNodeCount;
  unsigned __int16 *chainNodeForNode;
  unsigned __int16 *nodeForChainNode;
  int visBytes;
  char *pathVis;
  int nodeTreeCount;
  pathnode_tree_t *nodeTree;
};

struct GameWorldSp
{
  const char *name;
  PathData path;
};

Black Ops 2

The Black Ops 2 game maps (which are loaded exactly the same) are slightly different from its predecessors.

enum nodeType
{
  NODE_BADNODE = 0x0,
  NODE_PATHNODE = 0x1,
  NODE_COVER_STAND = 0x2,
  NODE_COVER_CROUCH = 0x3,
  NODE_COVER_CROUCH_WINDOW = 0x4,
  NODE_COVER_PRONE = 0x5,
  NODE_COVER_RIGHT = 0x6,
  NODE_COVER_LEFT = 0x7,
  NODE_COVER_PILLAR = 0x8,
  NODE_AMBUSH = 0x9,
  NODE_EXPOSED = 0xA,
  NODE_CONCEALMENT_STAND = 0xB,
  NODE_CONCEALMENT_CROUCH = 0xC,
  NODE_CONCEALMENT_PRONE = 0xD,
  NODE_REACQUIRE = 0xE,
  NODE_BALCONY = 0xF,
  NODE_SCRIPTED = 0x10,
  NODE_NEGOTIATION_BEGIN = 0x11,
  NODE_NEGOTIATION_END = 0x12,
  NODE_TURRET = 0x13,
  NODE_GUARD = 0x14,
  NODE_NUMTYPES = 0x15,
  NODE_DONTLINK = 0x15,
};

struct pathlink_s
{
  float fDist;
  unsigned __int16 nodeNum;
  char disconnectCount;
  char negotiationLink;
  char flags;
  char ubBadPlaceCount[5];
};

struct pathnode_constant_t
{
  nodeType type;
  int spawnflags;
  ScriptString targetname;
  ScriptString script_linkName;
  ScriptString script_noteworthy;
  ScriptString target;
  ScriptString animscript;
  int animscriptfunc;
  vec3_t vOrigin;
  float fAngle;
  vec2_t forward;
  float fRadius;
  float minUseDistSq;
  __int16 wOverlapNode[2];
  unsigned __int16 totalLinkCount;
  pathlink_s *Links;
};

struct SentientHandle
{
  unsigned __int16 number;
  unsigned __int16 infoIndex;
};

struct pathnode_dynamic_t
{
  SentientHandle pOwner;
  int iFreeTime;
  int iValidTime[3];
  int dangerousNodeTime[3];
  int inPlayerLOSTime;
  __int16 wLinkCount;
  __int16 wOverlapCount;
  __int16 turretEntNumber;
  __int16 userCount;
  bool hasBadPlaceLink;
};

struct pathnode_transient_t
{
  int iSearchFrame;
  pathnode_t *pNextOpen;
  pathnode_t *pPrevOpen;
  pathnode_t *pParent;
  float fCost;
  float fHeuristic;
  union
  {
    float nodeCost;
    float linkIndex;
  };
};

struct pathnode_t
{
  pathnode_constant_t constant;
  pathnode_dynamic_t dynamic;
  pathnode_transient_t transient;
};

struct pathnode_tree_nodes_t
{
  int nodeCount;
  unsigned __int16 *nodes;
};

union pathnode_tree_info_t
{
  pathnode_tree_t *child[2];
  pathnode_tree_nodes_t s;
};

struct pathnode_tree_t
{
  int axis;
  float dist;
  pathnode_tree_info_t u;
};

struct pathbasenode_t
{
  vec3_t vOrigin;
  unsigned int type;
};

struct PathData
{
  unsigned int nodeCount;
  unsigned int originalNodeCount;
  pathnode_t *nodes;
  pathbasenode_t *nodeBases;
  int visBytes;
  char *pathVis;
  int smoothBytes;
  char *smoothCache;
  int nodeTreeCount;
  pathnode_tree_t *nodeTree;
};

struct GameWorldSp
{
  const char *name;
  PathData path;
};

struct GameWorldMp
{
  const char *name;
  PathData path;
};

Call of Duty 4 Multiplayer

The multiplayer Call of Duty 4 game world is pretty much unneeded.

struct GameWorldMp
{
  const char *name;
};

Modern Warfare 2

Single Player

enum nodeType
{
  NODE_BADNODE = 0x0,
  NODE_PATHNODE = 0x1,
  NODE_COVER_STAND = 0x2,
  NODE_COVER_CROUCH = 0x3,
  NODE_COVER_CROUCH_WINDOW = 0x4,
  NODE_COVER_PRONE = 0x5,
  NODE_COVER_RIGHT = 0x6,
  NODE_COVER_LEFT = 0x7,
  NODE_COVER_WIDE_RIGHT = 0x8,
  NODE_COVER_WIDE_LEFT = 0x9,
  NODE_CONCEALMENT_STAND = 0xA,
  NODE_CONCEALMENT_CROUCH = 0xB,
  NODE_CONCEALMENT_PRONE = 0xC,
  NODE_REACQUIRE = 0xD,
  NODE_BALCONY = 0xE,
  NODE_SCRIPTED = 0xF,
  NODE_NEGOTIATION_BEGIN = 0x10,
  NODE_NEGOTIATION_END = 0x11,
  NODE_TURRET = 0x12,
  NODE_GUARD = 0x13,
  NODE_NUMTYPES = 0x14,
};

struct pathlink_s
{
  float fDist;
  unsigned __int16 nodeNum;
  char disconnectCount;
  char negotiationLink;
  char ubBadPlaceCount[4];
};

struct pathnode_constant_t
{
  nodeType type;
  unsigned __int16 spawnflags;
  ScriptString targetname;
  ScriptString script_linkName;
  ScriptString script_noteworthy;
  ScriptString target;
  ScriptString animscript;
  int animscriptfunc;
  float vOrigin[3];
  float fAngle;
  float forward[2];
  float fRadius;
  float minUseDistSq;
  __int16 wOverlapNode[2];
  unsigned __int16 totalLinkCount;
  pathlink_s *Links;
};

struct pathnode_t
{
  pathnode_constant_t constant;
       char unknown[0x48];
};

struct pathnode_tree_t
{
  int axis;
  float dist;
  pathnode_tree_info_t u;
};

struct pathnode_tree_nodes_t
{
  int nodeCount;
  unsigned short **nodes;
};

union pathnode_tree_info_t
{
  pathnode_tree_t *child[2];
  pathnode_tree_nodes_t s;
};

typdef char pathbasenode_t[0x10];

struct PathData
{
  unsigned int nodeCount;
  pathnode_t *nodes;
  pathbasenode_t *nodeBases;
  unsigned int chainNodeCount;
  unsigned __int16 *chainNodeForNode;
  unsigned __int16 *nodeForChainNode;
  int visBytes;
  char *pathVis;
  int nodeTreeCount;
  pathnode_tree_t *nodeTree;
};

struct unknownGameWorldSpStruct1Internal1Internal1
{
  char unknown1[0x34];
  unsigned int unknownCount;
  char * unknown2; //Size = ((unknownCount << 1) + unknownCount) << 2
};

struct unknownGameWorldSpStruct1Internal1Internal2
{
  unknownGameWorldSpStruct1Internal1Internal1 * unknownStruct;
};

struct unknownGameWorldSpStruct1Internal1
{
  const char * unknownString;
  unsigned int unknownCount1;
  unknownGameWorldSpStruct1Internal1Internal1 * unknownStructs1;
  unsigned int unknownCount2;
  unknownGameWorldSpStruct1Internal1Internal2 * unknownStructs2;
  unsigned int unknownCount3;
  unknownGameWorldSpStruct1Internal1Internal2 * unknownStructs3;
  char unknown[0x10];
};

struct unknownGameWorldSpStruct1
{
  unsigned int unknownCount;
  unknownGameWorldSpStruct1Internal1 * unknownStructs;
};

struct unknownGameWorldStruct2Internal1
{
  char * unknownString;
  short unknown1;
  short unknownCount1;
  unsigned short * unknown2; //Count = unknownCount1
};

struct unknownGameWorldStruct2
{
  unsigned int unknownCount1;
  char * unknown1; //Size = ((unknownCount1 << 1) + unknownCount1) << 2
  unsigned int unknownCount2;
  unknownGameWorldStruct2Internal1 * unknownStructs;
  char unknown2[0x6C];
};

struct GameWorldSp
{
  const char *name;
  PathData path;
       unknownGameWorldSpStruct1 unknownStruct1;
       unknownGameWorldStruct2 * unknownStruct2;
};

Multiplayer

struct GGlassPiece // len: 0x0C
{
    // 0x00..0x07: Xbox-correlated G_GlassPiece state fields.
    uint16_t DamageTaken;
    uint16_t CollapseTime;
    int32_t LastStateChangeTime;

    // 0x08..0x0B: Xbox names impactDir and impactPos; 
    // PS3 packing width is preserved here.
    uint16_t PackedImpactDir;
    uint16_t PackedImpactPos;
}

struct GGlassName // len 0x0C
{
    // 0x00: XString nameStr. PS3 stores row+0x00 into varXString and calls Load_XString.
    char* Name;

    // 0x04: G_GlassName.name. Xbox-correlated script string index 
    // copied by the fixed row load.
    uint16_t ScriptName;

    // 0x06: G_GlassName.pieceCount. PS3 uses this as the pieceIndices ushort count.
    uint16_t PieceCount;

    // 0x08: ushort*. PS3 aligns to 2 and loads pieceCount indices when non-null.
    uint16_t* PieceIndices;
}

struct GGlassData //len 0x80
{
    GGlassPiece* GlassPieces; // PS3 loads pieceCount fixed 0x0C-byte rows when non-null.
    int32_t PieceCount;

    // 0x08..0x0B: Xbox-correlated G_GlassData damage thresholds.
    uint16_t DamageToWeaken;
    uint16_t DamageToDestroy;

    // 0x0C: G_GlassData.glassNameCount. PS3 uses this as the G_GlassName array count.
    int32_t GlassNameCount;

    // 0x10: G_GlassName*. PS3 loads glassNameCount fixed 0x0C-byte rows when non-null.
    GGlassName* GlassNames;

    // 0x14..0x7F: PS3 copies these bytes as part of the fixed 0x80 root;
    unsigned char padding[108]; // seriously, this is how the loader does it
};

struct GameWorldMp
{
  const char* name;
  GGlassData* Glassdata;
};