Files
firestorm/Gameleap/code/mw4/Code/MW4/Vehicle_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

662 lines
15 KiB
C++

//===========================================================================//
// File: Vehicle_Tool.cpp //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 09/09/98 JSE Inital base class based off of Shadowrun/Adept //
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "MW4Headers.hpp"
#include "Vehicle.hpp"
#include "Subsystem.hpp"
#include "Engine.hpp"
#include "Torso.hpp"
#include "MWDamageObject.hpp"
#include "MaterialEffectHolder.hpp"
#include <Adept\Tool.hpp>
#include <Adept\EntityManager.hpp>
#include <MLR\MLRLight.hpp>
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Vehicle__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(Vehicle__GameModel));
BaseClass::ConstructGameModel(script);
Verify(stack_level == Tool::Instance->GetStackLevel());
Vehicle__GameModel *model =
Cast_Pointer(Vehicle__GameModel*, model_stream->GetPointer());
//
//------------------------------
// Set up the model file pointer
//------------------------------
//
NotationFile *model_file = script->modelFile;
Check_Object(model_file);
model->trailEffectsTable = ResourceID::Null;
Page *game_page = model_file->GetPage("GameData");
Check_Object(game_page);
//
//-------------------------
// Create the effects table
//-------------------------
//
NotationFile effects_file;
if (game_page->GetEntry("TrailEffectsFile", &effects_file))
model->trailEffectsTable = CreateEffectTableResource(&effects_file, MaterialCount);
//
//-------------------------------------------------------------
// If there is no shadow entry, set the stream resource to NULL
//-------------------------------------------------------------
//
NotationFile shadow_file;
if (!game_page->GetEntry("Shadow", &shadow_file))
model->shadowStream = ResourceID::Null;
//
//------------------------------------
// Otherwise, rebuild the light stream
//------------------------------------
//
else
{
Tool::Instance->PushFilePath(&shadow_file);
DynamicMemoryStream shadow_stream;
//
//----------------------------------------------------
// Read each light in and write it out into the binary
//----------------------------------------------------
//
MidLevelRenderer::WriteMLRVersion(&shadow_stream);
NotationFile::PageIterator *pages = shadow_file.MakePageIterator();
Check_Object(pages);
Page *shadow_page;
while ((shadow_page = pages->ReadAndNext()) != NULL)
{
Check_Object(shadow_page);
MidLevelRenderer::MLRLight* shadow =
MidLevelRenderer::MLRLight::Make(shadow_page);
Check_Object(shadow);
shadow->Save(&shadow_stream);
delete shadow;
}
//
//-----------------------------------------
// Only save out the stream if there is one
//-----------------------------------------
//
if (shadow_stream.GetBytesUsed() > 0)
{
shadow_stream.Rewind();
Resource shadow_resource(shadow_file.GetFileName());
shadow_resource.Save(&shadow_stream, shadow_file.GetFileDependencies());
shadow_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
Check_Object(&shadow_resource);
model->shadowStream = shadow_resource.GetResourceID();
}
else
{
model->shadowStream = ResourceID::Null;
Resource::ParentFileDependencies->AddDependencies(shadow_file.GetFileDependencies());
}
//
//------------------------
// Clean up the tool stack
//------------------------
//
Check_Object(pages);
delete pages;
Tool::Instance->PopFilePath();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
Vehicle__GameModel::ReadAndVerify(
Vehicle__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 FullStopTurnRateAttributeID:
{
if(!valid_data)
{
Scalar value = 10.1f*Radians_Per_Degree;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->fullStopTurnRate < 10.0f*Radians_Per_Degree)
{
_snprintf(
*error,
error_buffer,
"{[GameData]FullStopTurnRate=%f}: value must be >= 10.0!",
model->fullStopTurnRate*Degrees_Per_Radian
);
result = false;
}
break;
}
case TopSpeedTurnRateAttributeID:
{
if(!valid_data)
{
Scalar value = 10.1f*Radians_Per_Degree;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->topSpeedTurnRate < 10.0f*Radians_Per_Degree)
{
_snprintf(
*error,
error_buffer,
"{[GameData]TopSpeedTurnRate=%f}: value must be >= 10.0!",
model->topSpeedTurnRate
);
result = false;
}
break;
}
case MaxSpeedAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->maxSpeed < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MaxSpeed=%f}: value must be >= 0!",
model->maxSpeed
);
result = false;
}
break;
}
case MinMaxSpeedAttributeID:
{
if(!valid_data)
{
Scalar value = model->maxSpeed;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->minMaxSpeed < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MinMaxSpeed=%f}: value must be >= 0!",
model->minMaxSpeed
);
result = false;
}
break;
}
case MinSpeedAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->minSpeed > model->maxSpeed)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MinSpeed=%f}: value must be <= MaxSpeed %f!",
model->minSpeed,
model->maxSpeed
);
result = false;
}
break;
}
case MaxReverseSpeedAttributeID:
{
if(!valid_data)
{
Scalar value = -1.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->maxReverseSpeed > 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MaxReverseSpeed=%f}: value must be <= 0!",
model->maxReverseSpeed
);
result = false;
}
break;
}
case MinReverseSpeedAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->minReverseSpeed < model->maxReverseSpeed)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MinReverseSpeed=%f}: value must be >= MaxReverseSpeed!",
model->minReverseSpeed
);
result = false;
}
break;
}
case AccelerationAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->acceleration < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]Acceleration=%f}: value must be >= 0!",
model->acceleration
);
result = false;
}
break;
}
case DeccelerationAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->decceleration < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]Decceleration=%f}: value must be >= 0!",
model->decceleration
);
result = false;
}
break;
}
case ReverseAccelerationMultiplierAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->reverseAccelerationMultiplier < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]ReverseAccelerationMultiplier=%f}: value must be >= 0!",
model->reverseAccelerationMultiplier
);
result = false;
}
break;
}
case ReverseDeccelerationMultiplierAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->reverseDeccelerationMultiplier < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]ReverseDeccelerationMultiplier=%f}: value must be >= 0!",
model->reverseDeccelerationMultiplier
);
result = false;
}
break;
}
case TargetLockTimeAttributeID:
{
if(!valid_data)
{
Scalar value = 3.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->targetLockTime < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]TargetLockTime=%f}: value must be >= 0!",
model->targetLockTime
);
result = false;
}
break;
}
case MinStandTransitionSpeedAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->minStandTransitionSpeed < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MinStandTransitionSpeed=%f}: value must be > 0!",
model->minStandTransitionSpeed
);
result = false;
}
break;
}
case MaxGimpSpeedAttributeID:
{
if(!valid_data)
{
Scalar value = 0.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->maxGimpSpeed < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MaxGimpSpeed=%f}: value must be > 0!",
model->maxGimpSpeed
);
result = false;
}
break;
}
case MaxSlopeAttributeID:
{
if(!valid_data)
{
Scalar value = 55.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if (model->modelmaxSlope < 0)
{
_snprintf(
*error,
error_buffer,
"{[GameData]MaxSlope=%f}: value must be >= 0!",
model->modelmaxSlope
);
result = false;
}
else
{
model->modelmaxSlope = model->modelmaxSlope * Radians_Per_Degree;
}
break;
}
case StartSlopeDecelerationAttributeID:
{
if(!valid_data)
{
Scalar value = 40.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if (model->modelstartSlopeDeceleration < 0)
{
_snprintf(
*error,
error_buffer,
"{[GameData]StartSlopeDeceleration=%f}: value must be >= 0!",
model->modelstartSlopeDeceleration
);
result = false;
}
else
{
model->modelstartSlopeDeceleration = model->modelstartSlopeDeceleration * Radians_Per_Degree;
}
break;
}
case SlopeDecel1AttributeID:
{
if(!valid_data)
{
Scalar value = 20.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->slopeDecel1 < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]SlopeDecel1=%f}: value must be > 0!",
model->slopeDecel1
);
result = false;
}
break;
}
case SlopeDecel2AttributeID:
{
if(!valid_data)
{
Scalar value = 40.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->slopeDecel2 < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]SlopeDecel2=%f}: value must be > 0!",
model->slopeDecel2
);
result = false;
}
break;
}
case SlopeDecel3AttributeID:
{
if(!valid_data)
{
Scalar value = 60.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->slopeDecel3 < 0.0f)
{
_snprintf(
*error,
error_buffer,
"{[GameData]SlopeDecel3=%f}: value must be > 0!",
model->slopeDecel3
);
result = false;
}
break;
}
case AttackTypeAttributeID:
{
if(!valid_data)
{
int value = 0;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->m_attackType < 0)
{
_snprintf(
*error,
error_buffer,
"{[GameData]AttackType=%f}: value must be > 0!",
model->m_attackType
);
result = false;
}
break;
}
case TreadLengthAttributeID:
{
if(!valid_data)
{
// Default tread length is set to 6 meters
Scalar value = 6.0f;
attribute_entry->SetValue(model, &value);
result = true;
}
if(model->m_treadLength <= 0)
{
_snprintf(
*error,
error_buffer,
"{[GameData]TreadLength=%f}: value must be > 0!",
model->m_treadLength
);
result = false;
}
break;
}
}
return result;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Vehicle::SaveInstanceText(Page *instance_page)
{
Check_Object(this);
Check_Object(instance_page);
BaseClass::SaveInstanceText(instance_page);
//
//-------------------------
// Save the Execution State
//-------------------------
//
int execution_state = executionState->GetState();
MString execution_state_text;
switch(execution_state)
{
case ExecutionStateEngine::FallingMotionState:
{
execution_state_text = "FallingMotionState";
break;
}
case ExecutionStateEngine::FlyingMotionState:
{
execution_state_text = "FlyingMotionState";
break;
}
case ExecutionStateEngine::DrivingMotionState:
{
execution_state_text = "DrivingMotionState";
break;
}
}
if (execution_state_text)
{
instance_page->SetEntry("ExecutionState", execution_state_text);
}
}