mirror of
https://github.com/YGGverse/hlsdk-portable.git
synced 2025-01-24 05:34:18 +00:00
Remove files with ~
This commit is contained in:
parent
8c1c6cefa2
commit
6608fb78d5
153
dlls/Android.mk~
153
dlls/Android.mk~
@ -1,153 +0,0 @@
|
||||
#HLSDK server Android port
|
||||
#Copyright (c) nicknekit
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := server
|
||||
|
||||
include $(XASH3D_CONFIG)
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a-hard)
|
||||
LOCAL_MODULE_FILENAME = libserver_hardfp
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS += -D_LINUX -DCLIENT_WEAPONS -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf \
|
||||
-fno-exceptions -DNO_VOICEGAMEMGR -w
|
||||
|
||||
LOCAL_CPPFLAGS := $(LOCAL_CFLAGS) -frtti
|
||||
|
||||
LOCAL_C_INCLUDES := $(SDL_PATH)/include \
|
||||
$(LOCAL_PATH)/. \
|
||||
$(LOCAL_PATH)/wpn_shared \
|
||||
$(LOCAL_PATH)/../common \
|
||||
$(LOCAL_PATH)/../engine/common \
|
||||
$(LOCAL_PATH)/../engine \
|
||||
$(LOCAL_PATH)/../public \
|
||||
$(LOCAL_PATH)/../pm_shared \
|
||||
$(LOCAL_PATH)/../game_shared
|
||||
|
||||
LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \
|
||||
bonewheel.cpp \
|
||||
sawnoff.cpp \
|
||||
cross.cpp
|
||||
pepsigun.cpp \
|
||||
needle.cpp \
|
||||
katana.cpp \
|
||||
evilsci.cpp \
|
||||
sniper.cpp \
|
||||
glock2.cpp \
|
||||
mariozombie.cpp \
|
||||
megachav.cpp \
|
||||
pink_panthera.cpp \
|
||||
shrek.cpp \
|
||||
skeleton.cpp \
|
||||
skrillex.cpp \
|
||||
superchav.cpp \
|
||||
terror.cpp \
|
||||
zombozo.cpp \
|
||||
aflock.cpp \
|
||||
animating.cpp \
|
||||
animation.cpp \
|
||||
apache.cpp \
|
||||
barnacle.cpp \
|
||||
barney.cpp \
|
||||
bigmomma.cpp \
|
||||
bloater.cpp \
|
||||
bmodels.cpp \
|
||||
bullsquid.cpp \
|
||||
buttons.cpp \
|
||||
cbase.cpp \
|
||||
client.cpp \
|
||||
combat.cpp \
|
||||
controller.cpp \
|
||||
crossbow.cpp \
|
||||
crowbar.cpp \
|
||||
defaultai.cpp \
|
||||
doors.cpp \
|
||||
effects.cpp \
|
||||
egon.cpp \
|
||||
explode.cpp \
|
||||
flyingmonster.cpp \
|
||||
func_break.cpp \
|
||||
func_tank.cpp \
|
||||
game.cpp \
|
||||
gamerules.cpp \
|
||||
gargantua.cpp \
|
||||
gauss.cpp \
|
||||
genericmonster.cpp \
|
||||
ggrenade.cpp \
|
||||
globals.cpp \
|
||||
glock.cpp \
|
||||
gman.cpp \
|
||||
h_ai.cpp \
|
||||
h_battery.cpp \
|
||||
h_cycler.cpp \
|
||||
h_cine.cpp \
|
||||
h_export.cpp \
|
||||
handgrenade.cpp \
|
||||
hassassin.cpp \
|
||||
headcrab.cpp \
|
||||
healthkit.cpp \
|
||||
hgrunt.cpp \
|
||||
hornet.cpp \
|
||||
hornetgun.cpp \
|
||||
houndeye.cpp \
|
||||
ichthyosaur.cpp \
|
||||
islave.cpp \
|
||||
items.cpp \
|
||||
leech.cpp \
|
||||
lights.cpp \
|
||||
maprules.cpp \
|
||||
monstermaker.cpp \
|
||||
monsters.cpp \
|
||||
monsterstate.cpp \
|
||||
mortar.cpp \
|
||||
mp5.cpp \
|
||||
multiplay_gamerules.cpp \
|
||||
nihilanth.cpp \
|
||||
nodes.cpp \
|
||||
osprey.cpp \
|
||||
pathcorner.cpp \
|
||||
plane.cpp \
|
||||
plats.cpp \
|
||||
player.cpp \
|
||||
python.cpp \
|
||||
rat.cpp \
|
||||
roach.cpp \
|
||||
rpg.cpp \
|
||||
satchel.cpp \
|
||||
schedule.cpp \
|
||||
scientist.cpp \
|
||||
scripted.cpp \
|
||||
shotgun.cpp \
|
||||
singleplay_gamerules.cpp \
|
||||
skill.cpp \
|
||||
sound.cpp \
|
||||
soundent.cpp \
|
||||
spectator.cpp \
|
||||
squadmonster.cpp \
|
||||
squeakgrenade.cpp \
|
||||
subs.cpp \
|
||||
talkmonster.cpp \
|
||||
teamplay_gamerules.cpp \
|
||||
tentacle.cpp \
|
||||
tempmonster.cpp \
|
||||
triggers.cpp \
|
||||
tripmine.cpp \
|
||||
turret.cpp \
|
||||
util.cpp \
|
||||
weapons.cpp \
|
||||
world.cpp \
|
||||
xen.cpp \
|
||||
zombie.cpp \
|
||||
rock.cpp \
|
||||
../pm_shared/pm_debug.c \
|
||||
../pm_shared/pm_math.c \
|
||||
../pm_shared/pm_shared.c
|
||||
# ../game_shared/voice_gamemgr.cpp
|
||||
|
||||
LOCAL_LDLIBS := -llog
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
@ -1,733 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This source code contains proprietary and confidential information of
|
||||
* Valve LLC and its suppliers. Access to this code is restricted to
|
||||
* persons who have executed a written SDK license with Valve. Any access,
|
||||
* use or distribution of this code by or to any unlicensed person is illegal.
|
||||
*
|
||||
****/
|
||||
//=========================================================
|
||||
// monster template
|
||||
//=========================================================
|
||||
// UNDONE: Holster weapon?
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "talkmonster.h"
|
||||
#include "schedule.h"
|
||||
#include "defaultai.h"
|
||||
#include "scripted.h"
|
||||
#include "weapons.h"
|
||||
#include "soundent.h"
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
//=========================================================
|
||||
// first flag is barney dying for scripted sequences?
|
||||
#define BIGSMOKE_AE_DRAW ( 2 )
|
||||
#define BIGSMOKE_AE_SHOOT ( 3 )
|
||||
#define BIGSMOKE_AE_HOLSTER ( 4 )
|
||||
|
||||
#define BIGSMOKE_BODY_GUNHOLSTERED 0
|
||||
#define BIGSMOKE_BODY_GUNDRAWN 1
|
||||
#define BIGSMOKE_BODY_GUNGONE 2
|
||||
|
||||
class CBigSmoke : public CTalkMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int ISoundMask( void );
|
||||
void BigSmokeFirePistol( void );
|
||||
void AlertSound( void );
|
||||
int Classify( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
|
||||
void RunTask( Task_t *pTask );
|
||||
void StartTask( Task_t *pTask );
|
||||
virtual int ObjectCaps( void ) { return CTalkMonster :: ObjectCaps() | FCAP_IMPULSE_USE; }
|
||||
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
|
||||
BOOL CheckRangeAttack1( float flDot, float flDist );
|
||||
|
||||
void DeclineFollowing( void );
|
||||
|
||||
// Override these to set behavior
|
||||
Schedule_t *GetScheduleOfType( int Type );
|
||||
Schedule_t *GetSchedule( void );
|
||||
MONSTERSTATE GetIdealState( void );
|
||||
|
||||
void DeathSound( void );
|
||||
void PainSound( void );
|
||||
|
||||
void TalkInit( void );
|
||||
|
||||
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
BOOL m_fGunDrawn;
|
||||
float m_painTime;
|
||||
float m_checkAttackTime;
|
||||
BOOL m_lastAttackCheck;
|
||||
|
||||
// UNDONE: What is this for? It isn't used?
|
||||
float m_flPlayerDamage;// how much pain has the player inflicted on me?
|
||||
|
||||
CUSTOM_SCHEDULES
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_big_smoke, CBigSmoke )
|
||||
|
||||
TYPEDESCRIPTION CBigSmoke::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CBigSmoke, m_fGunDrawn, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CBigSmoke, m_painTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( CBigSmoke, m_checkAttackTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( CBigSmoke, m_lastAttackCheck, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CBigSmoke, m_flPlayerDamage, FIELD_FLOAT ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CBigSmoke, CTalkMonster )
|
||||
|
||||
//=========================================================
|
||||
// AI Schedules Specific to this monster
|
||||
//=========================================================
|
||||
Task_t tlBsFollow[] =
|
||||
{
|
||||
{ TASK_MOVE_TO_TARGET_RANGE, (float)128 }, // Move within 128 of target ent (client)
|
||||
{ TASK_SET_SCHEDULE, (float)SCHED_TARGET_FACE },
|
||||
};
|
||||
|
||||
Schedule_t slBsFollow[] =
|
||||
{
|
||||
{
|
||||
tlBsFollow,
|
||||
ARRAYSIZE( tlBsFollow ),
|
||||
bits_COND_NEW_ENEMY |
|
||||
bits_COND_LIGHT_DAMAGE |
|
||||
bits_COND_HEAVY_DAMAGE |
|
||||
bits_COND_HEAR_SOUND |
|
||||
bits_COND_PROVOKED,
|
||||
bits_SOUND_DANGER,
|
||||
"Follow"
|
||||
},
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// BarneyDraw - much better looking draw schedule for when
|
||||
// barney knows who he's gonna attack.
|
||||
//=========================================================
|
||||
Task_t tlBigSmokeEnemyDraw[] =
|
||||
{
|
||||
{ TASK_STOP_MOVING, 0 },
|
||||
{ TASK_FACE_ENEMY, 0 },
|
||||
{ TASK_PLAY_SEQUENCE_FACE_ENEMY, (float) ACT_ARM },
|
||||
};
|
||||
|
||||
Schedule_t slBigSmokeEnemyDraw[] =
|
||||
{
|
||||
{
|
||||
tlBigSmokeEnemyDraw,
|
||||
ARRAYSIZE( tlBigSmokeEnemyDraw ),
|
||||
0,
|
||||
0,
|
||||
"BigSmoke Enemy Draw"
|
||||
}
|
||||
};
|
||||
|
||||
Task_t tlBsFaceTarget[] =
|
||||
{
|
||||
{ TASK_SET_ACTIVITY, (float)ACT_IDLE },
|
||||
{ TASK_FACE_TARGET, (float)0 },
|
||||
{ TASK_SET_ACTIVITY, (float)ACT_IDLE },
|
||||
{ TASK_SET_SCHEDULE, (float)SCHED_TARGET_CHASE },
|
||||
};
|
||||
|
||||
Schedule_t slBsFaceTarget[] =
|
||||
{
|
||||
{
|
||||
tlBsFaceTarget,
|
||||
ARRAYSIZE( tlBsFaceTarget ),
|
||||
bits_COND_CLIENT_PUSH |
|
||||
bits_COND_NEW_ENEMY |
|
||||
bits_COND_LIGHT_DAMAGE |
|
||||
bits_COND_HEAVY_DAMAGE |
|
||||
bits_COND_HEAR_SOUND |
|
||||
bits_COND_PROVOKED,
|
||||
bits_SOUND_DANGER,
|
||||
"FaceTarget"
|
||||
},
|
||||
};
|
||||
|
||||
Task_t tlIdleBsStand[] =
|
||||
{
|
||||
{ TASK_STOP_MOVING, 0 },
|
||||
{ TASK_SET_ACTIVITY, (float)ACT_IDLE },
|
||||
{ TASK_WAIT, (float)2 }, // repick IDLESTAND every two seconds.
|
||||
{ TASK_TLK_HEADRESET, (float)0 }, // reset head position
|
||||
};
|
||||
|
||||
Schedule_t slIdleBsStand[] =
|
||||
{
|
||||
{
|
||||
tlIdleBsStand,
|
||||
ARRAYSIZE( tlIdleBsStand ),
|
||||
bits_COND_NEW_ENEMY |
|
||||
bits_COND_LIGHT_DAMAGE |
|
||||
bits_COND_HEAVY_DAMAGE |
|
||||
bits_COND_HEAR_SOUND |
|
||||
bits_COND_SMELL |
|
||||
bits_COND_PROVOKED,
|
||||
bits_SOUND_COMBAT |// sound flags - change these, and you'll break the talking code.
|
||||
//bits_SOUND_PLAYER |
|
||||
//bits_SOUND_WORLD |
|
||||
bits_SOUND_DANGER |
|
||||
bits_SOUND_MEAT |// scents
|
||||
bits_SOUND_CARCASS |
|
||||
bits_SOUND_GARBAGE,
|
||||
"IdleStand"
|
||||
},
|
||||
};
|
||||
|
||||
DEFINE_CUSTOM_SCHEDULES( CBigSmoke )
|
||||
{
|
||||
slBsFollow,
|
||||
slBigSmokeEnemyDraw,
|
||||
slBsFaceTarget,
|
||||
slIdleBsStand,
|
||||
};
|
||||
|
||||
IMPLEMENT_CUSTOM_SCHEDULES( CBigSmoke, CTalkMonster )
|
||||
|
||||
void CBigSmoke::StartTask( Task_t *pTask )
|
||||
{
|
||||
CTalkMonster::StartTask( pTask );
|
||||
}
|
||||
|
||||
void CBigSmoke::RunTask( Task_t *pTask )
|
||||
{
|
||||
switch( pTask->iTask )
|
||||
{
|
||||
case TASK_RANGE_ATTACK1:
|
||||
if( m_hEnemy != NULL && ( m_hEnemy->IsPlayer() ) )
|
||||
{
|
||||
pev->framerate = 1.5;
|
||||
}
|
||||
CTalkMonster::RunTask( pTask );
|
||||
break;
|
||||
default:
|
||||
CTalkMonster::RunTask( pTask );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// ISoundMask - returns a bit mask indicating which types
|
||||
// of sounds this monster regards.
|
||||
//=========================================================
|
||||
int CBigSmoke::ISoundMask( void)
|
||||
{
|
||||
return bits_SOUND_WORLD |
|
||||
bits_SOUND_COMBAT |
|
||||
bits_SOUND_CARCASS |
|
||||
bits_SOUND_MEAT |
|
||||
bits_SOUND_GARBAGE |
|
||||
bits_SOUND_DANGER |
|
||||
bits_SOUND_PLAYER;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Classify - indicates this monster's place in the
|
||||
// relationship table.
|
||||
//=========================================================
|
||||
int CBigSmoke::Classify( void )
|
||||
{
|
||||
return CLASS_PLAYER_ALLY;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// ALertSound - barney says "Freeze!"
|
||||
//=========================================================
|
||||
void CBigSmoke::AlertSound( void )
|
||||
{
|
||||
if( m_hEnemy != NULL )
|
||||
{
|
||||
if( FOkToSpeak() )
|
||||
{
|
||||
PlaySentence( "BA_ATTACK", RANDOM_FLOAT( 2.8, 3.2 ), VOL_NORM, ATTN_IDLE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// SetYawSpeed - allows each sequence to have a different
|
||||
// turn rate associated with it.
|
||||
//=========================================================
|
||||
void CBigSmoke::SetYawSpeed( void )
|
||||
{
|
||||
int ys;
|
||||
|
||||
ys = 0;
|
||||
|
||||
switch ( m_Activity )
|
||||
{
|
||||
case ACT_IDLE:
|
||||
ys = 70;
|
||||
break;
|
||||
case ACT_WALK:
|
||||
ys = 70;
|
||||
break;
|
||||
case ACT_RUN:
|
||||
ys = 90;
|
||||
break;
|
||||
default:
|
||||
ys = 70;
|
||||
break;
|
||||
}
|
||||
|
||||
pev->yaw_speed = ys;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// CheckRangeAttack1
|
||||
//=========================================================
|
||||
BOOL CBigSmoke::CheckRangeAttack1( float flDot, float flDist )
|
||||
{
|
||||
if( flDist <= 1024 && flDot >= 0.5 )
|
||||
{
|
||||
if( gpGlobals->time > m_checkAttackTime )
|
||||
{
|
||||
TraceResult tr;
|
||||
|
||||
Vector shootOrigin = pev->origin + Vector( 0, 0, 55 );
|
||||
CBaseEntity *pEnemy = m_hEnemy;
|
||||
Vector shootTarget = ( ( pEnemy->BodyTarget( shootOrigin ) - pEnemy->pev->origin ) + m_vecEnemyLKP );
|
||||
UTIL_TraceLine( shootOrigin, shootTarget, dont_ignore_monsters, ENT( pev ), &tr );
|
||||
m_checkAttackTime = gpGlobals->time + 1;
|
||||
if( tr.flFraction == 1.0 || ( tr.pHit != NULL && CBaseEntity::Instance( tr.pHit ) == pEnemy ) )
|
||||
m_lastAttackCheck = TRUE;
|
||||
else
|
||||
m_lastAttackCheck = FALSE;
|
||||
m_checkAttackTime = gpGlobals->time + 1.5;
|
||||
}
|
||||
return m_lastAttackCheck;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// BarneyFirePistol - shoots one round from the pistol at
|
||||
// the enemy barney is facing.
|
||||
//=========================================================
|
||||
void CBigSmoke::BigSmokeFirePistol( void )
|
||||
{
|
||||
Vector vecShootOrigin;
|
||||
|
||||
UTIL_MakeVectors( pev->angles );
|
||||
vecShootOrigin = pev->origin + Vector( 0, 0, 55 );
|
||||
Vector vecShootDir = ShootAtEnemy( vecShootOrigin );
|
||||
|
||||
Vector angDir = UTIL_VecToAngles( vecShootDir );
|
||||
SetBlending( 0, angDir.x );
|
||||
pev->effects = EF_MUZZLEFLASH;
|
||||
|
||||
FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_2DEGREES, 1024, BULLET_MONSTER_9MM );
|
||||
|
||||
int pitchShift = RANDOM_LONG( 0, 20 );
|
||||
|
||||
// Only shift about half the time
|
||||
if( pitchShift > 10 )
|
||||
pitchShift = 0;
|
||||
else
|
||||
pitchShift -= 5;
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, "BigSmoke/fire1.wav", 1, ATTN_NORM, 0, 100 + pitchShift );
|
||||
|
||||
CSoundEnt::InsertSound( bits_SOUND_COMBAT, pev->origin, 384, 0.3 );
|
||||
|
||||
// UNDONE: Reload?
|
||||
m_cAmmoLoaded--;// take away a bullet!
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// HandleAnimEvent - catches the monster-specific messages
|
||||
// that occur when tagged animation frames are played.
|
||||
//
|
||||
// Returns number of events handled, 0 if none.
|
||||
//=========================================================
|
||||
void CBigSmoke::HandleAnimEvent( MonsterEvent_t *pEvent )
|
||||
{
|
||||
switch( pEvent->event )
|
||||
{
|
||||
case BIGSMOKE_AE_SHOOT:
|
||||
BigSmokeFirePistol();
|
||||
break;
|
||||
case BIGSMOKE_AE_DRAW:
|
||||
// barney's bodygroup switches here so he can pull gun from holster
|
||||
pev->body = BIGSMOKE_BODY_GUNDRAWN;
|
||||
m_fGunDrawn = TRUE;
|
||||
break;
|
||||
case BIGSMOKE_AE_HOLSTER:
|
||||
// change bodygroup to replace gun in holster
|
||||
pev->body = BIGSMOKE_BODY_GUNHOLSTERED;
|
||||
m_fGunDrawn = FALSE;
|
||||
break;
|
||||
default:
|
||||
CTalkMonster::HandleAnimEvent( pEvent );
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CBigSmoke::Spawn()
|
||||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL( ENT( pev ), "models/bigsmoke.mdl" );
|
||||
UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->health = 350;
|
||||
pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin.
|
||||
m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
pev->body = 0; // gun in holster
|
||||
m_fGunDrawn = FALSE;
|
||||
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
|
||||
|
||||
MonsterInit();
|
||||
SetUse( &CTalkMonster::FollowerUse );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CBigSmoke::Precache()
|
||||
{
|
||||
PRECACHE_MODEL( "models/bigsmoke.mdl" );
|
||||
|
||||
PRECACHE_SOUND( "bigsmoke/fire1.wav" );
|
||||
|
||||
|
||||
// every new barney must call this, otherwise
|
||||
// when a level is loaded, nobody will talk (time is reset to 0)
|
||||
TalkInit();
|
||||
CTalkMonster::Precache();
|
||||
}
|
||||
|
||||
// Init talk data
|
||||
void CBigSmoke::TalkInit()
|
||||
{
|
||||
CTalkMonster::TalkInit();
|
||||
|
||||
// scientists speach group names (group names are in sentences.txt)
|
||||
m_szGrp[TLK_ANSWER] = "BA_ANSWER";
|
||||
m_szGrp[TLK_QUESTION] = "BA_QUESTION";
|
||||
m_szGrp[TLK_IDLE] = "BA_IDLE";
|
||||
m_szGrp[TLK_STARE] = "BA_STARE";
|
||||
m_szGrp[TLK_USE] = "BA_OK";
|
||||
m_szGrp[TLK_UNUSE] = "BA_WAIT";
|
||||
m_szGrp[TLK_STOP] = "BA_STOP";
|
||||
|
||||
m_szGrp[TLK_NOSHOOT] = "BA_SCARED";
|
||||
m_szGrp[TLK_HELLO] = "BA_HELLO";
|
||||
|
||||
m_szGrp[TLK_PLHURT1] = "!BA_CUREA";
|
||||
m_szGrp[TLK_PLHURT2] = "!BA_CUREB";
|
||||
m_szGrp[TLK_PLHURT3] = "!BA_CUREC";
|
||||
|
||||
m_szGrp[TLK_PHELLO] = NULL; //"BA_PHELLO"; // UNDONE
|
||||
m_szGrp[TLK_PIDLE] = NULL; //"BA_PIDLE"; // UNDONE
|
||||
m_szGrp[TLK_PQUESTION] = "BA_PQUEST"; // UNDONE
|
||||
|
||||
m_szGrp[TLK_SMELL] = "BA_SMELL";
|
||||
|
||||
m_szGrp[TLK_WOUND] = "BA_WOUND";
|
||||
m_szGrp[TLK_MORTAL] = "BA_MORTAL";
|
||||
|
||||
// get voice for head - just one barney voice for now
|
||||
m_voicePitch = 100;
|
||||
}
|
||||
|
||||
static BOOL IsFacing( entvars_t *pevTest, const Vector &reference )
|
||||
{
|
||||
Vector vecDir = reference - pevTest->origin;
|
||||
vecDir.z = 0;
|
||||
vecDir = vecDir.Normalize();
|
||||
Vector forward, angle;
|
||||
angle = pevTest->v_angle;
|
||||
angle.x = 0;
|
||||
UTIL_MakeVectorsPrivate( angle, forward, NULL, NULL );
|
||||
|
||||
// He's facing me, he meant it
|
||||
if( DotProduct( forward, vecDir ) > 0.96 ) // +/- 15 degrees or so
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int CBigSmoke::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
|
||||
{
|
||||
// make sure friends talk about it if player hurts talkmonsters...
|
||||
int ret = CTalkMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
|
||||
if( !IsAlive() || pev->deadflag == DEAD_DYING )
|
||||
return ret;
|
||||
|
||||
if( m_MonsterState != MONSTERSTATE_PRONE && ( pevAttacker->flags & FL_CLIENT ) )
|
||||
{
|
||||
m_flPlayerDamage += flDamage;
|
||||
|
||||
// This is a heurstic to determine if the player intended to harm me
|
||||
// If I have an enemy, we can't establish intent (may just be crossfire)
|
||||
if( m_hEnemy == NULL )
|
||||
{
|
||||
// If the player was facing directly at me, or I'm already suspicious, get mad
|
||||
if( ( m_afMemory & bits_MEMORY_SUSPICIOUS ) || IsFacing( pevAttacker, pev->origin ) )
|
||||
{
|
||||
// Alright, now I'm pissed!
|
||||
PlaySentence( "BA_MAD", 4, VOL_NORM, ATTN_NORM );
|
||||
|
||||
Remember( bits_MEMORY_PROVOKED );
|
||||
StopFollowing( TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hey, be careful with that
|
||||
PlaySentence( "BA_SHOT", 4, VOL_NORM, ATTN_NORM );
|
||||
Remember( bits_MEMORY_SUSPICIOUS );
|
||||
}
|
||||
}
|
||||
else if( !( m_hEnemy->IsPlayer()) && pev->deadflag == DEAD_NO )
|
||||
{
|
||||
PlaySentence( "BA_SHOT", 4, VOL_NORM, ATTN_NORM );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// PainSound
|
||||
//=========================================================
|
||||
void CBarney::PainSound( void )
|
||||
{
|
||||
if( gpGlobals->time < m_painTime )
|
||||
return;
|
||||
|
||||
m_painTime = gpGlobals->time + RANDOM_FLOAT( 0.5, 0.75 );
|
||||
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// DeathSound
|
||||
//=========================================================
|
||||
void CBarney::DeathSound( void )
|
||||
{
|
||||
}
|
||||
|
||||
void CBarney::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
|
||||
{
|
||||
switch( ptr->iHitgroup )
|
||||
{
|
||||
case HITGROUP_CHEST:
|
||||
case HITGROUP_STOMACH:
|
||||
if (bitsDamageType & ( DMG_BULLET | DMG_SLASH | DMG_BLAST ) )
|
||||
{
|
||||
flDamage = flDamage / 2;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if( bitsDamageType & ( DMG_BULLET | DMG_SLASH | DMG_CLUB ) )
|
||||
{
|
||||
flDamage -= 20;
|
||||
if( flDamage <= 0 )
|
||||
{
|
||||
UTIL_Ricochet( ptr->vecEndPos, 1.0 );
|
||||
flDamage = 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
// always a head shot
|
||||
ptr->iHitgroup = HITGROUP_HEAD;
|
||||
break;
|
||||
}
|
||||
|
||||
CTalkMonster::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
|
||||
}
|
||||
|
||||
void CBarney::Killed( entvars_t *pevAttacker, int iGib )
|
||||
{
|
||||
if( pev->body < BARNEY_BODY_GUNGONE )
|
||||
{
|
||||
// drop the gun!
|
||||
Vector vecGunPos;
|
||||
Vector vecGunAngles;
|
||||
|
||||
pev->body = BIGSMOKE_BODY_GUNGONE;
|
||||
|
||||
GetAttachment( 0, vecGunPos, vecGunAngles );
|
||||
|
||||
CBaseEntity *pGun = DropItem( "weapon_9mmhandgun", vecGunPos, vecGunAngles );
|
||||
}
|
||||
|
||||
SetUse( NULL );
|
||||
CTalkMonster::Killed( pevAttacker, iGib );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AI Schedules Specific to this monster
|
||||
//=========================================================
|
||||
Schedule_t *CBigSmoke::GetScheduleOfType( int Type )
|
||||
{
|
||||
Schedule_t *psched;
|
||||
|
||||
switch( Type )
|
||||
{
|
||||
case SCHED_ARM_WEAPON:
|
||||
if( m_hEnemy != NULL )
|
||||
{
|
||||
// face enemy, then draw.
|
||||
return slBigSmokeEnemyDraw;
|
||||
}
|
||||
break;
|
||||
// Hook these to make a looping schedule
|
||||
case SCHED_TARGET_FACE:
|
||||
// call base class default so that barney will talk
|
||||
// when 'used'
|
||||
psched = CTalkMonster::GetScheduleOfType( Type );
|
||||
|
||||
if( psched == slIdleStand )
|
||||
return slBaFaceTarget; // override this for different target face behavior
|
||||
else
|
||||
return psched;
|
||||
case SCHED_TARGET_CHASE:
|
||||
return slBaFollow;
|
||||
case SCHED_IDLE_STAND:
|
||||
// call base class default so that scientist will talk
|
||||
// when standing during idle
|
||||
psched = CTalkMonster::GetScheduleOfType( Type );
|
||||
|
||||
if( psched == slIdleStand )
|
||||
{
|
||||
// just look straight ahead.
|
||||
return slIdleBaStand;
|
||||
}
|
||||
else
|
||||
return psched;
|
||||
}
|
||||
|
||||
return CTalkMonster::GetScheduleOfType( Type );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// GetSchedule - Decides which type of schedule best suits
|
||||
// the monster's current state and conditions. Then calls
|
||||
// monster's member function to get a pointer to a schedule
|
||||
// of the proper type.
|
||||
//=========================================================
|
||||
Schedule_t *CBigSmoke::GetSchedule( void )
|
||||
{
|
||||
if( HasConditions( bits_COND_HEAR_SOUND ) )
|
||||
{
|
||||
CSound *pSound;
|
||||
pSound = PBestSound();
|
||||
|
||||
ASSERT( pSound != NULL );
|
||||
if( pSound && (pSound->m_iType & bits_SOUND_DANGER) )
|
||||
return GetScheduleOfType( SCHED_TAKE_COVER_FROM_BEST_SOUND );
|
||||
}
|
||||
if( HasConditions( bits_COND_ENEMY_DEAD ) && FOkToSpeak() )
|
||||
{
|
||||
PlaySentence( "BA_KILL", 4, VOL_NORM, ATTN_NORM );
|
||||
}
|
||||
|
||||
switch( m_MonsterState )
|
||||
{
|
||||
case MONSTERSTATE_COMBAT:
|
||||
{
|
||||
// dead enemy
|
||||
if( HasConditions( bits_COND_ENEMY_DEAD ) )
|
||||
{
|
||||
// call base class, all code to handle dead enemies is centralized there.
|
||||
return CBaseMonster::GetSchedule();
|
||||
}
|
||||
|
||||
// always act surprized with a new enemy
|
||||
if( HasConditions( bits_COND_NEW_ENEMY ) && HasConditions( bits_COND_LIGHT_DAMAGE ) )
|
||||
return GetScheduleOfType( SCHED_SMALL_FLINCH );
|
||||
|
||||
// wait for one schedule to draw gun
|
||||
if( !m_fGunDrawn )
|
||||
return GetScheduleOfType( SCHED_ARM_WEAPON );
|
||||
|
||||
if( HasConditions( bits_COND_HEAVY_DAMAGE ) )
|
||||
return GetScheduleOfType( SCHED_TAKE_COVER_FROM_ENEMY );
|
||||
}
|
||||
break;
|
||||
case MONSTERSTATE_ALERT:
|
||||
case MONSTERSTATE_IDLE:
|
||||
if( HasConditions( bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE ) )
|
||||
{
|
||||
// flinch if hurt
|
||||
return GetScheduleOfType( SCHED_SMALL_FLINCH );
|
||||
}
|
||||
|
||||
if( m_hEnemy == NULL && IsFollowing() )
|
||||
{
|
||||
if( !m_hTargetEnt->IsAlive() )
|
||||
{
|
||||
// UNDONE: Comment about the recently dead player here?
|
||||
StopFollowing( FALSE );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( HasConditions( bits_COND_CLIENT_PUSH ) )
|
||||
{
|
||||
return GetScheduleOfType( SCHED_MOVE_AWAY_FOLLOW );
|
||||
}
|
||||
return GetScheduleOfType( SCHED_TARGET_FACE );
|
||||
}
|
||||
}
|
||||
|
||||
if( HasConditions( bits_COND_CLIENT_PUSH ) )
|
||||
{
|
||||
return GetScheduleOfType( SCHED_MOVE_AWAY );
|
||||
}
|
||||
|
||||
// try to say something about smells
|
||||
TrySmellTalk();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CTalkMonster::GetSchedule();
|
||||
}
|
||||
|
||||
MONSTERSTATE CBigSmoke::GetIdealState( void )
|
||||
{
|
||||
return CTalkMonster::GetIdealState();
|
||||
}
|
||||
|
||||
void CBigSmoke::DeclineFollowing( void )
|
||||
{
|
||||
PlaySentence( "BA_POK", 2, VOL_NORM, ATTN_NORM );
|
||||
}
|
@ -1,658 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This source code contains proprietary and confidential information of
|
||||
* Valve LLC and its suppliers. Access to this code is restricted to
|
||||
* persons who have executed a written SDK license with Valve. Any access,
|
||||
* use or distribution of this code by or to any unlicensed person is illegal.
|
||||
*
|
||||
****/
|
||||
//=========================================================
|
||||
// monster template
|
||||
//=========================================================
|
||||
// UNDONE: Holster weapon?
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "talkmonster.h"
|
||||
#include "schedule.h"
|
||||
#include "defaultai.h"
|
||||
#include "scripted.h"
|
||||
#include "weapons.h"
|
||||
#include "soundent.h"
|
||||
#include "squadmonster.h"
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
//=========================================================
|
||||
// first flag is barney dying for scripted sequences?
|
||||
#define BIGSMOKE_AE_DRAW ( 2 )
|
||||
#define BIGSMOKE_AE_SHOOT ( 3 )
|
||||
#define BIGSMOKE_AE_HOLSTER ( 4 )
|
||||
|
||||
#define BIGSMOKE_BODY_GUNHOLSTERED 0
|
||||
#define BIGSMOKE_BODY_GUNDRAWN 1
|
||||
#define BIGSMOKE_BODY_GUNGONE 2
|
||||
|
||||
class CBigSmoke : public CSquadMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int ISoundMask( void );
|
||||
void BigSmokeFirePistol( void );
|
||||
void AlertSound( void );
|
||||
int Classify( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
|
||||
void RunTask( Task_t *pTask );
|
||||
void StartTask( Task_t *pTask );
|
||||
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
|
||||
BOOL CheckRangeAttack1( float flDot, float flDist );
|
||||
|
||||
void DeclineFollowing( void );
|
||||
|
||||
// Override these to set behavior
|
||||
Schedule_t *GetScheduleOfType( int Type );
|
||||
Schedule_t *GetSchedule( void );
|
||||
MONSTERSTATE GetIdealState( void );
|
||||
|
||||
void DeathSound( void );
|
||||
void PainSound( void );
|
||||
|
||||
void TalkInit( void );
|
||||
|
||||
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
|
||||
BOOL m_fGunDrawn;
|
||||
float m_painTime;
|
||||
float m_checkAttackTime;
|
||||
BOOL m_lastAttackCheck;
|
||||
|
||||
// UNDONE: What is this for? It isn't used?
|
||||
float m_flPlayerDamage;// how much pain has the player inflicted on me?
|
||||
|
||||
CUSTOM_SCHEDULES
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_big_smoke, CBigSmoke )
|
||||
|
||||
TYPEDESCRIPTION CBigSmoke::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CBigSmoke, m_fGunDrawn, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CBigSmoke, m_painTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( CBigSmoke, m_checkAttackTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( CBigSmoke, m_lastAttackCheck, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CBigSmoke, m_flPlayerDamage, FIELD_FLOAT ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CBigSmoke, CSquadMonster )
|
||||
|
||||
//=========================================================
|
||||
// AI Schedules Specific to this monster
|
||||
//=====
|
||||
|
||||
Task_t tlBsFollow[] =
|
||||
{
|
||||
{ TASK_MOVE_TO_TARGET_RANGE, (float)128 }, // Move within 128 of target ent (client)
|
||||
{ TASK_SET_SCHEDULE, (float)SCHED_TARGET_FACE },
|
||||
};
|
||||
|
||||
Schedule_t slBsFollow[] =
|
||||
{
|
||||
{
|
||||
tlBsFollow,
|
||||
ARRAYSIZE( tlBsFollow ),
|
||||
bits_COND_NEW_ENEMY |
|
||||
bits_COND_LIGHT_DAMAGE |
|
||||
bits_COND_HEAVY_DAMAGE |
|
||||
bits_COND_HEAR_SOUND |
|
||||
bits_COND_PROVOKED,
|
||||
bits_SOUND_DANGER,
|
||||
"Follow"
|
||||
},
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// BarneyDraw - much better looking draw schedule for when
|
||||
// barney knows who he's gonna attack.
|
||||
//=========================================================
|
||||
Task_t tlBigSmokeEnemyDraw[] =
|
||||
{
|
||||
{ TASK_STOP_MOVING, 0 },
|
||||
{ TASK_FACE_ENEMY, 0 },
|
||||
{ TASK_PLAY_SEQUENCE_FACE_ENEMY, (float) ACT_ARM },
|
||||
};
|
||||
|
||||
Schedule_t slBigSmokeEnemyDraw[] =
|
||||
{
|
||||
{
|
||||
tlBigSmokeEnemyDraw,
|
||||
ARRAYSIZE( tlBigSmokeEnemyDraw ),
|
||||
0,
|
||||
0,
|
||||
"BigSmoke Enemy Draw"
|
||||
}
|
||||
};
|
||||
|
||||
Task_t tlBsFaceTarget[] =
|
||||
{
|
||||
{ TASK_SET_ACTIVITY, (float)ACT_IDLE },
|
||||
{ TASK_FACE_TARGET, (float)0 },
|
||||
{ TASK_SET_ACTIVITY, (float)ACT_IDLE },
|
||||
{ TASK_SET_SCHEDULE, (float)SCHED_TARGET_CHASE },
|
||||
};
|
||||
|
||||
Schedule_t slBsFaceTarget[] =
|
||||
{
|
||||
{
|
||||
tlBsFaceTarget,
|
||||
ARRAYSIZE( tlBsFaceTarget ),
|
||||
bits_COND_CLIENT_PUSH |
|
||||
bits_COND_NEW_ENEMY |
|
||||
bits_COND_LIGHT_DAMAGE |
|
||||
bits_COND_HEAVY_DAMAGE |
|
||||
bits_COND_HEAR_SOUND |
|
||||
bits_COND_PROVOKED,
|
||||
bits_SOUND_DANGER,
|
||||
"FaceTarget"
|
||||
},
|
||||
};
|
||||
|
||||
Task_t tlIdleBsStand[] =
|
||||
{
|
||||
{ TASK_STOP_MOVING, 0 },
|
||||
{ TASK_SET_ACTIVITY, (float)ACT_IDLE },
|
||||
{ TASK_WAIT, (float)2 }, // repick IDLESTAND every two seconds.
|
||||
{ TASK_TLK_HEADRESET, (float)0 }, // reset head position
|
||||
};
|
||||
|
||||
Schedule_t slIdleBsStand[] =
|
||||
{
|
||||
{
|
||||
tlIdleBsStand,
|
||||
ARRAYSIZE( tlIdleBsStand ),
|
||||
bits_COND_NEW_ENEMY |
|
||||
bits_COND_LIGHT_DAMAGE |
|
||||
bits_COND_HEAVY_DAMAGE |
|
||||
bits_COND_HEAR_SOUND |
|
||||
bits_COND_SMELL |
|
||||
bits_COND_PROVOKED,
|
||||
bits_SOUND_COMBAT |// sound flags - change these, and you'll break the talking code.
|
||||
//bits_SOUND_PLAYER |
|
||||
//bits_SOUND_WORLD |
|
||||
bits_SOUND_DANGER |
|
||||
bits_SOUND_MEAT |// scents
|
||||
bits_SOUND_CARCASS |
|
||||
bits_SOUND_GARBAGE,
|
||||
"IdleStand"
|
||||
},
|
||||
};
|
||||
|
||||
DEFINE_CUSTOM_SCHEDULES( CBigSmoke )
|
||||
{
|
||||
slBsFollow,
|
||||
slBigSmokeEnemyDraw,
|
||||
slBsFaceTarget,
|
||||
slIdleBsStand,
|
||||
};
|
||||
|
||||
IMPLEMENT_CUSTOM_SCHEDULES( CBigSmoke, CSquadMonster )
|
||||
|
||||
void CBigSmoke::StartTask( Task_t *pTask )
|
||||
{
|
||||
CSquadMonster::StartTask( pTask );
|
||||
}
|
||||
|
||||
void CBigSmoke::RunTask( Task_t *pTask )
|
||||
{
|
||||
switch( pTask->iTask )
|
||||
{
|
||||
case TASK_RANGE_ATTACK1:
|
||||
if( m_hEnemy != NULL && ( m_hEnemy->IsPlayer() ) )
|
||||
{
|
||||
pev->framerate = 1.5;
|
||||
}
|
||||
CSquadMonster::RunTask( pTask );
|
||||
break;
|
||||
default:
|
||||
CSquadMonster::RunTask( pTask );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// ISoundMask - returns a bit mask indicating which types
|
||||
// of sounds this monster regards.
|
||||
//=========================================================
|
||||
int CBigSmoke::ISoundMask( void)
|
||||
{
|
||||
return bits_SOUND_WORLD |
|
||||
bits_SOUND_COMBAT |
|
||||
bits_SOUND_CARCASS |
|
||||
bits_SOUND_MEAT |
|
||||
bits_SOUND_GARBAGE |
|
||||
bits_SOUND_DANGER |
|
||||
bits_SOUND_PLAYER;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Classify - indicates this monster's place in the
|
||||
// relationship table.
|
||||
//=========================================================
|
||||
int CBigSmoke::Classify( void )
|
||||
{
|
||||
return CLASS_PLAYER_ALLY;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// ALertSound - barney says "Freeze!"
|
||||
//=========================================================
|
||||
void CBigSmoke::AlertSound( void )
|
||||
{
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// SetYawSpeed - allows each sequence to have a different
|
||||
// turn rate associated with it.
|
||||
//=========================================================
|
||||
void CBigSmoke::SetYawSpeed( void )
|
||||
{
|
||||
int ys;
|
||||
|
||||
ys = 0;
|
||||
|
||||
switch ( m_Activity )
|
||||
{
|
||||
case ACT_IDLE:
|
||||
ys = 70;
|
||||
break;
|
||||
case ACT_WALK:
|
||||
ys = 70;
|
||||
break;
|
||||
case ACT_RUN:
|
||||
ys = 90;
|
||||
break;
|
||||
default:
|
||||
ys = 70;
|
||||
break;
|
||||
}
|
||||
|
||||
pev->yaw_speed = ys;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// CheckRangeAttack1
|
||||
//=========================================================
|
||||
BOOL CBigSmoke::CheckRangeAttack1( float flDot, float flDist )
|
||||
{
|
||||
if( flDist <= 1024 && flDot >= 0.5 )
|
||||
{
|
||||
if( gpGlobals->time > m_checkAttackTime )
|
||||
{
|
||||
TraceResult tr;
|
||||
|
||||
Vector shootOrigin = pev->origin + Vector( 0, 0, 55 );
|
||||
CBaseEntity *pEnemy = m_hEnemy;
|
||||
Vector shootTarget = ( ( pEnemy->BodyTarget( shootOrigin ) - pEnemy->pev->origin ) + m_vecEnemyLKP );
|
||||
UTIL_TraceLine( shootOrigin, shootTarget, dont_ignore_monsters, ENT( pev ), &tr );
|
||||
m_checkAttackTime = gpGlobals->time + 1;
|
||||
if( tr.flFraction == 1.0 || ( tr.pHit != NULL && CBaseEntity::Instance( tr.pHit ) == pEnemy ) )
|
||||
m_lastAttackCheck = TRUE;
|
||||
else
|
||||
m_lastAttackCheck = FALSE;
|
||||
m_checkAttackTime = gpGlobals->time + 1.5;
|
||||
}
|
||||
return m_lastAttackCheck;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// BarneyFirePistol - shoots one round from the pistol at
|
||||
// the enemy barney is facing.
|
||||
//=========================================================
|
||||
void CBigSmoke::BigSmokeFirePistol( void )
|
||||
{
|
||||
Vector vecShootOrigin;
|
||||
|
||||
UTIL_MakeVectors( pev->angles );
|
||||
vecShootOrigin = pev->origin + Vector( 0, 0, 55 );
|
||||
Vector vecShootDir = ShootAtEnemy( vecShootOrigin );
|
||||
|
||||
Vector angDir = UTIL_VecToAngles( vecShootDir );
|
||||
SetBlending( 0, angDir.x );
|
||||
pev->effects = EF_MUZZLEFLASH;
|
||||
|
||||
FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_2DEGREES, 1024, BULLET_MONSTER_9MM );
|
||||
|
||||
int pitchShift = RANDOM_LONG( 0, 20 );
|
||||
|
||||
// Only shift about half the time
|
||||
if( pitchShift > 10 )
|
||||
pitchShift = 0;
|
||||
else
|
||||
pitchShift -= 5;
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, "BigSmoke/fire1.wav", 1, ATTN_NORM, 0, 100 + pitchShift );
|
||||
|
||||
CSoundEnt::InsertSound( bits_SOUND_COMBAT, pev->origin, 384, 0.3 );
|
||||
|
||||
// UNDONE: Reload?
|
||||
m_cAmmoLoaded--;// take away a bullet!
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// HandleAnimEvent - catches the monster-specific messages
|
||||
// that occur when tagged animation frames are played.
|
||||
//
|
||||
// Returns number of events handled, 0 if none.
|
||||
//=========================================================
|
||||
void CBigSmoke::HandleAnimEvent( MonsterEvent_t *pEvent )
|
||||
{
|
||||
switch( pEvent->event )
|
||||
{
|
||||
case BIGSMOKE_AE_SHOOT:
|
||||
BigSmokeFirePistol();
|
||||
break;
|
||||
case BIGSMOKE_AE_DRAW:
|
||||
// barney's bodygroup switches here so he can pull gun from holster
|
||||
pev->body = BIGSMOKE_BODY_GUNDRAWN;
|
||||
m_fGunDrawn = TRUE;
|
||||
break;
|
||||
case BIGSMOKE_AE_HOLSTER:
|
||||
// change bodygroup to replace gun in holster
|
||||
pev->body = BIGSMOKE_BODY_GUNHOLSTERED;
|
||||
m_fGunDrawn = FALSE;
|
||||
break;
|
||||
default:
|
||||
CSquadMonster::HandleAnimEvent( pEvent );
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CBigSmoke::Spawn()
|
||||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL( ENT( pev ), "models/bigsmoke.mdl" );
|
||||
UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->health = 350;
|
||||
pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin.
|
||||
m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
pev->body = 0; // gun in holster
|
||||
m_fGunDrawn = FALSE;
|
||||
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
|
||||
|
||||
MonsterInit();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CBigSmoke::Precache()
|
||||
{
|
||||
PRECACHE_MODEL( "models/bigsmoke.mdl" );
|
||||
|
||||
PRECACHE_SOUND( "bigsmoke/fire1.wav" );
|
||||
|
||||
|
||||
CSquadMonster::Precache();
|
||||
}
|
||||
|
||||
|
||||
static BOOL IsFacing( entvars_t *pevTest, const Vector &reference )
|
||||
{
|
||||
Vector vecDir = reference - pevTest->origin;
|
||||
vecDir.z = 0;
|
||||
vecDir = vecDir.Normalize();
|
||||
Vector forward, angle;
|
||||
angle = pevTest->v_angle;
|
||||
angle.x = 0;
|
||||
UTIL_MakeVectorsPrivate( angle, forward, NULL, NULL );
|
||||
|
||||
// He's facing me, he meant it
|
||||
if( DotProduct( forward, vecDir ) > 0.96 ) // +/- 15 degrees or so
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int CBigSmoke::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
|
||||
{
|
||||
// make sure friends talk about it if player hurts talkmonsters...
|
||||
int ret = CSquadMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
|
||||
if( !IsAlive() || pev->deadflag == DEAD_DYING )
|
||||
return ret;
|
||||
|
||||
if( m_MonsterState != MONSTERSTATE_PRONE && ( pevAttacker->flags & FL_CLIENT ) )
|
||||
{
|
||||
m_flPlayerDamage += flDamage;
|
||||
|
||||
// This is a heurstic to determine if the player intended to harm me
|
||||
// If I have an enemy, we can't establish intent (may just be crossfire)
|
||||
if( m_hEnemy == NULL )
|
||||
{
|
||||
// If the player was facing directly at me, or I'm already suspicious, get mad
|
||||
if( ( m_afMemory & bits_MEMORY_SUSPICIOUS ) || IsFacing( pevAttacker, pev->origin ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if( !( m_hEnemy->IsPlayer()) && pev->deadflag == DEAD_NO )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// PainSound
|
||||
//=========================================================
|
||||
void CBigSmoke::PainSound( void )
|
||||
{
|
||||
if( gpGlobals->time < m_painTime )
|
||||
return;
|
||||
|
||||
m_painTime = gpGlobals->time + RANDOM_FLOAT( 0.5, 0.75 );
|
||||
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// DeathSound
|
||||
//=========================================================
|
||||
void CBigSmoke::DeathSound( void )
|
||||
{
|
||||
}
|
||||
|
||||
void CBigSmoke::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
|
||||
{
|
||||
switch( ptr->iHitgroup )
|
||||
{
|
||||
case HITGROUP_CHEST:
|
||||
case HITGROUP_STOMACH:
|
||||
if (bitsDamageType & ( DMG_BULLET | DMG_SLASH | DMG_BLAST ) )
|
||||
{
|
||||
flDamage = flDamage / 2;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if( bitsDamageType & ( DMG_BULLET | DMG_SLASH | DMG_CLUB ) )
|
||||
{
|
||||
flDamage -= 20;
|
||||
if( flDamage <= 0 )
|
||||
{
|
||||
UTIL_Ricochet( ptr->vecEndPos, 1.0 );
|
||||
flDamage = 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
// always a head shot
|
||||
ptr->iHitgroup = HITGROUP_HEAD;
|
||||
break;
|
||||
}
|
||||
|
||||
CSquadMonster::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
|
||||
}
|
||||
|
||||
void CBigSmoke::Killed( entvars_t *pevAttacker, int iGib )
|
||||
{
|
||||
if( pev->body < BIGSMOKE_BODY_GUNGONE )
|
||||
{
|
||||
// drop the gun!
|
||||
Vector vecGunPos;
|
||||
Vector vecGunAngles;
|
||||
|
||||
pev->body = BIGSMOKE_BODY_GUNGONE;
|
||||
|
||||
GetAttachment( 0, vecGunPos, vecGunAngles );
|
||||
|
||||
CBaseEntity *pGun = DropItem( "weapon_9mmhandgun", vecGunPos, vecGunAngles );
|
||||
}
|
||||
|
||||
SetUse( NULL );
|
||||
CSquadMonster::Killed( pevAttacker, iGib );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AI Schedules Specific to this monster
|
||||
//=========================================================
|
||||
Schedule_t *CBigSmoke::GetScheduleOfType( int Type )
|
||||
{
|
||||
Schedule_t *psched;
|
||||
|
||||
switch( Type )
|
||||
{
|
||||
case SCHED_ARM_WEAPON:
|
||||
if( m_hEnemy != NULL )
|
||||
{
|
||||
// face enemy, then draw.
|
||||
return slBigSmokeEnemyDraw;
|
||||
}
|
||||
break;
|
||||
// Hook these to make a looping schedule
|
||||
case SCHED_TARGET_FACE:
|
||||
// call base class default so that barney will talk
|
||||
// when 'used'
|
||||
psched = CSquadMonster::GetScheduleOfType( Type );
|
||||
|
||||
if( psched == slIdleStand )
|
||||
return slBsFaceTarget; // override this for different target face behavior
|
||||
else
|
||||
return psched;
|
||||
case SCHED_TARGET_CHASE:
|
||||
return slBsFollow;
|
||||
case SCHED_IDLE_STAND:
|
||||
// call base class default so that scientist will talk
|
||||
// when standing during idle
|
||||
psched = CSquadMonster::GetScheduleOfType( Type );
|
||||
|
||||
if( psched == slIdleStand )
|
||||
{
|
||||
// just look straight ahead.
|
||||
return slIdleBaStand;
|
||||
}
|
||||
else
|
||||
return psched;
|
||||
}
|
||||
|
||||
return CSquadMonster::GetScheduleOfType( Type );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// GetSchedule - Decides which type of schedule best suits
|
||||
// the monster's current state and conditions. Then calls
|
||||
// monster's member function to get a pointer to a schedule
|
||||
// of the proper type.
|
||||
//=========================================================
|
||||
Schedule_t *CBigSmoke::GetSchedule( void )
|
||||
{
|
||||
if( HasConditions( bits_COND_HEAR_SOUND ) )
|
||||
{
|
||||
CSound *pSound;
|
||||
pSound = PBestSound();
|
||||
|
||||
ASSERT( pSound != NULL );
|
||||
if( pSound && (pSound->m_iType & bits_SOUND_DANGER) )
|
||||
return GetScheduleOfType( SCHED_TAKE_COVER_FROM_BEST_SOUND );
|
||||
}
|
||||
|
||||
switch( m_MonsterState )
|
||||
{
|
||||
case MONSTERSTATE_COMBAT:
|
||||
{
|
||||
// dead enemy
|
||||
if( HasConditions( bits_COND_ENEMY_DEAD ) )
|
||||
{
|
||||
// call base class, all code to handle dead enemies is centralized there.
|
||||
return CBaseMonster::GetSchedule();
|
||||
}
|
||||
|
||||
// always act surprized with a new enemy
|
||||
if( HasConditions( bits_COND_NEW_ENEMY ) && HasConditions( bits_COND_LIGHT_DAMAGE ) )
|
||||
return GetScheduleOfType( SCHED_SMALL_FLINCH );
|
||||
|
||||
// wait for one schedule to draw gun
|
||||
if( !m_fGunDrawn )
|
||||
return GetScheduleOfType( SCHED_ARM_WEAPON );
|
||||
|
||||
if( HasConditions( bits_COND_HEAVY_DAMAGE ) )
|
||||
return GetScheduleOfType( SCHED_TAKE_COVER_FROM_ENEMY );
|
||||
}
|
||||
break;
|
||||
case MONSTERSTATE_ALERT:
|
||||
case MONSTERSTATE_IDLE:
|
||||
if( HasConditions( bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE ) )
|
||||
{
|
||||
// flinch if hurt
|
||||
return GetScheduleOfType( SCHED_SMALL_FLINCH );
|
||||
}
|
||||
|
||||
|
||||
if( HasConditions( bits_COND_CLIENT_PUSH ) )
|
||||
{
|
||||
return GetScheduleOfType( SCHED_MOVE_AWAY );
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CSquadMonster::GetSchedule();
|
||||
}
|
||||
|
||||
MONSTERSTATE CBigSmoke::GetIdealState( void )
|
||||
{
|
||||
return CSquadMonster::GetIdealState();
|
||||
}
|
||||
|
||||
void CBigSmoke::DeclineFollowing( void )
|
||||
{
|
||||
PlaySentence( "BA_POK", 2, VOL_NORM, ATTN_NORM );
|
||||
}
|
455
dlls/cross.cpp~
455
dlls/cross.cpp~
@ -1,455 +0,0 @@
|
||||
#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD )
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
#include "gamerules.h"
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
#define BOLT_AIR_VELOCITY 1300
|
||||
#define BOLT_WATER_VELOCITY 1300
|
||||
|
||||
|
||||
// UNDONE: Save/restore this? Don't forget to set classname and LINK_ENTITY_TO_CLASS()
|
||||
//
|
||||
// OVERLOADS SOME ENTVARS:
|
||||
//
|
||||
// speed - the ideal magnitude of my velocity
|
||||
class CCrowbar2Bolt : public CBaseEntity
|
||||
{
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
int Classify( void );
|
||||
void EXPORT BubbleThink( void );
|
||||
void EXPORT BoltTouch( CBaseEntity *pOther );
|
||||
void EXPORT ExplodeThink( void );
|
||||
|
||||
int m_iTrail;
|
||||
|
||||
public:
|
||||
static CCrowbar2Bolt *BoltCreate( void );
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( crowbar2_bolt, CCrowbar2Bolt )
|
||||
|
||||
CCrowbar2Bolt *CCrowbar2Bolt::BoltCreate( void )
|
||||
{
|
||||
// Create a new entity with CCrossbowBolt private data
|
||||
CCrowbar2Bolt *pBolt = GetClassPtr( (CCrowbar2Bolt *)NULL );
|
||||
pBolt->pev->classname = MAKE_STRING( "crossbow_bolt" ); // g-cont. enable save\restore
|
||||
pBolt->Spawn();
|
||||
|
||||
return pBolt;
|
||||
}
|
||||
|
||||
void CCrowbar2Bolt::Spawn()
|
||||
{
|
||||
Precache();
|
||||
pev->movetype = MOVETYPE_FLY;
|
||||
pev->solid = SOLID_BBOX;
|
||||
|
||||
pev->gravity = 300;
|
||||
|
||||
SET_MODEL( ENT( pev ), "models/w_hammer.mdl" );
|
||||
|
||||
UTIL_SetOrigin( pev, pev->origin );
|
||||
UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ) );
|
||||
|
||||
SetTouch( &CCrowbar2Bolt::BoltTouch );
|
||||
SetThink( &CCrowbar2Bolt::BubbleThink );
|
||||
pev->nextthink = gpGlobals->time + 0.2;
|
||||
}
|
||||
|
||||
void CCrowbar2Bolt::Precache()
|
||||
{
|
||||
PRECACHE_MODEL( "models/w_hammer.mdl" );
|
||||
PRECACHE_SOUND( "weapons/hammer_hitbod1.wav" );
|
||||
PRECACHE_SOUND( "weapons/hammer_hitbod2.wav" );
|
||||
PRECACHE_SOUND( "weapons/g_bounce2.wav" );
|
||||
PRECACHE_SOUND( "fvox/beep.wav" );
|
||||
m_iTrail = PRECACHE_MODEL( "sprites/streak.spr" );
|
||||
}
|
||||
|
||||
int CCrowbar2Bolt::Classify( void )
|
||||
{
|
||||
return CLASS_NONE;
|
||||
}
|
||||
|
||||
void CCrowbar2Bolt::BoltTouch( CBaseEntity *pOther )
|
||||
{
|
||||
SetTouch( NULL );
|
||||
SetThink( NULL );
|
||||
|
||||
if( pOther->pev->takedamage )
|
||||
{
|
||||
TraceResult tr = UTIL_GetGlobalTrace();
|
||||
entvars_t *pevOwner;
|
||||
|
||||
pevOwner = VARS( pev->owner );
|
||||
|
||||
// UNDONE: this needs to call TraceAttack instead
|
||||
ClearMultiDamage();
|
||||
|
||||
if( pOther->IsPlayer() )
|
||||
{
|
||||
pOther->TraceAttack( pevOwner, 259, pev->velocity.Normalize(), &tr, DMG_ALWAYSGIB );
|
||||
}
|
||||
else
|
||||
{
|
||||
pOther->TraceAttack( pevOwner, 259, pev->velocity.Normalize(), &tr, DMG_BULLET | DMG_ALWAYSGIB );
|
||||
}
|
||||
|
||||
ApplyMultiDamage( pev, pevOwner );
|
||||
|
||||
pev->velocity = Vector( 0, 0, 0 );
|
||||
// play body "thwack" sound
|
||||
switch( RANDOM_LONG( 0, 1 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_BODY, "weapons/hammer_hitbod.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_BODY, "weapons/hammer_hitbod.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
}
|
||||
|
||||
if( !g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
Killed( pev, GIB_ALWAYS );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "weapons/hammer_hit.wav", RANDOM_FLOAT( 0.95, 1.0 ), ATTN_NORM, 0, 98 + RANDOM_LONG( 0, 7 ) );
|
||||
|
||||
SetThink( &CBaseEntity::SUB_Remove );
|
||||
pev->nextthink = gpGlobals->time;// this will get changed below if the bolt is allowed to stick in what it hit.
|
||||
|
||||
if( FClassnameIs( pOther->pev, "worldspawn" ) )
|
||||
{
|
||||
// if what we hit is static architecture, can stay around for a while.
|
||||
Vector vecDir = pev->velocity.Normalize();
|
||||
UTIL_SetOrigin( pev, pev->origin - vecDir * 12 );
|
||||
pev->angles = UTIL_VecToAngles( vecDir );
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->movetype = MOVETYPE_FLY;
|
||||
pev->velocity = Vector( 0, 0, 0 );
|
||||
pev->avelocity.z = 180;
|
||||
pev->angles.z = RANDOM_LONG( 180,360 );
|
||||
pev->nextthink = gpGlobals->time + 10.0;
|
||||
}
|
||||
else if( pOther->pev->movetype == MOVETYPE_PUSH || pOther->pev->movetype == MOVETYPE_PUSHSTEP )
|
||||
{
|
||||
Vector vecDir = pev->velocity.Normalize();
|
||||
UTIL_SetOrigin( pev, pev->origin - vecDir * 12 );
|
||||
pev->angles = UTIL_VecToAngles( vecDir );
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->velocity = Vector( 0, 0, 0 );
|
||||
pev->avelocity.z = 0;
|
||||
pev->angles.z = RANDOM_LONG( 0, 180 );
|
||||
pev->nextthink = gpGlobals->time + 10.0;
|
||||
|
||||
}
|
||||
|
||||
if( UTIL_PointContents( pev->origin ) != CONTENTS_WATER )
|
||||
{
|
||||
UTIL_Sparks( pev->origin );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CCrowbar2Bolt::BubbleThink( void )
|
||||
{
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
if( pev->waterlevel == 0 )
|
||||
return;
|
||||
|
||||
UTIL_BubbleTrail( pev->origin - pev->velocity * 0.1, pev->origin, 1 );
|
||||
}
|
||||
|
||||
void CCrowbar2Bolt::ExplodeThink( void )
|
||||
{
|
||||
int iContents = UTIL_PointContents( pev->origin );
|
||||
int iScale;
|
||||
|
||||
pev->dmg = 40;
|
||||
iScale = 10;
|
||||
|
||||
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
|
||||
WRITE_BYTE( TE_EXPLOSION );
|
||||
WRITE_COORD( pev->origin.x );
|
||||
WRITE_COORD( pev->origin.y );
|
||||
WRITE_COORD( pev->origin.z );
|
||||
if( iContents != CONTENTS_WATER )
|
||||
{
|
||||
WRITE_SHORT( g_sModelIndexFireball );
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE_SHORT( g_sModelIndexWExplosion );
|
||||
}
|
||||
WRITE_BYTE( iScale ); // scale * 10
|
||||
WRITE_BYTE( 15 ); // framerate
|
||||
WRITE_BYTE( TE_EXPLFLAG_NONE );
|
||||
MESSAGE_END();
|
||||
|
||||
entvars_t *pevOwner;
|
||||
|
||||
if( pev->owner )
|
||||
pevOwner = VARS( pev->owner );
|
||||
else
|
||||
pevOwner = NULL;
|
||||
|
||||
pev->owner = NULL; // can't traceline attack owner if this is set
|
||||
|
||||
::RadiusDamage( pev->origin, pev, pevOwner, pev->dmg, 128, CLASS_NONE, DMG_BLAST | DMG_ALWAYSGIB );
|
||||
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
#endif
|
||||
|
||||
enum crowbar_e
|
||||
{
|
||||
CROSSBOW_IDLE = 0,
|
||||
CROSSBOW_DRAW,
|
||||
CROSSBOW_HOLSTER,
|
||||
CROSSBOW_ATTACK1HIT
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_hammer, CCrowbar2 )
|
||||
|
||||
void CCrowbar2::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_HAMMER;
|
||||
SET_MODEL( ENT( pev ), "models/w_hammer.mdl" );
|
||||
|
||||
m_iDefaultAmmo = -1;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
int CCrowbar2::AddToPlayer( CBasePlayer *pPlayer )
|
||||
{
|
||||
if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
|
||||
WRITE_BYTE( m_iId );
|
||||
MESSAGE_END();
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CCrowbar2::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/w_hammer.mdl" );
|
||||
PRECACHE_MODEL( "models/v_hammer.mdl" );
|
||||
PRECACHE_MODEL( "models/p_hammer.mdl" );
|
||||
|
||||
PRECACHE_SOUND( "g_bounce2.wav" );
|
||||
|
||||
UTIL_PrecacheOther( "crossbow2_bolt" );
|
||||
|
||||
m_usCrossbow12 = PRECACHE_EVENT( 1, "events/crowbar.sc" );
|
||||
m_usCrossbow22 = PRECACHE_EVENT( 1, "events/crowbar.sc" );
|
||||
}
|
||||
|
||||
int CCrowbar2::GetItemInfo( ItemInfo *p )
|
||||
{
|
||||
p->pszName = STRING( pev->classname );
|
||||
p->pszAmmo1 = NULL;
|
||||
p->iMaxAmmo1 = -1;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = -1;
|
||||
p->iSlot = 0;
|
||||
p->iPosition = 4;
|
||||
p->iId = WEAPON_HAMMER;
|
||||
p->iFlags = 0;
|
||||
p->iWeight = -10;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CCrowbar2::Deploy()
|
||||
{
|
||||
if( m_iClip )
|
||||
return DefaultDeploy( "models/v_hammer.mdl", "models/p_hammer.mdl", CROSSBOW_DRAW, "bow" );
|
||||
return DefaultDeploy( "models/v_hammer.mdl", "models/p_hammer.mdl", CROSSBOW_DRAW, "bow" );
|
||||
}
|
||||
|
||||
void CCrowbar2::Holster( int skiplocal /* = 0 */ )
|
||||
{
|
||||
m_fInReload = FALSE;// cancel any reload in progress.
|
||||
|
||||
if( m_fInZoom )
|
||||
{
|
||||
SecondaryAttack();
|
||||
}
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
if( m_iClip )
|
||||
{
|
||||
SendWeaponAnim( CROSSBOW_HOLSTER );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CCrowbar2::PrimaryAttack( void )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
if( m_fInZoom && bIsMultiplayer() )
|
||||
#else
|
||||
if( m_fInZoom && g_pGameRules->IsMultiplayer() )
|
||||
#endif
|
||||
{
|
||||
FireSniperBolt();
|
||||
return;
|
||||
}
|
||||
|
||||
FireBolt();
|
||||
}
|
||||
|
||||
// this function only gets called in multiplayer
|
||||
void CCrowbar2::FireSniperBolt()
|
||||
{
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.35;
|
||||
|
||||
|
||||
TraceResult tr;
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
|
||||
|
||||
int flags;
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
flags = FEV_NOTHOST;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
|
||||
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow22, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 );
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
|
||||
UTIL_MakeVectors( anglesAim );
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition() - gpGlobals->v_up * 2;
|
||||
Vector vecDir = gpGlobals->v_forward;
|
||||
|
||||
UTIL_TraceLine( vecSrc, vecSrc + vecDir * 8192, dont_ignore_monsters, m_pPlayer->edict(), &tr );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
if( tr.pHit->v.takedamage )
|
||||
{
|
||||
ClearMultiDamage();
|
||||
CBaseEntity::Instance( tr.pHit )->TraceAttack( m_pPlayer->pev, 120, vecDir, &tr, DMG_BULLET | DMG_ALWAYSGIB );
|
||||
ApplyMultiDamage( pev, m_pPlayer->pev );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CCrowbar2::FireBolt()
|
||||
{
|
||||
TraceResult tr;
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
|
||||
|
||||
|
||||
int flags;
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
flags = FEV_NOTHOST;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
|
||||
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow12, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 );
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
|
||||
UTIL_MakeVectors( anglesAim );
|
||||
|
||||
anglesAim.x = -anglesAim.x;
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition() - gpGlobals->v_up * 2;
|
||||
Vector vecDir = gpGlobals->v_forward;
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
CCrowbar2Bolt *pBolt = CCrowbar2Bolt::BoltCreate();
|
||||
pBolt->pev->origin = vecSrc;
|
||||
pBolt->pev->angles = anglesAim;
|
||||
pBolt->pev->owner = m_pPlayer->edict();
|
||||
|
||||
if( m_pPlayer->pev->waterlevel == 3 )
|
||||
{
|
||||
pBolt->pev->velocity = vecDir * BOLT_WATER_VELOCITY;
|
||||
pBolt->pev->speed = BOLT_WATER_VELOCITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBolt->pev->velocity = vecDir * BOLT_AIR_VELOCITY;
|
||||
pBolt->pev->speed = BOLT_AIR_VELOCITY;
|
||||
}
|
||||
pBolt->pev->avelocity.z = 10;
|
||||
#endif
|
||||
|
||||
if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 )
|
||||
// HEV suit - indicate out of ammo condition
|
||||
m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 );
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.35;
|
||||
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.35;
|
||||
|
||||
if( m_iClip != 0 )
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5.0;
|
||||
else
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.75;
|
||||
}
|
||||
|
||||
|
||||
void CCrowbar2::WeaponIdle( void )
|
||||
{
|
||||
m_pPlayer->GetAutoaimVector( AUTOAIM_2DEGREES ); // get the autoaim vector but ignore it; used for autoaim crosshair in DM
|
||||
|
||||
ResetEmptySound();
|
||||
|
||||
if( m_flTimeWeaponIdle < UTIL_WeaponTimeBase() )
|
||||
{
|
||||
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 );
|
||||
if( flRand <= 0.75 )
|
||||
{
|
||||
if( m_iClip )
|
||||
{
|
||||
SendWeaponAnim( CROSSBOW_IDLE );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim( CROSSBOW_IDLE );
|
||||
}
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_iClip )
|
||||
{
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 90.0 / 30.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 80.0 / 30.0;
|
||||
}
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,332 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
#include "gamerules.h"
|
||||
|
||||
#define CROWBAR_BODYHIT_VOLUME 128
|
||||
#define CROWBAR_WALLHIT_VOLUME 512
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_crowbar, CCrowbar )
|
||||
|
||||
enum gauss_e
|
||||
{
|
||||
CROWBAR_IDLE = 0,
|
||||
CROWBAR_DRAW,
|
||||
CROWBAR_HOLSTER,
|
||||
CROWBAR_ATTACK1HIT,
|
||||
CROWBAR_ATTACK1MISS,
|
||||
CROWBAR_ATTACK2MISS,
|
||||
CROWBAR_ATTACK2HIT,
|
||||
CROWBAR_ATTACK3MISS,
|
||||
CROWBAR_ATTACK3HIT,
|
||||
CROWBAR_TAUNT
|
||||
};
|
||||
|
||||
|
||||
void CCrowbar::Spawn( )
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_CROWBAR;
|
||||
SET_MODEL( ENT( pev ), "models/w_crowbar.mdl" );
|
||||
m_iClip = -1;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
void CCrowbar::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/v_crowbar.mdl" );
|
||||
PRECACHE_MODEL( "models/w_crowbar.mdl" );
|
||||
PRECACHE_MODEL( "models/p_crowbar.mdl" );
|
||||
PRECACHE_SOUND( "weapons/cbar_hit1.wav" );
|
||||
PRECACHE_SOUND( "weapons/cbar_hit2.wav" );
|
||||
PRECACHE_SOUND( "weapons/cbar_hitbod1.wav" );
|
||||
PRECACHE_SOUND( "weapons/cbar_hitbod2.wav" );
|
||||
PRECACHE_SOUND( "weapons/cbar_hitbod3.wav" );
|
||||
PRECACHE_SOUND( "weapons/cbar_miss1.wav" );
|
||||
PRECACHE_SOUND( "taunts/taunt1.wav" );
|
||||
PRECACHE_SOUND( "taunts/taunt2.wav" );
|
||||
PRECACHE_SOUND( "taunts/taunt3.wav" );
|
||||
PRECACHE_SOUND( "taunts/taunt4.wav" );
|
||||
|
||||
|
||||
m_usCrowbar = PRECACHE_EVENT( 1, "events/crowbar.sc" );
|
||||
}
|
||||
|
||||
int CCrowbar::GetItemInfo( ItemInfo *p )
|
||||
{
|
||||
p->pszName = STRING( pev->classname );
|
||||
p->pszAmmo1 = NULL;
|
||||
p->iMaxAmmo1 = -1;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = WEAPON_NOCLIP;
|
||||
p->iSlot = 0;
|
||||
p->iPosition = 0;
|
||||
p->iId = WEAPON_CROWBAR;
|
||||
p->iWeight = CROWBAR_WEIGHT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CCrowbar::Deploy()
|
||||
{
|
||||
return DefaultDeploy( "models/v_crowbar.mdl", "models/p_crowbar.mdl", CROWBAR_DRAW, "crowbar" );
|
||||
}
|
||||
|
||||
void CCrowbar::Holster( int skiplocal /* = 0 */ )
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
SendWeaponAnim( CROWBAR_HOLSTER );
|
||||
}
|
||||
|
||||
void FindHullIntersection( const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity )
|
||||
{
|
||||
int i, j, k;
|
||||
float distance;
|
||||
float *minmaxs[2] = {mins, maxs};
|
||||
TraceResult tmpTrace;
|
||||
Vector vecHullEnd = tr.vecEndPos;
|
||||
Vector vecEnd;
|
||||
|
||||
distance = 1e6f;
|
||||
|
||||
vecHullEnd = vecSrc + ( ( vecHullEnd - vecSrc ) * 2 );
|
||||
UTIL_TraceLine( vecSrc, vecHullEnd, dont_ignore_monsters, pEntity, &tmpTrace );
|
||||
if( tmpTrace.flFraction < 1.0 )
|
||||
{
|
||||
tr = tmpTrace;
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
for( k = 0; k < 2; k++ )
|
||||
{
|
||||
vecEnd.x = vecHullEnd.x + minmaxs[i][0];
|
||||
vecEnd.y = vecHullEnd.y + minmaxs[j][1];
|
||||
vecEnd.z = vecHullEnd.z + minmaxs[k][2];
|
||||
|
||||
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, pEntity, &tmpTrace );
|
||||
if( tmpTrace.flFraction < 1.0 )
|
||||
{
|
||||
float thisDistance = ( tmpTrace.vecEndPos - vecSrc ).Length();
|
||||
if( thisDistance < distance )
|
||||
{
|
||||
tr = tmpTrace;
|
||||
distance = thisDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCrowbar::PrimaryAttack()
|
||||
{
|
||||
if( !Swing( 1 ) )
|
||||
{
|
||||
SetThink( &CCrowbar::SwingAgain );
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
}
|
||||
void CCrowbar::SecondaryAttack( void )
|
||||
{
|
||||
SendWeaponAnim( CROWBAR_TAUNT );
|
||||
switch( RANDOM_LONG( 0, 3 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "taunts/taunt1.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "taunts/taunt2.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "taunts/taunt3.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 3:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "taunts/taunt4.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
};
|
||||
pev->nextthink = gpGlobals->time + 2;
|
||||
}
|
||||
|
||||
void CCrowbar::Smack()
|
||||
{
|
||||
DecalGunshot( &m_trHit, BULLET_PLAYER_CROWBAR );
|
||||
}
|
||||
|
||||
void CCrowbar::SwingAgain( void )
|
||||
{
|
||||
Swing( 0 );
|
||||
}
|
||||
|
||||
int CCrowbar::Swing( int fFirst )
|
||||
{
|
||||
int fDidHit = FALSE;
|
||||
|
||||
TraceResult tr;
|
||||
|
||||
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition();
|
||||
Vector vecEnd = vecSrc + gpGlobals->v_forward * 32;
|
||||
|
||||
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
if( tr.flFraction >= 1.0 )
|
||||
{
|
||||
UTIL_TraceHull( vecSrc, vecEnd, dont_ignore_monsters, head_hull, ENT( m_pPlayer->pev ), &tr );
|
||||
if( tr.flFraction < 1.0 )
|
||||
{
|
||||
// Calculate the point of intersection of the line (or hull) and the object we hit
|
||||
// This is and approximation of the "best" intersection
|
||||
CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
|
||||
if( !pHit || pHit->IsBSPModel() )
|
||||
FindHullIntersection( vecSrc, tr, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX, m_pPlayer->edict() );
|
||||
vecEnd = tr.vecEndPos; // This is the point on the actual surface (the hull could have hit space)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usCrowbar,
|
||||
0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0,
|
||||
0.0, 0, 0.0 );
|
||||
|
||||
if( tr.flFraction >= 1.0 )
|
||||
{
|
||||
if( fFirst )
|
||||
{
|
||||
// miss
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( ( ( m_iSwing++ ) % 2 ) + 1 )
|
||||
{
|
||||
case 0:
|
||||
SendWeaponAnim( CROWBAR_ATTACK1HIT );
|
||||
break;
|
||||
case 1:
|
||||
SendWeaponAnim( CROWBAR_ATTACK2HIT );
|
||||
break;
|
||||
case 2:
|
||||
SendWeaponAnim( CROWBAR_ATTACK3HIT );
|
||||
break;
|
||||
}
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// hit
|
||||
fDidHit = TRUE;
|
||||
CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit );
|
||||
|
||||
ClearMultiDamage();
|
||||
|
||||
if( ( m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// first swing does full damage
|
||||
pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB );
|
||||
}
|
||||
else
|
||||
{
|
||||
// subsequent swings do half
|
||||
pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgCrowbar / 2, gpGlobals->v_forward, &tr, DMG_CLUB );
|
||||
}
|
||||
ApplyMultiDamage( m_pPlayer->pev, m_pPlayer->pev );
|
||||
|
||||
// play thwack, smack, or dong sound
|
||||
float flVol = 1.0;
|
||||
int fHitWorld = TRUE;
|
||||
|
||||
if( pEntity )
|
||||
{
|
||||
if( pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE )
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
}
|
||||
m_pPlayer->m_iWeaponVolume = CROWBAR_BODYHIT_VOLUME;
|
||||
if( !pEntity->IsAlive() )
|
||||
return TRUE;
|
||||
else
|
||||
flVol = 0.1;
|
||||
|
||||
fHitWorld = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// play texture hit sound
|
||||
// UNDONE: Calculate the correct point of intersection when we hit with the hull instead of the line
|
||||
|
||||
if( fHitWorld )
|
||||
{
|
||||
float fvolbar = TEXTURETYPE_PlaySound( &tr, vecSrc, vecSrc + ( vecEnd - vecSrc ) * 2, BULLET_PLAYER_CROWBAR );
|
||||
|
||||
if( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// override the volume here, cause we don't play texture sounds in multiplayer,
|
||||
// and fvolbar is going to be 0 from the above call.
|
||||
|
||||
fvolbar = 1;
|
||||
}
|
||||
|
||||
// also play crowbar strike
|
||||
switch( RANDOM_LONG( 0, 1 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hit1.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG( 0, 3 ) );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hit2.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG( 0, 3 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
// delay the decal a bit
|
||||
m_trHit = tr;
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = flVol * CROWBAR_WALLHIT_VOLUME;
|
||||
#endif
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25;
|
||||
|
||||
SetThink( &CCrowbar::Smack );
|
||||
pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
|
||||
}
|
||||
return fDidHit;
|
||||
}
|
@ -1,585 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
/*
|
||||
|
||||
===== generic grenade.cpp ========================================================
|
||||
|
||||
*/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "soundent.h"
|
||||
#include "decals.h"
|
||||
|
||||
//===================grenade
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade, CGrenade )
|
||||
|
||||
// Grenades flagged with this will be triggered when the owner calls detonateSatchelCharges
|
||||
#define SF_DETONATE 0x0001
|
||||
|
||||
//
|
||||
// Grenade Explode
|
||||
//
|
||||
void CGrenade::Explode( Vector vecSrc, Vector vecAim )
|
||||
{
|
||||
TraceResult tr;
|
||||
UTIL_TraceLine( pev->origin, pev->origin + Vector( 0, 0, -32 ), ignore_monsters, ENT( pev ), & tr );
|
||||
|
||||
Explode( &tr, DMG_BLAST );
|
||||
}
|
||||
|
||||
// UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution.
|
||||
void CGrenade::Explode( TraceResult *pTrace, int bitsDamageType )
|
||||
{
|
||||
float flRndSound;// sound randomizer
|
||||
|
||||
pev->model = iStringNull;//invisible
|
||||
pev->solid = SOLID_NOT;// intangible
|
||||
|
||||
pev->takedamage = DAMAGE_NO;
|
||||
|
||||
// Pull out of the wall a bit
|
||||
if( pTrace->flFraction != 1.0 )
|
||||
{
|
||||
pev->origin = pTrace->vecEndPos + ( pTrace->vecPlaneNormal * ( pev->dmg - 24 ) * 0.6 );
|
||||
}
|
||||
|
||||
int iContents = UTIL_PointContents( pev->origin );
|
||||
|
||||
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
|
||||
WRITE_BYTE( TE_EXPLOSION ); // This makes a dynamic light and the explosion sprites/sound
|
||||
WRITE_COORD( pev->origin.x ); // Send to PAS because of the sound
|
||||
WRITE_COORD( pev->origin.y );
|
||||
WRITE_COORD( pev->origin.z );
|
||||
if( iContents != CONTENTS_WATER )
|
||||
{
|
||||
WRITE_SHORT( g_sModelIndexFireball );
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE_SHORT( g_sModelIndexWExplosion );
|
||||
}
|
||||
WRITE_BYTE( ( pev->dmg - 50 ) * .60 ); // scale * 10
|
||||
WRITE_BYTE( 15 ); // framerate
|
||||
WRITE_BYTE( TE_EXPLFLAG_NONE );
|
||||
MESSAGE_END();
|
||||
|
||||
CSoundEnt::InsertSound( bits_SOUND_COMBAT, pev->origin, NORMAL_EXPLOSION_VOLUME, 3.0 );
|
||||
entvars_t *pevOwner;
|
||||
if( pev->owner )
|
||||
pevOwner = VARS( pev->owner );
|
||||
else
|
||||
pevOwner = NULL;
|
||||
|
||||
pev->owner = NULL; // can't traceline attack owner if this is set
|
||||
|
||||
RadiusDamage( pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType );
|
||||
|
||||
if( RANDOM_FLOAT( 0, 1 ) < 0.5 )
|
||||
{
|
||||
UTIL_DecalTrace( pTrace, DECAL_SCORCH1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_DecalTrace( pTrace, DECAL_SCORCH2 );
|
||||
}
|
||||
|
||||
flRndSound = RANDOM_FLOAT( 0, 1 );
|
||||
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris1.wav", 0.55, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris2.wav", 0.55, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris3.wav", 0.55, ATTN_NORM );
|
||||
break;
|
||||
}
|
||||
|
||||
pev->effects |= EF_NODRAW;
|
||||
SetThink( &CGrenade::Smoke );
|
||||
pev->velocity = g_vecZero;
|
||||
pev->nextthink = gpGlobals->time + 0.3;
|
||||
|
||||
if( iContents != CONTENTS_WATER )
|
||||
{
|
||||
int sparkCount = RANDOM_LONG( 0, 3 );
|
||||
for( int i = 0; i < sparkCount; i++ )
|
||||
Create( "spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
void CGrenade::Smoke( void )
|
||||
{
|
||||
if( UTIL_PointContents( pev->origin ) == CONTENTS_WATER )
|
||||
{
|
||||
UTIL_Bubbles( pev->origin - Vector( 64, 64, 64 ), pev->origin + Vector( 64, 64, 64 ), 100 );
|
||||
}
|
||||
else
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
|
||||
WRITE_BYTE( TE_SMOKE );
|
||||
WRITE_COORD( pev->origin.x );
|
||||
WRITE_COORD( pev->origin.y );
|
||||
WRITE_COORD( pev->origin.z );
|
||||
WRITE_SHORT( g_sModelIndexSmoke );
|
||||
WRITE_BYTE( ( pev->dmg - 50 ) * 0.80 ); // scale * 10
|
||||
WRITE_BYTE( 12 ); // framerate
|
||||
MESSAGE_END();
|
||||
}
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
|
||||
void CGrenade::Killed( entvars_t *pevAttacker, int iGib )
|
||||
{
|
||||
Detonate();
|
||||
}
|
||||
|
||||
// Timed grenade, this think is called when time runs out.
|
||||
void CGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
SetThink( &CGrenade::Detonate );
|
||||
pev->nextthink = gpGlobals->time;
|
||||
}
|
||||
|
||||
void CGrenade::PreDetonate( void )
|
||||
{
|
||||
CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, 400, 0.3 );
|
||||
|
||||
SetThink( &CGrenade::Detonate );
|
||||
pev->nextthink = gpGlobals->time + 1;
|
||||
}
|
||||
|
||||
void CGrenade::Detonate( void )
|
||||
{
|
||||
TraceResult tr;
|
||||
Vector vecSpot;// trace starts here!
|
||||
|
||||
vecSpot = pev->origin + Vector( 0, 0, 8 );
|
||||
UTIL_TraceLine( vecSpot, vecSpot + Vector( 0, 0, -40 ), ignore_monsters, ENT(pev), &tr );
|
||||
|
||||
Explode( &tr, DMG_BLAST );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Contact grenade, explode when it touches something
|
||||
//
|
||||
void CGrenade::ExplodeTouch( CBaseEntity *pOther )
|
||||
{
|
||||
TraceResult tr;
|
||||
Vector vecSpot;// trace starts here!
|
||||
|
||||
pev->enemy = pOther->edict();
|
||||
|
||||
vecSpot = pev->origin - pev->velocity.Normalize() * 32;
|
||||
UTIL_TraceLine( vecSpot, vecSpot + pev->velocity.Normalize() * 64, ignore_monsters, ENT( pev ), &tr );
|
||||
|
||||
Explode( &tr, DMG_BLAST );
|
||||
}
|
||||
|
||||
void CGrenade::DangerSoundThink( void )
|
||||
{
|
||||
if( !IsInWorld() )
|
||||
{
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
|
||||
CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, pev->velocity.Length(), 0.2 );
|
||||
pev->nextthink = gpGlobals->time + 0.2;
|
||||
|
||||
if( pev->waterlevel != 0 )
|
||||
{
|
||||
pev->velocity = pev->velocity * 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
void CGrenade::BounceTouch( CBaseEntity *pOther )
|
||||
{
|
||||
// don't hit the guy that launched this grenade
|
||||
if( pOther->edict() == pev->owner )
|
||||
return;
|
||||
|
||||
// only do damage if we're moving fairly fast
|
||||
if( m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 100 )
|
||||
{
|
||||
entvars_t *pevOwner = VARS( pev->owner );
|
||||
if( pevOwner )
|
||||
{
|
||||
TraceResult tr = UTIL_GetGlobalTrace();
|
||||
ClearMultiDamage();
|
||||
pOther->TraceAttack( pevOwner, 1, gpGlobals->v_forward, &tr, DMG_CLUB );
|
||||
ApplyMultiDamage( pev, pevOwner );
|
||||
}
|
||||
m_flNextAttack = gpGlobals->time + 1.0; // debounce
|
||||
}
|
||||
|
||||
Vector vecTestVelocity;
|
||||
// pev->avelocity = 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 = pev->velocity;
|
||||
vecTestVelocity.z *= 0.45;
|
||||
|
||||
if( !m_fRegisteredSound && vecTestVelocity.Length() <= 60 )
|
||||
{
|
||||
//ALERT( at_console, "Grenade Registered!: %f\n", vecTestVelocity.Length() );
|
||||
|
||||
// grenade is moving really slow. It's probably very close to where it will ultimately stop moving.
|
||||
// go ahead and emit the danger sound.
|
||||
|
||||
// register a radius louder than the explosion, so we make sure everyone gets out of the way
|
||||
CSoundEnt::InsertSound( bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3 );
|
||||
m_fRegisteredSound = TRUE;
|
||||
}
|
||||
|
||||
if( pev->flags & FL_ONGROUND )
|
||||
{
|
||||
// add a bit of static friction
|
||||
pev->velocity = pev->velocity * 0.8;
|
||||
|
||||
pev->sequence = RANDOM_LONG( 1, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// play bounce sound
|
||||
BounceSound();
|
||||
}
|
||||
pev->framerate = pev->velocity.Length() / 200.0;
|
||||
if( pev->framerate > 1.0 )
|
||||
pev->framerate = 1;
|
||||
else if( pev->framerate < 0.5 )
|
||||
pev->framerate = 0;
|
||||
}
|
||||
|
||||
void CGrenade::SlideTouch( CBaseEntity *pOther )
|
||||
{
|
||||
// don't hit the guy that launched this grenade
|
||||
if( pOther->edict() == pev->owner )
|
||||
return;
|
||||
|
||||
// pev->avelocity = Vector( 300, 300, 300 );
|
||||
if( pev->flags & FL_ONGROUND )
|
||||
{
|
||||
// add a bit of static friction
|
||||
pev->velocity = pev->velocity * 0.95;
|
||||
|
||||
if( pev->velocity.x != 0 || pev->velocity.y != 0 )
|
||||
{
|
||||
// maintain sliding sound
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BounceSound();
|
||||
}
|
||||
}
|
||||
|
||||
void CGrenade::BounceSound( void )
|
||||
{
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/grenade_hit1.wav", 0.25, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/grenade_hit2.wav", 0.25, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/grenade_hit3.wav", 0.25, ATTN_NORM );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGrenade::TumbleThink( void )
|
||||
{
|
||||
if( !IsInWorld() )
|
||||
{
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
|
||||
StudioFrameAdvance();
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
if( pev->dmgtime - 1 < gpGlobals->time )
|
||||
{
|
||||
CSoundEnt::InsertSound( bits_SOUND_DANGER, pev->origin + pev->velocity * ( pev->dmgtime - gpGlobals->time ), 400, 0.1 );
|
||||
}
|
||||
|
||||
if( pev->dmgtime <= gpGlobals->time )
|
||||
{
|
||||
SetThink( &CGrenade::Detonate );
|
||||
}
|
||||
if( pev->waterlevel != 0 )
|
||||
{
|
||||
pev->velocity = pev->velocity * 0.5;
|
||||
pev->framerate = 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
void CGrenade::Spawn( void )
|
||||
{
|
||||
pev->movetype = MOVETYPE_BOUNCE;
|
||||
pev->classname = MAKE_STRING( "grenade" );
|
||||
|
||||
pev->solid = SOLID_BBOX;
|
||||
|
||||
SET_MODEL( ENT( pev ), "models/grenade.mdl" );
|
||||
UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ) );
|
||||
|
||||
pev->dmg = 100;
|
||||
m_fRegisteredSound = FALSE;
|
||||
}
|
||||
|
||||
|
||||
CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity )
|
||||
{
|
||||
CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL );
|
||||
pGrenade->Spawn();
|
||||
// contact grenades arc lower
|
||||
pGrenade->pev->gravity = 0.5;// lower gravity since grenade is aerodynamic and engine doesn't know it.
|
||||
UTIL_SetOrigin( pGrenade->pev, vecStart );
|
||||
pGrenade->pev->velocity = vecVelocity;
|
||||
pGrenade->pev->angles = UTIL_VecToAngles( pGrenade->pev->velocity );
|
||||
pGrenade->pev->owner = ENT( pevOwner );
|
||||
|
||||
// make monsters afaid of it while in the air
|
||||
pGrenade->SetThink( &CGrenade::DangerSoundThink );
|
||||
pGrenade->pev->nextthink = gpGlobals->time;
|
||||
|
||||
// Tumble in air
|
||||
pGrenade->pev->avelocity.x = RANDOM_FLOAT( -100, -500 );
|
||||
|
||||
// Explode on contact
|
||||
pGrenade->SetTouch( &CGrenade::ExplodeTouch );
|
||||
|
||||
pGrenade->pev->dmg = gSkillData.plrDmgM203Grenade;
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
CGrenade *CGrenadeRock::ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time )
|
||||
{
|
||||
CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL );
|
||||
pGrenade->Spawn();
|
||||
UTIL_SetOrigin( pGrenade->pev, vecStart );
|
||||
pGrenade->pev->velocity = vecVelocity;
|
||||
pGrenade->pev->angles = UTIL_VecToAngles( pGrenade->pev->velocity );
|
||||
pGrenade->pev->owner = ENT( pevOwner );
|
||||
|
||||
pGrenade->SetTouch( &CGrenadeRock::BounceTouch ); // Bounce if touched
|
||||
|
||||
// Take one second off of the desired detonation time and set the think to PreDetonate. PreDetonate
|
||||
// will insert a DANGER sound into the world sound list and delay detonation for one second so that
|
||||
// the grenade explodes after the exact amount of time specified in the call to ShootTimed().
|
||||
|
||||
pGrenade->pev->dmgtime = gpGlobals->time + time;
|
||||
pGrenade->SetThink( &CGrenade::TumbleThink );
|
||||
pGrenade->pev->nextthink = gpGlobals->time + 0.1;
|
||||
if( time < 0.1 )
|
||||
{
|
||||
pGrenade->pev->nextthink = gpGlobals->time;
|
||||
pGrenade->pev->velocity = Vector( 0, 0, 0 );
|
||||
}
|
||||
|
||||
pGrenade->pev->sequence = RANDOM_LONG( 3, 6 );
|
||||
pGrenade->pev->framerate = 1.0;
|
||||
|
||||
// Tumble through the air
|
||||
// pGrenade->pev->avelocity.x = -400;
|
||||
|
||||
pGrenade->pev->gravity = 0.5;
|
||||
pGrenade->pev->friction = 0.8;
|
||||
|
||||
SET_MODEL( ENT( pGrenade->pev ), "models/w_rock.mdl" );
|
||||
pGrenade->pev->dmg = 100;
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
CGrenade *CGrenade::ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time )
|
||||
{
|
||||
CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL );
|
||||
pGrenade->Spawn();
|
||||
UTIL_SetOrigin( pGrenade->pev, vecStart );
|
||||
pGrenade->pev->velocity = vecVelocity;
|
||||
pGrenade->pev->angles = UTIL_VecToAngles( pGrenade->pev->velocity );
|
||||
pGrenade->pev->owner = ENT( pevOwner );
|
||||
|
||||
pGrenade->SetTouch( &CGrenade::BounceTouch ); // Bounce if touched
|
||||
|
||||
// Take one second off of the desired detonation time and set the think to PreDetonate. PreDetonate
|
||||
// will insert a DANGER sound into the world sound list and delay detonation for one second so that
|
||||
// the grenade explodes after the exact amount of time specified in the call to ShootTimed().
|
||||
|
||||
pGrenade->pev->dmgtime = gpGlobals->time + time;
|
||||
pGrenade->SetThink( &CGrenade::TumbleThink );
|
||||
pGrenade->pev->nextthink = gpGlobals->time + 0.1;
|
||||
if( time < 0.1 )
|
||||
{
|
||||
pGrenade->pev->nextthink = gpGlobals->time;
|
||||
pGrenade->pev->velocity = Vector( 0, 0, 0 );
|
||||
}
|
||||
|
||||
pGrenade->pev->sequence = RANDOM_LONG( 3, 6 );
|
||||
pGrenade->pev->framerate = 1.0;
|
||||
|
||||
// Tumble through the air
|
||||
// pGrenade->pev->avelocity.x = -400;
|
||||
|
||||
pGrenade->pev->gravity = 0.5;
|
||||
pGrenade->pev->friction = 0.8;
|
||||
|
||||
SET_MODEL( ENT( pGrenade->pev ), "models/w_grenade.mdl" );
|
||||
pGrenade->pev->dmg = 100;
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
CGrenade *CGrenade::ShootSatchelCharge( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity )
|
||||
{
|
||||
CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL );
|
||||
pGrenade->pev->movetype = MOVETYPE_BOUNCE;
|
||||
pGrenade->pev->classname = MAKE_STRING( "grenade" );
|
||||
|
||||
pGrenade->pev->solid = SOLID_BBOX;
|
||||
|
||||
SET_MODEL( ENT( pGrenade->pev ), "models/grenade.mdl" ); // Change this to satchel charge model
|
||||
|
||||
UTIL_SetSize( pGrenade->pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ) );
|
||||
|
||||
pGrenade->pev->dmg = 200;
|
||||
UTIL_SetOrigin( pGrenade->pev, vecStart );
|
||||
pGrenade->pev->velocity = vecVelocity;
|
||||
pGrenade->pev->angles = g_vecZero;
|
||||
pGrenade->pev->owner = ENT( pevOwner );
|
||||
|
||||
// Detonate in "time" seconds
|
||||
pGrenade->SetThink( &CBaseEntity::SUB_DoNothing );
|
||||
pGrenade->SetUse( &CGrenade::DetonateUse );
|
||||
pGrenade->SetTouch( &CGrenade::SlideTouch );
|
||||
pGrenade->pev->spawnflags = SF_DETONATE;
|
||||
|
||||
pGrenade->pev->friction = 0.9;
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
void CGrenadeRock::BounceTouch( CBaseEntity *pOther )
|
||||
{
|
||||
// don't hit the guy that launched this grenade
|
||||
if( pOther->edict() == pev->owner )
|
||||
return;
|
||||
|
||||
// only do damage if we're moving fairly fast
|
||||
if( m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 100 )
|
||||
{
|
||||
entvars_t *pevOwner = VARS( pev->owner );
|
||||
if( pevOwner )
|
||||
{
|
||||
TraceResult tr = UTIL_GetGlobalTrace();
|
||||
ClearMultiDamage();
|
||||
pOther->TraceAttack( pevOwner, 10, gpGlobals->v_forward, &tr, DMG_GIBALWAYS );
|
||||
ApplyMultiDamage( pev, pevOwner );
|
||||
}
|
||||
m_flNextAttack = gpGlobals->time + 1.0; // debounce
|
||||
}
|
||||
|
||||
Vector vecTestVelocity;
|
||||
// pev->avelocity = 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 = pev->velocity;
|
||||
vecTestVelocity.z *= 0.45;
|
||||
|
||||
if( !m_fRegisteredSound && vecTestVelocity.Length() <= 60 )
|
||||
{
|
||||
//ALERT( at_console, "Grenade Registered!: %f\n", vecTestVelocity.Length() );
|
||||
|
||||
// grenade is moving really slow. It's probably very close to where it will ultimately stop moving.
|
||||
// go ahead and emit the danger sound.
|
||||
|
||||
// register a radius louder than the explosion, so we make sure everyone gets out of the way
|
||||
CSoundEnt::InsertSound( bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3 );
|
||||
m_fRegisteredSound = TRUE;
|
||||
}
|
||||
|
||||
if( pev->flags & FL_ONGROUND )
|
||||
{
|
||||
// add a bit of static friction
|
||||
pev->velocity = pev->velocity * 0.8;
|
||||
|
||||
pev->sequence = RANDOM_LONG( 1, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// play bounce sound
|
||||
BounceSound();
|
||||
}
|
||||
pev->framerate = pev->velocity.Length() / 200.0;
|
||||
if( pev->framerate > 1.0 )
|
||||
pev->framerate = 1;
|
||||
else if( pev->framerate < 0.5 )
|
||||
pev->framerate = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CGrenade::UseSatchelCharges( entvars_t *pevOwner, SATCHELCODE code )
|
||||
{
|
||||
edict_t *pentFind;
|
||||
edict_t *pentOwner;
|
||||
|
||||
if( !pevOwner )
|
||||
return;
|
||||
|
||||
CBaseEntity *pOwner = CBaseEntity::Instance( pevOwner );
|
||||
|
||||
pentOwner = pOwner->edict();
|
||||
|
||||
pentFind = FIND_ENTITY_BY_CLASSNAME( NULL, "grenade" );
|
||||
while( !FNullEnt( pentFind ) )
|
||||
{
|
||||
CBaseEntity *pEnt = Instance( pentFind );
|
||||
if( pEnt )
|
||||
{
|
||||
if( FBitSet( pEnt->pev->spawnflags, SF_DETONATE ) && pEnt->pev->owner == pentOwner )
|
||||
{
|
||||
if( code == SATCHEL_DETONATE )
|
||||
pEnt->Use( pOwner, pOwner, USE_ON, 0 );
|
||||
else // SATCHEL_RELEASE
|
||||
pEnt->pev->owner = NULL;
|
||||
}
|
||||
}
|
||||
pentFind = FIND_ENTITY_BY_CLASSNAME( pentFind, "grenade" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//======================end grenade
|
@ -1,213 +0,0 @@
|
||||
/*
|
||||
Здесь был rainbow
|
||||
*/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
|
||||
#define HANDGRENADE_PRIMARY_VOLUME 450
|
||||
|
||||
enum handgrenade_e
|
||||
{
|
||||
HANDGRENADE_IDLE = 0,
|
||||
HANDGRENADE_FIDGET,
|
||||
HANDGRENADE_PINPULL,
|
||||
HANDGRENADE_THROW1, // toss
|
||||
HANDGRENADE_THROW2, // medium
|
||||
HANDGRENADE_THROW3, // hard
|
||||
HANDGRENADE_HOLSTER,
|
||||
HANDGRENADE_DRAW
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_handgrenade, CHandGrenade )
|
||||
|
||||
void CHandGrenade::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_HANDGRENADE;
|
||||
SET_MODEL( ENT( pev ), "models/w_grenade.mdl" );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
pev->dmg = gSkillData.plrDmgHandGrenade;
|
||||
#endif
|
||||
m_iDefaultAmmo = HANDGRENADE_DEFAULT_GIVE;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
void CHandGrenade::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/w_grenade.mdl" );
|
||||
PRECACHE_MODEL( "models/v_grenade.mdl" );
|
||||
PRECACHE_MODEL( "models/p_grenade.mdl" );
|
||||
}
|
||||
|
||||
int CHandGrenade::GetItemInfo( ItemInfo *p )
|
||||
{
|
||||
p->pszName = STRING( pev->classname );
|
||||
p->pszAmmo1 = "Hand Grenade";
|
||||
p->iMaxAmmo1 = HANDGRENADE_MAX_CARRY;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = WEAPON_NOCLIP;
|
||||
p->iSlot = 4;
|
||||
p->iPosition = 0;
|
||||
p->iId = m_iId = WEAPON_HANDGRENADE;
|
||||
p->iWeight = HANDGRENADE_WEIGHT;
|
||||
p->iFlags = ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CHandGrenade::Deploy()
|
||||
{
|
||||
m_flReleaseThrow = -1;
|
||||
return DefaultDeploy( "models/v_grenade.mdl", "models/p_grenade.mdl", HANDGRENADE_DRAW, "crowbar" );
|
||||
}
|
||||
|
||||
BOOL CHandGrenade::CanHolster( void )
|
||||
{
|
||||
// can only holster hand grenades when not primed!
|
||||
return ( m_flStartThrow == 0 );
|
||||
}
|
||||
|
||||
void CHandGrenade::Holster( int skiplocal /* = 0 */ )
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_HOLSTER );
|
||||
}
|
||||
else
|
||||
{
|
||||
// no more grenades!
|
||||
m_pPlayer->pev->weapons &= ~( 1 << WEAPON_HANDGRENADE );
|
||||
SetThink( &CBasePlayerItem::DestroyItem );
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "common/null.wav", 1.0, ATTN_NORM );
|
||||
}
|
||||
|
||||
void CHandGrenade::PrimaryAttack()
|
||||
{
|
||||
if( !m_flStartThrow && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0 )
|
||||
{
|
||||
m_flStartThrow = gpGlobals->time;
|
||||
m_flReleaseThrow = 0;
|
||||
|
||||
SendWeaponAnim( HANDGRENADE_PINPULL );
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
void CHandGrenade::WeaponIdle( void )
|
||||
{
|
||||
if( m_flReleaseThrow == 0 && m_flStartThrow )
|
||||
m_flReleaseThrow = gpGlobals->time;
|
||||
|
||||
if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
|
||||
return;
|
||||
|
||||
if( m_flStartThrow )
|
||||
{
|
||||
Vector angThrow = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
|
||||
|
||||
if( angThrow.x < 0 )
|
||||
angThrow.x = -10 + angThrow.x * ( ( 90 - 10 ) / 90.0 );
|
||||
else
|
||||
angThrow.x = -10 + angThrow.x * ( ( 90 + 10 ) / 90.0 );
|
||||
|
||||
float flVel = ( 90 - angThrow.x ) * 4;
|
||||
if( flVel > 500 )
|
||||
flVel = 500;
|
||||
|
||||
UTIL_MakeVectors( angThrow );
|
||||
|
||||
Vector vecSrc = m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 16;
|
||||
|
||||
Vector vecThrow = gpGlobals->v_forward * flVel + m_pPlayer->pev->velocity;
|
||||
|
||||
// alway explode 3 seconds after the pin was pulled
|
||||
float time = m_flStartThrow - gpGlobals->time + 3.0;
|
||||
if( time < 0 )
|
||||
time = 0;
|
||||
|
||||
CGrenade::ShootTimed( m_pPlayer->pev, vecSrc, vecThrow, time );
|
||||
|
||||
if( flVel < 500 )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_THROW1 );
|
||||
}
|
||||
else if( flVel < 1000 )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_THROW2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_THROW3 );
|
||||
}
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
m_flReleaseThrow = 0;
|
||||
m_flStartThrow = 0;
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
|
||||
|
||||
if( !m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
// just threw last grenade
|
||||
// set attack times in the future, and weapon idle in the future so we can see the whole throw
|
||||
// animation, weapon idle will automatically retire the weapon for us.
|
||||
m_flTimeWeaponIdle = m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;// ensure that the animation can finish playing
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if( m_flReleaseThrow > 0 )
|
||||
{
|
||||
// we've finished the throw, restart.
|
||||
m_flStartThrow = 0;
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_DRAW );
|
||||
}
|
||||
else
|
||||
{
|
||||
RetireWeapon();
|
||||
return;
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
|
||||
m_flReleaseThrow = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 );
|
||||
if( flRand <= 0.75 )
|
||||
{
|
||||
iAnim = HANDGRENADE_IDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );// how long till we do this again.
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = HANDGRENADE_FIDGET;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 75.0 / 30.0;
|
||||
}
|
||||
|
||||
SendWeaponAnim( iAnim );
|
||||
}
|
||||
}
|
307
dlls/katana.cpp~
307
dlls/katana.cpp~
@ -1,307 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
#include "gamerules.h"
|
||||
|
||||
#define CROWBAR_BODYHIT_VOLUME 128
|
||||
#define CROWBAR_WALLHIT_VOLUME 512
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_katana, CKatana )
|
||||
|
||||
enum gauss_e
|
||||
{
|
||||
CROWBAR_IDLE = 0,
|
||||
CROWBAR_DRAW,
|
||||
CROWBAR_HOLSTER,
|
||||
CROWBAR_ATTACK1HIT,
|
||||
CROWBAR_ATTACK1MISS,
|
||||
CROWBAR_ATTACK2MISS,
|
||||
CROWBAR_ATTACK2HIT,
|
||||
CROWBAR_ATTACK3MISS,
|
||||
CROWBAR_ATTACK3HIT
|
||||
};
|
||||
|
||||
|
||||
void CKatana::Spawn( )
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_KATANA;
|
||||
SET_MODEL( ENT( pev ), "models/w_katana.mdl" );
|
||||
m_iClip = -1;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
void CKatana::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/v_katana.mdl" );
|
||||
PRECACHE_MODEL( "models/w_katana.mdl" );
|
||||
PRECACHE_MODEL( "models/p_katana.mdl" );
|
||||
PRECACHE_SOUND( "weapons/katana_hit1.wav" );
|
||||
PRECACHE_SOUND( "weapons/katana_hit2.wav" );
|
||||
PRECACHE_SOUND( "weapons/katana_hitbod1.wav" );
|
||||
PRECACHE_SOUND( "weapons/katana_hitbod2.wav" );
|
||||
PRECACHE_SOUND( "weapons/katana_hitbod3.wav" );
|
||||
PRECACHE_SOUND( "weapons/katana_miss1.wav" );
|
||||
|
||||
|
||||
m_usKatana = PRECACHE_EVENT( 1, "events/crowbar.sc" );
|
||||
}
|
||||
|
||||
int CKatana::GetItemInfo( ItemInfo *p )
|
||||
{
|
||||
p->pszName = STRING( pev->classname );
|
||||
p->pszAmmo1 = NULL;
|
||||
p->iMaxAmmo1 = -1;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = WEAPON_NOCLIP;
|
||||
p->iSlot = 0;
|
||||
p->iPosition = 1;
|
||||
p->iId = WEAPON_KATANA;
|
||||
p->iWeight = CROWBAR_WEIGHT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CKatana::Deploy()
|
||||
{
|
||||
return DefaultDeploy( "models/v_katana.mdl", "models/p_katana.mdl", CROWBAR_DRAW, "katana" );
|
||||
}
|
||||
|
||||
void CKatana::Holster( int skiplocal /* = 0 */ )
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
SendWeaponAnim( CROWBAR_HOLSTER );
|
||||
}
|
||||
|
||||
void FindHullIntersection3( const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity )
|
||||
{
|
||||
int i, j, k;
|
||||
float distance;
|
||||
float *minmaxs[2] = {mins, maxs};
|
||||
TraceResult tmpTrace;
|
||||
Vector vecHullEnd = tr.vecEndPos;
|
||||
Vector vecEnd;
|
||||
|
||||
distance = 1e6f;
|
||||
|
||||
vecHullEnd = vecSrc + ( ( vecHullEnd - vecSrc ) * 2 );
|
||||
UTIL_TraceLine( vecSrc, vecHullEnd, dont_ignore_monsters, pEntity, &tmpTrace );
|
||||
if( tmpTrace.flFraction < 1.0 )
|
||||
{
|
||||
tr = tmpTrace;
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
for( k = 0; k < 2; k++ )
|
||||
{
|
||||
vecEnd.x = vecHullEnd.x + minmaxs[i][0];
|
||||
vecEnd.y = vecHullEnd.y + minmaxs[j][1];
|
||||
vecEnd.z = vecHullEnd.z + minmaxs[k][2];
|
||||
|
||||
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, pEntity, &tmpTrace );
|
||||
if( tmpTrace.flFraction < 1.0 )
|
||||
{
|
||||
float thisDistance = ( tmpTrace.vecEndPos - vecSrc ).Length();
|
||||
if( thisDistance < distance )
|
||||
{
|
||||
tr = tmpTrace;
|
||||
distance = thisDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CKatana::PrimaryAttack()
|
||||
{
|
||||
if( !Swing( 1 ) )
|
||||
{
|
||||
SetThink( &CKatana::SwingAgain );
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
void CKatana::Smack()
|
||||
{
|
||||
DecalGunshot( &m_trHit, BULLET_PLAYER_CROWBAR );
|
||||
}
|
||||
|
||||
void CKatana::SwingAgain( void )
|
||||
{
|
||||
Swing( 0 );
|
||||
}
|
||||
|
||||
int CKatana::Swing( int fFirst )
|
||||
{
|
||||
int fDidHit = FALSE;
|
||||
|
||||
TraceResult tr;
|
||||
|
||||
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition();
|
||||
Vector vecEnd = vecSrc + gpGlobals->v_forward * 32;
|
||||
|
||||
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
if( tr.flFraction >= 1.0 )
|
||||
{
|
||||
UTIL_TraceHull( vecSrc, vecEnd, dont_ignore_monsters, head_hull, ENT( m_pPlayer->pev ), &tr );
|
||||
if( tr.flFraction < 1.0 )
|
||||
{
|
||||
// Calculate the point of intersection of the line (or hull) and the object we hit
|
||||
// This is and approximation of the "best" intersection
|
||||
CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
|
||||
if( !pHit || pHit->IsBSPModel() )
|
||||
FindHullIntersection3( vecSrc, tr, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX, m_pPlayer->edict() );
|
||||
vecEnd = tr.vecEndPos; // This is the point on the actual surface (the hull could have hit space)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usKatana,
|
||||
0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0,
|
||||
0.0, 0, 0.0 );
|
||||
|
||||
if( tr.flFraction >= 1.0 )
|
||||
{
|
||||
if( fFirst )
|
||||
{
|
||||
// miss
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( ( ( m_iSwing++ ) % 2 ) + 1 )
|
||||
{
|
||||
case 0:
|
||||
SendWeaponAnim( CROWBAR_ATTACK1HIT );
|
||||
break;
|
||||
case 1:
|
||||
SendWeaponAnim( CROWBAR_ATTACK2HIT );
|
||||
break;
|
||||
case 2:
|
||||
SendWeaponAnim( CROWBAR_ATTACK3HIT );
|
||||
break;
|
||||
}
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// hit
|
||||
fDidHit = TRUE;
|
||||
CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit );
|
||||
|
||||
ClearMultiDamage();
|
||||
|
||||
if( ( m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// first swing does full damage
|
||||
pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB );
|
||||
}
|
||||
else
|
||||
{
|
||||
// subsequent swings do half
|
||||
pEntity->TraceAttack( m_pPlayer->pev, 30, gpGlobals->v_forward, &tr, DMG_CLUB );
|
||||
}
|
||||
ApplyMultiDamage( m_pPlayer->pev, m_pPlayer->pev );
|
||||
|
||||
// play thwack, smack, or dong sound
|
||||
float flVol = 1.0;
|
||||
int fHitWorld = TRUE;
|
||||
|
||||
if( pEntity )
|
||||
{
|
||||
if( pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE )
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/katana_hitbod1.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/katana_hitbod2.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/katana_hitbod3.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
}
|
||||
m_pPlayer->m_iWeaponVolume = CROWBAR_BODYHIT_VOLUME;
|
||||
if( !pEntity->IsAlive() )
|
||||
return TRUE;
|
||||
else
|
||||
flVol = 0.1;
|
||||
|
||||
fHitWorld = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// play texture hit sound
|
||||
// UNDONE: Calculate the correct point of intersection when we hit with the hull instead of the line
|
||||
|
||||
if( fHitWorld )
|
||||
{
|
||||
float fvolbar = TEXTURETYPE_PlaySound( &tr, vecSrc, vecSrc + ( vecEnd - vecSrc ) * 2, BULLET_PLAYER_CROWBAR );
|
||||
|
||||
if( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// override the volume here, cause we don't play texture sounds in multiplayer,
|
||||
// and fvolbar is going to be 0 from the above call.
|
||||
|
||||
fvolbar = 1;
|
||||
}
|
||||
|
||||
// also play crowbar strike
|
||||
switch( RANDOM_LONG( 0, 1 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/katana_hit1.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG( 0, 3 ) );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/katana_hit2.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG( 0, 3 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
// delay the decal a bit
|
||||
m_trHit = tr;
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = flVol * CROWBAR_WALLHIT_VOLUME;
|
||||
#endif
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25;
|
||||
|
||||
SetThink( &CKatana::Smack );
|
||||
pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
|
||||
}
|
||||
return fDidHit;
|
||||
}
|
271
dlls/knife.cpp~
271
dlls/knife.cpp~
@ -1,271 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
#include "gamerules.h"
|
||||
|
||||
void FindHullIntersection(const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity);
|
||||
|
||||
#define KNIFE_BODYHIT_VOLUME 128
|
||||
#define KNIFE_WALLHIT_VOLUME 512
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_knife, CKnife);
|
||||
|
||||
enum knife_e {
|
||||
KNIFE_IDLE1 = 0,
|
||||
KNIFE_DRAW,
|
||||
KNIFE_HOLSTER,
|
||||
KNIFE_ATTACK1HIT,
|
||||
KNIFE_ATTACK1MISS,
|
||||
KNIFE_ATTACK2MISS,
|
||||
KNIFE_ATTACK2HIT,
|
||||
KNIFE_ATTACK3MISS,
|
||||
KNIFE_ATTACK3HIT,
|
||||
KNIFE_IDLE2,
|
||||
KNIFE_IDLE3,
|
||||
KNIFE_CHARGE,
|
||||
KNIFE_STAB,
|
||||
};
|
||||
|
||||
|
||||
void CKnife::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_KNIFE;
|
||||
SET_MODEL(ENT(pev), "models/w_knife.mdl");
|
||||
m_iClip = -1;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
||||
void CKnife::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_knife.mdl");
|
||||
PRECACHE_MODEL("models/w_knife.mdl");
|
||||
PRECACHE_MODEL("models/p_knife.mdl");
|
||||
PRECACHE_SOUND("weapons/knife_hit_flesh1.wav");
|
||||
PRECACHE_SOUND("weapons/knife_hit_flesh2.wav");
|
||||
PRECACHE_SOUND("weapons/knife_hit_wall1.wav");
|
||||
PRECACHE_SOUND("weapons/knife_hit_wall2.wav");
|
||||
PRECACHE_SOUND("weapons/knife1.wav");
|
||||
PRECACHE_SOUND("weapons/knife2.wav");
|
||||
PRECACHE_SOUND("weapons/knife3.wav");
|
||||
|
||||
m_usKnife = PRECACHE_EVENT(1, "events/knife.sc");
|
||||
}
|
||||
|
||||
int CKnife::GetItemInfo(ItemInfo *p)
|
||||
{
|
||||
p->pszName = STRING(pev->classname);
|
||||
p->pszAmmo1 = NULL;
|
||||
p->iMaxAmmo1 = -1;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = WEAPON_NOCLIP;
|
||||
p->iSlot = 0;
|
||||
p->iPosition = 2;
|
||||
p->iId = WEAPON_KNIFE;
|
||||
p->iWeight = KNIFE_WEIGHT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL CKnife::Deploy()
|
||||
{
|
||||
return DefaultDeploy("models/v_knife.mdl", "models/p_knife.mdl", KNIFE_DRAW, "knife");
|
||||
}
|
||||
|
||||
void CKnife::Holster(int skiplocal /* = 0 */)
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
SendWeaponAnim(KNIFE_HOLSTER);
|
||||
}
|
||||
|
||||
void CKnife::PrimaryAttack()
|
||||
{
|
||||
if (!Swing(1))
|
||||
{
|
||||
SetThink(&CKnife::SwingAgain);
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CKnife::Smack()
|
||||
{
|
||||
DecalGunshot(&m_trHit, BULLET_PLAYER_CROWBAR);
|
||||
}
|
||||
|
||||
|
||||
void CKnife::SwingAgain(void)
|
||||
{
|
||||
Swing(0);
|
||||
}
|
||||
|
||||
|
||||
int CKnife::Swing(int fFirst)
|
||||
{
|
||||
int fDidHit = FALSE;
|
||||
|
||||
TraceResult tr;
|
||||
|
||||
UTIL_MakeVectors(m_pPlayer->pev->v_angle);
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition();
|
||||
Vector vecEnd = vecSrc + gpGlobals->v_forward * 32;
|
||||
|
||||
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr);
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
if (tr.flFraction >= 1.0)
|
||||
{
|
||||
UTIL_TraceHull(vecSrc, vecEnd, dont_ignore_monsters, head_hull, ENT(m_pPlayer->pev), &tr);
|
||||
if (tr.flFraction < 1.0)
|
||||
{
|
||||
// Calculate the point of intersection of the line (or hull) and the object we hit
|
||||
// This is and approximation of the "best" intersection
|
||||
CBaseEntity *pHit = CBaseEntity::Instance(tr.pHit);
|
||||
if (!pHit || pHit->IsBSPModel())
|
||||
FindHullIntersection(vecSrc, tr, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX, m_pPlayer->edict());
|
||||
vecEnd = tr.vecEndPos; // This is the point on the actual surface (the hull could have hit space)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PLAYBACK_EVENT_FULL(FEV_NOTHOST, m_pPlayer->edict(), m_usKnife,
|
||||
0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0,
|
||||
0.0, 0, 0.0);
|
||||
|
||||
|
||||
if (tr.flFraction >= 1.0)
|
||||
{
|
||||
if (fFirst)
|
||||
{
|
||||
// miss
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.5);
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (((m_iSwing++) % 2) + 1)
|
||||
{
|
||||
case 0:
|
||||
SendWeaponAnim(KNIFE_ATTACK1HIT); break;
|
||||
case 1:
|
||||
SendWeaponAnim(KNIFE_ATTACK2HIT); break;
|
||||
case 2:
|
||||
SendWeaponAnim(KNIFE_ATTACK3HIT); break;
|
||||
}
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
// hit
|
||||
fDidHit = TRUE;
|
||||
CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
|
||||
|
||||
ClearMultiDamage();
|
||||
|
||||
if ((m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase()) || g_pGameRules->IsMultiplayer())
|
||||
{
|
||||
// first swing does full damage
|
||||
pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgKnife, gpGlobals->v_forward, &tr, DMG_CLUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
// subsequent swings do half
|
||||
pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgKnife / 2, gpGlobals->v_forward, &tr, DMG_CLUB);
|
||||
}
|
||||
ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev);
|
||||
|
||||
// play thwack, smack, or dong sound
|
||||
float flVol = 1.0;
|
||||
int fHitWorld = TRUE;
|
||||
|
||||
if (pEntity)
|
||||
{
|
||||
if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE)
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch (RANDOM_LONG(0, 1))
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/knife_hit_flesh1.wav", 1, ATTN_NORM); break;
|
||||
case 1:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/knife_hit_flesh2.wav", 1, ATTN_NORM); break;
|
||||
}
|
||||
m_pPlayer->m_iWeaponVolume = KNIFE_BODYHIT_VOLUME;
|
||||
if (!pEntity->IsAlive())
|
||||
return TRUE;
|
||||
else
|
||||
flVol = 0.1;
|
||||
|
||||
fHitWorld = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// play texture hit sound
|
||||
// UNDONE: Calculate the correct point of intersection when we hit with the hull instead of the line
|
||||
|
||||
if (fHitWorld)
|
||||
{
|
||||
float fvolbar = TEXTURETYPE_PlaySound(&tr, vecSrc, vecSrc + (vecEnd - vecSrc) * 2, BULLET_PLAYER_CROWBAR);
|
||||
|
||||
if (g_pGameRules->IsMultiplayer())
|
||||
{
|
||||
// override the volume here, cause we don't play texture sounds in multiplayer,
|
||||
// and fvolbar is going to be 0 from the above call.
|
||||
|
||||
fvolbar = 1;
|
||||
}
|
||||
|
||||
// also play crowbar strike
|
||||
switch (RANDOM_LONG(0, 1))
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/knife_hit_wall1.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0, 3));
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/knife_hit_wall2.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0, 3));
|
||||
break;
|
||||
}
|
||||
|
||||
// delay the decal a bit
|
||||
m_trHit = tr;
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = flVol * KNIFE_WALLHIT_VOLUME;
|
||||
#endif
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.25);
|
||||
|
||||
SetThink(&CKnife::Smack);
|
||||
pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
|
||||
|
||||
|
||||
}
|
||||
return fDidHit;
|
||||
}
|
@ -1,205 +0,0 @@
|
||||
/*
|
||||
Здесь был rainbow
|
||||
*/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
|
||||
#define HANDGRENADE_PRIMARY_VOLUME 450
|
||||
|
||||
enum handgrenade_e
|
||||
{
|
||||
HANDGRENADE_IDLE = 0,
|
||||
HANDGRENADE_FIRE,
|
||||
HANDGRENADE_OPEN,
|
||||
HANDGRENADE_INSERT,
|
||||
HANDGRENADE_CLOSE,
|
||||
HANDGRENADE_DRAW
|
||||
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_pepsigun, CPepsigun )
|
||||
LINK_ENTITY_TO_CLASS( ammo_pepsi, CPepsigun )
|
||||
|
||||
void CPepsigun::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_PEPSIGUN;
|
||||
SET_MODEL( ENT( pev ), "models/w_pepsigun.mdl" );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
pev->dmg = 80;
|
||||
#endif
|
||||
m_iDefaultAmmo = 10000;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
void CPepsigun::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/w_pepsigun.mdl" );
|
||||
PRECACHE_MODEL( "models/v_pepsigun.mdl" );
|
||||
PRECACHE_MODEL( "models/p_pepsigun.mdl" );
|
||||
}
|
||||
|
||||
int CPepsigun::GetItemInfo( ItemInfo *p )
|
||||
{
|
||||
p->pszName = STRING( pev->classname );
|
||||
p->pszAmmo1 = "pepsi";
|
||||
p->iMaxAmmo1 = 20000;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = -1;
|
||||
p->iSlot = 2;
|
||||
p->iPosition = 4;
|
||||
p->iId = m_iId = WEAPON_PEPSIGUN;
|
||||
p->iWeight = PEPSIGUN_WEIGHT;
|
||||
p->iFlags = ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CPepsigun::Deploy()
|
||||
{
|
||||
m_flReleaseThrow = -1;
|
||||
return DefaultDeploy( "models/v_pepsigun.mdl", "models/p_pepsigun.mdl", HANDGRENADE_DRAW, "crowbar" );
|
||||
}
|
||||
|
||||
BOOL CPepsigun::CanHolster( void )
|
||||
{
|
||||
// can only holster hand grenades when not primed!
|
||||
return ( m_flStartThrow == 0 );
|
||||
}
|
||||
|
||||
void CPepsigun::Holster( int skiplocal /* = 0 */ )
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// no more grenades!
|
||||
m_pPlayer->pev->weapons &= ~( 1 << WEAPON_PEPSIGUN );
|
||||
SetThink( &CBasePlayerItem::DestroyItem );
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "common/null.wav", 1.0, ATTN_NORM );
|
||||
}
|
||||
|
||||
void CPepsigun::PrimaryAttack()
|
||||
{
|
||||
m_flStartThrow = gpGlobals->time;
|
||||
m_flReleaseThrow = 0;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.25;
|
||||
}
|
||||
|
||||
void CPepsigun::WeaponIdle( void )
|
||||
{
|
||||
if( m_flReleaseThrow == 0 && m_flStartThrow )
|
||||
m_flReleaseThrow = gpGlobals->time;
|
||||
|
||||
if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
|
||||
return;
|
||||
|
||||
if( m_flStartThrow )
|
||||
{
|
||||
Vector angThrow = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
|
||||
|
||||
if( angThrow.x < 0 )
|
||||
angThrow.x = -10 + angThrow.x * ( ( 90 - 10 ) / 90.0 );
|
||||
else
|
||||
angThrow.x = -10 + angThrow.x * ( ( 90 + 10 ) / 90.0 );
|
||||
|
||||
float flVel = ( 90 - angThrow.x ) * 4;
|
||||
if( flVel > 500 )
|
||||
flVel = 1400;
|
||||
|
||||
UTIL_MakeVectors( angThrow );
|
||||
|
||||
Vector vecSrc = m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 16;
|
||||
|
||||
Vector vecThrow = gpGlobals->v_forward * flVel + m_pPlayer->pev->velocity;
|
||||
|
||||
// alway explode 3 seconds after the pin was pulled
|
||||
float time = m_flStartThrow - gpGlobals->time + 3.0;
|
||||
if( time < 0 )
|
||||
time = 0;
|
||||
|
||||
CGrenade::ShootTimed( m_pPlayer->pev, vecSrc, vecThrow, time );
|
||||
|
||||
if( flVel < 500 )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_FIRE );
|
||||
}
|
||||
else if( flVel < 1000 )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_FIRE );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_FIRE );
|
||||
}
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
m_flReleaseThrow = 0;
|
||||
m_flStartThrow = 0;
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
|
||||
if( !m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
// just threw last grenade
|
||||
// set attack times in the future, and weapon idle in the future so we can see the whole throw
|
||||
// animation, weapon idle will automatically retire the weapon for us.
|
||||
m_flTimeWeaponIdle = m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;// ensure that the animation can finish playing
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if( m_flReleaseThrow > 0 )
|
||||
{
|
||||
// we've finished the throw, restart.
|
||||
m_flStartThrow = 0;
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_DRAW );
|
||||
}
|
||||
else
|
||||
{
|
||||
RetireWeapon();
|
||||
return;
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
|
||||
m_flReleaseThrow = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 );
|
||||
if( flRand <= 0.75 )
|
||||
{
|
||||
iAnim = HANDGRENADE_IDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );// how long till we do this again.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 75.0 / 30.0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
211
dlls/rock.cpp~
211
dlls/rock.cpp~
@ -1,211 +0,0 @@
|
||||
/*
|
||||
Здесь был rainbow
|
||||
*/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
|
||||
#define HANDGRENADE_PRIMARY_VOLUME 450
|
||||
|
||||
enum handgrenade_e
|
||||
{
|
||||
HANDGRENADE_IDLE = 0,
|
||||
HANDGRENADE_THROW2,
|
||||
HANDGRENADE_DRAW,
|
||||
HANDGRENADE_FIDGET
|
||||
|
||||
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_rock, CRock )
|
||||
|
||||
void CRock::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_ROCK;
|
||||
SET_MODEL( ENT( pev ), "models/w_rock.mdl" );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
pev->dmg = 40;
|
||||
#endif
|
||||
m_iDefaultAmmo = 10000000;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
void CRock::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/w_rock.mdl" );
|
||||
PRECACHE_MODEL( "models/v_rock.mdl" );
|
||||
PRECACHE_MODEL( "models/p_rock.mdl" );
|
||||
}
|
||||
|
||||
int CRock::GetItemInfo( ItemInfo *p )
|
||||
{
|
||||
p->pszName = STRING( pev->classname );
|
||||
p->pszAmmo1 = "Hand Grenade";
|
||||
p->iMaxAmmo1 = 10000000000000;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = WEAPON_NOCLIP;
|
||||
p->iSlot = 4;
|
||||
p->iPosition = 4;
|
||||
p->iId = m_iId = WEAPON_ROCK;
|
||||
p->iWeight = HANDGRENADE_WEIGHT;
|
||||
p->iFlags = ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CRock::Deploy()
|
||||
{
|
||||
m_flReleaseThrow = -1;
|
||||
return DefaultDeploy( "models/v_rock.mdl", "models/p_rock.mdl", HANDGRENADE_DRAW, "crowbar" );
|
||||
}
|
||||
|
||||
BOOL CRock::CanHolster( void )
|
||||
{
|
||||
// can only holster hand grenades when not primed!
|
||||
return ( m_flStartThrow == 0 );
|
||||
}
|
||||
|
||||
void CRock::Holster( int skiplocal /* = 0 */ )
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
// no more grenades!
|
||||
m_pPlayer->pev->weapons &= ~( 1 << WEAPON_HANDGRENADE );
|
||||
SetThink( &CBasePlayerItem::DestroyItem );
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "common/null.wav", 1.0, ATTN_NORM );
|
||||
}
|
||||
|
||||
void CRock::PrimaryAttack()
|
||||
{
|
||||
if( !m_flStartThrow && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0 )
|
||||
{
|
||||
m_flStartThrow = gpGlobals->time;
|
||||
m_flReleaseThrow = 0;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
void CRock::WeaponIdle( void )
|
||||
{
|
||||
if( m_flReleaseThrow == 0 && m_flStartThrow )
|
||||
m_flReleaseThrow = gpGlobals->time;
|
||||
|
||||
if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
|
||||
return;
|
||||
|
||||
if( m_flStartThrow )
|
||||
{
|
||||
Vector angThrow = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
|
||||
|
||||
if( angThrow.x < 0 )
|
||||
angThrow.x = -10 + angThrow.x * ( ( 90 - 10 ) / 90.0 );
|
||||
else
|
||||
angThrow.x = -10 + angThrow.x * ( ( 90 + 10 ) / 90.0 );
|
||||
|
||||
float flVel = ( 90 - angThrow.x ) * 4;
|
||||
if( flVel > 500 )
|
||||
flVel = 1300;
|
||||
|
||||
UTIL_MakeVectors( angThrow );
|
||||
|
||||
Vector vecSrc = m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 16;
|
||||
|
||||
Vector vecThrow = gpGlobals->v_forward * flVel + m_pPlayer->pev->velocity;
|
||||
|
||||
// alway explode 3 seconds after the pin was pulled
|
||||
float time = m_flStartThrow - gpGlobals->time + 3000000000;
|
||||
if( time < 0 )
|
||||
time = 0;
|
||||
|
||||
|
||||
CGrenadeRock::ShootTimed( m_pPlayer->pev, vecSrc, vecThrow, time );
|
||||
|
||||
|
||||
if( flVel < 500 )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_THROW2 );
|
||||
}
|
||||
else if( flVel < 1000 )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_THROW2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_THROW2 );
|
||||
}
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
m_flReleaseThrow = 0;
|
||||
m_flStartThrow = 0;
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
|
||||
|
||||
if( !m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
// just threw last grenade
|
||||
// set attack times in the future, and weapon idle in the future so we can see the whole throw
|
||||
// animation, weapon idle will automatically retire the weapon for us.
|
||||
m_flTimeWeaponIdle = m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;// ensure that the animation can finish playing
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if( m_flReleaseThrow > 0 )
|
||||
{
|
||||
// we've finished the throw, restart.
|
||||
m_flStartThrow = 0;
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
SendWeaponAnim( HANDGRENADE_DRAW );
|
||||
}
|
||||
else
|
||||
{
|
||||
RetireWeapon();
|
||||
return;
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
|
||||
m_flReleaseThrow = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 20 );
|
||||
if( flRand <= 0.75 )
|
||||
{
|
||||
iAnim = HANDGRENADE_IDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );// how long till we do this again.
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = HANDGRENADE_FIDGET;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 75.0 / 30.0;
|
||||
}
|
||||
|
||||
SendWeaponAnim( iAnim );
|
||||
}
|
||||
}
|
@ -1,351 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
#include "gamerules.h"
|
||||
|
||||
// special deathmatch shotgun spreads
|
||||
#define VECTOR_CONE_DM_SAWNOFF Vector( 1, 0.9, 0.00 )// 10 degrees by 5 degrees
|
||||
#define VECTOR_CONE_DM_DOUBLESAWNOFF Vector( 1, 0.9, 0.00 ) // 20 degrees by 5 degre
|
||||
|
||||
enum sawnoff_e
|
||||
{
|
||||
SAWNOFF_IDLE = 0,
|
||||
SAWNOFF_FIRE,
|
||||
SAWNOFF_FIRE2,
|
||||
SAWNOFF_RELOAD,
|
||||
SAWNOFF_PUMP,
|
||||
SAWNOFF_START_RELOAD,
|
||||
SAWNOFF_DRAW,
|
||||
SAWNOFF_HOLSTER,
|
||||
SAWNOFF_IDLE4,
|
||||
SAWNOFF_IDLE_DEEP
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_sawnoff, CSawnoff )
|
||||
|
||||
void CSawnoff::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_SAWNOFF;
|
||||
SET_MODEL( ENT( pev ), "models/w_sawnoff.mdl" );
|
||||
|
||||
m_iDefaultAmmo = SAWNOFF_DEFAULT_GIVE;
|
||||
|
||||
FallInit();// get ready to fall
|
||||
}
|
||||
|
||||
void CSawnoff::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/v_sawnoff.mdl" );
|
||||
PRECACHE_MODEL( "models/w_sawnoff.mdl" );
|
||||
PRECACHE_MODEL( "models/p_sawnoff.mdl" );
|
||||
|
||||
m_iShell = PRECACHE_MODEL( "models/shotgunshell.mdl" );// shotgun shell
|
||||
|
||||
PRECACHE_SOUND( "items/9mmclip1.wav" );
|
||||
|
||||
PRECACHE_SOUND( "weapons/dbarrel1.wav" );//shotgun
|
||||
PRECACHE_SOUND( "weapons/sbarrel1.wav" );//shotgun
|
||||
|
||||
PRECACHE_SOUND( "weapons/reload1.wav" ); // shotgun reload
|
||||
PRECACHE_SOUND( "weapons/reload3.wav" ); // shotgun reload
|
||||
|
||||
//PRECACHE_SOUND( "weapons/sshell1.wav" ); // shotgun reload - played on client
|
||||
//PRECACHE_SOUND( "weapons/sshell3.wav" ); // shotgun reload - played on client
|
||||
|
||||
PRECACHE_SOUND( "weapons/357_cock1.wav" ); // gun empty sound
|
||||
PRECACHE_SOUND( "weapons/scock1.wav" ); // cock gun
|
||||
|
||||
m_usSingleFire = PRECACHE_EVENT( 1, "events/shotgun1.sc" );
|
||||
m_usDoubleFire = PRECACHE_EVENT( 1, "events/shotgun2.sc" );
|
||||
}
|
||||
|
||||
int CSawnoff::AddToPlayer( CBasePlayer *pPlayer )
|
||||
{
|
||||
if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
|
||||
WRITE_BYTE( m_iId );
|
||||
MESSAGE_END();
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int CSawnoff::GetItemInfo( ItemInfo *p )
|
||||
{
|
||||
p->pszName = STRING( pev->classname );
|
||||
p->pszAmmo1 = "BUCKSHOT";
|
||||
p->iMaxAmmo1 = BUCKSHOT_MAX_CARRY;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = SAWNOFF_MAX_CLIP;
|
||||
p->iSlot = 2;
|
||||
p->iPosition = 3;
|
||||
p->iFlags = 0;
|
||||
p->iId = m_iId = WEAPON_SAWNOFF;
|
||||
p->iWeight = SAWNOFF_WEIGHT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CSawnoff::Deploy()
|
||||
{
|
||||
return DefaultDeploy( "models/v_sawnoff.mdl", "models/p_sawnoff.mdl", SAWNOFF_DRAW, "shotgun" );
|
||||
}
|
||||
|
||||
void CSawnoff::PrimaryAttack()
|
||||
{
|
||||
// don't fire underwater
|
||||
if( m_pPlayer->pev->waterlevel == 3 )
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15;
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_iClip <= 0 )
|
||||
{
|
||||
Reload();
|
||||
if( m_iClip == 0 )
|
||||
PlayEmptySound();
|
||||
return;
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME;
|
||||
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;
|
||||
|
||||
m_iClip--;
|
||||
|
||||
int flags;
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
flags = FEV_NOTHOST;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
m_pPlayer->pev->effects = (int)( m_pPlayer->pev->effects ) | EF_MUZZLEFLASH;
|
||||
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition();
|
||||
Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
|
||||
|
||||
Vector vecDir;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
if( bIsMultiplayer() )
|
||||
#else
|
||||
if( g_pGameRules->IsMultiplayer() )
|
||||
#endif
|
||||
{
|
||||
vecDir = m_pPlayer->FireBulletsPlayer( 25, vecSrc, vecAiming, VECTOR_CONE_DM_SAWNOFF, 2048, BULLET_PLAYER_BUCKSHOT, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed );
|
||||
}
|
||||
else
|
||||
{
|
||||
// regular old, untouched spread.
|
||||
vecDir = m_pPlayer->FireBulletsPlayer( 25, vecSrc, vecAiming, VECTOR_CONE_10DEGREES, 2048, BULLET_PLAYER_BUCKSHOT, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed );
|
||||
}
|
||||
|
||||
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usSingleFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 );
|
||||
|
||||
if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 )
|
||||
// HEV suit - indicate out of ammo condition
|
||||
m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 );
|
||||
|
||||
if( m_iClip != 0 )
|
||||
m_flPumpTime = gpGlobals->time + 0.5;
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75;
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75;
|
||||
if( m_iClip != 0 )
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5.0;
|
||||
else
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.75;
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
void CSawnoff::SecondaryAttack( void )
|
||||
{
|
||||
// don't fire underwater
|
||||
if( m_pPlayer->pev->waterlevel == 3 )
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15;
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_iClip <= 1 )
|
||||
{
|
||||
Reload();
|
||||
PlayEmptySound();
|
||||
return;
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME;
|
||||
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;
|
||||
|
||||
m_iClip -= 2;
|
||||
|
||||
int flags;
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
flags = FEV_NOTHOST;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
m_pPlayer->pev->effects = (int)( m_pPlayer->pev->effects ) | EF_MUZZLEFLASH;
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition();
|
||||
Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
|
||||
|
||||
Vector vecDir;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
if( bIsMultiplayer() )
|
||||
#else
|
||||
if( g_pGameRules->IsMultiplayer() )
|
||||
#endif
|
||||
{
|
||||
// tuned for deathmatch
|
||||
vecDir = m_pPlayer->FireBulletsPlayer( 50, vecSrc, vecAiming, VECTOR_CONE_DM_DOUBLESAWNOFF, 2048, BULLET_PLAYER_BUCKSHOT, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed );
|
||||
}
|
||||
else
|
||||
{
|
||||
// untouched default single player
|
||||
vecDir = m_pPlayer->FireBulletsPlayer( 50,vecSrc, vecAiming, VECTOR_CONE_10DEGREES, 2048, BULLET_PLAYER_BUCKSHOT, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed );
|
||||
}
|
||||
|
||||
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usDoubleFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 );
|
||||
|
||||
if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 )
|
||||
// HEV suit - indicate out of ammo condition
|
||||
m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 );
|
||||
|
||||
if( m_iClip != 0 )
|
||||
m_flPumpTime = gpGlobals->time + 0.95;
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.5;
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.5;
|
||||
if( m_iClip != 0 )
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 6.0;
|
||||
else
|
||||
m_flTimeWeaponIdle = 1.5;
|
||||
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
void CSawnoff::Reload( void )
|
||||
{
|
||||
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == SHOTGUN_MAX_CLIP )
|
||||
return;
|
||||
DefaultReload( SAWNOFF_MAX_CLIP, SAWNOFF_RELOAD, 1.5 );
|
||||
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/reload1.wav", 1, ATTN_NORM, 0, 85 + RANDOM_LONG( 0, 0x1f ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CSawnoff::WeaponIdle( void )
|
||||
{
|
||||
ResetEmptySound();
|
||||
|
||||
m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
|
||||
|
||||
if( m_flPumpTime && m_flPumpTime < gpGlobals->time )
|
||||
{
|
||||
// play pumping sound
|
||||
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/scock1.wav", 1, ATTN_NORM, 0, 95 + RANDOM_LONG( 0, 0x1f ) );
|
||||
m_flPumpTime = 0;
|
||||
}
|
||||
|
||||
if( m_flTimeWeaponIdle < UTIL_WeaponTimeBase() )
|
||||
{
|
||||
if( m_iClip == 0 && m_fInSpecialReload == 0 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else if( m_fInSpecialReload != 0 )
|
||||
{
|
||||
if( m_iClip != 8 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reload debounce has timed out
|
||||
SendWeaponAnim( SAWNOFF_PUMP );
|
||||
|
||||
// play cocking sound
|
||||
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/scock1.wav", 1, ATTN_NORM, 0, 95 + RANDOM_LONG( 0, 0x1f ) );
|
||||
m_fInSpecialReload = 0;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 );
|
||||
if( flRand <= 0.8 )
|
||||
{
|
||||
iAnim = SAWNOFF_IDLE_DEEP;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + ( 60.0 / 12.0 );// * RANDOM_LONG( 2, 5 );
|
||||
}
|
||||
else if( flRand <= 0.95 )
|
||||
{
|
||||
iAnim = SAWNOFF_IDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + ( 20.0 / 9.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = SAWNOFF_IDLE4;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + ( 20.0 / 9.0 );
|
||||
}
|
||||
SendWeaponAnim( iAnim );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CSawnoffAmmo : public CBasePlayerAmmo
|
||||
{
|
||||
void Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL( ENT( pev ), "models/w_shotbox.mdl" );
|
||||
CBasePlayerAmmo::Spawn();
|
||||
}
|
||||
void Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/w_shotbox.mdl" );
|
||||
PRECACHE_SOUND( "items/9mmclip1.wav" );
|
||||
}
|
||||
BOOL AddAmmo( CBaseEntity *pOther )
|
||||
{
|
||||
if( pOther->GiveAmmo( AMMO_BUCKSHOTBOX_GIVE, "BUCKSHOT", BUCKSHOT_MAX_CARRY ) != -1 )
|
||||
{
|
||||
EMIT_SOUND( ENT( pev ), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM );
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( ammo_cockshot, CSawnoffAmmo )
|
||||
|
1546
dlls/weapons.cpp~
1546
dlls/weapons.cpp~
File diff suppressed because it is too large
Load Diff
1256
dlls/weapons.h~~
1256
dlls/weapons.h~~
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user