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

284 lines
7.4 KiB
C++

//===========================================================================//
// File: Engine.cpp
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 09/09/98 JSE Inital base class based off of Shadowrun/Adept //
// 09/24/98 BDB Inital Engine subsytem class based off of Subsystem //
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "MW4Headers.hpp"
#include "Engine.hpp"
#include "Mech.hpp"
#include "HeatManager.hpp"
#include "SubsystemClassData.hpp"
//#############################################################################
//############################### Engine ################################
//#############################################################################
Engine::ClassData*
Engine::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
EngineClassID,
"MechWarrior4::Engine",
Subsystem::DefaultData,
0, NULL,
(Entity::Factory)Make,
(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
ExecutionStateEngine::DefaultData,
(Entity::GameModel::Factory)GameModel::ConstructGameModel,
NULL,
(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
(Entity::GameModel::ModelWrite)GameModel::WriteToText,
(Entity::GameModel::ModelSave)GameModel::SaveGameModel,
(Subsystem::StreamCreate) CreateStream
);
Register_Object(DefaultData);
DIRECT_GAME_MODEL_ATTRIBUTE(
Engine__GameModel,
TonsPerUpgrade,
m_tonsPerUpgrade,
Scalar
);
DIRECT_GAME_MODEL_ATTRIBUTE(
Engine__GameModel,
MPSPerUpgrade,
m_mpsPerUpgrade,
Scalar
);
CUSTOM_DIRECT_GAME_MODEL_ATTRIBUTE(
Engine__GameModel,
NumHeatSinks,
m_numHeatSinks,
int,
IntClassID
);
DIRECT_GAME_MODEL_ATTRIBUTE(
Engine__GameModel,
HeatSinkEfficiency,
m_heatSinkEfficiency,
Scalar
);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Engine*
Engine::Make(
CreateMessage *message,
ReplicatorID *base_id
)
{
Check_Object(message);
gos_PushCurrentHeap(Heap);
Engine *new_entity =
new Engine(DefaultData, message, base_id, NULL);
gos_PopCurrentHeap();
Check_Object(new_entity);
return new_entity;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Engine::Engine(
ClassData *class_data,
CreateMessage *message,
ReplicatorID *base_id,
ElementRenderer::Element *element
):
Subsystem(class_data, message, base_id, element)
{
Check_Object(message);
m_upgrades = message->m_engineUpgrades;
const GameModel *model = GetGameModel();
Check_Object(model);
m_engineTonnage = 0.0f;
for(int i=1; i <= m_upgrades; i++)
m_engineTonnage += i * model->m_tonsPerUpgrade;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Replicator::CreateMessage*
Engine::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file)
{
Check_Object(this);
Check_Object(stream);
stream->AllocateBytes(sizeof(CreateMessage));
Subsystem::SaveMakeMessage(stream, res_file);
CreateMessage *message =
Cast_Pointer(CreateMessage*, stream->GetPointer());
message->messageLength = sizeof(*message);
message->m_engineUpgrades = m_upgrades;
return message;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Engine::~Engine()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::ConnectHeatManager(HeatManager *heat_manager)
{
Check_Object(this);
Check_Object(heat_manager);
const GameModel *model = GetGameModel();
Check_Object(model);
if(heat_manager)
{
if (Network::GetInstance()->AmIServer())
{
for(int i=0;i<model->m_numHeatSinks;i++)
heat_manager->AddHeatObject(-model->m_heatSinkEfficiency, true);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::ConnectEngine(Vehicle *parent_mech)
{
Check_Object(this);
Check_Object(parent_mech);
m_parentMech = parent_mech;
const Vehicle::GameModel *mech_model = parent_mech->GetGameModel();
Check_Object(mech_model);
const GameModel *model = GetGameModel();
Check_Object(model);
m_mechMaxMaxMPS = mech_model->maxSpeed;
m_mechMinMaxMPS = mech_model->minMaxSpeed;
Verify(m_mechMaxMaxMPS >= m_mechMinMaxMPS);
m_maxUpgrades =(int)((m_mechMaxMaxMPS - m_mechMinMaxMPS) / model->m_mpsPerUpgrade);
SetNewSpeed();
//This is to do the tonnage verification and will end up working correctly.
int number_wanted = m_upgrades;
m_upgrades = 0;
for(int i=1; i<=number_wanted; i++)
Upgrade();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::SetNewSpeed()
{
Check_Object(this);
const GameModel *model = GetGameModel();
Check_Object(model);
m_maxSpeed = m_mechMinMaxMPS + (model->m_mpsPerUpgrade * m_upgrades);
Clamp(m_maxSpeed, m_mechMinMaxMPS, m_mechMaxMaxMPS);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::Upgrade()
{
Check_Object(this);
if(m_upgrades == m_maxUpgrades)
return;
const GameModel *model = GetGameModel();
Check_Object(model);
Scalar added_tonnage = (m_upgrades + 1) * model->m_tonsPerUpgrade;
if(m_parentMech->DoesHaveAvailableTonage(added_tonnage))
{
m_engineTonnage += added_tonnage;
m_upgrades ++;
Max_Clamp(m_upgrades, m_maxUpgrades);
SetNewSpeed();
m_parentMech->AddTonage(m_upgrades * model->m_tonsPerUpgrade);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::Degrade()
{
Check_Object(this);
if(m_upgrades == 0)
return;
const GameModel *model = GetGameModel();
Check_Object(model);
m_engineTonnage -= m_upgrades * model->m_tonsPerUpgrade;
m_parentMech->SubtractTonage(m_upgrades * model->m_tonsPerUpgrade);
m_upgrades --;
Min_Clamp(m_upgrades, 0);
SetNewSpeed();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::CreateStream(ResourceID data_list, MemoryStream *stream)
{
Check_Pointer(stream);
stream->AllocateBytes(sizeof(Engine__CreateMessage));
Subsystem::CreateStream(data_list, stream);
Engine__CreateMessage *create_message = Cast_Pointer(
Engine__CreateMessage *, stream->GetPointer());
create_message->m_engineUpgrades = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Engine::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}