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>
This commit is contained in:
@@ -0,0 +1,800 @@
|
||||
#include "munga.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "segment.h"
|
||||
#include "exptbl.h"
|
||||
#include "fileutil.h"
|
||||
#include "jmover.h"
|
||||
#include "schain.h"
|
||||
#include "notation.h"
|
||||
#include "namelist.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
MaterialList::MaterialList() :
|
||||
materialList(NULL)
|
||||
{
|
||||
listIterator = new CStringSocketIterator(materialList);
|
||||
Register_Object(listIterator);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
MaterialList::~MaterialList()
|
||||
{
|
||||
DeletePlugs();
|
||||
|
||||
Unregister_Object(listIterator);
|
||||
delete listIterator;
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Damage::Damage()
|
||||
{
|
||||
damageAmount = 0.0f;
|
||||
damageForce = Vector3D::Identity;
|
||||
surfaceNormal.x = 0.0f;
|
||||
surfaceNormal.y = 1.0f;
|
||||
surfaceNormal.z = 0.0f;
|
||||
impactPoint = Point3D::Identity;
|
||||
burstCount = 1.0f;
|
||||
Check_Fpu();
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
|
||||
EntitySegment*
|
||||
DamageZone::GetCurrentEffectSite(Enumeration effect_site_type)
|
||||
{
|
||||
Check(this);
|
||||
EntitySegment *return_segment;
|
||||
switch(effect_site_type)
|
||||
{
|
||||
Return_Default_Effect:
|
||||
case DefaultEffectSite:
|
||||
default:
|
||||
{
|
||||
SChainIteratorOf<EntitySegment*> iterator(defaultEffectSiteChain);
|
||||
Check(iterator.GetCurrent());
|
||||
return iterator.GetCurrent();
|
||||
}
|
||||
case InternalVideoEffectSite:
|
||||
{
|
||||
SChainIteratorOf<EntitySegment*> iterator(internalVideoEffectSiteChain);
|
||||
return_segment = iterator.GetCurrent();
|
||||
if (return_segment)
|
||||
{
|
||||
Check(return_segment);
|
||||
return return_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto Return_Default_Effect;
|
||||
}
|
||||
}
|
||||
case ExternalVideoEffectSite:
|
||||
{
|
||||
SChainIteratorOf<EntitySegment*> iterator(externalVideoEffectSiteChain);
|
||||
return_segment = iterator.GetCurrent();
|
||||
if (return_segment)
|
||||
{
|
||||
Check(return_segment);
|
||||
return return_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto Return_Default_Effect;
|
||||
}
|
||||
}
|
||||
case InternalAudioEffectSite:
|
||||
{
|
||||
SChainIteratorOf<EntitySegment*> iterator(internalAudioEffectSiteChain);
|
||||
return_segment = iterator.GetCurrent();
|
||||
if (return_segment)
|
||||
{
|
||||
Check(return_segment);
|
||||
return return_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto Return_Default_Effect;
|
||||
}
|
||||
}
|
||||
case ExternalAudioEffectSite:
|
||||
{
|
||||
SChainIteratorOf<EntitySegment*> iterator(externalAudioEffectSiteChain);
|
||||
return_segment = iterator.GetCurrent();
|
||||
if (return_segment)
|
||||
{
|
||||
Check(return_segment);
|
||||
return return_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto Return_Default_Effect;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
DamageZone::Reset(Logical )
|
||||
{
|
||||
SetDamageZoneState(DefaultState);
|
||||
damageZoneGraphicState.SetState(ExistsGraphicState);
|
||||
damageLevel = 0.0f;
|
||||
Check_Fpu();
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
DamageZone::WriteUpdateRecord(UpdateRecord *update_record)
|
||||
{
|
||||
Check(this);
|
||||
Check_Pointer(update_record);
|
||||
update_record->damageLevel = damageLevel;
|
||||
update_record->damageZoneState = damageZoneState.GetState();
|
||||
update_record->damageZoneGraphicState = damageZoneGraphicState.GetState();
|
||||
update_record->damageZoneIndex = damageZoneIndex;
|
||||
update_record->changedFlags = changedFlags;
|
||||
update_record->recordLength = sizeof(*update_record);
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Clear Flags here for MasterInstance DamageZones!
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
ResetChangedFlags();
|
||||
Check_Fpu();
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
DamageZone::ReadUpdateRecord(UpdateRecord *update_record)
|
||||
{
|
||||
Check(this);
|
||||
Check_Pointer(update_record);
|
||||
Verify(damageZoneIndex == update_record->damageZoneIndex);
|
||||
|
||||
damageLevel = update_record->damageLevel;
|
||||
damageZoneState.SetState(update_record->damageZoneState);
|
||||
damageZoneGraphicState.SetState(update_record->damageZoneGraphicState);
|
||||
changedFlags = update_record->changedFlags;
|
||||
Check_Fpu();
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
DamageZone::DamageZone(Simulation *owner, int damage_zone_index) :
|
||||
Node(DamageZoneClassID),
|
||||
materialTable(NULL, False),
|
||||
damageZoneState(DamageStateCount),
|
||||
damageZoneGraphicState(GraphicStateCount),
|
||||
defaultEffectSiteChain(NULL),
|
||||
internalVideoEffectSiteChain(NULL),
|
||||
externalVideoEffectSiteChain(NULL),
|
||||
internalAudioEffectSiteChain(NULL),
|
||||
externalAudioEffectSiteChain(NULL)
|
||||
{
|
||||
Check(owner);
|
||||
damageZoneIndex = damage_zone_index;
|
||||
owningSimulation = owner;
|
||||
damageLevel = 0.0f;
|
||||
explosionTable = NULL;
|
||||
for(int ii=0;ii<Damage::DamageTypeCount;ii++)
|
||||
{
|
||||
damageScale[ii] = 0.0f;
|
||||
}
|
||||
|
||||
damageZoneName = "TrivialDamageZone_Name";
|
||||
|
||||
changedFlags = 0;
|
||||
Reset();
|
||||
Check_Fpu();
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
DamageZone::DamageZone(
|
||||
Simulation *owning_simulation,
|
||||
int damage_zone_index,
|
||||
MemoryStream *stream
|
||||
) :
|
||||
Node(DamageZoneClassID),
|
||||
materialTable(NULL, False),
|
||||
damageZoneState(DamageStateCount),
|
||||
damageZoneGraphicState(GraphicStateCount),
|
||||
defaultEffectSiteChain(NULL),
|
||||
internalVideoEffectSiteChain(NULL),
|
||||
externalVideoEffectSiteChain(NULL),
|
||||
internalAudioEffectSiteChain(NULL),
|
||||
externalAudioEffectSiteChain(NULL)
|
||||
{
|
||||
Check(owning_simulation);
|
||||
Check(stream);
|
||||
|
||||
owningSimulation = owning_simulation;
|
||||
damageZoneIndex = damage_zone_index;
|
||||
damageLevel = 0.0f;
|
||||
explosionTable = NULL;
|
||||
Reset();
|
||||
|
||||
*stream >> damageZoneName;
|
||||
|
||||
if (owningSimulation->IsDerivedFrom(*JointedMover::GetClassDerivations()))
|
||||
{
|
||||
JointedMover *jointed_mover = Cast_Object(
|
||||
JointedMover*,
|
||||
owningSimulation
|
||||
);
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Read in all Effect Sites
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
int effect_site_count;
|
||||
int effect_site_index;
|
||||
EntitySegment *effect_site_segment;
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Read in External Video
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
for (int jj=0;jj<EffectSiteCount;++jj)
|
||||
{
|
||||
*stream >> effect_site_count;
|
||||
for(int ii=0;ii<effect_site_count;++ii)
|
||||
{
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Get the Site Segment From the Index
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
*stream >> effect_site_index;
|
||||
effect_site_segment = jointed_mover->GetSegment(effect_site_index);
|
||||
Check(effect_site_segment);
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Add the Segment to the Appropriate Chain
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
switch (jj)
|
||||
{
|
||||
case DefaultEffectSite:
|
||||
defaultEffectSiteChain.Add(effect_site_segment);
|
||||
break;
|
||||
case ExternalVideoEffectSite :
|
||||
externalVideoEffectSiteChain.Add(effect_site_segment);
|
||||
break;
|
||||
case InternalVideoEffectSite :
|
||||
internalVideoEffectSiteChain.Add(effect_site_segment);
|
||||
break;
|
||||
case ExternalAudioEffectSite :
|
||||
externalAudioEffectSiteChain.Add(effect_site_segment);
|
||||
break;
|
||||
case InternalAudioEffectSite :
|
||||
internalAudioEffectSiteChain.Add(effect_site_segment);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Read in these for consistancy
|
||||
// and for later improvements for
|
||||
// not Jointed Mover Objects!
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
int filler_int;
|
||||
for (int jj=0;jj<EffectSiteCount;++jj)
|
||||
{
|
||||
*stream >> filler_int;
|
||||
}
|
||||
}
|
||||
|
||||
*stream >> defaultArmorPoints;
|
||||
|
||||
int ii;
|
||||
for (ii=0; ii<Damage::DamageTypeCount; ii++)
|
||||
{
|
||||
*stream >> damageScale[ii];
|
||||
}
|
||||
|
||||
int skeleton_count;
|
||||
EntitySegment::SkeletonType skl_type;
|
||||
|
||||
*stream >> skeleton_count;
|
||||
|
||||
for(ii=0;ii<skeleton_count;++ii)
|
||||
{
|
||||
*stream >> skl_type;
|
||||
|
||||
int material_count;
|
||||
*stream >> material_count;
|
||||
if(!material_count)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
MaterialList *material_list = new MaterialList;
|
||||
Register_Object(material_list);
|
||||
for(int jj=0;jj<material_count;++jj)
|
||||
{
|
||||
CString new_material;
|
||||
*stream >> new_material;
|
||||
MaterialList::CStringPlug *new_plug =
|
||||
new MaterialList::CStringPlug(new_material);
|
||||
Register_Object(new_plug);
|
||||
material_list->Add(new_plug);
|
||||
}
|
||||
material_list->First();
|
||||
materialTable.AddValue(material_list, skl_type);
|
||||
}
|
||||
|
||||
changedFlags = 0;
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
DamageZone::~DamageZone()
|
||||
{
|
||||
MaterialTableIterator iterator(materialTable);
|
||||
iterator.DeletePlugs();
|
||||
|
||||
if (explosionTable)
|
||||
{
|
||||
Unregister_Object(explosionTable);
|
||||
delete explosionTable;
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
ExplosionTable*
|
||||
DamageZone::CreateExplosionTable(MemoryStream *explosion_stream)
|
||||
{
|
||||
Check(this);
|
||||
explosionTable = new ExplosionTable(explosion_stream);
|
||||
Register_Object(explosionTable);
|
||||
Check_Fpu();
|
||||
return explosionTable;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
DamageZone::TakeDamage(Damage &damage)
|
||||
{
|
||||
Check(this);
|
||||
Check_Pointer(&damage);
|
||||
|
||||
damageLevel += damage.damageAmount * damageScale[damage.damageType];
|
||||
Clamp(damageLevel, 0.0f, 1.0f);
|
||||
SetDamageLevelChangedFlag();
|
||||
if (damageLevel >= 1.0f)
|
||||
{
|
||||
SetDamageZoneState(BurningState);
|
||||
SetGraphicState(DestroyedGraphicState);
|
||||
SetGraphicStateChangedFlag();
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
DamageZone::TestInstance() const
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
DamageZone::CreateStreamedDamageZone(
|
||||
NotationFile *model_file,
|
||||
const char *,
|
||||
NotationFile *skl_file,
|
||||
CString damage_zone_name,
|
||||
MemoryStream *damage_zone_stream,
|
||||
NotationFile *dmg_file,
|
||||
const ResourceDirectories *directories
|
||||
)
|
||||
{
|
||||
Check_Pointer(damage_zone_name);
|
||||
Check_Pointer(&damage_zone_stream);
|
||||
Check_Pointer(directories);
|
||||
Check(dmg_file);
|
||||
|
||||
*damage_zone_stream << damage_zone_name;
|
||||
|
||||
//
|
||||
// Find dzone name in .dmg file
|
||||
//
|
||||
if(!dmg_file->PageExists(damage_zone_name))
|
||||
{
|
||||
std::cerr << damage_zone_name <<" listed in .skl, does not exist in .dmg file"<<std::endl;
|
||||
Check_Fpu();
|
||||
return -1;
|
||||
}
|
||||
if (skl_file)
|
||||
{
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Read and Write All The Effect Sites
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
WriteEffectSegmentIndicies(
|
||||
damage_zone_stream,
|
||||
damage_zone_name,
|
||||
dmg_file,
|
||||
skl_file,
|
||||
"DefaultEffectSiteName"
|
||||
);
|
||||
WriteEffectSegmentIndicies(
|
||||
damage_zone_stream,
|
||||
damage_zone_name,
|
||||
dmg_file,
|
||||
skl_file,
|
||||
"ExternalVideoEffectSiteName"
|
||||
);
|
||||
WriteEffectSegmentIndicies(
|
||||
damage_zone_stream,
|
||||
damage_zone_name,
|
||||
dmg_file,
|
||||
skl_file,
|
||||
"InternalVideoEffectSiteName"
|
||||
);
|
||||
WriteEffectSegmentIndicies(
|
||||
damage_zone_stream,
|
||||
damage_zone_name,
|
||||
dmg_file,
|
||||
skl_file,
|
||||
"ExternalAudioEffectSiteName"
|
||||
);
|
||||
WriteEffectSegmentIndicies(
|
||||
damage_zone_stream,
|
||||
damage_zone_name,
|
||||
dmg_file,
|
||||
skl_file,
|
||||
"InternalAudioEffectSiteName"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
int zero_int(0);
|
||||
for(int ii=0;ii<EffectSiteCount;++ii)
|
||||
{
|
||||
*damage_zone_stream << zero_int;
|
||||
}
|
||||
}
|
||||
|
||||
Scalar default_points;
|
||||
if(!dmg_file->GetEntry(
|
||||
damage_zone_name,
|
||||
"WeaponDamagePoints",
|
||||
&default_points
|
||||
)
|
||||
)
|
||||
{
|
||||
std::cerr<<damage_zone_name<<" Must have a WeaponDamagePoints"<<std::endl;
|
||||
return False;
|
||||
}
|
||||
if (!default_points)
|
||||
{
|
||||
std::cerr<<"DefaultDamagePoints must have a non-zero value !"<<std::endl;
|
||||
Check_Fpu();
|
||||
return False;
|
||||
}
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Write default armor values
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
*damage_zone_stream << default_points;
|
||||
|
||||
//
|
||||
// Read the damage Points values
|
||||
//
|
||||
float point_data;
|
||||
Scalar modified_armor;
|
||||
|
||||
if(!dmg_file->GetEntry(
|
||||
damage_zone_name,
|
||||
"CollisionDamagePoints",
|
||||
&point_data
|
||||
)
|
||||
)
|
||||
{
|
||||
modified_armor = 1.0f/default_points;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (point_data == 0.0f)
|
||||
{
|
||||
modified_armor = 1.0f/default_points;
|
||||
}
|
||||
else
|
||||
{
|
||||
modified_armor = 1.0f/point_data;
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
*damage_zone_stream << modified_armor;
|
||||
|
||||
if(!dmg_file->GetEntry(
|
||||
damage_zone_name,
|
||||
"BallisticDamagePoints",
|
||||
&point_data
|
||||
)
|
||||
)
|
||||
{
|
||||
modified_armor = 1.0f/default_points;
|
||||
}
|
||||
else
|
||||
{
|
||||
modified_armor = 1.0f/point_data;
|
||||
}
|
||||
*damage_zone_stream << modified_armor;
|
||||
|
||||
if(!dmg_file->GetEntry(
|
||||
damage_zone_name,
|
||||
"ExplosiveDamagePoints",
|
||||
&point_data
|
||||
)
|
||||
)
|
||||
{
|
||||
modified_armor = 1.0f/default_points;
|
||||
}
|
||||
else
|
||||
{
|
||||
modified_armor = 1.0f/point_data;
|
||||
}
|
||||
*damage_zone_stream << modified_armor;
|
||||
|
||||
if(!dmg_file->GetEntry(
|
||||
damage_zone_name,
|
||||
"LaserDamagePoints",
|
||||
&point_data
|
||||
)
|
||||
)
|
||||
{
|
||||
modified_armor = 1.0f/default_points;
|
||||
}
|
||||
else
|
||||
{
|
||||
modified_armor = 1.0f/point_data;
|
||||
}
|
||||
*damage_zone_stream << modified_armor;
|
||||
|
||||
if(!dmg_file->GetEntry(
|
||||
damage_zone_name,
|
||||
"EnergyDamagePoints",
|
||||
&point_data
|
||||
)
|
||||
)
|
||||
{
|
||||
modified_armor = 1.0f/default_points;
|
||||
}
|
||||
else
|
||||
{
|
||||
modified_armor = 1.0f/point_data;
|
||||
}
|
||||
*damage_zone_stream << modified_armor;
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Get dzm filename
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
NameList *dzm_namelist = model_file->MakeEntryList("video","dzm");
|
||||
if(!dzm_namelist)
|
||||
{
|
||||
int zero_scalar(0.0f);
|
||||
*damage_zone_stream << zero_scalar;
|
||||
return True;
|
||||
}
|
||||
Register_Object(dzm_namelist);
|
||||
int dzm_filecount;
|
||||
dzm_filecount = dzm_namelist->EntryCount();
|
||||
*damage_zone_stream << dzm_filecount;
|
||||
|
||||
if(dzm_filecount)
|
||||
{
|
||||
NameList::Entry *dzm_fileentry = dzm_namelist->GetFirstEntry();
|
||||
while(dzm_fileentry)
|
||||
{
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// write out the skeleton type of the material
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
//
|
||||
CString dzm_entry_name;
|
||||
dzm_entry_name = dzm_fileentry->GetName();
|
||||
|
||||
EntitySegment::SkeletonType skeleton_type;
|
||||
if (! dzm_entry_name.Compare("dzm") )
|
||||
{
|
||||
skeleton_type = EntitySegment::SkeletonType_N;
|
||||
}
|
||||
else if (! dzm_entry_name.Compare("dzms") )
|
||||
{
|
||||
skeleton_type = EntitySegment::SkeletonType_S;
|
||||
}
|
||||
else if (! dzm_entry_name.Compare("dzmt") )
|
||||
{
|
||||
skeleton_type = EntitySegment::SkeletonType_T;
|
||||
}
|
||||
else if (! dzm_entry_name.Compare("dzmo") )
|
||||
{
|
||||
skeleton_type = EntitySegment::SkeletonType_O;
|
||||
}
|
||||
else if (! dzm_entry_name.Compare("dzma") )
|
||||
{
|
||||
skeleton_type = EntitySegment::SkeletonType_A;
|
||||
}
|
||||
else if (! dzm_entry_name.Compare("dzmb") )
|
||||
{
|
||||
skeleton_type = EntitySegment::SkeletonType_B;
|
||||
}
|
||||
else if (! dzm_entry_name.Compare("dzmc") )
|
||||
{
|
||||
skeleton_type = EntitySegment::SkeletonType_C;
|
||||
}
|
||||
else if (! dzm_entry_name.Compare("dzmd") )
|
||||
{
|
||||
skeleton_type = EntitySegment::SkeletonType_D;
|
||||
}
|
||||
*damage_zone_stream << skeleton_type;
|
||||
|
||||
//
|
||||
// Get the name of the dzm File
|
||||
//
|
||||
char *filename = MakePathedFilename(
|
||||
directories->videoDirectory,
|
||||
dzm_fileentry->GetChar()
|
||||
);
|
||||
Register_Pointer(filename);
|
||||
//
|
||||
// Create a Notation file from the dzm ASCII File
|
||||
//
|
||||
NotationFile *dzm_file = new NotationFile(filename);
|
||||
Register_Object(dzm_file);
|
||||
|
||||
NameList *material_list;
|
||||
material_list = dzm_file->MakeEntryList(damage_zone_name, "material");
|
||||
int entry_count(0);
|
||||
if(material_list)
|
||||
{
|
||||
|
||||
Register_Object(material_list);
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Write out how many materials
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
entry_count = material_list->EntryCount();
|
||||
*damage_zone_stream << entry_count;
|
||||
if(entry_count)
|
||||
{
|
||||
NameList::Entry *dzm_entry;
|
||||
dzm_entry = material_list->GetFirstEntry();
|
||||
Check(dzm_entry);
|
||||
CString material_name;
|
||||
while(dzm_entry)
|
||||
{
|
||||
material_name = dzm_entry->GetChar();
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Write out the material name
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
*damage_zone_stream << material_name;
|
||||
dzm_entry = dzm_entry->GetNextEntry();
|
||||
}
|
||||
}
|
||||
Unregister_Object(material_list);
|
||||
delete material_list;
|
||||
}
|
||||
else
|
||||
{
|
||||
*damage_zone_stream << entry_count;
|
||||
}
|
||||
dzm_fileentry = dzm_fileentry->GetNextEntry();
|
||||
Unregister_Pointer(filename);
|
||||
delete filename;
|
||||
Unregister_Object(dzm_file);
|
||||
delete dzm_file;
|
||||
}
|
||||
}
|
||||
Unregister_Object(dzm_namelist);
|
||||
delete dzm_namelist;
|
||||
|
||||
Check_Fpu();
|
||||
return True;
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
int
|
||||
DamageZone::WriteEffectSegmentIndicies(
|
||||
MemoryStream *damage_zone_stream,
|
||||
const char *damage_zone_name,
|
||||
NotationFile *dmg_file,
|
||||
NotationFile *skl_file,
|
||||
const char *effect_type
|
||||
)
|
||||
{
|
||||
Check(dmg_file);
|
||||
Check(skl_file);
|
||||
Check_Pointer(damage_zone_name);
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Make an Entry list for this type of effect Site
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
int effect_count(0);
|
||||
NameList::Entry *effect_entry;
|
||||
NameList *effect_namelist = dmg_file->MakeEntryList(damage_zone_name, effect_type);
|
||||
if (!effect_namelist)
|
||||
{
|
||||
//
|
||||
//~~~~~~~~~~~
|
||||
// No Entries
|
||||
//~~~~~~~~~~~
|
||||
//
|
||||
*damage_zone_stream << effect_count;
|
||||
Check_Fpu();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Register_Object(effect_namelist);
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Write Out number of sites
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
effect_count = effect_namelist->EntryCount();
|
||||
*damage_zone_stream << effect_count;
|
||||
effect_entry = effect_namelist->GetFirstEntry();
|
||||
CString site_page_name;
|
||||
int effect_site_index;
|
||||
while(effect_entry)
|
||||
{
|
||||
site_page_name = effect_entry->GetChar();
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Get SegmentIndex for this effect site Name
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
effect_site_index =
|
||||
JointedMover::GetSegmentIndex(site_page_name, skl_file);
|
||||
if (effect_site_index == -1)
|
||||
{
|
||||
std::cerr<<site_page_name<<" not found in skl file !"<<std::endl;
|
||||
Unregister_Object(effect_namelist);
|
||||
delete effect_namelist;
|
||||
return -1;
|
||||
}
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~
|
||||
// Write Out the Index
|
||||
//~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
*damage_zone_stream << effect_site_index;
|
||||
effect_entry = effect_entry->GetNextEntry();
|
||||
}
|
||||
Unregister_Object(effect_namelist);
|
||||
delete effect_namelist;
|
||||
}
|
||||
Check_Fpu();
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user