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.
670 lines
18 KiB
C++
670 lines
18 KiB
C++
//===========================================================================//
|
|
// File: Tank.cpp
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 09/09/98 JSE Inital base class based off of Shadowrun/Adept //
|
|
// 09/23/98 BDB State engine update //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1998, Fasa Interactive //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "MW4Headers.hpp"
|
|
|
|
#include "Tank.hpp"
|
|
#include "gameinfo.hpp"
|
|
#include "AI.hpp"
|
|
#include "AI_UserConstants.hpp"
|
|
#include "Mech.hpp"
|
|
#include "MWDamageObject.hpp"
|
|
#include <adept\effect.hpp>
|
|
#include "obstacle.hpp"
|
|
|
|
// MSL 5.04 Tank Scorable
|
|
#include "MWMission.hpp"
|
|
|
|
#include <Adept\EntityManager.hpp>
|
|
#include <Adept\CollisionVolume.hpp>
|
|
#include <Adept\DamageObject.hpp>
|
|
|
|
//#############################################################################
|
|
//############################### Tank ##############################
|
|
//#############################################################################
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Tank::ClassData*
|
|
Tank::DefaultData = NULL;
|
|
|
|
DWORD MechWarrior4::Executed_Tank_Count = 0;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Tank::InitializeClass()
|
|
{
|
|
Check_Object(MWMover::ExecutionStateEngine::DefaultData);
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
TankClassID,
|
|
"MechWarrior4::Tank",
|
|
BaseClass::DefaultData,
|
|
0, NULL,
|
|
(Entity::Factory)Make,
|
|
(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
|
|
ExecutionStateEngine::DefaultData,
|
|
(Entity::GameModel::Factory)GameModel::ConstructGameModel,
|
|
(Entity::GameModel::Factory)GameModel::ConstructOBBStream,
|
|
(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
|
|
(Entity::GameModel::ModelWrite)GameModel::WriteToText,
|
|
(Entity::GameModel::ModelSave)GameModel::SaveGameModel,
|
|
AnimationStateEngine::Make
|
|
);
|
|
Register_Object(DefaultData);
|
|
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Tank::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Tank*
|
|
Tank::Make(
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
Check_Object(message);
|
|
gos_PushCurrentHeap(Heap);
|
|
Tank *new_entity = new
|
|
Tank(DefaultData, message, base_id, NULL);
|
|
gos_PopCurrentHeap();
|
|
Check_Object(new_entity);
|
|
|
|
|
|
Check_Object(EntityManager::GetInstance());
|
|
EntityManager::GetInstance()->AddMover(new_entity);
|
|
return new_entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Tank::Tank(
|
|
ClassData *class_data,
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id,
|
|
ElementRenderer::Element *element
|
|
):
|
|
Vehicle(class_data, message, base_id, element)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(message);
|
|
|
|
HookUpSubsystems();
|
|
CommonCreation(message);
|
|
|
|
// MSL 5.04 Tank Scorable
|
|
//should this tank be scored?
|
|
m_scoreThisTank = false;
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
Tank::~Tank()
|
|
{
|
|
Check_Object(EntityManager::GetInstance());
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Tank::Reuse(
|
|
const CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(message);
|
|
|
|
STOP(("Not implemented"));
|
|
BaseClass::Reuse(message, base_id);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Tank::CommonCreation(CreateMessage *message)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(message);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Tank::Respawn(Entity::CreateMessage *message)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(message);
|
|
|
|
BaseClass::Respawn(message);
|
|
CreateMessage *vehicle_message = Cast_Pointer(CreateMessage *, message);
|
|
CommonCreation(vehicle_message);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Tank::PreCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
|
|
PRECOLLISION_LOGIC("Tank");
|
|
#if defined(LAB_ONLY)
|
|
if (!instanceName)
|
|
MWGameInfo::g_LastVehicle[0] = '\0';
|
|
else
|
|
{
|
|
strncpy(MWGameInfo::g_LastVehicle, instanceName, sizeof(MWGameInfo::g_LastVehicle)-1);
|
|
MWGameInfo::g_LastVehicle[sizeof(MWGameInfo::g_LastVehicle)-1] = '\0';
|
|
}
|
|
MWGameInfo::g_LastVehiclePos = GetLocalToWorld ();
|
|
#endif
|
|
|
|
//
|
|
//-------------------------------------------------------------
|
|
// Let the base class deal with setting up the motion variables
|
|
//-------------------------------------------------------------
|
|
//
|
|
BaseClass::PreCollisionExecute(till);
|
|
Set_Statistic(Executed_Tank_Count, Executed_Tank_Count+1);
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// Any executing vehicle should not be in never execute state and should
|
|
// always use post collision
|
|
//----------------------------------------------------------------------
|
|
//
|
|
Check_Object(executionState);
|
|
int pre_state = executionState->GetState();
|
|
Verify(pre_state != ExecutionStateEngine::NeverExecuteState);
|
|
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
// Do the appropriate type of simulation. Animated motion state is for BRB
|
|
//-------------------------------------------------------------------------
|
|
//
|
|
Scalar time_slice = GetTimeSlice(till);
|
|
switch (pre_state)
|
|
{
|
|
//
|
|
//----------------------------------------------------
|
|
// Always execute state is for the normal driving code
|
|
//----------------------------------------------------
|
|
//
|
|
case ExecutionStateEngine::DyingState:
|
|
ComputeFrictionSpeed (time_slice);
|
|
UpdateVehiclePosition (time_slice);
|
|
break;
|
|
case ExecutionStateEngine::DrivingMotionState:
|
|
ComputeForwardSpeed(time_slice);
|
|
UpdateVehiclePosition(time_slice);
|
|
break;
|
|
|
|
//
|
|
//----------------------------------------------------
|
|
// Always execute state is for the normal driving code
|
|
//----------------------------------------------------
|
|
//
|
|
case ExecutionStateEngine::FlyingMotionState:
|
|
ComputeForwardSpeed(time_slice);
|
|
UpdateVehiclePosition(time_slice);
|
|
break;
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void Tank::PostCollisionExecute (Stuff::Time time)
|
|
{
|
|
Check_Object(this);
|
|
|
|
POSTCOLLISION_LOGIC("Tank");
|
|
lastParameterization = time;
|
|
initialLocalToParent = GetLocalToParent();
|
|
initialWorldSpaceVelocity = worldSpaceVelocity,
|
|
initialWorldSpaceAcceleration = worldSpaceAcceleration;
|
|
|
|
int pre_state = executionState->GetState();
|
|
Verify(pre_state != ExecutionStateEngine::NeverExecuteState);
|
|
|
|
switch (pre_state)
|
|
{
|
|
case ExecutionStateEngine::DyingState:
|
|
// check for unit stopped falling and moving
|
|
if ((localSpaceVelocity.linearMotion.z == 0.0f) && ((localSpaceVelocity.linearMotion.y == 0.0f)))
|
|
{
|
|
Verify (m_DeathDamageMode != -1);
|
|
Verify (m_DeathDamageType != -1);
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
DealSplashDamage();
|
|
|
|
SetDead ();
|
|
Entity::ReactToDestruction(m_DeathDamageMode,m_DeathDamageType);
|
|
|
|
// CreateEffect(model->secondaryDestroyedEffectResource, this);
|
|
if(!m_deathEntity.GetCurrent())
|
|
{
|
|
Entity *death_entity = CreateStaticHermitEntity(model->deathEntityResource);
|
|
if(death_entity)
|
|
{
|
|
m_deathEntity.Remove();
|
|
m_deathEntity.Add(death_entity);
|
|
}
|
|
}
|
|
executionState->RequestState(ExecutionStateEngine::NeverExecuteState);
|
|
entityElement->SetAlwaysCullMode();
|
|
RemoveCollision();
|
|
lastParameterization = GetTimeSlice (time);
|
|
initialLocalToParent = GetLocalToParent();
|
|
SyncMatrices(true);
|
|
}
|
|
break;
|
|
}
|
|
BaseClass::PostCollisionExecute (time);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
Tank::CollisionHandler(
|
|
Stuff::LinearMatrix4D *new_position,
|
|
Stuff::DynamicArrayOf<CollisionData> *collisions
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(collisions);
|
|
Verify(GetInterestLevel() != DormantInterestLevel);
|
|
bool shoulddamage=true;
|
|
//
|
|
//----------------------------------------------------------
|
|
// If we are destroyed, delete the collision list and return
|
|
//----------------------------------------------------------
|
|
//
|
|
if (IsDestroyed())
|
|
{
|
|
Verify(!newCollisions);
|
|
delete collisions;
|
|
return false;
|
|
}
|
|
|
|
//
|
|
//--------------------------------
|
|
// Ask the AI about the collision
|
|
//--------------------------------
|
|
//
|
|
if (m_AI)
|
|
{
|
|
if (!m_AI->ReactToCollision(collisions,shoulddamage)) // ai will return false if collision should not occur
|
|
{
|
|
Verify(!newCollisions);
|
|
delete collisions;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
//----------------------------------------
|
|
// Turn off collision if we are going fast
|
|
//----------------------------------------
|
|
//
|
|
#ifdef LAB_ONLY
|
|
if (m_DebugFast)
|
|
{
|
|
Verify(!newCollisions);
|
|
delete collisions;
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
//
|
|
//-----------------------
|
|
// Iterate the collisions
|
|
//-----------------------
|
|
//
|
|
bool just_bump = true;
|
|
for (int i=0; i<collisions->GetLength(); ++i)
|
|
{
|
|
CollisionData *data = &(*collisions)[i];
|
|
Check_Pointer(data);
|
|
|
|
//
|
|
//---------------------------------------------------------------------
|
|
// Look to see if we have run into a collider, and if so, calculate the
|
|
// relative velocity
|
|
//---------------------------------------------------------------------
|
|
//
|
|
Entity *other = data->m_otherEntity;
|
|
if (other->IsACollider())
|
|
{
|
|
just_bump = false;
|
|
Adept::Mover *adeptmover = Cast_Object(Adept::Mover*, other);
|
|
Vector3D rel_vel;
|
|
rel_vel.Subtract(adeptmover->worldSpaceVelocity.linearMotion, worldSpaceVelocity.linearMotion);
|
|
Scalar speed = rel_vel.GetLengthSquared();
|
|
MWObject *mover = Cast_Object(MWObject*, other);
|
|
|
|
//
|
|
//-------------------------------
|
|
// If its a mech, get its ratings
|
|
//-------------------------------
|
|
//
|
|
if (other->GetClassID() == MechClassID)
|
|
{
|
|
Mech *mech = Cast_Object(Mech*, mover);
|
|
int mech_class;
|
|
Scalar damage_received;
|
|
Scalar mech_speed;
|
|
if (mech->GetTonage() >= MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_mech_heavy_tonage))
|
|
{
|
|
damage_received = MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_mech_heavy_damage);
|
|
mech_speed = MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_mech_heavy_building_speed);
|
|
mech_class = HeavyCanWalkThruType;
|
|
}
|
|
else if (mech->GetTonage() >= MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_mech_medium_tonage))
|
|
{
|
|
damage_received = MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_mech_medium_damage);
|
|
mech_speed = MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_mech_medium_building_speed);
|
|
mech_class = MediumCanWalkThruType;
|
|
}
|
|
else
|
|
{
|
|
damage_received = MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_mech_light_damage);
|
|
mech_speed = MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_mech_light_building_speed);
|
|
mech_class = AnythingCanWalkThruType;
|
|
}
|
|
|
|
//
|
|
//----------------------
|
|
// See if it squishes us
|
|
//----------------------
|
|
//
|
|
if (GetWalkThruType() >= mech_class)
|
|
{
|
|
if (shoulddamage)
|
|
{
|
|
TakeDamageMessage damage_message(
|
|
GetReplicatorID(),
|
|
other->GetReplicatorID(),
|
|
100000.0f,
|
|
// MSL 5.05 Advance Mode
|
|
0,
|
|
RammingDamageFromAboveType,
|
|
data->m_normal,
|
|
data->m_worldIntersectionPoint,
|
|
0.0f,
|
|
false,
|
|
TakeDamageMessage::DefaultWeaponType
|
|
);
|
|
Receive(&damage_message);
|
|
}
|
|
}
|
|
|
|
//
|
|
//-----------------------------------------------
|
|
// See if we are going fast enough to get damaged
|
|
//-----------------------------------------------
|
|
//
|
|
else if (speed >= mech_speed)
|
|
{
|
|
speed = Sqrt(speed)*mover->GetTonage();
|
|
|
|
//
|
|
//------------------------
|
|
// Evaluate the DFA states
|
|
//------------------------
|
|
//
|
|
Scalar min_dfa_vel = MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_dfa_speed);
|
|
Entity::ExecutionStateEngine *engine = mech->executionState;
|
|
bool their_dfa = mech->worldSpaceVelocity.linearMotion.y <= -min_dfa_vel && engine->GetState() == ExecutionStateEngine::FlyingMotionState;
|
|
|
|
//
|
|
//---------------------------------------
|
|
// Use the appropriate collision modifier
|
|
//---------------------------------------
|
|
//
|
|
char damage_type;
|
|
if (their_dfa)
|
|
{
|
|
damage_type = RammingDamageFromAboveType;
|
|
speed *= MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_dfa_damage_given);
|
|
}
|
|
else
|
|
{
|
|
damage_type = RammingDamageFromAheadType;
|
|
speed *= damage_received;
|
|
}
|
|
|
|
//
|
|
//----------------------------------
|
|
// Set the damage message to ourself
|
|
//----------------------------------
|
|
//
|
|
// MSL 5.04 Tank Collision Damage
|
|
// MSL 5.06 Armor Mode
|
|
MWApplication *m_App;
|
|
m_App = MWApplication::GetInstance ();
|
|
m_ArmorMode = m_App->GetLocalNetParams()->m_armormodeOn;
|
|
|
|
if (shoulddamage)
|
|
{
|
|
if (m_ArmorMode)
|
|
{
|
|
TakeDamageMessage damage_message(
|
|
GetReplicatorID(),
|
|
other->GetReplicatorID(),
|
|
0.1f,
|
|
m_ArmorMode,
|
|
damage_type,
|
|
data->m_normal,
|
|
data->m_worldIntersectionPoint,
|
|
0.0f,
|
|
false,
|
|
TakeDamageMessage::DefaultWeaponType
|
|
);
|
|
Receive(&damage_message);
|
|
}
|
|
else
|
|
{
|
|
TakeDamageMessage damage_message(
|
|
GetReplicatorID(),
|
|
other->GetReplicatorID(),
|
|
speed,
|
|
m_ArmorMode,
|
|
damage_type,
|
|
data->m_normal,
|
|
data->m_worldIntersectionPoint,
|
|
0.0f,
|
|
false,
|
|
TakeDamageMessage::DefaultWeaponType
|
|
);
|
|
Receive(&damage_message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------------------
|
|
// If we've run into a static object, see if we can just kill it
|
|
//--------------------------------------------------------------
|
|
//
|
|
else
|
|
{
|
|
if (GetWalkThruType() <= other->GetWalkThruType())
|
|
{
|
|
if (shoulddamage)
|
|
{
|
|
TakeDamageMessage damage_message(
|
|
other->GetReplicatorID(),
|
|
GetReplicatorID(),
|
|
100000.0f,
|
|
// MSL 5.05 Advance Mode
|
|
0,
|
|
RammingDamageFromAboveType,
|
|
data->m_otherNormal,
|
|
data->m_worldIntersectionPoint,
|
|
0.0f,
|
|
false,
|
|
TakeDamageMessage::DefaultWeaponType
|
|
);
|
|
other->Receive(&damage_message);
|
|
}
|
|
}
|
|
|
|
//
|
|
//------------------------------
|
|
// Otherwise, just stop the tank
|
|
//------------------------------
|
|
//
|
|
else
|
|
just_bump = false;
|
|
}
|
|
}
|
|
|
|
//
|
|
//-------------------------------
|
|
// Slow down the tank as required
|
|
//-------------------------------
|
|
//
|
|
Scalar slowdown = MW4AI::UserConstants::m_Instance->Get(MW4AI::UserConstants::collision_tank_slowdown);
|
|
bool result = false;
|
|
if (just_bump)
|
|
{
|
|
if (currentSpeedMPS > 0.0f)
|
|
{
|
|
currentSpeedMPS -= slowdown;
|
|
Min_Clamp(currentSpeedMPS, 0.0f);
|
|
}
|
|
if (currentSpeedMPS < 0.0f)
|
|
{
|
|
currentSpeedMPS += slowdown;
|
|
Max_Clamp(currentSpeedMPS, 0.0f);
|
|
}
|
|
}
|
|
|
|
//
|
|
//-------------------------
|
|
// Otherwise, stop the tank
|
|
//-------------------------
|
|
//
|
|
else
|
|
{
|
|
result = true;
|
|
currentSpeedMPS = 0.0f;
|
|
*new_position = GetLocalToParent();
|
|
}
|
|
currentSpeedKPH = currentSpeedMPS * 3.6f;
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// If the tank isn't executing, it can't move or retain its collisions
|
|
//--------------------------------------------------------------------
|
|
//
|
|
Entity::ExecutionStateEngine *engine = executionState;
|
|
if (engine->GetState() == ExecutionStateEngine::NeverExecuteState || !IsUsingPostCollision())
|
|
{
|
|
Verify(!newCollisions);
|
|
delete collisions;
|
|
return false;
|
|
}
|
|
|
|
newCollisions = collisions;
|
|
return result;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Tank::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void Tank::ReactToDestruction(int damage_mode, int damage_type)
|
|
{
|
|
|
|
if (damage_mode != InternalDamageObject::DestructionDamageMode)
|
|
{
|
|
SPEW(("jerryeds", "DYING WITHOUT DEATH!!!"));
|
|
SPEW(("daberger", "DYING WITHOUT DEATH!!!"));
|
|
|
|
damage_mode = InternalDamageObject::DestructionDamageMode;
|
|
}
|
|
|
|
if ((localSpaceVelocity.linearMotion.z == 0.0f) && ((localSpaceVelocity.linearMotion.y == 0.0f)))
|
|
{
|
|
BaseClass::ReactToDestruction (damage_mode,damage_type);
|
|
return;
|
|
}
|
|
switch(damage_mode)
|
|
{
|
|
case InternalDamageObject::DestructionDamageMode:
|
|
{
|
|
// MSL 5.04 Tank Scorable
|
|
if (m_scoreThisTank)
|
|
{
|
|
Check_Object (Mission::GetInstance());
|
|
Mission::GetInstance()->ScoringReactToBuildingDeath (m_whoShotMeLast, GetReplicatorID());
|
|
}
|
|
|
|
if(m_AI)
|
|
{
|
|
Check_Object(m_AI);
|
|
m_AI->Die();
|
|
}
|
|
else
|
|
{
|
|
MW4AI::g_Rect4DHash->RemovePermRect (this);
|
|
}
|
|
|
|
if((!IsDestroyed()) && (!m_SecondaryExplosion.GetCurrent ()))
|
|
{
|
|
m_DeathDamageMode = damage_mode;
|
|
m_DeathDamageType = damage_type;
|
|
const GameModel *model = GetGameModel();
|
|
SetDying ();
|
|
Check_Object(model);
|
|
Effect *eff;
|
|
eff = CreateEffect(model->secondaryDestroyedEffectResource, this,true);
|
|
if (eff != NULL)
|
|
{
|
|
Check_Object (eff);
|
|
m_SecondaryExplosion.Add (eff);
|
|
executionState->RequestState(ExecutionStateEngine::DyingState);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|