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.
637 lines
17 KiB
C++
637 lines
17 KiB
C++
#include "MW4Headers.hpp"
|
|
|
|
#include "RTXWeaponSub.hpp"
|
|
#include "WeaponMover.hpp"
|
|
#include "SubsystemClassData.hpp"
|
|
#include "GUIWeaponManager.hpp"
|
|
|
|
#include <Adept\Site.hpp>
|
|
#include <Adept\Map.hpp>
|
|
|
|
//#############################################################################
|
|
//########################## ExecutionStateEngine #######################
|
|
//#############################################################################
|
|
|
|
RTXWeaponSub::ExecutionStateEngine::ClassData*
|
|
RTXWeaponSub::ExecutionStateEngine::DefaultData = NULL;
|
|
|
|
const StateEngine::StateEntry
|
|
RTXWeaponSub::ExecutionStateEngine::StateEntries[]=
|
|
{
|
|
STATE_ENTRY(RTXWeaponSub__ExecutionStateEngine, Jammed),
|
|
STATE_ENTRY(RTXWeaponSub__ExecutionStateEngine, Recharging)
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::ExecutionStateEngine::InitializeClass()
|
|
{
|
|
Check_Object(StateEngine::DefaultData);
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
RTXWeaponSub__ExecutionStateEngineClassID,
|
|
"RTXWeaponSub::ExecutionStateEngine",
|
|
BaseClass::DefaultData,
|
|
ELEMENTS(StateEntries), StateEntries,
|
|
(Entity::ExecutionStateEngine::Factory)Make,
|
|
(Entity::ExecutionStateEngine::FactoryRequest::Factory)
|
|
&FactoryRequest::ConstructFactoryRequest
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
RTXWeaponSub::ExecutionStateEngine*
|
|
RTXWeaponSub::ExecutionStateEngine::Make(
|
|
RTXWeaponSub *weapon,
|
|
FactoryRequest *request
|
|
)
|
|
{
|
|
Check_Object(weapon);
|
|
Check_Object(request);
|
|
gos_PushCurrentHeap(Heap);
|
|
RTXWeaponSub::ExecutionStateEngine *engine =
|
|
new RTXWeaponSub::ExecutionStateEngine(DefaultData, weapon, request);
|
|
gos_PopCurrentHeap();
|
|
return engine;
|
|
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
RTXWeaponSub::ExecutionStateEngine::RequestState(
|
|
int new_state,
|
|
void* data
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(owningEntity);
|
|
|
|
//
|
|
//------------------------------
|
|
// Quick exit if no state change
|
|
//------------------------------
|
|
//
|
|
if (new_state == currentState)
|
|
return currentState;
|
|
|
|
//
|
|
//-------------------------------------------------------
|
|
// If we are currently jammed, ignore a firing request
|
|
//-------------------------------------------------------
|
|
//
|
|
if ( currentState == JammedState && ( new_state == FiringState || new_state == ReloadingState ) )
|
|
{
|
|
return currentState;
|
|
}
|
|
|
|
if( new_state == FiringState && currentState == NeverExecuteState )
|
|
{
|
|
// Set the initial time of fire
|
|
RTXWeaponSub* owner = Cast_Object( RTXWeaponSub*, owningEntity );
|
|
owner->m_fireStartTime = owner->m_fireEndTime = gos_GetElapsedTime();
|
|
}
|
|
|
|
if (new_state == JammedState)
|
|
{
|
|
RTXWeaponSub* owner = Cast_Object( RTXWeaponSub*, owningEntity );
|
|
Check_Object(owner);
|
|
owner->StartJamState();
|
|
}
|
|
if (new_state == RechargingState)
|
|
{
|
|
RTXWeaponSub* owner = Cast_Object( RTXWeaponSub*, owningEntity );
|
|
Check_Object(owner);
|
|
owner->m_enterRecharge = gos_GetElapsedTime();
|
|
}
|
|
//
|
|
//
|
|
//---------------------
|
|
// Deal with our states
|
|
//---------------------
|
|
//
|
|
return ( BaseClass::RequestState(new_state, data) );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::ExecutionStateEngine::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
|
|
//#############################################################################
|
|
//############################### RTXWeaponSub ##########################
|
|
//#############################################################################
|
|
|
|
RTXWeaponSub::ClassData*
|
|
RTXWeaponSub::DefaultData = NULL;
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::ExecutionStateEngine::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
RTXWeaponSubClassID,
|
|
"MechWarrior4::RTXWeaponSub",
|
|
ProjectileWeapon::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(
|
|
RTXWeaponSub__GameModel,
|
|
TimeToPotentialJam,
|
|
m_timeToPotentialJam,
|
|
Scalar
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
RTXWeaponSub__GameModel,
|
|
TimeToJam,
|
|
m_timeToJam,
|
|
Scalar
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
RTXWeaponSub__GameModel,
|
|
TimeToUnjam,
|
|
m_timeToUnjam,
|
|
Scalar
|
|
);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
RTXWeaponSub*
|
|
RTXWeaponSub::Make(
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
Check_Object(message);
|
|
gos_PushCurrentHeap(Heap);
|
|
RTXWeaponSub *new_entity =
|
|
new RTXWeaponSub(DefaultData, message, base_id, NULL);
|
|
gos_PopCurrentHeap();
|
|
Check_Object(new_entity);
|
|
return new_entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
RTXWeaponSub::RTXWeaponSub(
|
|
ClassData *class_data,
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id,
|
|
ElementRenderer::Element *element
|
|
):
|
|
ProjectileWeapon(class_data, message, base_id, element),
|
|
m_jamStartTime( 0 ),
|
|
m_fireStartTime( 0 ),
|
|
m_fireEndTime( 0 )
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(message);
|
|
m_jamThisFrame = false;
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
RTXWeaponSub::~RTXWeaponSub()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::CreateProjectile(Time till)
|
|
{
|
|
Check_Object(this);
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
if(model->projectileModelResource != ResourceID::Null)
|
|
{
|
|
//
|
|
//---------------------------------
|
|
//Get the ClassID from the Resource
|
|
//---------------------------------
|
|
//
|
|
ClassID class_ID;
|
|
class_ID = GetClassIDFromDataListID(model->projectileModelResource);
|
|
Verify(class_ID != NullClassID);
|
|
|
|
ReplicatorID site_id = ReplicatorID::Null;
|
|
ReplicatorID target_id = ReplicatorID::Null;
|
|
Normal3D target_normal;
|
|
|
|
Motion3D initial_velocity = Motion3D::Identity;
|
|
Motion3D initial_acceleration = Motion3D::Identity;
|
|
Point3D site_local_to_world;
|
|
|
|
//
|
|
//-------------------------
|
|
//Initialize the velocities
|
|
//-------------------------
|
|
//
|
|
Check_Object(sitePointer);
|
|
site_local_to_world = sitePointer->GetLocalToWorld();
|
|
Vector3D projectile_direction;
|
|
Point3D target_point;
|
|
targetQuery.m_line->FindEnd(&target_point);
|
|
projectile_direction.Subtract(
|
|
target_point,
|
|
site_local_to_world
|
|
);
|
|
Check_Object(sitePointer);
|
|
site_local_to_world = sitePointer->GetLocalToWorld();
|
|
|
|
LinearMatrix4D direction_matrix = LinearMatrix4D::Identity;
|
|
direction_matrix.BuildTranslation((Stuff::Point3D)site_local_to_world);
|
|
direction_matrix.AlignLocalAxisToWorldVector(projectile_direction, Z_Axis, Y_Axis, X_Axis);
|
|
|
|
Vector3D initial_scale = model->initialLinearVelocity;
|
|
if(GetParentAsVehicle())
|
|
{
|
|
initial_scale.z += GetParentAsVehicle()->currentSpeedMPS;
|
|
}
|
|
|
|
initial_velocity.linearMotion.Multiply(
|
|
initial_scale,
|
|
direction_matrix
|
|
);
|
|
|
|
initial_acceleration.linearMotion = model->initialLinearAcceleration;
|
|
|
|
//
|
|
//------------------------------------
|
|
//Create the WeaponMover CreateMessage
|
|
//------------------------------------
|
|
//
|
|
|
|
WeaponMover::CreateMessage projectile_create_message(
|
|
sizeof(WeaponMover::CreateMessage),
|
|
DefaultEventPriority,
|
|
CreateMessage::DefaultFlags,
|
|
class_ID,
|
|
WeaponMover::DefaultFlags,
|
|
model->projectileModelResource,
|
|
direction_matrix,
|
|
0.0f,
|
|
WeaponMover::ExecutionStateEngine::StraightLineMotionState,
|
|
NameTable::NullObjectID,
|
|
Entity::DefaultAlignment,
|
|
initial_velocity,
|
|
initial_acceleration,
|
|
model->damageAmount,
|
|
model->heatToDeal,
|
|
model->maxDistance,
|
|
// MSL 5.03 Min Distance
|
|
// model->minDistance,
|
|
GetParentVehicle()->GetReplicatorID(),
|
|
model->splashRadius,
|
|
model->percentageOfDamageToDirectHit,
|
|
model->minPercentageOfDamageToSphereHit,
|
|
model->maxPercentageOfDamageToSphereHit,
|
|
model->itemID
|
|
);
|
|
MemoryStream stream(&projectile_create_message, projectile_create_message.messageLength);
|
|
|
|
Entity *entity;
|
|
ReplicatorID projectile_id = Connection::Hermit->GetNextReplicatorID();
|
|
entity = CreateEntity(&stream, &projectile_id, false);
|
|
Check_Object(entity);
|
|
Map::GetInstance()->AddChild(entity);
|
|
if (vehicleInterface)
|
|
{
|
|
vehicleInterface->PlayForce (VehicleInterface::FireProjectileForce);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Adding function for this, so we can update Jam at this time.
|
|
// this allows the server to jam and tell the client that it did.
|
|
//
|
|
//
|
|
void
|
|
RTXWeaponSub::Fire(Adept::Entity::CollisionQuery *query,
|
|
Stuff::Time time_locked,
|
|
const Stuff::Point3D& lockedTargetEntityPartOffset)
|
|
{
|
|
|
|
// MSL 5.03
|
|
BaseClass::Fire(query, time_locked, lockedTargetEntityPartOffset);
|
|
|
|
if (executionState->GetState() == ExecutionStateEngine::FiringState)
|
|
{
|
|
//
|
|
// Only jam if we are the person firing, or we are the server
|
|
//
|
|
// If we don't restrict this, then another client may refuse to show the shots because it thinks that the
|
|
// gun is jammed when it isn't
|
|
//
|
|
|
|
Check_Object(GetParentVehicle());
|
|
bool fServer = Network::GetInstance()->AmIServer();
|
|
bool fLocalPlayer = (GetReplicatorID().connectionID == Connection::Local->GetID());
|
|
|
|
//
|
|
//
|
|
//
|
|
if (fServer || fLocalPlayer)
|
|
{
|
|
const GameModel* model = GetGameModel();
|
|
Check_Object(model);
|
|
Check_Object(executionState);
|
|
// if we fired, check for jam
|
|
m_fireEndTime = gos_GetElapsedTime();
|
|
double cumulativeFiringTime = m_fireEndTime - m_fireStartTime;
|
|
|
|
//
|
|
// For servers, the rules are going to be different. If the fire time is at the absolute max, plus a buffer for lag
|
|
// then we will gaurantee a jam on the server, and have it refresh.
|
|
//
|
|
// This allows for some tolerance of various net traffic since we'd still prefer that the
|
|
// client handle this, but puts a cap on what we tolerate from a potential cheater.
|
|
if ( fLocalPlayer)
|
|
{
|
|
if ( cumulativeFiringTime >= model->m_timeToPotentialJam)
|
|
{
|
|
Stuff::Scalar idPermutation = (replicatorID.localID % 3)/3.0f; // have weapon's ID permutate it's jam time
|
|
Stuff::Scalar r = (Stuff::Scalar)fmod( gos_GetElapsedTime()+idPermutation, 1.0 );
|
|
|
|
Stuff::Scalar e = (Stuff::Scalar)(
|
|
( cumulativeFiringTime - model->m_timeToPotentialJam )
|
|
/ model->m_timeToJam );
|
|
// Potential to jam:
|
|
if ( r < e )
|
|
{
|
|
m_jamThisFrame = true;
|
|
}
|
|
}
|
|
}
|
|
else if (fServer)
|
|
{
|
|
if (cumulativeFiringTime >= (model->m_timeToJam + model->m_timeToPotentialJam + 2.0f))
|
|
{
|
|
m_jamThisFrame = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::PreCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
PRECOLLISION_LOGIC("Subsystem::RTXWeaponSub");
|
|
|
|
const GameModel* model = GetGameModel();
|
|
Check_Object(model);
|
|
Check_Object(executionState);
|
|
|
|
Stuff::Scalar timeSlice = GetTimeSlice( till );
|
|
|
|
int pre_state = executionState->GetState();
|
|
switch (pre_state)
|
|
{
|
|
case ExecutionStateEngine::FiringState:
|
|
{
|
|
UsePostCollision();
|
|
m_PlayedRechargeSound = false;
|
|
break;
|
|
}
|
|
|
|
case ExecutionStateEngine::ReloadingState:
|
|
{
|
|
Scalar count = model->reloadTime - GetTimeParameter(till);
|
|
Min_Clamp(count, 0.0f);
|
|
SetCount(count);
|
|
|
|
if (model->reloadTime > 0.49f)
|
|
{
|
|
if ((!m_PlayedRechargeSound) && (GetTimeParameter(till) >= model->reloadTime-0.5f))
|
|
{
|
|
if (GetParentVehicle ())
|
|
if (GetParentVehicle()->vehicleInterface)
|
|
{
|
|
GetParentVehicle ()->vehicleInterface->ReactToEvent (VehicleInterface::RECHARGE_PROJECTILE);
|
|
}
|
|
m_PlayedRechargeSound = true;
|
|
}
|
|
}
|
|
if(GetTimeParameter(till) > model->reloadTime)
|
|
{
|
|
executionState->RequestState(ExecutionStateEngine::RechargingState);
|
|
if(guiWeapon.GetCurrent())
|
|
guiWeapon.GetCurrent()->Ready();
|
|
m_PlayedRechargeSound = false;
|
|
}
|
|
IgnorePostCollision();
|
|
}
|
|
|
|
break;
|
|
case ExecutionStateEngine::RechargingState:
|
|
{
|
|
// In order to make the server and client agree on cumulative time more, I'll put a buffer in.
|
|
// but if we don't get a new fire request with .25 seconds of entering this state we'll assume recharge.
|
|
if ( (gos_GetElapsedTime() - m_enterRecharge ) >= 0.25f)
|
|
{
|
|
m_fireStartTime += timeSlice*2;
|
|
m_fireEndTime += timeSlice;
|
|
|
|
double cumulativeFiringTime = m_fireEndTime - m_fireStartTime;
|
|
|
|
|
|
if ( cumulativeFiringTime <= 0 )
|
|
{
|
|
executionState->RequestState(ExecutionStateEngine::NeverExecuteState);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case ExecutionStateEngine::JammedState:
|
|
{
|
|
if( gos_GetElapsedTime() - m_jamStartTime > model->m_timeToUnjam )
|
|
{
|
|
executionState->RequestState(ExecutionStateEngine::NeverExecuteState);
|
|
|
|
if(guiWeapon.GetCurrent())
|
|
guiWeapon.GetCurrent()->Ready();
|
|
}
|
|
else
|
|
{
|
|
// Update the gui time
|
|
if(guiWeapon.GetCurrent())
|
|
{
|
|
guiWeapon.GetCurrent()->SetJamCount( (Stuff::Scalar)(gos_GetElapsedTime() - m_jamStartTime) );
|
|
}
|
|
}
|
|
IgnorePostCollision();
|
|
break;
|
|
}
|
|
}
|
|
Weapon::PreCollisionExecute(till);
|
|
}
|
|
|
|
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::PostCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
|
|
POSTCOLLISION_LOGIC("Subsystem::RTXWeaponSub");
|
|
|
|
bool jammed = false;
|
|
if ( executionState->GetState() == ExecutionStateEngine::FiringState )
|
|
{
|
|
if (m_jamThisFrame)
|
|
{
|
|
executionState->RequestState(ExecutionStateEngine::JammedState);
|
|
jammed = true;
|
|
}
|
|
}
|
|
|
|
if ( !jammed )
|
|
ProjectileWeapon::PostCollisionExecute(till);
|
|
m_jamThisFrame = false;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
// This weapon needs to override this function. Unlike the normal projectile classes, this one requires that it
|
|
// be able to fire while in the "recharging" state.
|
|
//
|
|
|
|
bool
|
|
RTXWeaponSub::ReadyToFire()
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(executionState);
|
|
|
|
// if this is the local mech, always true in single player.
|
|
if (GetReplicatorID().connectionID == Connection::Local->GetID())
|
|
{
|
|
if (CanFireFromCurrentArm() == false)
|
|
{
|
|
return (false);
|
|
}
|
|
|
|
bool result;
|
|
result = (executionState->GetState()==ExecutionStateEngine::NeverExecuteState ||
|
|
executionState->GetState()==ExecutionStateEngine::RechargingState)
|
|
&& DoesHaveAmmo();
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
if (executionState->GetState()==ExecutionStateEngine::ReloadingState)
|
|
{
|
|
const GameModel* model = GetGameModel();
|
|
|
|
// 10% of the recharging plus the server-client packet time difference
|
|
if (gos_GetElapsedTime() - lastParameterization >= (model->reloadTime - (0.1f * model->reloadTime)))
|
|
{
|
|
executionState->RequestState(ExecutionStateEngine::RechargingState);
|
|
}
|
|
|
|
return DoesHaveAmmo();
|
|
}
|
|
|
|
|
|
bool result;
|
|
result = (executionState->GetState()==ExecutionStateEngine::NeverExecuteState ||
|
|
executionState->GetState()==ExecutionStateEngine::RechargingState) &&
|
|
DoesHaveAmmo();
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
void RTXWeaponSub::StartJamState()
|
|
{
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
m_jamStartTime = gos_GetElapsedTime();
|
|
if ( guiWeapon.GetCurrent() )
|
|
{
|
|
guiWeapon.GetCurrent()->RecoverFromJam();
|
|
guiWeapon.GetCurrent()->SetJamCount( model->m_timeToUnjam );
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
RTXWeaponSub::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
sprintf( buffer, "Cumulative = %d (start=%d, end=%d)\n", (int)(m_fireEndTime - m_fireStartTime), (int)m_fireStartTime, (int)m_fireEndTime );
|
|
Spew( 0, buffer );
|
|
|
|
sprintf( buffer, "Jammed = %d\n", (int)(gos_GetElapsedTime() - m_jamStartTime) );
|
|
Spew( 0,buffer );
|
|
|
|
sprintf( buffer, "Cumulative = %d (start=%d, end=%d)\n", (int)(m_fireEndTime - m_fireStartTime), (int)m_fireStartTime, (int)m_fireEndTime );
|
|
Spew( 0, buffer );
|
|
*/
|
|
|