Browse Source

Merge @malortie's patches for The Gate.

thegate
Night Owl 8 years ago
parent
commit
89eb528c16
  1. 288
      cl_dll/TheGate/scope.cpp
  2. 48
      cl_dll/ev_hldm.cpp
  3. 7
      cl_dll/ev_hldm.h
  4. 2
      cl_dll/hud.cpp
  5. 34
      cl_dll/hud.h
  6. 100
      dlls/TheGate/command.cpp
  7. 103
      dlls/TheGate/scientist2.cpp
  8. 14
      dlls/cbase.cpp
  9. 3
      dlls/combat.cpp
  10. 96
      dlls/crossbow.cpp
  11. 27
      dlls/handgrenade.cpp
  12. 4
      dlls/hgrunt.cpp
  13. 28
      dlls/houndeye.cpp
  14. 10
      dlls/mp5.cpp
  15. 15
      dlls/player.cpp
  16. 2
      dlls/player.h
  17. 157
      dlls/rpg.cpp
  18. 95
      dlls/scientist.cpp
  19. 119
      dlls/scientist.h
  20. 14
      dlls/scripted.cpp
  21. 14
      dlls/triggers.cpp
  22. 1
      dlls/weapons.cpp
  23. 4
      dlls/weapons.h

288
cl_dll/TheGate/scope.cpp

