You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1104 lines
32 KiB
1104 lines
32 KiB
/*** |
|
* |
|
* 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. |
|
* |
|
****/ |
|
#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD ) |
|
|
|
#include "extdll.h" |
|
#include "util.h" |
|
#include "cbase.h" |
|
#include "monsters.h" |
|
#include "weapons.h" |
|
#include "nodes.h" |
|
#include "player.h" |
|
#include "hornet.h" |
|
#include "gamerules.h" |
|
#include "effects.h" |
|
#include "BMOD_messaging.h" |
|
#include "decals.h" |
|
#include "BMOD_zapgunrift.h" |
|
#include "shake.h" |
|
#include "squeakgrenade.h" |
|
|
|
short iBSquidSpitSprite; |
|
|
|
extern cvar_t bm_freezetime; |
|
extern cvar_t bm_hornet_mod; |
|
|
|
enum hgun_e |
|
{ |
|
HGUN_IDLE1 = 0, |
|
HGUN_FIDGETSWAY, |
|
HGUN_FIDGETSHAKE, |
|
HGUN_DOWN, |
|
HGUN_UP, |
|
HGUN_SHOOT |
|
}; |
|
|
|
enum hgun_phase |
|
{ |
|
HGUN_IDLE = 0, |
|
HGUN_CHARGE, |
|
HGUN_ZAP, |
|
HGUN_ZAP_DONE, |
|
HGUN_SPIT |
|
}; |
|
|
|
enum firemode_e |
|
{ |
|
FIREMODE_TRACK = 0, |
|
FIREMODE_FAST |
|
}; |
|
|
|
//========================================================= |
|
// Bullsquid's spit projectile |
|
//========================================================= |
|
class BMODSquidSpit : public CBaseEntity |
|
{ |
|
public: |
|
void Spawn( void ); |
|
|
|
static void Shoot( entvars_t *Owner, Vector vecStart, Vector vecVelocity ); |
|
void Touch( CBaseEntity *pOther ); |
|
void EXPORT Animate( void ); |
|
|
|
static TYPEDESCRIPTION m_SaveData[]; |
|
|
|
int m_maxFrame; |
|
entvars_t *pevOwner; |
|
|
|
}; |
|
|
|
LINK_ENTITY_TO_CLASS( squidspit, BMODSquidSpit ); |
|
|
|
void BMODSquidSpit:: Spawn( void ) |
|
{ |
|
pev->movetype = MOVETYPE_FLY; |
|
pev->classname = MAKE_STRING( "squidspit" ); |
|
|
|
pev->solid = SOLID_BBOX; |
|
pev->rendermode = kRenderTransAlpha; |
|
pev->renderamt = 255; |
|
|
|
SET_MODEL( ENT( pev ), "sprites/bigspit.spr" ); |
|
pev->frame = 0; |
|
pev->scale = 0.5; |
|
|
|
UTIL_SetSize( pev, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ) ); |
|
|
|
m_maxFrame = (float)MODEL_FRAMES( pev->modelindex ) - 1; |
|
|
|
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); |
|
WRITE_BYTE( TE_BEAMFOLLOW ); |
|
WRITE_SHORT( entindex() ); // entity |
|
WRITE_SHORT( g_sModelIndexLightning ); // model |
|
WRITE_BYTE( 2 ); // life |
|
WRITE_BYTE( 4 ); // width |
|
WRITE_BYTE( 128 ); // r, g, b |
|
WRITE_BYTE( 200 ); // r, g, b |
|
WRITE_BYTE( 0 ); // r, g, b |
|
WRITE_BYTE( 255 ); // brightness |
|
MESSAGE_END(); // move PHS/PVS data sending into here (SEND_ALL, SEND_PVS, SEND_PHS) |
|
} |
|
|
|
void BMODSquidSpit::Animate( void ) |
|
{ |
|
pev->nextthink = gpGlobals->time + 0.1f; |
|
|
|
if( pev->frame++ ) |
|
{ |
|
if( pev->frame > m_maxFrame ) |
|
{ |
|
pev->frame = 0; |
|
} |
|
} |
|
} |
|
|
|
void BMODSquidSpit::Shoot( entvars_t *Owner, Vector vecStart, Vector vecVelocity ) |
|
{ |
|
BMODSquidSpit *pSpit = GetClassPtr( (BMODSquidSpit *)NULL ); |
|
pSpit->Spawn(); |
|
|
|
UTIL_SetOrigin( pSpit->pev, vecStart ); |
|
pSpit->pev->velocity = vecVelocity; |
|
pSpit->pev->owner = ENT( Owner ); |
|
pSpit->pevOwner = Owner; |
|
|
|
pSpit->SetThink( &BMODSquidSpit::Animate ); |
|
pSpit->pev->nextthink = gpGlobals->time + 0.1f; |
|
} |
|
|
|
void BMODSquidSpit::Touch( CBaseEntity *pOther ) |
|
{ |
|
TraceResult tr; |
|
int iPitch; |
|
|
|
// splat sound |
|
iPitch = RANDOM_FLOAT( 90, 110 ); |
|
|
|
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "bullchicken/bc_acid1.wav", 1, ATTN_NORM, 0, iPitch ); |
|
|
|
switch( RANDOM_LONG( 0, 1 ) ) |
|
{ |
|
case 0: |
|
EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, "bullchicken/bc_spithit1.wav", 1, ATTN_NORM, 0, iPitch ); |
|
break; |
|
case 1: |
|
EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, "bullchicken/bc_spithit2.wav", 1, ATTN_NORM, 0, iPitch ); |
|
break; |
|
} |
|
|
|
// make a splat on the wall |
|
UTIL_TraceLine( pev->origin, pev->origin + pev->velocity, dont_ignore_monsters, ENT( pev ), &tr ); |
|
UTIL_DecalTrace( &tr, DECAL_SPIT1 + RANDOM_LONG( 0, 1 ) ); |
|
|
|
// make some flecks |
|
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, tr.vecEndPos ); |
|
WRITE_BYTE( TE_SPRITE_SPRAY ); |
|
WRITE_COORD( tr.vecEndPos.x ); // pos |
|
WRITE_COORD( tr.vecEndPos.y ); |
|
WRITE_COORD( tr.vecEndPos.z ); |
|
WRITE_COORD( tr.vecPlaneNormal.x ); // dir |
|
WRITE_COORD( tr.vecPlaneNormal.y ); |
|
WRITE_COORD( tr.vecPlaneNormal.z ); |
|
WRITE_SHORT( iBSquidSpitSprite ); // model |
|
WRITE_BYTE( 5 ); // count |
|
WRITE_BYTE( 30 ); // speed |
|
WRITE_BYTE( 80 ); // noise ( client will divide by 100 ) |
|
MESSAGE_END(); |
|
|
|
if( pOther->IsPlayer() ) |
|
{ |
|
ClearMultiDamage(); |
|
pOther->TraceAttack( pevOwner, 30, pev->origin + pev->velocity, &tr, DMG_GENERIC ); |
|
ApplyMultiDamage( pev, pevOwner ); |
|
} |
|
|
|
SetThink( &CBaseEntity::SUB_Remove ); |
|
pev->nextthink = gpGlobals->time; |
|
} |
|
|
|
#include "BMOD_hornetgun.h" |
|
|
|
LINK_ENTITY_TO_CLASS( weapon_hornetgun, CHgun ) |
|
|
|
//========================================================= |
|
// ClearBeams - remove all beams |
|
//========================================================= |
|
void CHgun::ClearBeams() |
|
{ |
|
for( int i = 0; i < HGUN_MAX_BEAMS; i++ ) |
|
{ |
|
if( m_pBeam[i] ) |
|
{ |
|
UTIL_Remove( m_pBeam[i] ); |
|
m_pBeam[i] = NULL; |
|
} |
|
} |
|
m_iBeams = 0; |
|
|
|
STOP_SOUND( ENT(m_pPlayer->pev), CHAN_WEAPON, "debris/zap4.wav" ); |
|
} |
|
|
|
//========================================================= |
|
// ArmBeam - small beam from arm to nearby geometry |
|
//========================================================= |
|
|
|
void CHgun::ArmBeam( Vector color ) |
|
{ |
|
TraceResult tr; |
|
float flDist = 1.0; |
|
|
|
if( m_iBeams >= HGUN_MAX_BEAMS ) |
|
return; |
|
|
|
// UTIL_MakeAimVectors( pev->angles ); |
|
Vector vecSrc = m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12; |
|
|
|
for( int i = 0; i < 3; i++ ) |
|
{ |
|
Vector vecAim = gpGlobals->v_right * RANDOM_FLOAT( -1, 1 ) + gpGlobals->v_up * RANDOM_FLOAT( -1, 1 ); |
|
TraceResult tr1; |
|
UTIL_TraceLine( vecSrc, vecSrc + vecAim * 512, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr1 ); |
|
if( flDist > tr1.flFraction ) |
|
{ |
|
tr = tr1; |
|
flDist = tr.flFraction; |
|
} |
|
} |
|
|
|
// Couldn't find anything close enough |
|
if( flDist == 1.0f ) |
|
return; |
|
|
|
// DecalGunshot( &tr, BULLET_PLAYER_CROWBAR ); |
|
|
|
m_pBeam[m_iBeams] = CBeam::BeamCreate( "sprites/lgtning.spr", 30 ); |
|
if( !m_pBeam[m_iBeams] ) |
|
return; |
|
|
|
m_pBeam[m_iBeams]->PointEntInit( tr.vecEndPos, m_pPlayer->entindex() ); |
|
m_pBeam[m_iBeams]->SetEndAttachment( 1 ); |
|
// m_pBeam[m_iBeams]->SetColor( 96, 128, 16 ); |
|
m_pBeam[m_iBeams]->SetColor( color.x, color.y, color.z ); |
|
m_pBeam[m_iBeams]->SetBrightness( 64 ); |
|
m_pBeam[m_iBeams]->SetNoise( 80 ); |
|
m_pBeam[m_iBeams]->pev->spawnflags |= SF_BEAM_TEMPORARY; |
|
m_iBeams++; |
|
} |
|
|
|
//========================================================= |
|
// ZapBeam - heavy damage directly forward |
|
//========================================================= |
|
void CHgun::ZapBeam( void ) |
|
{ |
|
Vector vecSrc, vecAim, vecOrig; |
|
TraceResult tr; |
|
CBaseEntity *pEntity; |
|
|
|
/* |
|
if (m_iBeams >= HGUN_MAX_BEAMS) |
|
return; |
|
*/ |
|
|
|
// UTIL_MakeVectors( m_pPlayer->pev->v_angle ); |
|
vecOrig = m_pPlayer->GetGunPosition(); |
|
vecSrc = m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12; |
|
vecAim = gpGlobals->v_forward; |
|
|
|
UTIL_TraceLine( vecOrig, vecOrig + vecAim * 2048, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr ); |
|
|
|
for( int i = 0; i < 2; i++ ) |
|
{ |
|
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); |
|
WRITE_BYTE( TE_BEAMPOINTS ); |
|
WRITE_COORD( vecSrc.x ); |
|
WRITE_COORD( vecSrc.y ); |
|
WRITE_COORD( vecSrc.z ); |
|
WRITE_COORD( tr.vecEndPos.x ); |
|
WRITE_COORD( tr.vecEndPos.y ); |
|
WRITE_COORD( tr.vecEndPos.z ); |
|
WRITE_SHORT( iZapBeamSpr ); |
|
WRITE_BYTE( 0 ); // Starting frame |
|
WRITE_BYTE( 0 ); // framerate * 0.1 |
|
WRITE_BYTE( 2 ); // life * 0.1 |
|
WRITE_BYTE( 50 ); // width |
|
WRITE_BYTE( 20 ); // noise |
|
WRITE_BYTE( 180 ); // color r,g,b |
|
WRITE_BYTE( 255 ); // color r,g,b |
|
WRITE_BYTE( 96 ); // color r,g,b |
|
WRITE_BYTE( 255 ); // brightness |
|
WRITE_BYTE( 0 ); // scroll speed |
|
MESSAGE_END(); |
|
} |
|
|
|
UTIL_DecalTrace( &tr, DECAL_SMALLSCORCH1 + RANDOM_LONG( 0, 2 ) ); |
|
|
|
/* |
|
m_pBeam[m_iBeams] = CBeam::BeamCreate( "sprites/lgtning.spr", 50 ); |
|
if( !m_pBeam[m_iBeams] ) |
|
return; |
|
m_pBeam[m_iBeams]->PointEntInit( tr.vecEndPos, m_pPlayer->entindex() ); |
|
m_pBeam[m_iBeams]->SetEndAttachment( 1 ); |
|
m_pBeam[m_iBeams]->SetColor( 180, 255, 96 ); |
|
m_pBeam[m_iBeams]->SetBrightness( 255 ); |
|
m_pBeam[m_iBeams]->SetNoise( 20 ); |
|
m_pBeam[m_iBeams]->pev->spawnflags |= SF_BEAM_TEMPORARY; |
|
m_iBeams++; |
|
*/ |
|
|
|
pEntity = CBaseEntity::Instance(tr.pHit); |
|
if( pEntity != NULL && pEntity->pev->takedamage ) |
|
{ |
|
// pEntity->TakeDamage( pev, VARS (pev->owner), 45, DMG_SHOCK ); |
|
ClearMultiDamage(); |
|
entvars_t *Owner; |
|
Owner = VARS( pev->owner ); |
|
pEntity->TraceAttack( Owner, 90, vecAim, &tr, DMG_SHOCK | DMG_ALWAYSGIB ); |
|
ApplyMultiDamage( pev, Owner ); |
|
UTIL_ScreenFade( pEntity, Vector(180,255,96), 2, 0.5, 128, FFADE_IN ); |
|
} |
|
|
|
UTIL_EmitAmbientSound( ENT( m_pPlayer->pev ), tr.vecEndPos, "weapons/electro4.wav", 0.5, ATTN_NORM, 0, RANDOM_LONG( 140, 160 ) ); |
|
|
|
if( UTIL_PointContents( tr.vecEndPos ) == CONTENTS_WATER ) |
|
{ |
|
CBaseEntity *pRift = CBaseEntity::Create( "zaprift", tr.vecEndPos, UTIL_VecToAngles( tr.vecPlaneNormal ), m_pPlayer->edict() ); |
|
// UTIL_EmitAmbientSound( ENT(m_pPlayer->pev), tr.vecEndPos, "weapons/electro4.wav", 50, ATTN_NORM, 0, 300 ); |
|
} |
|
} |
|
|
|
//========================================================= |
|
// Freeze Ray - |
|
//========================================================= |
|
void CHgun::FreezeRay( void ) |
|
{ |
|
Vector vecSrc, vecAim, vecOrig; |
|
TraceResult tr; |
|
CBaseEntity *pEntity; |
|
|
|
if( ( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] < 12 ) || m_pPlayer->pev->waterlevel == 3 ) |
|
{ |
|
return; |
|
} |
|
|
|
vecOrig = m_pPlayer->GetGunPosition(); |
|
vecSrc = m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12; |
|
vecAim = gpGlobals->v_forward; |
|
UTIL_TraceLine( vecOrig, vecOrig + vecAim * 2048, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr ); |
|
|
|
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); |
|
WRITE_BYTE( TE_BEAMPOINTS ); |
|
WRITE_COORD( vecSrc.x ); |
|
WRITE_COORD( vecSrc.y ); |
|
WRITE_COORD( vecSrc.z ); |
|
WRITE_COORD( tr.vecEndPos.x ); |
|
WRITE_COORD( tr.vecEndPos.y ); |
|
WRITE_COORD( tr.vecEndPos.z ); |
|
WRITE_SHORT( iZapBeamSpr ); |
|
WRITE_BYTE( 0 ); // Starting frame |
|
WRITE_BYTE( 0 ); // framerate * 0.1 |
|
WRITE_BYTE( 3 ); // life * 0.1 |
|
WRITE_BYTE( 200 ); // width |
|
WRITE_BYTE( 2 ); // noise |
|
WRITE_BYTE( 220 ); // color r,g,b |
|
WRITE_BYTE( 220 ); // color r,g,b |
|
WRITE_BYTE( 255 ); // color r,g,b |
|
WRITE_BYTE( 255 ); // brightness |
|
WRITE_BYTE( 0 ); // scroll speed |
|
MESSAGE_END(); |
|
|
|
UTIL_DecalTrace( &tr, DECAL_MOMMASPLAT ); |
|
|
|
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); |
|
WRITE_BYTE( TE_SPRITETRAIL );// TE_RAILTRAIL); |
|
WRITE_COORD( vecSrc.x ); |
|
WRITE_COORD( vecSrc.y ); |
|
WRITE_COORD( vecSrc.z ); |
|
WRITE_COORD( tr.vecEndPos.x ); |
|
WRITE_COORD( tr.vecEndPos.y ); |
|
WRITE_COORD( tr.vecEndPos.z ); |
|
WRITE_SHORT( m_sGlowSpr ); // model |
|
WRITE_BYTE( 20 ); // count |
|
WRITE_BYTE( 10 ); // life * 10 |
|
WRITE_BYTE( RANDOM_LONG( 1, 2 ) ); // size * 10 |
|
WRITE_BYTE( 10 ); // amplitude * 0.1 |
|
WRITE_BYTE( 0 ); // speed * 100 |
|
MESSAGE_END(); |
|
|
|
pEntity = CBaseEntity::Instance( tr.pHit ); |
|
if( pEntity != NULL && pEntity->pev->takedamage && pEntity->IsPlayer() ) |
|
{ |
|
CBasePlayer *pPlayer = (CBasePlayer *)pEntity; |
|
|
|
UTIL_ScreenFade( pPlayer, Vector( 0, 0, 255 ), 2.0, 1.0, 128, FFADE_IN ); |
|
|
|
pPlayer->pev->rendermode = kRenderNormal; |
|
pPlayer->pev->renderfx = kRenderFxGlowShell; |
|
|
|
pPlayer->pev->rendercolor.x = 240; // red |
|
pPlayer->pev->rendercolor.y = 240; // green |
|
pPlayer->pev->rendercolor.z = 255; // blue |
|
|
|
pPlayer->pev->renderamt = 60; // glow shell distance from entity |
|
|
|
float freezetime = Q_max (0.6f, bm_freezetime.value); |
|
|
|
// freeze the player and set the "unfreeze" time... |
|
pPlayer->EnableControl(FALSE); |
|
pPlayer->m_vFreezeAngle = pPlayer->pev->v_angle; |
|
// pPlayer->pev->movetype = MOVETYPE_TOSS; |
|
|
|
pPlayer->m_flFreezeTime = gpGlobals->time + freezetime; |
|
//RuneMsg( pPlayer, "YOU ARE FROZEN!!!", Vector(100,100,255), freezetime - .5); |
|
PrintMessage( pPlayer, BMOD_CHAN_RUNE, Vector(100,100,255), Vector (.1, freezetime - 0.5f, .1), "YOU ARE FROZEN!!!"); |
|
|
|
} |
|
|
|
UTIL_EmitAmbientSound( ENT(m_pPlayer->pev), tr.vecEndPos, "weapons/electro4.wav", 0.5, ATTN_NORM, 0, RANDOM_LONG( 140, 160 )); |
|
|
|
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] = 0; |
|
m_flNextPrimaryAttack = gpGlobals->time + 0.25f; |
|
|
|
m_flRechargeTime = gpGlobals->time + 0.5f; |
|
|
|
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME; |
|
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH; |
|
|
|
SendWeaponAnim( HGUN_SHOOT ); |
|
|
|
// player "shoot" animation |
|
m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
m_flTimeWeaponIdle = gpGlobals->time + RANDOM_FLOAT( 10, 15 ); |
|
m_pPlayer->pev->punchangle.x = RANDOM_FLOAT( 0, 2 ); |
|
} |
|
|
|
|
|
//========================================================= |
|
// BeamGlow - brighten all beams |
|
//========================================================= |
|
void CHgun::BeamGlow() |
|
{ |
|
int b = m_iBeams * 32; |
|
if( b > 255 ) |
|
b = 255; |
|
|
|
for( int i = 0; i < m_iBeams; i++ ) |
|
{ |
|
if( m_pBeam[i]->GetBrightness() != 255 ) |
|
{ |
|
m_pBeam[i]->SetBrightness( b ); |
|
} |
|
} |
|
} |
|
|
|
BOOL CHgun::IsUseable( void ) |
|
{ |
|
return TRUE; |
|
} |
|
|
|
void CHgun::Spawn() |
|
{ |
|
Precache(); |
|
m_iId = WEAPON_HORNETGUN; |
|
SET_MODEL( ENT( pev ), "models/w_hgun.mdl" ); |
|
|
|
m_iDefaultAmmo = HIVEHAND_DEFAULT_GIVE; |
|
m_iFirePhase = 0; |
|
m_iFireMode = 0; |
|
|
|
FallInit();// get ready to fall down. |
|
} |
|
|
|
void CHgun::Precache( void ) |
|
{ |
|
PRECACHE_MODEL( "models/v_hgun.mdl" ); |
|
PRECACHE_MODEL( "models/w_hgun.mdl" ); |
|
PRECACHE_MODEL( "models/p_hgun.mdl" ); |
|
|
|
m_usHornetFire = PRECACHE_EVENT( 1, "events/firehornet.sc" ); |
|
|
|
UTIL_PrecacheOther( "hornet" ); |
|
UTIL_PrecacheOther( "zaprift" ); |
|
UTIL_PrecacheOther( "zapbounce" ); |
|
PRECACHE_SOUND( "debris/zap4.wav" ); |
|
PRECACHE_SOUND( "weapons/electro4.wav" ); |
|
PRECACHE_SOUND( "hassault/hw_shoot1.wav" ); |
|
iZapBeamSpr = PRECACHE_MODEL( "sprites/lgtning.spr" ); |
|
|
|
PRECACHE_MODEL( "sprites/bigspit.spr" ); |
|
iBSquidSpitSprite = PRECACHE_MODEL( "sprites/tinyspit.spr" );// client side spittle. |
|
PRECACHE_SOUND( "bullchicken/bc_acid1.wav" ); |
|
PRECACHE_SOUND( "bullchicken/bc_spithit1.wav" ); |
|
PRECACHE_SOUND( "bullchicken/bc_spithit2.wav" ); |
|
PRECACHE_SOUND( "bullchicken/bc_attack2.wav" ); |
|
PRECACHE_SOUND( "bullchicken/bc_attack3.wav" ); |
|
PRECACHE_SOUND( "leech/leech_bite1.wav" ); |
|
|
|
m_sGlowSpr = PRECACHE_MODEL( "sprites/glow04.spr" ); |
|
} |
|
|
|
int CHgun::AddToPlayer( CBasePlayer *pPlayer ) |
|
{ |
|
if( CBasePlayerWeapon::AddToPlayer( pPlayer ) ) |
|
{ |
|
#ifndef CLIENT_DLL |
|
if( g_pGameRules->IsMultiplayer() ) |
|
{ |
|
// in multiplayer, all hivehands come full. |
|
pPlayer->m_rgAmmo[PrimaryAmmoIndex()] = 12; |
|
} |
|
#endif |
|
MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev ); |
|
WRITE_BYTE( m_iId ); |
|
MESSAGE_END(); |
|
return TRUE; |
|
} |
|
return FALSE; |
|
} |
|
|
|
int CHgun::GetItemInfo( ItemInfo *p ) |
|
{ |
|
p->pszName = STRING( pev->classname ); |
|
p->pszAmmo1 = "Hornets"; |
|
p->iMaxAmmo1 = m_iMaxammo; |
|
p->pszAmmo2 = NULL; |
|
p->iMaxAmmo2 = -1; |
|
p->iMaxClip = WEAPON_NOCLIP; |
|
p->iSlot = 3; |
|
p->iPosition = 3; |
|
p->iId = m_iId = WEAPON_HORNETGUN; |
|
p->iFlags = ITEM_FLAG_NOAUTOSWITCHEMPTY | ITEM_FLAG_NOAUTORELOAD; |
|
p->iWeight = HORNETGUN_WEIGHT; |
|
|
|
return 1; |
|
} |
|
|
|
BOOL CHgun::Deploy() |
|
{ |
|
// BMOD Edit - Modified hornet message |
|
if( bm_hornet_mod.value ) |
|
PrintMessage( m_pPlayer, BMOD_CHAN_WEAPON, Vector( 20, 250, 20 ), Vector( 1, 4, 2 ), "HORNET GUN\nACID SPIT - LIGHTNING - FREEZE RAY - SNARKS\nSECONDARY FIRE: Switches modes." ); |
|
|
|
return DefaultDeploy( "models/v_hgun.mdl", "models/p_hgun.mdl", HGUN_UP, "hive" ); |
|
} |
|
|
|
void CHgun::Holster( int skiplocal /* = 0 */ ) |
|
{ |
|
ClearBeams(); |
|
m_iFirePhase = HGUN_IDLE; |
|
|
|
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5f; |
|
SendWeaponAnim( HGUN_DOWN ); |
|
|
|
//!!!HACKHACK - can't select hornetgun if it's empty! no way to get ammo for it, either. |
|
if( !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) |
|
{ |
|
m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] = 1; |
|
} |
|
} |
|
|
|
void CHgun::SecondaryAttack() |
|
{ |
|
if( !bm_hornet_mod.value ) |
|
{ |
|
OldSecondaryAttack(); |
|
return; |
|
} |
|
|
|
m_iFireMode = ( m_iFireMode + 1 ) % 5; |
|
|
|
switch( m_iFireMode ) |
|
{ |
|
case 0: |
|
PrintMessage( m_pPlayer, BMOD_CHAN_WEAPON, Vector( 20, 250, 20 ), Vector( 1, 4, 2 ), "\n\nAcid Spit Mode - 3 per shot"); |
|
break; |
|
case 1: |
|
PrintMessage( m_pPlayer, BMOD_CHAN_WEAPON, Vector( 20, 250, 20 ), Vector( 1, 4, 2 ), "\n\nLightning Mode - 4 per shot"); |
|
break; |
|
case 2: |
|
PrintMessage( m_pPlayer, BMOD_CHAN_WEAPON, Vector( 20, 250, 20 ), Vector( 1, 4, 2 ), "\n\nMultizap Mode - 12 per shot"); |
|
break; |
|
case 3: |
|
PrintMessage( m_pPlayer, BMOD_CHAN_WEAPON, Vector( 20, 250, 20 ), Vector( 1, 4, 2 ), "\n\nFreeze Ray Mode - 12 per shot"); |
|
break; |
|
case 4: |
|
PrintMessage( m_pPlayer, BMOD_CHAN_WEAPON, Vector( 20, 250, 20 ), Vector( 1, 4, 2 ), "\n\nSnark Launcher Mode - 1 Snark per shot"); |
|
break; |
|
} |
|
|
|
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "leech/leech_bite1.wav", 1, ATTN_NORM ); |
|
m_flNextSecondaryAttack = gpGlobals->time + 0.5f; |
|
} |
|
|
|
void CHgun::ZapGun() |
|
{ |
|
if( m_iFirePhase == HGUN_IDLE ) |
|
Reload(); |
|
|
|
if( ( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] < 4 ) || ( m_fNextPhaseTime > gpGlobals->time ) ) |
|
{ |
|
return; |
|
} |
|
|
|
if( m_pPlayer->pev->waterlevel > 0 ) |
|
{ |
|
|
|
// m_pPlayer->TakeDamage( VARS( eoNullEntity ), VARS( eoNullEntity ), 50, DMG_SHOCK ); |
|
UTIL_ScreenFade( this, Vector( 180, 255, 96 ), 2, 0.5, 128, FFADE_IN ); |
|
|
|
CBaseEntity *pRift = CBaseEntity::Create( "zaprift", pev->origin, pev->angles, ENT( pev ) ); |
|
|
|
m_pPlayer->TakeDamage( m_pPlayer->pev, m_pPlayer->pev, 100, DMG_SHOCK ); |
|
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0, 100 + m_iBeams * 10 ); |
|
m_flNextPrimaryAttack = m_flNextPrimaryAttack + 1.5f; |
|
return; |
|
} |
|
|
|
switch( m_iFirePhase ) |
|
{ |
|
case HGUN_IDLE: |
|
m_flTimeWeaponIdle = gpGlobals->time; |
|
m_iFirePhase = HGUN_CHARGE; |
|
m_fNextPhaseTime = 0; |
|
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME; |
|
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH; |
|
case HGUN_CHARGE: |
|
if( m_fNextPhaseTime < gpGlobals->time ) |
|
{ |
|
if( m_iBeams < HGUN_MAX_BEAMS ) |
|
{ |
|
ArmBeam( Vector( 96, 128, 16 ) ); |
|
BeamGlow(); |
|
m_fNextPhaseTime = gpGlobals->time + HGUN_CHARGE_TIME; |
|
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0,100 + m_iBeams * 10 ); |
|
} |
|
else |
|
{ |
|
m_iFirePhase = HGUN_ZAP; |
|
m_fNextPhaseTime = gpGlobals->time + 0.1f; |
|
} |
|
} |
|
break; |
|
case HGUN_ZAP: |
|
ClearBeams(); |
|
ZapBeam(); |
|
m_iFirePhase = HGUN_ZAP_DONE; |
|
m_fNextPhaseTime = gpGlobals->time + HGUN_ZAP_TIME; |
|
EMIT_SOUND_DYN( ENT(m_pPlayer->pev), CHAN_WEAPON, "hassault/hw_shoot1.wav", 1, ATTN_NORM, 0, RANDOM_LONG( 130, 160 ) ); |
|
SendWeaponAnim( HGUN_SHOOT ); |
|
|
|
// player "shoot" animation |
|
m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= 4; |
|
m_flRechargeTime = gpGlobals->time + 0.5f; |
|
m_pPlayer->pev->punchangle.x = RANDOM_FLOAT( 0, 2 ); |
|
break; |
|
case HGUN_ZAP_DONE: |
|
ClearBeams(); |
|
m_flNextPrimaryAttack = gpGlobals->time + 0.25f; |
|
m_flTimeWeaponIdle = gpGlobals->time + 0.1f; |
|
break; |
|
} |
|
} |
|
|
|
void CHgun::MultiZapGun() |
|
{ |
|
CZapBounce *pRift = NULL; |
|
|
|
if( m_iFirePhase == HGUN_IDLE ) |
|
Reload(); |
|
|
|
if( ( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] < 12 ) || ( m_fNextPhaseTime > gpGlobals->time ) ) |
|
{ |
|
return; |
|
} |
|
|
|
if( m_pPlayer->pev->waterlevel > 0 ) |
|
{ |
|
UTIL_ScreenFade( this, Vector( 180, 255, 96 ), 2, 0.5, 128, FFADE_IN ); |
|
m_pPlayer->TakeDamage( m_pPlayer->pev, m_pPlayer->pev, 100, DMG_SHOCK ); |
|
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0, 100 + m_iBeams * 10 ); |
|
m_flNextPrimaryAttack = m_flNextPrimaryAttack + 1.5f; |
|
return; |
|
} |
|
|
|
switch( m_iFirePhase ) |
|
{ |
|
case HGUN_IDLE: |
|
m_flTimeWeaponIdle = gpGlobals->time; |
|
m_iFirePhase = HGUN_CHARGE; |
|
m_fNextPhaseTime = 0; |
|
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME; |
|
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH; |
|
case HGUN_CHARGE: |
|
if( m_fNextPhaseTime < gpGlobals->time ) |
|
{ |
|
if( m_iBeams < HGUN_MAX_BEAMS / 2 ) |
|
{ |
|
ArmBeam( Vector( 16, 96, 128 ) ); |
|
BeamGlow(); |
|
m_fNextPhaseTime = gpGlobals->time + HGUN_CHARGE_TIME; |
|
EMIT_SOUND_DYN( ENT(m_pPlayer->pev), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0,100 + m_iBeams * 10 ); |
|
} |
|
else |
|
m_iFirePhase = HGUN_ZAP; |
|
m_fNextPhaseTime = gpGlobals->time + 0.1f; |
|
} |
|
break; |
|
case HGUN_ZAP: |
|
ClearBeams(); |
|
pRift = (CZapBounce*)CBaseEntity::Create( "zapbounce", |
|
m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12, |
|
gpGlobals->v_forward, |
|
m_pPlayer->edict() ); |
|
if( pRift ) |
|
{ |
|
pRift->m_fDamage = 90; |
|
pRift->m_iBounce = 5; |
|
pRift->pentIgnore = ENT( m_pPlayer->pev ); |
|
pRift->m_bFirstZap = TRUE; |
|
pRift->BounceThink(); |
|
} |
|
m_iFirePhase = HGUN_ZAP_DONE; |
|
m_fNextPhaseTime = gpGlobals->time + HGUN_ZAP_TIME; |
|
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_WEAPON, "hassault/hw_shoot1.wav", 1, ATTN_NORM, 0, RANDOM_LONG( 130, 160 ) ); |
|
SendWeaponAnim( HGUN_SHOOT ); |
|
// player "shoot" animation |
|
m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= 12; |
|
m_flRechargeTime = gpGlobals->time + 0.5f; |
|
m_pPlayer->pev->punchangle.x = RANDOM_FLOAT( 0, 2 ); |
|
break; |
|
case HGUN_ZAP_DONE: |
|
ClearBeams(); |
|
m_flNextPrimaryAttack = gpGlobals->time + 0.25f; |
|
m_flTimeWeaponIdle = gpGlobals->time + 0.1f; |
|
break; |
|
} |
|
} |
|
|
|
void CHgun::PrimaryAttack( void ) |
|
{ |
|
if( !bm_hornet_mod.value ) |
|
{ |
|
OldPrimaryAttack(); |
|
return; |
|
} |
|
|
|
Reload(); |
|
|
|
switch( m_iFireMode ) |
|
{ |
|
case 0: |
|
SquidSpit(); |
|
break; |
|
case 1: |
|
ZapGun(); |
|
break; |
|
case 2: |
|
MultiZapGun(); |
|
break; |
|
case 3: |
|
FreezeRay(); |
|
break; |
|
case 4: |
|
LaunchSnark(); |
|
break; |
|
} |
|
} |
|
|
|
void CHgun::SquidSpit( void ) |
|
{ |
|
if( ( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] < 3 ) || ( m_iFirePhase != HGUN_IDLE ) ) |
|
{ |
|
return; |
|
} |
|
|
|
Vector vecSrc, vecDir, vecOrig; |
|
int iSpittle, iSpitSpeed; |
|
TraceResult tr; |
|
|
|
// UTIL_MakeVectors( m_pPlayer->pev->v_angle ); |
|
|
|
// Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; |
|
// UTIL_MakeVectors( anglesAim ); |
|
|
|
vecOrig = m_pPlayer->GetGunPosition(); |
|
vecSrc = m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12; |
|
// vecDir = m_pPlayer->pev->v_angle; |
|
// vecDir = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); |
|
vecDir = gpGlobals->v_forward; |
|
UTIL_TraceLine( vecOrig, vecOrig + vecDir * 2048, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr ); |
|
vecDir = ( tr.vecEndPos - vecSrc ).Normalize(); |
|
|
|
if( m_pPlayer->pev->waterlevel == 3 ) |
|
{ |
|
iSpittle = 15; |
|
iSpitSpeed = 120; |
|
} |
|
else |
|
{ |
|
// CSquidSpit::Shoot( m_pPlayer->edict(), vecSrc, vecDir * 900 ); |
|
// CBaseEntity *pSpit = CBaseEntity::Create( "squidspit", vecSrc, vecDir , pev->owner ); |
|
BMODSquidSpit::Shoot( m_pPlayer->pev, vecSrc, vecDir * 1100 ); |
|
iSpittle = 5; |
|
iSpitSpeed = 80; |
|
} |
|
|
|
m_flNextPrimaryAttack = gpGlobals->time + 0.25f; |
|
|
|
// spew the spittle temporary ents. |
|
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSrc ); |
|
WRITE_BYTE( TE_SPRITE_SPRAY ); |
|
WRITE_COORD( vecSrc.x ); // pos |
|
WRITE_COORD( vecSrc.y ); |
|
WRITE_COORD( vecSrc.z ); |
|
WRITE_COORD( vecDir.x ); // dir |
|
WRITE_COORD( vecDir.y ); |
|
WRITE_COORD( vecDir.z ); |
|
WRITE_SHORT( iBSquidSpitSprite ); // model |
|
WRITE_BYTE( iSpittle ); // count |
|
WRITE_BYTE( iSpitSpeed ); // speed |
|
WRITE_BYTE( 25 ); // noise ( client will divide by 100 ) |
|
MESSAGE_END(); |
|
|
|
switch( RANDOM_LONG( 0, 1 ) ) |
|
{ |
|
case 0: |
|
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "bullchicken/bc_attack2.wav", 1, ATTN_NORM ); |
|
break; |
|
case 1: |
|
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "bullchicken/bc_attack3.wav", 1, ATTN_NORM ); |
|
break; |
|
} |
|
|
|
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= 3; |
|
m_flRechargeTime = gpGlobals->time + 0.5f; |
|
|
|
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME; |
|
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH; |
|
|
|
SendWeaponAnim( HGUN_SHOOT ); |
|
|
|
// player "shoot" animation |
|
m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
m_flTimeWeaponIdle = gpGlobals->time + RANDOM_FLOAT ( 10, 15 ); |
|
m_pPlayer->pev->punchangle.x = RANDOM_FLOAT( 0, 2 ); |
|
} |
|
|
|
void CHgun::LaunchSnark( void ) |
|
{ |
|
if( ( m_pPlayer->m_rgAmmo[m_pPlayer->GetAmmoIndex( "Snarks" )] < 1 ) || ( m_iFirePhase != HGUN_IDLE ) ) |
|
{ |
|
return; |
|
} |
|
|
|
Vector vecSrc, vecDir, vecOrig; |
|
int iSpittle, iSpitSpeed; |
|
TraceResult tr; |
|
|
|
vecOrig = m_pPlayer->GetGunPosition(); |
|
vecSrc = m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12; |
|
// vecDir = m_pPlayer->pev->v_angle; |
|
// vecDir = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); |
|
vecDir = gpGlobals->v_forward; |
|
UTIL_TraceLine( vecSrc + gpGlobals->v_forward * 20, vecSrc + gpGlobals->v_forward * 40, dont_ignore_monsters, NULL, &tr ); |
|
vecDir = ( tr.vecEndPos - vecSrc ).Normalize(); |
|
|
|
if( m_pPlayer->pev->waterlevel == 3 ) |
|
{ |
|
iSpittle = 15; |
|
iSpitSpeed = 120; |
|
} |
|
else |
|
{ |
|
CBaseEntity *pSqueak = CBaseEntity::Create( "monster_snark", tr.vecEndPos, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); |
|
pSqueak->pev->velocity = gpGlobals->v_forward * 1500 + m_pPlayer->pev->velocity; |
|
( (CSqueakGrenade*)pSqueak )->m_bWasLaunched = TRUE; |
|
EMIT_SOUND_DYN( ENT( pSqueak->pev ), CHAN_VOICE, "squeek/sqk_hunt2.wav", 1, ATTN_NORM, 0, 105 ); |
|
|
|
iSpittle = 5; |
|
iSpitSpeed = 80; |
|
} |
|
|
|
m_flNextPrimaryAttack = gpGlobals->time + 0.4f; |
|
|
|
// spew the spittle temporary ents. |
|
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSrc ); |
|
WRITE_BYTE( TE_SPRITE_SPRAY ); |
|
WRITE_COORD( vecSrc.x ); // pos |
|
WRITE_COORD( vecSrc.y ); |
|
WRITE_COORD( vecSrc.z ); |
|
WRITE_COORD( vecDir.x ); // dir |
|
WRITE_COORD( vecDir.y ); |
|
WRITE_COORD( vecDir.z ); |
|
WRITE_SHORT( iBSquidSpitSprite ); // model |
|
WRITE_BYTE( iSpittle ); // count |
|
WRITE_BYTE( iSpitSpeed ); // speed |
|
WRITE_BYTE( 25 ); // noise ( client will divide by 100 ) |
|
MESSAGE_END(); |
|
|
|
switch( RANDOM_LONG( 0, 1 ) ) |
|
{ |
|
case 0: |
|
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "bullchicken/bc_attack2.wav", 1, ATTN_NORM ); |
|
break; |
|
case 1: |
|
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "bullchicken/bc_attack3.wav", 1, ATTN_NORM ); |
|
break; |
|
} |
|
|
|
m_pPlayer->m_rgAmmo[m_pPlayer->GetAmmoIndex( "Snarks" )] -= 1; |
|
m_flRechargeTime = gpGlobals->time + 0.5f; |
|
|
|
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME; |
|
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH; |
|
|
|
SendWeaponAnim( HGUN_SHOOT ); |
|
|
|
// player "shoot" animation |
|
m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
m_flTimeWeaponIdle = gpGlobals->time + RANDOM_FLOAT( 10, 15 ); |
|
m_pPlayer->pev->punchangle.x = RANDOM_FLOAT( 0, 2 ); |
|
} |
|
|
|
void CHgun::OldPrimaryAttack() |
|
{ |
|
Reload(); |
|
|
|
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) |
|
{ |
|
return; |
|
} |
|
#ifndef CLIENT_DLL |
|
UTIL_MakeVectors( m_pPlayer->pev->v_angle ); |
|
|
|
CBaseEntity *pHornet = CBaseEntity::Create( "hornet", m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 16.0f + gpGlobals->v_right * 8.0f + gpGlobals->v_up * -12.0f, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); |
|
pHornet->pev->velocity = gpGlobals->v_forward * 300.0f; |
|
|
|
m_flRechargeTime = gpGlobals->time + 0.5f; |
|
#endif |
|
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; |
|
|
|
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME; |
|
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH; |
|
|
|
int flags; |
|
#if defined( CLIENT_WEAPONS ) |
|
flags = FEV_NOTHOST; |
|
#else |
|
flags = 0; |
|
#endif |
|
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usHornetFire, 0.0f, g_vecZero, g_vecZero, 0.0f, 0.0f, FIREMODE_TRACK, 0, 0, 0 ); |
|
|
|
// player "shoot" animation |
|
m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
m_flNextPrimaryAttack = m_flNextPrimaryAttack + 0.25f; |
|
|
|
if( m_flNextPrimaryAttack < UTIL_WeaponTimeBase() ) |
|
{ |
|
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25f; |
|
} |
|
|
|
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); |
|
} |
|
|
|
void CHgun::OldSecondaryAttack( void ) |
|
{ |
|
Reload(); |
|
|
|
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) |
|
{ |
|
return; |
|
} |
|
|
|
//Wouldn't be a bad idea to completely predict these, since they fly so fast... |
|
#ifndef CLIENT_DLL |
|
CBaseEntity *pHornet; |
|
Vector vecSrc; |
|
|
|
UTIL_MakeVectors( m_pPlayer->pev->v_angle ); |
|
|
|
vecSrc = m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 16.0f + gpGlobals->v_right * 8.0f + gpGlobals->v_up * -12.0f; |
|
|
|
m_iFirePhase++; |
|
switch( m_iFirePhase ) |
|
{ |
|
case 1: |
|
vecSrc = vecSrc + gpGlobals->v_up * 8.0f; |
|
break; |
|
case 2: |
|
vecSrc = vecSrc + gpGlobals->v_up * 8.0f; |
|
vecSrc = vecSrc + gpGlobals->v_right * 8.0f; |
|
break; |
|
case 3: |
|
vecSrc = vecSrc + gpGlobals->v_right * 8.0f; |
|
break; |
|
case 4: |
|
vecSrc = vecSrc + gpGlobals->v_up * -8.0f; |
|
vecSrc = vecSrc + gpGlobals->v_right * 8.0f; |
|
break; |
|
case 5: |
|
vecSrc = vecSrc + gpGlobals->v_up * -8.0f; |
|
break; |
|
case 6: |
|
vecSrc = vecSrc + gpGlobals->v_up * -8.0f; |
|
vecSrc = vecSrc + gpGlobals->v_right * -8.0f; |
|
break; |
|
case 7: |
|
vecSrc = vecSrc + gpGlobals->v_right * -8.0f; |
|
break; |
|
case 8: |
|
vecSrc = vecSrc + gpGlobals->v_up * 8.0f; |
|
vecSrc = vecSrc + gpGlobals->v_right * -8.0f; |
|
m_iFirePhase = 0; |
|
break; |
|
} |
|
|
|
pHornet = CBaseEntity::Create( "hornet", vecSrc, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); |
|
pHornet->pev->velocity = gpGlobals->v_forward * 1200.0f; |
|
pHornet->pev->angles = UTIL_VecToAngles( pHornet->pev->velocity ); |
|
|
|
pHornet->SetThink( &CHornet::StartDart ); |
|
|
|
m_flRechargeTime = gpGlobals->time + 0.5f; |
|
#endif |
|
int flags; |
|
#if defined( CLIENT_WEAPONS ) |
|
flags = FEV_NOTHOST; |
|
#else |
|
flags = 0; |
|
#endif |
|
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usHornetFire, 0.0f, g_vecZero, g_vecZero, 0.0f, 0.0f, FIREMODE_FAST, 0, 0, 0 ); |
|
|
|
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; |
|
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME; |
|
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH; |
|
|
|
// player "shoot" animation |
|
m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.1f; |
|
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10.0f, 15.0f ); |
|
} |
|
|
|
void CHgun::Reload( void ) |
|
{ |
|
m_iMaxammo = (bm_hornet_mod.value) ? 12 : 8; |
|
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] >= m_iMaxammo ) |
|
return; |
|
|
|
while( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] < m_iMaxammo && m_flRechargeTime < gpGlobals->time ) |
|
{ |
|
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]++; |
|
m_flRechargeTime += 0.5f; |
|
} |
|
} |
|
|
|
void CHgun::WeaponIdle( void ) |
|
{ |
|
Reload(); |
|
m_iFirePhase = HGUN_IDLE; |
|
if( m_iBeams ) |
|
ClearBeams(); |
|
|
|
if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() ) |
|
return; |
|
|
|
int iAnim; |
|
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0.0f, 1.0f ); |
|
if( flRand <= 0.75f ) |
|
{ |
|
iAnim = HGUN_IDLE1; |
|
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 30.0f / 16.0f * 2.0f; |
|
} |
|
else if( flRand <= 0.875f ) |
|
{ |
|
iAnim = HGUN_FIDGETSWAY; |
|
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 40.0f / 16.0f; |
|
} |
|
else |
|
{ |
|
iAnim = HGUN_FIDGETSHAKE; |
|
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 35.0f / 16.0f; |
|
} |
|
SendWeaponAnim( iAnim ); |
|
} |
|
#endif
|
|
|