Night Owl
8 years ago
28 changed files with 2257 additions and 418 deletions
@ -0,0 +1,229 @@
@@ -0,0 +1,229 @@
|
||||
/***
|
||||
* |
||||
* 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 "soundent.h" |
||||
#include "gamerules.h" |
||||
|
||||
enum ak47_e |
||||
{ |
||||
AK47_LONGIDLE = 0, |
||||
AK47_IDLE1, |
||||
AK47_LAUNCH, |
||||
AK47_RELOAD, |
||||
AK47_DEPLOY, |
||||
AK47_FIRE1, |
||||
AK47_FIRE2, |
||||
AK47_FIRE3, |
||||
}; |
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_ak47, CAK47); |
||||
|
||||
void CAK47::Spawn() |
||||
{ |
||||
Precache(); |
||||
SET_MODEL(ENT(pev), "models/w_ak47.mdl"); |
||||
m_iId = WEAPON_AK47; |
||||
|
||||
m_iDefaultAmmo = AK47_DEFAULT_GIVE; |
||||
|
||||
FallInit();// get ready to fall down.
|
||||
} |
||||
|
||||
|
||||
void CAK47::Precache(void) |
||||
{ |
||||
PRECACHE_MODEL("models/v_ak47.mdl"); |
||||
PRECACHE_MODEL("models/w_ak47.mdl"); |
||||
PRECACHE_MODEL("models/p_9mmAR.mdl"); |
||||
|
||||
m_iShell = PRECACHE_MODEL("models/shell.mdl");// brass shellTE_MODEL
|
||||
|
||||
PRECACHE_MODEL("models/w_ak47clip.mdl"); |
||||
PRECACHE_SOUND("items/9mmclip1.wav"); |
||||
|
||||
PRECACHE_SOUND("items/akclipinsert1.wav"); |
||||
PRECACHE_SOUND("items/akcliprelease1.wav"); |
||||
|
||||
PRECACHE_SOUND("weapons/ak1.wav"); |
||||
PRECACHE_SOUND("weapons/ak2.wav"); |
||||
PRECACHE_SOUND("weapons/ak3.wav"); |
||||
|
||||
PRECACHE_SOUND("weapons/357_cock1.wav"); |
||||
|
||||
m_usAK47 = PRECACHE_EVENT(1, "events/ak47.sc"); |
||||
} |
||||
|
||||
int CAK47::GetItemInfo(ItemInfo *p) |
||||
{ |
||||
p->pszName = STRING(pev->classname); |
||||
p->pszAmmo1 = "ak47"; |
||||
p->iMaxAmmo1 = AK47_MAX_CARRY; |
||||
p->pszAmmo2 = NULL; |
||||
p->iMaxAmmo2 = -1; |
||||
p->iMaxClip = AK47_MAX_CLIP; |
||||
p->iSlot = 2; |
||||
p->iPosition = 3; |
||||
p->iFlags = 0; |
||||
p->iId = m_iId = WEAPON_AK47; |
||||
p->iWeight = AK47_WEIGHT; |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
BOOL CAK47::Deploy() |
||||
{ |
||||
BOOL bResult = DefaultDeploy("models/v_ak47.mdl", "models/p_9mmAR.mdl", AK47_DEPLOY, "ak47"); |
||||
|
||||
if (bResult) |
||||
{ |
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1; |
||||
} |
||||
|
||||
return bResult; |
||||
} |
||||
|
||||
|
||||
void CAK47::PrimaryAttack() |
||||
{ |
||||
// don't fire underwater
|
||||
if (m_pPlayer->pev->waterlevel == 3) |
||||
{ |
||||
PlayEmptySound(); |
||||
m_flNextPrimaryAttack = 0.15; |
||||
return; |
||||
} |
||||
|
||||
if (m_iClip <= 0) |
||||
{ |
||||
PlayEmptySound(); |
||||
m_flNextPrimaryAttack = 0.15; |
||||
return; |
||||
} |
||||
|
||||
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME; |
||||
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH; |
||||
|
||||
m_iClip--; |
||||
|
||||
|
||||
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; |
||||
Vector vecSpread; |
||||
|
||||
// Allow for higher accuracy when the player is crouching.
|
||||
if (m_pPlayer->pev->flags & FL_DUCKING) |
||||
{ |
||||
vecSpread = VECTOR_CONE_2DEGREES; |
||||
} |
||||
else |
||||
{ |
||||
vecSpread = VECTOR_CONE_5DEGREES; |
||||
} |
||||
|
||||
// single player spread
|
||||
vecDir = m_pPlayer->FireBulletsPlayer(1, vecSrc, vecAiming, vecSpread, 8192, BULLET_PLAYER_AK47, 2, 0, m_pPlayer->pev, m_pPlayer->random_seed); |
||||
|
||||
int flags; |
||||
#if defined( CLIENT_WEAPONS ) |
||||
flags = FEV_NOTHOST; |
||||
#else |
||||
flags = 0; |
||||
#endif |
||||
|
||||
PLAYBACK_EVENT_FULL(flags, m_pPlayer->edict(), m_usAK47, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0); |
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.1); |
||||
|
||||
if (m_flNextPrimaryAttack < UTIL_WeaponTimeBase()) |
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1; |
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15); |
||||
} |
||||
|
||||
void CAK47::Reload(void) |
||||
{ |
||||
if (m_pPlayer->ammo_ak47 <= 0) |
||||
return; |
||||
|
||||
DefaultReload(AK47_MAX_CLIP, AK47_RELOAD, 2.8); |
||||
} |
||||
|
||||
|
||||
void CAK47::WeaponIdle(void) |
||||
{ |
||||
ResetEmptySound(); |
||||
|
||||
m_pPlayer->GetAutoaimVector(AUTOAIM_5DEGREES); |
||||
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase()) |
||||
return; |
||||
|
||||
int iAnim; |
||||
switch (RANDOM_LONG(0, 1)) |
||||
{ |
||||
case 0: |
||||
iAnim = AK47_LONGIDLE; |
||||
break; |
||||
|
||||
default: |
||||
case 1: |
||||
iAnim = AK47_IDLE1; |
||||
break; |
||||
} |
||||
|
||||
SendWeaponAnim(iAnim); |
||||
|
||||
m_flTimeWeaponIdle = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15); // how long till we do this again.
|
||||
} |
||||
|
||||
|
||||
class CAK47AmmoClip : public CBasePlayerAmmo |
||||
{ |
||||
void Spawn(void) |
||||
{ |
||||
Precache(); |
||||
SET_MODEL(ENT(pev), "models/w_ak47clip.mdl"); |
||||
CBasePlayerAmmo::Spawn(); |
||||
} |
||||
void Precache(void) |
||||
{ |
||||
PRECACHE_MODEL("models/w_ak47clip.mdl"); |
||||
PRECACHE_SOUND("items/9mmclip1.wav"); |
||||
} |
||||
BOOL AddAmmo(CBaseEntity *pOther) |
||||
{ |
||||
int bResult = (pOther->GiveAmmo(AMMO_AK47_GIVE, "ak47", AK47_MAX_CARRY) != -1); |
||||
if (bResult) |
||||
{ |
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); |
||||
} |
||||
return bResult; |
||||
} |
||||
}; |
||||
LINK_ENTITY_TO_CLASS(ammo_ak47, CAK47AmmoClip); |
@ -0,0 +1,345 @@
@@ -0,0 +1,345 @@
|
||||
/***
|
||||
* |
||||
* 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. |
||||
* |
||||
* 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. |
||||
* |
||||
****/ |
||||
|
||||
// UNDONE: Don't flinch every time you get hit
|
||||
|
||||
#include "extdll.h" |
||||
#include "util.h" |
||||
#include "cbase.h" |
||||
#include "monsters.h" |
||||
#include "schedule.h" |
||||
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
//=========================================================
|
||||
#define DIABLO_AE_ATTACK_RIGHT 0x01 |
||||
#define DIABLO_AE_ATTACK_LEFT 0x02 |
||||
#define DIABLO_AE_ATTACK_BOTH 0x03 |
||||
|
||||
#define DIABLO_FLINCH_DELAY 2 // at most one flinch every n secs
|
||||
|
||||
class CDiablo : public CBaseMonster |
||||
{ |
||||
public: |
||||
void Spawn(void); |
||||
void Precache(void); |
||||
void SetYawSpeed(void); |
||||
int Classify(void); |
||||
void HandleAnimEvent(MonsterEvent_t *pEvent); |
||||
int IgnoreConditions(void); |
||||
|
||||
float m_flNextFlinch; |
||||
|
||||
void PainSound(void); |
||||
void AlertSound(void); |
||||
void IdleSound(void); |
||||
void AttackSound(void); |
||||
|
||||
static const char *pAttackSounds[]; |
||||
static const char *pIdleSounds[]; |
||||
static const char *pAlertSounds[]; |
||||
static const char *pPainSounds[]; |
||||
static const char *pAttackHitSounds[]; |
||||
static const char *pAttackMissSounds[]; |
||||
|
||||
// No range attacks
|
||||
BOOL CheckRangeAttack1(float flDot, float flDist) { return FALSE; } |
||||
BOOL CheckRangeAttack2(float flDot, float flDist) { return FALSE; } |
||||
int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType); |
||||
|
||||
void SetActivity(Activity NewActivity); |
||||
}; |
||||
|
||||
LINK_ENTITY_TO_CLASS(monster_diablo, CDiablo); |
||||
|
||||
const char *CDiablo::pAttackHitSounds[] = |
||||
{ |
||||
"diablo/diablo_claw1.wav", |
||||
"diablo/diablo_claw2.wav", |
||||
"diablo/diablo_claw3.wav", |
||||
}; |
||||
|
||||
const char *CDiablo::pAttackMissSounds[] = |
||||
{ |
||||
"diablo/diablo_claw_miss1.wav", |
||||
"diablo/diablo_claw_miss2.wav", |
||||
}; |
||||
|
||||
const char *CDiablo::pAttackSounds[] = |
||||
{ |
||||
"diablo/diablo_attack1.wav", |
||||
"diablo/diablo_attack2.wav", |
||||
}; |
||||
|
||||
const char *CDiablo::pIdleSounds[] = |
||||
{ |
||||
"diablo/diablo_idle1.wav", |
||||
"diablo/diablo_idle2.wav", |
||||
"diablo/diablo_idle3.wav", |
||||
}; |
||||
|
||||
const char *CDiablo::pAlertSounds[] = |
||||
{ |
||||
"diablo/diablo_alert10.wav", |
||||
"diablo/diablo_alert20.wav", |
||||
"diablo/diablo_alert30.wav", |
||||
}; |
||||
|
||||
const char *CDiablo::pPainSounds[] = |
||||
{ |
||||
"diablo/diablo_pain1.wav", |
||||
"diablo/diablo_pain2.wav", |
||||
}; |
||||
|
||||
//=========================================================
|
||||
// Classify - indicates this monster's place in the
|
||||
// relationship table.
|
||||
//=========================================================
|
||||
int CDiablo::Classify(void) |
||||
{ |
||||
return CLASS_ALIEN_PREDATOR; |
||||
} |
||||
|
||||
//=========================================================
|
||||
// SetYawSpeed - allows each sequence to have a different
|
||||
// turn rate associated with it.
|
||||
//=========================================================
|
||||
void CDiablo::SetYawSpeed(void) |
||||
{ |
||||
int ys; |
||||
|
||||
ys = 140; // 120
|
||||
|
||||
#if 0 |
||||
switch (m_Activity) |
||||
{ |
||||
} |
||||
#endif |
||||
|
||||
pev->yaw_speed = ys; |
||||
} |
||||
|
||||
int CDiablo::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) |
||||
{ |
||||
// Take 30% damage from bullets
|
||||
if (bitsDamageType == DMG_BULLET) |
||||
{ |
||||
Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5; |
||||
vecDir = vecDir.Normalize(); |
||||
float flForce = DamageForce(flDamage); |
||||
pev->velocity = pev->velocity + vecDir * flForce; |
||||
flDamage *= 0.3; |
||||
} |
||||
|
||||
// HACK HACK -- until we fix this.
|
||||
if (IsAlive()) |
||||
PainSound(); |
||||
return CBaseMonster::TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType); |
||||
} |
||||
|
||||
void CDiablo::PainSound(void) |
||||
{ |
||||
int pitch = 95 + RANDOM_LONG(0, 9); |
||||
|
||||
if (RANDOM_LONG(0, 5) < 2) |
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pPainSounds), 1.0, ATTN_NORM, 0, pitch); |
||||
} |
||||
|
||||
void CDiablo::AlertSound(void) |
||||
{ |
||||
int pitch = 95 + RANDOM_LONG(0, 9); |
||||
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAlertSounds), 1.0, ATTN_NORM, 0, pitch); |
||||
} |
||||
|
||||
void CDiablo::IdleSound(void) |
||||
{ |
||||
int pitch = 100 + RANDOM_LONG(-5, 5); |
||||
|
||||
// Play a random idle sound
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pIdleSounds), 1.0, ATTN_NORM, 0, pitch); |
||||
} |
||||
|
||||
void CDiablo::AttackSound(void) |
||||
{ |
||||
int pitch = 100 + RANDOM_LONG(-5, 5); |
||||
|
||||
// Play a random attack sound
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAttackSounds), 1.0, ATTN_NORM, 0, pitch); |
||||
} |
||||
|
||||
|
||||
//=========================================================
|
||||
// HandleAnimEvent - catches the monster-specific messages
|
||||
// that occur when tagged animation frames are played.
|
||||
//=========================================================
|
||||
void CDiablo::HandleAnimEvent(MonsterEvent_t *pEvent) |
||||
{ |
||||
switch (pEvent->event) |
||||
{ |
||||
case DIABLO_AE_ATTACK_RIGHT: |
||||
{ |
||||
// do stuff for this event.
|
||||
// ALERT( at_console, "Slash right!\n" );
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack(70, gSkillData.diabloDmgOneSlash, DMG_SLASH | DMG_NEVERGIB); |
||||
if (pHurt) |
||||
{ |
||||
if (pHurt->pev->flags & (FL_MONSTER | FL_CLIENT)) |
||||
{ |
||||
pHurt->pev->punchangle.z = -18; |
||||
pHurt->pev->punchangle.x = 5; |
||||
pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_right * 100; |
||||
} |
||||
// Play a random attack hit sound
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pAttackHitSounds), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5, 5)); |
||||
} |
||||
else // Play a random attack miss sound
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pAttackMissSounds), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5, 5)); |
||||
|
||||
if (RANDOM_LONG(0, 1)) |
||||
AttackSound(); |
||||
} |
||||
break; |
||||
|
||||
case DIABLO_AE_ATTACK_LEFT: |
||||
{ |
||||
// do stuff for this event.
|
||||
// ALERT( at_console, "Slash left!\n" );
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack(70, gSkillData.diabloDmgOneSlash, DMG_SLASH | DMG_NEVERGIB); |
||||
if (pHurt) |
||||
{ |
||||
if (pHurt->pev->flags & (FL_MONSTER | FL_CLIENT)) |
||||
{ |
||||
pHurt->pev->punchangle.z = 18; |
||||
pHurt->pev->punchangle.x = 5; |
||||
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_right * 100; |
||||
} |
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pAttackHitSounds), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5, 5)); |
||||
} |
||||
else |
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pAttackMissSounds), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5, 5)); |
||||
|
||||
if (RANDOM_LONG(0, 1)) |
||||
AttackSound(); |
||||
} |
||||
break; |
||||
|
||||
case DIABLO_AE_ATTACK_BOTH: |
||||
{ |
||||
// do stuff for this event.
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack(70, gSkillData.diabloDmgBothSlash, DMG_SLASH | DMG_NEVERGIB); |
||||
if (pHurt) |
||||
{ |
||||
if (pHurt->pev->flags & (FL_MONSTER | FL_CLIENT)) |
||||
{ |
||||
pHurt->pev->punchangle.x = 5; |
||||
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_forward * -100; |
||||
} |
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pAttackHitSounds), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5, 5)); |
||||
} |
||||
else |
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pAttackMissSounds), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5, 5)); |
||||
|
||||
if (RANDOM_LONG(0, 1)) |
||||
AttackSound(); |
||||
} |
||||
break; |
||||
|
||||
default: |
||||
CBaseMonster::HandleAnimEvent(pEvent); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CDiablo::Spawn() |
||||
{ |
||||
Precache(); |
||||
|
||||
SET_MODEL(ENT(pev), "models/diablo.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 = gSkillData.diabloHealth; |
||||
pev->view_ofs = VEC_VIEW;// position of the eyes relative to monster's origin.
|
||||
m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
m_MonsterState = MONSTERSTATE_NONE; |
||||
m_afCapability = bits_CAP_DOORS_GROUP; |
||||
|
||||
MonsterInit(); |
||||
} |
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CDiablo::Precache() |
||||
{ |
||||
PRECACHE_MODEL("models/diablo.mdl"); |
||||
|
||||
PRECACHE_SOUND_ARRAY(pAttackHitSounds); |
||||
PRECACHE_SOUND_ARRAY(pAttackMissSounds); |
||||
PRECACHE_SOUND_ARRAY(pAttackSounds); |
||||
PRECACHE_SOUND_ARRAY(pIdleSounds); |
||||
PRECACHE_SOUND_ARRAY(pAlertSounds); |
||||
PRECACHE_SOUND_ARRAY(pPainSounds); |
||||
} |
||||
|
||||
|
||||
void CDiablo::SetActivity(Activity newActivity) |
||||
{ |
||||
if (m_MonsterState == MONSTERSTATE_COMBAT) |
||||
{ |
||||
if (newActivity == ACT_WALK) |
||||
newActivity = ACT_RUN; |
||||
} |
||||
|
||||
CBaseMonster::SetActivity(newActivity); |
||||
} |
||||
|
||||
//=========================================================
|
||||
// AI Schedules Specific to this monster
|
||||
//=========================================================
|
||||
|
||||
|
||||
|
||||
int CDiablo::IgnoreConditions(void) |
||||
{ |
||||
int iIgnore = CBaseMonster::IgnoreConditions(); |
||||
|
||||
if ((m_Activity == ACT_MELEE_ATTACK1) || (m_Activity == ACT_MELEE_ATTACK1)) |
||||
{ |
||||
#if 0 |
||||
if (pev->health < 20) |
||||
iIgnore |= (bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE); |
||||
else |
||||
#endif |
||||
if (m_flNextFlinch >= gpGlobals->time) |
||||
iIgnore |= (bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE); |
||||
} |
||||
|
||||
if ((m_Activity == ACT_SMALL_FLINCH) || (m_Activity == ACT_BIG_FLINCH)) |
||||
{ |
||||
if (m_flNextFlinch < gpGlobals->time) |
||||
m_flNextFlinch = gpGlobals->time + DIABLO_FLINCH_DELAY; |
||||
} |
||||
|
||||
return iIgnore; |
||||
|
||||
} |
@ -0,0 +1,251 @@
@@ -0,0 +1,251 @@
|
||||
/***
|
||||
* |
||||
* 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. |
||||
* |
||||
* 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. |
||||
* |
||||
****/ |
||||
|
||||
|
||||
#include "extdll.h" |
||||
#include "plane.h" |
||||
#include "util.h" |
||||
#include "cbase.h" |
||||
#include "monsters.h" |
||||
#include "schedule.h" |
||||
#include "animation.h" |
||||
#include "weapons.h" |
||||
#include "soundent.h" |
||||
#include "effects.h" |
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
//=========================================================
|
||||
#define HASSAULT_AE_BURST1 ( 1 ) |
||||
#define HASSAULT_AE_BURST2 ( 2 ) |
||||
#define HASSAULT_AE_BURST3 ( 3 ) |
||||
#define HASSAULT_AE_BURST4 ( 4 ) |
||||
#define HASSAULT_AE_BURST5 ( 5 ) |
||||
#define HASSAULT_AE_BURST6 ( 6 ) |
||||
#define HASSAULT_AE_BURST7 ( 7 ) |
||||
#define HASSAULT_AE_BURST8 ( 8 ) |
||||
#define HASSAULT_AE_BURST9 ( 9 ) |
||||
#define HASSAULT_AE_PAIN1 ( 10 ) |
||||
#define HASSAULT_AE_PAIN2 ( 11 ) |
||||
|
||||
class CHassault : public CBaseMonster |
||||
{ |
||||
public: |
||||
void Spawn(void); |
||||
void Precache(void); |
||||
void SetYawSpeed(void); |
||||
int Classify(void); |
||||
void HandleAnimEvent(MonsterEvent_t* pEvent); |
||||
|
||||
void DeathSound(void); |
||||
|
||||
BOOL CheckMeleeAttack1(float flDot, float flDist) { return FALSE; } |
||||
BOOL CheckMeleeAttack2(float flDot, float flDist) { return FALSE; } |
||||
BOOL CheckRangeAttack2(float flDot, float flDist) { return FALSE; } |
||||
|
||||
void Shoot(void); |
||||
|
||||
static const char *pDeathSounds[]; |
||||
static const char *pPainSounds[]; |
||||
static const char *pBurstSounds[]; |
||||
|
||||
private: |
||||
int m_iShell; |
||||
}; |
||||
|
||||
LINK_ENTITY_TO_CLASS(monster_hassault, CHassault); |
||||
|
||||
const char *CHassault::pPainSounds[] = |
||||
{ |
||||
"hgrunt/gr_pain1.wav", |
||||
"hgrunt/gr_pain2.wav", |
||||
"hgrunt/gr_pain3.wav", |
||||
"hgrunt/gr_pain4.wav", |
||||
"hgrunt/gr_pain5.wav", |
||||
}; |
||||
|
||||
const char *CHassault::pDeathSounds[] = |
||||
{ |
||||
"hgrunt/gr_die1.wav", |
||||
"hgrunt/gr_die2.wav", |
||||
"hgrunt/gr_die3.wav", |
||||
}; |
||||
|
||||
const char *CHassault::pBurstSounds[] = |
||||
{ |
||||
"hassault/hw_shoot1.wav", |
||||
"hassault/hw_shoot2.wav", |
||||
"hassault/hw_shoot3.wav", |
||||
}; |
||||
|
||||
//=========================================================
|
||||
// SetYawSpeed - allows each sequence to have a different
|
||||
// turn rate associated with it.
|
||||
//=========================================================
|
||||
void CHassault::SetYawSpeed(void) |
||||
{ |
||||
int ys; |
||||
|
||||
switch (m_Activity) |
||||
{ |
||||
case ACT_IDLE: |
||||
ys = 150; |
||||
break; |
||||
case ACT_RUN: |
||||
case ACT_WALK: |
||||
ys = 180; |
||||
break; |
||||
case ACT_RANGE_ATTACK1: |
||||
ys = 120; |
||||
break; |
||||
case ACT_TURN_LEFT: |
||||
case ACT_TURN_RIGHT: |
||||
ys = 180; |
||||
break; |
||||
default: |
||||
ys = 90; |
||||
break; |
||||
} |
||||
|
||||
pev->yaw_speed = ys; |
||||
} |
||||
|
||||
//=========================================================
|
||||
// HandleAnimEvent - catches the monster-specific messages
|
||||
// that occur when tagged animation frames are played.
|
||||
//=========================================================
|
||||
void CHassault::HandleAnimEvent(MonsterEvent_t *pEvent) |
||||
{ |
||||
switch (pEvent->event) |
||||
{ |
||||
case HASSAULT_AE_BURST1: |
||||
case HASSAULT_AE_BURST2: |
||||
case HASSAULT_AE_BURST3: |
||||
case HASSAULT_AE_BURST4: |
||||
case HASSAULT_AE_BURST5: |
||||
case HASSAULT_AE_BURST6: |
||||
case HASSAULT_AE_BURST7: |
||||
case HASSAULT_AE_BURST8: |
||||
case HASSAULT_AE_BURST9: |
||||
|
||||
Shoot(); |
||||
EMIT_SOUND(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pBurstSounds), 1, ATTN_NORM); |
||||
|
||||
break; |
||||
|
||||
case HASSAULT_AE_PAIN1: |
||||
case HASSAULT_AE_PAIN2: |
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pPainSounds), 1, ATTN_NORM); |
||||
break; |
||||
|
||||
default: |
||||
CBaseMonster::HandleAnimEvent(pEvent); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CHassault::Spawn() |
||||
{ |
||||
Precache(); |
||||
|
||||
SET_MODEL(ENT(pev), "models/hassault.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->effects = 0; |
||||
pev->health = gSkillData.hassaultHealth; |
||||
m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
m_MonsterState = MONSTERSTATE_NONE; |
||||
|
||||
m_afCapability = bits_CAP_SQUAD | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP; |
||||
|
||||
m_HackedGunPos = Vector(0, 0, 55); |
||||
|
||||
m_cAmmoLoaded = 1; |
||||
ClearConditions(bits_COND_NO_AMMO_LOADED); |
||||
|
||||
MonsterInit(); |
||||
} |
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CHassault::Precache() |
||||
{ |
||||
PRECACHE_MODEL("models/hassault.mdl"); |
||||
|
||||
PRECACHE_SOUND("hassault/hw_gun4.wav"); |
||||
|
||||
PRECACHE_SOUND_ARRAY(pPainSounds); |
||||
PRECACHE_SOUND_ARRAY(pDeathSounds); |
||||
PRECACHE_SOUND_ARRAY(pBurstSounds); |
||||
|
||||
PRECACHE_SOUND("hassault/hw_spin.wav"); |
||||
PRECACHE_SOUND("hassault/hw_spindown.wav"); |
||||
PRECACHE_SOUND("hassault/hw_spinup.wav"); |
||||
|
||||
m_iShell = PRECACHE_MODEL("models/shell.mdl");// brass shell
|
||||
} |
||||
|
||||
//=========================================================
|
||||
// Classify - indicates this monster's place in the
|
||||
// relationship table.
|
||||
//=========================================================
|
||||
int CHassault::Classify(void) |
||||
{ |
||||
return CLASS_HUMAN_MILITARY; |
||||
} |
||||
|
||||
//=========================================================
|
||||
// Shoot
|
||||
//=========================================================
|
||||
void CHassault::Shoot(void) |
||||
{ |
||||
if (m_hEnemy == NULL) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
Vector vecShootOrigin = GetGunPosition(); |
||||
Vector vecShootDir = ShootAtEnemy(vecShootOrigin); |
||||
|
||||
UTIL_MakeVectors(pev->angles); |
||||
|
||||
Vector vecShellVelocity = gpGlobals->v_right * RANDOM_FLOAT(40, 90) + gpGlobals->v_up * RANDOM_FLOAT(75, 200) + gpGlobals->v_forward * RANDOM_FLOAT(-40, 40); |
||||
EjectBrass(vecShootOrigin - vecShootDir * 24, vecShellVelocity, pev->angles.y, m_iShell, TE_BOUNCE_SHELL); |
||||
FireBullets(1, vecShootOrigin, vecShootDir, VECTOR_CONE_15DEGREES, 2048, BULLET_MONSTER_HVMG); // shoot +-5 degrees
|
||||
|
||||
pev->effects |= EF_MUZZLEFLASH; |
||||
|
||||
// m_cAmmoLoaded--;// take away a bullet!
|
||||
|
||||
Vector angDir = UTIL_VecToAngles(vecShootDir); |
||||
SetBlending(0, angDir.x); |
||||
} |
||||
|
||||
|
||||
//=========================================================
|
||||
// DeathSound
|
||||
//=========================================================
|
||||
void CHassault::DeathSound(void) |
||||
{ |
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pDeathSounds), 1, ATTN_IDLE); |
||||
} |
@ -0,0 +1,229 @@
@@ -0,0 +1,229 @@
|
||||
/***
|
||||
* |
||||
* 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 "soundent.h" |
||||
#include "gamerules.h" |
||||
|
||||
enum mac10_e |
||||
{ |
||||
MAC10_LONGIDLE = 0, |
||||
MAC10_IDLE1, |
||||
MAC10_LAUNCH, |
||||
MAC10_RELOAD, |
||||
MAC10_DEPLOY, |
||||
MAC10_FIRE1, |
||||
MAC10_FIRE2, |
||||
MAC10_FIRE3, |
||||
}; |
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_mac10, CMac10); |
||||
|
||||
void CMac10::Spawn() |
||||
{ |
||||
Precache(); |
||||
SET_MODEL(ENT(pev), "models/w_mac10.mdl"); |
||||
m_iId = WEAPON_MAC10; |
||||
|
||||
m_iDefaultAmmo = MAC10_DEFAULT_GIVE; |
||||
|
||||
FallInit();// get ready to fall down.
|
||||
} |
||||
|
||||
|
||||
void CMac10::Precache(void) |
||||
{ |
||||
PRECACHE_MODEL("models/v_mac10.mdl"); |
||||
PRECACHE_MODEL("models/w_mac10.mdl"); |
||||
PRECACHE_MODEL("models/p_9mmAR.mdl"); |
||||
|
||||
m_iShell = PRECACHE_MODEL("models/shell.mdl");// brass shellTE_MODEL
|
||||
|
||||
PRECACHE_MODEL("models/w_mac10clip.mdl"); |
||||
PRECACHE_SOUND("items/9mmclip1.wav"); |
||||
|
||||
PRECACHE_SOUND("items/mac10clipinsert1.wav"); |
||||
PRECACHE_SOUND("items/mac10cliprelease1.wav"); |
||||
|
||||
PRECACHE_SOUND("weapons/mac1.wav"); |
||||
PRECACHE_SOUND("weapons/mac2.wav"); |
||||
PRECACHE_SOUND("weapons/mac3.wav"); |
||||
|
||||
PRECACHE_SOUND("weapons/357_cock1.wav"); |
||||
|
||||
m_usMac10 = PRECACHE_EVENT(1, "events/mac10.sc"); |
||||
} |
||||
|
||||
int CMac10::GetItemInfo(ItemInfo *p) |
||||
{ |
||||
p->pszName = STRING(pev->classname); |
||||
p->pszAmmo1 = "mac10"; |
||||
p->iMaxAmmo1 = MAC10_MAX_CARRY; |
||||
p->pszAmmo2 = NULL; |
||||
p->iMaxAmmo2 = -1; |
||||
p->iMaxClip = MAC10_MAX_CLIP; |
||||
p->iSlot = 1; |
||||
p->iPosition = 1; |
||||
p->iFlags = 0; |
||||
p->iId = m_iId = WEAPON_MAC10; |
||||
p->iWeight = MAC10_WEIGHT; |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
BOOL CMac10::Deploy() |
||||
{ |
||||
BOOL bResult = DefaultDeploy("models/v_mac10.mdl", "models/p_9mmAR.mdl", MAC10_DEPLOY, "mac10"); |
||||
|
||||
if ( bResult ) |
||||
{ |
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.8; |
||||
} |
||||
|
||||
return bResult; |
||||
} |
||||
|
||||
|
||||
void CMac10::PrimaryAttack() |
||||
{ |
||||
// don't fire underwater
|
||||
if (m_pPlayer->pev->waterlevel == 3) |
||||
{ |
||||
PlayEmptySound(); |
||||
m_flNextPrimaryAttack = 0.15; |
||||
return; |
||||
} |
||||
|
||||
if (m_iClip <= 0) |
||||
{ |
||||
PlayEmptySound(); |
||||
m_flNextPrimaryAttack = 0.15; |
||||
return; |
||||
} |
||||
|
||||
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME; |
||||
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH; |
||||
|
||||
m_iClip--; |
||||
|
||||
|
||||
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; |
||||
Vector vecSpread; |
||||
|
||||
// Allow for higher accuracy when the player is crouching.
|
||||
if (m_pPlayer->pev->flags & FL_DUCKING) |
||||
{ |
||||
vecSpread = VECTOR_CONE_1DEGREES; |
||||
} |
||||
else |
||||
{ |
||||
vecSpread = VECTOR_CONE_4DEGREES; |
||||
} |
||||
|
||||
// single player spread
|
||||
vecDir = m_pPlayer->FireBulletsPlayer(1, vecSrc, vecAiming, vecSpread, 8192, BULLET_PLAYER_MAC10, 2, 0, m_pPlayer->pev, m_pPlayer->random_seed); |
||||
|
||||
int flags; |
||||
#if defined( CLIENT_WEAPONS ) |
||||
flags = FEV_NOTHOST; |
||||
#else |
||||
flags = 0; |
||||
#endif |
||||
|
||||
PLAYBACK_EVENT_FULL(flags, m_pPlayer->edict(), m_usMac10, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0); |
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.1); |
||||
|
||||
if (m_flNextPrimaryAttack < UTIL_WeaponTimeBase()) |
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1; |
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15); |
||||
} |
||||
|
||||
void CMac10::Reload(void) |
||||
{ |
||||
if (m_pPlayer->ammo_mac10 <= 0) |
||||
return; |
||||
|
||||
DefaultReload(MAC10_MAX_CLIP, MAC10_RELOAD, 2.7); |
||||
} |
||||
|
||||
|
||||
void CMac10::WeaponIdle(void) |
||||
{ |
||||
ResetEmptySound(); |
||||
|
||||
m_pPlayer->GetAutoaimVector(AUTOAIM_5DEGREES); |
||||
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase()) |
||||
return; |
||||
|
||||
int iAnim; |
||||
switch (RANDOM_LONG(0, 1)) |
||||
{ |
||||
case 0: |
||||
iAnim = MAC10_LONGIDLE; |
||||
break; |
||||
|
||||
default: |
||||
case 1: |
||||
iAnim = MAC10_IDLE1; |
||||
break; |
||||
} |
||||
|
||||
SendWeaponAnim(iAnim); |
||||
|
||||
m_flTimeWeaponIdle = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15); // how long till we do this again.
|
||||
} |
||||
|
||||
|
||||
class CMac10AmmoClip : public CBasePlayerAmmo |
||||
{ |
||||
void Spawn(void) |
||||
{ |
||||
Precache(); |
||||
SET_MODEL(ENT(pev), "models/w_mac10clip.mdl"); |
||||
CBasePlayerAmmo::Spawn(); |
||||
} |
||||
void Precache(void) |
||||
{ |
||||
PRECACHE_MODEL("models/w_mac10clip.mdl"); |
||||
PRECACHE_SOUND("items/9mmclip1.wav"); |
||||
} |
||||
BOOL AddAmmo(CBaseEntity *pOther) |
||||
{ |
||||
int bResult = (pOther->GiveAmmo(AMMO_MAC10_GIVE, "mac10", MAC10_MAX_CARRY) != -1); |
||||
if (bResult) |
||||
{ |
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); |
||||
} |
||||
return bResult; |
||||
} |
||||
}; |
||||
LINK_ENTITY_TO_CLASS(ammo_mac10, CMac10AmmoClip); |
Loading…
Reference in new issue