mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-07 17:29:36 +00:00
add hl1,portal,dod source code
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hl1_basecombatweapon_shared.h"
|
||||
|
||||
#include "hl1_player_shared.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( basehl1combatweapon, CBaseHL1CombatWeapon );
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( BaseHL1CombatWeapon , DT_BaseHL1CombatWeapon )
|
||||
|
||||
BEGIN_NETWORK_TABLE( CBaseHL1CombatWeapon , DT_BaseHL1CombatWeapon )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CBaseHL1CombatWeapon )
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
|
||||
void CBaseHL1CombatWeapon::Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
|
||||
SetSolid( SOLID_BBOX );
|
||||
m_flNextEmptySoundTime = 0.0f;
|
||||
|
||||
// Weapons won't show up in trace calls if they are being carried...
|
||||
RemoveEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID );
|
||||
|
||||
m_iState = WEAPON_NOT_CARRIED;
|
||||
// Assume
|
||||
m_nViewModelIndex = 0;
|
||||
|
||||
// If I use clips, set my clips to the default
|
||||
if ( UsesClipsForAmmo1() )
|
||||
{
|
||||
m_iClip1 = GetDefaultClip1();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPrimaryAmmoCount( GetDefaultClip1() );
|
||||
m_iClip1 = WEAPON_NOCLIP;
|
||||
}
|
||||
if ( UsesClipsForAmmo2() )
|
||||
{
|
||||
m_iClip2 = GetDefaultClip2();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSecondaryAmmoCount( GetDefaultClip2() );
|
||||
m_iClip2 = WEAPON_NOCLIP;
|
||||
}
|
||||
|
||||
SetModel( GetWorldModel() );
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
FallInit();
|
||||
SetCollisionGroup( COLLISION_GROUP_WEAPON );
|
||||
|
||||
m_takedamage = DAMAGE_EVENTS_ONLY;
|
||||
|
||||
SetBlocksLOS( false );
|
||||
|
||||
// Default to non-removeable, because we don't want the
|
||||
// game_weapon_manager entity to remove weapons that have
|
||||
// been hand-placed by level designers. We only want to remove
|
||||
// weapons that have been dropped by NPC's.
|
||||
SetRemoveable( false );
|
||||
#endif
|
||||
|
||||
//Make weapons easier to pick up in MP.
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
CollisionProp()->UseTriggerBounds( true, 36 );
|
||||
}
|
||||
else
|
||||
{
|
||||
CollisionProp()->UseTriggerBounds( true, 24 );
|
||||
}
|
||||
|
||||
// Use more efficient bbox culling on the client. Otherwise, it'll setup bones for most
|
||||
// characters even when they're not in the frustum.
|
||||
AddEffects( EF_BONEMERGE_FASTCULL );
|
||||
}
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
|
||||
#define HL1_BOB_CYCLE_MIN 1.0f
|
||||
#define HL1_BOB_CYCLE_MAX 0.45f
|
||||
#define HL1_BOB 0.002f
|
||||
#define HL1_BOB_UP 0.5f
|
||||
|
||||
float g_lateralBob;
|
||||
float g_verticalBob;
|
||||
|
||||
static ConVar cl_bobcycle( "cl_bobcycle","0.8" );
|
||||
static ConVar cl_bob( "cl_bob","0.002" );
|
||||
static ConVar cl_bobup( "cl_bobup","0.5" );
|
||||
|
||||
// Register these cvars if needed for easy tweaking
|
||||
static ConVar v_iyaw_cycle( "v_iyaw_cycle", "2"/*, FCVAR_UNREGISTERED*/ );
|
||||
static ConVar v_iroll_cycle( "v_iroll_cycle", "0.5"/*, FCVAR_UNREGISTERED*/ );
|
||||
static ConVar v_ipitch_cycle( "v_ipitch_cycle", "1"/*, FCVAR_UNREGISTERED*/ );
|
||||
static ConVar v_iyaw_level( "v_iyaw_level", "0.3"/*, FCVAR_UNREGISTERED*/ );
|
||||
static ConVar v_iroll_level( "v_iroll_level", "0.1"/*, FCVAR_UNREGISTERED*/ );
|
||||
static ConVar v_ipitch_level( "v_ipitch_level", "0.3"/*, FCVAR_UNREGISTERED*/ );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float CBaseHL1CombatWeapon::CalcViewmodelBob( void )
|
||||
{
|
||||
static float bobtime;
|
||||
static float lastbobtime;
|
||||
float cycle;
|
||||
|
||||
CBasePlayer *player = ToBasePlayer( GetOwner() );
|
||||
//Assert( player );
|
||||
|
||||
//NOTENOTE: For now, let this cycle continue when in the air, because it snaps badly without it
|
||||
|
||||
if ( ( !gpGlobals->frametime ) || ( player == NULL ) )
|
||||
{
|
||||
//NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
|
||||
return 0.0f;// just use old value
|
||||
}
|
||||
|
||||
//Find the speed of the player
|
||||
float speed = player->GetLocalVelocity().Length2D();
|
||||
|
||||
//FIXME: This maximum speed value must come from the server.
|
||||
// MaxSpeed() is not sufficient for dealing with sprinting - jdw
|
||||
|
||||
speed = clamp( speed, -320, 320 );
|
||||
|
||||
float bob_offset = RemapVal( speed, 0, 320, 0.0f, 1.0f );
|
||||
|
||||
bobtime += ( gpGlobals->curtime - lastbobtime ) * bob_offset;
|
||||
lastbobtime = gpGlobals->curtime;
|
||||
|
||||
//Calculate the vertical bob
|
||||
cycle = bobtime - (int)(bobtime/HL1_BOB_CYCLE_MAX)*HL1_BOB_CYCLE_MAX;
|
||||
cycle /= HL1_BOB_CYCLE_MAX;
|
||||
|
||||
if ( cycle < HL1_BOB_UP )
|
||||
{
|
||||
cycle = M_PI * cycle / HL1_BOB_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
cycle = M_PI + M_PI*(cycle-HL1_BOB_UP)/(1.0 - HL1_BOB_UP);
|
||||
}
|
||||
|
||||
g_verticalBob = speed*0.005f;
|
||||
g_verticalBob = g_verticalBob*0.3 + g_verticalBob*0.7*sin(cycle);
|
||||
|
||||
g_verticalBob = clamp( g_verticalBob, -7.0f, 4.0f );
|
||||
|
||||
//Calculate the lateral bob
|
||||
cycle = bobtime - (int)(bobtime/HL1_BOB_CYCLE_MAX*2)*HL1_BOB_CYCLE_MAX*2;
|
||||
cycle /= HL1_BOB_CYCLE_MAX*2;
|
||||
|
||||
if ( cycle < HL1_BOB_UP )
|
||||
{
|
||||
cycle = M_PI * cycle / HL1_BOB_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
cycle = M_PI + M_PI*(cycle-HL1_BOB_UP)/(1.0 - HL1_BOB_UP);
|
||||
}
|
||||
|
||||
g_lateralBob = speed*0.005f;
|
||||
g_lateralBob = g_lateralBob*0.3 + g_lateralBob*0.7*sin(cycle);
|
||||
g_lateralBob = clamp( g_lateralBob, -7.0f, 4.0f );
|
||||
|
||||
//NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &origin -
|
||||
// &angles -
|
||||
// viewmodelindex -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseHL1CombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
|
||||
{
|
||||
Vector forward, right;
|
||||
AngleVectors( angles, &forward, &right, NULL );
|
||||
|
||||
CalcViewmodelBob();
|
||||
|
||||
// Apply bob, but scaled down to 40%
|
||||
VectorMA( origin, g_verticalBob * 0.1f, forward, origin );
|
||||
|
||||
// Z bob a bit more
|
||||
origin[2] += g_verticalBob * 0.1f;
|
||||
|
||||
// bob the angles
|
||||
angles[ ROLL ] += g_verticalBob * 0.5f;
|
||||
angles[ PITCH ] -= g_verticalBob * 0.4f;
|
||||
|
||||
angles[ YAW ] -= g_lateralBob * 0.3f;
|
||||
|
||||
VectorMA( origin, g_lateralBob * 0.8f, right, origin );
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
Vector CBaseHL1CombatWeapon::GetSoundEmissionOrigin() const
|
||||
{
|
||||
if ( gpGlobals->maxClients == 1 || !GetOwner() )
|
||||
return CBaseCombatWeapon::GetSoundEmissionOrigin();
|
||||
|
||||
// Vector vecOwner = GetOwner()->GetSoundEmissionOrigin();
|
||||
// Vector vecThis = WorldSpaceCenter();
|
||||
// DevMsg("SoundEmissionOrigin: Owner: %4.1f,%4.1f,%4.1f Default:%4.1f,%4.1f,%4.1f\n",
|
||||
// vecOwner.x, vecOwner.y, vecOwner.z,
|
||||
// vecThis.x, vecThis.y, vecThis.z );
|
||||
|
||||
// TEMP fix for HL1MP... sounds are sometimes beeing emitted underneath the ground
|
||||
return GetOwner()->GetSoundEmissionOrigin();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "basecombatweapon_shared.h"
|
||||
|
||||
#ifndef BASEHLCOMBATWEAPON_SHARED_H
|
||||
#define BASEHLCOMBATWEAPON_SHARED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
#define CBaseHL1CombatWeapon C_BaseHL1CombatWeapon
|
||||
#endif
|
||||
|
||||
class CBaseHL1CombatWeapon : public CBaseCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CBaseHL1CombatWeapon, CBaseCombatWeapon );
|
||||
public:
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
public:
|
||||
void Spawn( void );
|
||||
|
||||
public:
|
||||
// Server Only Methods
|
||||
#if !defined( CLIENT_DLL )
|
||||
DECLARE_DATADESC();
|
||||
|
||||
virtual void Precache();
|
||||
|
||||
void FallInit( void ); // prepare to fall to the ground
|
||||
virtual void FallThink( void ); // make the weapon fall to the ground after spawning
|
||||
|
||||
void EjectShell( CBaseEntity *pPlayer, int iType );
|
||||
|
||||
Vector GetSoundEmissionOrigin() const;
|
||||
#else
|
||||
|
||||
virtual void AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles );
|
||||
virtual float CalcViewmodelBob( void );
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // BASEHLCOMBATWEAPON_SHARED_H
|
||||
@@ -0,0 +1,305 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "gamemovement.h"
|
||||
#include "in_buttons.h"
|
||||
#include <stdarg.h>
|
||||
#include "movevars_shared.h"
|
||||
#include "engine/IEngineTrace.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "decals.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "hl1_gamemovement.h"
|
||||
|
||||
|
||||
// Expose our interface.
|
||||
static CHL1GameMovement g_GameMovement;
|
||||
IGameMovement *g_pGameMovement = ( IGameMovement * )&g_GameMovement;
|
||||
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CGameMovement, IGameMovement, INTERFACENAME_GAMEMOVEMENT, g_GameMovement );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "hl1/c_hl1mp_player.h"
|
||||
#else
|
||||
#include "hl1mp_player.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHL1GameMovement::CheckJumpButton( void )
|
||||
{
|
||||
m_pHL1Player = ToHL1Player( player );
|
||||
|
||||
Assert( m_pHL1Player );
|
||||
|
||||
if (m_pHL1Player->pl.deadflag)
|
||||
{
|
||||
mv->m_nOldButtons |= IN_JUMP ; // don't jump again until released
|
||||
return false;
|
||||
}
|
||||
|
||||
// See if we are waterjumping. If so, decrement count and return.
|
||||
if (m_pHL1Player->m_flWaterJumpTime)
|
||||
{
|
||||
m_pHL1Player->m_flWaterJumpTime -= gpGlobals->frametime;
|
||||
if (m_pHL1Player->m_flWaterJumpTime < 0)
|
||||
m_pHL1Player->m_flWaterJumpTime = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are in the water most of the way...
|
||||
if ( m_pHL1Player->GetWaterLevel() >= 2 )
|
||||
{
|
||||
// swimming, not jumping
|
||||
SetGroundEntity( NULL );
|
||||
|
||||
if(m_pHL1Player->GetWaterType() == CONTENTS_WATER) // We move up a certain amount
|
||||
mv->m_vecVelocity[2] = 100;
|
||||
else if (m_pHL1Player->GetWaterType() == CONTENTS_SLIME)
|
||||
mv->m_vecVelocity[2] = 80;
|
||||
|
||||
// play swiming sound
|
||||
if ( m_pHL1Player->m_flSwimSoundTime <= 0 )
|
||||
{
|
||||
// Don't play sound again for 1 second
|
||||
m_pHL1Player->m_flSwimSoundTime = 1000;
|
||||
PlaySwimSound();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// No more effect
|
||||
if (m_pHL1Player->GetGroundEntity() == NULL)
|
||||
{
|
||||
mv->m_nOldButtons |= IN_JUMP;
|
||||
return false; // in air, so no effect
|
||||
}
|
||||
|
||||
if ( mv->m_nOldButtons & IN_JUMP )
|
||||
return false; // don't pogo stick
|
||||
|
||||
// In the air now.
|
||||
SetGroundEntity( NULL );
|
||||
|
||||
m_pHL1Player->PlayStepSound( (Vector &)mv->GetAbsOrigin(), player->GetSurfaceData(), 1.0, true );
|
||||
|
||||
MoveHelper()->PlayerSetAnimation( PLAYER_JUMP );
|
||||
|
||||
float flGroundFactor = 1.0f;
|
||||
if ( player->GetSurfaceData() )
|
||||
{
|
||||
flGroundFactor = 1.0;//player->GetSurfaceData()->game.jumpFactor;
|
||||
}
|
||||
|
||||
// Acclerate upward
|
||||
// If we are ducking...
|
||||
float startz = mv->m_vecVelocity[2];
|
||||
if ( ( m_pHL1Player->m_Local.m_bDucking ) || ( m_pHL1Player->GetFlags() & FL_DUCKING ) )
|
||||
{
|
||||
// d = 0.5 * g * t^2 - distance traveled with linear accel
|
||||
// t = sqrt(2.0 * 45 / g) - how long to fall 45 units
|
||||
// v = g * t - velocity at the end (just invert it to jump up that high)
|
||||
// v = g * sqrt(2.0 * 45 / g )
|
||||
// v^2 = g * g * 2.0 * 45 / g
|
||||
// v = sqrt( g * 2.0 * 45 )
|
||||
|
||||
// Adjust for super long jump module
|
||||
// UNDONE -- note this should be based on forward angles, not current velocity.
|
||||
if ( m_pHL1Player->m_bHasLongJump &&
|
||||
( mv->m_nButtons & IN_DUCK ) &&
|
||||
( m_pHL1Player->m_Local.m_flDucktime > 0 ) &&
|
||||
mv->m_vecVelocity.Length() > 50 )
|
||||
{
|
||||
m_pHL1Player->m_Local.m_vecPunchAngle.Set( PITCH, -5 );
|
||||
|
||||
mv->m_vecVelocity = m_vecForward * PLAYER_LONGJUMP_SPEED * 1.6;
|
||||
mv->m_vecVelocity.z = sqrt(2 * 800 * 56.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mv->m_vecVelocity[2] = flGroundFactor * sqrt(2 * 800 * 45.0); // 2 * gravity * height
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mv->m_vecVelocity[2] += flGroundFactor * sqrt(2 * 800 * 45.0); // 2 * gravity * height
|
||||
}
|
||||
FinishGravity();
|
||||
|
||||
mv->m_outWishVel.z += mv->m_vecVelocity[2] - startz;
|
||||
mv->m_outStepHeight += 0.1f;
|
||||
|
||||
if ( gpGlobals->maxClients > 1 )
|
||||
#ifdef CLIENT_DLL
|
||||
(dynamic_cast<C_HL1MP_Player*>(m_pHL1Player))->DoAnimationEvent( PLAYERANIMEVENT_JUMP );
|
||||
#else
|
||||
(dynamic_cast<CHL1MP_Player*>(m_pHL1Player))->DoAnimationEvent( PLAYERANIMEVENT_JUMP );
|
||||
#endif
|
||||
|
||||
// Flag that we jumped.
|
||||
mv->m_nOldButtons |= IN_JUMP; // don't jump again until released
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: See if duck button is pressed and do the appropriate things
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHL1GameMovement::Duck( void )
|
||||
{
|
||||
int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame
|
||||
int buttonsPressed = buttonsChanged & mv->m_nButtons; // The changed ones still down are "pressed"
|
||||
int buttonsReleased = buttonsChanged & mv->m_nOldButtons; // The changed ones which were previously down are "released"
|
||||
|
||||
// Check to see if we are in the air.
|
||||
bool bInAir = ( player->GetGroundEntity() == NULL );
|
||||
bool bInDuck = ( player->GetFlags() & FL_DUCKING ) ? true : false;
|
||||
|
||||
if ( mv->m_nButtons & IN_DUCK )
|
||||
{
|
||||
mv->m_nOldButtons |= IN_DUCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
mv->m_nOldButtons &= ~IN_DUCK;
|
||||
}
|
||||
|
||||
// Handle death.
|
||||
if ( IsDead() )
|
||||
{
|
||||
if ( bInDuck )
|
||||
{
|
||||
// Unduck
|
||||
FinishUnDuck();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
HandleDuckingSpeedCrop();
|
||||
|
||||
// If the player is holding down the duck button, the player is in duck transition, ducking, or duck-jumping.
|
||||
if ( ( mv->m_nButtons & IN_DUCK ) || player->m_Local.m_bDucking || bInDuck )
|
||||
{
|
||||
if ( ( mv->m_nButtons & IN_DUCK ) )
|
||||
{
|
||||
// Have the duck button pressed, but the player currently isn't in the duck position.
|
||||
if ( ( buttonsPressed & IN_DUCK ) && !bInDuck )
|
||||
{
|
||||
// Use 1 second so super long jump will work
|
||||
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
|
||||
player->m_Local.m_bDucking = true;
|
||||
}
|
||||
|
||||
// The player is in duck transition and not duck-jumping.
|
||||
if ( player->m_Local.m_bDucking )
|
||||
{
|
||||
float flDuckMilliseconds = MAX( 0.0f, GAMEMOVEMENT_DUCK_TIME - ( float )player->m_Local.m_flDucktime );
|
||||
float flDuckSeconds = flDuckMilliseconds / GAMEMOVEMENT_DUCK_TIME;
|
||||
|
||||
// Finish in duck transition when transition time is over, in "duck", in air.
|
||||
if ( ( flDuckSeconds > TIME_TO_DUCK ) || bInDuck || bInAir )
|
||||
{
|
||||
FinishDuck();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calc parametric time
|
||||
float flDuckFraction = SimpleSpline( flDuckSeconds / TIME_TO_DUCK );
|
||||
SetDuckedEyeOffset( flDuckFraction );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to unduck unless automovement is not allowed
|
||||
// NOTE: When not onground, you can always unduck
|
||||
if ( player->m_Local.m_bAllowAutoMovement || bInAir )
|
||||
{
|
||||
if ( ( buttonsReleased & IN_DUCK ) && bInDuck )
|
||||
{
|
||||
// Use 1 second so super long jump will work
|
||||
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
|
||||
}
|
||||
|
||||
// Check to see if we are capable of unducking.
|
||||
if ( CanUnduck() )
|
||||
{
|
||||
// or unducking
|
||||
if ( ( player->m_Local.m_bDucking || player->m_Local.m_bDucked ) )
|
||||
{
|
||||
float flDuckMilliseconds = MAX( 0.0f, GAMEMOVEMENT_DUCK_TIME - (float)player->m_Local.m_flDucktime );
|
||||
float flDuckSeconds = flDuckMilliseconds / GAMEMOVEMENT_DUCK_TIME;
|
||||
|
||||
// Finish ducking immediately if duck time is over or not on ground
|
||||
if ( flDuckSeconds > TIME_TO_UNDUCK || ( bInAir ) )
|
||||
{
|
||||
FinishUnDuck();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calc parametric time
|
||||
float flDuckFraction = SimpleSpline( 1.0f - ( flDuckSeconds / TIME_TO_UNDUCK ) );
|
||||
SetDuckedEyeOffset( flDuckFraction );
|
||||
player->m_Local.m_bDucking = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Still under something where we can't unduck, so make sure we reset this timer so
|
||||
// that we'll unduck once we exit the tunnel, etc.
|
||||
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
|
||||
SetDuckedEyeOffset( 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CHL1GameMovement::HandleDuckingSpeedCrop()
|
||||
{
|
||||
if ( !( m_iSpeedCropped & SPEED_CROPPED_DUCK ) )
|
||||
{
|
||||
if ( player->GetFlags() & FL_DUCKING )
|
||||
{
|
||||
float frac = 0.33333333f;
|
||||
mv->m_flForwardMove *= frac;
|
||||
mv->m_flSideMove *= frac;
|
||||
mv->m_flUpMove *= frac;
|
||||
m_iSpeedCropped |= SPEED_CROPPED_DUCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CHL1GameMovement::CheckParameters( void )
|
||||
{
|
||||
if ( mv->m_nButtons & IN_SPEED )
|
||||
{
|
||||
mv->m_flClientMaxSpeed = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
mv->m_flClientMaxSpeed = mv->m_flMaxSpeed;
|
||||
}
|
||||
|
||||
CHL1_Player* pHL1Player = dynamic_cast<CHL1_Player*>(player);
|
||||
if( pHL1Player && pHL1Player->IsPullingObject() )
|
||||
{
|
||||
mv->m_flClientMaxSpeed = mv->m_flMaxSpeed * 0.5f;
|
||||
}
|
||||
|
||||
BaseClass::CheckParameters();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_HL1_GAMEMOVEMENT_H
|
||||
#define C_HL1_GAMEMOVEMENT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "hl1/hl1_c_player.h"
|
||||
#else
|
||||
#include "hl1_player.h"
|
||||
#endif
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
class CHL1_Player;
|
||||
#define CHL1_Player C_HL1_Player
|
||||
#endif
|
||||
|
||||
#define PLAYER_LONGJUMP_SPEED 350 // how fast we longjump
|
||||
|
||||
class CHL1GameMovement : public CGameMovement
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CHL1GameMovement, CGameMovement );
|
||||
|
||||
virtual bool CheckJumpButton( void );
|
||||
|
||||
// Duck
|
||||
virtual void Duck( void );
|
||||
virtual void HandleDuckingSpeedCrop();
|
||||
virtual void CheckParameters( void );
|
||||
|
||||
protected:
|
||||
CHL1_Player *m_pHL1Player;
|
||||
};
|
||||
|
||||
#endif //C_HL1_GAMEMOVEMENT_H
|
||||
@@ -0,0 +1,741 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: The Half-Life 1 game rules, such as the relationship tables and ammo
|
||||
// damage cvars.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hl1_gamerules.h"
|
||||
#include "ammodef.h"
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
|
||||
#else
|
||||
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
#include "gamerules.h"
|
||||
#include "teamplay_gamerules.h"
|
||||
#include "hl1_player.h"
|
||||
#include "voice_gamemgr.h"
|
||||
#include "hl1mp_weapon_satchel.h"
|
||||
#endif
|
||||
|
||||
|
||||
REGISTER_GAMERULES_CLASS( CHalfLife1 );
|
||||
|
||||
|
||||
ConVar sk_plr_dmg_crowbar ( "sk_plr_dmg_crowbar", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_npc_dmg_9mm_bullet ( "sk_npc_dmg_9mm_bullet", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_plr_dmg_9mm_bullet ( "sk_plr_dmg_9mm_bullet", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_9mm_bullet ( "sk_max_9mm_bullet", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_npc_dmg_9mmAR_bullet ( "sk_npc_dmg_9mmAR_bullet", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_357_bullet ( "sk_plr_dmg_357_bullet", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_357_bullet ( "sk_max_357_bullet", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_buckshot ( "sk_plr_dmg_buckshot", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_buckshot ( "sk_max_buckshot", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_mp5_grenade ( "sk_plr_dmg_mp5_grenade", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_mp5_grenade ( "sk_max_mp5_grenade", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_mp5_grenade_radius ( "sk_mp5_grenade_radius", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_rpg ( "sk_plr_dmg_rpg", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_rpg_rocket ( "sk_max_rpg_rocket", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_xbow_bolt_plr ( "sk_plr_dmg_xbow_bolt_plr", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_plr_dmg_xbow_bolt_npc ( "sk_plr_dmg_xbow_bolt_npc", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_xbow_bolt ( "sk_max_xbow_bolt", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_egon_narrow ( "sk_plr_dmg_egon_narrow", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_plr_dmg_egon_wide ( "sk_plr_dmg_egon_wide", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_uranium ( "sk_max_uranium", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_gauss ( "sk_plr_dmg_gauss", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_grenade ( "sk_plr_dmg_grenade", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_grenade ( "sk_max_grenade", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_hornet ( "sk_plr_dmg_hornet", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_npc_dmg_hornet ( "sk_npc_dmg_hornet", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_hornet ( "sk_max_hornet", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_max_snark ( "sk_max_snark", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_tripmine ( "sk_plr_dmg_tripmine", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_tripmine ( "sk_max_tripmine", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_plr_dmg_satchel ( "sk_plr_dmg_satchel", "0", FCVAR_REPLICATED );
|
||||
ConVar sk_max_satchel ( "sk_max_satchel", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_npc_dmg_12mm_bullet ( "sk_npc_dmg_12mm_bullet", "0", FCVAR_REPLICATED );
|
||||
|
||||
ConVar sk_mp_dmg_multiplier ( "sk_mp_dmg_multiplier", "2.0" );
|
||||
|
||||
// Damage Queries.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CHalfLife1::Damage_GetShowOnHud( void )
|
||||
{
|
||||
int iDamage = (DMG_POISON | DMG_ACID | DMG_DISSOLVE/*DMG_FREEZE | DMG_SLOWFREEZE*/ | DMG_DROWN | DMG_BURN | DMG_SLOWBURN | DMG_NERVEGAS | DMG_RADIATION | DMG_SHOCK);
|
||||
return iDamage;
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
extern bool g_fGameOver;
|
||||
|
||||
const char *CHalfLife1::GetGameDescription( void )
|
||||
{
|
||||
if ( IsMultiplayer() )
|
||||
{
|
||||
return "Half-Life 1: Deathmatch";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Half-Life 1";
|
||||
}
|
||||
}
|
||||
|
||||
class CVoiceGameMgrHelper : public IVoiceGameMgrHelper
|
||||
{
|
||||
public:
|
||||
virtual bool CanPlayerHearPlayer( CBasePlayer *pListener, CBasePlayer *pTalker, bool &bProximity )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
CVoiceGameMgrHelper g_VoiceGameMgrHelper;
|
||||
IVoiceGameMgrHelper *g_pVoiceGameMgrHelper = &g_VoiceGameMgrHelper;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input :
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
CHalfLife1::CHalfLife1()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called each time a player uses a "cmd" command
|
||||
// Input : *pEdict - the player who issued the command
|
||||
// Use engine.Cmd_Argv, engine.Cmd_Argv, and engine.Cmd_Argc to get
|
||||
// pointers the character string command.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHalfLife1::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
|
||||
{
|
||||
if( BaseClass::ClientCommand( pEdict, args ) )
|
||||
return true;
|
||||
|
||||
CHL1_Player *pPlayer = (CHL1_Player *) pEdict;
|
||||
|
||||
if ( pPlayer->ClientCommand( args ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Player has just spawned. Equip them.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHalfLife1::PlayerSpawn( CBasePlayer *pPlayer )
|
||||
{
|
||||
// pPlayer->EquipSuit();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: MULTIPLAYER BODY QUE HANDLING
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCorpse : public CBaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( CCorpse, CBaseAnimating );
|
||||
public:
|
||||
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; }
|
||||
|
||||
public:
|
||||
CNetworkVar( int, m_nReferencePlayer );
|
||||
};
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CCorpse, DT_Corpse)
|
||||
SendPropInt( SENDINFO(m_nReferencePlayer), 10, SPROP_UNSIGNED )
|
||||
END_SEND_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( bodyque, CCorpse );
|
||||
|
||||
|
||||
CCorpse *g_pBodyQueueHead;
|
||||
|
||||
void InitBodyQue(void)
|
||||
{
|
||||
CCorpse *pEntity = ( CCorpse * )CreateEntityByName( "bodyque" );
|
||||
pEntity->AddEFlags( EFL_KEEP_ON_RECREATE_ENTITIES );
|
||||
g_pBodyQueueHead = pEntity;
|
||||
CCorpse *p = g_pBodyQueueHead;
|
||||
|
||||
// Reserve 3 more slots for dead bodies
|
||||
for ( int i = 0; i < 3; i++ )
|
||||
{
|
||||
CCorpse *next = ( CCorpse * )CreateEntityByName( "bodyque" );
|
||||
next->AddEFlags( EFL_KEEP_ON_RECREATE_ENTITIES );
|
||||
p->SetOwnerEntity( next );
|
||||
p = next;
|
||||
}
|
||||
|
||||
p->SetOwnerEntity( g_pBodyQueueHead );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: make a body que entry for the given ent so the ent can be respawned elsewhere
|
||||
// GLOBALS ASSUMED SET: g_eoBodyQueueHead
|
||||
//-----------------------------------------------------------------------------
|
||||
void CopyToBodyQue( CBaseAnimating *pCorpse )
|
||||
{
|
||||
if ( pCorpse->IsEffectActive( EF_NODRAW ) )
|
||||
return;
|
||||
|
||||
CCorpse *pHead = g_pBodyQueueHead;
|
||||
|
||||
pHead->CopyAnimationDataFrom( pCorpse );
|
||||
|
||||
pHead->SetMoveType( MOVETYPE_FLYGRAVITY );
|
||||
pHead->SetAbsVelocity( pCorpse->GetAbsVelocity() );
|
||||
pHead->ClearFlags();
|
||||
pHead->m_nReferencePlayer = ENTINDEX( pCorpse );
|
||||
|
||||
pHead->SetLocalAngles( pCorpse->GetAbsAngles() );
|
||||
UTIL_SetOrigin(pHead, pCorpse->GetAbsOrigin());
|
||||
|
||||
UTIL_SetSize(pHead, pCorpse->WorldAlignMins(), pCorpse->WorldAlignMaxs());
|
||||
g_pBodyQueueHead = (CCorpse *)pHead->GetOwnerEntity();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Initialize all default class relationships
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CHalfLife1::InitDefaultAIRelationships( void )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Allocate memory for default relationships
|
||||
CBaseCombatCharacter::AllocateDefaultRelationships();
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// First initialize table so we can report missing relationships
|
||||
// --------------------------------------------------------------
|
||||
for (i=0;i<NUM_AI_CLASSES;i++)
|
||||
{
|
||||
for (j=0;j<NUM_AI_CLASSES;j++)
|
||||
{
|
||||
// By default all relationships are neutral of priority zero
|
||||
CBaseCombatCharacter::SetDefaultRelationship( (Class_T)i, (Class_T)j, D_NU, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_NONE
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_PLAYER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_HUMAN_PASSIVE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_PLAYER_ALLY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_PREY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_HUMAN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_HUMAN_PASSIVE
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_PLAYER, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_HUMAN_PASSIVE, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_PLAYER_ALLY, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_PREY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_MILITARY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_PREDATOR, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_PLAYER
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_PLAYER, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_HUMAN_PASSIVE, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_PLAYER_ALLY, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_MACHINE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_PLAYER_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_PLAYER_ALLY
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_PLAYER, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_HUMAN_PASSIVE, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_PLAYER_ALLY, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_MACHINE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_PREY
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_PREY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_PREDATOR, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_MILITARY
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_PREY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_MACHINE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_MONSTER
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_PREY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_MACHINE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_PREDATOR
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_HUMAN_MILITARY
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_HUMAN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_MACHINE
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_HUMAN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_PLAYER_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_BIOWEAPON
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_MILITARY, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_PLAYER_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_PLAYER_BIOWEAPON
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_INSECT
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_NONE, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_MACHINE, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_PLAYER, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_HUMAN_PASSIVE, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_HUMAN_MILITARY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_MONSTER, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_PREY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_PREDATOR, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_PLAYER_ALLY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_INSECT, D_NU, 0 );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Return classify text for classify type
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
const char* CHalfLife1::AIClassText(int classType)
|
||||
{
|
||||
switch (classType)
|
||||
{
|
||||
case CLASS_NONE: return "CLASS_NONE";
|
||||
case CLASS_HUMAN_PASSIVE: return "CLASS_HUMAN_PASSIVE";
|
||||
case CLASS_PLAYER_ALLY: return "CLASS_PLAYER_ALLY";
|
||||
case CLASS_PLAYER: return "CLASS_PLAYER";
|
||||
case CLASS_ALIEN_PREY: return "CLASS_ALIEN_PREY";
|
||||
case CLASS_ALIEN_MILITARY: return "CLASS_ALIEN_MILITARY";
|
||||
case CLASS_ALIEN_MONSTER: return "CLASS_ALIEN_MONSTER";
|
||||
case CLASS_ALIEN_PREDATOR: return "CLASS_ALIEN_PREDATOR";
|
||||
case CLASS_HUMAN_MILITARY: return "CLASS_HUMAN_MILITARY";
|
||||
case CLASS_MACHINE: return "CLASS_MACHINE";
|
||||
case CLASS_ALIEN_BIOWEAPON: return "CLASS_ALIEN_BIOWEAPON";
|
||||
case CLASS_PLAYER_BIOWEAPON: return "CLASS_PLAYER_BIOWEAPON";
|
||||
|
||||
default: return "MISSING CLASS in ClassifyText()";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CHalfLife1::PlayerThink( CBasePlayer *pPlayer )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool CHalfLife1::CanHavePlayerItem( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon )
|
||||
{
|
||||
if ( FClassnameIs( pWeapon, "weapon_satchel" ) )
|
||||
{
|
||||
CWeaponSatchel *satchel = static_cast< CWeaponSatchel * >( pPlayer->Weapon_OwnsThisType( "weapon_satchel" ) );
|
||||
if ( satchel )
|
||||
{
|
||||
if ( satchel->HasChargeDeployed() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
float CHalfLife1::FlPlayerFallDamage( CBasePlayer *pPlayer )
|
||||
{
|
||||
CBaseEntity *pGroundEntity = pPlayer->GetGroundEntity();
|
||||
|
||||
if( pGroundEntity && pGroundEntity->ClassMatches( "func_breakable" ) )
|
||||
{
|
||||
// FIXME touchtrace will be wrong.
|
||||
pGroundEntity->Touch( pPlayer );
|
||||
|
||||
if( pGroundEntity->m_iHealth <= 0 )
|
||||
{
|
||||
// The breakable broke when we hit it, don't take falling damage
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return BaseClass::FlPlayerFallDamage( pPlayer );
|
||||
}
|
||||
|
||||
|
||||
class CTraceFilterHitAllExcept : public CTraceFilter
|
||||
{
|
||||
public:
|
||||
// It does have a base, but we'll never network anything below here..
|
||||
DECLARE_CLASS_NOBASE( CTraceFilterHitAllExcept );
|
||||
|
||||
CTraceFilterHitAllExcept( const IHandleEntity *passedict )
|
||||
{
|
||||
m_pPassEnt = passedict;
|
||||
}
|
||||
|
||||
bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
|
||||
{
|
||||
if ( m_pPassEnt && ( m_pPassEnt == pServerEntity ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const IHandleEntity *m_pPassEnt;
|
||||
};
|
||||
|
||||
void CHalfLife1::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore )
|
||||
{
|
||||
CBaseEntity *pEntity = NULL;
|
||||
trace_t tr;
|
||||
float flAdjustedDamage, falloff;
|
||||
Vector vecSpot;
|
||||
|
||||
Vector vecSrc = vecSrcIn;
|
||||
|
||||
if ( flRadius )
|
||||
falloff = info.GetDamage() / flRadius;
|
||||
else
|
||||
falloff = 1.0;
|
||||
|
||||
int bInWater = (UTIL_PointContents ( vecSrc ) & MASK_WATER) ? true : false;
|
||||
|
||||
vecSrc.z += 1;// in case grenade is lying on the ground
|
||||
|
||||
// iterate on all entities in the vicinity.
|
||||
for ( CEntitySphereQuery sphere( vecSrc, flRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
|
||||
{
|
||||
if ( pEntity->m_takedamage != DAMAGE_NO )
|
||||
{
|
||||
// UNDONE: this should check a damage mask, not an ignore
|
||||
if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore )
|
||||
{// houndeyes don't hurt other houndeyes with their attack
|
||||
continue;
|
||||
}
|
||||
|
||||
// blast's don't tavel into or out of water
|
||||
if (bInWater && pEntity->GetWaterLevel() == 0)
|
||||
continue;
|
||||
if (!bInWater && pEntity->GetWaterLevel() == 3)
|
||||
continue;
|
||||
|
||||
// radius damage can only be blocked by the world
|
||||
vecSpot = pEntity->BodyTarget( vecSrc );
|
||||
|
||||
CTraceFilterHitAllExcept traceFilter( info.GetInflictor() );
|
||||
UTIL_TraceLine( vecSrc, vecSpot, CONTENTS_SOLID, &traceFilter, &tr );
|
||||
|
||||
if ( tr.fraction == 1.0 || tr.m_pEnt == pEntity )
|
||||
{// the explosion can 'see' this entity, so hurt them!
|
||||
if (tr.startsolid)
|
||||
{
|
||||
// if we're stuck inside them, fixup the position and distance
|
||||
tr.endpos = vecSrc;
|
||||
tr.fraction = 0.0;
|
||||
}
|
||||
|
||||
// decrease damage for an ent that's farther from the bomb.
|
||||
flAdjustedDamage = ( vecSrc - tr.endpos ).Length() * falloff;
|
||||
flAdjustedDamage = info.GetDamage() - flAdjustedDamage;
|
||||
|
||||
if ( flAdjustedDamage > 0 )
|
||||
{
|
||||
CTakeDamageInfo adjustedInfo = info;
|
||||
adjustedInfo.SetDamage( flAdjustedDamage );
|
||||
|
||||
Vector vecDir = vecSpot - vecSrc;
|
||||
VectorNormalize( vecDir );
|
||||
|
||||
// If we don't have a damage force, manufacture one
|
||||
if ( adjustedInfo.GetDamagePosition() == vec3_origin || adjustedInfo.GetDamageForce() == vec3_origin )
|
||||
{
|
||||
CalculateExplosiveDamageForce( &adjustedInfo, vecDir, vecSrc );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume the force passed in is the maximum force. Decay it based on falloff.
|
||||
float flForce = adjustedInfo.GetDamageForce().Length() * falloff;
|
||||
adjustedInfo.SetDamageForce( vecDir * flForce );
|
||||
adjustedInfo.SetDamagePosition( vecSrc );
|
||||
}
|
||||
|
||||
if (tr.fraction != 1.0)
|
||||
{
|
||||
ClearMultiDamage( );
|
||||
Vector dir = tr.endpos - vecSrc;
|
||||
VectorNormalize( dir );
|
||||
pEntity->DispatchTraceAttack( adjustedInfo, dir, &tr );
|
||||
ApplyMultiDamage();
|
||||
}
|
||||
else
|
||||
{
|
||||
pEntity->TakeDamage( adjustedInfo );
|
||||
}
|
||||
// Now hit all triggers along the way that respond to damage...
|
||||
Vector dir = tr.endpos - vecSrc;
|
||||
pEntity->TraceAttackToTriggers( adjustedInfo, vecSrc, tr.endpos, dir );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------- //
|
||||
// CHalfLife1 shared implementation.
|
||||
// ------------------------------------------------------------------------------------- //
|
||||
|
||||
bool CHalfLife1::ShouldCollide( int collisionGroup0, int collisionGroup1 )
|
||||
{
|
||||
// HL2 treats movement and tracing against players the same, so just remap here
|
||||
if ( collisionGroup0 == COLLISION_GROUP_PLAYER_MOVEMENT )
|
||||
{
|
||||
collisionGroup0 = COLLISION_GROUP_PLAYER;
|
||||
}
|
||||
|
||||
if( collisionGroup1 == COLLISION_GROUP_PLAYER_MOVEMENT )
|
||||
{
|
||||
collisionGroup1 = COLLISION_GROUP_PLAYER;
|
||||
}
|
||||
|
||||
if ( collisionGroup0 > collisionGroup1 )
|
||||
{
|
||||
// swap so that lowest is always first
|
||||
int tmp = collisionGroup0;
|
||||
collisionGroup0 = collisionGroup1;
|
||||
collisionGroup1 = tmp;
|
||||
}
|
||||
|
||||
return BaseClass::ShouldCollide( collisionGroup0, collisionGroup1 );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------- //
|
||||
// Global functions.
|
||||
// ------------------------------------------------------------------------------------- //
|
||||
|
||||
// shared ammo definition
|
||||
// JAY: Trying to make a more physical bullet response
|
||||
#define BULLET_MASS_GRAINS_TO_LB(grains) (0.002285*(grains)/16.0f)
|
||||
#define BULLET_MASS_GRAINS_TO_KG(grains) lbs2kg(BULLET_MASS_GRAINS_TO_LB(grains))
|
||||
|
||||
// exaggerate all of the forces, but use real numbers to keep them consistent
|
||||
#define BULLET_IMPULSE_EXAGGERATION 3
|
||||
|
||||
// convert a velocity in ft/sec and a mass in grains to an impulse in kg in/s
|
||||
#define BULLET_IMPULSE(grains, ftpersec) ((ftpersec)*12*BULLET_MASS_GRAINS_TO_KG(grains)*BULLET_IMPULSE_EXAGGERATION)
|
||||
|
||||
CAmmoDef *GetAmmoDef()
|
||||
{
|
||||
static CAmmoDef def;
|
||||
static bool bInitted = false;
|
||||
|
||||
if ( !bInitted )
|
||||
{
|
||||
bInitted = true;
|
||||
|
||||
def.AddAmmoType( "9mmRound", DMG_BULLET | DMG_NEVERGIB, TRACER_LINE, "sk_plr_dmg_9mm_bullet", "sk_npc_dmg_9mm_bullet","sk_max_9mm_bullet", BULLET_IMPULSE(500, 1325), 0 );
|
||||
def.AddAmmoType( "357Round", DMG_BULLET | DMG_NEVERGIB, TRACER_NONE, "sk_plr_dmg_357_bullet", NULL, "sk_max_357_bullet", BULLET_IMPULSE(650, 6000), 0 );
|
||||
def.AddAmmoType( "Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, "sk_plr_dmg_buckshot", NULL, "sk_max_buckshot", BULLET_IMPULSE(200, 1200), 0 );
|
||||
def.AddAmmoType( "XBowBolt", DMG_BULLET | DMG_NEVERGIB, TRACER_LINE, "sk_plr_dmg_xbow_bolt_plr",NULL, "sk_max_xbow_bolt", BULLET_IMPULSE( 200, 1200), 0 );
|
||||
def.AddAmmoType( "MP5_Grenade", DMG_BURN | DMG_BLAST, TRACER_NONE, "sk_plr_dmg_mp5_grenade", NULL, "sk_max_mp5_grenade", 0, 0 );
|
||||
def.AddAmmoType( "RPG_Rocket", DMG_BURN | DMG_BLAST, TRACER_NONE, "sk_plr_dmg_rpg", NULL, "sk_max_rpg_rocket", 0, 0 );
|
||||
def.AddAmmoType( "Uranium", DMG_ENERGYBEAM, TRACER_NONE, NULL, NULL, "sk_max_uranium", 0, 0 );
|
||||
def.AddAmmoType( "Grenade", DMG_BURN | DMG_BLAST, TRACER_NONE, "sk_plr_dmg_grenade", NULL, "sk_max_grenade", 0, 0 );
|
||||
def.AddAmmoType( "Hornet", DMG_BULLET, TRACER_NONE, "sk_plr_dmg_hornet", "sk_npc_dmg_hornet", "sk_max_hornet", BULLET_IMPULSE(100, 1200), 0 );
|
||||
def.AddAmmoType( "Snark", DMG_SLASH, TRACER_NONE, "sk_snark_dmg_bite", NULL, "sk_max_snark", 0, 0 );
|
||||
def.AddAmmoType( "TripMine", DMG_BURN | DMG_BLAST, TRACER_NONE, "sk_plr_dmg_tripmine", NULL, "sk_max_tripmine", 0, 0 );
|
||||
def.AddAmmoType( "Satchel", DMG_BURN | DMG_BLAST, TRACER_NONE, "sk_plr_dmg_satchel", NULL, "sk_max_satchel", 0, 0 );
|
||||
|
||||
def.AddAmmoType( "12mmRound", DMG_BULLET | DMG_NEVERGIB, TRACER_LINE, NULL, "sk_npc_dmg_12mm_bullet",NULL, BULLET_IMPULSE(300, 1200), 0 );
|
||||
|
||||
def.AddAmmoType( "Gravity", DMG_CRUSH, TRACER_NONE, 0, 0, 8, 0, 0 );
|
||||
}
|
||||
|
||||
return &def;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: The HL2 Game rules object
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef HL1_GAMERULES_H
|
||||
#define HL1_GAMERULES_H
|
||||
#pragma once
|
||||
|
||||
#include "gamerules.h"
|
||||
#include "singleplay_gamerules.h"
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CHalfLife1 C_HalfLife1
|
||||
#endif
|
||||
|
||||
|
||||
class CHalfLife1 : public CSingleplayRules
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( CHalfLife1, CSingleplayRules );
|
||||
|
||||
// Damage Queries.
|
||||
virtual int Damage_GetShowOnHud( void );
|
||||
|
||||
// Client/server shared implementation.
|
||||
virtual bool ShouldCollide( int collisionGroup0, int collisionGroup1 );
|
||||
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
CHalfLife1();
|
||||
virtual ~CHalfLife1() {}
|
||||
|
||||
virtual bool ClientCommand( CBaseEntity *pEdict, const CCommand &args );
|
||||
virtual void PlayerSpawn( CBasePlayer *pPlayer );
|
||||
|
||||
virtual void InitDefaultAIRelationships( void );
|
||||
virtual const char * AIClassText(int classType);
|
||||
virtual const char * GetGameDescription( void );
|
||||
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer );
|
||||
|
||||
// Ammo
|
||||
virtual void PlayerThink( CBasePlayer *pPlayer );
|
||||
bool CanHavePlayerItem( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon );
|
||||
|
||||
void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore );
|
||||
|
||||
int DefaultFOV( void ) { return 90; }
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // HL1_GAMERULES_H
|
||||
@@ -0,0 +1,373 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "tier0/vprof.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "hl1_player_shared.h"
|
||||
#include "hl1/c_hl1mp_player.h"
|
||||
//#define CRecipientFilter C_RecipientFilter
|
||||
#else
|
||||
#include "hl1mp_player.h"
|
||||
#endif
|
||||
|
||||
// When moving this fast, he plays run anim.
|
||||
#define ARBITRARY_RUN_SPEED 175.0f
|
||||
|
||||
#define MAX_STANDING_RUN_SPEED 320
|
||||
#define MAX_CROUCHED_RUN_SPEED 110
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// CPlayerAnimState declaration.
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
|
||||
class CPlayerAnimState : public IHL1MPPlayerAnimState, public CBasePlayerAnimState
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( CPlayerAnimState, CBasePlayerAnimState );
|
||||
|
||||
CPlayerAnimState();
|
||||
void Init( CHL1MP_Player *pPlayer );
|
||||
|
||||
// This is called by both the client and the server in the same way to trigger events for
|
||||
// players firing, jumping, throwing grenades, etc.
|
||||
virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData );
|
||||
virtual int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle );
|
||||
virtual float SetOuterBodyYaw( float flValue );
|
||||
virtual Activity CalcMainActivity();
|
||||
virtual float GetCurrentMaxGroundSpeed();
|
||||
virtual void ClearAnimationState();
|
||||
virtual bool ShouldUpdateAnimState();
|
||||
virtual int SelectWeightedSequence( Activity activity ) ;
|
||||
|
||||
float CalcMovementPlaybackRate( bool *bIsMoving );
|
||||
|
||||
virtual void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const char* GetWeaponSuffix();
|
||||
bool HandleJumping();
|
||||
bool HandleDeath( Activity *deathActivity );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
CHL1MP_Player *m_pOuter;
|
||||
|
||||
bool m_bJumping;
|
||||
bool m_bFirstJumpFrame;
|
||||
float m_flJumpStartTime;
|
||||
|
||||
bool m_bFiring;
|
||||
float m_flFireStartTime;
|
||||
|
||||
bool m_bDying;
|
||||
Activity m_DeathActivity;
|
||||
};
|
||||
|
||||
|
||||
IHL1MPPlayerAnimState* CreatePlayerAnimState( CHL1MP_Player *pPlayer )
|
||||
{
|
||||
CPlayerAnimState *pRet = new CPlayerAnimState;
|
||||
pRet->Init( pPlayer );
|
||||
return pRet;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// CPlayerAnimState implementation.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
CPlayerAnimState::CPlayerAnimState()
|
||||
{
|
||||
m_pOuter = NULL;
|
||||
m_bJumping = false;
|
||||
m_bFirstJumpFrame = false;
|
||||
m_bFiring = false;
|
||||
}
|
||||
|
||||
|
||||
void CPlayerAnimState::Init( CHL1MP_Player *pPlayer )
|
||||
{
|
||||
m_pOuter = pPlayer;
|
||||
|
||||
CModAnimConfig config;
|
||||
config.m_flMaxBodyYawDegrees = 90;
|
||||
config.m_LegAnimType = LEGANIM_GOLDSRC;
|
||||
config.m_bUseAimSequences = true;
|
||||
|
||||
BaseClass::Init( pPlayer, config );
|
||||
}
|
||||
|
||||
|
||||
const char* CPlayerAnimState::GetWeaponSuffix()
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = m_pOuter->GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
return pWeapon->GetWpnData().szAnimationPrefix;
|
||||
else
|
||||
return "shotgun";
|
||||
}
|
||||
|
||||
|
||||
int CPlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle )
|
||||
{
|
||||
const char *pWeaponSuffix = GetWeaponSuffix();
|
||||
if ( !pWeaponSuffix )
|
||||
return 0;
|
||||
|
||||
if ( strcmp( pWeaponSuffix, "glock" ) == 0 )
|
||||
pWeaponSuffix = "onehanded";
|
||||
|
||||
// Are we aiming or firing?
|
||||
const char *pAimOrShoot = "aim";
|
||||
if ( m_bFiring )
|
||||
pAimOrShoot = "shoot";
|
||||
|
||||
// Are we standing or crouching?
|
||||
int iSequence = 0;
|
||||
const char *pPrefix = "ref";
|
||||
if ( m_bDying )
|
||||
{
|
||||
// While dying, only play the main sequence.. don't layer this one on top.
|
||||
*flAimSequenceWeight = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( GetCurrentMainSequenceActivity() )
|
||||
{
|
||||
case ACT_CROUCHIDLE:
|
||||
case ACT_RUN_CROUCH:
|
||||
pPrefix = "crouch";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iSequence = CalcSequenceIndex( "%s_%s_%s", pPrefix, pAimOrShoot, pWeaponSuffix );
|
||||
|
||||
// Check if we're done firing.
|
||||
if ( m_bFiring )
|
||||
{
|
||||
float dur = m_pOuter->SequenceDuration( iSequence );
|
||||
*flCycle = (gpGlobals->curtime - m_flFireStartTime) / dur;
|
||||
if ( *flCycle >= 1 )
|
||||
{
|
||||
*flCycle = 1;
|
||||
m_bFiring = false;
|
||||
}
|
||||
}
|
||||
|
||||
return iSequence;
|
||||
}
|
||||
|
||||
|
||||
void CPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
|
||||
{
|
||||
if ( event == PLAYERANIMEVENT_JUMP )
|
||||
{
|
||||
// Main animation goes to ACT_HOP.
|
||||
m_bJumping = true;
|
||||
m_bFirstJumpFrame = true;
|
||||
m_flJumpStartTime = gpGlobals->curtime;
|
||||
}
|
||||
else if ( event == PLAYERANIMEVENT_FIRE_GUN )
|
||||
{
|
||||
// The middle part of the aim layer sequence becomes "shoot" until that animation is complete.
|
||||
m_bFiring = true;
|
||||
m_flFireStartTime = gpGlobals->curtime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float CPlayerAnimState::SetOuterBodyYaw( float flValue )
|
||||
{
|
||||
// m_pOuter->SetBoneController( 0, flValue );
|
||||
|
||||
float fAcc = flValue / 4;
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
m_pOuter->SetBoneController( i, fAcc );
|
||||
}
|
||||
|
||||
return flValue;
|
||||
}
|
||||
|
||||
|
||||
bool CPlayerAnimState::HandleJumping()
|
||||
{
|
||||
if ( m_bJumping )
|
||||
{
|
||||
if ( m_bFirstJumpFrame )
|
||||
{
|
||||
m_bFirstJumpFrame = false;
|
||||
RestartMainSequence(); // Reset the animation.
|
||||
}
|
||||
|
||||
// Don't check if he's on the ground for a sec.. sometimes the client still has the
|
||||
// on-ground flag set right when the message comes in.
|
||||
if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
|
||||
{
|
||||
if ( m_pOuter->GetFlags() & FL_ONGROUND )
|
||||
{
|
||||
m_bJumping = false;
|
||||
RestartMainSequence(); // Reset the animation.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Are we still jumping? If so, keep playing the jump animation.
|
||||
return m_bJumping;
|
||||
}
|
||||
|
||||
int CPlayerAnimState::SelectWeightedSequence( Activity activity )
|
||||
{
|
||||
return m_pOuter->m_iRealSequence;
|
||||
}
|
||||
|
||||
bool CPlayerAnimState::HandleDeath( Activity *deathActivity )
|
||||
{
|
||||
if ( m_bDying )
|
||||
{
|
||||
if ( m_pOuter->IsAlive() )
|
||||
{
|
||||
m_bDying = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*deathActivity = m_DeathActivity;
|
||||
}
|
||||
}
|
||||
return m_bDying;
|
||||
}
|
||||
|
||||
|
||||
Activity CPlayerAnimState::CalcMainActivity()
|
||||
{
|
||||
Activity deathActivity = ACT_IDLE;
|
||||
if ( HandleDeath( &deathActivity ) )
|
||||
{
|
||||
return deathActivity;
|
||||
}
|
||||
else if ( HandleJumping() )
|
||||
{
|
||||
return ACT_HOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
Activity idealActivity = ACT_IDLE;
|
||||
float flOuterSpeed = GetOuterXYSpeed();
|
||||
|
||||
if ( m_pOuter->GetFlags() & FL_DUCKING )
|
||||
{
|
||||
if ( flOuterSpeed > 0.1f )
|
||||
idealActivity = ACT_RUN_CROUCH;
|
||||
else
|
||||
idealActivity = ACT_CROUCHIDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( flOuterSpeed > 0.1f )
|
||||
{
|
||||
if ( flOuterSpeed > ARBITRARY_RUN_SPEED )
|
||||
idealActivity = ACT_RUN;
|
||||
else
|
||||
idealActivity = ACT_WALK;
|
||||
}
|
||||
else
|
||||
{
|
||||
idealActivity = ACT_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
return idealActivity ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float CPlayerAnimState::GetCurrentMaxGroundSpeed()
|
||||
{
|
||||
Activity act = GetCurrentMainSequenceActivity();
|
||||
if ( act == ACT_CROUCHIDLE || act == ACT_RUN_CROUCH )
|
||||
return MAX_CROUCHED_RUN_SPEED;
|
||||
else
|
||||
return MAX_STANDING_RUN_SPEED;
|
||||
}
|
||||
|
||||
|
||||
void CPlayerAnimState::ClearAnimationState()
|
||||
{
|
||||
m_bJumping = false;
|
||||
m_bFiring = false;
|
||||
m_bDying = false;
|
||||
|
||||
BaseClass::ClearAnimationState();
|
||||
}
|
||||
|
||||
|
||||
bool CPlayerAnimState::ShouldUpdateAnimState()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
float CPlayerAnimState::CalcMovementPlaybackRate( bool *bIsMoving )
|
||||
{
|
||||
// Determine ideal playback rate
|
||||
Vector vel;
|
||||
GetOuterAbsVelocity( vel );
|
||||
|
||||
float flReturnValue = BaseClass::CalcMovementPlaybackRate( bIsMoving );
|
||||
|
||||
Activity eActivity = GetOuter()->GetSequenceActivity( GetOuter()->GetSequence() ) ;
|
||||
|
||||
if ( eActivity == ACT_RUN || eActivity == ACT_WALK || eActivity == ACT_CROUCH )
|
||||
{
|
||||
VectorNormalize( vel );
|
||||
|
||||
Vector vForward;
|
||||
AngleVectors( GetOuter()->EyeAngles(), &vForward );
|
||||
|
||||
float flDot = DotProduct( vel, vForward );
|
||||
|
||||
if ( flDot < 0 )
|
||||
{
|
||||
flReturnValue *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
return flReturnValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
|
||||
{
|
||||
VPROF( "CBasePlayerAnimState::ComputePoseParam_BodyPitch" );
|
||||
|
||||
// Get pitch from v_angle
|
||||
float flPitch = -m_flEyePitch;
|
||||
if ( flPitch > 180.0f )
|
||||
{
|
||||
flPitch -= 360.0f;
|
||||
}
|
||||
flPitch = clamp( flPitch, -50, 45 );
|
||||
|
||||
// See if we have a blender for pitch
|
||||
int pitch = GetOuter()->LookupPoseParameter( pStudioHdr, "XR" );
|
||||
if ( pitch < 0 )
|
||||
return;
|
||||
|
||||
GetOuter()->SetPoseParameter( pStudioHdr, pitch, flPitch );
|
||||
g_flLastBodyPitch = flPitch;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef HL1_PLAYER_SHARED_H
|
||||
#define HL1_PLAYER_SHARED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "cbase.h"
|
||||
#include "base_playeranimstate.h"
|
||||
|
||||
// Shared header file for players
|
||||
#if defined( CLIENT_DLL )
|
||||
//#define CHL1_Player C_BaseHLPlayer //FIXME: Lovely naming job between server and client here...
|
||||
class C_HL1MP_Player;
|
||||
#define CHL1MP_Player C_HL1MP_Player
|
||||
#else
|
||||
//#include "hl1_player.h"
|
||||
class CHL1MP_Player;
|
||||
#endif
|
||||
|
||||
#include "studio.h"
|
||||
|
||||
enum PlayerAnimEvent_t
|
||||
{
|
||||
PLAYERANIMEVENT_FIRE_GUN=0,
|
||||
PLAYERANIMEVENT_THROW_GRENADE,
|
||||
PLAYERANIMEVENT_JUMP,
|
||||
PLAYERANIMEVENT_RELOAD,
|
||||
PLAYERANIMEVENT_DIE,
|
||||
|
||||
PLAYERANIMEVENT_COUNT
|
||||
};
|
||||
|
||||
class IHL1MPPlayerAnimState : virtual public IPlayerAnimState
|
||||
{
|
||||
public:
|
||||
// This is called by both the client and the server in the same way to trigger events for
|
||||
// players firing, jumping, throwing grenades, etc.
|
||||
virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData ) = 0;
|
||||
};
|
||||
|
||||
IHL1MPPlayerAnimState* CreatePlayerAnimState( CHL1MP_Player *pPlayer );
|
||||
|
||||
// If this is set, then the game code needs to make sure to send player animation events
|
||||
// to the local player if he's the one being watched.
|
||||
extern ConVar cl_showanimstate;
|
||||
|
||||
#endif // HL1_PLAYER_SHARED_H
|
||||
@@ -0,0 +1,20 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef HL1_SHAREDDEFS_H
|
||||
#define HL1_SHAREDDEFS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
//--------------
|
||||
// HL1 SPECIFIC
|
||||
//--------------
|
||||
#define DMG_MISSILEDEFENSE (DMG_LASTGENERICFLAG<<2) // The only kind of damage missiles take. (special missile defense)
|
||||
|
||||
|
||||
#endif // HL1_SHAREDDEFS_H
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "usermessages.h"
|
||||
#include "shake.h"
|
||||
#include "voice_gamemgr.h"
|
||||
// NVNT include to register in haptic user messages
|
||||
#include "haptics/haptic_msgs.h"
|
||||
|
||||
void RegisterUserMessages( void )
|
||||
{
|
||||
usermessages->Register( "Geiger", 1 );
|
||||
usermessages->Register( "Train", 1 );
|
||||
usermessages->Register( "HudText", -1 );
|
||||
usermessages->Register( "SayText", -1 );
|
||||
usermessages->Register( "SayText2", -1 );
|
||||
usermessages->Register( "TextMsg", -1 );
|
||||
usermessages->Register( "HudMsg", -1 );
|
||||
usermessages->Register( "ResetHUD", 1 ); // called every respawn
|
||||
usermessages->Register( "GameTitle", 0 );
|
||||
usermessages->Register( "ItemPickup", -1 );
|
||||
usermessages->Register( "ShowMenu", -1 );
|
||||
usermessages->Register( "Shake", 13 );
|
||||
usermessages->Register( "Fade", 10 );
|
||||
usermessages->Register( "VGUIMenu", -1 ); // Show VGUI menu
|
||||
usermessages->Register( "Rumble", 3 ); // Send a rumble to a controller
|
||||
usermessages->Register( "Battery", 2 );
|
||||
usermessages->Register( "Damage", 18 );
|
||||
usermessages->Register( "VoiceMask", VOICE_MAX_PLAYERS_DW*4 * 2 + 1 );
|
||||
usermessages->Register( "RequestState", 0 );
|
||||
usermessages->Register( "CloseCaption", -1 ); // Show a caption (by string id number)(duration in 10th of a second)
|
||||
usermessages->Register( "HintText", -1 ); // Displays hint text display
|
||||
usermessages->Register( "KeyHintText", -1 ); // Displays hint text display
|
||||
usermessages->Register( "AmmoDenied", 2 );
|
||||
|
||||
// NVNT register haptic user messages
|
||||
RegisterHapticMessages();
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
|
||||
#include "effect_dispatch_data.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#else
|
||||
#include "te_effect_dispatch.h"
|
||||
#endif
|
||||
|
||||
#include "hl1_player_shared.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( basehl1mpcombatweapon, CBaseHL1MPCombatWeapon );
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( BaseHL1MPCombatWeapon , DT_BaseHL1MPCombatWeapon )
|
||||
|
||||
BEGIN_NETWORK_TABLE( CBaseHL1MPCombatWeapon , DT_BaseHL1MPCombatWeapon )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CBaseHL1MPCombatWeapon )
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
|
||||
CBaseHL1MPCombatWeapon::CBaseHL1MPCombatWeapon()
|
||||
{
|
||||
SetPredictionEligible( true );
|
||||
AddSolidFlags( FSOLID_TRIGGER ); // Nothing collides with these but it gets touches.
|
||||
}
|
||||
|
||||
|
||||
void CBaseHL1MPCombatWeapon::EjectShell( CBaseEntity *pPlayer, int iType )
|
||||
{
|
||||
QAngle angShellAngles = pPlayer->GetAbsAngles();
|
||||
|
||||
Vector vecForward, vecRight, vecUp;
|
||||
AngleVectors( angShellAngles, &vecForward, &vecRight, &vecUp );
|
||||
|
||||
Vector vecShellPosition = pPlayer->GetAbsOrigin() + pPlayer->GetViewOffset();
|
||||
switch ( iType )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
vecShellPosition += vecRight * 4;
|
||||
vecShellPosition += vecUp * -12;
|
||||
vecShellPosition += vecForward * 20;
|
||||
break;
|
||||
case 1:
|
||||
vecShellPosition += vecRight * 6;
|
||||
vecShellPosition += vecUp * -12;
|
||||
vecShellPosition += vecForward * 32;
|
||||
break;
|
||||
}
|
||||
|
||||
Vector vecShellVelocity = vec3_origin; // pPlayer->GetAbsVelocity();
|
||||
vecShellVelocity += vecRight * random->RandomFloat( 50, 70 );
|
||||
vecShellVelocity += vecUp * random->RandomFloat( 100, 150 );
|
||||
vecShellVelocity += vecForward * 25;
|
||||
|
||||
angShellAngles.x = 0;
|
||||
angShellAngles.z = 0;
|
||||
|
||||
CEffectData data;
|
||||
data.m_vStart = vecShellVelocity;
|
||||
data.m_vOrigin = vecShellPosition;
|
||||
data.m_vAngles = angShellAngles;
|
||||
data.m_fFlags = iType;
|
||||
|
||||
DispatchEffect( "HL1ShellEject", data );
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
|
||||
void CBaseHL1MPCombatWeapon::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if ( GetPredictable() && !ShouldPredict() )
|
||||
ShutdownPredictable();
|
||||
}
|
||||
|
||||
|
||||
bool CBaseHL1MPCombatWeapon::ShouldPredict()
|
||||
{
|
||||
if ( GetOwner() && GetOwner() == C_BasePlayer::GetLocalPlayer() )
|
||||
return true;
|
||||
|
||||
return BaseClass::ShouldPredict();
|
||||
}
|
||||
|
||||
|
||||
void CBaseHL1MPCombatWeapon::ApplyBoneMatrixTransform( matrix3x4_t& transform )
|
||||
{
|
||||
BaseClass::ApplyBoneMatrixTransform( transform );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
bool CBaseHL1MPCombatWeapon::IsPredicted() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CBasePlayer* CBaseHL1MPCombatWeapon::GetPlayerOwner() const
|
||||
{
|
||||
return dynamic_cast< CBasePlayer* >( GetOwner() );
|
||||
}
|
||||
|
||||
|
||||
void CBaseHL1MPCombatWeapon::WeaponSound( WeaponSound_t sound_type, float soundtime /* = 0.0f */ )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
// If we have some sounds from the weapon classname.txt file, play a random one of them
|
||||
const char *shootsound = GetWpnData().aShootSounds[ sound_type ];
|
||||
if ( !shootsound || !shootsound[0] )
|
||||
return;
|
||||
|
||||
CBroadcastRecipientFilter filter; // this is client side only
|
||||
if ( !te->CanPredict() )
|
||||
return;
|
||||
|
||||
CBaseEntity::EmitSound( filter, GetPlayerOwner()->entindex(), shootsound, &GetPlayerOwner()->GetAbsOrigin() );
|
||||
#else
|
||||
BaseClass::WeaponSound( sound_type, soundtime );
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include "hl1_basecombatweapon_shared.h"
|
||||
|
||||
#ifndef BASEHL1MPCOMBATWEAPON_SHARED_H
|
||||
#define BASEHL1MPCOMBATWEAPON_SHARED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
#define CBaseHL1MPCombatWeapon C_BaseHL1MPCombatWeapon
|
||||
#endif
|
||||
|
||||
|
||||
class CBaseHL1MPCombatWeapon : public CBaseHL1CombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CBaseHL1MPCombatWeapon, CBaseHL1CombatWeapon );
|
||||
public :
|
||||
CBaseHL1MPCombatWeapon();
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
public :
|
||||
void EjectShell( CBaseEntity *pPlayer, int iType );
|
||||
|
||||
CBasePlayer* GetPlayerOwner() const;
|
||||
virtual void WeaponSound( WeaponSound_t sound_type, float soundtime = 0.0f );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
void OnDataChanged( DataUpdateType_t type );
|
||||
bool ShouldPredict();
|
||||
|
||||
void ApplyBoneMatrixTransform( matrix3x4_t& transform );
|
||||
#endif
|
||||
bool IsPredicted() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BASEHL1MPCOMBATWEAPON_SHARED_H
|
||||
@@ -0,0 +1,739 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include "cbase.h"
|
||||
#include "hl1mp_gamerules.h"
|
||||
#include "viewport_panel_names.h"
|
||||
#include "gameeventdefs.h"
|
||||
#include <KeyValues.h>
|
||||
#include "ammodef.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
|
||||
#include "hl1/c_hl1mp_player.h"
|
||||
|
||||
#else
|
||||
|
||||
#include "eventqueue.h"
|
||||
#include "player.h"
|
||||
#include "gamerules.h"
|
||||
#include "game.h"
|
||||
#include "items.h"
|
||||
#include "entitylist.h"
|
||||
#include "in_buttons.h"
|
||||
#include <ctype.h>
|
||||
#include "voice_gamemgr.h"
|
||||
#include "iscorer.h"
|
||||
#include "hl1mp_player.h"
|
||||
#include "team.h"
|
||||
#include "voice_gamemgr.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "hl1mp_bot_temp.h"
|
||||
#endif
|
||||
|
||||
ConVar sv_hl1mp_weapon_respawn_time( "sv_hl1mp_weapon_respawn_time", "20", FCVAR_GAMEDLL | FCVAR_NOTIFY );
|
||||
ConVar sv_hl1mp_item_respawn_time( "sv_hl1mp_item_respawn_time", "30", FCVAR_GAMEDLL | FCVAR_NOTIFY );
|
||||
|
||||
|
||||
extern ConVar mp_chattime;
|
||||
|
||||
extern CBaseEntity *g_pLastCombineSpawn;
|
||||
extern CBaseEntity *g_pLastRebelSpawn;
|
||||
|
||||
//#define WEAPON_MAX_DISTANCE_FROM_SPAWN 64
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
REGISTER_GAMERULES_CLASS( CHL1MPRules );
|
||||
|
||||
BEGIN_NETWORK_TABLE_NOBASE( CHL1MPRules, DT_HL1MPRules )
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
RecvPropBool( RECVINFO( m_bTeamPlayEnabled ) ),
|
||||
#else
|
||||
SendPropBool( SENDINFO( m_bTeamPlayEnabled ) ),
|
||||
#endif
|
||||
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( hl1mp_gamerules, CHL1MPGameRulesProxy );
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( HL1MPGameRulesProxy, DT_HL1MPGameRulesProxy )
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
void RecvProxy_HL1MPRules( const RecvProp *pProp, void **pOut, void *pData, int objectID )
|
||||
{
|
||||
CHL1MPRules *pRules = HL1MPRules();
|
||||
Assert( pRules );
|
||||
*pOut = pRules;
|
||||
}
|
||||
|
||||
BEGIN_RECV_TABLE( CHL1MPGameRulesProxy, DT_HL1MPGameRulesProxy )
|
||||
RecvPropDataTable( "hl1mp_gamerules_data", 0, 0, &REFERENCE_RECV_TABLE( DT_HL1MPRules ), RecvProxy_HL1MPRules )
|
||||
END_RECV_TABLE()
|
||||
#else
|
||||
void* SendProxy_HL1MPRules( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID )
|
||||
{
|
||||
CHL1MPRules *pRules = HL1MPRules();
|
||||
Assert( pRules );
|
||||
return pRules;
|
||||
}
|
||||
|
||||
BEGIN_SEND_TABLE( CHL1MPGameRulesProxy, DT_HL1MPGameRulesProxy )
|
||||
SendPropDataTable( "hl1mp_gamerules_data", 0, &REFERENCE_SEND_TABLE( DT_HL1MPRules ), SendProxy_HL1MPRules )
|
||||
END_SEND_TABLE()
|
||||
#endif
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
#if 0
|
||||
class CVoiceGameMgrHelper : public IVoiceGameMgrHelper
|
||||
{
|
||||
public:
|
||||
virtual bool CanPlayerHearPlayer( CBasePlayer *pListener, CBasePlayer *pTalker )
|
||||
{
|
||||
return ( pListener->GetTeamNumber() == pTalker->GetTeamNumber() );
|
||||
}
|
||||
};
|
||||
CVoiceGameMgrHelper g_VoiceGameMgrHelper;
|
||||
IVoiceGameMgrHelper *g_pVoiceGameMgrHelper = &g_VoiceGameMgrHelper;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
// Handler for the "bot" command.
|
||||
void Bot_f()
|
||||
{
|
||||
// Look at -count.
|
||||
int count = 1;
|
||||
count = clamp( count, 1, 16 );
|
||||
|
||||
int iTeam = 0;
|
||||
|
||||
// Look at -frozen.
|
||||
bool bFrozen = false;
|
||||
|
||||
// Ok, spawn all the bots.
|
||||
while ( --count >= 0 )
|
||||
{
|
||||
BotPutInServer( bFrozen, iTeam );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ConCommand cc_Bot( "bot", Bot_f, "Add a bot.", FCVAR_CHEAT );
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
CHL1MPRules::CHL1MPRules()
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
m_bTeamPlayEnabled = teamplay.GetBool();
|
||||
|
||||
if ( IsTeamplay() )
|
||||
{
|
||||
// Create basic server teams
|
||||
|
||||
CTeam *pTeam = static_cast<CTeam*>(CreateEntityByName( "team_manager" ));
|
||||
pTeam->Init( "Unassigned", 0 );
|
||||
g_Teams.AddToTail( pTeam );
|
||||
|
||||
pTeam = static_cast<CTeam*>(CreateEntityByName( "team_manager" ));
|
||||
pTeam->Init( "Spectator", 1 );
|
||||
g_Teams.AddToTail( pTeam );
|
||||
|
||||
char *pName;
|
||||
char szTeamlist[TEAMPLAY_TEAMLISTLENGTH];
|
||||
|
||||
// loop through all teams, recounting everything
|
||||
int num_teams = 0;
|
||||
|
||||
// Copy all of the teams from the teamlist
|
||||
// make a copy because strtok is destructive
|
||||
Q_strncpy( szTeamlist, teamlist.GetString(), sizeof(teamlist) );
|
||||
pName = szTeamlist;
|
||||
pName = strtok( pName, "," );
|
||||
while ( pName != NULL && *pName )
|
||||
{
|
||||
if ( GetTeamIndex( pName ) < 0 )
|
||||
{
|
||||
// create team
|
||||
pTeam = static_cast<CTeam*>(CreateEntityByName( "team_manager" ));
|
||||
pTeam->Init( pName, num_teams + 2 );
|
||||
g_Teams.AddToTail( pTeam );
|
||||
|
||||
num_teams++;
|
||||
}
|
||||
pName = strtok( NULL, "," );
|
||||
}
|
||||
|
||||
// Manually create teams
|
||||
if ( num_teams == 0 )
|
||||
{
|
||||
pTeam = static_cast<CTeam*>(CreateEntityByName( "team_manager" ) );
|
||||
pTeam->Init( "robo", num_teams + 2 );
|
||||
g_Teams.AddToTail( pTeam );
|
||||
num_teams++;
|
||||
|
||||
pTeam = static_cast<CTeam*>(CreateEntityByName( "team_manager" ) );
|
||||
pTeam->Init( "hgrunt", num_teams + 2 );
|
||||
g_Teams.AddToTail( pTeam );
|
||||
num_teams++;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CHL1MPRules::~CHL1MPRules( void )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
// Note, don't delete each team since they are in the gEntList and will
|
||||
// automatically be deleted from there, instead.
|
||||
g_Teams.Purge();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CHL1MPRules::CreateStandardEntities( void )
|
||||
{
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// Create the entity that will send our data to the client.
|
||||
|
||||
BaseClass::CreateStandardEntities();
|
||||
|
||||
#ifdef _DEBUG
|
||||
CBaseEntity *pEnt =
|
||||
#endif
|
||||
CBaseEntity::Create( "hl1mp_gamerules", vec3_origin, vec3_angle );
|
||||
Assert( pEnt );
|
||||
#endif
|
||||
}
|
||||
|
||||
float CHL1MPRules::GetAmmoDamage( CBaseEntity *pAttacker, CBaseEntity *pVictim, int nAmmoType )
|
||||
{
|
||||
return BaseClass::GetAmmoDamage( pAttacker, pVictim, nAmmoType ) * GetDamageMultiplier();
|
||||
}
|
||||
|
||||
float CHL1MPRules::GetDamageMultiplier( void )
|
||||
{
|
||||
if ( IsMultiplayer() )
|
||||
return sk_mp_dmg_multiplier.GetFloat();
|
||||
else
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
|
||||
bool CHL1MPRules::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
if( BaseClass::ClientCommand( pEdict, args ) )
|
||||
return true;
|
||||
|
||||
|
||||
CHL1MP_Player *pPlayer = (CHL1MP_Player *) pEdict;
|
||||
|
||||
if ( pPlayer->ClientCommand( args ) )
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
|
||||
|
||||
void CHL1MPRules::Think ( void )
|
||||
{
|
||||
CGameRules::Think();
|
||||
|
||||
if ( g_fGameOver ) // someone else quit the game already
|
||||
{
|
||||
// check to see if we should change levels now
|
||||
if ( m_flIntermissionEndTime < gpGlobals->curtime )
|
||||
{
|
||||
ChangeLevel(); // intermission is over
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float flTimeLimit = mp_timelimit.GetFloat() * 60;
|
||||
float flFragLimit = fraglimit.GetFloat();
|
||||
|
||||
if ( flTimeLimit != 0 && gpGlobals->curtime >= flTimeLimit )
|
||||
{
|
||||
GoToIntermission();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( flFragLimit )
|
||||
{
|
||||
if( IsTeamplay() == true )
|
||||
{
|
||||
for (int i = TEAM_SPECTATOR+1; i < GetNumberOfTeams(); i++)
|
||||
{
|
||||
if ( GetGlobalTeam(i)->GetScore() >= flFragLimit )
|
||||
{
|
||||
GoToIntermission();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if any player is over the frag limit
|
||||
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
|
||||
|
||||
if ( pPlayer && pPlayer->FragCount() >= flFragLimit )
|
||||
{
|
||||
GoToIntermission();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ManageObjectRelocation();
|
||||
}
|
||||
|
||||
|
||||
void CHL1MPRules::GoToIntermission()
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
if ( g_fGameOver )
|
||||
return;
|
||||
|
||||
g_fGameOver = true;
|
||||
|
||||
m_flIntermissionEndTime = gpGlobals->curtime + mp_chattime.GetInt();
|
||||
|
||||
for ( int i = 0; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
|
||||
|
||||
if ( !pPlayer )
|
||||
continue;
|
||||
|
||||
pPlayer->ShowViewPortPanel( PANEL_SCOREBOARD );
|
||||
pPlayer->AddFlag( FL_FROZEN );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
const char * CHL1MPRules::SetDefaultPlayerTeam( CBasePlayer *pPlayer )
|
||||
{
|
||||
if ( !IsTeamplay() )
|
||||
{
|
||||
CMultiplayRules::SetDefaultPlayerTeam( pPlayer );
|
||||
return "";
|
||||
}
|
||||
|
||||
int clientIndex = pPlayer->entindex();
|
||||
|
||||
char szTeam[128];
|
||||
Q_FileBase( engine->GetClientConVarValue( clientIndex, "cl_playermodel" ), szTeam, 128 );
|
||||
|
||||
const char * team = szTeam;
|
||||
|
||||
int iTeam = GetTeamIndex( team );
|
||||
if ( iTeam == -1 || !IsValidTeam( team ) )
|
||||
{
|
||||
team = TeamWithFewestPlayers();
|
||||
iTeam = GetTeamIndex(team);
|
||||
}
|
||||
|
||||
pPlayer->ChangeTeam( iTeam );
|
||||
|
||||
return team;
|
||||
}
|
||||
|
||||
|
||||
const char * CHL1MPRules::TeamWithFewestPlayers( void )
|
||||
{
|
||||
const char * szName = "";
|
||||
int iNumPlayers = 0xFFFF;
|
||||
for (int i = TEAM_SPECTATOR+1; i < GetNumberOfTeams(); i++)
|
||||
{
|
||||
if ( GetGlobalTeam(i)->GetNumPlayers() < iNumPlayers )
|
||||
{
|
||||
szName = GetGlobalTeam(i)->GetName();
|
||||
iNumPlayers = GetGlobalTeam(i)->GetNumPlayers();
|
||||
}
|
||||
}
|
||||
|
||||
return szName;
|
||||
}
|
||||
|
||||
|
||||
void CHL1MPRules::InitHUD( CBasePlayer *pPlayer )
|
||||
{
|
||||
SetDefaultPlayerTeam( pPlayer );
|
||||
BaseClass::InitHUD( pPlayer );
|
||||
}
|
||||
|
||||
|
||||
void CHL1MPRules::ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, bool bKill, bool bGib )
|
||||
{
|
||||
BaseClass::ChangePlayerTeam( pPlayer, pTeamName, bKill, bGib );
|
||||
}
|
||||
|
||||
|
||||
void CHL1MPRules::ClientSettingsChanged( CBasePlayer *pPlayer )
|
||||
{
|
||||
CHL1MP_Player *pHL1Player = ToHL1MPPlayer( pPlayer );
|
||||
|
||||
if ( pHL1Player == NULL )
|
||||
return;
|
||||
|
||||
// strip down to just the name
|
||||
char szTempCurrentModel[128];
|
||||
Q_FileBase( modelinfo->GetModelName( pPlayer->GetModel() ), szTempCurrentModel, 128 );
|
||||
const char *pCurrentModel = szTempCurrentModel;
|
||||
|
||||
char szTempModelName[128];
|
||||
Q_FileBase( engine->GetClientConVarValue( engine->IndexOfEdict( pPlayer->edict() ), "cl_playermodel" ), szTempModelName, 128 );
|
||||
const char *szModelName = szTempModelName;
|
||||
|
||||
//If we're different.
|
||||
if ( strlen( szModelName ) > 0 && stricmp( szModelName, pCurrentModel ) )
|
||||
{
|
||||
//Too soon, set the cvar back to what it was.
|
||||
//Note: this will make this function be called again
|
||||
//but since our models will match it'll just skip this whole dealio.
|
||||
if ( pHL1Player->GetNextModelChangeTime() >= gpGlobals->curtime )
|
||||
{
|
||||
char szReturnString[512];
|
||||
|
||||
Q_snprintf( szReturnString, sizeof (szReturnString ), "cl_playermodel %s\n", pCurrentModel );
|
||||
engine->ClientCommand ( pHL1Player->edict(), szReturnString );
|
||||
|
||||
Q_snprintf( szReturnString, sizeof( szReturnString ), "Please wait %d more seconds before trying to switch.\n", (int)(pHL1Player->GetNextModelChangeTime() - gpGlobals->curtime) );
|
||||
ClientPrint( pHL1Player, HUD_PRINTTALK, szReturnString );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( HL1MPRules()->IsTeamplay() == false )
|
||||
{
|
||||
pHL1Player->SetPlayerModel();
|
||||
|
||||
//const char *pszCurrentModelName = modelinfo->GetModelName( pHL1Player->GetModel() );
|
||||
|
||||
//char szReturnString[128];
|
||||
//Q_snprintf( szReturnString, sizeof( szReturnString ), "Your player model is: %s\n", pszCurrentModelName );
|
||||
|
||||
//Printing the model path for the average player is way too verbose - ml
|
||||
//ClientPrint( pHL1Player, HUD_PRINTTALK, szReturnString );
|
||||
}
|
||||
else
|
||||
{
|
||||
int iTeam = GetTeamIndex( szModelName );
|
||||
if ( iTeam == -1 || !IsValidTeam( szModelName ) )
|
||||
{
|
||||
const char * team = TeamWithFewestPlayers();
|
||||
iTeam = GetTeamIndex( team );
|
||||
}
|
||||
|
||||
pPlayer->ChangeTeam( iTeam );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::ClientSettingsChanged( pPlayer );
|
||||
}
|
||||
|
||||
|
||||
int CHL1MPRules::GetTeamIndex( const char * pName )
|
||||
{
|
||||
for ( int i = 0; i < GetNumberOfTeams(); i++ )
|
||||
{
|
||||
if ( strcmp( g_Teams[i]->GetName(), pName ) == 0 )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
float CHL1MPRules::FlWeaponRespawnTime( CBaseCombatWeapon *pWeapon )
|
||||
{
|
||||
if ( weaponstay.GetInt() > 0 )
|
||||
{
|
||||
// make sure it's only certain weapons
|
||||
if ( !(pWeapon->GetWeaponFlags() & ITEM_FLAG_LIMITINWORLD) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return sv_hl1mp_weapon_respawn_time.GetInt();
|
||||
}
|
||||
|
||||
|
||||
float CHL1MPRules::FlItemRespawnTime( CItem *pItem )
|
||||
{
|
||||
return sv_hl1mp_item_respawn_time.GetInt();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This is a direct rip from CHalfLife1
|
||||
void CHL1MPRules::InitDefaultAIRelationships( void )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Allocate memory for default relationships
|
||||
CBaseCombatCharacter::AllocateDefaultRelationships();
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// First initialize table so we can report missing relationships
|
||||
// --------------------------------------------------------------
|
||||
for (i=0;i<NUM_AI_CLASSES;i++)
|
||||
{
|
||||
for (j=0;j<NUM_AI_CLASSES;j++)
|
||||
{
|
||||
// By default all relationships are neutral of priority zero
|
||||
CBaseCombatCharacter::SetDefaultRelationship( (Class_T)i, (Class_T)j, D_NU, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_NONE
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_PLAYER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_HUMAN_PASSIVE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_PLAYER_ALLY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_PREY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_HUMAN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_NONE, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_HUMAN_PASSIVE
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_PLAYER, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_HUMAN_PASSIVE, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_PLAYER_ALLY, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_PREY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_MILITARY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_PREDATOR, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_PASSIVE, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_PLAYER
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_PLAYER, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_HUMAN_PASSIVE, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_PLAYER_ALLY, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_MACHINE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_ALIEN_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_PLAYER_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_PLAYER_ALLY
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_PLAYER, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_HUMAN_PASSIVE, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_PLAYER_ALLY, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_MACHINE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_ALLY, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_PREY
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_PREY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_PREDATOR, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREY, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_MILITARY
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_PREY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_MACHINE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MILITARY, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_MONSTER
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_PREY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_MACHINE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_MONSTER, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_PREDATOR
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_MONSTER, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_PREDATOR, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_HUMAN_MILITARY
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_HUMAN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_HUMAN_MILITARY, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_MACHINE
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_HUMAN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_ALIEN_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_PLAYER_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_MACHINE, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_ALIEN_BIOWEAPON
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_MILITARY, D_LI, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_PREDATOR, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_PLAYER_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_ALIEN_BIOWEAPON, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_PLAYER_BIOWEAPON
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_NONE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_MACHINE, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_PLAYER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_HUMAN_PASSIVE, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_HUMAN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_MILITARY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_MONSTER, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_PREY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_PREDATOR, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_PLAYER_ALLY, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_ALIEN_BIOWEAPON, D_HT, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_PLAYER_BIOWEAPON, CLASS_INSECT, D_NU, 0 );
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// > CLASS_INSECT
|
||||
// ------------------------------------------------------------
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_NONE, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_MACHINE, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_PLAYER, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_HUMAN_PASSIVE, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_HUMAN_MILITARY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_MILITARY, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_MONSTER, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_PREY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_PREDATOR, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_PLAYER_ALLY, D_FR, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_ALIEN_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_PLAYER_BIOWEAPON, D_NU, 0 );
|
||||
CBaseCombatCharacter::SetDefaultRelationship( CLASS_INSECT, CLASS_INSECT, D_NU, 0 );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef HL1MP_GAMERULES_H
|
||||
#define HL1MP_GAMERULES_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "gamerules.h"
|
||||
#include "teamplay_gamerules.h"
|
||||
|
||||
extern ConVar sk_mp_dmg_multiplier ;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CHL1MPRules C_HL1MPRules
|
||||
#define CHL1MPGameRulesProxy C_HL1MPGameRulesProxy
|
||||
#endif
|
||||
|
||||
|
||||
class CHL1MPGameRulesProxy : public CGameRulesProxy
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CHL1MPGameRulesProxy, CGameRulesProxy );
|
||||
DECLARE_NETWORKCLASS();
|
||||
};
|
||||
|
||||
|
||||
class CHL1MPRules : public CTeamplayRules
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CHL1MPRules, CTeamplayRules );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
DECLARE_CLIENTCLASS_NOBASE();
|
||||
#else
|
||||
DECLARE_SERVERCLASS_NOBASE();
|
||||
#endif
|
||||
|
||||
CHL1MPRules();
|
||||
virtual ~CHL1MPRules();
|
||||
|
||||
virtual void CreateStandardEntities( void );
|
||||
|
||||
virtual bool IsTeamplay( void )
|
||||
{
|
||||
return m_bTeamPlayEnabled;
|
||||
}
|
||||
|
||||
virtual float GetAmmoDamage( CBaseEntity *pAttacker, CBaseEntity *pVictim, int nAmmoType );
|
||||
virtual float GetDamageMultiplier( void );
|
||||
|
||||
virtual bool IsConnectedUserInfoChangeAllowed( CBasePlayer *pPlayer )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool ClientCommand( CBaseEntity *pEdict, const CCommand &args );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
virtual const char *GetGameDescription( void ) { return "Half-Life Deathmatch: Source"; } // this is the game name that gets seen in the server browser
|
||||
|
||||
virtual void Think ( void );
|
||||
|
||||
virtual void GoToIntermission( void );
|
||||
|
||||
virtual void InitDefaultAIRelationships( void );
|
||||
|
||||
virtual float FlWeaponRespawnTime( CBaseCombatWeapon *pWeapon );
|
||||
virtual float FlItemRespawnTime( CItem *pItem );
|
||||
|
||||
virtual const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer );
|
||||
virtual void InitHUD( CBasePlayer *pPlayer );
|
||||
virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, bool bKill, bool bGib );
|
||||
virtual void ClientSettingsChanged( CBasePlayer *pPlayer );
|
||||
|
||||
virtual int GetTeamIndex( const char * pName );
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
const char *TeamWithFewestPlayers( void );
|
||||
|
||||
CNetworkVar( bool, m_bTeamPlayEnabled );
|
||||
};
|
||||
|
||||
|
||||
inline CHL1MPRules* HL1MPRules()
|
||||
{
|
||||
return dynamic_cast<CHL1MPRules*>(g_pGameRules);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,289 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: 357 - hand gun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_baseplayer.h"
|
||||
#else
|
||||
#include "player.h"
|
||||
#endif
|
||||
#include "gamerules.h"
|
||||
#include "in_buttons.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeapon357 C_Weapon357
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeapon357
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CWeapon357 : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeapon357, CBaseHL1CombatWeapon );
|
||||
public:
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
CWeapon357( void );
|
||||
|
||||
void Precache( void );
|
||||
bool Deploy( void );
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
bool Reload( void );
|
||||
void WeaponIdle( void );
|
||||
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
// DECLARE_DATADESC();
|
||||
|
||||
private:
|
||||
void ToggleZoom( void );
|
||||
|
||||
private:
|
||||
CNetworkVar( float, m_fInZoom );
|
||||
};
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( Weapon357, DT_Weapon357 );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeapon357, DT_Weapon357 )
|
||||
#ifdef CLIENT_DLL
|
||||
RecvPropFloat( RECVINFO( m_fInZoom ) ),
|
||||
#else
|
||||
SendPropFloat( SENDINFO( m_fInZoom ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeapon357 )
|
||||
#ifdef CLIENT_DLL
|
||||
DEFINE_PRED_FIELD( m_fInZoom, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
#endif
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_357, CWeapon357 );
|
||||
|
||||
PRECACHE_WEAPON_REGISTER( weapon_357 );
|
||||
|
||||
//IMPLEMENT_SERVERCLASS_ST( CWeapon357, DT_Weapon357 )
|
||||
//END_SEND_TABLE()
|
||||
|
||||
//BEGIN_DATADESC( CWeapon357 )
|
||||
//END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CWeapon357::CWeapon357( void )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = false;
|
||||
m_fInZoom = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeapon357::Precache( void )
|
||||
{
|
||||
BaseClass::Precache();
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
UTIL_PrecacheOther( "ammo_357" );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CWeapon357::Deploy( void )
|
||||
{
|
||||
// Bodygroup stuff not currently working correctly
|
||||
// if ( g_pGameRules->IsMultiplayer() )
|
||||
// {
|
||||
// enable laser sight geometry.
|
||||
// SetBodygroup( 4, 1 );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// SetBodygroup( 4, 0 );
|
||||
// }
|
||||
|
||||
return BaseClass::Deploy();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeapon357::PrimaryAttack( void )
|
||||
{
|
||||
// Only the player fires this way so we can cast
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_iClip1 <= 0 )
|
||||
{
|
||||
if ( !m_bFireOnEmpty )
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
m_flNextPrimaryAttack = 0.15;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
WeaponSound( SINGLE );
|
||||
pPlayer->DoMuzzleFlash();
|
||||
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.75;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.75;
|
||||
|
||||
m_iClip1--;
|
||||
|
||||
Vector vecSrc = pPlayer->Weapon_ShootPosition();
|
||||
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
|
||||
|
||||
// pPlayer->FireBullets( 1, vecSrc, vecAiming, VECTOR_CONE_1DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );
|
||||
|
||||
FireBulletsInfo_t info( 1, vecSrc, vecAiming, VECTOR_CONE_1DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
|
||||
info.m_pAttacker = pPlayer;
|
||||
|
||||
pPlayer->FireBullets( info );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );
|
||||
#endif
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -10, 0, 0 ) );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.2 );
|
||||
#endif
|
||||
|
||||
if ( !m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
// HEV suit - indicate out of ammo condition
|
||||
pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeapon357::SecondaryAttack( void )
|
||||
{
|
||||
// only in multiplayer
|
||||
if ( !g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
// unless we have cheats on
|
||||
if ( !sv_cheats->GetBool() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ToggleZoom();
|
||||
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
|
||||
}
|
||||
|
||||
|
||||
bool CWeapon357::Reload( void )
|
||||
{
|
||||
bool fRet;
|
||||
|
||||
fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
|
||||
if ( fRet )
|
||||
{
|
||||
if ( m_fInZoom )
|
||||
{
|
||||
ToggleZoom();
|
||||
}
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
void CWeapon357::WeaponIdle( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
|
||||
}
|
||||
|
||||
if ( !HasWeaponIdleTimeElapsed() )
|
||||
return;
|
||||
|
||||
if ( random->RandomFloat( 0, 1 ) <= 0.9 )
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_IDLE );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_FIDGET );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CWeapon357::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
{
|
||||
if ( m_fInZoom )
|
||||
{
|
||||
ToggleZoom();
|
||||
}
|
||||
|
||||
return BaseClass::Holster( pSwitchingTo );
|
||||
}
|
||||
|
||||
|
||||
void CWeapon357::ToggleZoom( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
if ( m_fInZoom )
|
||||
{
|
||||
if ( pPlayer->SetFOV( this, 0 ) )
|
||||
{
|
||||
m_fInZoom = false;
|
||||
pPlayer->ShowViewModel( true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pPlayer->SetFOV( this, 40 ) )
|
||||
{
|
||||
m_fInZoom = true;
|
||||
pPlayer->ShowViewModel( false );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,648 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Crossbow
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
//#include "AI_BaseNPC.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_baseplayer.h"
|
||||
#else
|
||||
#include "player.h"
|
||||
#endif
|
||||
//#include "player.h"
|
||||
#include "gamerules.h"
|
||||
#include "in_buttons.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "soundent.h"
|
||||
#include "entitylist.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "IEffects.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#else
|
||||
#include "te_effect_dispatch.h"
|
||||
#endif
|
||||
|
||||
#define BOLT_MODEL "models/crossbow_bolt.mdl"
|
||||
|
||||
#define BOLT_AIR_VELOCITY 2000
|
||||
#define BOLT_WATER_VELOCITY 1000
|
||||
|
||||
extern ConVar sk_plr_dmg_xbow_bolt_plr;
|
||||
extern ConVar sk_plr_dmg_xbow_bolt_npc;
|
||||
|
||||
extern short g_sModelIndexFireball; // (in combatweapon.cpp) holds the index for the fireball
|
||||
|
||||
#if !defined(CLIENT_DLL)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Crossbow Bolt
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCrossbowBolt : public CBaseCombatCharacter
|
||||
{
|
||||
DECLARE_CLASS( CCrossbowBolt, CBaseCombatCharacter );
|
||||
|
||||
public:
|
||||
CCrossbowBolt()
|
||||
{
|
||||
m_bExplode = true;
|
||||
}
|
||||
|
||||
Class_T Classify( void ) { return CLASS_NONE; }
|
||||
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void BubbleThink( void );
|
||||
void BoltTouch( CBaseEntity *pOther );
|
||||
void ExplodeThink( void );
|
||||
void SetExplode( bool bVal ) { m_bExplode = bVal; }
|
||||
bool CreateVPhysics( void );
|
||||
unsigned int PhysicsSolidMaskForEntity() const;
|
||||
|
||||
static CCrossbowBolt *BoltCreate( const Vector &vecOrigin, const QAngle &angAngles, CBasePlayer *pentOwner = NULL );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
private:
|
||||
bool m_bExplode;
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( crossbow_bolt, CCrossbowBolt );
|
||||
|
||||
BEGIN_DATADESC( CCrossbowBolt )
|
||||
// Function Pointers
|
||||
DEFINE_FUNCTION( BubbleThink ),
|
||||
DEFINE_FUNCTION( BoltTouch ),
|
||||
DEFINE_FUNCTION( ExplodeThink ),
|
||||
END_DATADESC()
|
||||
|
||||
CCrossbowBolt *CCrossbowBolt::BoltCreate( const Vector &vecOrigin, const QAngle &angAngles, CBasePlayer *pentOwner )
|
||||
{
|
||||
// Create a new entity with CCrossbowBolt private data
|
||||
CCrossbowBolt *pBolt = (CCrossbowBolt *)CreateEntityByName( "crossbow_bolt" );
|
||||
UTIL_SetOrigin( pBolt, vecOrigin );
|
||||
pBolt->SetAbsAngles( angAngles );
|
||||
pBolt->Spawn();
|
||||
pBolt->SetOwnerEntity( pentOwner );
|
||||
|
||||
return pBolt;
|
||||
}
|
||||
|
||||
void CCrossbowBolt::Spawn( )
|
||||
{
|
||||
Precache( );
|
||||
|
||||
SetModel( BOLT_MODEL );
|
||||
UTIL_SetSize( this, -Vector(1, 1, 1), Vector(1, 1, 1) );
|
||||
|
||||
SetSolid( SOLID_BBOX );
|
||||
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
|
||||
SetGravity( UTIL_ScaleForGravity( 40 ) ); // use a really low gravity (40 in/s^2)
|
||||
|
||||
SetTouch( &CCrossbowBolt::BoltTouch );
|
||||
|
||||
SetThink( &CCrossbowBolt::BubbleThink );
|
||||
SetNextThink( gpGlobals->curtime + 0.2 );
|
||||
|
||||
m_bExplode = true;
|
||||
}
|
||||
|
||||
|
||||
void CCrossbowBolt::Precache( )
|
||||
{
|
||||
PrecacheModel( BOLT_MODEL );
|
||||
PrecacheScriptSound( "BaseGrenade.Explode" );
|
||||
}
|
||||
|
||||
void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
|
||||
{
|
||||
if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) )
|
||||
return;
|
||||
|
||||
SetTouch( NULL );
|
||||
SetThink( NULL );
|
||||
|
||||
if ( pOther->m_takedamage != DAMAGE_NO )
|
||||
{
|
||||
trace_t tr, tr2;
|
||||
tr = BaseClass::GetTouchTrace( );
|
||||
Vector vecNormalizedVel = GetAbsVelocity();
|
||||
|
||||
ClearMultiDamage( );
|
||||
VectorNormalize( vecNormalizedVel );
|
||||
|
||||
if ( pOther->IsPlayer() )
|
||||
{
|
||||
float m_fDamage = sk_plr_dmg_xbow_bolt_plr.GetFloat() * g_pGameRules->GetDamageMultiplier();
|
||||
|
||||
// If multiplayer sniper bolt, multiply damage by 4
|
||||
if ( g_pGameRules->IsMultiplayer() && !m_bExplode )
|
||||
m_fDamage *= 4;
|
||||
|
||||
CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), m_fDamage,DMG_NEVERGIB );
|
||||
CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos );
|
||||
pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
|
||||
}
|
||||
else
|
||||
{
|
||||
CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_xbow_bolt_npc.GetFloat() * g_pGameRules->GetDamageMultiplier(), DMG_BULLET | DMG_NEVERGIB );
|
||||
CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos );
|
||||
pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
|
||||
}
|
||||
|
||||
ApplyMultiDamage();
|
||||
|
||||
SetAbsVelocity( Vector( 0, 0, 0 ) );
|
||||
|
||||
// play body "thwack" sound
|
||||
EmitSound( "Weapon_Crossbow.BoltHitBody" );
|
||||
|
||||
Vector vForward;
|
||||
|
||||
AngleVectors( GetAbsAngles(), &vForward );
|
||||
VectorNormalize ( vForward );
|
||||
|
||||
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vForward * 128, MASK_OPAQUE, pOther, COLLISION_GROUP_NONE, &tr2 );
|
||||
|
||||
if ( tr2.fraction != 1.0f )
|
||||
{
|
||||
// NDebugOverlay::Box( tr2.endpos, Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 255, 0, 0, 10 );
|
||||
// NDebugOverlay::Box( GetAbsOrigin(), Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 0, 255, 0, 10 );
|
||||
|
||||
CEffectData data;
|
||||
|
||||
data.m_vOrigin = tr2.endpos;
|
||||
data.m_vNormal = vForward;
|
||||
data.m_nEntIndex = tr2.fraction != 1.0f;
|
||||
|
||||
DispatchEffect( "BoltImpact", data );
|
||||
}
|
||||
|
||||
if ( !g_pGameRules->IsMultiplayer() || !m_bExplode )
|
||||
{
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitSound( "Weapon_Crossbow.BoltHitWorld" );
|
||||
|
||||
SetThink( &CCrossbowBolt::SUB_Remove );
|
||||
SetNextThink( gpGlobals->curtime );// this will get changed below if the bolt is allowed to stick in what it hit.
|
||||
|
||||
if ( m_bExplode == false )
|
||||
{
|
||||
Vector vForward;
|
||||
AngleVectors( GetAbsAngles(), &vForward );
|
||||
VectorNormalize ( vForward );
|
||||
|
||||
CEffectData data;
|
||||
|
||||
data.m_vOrigin = GetAbsOrigin();
|
||||
data.m_vNormal = vForward;
|
||||
data.m_nEntIndex = 0;
|
||||
|
||||
DispatchEffect( "BoltImpact", data );
|
||||
}
|
||||
|
||||
if ( UTIL_PointContents( GetAbsOrigin() ) != CONTENTS_WATER)
|
||||
{
|
||||
g_pEffects->Sparks( GetAbsOrigin() );
|
||||
}
|
||||
}
|
||||
|
||||
// Set up an explosion in one tenth of a second
|
||||
if ( g_pGameRules->IsMultiplayer() && m_bExplode )
|
||||
{
|
||||
SetThink( &CCrossbowBolt::ExplodeThink );
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
}
|
||||
}
|
||||
|
||||
void CCrossbowBolt::ExplodeThink( void )
|
||||
{
|
||||
// int iContents = UTIL_PointContents( pev->origin );
|
||||
CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_xbow_bolt_npc.GetFloat() * g_pGameRules->GetDamageMultiplier(), DMG_BLAST );
|
||||
|
||||
::RadiusDamage( dmgInfo, GetAbsOrigin(), 128, CLASS_NONE, NULL );
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
CPASFilter filter( GetAbsOrigin() );
|
||||
|
||||
te->Explosion( filter, /* filter */
|
||||
0.0, /* delay */
|
||||
&GetAbsOrigin(), /* pos */
|
||||
g_sModelIndexFireball, /* modelindex */
|
||||
0.2, /* scale */
|
||||
25, /* framerate */
|
||||
TE_EXPLFLAG_NONE, /* flags */
|
||||
128, /* radius */
|
||||
64, /* magnitude */
|
||||
NULL, /* normal */
|
||||
'C' ); /* materialType */
|
||||
|
||||
//CSoundEnt::InsertSound ( SOUND_COMBAT, GetAbsOrigin(), BASEGRENADE_EXPLOSION_VOLUME, 3.0 );
|
||||
EmitSound( "BaseGrenade.Explode" );
|
||||
#endif
|
||||
|
||||
|
||||
SetThink( &CCrossbowBolt::SUB_Remove );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
|
||||
AddEffects( EF_NODRAW );
|
||||
}
|
||||
|
||||
void CCrossbowBolt::BubbleThink( void )
|
||||
{
|
||||
QAngle angNewAngles;
|
||||
|
||||
VectorAngles( GetAbsVelocity(), angNewAngles );
|
||||
SetAbsAngles( angNewAngles );
|
||||
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
|
||||
if ( GetWaterLevel() == 0 )
|
||||
return;
|
||||
|
||||
UTIL_BubbleTrail( GetAbsOrigin() - GetAbsVelocity() * 0.1, GetAbsOrigin(), 1 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CCrossbowBolt::CreateVPhysics( void )
|
||||
{
|
||||
// Create the object in the physics system
|
||||
VPhysicsInitNormal( SOLID_BBOX, FSOLID_NOT_STANDABLE, false );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int CCrossbowBolt::PhysicsSolidMaskForEntity() const
|
||||
{
|
||||
return ( BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_HITBOX ) & ~CONTENTS_GRATE;
|
||||
}
|
||||
|
||||
|
||||
#endif // crossbowbolt
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeaponCrossbow
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponCrossbow C_WeaponCrossbow
|
||||
#endif
|
||||
|
||||
class CWeaponCrossbow : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponCrossbow, CBaseHL1MPCombatWeapon );
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
CWeaponCrossbow( void );
|
||||
|
||||
void Precache( void );
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
bool Reload( void );
|
||||
void WeaponIdle( void );
|
||||
bool Deploy( void );
|
||||
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// DECLARE_ACTTABLE();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void FireBolt( void );
|
||||
void ToggleZoom( void );
|
||||
|
||||
private:
|
||||
// bool m_fInZoom;
|
||||
CNetworkVar( bool, m_fInZoom );
|
||||
};
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponCrossbow, DT_WeaponCrossbow );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponCrossbow, DT_WeaponCrossbow )
|
||||
#ifdef CLIENT_DLL
|
||||
RecvPropBool( RECVINFO( m_fInZoom ) ),
|
||||
#else
|
||||
SendPropBool( SENDINFO( m_fInZoom ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponCrossbow )
|
||||
#ifdef CLIENT_DLL
|
||||
DEFINE_PRED_FIELD( m_fInZoom, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
|
||||
#endif
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_crossbow, CWeaponCrossbow );
|
||||
|
||||
PRECACHE_WEAPON_REGISTER( weapon_crossbow );
|
||||
|
||||
//IMPLEMENT_SERVERCLASS_ST( CWeaponCrossbow, DT_WeaponCrossbow )
|
||||
//END_SEND_TABLE()
|
||||
|
||||
BEGIN_DATADESC( CWeaponCrossbow )
|
||||
END_DATADESC()
|
||||
|
||||
#if 0
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
acttable_t CWeaponCrossbow::m_acttable[] =
|
||||
{
|
||||
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_CROSSBOW, false },
|
||||
// { ACT_HL2MP_RUN, ACT_HL2MP_RUN_CROSSBOW, false },
|
||||
// { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_CROSSBOW, false },
|
||||
// { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_CROSSBOW, false },
|
||||
// { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false },
|
||||
// { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_CROSSBOW, false },
|
||||
// { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_CROSSBOW, false },
|
||||
};
|
||||
|
||||
IMPLEMENT_ACTTABLE(CWeaponCrossbow);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CWeaponCrossbow::CWeaponCrossbow( void )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = true;
|
||||
m_fInZoom = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponCrossbow::Precache( void )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
UTIL_PrecacheOther( "crossbow_bolt" );
|
||||
#endif
|
||||
|
||||
PrecacheScriptSound( "Weapon_Crossbow.BoltHitBody" );
|
||||
PrecacheScriptSound( "Weapon_Crossbow.BoltHitWorld" );
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponCrossbow::PrimaryAttack( void )
|
||||
{
|
||||
if ( m_fInZoom && g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// FireSniperBolt();
|
||||
FireBolt();
|
||||
}
|
||||
else
|
||||
{
|
||||
FireBolt();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponCrossbow::SecondaryAttack( void )
|
||||
{
|
||||
ToggleZoom();
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponCrossbow::FireBolt( void )
|
||||
{
|
||||
if ( m_iClip1 <= 0 )
|
||||
{
|
||||
if ( !m_bFireOnEmpty )
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
m_flNextPrimaryAttack = 0.15;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
|
||||
|
||||
if ( pOwner == NULL )
|
||||
return;
|
||||
|
||||
Vector vecAiming = pOwner->GetAutoaimVector( AUTOAIM_2DEGREES );
|
||||
Vector vecSrc = pOwner->Weapon_ShootPosition();
|
||||
|
||||
QAngle angAiming;
|
||||
VectorAngles( vecAiming, angAiming );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
CCrossbowBolt *pBolt = CCrossbowBolt::BoltCreate( vecSrc, angAiming, pOwner );
|
||||
|
||||
// In multiplayer, secondary fire is instantaneous.
|
||||
if ( g_pGameRules->IsMultiplayer() && m_fInZoom )
|
||||
{
|
||||
Vector vecEnd = vecSrc + ( vecAiming * MAX_TRACE_LENGTH );
|
||||
|
||||
trace_t trace;
|
||||
UTIL_TraceLine( vecSrc, vecEnd, MASK_SHOT, GetOwner(), COLLISION_GROUP_NONE, &trace );
|
||||
pBolt->SetAbsOrigin( trace.endpos );
|
||||
|
||||
// We hit someone
|
||||
if ( trace.m_pEnt && trace.m_pEnt->m_takedamage )
|
||||
{
|
||||
pBolt->SetExplode( false );
|
||||
pBolt->BoltTouch( trace.m_pEnt );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pOwner->GetWaterLevel() == 3 )
|
||||
{
|
||||
pBolt->SetAbsVelocity( vecAiming * BOLT_WATER_VELOCITY );
|
||||
}
|
||||
else
|
||||
{
|
||||
pBolt->SetAbsVelocity( vecAiming * BOLT_AIR_VELOCITY );
|
||||
}
|
||||
}
|
||||
|
||||
pBolt->SetLocalAngularVelocity( QAngle( 0, 0, 10 ) );
|
||||
|
||||
if ( m_fInZoom || !g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
pBolt->SetExplode( false );
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
m_iClip1--;
|
||||
|
||||
pOwner->ViewPunch( QAngle( -2, 0, 0 ) );
|
||||
|
||||
WeaponSound( SINGLE );
|
||||
WeaponSound( RELOAD );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 200, 0.2 );
|
||||
#endif
|
||||
|
||||
if ( m_iClip1 > 0 )
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
}
|
||||
else if ( pOwner->GetAmmoCount(m_iPrimaryAmmoType) > 0 )
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
|
||||
}
|
||||
|
||||
if ( !m_iClip1 && pOwner->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
// HEV suit - indicate out of ammo condition
|
||||
pOwner->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
|
||||
}
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.75;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.75;
|
||||
|
||||
if ( m_iClip1 > 0 )
|
||||
{
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 5.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 0.75 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CWeaponCrossbow::Reload( void )
|
||||
{
|
||||
bool fRet;
|
||||
|
||||
fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
|
||||
if ( fRet )
|
||||
{
|
||||
if ( m_fInZoom )
|
||||
{
|
||||
ToggleZoom();
|
||||
}
|
||||
|
||||
WeaponSound( RELOAD );
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponCrossbow::WeaponIdle( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->GetAutoaimVector( AUTOAIM_2DEGREES );
|
||||
}
|
||||
|
||||
if ( !HasWeaponIdleTimeElapsed() )
|
||||
return;
|
||||
|
||||
int iAnim;
|
||||
float flRand = random->RandomFloat( 0, 1 );
|
||||
if ( flRand <= 0.75 )
|
||||
{
|
||||
if ( m_iClip1 <= 0 )
|
||||
iAnim = ACT_CROSSBOW_IDLE_UNLOADED;
|
||||
else
|
||||
iAnim = ACT_VM_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_iClip1 <= 0 )
|
||||
iAnim = ACT_CROSSBOW_FIDGET_UNLOADED;
|
||||
else
|
||||
iAnim = ACT_VM_FIDGET;
|
||||
}
|
||||
|
||||
SendWeaponAnim( iAnim );
|
||||
}
|
||||
|
||||
|
||||
bool CWeaponCrossbow::Deploy( void )
|
||||
{
|
||||
if ( m_iClip1 <= 0 )
|
||||
{
|
||||
return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_CROSSBOW_DRAW_UNLOADED, (char*)GetAnimPrefix() );
|
||||
}
|
||||
|
||||
return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_VM_DRAW, (char*)GetAnimPrefix() );
|
||||
}
|
||||
|
||||
|
||||
bool CWeaponCrossbow::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
{
|
||||
if ( m_fInZoom )
|
||||
{
|
||||
ToggleZoom();
|
||||
}
|
||||
|
||||
return BaseClass::Holster( pSwitchingTo );
|
||||
}
|
||||
|
||||
|
||||
void CWeaponCrossbow::ToggleZoom( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(CLIENT_DLL)
|
||||
if ( m_fInZoom )
|
||||
{
|
||||
if ( pPlayer->SetFOV( this, 0 ) )
|
||||
{
|
||||
m_fInZoom = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pPlayer->SetFOV( this, 20 ) )
|
||||
{
|
||||
m_fInZoom = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Egon
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
#include "Sprite.h"
|
||||
#include "beam_shared.h"
|
||||
#include "takedamageinfo.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
//#include "AI_BaseNPC.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_baseplayer.h"
|
||||
#include "hl1/hl1_c_player.h"
|
||||
#else
|
||||
#include "player.h"
|
||||
#include "hl1_player.h"
|
||||
#endif
|
||||
|
||||
//#include "player.h"
|
||||
#include "gamerules.h"
|
||||
#include "in_buttons.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "IEffects.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#else
|
||||
#include "te_effect_dispatch.h"
|
||||
#endif
|
||||
|
||||
|
||||
enum EGON_FIRESTATE { FIRE_OFF, FIRE_STARTUP, FIRE_CHARGE };
|
||||
|
||||
#define EGON_PULSE_INTERVAL 0.1
|
||||
#define EGON_DISCHARGE_INTERVAL 0.1
|
||||
|
||||
#define EGON_BEAM_SPRITE "sprites/xbeam1.vmt"
|
||||
#define EGON_FLARE_SPRITE "sprites/XSpark1.vmt"
|
||||
|
||||
extern ConVar sk_plr_dmg_egon_wide;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeaponEgon
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponEgon C_WeaponEgon
|
||||
#endif
|
||||
|
||||
class CWeaponEgon : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponEgon, CBaseHL1MPCombatWeapon );
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
CWeaponEgon(void);
|
||||
|
||||
virtual bool Deploy( void );
|
||||
void PrimaryAttack( void );
|
||||
virtual void Precache( void );
|
||||
|
||||
void SecondaryAttack( void )
|
||||
{
|
||||
PrimaryAttack();
|
||||
}
|
||||
|
||||
void WeaponIdle( void );
|
||||
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
// DECLARE_DATADESC();
|
||||
|
||||
private:
|
||||
bool HasAmmo( void );
|
||||
void UseAmmo( int count );
|
||||
void Attack( void );
|
||||
void EndAttack( void );
|
||||
void Fire( const Vector &vecOrigSrc, const Vector &vecDir );
|
||||
void UpdateEffect( const Vector &startPoint, const Vector &endPoint );
|
||||
void CreateEffect( void );
|
||||
void DestroyEffect( void );
|
||||
|
||||
EGON_FIRESTATE m_fireState;
|
||||
float m_flAmmoUseTime; // since we use < 1 point of ammo per update, we subtract ammo on a timer.
|
||||
float m_flShakeTime;
|
||||
float m_flStartFireTime;
|
||||
float m_flDmgTime;
|
||||
CHandle<CSprite> m_hSprite;
|
||||
CHandle<CBeam> m_hBeam;
|
||||
CHandle<CBeam> m_hNoise;
|
||||
};
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponEgon, DT_WeaponEgon );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponEgon, DT_WeaponEgon )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponEgon )
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_egon, CWeaponEgon );
|
||||
PRECACHE_WEAPON_REGISTER( weapon_egon );
|
||||
|
||||
/*
|
||||
IMPLEMENT_SERVERCLASS_ST( CWeaponEgon, DT_WeaponEgon )
|
||||
END_SEND_TABLE()
|
||||
*/
|
||||
|
||||
/*
|
||||
BEGIN_DATADESC( CWeaponEgon )
|
||||
DEFINE_FIELD( m_fireState, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( m_flAmmoUseTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_flShakeTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_flStartFireTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_flDmgTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_hSprite, FIELD_EHANDLE ),
|
||||
DEFINE_FIELD( m_hBeam, FIELD_EHANDLE ),
|
||||
DEFINE_FIELD( m_hNoise, FIELD_EHANDLE ),
|
||||
END_DATADESC()
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CWeaponEgon::CWeaponEgon( void )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponEgon::Precache( void )
|
||||
{
|
||||
PrecacheScriptSound( "Weapon_Gluon.Start" );
|
||||
PrecacheScriptSound( "Weapon_Gluon.Run" );
|
||||
PrecacheScriptSound( "Weapon_Gluon.Off" );
|
||||
|
||||
PrecacheModel( EGON_BEAM_SPRITE );
|
||||
PrecacheModel( EGON_FLARE_SPRITE );
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
bool CWeaponEgon::Deploy( void )
|
||||
{
|
||||
m_fireState = FIRE_OFF;
|
||||
|
||||
return BaseClass::Deploy();
|
||||
}
|
||||
|
||||
bool CWeaponEgon::HasAmmo( void )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWeaponEgon::UseAmmo( int count )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) >= count )
|
||||
pPlayer->RemoveAmmo( count, m_iPrimaryAmmoType );
|
||||
else
|
||||
pPlayer->RemoveAmmo( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ), m_iPrimaryAmmoType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponEgon::PrimaryAttack( void )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// don't fire underwater
|
||||
if ( pPlayer->GetWaterLevel() == 3 )
|
||||
{
|
||||
if ( m_fireState != FIRE_OFF || m_hBeam )
|
||||
{
|
||||
EndAttack();
|
||||
}
|
||||
else
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
}
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector vecAiming = pPlayer->GetAutoaimVector( 0 );
|
||||
Vector vecSrc = pPlayer->Weapon_ShootPosition( );
|
||||
|
||||
switch( m_fireState )
|
||||
{
|
||||
case FIRE_OFF:
|
||||
{
|
||||
if ( !HasAmmo() )
|
||||
{
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.25;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.25;
|
||||
WeaponSound( EMPTY );
|
||||
return;
|
||||
}
|
||||
|
||||
m_flAmmoUseTime = gpGlobals->curtime;// start using ammo ASAP.
|
||||
|
||||
EmitSound( "Weapon_Gluon.Start" );
|
||||
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
|
||||
m_flShakeTime = 0;
|
||||
m_flStartFireTime = gpGlobals->curtime;
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 0.1 );
|
||||
|
||||
m_flDmgTime = gpGlobals->curtime + EGON_PULSE_INTERVAL;
|
||||
m_fireState = FIRE_STARTUP;
|
||||
}
|
||||
break;
|
||||
|
||||
case FIRE_STARTUP:
|
||||
{
|
||||
Fire( vecSrc, vecAiming );
|
||||
|
||||
if ( gpGlobals->curtime >= ( m_flStartFireTime + 2.0 ) )
|
||||
{
|
||||
EmitSound( "Weapon_Gluon.Run" );
|
||||
|
||||
m_fireState = FIRE_CHARGE;
|
||||
}
|
||||
|
||||
if ( !HasAmmo() )
|
||||
{
|
||||
EndAttack();
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
|
||||
}
|
||||
}
|
||||
case FIRE_CHARGE:
|
||||
{
|
||||
Fire( vecSrc, vecAiming );
|
||||
|
||||
if ( !HasAmmo() )
|
||||
{
|
||||
EndAttack();
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CWeaponEgon::Fire( const Vector &vecOrigSrc, const Vector &vecDir )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 450, 0.1 );
|
||||
WeaponSound( SINGLE );
|
||||
|
||||
Vector vecDest = vecOrigSrc + (vecDir * MAX_TRACE_LENGTH);
|
||||
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( vecOrigSrc, vecDest, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( tr.allsolid )
|
||||
return;
|
||||
|
||||
CBaseEntity *pEntity = tr.m_pEnt;
|
||||
if ( pEntity == NULL )
|
||||
return;
|
||||
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
if ( m_hSprite )
|
||||
{
|
||||
if ( pEntity->m_takedamage != DAMAGE_NO )
|
||||
{
|
||||
m_hSprite->TurnOn();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hSprite->TurnOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_flDmgTime < gpGlobals->curtime )
|
||||
{
|
||||
// wide mode does damage to the ent, and radius damage
|
||||
if ( pEntity->m_takedamage != DAMAGE_NO )
|
||||
{
|
||||
ClearMultiDamage();
|
||||
CTakeDamageInfo info( this, pPlayer, sk_plr_dmg_egon_wide.GetFloat() * g_pGameRules->GetDamageMultiplier(), DMG_ENERGYBEAM | DMG_ALWAYSGIB );
|
||||
CalculateMeleeDamageForce( &info, vecDir, tr.endpos );
|
||||
pEntity->DispatchTraceAttack( info, vecDir, &tr );
|
||||
ApplyMultiDamage();
|
||||
}
|
||||
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// radius damage a little more potent in multiplayer.
|
||||
#ifndef CLIENT_DLL
|
||||
RadiusDamage( CTakeDamageInfo( this, pPlayer, sk_plr_dmg_egon_wide.GetFloat() * g_pGameRules->GetDamageMultiplier() / 4, DMG_ENERGYBEAM | DMG_BLAST | DMG_ALWAYSGIB ), tr.endpos, 128, CLASS_NONE, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( !pPlayer->IsAlive() )
|
||||
return;
|
||||
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
//multiplayer uses 5 ammo/second
|
||||
if ( gpGlobals->curtime >= m_flAmmoUseTime )
|
||||
{
|
||||
UseAmmo( 1 );
|
||||
m_flAmmoUseTime = gpGlobals->curtime + 0.2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wide mode uses 10 charges per second in single player
|
||||
if ( gpGlobals->curtime >= m_flAmmoUseTime )
|
||||
{
|
||||
UseAmmo( 1 );
|
||||
m_flAmmoUseTime = gpGlobals->curtime + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
m_flDmgTime = gpGlobals->curtime + EGON_DISCHARGE_INTERVAL;
|
||||
if ( m_flShakeTime < gpGlobals->curtime )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
UTIL_ScreenShake( tr.endpos, 5.0, 150.0, 0.75, 250.0, SHAKE_START );
|
||||
#endif
|
||||
m_flShakeTime = gpGlobals->curtime + 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
Vector vecUp, vecRight;
|
||||
QAngle angDir;
|
||||
|
||||
VectorAngles( vecDir, angDir );
|
||||
AngleVectors( angDir, NULL, &vecRight, &vecUp );
|
||||
|
||||
Vector tmpSrc = vecOrigSrc + (vecUp * -8) + (vecRight * 3);
|
||||
UpdateEffect( tmpSrc, tr.endpos );
|
||||
}
|
||||
|
||||
void CWeaponEgon::UpdateEffect( const Vector &startPoint, const Vector &endPoint )
|
||||
{
|
||||
if ( !m_hBeam )
|
||||
{
|
||||
CreateEffect();
|
||||
}
|
||||
|
||||
if ( m_hBeam )
|
||||
{
|
||||
m_hBeam->SetStartPos( endPoint );
|
||||
}
|
||||
|
||||
if ( m_hSprite )
|
||||
{
|
||||
m_hSprite->SetAbsOrigin( endPoint );
|
||||
|
||||
m_hSprite->m_flFrame += 8 * gpGlobals->frametime;
|
||||
if ( m_hSprite->m_flFrame > m_hSprite->Frames() )
|
||||
m_hSprite->m_flFrame = 0;
|
||||
}
|
||||
|
||||
if ( m_hNoise )
|
||||
{
|
||||
m_hNoise->SetStartPos( endPoint );
|
||||
}
|
||||
}
|
||||
|
||||
void CWeaponEgon::CreateEffect( void )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DestroyEffect();
|
||||
|
||||
m_hBeam = CBeam::BeamCreate( EGON_BEAM_SPRITE, 3.5 );
|
||||
m_hBeam->PointEntInit( GetAbsOrigin(), this );
|
||||
m_hBeam->SetBeamFlags( FBEAM_SINENOISE );
|
||||
m_hBeam->SetEndAttachment( 1 );
|
||||
m_hBeam->AddSpawnFlags( SF_BEAM_TEMPORARY ); // Flag these to be destroyed on save/restore or level transition
|
||||
m_hBeam->SetOwnerEntity( pPlayer );
|
||||
m_hBeam->SetScrollRate( 10 );
|
||||
m_hBeam->SetBrightness( 200 );
|
||||
m_hBeam->SetColor( 50, 50, 255 );
|
||||
m_hBeam->SetNoise( 0.2 );
|
||||
|
||||
m_hNoise = CBeam::BeamCreate( EGON_BEAM_SPRITE, 5.0 );
|
||||
m_hNoise->PointEntInit( GetAbsOrigin(), this );
|
||||
m_hNoise->SetEndAttachment( 1 );
|
||||
m_hNoise->AddSpawnFlags( SF_BEAM_TEMPORARY );
|
||||
m_hNoise->SetOwnerEntity( pPlayer );
|
||||
m_hNoise->SetScrollRate( 25 );
|
||||
m_hNoise->SetBrightness( 200 );
|
||||
m_hNoise->SetColor( 50, 50, 255 );
|
||||
m_hNoise->SetNoise( 0.8 );
|
||||
|
||||
m_hSprite = CSprite::SpriteCreate( EGON_FLARE_SPRITE, GetAbsOrigin(), false );
|
||||
m_hSprite->SetScale( 1.0 );
|
||||
m_hSprite->SetTransparency( kRenderGlow, 255, 255, 255, 255, kRenderFxNoDissipation );
|
||||
m_hSprite->AddSpawnFlags( SF_SPRITE_TEMPORARY );
|
||||
m_hSprite->SetOwnerEntity( pPlayer );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void CWeaponEgon::DestroyEffect( void )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
if ( m_hBeam )
|
||||
{
|
||||
UTIL_Remove( m_hBeam );
|
||||
m_hBeam = NULL;
|
||||
}
|
||||
if ( m_hNoise )
|
||||
{
|
||||
UTIL_Remove( m_hNoise );
|
||||
m_hNoise = NULL;
|
||||
}
|
||||
if ( m_hSprite )
|
||||
{
|
||||
m_hSprite->Expand( 10, 500 );
|
||||
m_hSprite = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CWeaponEgon::EndAttack( void )
|
||||
{
|
||||
StopSound( "Weapon_Gluon.Run" );
|
||||
|
||||
if ( m_fireState != FIRE_OFF )
|
||||
{
|
||||
EmitSound( "Weapon_Gluon.Off" );
|
||||
}
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 2.0 );
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
|
||||
|
||||
m_fireState = FIRE_OFF;
|
||||
|
||||
DestroyEffect();
|
||||
}
|
||||
|
||||
bool CWeaponEgon::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
{
|
||||
EndAttack();
|
||||
|
||||
return BaseClass::Holster( pSwitchingTo );
|
||||
}
|
||||
|
||||
void CWeaponEgon::WeaponIdle( void )
|
||||
{
|
||||
if ( !HasWeaponIdleTimeElapsed() )
|
||||
return;
|
||||
|
||||
if ( m_fireState != FIRE_OFF )
|
||||
EndAttack();
|
||||
|
||||
int iAnim;
|
||||
|
||||
float flRand = random->RandomFloat( 0,1 );
|
||||
float flIdleTime;
|
||||
if ( flRand <= 0.5 )
|
||||
{
|
||||
iAnim = ACT_VM_IDLE;
|
||||
flIdleTime = gpGlobals->curtime + random->RandomFloat( 10, 15 );
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = ACT_VM_FIDGET;
|
||||
flIdleTime = gpGlobals->curtime + 3.0;
|
||||
}
|
||||
|
||||
SendWeaponAnim( iAnim );
|
||||
|
||||
SetWeaponIdleTime( flIdleTime );
|
||||
}
|
||||
@@ -0,0 +1,719 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Gauss
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
//#include "AI_BaseNPC.h"
|
||||
#include "takedamageinfo.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "hl1/hl1_c_player.h"
|
||||
#else
|
||||
#include "hl1_player.h"
|
||||
#endif
|
||||
#include "gamerules.h"
|
||||
#include "in_buttons.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "soundenvelope.h"
|
||||
//#include "hl1_player.h"
|
||||
#include "shake.h"
|
||||
#include "effect_dispatch_data.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#else
|
||||
#include "te_effect_dispatch.h"
|
||||
#endif
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
|
||||
#define GAUSS_GLOW_SPRITE "sprites/hotglow.vmt"
|
||||
#define GAUSS_BEAM_SPRITE "sprites/smoke.vmt"
|
||||
|
||||
|
||||
extern ConVar sk_plr_dmg_gauss;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponGauss C_WeaponGauss
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeaponGauss
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class CWeaponGauss : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponGauss, CBaseHL1MPCombatWeapon );
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
CWeaponGauss( void );
|
||||
|
||||
void Precache( void );
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
void WeaponIdle( void );
|
||||
void AddViewKick( void );
|
||||
bool Deploy( void );
|
||||
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
private:
|
||||
void StopSpinSound( void );
|
||||
float GetFullChargeTime( void );
|
||||
void StartFire( void );
|
||||
void Fire( Vector vecOrigSrc, Vector vecDir, float flDamage );
|
||||
|
||||
private:
|
||||
// int m_nAttackState;
|
||||
// bool m_bPrimaryFire;
|
||||
CNetworkVar( int, m_nAttackState);
|
||||
CNetworkVar( bool, m_bPrimaryFire);
|
||||
|
||||
CSoundPatch *m_sndCharge;
|
||||
};
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponGauss, DT_WeaponGauss );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponGauss, DT_WeaponGauss )
|
||||
#ifdef CLIENT_DLL
|
||||
RecvPropInt( RECVINFO( m_nAttackState ) ),
|
||||
RecvPropBool( RECVINFO( m_bPrimaryFire ) ),
|
||||
#else
|
||||
SendPropInt( SENDINFO( m_nAttackState ) ),
|
||||
SendPropBool( SENDINFO( m_bPrimaryFire ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponGauss )
|
||||
#ifdef CLIENT_DLL
|
||||
DEFINE_PRED_FIELD( m_nAttackState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_bPrimaryFire, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
|
||||
#endif
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_gauss, CWeaponGauss );
|
||||
|
||||
PRECACHE_WEAPON_REGISTER( weapon_gauss );
|
||||
|
||||
//IMPLEMENT_SERVERCLASS_ST( CWeaponGauss, DT_WeaponGauss )
|
||||
//END_SEND_TABLE()
|
||||
|
||||
BEGIN_DATADESC( CWeaponGauss )
|
||||
DEFINE_FIELD( m_nAttackState, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( m_bPrimaryFire, FIELD_BOOLEAN ),
|
||||
DEFINE_SOUNDPATCH( m_sndCharge ),
|
||||
END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CWeaponGauss::CWeaponGauss( void )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = false;
|
||||
|
||||
m_bPrimaryFire = false;
|
||||
m_nAttackState = 0;
|
||||
m_sndCharge = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponGauss::Precache( void )
|
||||
{
|
||||
PrecacheModel( GAUSS_GLOW_SPRITE );
|
||||
PrecacheModel( GAUSS_BEAM_SPRITE );
|
||||
|
||||
PrecacheScriptSound( "Weapon_Gauss.Zap1" );
|
||||
PrecacheScriptSound( "Weapon_Gauss.Zap2" );
|
||||
PrecacheScriptSound( "Weapon_Gauss.Fire" );
|
||||
PrecacheScriptSound( "Weapon_Gauss.StaticDischarge" );
|
||||
PrecacheScriptSound( "Weapon_Gauss.Spin" );
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
float CWeaponGauss::GetFullChargeTime( void )
|
||||
{
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
return 1.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponGauss::PrimaryAttack( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) < 2 )
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime + 0.5 );
|
||||
return;
|
||||
}
|
||||
|
||||
//FIXME pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_FIRE_VOLUME;
|
||||
m_bPrimaryFire = true;
|
||||
|
||||
pPlayer->RemoveAmmo( 2, m_iPrimaryAmmoType );
|
||||
|
||||
StartFire();
|
||||
m_nAttackState = 0;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 1.0 );
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime + 0.2 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponGauss::SecondaryAttack( void )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// don't fire underwater
|
||||
if ( pPlayer->GetWaterLevel() == 3 )
|
||||
{
|
||||
if ( m_nAttackState != 0 )
|
||||
{
|
||||
EmitSound( "Weapon_Gauss.Zap1" );
|
||||
SendWeaponAnim( ACT_VM_IDLE );
|
||||
m_nAttackState = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
}
|
||||
|
||||
m_flNextSecondaryAttack = m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_nAttackState == 0 )
|
||||
{
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime + 0.5 );
|
||||
return;
|
||||
}
|
||||
|
||||
m_bPrimaryFire = false;
|
||||
|
||||
pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType ); // take one ammo just to start the spin
|
||||
pPlayer->m_flNextAmmoBurn = gpGlobals->curtime;
|
||||
|
||||
// spin up
|
||||
//FIXME pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_CHARGE_VOLUME;
|
||||
|
||||
SendWeaponAnim( ACT_GAUSS_SPINUP );
|
||||
m_nAttackState = 1;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
|
||||
pPlayer->m_flStartCharge = gpGlobals->curtime;
|
||||
pPlayer->m_flAmmoStartCharge = gpGlobals->curtime + GetFullChargeTime();
|
||||
|
||||
//Start looping sound
|
||||
if ( m_sndCharge == NULL )
|
||||
{
|
||||
CPASAttenuationFilter filter( this );
|
||||
m_sndCharge = (CSoundEnvelopeController::GetController()).SoundCreate( filter, entindex(), CHAN_WEAPON, "Weapon_Gauss.Spin", ATTN_NORM );
|
||||
}
|
||||
|
||||
if ( m_sndCharge != NULL )
|
||||
{
|
||||
(CSoundEnvelopeController::GetController()).Play( m_sndCharge, 1.0f, 110 );
|
||||
}
|
||||
}
|
||||
else if (m_nAttackState == 1)
|
||||
{
|
||||
if ( HasWeaponIdleTimeElapsed() )
|
||||
{
|
||||
SendWeaponAnim( ACT_GAUSS_SPINCYCLE );
|
||||
m_nAttackState = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// during the charging process, eat one bit of ammo every once in a while
|
||||
if ( gpGlobals->curtime >= pPlayer->m_flNextAmmoBurn && pPlayer->m_flNextAmmoBurn != 1000 )
|
||||
{
|
||||
pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
|
||||
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
pPlayer->m_flNextAmmoBurn = gpGlobals->curtime + 0.1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPlayer->m_flNextAmmoBurn = gpGlobals->curtime + 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
// out of ammo! force the gun to fire
|
||||
StartFire();
|
||||
m_nAttackState = 0;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 1.0 );
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime + 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( gpGlobals->curtime >= pPlayer->m_flAmmoStartCharge )
|
||||
{
|
||||
// don't eat any more ammo after gun is fully charged.
|
||||
pPlayer->m_flNextAmmoBurn = 1000;
|
||||
}
|
||||
|
||||
int pitch = ( gpGlobals->curtime - pPlayer->m_flStartCharge ) * ( 150 / GetFullChargeTime() ) + 100;
|
||||
if ( pitch > 250 )
|
||||
pitch = 250;
|
||||
|
||||
// ALERT( at_console, "%d %d %d\n", m_nAttackState, m_iSoundState, pitch );
|
||||
|
||||
// if ( m_iSoundState == 0 )
|
||||
// ALERT( at_console, "sound state %d\n", m_iSoundState );
|
||||
|
||||
if ( m_sndCharge != NULL )
|
||||
{
|
||||
(CSoundEnvelopeController::GetController()).SoundChangePitch( m_sndCharge, pitch, 0 );
|
||||
}
|
||||
|
||||
//FIXME m_pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_CHARGE_VOLUME;
|
||||
|
||||
// m_flTimeWeaponIdle = gpGlobals->curtime + 0.1;
|
||||
if ( pPlayer->m_flStartCharge < gpGlobals->curtime - 10 )
|
||||
{
|
||||
// Player charged up too long. Zap him.
|
||||
EmitSound( "Weapon_Gauss.Zap1" );
|
||||
EmitSound( "Weapon_Gauss.Zap2" );
|
||||
|
||||
m_nAttackState = 0;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 1.0 );
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime + 1.0 );
|
||||
|
||||
#if !defined(CLIENT_DLL )
|
||||
// Add DMG_CRUSH because we don't want any physics force
|
||||
pPlayer->TakeDamage( CTakeDamageInfo( this, this, 50, DMG_SHOCK | DMG_CRUSH ) );
|
||||
|
||||
color32 gaussDamage = {255,128,0,128};
|
||||
UTIL_ScreenFade( pPlayer, gaussDamage, 2, 0.5, FFADE_IN );
|
||||
#endif
|
||||
|
||||
SendWeaponAnim( ACT_VM_IDLE );
|
||||
|
||||
StopSpinSound();
|
||||
// Player may have been killed and this weapon dropped, don't execute any more code after this!
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// StartFire- since all of this code has to run and then
|
||||
// call Fire(), it was easier at this point to rip it out
|
||||
// of weaponidle() and make its own function then to try to
|
||||
// merge this into Fire(), which has some identical variable names
|
||||
//=========================================================
|
||||
void CWeaponGauss::StartFire( void )
|
||||
{
|
||||
float flDamage;
|
||||
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector vecAiming = pPlayer->GetAutoaimVector( 0 );
|
||||
Vector vecSrc = pPlayer->Weapon_ShootPosition( );
|
||||
|
||||
if ( gpGlobals->curtime - pPlayer->m_flStartCharge > GetFullChargeTime() )
|
||||
{
|
||||
flDamage = 200;
|
||||
}
|
||||
else
|
||||
{
|
||||
flDamage = 200 * (( gpGlobals->curtime - pPlayer->m_flStartCharge) / GetFullChargeTime() );
|
||||
}
|
||||
|
||||
if ( m_bPrimaryFire )
|
||||
{
|
||||
flDamage = sk_plr_dmg_gauss.GetFloat() * g_pGameRules->GetDamageMultiplier();
|
||||
}
|
||||
|
||||
//ALERT ( at_console, "Time:%f Damage:%f\n", gpGlobals->curtime - m_pPlayer->m_flStartCharge, flDamage );
|
||||
Vector vecNewVel = pPlayer->GetAbsVelocity();
|
||||
float flZVel = vecNewVel.z;
|
||||
|
||||
if ( !m_bPrimaryFire )
|
||||
{
|
||||
vecNewVel = vecNewVel - vecAiming * flDamage * 5;
|
||||
pPlayer->SetAbsVelocity( vecNewVel );
|
||||
}
|
||||
|
||||
if ( !g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// in deathmatch, gauss can pop you up into the air. Not in single play.
|
||||
vecNewVel.z = flZVel;
|
||||
pPlayer->SetAbsVelocity( vecNewVel );
|
||||
}
|
||||
|
||||
// player "shoot" animation
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
// time until aftershock 'static discharge' sound
|
||||
pPlayer->m_flPlayAftershock = gpGlobals->curtime + random->RandomFloat( 0.3, 0.8 );
|
||||
|
||||
Fire( vecSrc, vecAiming, flDamage );
|
||||
}
|
||||
|
||||
void CWeaponGauss::Fire( Vector vecOrigSrc, Vector vecDir, float flDamage )
|
||||
{
|
||||
CBaseEntity *pIgnore;
|
||||
Vector vecSrc = vecOrigSrc;
|
||||
Vector vecDest = vecSrc + vecDir * MAX_TRACE_LENGTH;
|
||||
bool fFirstBeam = true;
|
||||
bool fHasPunched = false;
|
||||
float flMaxFrac = 1.0;
|
||||
int nMaxHits = 10;
|
||||
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//FIXME pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_FIRE_VOLUME;
|
||||
|
||||
StopSpinSound();
|
||||
|
||||
pIgnore = pPlayer;
|
||||
|
||||
// ALERT( at_console, "%f %f\n", tr.flFraction, flMaxFrac );
|
||||
|
||||
while ( flDamage > 10 && nMaxHits > 0 )
|
||||
{
|
||||
trace_t tr;
|
||||
|
||||
nMaxHits--;
|
||||
|
||||
// ALERT( at_console, "." );
|
||||
UTIL_TraceLine( vecSrc, vecDest, MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( tr.allsolid )
|
||||
break;
|
||||
|
||||
CBaseEntity *pEntity = tr.m_pEnt;
|
||||
if (pEntity == NULL)
|
||||
break;
|
||||
|
||||
CBroadcastRecipientFilter filter;
|
||||
CEffectData data6;
|
||||
if ( fFirstBeam )
|
||||
{
|
||||
pPlayer->DoMuzzleFlash();
|
||||
fFirstBeam = false;
|
||||
|
||||
data6.m_vOrigin = tr.endpos;
|
||||
// data6.m_nEntIndex = pPlayer->GetViewModel()->entindex();
|
||||
#ifdef CLIENT_DLL
|
||||
data6.m_hEntity = pPlayer;
|
||||
#else
|
||||
data6.m_nEntIndex = pPlayer->entindex();
|
||||
#endif
|
||||
data6.m_fFlags = m_bPrimaryFire;
|
||||
te->DispatchEffect( filter, 0.0, data6.m_vOrigin, "HL1GaussBeam", data6 );
|
||||
}
|
||||
else
|
||||
{
|
||||
data6.m_vOrigin = tr.endpos;
|
||||
data6.m_vStart = vecSrc;
|
||||
data6.m_fFlags = m_bPrimaryFire;
|
||||
te->DispatchEffect( filter, 0.0, data6.m_vOrigin, "HL1GaussBeamReflect", data6 );
|
||||
}
|
||||
|
||||
bool fShouldDamageEntity = ( pEntity->m_takedamage != DAMAGE_NO );
|
||||
|
||||
if ( fShouldDamageEntity )
|
||||
{
|
||||
ClearMultiDamage();
|
||||
CTakeDamageInfo info( this, pPlayer, flDamage, DMG_ENERGYBEAM );
|
||||
CalculateMeleeDamageForce( &info, vecDir, tr.endpos );
|
||||
pEntity->DispatchTraceAttack( info, vecDir, &tr );
|
||||
ApplyMultiDamage();
|
||||
}
|
||||
|
||||
if ( pEntity->IsBSPModel() && !fShouldDamageEntity )
|
||||
{
|
||||
float n;
|
||||
|
||||
pIgnore = NULL;
|
||||
|
||||
n = -DotProduct( tr.plane.normal, vecDir );
|
||||
|
||||
if ( n < 0.5 ) // 60 degrees
|
||||
{
|
||||
// ALERT( at_console, "reflect %f\n", n );
|
||||
// reflect
|
||||
Vector vecReflect;
|
||||
|
||||
vecReflect = 2.0 * tr.plane.normal * n + vecDir;
|
||||
flMaxFrac = flMaxFrac - tr.fraction;
|
||||
vecDir = vecReflect;
|
||||
vecSrc = tr.endpos;// + vecDir * 8;
|
||||
vecDest = vecSrc + vecDir * MAX_TRACE_LENGTH;
|
||||
|
||||
#if !defined(CLIENT_DLL)
|
||||
// explode a bit
|
||||
RadiusDamage( CTakeDamageInfo( this, pPlayer, flDamage * n, DMG_BLAST ), tr.endpos, flDamage * n * 2.5, CLASS_NONE, NULL );
|
||||
#endif
|
||||
|
||||
CEffectData data1;
|
||||
data1.m_vOrigin = tr.endpos;
|
||||
data1.m_vNormal = tr.plane.normal;
|
||||
data1.m_flMagnitude = flDamage * n;
|
||||
DispatchEffect( "HL1GaussReflect", data1 );
|
||||
|
||||
// lose energy
|
||||
if (n == 0)
|
||||
n = 0.1;
|
||||
|
||||
flDamage = flDamage * (1 - n);
|
||||
}
|
||||
else
|
||||
{
|
||||
// tunnel
|
||||
UTIL_ImpactTrace( &tr, DMG_ENERGYBEAM );
|
||||
|
||||
CEffectData data4;
|
||||
data4.m_vOrigin = tr.endpos;
|
||||
data4.m_flMagnitude = flDamage;
|
||||
DispatchEffect( "HL1GaussWallImpact1", data4 );
|
||||
|
||||
// limit it to one hole punch
|
||||
if ( fHasPunched )
|
||||
break;
|
||||
|
||||
fHasPunched = true;
|
||||
|
||||
// try punching through wall if secondary attack (primary is incapable of breaking through)
|
||||
if ( !m_bPrimaryFire )
|
||||
{
|
||||
trace_t punch_tr;
|
||||
|
||||
UTIL_TraceLine( tr.endpos + vecDir * 8, vecDest, MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &punch_tr);
|
||||
if ( !punch_tr.allsolid )
|
||||
{
|
||||
trace_t exit_tr;
|
||||
// trace backwards to find exit point
|
||||
UTIL_TraceLine( punch_tr.endpos, tr.endpos, MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &exit_tr);
|
||||
|
||||
float n = (exit_tr.endpos - tr.endpos).Length( );
|
||||
|
||||
if ( n < flDamage )
|
||||
{
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
|
||||
flDamage -= n;
|
||||
|
||||
CEffectData data2;
|
||||
data2.m_vOrigin = tr.endpos;
|
||||
data2.m_vNormal = vecDir;
|
||||
DispatchEffect( "HL1GaussWallPunchEnter", data2 );
|
||||
|
||||
UTIL_ImpactTrace( &exit_tr, DMG_ENERGYBEAM );
|
||||
|
||||
CEffectData data3;
|
||||
data3.m_vOrigin = exit_tr.endpos;
|
||||
data3.m_vNormal = vecDir;
|
||||
data3.m_flMagnitude = flDamage;
|
||||
DispatchEffect( "HL1GaussWallPunchExit", data3 );
|
||||
|
||||
// ALERT( at_console, "punch %f\n", n );
|
||||
|
||||
// exit blast damage
|
||||
float flDamageRadius;
|
||||
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
flDamageRadius = flDamage * 1.75; // Old code == 2.5
|
||||
}
|
||||
else
|
||||
{
|
||||
flDamageRadius = flDamage * 2.5;
|
||||
}
|
||||
|
||||
#if !defined( CLIENT_DLL)
|
||||
RadiusDamage( CTakeDamageInfo( this, pPlayer, flDamage, DMG_BLAST ), exit_tr.endpos + vecDir * 8, flDamageRadius, CLASS_NONE, NULL );
|
||||
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 1024, 3.0 );
|
||||
#endif
|
||||
|
||||
vecSrc = exit_tr.endpos + vecDir;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//ALERT( at_console, "blocked %f\n", n );
|
||||
flDamage = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//ALERT( at_console, "blocked solid\n" );
|
||||
if ( m_bPrimaryFire )
|
||||
{
|
||||
// slug doesn't punch through ever with primary
|
||||
// fire, so leave a little glowy bit and make some balls
|
||||
CEffectData data5;
|
||||
data5.m_vOrigin = tr.endpos;
|
||||
data5.m_vNormal = tr.plane.normal;
|
||||
DispatchEffect( "HL1GaussWallImpact2", data5 );
|
||||
#if !defined( CLIENT_DLL)
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.5 );
|
||||
#endif
|
||||
}
|
||||
|
||||
flDamage = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vecSrc = tr.endpos + vecDir;
|
||||
pIgnore = pEntity;
|
||||
}
|
||||
}
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -2, 0, 0 ) );
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
|
||||
CPASAttenuationFilter filter( this );
|
||||
|
||||
CSoundParameters params;
|
||||
if ( GetParametersForSound( "Weapon_Gauss.Fire", params, NULL ) )
|
||||
{
|
||||
EmitSound_t ep( params );
|
||||
ep.m_flVolume = 0.5 + flDamage * (1.0 / 400.0);
|
||||
EmitSound( filter, entindex(), ep );
|
||||
}
|
||||
}
|
||||
|
||||
void CWeaponGauss::WeaponIdle( void )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// play aftershock static discharge
|
||||
if ( pPlayer->m_flPlayAftershock && pPlayer->m_flPlayAftershock < gpGlobals->curtime )
|
||||
{
|
||||
EmitSound( "Weapon_Gauss.StaticDischarge" );
|
||||
pPlayer->m_flPlayAftershock = 0.0;
|
||||
}
|
||||
|
||||
if ( !HasWeaponIdleTimeElapsed() )
|
||||
return;
|
||||
|
||||
if ( m_nAttackState != 0 )
|
||||
{
|
||||
StartFire();
|
||||
m_nAttackState = 0;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 2.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
float flRand = random->RandomFloat( 0, 1 );
|
||||
if ( flRand <= 0.75 )
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_IDLE );
|
||||
SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_FIDGET );
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================================================
|
||||
AddViewKick
|
||||
==================================================
|
||||
*/
|
||||
|
||||
void CWeaponGauss::AddViewKick( void )
|
||||
{
|
||||
}
|
||||
|
||||
bool CWeaponGauss::Deploy( void )
|
||||
{
|
||||
if ( DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_VM_DRAW, (char*)GetAnimPrefix() ) )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->m_flPlayAftershock = 0.0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CWeaponGauss::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
{
|
||||
|
||||
StopSpinSound();
|
||||
m_nAttackState = 0;
|
||||
|
||||
return BaseClass::Holster(pSwitchingTo);
|
||||
}
|
||||
|
||||
void CWeaponGauss::StopSpinSound( void )
|
||||
{
|
||||
if ( m_sndCharge != NULL )
|
||||
{
|
||||
(CSoundEnvelopeController::GetController()).SoundDestroy( m_sndCharge );
|
||||
m_sndCharge = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Glock - hand gun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
//#include "AI_BaseNPC.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_baseplayer.h"
|
||||
#else
|
||||
#include "player.h"
|
||||
#endif
|
||||
#include "gamerules.h"
|
||||
#include "in_buttons.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponGlock C_WeaponGlock
|
||||
#endif
|
||||
|
||||
class CWeaponGlock : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponGlock, CBaseHL1MPCombatWeapon );
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
public:
|
||||
|
||||
CWeaponGlock(void);
|
||||
|
||||
void Precache( void );
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
bool Reload( void );
|
||||
void WeaponIdle( void );
|
||||
void DryFire( void );
|
||||
|
||||
private:
|
||||
void GlockFire( float flSpread , float flCycleTime, bool fUseAutoAim );
|
||||
};
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponGlock, DT_WeaponGlock );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponGlock, DT_WeaponGlock )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_glock, CWeaponGlock );
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponGlock )
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
PRECACHE_WEAPON_REGISTER( weapon_glock );
|
||||
|
||||
|
||||
CWeaponGlock::CWeaponGlock( void )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = true;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponGlock::Precache( void )
|
||||
{
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
|
||||
void CWeaponGlock::DryFire( void )
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
SendWeaponAnim( ACT_VM_DRYFIRE );
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponGlock::PrimaryAttack( void )
|
||||
{
|
||||
GlockFire( 0.01, 0.3, TRUE );
|
||||
}
|
||||
|
||||
|
||||
void CWeaponGlock::SecondaryAttack( void )
|
||||
{
|
||||
GlockFire( 0.1, 0.2, FALSE );
|
||||
}
|
||||
|
||||
|
||||
void CWeaponGlock::GlockFire( float flSpread , float flCycleTime, bool fUseAutoAim )
|
||||
{
|
||||
// Only the player fires this way so we can cast
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_iClip1 <= 0 )
|
||||
{
|
||||
if ( !m_bFireOnEmpty )
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
DryFire();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
WeaponSound( SINGLE );
|
||||
|
||||
pPlayer->DoMuzzleFlash();
|
||||
|
||||
m_iClip1--;
|
||||
|
||||
if ( m_iClip1 == 0 )
|
||||
SendWeaponAnim( ACT_GLOCK_SHOOTEMPTY );
|
||||
else
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + flCycleTime;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + flCycleTime;
|
||||
|
||||
Vector vecSrc = pPlayer->Weapon_ShootPosition();
|
||||
Vector vecAiming;
|
||||
|
||||
if ( fUseAutoAim )
|
||||
{
|
||||
vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
|
||||
}
|
||||
else
|
||||
{
|
||||
vecAiming = pPlayer->GetAutoaimVector( 0 );
|
||||
}
|
||||
|
||||
// pPlayer->FireBullets( 1, vecSrc, vecAiming, Vector( flSpread, flSpread, flSpread ), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );
|
||||
FireBulletsInfo_t info( 1, vecSrc, vecAiming, Vector( flSpread, flSpread, flSpread ), MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
|
||||
info.m_pAttacker = pPlayer;
|
||||
pPlayer->FireBullets( info );
|
||||
|
||||
EjectShell( pPlayer, 0 );
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -2, 0, 0 ) );
|
||||
#if !defined(CLIENT_DLL)
|
||||
pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );
|
||||
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 400, 0.2 );
|
||||
#endif
|
||||
|
||||
if ( !m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
// HEV suit - indicate out of ammo condition
|
||||
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
|
||||
}
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) );
|
||||
}
|
||||
|
||||
|
||||
bool CWeaponGlock::Reload( void )
|
||||
{
|
||||
bool iResult;
|
||||
|
||||
if ( m_iClip1 == 0 )
|
||||
iResult = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_GLOCK_SHOOT_RELOAD );
|
||||
else
|
||||
iResult = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CWeaponGlock::WeaponIdle( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
|
||||
}
|
||||
|
||||
// only idle if the slid isn't back
|
||||
if ( m_iClip1 != 0 )
|
||||
{
|
||||
BaseClass::WeaponIdle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Hand grenade
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
//#include "AI_BaseNPC.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "hl1/hl1_c_player.h"
|
||||
#else
|
||||
#include "hl1_player.h"
|
||||
#endif
|
||||
#include "gamerules.h"
|
||||
#include "in_buttons.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "hl1_basegrenade.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define HANDGRENADE_MODEL "models/w_grenade.mdl"
|
||||
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
extern ConVar sk_plr_dmg_grenade;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CHandGrenade
|
||||
//-----------------------------------------------------------------------------
|
||||
LINK_ENTITY_TO_CLASS( grenade_hand, CHandGrenade );
|
||||
|
||||
BEGIN_DATADESC( CHandGrenade )
|
||||
DEFINE_ENTITYFUNC( BounceTouch ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
void CHandGrenade::Spawn( void )
|
||||
{
|
||||
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
|
||||
SetSolid( SOLID_BBOX );
|
||||
AddSolidFlags( FSOLID_NOT_STANDABLE );
|
||||
|
||||
SetModel( HANDGRENADE_MODEL );
|
||||
|
||||
UTIL_SetSize( this, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ) );
|
||||
|
||||
m_bHasWarnedAI = false;
|
||||
}
|
||||
|
||||
|
||||
void CHandGrenade::Precache( void )
|
||||
{
|
||||
BaseClass::Precache( );
|
||||
|
||||
PrecacheScriptSound( "Weapon_HandGrenade.GrenadeBounce" );
|
||||
|
||||
PrecacheModel( HANDGRENADE_MODEL );
|
||||
}
|
||||
|
||||
|
||||
void CHandGrenade::ShootTimed( CBaseCombatCharacter *pOwner, Vector vecVelocity, float flTime )
|
||||
{
|
||||
SetAbsVelocity( vecVelocity );
|
||||
|
||||
SetThrower( pOwner );
|
||||
SetOwnerEntity( pOwner );
|
||||
|
||||
SetTouch( &CHandGrenade::BounceTouch ); // Bounce if touched
|
||||
|
||||
m_flDetonateTime = gpGlobals->curtime + flTime;
|
||||
SetThink( &CBaseGrenade::TumbleThink );
|
||||
SetNextThink( gpGlobals->curtime + 0.1 );
|
||||
if ( flTime < 0.1 )
|
||||
{
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
SetAbsVelocity( vec3_origin );
|
||||
}
|
||||
|
||||
// SetSequence( SelectWeightedSequence( ACT_GRENADE_TOSS ) );
|
||||
SetSequence( 0 );
|
||||
m_flPlaybackRate = 1.0;
|
||||
|
||||
SetAbsAngles( QAngle( 0,0,60) );
|
||||
|
||||
AngularImpulse angImpulse;
|
||||
angImpulse[0] = random->RandomInt( -200, 200 );
|
||||
angImpulse[1] = random->RandomInt( 400, 500 );
|
||||
angImpulse[2] = random->RandomInt( -100, 100 );
|
||||
ApplyLocalAngularVelocityImpulse( angImpulse );
|
||||
|
||||
SetGravity( UTIL_ScaleForGravity( 400 ) ); // use a lower gravity for grenades to make them easier to see
|
||||
SetFriction( 0.8 );
|
||||
|
||||
SetDamage( sk_plr_dmg_grenade.GetFloat() );
|
||||
SetDamageRadius( GetDamage() * 2.5 );
|
||||
}
|
||||
|
||||
|
||||
void CHandGrenade ::BounceSound( void )
|
||||
{
|
||||
EmitSound( "Weapon_HandGrenade.GrenadeBounce" );
|
||||
}
|
||||
|
||||
|
||||
void CHandGrenade::BounceTouch( CBaseEntity *pOther )
|
||||
{
|
||||
if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER | FSOLID_VOLUME_CONTENTS) )
|
||||
return;
|
||||
|
||||
// don't hit the guy that launched this grenade
|
||||
if ( pOther == GetThrower() )
|
||||
return;
|
||||
|
||||
// Do a special test for players
|
||||
if ( pOther->IsPlayer() )
|
||||
{
|
||||
// Never hit a player again (we'll explode and fixup anyway)
|
||||
SetCollisionGroup( COLLISION_GROUP_DEBRIS );
|
||||
}
|
||||
// only do damage if we're moving fairly fast
|
||||
if ( (pOther->m_takedamage != DAMAGE_NO) && (m_flNextAttack < gpGlobals->curtime && GetAbsVelocity().Length() > 100))
|
||||
{
|
||||
if ( GetThrower() )
|
||||
{
|
||||
trace_t tr;
|
||||
tr = CBaseEntity::GetTouchTrace( );
|
||||
ClearMultiDamage( );
|
||||
Vector forward;
|
||||
AngleVectors( GetAbsAngles(), &forward );
|
||||
|
||||
CTakeDamageInfo info( this, GetThrower(), 1, DMG_CLUB );
|
||||
CalculateMeleeDamageForce( &info, forward, tr.endpos );
|
||||
pOther->DispatchTraceAttack( info, forward, &tr );
|
||||
ApplyMultiDamage();
|
||||
}
|
||||
m_flNextAttack = gpGlobals->curtime + 1.0; // debounce
|
||||
}
|
||||
|
||||
Vector vecTestVelocity;
|
||||
// m_vecAngVelocity = Vector (300, 300, 300);
|
||||
|
||||
// this is my heuristic for modulating the grenade velocity because grenades dropped purely vertical
|
||||
// or thrown very far tend to slow down too quickly for me to always catch just by testing velocity.
|
||||
// trimming the Z velocity a bit seems to help quite a bit.
|
||||
vecTestVelocity = GetAbsVelocity();
|
||||
vecTestVelocity.z *= 0.45;
|
||||
|
||||
if ( !m_bHasWarnedAI && vecTestVelocity.Length() <= 60 )
|
||||
{
|
||||
// grenade is moving really slow. It's probably very close to where it will ultimately stop moving.
|
||||
// emit the danger sound.
|
||||
|
||||
// register a radius louder than the explosion, so we make sure everyone gets out of the way
|
||||
CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), m_flDamage / 0.4, 0.3 );
|
||||
m_bHasWarnedAI = TRUE;
|
||||
}
|
||||
|
||||
// HACKHACK - On ground isn't always set, so look for ground underneath
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( tr.fraction < 1.0 )
|
||||
{
|
||||
// add a bit of static friction
|
||||
// SetAbsVelocity( GetAbsVelocity() * 0.8 );
|
||||
SetSequence( SelectWeightedSequence( ACT_IDLE ) );
|
||||
SetAbsAngles( vec3_angle );
|
||||
}
|
||||
|
||||
// play bounce sound
|
||||
BounceSound();
|
||||
|
||||
m_flPlaybackRate = GetAbsVelocity().Length() / 200.0;
|
||||
if (m_flPlaybackRate > 1.0)
|
||||
m_flPlaybackRate = 1;
|
||||
else if (m_flPlaybackRate < 0.5)
|
||||
m_flPlaybackRate = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponHandGrenade C_WeaponHandGrenade
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeaponHandGrenade
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CWeaponHandGrenade : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponHandGrenade, CBaseHL1MPCombatWeapon );
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
CWeaponHandGrenade( void );
|
||||
|
||||
void Precache( void );
|
||||
void PrimaryAttack( void );
|
||||
void WeaponIdle( void );
|
||||
bool Deploy( void );
|
||||
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
private:
|
||||
// float m_flStartThrow;
|
||||
// float m_flReleaseThrow;
|
||||
CNetworkVar( float, m_flStartThrow );
|
||||
CNetworkVar( float, m_flReleaseThrow );
|
||||
};
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHandGrenade, DT_WeaponHandGrenade );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponHandGrenade, DT_WeaponHandGrenade )
|
||||
#ifdef CLIENT_DLL
|
||||
RecvPropFloat( RECVINFO( m_flStartThrow ) ),
|
||||
RecvPropFloat( RECVINFO( m_flReleaseThrow ) ),
|
||||
#else
|
||||
SendPropFloat( SENDINFO( m_flStartThrow ) ),
|
||||
SendPropFloat( SENDINFO( m_flReleaseThrow ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponHandGrenade )
|
||||
#ifdef CLIENT_DLL
|
||||
DEFINE_PRED_FIELD( m_flStartThrow, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_flReleaseThrow, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
|
||||
#endif
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_handgrenade, CWeaponHandGrenade );
|
||||
|
||||
PRECACHE_WEAPON_REGISTER( weapon_handgrenade );
|
||||
|
||||
//IMPLEMENT_SERVERCLASS_ST( CWeaponHandGrenade, DT_WeaponHandGrenade )
|
||||
//END_SEND_TABLE()
|
||||
|
||||
BEGIN_DATADESC( CWeaponHandGrenade )
|
||||
END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CWeaponHandGrenade::CWeaponHandGrenade( void )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponHandGrenade::Precache( void )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
UTIL_PrecacheOther( "grenade_hand" );
|
||||
#endif
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponHandGrenade::PrimaryAttack( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( m_flStartThrow <= 0 ) && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
|
||||
{
|
||||
m_flStartThrow = gpGlobals->curtime;
|
||||
m_flReleaseThrow = 0;
|
||||
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CWeaponHandGrenade::WeaponIdle( void )
|
||||
{
|
||||
if ( m_flReleaseThrow == 0 && m_flStartThrow )
|
||||
m_flReleaseThrow = gpGlobals->curtime;
|
||||
|
||||
if ( !HasWeaponIdleTimeElapsed() )
|
||||
return;
|
||||
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_flStartThrow )
|
||||
{
|
||||
Vector vecAiming = pPlayer->GetAutoaimVector( 0 );
|
||||
|
||||
QAngle angThrow;
|
||||
VectorAngles( vecAiming, angThrow );
|
||||
|
||||
Vector vecUp;
|
||||
Vector vecRight;
|
||||
AngleVectors( angThrow, NULL, &vecRight, &vecUp );
|
||||
|
||||
if ( angThrow.x > 180 ) // player is pitching up
|
||||
angThrow.x = -15 - ( 360 - angThrow.x ) * ( ( 90 - 10 ) / 90.0 );
|
||||
else // player is pitching down
|
||||
angThrow.x = -15 + angThrow.x * ( ( 90 + 10 ) / 90.0 );
|
||||
|
||||
float flVel = ( 90 - angThrow.x ) * 4;
|
||||
if ( flVel > 500 )
|
||||
flVel = 500;
|
||||
|
||||
Vector vecFwd;
|
||||
AngleVectors( angThrow, &vecFwd );
|
||||
|
||||
Vector vecSrc = pPlayer->EyePosition() + vecFwd * 16;
|
||||
Vector vecThrow = vecFwd * flVel + pPlayer->GetAbsVelocity();
|
||||
|
||||
QAngle angles;
|
||||
VectorAngles( vecThrow, angles );
|
||||
#ifndef CLIENT_DLL
|
||||
CHandGrenade *pGrenade = (CHandGrenade*)Create( "grenade_hand", vecSrc, angles );
|
||||
if ( pGrenade )
|
||||
{
|
||||
// always explode 3 seconds after the pin was pulled
|
||||
float flTime = m_flStartThrow - gpGlobals->curtime + 3.0;
|
||||
if ( flTime < 0 )
|
||||
{
|
||||
flTime = 0;
|
||||
}
|
||||
|
||||
pGrenade->ShootTimed( pPlayer, vecThrow, flTime );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( flVel < 500 )
|
||||
{
|
||||
SendWeaponAnim( ACT_HANDGRENADE_THROW1 );
|
||||
}
|
||||
else if ( flVel < 1000 )
|
||||
{
|
||||
SendWeaponAnim( ACT_HANDGRENADE_THROW2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim( ACT_HANDGRENADE_THROW3 );
|
||||
}
|
||||
|
||||
// player "shoot" animation
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
m_flReleaseThrow = 0;
|
||||
m_flStartThrow = 0;
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
|
||||
|
||||
pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
|
||||
|
||||
return;
|
||||
}
|
||||
else if ( m_flReleaseThrow > 0 )
|
||||
{
|
||||
// we've finished the throw, restart.
|
||||
m_flStartThrow = 0;
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_DRAW );
|
||||
}
|
||||
else
|
||||
{
|
||||
// RetireWeapon();
|
||||
return;
|
||||
}
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) );
|
||||
m_flReleaseThrow = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
|
||||
{
|
||||
float flRand = random->RandomFloat( 0, 1 );
|
||||
if ( flRand <= 0.75 )
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_IDLE );
|
||||
SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) );// how long till we do this again.
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim( ACT_VM_FIDGET );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CWeaponHandGrenade::Deploy( void )
|
||||
{
|
||||
m_flReleaseThrow = -1;
|
||||
|
||||
return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_VM_DRAW, (char*)GetAnimPrefix() );
|
||||
}
|
||||
|
||||
bool CWeaponHandGrenade::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( m_flStartThrow > 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !BaseClass::Holster( pSwitchingTo ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
SetThink( &CWeaponHandGrenade::DestroyItem );
|
||||
SetNextThink( gpGlobals->curtime + 0.1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime + 0.5 );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Hornetgun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
//#include "AI_BaseNPC.h"
|
||||
#include "gamerules.h"
|
||||
#include "in_buttons.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "hl1/c_hl1mp_player.h"
|
||||
#else
|
||||
#include "hl1mp_player.h"
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#if !defined(CLIENT_DLL)
|
||||
#include "hl1_npc_hornet.h"
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeaponHgun
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponHgun C_WeaponHgun
|
||||
#endif
|
||||
|
||||
class CWeaponHgun : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponHgun, CBaseHL1MPCombatWeapon );
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
CWeaponHgun( void );
|
||||
|
||||
void Precache( void );
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
void WeaponIdle( void );
|
||||
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||||
bool Reload( void );
|
||||
|
||||
virtual void ItemPostFrame( void );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
private:
|
||||
|
||||
// float m_flRechargeTime;
|
||||
// int m_iFirePhase;
|
||||
|
||||
CNetworkVar( float, m_flRechargeTime );
|
||||
CNetworkVar( int, m_iFirePhase );
|
||||
};
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHgun, DT_WeaponHgun );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponHgun, DT_WeaponHgun )
|
||||
#ifdef CLIENT_DLL
|
||||
RecvPropFloat( RECVINFO( m_flRechargeTime ) ),
|
||||
RecvPropInt( RECVINFO( m_iFirePhase ) ),
|
||||
#else
|
||||
SendPropFloat( SENDINFO( m_flRechargeTime ) ),
|
||||
SendPropInt( SENDINFO( m_iFirePhase ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponHgun )
|
||||
#ifdef CLIENT_DLL
|
||||
DEFINE_PRED_FIELD( m_flRechargeTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_iFirePhase, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
#endif
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_hornetgun, CWeaponHgun );
|
||||
|
||||
PRECACHE_WEAPON_REGISTER( weapon_hornetgun );
|
||||
|
||||
//IMPLEMENT_SERVERCLASS_ST( CWeaponHgun, DT_WeaponHgun )
|
||||
//END_SEND_TABLE()
|
||||
|
||||
BEGIN_DATADESC( CWeaponHgun )
|
||||
DEFINE_FIELD( m_flRechargeTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_iFirePhase, FIELD_INTEGER ),
|
||||
END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CWeaponHgun::CWeaponHgun( void )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = true;
|
||||
|
||||
m_flRechargeTime = 0.0;
|
||||
m_iFirePhase = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponHgun::Precache( void )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
UTIL_PrecacheOther( "hornet" );
|
||||
#endif
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponHgun::PrimaryAttack( void )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WeaponSound( SINGLE );
|
||||
#if !defined(CLIENT_DLL)
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 200, 0.2 );
|
||||
#endif
|
||||
pPlayer->DoMuzzleFlash();
|
||||
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
Vector vForward, vRight, vUp;
|
||||
QAngle vecAngles;
|
||||
|
||||
pPlayer->EyeVectors( &vForward, &vRight, &vUp );
|
||||
VectorAngles( vForward, vecAngles );
|
||||
|
||||
#if !defined(CLIENT_DLL)
|
||||
CBaseEntity *pHornet = CBaseEntity::Create( "hornet", pPlayer->Weapon_ShootPosition() + vForward * 16 + vRight * 8 + vUp * -12, vecAngles, pPlayer );
|
||||
pHornet->SetAbsVelocity( vForward * 300 );
|
||||
#endif
|
||||
|
||||
m_flRechargeTime = gpGlobals->curtime + 0.5;
|
||||
|
||||
pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -2, 0, 0 ) );
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextPrimaryAttack + 0.25;
|
||||
|
||||
if (m_flNextPrimaryAttack < gpGlobals->curtime )
|
||||
{
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.25;
|
||||
}
|
||||
|
||||
SetWeaponIdleTime( random->RandomFloat( 10, 15 ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponHgun::SecondaryAttack( void )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WeaponSound( SINGLE );
|
||||
#if !defined(CLIENT_DLL)
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 200, 0.2 );
|
||||
#endif
|
||||
pPlayer->DoMuzzleFlash();
|
||||
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
CBaseEntity *pHornet;
|
||||
Vector vecSrc;
|
||||
|
||||
Vector vForward, vRight, vUp;
|
||||
QAngle vecAngles;
|
||||
|
||||
pPlayer->EyeVectors( &vForward, &vRight, &vUp );
|
||||
VectorAngles( vForward, vecAngles );
|
||||
|
||||
vecSrc = pPlayer->Weapon_ShootPosition() + vForward * 16 + vRight * 8 + vUp * -12;
|
||||
|
||||
m_iFirePhase++;
|
||||
switch ( m_iFirePhase )
|
||||
{
|
||||
case 1:
|
||||
vecSrc = vecSrc + vUp * 8;
|
||||
break;
|
||||
case 2:
|
||||
vecSrc = vecSrc + vUp * 8;
|
||||
vecSrc = vecSrc + vRight * 8;
|
||||
break;
|
||||
case 3:
|
||||
vecSrc = vecSrc + vRight * 8;
|
||||
break;
|
||||
case 4:
|
||||
vecSrc = vecSrc + vUp * -8;
|
||||
vecSrc = vecSrc + vRight * 8;
|
||||
break;
|
||||
case 5:
|
||||
vecSrc = vecSrc + vUp * -8;
|
||||
break;
|
||||
case 6:
|
||||
vecSrc = vecSrc + vUp * -8;
|
||||
vecSrc = vecSrc + vRight * -8;
|
||||
break;
|
||||
case 7:
|
||||
vecSrc = vecSrc + vRight * -8;
|
||||
break;
|
||||
case 8:
|
||||
vecSrc = vecSrc + vUp * 8;
|
||||
vecSrc = vecSrc + vRight * -8;
|
||||
m_iFirePhase = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
pHornet = NULL;
|
||||
#else
|
||||
pHornet = CBaseEntity::Create( "hornet", vecSrc, vecAngles, pPlayer );
|
||||
pHornet->SetAbsVelocity( vForward * 1200 );
|
||||
pHornet->SetThink( &CNPC_Hornet::StartDart );
|
||||
#endif
|
||||
|
||||
m_flRechargeTime = gpGlobals->curtime + 0.5;
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -2, 0, 0 ) );
|
||||
pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + 0.1;
|
||||
SetWeaponIdleTime( random->RandomFloat( 10, 15 ) );
|
||||
}
|
||||
|
||||
void CWeaponHgun::WeaponIdle( void )
|
||||
{
|
||||
if ( !HasWeaponIdleTimeElapsed() )
|
||||
return;
|
||||
|
||||
int iAnim;
|
||||
float flRand = random->RandomFloat( 0, 1 );
|
||||
if ( flRand <= 0.75 )
|
||||
{
|
||||
iAnim = ACT_VM_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = ACT_VM_FIDGET;
|
||||
}
|
||||
|
||||
SendWeaponAnim( iAnim );
|
||||
}
|
||||
|
||||
bool CWeaponHgun::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
{
|
||||
bool bRet;
|
||||
|
||||
bRet = BaseClass::Holster( pSwitchingTo );
|
||||
|
||||
if ( bRet )
|
||||
{
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
#if !defined(CLIENT_DLL)
|
||||
//!!!HACKHACK - can't select hornetgun if it's empty! no way to get ammo for it, either.
|
||||
int iCount = pPlayer->GetAmmoCount( m_iPrimaryAmmoType );
|
||||
if ( iCount <= 0 )
|
||||
{
|
||||
pPlayer->GiveAmmo( iCount+1, m_iPrimaryAmmoType, true );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool CWeaponHgun::Reload( void )
|
||||
{
|
||||
if ( m_flRechargeTime >= gpGlobals->curtime )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
if ( !g_pGameRules->CanHaveAmmo( pPlayer, m_iPrimaryAmmoType ) )
|
||||
return true;
|
||||
|
||||
while ( ( m_flRechargeTime < gpGlobals->curtime ) && g_pGameRules->CanHaveAmmo( pPlayer, m_iPrimaryAmmoType ) )
|
||||
{
|
||||
pPlayer->GiveAmmo( 1, m_iPrimaryAmmoType, true );
|
||||
m_flRechargeTime += 0.5;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWeaponHgun::ItemPostFrame( void )
|
||||
{
|
||||
Reload();
|
||||
|
||||
BaseClass::ItemPostFrame();
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
//#include "basecombatweapon.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
#include "npcevent.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
//#include "AI_BaseNPC.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "hl1/hl1_c_player.h"
|
||||
#else
|
||||
#include "player.h"
|
||||
#endif
|
||||
#include "hl1mp_weapon_mp5.h"
|
||||
//#include "hl1_weapon_mp5.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "hl1_grenade_mp5.h"
|
||||
#endif
|
||||
#include "gamerules.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
#include "in_buttons.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
|
||||
extern ConVar sk_plr_dmg_mp5_grenade;
|
||||
extern ConVar sk_max_mp5_grenade;
|
||||
extern ConVar sk_mp5_grenade_radius;
|
||||
|
||||
//=========================================================
|
||||
//=========================================================
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponMP5, DT_WeaponMP5 );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponMP5, DT_WeaponMP5 )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponMP5 )
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_mp5, CWeaponMP5 );
|
||||
|
||||
PRECACHE_WEAPON_REGISTER(weapon_mp5);
|
||||
|
||||
//IMPLEMENT_SERVERCLASS_ST( CWeaponMP5, DT_WeaponMP5 )
|
||||
//END_SEND_TABLE()
|
||||
|
||||
BEGIN_DATADESC( CWeaponMP5 )
|
||||
END_DATADESC()
|
||||
|
||||
CWeaponMP5::CWeaponMP5( )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = false;
|
||||
}
|
||||
|
||||
void CWeaponMP5::Precache( void )
|
||||
{
|
||||
BaseClass::Precache();
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
UTIL_PrecacheOther( "grenade_mp5" );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void CWeaponMP5::PrimaryAttack( void )
|
||||
{
|
||||
// Only the player fires this way so we can cast
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_iClip1 <= 0 )
|
||||
{
|
||||
DryFire();
|
||||
return;
|
||||
}
|
||||
|
||||
WeaponSound( SINGLE );
|
||||
|
||||
pPlayer->DoMuzzleFlash();
|
||||
|
||||
m_iClip1--;
|
||||
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.1;
|
||||
|
||||
Vector vecSrc = pPlayer->Weapon_ShootPosition();
|
||||
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
|
||||
|
||||
if ( !g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// optimized multiplayer. Widened to make it easier to hit a moving player
|
||||
// pPlayer->FireBullets( 1, vecSrc, vecAiming, VECTOR_CONE_6DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2 );
|
||||
FireBulletsInfo_t info( 1, vecSrc, vecAiming, VECTOR_CONE_6DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
|
||||
info.m_pAttacker = pPlayer;
|
||||
info.m_iTracerFreq = 2;
|
||||
|
||||
pPlayer->FireBullets( info );
|
||||
}
|
||||
else
|
||||
{
|
||||
// single player spread
|
||||
// pPlayer->FireBullets( 1, vecSrc, vecAiming, VECTOR_CONE_3DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2 );
|
||||
FireBulletsInfo_t info( 1, vecSrc, vecAiming, VECTOR_CONE_3DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
|
||||
info.m_pAttacker = pPlayer;
|
||||
info.m_iTracerFreq = 2;
|
||||
|
||||
pPlayer->FireBullets( info );
|
||||
}
|
||||
|
||||
EjectShell( pPlayer, 0 );
|
||||
|
||||
pPlayer->ViewPunch( QAngle( random->RandomFloat( -2, 2 ), 0, 0 ) );
|
||||
#ifdef CLIENT_DLL
|
||||
pPlayer->DoMuzzleFlash();
|
||||
#else
|
||||
pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.2 );
|
||||
#endif
|
||||
|
||||
if ( !m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
// HEV suit - indicate out of ammo condition
|
||||
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
|
||||
}
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) );
|
||||
}
|
||||
|
||||
|
||||
void CWeaponMP5::SecondaryAttack( void )
|
||||
{
|
||||
// Only the player fires this way so we can cast
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
if (!pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iSecondaryAmmoType ) <= 0 )
|
||||
{
|
||||
DryFire( );
|
||||
return;
|
||||
}
|
||||
|
||||
WeaponSound(WPN_DOUBLE);
|
||||
|
||||
pPlayer->DoMuzzleFlash();
|
||||
|
||||
Vector vecSrc = pPlayer->Weapon_ShootPosition();
|
||||
Vector vecThrow = pPlayer->GetAutoaimVector( 0 ) * 800;
|
||||
QAngle angGrenAngle;
|
||||
|
||||
VectorAngles( vecThrow, angGrenAngle );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
CGrenadeMP5 * m_pMyGrenade = (CGrenadeMP5*)Create( "grenade_mp5", vecSrc, angGrenAngle, GetOwner() );
|
||||
m_pMyGrenade->SetAbsVelocity( vecThrow );
|
||||
m_pMyGrenade->SetLocalAngularVelocity( QAngle( random->RandomFloat( -100, -500 ), 0, 0 ) );
|
||||
m_pMyGrenade->SetMoveType( MOVETYPE_FLYGRAVITY );
|
||||
m_pMyGrenade->SetThrower( GetOwner() );
|
||||
m_pMyGrenade->SetDamage( sk_plr_dmg_mp5_grenade.GetFloat() * g_pGameRules->GetDamageMultiplier() );
|
||||
#endif
|
||||
|
||||
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -10, 0, 0 ) );
|
||||
|
||||
// Register a muzzleflash for the AI.
|
||||
#if !defined(CLIENT_DLL)
|
||||
pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.2 );
|
||||
#endif
|
||||
|
||||
// Decrease ammo
|
||||
pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType );
|
||||
if ( pPlayer->GetAmmoCount( m_iSecondaryAmmoType ) <= 0 )
|
||||
{
|
||||
// HEV suit - indicate out of ammo condition
|
||||
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
|
||||
}
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 5.0 );
|
||||
}
|
||||
|
||||
|
||||
void CWeaponMP5::DryFire( void )
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.15;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.15;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponMP5::WeaponIdle( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
|
||||
}
|
||||
|
||||
bool bElapsed = HasWeaponIdleTimeElapsed();
|
||||
|
||||
BaseClass::WeaponIdle();
|
||||
|
||||
if( bElapsed )
|
||||
SetWeaponIdleTime( gpGlobals->curtime + random->RandomInt( 3, 5 ) );
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Projectile shot from the MP5
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef WEAPONMP5_H
|
||||
#define WEAPONMP5_H
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "hl1_basegrenade.h"
|
||||
#endif
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
class CGrenadeMP5;
|
||||
#else
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponMP5 C_WeaponMP5
|
||||
#endif
|
||||
|
||||
class CWeaponMP5 : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponMP5, CBaseHL1MPCombatWeapon );
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
CWeaponMP5();
|
||||
|
||||
void Precache( void );
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
void DryFire( void );
|
||||
void WeaponIdle( void );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
||||
|
||||
#endif //WEAPONMP5_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: RPG
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
|
||||
#ifndef WEAPON_RPG_H
|
||||
#define WEAPON_RPG_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "iviewrender_beams.h"
|
||||
#include "c_smoke_trail.h"
|
||||
#endif
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
#include "smoke_trail.h"
|
||||
#include "Sprite.h"
|
||||
#include "npcevent.h"
|
||||
#include "beam_shared.h"
|
||||
#include "hl1_basegrenade.h"
|
||||
|
||||
class CWeaponRPG;
|
||||
|
||||
//###########################################################################
|
||||
// CRpgRocket
|
||||
//###########################################################################
|
||||
class CRpgRocket : public CHL1BaseGrenade
|
||||
{
|
||||
DECLARE_CLASS( CRpgRocket, CHL1BaseGrenade );
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
public:
|
||||
CRpgRocket();
|
||||
|
||||
Class_T Classify( void ) { return CLASS_NONE; }
|
||||
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void RocketTouch( CBaseEntity *pOther );
|
||||
void IgniteThink( void );
|
||||
void SeekThink( void );
|
||||
|
||||
virtual void Detonate( void );
|
||||
|
||||
static CRpgRocket *Create( const Vector &vecOrigin, const QAngle &angAngles, CBasePlayer *pentOwner = NULL );
|
||||
|
||||
CHandle<CWeaponRPG> m_hOwner;
|
||||
float m_flIgniteTime;
|
||||
int m_iTrail;
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CLaserDot C_LaserDot
|
||||
#endif
|
||||
|
||||
class CLaserDot;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponRPG C_WeaponRPG
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeaponRPG
|
||||
//-----------------------------------------------------------------------------
|
||||
class CWeaponRPG : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponRPG, CBaseHL1MPCombatWeapon );
|
||||
public:
|
||||
|
||||
CWeaponRPG( void );
|
||||
~CWeaponRPG();
|
||||
|
||||
void ItemPostFrame( void );
|
||||
void Precache( void );
|
||||
bool Deploy( void );
|
||||
void PrimaryAttack( void );
|
||||
void WeaponIdle( void );
|
||||
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||||
void NotifyRocketDied( void );
|
||||
bool Reload( void );
|
||||
|
||||
void Drop( const Vector &vecVelocity );
|
||||
|
||||
virtual int GetDefaultClip1( void ) const;
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
private:
|
||||
void CreateLaserPointer( void );
|
||||
void UpdateSpot( void );
|
||||
bool IsGuiding( void );
|
||||
void StartGuiding( void );
|
||||
void StopGuiding( void );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// DECLARE_ACTTABLE();
|
||||
#endif
|
||||
|
||||
private:
|
||||
// bool m_bGuiding;
|
||||
// CHandle<CLaserDot> m_hLaserDot;
|
||||
// CHandle<CRpgRocket> m_hMissile;
|
||||
// bool m_bIntialStateUpdate;
|
||||
// bool m_bLaserDotSuspended;
|
||||
// float m_flLaserDotReviveTime;
|
||||
|
||||
CNetworkVar( bool, m_bGuiding );
|
||||
CNetworkVar( bool, m_bIntialStateUpdate );
|
||||
CNetworkVar( bool, m_bLaserDotSuspended );
|
||||
CNetworkVar( float, m_flLaserDotReviveTime );
|
||||
|
||||
CNetworkHandle( CBaseEntity, m_hMissile );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
CHandle<CLaserDot> m_hLaserDot;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif // WEAPON_RPG_H
|
||||
@@ -0,0 +1,600 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Satchel charge
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1_basecombatweapon_shared.h"
|
||||
//#include "basecombatweapon.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_baseplayer.h"
|
||||
#else
|
||||
#include "player.h"
|
||||
#endif
|
||||
//#include "AI_BaseNPC.h"
|
||||
//#include "player.h"
|
||||
#include "gamerules.h"
|
||||
#include "in_buttons.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#endif
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "hl1mp_weapon_satchel.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeaponSatchel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#define SATCHEL_VIEW_MODEL "models/v_satchel.mdl"
|
||||
#define SATCHEL_WORLD_MODEL "models/w_satchel.mdl"
|
||||
#define SATCHELRADIO_VIEW_MODEL "models/v_satchel_radio.mdl"
|
||||
#define SATCHELRADIO_WORLD_MODEL "models/w_satchel.mdl" // this needs fixing if we do multiplayer
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponSatchel, DT_WeaponSatchel );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponSatchel, DT_WeaponSatchel )
|
||||
#ifdef CLIENT_DLL
|
||||
RecvPropInt( RECVINFO( m_iRadioViewIndex ) ),
|
||||
RecvPropInt( RECVINFO( m_iRadioWorldIndex ) ),
|
||||
RecvPropInt( RECVINFO( m_iSatchelViewIndex ) ),
|
||||
RecvPropInt( RECVINFO( m_iSatchelWorldIndex ) ),
|
||||
RecvPropInt( RECVINFO( m_iChargeReady ) ),
|
||||
#else
|
||||
SendPropInt( SENDINFO( m_iRadioViewIndex ) ),
|
||||
SendPropInt( SENDINFO( m_iRadioWorldIndex ) ),
|
||||
SendPropInt( SENDINFO( m_iSatchelViewIndex ) ),
|
||||
SendPropInt( SENDINFO( m_iSatchelWorldIndex ) ),
|
||||
SendPropInt( SENDINFO( m_iChargeReady ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_satchel, CWeaponSatchel );
|
||||
|
||||
PRECACHE_WEAPON_REGISTER( weapon_satchel );
|
||||
|
||||
//IMPLEMENT_SERVERCLASS_ST( CWeaponSatchel, DT_WeaponSatchel )
|
||||
//END_SEND_TABLE()
|
||||
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponSatchel )
|
||||
#ifdef CLIENT_DLL
|
||||
DEFINE_PRED_FIELD( m_iRadioViewIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
|
||||
DEFINE_PRED_FIELD( m_iRadioWorldIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
|
||||
DEFINE_PRED_FIELD( m_iSatchelViewIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
|
||||
DEFINE_PRED_FIELD( m_iSatchelWorldIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
|
||||
DEFINE_PRED_FIELD( m_iChargeReady, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
#endif
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
|
||||
BEGIN_DATADESC( CWeaponSatchel )
|
||||
DEFINE_FIELD( m_iChargeReady, FIELD_INTEGER ),
|
||||
|
||||
// DEFINE_FIELD( m_iRadioViewIndex, FIELD_INTEGER ),
|
||||
// DEFINE_FIELD( m_iRadioWorldIndex, FIELD_INTEGER ),
|
||||
// DEFINE_FIELD( m_iSatchelViewIndex, FIELD_INTEGER ),
|
||||
// DEFINE_FIELD( m_iSatchelWorldIndex, FIELD_INTEGER ),
|
||||
END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CWeaponSatchel::CWeaponSatchel( void )
|
||||
{
|
||||
m_bReloadsSingly = false;
|
||||
m_bFiresUnderwater = true;
|
||||
}
|
||||
|
||||
void CWeaponSatchel::Equip( CBaseCombatCharacter *pOwner )
|
||||
{
|
||||
BaseClass::Equip( pOwner );
|
||||
|
||||
m_iChargeReady = 0; // this satchel charge weapon now forgets that any satchels are deployed by it.
|
||||
}
|
||||
|
||||
bool CWeaponSatchel::HasAnyAmmo( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
|
||||
{
|
||||
// player is carrying some satchels
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( HasChargeDeployed() )
|
||||
{
|
||||
// player isn't carrying any satchels, but has some out
|
||||
return true;
|
||||
}
|
||||
|
||||
return BaseClass::HasAnyAmmo();
|
||||
}
|
||||
|
||||
bool CWeaponSatchel::CanDeploy( void )
|
||||
{
|
||||
if ( HasAnyAmmo() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponSatchel::Precache( void )
|
||||
{
|
||||
m_iSatchelViewIndex = PrecacheModel( SATCHEL_VIEW_MODEL );
|
||||
m_iSatchelWorldIndex = PrecacheModel( SATCHEL_WORLD_MODEL );
|
||||
m_iRadioViewIndex = PrecacheModel( SATCHELRADIO_VIEW_MODEL );
|
||||
m_iRadioWorldIndex = PrecacheModel( SATCHELRADIO_WORLD_MODEL );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
UTIL_PrecacheOther( "monster_satchel" );
|
||||
#endif
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
void CWeaponSatchel::ItemPostFrame( void )
|
||||
{
|
||||
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
|
||||
if (!pOwner)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime) )
|
||||
{
|
||||
// If the firing button was just pressed, reset the firing time
|
||||
if ( pOwner->m_afButtonPressed & IN_ATTACK )
|
||||
{
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime;
|
||||
}
|
||||
|
||||
PrimaryAttack();
|
||||
}
|
||||
|
||||
BaseClass::ItemPostFrame();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponSatchel::PrimaryAttack( void )
|
||||
{
|
||||
switch ( m_iChargeReady )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Throw();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
CBaseEntity *pSatchel = NULL;
|
||||
|
||||
while ( (pSatchel = gEntList.FindEntityByClassname( pSatchel, "monster_satchel" ) ) != NULL)
|
||||
{
|
||||
if ( pSatchel->GetOwnerEntity() == pPlayer )
|
||||
{
|
||||
pSatchel->Use( pPlayer, pPlayer, USE_ON, 0 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_iChargeReady = 2;
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
// we're reloading, don't allow fire
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWeaponSatchel::SecondaryAttack( void )
|
||||
{
|
||||
if ( m_iChargeReady != 2 )
|
||||
{
|
||||
Throw();
|
||||
}
|
||||
}
|
||||
|
||||
void CWeaponSatchel::Throw( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
|
||||
{
|
||||
Vector vecForward;
|
||||
pPlayer->EyeVectors( &vecForward );
|
||||
|
||||
Vector vecSrc = pPlayer->WorldSpaceCenter();
|
||||
Vector vecThrow = vecForward * 274 + pPlayer->GetAbsVelocity();
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
CBaseEntity *pSatchel = Create( "monster_satchel", vecSrc, QAngle( 0, 0, 90 ), pPlayer );
|
||||
if ( pSatchel )
|
||||
{
|
||||
pSatchel->SetAbsVelocity( vecThrow );
|
||||
QAngle angVel = pSatchel->GetLocalAngularVelocity();
|
||||
angVel.y = 400;
|
||||
pSatchel->SetLocalAngularVelocity( angVel );
|
||||
|
||||
ActivateRadioModel();
|
||||
|
||||
SendWeaponAnim( ACT_VM_DRAW );
|
||||
|
||||
// player "shoot" animation
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
m_iChargeReady = 1;
|
||||
|
||||
pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
void CWeaponSatchel::WeaponIdle( void )
|
||||
{
|
||||
if ( !HasWeaponIdleTimeElapsed() )
|
||||
return;
|
||||
|
||||
switch( m_iChargeReady )
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
SendWeaponAnim( ACT_VM_FIDGET );
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
if ( pPlayer && (pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0) )
|
||||
{
|
||||
m_iChargeReady = 0;
|
||||
if ( !pPlayer->SwitchToNextBestWeapon( pPlayer->GetActiveWeapon() ) )
|
||||
{
|
||||
Holster();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ActivateSatchelModel();
|
||||
|
||||
SendWeaponAnim( ACT_VM_DRAW );
|
||||
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
|
||||
m_iChargeReady = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) );// how long till we do this again.
|
||||
}
|
||||
|
||||
bool CWeaponSatchel::Deploy( void )
|
||||
{
|
||||
SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) );
|
||||
|
||||
if ( HasChargeDeployed() )
|
||||
{
|
||||
ActivateRadioModel();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSatchelModel();
|
||||
}
|
||||
|
||||
bool bRet = BaseClass::Deploy();
|
||||
if ( bRet )
|
||||
{
|
||||
//
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime + 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
return bRet;
|
||||
|
||||
}
|
||||
|
||||
bool CWeaponSatchel::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
{
|
||||
if ( !BaseClass::Holster( pSwitchingTo ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime + 0.5 );
|
||||
|
||||
if ( (pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0) && !HasChargeDeployed() )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
SetThink( &CWeaponSatchel::DestroyItem );
|
||||
SetNextThink( gpGlobals->curtime + 0.1 );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWeaponSatchel::ActivateSatchelModel( void )
|
||||
{
|
||||
m_iViewModelIndex = m_iSatchelViewIndex;
|
||||
m_iWorldModelIndex = m_iSatchelWorldIndex;
|
||||
SetModel( GetViewModel() );
|
||||
}
|
||||
|
||||
void CWeaponSatchel::ActivateRadioModel( void )
|
||||
{
|
||||
m_iViewModelIndex = m_iRadioViewIndex;
|
||||
m_iWorldModelIndex = m_iRadioWorldIndex;
|
||||
SetModel( GetViewModel() );
|
||||
}
|
||||
|
||||
const char *CWeaponSatchel::GetViewModel( int ) const
|
||||
{
|
||||
if ( m_iViewModelIndex == m_iSatchelViewIndex )
|
||||
{
|
||||
return SATCHEL_VIEW_MODEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SATCHELRADIO_VIEW_MODEL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CWeaponSatchel::GetWorldModel( void ) const
|
||||
{
|
||||
if ( m_iViewModelIndex == m_iSatchelViewIndex )
|
||||
{
|
||||
return SATCHEL_WORLD_MODEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SATCHELRADIO_WORLD_MODEL;
|
||||
}
|
||||
}
|
||||
|
||||
void CWeaponSatchel::OnRestore( void )
|
||||
{
|
||||
BaseClass::OnRestore();
|
||||
if ( HasChargeDeployed() )
|
||||
{
|
||||
ActivateRadioModel();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSatchelModel();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
//-----------------------------------------------------------------------------
|
||||
// CSatchelCharge
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define SATCHEL_CHARGE_MODEL "models/w_satchel.mdl"
|
||||
|
||||
|
||||
extern ConVar sk_plr_dmg_satchel;
|
||||
|
||||
|
||||
BEGIN_DATADESC( CSatchelCharge )
|
||||
DEFINE_FIELD( m_flNextBounceSoundTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_bInAir, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_vLastPosition, FIELD_POSITION_VECTOR ),
|
||||
|
||||
// Function Pointers
|
||||
DEFINE_ENTITYFUNC( SatchelTouch ),
|
||||
DEFINE_THINKFUNC( SatchelThink ),
|
||||
DEFINE_USEFUNC( SatchelUse ),
|
||||
END_DATADESC()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_satchel, CSatchelCharge );
|
||||
|
||||
//=========================================================
|
||||
// Deactivate - do whatever it is we do to an orphaned
|
||||
// satchel when we don't want it in the world anymore.
|
||||
//=========================================================
|
||||
void CSatchelCharge::Deactivate( void )
|
||||
{
|
||||
AddSolidFlags( FSOLID_NOT_SOLID );
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
|
||||
|
||||
void CSatchelCharge::Spawn( void )
|
||||
{
|
||||
Precache( );
|
||||
// motor
|
||||
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_SLIDE );
|
||||
SetSolid( SOLID_BBOX );
|
||||
|
||||
SetModel( SATCHEL_CHARGE_MODEL );
|
||||
|
||||
UTIL_SetSize( this, Vector( -4, -4, 0), Vector(4, 4, 8) );
|
||||
|
||||
SetTouch( &CSatchelCharge::SatchelTouch );
|
||||
SetUse( &CSatchelCharge::SatchelUse );
|
||||
SetThink( &CSatchelCharge::SatchelThink );
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
|
||||
m_flDamage = sk_plr_dmg_satchel.GetFloat();
|
||||
m_DmgRadius = m_flDamage * 2.5;
|
||||
m_takedamage = DAMAGE_NO;
|
||||
m_iHealth = 1;
|
||||
|
||||
SetGravity( UTIL_ScaleForGravity( 560 ) ); // slightly lower gravity
|
||||
SetFriction( 0.97 ); //used in SatchelTouch to slow us when sliding
|
||||
SetSequence( LookupSequence( "onback" ) );
|
||||
|
||||
m_bInAir = false;
|
||||
m_flNextBounceSoundTime = 0;
|
||||
|
||||
m_vLastPosition = vec3_origin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input :
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSatchelCharge::SatchelUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
SetThink( &CBaseGrenade::Detonate );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input :
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSatchelCharge::SatchelTouch( CBaseEntity *pOther )
|
||||
{
|
||||
Assert( pOther );
|
||||
if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER | FSOLID_VOLUME_CONTENTS) || GetWaterLevel() > 0 )
|
||||
return;
|
||||
|
||||
StudioFrameAdvance( );
|
||||
|
||||
UpdateSlideSound();
|
||||
|
||||
if ( m_bInAir )
|
||||
{
|
||||
BounceSound();
|
||||
m_bInAir = false;
|
||||
}
|
||||
|
||||
// add a bit of static friction
|
||||
SetAbsVelocity( GetAbsVelocity() * GetFriction() );
|
||||
SetLocalAngularVelocity( GetLocalAngularVelocity() * GetFriction() );
|
||||
}
|
||||
|
||||
void CSatchelCharge::UpdateSlideSound( void )
|
||||
{
|
||||
// HACKHACK - On ground isn't always set, so look for ground underneath
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( !(tr.fraction < 1.0) )
|
||||
{
|
||||
m_bInAir = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CSatchelCharge::SatchelThink( void )
|
||||
{
|
||||
UpdateSlideSound();
|
||||
|
||||
StudioFrameAdvance( );
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
|
||||
if (!IsInWorld())
|
||||
{
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
|
||||
Vector vecNewVel = GetAbsVelocity();
|
||||
|
||||
if ( GetWaterLevel() > 0 )
|
||||
{
|
||||
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
|
||||
vecNewVel *= 0.8;
|
||||
SetLocalAngularVelocity( GetLocalAngularVelocity() * 0.9 );
|
||||
|
||||
vecNewVel.z = 0;
|
||||
SetGravity( -0.2 );
|
||||
}
|
||||
else if ( GetWaterLevel() == 0 )
|
||||
{
|
||||
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_SLIDE );
|
||||
|
||||
SetGravity( 1.0 );
|
||||
}
|
||||
|
||||
SetAbsVelocity( vecNewVel );
|
||||
}
|
||||
|
||||
void CSatchelCharge::Precache( void )
|
||||
{
|
||||
PrecacheModel( SATCHEL_CHARGE_MODEL );
|
||||
PrecacheScriptSound( "SatchelCharge.Bounce" );
|
||||
}
|
||||
|
||||
void CSatchelCharge::BounceSound( void )
|
||||
{
|
||||
if ( gpGlobals->curtime > m_flNextBounceSoundTime )
|
||||
{
|
||||
EmitSound( "SatchelCharge.Bounce" );
|
||||
|
||||
m_flNextBounceSoundTime = gpGlobals->curtime + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input :
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
CSatchelCharge::CSatchelCharge(void)
|
||||
{
|
||||
m_vLastPosition.Init();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef HL1_WEAPON_SATCHEL_H
|
||||
#define HL1_WEAPON_SATCHEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
#include "hl1_basegrenade.h"
|
||||
#include "hl1_basecombatweapon_shared.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponSatchel C_WeaponSatchel
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CWeaponSatchel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CWeaponSatchel : public CBaseHL1CombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponSatchel, CBaseHL1CombatWeapon );
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
public:
|
||||
|
||||
CWeaponSatchel( void );
|
||||
|
||||
void Equip( CBaseCombatCharacter *pOwner );
|
||||
bool HasAnyAmmo( void );
|
||||
bool CanDeploy( void );
|
||||
void Precache( void );
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
void WeaponIdle( void );
|
||||
bool Deploy( void );
|
||||
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||||
|
||||
void ItemPostFrame( void );
|
||||
const char *GetViewModel( int viewmodelindex = 0 ) const;
|
||||
const char *GetWorldModel( void ) const;
|
||||
|
||||
bool HasChargeDeployed() { return ( m_iChargeReady != 0 ); }
|
||||
|
||||
void OnRestore( void );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
private:
|
||||
void Throw( void );
|
||||
void ActivateSatchelModel( void );
|
||||
void ActivateRadioModel( void );
|
||||
|
||||
private:
|
||||
CNetworkVar( int, m_iRadioViewIndex );
|
||||
CNetworkVar( int, m_iRadioWorldIndex );
|
||||
CNetworkVar( int, m_iSatchelViewIndex );
|
||||
CNetworkVar( int, m_iSatchelWorldIndex );
|
||||
CNetworkVar( int, m_iChargeReady );
|
||||
};
|
||||
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
//-----------------------------------------------------------------------------
|
||||
// CSatchelCharge
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CSatchelCharge : public CHL1BaseGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CSatchelCharge, CHL1BaseGrenade );
|
||||
|
||||
CSatchelCharge();
|
||||
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SatchelTouch( CBaseEntity *pOther );
|
||||
void SatchelThink( void );
|
||||
void SatchelUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
private:
|
||||
Vector m_vLastPosition;
|
||||
float m_flNextBounceSoundTime;
|
||||
bool m_bInAir;
|
||||
|
||||
private:
|
||||
void BounceSound( void );
|
||||
void UpdateSlideSound( void );
|
||||
void Deactivate( void );
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif // HL1_WEAPON_SATCHEL_H
|
||||
@@ -0,0 +1,417 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is the Shotgun weapon
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "hl1mp_basecombatweapon_shared.h"
|
||||
//#include "basecombatcharacter.h"
|
||||
//#include "AI_BaseNPC.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_baseplayer.h"
|
||||
#else
|
||||
#include "player.h"
|
||||
#endif
|
||||
#include "gamerules.h" // For g_pGameRules
|
||||
#include "in_buttons.h"
|
||||
//#include "soundent.h"
|
||||
#include "vstdlib/random.h"
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CWeaponShotgun C_WeaponShotgun
|
||||
#endif
|
||||
|
||||
// special deathmatch shotgun spreads
|
||||
#define VECTOR_CONE_DM_SHOTGUN Vector( 0.08716, 0.04362, 0.00 )// 10 degrees by 5 degrees
|
||||
#define VECTOR_CONE_DM_DOUBLESHOTGUN Vector( 0.17365, 0.04362, 0.00 ) // 20 degrees by 5 degrees
|
||||
|
||||
|
||||
class CWeaponShotgun : public CBaseHL1MPCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( CWeaponShotgun, CBaseHL1MPCombatWeapon );
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
private:
|
||||
// float m_flPumpTime;
|
||||
// int m_fInSpecialReload;
|
||||
|
||||
CNetworkVar( float, m_flPumpTime);
|
||||
CNetworkVar( int, m_fInSpecialReload );
|
||||
|
||||
public:
|
||||
void Precache( void );
|
||||
|
||||
bool Reload( void );
|
||||
void FillClip( void );
|
||||
void WeaponIdle( void );
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
void DryFire( void );
|
||||
|
||||
// DECLARE_SERVERCLASS();
|
||||
// DECLARE_DATADESC();
|
||||
|
||||
CWeaponShotgun(void);
|
||||
|
||||
//#ifndef CLIENT_DLL
|
||||
// DECLARE_ACTTABLE();
|
||||
//#endif
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponShotgun, DT_WeaponShotgun );
|
||||
|
||||
BEGIN_NETWORK_TABLE( CWeaponShotgun, DT_WeaponShotgun )
|
||||
#ifdef CLIENT_DLL
|
||||
RecvPropFloat( RECVINFO( m_flPumpTime ) ),
|
||||
RecvPropInt( RECVINFO( m_fInSpecialReload ) ),
|
||||
#else
|
||||
SendPropFloat( SENDINFO( m_flPumpTime ) ),
|
||||
SendPropInt( SENDINFO( m_fInSpecialReload ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CWeaponShotgun )
|
||||
#ifdef CLIENT_DLL
|
||||
DEFINE_PRED_FIELD( m_flPumpTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_fInSpecialReload, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
#endif
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_shotgun, CWeaponShotgun );
|
||||
PRECACHE_WEAPON_REGISTER(weapon_shotgun);
|
||||
|
||||
//IMPLEMENT_SERVERCLASS_ST( CWeaponShotgun, DT_WeaponShotgun )
|
||||
//END_SEND_TABLE()
|
||||
|
||||
//BEGIN_DATADESC( CWeaponShotgun )
|
||||
//END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CWeaponShotgun::CWeaponShotgun( void )
|
||||
{
|
||||
m_bReloadsSingly = true;
|
||||
m_bFiresUnderwater = false;
|
||||
m_flPumpTime = 0.0;
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponShotgun::Precache( void )
|
||||
{
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
void CWeaponShotgun::PrimaryAttack( void )
|
||||
{
|
||||
// Only the player fires this way so we can cast
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
if (!pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_iClip1 <= 0 )
|
||||
{
|
||||
Reload();
|
||||
if ( m_iClip1 <= 0 )
|
||||
DryFire( );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// MUST call sound before removing a round from the clip of a CMachineGun
|
||||
WeaponSound( SINGLE );
|
||||
|
||||
pPlayer->DoMuzzleFlash();
|
||||
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
// Don't fire again until fire animation has completed
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.75;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.75;
|
||||
m_iClip1 -= 1;
|
||||
|
||||
Vector vecSrc = pPlayer->Weapon_ShootPosition();
|
||||
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
|
||||
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
FireBulletsInfo_t info( 4, vecSrc, vecAiming, VECTOR_CONE_DM_SHOTGUN, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
|
||||
info.m_pAttacker = pPlayer;
|
||||
|
||||
pPlayer->FireBullets( info );
|
||||
}
|
||||
else
|
||||
{
|
||||
FireBulletsInfo_t info( 6, vecSrc, vecAiming, VECTOR_CONE_10DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
|
||||
info.m_pAttacker = pPlayer;
|
||||
|
||||
pPlayer->FireBullets( info );
|
||||
|
||||
// pPlayer->FireBullets( 6, vecSrc, vecAiming, VECTOR_CONE_10DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );
|
||||
}
|
||||
|
||||
EjectShell( pPlayer, 1 );
|
||||
|
||||
#if !defined(CLIENT_DLL)
|
||||
pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 1.0 );
|
||||
#endif
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -5, 0, 0 ) );
|
||||
|
||||
// CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.2 );
|
||||
WeaponSound( SINGLE );
|
||||
|
||||
if ( !m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
// HEV suit - indicate out of ammo condition
|
||||
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
|
||||
}
|
||||
|
||||
if ( m_iClip1 > 0 )
|
||||
{
|
||||
m_flPumpTime = gpGlobals->curtime + 0.5;
|
||||
}
|
||||
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponShotgun::SecondaryAttack( void )
|
||||
{
|
||||
// Only the player fires this way so we can cast
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
if (!pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_iClip1 <= 1 )
|
||||
{
|
||||
Reload();
|
||||
if ( m_iClip1 <= 0 )
|
||||
DryFire( );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer->GetWaterLevel() == 3 )
|
||||
{
|
||||
// This weapon doesn't fire underwater
|
||||
WeaponSound(EMPTY);
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.2;
|
||||
return;
|
||||
}
|
||||
|
||||
// MUST call sound before removing a round from the clip of a CMachineGun
|
||||
WeaponSound( WPN_DOUBLE );
|
||||
|
||||
pPlayer->DoMuzzleFlash();
|
||||
|
||||
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
|
||||
pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
// Don't fire again until fire animation has completed
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 1.5;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 1.5;
|
||||
|
||||
m_iClip1 -= 2; // Shotgun uses same clip for primary and secondary attacks
|
||||
|
||||
Vector vecSrc = pPlayer->Weapon_ShootPosition();
|
||||
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
|
||||
|
||||
// Fire the bullets
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
FireBulletsInfo_t info( 8, vecSrc, vecAiming, VECTOR_CONE_DM_DOUBLESHOTGUN, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
|
||||
info.m_pAttacker = pPlayer;
|
||||
|
||||
pPlayer->FireBullets( info );
|
||||
|
||||
// pPlayer->FireBullets( 8, vecSrc, vecAiming, VECTOR_CONE_DM_DOUBLESHOTGUN, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
FireBulletsInfo_t info( 12, vecSrc, vecAiming, VECTOR_CONE_10DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
|
||||
|
||||
pPlayer->FireBullets( info );
|
||||
// pPlayer->FireBullets( 12, vecSrc, vecAiming, VECTOR_CONE_10DEGREES, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );
|
||||
}
|
||||
|
||||
EjectShell( pPlayer, 1 );
|
||||
EjectShell( pPlayer, 1 );
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -10, 0, 0 ) );
|
||||
#if !defined(CLIENT_DLL)
|
||||
pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 1.0 );
|
||||
#endif
|
||||
|
||||
// CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 800, 0.2 );
|
||||
WeaponSound( SINGLE );
|
||||
|
||||
if ( !m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
{
|
||||
// HEV suit - indicate out of ammo condition
|
||||
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
|
||||
}
|
||||
|
||||
if ( m_iClip1 > 0 )
|
||||
{
|
||||
m_flPumpTime = gpGlobals->curtime + 0.5;
|
||||
}
|
||||
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
|
||||
bool CWeaponShotgun::Reload( void )
|
||||
{
|
||||
CBaseCombatCharacter *pOwner = GetOwner();
|
||||
|
||||
if ( pOwner == NULL )
|
||||
return false;
|
||||
|
||||
if ( pOwner->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
|
||||
return false;
|
||||
|
||||
if ( m_iClip1 >= GetMaxClip1() )
|
||||
return false;
|
||||
|
||||
// don't reload until recoil is done
|
||||
if ( m_flNextPrimaryAttack > gpGlobals->curtime )
|
||||
return false;
|
||||
|
||||
// check to see if we're ready to reload
|
||||
if ( m_fInSpecialReload == 0 )
|
||||
{
|
||||
SendWeaponAnim( ACT_SHOTGUN_RELOAD_START );
|
||||
m_fInSpecialReload = 1;
|
||||
|
||||
pOwner->m_flNextAttack = gpGlobals->curtime + 0.6;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 0.6 );
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if ( m_fInSpecialReload == 1 )
|
||||
{
|
||||
if ( !HasWeaponIdleTimeElapsed() )
|
||||
return false;
|
||||
|
||||
// was waiting for gun to move to side
|
||||
m_fInSpecialReload = 2;
|
||||
|
||||
// Play reload on different channel as otherwise steals channel away from fire sound
|
||||
WeaponSound( RELOAD );
|
||||
SendWeaponAnim( ACT_VM_RELOAD );
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
|
||||
}
|
||||
else
|
||||
{
|
||||
FillClip();
|
||||
m_fInSpecialReload = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponShotgun::FillClip( void )
|
||||
{
|
||||
CBaseCombatCharacter *pOwner = GetOwner();
|
||||
|
||||
if ( pOwner == NULL )
|
||||
return;
|
||||
|
||||
// Add them to the clip
|
||||
m_iClip1++;
|
||||
pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType );
|
||||
}
|
||||
|
||||
|
||||
void CWeaponShotgun::DryFire( void )
|
||||
{
|
||||
WeaponSound( EMPTY );
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.75;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.75;
|
||||
}
|
||||
|
||||
|
||||
void CWeaponShotgun::WeaponIdle( void )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
if ( pPlayer == NULL )
|
||||
return;
|
||||
|
||||
pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
|
||||
|
||||
if ( m_flPumpTime && m_flPumpTime < gpGlobals->curtime )
|
||||
{
|
||||
// play pumping sound
|
||||
WeaponSound( SPECIAL1 );
|
||||
m_flPumpTime = 0;
|
||||
}
|
||||
|
||||
if ( HasWeaponIdleTimeElapsed() )
|
||||
{
|
||||
if ( m_iClip1 == 0 && m_fInSpecialReload == 0 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else if ( m_fInSpecialReload != 0 )
|
||||
{
|
||||
if ( m_iClip1 != 8 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
|
||||
{
|
||||
Reload( );
|
||||
}
|
||||
else
|
||||
{
|
||||
// reload debounce has timed out
|
||||
SendWeaponAnim( ACT_SHOTGUN_PUMP );
|
||||
|
||||
// play cocking sound
|
||||
WeaponSound( SPECIAL1 );
|
||||
m_fInSpecialReload = 0;
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 1.5 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = random->RandomFloat( 0, 1 );
|
||||
|
||||
if ( flRand <= 0.8 )
|
||||
{
|
||||
iAnim = ACT_SHOTGUN_IDLE_DEEP;
|
||||
}
|
||||
else if ( flRand <= 0.95 )
|
||||
{
|
||||
iAnim = ACT_VM_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = ACT_SHOTGUN_IDLE4;
|
||||
}
|
||||
|
||||
SendWeaponAnim( iAnim );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user