Files
BT412/engine/MUNGA/cultural.h
T
arcattackandClaude Opus 4.8 7b7d465e5e Initial commit: bt411 -- standalone Windows BattleTech (Tesla 4.10 port)
Clean, self-contained extraction of the BattleTech-specific work from the
reverse-engineering workspace -- engine + game + content + build, with nothing
from Red Planet or the raw archive dumps. Builds green (Win32) and runs the
single-player drive->animate->target->fire->damage->destroy loop out of the box.

Layout:
  engine/   MUNGA + MUNGA_L4 shared 2007 engine, carrying our BT render/loader
            work (bgfload/L4D3D/L4VIDEO: BSL bit-slice decode, LOD/ground/shadow
            models) + image codec; the minimal rp/ headers the audio HAL needs
  game/     reconstructed BT logic + surviving-original BT source + fwd shims
            + WinMain launcher
  content/  full runtime tree (BTL4.RES, VIDEO/, GAUGE/, AUDIO/, eggs, BTDPL.INI)
  docs/     format specs + reconstruction ledgers
  reference/ raw Ghidra pseudocode (recon source-of-truth) + decomp exporter
  tools/    MP console emulator + map/resource scanners

One top-level CMake builds munga_engine lib + bt410_l4 game lib + btl4.exe.
All paths relativized (186 fwd shims + ~437 CMake abs paths -> repo-relative);
DXSDK is the one external, overridable via -DDXSDK. Verified: builds to a
byte-identical 2.27MB exe and runs combat (TARGET DESTROYED, 0 crashes) against
the bundled content.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 21:03:40 -05:00

353 lines
7.4 KiB
C++

