etqw-sdk/source/game/Weapon.h

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__ */