Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1246 lines
35 KiB
C++

#include "MW4Headers.hpp"
#include "MWObject.hpp"
#include "Subsystem.hpp"
#include "Torso.hpp"
#include "MWDamageObject.hpp"
#include "HeatManager.hpp"
#include "gameinfo.hpp"
#include "MWApplication.hpp"
#include <MissionLang\Resource.h>
#include <Adept\Tool.hpp>
#include <Adept\EntityManager.hpp>
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int MWObject__GameModel::ConvertStringToMoveType (const char *str)
{
if (!str)
return NONE_MOVETYPE;
if (!stricmp (str,"LEGMOVETYPE"))
return LEG_MOVETYPE;
if (!stricmp (str,"LEGJUMPMOVETYPE"))
return LEGJUMP_MOVETYPE;
if (!stricmp (str,"TRACKMOVETYPE"))
return TRACK_MOVETYPE;
if (!stricmp (str,"WHEELMOVETYPE"))
return WHEEL_MOVETYPE;
if (!stricmp (str,"FLYERMOVETYPE"))
return FLYER_MOVETYPE;
if (!stricmp (str,"HOVERMOVETYPE"))
return HOVER_MOVETYPE;
if (!stricmp (str,"HELIMOVETYPE"))
return HELI_MOVETYPE;
if (!stricmp (str,"DROPSHIPMOVETYPE"))
return DROPSHIP_MOVETYPE;
if (!stricmp (str,"WATERMOVETYPE"))
return WATER_MOVETYPE;
gosREPORT (false,"Unknown movement type in MWObject gamemodel");
return NONE_MOVETYPE;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWObject__CreateMessage::ConstructCreateMessage(Script *script)
{
Check_Object(script);
#if defined(_ARMOR)
int stack_level = Tool::Instance->GetStackLevel();
#endif
#ifdef LAB_ONLY
strcpy(MWGameInfo::g_ResourceFile, (char *)(script->instancePage->GetNotationFile()->GetFileName()));
strcpy(MWGameInfo::g_ResourceEntry, (char *)(script->instancePage->GetName()));
#endif
//
//--------------
// Set up stream
//--------------
//
MemoryStream *message_stream = script->messageStream;
Check_Object(message_stream);
message_stream->AllocateBytes(sizeof(MWObject__CreateMessage));
BaseClass::ConstructCreateMessage(script);
MWObject__CreateMessage *message =
Cast_Pointer(
MWObject__CreateMessage*,
message_stream->GetPointer()
);
message->messageLength = sizeof(*message);
//
//---------------------------------------------------------------
// Point at the notation file and make other files relative to it
//---------------------------------------------------------------
//
Page *instance_page = script->instancePage;
Check_Object(instance_page);
NotationFile *instance_file = instance_page->GetNotationFile();
Check_Object(instance_file);
Check_Object(Tool::Instance);
Tool::Instance->PushFilePath(instance_file);
Check_Object(Resource::ParentFileDependencies);
//
//--------------------------------------
// Make sure that no armature exists yet
//--------------------------------------
//
{
Verify(!message->armatureStreamResourceID);
NotationFile armatures_file;
if (instance_page->GetEntry("Armature", &armatures_file))
{
const char* armatures_filename = armatures_file.GetFileName();
//
//------------------------------------------------------------------
// Look for the armature stream resource to see if it is up to date
//------------------------------------------------------------------
//
Resource armature_resource(armatures_filename);
if (
armature_resource.DoesResourceExist() &&
armature_resource.IsResourceUpToDate()
)
{
WORD span;
armature_resource.LoadData();
armature_resource >> span;
Verify(span > 0);
*script->baseID += span;
message->armatureStreamResourceID = armature_resource.GetResourceID();
message->replicatorID += span;
if (!armature_resource.IsRegistered())
armature_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
}
//
//------------------------------------------------
// For each instance_page, an entity will be built
//------------------------------------------------
//
else
{
FileDependencies arm_deps(*armatures_file.GetFileDependencies());
FileDependencies *parent = Resource::ParentFileDependencies;
Resource::ParentFileDependencies = &arm_deps;
Tool::Instance->PushFilePath(&armatures_file);
DynamicMemoryStream armature_stream;
armature_stream << static_cast<WORD>(0);
ReplicatorID starting_id = *script->baseID;
NotationFile::PageIterator *instance_names = armatures_file.MakePageIterator();
Check_Object(instance_names);
Page *instance;
while ((instance = instance_names->ReadAndNext()) != NULL)
{
Check_Object(instance);
//
//-----------------------------------------
// Create the entity for this instance_page
//-----------------------------------------
//
bool on_root = false;
instance->GetEntry("AttachedToRoot", &on_root);
if (on_root)
{
Entity::CreateMessage *message =
Tool::Instance->ConstructCreateMessage(
&armature_stream,
instance,
script->baseID
);
Check_Object(message);
armature_stream.AdvancePointer(message->messageLength);
}
}
//
//-----------------------------------------
// Only save out the stream if there is one
//-----------------------------------------
//
if (armature_stream.GetBytesUsed() > sizeof(WORD))
{
armature_stream.Rewind();
Verify(*script->baseID != starting_id);
WORD span =
static_cast<WORD>(script->baseID->localID - starting_id.localID);
armature_stream << span;
armature_resource.Save(&armature_stream, &arm_deps);
Check_Object(&armature_resource);
message->armatureStreamResourceID = armature_resource.GetResourceID();
message->replicatorID += span;
}
else
message->armatureStreamResourceID = ResourceID::Null;
if (!armature_resource.IsRegistered())
parent->AddDependencies(&arm_deps);
Resource::ParentFileDependencies = parent;
//
//------------------------
// Clean up the tool stack
//------------------------
//
Check_Object(instance_names);
delete instance_names;
Tool::Instance->PopFilePath();
}
}
}
//
//------------------------------------------------------------
// Create messages for the subsystem stream only if it's there
//------------------------------------------------------------
//
{
NotationFile subsystems_file;
message->subsystemStreamResourceID = ResourceID::Null;
if (instance_page->GetEntry("Subsystems", &subsystems_file))
{
const char *subsystems_filename = subsystems_file.GetFileName();
Check_Pointer(subsystems_filename);
//
//------------------------------------------------------------------
// Look for the subsystem stream resource to see if it is up to date
//------------------------------------------------------------------
//
Resource subsystem_resource(subsystems_filename);
if (
subsystem_resource.DoesResourceExist() &&
subsystem_resource.IsResourceUpToDate()
)
{
subsystem_resource.LoadData();
WORD span;
subsystem_resource >> span;
Verify(span > 0);
*script->baseID += span;
message->subsystemStreamResourceID = subsystem_resource.GetResourceID();
message->replicatorID += span;
if (!subsystem_resource.IsRegistered())
subsystem_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
}
else
{
//
//---------------------------------------
// For each instance_page, an entity will be built
//---------------------------------------
//
FileDependencies sub_deps(*subsystems_file.GetFileDependencies());
FileDependencies *parent = Resource::ParentFileDependencies;
Resource::ParentFileDependencies = &sub_deps;
Tool::Instance->PushFilePath(&subsystems_file);
DynamicMemoryStream subsystem_stream(sizeof(WORD));
subsystem_stream << static_cast<WORD>(0);
ReplicatorID starting_id = *script->baseID;
NotationFile::PageIterator *instance_names = subsystems_file.MakePageIterator();
Check_Object(instance_names);
Page *instance;
while ((instance = instance_names->ReadAndNext()) != NULL)
{
Check_Object(instance);
//
//--------------------------------
// Create the entity for this instance_page
//--------------------------------
//
Entity::CreateMessage *message =
Tool::Instance->ConstructCreateMessage(
&subsystem_stream,
instance,
script->baseID
);
Check_Object(message);
subsystem_stream.AdvancePointer(message->messageLength);
}
//
//-----------------------------------------
// Only save out the stream if there is one
//-----------------------------------------
//
if (subsystem_stream.GetBytesUsed() > sizeof(WORD))
{
subsystem_stream.Rewind();
Verify(*script->baseID != starting_id);
WORD span =
static_cast<WORD>(script->baseID->localID - starting_id.localID);
subsystem_stream << span;
subsystem_resource.Save(&subsystem_stream, &sub_deps);
Check_Object(&subsystem_resource);
message->subsystemStreamResourceID = subsystem_resource.GetResourceID();
message->replicatorID += span;
}
else
message->subsystemStreamResourceID = ResourceID::Null;
if (!subsystem_resource.IsRegistered())
parent->AddDependencies(&sub_deps);
Resource::ParentFileDependencies = parent;
//
//------------------------
// Clean up the tool stack
//------------------------
//
Check_Object(instance_names);
delete instance_names;
Tool::Instance->PopFilePath();
}
}
}
//
//----------------------------------------------------------
// Create messages a damage object stream only if it's there
//----------------------------------------------------------
//
{
NotationFile damage_file;
message->damageStreamResourceID = ResourceID::Null;
if (instance_page->GetEntry("DamageObjects", &damage_file))
{
Check_Object(Tool::Instance);
const char* damage_filename = damage_file.GetFileName();
Check_Pointer(damage_filename);
//
//---------------------------------------------------------------
// Look for the damage stream resource to see if it is up to date
//---------------------------------------------------------------
//
Resource damage_resource(damage_filename);
if (
damage_resource.DoesResourceExist() &&
damage_resource.IsResourceUpToDate()
)
{
message->damageStreamResourceID = damage_resource.GetResourceID();
if (!damage_resource.IsRegistered())
damage_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
}
else
{
//
//---------------------------------------
// For each instance_page, an entity will be built
//---------------------------------------
//
FileDependencies damage_deps(*damage_file.GetFileDependencies());
FileDependencies *parent = Resource::ParentFileDependencies;
Resource::ParentFileDependencies = &damage_deps;
Tool::Instance->PushFilePath(&damage_file);
DynamicMemoryStream damage_stream;
NotationFile::PageIterator *damage_names = damage_file.MakePageIterator();
Check_Object(damage_names);
Page *damage_instance;
//
//---------------------------------------
// Create the damage Object for this instance_page
//---------------------------------------
//
while ((damage_instance = damage_names->ReadAndNext()) != NULL)
{
//
//-------------------------------------------------------
//Check to see if we are internal or just a damage object
//-------------------------------------------------------
//
int damage_zone;
if (!damage_instance->GetEntry("DamageZone", &damage_zone))
{
DamageObject::ConstructDamageObjectStream(
&damage_stream,
damage_instance
);
}
else
{
MWInternalDamageObject::ConstructMWInternalDamageObjectStream(
&damage_stream,
damage_instance
);
}
}
//
//-----------------------------------------
// Only save out the stream if there is one
//-----------------------------------------
//
if (damage_stream.GetBytesUsed())
{
damage_resource.Save(
&damage_stream,
&damage_deps
);
if (!damage_resource.IsRegistered())
parent->AddDependencies(&damage_deps);
Check_Object(&damage_resource);
message->damageStreamResourceID = damage_resource.GetResourceID();
}
else
message->damageStreamResourceID = ResourceID::Null;
Resource::ParentFileDependencies = parent;
//------------------------
// Clean up the tool stack
//------------------------
//
Check_Object(damage_names);
delete damage_names;
Tool::Instance->PopFilePath();
}
}
}
const char *skin_name;
message->skinPrefix = DefaultSkinPrefix;
if(instance_page->GetEntry("Skin", &skin_name))
message->skinPrefix = *skin_name;
message->teamDecal = 0;
instance_page->GetEntry("TeamDecal", &message->teamDecal);
message->pilotDecal = 0;
instance_page->GetEntry("PilotDecal", &message->pilotDecal);
message->nameIndex = -1;
instance_page->GetEntry("NameIndex", &message->nameIndex);
message->doesHaveInstanceName = false;
instance_page->GetEntry("DoesHaveInstanceName", &message->doesHaveInstanceName);
Tool::Instance->PopFilePath();
Verify(stack_level == Tool::Instance->GetStackLevel());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWObject__GameModel::ConstructGameModel(Script *script)
{
Check_Object(script);
#if defined(_ARMOR)
int stack_level = Tool::Instance->GetStackLevel();
#endif
//
//--------------
// Set up stream
//--------------
//
MemoryStream *model_stream = script->modelStream;
Check_Object(model_stream);
model_stream->AllocateBytes(sizeof(MWObject__GameModel));
BaseClass::ConstructGameModel(script);
MWObject__GameModel *model =
Cast_Pointer(MWObject__GameModel*, model_stream->GetPointer());
NotationFile *model_file = script->modelFile;
Check_Object(model_file);
const char *temp_name = NULL;
Page *game_page = model_file->GetPage("GameData");
Check_Object(game_page);
game_page->GetEntry("AnimationScript", &temp_name);
model->animScriptName[0] = NULL;
if (temp_name != NULL)
{
Str_Copy(model->animScriptName, temp_name, sizeof(model->animScriptName));
}
const char *str = NULL;
game_page->GetEntry("MoveTypeFlag",&str);
model->moveTypeFlag = ConvertStringToMoveType (str);
//
//---------------------------------------------
//Create the array of Damage Effect ResourceIDs
//---------------------------------------------
//
model->idleEffectResourceID = ResourceID::Null;
NotationFile effects_file;
if(game_page->GetEntry("IdleEffectsFile", &effects_file))
{
const char *effects_file_name = effects_file.GetFileName();
Check_Pointer(effects_file_name);
//
//------------------------------------------------------------------
// Look for the subsystem stream resource to see if it is up to date
//------------------------------------------------------------------
//
Resource effects_resource(effects_file_name);
if (
effects_resource.DoesResourceExist() &&
effects_resource.IsResourceUpToDate()
)
{
model->idleEffectResourceID = effects_resource.GetResourceID();
if (!effects_resource.IsRegistered())
effects_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
}
else
{
//
//---------------------------------------
// For each page, an entity will be built
//---------------------------------------
//
FileDependencies effect_deps(*effects_file.GetFileDependencies());
FileDependencies *parent = Resource::ParentFileDependencies;
Resource::ParentFileDependencies = &effect_deps;
Tool::Instance->PushFilePath(&effects_file);
DynamicMemoryStream effects_stream;
NotationFile::PageIterator *instance_names = effects_file.MakePageIterator();
Check_Object(instance_names);
Page *instance;
while ((instance = instance_names->ReadAndNext()) != NULL)
{
Check_Object(instance);
//
//--------------------------------
// Create the entity for this page
//--------------------------------
//
//First get and create the effect resource and store the ID
const char* effect_file;
instance->GetEntry("EffectFile", &effect_file, true);
Resource effect_entry_resource;
Tool::Instance->ConstructDataList(&effect_entry_resource, effect_file);
Check_Object(&effect_entry_resource);
Verify(effect_entry_resource.DoesResourceExist());
effects_stream << effect_entry_resource.GetResourceID();
//Next read in the site name and store it
const char *site_name;
MString site_string;
instance->GetEntry("SiteName", &site_name);
Check_Pointer(site_name);
site_string = site_name;
effects_stream << site_string;
}
//
//-----------------------------------------
// Only save out the stream if there is one
//-----------------------------------------
//
if (effects_stream.GetBytesUsed() > 0)
{
effects_resource.Save(&effects_stream, &effect_deps);
if (!effects_resource.IsRegistered())
parent->AddDependencies(&effect_deps);
Check_Object(&effects_resource);
model->idleEffectResourceID = effects_resource.GetResourceID();
}
else
model->idleEffectResourceID = ResourceID::Null;
Resource::ParentFileDependencies = parent;
//
//------------------------
// Clean up the tool stack
//------------------------
//
Check_Object(instance_names);
delete instance_names;
Tool::Instance->PopFilePath();
}
}
Verify(stack_level == Tool::Instance->GetStackLevel());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWObject__GameModel::ConstructOBBStream(Script *script)
{
Check_Object(script);
Check_Object(Resource::ParentFileDependencies);
//
//--------------
// Set up stream
//--------------
//
MemoryStream *model_stream = script->modelStream;
Check_Object(model_stream);
MWObject__GameModel *model =
Cast_Pointer(MWObject__GameModel*, model_stream->GetPointer());
//
//------------------------------
// See if there is an OBB stream
//------------------------------
//
NotationFile *model_file = script->modelFile;
Check_Object(model_file);
Page *game_page = model_file->GetPage("GameData");
Check_Object(game_page);
const char* obb_stream_name;
//
//---------------------------------------------------
// If there is a solid OBB, store it in the resources
//---------------------------------------------------
//
model->obbStreamResourceID = ResourceID::Null;
if (game_page->GetEntry("SolidOBB", &obb_stream_name))
{
Check_Pointer(obb_stream_name);
FileStream solid_stream(obb_stream_name);
MString file_name = model_file->GetFileName();
file_name += "{SolidOBB}";
Resource obb_res(file_name);
if (!obb_res.DoesResourceExist() || !obb_res.IsResourceUpToDate())
{
FileDependencies obb_dependencies;
obb_dependencies.AddDependency(&solid_stream);
obb_res.Save(&solid_stream, &obb_dependencies);
if (!obb_res.IsRegistered())
obb_res.AddFileDependenciesTo(Resource::ParentFileDependencies);
}
else if (!obb_res.IsRegistered())
obb_res.AddFileDependenciesTo(Resource::ParentFileDependencies);
model->obbStreamResourceID = obb_res.GetResourceID();
}
//
//----------------------------------------------------------
// If there is a hierarchical OBB, store it in the resources
//----------------------------------------------------------
//
model->hierarchicalOBBStreamResourceID = ResourceID::Null;
if (game_page->GetEntry("HierarchicalOBB", &obb_stream_name))
{
Check_Pointer(obb_stream_name);
FileStream solid_stream(obb_stream_name);
MString file_name = model_file->GetFileName();
file_name += "{HierarchicalOBB}";
Resource obb_res(file_name);
if (!obb_res.DoesResourceExist() || !obb_res.IsResourceUpToDate())
{
FileDependencies obb_dependencies;
obb_dependencies.AddDependency(&solid_stream);
obb_res.Save(&solid_stream, &obb_dependencies);
if (!obb_res.IsRegistered())
obb_res.AddFileDependenciesTo(Resource::ParentFileDependencies);
}
else if (!obb_res.IsRegistered())
obb_res.AddFileDependenciesTo(Resource::ParentFileDependencies);
model->hierarchicalOBBStreamResourceID = obb_res.GetResourceID();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
MWObject__GameModel::ReadAndVerify(
MWObject__GameModel *model,
ModelAttributeEntry *attribute_entry,
const char *data,
char **error,
int error_buffer
)
{
Check_Object(attribute_entry);
bool result = false;
bool valid_data = (*data != '\0');
//
//----------------------------------------
//Read in the values from the data entered
//----------------------------------------
//
result =
BaseClass::ReadAndVerify(
model,
attribute_entry,
data,
error,
error_buffer
);
//
//---------------------------
//Verify all the model values
//---------------------------
//
switch(attribute_entry->attributeID)
{
case DestroyedEffectResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
case DeathEntityResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
case SecondaryDestroyedEffectResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
case SecondaryDeathEntityResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
case VehicleTonnageAttributeID:
{
if(!valid_data)
{
Scalar value = 1.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->vehicleTonnage < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]VehicleTonnage=%f}: value must be >= 0!",
model->vehicleTonnage
);
result = false;
}
break;
}
case MaxVehicleTonnageAttributeID:
{
if(!valid_data)
{
Scalar value = 500.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->maxVehicleTonnage < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MaxVehicleTonnage=%f}: value must be >= 0!",
model->maxVehicleTonnage
);
result = false;
}
break;
}
case EyeSiteNameAttributeID:
{
if(!valid_data)
{
char *value;
value = new char[MaxStringLength];
Register_Pointer(value);
Str_Copy(value, "site_eyepoint", MaxStringLength);
attribute_entry->SetValue(model, value);
result = true;
Unregister_Pointer(value);
delete value;
break;
}
break;
}
case PartDestructionEffectResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
case SplashDamageRadiusAttributeID:
{
if(!valid_data)
{
Scalar value = 1.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->splashDamageRadius < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]SplashDamageRadius=%f}: value must be > 0!",
model->splashDamageRadius
);
result = false;
}
break;
}
case SplashDamageAmountAttributeID:
{
if(!valid_data)
{
Scalar value = 1.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->splashDamageAmount < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]SplashDamageAmount=%f}: value must be > 0!",
model->splashDamageAmount
);
result = false;
}
break;
}
case VehicleBattleValueAttributeID:
{
if(!valid_data)
{
int value = 0;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->vehicleBattleValue < 0)
{
_snprintf(
*error,
error_buffer,
"{[GameData]VehicleBattleValue=%f}: value must be >= 0!",
model->vehicleBattleValue
);
result = false;
}
break;
}
case CoolantEffectResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
case OverHeatEffectResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
case EjectEffectResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
case SplashHeatAmountAttributeID:
{
if(!valid_data)
{
Scalar value = 1.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->splashHeatAmount < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]SplashHeatAmount=%f}: value must be >= 0!",
model->splashHeatAmount
);
result = false;
}
break;
}
case NameIndexAttributeID:
{
if(!valid_data)
{
int value = IDS_NONAME;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->m_nameIndex < 0)
{
_snprintf(
*error,
error_buffer,
"{[GameData]NameIndex=%f}: value must be >= 0!",
model->m_nameIndex
);
result = false;
}
break;
}
}
return result;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWObject::SaveInstanceText(Page *instance_page)
{
Check_Object(this);
Check_Object(instance_page);
BaseClass::SaveInstanceText(instance_page);
//
//----------------------------
//Save all of the stream names
//----------------------------
//
if(armatureStreamResourceID != ResourceID::Null)
{
Resource armature_resource(armatureStreamResourceID);
Verify(armature_resource.DoesResourceExist());
instance_page->SetEntry("Armature", armature_resource.GetName());
}
if(subsystemStreamResourceID != ResourceID::Null)
{
Resource subsystem_resource(subsystemStreamResourceID);
Verify(subsystem_resource.DoesResourceExist());
instance_page->SetEntry("Subsystems", subsystem_resource.GetName());
}
if(!invulnerable && damageStreamResourceID != ResourceID::Null)
{
Resource damage_resource(damageStreamResourceID);
Verify(damage_resource.DoesResourceExist());
instance_page->SetEntry("DamageObjects", damage_resource.GetName());
}
if(m_heatManager)
instance_page->SetEntry("CurrentHeat", m_heatManager->GetHeat());
char szTemp[2];
szTemp[0] = m_skinPrefix;
szTemp[1] = 0;
instance_page->SetEntry("Skin", szTemp);
instance_page->SetEntry("TeamDecal", m_teamDecal);
instance_page->SetEntry("PilotDecal", m_teamDecal);
instance_page->SetEntry("DoesHaveInstanceName", m_doesHaveInstanceName);
if(m_doesHaveInstanceName)
instance_page->SetEntry("@LocalizedInstanceName", instanceName);
if(m_localizeIndex > -1)
// instance_page->SetEntry("NameIndex", m_localizeIndex);
// Wipe this value out so that NameTable doesn't replace a define with a hard number.
instance_page->SetEntry("NameIndex", -1);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ResourceID
MWObject__GameModel::CreateEffectTableResource(Stuff::NotationFile *effect_file, BYTE length)
{
Check_Object(Resource::ParentFileDependencies);
Resource table_resource(effect_file->GetFileName());
if (
table_resource.DoesResourceExist() &&
table_resource.IsResourceUpToDate()
)
{
if (!table_resource.IsRegistered())
table_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
return table_resource.GetResourceID();
}
DynamicMemoryStream effects_stream(sizeof(int) + length * sizeof(ResourceID));
//
//----------------------
//Create the stream here
//----------------------
//
effects_stream << length;
ResourceID *stream_array = Cast_Pointer(ResourceID *, effects_stream.GetPointer());
for(int i=0;i<length;i++)
{
stream_array[i] = ResourceID::Null;
}
Check_Object(effect_file);
Page *effect_page = effect_file->FindPage("EffectList");
if (effect_page)
{
ChainOf<Note*> *effects = effect_page->MakeNoteChain("Effect");
Check_Object(effects);
Page::NoteIterator effects_list(effects);
Note *effects_entry;
while ((effects_entry = effects_list.ReadAndNext()) != NULL)
{
Check_Object(effects_entry);
const char *effect_data;
effects_entry->GetEntry(&effect_data);
Check_Pointer(effect_data);
MString entry_string;
MString effect_file_name;
entry_string = effect_data;
effect_file_name = entry_string.GetNthToken(0, ",");
Check_Object(Tool::Instance);
Check_Object(ResourceManager::Instance);
Resource effect_resource;
Tool::Instance->ConstructDataList(&effect_resource, effect_file_name);
Check_Object(&effect_resource);
Verify(effect_resource.DoesResourceExist());
MString material_name;
material_name = entry_string.GetNthToken(1, ",");
int material_num = MaterialTypeTextToAscii(material_name);
Verify(material_num < length);
stream_array[material_num] = effect_resource.GetResourceID();
}
if (effects_stream.GetBytesUsed() > 0)
{
table_resource.Save(
&effects_stream,
Resource::ParentFileDependencies
);
Check_Object(&table_resource);
delete effects;
return table_resource.GetResourceID();
}
delete effects;
}
return ResourceID::Null;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWObject::CreateArmatureStream(MemoryStream *stream, NotationFile *notation_file)
{
Check_Pointer(stream);
Check_Pointer(notation_file);
Tool::Instance->PushFilePath(notation_file);
FileDependencies arm_deps(*notation_file->GetFileDependencies());
FileDependencies *parent = Resource::ParentFileDependencies;
Resource::ParentFileDependencies = &arm_deps;
*stream << static_cast<WORD>(0);
ReplicatorID starting_id = ReplicatorID::Null;
NotationFile::PageIterator *instance_names = notation_file->MakePageIterator();
Check_Object(instance_names);
Page *instance;
while ((instance = instance_names->ReadAndNext()) != NULL)
{
Check_Object(instance);
//
//-----------------------------------------
// Create the entity for this instance_page
//-----------------------------------------
//
bool on_root = false;
instance->GetEntry("AttachedToRoot", &on_root);
if (on_root)
{
Entity::CreateMessage *message =
Tool::Instance->ConstructCreateMessage(
stream,
instance,
&starting_id
);
Check_Object(message);
stream->AdvancePointer(message->messageLength);
}
}
if (stream->GetBytesUsed() > sizeof(WORD))
{
stream->Rewind();
WORD span =
static_cast<WORD>(starting_id.localID - 0);
*stream << span;
}
//
//------------------------
// Clean up the tool stack
//------------------------
//
Resource::ParentFileDependencies = parent;
Check_Object(instance_names);
delete instance_names;
Tool::Instance->PopFilePath();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWObject::CreateDamageStream(MemoryStream *stream, NotationFile *notation_file)
{
Check_Pointer(stream);
Check_Pointer(notation_file);
FileDependencies damage_deps(*notation_file->GetFileDependencies());
FileDependencies *parent = Resource::ParentFileDependencies;
Resource::ParentFileDependencies = &damage_deps;
Tool::Instance->PushFilePath(notation_file);
NotationFile::PageIterator *damage_names = notation_file->MakePageIterator();
Check_Object(damage_names);
Page *damage_instance;
//
//---------------------------------------
// Create the damage Object for this instance_page
//---------------------------------------
//
while ((damage_instance = damage_names->ReadAndNext()) != NULL)
{
//
//-------------------------------------------------------
//Check to see if we are internal or just a damage object
//-------------------------------------------------------
//
int damage_zone;
if (!damage_instance->GetEntry("DamageZone", &damage_zone))
{
DamageObject::ConstructDamageObjectStream(stream, damage_instance);
}
else
{
MWInternalDamageObject::ConstructMWInternalDamageObjectStream(stream, damage_instance);
}
}
Resource::ParentFileDependencies = parent;
Check_Object(damage_names);
delete damage_names;
Tool::Instance->PopFilePath();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWObject::CreateSubsystemStream(MemoryStream *stream, NotationFile *notation_file)
{
Check_Pointer(stream);
Check_Pointer(notation_file);
FileDependencies sub_deps(*notation_file->GetFileDependencies());
FileDependencies *parent = Resource::ParentFileDependencies;
Resource::ParentFileDependencies = &sub_deps;
Tool::Instance->PushFilePath(notation_file);
*stream << static_cast<WORD>(0);
ReplicatorID starting_id = ReplicatorID::Null;
NotationFile::PageIterator *instance_names = notation_file->MakePageIterator();
Check_Object(instance_names);
Page *instance;
while ((instance = instance_names->ReadAndNext()) != NULL)
{
Check_Object(instance);
//
//-----------------------------------------
// Create the entity for this instance_page
//-----------------------------------------
//
Entity::CreateMessage *message =
Tool::Instance->ConstructCreateMessage(
stream,
instance,
&starting_id
);
Check_Object(message);
stream->AdvancePointer(message->messageLength);
}
//
//-----------------------------------------
// Only save out the stream if there is one
//-----------------------------------------
//
if (stream->GetBytesUsed() > sizeof(WORD))
{
stream->Rewind();
WORD span =
static_cast<WORD>(starting_id.localID - 0);
*stream << span;
}
Resource::ParentFileDependencies = parent;
Check_Object(instance_names);
delete instance_names;
Tool::Instance->PopFilePath();
}