Files
firestorm/Gameleap/code/mw4/Libraries/Adept/Map_Tool.cpp
T
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

512 lines
16 KiB
C++

#include "AdeptHeaders.hpp"
#include "Map.hpp"
#include "RendererManager.hpp"
#include "Tool.hpp"
#include <ElementRenderer\GridElement.hpp>
#include "NameTable.hpp"
#include "Zone.hpp"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Map__CreateMessage::ConstructCreateMessage(Script *script)
{
Check_Object(script);
#if defined(_ARMOR)
int stack_level = Tool::Instance->GetStackLevel();
#endif
//
//--------------
// Set up stream
//--------------
//
MemoryStream *message_stream = script->messageStream;
Check_Object(message_stream);
message_stream->AllocateBytes(sizeof(Map__CreateMessage));
Entity__CreateMessage::ConstructCreateMessage(script);
Map__CreateMessage *message =
Cast_Pointer(
Map__CreateMessage*,
message_stream->GetPointer()
);
message->messageLength = sizeof(*message);
//
//-------------------------------------------------------------------------
// No matter what the instance file said, all maps are independent entities
//-------------------------------------------------------------------------
//
message->replicatorFlags &= ~Replicator::ReplicatorModeMask;
message->replicatorFlags |= Replicator::IndependentMode;
//
//---------------------------------------------------------------
// Point at the notation file and make other files relative to it
//---------------------------------------------------------------
//
Page *page = script->instancePage;
Check_Object(page);
//
//---------------------------------------------------------------------
// Open up the contents file, and see if its empty. If so, we are done
//---------------------------------------------------------------------
//
NotationFile props_file;
page->GetEntry("Props", &props_file);
NotationFile::PageIterator *pages = props_file.MakePageIterator();
Check_Object(pages);
if (!pages->GetSize())
{
message->m_propStreamResourceID = ResourceID::Null;
Verify(stack_level == Tool::Instance->GetStackLevel());
delete pages;
return;
}
//
//-------------------------------------------------------------
// Look for the prop stream resource to see if it is up to date
//-------------------------------------------------------------
//
STOP(("Not updated"));
const char* props_filename = props_file.GetFileName();
Resource prop_resource(props_filename);
if (
prop_resource.DoesResourceExist() &&
prop_resource.IsResourceUpToDate()
)
{
WORD span;
prop_resource >> span;
Verify(span > 0);
*script->baseID += span;
message->replicatorID += span;
message->m_propStreamResourceID = prop_resource.GetResourceID();
}
//
//---------------------------------------
// For each page, an entity will be built
//---------------------------------------
//
else
{
Check_Object(Tool::Instance);
Tool::Instance->PushFilePath(&props_file);
DynamicMemoryStream prop_stream(sizeof(WORD));
prop_stream << static_cast<WORD>(0);
Page *instance;
ReplicatorID starting_id = *script->baseID;
while ((instance = pages->ReadAndNext()) != NULL)
{
Check_Object(instance);
//
//--------------------------------
// Create the entity for this page
//--------------------------------
//
const char *instance_name = instance->GetName();
Check_Pointer(instance_name);
Entity::CreateMessage *message =
Tool::Instance->ConstructCreateMessage(
&prop_stream,
instance,
script->baseID
);
Check_Object(message);
Check_Object(NameTable::GetInstance());
message->nameID = NameTable::GetInstance()->FindID(instance_name);
prop_stream.AdvancePointer(message->messageLength);
}
//
//-----------------------------------------
// Only save out the stream if there is one
//-----------------------------------------
//
if (prop_stream.GetBytesUsed() > sizeof(WORD))
{
prop_stream.Rewind();
Verify(*script->baseID != starting_id);
WORD span =
static_cast<WORD>(script->baseID->localID - starting_id.localID);
prop_stream << span;
message->replicatorID += span;
prop_resource.Save(&prop_stream, props_file.GetFileDependencies());
Check_Object(&prop_resource);
message->m_propStreamResourceID = prop_resource.GetResourceID();
}
else
message->m_propStreamResourceID = ResourceID::Null;
Tool::Instance->PopFilePath();
}
//
//------------------------
// Clean up the tool stack
//------------------------
//
Check_Object(pages);
delete pages;
Verify(stack_level == Tool::Instance->GetStackLevel());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Map__GameModel::ConstructGameModel(Script *script)
{
Check_Object(script);
Check_Object(Tool::Instance);
#if defined(_ARMOR)
int stack_index = Tool::Instance->GetStackLevel();
#endif
Check_Object(Resource::ParentFileDependencies);
//
//--------------
// Set up stream
//--------------
//
MemoryStream *model_stream = script->modelStream;
Check_Object(model_stream);
model_stream->AllocateBytes(sizeof(Map__GameModel));
Entity__GameModel::ConstructGameModel(script);
Map__GameModel *model =
Cast_Pointer(Map__GameModel*, model_stream->GetPointer());
Check_Object(model);
NotationFile *model_file = script->modelFile;
Check_Object(model_file);
Tool::Instance->PushFilePath(model_file);
//
//-------------------------------------
// We need to get our grid element file
//-------------------------------------
//
Page *page = model_file->FindPage("GameData");
Check_Object(page);
model->m_waterLevel = 0.0f;
page->GetEntry("WaterLevel", &model->m_waterLevel);
const char* grid_filename;
page->GetEntry("Grid", &grid_filename, true);
FileStream grid_file(grid_filename);
Tool::Instance->PushFilePath(&grid_file);
grid_filename = grid_file.GetFileName();
const char* hudmap_filename;
model->m_HudMap[0] = 0;
if (page->GetEntry ("hudmap",&hudmap_filename,false))
{
Str_Copy (model->m_HudMap,hudmap_filename,128);
}
//
//---------------------------------------------------------------
// See if the resource already exists, and if so, just use its ID
//---------------------------------------------------------------
//
Resource grid_resource(grid_filename);
MString zones_name = grid_filename;
zones_name += "{zones}";
Resource zones_resource(zones_name);
if (!grid_resource.DoesResourceExist() || !grid_resource.IsResourceUpToDate())
{
FileDependencies grid_dependencies;
grid_dependencies.AddDependency(&grid_file);
//
//--------------------------------------------------------------------
// Now, create the actual grid and see how big it is. We will need to
// resourcify that number of erf's
//--------------------------------------------------------------------
//
ElementRenderer::GridElement *grid =
Cast_Object(
ElementRenderer::GridElement*,
ElementRenderer::Element::Create(
&grid_file,
ElementRenderer::ReadERFVersion(&grid_file)
)
);
grid_file.Rewind();
BYTE x,z;
grid->GetSize(&z, &x);
WORD zone_count = static_cast<WORD>(x*z);
if (
x>26 || z>26 || !zone_count
|| !grid->IsDerivedFrom(ElementRenderer::GridElement::DefaultData)
)
{
STOP((
"%s{[GameData]Grid=%s}: Bad grid element!",
model_file->GetFileName(),
grid_filename
));
}
DynamicArrayOf<Zone::ResourceData> zones(zone_count);
Check_Object(grid);
delete grid;
//
//---------------------------------------------------------------
// For each zone in the grid, look for the corresponding erf file
//---------------------------------------------------------------
//
unsigned zone=0;
for (unsigned r=0; r<z; ++r)
{
for (unsigned c=0; c<x; ++c)
{
//
//-------------------------
// We need to tile geometry
//-------------------------
//
char buffer[17];
#if defined(_ARMOR)
int count =
#endif
sprintf(buffer, "%c%c.erf", r+'A', c+'A');
Verify(count < sizeof(buffer));
FileStream erf_file(buffer);
const char* zone_filename = erf_file.GetFileName();
//
//---------------------------------------------------------------
// See if the resource already exists, and if so, just use its ID
//---------------------------------------------------------------
//
Resource zone_resource(zone_filename);
if (!zone_resource.DoesResourceExist() || !zone_resource.IsResourceUpToDate())
{
FileDependencies zone_dependencies;
zone_dependencies.AddDependency(&erf_file);
zone_resource.Save(&erf_file, &zone_dependencies);
}
zone_resource.AddFileDependenciesTo(&grid_dependencies);
zones[zone].m_geometryResourceID = zone_resource.GetResourceID();
//
//----------------------------
// We need to get our tile bsp
//----------------------------
//
#if defined(_ARMOR)
count =
#endif
sprintf(buffer, "%c%c.bsp", r+'A', c+'A');
Verify(count < sizeof(buffer));
FileStream bsp_file(buffer);
zone_filename = bsp_file.GetFileName();
//
//---------------------------------------------------------------
// See if the resource already exists, and if so, just use its ID
//---------------------------------------------------------------
//
Resource bsp_resource(zone_filename);
if (!bsp_resource.DoesResourceExist() || !bsp_resource.IsResourceUpToDate())
{
FileDependencies zone_dependencies;
zone_dependencies.AddDependency(&bsp_file);
bsp_resource.Save(&bsp_file, &zone_dependencies);
}
bsp_resource.AddFileDependenciesTo(&grid_dependencies);
zones[zone].m_bspResourceID = bsp_resource.GetResourceID();
//
//---------------------------------
// We need to get our tile material
//---------------------------------
//
#if defined(_ARMOR)
count =
#endif
sprintf(buffer, "%c%c.material", r+'A', c+'A');
Verify(count < sizeof(buffer));
if (!gos_DoesFileExist(buffer))
zones[zone].m_materialResourceID = ResourceID::Null;
else
{
FileStream material_file(buffer);
zone_filename = material_file.GetFileName();
//
//---------------------------------------------------------------
// See if the resource already exists, and if so, just use its ID
//---------------------------------------------------------------
//
Resource material_resource(zone_filename);
if (!material_resource.DoesResourceExist() || !material_resource.IsResourceUpToDate())
{
FileDependencies zone_dependencies;
zone_dependencies.AddDependency(&material_file);
material_resource.Save(&material_file, &zone_dependencies);
}
material_resource.AddFileDependenciesTo(&grid_dependencies);
zones[zone].m_materialResourceID = material_resource.GetResourceID();
}
++zone;
}
}
//
//-------------------------------------------
// Now save out the resource IDs of the model
//-------------------------------------------
//
MemoryStream res_id_stream(zones.GetData(), zones.GetSize());
zones_resource.Save(&res_id_stream, &grid_dependencies);
grid_resource.Save(&grid_file, &grid_dependencies);
if (!zones_resource.IsRegistered())
Resource::ParentFileDependencies->AddDependencies(&grid_dependencies);
}
else if (!grid_resource.IsRegistered())
grid_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
model->m_gridElementResourceID = grid_resource.GetResourceID();
model->m_zoneArrayResourceID = zones_resource.GetResourceID();
Tool::Instance->PopFilePath();
//
//-----------------------------
// Set up the texture spec file
//-----------------------------
//
const char* texture_filename;
if (page->GetEntry("TextureData", &texture_filename))
{
FileStream file_stream(texture_filename);
const char* file_name = file_stream.GetFileName();
Resource texture_res(file_name);
if (!texture_res.DoesResourceExist() || !texture_res.IsResourceUpToDate())
{
FileDependencies tex_dependencies;
tex_dependencies.AddDependency(&file_stream);
texture_res.Save(&file_stream, &tex_dependencies);
if (!texture_res.IsRegistered())
Resource::ParentFileDependencies->AddDependencies(&tex_dependencies);
}
else if (!texture_res.IsRegistered())
texture_res.AddFileDependenciesTo(Resource::ParentFileDependencies);
model->m_textureDataResourceID = texture_res.GetResourceID();
//
//-----------------------------
// Load up the TCF file
//-----------------------------
//
const char* tcf_filename;
model->m_tcfResourceID = ResourceID::Null;
page->GetEntry("TCFFilename", &tcf_filename, true);
MString long_filename("Content\\Textures\\CompostTexture\\");
long_filename += tcf_filename;
FileStream tcf_file_stream(long_filename);
const char* tcf_file_name = tcf_file_stream.GetFileName();
Resource tcf_res(tcf_file_name);
if (!tcf_res.DoesResourceExist() || !tcf_res.IsResourceUpToDate())
{
FileDependencies tcf_dependencies;
tcf_dependencies.AddDependency(&tcf_file_stream);
tcf_res.Save(&tcf_file_stream, &tcf_dependencies);
if (!tcf_res.IsRegistered())
Resource::ParentFileDependencies->AddDependencies(&tcf_dependencies);
}
else if (!tcf_res.IsRegistered())
tcf_res.AddFileDependenciesTo(Resource::ParentFileDependencies);
model->m_tcfResourceID = tcf_res.GetResourceID();
}
else
{
model->m_textureDataResourceID = ResourceID::Null;
model->m_tcfResourceID = ResourceID::Null;
}
//
//-----------------------------
// Set up the cultural data
//-----------------------------
//
const char* cultualdata_filename;
model->m_culturalDataResourceID = ResourceID::Null;
if (page->GetEntry("CulturalData", &cultualdata_filename))
{
FileStream file_stream(cultualdata_filename);
const char* file_name = file_stream.GetFileName();
Resource culturaldata_res(file_name);
if (!culturaldata_res.DoesResourceExist() || !culturaldata_res.IsResourceUpToDate())
{
FileDependencies culturaldata_dependencies;
culturaldata_dependencies.AddDependency(&file_stream);
culturaldata_res.Save(&file_stream, &culturaldata_dependencies);
if (!culturaldata_res.IsRegistered())
Resource::ParentFileDependencies->AddDependencies(&culturaldata_dependencies);
}
else if (!culturaldata_res.IsRegistered())
culturaldata_res.AddFileDependenciesTo(Resource::ParentFileDependencies);
model->m_culturalDataResourceID = culturaldata_res.GetResourceID();
}
else
model->m_culturalDataResourceID = ResourceID::Null;
Tool::Instance->PopFilePath();
Verify(stack_index == Tool::Instance->GetStackLevel());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
Map__GameModel::ReadAndVerify(
Map__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 =
Entity__GameModel::ReadAndVerify(
model,
attribute_entry,
data,
error,
error_buffer
);
//
//---------------------------
//Verify all the model values
//---------------------------
//
switch(attribute_entry->attributeID)
{
case DamageCraterResourceAttributeID:
{
if(!valid_data)
{
ResourceID value = ResourceID::Null;
attribute_entry->SetValue(model, (void *)&value);
result = true;
}
break;
}
}
return result;
}