//===========================================================================// // 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 #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 *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 m_SecondaryExplosion; Adept::ResourceID currentTrailID; Stuff::SlotOf 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 ¤t_position, Stuff::YawPitchRoll ¤t_rotation); virtual void GetDeadReckonedNetworkPosition(Stuff::Point3D ¤t_position, Stuff::YawPitchRoll ¤t_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 ¤t_position, Stuff::YawPitchRoll ¤t_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) { } }