Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
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.
2026-06-24 21:28:16 -05:00

558 lines
13 KiB
C++

//===========================================================================//
// File: Weapon.hpp
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 09/09/98 JSE Inital base class based off of Shadowrun/Adept
// 09/24/98 BDB Inital Weapon subsystem based off of Subsystem.hpp
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "MW4.hpp"
#include "Subsystem.hpp"
#include "vehicleInterface.hpp"
namespace Adept
{
class Site;
}
namespace MechWarrior4
{
class Vehicle;
class Engine;
class MWMover;
class Vehicle;
class GUIWeapon;
class HeatManager;
void WeaponSecurityCheckStart();
void WeaponSecurityCheckStop();
//##########################################################################
//################## Weapon::CreateMessage ###########################
//##########################################################################
class Weapon__CreateMessage:
public Subsystem__CreateMessage
{
public:
typedef Subsystem__CreateMessage BaseClass;
char
siteName[128];
char
ejectSiteName[128];
int
groupIndex;
int
ammoCount;
int
initialAmmoCount;
// MSL 5.04 Rear Firing Weapons
int
m_weaponFacing;
Weapon__CreateMessage(
size_t length,
int priority,
int message_flags,
Stuff::RegisteredClass::ClassID class_id,
int replicator_flags,
const ResourceID& instance_id,
const Stuff::LinearMatrix4D &creation_matrix,
Stuff::Scalar age,
int execution_state,
int name_id,
int entity_alignment,
int subsystem_index,
BYTE location_id,
int critical_hits,
const char *site_name,
int group_index,
int ammo_count,
int initial_ammo,
const char *eject_site,
// MSL 5.04 Rear Firing Weapons
int weapon_facing
):
Subsystem__CreateMessage(
length,
priority,
message_flags,
class_id,
replicator_flags,
instance_id,
creation_matrix,
age,
execution_state,
name_id,
entity_alignment,
subsystem_index,
location_id,
critical_hits
),
groupIndex(group_index),
ammoCount(ammo_count),
// MSL 5.04 Rear Firing Weapons
m_weaponFacing(weapon_facing),
initialAmmoCount(initial_ammo)
{
Check_Pointer(site_name);
Str_Copy(siteName, site_name, sizeof(siteName));
Str_Copy(ejectSiteName, eject_site, sizeof(ejectSiteName));
}
static void
ConstructCreateMessage(Script *script);
};
//##########################################################################
//########################### Weapon GameModel ########################
//##########################################################################
class Weapon__GameModel;
typedef Subsystem__ClassData Weapon__ClassData;
typedef Subsystem__Message Weapon__Message;
typedef Subsystem__ExecutionStateEngine Weapon__ExecutionStateEngine;
class Weapon__GameModel:
public Subsystem::GameModel
{
public:
typedef Subsystem::GameModel BaseClass;
Adept::ResourceID
muzzleFlashResource;
Adept::ResourceID
ejectEffectResource;
Stuff::Scalar
heat;
Stuff::Scalar
heatSpreadTime;
int
maxAmmoCount;
int
numFire;
int
ammoPerShot;
Stuff::Scalar
heatToDeal;
Stuff::Scalar
damageAmount;
Stuff::Scalar
maxDistance;
// MSL 5.03 Min Distance
// Stuff::Scalar
// minDistance;
Scalar
splashRadius;
Stuff::Scalar
percentageOfDamageToDirectHit;
Stuff::Scalar
minPercentageOfDamageToSphereHit;
Stuff::Scalar
maxPercentageOfDamageToSphereHit;
Stuff::Scalar
reloadTime;
Stuff::Scalar
m_lightAmpFlareOut;
Stuff::Scalar
m_HudEffect; // jcem
enum {
MuzzleFlashResourceAttributeID = Subsystem__GameModel::NextAttributeID,
EjectEffectResourceAttributeID,
HeatAttributeID,
HeatSpreadTimeAttributeID,
MaxAmmoAttributeID,
AmmoPerShotAttributeID,
HeatToDealAttributeID,
SplashRadiusAttributeID,
PercentageOfDamageToDirectHitAttributeID,
MinPercentageOfDamageToSphereHitAttributeID,
MaxPercentageOfDamageToSphereHitAttributeID,
DamageAmountAttributeID,
MaxDistanceAttributeID,
// MSL 5.03 Min Distance
// MinDistanceAttributeID,
ReloadTimeAttributeID,
LightAmpFlareOutAttributeID,
NumFireAttributeID,
HudEffectAttributeID,
NextAttributeID
};
static bool
ReadAndVerify(
Weapon__GameModel *model,
ModelAttributeEntry *attribute_entry,
const char *data,
char **error,
int error_buffer = 128
);
static void
ConstructGameModel(Script *script);
};
//##########################################################################
//########################### Weapon ####################################
//##########################################################################
class Weapon:
public Subsystem
{
public:
static void
InitializeClass();
static void
TerminateClass();
typedef Subsystem BaseClass;
//##########################################################################
// Inheritance support
//
public:
typedef Weapon__ClassData ClassData;
typedef Weapon__GameModel GameModel;
typedef Weapon__Message Message;
typedef Weapon__ExecutionStateEngine ExecutionStateEngine;
typedef Weapon__CreateMessage CreateMessage;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Run-time Construction and Destruction Support
//
public:
static Weapon*
Make(
CreateMessage *message,
ReplicatorID *base_id
);
Adept::Replicator::CreateMessage*
SaveMakeMessage(Stuff::MemoryStream *stream, Adept::ResourceFile *res_file);
void
SaveInstanceText(Stuff::Page *page);
void
Respawn(Adept::Entity::CreateMessage *message);
void
CommonCreation(CreateMessage *message);
static void
CreateStream(
Adept::ResourceID data_list,
Stuff::MemoryStream *stream
);
protected:
Weapon(
ClassData *class_data,
CreateMessage *message,
ReplicatorID *base_id,
ElementRenderer::Element *element
);
~Weapon();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data & Game Model Support
//
public:
const GameModel*
GetGameModel()
{return Cast_Pointer(const GameModel*, gameModelResource.GetPointer());}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Simulation Support
//
enum
{
WeaponGroup1FlagBit = 0,
WeaponGroup2FlagBit,
WeaponGroup3FlagBit,
WeaponGroup4FlagBit,
WeaponGroup5FlagBit,
WeaponGroup6FlagBit
};
enum
{
WeaponGroup1Flag = 1<<WeaponGroup1FlagBit,
WeaponGroup2Flag = 1<<WeaponGroup2FlagBit,
WeaponGroup3Flag = 1<<WeaponGroup3FlagBit,
WeaponGroup4Flag = 1<<WeaponGroup4FlagBit,
WeaponGroup5Flag = 1<<WeaponGroup5FlagBit,
WeaponGroup6Flag = 1<<WeaponGroup6FlagBit,
DefaultWeaponGroupFlags = 0
};
enum
{
FacingForwardFlagBit = 0,
FacingBackFlagBit,
FacingAllFlagBit,
};
enum
{
FacingForwardFlag = 1<<FacingForwardFlagBit,
FacingBackFlag = 1<<FacingBackFlagBit,
FacingAllFlag = 1<<FacingAllFlagBit,
};
VehicleInterface *vehicleInterface;
bool m_PlayedRechargeSound;
bool
IsInWeaponGroup1()
{Check_Object(this); return (groupIndexFlags & WeaponGroup1Flag) != 0;}
bool
IsInWeaponGroup2()
{Check_Object(this); return (groupIndexFlags & WeaponGroup2Flag) != 0;}
bool
IsInWeaponGroup3()
{Check_Object(this); return (groupIndexFlags & WeaponGroup3Flag) != 0;}
bool
IsInWeaponGroup4()
{Check_Object(this); return (groupIndexFlags & WeaponGroup4Flag) != 0;}
bool
IsInWeaponGroup5()
{Check_Object(this); return (groupIndexFlags & WeaponGroup5Flag) != 0;}
bool
IsInWeaponGroup6()
{Check_Object(this); return (groupIndexFlags & WeaponGroup6Flag) != 0;}
void
SetGroup1()
{Check_Object(this); groupIndexFlags |= WeaponGroup1Flag;}
void
SetGroup2()
{Check_Object(this); groupIndexFlags |= WeaponGroup2Flag;}
void
SetGroup3()
{Check_Object(this); groupIndexFlags |= WeaponGroup3Flag;}
void
SetGroup4()
{Check_Object(this); groupIndexFlags |= WeaponGroup4Flag;}
void
SetGroup5()
{Check_Object(this); groupIndexFlags |= WeaponGroup5Flag;}
void
SetGroup6()
{Check_Object(this); groupIndexFlags |= WeaponGroup6Flag;}
void
ClearGroup1()
{Check_Object(this); groupIndexFlags &= ~WeaponGroup1Flag;}
void
ClearGroup2()
{Check_Object(this); groupIndexFlags &= ~WeaponGroup2Flag;}
void
ClearGroup3()
{Check_Object(this); groupIndexFlags &= ~WeaponGroup3Flag;}
void
ClearGroup4()
{Check_Object(this); groupIndexFlags &= ~WeaponGroup4Flag;}
void
ClearGroup5()
{Check_Object(this); groupIndexFlags &= ~WeaponGroup5Flag;}
void
ClearGroup6()
{Check_Object(this); groupIndexFlags &= ~WeaponGroup6Flag;}
void
SetWeaponGroup(int group);
void
ClearWeaponGroup(int group);
void
ApplyHeat();
int GetAmmoCount()
{Check_Object(this); return DECRYPT(encryptedAmmoCount);}
// MSL 5.05 Rear Firing Weapons
int GetWeaponFacing()
{Check_Object(this); return m_weaponFacing;}
void
SetWeaponFacing(int facing)
{Check_Object(this); m_weaponFacing = facing;}
void
ClearWeaponFacing()
{Check_Object(this); m_weaponFacing = 0;}
void SetAmmoCount(int ammo_count)
{Check_Object(this); encryptedAmmoCount = ENCRYPT(ammo_count);};
bool DoesHaveAmmo();
void ClearAmmo()
{Check_Object(this); encryptedAmmoCount = ENCRYPT(0);}
void UseAmmo();
bool AddAmmoPack();
bool RemoveAmmoPack();
int GetAmmoPacks();
int GetAmmoPerPack();
void
DestroySubsystem();
bool
TakeCriticalHit();
int
weaponID;
// MSL 5.04 Rear Firing Weapons
int m_weaponFacing;
Stuff::MString
siteName;
Stuff::MString
ejectSiteName;
Engine*
enginePointer;
HeatManager*
heatPointer;
Adept::Site*
sitePointer;
Adept::Site*
ejectSitePointer;
int
groupIndexFlags;
Stuff::SlotOf<GUIWeapon*>
guiWeapon;
bool
ConnectSubsystem();
bool
DisconnectSubsystem();
void
ConnectHeatManager(HeatManager *heat_manager)
{Check_Object(this); heatPointer = heat_manager;}
void
FireWeapon(Adept::Entity::CollisionQuery *query,
Stuff::Time time_locked,
const Stuff::Point3D& lockedTargetEntityPartOffset);
void QuickFireWeapon (Adept::Entity *target);
virtual void
CreateMuzzleFlash();
void
CreateEjectEffect();
void
CreateLightAmpFlareOut();
virtual bool
ReadyToFire()
{
Check_Object(this);
return false;
}
Stuff::Scalar
GetTotalHeatGenerated();
void
SetWeaponID(int weapon_id)
{
weaponID = weapon_id;
}
int
GetWeaponID(void)
{
return weaponID;
}
Stuff::Scalar
GetAIWaitValue() const;
void
SetMaxWaitValue();
Stuff::Time
GetLastTimeReadyToFire() const;
bool
HasFiredAmmo()
{Check_Object(this); return (initialAmmoCount - DECRYPT(encryptedAmmoCount)) > 0;}
void
Reload()
{Check_Object(this); encryptedAmmoCount = ENCRYPT(initialAmmoCount);}
int encryptedAmmoCount;
int initialAmmoCount;
bool
CanFireFromCurrentArm();
bool
CanFireForward();
bool
CanFireRight();
bool
CanFireLeft();
bool
CanFireBackward();
void
SetNonrandomWaitTimes(bool use_nonrandom);
protected:
virtual void
Fire(Adept::Entity::CollisionQuery *query,
Stuff::Time time_locked,
const Stuff::Point3D& lockedTargetEntityPartOffset)
{ }
virtual void QuickFire (Adept::Entity *target)
{ }
void SetCount(Stuff::Scalar count);
void GenerateAIWaitValue();
private:
Stuff::Scalar m_AI_WaitValue;
Stuff::Time m_AI_LastTimeReadyToFire;
Stuff::Scalar m_AI_LastCountValue;
bool m_AI_NonrandomWaitTimes;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Test Support
//
public:
void
TestInstance() const;
};
}