518 lines
16 KiB
C
518 lines
16 KiB
C
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
#ifndef __GAME_WEAPON_H__
|
||
|
#define __GAME_WEAPON_H__
|
||
|
|
||
|
#include "interfaces/NetworkInterface.h"
|
||
|
#include "client/ClientEntity.h"
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
Player Weapon
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
#include "AnimatedEntity.h"
|
||
|
|
||
|
typedef enum {
|
||
|
WP_READY,
|
||
|
WP_RELOAD,
|
||
|
WP_HOLSTERED,
|
||
|
WP_RISING,
|
||
|
WP_LOWERING
|
||
|
} weaponStatus_t;
|
||
|
|
||
|
class idWeapon;
|
||
|
|
||
|
class sdWeaponNetworkInterface : public sdNetworkInterface {
|
||
|
public:
|
||
|
sdWeaponNetworkInterface( void ) { owner = NULL; }
|
||
|
|
||
|
void Init( idWeapon* _owner ) { owner = _owner; }
|
||
|
|
||
|
virtual void HandleNetworkMessage( idPlayer* player, const char* message );
|
||
|
virtual void HandleNetworkEvent( const char* message );
|
||
|
|
||
|
protected:
|
||
|
idWeapon* owner;
|
||
|
};
|
||
|
|
||
|
class sdWeaponLockInfo {
|
||
|
public:
|
||
|
sdWeaponLockInfo( void ) { lockingSound = NULL; lockedSound = NULL; lockDistance = 0.f; supported = false; lockFriendly = false; sticky = false; }
|
||
|
|
||
|
void Load( const idDict& dict );
|
||
|
|
||
|
void SetSupported( bool value ) { supported = value; }
|
||
|
|
||
|
bool IsSupported( void ) const { return supported; }
|
||
|
bool IsSticky( void ) const { return sticky; }
|
||
|
float GetLockDistance( void ) const { return lockDistance; }
|
||
|
const idSoundShader* GetLockingSound( void ) const { return lockingSound; }
|
||
|
const idSoundShader* GetLockedSound( void ) const { return lockedSound; }
|
||
|
int GetLockDuration( void ) const { return lockDuration; }
|
||
|
bool LockFriendly( void ) const { return lockFriendly; }
|
||
|
|
||
|
const sdDeclTargetInfo* GetLockFilter( void ) const { return lockFilter; }
|
||
|
|
||
|
private:
|
||
|
const idSoundShader* lockingSound;
|
||
|
const idSoundShader* lockedSound;
|
||
|
float lockDistance;
|
||
|
int lockDuration;
|
||
|
bool supported;
|
||
|
bool lockFriendly;
|
||
|
bool sticky;
|
||
|
const sdDeclTargetInfo* lockFilter;
|
||
|
};
|
||
|
|
||
|
class idPlayer;
|
||
|
class idProjectile;
|
||
|
class idMoveableItem;
|
||
|
class sdPlayerStatEntry;
|
||
|
|
||
|
extern const idEventDef EV_Weapon_LaunchProjectiles;
|
||
|
|
||
|
typedef struct modInfo_s {
|
||
|
const idDeclEntityDef* projectileDef;
|
||
|
const char* clientProjectileScript;
|
||
|
ammoType_t ammoType;
|
||
|
int ammoRequired; // amount of ammo to use each shot. 0 means weapon doesn't need ammo.
|
||
|
int clipSize; // 0 means no reload
|
||
|
int lowAmmo; // if ammo in clip hits this threshold, snd_
|
||
|
} modInfo_t;
|
||
|
|
||
|
struct weaponSpreadValues_t {
|
||
|
float min;
|
||
|
float max;
|
||
|
float inc;
|
||
|
int numIgnoreRounds; // e.g., the assualt rifle's burst fire should all have the same cone
|
||
|
int maxSettleTime;
|
||
|
|
||
|
// movement dependant
|
||
|
float viewRateMin;
|
||
|
float viewRateMax;
|
||
|
float viewRateInc;
|
||
|
};
|
||
|
|
||
|
struct weaponAimValues_t {
|
||
|
float bobscaleyaw;
|
||
|
float bobscalepitch;
|
||
|
float lagscaleyaw;
|
||
|
float lagscalepitch;
|
||
|
float speedlr;
|
||
|
};
|
||
|
|
||
|
struct weaponFeedback_t {
|
||
|
int recoilTime;
|
||
|
idAngles recoilAngles;
|
||
|
float kickback;
|
||
|
float kickbackProne;
|
||
|
};
|
||
|
|
||
|
enum weaponSpreadValueIndex_t {
|
||
|
WSV_STANDING,
|
||
|
WSV_CROUCHING,
|
||
|
WSV_PRONE,
|
||
|
WSV_JUMPING,
|
||
|
WSV_NUM,
|
||
|
};
|
||
|
|
||
|
enum weaponAimValueIndex_t {
|
||
|
WAV_NORMAL,
|
||
|
WAV_IRONSIGHTS,
|
||
|
WAV_NUM,
|
||
|
};
|
||
|
|
||
|
class idWeapon : public idAnimatedEntity {
|
||
|
public:
|
||
|
CLASS_PROTOTYPE( idWeapon );
|
||
|
|
||
|
idWeapon();
|
||
|
virtual ~idWeapon();
|
||
|
|
||
|
// Init
|
||
|
void Spawn( void );
|
||
|
void SetOwner( idPlayer* _owner );
|
||
|
idPlayer* GetOwner( void ) { return owner; }
|
||
|
virtual bool ShouldConstructScriptObjectAtSpawn( void ) const;
|
||
|
|
||
|
virtual bool StartSynced( void ) const { return true; }
|
||
|
|
||
|
void UpdateVisibility( void );
|
||
|
|
||
|
virtual bool NoThink( void ) const { return true; }
|
||
|
|
||
|
bool OnActivate( idPlayer* player, float distance );
|
||
|
bool OnActivateHeld( idPlayer* player, float distance );
|
||
|
bool OnUsed( idPlayer* player, float distance );
|
||
|
bool OnWeapNext();
|
||
|
bool OnWeapPrev();
|
||
|
|
||
|
virtual sdTeamInfo* GetGameTeam( void ) const;
|
||
|
|
||
|
// Weapon definition management
|
||
|
void Clear( void );
|
||
|
void LinkScriptVariables( void );
|
||
|
void GetWeaponDef( const sdDeclInvItem* item );
|
||
|
bool IsLinked( void );
|
||
|
|
||
|
void MakeReady( void ) { Event_WeaponReady(); }
|
||
|
void OnProxyEnter( void );
|
||
|
void OnProxyExit( void );
|
||
|
|
||
|
void LogTimeUsed( void );
|
||
|
|
||
|
virtual void SetModel( const char *modelname );
|
||
|
bool GetGlobalJointTransform( bool viewModel, const jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis );
|
||
|
|
||
|
void UpdateShadows( void );
|
||
|
|
||
|
// State control/player interface
|
||
|
void Think( void );
|
||
|
void Raise( void );
|
||
|
void PutAway( void );
|
||
|
void Reload( void );
|
||
|
void LowerWeapon( void );
|
||
|
void RaiseWeapon( void );
|
||
|
void HideWorldModel( void );
|
||
|
void ShowWorldModel( void );
|
||
|
void OwnerDied( void );
|
||
|
void BeginAttack( void );
|
||
|
void EndAttack( void );
|
||
|
|
||
|
void UpdateSpreadValue( void );
|
||
|
void UpdateSpreadValue( const idVec3& velocity, const idAngles& angles, const idAngles& oldAngles );
|
||
|
|
||
|
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||
|
virtual bool ClientReceiveUnreliableEvent( int event, int time, const idBitMsg &msg );
|
||
|
|
||
|
void DoStanceTransition( weaponSpreadValueIndex_t oldStanceState );
|
||
|
|
||
|
void BeginModeSwitch( void );
|
||
|
void EndModeSwitch( void );
|
||
|
|
||
|
void BeginAltFire( void );
|
||
|
void EndAltFire( void );
|
||
|
|
||
|
bool IsReady( void ) const;
|
||
|
bool IsReloading( void ) const;
|
||
|
bool IsHolstered( void ) const;
|
||
|
void InstantSwitch( void );
|
||
|
bool CanAttack( void );
|
||
|
|
||
|
bool IsAttacking( void ) const;
|
||
|
|
||
|
const idVec3& GetViewOffset( void ) const { return viewOffset; }
|
||
|
|
||
|
float GetLargeFOVScale( void ) const { return largeFOVScale; }
|
||
|
|
||
|
float GetSpreadValue() const;
|
||
|
float GetSpreadValueNormalized( bool useGlobalMax = true ) const;
|
||
|
float GetCrosshairSpreadMin() const { return crosshairSpreadMin; }
|
||
|
float GetCrosshairSpreadMax() const { return crosshairSpreadMax; }
|
||
|
float GetCrosshairSpreadScale() const { return crosshairSpreadScale; }
|
||
|
|
||
|
int GetGrenadeFuseTime( void );
|
||
|
|
||
|
void SetOwnerStanceState( weaponSpreadValueIndex_t state );
|
||
|
|
||
|
// Script state management
|
||
|
virtual sdProgramThread* ConstructScriptObject( void );
|
||
|
virtual void DeconstructScriptObject( void );
|
||
|
void SetState( const char *statename, int blendFrames );
|
||
|
void UpdateScript( void );
|
||
|
|
||
|
// Visual presentation
|
||
|
virtual void Present( void );
|
||
|
virtual void FreeModelDef( void );
|
||
|
void PresentWeapon( void );
|
||
|
void SwayAngles( idAngles& angles ) const;
|
||
|
|
||
|
// Ammo
|
||
|
static ammoType_t GetAmmoType( const char *ammoname );
|
||
|
ammoType_t GetAmmoType( int modIndex ) const;
|
||
|
int ShotsAvailable( int modIndex ) const;
|
||
|
int GetClipSize( int modIndex ) const;
|
||
|
int LowAmmo( int modIndex ) const;
|
||
|
int AmmoRequired( int modIndex ) const;
|
||
|
bool IsClipBased() const;
|
||
|
bool UsesStroyent() const;
|
||
|
|
||
|
void UpdatePlayerWeaponInfo(); //mal: update what this player's current weapon is for the bots.
|
||
|
const playerWeaponTypes_t& GetPlayerWeaponNum( void ) const { return playerWeaponNum; }
|
||
|
bool IsIronSightsEnabled( void );
|
||
|
|
||
|
const weaponAimValues_t& GetAimValues( weaponAimValueIndex_t index ) { return aimValues[ index ]; }
|
||
|
|
||
|
virtual sdNetworkInterface* GetNetworkInterface( void ) { return &networkInterface; }
|
||
|
|
||
|
const sdWeaponLockInfo* GetLockInfo( void ) const { return &lockInfo; }
|
||
|
|
||
|
void ClampAngles( idAngles& angles, const idAngles& oldAngles ) const;
|
||
|
|
||
|
float GetDriftScale( void ) const { return driftScale; }
|
||
|
|
||
|
bool GetFov( float& fov ) const;
|
||
|
|
||
|
static void RegisterCVarCallback( void );
|
||
|
static void UnRegisterCVarCallback( void );
|
||
|
static void UpdateWeaponVisibility( void );
|
||
|
|
||
|
const sdDeclInvItem* GetInvItemDecl( void ) const { return weaponItem; }
|
||
|
|
||
|
void SetNumWorldModels( int count );
|
||
|
|
||
|
// allow scripts to cleanup their state before we do something like lower from code (e.g. allow the script to exit iron-sights)
|
||
|
void ScriptCleanup( void );
|
||
|
|
||
|
bool ActivateAttack( void ) const { return activateAttack; }
|
||
|
|
||
|
private:
|
||
|
void SetupAnimClass( const char* prefix );
|
||
|
|
||
|
// script control
|
||
|
idScriptBool WEAPON_ATTACK;
|
||
|
idScriptBool WEAPON_ALTFIRE;
|
||
|
idScriptBool WEAPON_MODESWITCH;
|
||
|
idScriptBool WEAPON_RELOAD;
|
||
|
idScriptBool WEAPON_RAISEWEAPON;
|
||
|
idScriptBool WEAPON_LOWERWEAPON;
|
||
|
idScriptBool WEAPON_HIDE;
|
||
|
|
||
|
weaponStatus_t status;
|
||
|
|
||
|
sdProgramThread* thread;
|
||
|
|
||
|
idStr state;
|
||
|
idStr idealState;
|
||
|
|
||
|
int animBlendFrames;
|
||
|
int animDoneTime;
|
||
|
bool isLinked;
|
||
|
bool modelDisabled;
|
||
|
bool worldModelDisabled;
|
||
|
bool activateAttack;
|
||
|
|
||
|
sdWeaponLockInfo lockInfo;
|
||
|
|
||
|
struct stats_t {
|
||
|
sdPlayerStatEntry* shotsFired;
|
||
|
sdPlayerStatEntry* timeUsed;
|
||
|
};
|
||
|
stats_t stats;
|
||
|
|
||
|
const sdProgram::sdFunction* onActivateFunc;
|
||
|
const sdProgram::sdFunction* onActivateFuncHeld;
|
||
|
const sdProgram::sdFunction* onUsedFunc;
|
||
|
const sdProgram::sdFunction* onWeapNextFunc;
|
||
|
const sdProgram::sdFunction* onWeapPrevFunc;
|
||
|
const sdProgram::sdFunction* cleanupFunc;
|
||
|
const sdProgram::sdFunction* getGrenadeFuseStartFunc;
|
||
|
const sdProgram::sdFunction* ironSightsEnabledFunc;
|
||
|
|
||
|
playerWeaponTypes_t playerWeaponNum;
|
||
|
|
||
|
// precreated projectile
|
||
|
idEntity *projectileEnt;
|
||
|
|
||
|
idPlayer* owner;
|
||
|
|
||
|
idList< rvClientEntityPtr< sdClientAnimated > > worldModels;
|
||
|
idList< jointHandle_t > barrelJointsWorld;
|
||
|
|
||
|
// hiding (for GUIs and NPCs)
|
||
|
int hideTime;
|
||
|
float hideDistance;
|
||
|
int hideStartTime;
|
||
|
float hideStart;
|
||
|
float hideEnd;
|
||
|
float hideOffset;
|
||
|
bool hide;
|
||
|
bool disabled;
|
||
|
|
||
|
float largeFOVScale;
|
||
|
|
||
|
// some weapons aren't clip-based (e.g. grenades) and this affects the GUI
|
||
|
bool clipBased;
|
||
|
|
||
|
// some strogg weapons' ammo is not based on stroyent
|
||
|
bool usesStroyent;
|
||
|
|
||
|
// these are the player render view parms, which include bobbing
|
||
|
idVec3 playerViewOrigin;
|
||
|
idMat3 playerViewAxis;
|
||
|
|
||
|
// the view weapon render entity parms
|
||
|
idVec3 viewWeaponOrigin;
|
||
|
idMat3 viewWeaponAxis;
|
||
|
|
||
|
idVec3 viewOffset;
|
||
|
|
||
|
float viewForeShorten;
|
||
|
idMat3 viewForeShortenAxis;
|
||
|
|
||
|
idInterpolate< float > zoomFov;
|
||
|
|
||
|
weaponSpreadValueIndex_t ownerStanceState;
|
||
|
|
||
|
weaponSpreadValues_t spreadValues[ WSV_NUM ];
|
||
|
weaponAimValues_t aimValues[ WAV_NUM ];
|
||
|
float spreadValueMax; // used to normalize against
|
||
|
bool spreadEvalVelocity;
|
||
|
bool spreadEvalView;
|
||
|
|
||
|
float spreadCurrentValue;
|
||
|
float spreadModifier;
|
||
|
|
||
|
float crosshairSpreadMin;
|
||
|
float crosshairSpreadMax;
|
||
|
float crosshairSpreadScale;
|
||
|
|
||
|
float driftScale;
|
||
|
|
||
|
float zoomPitchAmplitude;
|
||
|
float zoomPitchFrequency;
|
||
|
float zoomPitchMinAmplitude;
|
||
|
float zoomYawAmplitude;
|
||
|
float zoomYawFrequency;
|
||
|
float zoomYawMinAmplitude;
|
||
|
bool swayEnabled;
|
||
|
|
||
|
// weapon definition
|
||
|
const sdDeclInvItem* weaponItem;
|
||
|
|
||
|
const sdDeclDamage* meleeDamage;
|
||
|
const sdDeclDamage* meleeSpecialDamage;
|
||
|
|
||
|
// weapon kick
|
||
|
int kick_endtime;
|
||
|
int muzzle_kick_time;
|
||
|
int muzzle_kick_maxtime;
|
||
|
idAngles muzzle_kick_angles;
|
||
|
idVec3 muzzle_kick_offset;
|
||
|
|
||
|
// zoom
|
||
|
|
||
|
// joints from models
|
||
|
jointHandle_t barrelJointView;
|
||
|
|
||
|
trace_t meleeTrace; // FIXME: static?
|
||
|
|
||
|
sdWeaponNetworkInterface networkInterface;
|
||
|
|
||
|
angleClamp_t clampPitch;
|
||
|
angleClamp_t clampYaw;
|
||
|
bool clampEnabled;
|
||
|
idAngles clampBaseAngles;
|
||
|
|
||
|
int tracerCounter;
|
||
|
|
||
|
int timeStartedUsing;
|
||
|
|
||
|
rvClientEntityPtr< rvClientEffect > lastTracer;
|
||
|
|
||
|
renderEntity_t dofRenderEntity;
|
||
|
int dofModelDefHandle;
|
||
|
const idDeclSkin* dofSkin;
|
||
|
|
||
|
const idDeclSkin* climateSkin;
|
||
|
|
||
|
weaponFeedback_t feedback;
|
||
|
|
||
|
// Visual presentation
|
||
|
void InitWorldModel( int index );
|
||
|
void MuzzleRise( idVec3 &origin, idMat3 &axis );
|
||
|
|
||
|
void SetupStats( const char* statName );
|
||
|
|
||
|
virtual void SetSkin( const idDeclSkin* skin );
|
||
|
|
||
|
// script events
|
||
|
void Event_Clear( void );
|
||
|
void Event_GetOwner( void );
|
||
|
void Event_GetWeaponState( void );
|
||
|
void Event_WeaponState( const char *statename, int blendFrames );
|
||
|
void Event_SetWeaponStatus( float newStatus );
|
||
|
void Event_WeaponReady( void );
|
||
|
void Event_WeaponReloading( void );
|
||
|
void Event_WeaponHolstered( void );
|
||
|
void Event_WeaponRising( void );
|
||
|
void Event_WeaponLowering( void );
|
||
|
void Event_AddToClip( int modIndex, int amount );
|
||
|
void Event_AmmoInClip( int modIndex );
|
||
|
void Event_NeedsAmmo( int modIndex );
|
||
|
void Event_AmmoAvailable( int modIndex );
|
||
|
void Event_AmmoRequired( int modIndex );
|
||
|
void Event_AmmoType( int modIndex );
|
||
|
void Event_UseAmmo( ammoType_t type, int amount );
|
||
|
void Event_ClipSize( int modIndex );
|
||
|
void Event_PlayAnim( animChannel_t channel, const char *animname );
|
||
|
void Event_PlayCycle( animChannel_t channel, const char *animname );
|
||
|
void Event_AnimDone( animChannel_t channel, int blendFrames );
|
||
|
void Event_SetBlendFrames( animChannel_t channel, int blendFrames );
|
||
|
void Event_GetBlendFrames( animChannel_t channel );
|
||
|
void Event_Next( void );
|
||
|
void Event_LaunchProjectiles( int numProjectiles, int projectileIndex, float spread, float fuseOffset, float launchPower, float dmgPower );
|
||
|
void Event_DoProjectileTracer( int projectileIndex, const idVec3& start, const idVec3& end );
|
||
|
void Event_CreateProjectile( int projectileIndex );
|
||
|
void Event_Melee( int contentMask, float distance, bool ignoreOwner, bool useAntiLag );
|
||
|
void Event_MeleeAttack( float damageScale );
|
||
|
void Event_SaveMeleeTrace( void );
|
||
|
void Event_GetMeleeFraction( void );
|
||
|
void Event_GetMeleeEndPos( void );
|
||
|
void Event_GetMeleePoint( void );
|
||
|
void Event_GetMeleeNormal( void );
|
||
|
void Event_GetMeleeEntity( void );
|
||
|
void Event_GetMeleeSurfaceFlags( void );
|
||
|
void Event_GetMeleeSurfaceType( void );
|
||
|
void Event_GetMeleeSurfaceColor( void );
|
||
|
void Event_GetMeleeJoint( void );
|
||
|
void Event_GetMeleeBody( void );
|
||
|
|
||
|
void Event_AutoReload( void );
|
||
|
void Event_NetReload( void );
|
||
|
void Event_NetEndReload( void );
|
||
|
void Event_EnableTargetLock( bool enable );
|
||
|
void Event_SetFov( float startFov, float endFov, float duration );
|
||
|
void Event_SetFovStart( float startFov, float endFov, float startTime, float duration );
|
||
|
void Event_ClearFov( void );
|
||
|
void Event_GetFov( void );
|
||
|
void Event_EnableClamp( const idAngles& baseAngles );
|
||
|
void Event_DisableClamp( void );
|
||
|
void Event_GetSpreadValue( void );
|
||
|
void Event_IncreaseSpreadValue( void );
|
||
|
void Event_SetSpreadModifier( float modifier );
|
||
|
void Event_Hide( void );
|
||
|
void Event_Show( void );
|
||
|
// weapons that don't do melee or projectile attacks still need to indicate they've been fired to their owner
|
||
|
void Event_Fired( void );
|
||
|
void Event_GetWorldModel( int index );
|
||
|
void Event_EnableSway( bool enable );
|
||
|
void Event_SetDriftScale( float scale );
|
||
|
void Event_ResetTracerCounter( void );
|
||
|
void Event_GetLastTracer( void );
|
||
|
void Event_SetupAnimClass( const char* prefix );
|
||
|
void Event_HasWeaponAnim( const char* anim );
|
||
|
void Event_SetStatName( const char* statName );
|
||
|
|
||
|
void Event_SendTracerMessage( const idVec3& start, const idVec3& end, float strength );
|
||
|
|
||
|
enum {
|
||
|
EVENT_RELOAD = idEntity::EVENT_MAXEVENTS,
|
||
|
EVENT_TRACER, // unreliable event
|
||
|
EVENT_MAXEVENTS
|
||
|
};
|
||
|
};
|
||
|
|
||
|
ID_INLINE bool idWeapon::IsLinked( void ) {
|
||
|
return isLinked;
|
||
|
}
|
||
|
|
||
|
#endif /* !__GAME_WEAPON_H__ */
|
||
|
|
||
|
|