@ -0,0 +1,288 @@ @@ -0,0 +1,288 @@
/***
*
* 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 "hud.h"
#include "cl_util.h"
#include "parsemsg.h"
#include <string.h>
#include <stdio.h>
#define SCOPE_SMALL 0
#define SCOPE_MEDIUM 1
#define SCOPE_LARGE 2
static int HUD_IsWidescreen(int iWidth, int iHeight)
{
float ratio = iWidth / iHeight;
return (ratio >= 1.77) ? 1 : 0;
}
DECLARE_MESSAGE(m_Scope, Scope)
int CHudScope::Init(void)
{
HOOK_MESSAGE(Scope);
// Make inactive.
m_iFlags &= ~HUD_ACTIVE;
gHUD.AddHudElem(this);
return 1;
};
void CHudScope::Reset(void)
{
// Make inactive.
m_iFlags &= ~HUD_ACTIVE;
}
int CHudScope::VidInit(void)
{
for (int i = 0; i < SCOPE_HSPRITE_COUNT; i++)
m_scopes[i] = 0;
m_ScopeSize = 0;
int sw = ScreenWidth, sh = ScreenHeight;
//
// Determine the ideal scope size to use.
//
// Widescreen support. 1:77
if (HUD_IsWidescreen(sw, sh))
{
if (sh > 576)
{
if (sh > 800)
{
m_ScopeSize = SCOPE_LARGE;
}
else
{
m_ScopeSize = SCOPE_MEDIUM;
}
}
else
{
m_ScopeSize = SCOPE_SMALL;
}
}
// Normal display. 1:33
else
{
if (sh > 600)
{
if (sh > 768)
{
m_ScopeSize = SCOPE_LARGE;
}
else
{
m_ScopeSize = SCOPE_MEDIUM;
}
}
else
{
m_ScopeSize = SCOPE_SMALL;
}
}
// Make inactive.
m_iFlags &= ~HUD_ACTIVE;
return 1;
};
int CHudScope::Draw(float flTime)
{
if (!(m_iFlags & HUD_ACTIVE))
return 1;
int x, y, w, h;
x = y = 0;
if (!m_scopes[0])
{
switch (m_ScopeSize)
{
default:
case SCOPE_SMALL:
m_scopes[0] = LoadSprite("sprites/scope/0.spr");
break;
case SCOPE_MEDIUM:
m_scopes[SCOPE_U_L] = LoadSprite("sprites/scope/800/U_L.spr");
m_scopes[SCOPE_U_M_L] = LoadSprite("sprites/scope/800/U_M_L.spr");
m_scopes[SCOPE_U_M_R] = LoadSprite("sprites/scope/800/U_M_R.spr");
m_scopes[SCOPE_U_R] = LoadSprite("sprites/scope/800/U_R.spr");
m_scopes[SCOPE_M_L] = LoadSprite("sprites/scope/800/M_L.spr");
m_scopes[SCOPE_M_R] = LoadSprite("sprites/scope/800/M_R.spr");
m_scopes[SCOPE_L_L] = LoadSprite("sprites/scope/800/L_L.spr");
m_scopes[SCOPE_L_M_L] = LoadSprite("sprites/scope/800/L_M_L.spr");
m_scopes[SCOPE_L_M_R] = LoadSprite("sprites/scope/800/L_M_R.spr");
m_scopes[SCOPE_L_R] = LoadSprite("sprites/scope/800/L_R.spr");
break;
case SCOPE_LARGE:
m_scopes[SCOPE_U_L] = LoadSprite("sprites/scope/1024/U_L.spr");
m_scopes[SCOPE_U_M_L] = LoadSprite("sprites/scope/1024/U_M_L.spr");
m_scopes[SCOPE_U_M_R] = LoadSprite("sprites/scope/1024/U_M_R.spr");
m_scopes[SCOPE_U_R] = LoadSprite("sprites/scope/1024/U_R.spr");
m_scopes[SCOPE_M_L] = LoadSprite("sprites/scope/1024/M_L.spr");
m_scopes[SCOPE_M_R] = LoadSprite("sprites/scope/1024/M_R.spr");
m_scopes[SCOPE_L_L] = LoadSprite("sprites/scope/1024/L_L.spr");
m_scopes[SCOPE_L_M_L] = LoadSprite("sprites/scope/1024/L_M_L.spr");
m_scopes[SCOPE_L_M_R] = LoadSprite("sprites/scope/1024/L_M_R.spr");
m_scopes[SCOPE_L_R] = LoadSprite("sprites/scope/1024/L_R.spr");
break;
}
}
w = SPR_Width(m_scopes[0], 0);
h = SPR_Height(m_scopes[0], 0);
int r, g, b, a;
UnpackRGB(r, g, b, RGB_YELLOWISH);
switch (m_ScopeSize)
{
default:
//
// Small scope.
//
case SCOPE_SMALL:
//
// This uses one sprite.
//
x = ScreenWidth / 2 - w;
y = ScreenHeight / 2 - h;
//-----------------------
// Top left scope.
//-----------------------
SPR_Set(m_scopes[0], r, g, b);
SPR_DrawHoles(0, x, y, NULL);
//-----------------------
// Top right scope.
//-----------------------
SPR_Set(m_scopes[0], r, g, b);
SPR_DrawHoles(1, x + w, y, NULL);
//-----------------------
// Bottom right scope.
//-----------------------
SPR_Set(m_scopes[0], r, g, b);
SPR_DrawHoles(2, x + w, y + h, NULL);
//-----------------------
// Bottom left scope.
//-----------------------
SPR_Set(m_scopes[0], r, g, b);
SPR_DrawHoles(3, x, y + h, NULL);
break;
//
// Medium & Large scopes.
//
case SCOPE_MEDIUM:
case SCOPE_LARGE:
x = ScreenWidth / 2 - w * 2;
y = ScreenHeight / 2 - (h * 3) / 2;
//-----------------------
// Upper part.
//-----------------------
SPR_Set(m_scopes[SCOPE_U_L], r, g, b);
SPR_DrawHoles(0, x, y, NULL);
SPR_Set(m_scopes[SCOPE_U_M_L], r, g, b);
SPR_DrawHoles(0, x + w, y, NULL);
SPR_Set(m_scopes[SCOPE_U_M_R], r, g, b);
SPR_DrawHoles(0, x + w * 2, y, NULL);
SPR_Set(m_scopes[SCOPE_U_R], r, g, b);
SPR_DrawHoles(0, x + w * 3, y, NULL);
//-----------------------
// Middle part.
//-----------------------
SPR_Set(m_scopes[SCOPE_M_L], r, g, b);
SPR_DrawHoles(0, x, y + h, NULL);
SPR_Set(m_scopes[SCOPE_M_R], r, g, b);
SPR_DrawHoles(0, x + w * 3, y + h, NULL);
//-----------------------
// Lower part.
//-----------------------
SPR_Set(m_scopes[SCOPE_L_L], r, g, b);
SPR_DrawHoles(0, x, y + h * 2, NULL);
SPR_Set(m_scopes[SCOPE_L_M_L], r, g, b);
SPR_DrawHoles(0, x + w, y + h * 2, NULL);
SPR_Set(m_scopes[SCOPE_L_M_R], r, g, b);
SPR_DrawHoles(0, x + w * 2, y + h * 2, NULL);
SPR_Set(m_scopes[SCOPE_L_R], r, g, b);
SPR_DrawHoles(0, x + w * 3, y + h * 2, NULL);
break;
}
r = g = b = 0;
a = 255;
// Draw left bar.
gEngfuncs.pfnFillRGBABlend(0, 0, x + 1, ScreenHeight, r, g, b, a);
// Draw right bar.
gEngfuncs.pfnFillRGBABlend(ScreenWidth - x - 1, 0, ScreenWidth, ScreenHeight, r, g, b, a);
// Draw top bar.
gEngfuncs.pfnFillRGBABlend(0, 0, ScreenWidth, y + 1, r, g, b, a);
// Draw bottom bar.
gEngfuncs.pfnFillRGBABlend(0, ScreenHeight - y - 1, ScreenWidth, ScreenHeight, r, g, b, a);
return 1;
}
int CHudScope::MsgFunc_Scope(const char *pszName, int iSize, void *pbuf)
{
BEGIN_READ(pbuf, iSize);
int fOn = READ_BYTE();
if (fOn)
{
// Make active.
m_iFlags |= HUD_ACTIVE;
}
else
{
// Make inactive.
m_iFlags &= ~HUD_ACTIVE;
}
return 1;
}

48
cl_dll/ev_hldm.cpp

@ -317,6 +317,7 @@ void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType ) @@ -317,6 +317,7 @@ void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType )
case BULLET_MONSTER_MP5:
case BULLET_PLAYER_BUCKSHOT:
case BULLET_PLAYER_357:
case BULLET_PLAYER_SNIPER:
default:
// smoke and decal
EV_HLDM_GunshotDecalTrace( pTrace, EV_HLDM_DamageDecal( pe ) );
@ -445,6 +446,7 @@ void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int @@ -445,6 +446,7 @@ void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int
EV_HLDM_DecalGunshot( &tr, iBulletType );
break;
case BULLET_PLAYER_357:
case BULLET_PLAYER_SNIPER:
EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
EV_HLDM_DecalGunshot( &tr, iBulletType );
break;
@ -1303,23 +1305,36 @@ void EV_FireCrossbow( event_args_t *args ) @@ -1303,23 +1305,36 @@ void EV_FireCrossbow( event_args_t *args )
{
int idx;
vec3_t origin;
vec3_t angles;
vec3_t velocity;
vec3_t vecSrc, vecAiming;
vec3_t up, right, forward;
float flSpread = 0.01;
idx = args->entindex;
VectorCopy( args->origin, origin );
VectorCopy( args->angles, angles );
VectorCopy( args->velocity, velocity );
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/xbow_fire1.wav", 1, ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) );
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/xbow_reload1.wav", gEngfuncs.pfnRandomFloat( 0.95, 1.0 ), ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) );
AngleVectors( angles, forward, right, up );
//Only play the weapon anims if I shot it.
if( EV_IsLocal( idx ) )
{
if( args->iparam1 )
gEngfuncs.pEventAPI->EV_WeaponAnimation( CROSSBOW_FIRE1, 1 );
else if ( args->iparam2 )
gEngfuncs.pEventAPI->EV_WeaponAnimation( CROSSBOW_FIRE3, 1 );
// Add muzzle flash to current weapon model
EV_MuzzleFlash();
gEngfuncs.pEventAPI->EV_WeaponAnimation( CROSSBOW_FIRE1, 0 );
V_PunchAxis( 0, -2.0 );
}
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/xbow_fire1.wav", 1, ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) );
EV_GetGunPosition( args, vecSrc, origin );
VectorCopy( forward, vecAiming );
EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_SNIPER, 0, 0, args->fparam1, args->fparam2 );
}
//======================
// CROSSBOW END
@ -1331,15 +1346,13 @@ void EV_FireCrossbow( event_args_t *args ) @@ -1331,15 +1346,13 @@ void EV_FireCrossbow( event_args_t *args )
enum rpg_e
{
RPG_IDLE = 0,
RPG_FIDGET,
RPG_RELOAD, // to reload
RPG_FIRE2, // to empty
RPG_HOLSTER1, // loaded
RPG_DRAW1, // loaded
RPG_HOLSTER2, // unloaded
RPG_DRAW_UL, // unloaded
RPG_IDLE_UL, // unloaded idle
RPG_FIDGET_UL // unloaded fidget
RPG_DRAW1,
RPG_AIMED,
RPG_LAUNCH,
RPG_DOWN_TO_UP,
RPG_UP_TO_DOWN,
RPG_RELOAD_AIMED,
RPG_RELOAD_IDLE
};
void EV_FireRpg( event_args_t *args )
@ -1351,12 +1364,11 @@ void EV_FireRpg( event_args_t *args ) @@ -1351,12 +1364,11 @@ void EV_FireRpg( event_args_t *args )
VectorCopy( args->origin, origin );
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/rocketfire1.wav", 0.9, ATTN_NORM, 0, PITCH_NORM );
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/glauncher.wav", 0.7, ATTN_NORM, 0, PITCH_NORM );
//Only play the weapon anims if I shot it.
if( EV_IsLocal( idx ) )
{
gEngfuncs.pEventAPI->EV_WeaponAnimation( RPG_FIRE2, 1 );
gEngfuncs.pEventAPI->EV_WeaponAnimation( RPG_LAUNCH, 0 );
V_PunchAxis( 0, -5.0 );
}

7
cl_dll/ev_hldm.h

@ -17,7 +17,7 @@ typedef enum @@ -17,7 +17,7 @@ typedef enum
BULLET_PLAYER_357, // python
BULLET_PLAYER_BUCKSHOT, // shotgun
BULLET_PLAYER_CROWBAR, // crowbar swipe
BULLET_PLAYER_SNIPER,
BULLET_MONSTER_9MM,
BULLET_MONSTER_MP5,
BULLET_MONSTER_12MM
@ -30,11 +30,10 @@ enum glock_e @@ -30,11 +30,10 @@ enum glock_e
GLOCK_IDLE3,
GLOCK_SHOOT,
GLOCK_SHOOT_EMPTY,
GLOCK_RELOAD_EMPTY,
GLOCK_RELOAD,
GLOCK_RELOAD_NOT_EMPTY,
GLOCK_DRAW,
GLOCK_HOLSTER,
GLOCK_ADD_SILENCER
GLOCK_EMPTY_IDLE
};
enum shotgun_e

2
cl_dll/hud.cpp

@ -227,6 +227,7 @@ void CHud::Init( void ) @@ -227,6 +227,7 @@ void CHud::Init( void )
m_AmmoSecondary.Init();
m_TextMessage.Init();
m_StatusIcons.Init();
m_Scope.Init();
m_MOTD.Init();
m_Scoreboard.Init();
@ -396,6 +397,7 @@ void CHud::VidInit( void ) @@ -396,6 +397,7 @@ void CHud::VidInit( void )
m_AmmoSecondary.VidInit();
m_TextMessage.VidInit();
m_StatusIcons.VidInit();
m_Scope.VidInit();
m_Scoreboard.VidInit();
m_MOTD.VidInit();
}

34
cl_dll/hud.h

@ -556,6 +556,39 @@ private: @@ -556,6 +556,39 @@ private:
icon_sprite_t m_IconList[MAX_ICONSPRITES];
};
//
//-----------------------------------------------------
//
class CHudScope : public CHudBase
{
public:
virtual int Init( void );
virtual int VidInit( void );
virtual int Draw( float fTime );
virtual void Reset( void );
int MsgFunc_Scope( const char *pszName, int iSize, void *pbuf );
private:
enum
{
SCOPE_U_L = 0, // Up - Left
SCOPE_U_M_L, // Up - Middle - Left
SCOPE_U_M_R, // Up - Middle - Right
SCOPE_U_R, // Up - Right
SCOPE_M_L, // Middle - Left
SCOPE_M_R, // Middle - right
SCOPE_L_L, // Low - left
SCOPE_L_M_L, // Low - middle - left
SCOPE_L_M_R, // Low - middle - right
SCOPE_L_R, // Low - right
SCOPE_HSPRITE_COUNT // <-- Must be the last.
};
HSPRITE m_scopes[SCOPE_HSPRITE_COUNT];
int m_ScopeSize;
};
//
//-----------------------------------------------------
//
@ -631,6 +664,7 @@ public: @@ -631,6 +664,7 @@ public:
CHudAmmoSecondary m_AmmoSecondary;
CHudTextMessage m_TextMessage;
CHudStatusIcons m_StatusIcons;
CHudScope m_Scope;
CHudScoreboard m_Scoreboard;
CHudMOTD m_MOTD;

100
dlls/TheGate/command.cpp

@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
/***
*
* 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 "customentity.h"
#include "effects.h"
#include "weapons.h"
class CTriggerCommand : public CPointEntity
{
public:
void Spawn(void);
void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
private:
void PlayMP3(CBaseEntity* pClient, const char* song);
};
LINK_ENTITY_TO_CLASS(trigger_command, CTriggerCommand);
void CTriggerCommand::Spawn(void)
{
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects = 0;
pev->frame = 0;
}
void CTriggerCommand::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
if (!pActivator || !pActivator->IsNetClient())
return;
const char* command = STRING(pev->netname);
if (!command || !*command)
return;
// ALERT(at_console, "%s with command \"%s\"\n", STRING(pev->classname), command);
char* str = NULL;
if ((str = (char*)strstr(command, "playmp3")) != NULL)
{
int pchlen = 0;
int extlen = 3; // "mp3" excluding NULL terminator.
int ideallen = 0;
char* pch = NULL, *lastpch = NULL;
char* song = NULL;
pch = strtok(str, " .");
while (pch)
{
pchlen = strlen(pch);
ideallen = (pchlen <= extlen) ? pchlen : extlen;
if (strncmp(pch, "mp3", sizeof(char) * ideallen) == 0)
{
pch = NULL;
}
else
{
lastpch = pch;
pch = strtok(NULL, " .");
}
}
song = lastpch;
PlayMP3(pActivator, song);
}
UTIL_Remove(this);
}
void CTriggerCommand::PlayMP3(CBaseEntity* pClient, const char* song)
{
ASSERT(pClient != NULL);
char cmd[128];
sprintf(cmd, "play media/%s.mp3\n", song);
CLIENT_COMMAND(ENT(pClient->pev),cmd);
}

103
dlls/TheGate/scientist2.cpp

@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
/***
*
* 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 "util.h"
#include "cbase.h"
#include "monsters.h"
#include "talkmonster.h"
#include "schedule.h"
#include "defaultai.h"
#include "scripted.h"
#include "animation.h"
#include "soundent.h"
#include "scientist.h"
class CScientist2 : public CScientist
{
public:
void Spawn(void);
void Precache(void);
BOOL CanHeal(void) { return FALSE; }
MONSTERSTATE GetIdealState(void);
void DeathSound(void) {}
void PainSound(void) {}
};
LINK_ENTITY_TO_CLASS(monster_scientist2, CScientist2);
void CScientist2::Spawn(void)
{
Precache();
SET_MODEL(ENT(pev), "models/scientist2.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.scientistHealth;
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 scientists will notice player and say hello
m_MonsterState = MONSTERSTATE_NONE;
// m_flDistTooFar = 256.0;
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_OPEN_DOORS | bits_CAP_AUTO_DOORS | bits_CAP_USE;
// White hands
pev->skin = 0;
if (pev->body == -1)
{// -1 chooses a random head
pev->body = RANDOM_LONG(0, NUM_SCIENTIST_HEADS - 1);// pick a head, any head
}
MonsterInit();
SetUse(&CScientist2::FollowerUse);
}
void CScientist2::Precache(void)
{
PRECACHE_MODEL("models/scientist2.mdl");
// every new scientist must call this, otherwise
// when a level is loaded, nobody will talk (time is reset to 0)
TalkInit();
CTalkMonster::Precache();
}
MONSTERSTATE CScientist2::GetIdealState(void)
{
switch (m_MonsterState)
{
case MONSTERSTATE_ALERT:
case MONSTERSTATE_IDLE:
return CScientist::GetIdealState();
case MONSTERSTATE_COMBAT:
m_IdealMonsterState = MONSTERSTATE_ALERT;
return CScientist::GetIdealState();
default:
return CScientist::GetIdealState();
}
return CScientist::GetIdealState();
}

14
dlls/cbase.cpp

@ -135,6 +135,20 @@ int DispatchSpawn( edict_t *pent ) @@ -135,6 +135,20 @@ int DispatchSpawn( edict_t *pent )
if( pEntity )
{
//
// The Gate:
//
// Prevent level shutting down due to engine limitation.
//
if( FStrEq( STRING( gpGlobals->mapname ), "gate18" ) )
{
if( FStringNull( pEntity->pev->targetname ) )
{
if( FClassnameIs( pEntity->pev, "monster_furniture" ) )
return 0;
}
}
// Initialize these or entities who don't link to the world won't have anything in here
pEntity->pev->absmin = pEntity->pev->origin - Vector( 1, 1, 1 );
pEntity->pev->absmax = pEntity->pev->origin + Vector( 1, 1, 1 );

3
dlls/combat.cpp

@ -1535,6 +1535,9 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi @@ -1535,6 +1535,9 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi
case BULLET_PLAYER_357:
pEntity->TraceAttack( pevAttacker, gSkillData.plrDmg357, vecDir, &tr, DMG_BULLET );
break;
case BULLET_PLAYER_SNIPER:
pEntity->TraceAttack( pevAttacker, gSkillData.plrDmgCrossbowClient, vecDir, &tr, DMG_BULLET );
break;
case BULLET_NONE: // FIX
pEntity->TraceAttack( pevAttacker, 50, vecDir, &tr, DMG_CLUB );
TEXTURETYPE_PlaySound( &tr, vecSrc, vecEnd, iBulletType );

96
dlls/crossbow.cpp

@ -236,6 +236,8 @@ void CCrossbowBolt::ExplodeThink( void ) @@ -236,6 +236,8 @@ void CCrossbowBolt::ExplodeThink( void )
}
#endif
extern int gmsgScope;
enum crossbow_e
{
CROSSBOW_IDLE1 = 0, // full
@ -393,68 +395,50 @@ void CCrossbow::FireSniperBolt() @@ -393,68 +395,50 @@ void CCrossbow::FireSniperBolt()
void CCrossbow::FireBolt()
{
TraceResult tr;
// 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 = QUIET_GUN_VOLUME;
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME;
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;
m_iClip--;
int flags;
#if defined( CLIENT_WEAPONS )
flags = FEV_NOTHOST;
#else
flags = 0;
#endif
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 );
m_pPlayer->pev->effects = (int)( m_pPlayer->pev->effects ) | EF_MUZZLEFLASH;
// 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();
Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_2DEGREES );
Vector vecDir = m_pPlayer->FireBulletsPlayer( 1, vecSrc, vecAiming, Vector( 0, 0, 0 ), 8192, BULLET_PLAYER_SNIPER, 2, 0, m_pPlayer->pev, m_pPlayer->random_seed );
anglesAim.x = -anglesAim.x;
Vector vecSrc = m_pPlayer->GetGunPosition() - gpGlobals->v_up * 2;
Vector vecDir = gpGlobals->v_forward;
#ifndef CLIENT_DLL
CCrossbowBolt *pBolt = CCrossbowBolt::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;
int flags;
#if defined( CLIENT_WEAPONS )
flags = FEV_NOTHOST;
#else
flags = 0;
#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 );
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 );
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75;
m_flNextPrimaryAttack = GetNextAttackDelay( 2.2 );
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75;
if( m_flNextPrimaryAttack < UTIL_WeaponTimeBase() )
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 2.2;
if( m_iClip != 0 )
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5.0;
else
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.75;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
}
void CCrossbow::SecondaryAttack()
@ -470,6 +454,12 @@ void CCrossbow::SecondaryAttack() @@ -470,6 +454,12 @@ void CCrossbow::SecondaryAttack()
m_fInZoom = 1;
}
#ifndef CLIENT_DLL
MESSAGE_BEGIN( MSG_ONE, gmsgScope, NULL, m_pPlayer->pev );
WRITE_BYTE( m_fInZoom );
MESSAGE_END();
#endif
pev->nextthink = UTIL_WeaponTimeBase() + 0.1;
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.0;
}
@ -484,7 +474,7 @@ void CCrossbow::Reload( void ) @@ -484,7 +474,7 @@ void CCrossbow::Reload( void )
SecondaryAttack();
}
if( DefaultReload( 5, CROSSBOW_RELOAD, 4.5 ) )
if( DefaultReload( 5, CROSSBOW_RELOAD, 3.2 ) )
{
EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/xbow_reload1.wav", RANDOM_FLOAT( 0.95, 1.0 ), ATTN_NORM, 0, 93 + RANDOM_LONG( 0, 0xF ) );
}
@ -500,30 +490,14 @@ void CCrossbow::WeaponIdle( void ) @@ -500,30 +490,14 @@ void CCrossbow::WeaponIdle( void )
{
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 );
if( flRand <= 0.75 )
{
if( m_iClip )
{
SendWeaponAnim( CROSSBOW_IDLE1 );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 121.0 / 15.0;
}
else
{
SendWeaponAnim( CROSSBOW_IDLE2 );
}
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
}
else
{
if( m_iClip )
{
SendWeaponAnim( CROSSBOW_FIDGET1 );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 90.0 / 30.0;
}
else
{
SendWeaponAnim( CROSSBOW_FIDGET2 );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 80.0 / 30.0;
}
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 121.0 / 15.0;
}
}
}

27
dlls/handgrenade.cpp

@ -26,13 +26,14 @@ @@ -26,13 +26,14 @@
enum handgrenade_e
{
HANDGRENADE_IDLE = 0,
HANDGRENADE_FIDGET,
HANDGRENADE_DRAW,
HANDGRENADE_PINPULL,
HANDGRENADE_THROW1, // toss
HANDGRENADE_THROW2, // medium
HANDGRENADE_THROW3, // hard
HANDGRENADE_HOLSTER,
HANDGRENADE_DRAW
HANDGRENADE_THROW,
HANDGRENADE_EXPLODING_IDLE,
HANDGRENADE_EXPLODING_DRAW,
HANDGRENADE_EXPLODING_PINPULL,
HANDGRENADE_EXPLODING_THROW
};
LINK_ENTITY_TO_CLASS( weapon_handgrenade, CHandGrenade )
@ -152,18 +153,7 @@ void CHandGrenade::WeaponIdle( void ) @@ -152,18 +153,7 @@ void CHandGrenade::WeaponIdle( void )
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 );
}
SendWeaponAnim( HANDGRENADE_THROW );
// player "shoot" animation
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
@ -206,6 +196,9 @@ void CHandGrenade::WeaponIdle( void ) @@ -206,6 +196,9 @@ void CHandGrenade::WeaponIdle( void )
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
{
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 31.0 / 10.0;
SendWeaponAnim( HANDGRENADE_IDLE );
int iAnim;
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 );
if( flRand <= 0.75 )

4
dlls/hgrunt.cpp

@ -267,6 +267,10 @@ int CHGrunt::IRelationship( CBaseEntity *pTarget ) @@ -267,6 +267,10 @@ int CHGrunt::IRelationship( CBaseEntity *pTarget )
return R_NM;
}
if( FClassnameIs( pTarget->pev, "monster_houndeye" ) )
{
return R_NO;
}
return CSquadMonster::IRelationship( pTarget );
}

28
dlls/houndeye.cpp

@ -32,7 +32,7 @@ extern CGraph WorldGraph; @@ -32,7 +32,7 @@ extern CGraph WorldGraph;
// houndeye does 20 points of damage spread over a sphere 384 units in diameter, and each additional
// squad member increases the BASE damage by 110%, per the spec.
#define HOUNDEYE_MAX_SQUAD_SIZE 4
#define HOUNDEYE_MAX_ATTACK_RADIUS 384
#define HOUNDEYE_MAX_ATTACK_RADIUS 144
#define HOUNDEYE_SQUAD_BONUS (float)1.1
#define HOUNDEYE_EYE_FRAMES 4 // how many different switchable maps for the eye
@ -98,6 +98,7 @@ public: @@ -98,6 +98,7 @@ public:
BOOL FCanActiveIdle( void );
Schedule_t *GetScheduleOfType( int Type );
Schedule_t *GetSchedule( void );
int IRelationship(CBaseEntity *pTarget);
int Save( CSave &save );
int Restore( CRestore &restore );
@ -290,8 +291,17 @@ void CHoundeye::HandleAnimEvent( MonsterEvent_t *pEvent ) @@ -290,8 +291,17 @@ void CHoundeye::HandleAnimEvent( MonsterEvent_t *pEvent )
break;
}
case HOUND_AE_THUMP:
// emit the shockwaves
SonicAttack();
{
// SOUND HERE!
CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.bullsquidDmgBite, DMG_SLASH );
if( pHurt )
{
pHurt->pev->punchangle.x = 5;
pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_forward * 16;
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_up * 2;
}
}
break;
case HOUND_AE_ANGERSOUND1:
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "houndeye/he_pain3.wav", 1, ATTN_NORM );
@ -323,7 +333,7 @@ void CHoundeye::Spawn() @@ -323,7 +333,7 @@ void CHoundeye::Spawn()
pev->solid = SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_STEP;
m_bloodColor = BLOOD_COLOR_YELLOW;
m_bloodColor = BLOOD_COLOR_RED;
pev->effects = 0;
pev->health = gSkillData.houndeyeHealth;
pev->yaw_speed = 5;//!!! should we put this in the monster's changeanim function since turn rates may vary with state/anim?
@ -1293,3 +1303,13 @@ Schedule_t *CHoundeye::GetSchedule( void ) @@ -1293,3 +1303,13 @@ Schedule_t *CHoundeye::GetSchedule( void )
return CSquadMonster::GetSchedule();
}
int CHoundeye::IRelationship( CBaseEntity *pTarget )
{
if( FClassnameIs( pTarget->pev, "monster_human_grunt" ) || FClassnameIs( pTarget->pev, "monster_grunt_repel" ) )
{
return R_NO;
}
return CSquadMonster::IRelationship( pTarget );
}

10
dlls/mp5.cpp

@ -173,10 +173,6 @@ void CMP5::PrimaryAttack() @@ -173,10 +173,6 @@ void CMP5::PrimaryAttack()
#endif
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usMP5, 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 );
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
if( m_flNextPrimaryAttack < UTIL_WeaponTimeBase() )
@ -230,10 +226,6 @@ void CMP5::SecondaryAttack( void ) @@ -230,10 +226,6 @@ void CMP5::SecondaryAttack( void )
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1;
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5;// idle pretty soon after shooting.
if( !m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] )
// HEV suit - indicate out of ammo condition
m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 );
}
void CMP5::Reload( void )
@ -241,7 +233,7 @@ void CMP5::Reload( void ) @@ -241,7 +233,7 @@ void CMP5::Reload( void )
if( m_pPlayer->ammo_9mm <= 0 )
return;
DefaultReload( MP5_MAX_CLIP, MP5_RELOAD, 1.5 );
DefaultReload( MP5_MAX_CLIP, MP5_RELOAD, 2.5 );
}
void CMP5::WeaponIdle( void )

15
dlls/player.cpp

@ -115,6 +115,7 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] = @@ -115,6 +115,7 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] =
DEFINE_FIELD( CBasePlayer, m_pTank, FIELD_EHANDLE ),
DEFINE_FIELD( CBasePlayer, m_iHideHUD, FIELD_INTEGER ),
DEFINE_FIELD( CBasePlayer, m_iFOV, FIELD_INTEGER ),
DEFINE_FIELD( CBasePlayer, m_bUpdatePlayerModel, FIELD_BOOLEAN ),
//DEFINE_FIELD( CBasePlayer, m_fDeadTime, FIELD_FLOAT ), // only used in multiplayer games
//DEFINE_FIELD( CBasePlayer, m_fGameHUDInitialized, FIELD_INTEGER ), // only used in multiplayer games
@ -184,6 +185,8 @@ int gmsgTeamNames = 0; @@ -184,6 +185,8 @@ int gmsgTeamNames = 0;
int gmsgStatusText = 0;
int gmsgStatusValue = 0;
int gmsgScope = 0;
void LinkUserMessages( void )
{
// Already taken care of?
@ -228,6 +231,8 @@ void LinkUserMessages( void ) @@ -228,6 +231,8 @@ void LinkUserMessages( void )
gmsgStatusText = REG_USER_MSG( "StatusText", -1 );
gmsgStatusValue = REG_USER_MSG( "StatusValue", 3 );
gmsgScope = REG_USER_MSG( "Scope", 1 );
}
LINK_ENTITY_TO_CLASS( player, CBasePlayer )
@ -2499,6 +2504,12 @@ void CBasePlayer::PostThink() @@ -2499,6 +2504,12 @@ void CBasePlayer::PostThink()
m_afButtonLast = pev->button;
pt_end:
if( m_bUpdatePlayerModel )
{
CLIENT_COMMAND( edict(), "model player\n" );
m_bUpdatePlayerModel = FALSE;
}
#if defined( CLIENT_WEAPONS )
// Decay timers on weapons
// go through all of the weapons and make a list of the ones to pack
@ -2775,6 +2786,8 @@ void CBasePlayer::Spawn( void ) @@ -2775,6 +2786,8 @@ void CBasePlayer::Spawn( void )
m_flNextChatTime = gpGlobals->time;
m_bUpdatePlayerModel = FALSE;
g_pGameRules->PlayerSpawn( this );
}
@ -2898,6 +2911,8 @@ int CBasePlayer::Restore( CRestore &restore ) @@ -2898,6 +2911,8 @@ int CBasePlayer::Restore( CRestore &restore )
// Barring that, we clear it out here instead of using the incorrect restored time value.
m_flNextAttack = UTIL_WeaponTimeBase();
#endif
m_bUpdatePlayerModel = TRUE;
return status;
}

2
dlls/player.h

@ -308,6 +308,8 @@ public: @@ -308,6 +308,8 @@ public:
char m_SbarString1[ SBAR_STRING_SIZE ];
float m_flNextChatTime;
BOOL m_bUpdatePlayerModel;
};
#define AUTOAIM_2DEGREES 0.0348994967025

157
dlls/rpg.cpp

@ -26,15 +26,13 @@ @@ -26,15 +26,13 @@
enum rpg_e
{
RPG_IDLE = 0,
RPG_FIDGET,
RPG_RELOAD, // to reload
RPG_FIRE2, // to empty
RPG_HOLSTER1, // loaded
RPG_DRAW1, // loaded
RPG_HOLSTER2, // unloaded
RPG_DRAW_UL, // unloaded
RPG_IDLE_UL, // unloaded idle
RPG_FIDGET_UL // unloaded fidget
RPG_DRAW1,
RPG_AIMED,
RPG_LAUNCH,
RPG_DOWN_TO_UP,
RPG_UP_TO_DOWN,
RPG_RELOAD_AIMED,
RPG_RELOAD_IDLE
};
LINK_ENTITY_TO_CLASS( weapon_rpg, CRpg )
@ -132,16 +130,16 @@ void CRpgRocket::Spawn( void ) @@ -132,16 +130,16 @@ void CRpgRocket::Spawn( void )
pev->classname = MAKE_STRING( "rpg_rocket" );
SetThink( &CRpgRocket::IgniteThink );
SetTouch( &CGrenade::ExplodeTouch );
SetTouch( &CRpgRocket::ExplodeTouch );
pev->angles.x -= 30;
pev->angles.x -= 1;
UTIL_MakeVectors( pev->angles );
pev->angles.x = -( pev->angles.x + 30 );
pev->angles.x = -( pev->angles.x + 1 );
pev->velocity = gpGlobals->v_forward * 250;
pev->gravity = 0.5;
pev->gravity = 0.0;
pev->nextthink = gpGlobals->time + 0.4;
pev->nextthink = gpGlobals->time + 0.05;
pev->dmg = gSkillData.plrDmgRPG;
}
@ -194,8 +192,58 @@ void CRpgRocket::IgniteThink( void ) @@ -194,8 +192,58 @@ void CRpgRocket::IgniteThink( void )
m_flIgniteTime = gpGlobals->time;
// set to follow laser spot
SetThink( &CRpgRocket::FollowThink );
// Move in forward direction. Ignore guiding.
SetThink( &CRpgRocket::FlyThink );
pev->nextthink = gpGlobals->time + 0.1;
}
void CRpgRocket::FlyThink( void )
{
Vector vecTarget;
UTIL_MakeAimVectors( pev->angles );
vecTarget = gpGlobals->v_forward;
pev->angles = UTIL_VecToAngles( vecTarget );
// this acceleration and turning math is totally wrong, but it seems to respond well so don't change it.
float flSpeed = pev->velocity.Length();
if( gpGlobals->time - m_flIgniteTime < 1.0 )
{
pev->velocity = pev->velocity * 0.2 + vecTarget * ( flSpeed * 0.8 + 400 );
if( pev->waterlevel == 3 )
{
// go slow underwater
if( pev->velocity.Length() > 300 )
{
pev->velocity = pev->velocity.Normalize() * 300;
}
UTIL_BubbleTrail( pev->origin - pev->velocity * 0.1, pev->origin, 4 );
}
else
{
if( pev->velocity.Length() > 2000 )
{
pev->velocity = pev->velocity.Normalize() * 2000;
}
}
}
else
{
if( pev->effects & EF_LIGHT )
{
pev->effects = 0;
STOP_SOUND( ENT( pev ), CHAN_VOICE, "weapons/rocket1.wav" );
}
pev->velocity = pev->velocity * 0.2 + vecTarget * flSpeed * 0.798;
if( pev->waterlevel == 0 && pev->velocity.Length() < 1500 )
{
Detonate();
}
}
// ALERT( at_console, "%.0f\n", flSpeed );
pev->nextthink = gpGlobals->time + 0.1;
}
@ -299,23 +347,8 @@ void CRpg::Reload( void ) @@ -299,23 +347,8 @@ void CRpg::Reload( void )
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
if( m_cActiveRockets && m_fSpotActive )
{
// no reloading when there are active missiles tracking the designator.
// ward off future autoreload attempts by setting next attack time into the future for a bit.
return;
}
#ifndef CLIENT_DLL
if( m_pSpot && m_fSpotActive )
{
m_pSpot->Suspend( 2.1 );
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 2.1;
}
#endif
if( m_iClip == 0 )
iResult = DefaultReload( RPG_MAX_CLIP, RPG_RELOAD, 2 );
iResult = DefaultReload( RPG_MAX_CLIP, RPG_RELOAD_IDLE, 3.5 );
if( iResult )
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
@ -327,7 +360,7 @@ void CRpg::Spawn() @@ -327,7 +360,7 @@ void CRpg::Spawn()
m_iId = WEAPON_RPG;
SET_MODEL( ENT( pev ), "models/w_rpg.mdl" );
m_fSpotActive = 1;
m_fSpotActive = 0;
#ifdef CLIENT_DLL
if( bIsMultiplayer() )
@ -394,22 +427,11 @@ int CRpg::AddToPlayer( CBasePlayer *pPlayer ) @@ -394,22 +427,11 @@ int CRpg::AddToPlayer( CBasePlayer *pPlayer )
BOOL CRpg::Deploy()
{
if( m_iClip == 0 )
{
return DefaultDeploy( "models/v_rpg.mdl", "models/p_rpg.mdl", RPG_DRAW_UL, "rpg" );
}
return DefaultDeploy( "models/v_rpg.mdl", "models/p_rpg.mdl", RPG_DRAW1, "rpg" );
}
BOOL CRpg::CanHolster( void )
{
if( m_fSpotActive && m_cActiveRockets )
{
// can't put away while guiding a missile.
return FALSE;
}
return TRUE;
}
@ -418,16 +440,6 @@ void CRpg::Holster( int skiplocal /* = 0 */ ) @@ -418,16 +440,6 @@ void CRpg::Holster( int skiplocal /* = 0 */ )
m_fInReload = FALSE;// cancel any reload in progress.
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
SendWeaponAnim( RPG_HOLSTER1 );
#ifndef CLIENT_DLL
if( m_pSpot )
{
m_pSpot->Killed( NULL, GIB_NEVER );
m_pSpot = NULL;
}
#endif
}
void CRpg::PrimaryAttack()
@ -471,27 +483,14 @@ void CRpg::PrimaryAttack() @@ -471,27 +483,14 @@ void CRpg::PrimaryAttack()
PlayEmptySound();
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.2;
}
UpdateSpot();
}
void CRpg::SecondaryAttack()
{
m_fSpotActive = !m_fSpotActive;
#ifndef CLIENT_DLL
if( !m_fSpotActive && m_pSpot )
{
m_pSpot->Killed( NULL, GIB_NORMAL );
m_pSpot = NULL;
}
#endif
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.2;
}
void CRpg::WeaponIdle( void )
{
UpdateSpot();
ResetEmptySound();
if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
@ -499,28 +498,8 @@ void CRpg::WeaponIdle( void ) @@ -499,28 +498,8 @@ void CRpg::WeaponIdle( void )
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
{
int iAnim;
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 );
if( flRand <= 0.75 || m_fSpotActive )
{
if( m_iClip == 0 )
iAnim = RPG_IDLE_UL;
else
iAnim = RPG_IDLE;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 90.0 / 15.0;
}
else
{
if( m_iClip == 0 )
iAnim = RPG_FIDGET_UL;
else
iAnim = RPG_FIDGET;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3.0;
}
SendWeaponAnim( iAnim );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0 / 20.0;
SendWeaponAnim( RPG_IDLE );
}
else
{

95
dlls/scientist.cpp

@ -26,16 +26,7 @@ @@ -26,16 +26,7 @@
#include "scripted.h"
#include "animation.h"
#include "soundent.h"
#define NUM_SCIENTIST_HEADS 4 // four heads available for scientist model
enum
{
HEAD_GLASSES = 0,
HEAD_EINSTEIN = 1,
HEAD_LUTHER = 2,
HEAD_SLICK = 3
};
#include "scientist.h"
enum
{
@ -68,55 +59,6 @@ enum @@ -68,55 +59,6 @@ enum
//=======================================================
// Scientist
//=======================================================
class CScientist : public CTalkMonster
{
public:
void Spawn( void );
void Precache( void );
void SetYawSpeed( void );
int Classify( void );
void HandleAnimEvent( MonsterEvent_t *pEvent );
void RunTask( Task_t *pTask );
void StartTask( Task_t *pTask );
int ObjectCaps( void ) { return CTalkMonster::ObjectCaps() | FCAP_IMPULSE_USE; }
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
virtual int FriendNumber( int arrayNumber );
void SetActivity( Activity newActivity );
Activity GetStoppedActivity( void );
int ISoundMask( void );
void DeclineFollowing( void );
float CoverRadius( void ) { return 1200; } // Need more room for cover because scientists want to get far away!
BOOL DisregardEnemy( CBaseEntity *pEnemy ) { return !pEnemy->IsAlive() || ( gpGlobals->time - m_fearTime ) > 15; }
BOOL CanHeal( void );
void Heal( void );
void Scream( 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 Killed( entvars_t *pevAttacker, int iGib );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
CUSTOM_SCHEDULES
private:
float m_painTime;
float m_healTime;
float m_fearTime;
};
LINK_ENTITY_TO_CLASS( monster_scientist, CScientist )
@ -1082,20 +1024,6 @@ int CScientist::FriendNumber( int arrayNumber ) @@ -1082,20 +1024,6 @@ int CScientist::FriendNumber( int arrayNumber )
//=========================================================
// Dead Scientist PROP
//=========================================================
class CDeadScientist : public CBaseMonster
{
public:
void Spawn( void );
int Classify( void )
{
return CLASS_HUMAN_PASSIVE;
}
void KeyValue( KeyValueData *pkvd );
int m_iPose;// which sequence to display
static char *m_szPoses[7];
};
char *CDeadScientist::m_szPoses[] =
{
"lying_on_back",
@ -1160,27 +1088,6 @@ void CDeadScientist::Spawn() @@ -1160,27 +1088,6 @@ void CDeadScientist::Spawn()
//=========================================================
// Sitting Scientist PROP
//=========================================================
class CSittingScientist : public CScientist // kdb: changed from public CBaseMonster so he can speak
{
public:
void Spawn( void );
void Precache( void );
void EXPORT SittingThink( void );
int Classify( void );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
virtual void SetAnswerQuestion( CTalkMonster *pSpeaker );
int FriendNumber( int arrayNumber );
int FIdleSpeak( void );
int m_baseSequence;
int m_headTurn;
float m_flResponseDelay;
};
LINK_ENTITY_TO_CLASS( monster_sitting_scientist, CSittingScientist )
TYPEDESCRIPTION CSittingScientist::m_SaveData[] =

119
dlls/scientist.h

@ -0,0 +1,119 @@ @@ -0,0 +1,119 @@
/***
*
* 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.
*
****/
#ifndef SCIENTIST_H
#define SCIENTIST_H
#if defined ( THEGATE_DLL )
#define NUM_SCIENTIST_HEADS 4 // four heads available for scientist model
enum { HEAD_GLASSES = 0, HEAD_EINSTEIN = 1, HEAD_LUTHER = 2, HEAD_SLICK = 3 };
//=======================================================
// Scientist
//=======================================================
class CScientist : public CTalkMonster
{
public:
void Spawn( void );
void Precache( void );
void SetYawSpeed( void );
int Classify ( void );
void HandleAnimEvent( MonsterEvent_t *pEvent );
void RunTask( Task_t *pTask );
void StartTask( Task_t *pTask );
int ObjectCaps( void ) { return CTalkMonster :: ObjectCaps() | FCAP_IMPULSE_USE; }
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
virtual int FriendNumber( int arrayNumber );
void SetActivity ( Activity newActivity );
Activity GetStoppedActivity( void );
int ISoundMask( void );
void DeclineFollowing( void );
float CoverRadius( void ) { return 1200; } // Need more room for cover because scientists want to get far away!
BOOL DisregardEnemy( CBaseEntity *pEnemy ) { return !pEnemy->IsAlive() || (gpGlobals->time - m_fearTime) > 15; }
BOOL CanHeal( void );
void Heal( void );
void Scream( 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 Killed( entvars_t *pevAttacker, int iGib );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
CUSTOM_SCHEDULES;
private:
float m_painTime;
float m_healTime;
float m_fearTime;
};
//=========================================================
// Dead Scientist PROP
//=========================================================
class CDeadScientist : public CBaseMonster
{
public:
void Spawn(void);
int Classify(void) { return CLASS_HUMAN_PASSIVE; }
void KeyValue(KeyValueData *pkvd);
int m_iPose;// which sequence to display
static char *m_szPoses[7];
};
//=========================================================
// Sitting Scientist PROP
//=========================================================
class CSittingScientist : public CScientist // kdb: changed from public CBaseMonster so he can speak
{
public:
void Spawn( void );
void Precache( void );
void EXPORT SittingThink( void );
int Classify ( void );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
virtual void SetAnswerQuestion( CTalkMonster *pSpeaker );
int FriendNumber( int arrayNumber );
int FIdleSpeak ( void );
int m_baseSequence;
int m_headTurn;
float m_flResponseDelay;
};
#endif // defined ( THEGATE_DLL )
#endif // SCIENTIST_H

14
dlls/scripted.cpp

@ -1157,11 +1157,23 @@ public: @@ -1157,11 +1157,23 @@ public:
void Spawn( void );
void Die( void );
int Classify( void );
virtual int ObjectCaps( void ) { return (CBaseMonster::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); }
virtual int ObjectCaps( void );
};
LINK_ENTITY_TO_CLASS( monster_furniture, CFurniture )
int CFurniture::ObjectCaps( void )
{
int caps = ( CBaseMonster::ObjectCaps() & ~FCAP_ACROSS_TRANSITION );
if( FStrEq( STRING( gpGlobals->mapname ), "gate18" ) )
{
caps |= FCAP_DONT_SAVE;
}
return caps;
}
//=========================================================
// Furniture is killed
//=========================================================

14
dlls/triggers.cpp

@ -779,6 +779,20 @@ void CTargetCDAudio::Play( void ) @@ -779,6 +779,20 @@ void CTargetCDAudio::Play( void )
void CTriggerHurt::Spawn( void )
{
//
// The Gate:
//
// Remove to prevent a crash.
//
if( FStrEq( STRING( gpGlobals->mapname ), "tombtest2" ) )
{
if( !FStringNull( pev->targetname ) && FStrEq( STRING( pev->targetname ), "secondspikes" ) )
{
UTIL_Remove( this );
return;
}
}
InitTrigger();
SetTouch( &CBaseTrigger::HurtTouch );

1
dlls/weapons.cpp

@ -169,6 +169,7 @@ void DecalGunshot( TraceResult *pTrace, int iBulletType ) @@ -169,6 +169,7 @@ void DecalGunshot( TraceResult *pTrace, int iBulletType )
case BULLET_MONSTER_MP5:
case BULLET_PLAYER_BUCKSHOT:
case BULLET_PLAYER_357:
case BULLET_PLAYER_SNIPER:
default:
// smoke and decal
UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) );

4
dlls/weapons.h

@ -174,7 +174,7 @@ typedef enum @@ -174,7 +174,7 @@ typedef enum
BULLET_PLAYER_357, // python
BULLET_PLAYER_BUCKSHOT, // shotgun
BULLET_PLAYER_CROWBAR, // crowbar swipe
BULLET_PLAYER_SNIPER,
BULLET_MONSTER_9MM,
BULLET_MONSTER_MP5,
BULLET_MONSTER_12MM
@ -710,6 +710,8 @@ public: @@ -710,6 +710,8 @@ public:
static TYPEDESCRIPTION m_SaveData[];
void Spawn( void );
void Precache( void );
void EXPORT FlyThink( void );
void EXPORT FollowThink( void );
void EXPORT IgniteThink( void );
void EXPORT RocketTouch( CBaseEntity *pOther );

Loading…
Cancel
Save