#pragma once
#include "terrain.h"
#include "memstrm.h"
#include "resource.h"
#include "notation.h"
#include "team.h"
class ScenarioRole;
//##########################################################################
//################## CulturalIcon::ModelResource #######################
//##########################################################################
struct CulturalIcon__ModelResource
{
Scalar destroyedYTranslation;
Scalar timeDelay;
ResourceDescription::ResourceID explosionResourceID;
ResourceDescription::ResourceID crunchExplosionResourceID;
Logical sinkCollisionVolume, stoppingCollisionVolume;
};
//##########################################################################
//##################### Class CulturalIcon ##########################
//##########################################################################
class CulturalIcon :
public UnscalableTerrain
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data support
//
public:
static Derivation *GetClassDerivations();
static SharedData DefaultData;
private:
static const HandlerEntry MessageHandlerEntries[];
protected:
//static MessageHandlerSet MessageHandlers;
static MessageHandlerSet& GetMessageHandlers();
public:
enum {
SetBurningStateMessageID = UnscalableTerrain::NextMessageID,
NextMessageID
};
void
TakeDamageMessageHandler(TakeDamageMessage *damage_message);
void
SetBurningStateMessageHandler(Message *burning_message);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision Volume Support
//
protected:
void
UpdateCollisionVolumes();
enum {
RemoveCollisionVolumeOnDeathBit = UnscalableTerrain::NextBit,
StoppingCollisionVolumeBit,
NextBit
};
enum {
RemoveCollisionVolumeOnDeathFlag = 1 << RemoveCollisionVolumeOnDeathBit,
StoppingCollisionVolumeFlag = 1 << StoppingCollisionVolumeBit
};
void
SetRemoveCollisionVolumeFlag()
{Check(this); simulationFlags |= RemoveCollisionVolumeOnDeathFlag;}
Logical RemoveCollisionVolumeOnDeath() const
{
Check(this);
return (simulationFlags & RemoveCollisionVolumeOnDeathFlag) != 0;
}
void
SetStoppingCollisionVolumeFlag()
{Check(this); simulationFlags |= StoppingCollisionVolumeFlag; }
ResourceDescription::ResourceID
explosionResourceID;
ResourceDescription::ResourceID
crunchExplosionResourceID;
Scalar
destroyedYTranslation;
Scalar
timeDelay;
public:
Logical IsStoppingCollisionVolume() const
{
Check(this);
return (simulationFlags&StoppingCollisionVolumeFlag) != 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support
//
public:
enum {
TeamNameAttributeID = UnscalableTerrain::NextAttributeID,
NextAttributeID
};
enum {
BurningState = UnscalableTerrain::StateCount,
WaitingToBurn,
StateCount
};
char
teamName[64];
private:
static const IndexEntry AttributePointers[];
protected:
//static AttributeIndexSet AttributeIndex
static AttributeIndexSet& GetAttributeIndex();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
public:
typedef CulturalIcon__ModelResource ModelResource;
CulturalIcon(
MakeMessage *creation_message,
SharedData &shared_data = DefaultData
);
~CulturalIcon();
void
ReadUpdateRecord(Simulation::UpdateRecord *message);
Logical
TestInstance() const;
static Logical
CreateMakeMessage (
MakeMessage *creation_message,
NotationFile *model_file,
const ResourceDirectories *directories
);
static CulturalIcon*
Make(MakeMessage *creation_message);
static int
CreateModelResource (
ResourceFile *resource_file,
const char *model_name,
NotationFile *model_file,
const ResourceDirectories *directories,
ModelResource* model = NULL
);
static int
CreateDamageZoneStream (
ResourceFile *resource_file,
const char *model_name,
NotationFile *model_file,
const ResourceDirectories *directories
);
};
//##########################################################################
//################## Landmark::MakeMessage #############################
//##########################################################################
class Landmark__MakeMessage :
public CulturalIcon::MakeMessage
{
public:
int
landmarkID;
char
roleName[64];
char
landmarkName[64];
char
teamName[64];
Landmark__MakeMessage();
Landmark__MakeMessage(
Receiver::MessageID message_ID,
size_t length,
const EntityID &entity_ID,
Entity::ClassID class_ID,
ResourceDescription::ResourceID resource_ID,
LWord instance_flags,
const Origin &origin,
char *team_name,
int landmark_ID,
CString role_name
) :
CulturalIcon::MakeMessage(
message_ID,
length,
entity_ID,
class_ID,
EntityID::Null,
resource_ID,
instance_flags,
origin
),
landmarkID(landmark_ID)
{
Str_Copy(teamName, team_name, sizeof(teamName));
Str_Copy(roleName, (const char*)role_name, sizeof(roleName));
}
};
//##########################################################################
//################## Landmark::ModelResource #######################
//##########################################################################
struct Landmark__ModelResource :
public CulturalIcon::ModelResource
{
#if 0
ResourceDescription::ResourceID
roleResourceID;
#endif
};
//##########################################################################
//##################### Class Landmark ##########################
//##########################################################################
class Landmark :
public CulturalIcon
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data support
//
public:
static Derivation *GetClassDerivations();
static SharedData DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Message Support
//
private:
static const HandlerEntry MessageHandlerEntries[];
protected:
static MessageHandlerSet MessageHandlers;
public:
void
TakeDamageMessageHandler(TakeDamageMessage *damage_message);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Local Data support
//
protected:
ScenarioRole
*scenarioRole;
int
landmarkID;
Team
*owningTeam;
char
teamName[64];
public:
const ScenarioRole*
GetScenarioRole() const
{Check(this); return scenarioRole; }
void
SetScenarioRole(ScenarioRole *scenario_role)
{ Check(this); scenarioRole = scenario_role; }
int
GetLandmarkID() const
{Check(this); return landmarkID; }
Team*
GetOwningTeam()
{Check(this); return owningTeam; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructor / Destructor support
//
public:
typedef Landmark__MakeMessage MakeMessage;
typedef Landmark__ModelResource ModelResource;
Landmark(
MakeMessage *creation_message,
SharedData &shared_data = DefaultData
);
~Landmark();
Logical
TestInstance() const;
static Logical
CreateMakeMessage (
MakeMessage *creation_message,
NotationFile *model_file,
const ResourceDirectories *directories
);
static Landmark*
Make(MakeMessage *creation_message);
static int
CreateModelResource (
ResourceFile *resource_file,
const char *model_name,
NotationFile *model_file,
const ResourceDirectories *directories,
ModelResource* model = NULL
);
};