Myomers (: PoweredSubsystem) -- locomotion muscle: seek-voltage drive table (scaled by the generator's rated voltage via ResolveVoltageSource), efficiency + heat-range members; MyomersSimulation staged. Condenser (: HeatSink) -- active refrigeration in a coolant loop; valveState/refrigerationFactor/condenserNumber. Both ctors chain their parents + init from resource; statics/dtor/test real. Heat/power subsystem family now COMPLETE (11 classes): MechSubsystem, HeatableSubsystem, HeatSink, PoweredSubsystem, Generator, Condenser, Sensor, Myomers, HeatWatcher, PowerWatcher, Gyroscope, HUD, Torso. BT: 31 ok. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
390 lines
9.6 KiB
C++
390 lines
9.6 KiB
C++
//===========================================================================//
|
|
// File: heat.cpp //
|
|
// Project: BattleTech Brick: Mech subsystems //
|
|
// Contents: HeatableSubsystem -- a MechSubsystem with a thermal state //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include <bt.hpp>
|
|
#pragma hdrstop
|
|
|
|
#if !defined(HEAT_HPP)
|
|
# include <heat.hpp>
|
|
#endif
|
|
|
|
#if !defined(MECH_HPP)
|
|
# include <mech.hpp>
|
|
#endif
|
|
|
|
//
|
|
//#############################################################################
|
|
// Shared data support -- reuses the base Subsystem sets (no boot-critical
|
|
// handlers / attributes of its own).
|
|
//#############################################################################
|
|
//
|
|
Derivation
|
|
HeatableSubsystem::ClassDerivations(
|
|
MechSubsystem::ClassDerivations,
|
|
"HeatableSubsystem"
|
|
);
|
|
|
|
HeatableSubsystem::SharedData
|
|
HeatableSubsystem::DefaultData(
|
|
HeatableSubsystem::ClassDerivations,
|
|
Subsystem::MessageHandlers,
|
|
Subsystem::AttributeIndex,
|
|
Subsystem::StateCount
|
|
);
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
HeatableSubsystem::HeatableSubsystem(
|
|
Mech *owner,
|
|
int subsystem_ID,
|
|
SubsystemResource *subsystem_resource,
|
|
SharedData &shared_data
|
|
):
|
|
MechSubsystem(
|
|
owner,
|
|
subsystem_ID,
|
|
(MechSubsystem::SubsystemResource *)subsystem_resource,
|
|
shared_data
|
|
)
|
|
{
|
|
Check(owner);
|
|
Check_Pointer(subsystem_resource);
|
|
ResetToInitialState();
|
|
Check_Fpu();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
HeatableSubsystem::~HeatableSubsystem()
|
|
{
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
HeatableSubsystem::ResetToInitialState()
|
|
{
|
|
Check(this);
|
|
currentTemperature = 300.0f;
|
|
heatLoad = 0.0f;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Logical
|
|
HeatableSubsystem::TestClass(Mech &)
|
|
{
|
|
return True;
|
|
}
|
|
|
|
Logical
|
|
HeatableSubsystem::TestInstance() const
|
|
{
|
|
return IsDerivedFrom(ClassDerivations);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// CreateStreamedSubsystem Model-load-time construction (thermal resource +
|
|
// damage-zone stream). Not yet reconstructed (see MECHSUB.NOTES.md).
|
|
//#############################################################################
|
|
//
|
|
int
|
|
HeatableSubsystem::CreateStreamedSubsystem(
|
|
NotationFile *,
|
|
const char *,
|
|
const char *,
|
|
SubsystemResource *,
|
|
NotationFile *,
|
|
const ResourceDirectories *,
|
|
int
|
|
)
|
|
{
|
|
Fail("HeatableSubsystem::CreateStreamedSubsystem -- heat.cpp not yet reconstructed");
|
|
return 0;
|
|
}
|
|
|
|
//###########################################################################
|
|
//############################## HeatSink ###############################
|
|
//###########################################################################
|
|
|
|
//
|
|
//#############################################################################
|
|
// Shared data support
|
|
//#############################################################################
|
|
//
|
|
Derivation
|
|
HeatSink::ClassDerivations(
|
|
HeatableSubsystem::ClassDerivations,
|
|
"HeatSink"
|
|
);
|
|
|
|
HeatSink::SharedData
|
|
HeatSink::DefaultData(
|
|
HeatSink::ClassDerivations,
|
|
Subsystem::MessageHandlers,
|
|
Subsystem::AttributeIndex,
|
|
Subsystem::StateCount
|
|
);
|
|
|
|
//
|
|
//#############################################################################
|
|
// The heat sink -- a thermal mass with a coolant loop. A master sink drives
|
|
// the per-frame thermal simulation.
|
|
//#############################################################################
|
|
//
|
|
HeatSink::HeatSink(
|
|
Mech *owner,
|
|
int subsystem_ID,
|
|
SubsystemResource *subsystem_resource,
|
|
SharedData &shared_data
|
|
):
|
|
HeatableSubsystem(owner, subsystem_ID, subsystem_resource, shared_data),
|
|
linkedSinks(),
|
|
heatAlarm(3)
|
|
{
|
|
Check(owner);
|
|
Check_Pointer(subsystem_resource);
|
|
|
|
currentTemperature = subsystem_resource->startingTemperature;
|
|
degradationTemperature = subsystem_resource->degradationTemperature;
|
|
failureTemperature = subsystem_resource->failureTemperature;
|
|
|
|
heatLoad = 0.0f;
|
|
coolantEfficiency = 0.5f;
|
|
thermalCapacity = 1.0f;
|
|
coolantLevel = thermalCapacity;
|
|
coolantDraw = 0.0f;
|
|
coolantAvailable = 1;
|
|
coolantActive = 0;
|
|
|
|
startingTemperature = currentTemperature;
|
|
thermalConductance = subsystem_resource->thermalConductance;
|
|
|
|
heatFilter.SetSize(15, 0.0f);
|
|
filterDecay = 0.4f;
|
|
thermalMass = subsystem_resource->thermalMass;
|
|
heatEnergy = thermalMass * startingTemperature;
|
|
coolantFlowScale = 1.0f;
|
|
massScale = 1.0f;
|
|
|
|
pendingHeat = 0.0f;
|
|
radiatedHeat = 0.0f;
|
|
|
|
Check_Fpu();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
HeatSink::~HeatSink()
|
|
{
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
HeatSink::ResetToInitialState(Logical /*powered*/)
|
|
{
|
|
Check(this);
|
|
currentTemperature = startingTemperature;
|
|
heatLoad = 0.0f;
|
|
coolantLevel = thermalCapacity;
|
|
coolantDraw = 0.0f;
|
|
coolantActive = 0;
|
|
heatEnergy = thermalMass * startingTemperature;
|
|
pendingHeat = 0.0f;
|
|
radiatedHeat = 0.0f;
|
|
heatAlarm.SetLevel(0);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Logical
|
|
HeatSink::TestClass(Mech &)
|
|
{
|
|
return True;
|
|
}
|
|
|
|
Logical
|
|
HeatSink::TestInstance() const
|
|
{
|
|
return IsDerivedFrom(ClassDerivations);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// Per-frame thermal simulation (heat conduction, coolant draw, radiation).
|
|
// Not yet reconstructed -- fires only once the mech is ticking.
|
|
//#############################################################################
|
|
//
|
|
void
|
|
HeatSink::HeatSinkSimulation(Scalar)
|
|
{
|
|
Fail("HeatSink::HeatSinkSimulation -- heat.cpp not yet reconstructed");
|
|
}
|
|
|
|
Scalar
|
|
HeatSink::DrawCoolant(Scalar)
|
|
{
|
|
Fail("HeatSink::DrawCoolant -- heat.cpp not yet reconstructed");
|
|
return 0.0f;
|
|
}
|
|
|
|
//###########################################################################
|
|
//############################# HeatWatcher #############################
|
|
//###########################################################################
|
|
|
|
Derivation
|
|
HeatWatcher::ClassDerivations(
|
|
MechSubsystem::ClassDerivations,
|
|
"HeatWatcher"
|
|
);
|
|
|
|
HeatWatcher::SharedData
|
|
HeatWatcher::DefaultData(
|
|
HeatWatcher::ClassDerivations,
|
|
Subsystem::MessageHandlers,
|
|
Subsystem::AttributeIndex,
|
|
Subsystem::StateCount
|
|
);
|
|
|
|
HeatWatcher::HeatWatcher(
|
|
Mech *owner,
|
|
int subsystem_ID,
|
|
SubsystemResource *subsystem_resource,
|
|
SharedData &shared_data
|
|
):
|
|
MechSubsystem(
|
|
owner,
|
|
subsystem_ID,
|
|
(MechSubsystem::SubsystemResource *)subsystem_resource,
|
|
shared_data
|
|
),
|
|
watchedLink(),
|
|
heatAlarm(3)
|
|
{
|
|
Check(owner);
|
|
Check_Pointer(subsystem_resource);
|
|
|
|
degradationTemperature = subsystem_resource->degradationTemperature;
|
|
failureTemperature = subsystem_resource->failureTemperature;
|
|
watchedSubsystem = subsystem_resource->watchedSubsystem;
|
|
|
|
//
|
|
// The master instance runs WatchSimulation per-frame; the install is
|
|
// deferred with that (staged) method.
|
|
//
|
|
Check_Fpu();
|
|
}
|
|
|
|
HeatWatcher::~HeatWatcher()
|
|
{
|
|
}
|
|
|
|
Logical
|
|
HeatWatcher::TestClass(Mech &)
|
|
{
|
|
return True;
|
|
}
|
|
|
|
Logical
|
|
HeatWatcher::TestInstance() const
|
|
{
|
|
return IsDerivedFrom(ClassDerivations);
|
|
}
|
|
|
|
void
|
|
HeatWatcher::ResetToInitialState(Logical /*powered*/)
|
|
{
|
|
Check(this);
|
|
heatAlarm.SetLevel(0);
|
|
}
|
|
|
|
//
|
|
// Per-frame: resolve the watched subsystem, read its temperature, drive the
|
|
// 3-level alarm. Not yet reconstructed.
|
|
//
|
|
void
|
|
HeatWatcher::WatchSimulation(Scalar)
|
|
{
|
|
Fail("HeatWatcher::WatchSimulation -- heat.cpp not yet reconstructed");
|
|
}
|
|
|
|
//###########################################################################
|
|
//############################## Condenser #############################
|
|
//###########################################################################
|
|
|
|
Derivation
|
|
Condenser::ClassDerivations(
|
|
HeatSink::ClassDerivations,
|
|
"Condenser"
|
|
);
|
|
|
|
Condenser::SharedData
|
|
Condenser::DefaultData(
|
|
Condenser::ClassDerivations,
|
|
Subsystem::MessageHandlers,
|
|
Subsystem::AttributeIndex,
|
|
Subsystem::StateCount
|
|
);
|
|
|
|
Condenser::Condenser(
|
|
Mech *owner,
|
|
int subsystem_ID,
|
|
SubsystemResource *subsystem_resource,
|
|
SharedData &shared_data
|
|
):
|
|
HeatSink(owner, subsystem_ID, subsystem_resource, shared_data)
|
|
{
|
|
Check(owner);
|
|
Check_Pointer(subsystem_resource);
|
|
|
|
valveState = 0;
|
|
refrigerationFactor = subsystem_resource->refrigerationFactor;
|
|
|
|
//
|
|
// Condenser number from the segment-name suffix ('A' -> 1 ...).
|
|
//
|
|
const char *name = GetName();
|
|
condenserNumber = name[strlen(name) - 1] - 0x40;
|
|
|
|
Check_Fpu();
|
|
}
|
|
|
|
Condenser::~Condenser()
|
|
{
|
|
}
|
|
|
|
Logical
|
|
Condenser::TestClass(Mech &)
|
|
{
|
|
return True;
|
|
}
|
|
|
|
Logical
|
|
Condenser::TestInstance() const
|
|
{
|
|
return IsDerivedFrom(ClassDerivations);
|
|
}
|