From 82aca8bec800eb6b849b9269ffcb6146e3871dcf Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sat, 19 Nov 2016 20:13:49 +0500 Subject: [PATCH] Merge Uncle Mike's patches for "Blue Shift". --- cl_dll/ammo.cpp | 32 +++++---- cl_dll/health.cpp | 4 +- cl_dll/hud.h | 4 +- dlls/effects.cpp | 120 +++++++++++++++++++++++++++++++ dlls/genericmonster.cpp | 11 ++- dlls/items.cpp | 73 +++++++++++++++++-- dlls/scientist.cpp | 155 +++++++++++++++++++++++++++------------- dlls/talkmonster.cpp | 3 +- dlls/triggers.cpp | 21 +++++- 9 files changed, 348 insertions(+), 75 deletions(-) diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index 988bd6fa..6b02af61 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -305,6 +305,9 @@ void CHudAmmo::Reset( void ) gHR.Reset(); //VidInit(); + static wrect_t nullrc; + SetCrosshair( 0, nullrc, 0, 0, 0 ); //reset crosshair + m_pWeapon = NULL; //reset last weapon } int CHudAmmo::VidInit( void ) @@ -604,22 +607,25 @@ int CHudAmmo::MsgFunc_CurWeapon( const char *pszName, int iSize, void *pbuf ) m_pWeapon = pWeapon; - if( gHUD.m_iFOV >= 90 ) - { - // normal crosshairs - if( fOnTarget && m_pWeapon->hAutoaim ) - SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255 ); - else - SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 ); - } - else + if( !( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) ) { - // zoomed crosshairs - if( fOnTarget && m_pWeapon->hZoomedAutoaim ) - SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255 ); + if( gHUD.m_iFOV >= 90 ) + { + // normal crosshairs + if( fOnTarget && m_pWeapon->hAutoaim ) + SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255 ); + else + SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 ); + } else - SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255 ); + { + // zoomed crosshairs + if( fOnTarget && m_pWeapon->hZoomedAutoaim ) + SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255 ); + else + SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255 ); + } } m_fFade = 200.0f; //!!! diff --git a/cl_dll/health.cpp b/cl_dll/health.cpp index d4979c35..d66e81ad 100644 --- a/cl_dll/health.cpp +++ b/cl_dll/health.cpp @@ -231,7 +231,9 @@ int CHudHealth::Draw( float flTime ) int iHeight = gHUD.m_iFontHeight; int iWidth = HealthWidth / 10; - FillRGBA( x, y, iWidth, iHeight, 255, 160, 0, a ); + + UnpackRGB( r, g, b, RGB_YELLOWISH ); + FillRGBA( x, y, iWidth, iHeight, r, g, b, a ); } DrawDamage( flTime ); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index ec236003..1884d413 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -20,8 +20,8 @@ // CHud handles the message, calculation, and drawing the HUD // -#define RGB_YELLOWISH 0x00FFA000 //255,160,0 -#define RGB_REDISH 0x00FF1010 //255,160,0 +#define RGB_YELLOWISH 0x008080FF //128,128,255 +#define RGB_REDISH 0x008080FF //128,128,255 #define RGB_GREENISH 0x0000A000 //0,160,0 #include "wrect.h" diff --git a/dlls/effects.cpp b/dlls/effects.cpp index e9492dd6..fd3875d7 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -2182,6 +2182,8 @@ public: void CItemSoda::Precache( void ) { + PRECACHE_MODEL( "models/can.mdl" ); + PRECACHE_SOUND( "weapons/g_bounce.wav" ); } LINK_ENTITY_TO_CLASS( item_sodacan, CItemSoda ) @@ -2232,3 +2234,121 @@ void CItemSoda::CanTouch( CBaseEntity *pOther ) SetThink( &CBaseEntity::SUB_Remove ); pev->nextthink = gpGlobals->time; } + +//========================================================= +// env_warpball +//========================================================= +#define SF_REMOVE_ON_FIRE 0x0001 +#define SF_KILL_CENTER 0x0002 + +class CEnvWarpBall : public CBaseEntity +{ +public: + void Precache( void ); + void Spawn( void ) { Precache(); } + void Think( void ); + void KeyValue( KeyValueData *pkvd ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + virtual int ObjectCaps( void ) { return CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } + Vector vecOrigin; +}; + +LINK_ENTITY_TO_CLASS( env_warpball, CEnvWarpBall ) + +void CEnvWarpBall::KeyValue( KeyValueData *pkvd ) +{ + if( FStrEq( pkvd->szKeyName, "radius" ) ) + { + pev->button = atoi( pkvd->szValue ); + pkvd->fHandled = TRUE; + } + if( FStrEq( pkvd->szKeyName, "warp_target" ) ) + { + pev->message = ALLOC_STRING( pkvd->szValue ); + pkvd->fHandled = TRUE; + } + if( FStrEq( pkvd->szKeyName, "damage_delay" ) ) + { + pev->frags = atof( pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else + CBaseEntity::KeyValue( pkvd ); +} + +void CEnvWarpBall::Precache( void ) +{ + PRECACHE_MODEL( "sprites/lgtning.spr" ); + PRECACHE_MODEL( "sprites/Fexplo1.spr" ); + PRECACHE_SOUND( "debris/beamstart2.wav" ); + PRECACHE_SOUND( "debris/beamstart7.wav" ); +} + +void CEnvWarpBall::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) +{ + int iTimes = 0; + int iDrawn = 0; + TraceResult tr; + Vector vecDest; + CBeam *pBeam; + CBaseEntity *pEntity = UTIL_FindEntityByTargetname( NULL, STRING( pev->message ) ); + edict_t *pos; + + if( pEntity )//target found ? + { + vecOrigin = pEntity->pev->origin; + pos = pEntity->edict(); + } + else + { + //use as center + vecOrigin = pev->origin; + pos = edict(); + } + EMIT_SOUND( pos, CHAN_BODY, "debris/beamstart2.wav", 1, ATTN_NORM ); + UTIL_ScreenShake( vecOrigin, 6, 160, 1.0, pev->button ); + CSprite *pSpr = CSprite::SpriteCreate( "sprites/Fexplo1.spr", vecOrigin, TRUE ); + pSpr->AnimateAndDie( 18 ); + pSpr->SetTransparency( kRenderGlow, 77, 210, 130, 255, kRenderFxNoDissipation ); + EMIT_SOUND( pos, CHAN_ITEM, "debris/beamstart7.wav", 1, ATTN_NORM ); + int iBeams = RANDOM_LONG( 20, 40 ); + while( iDrawn < iBeams && iTimes < ( iBeams * 3 ) ) + { + vecDest = pev->button * ( Vector( RANDOM_FLOAT( -1,1 ), RANDOM_FLOAT( -1,1 ), RANDOM_FLOAT( -1,1 ) ).Normalize() ); + UTIL_TraceLine( vecOrigin, vecOrigin + vecDest, ignore_monsters, NULL, &tr ); + if( tr.flFraction != 1.0 ) + { + // we hit something. + iDrawn++; + pBeam = CBeam::BeamCreate( "sprites/lgtning.spr", 200 ); + pBeam->PointsInit( vecOrigin, tr.vecEndPos ); + pBeam->SetColor( 20, 243, 20 ); + pBeam->SetNoise( 65 ); + pBeam->SetBrightness( 220 ); + pBeam->SetWidth( 30 ); + pBeam->SetScrollRate( 35 ); + pBeam->SetThink( &CBeam:: SUB_Remove ); + pBeam->pev->nextthink = gpGlobals->time + RANDOM_FLOAT( 0.5, 1.6 ); + } + iTimes++; + } + pev->nextthink = gpGlobals->time + pev->frags; +} + +void CEnvWarpBall::Think( void ) +{ + SUB_UseTargets( this, USE_TOGGLE, 0 ); + + if( pev->spawnflags & SF_KILL_CENTER ) + { + CBaseEntity *pMonster = NULL; + + while( ( pMonster = UTIL_FindEntityInSphere( pMonster, vecOrigin, 72 ) ) != NULL ) + { + if( FBitSet( pMonster->pev->flags, FL_MONSTER ) || FClassnameIs( pMonster->pev, "player" ) ) + pMonster->TakeDamage( pev, pev, 100, DMG_GENERIC ); + } + } + if( pev->spawnflags & SF_REMOVE_ON_FIRE ) + UTIL_Remove( this ); +} diff --git a/dlls/genericmonster.cpp b/dlls/genericmonster.cpp index c40bb802..782c5a41 100644 --- a/dlls/genericmonster.cpp +++ b/dlls/genericmonster.cpp @@ -20,15 +20,17 @@ #include "cbase.h" #include "monsters.h" #include "schedule.h" +#include "talkmonster.h" // For holograms, make them not solid so the player can walk through them #define SF_GENERICMONSTER_NOTSOLID 4 +#define SF_HEAD_CONTROLLER 8 //========================================================= // Monster's Anim Events Go Here //========================================================= -class CGenericMonster : public CBaseMonster +class CGenericMonster : public CTalkMonster { public: void Spawn( void ); @@ -119,6 +121,11 @@ void CGenericMonster::Spawn() MonsterInit(); + if( pev->spawnflags & SF_HEAD_CONTROLLER ) + { + m_afCapability = bits_CAP_TURN_HEAD; + } + if( pev->spawnflags & SF_GENERICMONSTER_NOTSOLID ) { pev->solid = SOLID_NOT; @@ -131,6 +138,8 @@ void CGenericMonster::Spawn() //========================================================= void CGenericMonster::Precache() { + CTalkMonster::Precache(); + TalkInit(); PRECACHE_MODEL( (char *)STRING( pev->model ) ); } diff --git a/dlls/items.cpp b/dlls/items.cpp index d9cc7871..dcac8adf 100644 --- a/dlls/items.cpp +++ b/dlls/items.cpp @@ -199,6 +199,74 @@ class CItemSuit : public CItem LINK_ENTITY_TO_CLASS( item_suit, CItemSuit ) +class CItemArmorVest : public CItem +{ + void Spawn( void ) + { + Precache(); + SET_MODEL( ENT( pev ), "models/barney_vest.mdl" ); + CItem::Spawn(); + } + void Precache( void ) + { + PRECACHE_MODEL( "models/barney_vest.mdl" ); + PRECACHE_SOUND( "items/gunpickup2.wav" ); + } + BOOL MyTouch( CBasePlayer *pPlayer ) + { + if( ( pPlayer->pev->armorvalue < MAX_NORMAL_BATTERY ) && + ( pPlayer->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) + { + pPlayer->pev->armorvalue += 60; + pPlayer->pev->armorvalue = min( pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY ); + + EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); + + MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); + WRITE_STRING( STRING( pev->classname ) ); + MESSAGE_END(); + return TRUE; + } + return FALSE; + } +}; + +LINK_ENTITY_TO_CLASS( item_armorvest, CItemArmorVest ) + +class CItemHelmet : public CItem +{ + void Spawn( void ) + { + Precache(); + SET_MODEL( ENT( pev ), "models/barney_helmet.mdl" ); + CItem::Spawn(); + } + void Precache( void ) + { + PRECACHE_MODEL( "models/barney_helmet.mdl" ); + PRECACHE_SOUND( "items/gunpickup2.wav" ); + } + BOOL MyTouch( CBasePlayer *pPlayer ) + { + if( ( pPlayer->pev->armorvalue < MAX_NORMAL_BATTERY ) && + ( pPlayer->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) + { + pPlayer->pev->armorvalue += 40; + pPlayer->pev->armorvalue = min( pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY ); + + EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); + + MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); + WRITE_STRING( STRING( pev->classname ) ); + MESSAGE_END(); + return TRUE; + } + return FALSE; + } +}; + +LINK_ENTITY_TO_CLASS( item_helmet, CItemHelmet ) + class CItemBattery : public CItem { void Spawn( void ) @@ -214,11 +282,6 @@ class CItemBattery : public CItem } BOOL MyTouch( CBasePlayer *pPlayer ) { - if( pPlayer->pev->deadflag != DEAD_NO ) - { - return FALSE; - } - if( ( pPlayer->pev->armorvalue < MAX_NORMAL_BATTERY ) && ( pPlayer->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) { diff --git a/dlls/scientist.cpp b/dlls/scientist.cpp index 4e60c58e..8f026969 100644 --- a/dlls/scientist.cpp +++ b/dlls/scientist.cpp @@ -119,6 +119,7 @@ private: }; LINK_ENTITY_TO_CLASS( monster_scientist, CScientist ) +LINK_ENTITY_TO_CLASS( monster_rosenberg, CScientist ) TYPEDESCRIPTION CScientist::m_SaveData[] = { @@ -419,7 +420,10 @@ void CScientist::DeclineFollowing( void ) { Talk( 10 ); m_hTalkTarget = m_hEnemy; - PlaySentence( "SC_POK", 2, VOL_NORM, ATTN_NORM ); + if( FClassnameIs( pev, "monster_rosenberg" ) ) + PlaySentence( "RO_POK", 2, VOL_NORM, ATTN_NORM ); + else + PlaySentence( "SC_POK", 2, VOL_NORM, ATTN_NORM ); } void CScientist::Scream( void ) @@ -428,7 +432,10 @@ void CScientist::Scream( void ) { Talk( 10 ); m_hTalkTarget = m_hEnemy; - PlaySentence( "SC_SCREAM", RANDOM_FLOAT( 3, 6 ), VOL_NORM, ATTN_NORM ); + if( FClassnameIs( pev, "monster_rosenberg" ) ) + PlaySentence( "RO_SCREAM", RANDOM_FLOAT( 3, 6 ), VOL_NORM, ATTN_NORM ); + else + PlaySentence( "SC_SCREAM", RANDOM_FLOAT( 3, 6 ), VOL_NORM, ATTN_NORM ); } } @@ -447,7 +454,10 @@ void CScientist::StartTask( Task_t *pTask ) //if( FOkToSpeak() ) Talk( 2 ); m_hTalkTarget = m_hTargetEnt; - PlaySentence( "SC_HEAL", 2, VOL_NORM, ATTN_IDLE ); + if( FClassnameIs( pev, "monster_rosenberg" ) ) + PlaySentence( "RO_HEAL", 2, VOL_NORM, ATTN_IDLE ); + else + PlaySentence( "SC_HEAL", 2, VOL_NORM, ATTN_IDLE ); TaskComplete(); break; case TASK_SCREAM: @@ -464,10 +474,17 @@ void CScientist::StartTask( Task_t *pTask ) { Talk( 2 ); m_hTalkTarget = m_hEnemy; - if( m_hEnemy->IsPlayer() ) - PlaySentence( "SC_PLFEAR", 5, VOL_NORM, ATTN_NORM ); + if( FClassnameIs( pev, "monster_rosenberg" ) ) + { + PlaySentence( "RO_FEAR", 5, VOL_NORM, ATTN_NORM ); + } else - PlaySentence( "SC_FEAR", 5, VOL_NORM, ATTN_NORM ); + { + if( m_hEnemy->IsPlayer() ) + PlaySentence( "SC_PLFEAR", 5, VOL_NORM, ATTN_NORM ); + else + PlaySentence( "SC_FEAR", 5, VOL_NORM, ATTN_NORM ); + } } TaskComplete(); break; @@ -642,7 +659,10 @@ void CScientist::Spawn( void ) pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = BLOOD_COLOR_RED; - pev->health = gSkillData.scientistHealth; + if( FClassnameIs( pev, "monster_rosenberg" ) ) + pev->health = gSkillData.scientistHealth * 2; + else + 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; @@ -679,6 +699,7 @@ void CScientist::Precache( void ) PRECACHE_SOUND( "scientist/sci_pain3.wav" ); PRECACHE_SOUND( "scientist/sci_pain4.wav" ); PRECACHE_SOUND( "scientist/sci_pain5.wav" ); + PRECACHE_SOUND( "rosenberg/ro_pain1.wav" ); // every new scientist must call this, otherwise // when a level is loaded, nobody will talk (time is reset to 0) @@ -699,28 +720,54 @@ void CScientist::TalkInit() m_szFriends[2] = "monster_barney"; // scientists speach group names (group names are in sentences.txt) - - m_szGrp[TLK_ANSWER] = "SC_ANSWER"; - m_szGrp[TLK_QUESTION] = "SC_QUESTION"; - m_szGrp[TLK_IDLE] = "SC_IDLE"; - m_szGrp[TLK_STARE] = "SC_STARE"; - m_szGrp[TLK_USE] = "SC_OK"; - m_szGrp[TLK_UNUSE] = "SC_WAIT"; - m_szGrp[TLK_STOP] = "SC_STOP"; - m_szGrp[TLK_NOSHOOT] = "SC_SCARED"; - m_szGrp[TLK_HELLO] = "SC_HELLO"; - - m_szGrp[TLK_PLHURT1] = "!SC_CUREA"; - m_szGrp[TLK_PLHURT2] = "!SC_CUREB"; - m_szGrp[TLK_PLHURT3] = "!SC_CUREC"; - - m_szGrp[TLK_PHELLO] = "SC_PHELLO"; - m_szGrp[TLK_PIDLE] = "SC_PIDLE"; - m_szGrp[TLK_PQUESTION] = "SC_PQUEST"; - m_szGrp[TLK_SMELL] = "SC_SMELL"; - - m_szGrp[TLK_WOUND] = "SC_WOUND"; - m_szGrp[TLK_MORTAL] = "SC_MORTAL"; + if( FClassnameIs( pev, "monster_rosenberg" ) ) + { + m_szGrp[TLK_ANSWER] = "RO_ANSWER"; + m_szGrp[TLK_QUESTION] = "RO_QUESTION"; + m_szGrp[TLK_IDLE] = "RO_IDLE"; + m_szGrp[TLK_STARE] = "RO_STARE"; + m_szGrp[TLK_USE] = "RO_OK"; + m_szGrp[TLK_UNUSE] = "RO_WAIT"; + m_szGrp[TLK_STOP] = "RO_STOP"; + m_szGrp[TLK_NOSHOOT] = "RO_SCARED"; + m_szGrp[TLK_HELLO] = "RO_HELLO"; + + m_szGrp[TLK_PLHURT1] = "!RO_CUREA"; + m_szGrp[TLK_PLHURT2] = "!RO_CUREB"; + m_szGrp[TLK_PLHURT3] = "!RO_CUREC"; + + m_szGrp[TLK_PHELLO] = "RO_PHELLO"; + m_szGrp[TLK_PIDLE] = "RO_PIDLE"; + m_szGrp[TLK_PQUESTION] = "RO_PQUEST"; + m_szGrp[TLK_SMELL] = "RO_SMELL"; + + m_szGrp[TLK_WOUND] = "RO_WOUND"; + m_szGrp[TLK_MORTAL] = "RO_MORTAL"; + } + else + { + m_szGrp[TLK_ANSWER] = "SC_ANSWER"; + m_szGrp[TLK_QUESTION] = "SC_QUESTION"; + m_szGrp[TLK_IDLE] = "SC_IDLE"; + m_szGrp[TLK_STARE] = "SC_STARE"; + m_szGrp[TLK_USE] = "SC_OK"; + m_szGrp[TLK_UNUSE] = "SC_WAIT"; + m_szGrp[TLK_STOP] = "SC_STOP"; + m_szGrp[TLK_NOSHOOT] = "SC_SCARED"; + m_szGrp[TLK_HELLO] = "SC_HELLO"; + + m_szGrp[TLK_PLHURT1] = "!SC_CUREA"; + m_szGrp[TLK_PLHURT2] = "!SC_CUREB"; + m_szGrp[TLK_PLHURT3] = "!SC_CUREC"; + + m_szGrp[TLK_PHELLO] = "SC_PHELLO"; + m_szGrp[TLK_PIDLE] = "SC_PIDLE"; + m_szGrp[TLK_PQUESTION] = "SC_PQUEST"; + m_szGrp[TLK_SMELL] = "SC_SMELL"; + + m_szGrp[TLK_WOUND] = "SC_WOUND"; + m_szGrp[TLK_MORTAL] = "SC_MORTAL"; + } // get voice for head switch( pev->body % 3 ) @@ -736,7 +783,7 @@ void CScientist::TalkInit() m_voicePitch = 95; break; //luther case HEAD_SLICK: - m_voicePitch = 100; + m_voicePitch = 85; break; //slick } } @@ -745,8 +792,11 @@ int CScientist::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, flo { if( pevInflictor && pevInflictor->flags & FL_CLIENT ) { - Remember( bits_MEMORY_PROVOKED ); - StopFollowing( TRUE ); + if( !FClassnameIs( pev, "monster_rosenberg" ) ) + { + Remember( bits_MEMORY_PROVOKED ); + StopFollowing( TRUE ); + } } // make sure friends talk about it if player hurts scientist... @@ -776,24 +826,27 @@ void CScientist::PainSound( void ) m_painTime = gpGlobals->time + RANDOM_FLOAT( 0.5, 0.75 ); - switch( RANDOM_LONG( 0, 4 ) ) - { - case 0: - EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain1.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); - break; - case 1: - EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain2.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); - break; - case 2: - EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain3.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); - break; - case 3: - EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain4.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); - break; - case 4: - EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain5.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); - break; - } + if( FClassnameIs( pev, "monster_rosenberg" ) ) + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "rosenberg/ro_pain1.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); + else + switch( RANDOM_LONG( 0, 4 ) ) + { + case 0: + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain1.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); + break; + case 1: + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain2.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); + break; + case 2: + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain3.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); + break; + case 3: + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain4.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); + break; + case 4: + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain5.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); + break; + } } //========================================================= @@ -953,7 +1006,7 @@ Schedule_t *CScientist::GetSchedule( void ) } return GetScheduleOfType( SCHED_TARGET_FACE ); // Just face and follow. } - else // UNDONE: When afraid, scientist won't move out of your way. Keep This? If not, write move away scared + else if( !FClassnameIs( pev, "monster_rosenberg" ) ) // UNDONE: When afraid, scientist won't move out of your way. Keep This? If not, write move away scared { if( HasConditions( bits_COND_NEW_ENEMY ) ) // I just saw something new and scary, react return GetScheduleOfType( SCHED_FEAR ); // React to something scary diff --git a/dlls/talkmonster.cpp b/dlls/talkmonster.cpp index a0a52f52..2efb0ed0 100644 --- a/dlls/talkmonster.cpp +++ b/dlls/talkmonster.cpp @@ -879,7 +879,8 @@ int CTalkMonster::FOkToSpeak( void ) if( gpGlobals->time <= CTalkMonster::g_talkWaitTime ) return FALSE; - if( pev->spawnflags & SF_MONSTER_GAG ) + // monster generic can speak always + if( pev->spawnflags & SF_MONSTER_GAG && !FClassnameIs( pev, "monster_generic" ) ) return FALSE; if( m_MonsterState == MONSTERSTATE_PRONE ) diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index d7f9483c..57d2b42d 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -1190,7 +1190,6 @@ void CBaseTrigger::CounterUse( CBaseEntity *pActivator, CBaseEntity *pCaller, US return; BOOL fTellActivator = - ( m_hActivator != 0 ) && FClassnameIs( m_hActivator->pev, "player" ) && !FBitSet( pev->spawnflags, SPAWNFLAG_NOMESSAGE ); if( m_cTriggersLeft != 0 ) @@ -2039,6 +2038,26 @@ void CTriggerGravity::GravityTouch( CBaseEntity *pOther ) pOther->pev->gravity = pev->gravity; } +class CTriggerPlayerFreeze : public CBaseDelay +{ +public: + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } +}; + +LINK_ENTITY_TO_CLASS( trigger_playerfreeze, CTriggerPlayerFreeze ) + +void CTriggerPlayerFreeze::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) +{ + if( !pActivator || !pActivator->IsPlayer() ) + pActivator = CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) ); + + if( pActivator->pev->flags & FL_FROZEN ) + ( (CBasePlayer *)( (CBaseEntity *)pActivator ) )->EnableControl( TRUE ); + else + ( (CBasePlayer *)( (CBaseEntity *)pActivator ) )->EnableControl( FALSE ); +}; + // this is a really bad idea. class CTriggerChangeTarget : public CBaseDelay {