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.
712 lines
19 KiB
C++
712 lines
19 KiB
C++
#include "MW4Headers.hpp"
|
|
|
|
#include "BombastWeapon.hpp"
|
|
#include "Vehicle.hpp"
|
|
#include "BeamEntity.hpp"
|
|
#include "GUIWeaponManager.hpp"
|
|
#include "VehicleInterface.hpp"
|
|
#include "SubsystemClassData.hpp"
|
|
|
|
#include <Adept\Map.hpp>
|
|
#include <Adept\EntityManager.hpp>
|
|
#include <Adept\Effect.hpp>
|
|
#include <Adept\Site.hpp>
|
|
|
|
#include <MLR\MLRTexturePool.hpp>
|
|
|
|
//#############################################################################
|
|
//########################## ExecutionStateEngine #######################
|
|
//#############################################################################
|
|
|
|
BombastWeapon::ExecutionStateEngine::ClassData*
|
|
BombastWeapon::ExecutionStateEngine::DefaultData = NULL;
|
|
|
|
const StateEngine::StateEntry
|
|
BombastWeapon::ExecutionStateEngine::StateEntries[]=
|
|
{
|
|
STATE_ENTRY(BombastWeapon__ExecutionStateEngine, Charging)
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::ExecutionStateEngine::InitializeClass()
|
|
{
|
|
Check_Object(StateEngine::DefaultData);
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
BombastWeapon__ExecutionStateEngineClassID,
|
|
"BombastWeapon::ExecutionStateEngine",
|
|
BaseClass::DefaultData,
|
|
ELEMENTS(StateEntries), StateEntries,
|
|
(Entity::ExecutionStateEngine::Factory)Make,
|
|
(Entity::ExecutionStateEngine::FactoryRequest::Factory)
|
|
&FactoryRequest::ConstructFactoryRequest
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::ExecutionStateEngine::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
BombastWeapon::ExecutionStateEngine*
|
|
BombastWeapon::ExecutionStateEngine::Make(
|
|
BombastWeapon *weapon,
|
|
FactoryRequest *request
|
|
)
|
|
{
|
|
Check_Object(weapon);
|
|
Check_Object(request);
|
|
gos_PushCurrentHeap(Heap);
|
|
BombastWeapon::ExecutionStateEngine *engine =
|
|
new BombastWeapon::ExecutionStateEngine(DefaultData, weapon, request);
|
|
gos_PopCurrentHeap();
|
|
|
|
return engine;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
BombastWeapon::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 firing, see if this is the start of the bombast. If so,
|
|
// start the charging processes instead. Otherwise don't let anything
|
|
// fire until at least half a second has gone by
|
|
//--------------------------------------------------------------------
|
|
//
|
|
BombastWeapon *beam;
|
|
beam = Cast_Object(BombastWeapon*, owningEntity);
|
|
if (new_state == FiringState)
|
|
{
|
|
switch (currentState)
|
|
{
|
|
case NeverExecuteState:
|
|
new_state = ChargingState;
|
|
break;
|
|
case ChargingState:
|
|
if ((gos_GetElapsedTime() - beam->startChargeTime) <= 0.5f)
|
|
return currentState;
|
|
break;
|
|
case RechargingState:
|
|
return currentState;
|
|
}
|
|
}
|
|
|
|
//
|
|
//---------------------------------------------------------------------
|
|
// Otherwise, make sure we only enter charging state from never execute
|
|
//---------------------------------------------------------------------
|
|
//
|
|
else if ((new_state == ChargingState) && (currentState != NeverExecuteState))
|
|
return currentState;
|
|
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
// We are calling weapon directly because we do not want beam functionality
|
|
//-------------------------------------------------------------------------
|
|
//
|
|
switch (BaseClass::BaseClass::RequestState(new_state, data))
|
|
{
|
|
case ChargingState:
|
|
{
|
|
beam->UsePostCollision();
|
|
beam->lastParameterization = gos_GetElapsedTime();
|
|
beam->startChargeTime = gos_GetElapsedTime();
|
|
beam->percentCharged = 0.25f;
|
|
beam->beamRechargeTime = 0.0f;
|
|
break;
|
|
}
|
|
case FiringState:
|
|
{
|
|
//We need to set up new target info here!
|
|
|
|
beam->UsePostCollision();
|
|
Check_Object(EntityManager::GetInstance());
|
|
EntityManager::GetInstance()->RequestPostCollisionExecution(beam);
|
|
|
|
// Start the sound
|
|
beam->beamStartSFX = 1;
|
|
beam->LeaveNeverExecuteState();
|
|
beam->lastParameterization = gos_GetElapsedTime();
|
|
if(beam->guiWeapon.GetCurrent())
|
|
beam->guiWeapon.GetCurrent()->Reload();
|
|
beam->ApplyHeat();
|
|
beam->beamRechargeTime = (Scalar)(gos_GetElapsedTime() - beam->startChargeTime);
|
|
const BeamWeapon::GameModel *beam_model = beam->GetGameModel();
|
|
Clamp(beam->beamRechargeTime, 0.0f, beam_model->reloadTime);
|
|
}
|
|
break;
|
|
case NeverExecuteState:
|
|
case DestroyedState:
|
|
break;
|
|
default:
|
|
{
|
|
owningEntity->IgnorePostCollision();
|
|
break;
|
|
}
|
|
}
|
|
return currentState;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::ExecutionStateEngine::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//#############################################################################
|
|
//############################### BombastWeapon #########################
|
|
//#############################################################################
|
|
|
|
BombastWeapon::ClassData*
|
|
BombastWeapon::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
BombastWeaponClassID,
|
|
"MechWarrior4::BombastWeapon",
|
|
BaseClass::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);
|
|
|
|
INDIRECT_STATE_ATTRIBUTE(
|
|
BombastWeapon,
|
|
ExecutionState,
|
|
executionState,
|
|
BombastWeapon__ExecutionStateEngine
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
MaxChargeTime,
|
|
maxChargeTime,
|
|
Scalar
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
TimeForMaxCharge,
|
|
timeForMaxCharge,
|
|
Scalar
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
ChargeEffectResource,
|
|
chargeEffectResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
InitialChargeBeamResource,
|
|
initialChargeBeamResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
HalfChargeBeamResource,
|
|
halfChargeBeamResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
ThreeQuarterChargeBeamResource,
|
|
threeQuarterChargeBeamResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
FullChargeBeamResource,
|
|
fullChargeBeamResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
InitialChargeFlareResource,
|
|
initialChargeFlareResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
HalfChargeFlareResource,
|
|
halfChargeFlareResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
ThreeQuarterChargeFlareResource,
|
|
threeQuarterChargeFlareResource,
|
|
ResourceID
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
BombastWeapon__GameModel,
|
|
FullChargeFlareResource,
|
|
fullChargeFlareResource,
|
|
ResourceID
|
|
);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
BombastWeapon*
|
|
BombastWeapon::Make(
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
gos_PushCurrentHeap(Heap);
|
|
BombastWeapon *new_entity =
|
|
new BombastWeapon(DefaultData, message, base_id, NULL);
|
|
gos_PopCurrentHeap();
|
|
Check_Object(new_entity);
|
|
return new_entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
BombastWeapon::BombastWeapon(
|
|
ClassData *class_data,
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id,
|
|
ElementRenderer::Element *element
|
|
):
|
|
BeamWeapon(class_data, message, base_id, element),
|
|
chargeEffect(NULL)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(message);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
BombastWeapon::~BombastWeapon()
|
|
{
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool BombastWeapon::ReadyToFire()
|
|
{
|
|
|
|
|
|
if (CanFireFromCurrentArm() == false)
|
|
{
|
|
return (false);
|
|
}
|
|
|
|
if (executionState->GetState()==ExecutionStateEngine::NeverExecuteState)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if ( executionState->GetState() == ExecutionStateEngine::ChargingState )
|
|
{
|
|
if ((gos_GetElapsedTime() - startChargeTime) > 0.5f)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void BombastWeapon::PreCollisionExecute(Time till)
|
|
{
|
|
PRECOLLISION_LOGIC("Subsystem::Bombast");
|
|
|
|
Check_Object(executionState);
|
|
int pre_state = executionState->GetState();
|
|
|
|
|
|
switch (pre_state)
|
|
{
|
|
case ExecutionStateEngine::ChargingState:
|
|
{
|
|
if((GetTimeParameter(till) > 1.0f) && (percentCharged < 1.0f))
|
|
{
|
|
percentCharged = percentCharged + 0.25f;
|
|
lastParameterization = gos_GetElapsedTime();
|
|
}
|
|
#if 0
|
|
if((gos_GetElapsedTime() - startChargeTime) > model->maxChargeTime)
|
|
{
|
|
Verify(GetParentVehicle()->IsDerivedFrom(Vehicle::DefaultData));
|
|
Vehicle *vehicle = Cast_Object(Vehicle *, GetParentVehicle());
|
|
Check_Object(vehicle);
|
|
|
|
if(vehicle->vehicleInterface)
|
|
{
|
|
vehicle->vehicleInterface->targetQuery.m_raySource =
|
|
vehicle->vehicleInterface->targetEntityPart.GetCurrent();
|
|
Fire(&vehicle->vehicleInterface->targetQuery, 0.0f, Stuff::Point3D::Identity);
|
|
}
|
|
else
|
|
{
|
|
executionState->RequestState(ExecutionStateEngine::FiringState);
|
|
}
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
BaseClass::PreCollisionExecute(till);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::PostCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(executionState);
|
|
|
|
POSTCOLLISION_LOGIC("Subsystem::Bombast");
|
|
int pre_state = executionState->GetState();
|
|
|
|
switch (pre_state)
|
|
{
|
|
case ExecutionStateEngine::ChargingState:
|
|
{
|
|
//
|
|
//--------------------------
|
|
//Create the charging effect
|
|
//--------------------------
|
|
//
|
|
if(!chargeEffect.GetCurrent())
|
|
CreateChargeEffect();
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
if(chargeEffect.GetCurrent())
|
|
chargeEffect.GetCurrent()->SentenceToDeathRow();
|
|
|
|
BaseClass::PostCollisionExecute(till);
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void BombastWeapon::CreateBeam()
|
|
{
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
ResourceID beam_resource;
|
|
if(percentCharged <= 0.25f)
|
|
beam_resource = model->initialChargeBeamResource;
|
|
else if(percentCharged <= 0.50f)
|
|
beam_resource = model->halfChargeBeamResource;
|
|
else if(percentCharged <= 0.75)
|
|
beam_resource = model->threeQuarterChargeBeamResource;
|
|
else
|
|
beam_resource = model->fullChargeBeamResource;
|
|
|
|
Verify(beam_resource != ResourceID::Null);
|
|
|
|
ClassID class_ID;
|
|
class_ID = GetClassIDFromDataListID(beam_resource);
|
|
Verify(class_ID != NullClassID);
|
|
|
|
Point3D target_point = Point3D::Identity;
|
|
ReplicatorID target_id = ReplicatorID::Null;
|
|
Normal3D target_normal(1.0f, 0.0f, 0.0f);
|
|
|
|
Check_Object(sitePointer);
|
|
const char *site_name = sitePointer->GetName();
|
|
ReplicatorID inflicting_id = ReplicatorID::Null;
|
|
inflicting_id = GetParentVehicle()->GetReplicatorID();
|
|
|
|
if(targetQuery.m_line->m_length > model->maxDistance)
|
|
{
|
|
targetQuery.m_line->m_length = model->maxDistance;
|
|
targetQuery.m_line->FindEnd(&target_point);
|
|
targetQuery.m_raySource = NULL;
|
|
}
|
|
else
|
|
{
|
|
if(targetQuery.m_raySource)
|
|
{
|
|
Check_Object(targetQuery.m_raySource);
|
|
target_id = targetQuery.m_raySource->GetReplicatorID();
|
|
targetQuery.m_line->FindEnd(&target_point);
|
|
target_normal = *targetQuery.m_normal;
|
|
}
|
|
else
|
|
{
|
|
targetQuery.m_line->FindEnd(&target_point);
|
|
}
|
|
}
|
|
|
|
Stuff::Scalar damage_amount, heat_amount;
|
|
damage_amount = percentCharged * model->damageAmount;
|
|
heat_amount = percentCharged * model->heatToDeal;
|
|
|
|
BeamEntity::CreateMessage beam_create_message(
|
|
sizeof(BeamEntity::CreateMessage),
|
|
DefaultEventPriority,
|
|
CreateMessage::DefaultFlags,
|
|
class_ID,
|
|
BeamEntity::DefaultFlags,
|
|
beam_resource,
|
|
sitePointer->GetLocalToWorld(),
|
|
0.0f,
|
|
ExecutionStateEngine::AlwaysExecuteState,
|
|
NameTable::NullObjectID,
|
|
Entity::DefaultAlignment,
|
|
inflicting_id,
|
|
site_name,
|
|
target_point,
|
|
target_id,
|
|
target_normal,
|
|
damage_amount,
|
|
heat_amount,
|
|
targetQuery.m_material,
|
|
model->maxDistance,
|
|
// MSL 5.03 Min Distance
|
|
// model->minDistance,
|
|
model->itemID
|
|
);
|
|
MemoryStream stream(&beam_create_message, beam_create_message.messageLength);
|
|
|
|
Entity *entity;
|
|
ReplicatorID beam_id = Connection::Hermit->GetNextReplicatorID();
|
|
entity = CreateEntity(&stream, &beam_id, false);
|
|
Check_Object(entity);
|
|
Verify(entity->IsDerivedFrom(BeamEntity::DefaultData));
|
|
beamEntity.Add(Cast_Object(BeamEntity *, entity));
|
|
Check_Object(Map::GetInstance());
|
|
Map::GetInstance()->AddChild(beamEntity.GetCurrent());
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::CreateChargeEffect()
|
|
{
|
|
Check_Object(this);
|
|
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
if(model->chargeEffectResource == ResourceID::Null)
|
|
return;
|
|
|
|
Resource charge_resource(model->chargeEffectResource);
|
|
|
|
if(charge_resource.DoesResourceExist())
|
|
{
|
|
ClassID class_ID;
|
|
class_ID = GetClassIDFromDataListID(model->chargeEffectResource);
|
|
Verify(class_ID != NullClassID);
|
|
|
|
LinearMatrix4D effect_position = LinearMatrix4D::Identity;
|
|
UnitVector3D unit_forward;
|
|
Check_Object(sitePointer);
|
|
LinearMatrix4D site_position = sitePointer->GetLocalToWorld();
|
|
site_position.GetLocalForwardInWorld(&unit_forward);
|
|
effect_position.AlignLocalAxisToWorldVector(unit_forward, Y_Axis, X_Axis, Z_Axis);
|
|
Point3D muzzle_translation;
|
|
muzzle_translation = sitePointer->GetLocalToWorld();
|
|
effect_position.BuildTranslation(muzzle_translation);
|
|
|
|
Effect::CreateMessage effect_create_message(
|
|
sizeof(Effect::CreateMessage),
|
|
DefaultEventPriority,
|
|
CreateMessage::DefaultFlags,
|
|
class_ID,
|
|
Effect::DefaultFlags,
|
|
model->chargeEffectResource,
|
|
effect_position,
|
|
0.0f,
|
|
ExecutionStateEngine::AlwaysExecuteState,
|
|
NameTable::NullObjectID,
|
|
Entity::DefaultAlignment
|
|
);
|
|
MemoryStream stream(&effect_create_message, effect_create_message.messageLength);
|
|
|
|
Entity *entity;
|
|
ReplicatorID beam_id = Connection::Hermit->GetNextReplicatorID();
|
|
entity = CreateEntity(&stream, &beam_id, false);
|
|
Check_Object(Map::GetInstance());
|
|
Map::GetInstance()->AddChild(entity);
|
|
chargeEffect.Remove();
|
|
chargeEffect.Add(Cast_Object(Effect *, entity));
|
|
chargeEffect.GetCurrent()->SetFollowEntity(sitePointer);
|
|
chargeEffect.GetCurrent()->SyncMatrices(true);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::CleanUpCreatedBeam()
|
|
{
|
|
Check_Object(this);
|
|
if(beamEntity.GetCurrent())
|
|
beamEntity.GetCurrent()->SentenceToDeathRow();
|
|
if(chargeEffect.GetCurrent())
|
|
chargeEffect.GetCurrent()->SentenceToDeathRow();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::CreateMuzzleFlash()
|
|
{
|
|
Check_Object(this);
|
|
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
ResourceID flare_resource;
|
|
if(percentCharged <= 0.25f)
|
|
flare_resource = model->initialChargeFlareResource;
|
|
else if(percentCharged <= 0.50f)
|
|
flare_resource = model->halfChargeFlareResource;
|
|
else if(percentCharged < 0.75)
|
|
flare_resource = model->threeQuarterChargeFlareResource;
|
|
else
|
|
flare_resource = model->fullChargeFlareResource;
|
|
|
|
Verify(flare_resource != ResourceID::Null);
|
|
|
|
// if(model->muzzleFlashResource == ResourceID::Null)
|
|
// return;
|
|
|
|
Resource muzzle_flash_resource(flare_resource);
|
|
if(muzzle_flash_resource.DoesResourceExist())
|
|
{
|
|
ClassID class_ID;
|
|
class_ID = GetClassIDFromDataListID(flare_resource);
|
|
Verify(class_ID != NullClassID);
|
|
|
|
LinearMatrix4D effect_position = LinearMatrix4D::Identity;
|
|
UnitVector3D unit_forward;
|
|
Check_Object(sitePointer);
|
|
LinearMatrix4D site_position = sitePointer->GetLocalToWorld();
|
|
site_position.GetLocalForwardInWorld(&unit_forward);
|
|
effect_position.AlignLocalAxisToWorldVector(unit_forward, Y_Axis, X_Axis, Z_Axis);
|
|
Point3D muzzle_translation;
|
|
muzzle_translation = sitePointer->GetLocalToWorld();
|
|
effect_position.BuildTranslation(muzzle_translation);
|
|
|
|
Effect::CreateMessage effect_create_message(
|
|
sizeof(Effect::CreateMessage),
|
|
DefaultEventPriority,
|
|
CreateMessage::DefaultFlags,
|
|
class_ID,
|
|
Effect::DefaultFlags,
|
|
flare_resource,
|
|
effect_position,
|
|
0.0f,
|
|
ExecutionStateEngine::AlwaysExecuteState,
|
|
NameTable::NullObjectID,
|
|
Entity::DefaultAlignment
|
|
);
|
|
MemoryStream stream(&effect_create_message, effect_create_message.messageLength);
|
|
|
|
Entity *entity;
|
|
ReplicatorID beam_id = Connection::Hermit->GetNextReplicatorID();
|
|
entity = CreateEntity(&stream, &beam_id, false);
|
|
Check_Object(Map::GetInstance());
|
|
Map::GetInstance()->AddChild(entity);
|
|
Effect *effect;
|
|
effect = Cast_Object(Effect *, entity);
|
|
effect->SetFollowEntity(sitePointer);
|
|
entity->SyncMatrices(true);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::SetQuery(CollisionQuery *query)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(sitePointer);
|
|
|
|
targetQuery.m_collisionMask = query->m_collisionMask;
|
|
targetQuery.m_material = query->m_material;
|
|
targetQuery.m_raySource = query->m_raySource;
|
|
|
|
collisionLine = *query->m_line;
|
|
collisionNormal = *query->m_normal;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
BombastWeapon::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|