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.
704 lines
17 KiB
C++
704 lines
17 KiB
C++
#include "MW4Headers.hpp"
|
|
|
|
#include "MFB.hpp"
|
|
#include "gameinfo.hpp"
|
|
#include "Mech.hpp"
|
|
#include "Weapon.hpp"
|
|
#include "MWDamageObject.hpp"
|
|
#include "CombatAI.hpp"
|
|
#include "HeatManager.hpp"
|
|
|
|
#include <Adept\EntityManager.hpp>
|
|
#include <Adept\DamageObject.hpp>
|
|
#include <Adept\Effect.hpp>
|
|
|
|
//#############################################################################
|
|
//############################### MFB ###################################
|
|
//#############################################################################
|
|
|
|
const StateEngine::StateEntry
|
|
MFB::ExecutionStateEngine::StateEntries[]=
|
|
{
|
|
STATE_ENTRY(MFB__ExecutionStateEngine, Repair),
|
|
STATE_ENTRY(MFB__ExecutionStateEngine, OpeningMotion)
|
|
};
|
|
|
|
|
|
MFB::ExecutionStateEngine::ClassData*
|
|
MFB::ExecutionStateEngine::DefaultData = NULL;
|
|
|
|
ChainOf<MFB*>
|
|
*MFB::s_MFBs = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::ExecutionStateEngine::InitializeClass()
|
|
{
|
|
Check_Object(BaseClass::DefaultData);
|
|
Verify(!DefaultData);
|
|
|
|
DefaultData =
|
|
new ClassData(
|
|
MFB__ExecutionStateEngineClassID,
|
|
"MFB::ExecutionStateEngine",
|
|
BaseClass::DefaultData,
|
|
ELEMENTS(StateEntries), StateEntries,
|
|
(Entity::ExecutionStateEngine::Factory)Make,
|
|
(Entity::ExecutionStateEngine::FactoryRequest::Factory)
|
|
&FactoryRequest::ConstructFactoryRequest
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::ExecutionStateEngine::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MFB::ExecutionStateEngine*
|
|
MFB::ExecutionStateEngine::Make(
|
|
MFB *vehicle,
|
|
FactoryRequest *request
|
|
)
|
|
{
|
|
Check_Object(vehicle);
|
|
Check_Object(request);
|
|
gos_PushCurrentHeap(Heap);
|
|
MFB::ExecutionStateEngine *engine =
|
|
new MFB::ExecutionStateEngine(DefaultData, vehicle, request);
|
|
gos_PopCurrentHeap();
|
|
return engine;
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MFB::ExecutionStateEngine::RequestState(
|
|
int new_state,
|
|
void* data
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(owningEntity);
|
|
|
|
//
|
|
//-------------------------------------------
|
|
// If there is no change of state just return
|
|
//-------------------------------------------
|
|
//
|
|
if (new_state == currentState)
|
|
return currentState;
|
|
|
|
#if 0
|
|
MFB *mfb = Cast_Object(MFB*, owningEntity);
|
|
Check_Object(mfb);
|
|
#endif
|
|
switch (BaseClass::RequestState(new_state, data))
|
|
{
|
|
case OpeningMotionState:
|
|
// mfb->animStateEngine->RequestState(MechAnimationStateEngine::OpeningState);
|
|
break;
|
|
}
|
|
|
|
return currentState;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::ExecutionStateEngine::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MFB::ClassData*
|
|
MFB::DefaultData = NULL;
|
|
|
|
DWORD MechWarrior4::Executed_MFB_Count = 0;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::InitializeClass()
|
|
{
|
|
Check_Object(MWMover::ExecutionStateEngine::DefaultData);
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
MFBClassID,
|
|
"MechWarrior4::MFB",
|
|
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);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
MFB__GameModel,
|
|
RepairEffectResource,
|
|
m_repairEffectResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
MFB__GameModel,
|
|
RepairCenterOffset,
|
|
m_repairCenterOffset,
|
|
Stuff::Vector3D
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
MFB__GameModel,
|
|
RepairDistance,
|
|
m_repairDistance,
|
|
Stuff::Scalar
|
|
);
|
|
|
|
s_MFBs = new ChainOf<MFB*>(NULL);
|
|
Check_Pointer(s_MFBs);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
|
|
s_MFBs->DeletePlugs();
|
|
delete s_MFBs;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MFB*
|
|
MFB::Make(
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
Check_Object(message);
|
|
gos_PushCurrentHeap(Heap);
|
|
MFB *new_entity = new
|
|
MFB(DefaultData, message, base_id, NULL);
|
|
gos_PopCurrentHeap();
|
|
Check_Object(new_entity);
|
|
|
|
|
|
Check_Object(EntityManager::GetInstance());
|
|
EntityManager::GetInstance()->AddMover(new_entity);
|
|
return new_entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MFB::MFB(
|
|
ClassData *class_data,
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id,
|
|
ElementRenderer::Element *element
|
|
):
|
|
Vehicle(class_data, message, base_id, element),
|
|
m_repairEffect(NULL),
|
|
m_repairingMech(NULL)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(message);
|
|
|
|
HookUpSubsystems();
|
|
CommonCreation(message);
|
|
|
|
s_MFBs->Add(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
MFB::~MFB()
|
|
{
|
|
if(m_weaponIterator)
|
|
{
|
|
delete m_weaponIterator;
|
|
}
|
|
if(m_internalIterator)
|
|
{
|
|
delete m_internalIterator;
|
|
}
|
|
if(m_armorIterator)
|
|
{
|
|
delete m_armorIterator;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::Reuse(
|
|
const CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(message);
|
|
|
|
STOP(("Not implemented"));
|
|
BaseClass::Reuse(message, base_id);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::CommonCreation(CreateMessage *message)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(message);
|
|
|
|
//m_RepairDistance = 18.0f;
|
|
m_CurrentMechUsing = NULL;
|
|
m_currentState = FixingGimpState;
|
|
m_nextRepairTime = gos_GetElapsedTime();
|
|
m_weaponIterator = NULL;
|
|
m_internalIterator = NULL;
|
|
m_armorIterator = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::Respawn(Entity::CreateMessage *message)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(message);
|
|
|
|
BaseClass::Respawn(message);
|
|
CreateMessage *vehicle_message = Cast_Pointer(CreateMessage *, message);
|
|
CommonCreation(vehicle_message);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void MFB::TurnOn (void)
|
|
{
|
|
lastParameterization = gos_GetElapsedTime ();
|
|
executionState->RequestState(ExecutionStateEngine::DrivingMotionState);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::PreCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
|
|
PRECOLLISION_LOGIC("MFB");
|
|
#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_MFB_Count, Executed_MFB_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::DrivingMotionState:
|
|
// ComputeForwardSpeed(time_slice);
|
|
// UpdateVehiclePosition(time_slice);
|
|
break;
|
|
//
|
|
//-----------------------------------------------------------
|
|
//We need to repair now...some mech powered down inside of us
|
|
//-----------------------------------------------------------
|
|
//
|
|
case ExecutionStateEngine::RepairState:
|
|
if(gos_GetElapsedTime() > m_nextRepairTime)
|
|
RepairTargetMech(time_slice);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::PostCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(executionState);
|
|
POSTCOLLISION_LOGIC("MFB");
|
|
|
|
switch(executionState->GetState())
|
|
{
|
|
case ExecutionStateEngine::RepairState:
|
|
CreateRepairEffect();
|
|
break;
|
|
}
|
|
|
|
BaseClass::PostCollisionExecute(till);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MFB::CollisionHandler(
|
|
Stuff::LinearMatrix4D *new_position,
|
|
Stuff::DynamicArrayOf<CollisionData> *collisions
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Verify(GetInterestLevel() != DormantInterestLevel);
|
|
Verify(EntityManager::GetInstance()->IsInPostCollisionExecution(this));
|
|
|
|
Verify(!newCollisions);
|
|
delete collisions;
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::RepairTargetMech(Scalar time_slice)
|
|
{
|
|
Check_Object(this);
|
|
|
|
Mech *mech = m_repairingMech.GetCurrent();
|
|
if(mech)
|
|
{
|
|
if (mech->vehicleInterface)
|
|
{
|
|
mech->vehicleInterface->ReactToEvent (VehicleInterface::MISSILE_LOCKLOST);
|
|
}
|
|
Check_Object(mech);
|
|
if(!mech->vehicleShutDown)
|
|
{
|
|
ShutMFBDown();
|
|
return;
|
|
}
|
|
switch(m_currentState)
|
|
{
|
|
case FixingGimpState:
|
|
{
|
|
//First check to see if we fix gimp
|
|
if(mech->IsGimped())
|
|
{
|
|
mech->RepairGimp();
|
|
m_nextRepairTime = gos_GetElapsedTime() + 6.0f;
|
|
m_currentState = ReloadingAmmoState;
|
|
return;
|
|
}
|
|
}
|
|
case ReloadingAmmoState:
|
|
{
|
|
Weapon *weapon;
|
|
m_currentState = ReloadingAmmoState;
|
|
while((weapon = m_weaponIterator->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(weapon);
|
|
if(weapon->HasFiredAmmo())
|
|
{
|
|
weapon->Reload();
|
|
m_nextRepairTime = gos_GetElapsedTime() + 2.0f;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
case ReloadingCoolantState:
|
|
{
|
|
m_currentState = ReloadingCoolantState;
|
|
Check_Object(mech->m_heatManager);
|
|
|
|
if(mech->m_heatManager->GetCoolant() < mech->m_heatManager->GetMaxCoolant())
|
|
{
|
|
mech->m_heatManager->AddCoolant(mech->m_heatManager->GetMaxCoolant());
|
|
m_nextRepairTime = gos_GetElapsedTime() + 2.0f;
|
|
return;
|
|
}
|
|
}
|
|
case FixingInternalState:
|
|
{
|
|
MWInternalDamageObject *internal;
|
|
m_currentState = FixingInternalState;
|
|
while((internal = m_internalIterator->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(internal);
|
|
if(internal->CanRepair())
|
|
{
|
|
internal->Reuse();
|
|
m_nextRepairTime = gos_GetElapsedTime() + 0.10f;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
case FixingArmorState:
|
|
{
|
|
DamageObject *armor;
|
|
m_currentState = FixingArmorState;
|
|
while((armor = m_armorIterator->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(armor);
|
|
if(armor->CanRepair())
|
|
{
|
|
armor->Reuse();
|
|
// MSL 5.05 Changed Repair time for external armor
|
|
// m_nextRepairTime = gos_GetElapsedTime() + 0.10f;
|
|
m_nextRepairTime = gos_GetElapsedTime() + 1.0f;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
mech->ShutDownRequest(false);
|
|
if (mech->vehicleInterface)
|
|
{
|
|
mech->vehicleInterface->ReactToEvent (VehicleInterface::REPAIR_STOP);
|
|
}
|
|
ShutMFBDown();
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::StartNewMech(Mech *new_mech)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(new_mech);
|
|
|
|
m_repairingMech.Remove();
|
|
m_repairingMech.Add(new_mech);
|
|
|
|
m_currentState = FixingGimpState;
|
|
|
|
if(m_weaponIterator)
|
|
{
|
|
delete m_weaponIterator;
|
|
}
|
|
m_weaponIterator = new WeaponIteratorType(&new_mech->weaponChain);
|
|
if(m_internalIterator)
|
|
{
|
|
delete m_internalIterator;
|
|
}
|
|
m_internalIterator = new InternalIteratorType(&new_mech->internalDamageObjects);
|
|
if(m_armorIterator)
|
|
{
|
|
delete m_armorIterator;
|
|
}
|
|
m_armorIterator = new ArmorIteratorType(&new_mech->damageObjects);
|
|
|
|
Check_Object(executionState);
|
|
executionState->RequestState(ExecutionStateEngine::RepairState);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::ShutMFBDown()
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(executionState);
|
|
|
|
executionState->RequestState(ExecutionStateEngine::NeverExecuteState);
|
|
if(m_repairEffect.GetCurrent())
|
|
{
|
|
m_repairEffect.GetCurrent()->executionState->RequestState(Effect::ExecutionStateEngine::StoppingState);
|
|
m_repairEffect.Remove();
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::CreateRepairEffect()
|
|
{
|
|
Check_Object(this);
|
|
|
|
if(!m_repairEffect.GetCurrent())
|
|
{
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
Effect *effect =
|
|
CreateLoopingEffect(model->m_repairEffectResource, this);
|
|
|
|
if(effect)
|
|
m_repairEffect.Add(effect);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MFB::IsWithin(
|
|
Entity *target,
|
|
Vector3D offset,
|
|
Scalar distance,
|
|
bool ignorey
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(target);
|
|
|
|
Vector3D target_line = Vector3D::Identity;
|
|
Point3D our_position;
|
|
Point3D target_position;
|
|
|
|
target_position = target->GetLocalToWorld();
|
|
our_position.Multiply(offset, GetLocalToWorld());
|
|
|
|
Point3D our_translation;
|
|
our_translation = GetLocalToWorld();
|
|
our_position.Add(our_position, our_translation);
|
|
if ((our_position.y < -1500) || (target_position.y < -1500)) // units in hell are never near each other
|
|
return false;
|
|
|
|
if (ignorey)
|
|
{
|
|
our_position.y = 0;
|
|
target_position.y = 0;
|
|
}
|
|
|
|
target_line.Subtract(target_position, our_position);
|
|
|
|
return target_line.GetLengthSquared() <= (distance * distance);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MFB*
|
|
MFB::IsWithinMFB(Mech *mech)
|
|
{
|
|
Check_Object(mech);
|
|
|
|
MFB *mfb;
|
|
ChainIteratorOf<MFB *> iterator(s_MFBs);
|
|
|
|
while((mfb = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(mfb);
|
|
|
|
//make sure the mfb is not destroyed and the mech is within 10.0 meters
|
|
if(!mfb->IsDestroyed())
|
|
{
|
|
if(mfb->IsWithin(mech, mfb->GetGameModel()->m_repairCenterOffset, mfb->GetGameModel()->m_repairDistance))
|
|
{//if(mech->IsWithin(mfb, mfb->GetGameModel()->m_repairDistance))
|
|
// MSL 5.03 Checks for Team Alignment
|
|
// If your not the same alignment as the MFB you can't use it
|
|
// MSL 5.05 Checks and allows for No Team
|
|
if ((mfb->GetAlignment() == mech->GetAlignment()) ||
|
|
(mech->GetTeam() == MWApplication::No_Team))
|
|
{
|
|
if (mech->vehicleInterface)
|
|
{
|
|
mech->vehicleInterface->ReactToEvent (VehicleInterface::REPAIR_START);
|
|
}
|
|
mfb->StartNewMech(mech);
|
|
return mfb;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::ReactToDestruction(int damage_mode, int damage_type)
|
|
{
|
|
Check_Object(this);
|
|
|
|
if(!IsDestroyed())
|
|
{
|
|
if(m_AI)
|
|
{
|
|
Check_Object(m_AI);
|
|
m_AI->Die();
|
|
}
|
|
|
|
SetDestroyedFlag(damage_mode);
|
|
|
|
if (damage_type != SplashDamageType)
|
|
DealSplashDamage();
|
|
|
|
MW4AI::g_Rect4DHash->RemovePermRect (this);
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
CreateEffect(model->destroyedEffectResource, (Point3D)GetLocalToWorld());
|
|
Entity *death_entity = CreateStaticHermitEntity(model->deathEntityResource);
|
|
if((death_entity) && (!m_deathEntity.GetCurrent()))
|
|
{
|
|
m_deathEntity.Remove();
|
|
m_deathEntity.Add(death_entity);
|
|
}
|
|
|
|
|
|
RemoveFromExecution();
|
|
|
|
|
|
}
|
|
|
|
Entity::ReactToDestruction(damage_mode, damage_type);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MFB::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|