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

706 lines
17 KiB
C++

//===========================================================================//
// File: Vehicle.hpp
//---------------------------------------------------------------------------//
// 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 //
//===========================================================================//
#pragma once
#include "MW4.hpp"
#pragma warning (push)
#include <stlport\string>
#pragma warning (pop)
#include "MWObject.hpp"
#include "Engine.hpp"
#include "SensorCellMap.hpp"
namespace Adept
{
class ShadowLight;
}
namespace Adept
{
class DamageObject;
class Effect;
}
namespace MechWarrior4
{
class Vehicle;
class Torso;
class Engine;
class VehicleInterface;
class MWInternalDamageObject;
class Weapon;
class MoverAI;
class CombatAI;
void VehicleSecurityCheckStart();
void VehicleSecurityCheckStop();
class VehicleCommand :
public Stuff::Plug
{
public:
enum
{
JumpCommand = 0,
PowerDownCommand,
CrouchCommand,
GetUpCommand,
PressFlushCommand,
ReleaseFlushCommand,
SelfDestructCommand,
SetTargetCommand,
ToggleSearchLightCommand,
Lancemate1Command,
Lancemate2Command,
Lancemate3Command,
LancemateAllCommand,
LancemateAttackMyTargetCommand,
LancemateDefendMyTargetCommand,
LancemateFormOnMeCommand,
LancemateHoldFireCommand,
LancemateGoToMyNavPointCommand,
LancemateStopCommand,
LancemateShutDownCommand,
LancemateAttackNearestCommand,
LancemateRepairCommand,
StopJumpCommand,
EjectCommand
};
int m_Command;
VehicleCommand():Stuff::Plug(DefaultData)
{
}
};
//##########################################################################
//##################### Vehicle::ModelResource ########################
//##########################################################################
class Vehicle__GameModel:
public MWObject__GameModel
{
public:
typedef MWObject__GameModel BaseClass;
Stuff::Scalar
modelmaxSlope,
modelstartSlopeDeceleration,
slopeDecel1,
slopeDecel2,
slopeDecel3;
Stuff::Radian
topSpeedTurnRate,
fullStopTurnRate; // Turn rate of vehicle
Stuff::Scalar
minSpeed,
maxSpeed,
minReverseSpeed,
maxReverseSpeed,
minMaxSpeed; //Used for engine upgrading on the mech level
// max speed when gimped
Stuff::Scalar
maxGimpSpeed;
// if you request to stand you will imediatly
// transition if you are less than this speed
Stuff::Scalar
minStandTransitionSpeed;
Stuff::Scalar
acceleration;
Stuff::Scalar
decceleration;
Stuff::Scalar
reverseAccelerationMultiplier;
Stuff::Scalar
reverseDeccelerationMultiplier;
Stuff::Scalar
targetLockTime;
Adept::ResourceID
trailEffectsTable,
shadowStream;
int
m_attackType;
Stuff::Scalar m_treadLength;
enum {
TopSpeedTurnRateAttributeID = MWObject__GameModel::NextAttributeID,
FullStopTurnRateAttributeID,
MaxReverseSpeedAttributeID,
MinReverseSpeedAttributeID,
MaxSpeedAttributeID,
MinMaxSpeedAttributeID,
MinSpeedAttributeID,
AccelerationAttributeID,
DeccelerationAttributeID,
ReverseAccelerationMultiplierAttributeID,
ReverseDeccelerationMultiplierAttributeID,
TargetLockTimeAttributeID,
MaxGimpSpeedAttributeID,
MinStandTransitionSpeedAttributeID,
MaxSlopeAttributeID,
StartSlopeDecelerationAttributeID,
SlopeDecel1AttributeID,
SlopeDecel2AttributeID,
SlopeDecel3AttributeID,
AttackTypeAttributeID,
TreadLengthAttributeID,
NextAttributeID
};
static bool
ReadAndVerify(
Vehicle__GameModel *model,
Adept::ModelAttributeEntry *attribute_entry,
const char *data,
char **error,
int error_buffer = 128
);
static void
ConstructGameModel(Script *script);
};
//##########################################################################
//############### Vehicle::ExecutionStateEngine ######################
//##########################################################################
class Vehicle__ExecutionStateEngine:
public MWObject::ExecutionStateEngine
{
public:
static void
InitializeClass();
static void
TerminateClass();
typedef MWObject::ExecutionStateEngine BaseClass;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Run-time Construction and Destruction Support
//
public:
typedef Vehicle__ExecutionStateEngine*
(*Factory)(
Vehicle *entity,
FactoryRequest *request
);
static Vehicle__ExecutionStateEngine*
Make(
Vehicle *mover,
FactoryRequest *request
);
protected:
Vehicle__ExecutionStateEngine(
ClassData *class_data,
Vehicle *mover,
FactoryRequest *request
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// State stuff
//
public:
enum {
FallingMotionState = MWMover::ExecutionStateEngine::StateCount,
FlyingMotionState,
AnimatedMotionState,
DrivingMotionState,
DestroyedState,
AIMotionState, // ai is controlling system
DyingState, // vehicle is sliding to a stop before blowing up
DroppingState, // vehicle is droping from a dropship
StateCount
};
int
RequestState(
int new_state,
void* data = NULL
);
protected:
static const StateEntry
StateEntries[];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Test Support
//
public:
void
TestInstance() const;
};
//##########################################################################
//############################ Vehicle ###############################
//##########################################################################
//-------------------------------------------------------------------------
// The following helper classes must always be typedef'd or overriden by an
// inheritor
//
typedef MWObject__Message Vehicle__Message;
typedef MWObject__UpdateMessage Vehicle__UpdateMessage;
typedef MWObject__CreateMessage Vehicle__CreateMessage;
typedef MWObject__ClassData Vehicle__ClassData;
extern DWORD Executed_Vehicle_Count;
//----------------------- End of inheritance stuff ------------------------
class Vehicle:
public MWObject
{
friend class MovementClass;
public:
static void
InitializeClass();
static void
TerminateClass();
typedef MWObject BaseClass;
friend class Vehicle__ExecutionStateEngine;
//##########################################################################
// Inheritance support
//
public:
typedef Vehicle__ClassData ClassData;
typedef Vehicle__GameModel GameModel;
typedef Vehicle__Message Message;
typedef Vehicle__ExecutionStateEngine ExecutionStateEngine;
typedef Vehicle__CreateMessage CreateMessage;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Run-time Construction and Destruction Support
//
public:
static Vehicle*
Make(
CreateMessage *message,
Adept::ReplicatorID *base_id
);
void
SaveInstanceText(Stuff::Page *page);
protected:
Vehicle(
ClassData *class_data,
CreateMessage *message,
Adept::ReplicatorID *base_id,
ElementRenderer::Element *element
);
void
Respawn(Adept::Entity::CreateMessage *message);
void
CommonCreation(CreateMessage *message);
void
Reuse(
const CreateMessage *message,
Adept::ReplicatorID *base_id
);
~Vehicle();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Game Model Support
//
public:
const GameModel*
GetGameModel()
{
Check_Object(this);
return Cast_Pointer(const GameModel*,gameModelResource.GetPointer());
}
virtual Stuff::Scalar
GetTurnSpeed()
{
Check_Object(this);
const GameModel *model = GetGameModel();
#ifdef LAB_ONLY
if (m_DebugFast)
{
return Lerp(model->fullStopTurnRate, model->topSpeedTurnRate, (currentSpeedMPS/10.0f)/model->maxSpeed);
}
else
#endif
return Lerp(model->fullStopTurnRate, model->topSpeedTurnRate, currentSpeedMPS/model->maxSpeed);
}
virtual Stuff::Scalar GetMaxSpeed();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support
//
public:
enum {
SpeedDemandMPSAttributeID = MWObject::NextAttributeID,
CurrentSpeedMPSAttributeID,
LocalGroundPitchAttributeID,
LocalGroundRollAttributeID,
RawLocalGroundPitchAttributeID,
RawLocalGroundRollAttributeID,
VehicleMovingSFXAttributeID,
VehicleIdleSFXAttributeID,
VehicleDyingSFXAttributeID,
NextAttributeID
};
public:
int
vehicleMovingSFX,
vehicleIdleSFX,
vehicleDyingSFX;
void SetMoving()
{Check_Pointer(this); vehicleMovingSFX = 1; vehicleIdleSFX = 0; vehicleDyingSFX = 0;}
void SetIdle()
{Check_Pointer(this); vehicleMovingSFX = 0; vehicleIdleSFX = 1; vehicleDyingSFX = 0;}
void SetDying ()
{Check_Pointer(this); vehicleMovingSFX = 0; vehicleIdleSFX = 0; vehicleDyingSFX = 1;}
void SetDead()
{Check_Pointer(this); vehicleMovingSFX = 0; vehicleIdleSFX = 0; vehicleDyingSFX = 0;}
int m_LastState;
Stuff::Scalar
speedDemand,
yawDemand,
pitchDemand,
rollDemand,
speedDemandMPS,
currentSpeedMPS,
currentSpeedKPH,
speedDemandKPH;
Stuff::Scalar
maxSlope,
startSlopeDeceleration;
#ifdef LAB_ONLY
bool m_DebugFast;
#endif
Stuff::Scalar m_WaterDelta; // depth of unit in water
Stuff::Scalar
m_groundRaycastHeight; // height of solid collision volume so that we don't pop on buildings
Stuff::Point3D dirRequest; // for movement
bool followDirRequest; // true if track dirRequest point
bool followDirRequestReverse; // true if should track to reverse of dirRequest
int m_DeathDamageMode; // for dieing mode to pass on after skid to stop
int m_DeathDamageType;
Stuff::Scalar
localGroundPitch,
localGroundRoll,
rawLocalGroundPitch,
rawLocalGroundRoll; // raw are plain numbers that are not locked to a degree
Stuff::Scalar m_RawGroundPitch; // true ground pitch
Stuff::Vector3D m_LocalNormal,m_WorldAvgNormal;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This is for inteface commands and network commands...
//
void ClearLancemate(void);
virtual void ProcessCommand(int command);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Animation Support
//
public:
virtual void AnimDiagTest1(void){animStateEngine->RequestState(AnimationStateEngine::Test1State);};
virtual void AnimDiagTest2(void){animStateEngine->RequestState(AnimationStateEngine::Test2State);};
virtual void AnimDiagTest3(void){animStateEngine->RequestState(AnimationStateEngine::Test3State);};
virtual void AnimDiagTest4(void){animStateEngine->RequestState(AnimationStateEngine::Test4State);};
virtual void AnimDiagTest5(void){animStateEngine->RequestState(AnimationStateEngine::Test5State);};
virtual void AnimDiagTest6(void){animStateEngine->RequestState(AnimationStateEngine::Test6State);};
virtual void AnimDiagTest7(void){animStateEngine->RequestState(AnimationStateEngine::Test7State);};
virtual void AnimDiagTest8(void){animStateEngine->RequestState(AnimationStateEngine::Test8State);};
void FindGroundAngle(void);
void FindGroundAngleUnitDiamond(void);
bool internalViewPoint;
bool usingEyeSpring;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Execution Support
//
public:
void ReactToDestruction(int damage_mode, int damage_type);
virtual void TurnOn (void);
virtual void TurnOff (void);
virtual void GetTransSpeedKPH (Stuff::Scalar& forward,Stuff::Scalar& reverse)
{ forward = 0;reverse = 0;}
virtual void GetMaxSpeedKPH (Stuff::Scalar& forward,Stuff::Scalar& reverse)
{ forward = 0;reverse = 0;}
virtual void GetTransSpeedNormalized (Stuff::Scalar& forward,Stuff::Scalar& reverse)
{ forward = 0;reverse = 0;}
int
GetExecutionSlot();
void
PreCollisionExecute(Stuff::Time till);
#if defined(LAB_ONLY)
void
SyncMatrices(bool update_matrix);
#endif
void
PostCollisionExecute(Stuff::Time till);
bool
CollisionHandler(
Stuff::LinearMatrix4D *new_position,
Stuff::DynamicArrayOf<CollisionData> *collisions
);
void RemoveFromExecution();
int
GetTableArray()
{Check_Object(this); return Adept::NameTable::VehicleArray;}
virtual void
AddStatsToString(std::string& s);
void CreateTrail();
void SelfDestruct();
virtual void ProcessSelfDestruct();
virtual void Eject() { }
int m_needSelfDestruct;
SlotOf <Adept::Effect *> m_SecondaryExplosion;
Adept::ResourceID
currentTrailID;
Stuff::SlotOf<Adept::Effect *>
currentTrailEffect;
BYTE
materialHit;
virtual void ComputeForwardSpeed(Stuff::Scalar time_slice);
void ComputeFrictionSpeed(Stuff::Scalar time_slice);
bool
vehicleRunsInterface;
enum {
FootNormal,
FootLocked,
FootReturn
};
int leftFootDown;
int rightFootDown;
static Stuff::Scalar
Vehicle::GetHeightAtPoint(
const Stuff::Point3D& point,
Adept::Entity* from_who
);
int
respawnCount;
//These are mirrored in a defines file that is read in by vehicles who need this.
//So when you add here you must match your changes in the attacktype.defines file
enum{
DefaultAttackType = 0,
NightShadeAttackType,
ShiloneAttackType
};
int
teamNumber;
void
SetTeam(int team)
{
teamNumber = team;
}
int
GetTeam()
{
return teamNumber;
}
// MSL 5.06 Armor Mode
int
m_ArmorMode;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Test Support
//
public:
void
TestInstance() const;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
public:
void
UpdateVehiclePosition(const Stuff::Scalar time_slice );
void
HookUpSubsystems(void);
void
BecomeInteresting(bool render_me);
void
BecomeUninteresting();
Engine*
GetEngine(void)
{return engine;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Dead-reckoning functions
//
public:
Stuff::Point3D&
EstimateFuturePosition(
Stuff::Point3D *new_position,
Stuff::Scalar seconds,
bool consider_terrain = true
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Network Smoothing
//
bool
correctingPosition,
correctingRotation;
Stuff::Point3D
correctionPosition;
Stuff::YawPitchRoll
correctionAngle;
Stuff::Scalar
rotationCorrectionTime;
Stuff::Scalar
positionCorrectionTime;
virtual void GetNetworkPosition(Stuff::Point3D &current_position, Stuff::YawPitchRoll &current_rotation);
virtual void GetDeadReckonedNetworkPosition(Stuff::Point3D &current_position, Stuff::YawPitchRoll &current_rotation);
virtual void ClearNetworkPosition();
virtual void SetNetworkCorretionPosition(Stuff::Point3D new_position, Stuff::YawPitchRoll new_rotation, Point3D velocity, Scalar vel_request, Scalar latency, Scalar update_rate);
virtual bool GetNetworkAdjustment(Stuff::Scalar time_slice, Stuff::Point3D &current_position, Stuff::YawPitchRoll &current_rotation);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Sensor cell map
protected:
int
m_SensorCellMapX;
int
m_SensorCellMapZ;
Stuff::Time
m_LastSensorCellPositionUpdate;
SensorCellMap*
GetSensorCellMap();
void
AddToSensorCellMap();
void
RemoveFromSensorCellMap();
void
UpdateSensorCellMapPosition();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Subsystem vars
public:
bool
DoesHaveLightAmp()
{Check_Object(this); return m_doesHaveLightAmp;}
protected:
Engine
*engine;
Adept::ShadowLight
*shadow;
// MSL 5.02 Shadow
Stuff::Scalar
shadowIntensity;
bool
m_doesHaveLightAmp;
};
inline
Vehicle__ExecutionStateEngine::Vehicle__ExecutionStateEngine(
ClassData *class_data,
Vehicle *vehicle,
FactoryRequest *request
):
BaseClass(class_data, vehicle, request)
{
}
}