Game Map Asset: Difference between revisions
| Line 454: | Line 454: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Multiplayer === | === Multiplayer === | ||
<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; | ||
unsigned char padding[108]; // seriously, this is how the loader does it | |||
}; | }; | ||
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;
};