Paranoia2/dlls/weapons.h

709 lines
29 KiB
C
Raw Normal View History

2020-08-31 18:50:41 +02:00
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef WEAPONS_H
#define WEAPONS_H
#include <bullets.h>
#include "effects.h"
#include "player.h"
class CBasePlayer;
class CBasePlayerItem;
extern int gmsgWeapPickup;
// Contact Grenade / Timed grenade
class CGrenade : public CBaseMonster
{
public:
void Spawn( void );
static CGrenade *ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time, float damage = 100.0f );
static CGrenade *ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity );
static CGrenade *ShootGeneric( CBaseEntity *pOwner, Vector vecStart, Vector vecVelocity, string_t classname );
void Explode( Vector vecSrc, Vector vecAim );
void Explode( TraceResult *pTrace, int bitsDamageType );
void EXPORT Smoke( void );
void EXPORT BounceTouch( CBaseEntity *pOther );
void EXPORT SlideTouch( CBaseEntity *pOther );
void EXPORT ExplodeTouch( CBaseEntity *pOther );
void EXPORT DangerSoundThink( void );
void EXPORT PreDetonate( void );
void EXPORT Detonate( void );
void EXPORT DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT TumbleThink( void );
virtual void BounceSound( void );
virtual int BloodColor( void ) { return DONT_BLEED; }
virtual void Killed( entvars_t *pevAttacker, int iGib );
BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet.
};
class CRpgRocket : public CGrenade
{
public:
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
void Spawn( void );
void Precache( void );
void EXPORT FollowThink( void );
void EXPORT IgniteThink( void );
void EXPORT RocketTouch( CBaseEntity *pOther );
static CRpgRocket *CreateRpgRocket( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CBasePlayerItem *pLauncher );
int m_iFireTrail; // Wargon: переменная для огненного следа у ракет.
2020-08-31 18:50:41 +02:00
int m_iTrail;
float m_flIgniteTime;
CBasePlayerItem *m_pLauncher;// pointer back to the launcher that fired me.
};
class CLaserSpot : public CBaseEntity
{
void Spawn( void );
void Precache( void );
int ObjectCaps( void ) { return FCAP_DONT_SAVE; }
public:
void Update( CBasePlayer *m_pPlayer );
void Suspend( float flSuspendTime );
void EXPORT Revive( void );
static CLaserSpot *CreateSpot( void );
static CLaserSpot *CreateSpot( const char* spritename );
};
// hardcoded ID's
#define WEAPON_NONE 0
#define WEAPON_PAINKILLER 31
#define WEAPON_CUSTOM_COUNT WEAPON_PAINKILLER
#define WEAPON_ALLWEAPONS (~BIT( WEAPON_PAINKILLER ))
#define MAX_WEAPONS 32 // a 32-bit integer limit
#define MAX_AMMO_DESC 256 // various combinations of entities that contain ammo
#define MAX_SHOOTSOUNDS 8 // max of four random shoot sounds
#define MAX_NORMAL_BATTERY 100
// suit definitions
#define BAREHAND_SUIT 0 // just in case
#define MILITARY_SUIT 1 // gordon suit
#define NUM_HANDS 2 // number of hands: barney and gordon
#define PLAYER_HAS_SUIT ( FBitSet( m_pPlayer->m_iHideHUD, ITEM_SUIT ))
#define PLAYER_DRAW_SUIT ( FBitSet( pev->body, MILITARY_SUIT ))
// the maximum amount of ammo each weapon's clip can hold
#define WEAPON_NOCLIP -1
// reload code
#define NOT_IN_RELOAD 0
#define START_RELOAD 1
#define CONTINUE_RELOAD 2 // for shotgun
#define EMPTY_RELOAD 3
#define NORMAL_RELOAD 4
// zoom code
#define NOT_IN_ZOOM 0 // zoom not used
#define NORMAL_ZOOM 1 // default zooming (button one shot)
#define UPDATE_ZOOM 2 // increase zoom (button holding down)
#define RESET_ZOOM 3 // disable zoom
#define ZOOM_MAXIMUM 20
#define ZOOM_DEFAULT 50
// ammo code
#define AMMO_UNKNOWN 0
#define AMMO_PRIMARY 1
#define AMMO_SECONDARY 2
#define ITEM_FLAG_SELECTONEMPTY BIT( 0 ) // can select while ammo is out
#define ITEM_FLAG_NOAUTORELOAD BIT( 1 ) // manual reload only
#define ITEM_FLAG_NOAUTOSWITCHEMPTY BIT( 2 ) // don't switch to another gun while ammo is out
#define ITEM_FLAG_LIMITINWORLD BIT( 3 ) // limit count in world (e.g. explodables)
#define ITEM_FLAG_EXHAUSTIBLE BIT( 4 ) // A player can totally exhaust their ammo supply and lose this weapon
#define ITEM_FLAG_NODUPLICATE BIT( 5 ) // player can't give this weapon again (e.g. knife, crowbar)
#define ITEM_FLAG_USEAUTOAIM BIT( 6 ) // weapon uses autoaim
#define ITEM_FLAG_ALLOW_FIREMODE BIT( 7 ) // allow to change firemode
#define ITEM_FLAG_SHOOT_UNDERWATER BIT( 8 ) // weapon can be shoot underwater (e.g. glock)
#define ITEM_FLAG_IRONSIGHT BIT( 9 ) // enable client effects: DOF, breathing etc
#define ITEM_FLAG_AUTOFIRE BIT( 10 ) // hold attack for auto-fire
#define ITEM_FLAG_SCOPE BIT( 11 ) // using scope instead of IronSight
#define ITEM_FLAG_NODROP BIT( 12 ) // don't drop this weapon
#define WEAPON_IS_ONTARGET 0x40
typedef enum
{
ATTACK_NONE = 0, // no action
ATTACK_AMMO1, // fire primary ammo
ATTACK_AMMO2, // fire secondary ammo
ATTACK_LASER_DOT, // enable laser dot
ATTACK_ZOOM, // enable zoom
ATTACK_FLASHLIGHT, // enable flashlight
ATTACK_SWITCHMODE, // play two beetwen anims and change body
ATTACK_SWING, // knife swing
ATTACK_IRONSIGHT, // iron sight on and off
ATTACK_SCOPE // iron sight & scope
} e_attack;
enum
{
SPREAD_LINEAR = 0, // изменение разброса линейно во времени
SPREAD_QUAD, // по параболе (вначале узкий, потом резко расширяется)
SPREAD_CUBE, // кубическая парабола
SPREAD_SQRT, // наоборот (быстро расширяется и плавно переходит в максимальный)
2020-08-31 18:50:41 +02:00
};
typedef struct
{
RandomRange range; // min spread .. max spread
int type; // spread equalize
float expand; // spread expand
} spread_t;
typedef struct
{
float maxSpeed; // clamp at maximum
float jumpHeight; // clamp at maximum
} player_settings_t;
// client feedback
typedef struct
{
RandomRange punchangle[3]; // range of x,y,z
RandomRange recoil;
} feedback_t;
typedef struct
{
int iSlot; // hud slot
int iPosition; // hud position
string_t iViewModel; // path to viewmodel
string_t iHandModel; // path to optional hands model
string_t iWorldModel; // path to worldmodel
char szAnimExt[16]; // player anim postfix
const char *pszAmmo1; // ammo 1 type
int iMaxAmmo1; // max ammo 1
const char *pszAmmo2; // ammo 2 type
int iMaxAmmo2; // max ammo 2
RandomRange iDefaultAmmo1; // default primary ammo
RandomRange iDefaultAmmo2; // default secondary ammo
const char *pszName; // unique weapon name
int iMaxClip; // clip size
int iId; // unique weapon ID
int iFlags; // misc flags
int iWeight; // this value used to determine this weapon's importance in autoselection.
int attack1; // attack1 type
int attack2; // attack2 type
float fNextAttack1; // nextattack
float fNextAttack2; // next secondary attack
Vector vecThrowOffset; // throw view offset for melee grenades
string_t shootsound1[MAX_SHOOTSOUNDS]; // primary attack sounds
string_t shootsound2[MAX_SHOOTSOUNDS]; // secondary attack sounds
string_t emptysounds[MAX_SHOOTSOUNDS]; // empty sound
int sndcount1; // primary attack sound count
int sndcount2; // secondary attack sound count
int emptysndcount; // empty sounds count
string_t smashDecals[2]; // decal groups for swing weapon (crowbar, knife)
spread_t spread1[2]; // customizable spread from Paranoia
spread_t spread2[2]; // same but for secondary attack
feedback_t feedback1[2]; // client feedback for primary attack (recoil, punch, speed etc)
feedback_t feedback2[2]; // same but for secondary attack
player_settings_t plr_settings[2]; // player speed and player jumpheight
float spreadtime; // time to return to normal spread
int iVolume; // weapon volume
int iFlash; // weapon flash
RandomRange recoil1; // recoil 1 attack
RandomRange recoil2; // recoil 2 attack
} ItemInfo;
typedef struct
{
const char *pszName;
int iMaxCarry;
int iShellIndex; // precached shell model index
int iNumShots; // > 1 is fraction
string_t iMissileClassName; // it's a projectile ammo (grenades etc)
float flDistance; // typically 2048 for fractions
float flPlayerDamage;
float flMonsterDamage;
int iId;
} AmmoInfo;
// ammo_entity description
typedef struct
{
string_t classname; // to link with real entity
string_t ammomodel; // model to show
string_t clipsound; // sound when touch entity
AmmoInfo *type; // pointer to ammo specification
RandomRange count;
} AmmoDesc;
// Items that the player has in their inventory that they can use
class CBasePlayerItem : public CBaseAnimating
{
public:
// buz: get advance spread vec to send it to client
// gun dont use advanced spread by default
virtual Vector GetSpreadVec( void );
// buz: gun jumping actions
virtual void PlayerJump( void );
virtual void PlayerWalk( void );
virtual void PlayerRun( void );
// buz: get current weapon mode (for toggleable weapons)
virtual int GetMode( void )
{
if( FBitSet( iFlags(), ITEM_FLAG_SCOPE|ITEM_FLAG_IRONSIGHT ) && !m_fInReload )
{
if( FBitSet( iFlags(), ITEM_FLAG_SCOPE ))
return (m_iIronSight) ? 3 : 1;
return (m_iIronSight + 1);
}
return 0; // 0 means gun dont use mode
}
virtual void WeaponToggleMode( void );
virtual void SetObjectCollisionBox( void );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
virtual int AddToPlayer( CBasePlayer *pPlayer ); // return TRUE if the item you want the item added to the player inventory
virtual int AddDuplicate( CBasePlayerItem *pItem ); // return TRUE if you want your duplicate removed from world
void EXPORT DestroyItem( void );
void EXPORT DefaultTouch( CBaseEntity *pOther ); // default weapon touch
void EXPORT KnifeDecal1( void );
void EXPORT KnifeDecal2( void );
void Precache( void );
void Spawn( void );
// Wargon: Переменные для юзабельности оружий.
2020-08-31 18:50:41 +02:00
void EXPORT DefaultUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { DefaultTouch( pActivator ); }
virtual int ObjectCaps( void ) { return m_iItemCaps | FCAP_ACROSS_TRANSITION | FCAP_USE_ONLY; }
// generic "shared" ammo handlers
BOOL AddPrimaryAmmo( int iCount, const char *szName, int iMaxClip, int iMaxCarry, BOOL duplicate );
BOOL AddSecondaryAmmo( int iCount, const char *szName, int iMaxCarry );
void EXPORT FallThink ( void );// when an item is first spawned, this think is run to determine when the object has hit the ground.
void EXPORT Materialize( void );// make a weapon visible and tangible
void EXPORT AttemptToMaterialize( void ); // the weapon desires to become visible and tangible, if the game rules allow for it
CBaseEntity* Respawn ( void );// copy a weapon
void FallInit( void );
void CheckRespawn( void );
virtual int GetItemInfo( ItemInfo *p );
virtual BOOL CanDeploy( void );
virtual BOOL CanHolster( void ); // can this weapon be put away right now?
virtual BOOL IsUseable( void );
virtual BOOL HasAmmo( void );
virtual BOOL WaitForHolster( void ) { return m_fWaitForHolster; }
virtual BOOL AllowToDrop( void ) { return !FBitSet( iFlags(), ITEM_FLAG_NODROP ); }
virtual void ItemPreFrame( void ) { return; } // called each frame by the player PreThink
virtual void ItemPostFrame( void ); // called each frame by the player PostThink
virtual int ExtractAmmo( CBasePlayerItem *pWeapon, BOOL duplicate ); // Return TRUE if you can add ammo to yourself when picked up
virtual int ExtractClipAmmo( CBasePlayerItem *pWeapon ); // Return TRUE if you can add ammo to yourself when picked up
virtual int AddWeapon( void ) { ExtractAmmo( this, FALSE ); return TRUE; }; // Return TRUE if you want to add yourself to the player
virtual void PlayClientFire( const Vector &vecDir, float spread, int iAnim, int shellidx, string_t shootsnd, int cShots = 1 );
virtual void SendWeaponAnim( int iAnim, float framerate = 1.0f );
virtual void Drop( void );
virtual void Kill( void );
virtual void AttachToPlayer ( CBasePlayer *pPlayer );
virtual int PrimaryAmmoIndex( void );
virtual int SecondaryAmmoIndex( void );
virtual int UpdateClientData( CBasePlayer *pPlayer );
virtual void UpdateItemInfo( void ) {}; // updates HUD state
Vector GetConeVectorForDegree( int degree );
Vector CalcSpreadVec( const spread_t *info, float &spread );
void DoEqualizeSpread( int type, float &spread );
float ExpandSpread( float expandPower );
float CalcSpread( void );
void SetDefaultParams( ItemInfo *II );
int ParseWeaponFile( ItemInfo *II, const char *filename ); // parse weapon_*.txt
int ParseWeaponData( ItemInfo *II, char *file ); // parse WeaponData {}
int ParsePrimaryAttack( ItemInfo *II, char *pfile ); // parse PrimaryAttack {}
int ParseSecondaryAttack( ItemInfo *II, char *pfile ); // parse SeconadryAttack {}
int ParseSoundData( ItemInfo *II, char *pfile ); // parse SoundData {}
char *ParseViewPunch( char *pfile, feedback_t *pFeed );
int ParseItemFlags( char *pfile );
// HudData will be parsed on the client side
virtual void GenerateID( void ); // generate unique ID number for each weapon
virtual bool FindWeaponID( void );
int GetAnimation( Activity activity );
int SetAnimation( Activity activity, float fps = 1.0f );
int SetAnimation( char *name, float fps = 1.0f );
Activity GetIronSightActivity( Activity act );
int UseAmmo( const char *ammo, int count );
int GetAmmoType( const char *ammo ); // incredible stupid way...
inline int IsEmptyReload( void ) { return m_iStepReload == EMPTY_RELOAD ? TRUE : FALSE; }
int ShootGeneric( const char *ammo, int primary, int cShots = 1 );
int ThrowGeneric( const char *ammo, int primary, int cShots = 1 );
int GetCurrentAttack( const char *ammo, int primary );
int PlayCurrentAttack( int action, int primary );
void PlayAttackSound( int primary );
void ApplyPlayerSettings( bool bReset );
void SetPlayerEffects( void );
float AutoAimDelta( int primary );
float SetNextAttack( float delay ) { return m_pPlayer->m_flNextAttack = gpGlobals->time + delay; }
float SetNextIdle( float delay ) { return m_flTimeWeaponIdle = gpGlobals->time + delay; }
float SequenceDuration( void ) { return CBaseAnimating :: SequenceDuration( m_pPlayer->pev->weaponanim ); }
static ItemInfo ItemInfoArray[MAX_WEAPONS];
static int m_iGlobalID; // unique ID for each weapon
// weapon routines
void ZoomUpdate( void );
void ZoomReset( void );
CBasePlayer *m_pPlayer;
CBasePlayerItem *m_pNext;
CLaserSpot *m_pSpot; // LTD spot (don't save this, becase spot have FCAP_DONT_SAVE flag)
int m_iId; // WEAPON_???
int m_iItemCaps;
TraceResult m_trHit; // for knife
BOOL m_fWaitForHolster; // weapon waiting for holster
string_t m_iHandModel; // in case it present
// virtual methods for ItemInfo acess
int iItemPosition( void ) { return ItemInfoArray[m_iId].iPosition; }
int iItemSlot( void ) { return ItemInfoArray[m_iId].iSlot + 1; }
int iViewModel( void ) { return ItemInfoArray[m_iId].iViewModel; }
int iHandModel( void ) { return ItemInfoArray[m_iId].iHandModel; }
int iWorldModel( void ) { return ItemInfoArray[m_iId].iWorldModel; }
int iDefaultAmmo1( void ) { return (int)ItemInfoArray[m_iId].iDefaultAmmo1.Random(); }
int iDefaultAmmo2( void ) { return (int)ItemInfoArray[m_iId].iDefaultAmmo2.Random(); }
int iMaxAmmo1( void ) { return ItemInfoArray[m_iId].iMaxAmmo1; }
int iMaxAmmo2( void ) { return ItemInfoArray[m_iId].iMaxAmmo2; }
int iMaxClip( void ) { return ItemInfoArray[m_iId].iMaxClip; }
int iWeight( void ) { return ItemInfoArray[m_iId].iWeight; }
int iFlags( void ) { return ItemInfoArray[m_iId].iFlags; }
int iAttack1( void ) { return ItemInfoArray[m_iId].attack1; }
int sndcnt1( void ) { return ItemInfoArray[m_iId].sndcount1; }
int sndcnt2( void ) { return ItemInfoArray[m_iId].sndcount2; }
int emptycnt( void ) { return ItemInfoArray[m_iId].emptysndcount; }
string_t ShootSnd1( void ) { return ItemInfoArray[m_iId].shootsound1[RANDOM_LONG( 0, sndcnt1( ) - 1)]; }
string_t ShootSnd2( void ) { return ItemInfoArray[m_iId].shootsound2[RANDOM_LONG( 0, sndcnt2( ) - 1)]; }
string_t EmptySnd( void ) { return ItemInfoArray[m_iId].emptysounds[RANDOM_LONG( 0, emptycnt() - 1)]; }
int iAttack2( void ) { return ItemInfoArray[m_iId].attack2; }
char *szAnimExt( void ) { return ItemInfoArray[m_iId].szAnimExt; }
float fNextAttack1( void ) { return ItemInfoArray[m_iId].fNextAttack1; }
float fNextAttack2( void ) { return ItemInfoArray[m_iId].fNextAttack2; }
float fRecoil1( void ) { return ItemInfoArray[m_iId].recoil1.Random(); }
float fRecoil2( void ) { return ItemInfoArray[m_iId].recoil2.Random(); }
const char *pszAmmo1( void ) { return ItemInfoArray[m_iId].pszAmmo1; }
const char *pszName( void ) { return ItemInfoArray[m_iId].pszName; }
const char *pszAmmo2( void ) { return ItemInfoArray[m_iId].pszAmmo2; }
const spread_t *pSpread1( void ) { return &ItemInfoArray[m_iId].spread1[m_iIronSight]; }
const spread_t *pSpread2( void ) { return &ItemInfoArray[m_iId].spread2[m_iIronSight]; }
const feedback_t *pFeedback1( void ) { return &ItemInfoArray[m_iId].feedback1[m_iIronSight]; }
const feedback_t *pFeedback2( void ) { return &ItemInfoArray[m_iId].feedback2[m_iIronSight]; }
const char *pszDecalName( int type ) { return STRING( ItemInfoArray[m_iId].smashDecals[type] ); }
float ClientMaxSpeed( void ) { return ItemInfoArray[m_iId].plr_settings[m_iIronSight].maxSpeed; }
float ClientJumpHeight( void ) { return ItemInfoArray[m_iId].plr_settings[m_iIronSight].jumpHeight; }
Vector vecThrowOffset( void ) { return ItemInfoArray[m_iId].vecThrowOffset; }
float fSpreadTime( void ) { return ItemInfoArray[m_iId].spreadtime; }
int iVolume( void ) { return ItemInfoArray[m_iId].iVolume; }
int iFlash( void ) { return ItemInfoArray[m_iId].iFlash; }
int m_iWeaponAutoFire; // 0 - semi-auto, 1 - full auto
int m_iDefaultAmmo1; // how much ammo you get when you pick up this weapon as placed by a level designer.
int m_iDefaultAmmo2; // how much ammo you get when you pick up this weapon as placed by a level designer.
float m_flNextPrimaryAttack; // soonest time ItemPostFrame will call PrimaryAttack
float m_flNextSecondaryAttack; // soonest time ItemPostFrame will call SecondaryAttack
float m_flTimeWeaponIdle; // soonest time ItemPostFrame will call WeaponIdle
int m_iPrimaryAmmoType; // "primary" ammo index into players m_rgAmmo[]
int m_iSecondaryAmmoType; // "secondary" ammo index into players m_rgAmmo[]
int m_fFireOnEmpty; // True when the gun is empty and the player is still holding down the attack key(s)
float m_flTimeUpdate; // special time for additional effects
int m_iStepReload; // reload state (e.g. for shotgun)
int m_iIronSight; // iron sight is enabled
float m_flSpreadTime; // time to return from full spread
float m_flLastShotTime; // time from last shot
float m_flLastSpreadPower; // [0..1] range value
int m_cActiveRockets; // stuff for rpg with LTD
int m_iClip; // number of shots left in the primary weapon clip, -1 it not used
int m_iSpot; // enable laser dot
int m_iZoom; // zoom current level
int m_iBody; // viewmodel body
int m_iSkin; // viewmodel skin
int m_fInReload; // Are we in the middle of a reload;
int m_iPlayEmptySound; // trigger to playing empty sound once
int m_iClientAnim; // used to resend anim on save\restore
int m_iClientClip; // the last version of m_iClip sent to hud dll
int m_iClientWeaponState; // the last version of the weapon state sent to hud dll (is current weapon, is on target)
int m_iClientSkin; // the last version of m_iSkin sent to hud dll
int m_iClientBody; // the last version of m_iBody sent to hud dll
float m_flHoldTime; // button holdtime
// this methods can be overloaded
virtual void RetireWeapon( void );
virtual BOOL ShouldWeaponIdle( void ) { return FALSE; };
virtual BOOL PlayEmptySound( void );
virtual void ResetEmptySound( void );
// default methods
BOOL DefaultDeploy( Activity sequence );
BOOL DefaultHolster( Activity sequence, bool force = false );
BOOL DefaultReload( Activity sequence );
BOOL DefaultSwing( int primary );
void DefaultIdle( void );
virtual void PrimaryAttack( void ) // do "+ATTACK"
{
if( !m_iWeaponAutoFire && !FBitSet( m_pPlayer->m_afButtonPressed, IN_ATTACK ))
return; // no effect for hold button
int iResult = PlayCurrentAttack( iAttack1(), true );
if( iResult == 1 )
{
const feedback_t *pFB = pFeedback1();
m_pPlayer->ViewPunch( pFB->punchangle[0].Random(), pFB->punchangle[1].Random(), pFB->punchangle[2].Random() );
m_pPlayer->pev->velocity = m_pPlayer->pev->velocity - gpGlobals->v_forward * fRecoil1();
PrimaryPostAttack(); // run post effects
float flNextAttack = fNextAttack1();
if( flNextAttack == -1.0f )
flNextAttack = SequenceDuration();
if( m_flNextPrimaryAttack < UTIL_WeaponTimeBase( ))
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + flNextAttack + 0.02f;
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + flNextAttack;
if( HasAmmo( )) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_FLOAT( 10.0f, 15.0f );
}
else if( iResult == 0 )
{
float flNextAttack = 0.1f;
if( GetAnimation( ACT_VM_SHOOT_EMPTY ) != -1 )
{
SetAnimation( ACT_VM_SHOOT_EMPTY );
flNextAttack = SequenceDuration();
}
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + flNextAttack;
PlayEmptySound();
}
m_iStepReload = NOT_IN_RELOAD; // reset reload
}
virtual void SecondaryAttack( void ) // do "+ATTACK2"
{
if( !FBitSet( m_pPlayer->m_afButtonPressed, IN_ATTACK2 ))
return; // no effect for hold button
int iResult = PlayCurrentAttack( iAttack2(), false );
if( iResult == 1 )
{
const feedback_t *pFB = pFeedback2();
m_pPlayer->ViewPunch( pFB->punchangle[0].Random(), pFB->punchangle[1].Random(), pFB->punchangle[2].Random() );
m_pPlayer->pev->velocity = m_pPlayer->pev->velocity - gpGlobals->v_forward * fRecoil2();
SecondaryPostAttack(); // run post effects
float flNextAttack = fNextAttack2();
if( flNextAttack == -1.0f )
flNextAttack = SequenceDuration();
if( m_flNextSecondaryAttack < UTIL_WeaponTimeBase() )
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + flNextAttack + 0.02f;
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + flNextAttack;
if( HasAmmo( )) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_FLOAT( 10.0f, 15.0f );
}
else if( iResult == 0 )
{
float flNextAttack = 0.1f;
if( GetAnimation( ACT_VM_SHOOT_EMPTY ) != -1 )
{
SetAnimation( ACT_VM_SHOOT_EMPTY );
flNextAttack = SequenceDuration();
}
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + flNextAttack;
PlayEmptySound();
}
m_iStepReload = NOT_IN_RELOAD; // reset reload
}
virtual void Reload( void ){ DefaultReload( ACT_VM_RELOAD ); } // do "+RELOAD"
virtual void PrimaryPostAttack( void ) {}
virtual void SecondaryPostAttack( void ) {}
virtual void PostReload( void ) {}
virtual void PostIdle( void ) {} // calling every frame
virtual void WeaponIdle( void ){ DefaultIdle(); } // called when no buttons pressed
virtual void Deploy( void ); // deploy function
virtual void Holster( bool force = false ); // holster function
};
class CBasePlayerAmmo : public CBaseEntity
{
public:
void Precache( void );
void Spawn( void );
// Wargon: Переменные для юзабельности патронов.
2020-08-31 18:50:41 +02:00
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
void EXPORT DefaultUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { DefaultTouch( pActivator ); }
virtual int ObjectCaps( void ) { return m_iAmmoCaps | FCAP_ACROSS_TRANSITION | FCAP_USE_ONLY; }
virtual BOOL IsGenericAmmo( void ) { return ( FStrEq( STRING( pev->classname ), "ammo_generic" ) && pev->netname != iStringNull ); }
void KeyValue( KeyValueData *pkvd );
BOOL InitGenericAmmo( void );
RandomRange m_rAmmoCount;
BOOL m_bCustomAmmo; // it's a virtual entity
string_t m_iAmmoType; // just store name of ammo so we can find them again
int m_iAmmoCaps;
static AmmoInfo AmmoInfoArray[MAX_AMMO_SLOTS];
static AmmoDesc AmmoDescArray[MAX_AMMO_DESC];
void EXPORT DefaultTouch( CBaseEntity *pOther ); // default weapon touch
virtual BOOL AddAmmo( CBaseEntity *pOther );
CBaseEntity* Respawn( void );
void EXPORT Materialize( void );
};
extern DLL_GLOBAL short g_sModelIndexLaser;// holds the index for the laser beam
extern DLL_GLOBAL const char *g_pModelNameLaser;
extern DLL_GLOBAL short g_sModelIndexLaserDot;// holds the index for the laser beam dot
extern DLL_GLOBAL short g_sModelIndexFireball;// holds the index for the fireball
extern DLL_GLOBAL short g_sModelIndexSmoke;// holds the index for the smoke cloud
extern DLL_GLOBAL short g_sModelIndexWExplosion;// holds the index for the underwater explosion
extern DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model
extern DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for blood drops
extern DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for blood spray (bigger)
extern DLL_GLOBAL short g_sModelIndexWaterSplash;
extern DLL_GLOBAL short g_sModelIndexSmokeTrail;
extern DLL_GLOBAL short g_sModelIndexNull;
extern void ClearMultiDamage( void );
extern void ApplyMultiDamage( entvars_t* pevInflictor, entvars_t* pevAttacker );
extern void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType );
extern void DecalGunshot( TraceResult *pTrace, int iBulletType, const Vector &vecSrc, bool fromPlayer = false );
extern void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage);
extern const char *DamageDecal( CBaseEntity *pEntity, int bitsDamageType );
extern void RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType );
extern void UTIL_InitAmmoDescription( const char *filename );
extern void UTIL_InitWeaponDescription( const char *pattern );
extern void AddAmmoNameToAmmoRegistry( const char *szAmmoname );
extern AmmoInfo *UTIL_FindAmmoType( const char *szAmmoname );
typedef struct
{
CBaseEntity *pEntity;
float amount;
int type;
} MULTIDAMAGE;
extern MULTIDAMAGE gMultiDamage;
#define LOUD_GUN_VOLUME 1000
#define NORMAL_GUN_VOLUME 600
#define QUIET_GUN_VOLUME 200
#define NO_GUN_VOLUME 0
#define BRIGHT_GUN_FLASH 512
#define NORMAL_GUN_FLASH 256
#define DIM_GUN_FLASH 128
#define NO_GUN_FLASH 0
#define KNIFE_BODYHIT_VOLUME 128
#define KNIFE_WALLHIT_VOLUME 512
#define BIG_EXPLOSION_VOLUME 2048
#define NORMAL_EXPLOSION_VOLUME 1024
#define SMALL_EXPLOSION_VOLUME 512
#define WEAPON_ACTIVITY_VOLUME 64
#define VECTOR_CONE_1DEGREES Vector( 0.00873, 0.00873, 0.00873 )
#define VECTOR_CONE_2DEGREES Vector( 0.01745, 0.01745, 0.01745 )
#define VECTOR_CONE_3DEGREES Vector( 0.02618, 0.02618, 0.02618 )
#define VECTOR_CONE_4DEGREES Vector( 0.03490, 0.03490, 0.03490 )
#define VECTOR_CONE_5DEGREES Vector( 0.04362, 0.04362, 0.04362 )
#define VECTOR_CONE_6DEGREES Vector( 0.05234, 0.05234, 0.05234 )
#define VECTOR_CONE_7DEGREES Vector( 0.06105, 0.06105, 0.06105 )
#define VECTOR_CONE_8DEGREES Vector( 0.06976, 0.06976, 0.06976 )
#define VECTOR_CONE_9DEGREES Vector( 0.07846, 0.07846, 0.07846 )
#define VECTOR_CONE_10DEGREES Vector( 0.08716, 0.08716, 0.08716 )
#define VECTOR_CONE_15DEGREES Vector( 0.13053, 0.13053, 0.13053 )
#define VECTOR_CONE_20DEGREES Vector( 0.17365, 0.17365, 0.17365 )
//=========================================================
// CWeaponBox - a single entity that can store weapons
// and ammo.
//=========================================================
class CWeaponBox : public CBaseAnimating
{
void Precache( void );
void Spawn( void );
void Touch( CBaseEntity *pOther );
void KeyValue( KeyValueData *pkvd );
BOOL IsEmpty( void );
int GiveAmmo( int iCount, const char *szName );
int MaxAmmoCarry( int iszName );
void SetObjectCollisionBox( void );
public:
void EXPORT Kill( void );
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
BOOL HasWeapon( CBasePlayerItem *pCheckItem );
BOOL PackWeapon( CBasePlayerItem *pWeapon );
BOOL PackAmmo( int iszName, int iCount );
CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES];// one slot for each
int m_rgiszAmmo[MAX_AMMO_SLOTS];// ammo names
int m_rgAmmo[MAX_AMMO_SLOTS];// ammo quantities
int m_cAmmoTypes;// how many ammo types packed into this box (if packed by a level designer)
};
#endif // WEAPONS_H