Browse Source

Merge branch 'bshift' into mobile_hacks

mobile_hacks
Andrey Akhmichin 5 years ago
parent
commit
227e317d9b
  1. 20
      .travis.yml
  2. 2
      cl_dll/Android.mk
  3. 2
      cl_dll/CMakeLists.txt
  4. 4
      cl_dll/hud.h
  5. 2
      dlls/Android.mk
  6. 2
      dlls/CMakeLists.txt
  7. 2
      dlls/crowbar.cpp
  8. 245
      dlls/effects.cpp
  9. 90
      dlls/genericmonster.cpp
  10. 68
      dlls/items.cpp
  11. 4
      dlls/player.cpp
  12. 213
      dlls/scientist.cpp
  13. 1
      dlls/talkmonster.cpp
  14. 20
      dlls/triggers.cpp
  15. 2
      dlls/weapons.cpp

20
.travis.yml

@ -5,12 +5,20 @@ compiler:
os: os:
- linux - linux
- osx - osx
sudo: true addons:
apt:
packages:
- gcc-multilib
- g++-multilib
before_script: before_script:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install gcc-multilib g++-multilib; fi - curl http://libsdl.org/release/SDL2-devel-2.0.7-mingw.tar.gz | tar xzf -
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "gcc" ]]; then sudo apt-get install mingw-w64-i686-dev binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686; fi - mv SDL2-2.0.7/i686-w64-mingw32/include/SDL2 cl_dll/
script: script:
- mkdir -p build && cd build - mkdir -p build && cd build
- cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=0 && make -j3 && rm -rf * - cmake ../ -DCMAKE_C_FLAGS="-O2 -pipe -DNDEBUG -fvisibility=hidden -fomit-frame-pointer" -DCMAKE_CXX_FLAGS="-fno-exceptions -fno-rtti" -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined -Wl,--strip-all" -DGOLDSOURCE_SUPPORT=1 -DUSE_VOICEMGR=0 && make -j3
- cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=1 && make -j3 && rm -rf * - mkdir -p $TRAVIS_BRANCH-$TRAVIS_OS_NAME-$CC/cl_dlls
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "gcc" ]]; then cd ..; mkdir build-mingw; cd build-mingw; cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ && make -j3; fi - mkdir -p $TRAVIS_BRANCH-$TRAVIS_OS_NAME-$CC/dlls
- cp cl_dll/client.* $TRAVIS_BRANCH-$TRAVIS_OS_NAME-$CC/cl_dlls
- cp dlls/hl.* $TRAVIS_BRANCH-$TRAVIS_OS_NAME-$CC/dlls
- tar -J -cf $TRAVIS_BRANCH-$TRAVIS_OS_NAME-$CC.txz $TRAVIS_BRANCH-$TRAVIS_OS_NAME-$CC
- curl --upload-file $TRAVIS_BRANCH-$TRAVIS_OS_NAME-$CC.txz https://transfer.sh/$TRAVIS_BRANCH-$TRAVIS_OS_NAME-$CC.txz

2
cl_dll/Android.mk

@ -92,7 +92,7 @@ SRCS+=./input_xash3d.cpp
SRCS+=./scoreboard.cpp SRCS+=./scoreboard.cpp
SRCS+=./MOTD.cpp SRCS+=./MOTD.cpp
INCLUDES = -I../common -I. -I../game_shared -I../pm_shared -I../engine -I../dlls -I../utils/false_vgui/include INCLUDES = -I../common -I. -I../game_shared -I../pm_shared -I../engine -I../dlls -I../utils/false_vgui/include
DEFINES = -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w -D_snprintf=snprintf DEFINES = -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -DCROWBAR_IDLE_ANIM -w -D_snprintf=snprintf
LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \
$(LOCAL_PATH)/../common \ $(LOCAL_PATH)/../common \

2
cl_dll/CMakeLists.txt

@ -31,7 +31,7 @@ if(HAVE_TGMATH_H)
add_definitions(-DHAVE_TGMATH_H) add_definitions(-DHAVE_TGMATH_H)
endif() endif()
add_definitions(-DCLIENT_WEAPONS -DCLIENT_DLL) add_definitions(-DCLIENT_WEAPONS -DCLIENT_DLL -DCROWBAR_IDLE_ANIM -DCROWBAR_FIX_RAPID_CROWBAR -DCROWBAR_DELAY_FIX)
if(NOT MSVC) if(NOT MSVC)
add_compile_options(-fno-exceptions) # GCC/Clang flag add_compile_options(-fno-exceptions) # GCC/Clang flag

4
cl_dll/hud.h

@ -22,8 +22,8 @@
#pragma once #pragma once
#ifndef HUD_H #ifndef HUD_H
#define HUD_H #define HUD_H
#define RGB_YELLOWISH 0x00FFA000 //255,160,0 #define RGB_YELLOWISH 0x005F5FFF //95,95,255
#define RGB_REDISH 0x00FF1010 //255,160,0 #define RGB_REDISH 0x00FF1010 //255,16,16
#define RGB_GREENISH 0x0000A000 //0,160,0 #define RGB_GREENISH 0x0000A000 //0,160,0
#include "wrect.h" #include "wrect.h"

2
dlls/Android.mk

@ -14,7 +14,7 @@ LOCAL_MODULE_FILENAME = libserver_hardfp
endif endif
LOCAL_CFLAGS += -D_LINUX -DCLIENT_WEAPONS -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf \ LOCAL_CFLAGS += -D_LINUX -DCLIENT_WEAPONS -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf \
-fno-exceptions -DNO_VOICEGAMEMGR -w -fno-exceptions -DNO_VOICEGAMEMGR -DCROWBAR_IDLE_ANIM -w
LOCAL_CPPFLAGS := $(LOCAL_CFLAGS) LOCAL_CPPFLAGS := $(LOCAL_CFLAGS)

2
dlls/CMakeLists.txt

@ -31,7 +31,7 @@ if(HAVE_TGMATH_H)
add_definitions(-DHAVE_TGMATH_H) add_definitions(-DHAVE_TGMATH_H)
endif() endif()
add_definitions(-DCLIENT_WEAPONS) add_definitions(-DCLIENT_WEAPONS -DCROWBAR_IDLE_ANIM -DCROWBAR_FIX_RAPID_CROWBAR -DCROWBAR_DELAY_FIX)
if(NOT MSVC) if(NOT MSVC)
add_compile_options(-fno-exceptions) # GCC/Clang flag add_compile_options(-fno-exceptions) # GCC/Clang flag

2
dlls/crowbar.cpp

@ -337,7 +337,7 @@ int CCrowbar::Swing( int fFirst )
SetThink( &CCrowbar::Smack ); SetThink( &CCrowbar::Smack );
pev->nextthink = UTIL_WeaponTimeBase() + 0.2f; pev->nextthink = UTIL_WeaponTimeBase() + 0.2f;
#endif #endif
#if CROWBAR_DELAY_FIX #ifdef CROWBAR_DELAY_FIX
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25f; m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25f;
#else #else
m_flNextPrimaryAttack = GetNextAttackDelay( 0.25f ); m_flNextPrimaryAttack = GetNextAttackDelay( 0.25f );

245
dlls/effects.cpp

@ -365,7 +365,7 @@ public:
void Zap( const Vector &vecSrc, const Vector &vecDest ); void Zap( const Vector &vecSrc, const Vector &vecDest );
void EXPORT StrikeUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); void EXPORT StrikeUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); void EXPORT ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
static CLightning *LightningCreate( const char *pSpriteName, int width );
inline BOOL ServerSide( void ) inline BOOL ServerSide( void )
{ {
if( m_life == 0 && !( pev->spawnflags & SF_BEAM_RING ) ) if( m_life == 0 && !( pev->spawnflags & SF_BEAM_RING ) )
@ -912,6 +912,19 @@ void CLightning::BeamUpdateVars( void )
SetFlags( BEAM_FSHADEOUT ); SetFlags( BEAM_FSHADEOUT );
} }
CLightning *CLightning::LightningCreate( const char *pSpriteName, int width )
{
// Create a new entity with CLightning private data
CLightning *pBeam = GetClassPtr( (CLightning *)NULL );
pBeam->BeamInit( pSpriteName, width );
pBeam->pev->classname = MAKE_STRING( "env_beam" );
pBeam->m_iszSpriteName = MAKE_STRING( pSpriteName );
pBeam->m_boltWidth = width;
return pBeam;
}
LINK_ENTITY_TO_CLASS( env_laser, CLaser ) LINK_ENTITY_TO_CLASS( env_laser, CLaser )
TYPEDESCRIPTION CLaser::m_SaveData[] = TYPEDESCRIPTION CLaser::m_SaveData[] =
@ -2233,3 +2246,233 @@ void CItemSoda::CanTouch( CBaseEntity *pOther )
SetThink( &CBaseEntity::SUB_Remove ); SetThink( &CBaseEntity::SUB_Remove );
pev->nextthink = gpGlobals->time; pev->nextthink = gpGlobals->time;
} }
//=========================================================
// env_warpball
//=========================================================
#define SF_REMOVE_ON_FIRE 0x0001
#define SF_KILL_CENTER 0x0002
class CWarpBall : public CBaseEntity
{
public:
void Precache();
void Spawn();
void EXPORT BallThink();
void KeyValue( KeyValueData *pkvd );
void EXPORT WarpBallUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
static CWarpBall *CreateWarpBall( const Vector &p_VecOrigin );
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
// private:
CLightning *m_pBeams;
CSprite *m_pSprite;
// int m_iBeams;
float m_flLastTime;
float m_flMaxFrame;
float m_flBeamRadius;
string_t m_iszWarpTarget;
float m_flWarpStart;
float m_flDamageDelay;
// float m_flTargetDelay;
BOOL m_fPlaying;
BOOL m_fDamageApplied;
// BOOL m_fBeamsCleared;
};
LINK_ENTITY_TO_CLASS( env_warpball, CWarpBall )
TYPEDESCRIPTION CWarpBall::m_SaveData[] =
{
// DEFINE_FIELD( CWarpBall, m_iBeams, FIELD_INTEGER ),
DEFINE_FIELD( CWarpBall, m_flLastTime, FIELD_FLOAT ),
DEFINE_FIELD( CWarpBall, m_flMaxFrame, FIELD_FLOAT ),
DEFINE_FIELD( CWarpBall, m_flBeamRadius, FIELD_FLOAT ),
DEFINE_FIELD( CWarpBall, m_iszWarpTarget, FIELD_STRING ),
DEFINE_FIELD( CWarpBall, m_flWarpStart, FIELD_FLOAT ),
DEFINE_FIELD( CWarpBall, m_flDamageDelay, FIELD_FLOAT ),
// DEFINE_FIELD( CWarpBall, m_flTargetDelay, FIELD_FLOAT ),
DEFINE_FIELD( CWarpBall, m_fPlaying, FIELD_BOOLEAN ),
DEFINE_FIELD( CWarpBall, m_fDamageApplied, FIELD_BOOLEAN ),
// DEFINE_FIELD( CWarpBall, m_fBeamsCleared, FIELD_BOOLEAN ),
DEFINE_FIELD( CWarpBall, m_pBeams, FIELD_CLASSPTR ),
DEFINE_FIELD( CWarpBall, m_pSprite, FIELD_CLASSPTR ),
};
IMPLEMENT_SAVERESTORE( CWarpBall, CBaseEntity )
void CWarpBall::KeyValue( KeyValueData *pkvd )
{
if( FStrEq( pkvd->szKeyName, "radius" ) )
{
m_flBeamRadius = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "warp_target" ) )
{
m_iszWarpTarget = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "damage_delay" ) )
{
m_flDamageDelay = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
CBaseEntity::KeyValue( pkvd );
}
void CWarpBall::Spawn()
{
Precache();
pev->movetype = MOVETYPE_NONE;
pev->solid = SOLID_NOT;
UTIL_SetOrigin( pev, pev->origin );
UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ) );
pev->rendermode = kRenderGlow;
pev->renderamt = 255;
pev->renderfx = kRenderFxNoDissipation;
pev->framerate = 10;
m_pSprite = CSprite::SpriteCreate( "sprites/Fexplo1.spr", pev->origin, 1 );
m_pSprite->TurnOff();
SetUse( &CWarpBall::WarpBallUse );
}
void CWarpBall::Precache()
{
PRECACHE_MODEL( "sprites/lgtning.spr" );
PRECACHE_MODEL( "sprites/Fexplo1.spr" );
PRECACHE_MODEL( "sprites/XFlare1.spr" );
PRECACHE_SOUND( "debris/alien_teleport.wav" );
}
void CWarpBall::WarpBallUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
CBaseEntity *pEntity;
int r = 77, g = 210, b = 130;
if( m_fPlaying )
return;
if( m_iszWarpTarget )
{
pEntity = UTIL_FindEntityByTargetname( NULL, STRING( m_iszWarpTarget ) );
if( pEntity )
UTIL_SetOrigin( pev, pEntity->pev->origin );
}
SET_MODEL( ENT( pev ), "sprites/XFlare1.spr" );
m_flMaxFrame = (float)MODEL_FRAMES( pev->modelindex ) - 1;
pev->rendercolor = Vector( r, g, b );
pev->scale = 1.2;
pev->frame = 0;
if( m_pSprite )
{
m_pSprite->SetTransparency( kRenderGlow, r, g, b, 255, kRenderFxNoDissipation );
m_pSprite->pev->scale = 1.0;
m_pSprite->TurnOn();
}
if( !m_pBeams )
{
m_pBeams = CLightning::LightningCreate( "sprites/lgtning.spr", 18 );
if( m_pBeams )
{
UTIL_SetOrigin( m_pBeams->pev, pev->origin );
m_pBeams->m_restrike = -0.5;
m_pBeams->SetColor( 0, 255, 0 );
m_pBeams->m_noiseAmplitude = 65;
m_pBeams->m_life = 0.5;
m_pBeams->m_radius = m_flBeamRadius;
m_pBeams->m_iszStartEntity = pev->targetname;
SetBits( m_pBeams->pev->spawnflags, SF_BEAM_TOGGLE | SF_BEAM_SPARKEND );
m_pBeams->BeamUpdateVars();
}
}
if( m_pBeams )
{
m_pBeams->Spawn();
m_pBeams->pev->solid = SOLID_NOT;
m_pBeams->SetThink( &CLightning::StrikeThink );
m_pBeams->pev->nextthink = gpGlobals->time + 0.1;
}
SetThink( &CWarpBall::BallThink );
pev->nextthink = gpGlobals->time + 0.1;
m_flLastTime = gpGlobals->time;
// m_fBeamsCleared = FALSE;
m_fPlaying = TRUE;
if( !m_flDamageDelay )
{
RadiusDamage( pev->origin, pev, pev, 300.0, 48.0, CLASS_NONE, DMG_SHOCK );
m_fDamageApplied = TRUE;
}
else
{
m_fDamageApplied = FALSE;
}
SUB_UseTargets( this, USE_TOGGLE, 0.0 );
UTIL_ScreenShake( pev->origin, 4.0, 100.0, 2.0, 1000.0 );
m_flWarpStart = gpGlobals->time;
EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, "debris/alien_teleport.wav", 1.0, ATTN_NORM, 0, PITCH_NORM );
}
void CWarpBall::BallThink( void )
{
pev->frame = ( gpGlobals->time - m_flLastTime ) * pev->framerate + pev->frame;
if( pev->frame > m_flMaxFrame )
{
SET_MODEL( ENT( pev ), "" );
SetThink( NULL );
if( pev->spawnflags & SF_REMOVE_ON_FIRE )
{
UTIL_Remove( m_pSprite );
UTIL_Remove( m_pBeams );
UTIL_Remove( this );
}
if( m_pSprite )
m_pSprite->TurnOff();
m_fPlaying = 0;
}
else
{
if( ( pev->spawnflags & SF_KILL_CENTER ) && !m_fDamageApplied
&& gpGlobals->time - m_flWarpStart >= m_flDamageDelay )
{
RadiusDamage( pev->origin, pev, pev, 300.0, 48.0, CLASS_NONE, DMG_SHOCK );
m_fDamageApplied = TRUE;
}
if( m_pBeams )
{
if( pev->frame >= m_flMaxFrame - 4.0 )
{
m_pBeams->SetThink( NULL );
m_pBeams->pev->nextthink = gpGlobals->time;
}
}
pev->nextthink = gpGlobals->time + 0.1;
m_flLastTime = gpGlobals->time;
}
}
CWarpBall *CWarpBall::CreateWarpBall( const Vector &p_VecOrigin )
{
// Create a new entity with CWarpball private data
CWarpBall *pWarpBall = GetClassPtr( (CWarpBall *)NULL );
pWarpBall->pev->classname = MAKE_STRING( "env_warpball" );
UTIL_SetOrigin( pWarpBall->pev, p_VecOrigin );
return pWarpBall;
}

90
dlls/genericmonster.cpp

@ -23,11 +23,11 @@
// For holograms, make them not solid so the player can walk through them // For holograms, make them not solid so the player can walk through them
#define SF_GENERICMONSTER_NOTSOLID 4 #define SF_GENERICMONSTER_NOTSOLID 4
#define SF_HEAD_CONTROLLER 8
//========================================================= //=========================================================
// Monster's Anim Events Go Here // Monster's Anim Events Go Here
//========================================================= //=========================================================
class CGenericMonster : public CBaseMonster class CGenericMonster : public CBaseMonster
{ {
public: public:
@ -37,10 +37,33 @@ public:
int Classify( void ); int Classify( void );
void HandleAnimEvent( MonsterEvent_t *pEvent ); void HandleAnimEvent( MonsterEvent_t *pEvent );
int ISoundMask( void ); int ISoundMask( void );
void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener );
void IdleHeadTurn( Vector &vecFriend );
void EXPORT MonsterThink();
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
private:
float m_talkTime;
EHANDLE m_hTalkTarget;
float m_flIdealYaw;
float m_flCurrentYaw;
}; };
LINK_ENTITY_TO_CLASS( monster_generic, CGenericMonster ) LINK_ENTITY_TO_CLASS( monster_generic, CGenericMonster )
TYPEDESCRIPTION CGenericMonster::m_SaveData[] =
{
DEFINE_FIELD( CGenericMonster, m_talkTime, FIELD_FLOAT ),
DEFINE_FIELD( CGenericMonster, m_hTalkTarget, FIELD_EHANDLE ),
DEFINE_FIELD( CGenericMonster, m_flIdealYaw, FIELD_FLOAT ),
DEFINE_FIELD( CGenericMonster, m_flCurrentYaw, FIELD_FLOAT ),
};
IMPLEMENT_SAVERESTORE( CGenericMonster, CBaseMonster )
//========================================================= //=========================================================
// Classify - indicates this monster's place in the // Classify - indicates this monster's place in the
// relationship table. // relationship table.
@ -119,6 +142,13 @@ void CGenericMonster::Spawn()
MonsterInit(); MonsterInit();
if( pev->spawnflags & SF_HEAD_CONTROLLER )
{
m_afCapability = bits_CAP_TURN_HEAD;
}
m_flIdealYaw = m_flCurrentYaw = 0;
if( pev->spawnflags & SF_GENERICMONSTER_NOTSOLID ) if( pev->spawnflags & SF_GENERICMONSTER_NOTSOLID )
{ {
pev->solid = SOLID_NOT; pev->solid = SOLID_NOT;
@ -134,6 +164,64 @@ void CGenericMonster::Precache()
PRECACHE_MODEL( STRING( pev->model ) ); PRECACHE_MODEL( STRING( pev->model ) );
} }
void CGenericMonster::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener )
{
m_talkTime = gpGlobals->time + duration;
PlaySentence( pszSentence, duration, volume, attenuation );
m_hTalkTarget = pListener;
}
void CGenericMonster::IdleHeadTurn( Vector &vecFriend )
{
// turn head in desired direction only if ent has a turnable head
if( m_afCapability & bits_CAP_TURN_HEAD )
{
float yaw = VecToYaw( vecFriend - pev->origin ) - pev->angles.y;
if( yaw > 180 )
yaw -= 360;
if( yaw < -180 )
yaw += 360;
m_flIdealYaw = yaw;
}
}
void CGenericMonster::MonsterThink()
{
if( m_afCapability & bits_CAP_TURN_HEAD )
{
if( m_hTalkTarget != 0 )
{
if( gpGlobals->time > m_talkTime )
{
m_flIdealYaw = 0;
m_hTalkTarget = 0;
}
else
{
IdleHeadTurn( m_hTalkTarget->pev->origin );
}
}
if( m_flCurrentYaw != m_flIdealYaw )
{
if( m_flCurrentYaw <= m_flIdealYaw )
{
m_flCurrentYaw += Q_min( m_flIdealYaw - m_flCurrentYaw, 20.0f );
}
else
{
m_flCurrentYaw -= Q_min( m_flCurrentYaw - m_flIdealYaw, 20.0f );
}
SetBoneController( 0, m_flCurrentYaw );
}
}
CBaseMonster::MonsterThink();
}
//========================================================= //=========================================================
// AI Schedules Specific to this monster // AI Schedules Specific to this monster
//========================================================= //=========================================================

68
dlls/items.cpp

@ -200,6 +200,74 @@ class CItemSuit : public CItem
LINK_ENTITY_TO_CLASS( item_suit, CItemSuit ) 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 = Q_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 = Q_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 class CItemBattery : public CItem
{ {
void Spawn( void ) void Spawn( void )

4
dlls/player.cpp

@ -3458,7 +3458,9 @@ void CBasePlayer::CheatImpulseCommands( int iImpulse )
case 101: case 101:
gEvilImpulse101 = TRUE; gEvilImpulse101 = TRUE;
GiveNamedItem( "item_suit" ); GiveNamedItem( "item_suit" );
GiveNamedItem( "item_battery" ); GiveNamedItem( "item_armorvest" );
GiveNamedItem( "item_helmet" );
// GiveNamedItem( "item_battery" );
GiveNamedItem( "weapon_crowbar" ); GiveNamedItem( "weapon_crowbar" );
GiveNamedItem( "weapon_9mmhandgun" ); GiveNamedItem( "weapon_9mmhandgun" );
GiveNamedItem( "ammo_9mmclip" ); GiveNamedItem( "ammo_9mmclip" );

213
dlls/scientist.cpp

@ -119,6 +119,7 @@ private:
}; };
LINK_ENTITY_TO_CLASS( monster_scientist, CScientist ) LINK_ENTITY_TO_CLASS( monster_scientist, CScientist )
LINK_ENTITY_TO_CLASS( monster_rosenberg, CScientist )
TYPEDESCRIPTION CScientist::m_SaveData[] = TYPEDESCRIPTION CScientist::m_SaveData[] =
{ {
@ -419,7 +420,10 @@ void CScientist::DeclineFollowing( void )
{ {
Talk( 10 ); Talk( 10 );
m_hTalkTarget = m_hEnemy; 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 ) void CScientist::Scream( void )
@ -428,7 +432,10 @@ void CScientist::Scream( void )
{ {
Talk( 10 ); Talk( 10 );
m_hTalkTarget = m_hEnemy; m_hTalkTarget = m_hEnemy;
PlaySentence( "SC_SCREAM", RANDOM_FLOAT( 3.0f, 6.0f ), VOL_NORM, ATTN_NORM ); if( FClassnameIs( pev, "monster_rosenberg" ) )
PlaySentence( "RO_SCREAM", RANDOM_FLOAT( 3.0f, 6.0f ), VOL_NORM, ATTN_NORM );
else
PlaySentence( "SC_SCREAM", RANDOM_FLOAT( 3.0f, 6.0f ), VOL_NORM, ATTN_NORM );
} }
} }
@ -447,7 +454,10 @@ void CScientist::StartTask( Task_t *pTask )
//if( FOkToSpeak() ) //if( FOkToSpeak() )
Talk( 2 ); Talk( 2 );
m_hTalkTarget = m_hTargetEnt; 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(); TaskComplete();
break; break;
case TASK_SCREAM: case TASK_SCREAM:
@ -465,12 +475,19 @@ void CScientist::StartTask( Task_t *pTask )
Talk( 2 ); Talk( 2 );
m_hTalkTarget = m_hEnemy; m_hTalkTarget = m_hEnemy;
//The enemy can be null here. - Solokiller if( FClassnameIs( pev, "monster_rosenberg" ) )
//Discovered while testing the barnacle grapple on headcrabs with scientists in view. {
if( m_hEnemy != 0 && m_hEnemy->IsPlayer() ) PlaySentence( "RO_FEAR", 5, VOL_NORM, ATTN_NORM );
PlaySentence( "SC_PLFEAR", 5, VOL_NORM, ATTN_NORM ); }
else else
PlaySentence( "SC_FEAR", 5, VOL_NORM, ATTN_NORM ); {
//The enemy can be null here. - Solokiller
//Discovered while testing the barnacle grapple on headcrabs with scientists in view.
if( m_hEnemy != 0 && m_hEnemy->IsPlayer() )
PlaySentence( "SC_PLFEAR", 5, VOL_NORM, ATTN_NORM );
else
PlaySentence( "SC_FEAR", 5, VOL_NORM, ATTN_NORM );
}
} }
TaskComplete(); TaskComplete();
break; break;
@ -647,7 +664,10 @@ void CScientist::Spawn( void )
pev->solid = SOLID_SLIDEBOX; pev->solid = SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_STEP; pev->movetype = MOVETYPE_STEP;
m_bloodColor = BLOOD_COLOR_RED; 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. 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_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_MonsterState = MONSTERSTATE_NONE;
@ -679,11 +699,26 @@ void CScientist::Spawn( void )
void CScientist::Precache( void ) void CScientist::Precache( void )
{ {
PRECACHE_MODEL( "models/scientist.mdl" ); PRECACHE_MODEL( "models/scientist.mdl" );
PRECACHE_SOUND( "scientist/sci_pain1.wav" ); if( !FClassnameIs( pev, "monster_rosenberg" ) )
PRECACHE_SOUND( "scientist/sci_pain2.wav" ); {
PRECACHE_SOUND( "scientist/sci_pain3.wav" ); PRECACHE_SOUND( "scientist/sci_pain1.wav" );
PRECACHE_SOUND( "scientist/sci_pain4.wav" ); PRECACHE_SOUND( "scientist/sci_pain2.wav" );
PRECACHE_SOUND( "scientist/sci_pain5.wav" ); PRECACHE_SOUND( "scientist/sci_pain3.wav" );
PRECACHE_SOUND( "scientist/sci_pain4.wav" );
PRECACHE_SOUND( "scientist/sci_pain5.wav" );
}
else
{
PRECACHE_SOUND( "rosenberg/ro_pain0.wav" );
PRECACHE_SOUND( "rosenberg/ro_pain1.wav" );
PRECACHE_SOUND( "rosenberg/ro_pain2.wav" );
PRECACHE_SOUND( "rosenberg/ro_pain3.wav" );
PRECACHE_SOUND( "rosenberg/ro_pain4.wav" );
PRECACHE_SOUND( "rosenberg/ro_pain5.wav" );
PRECACHE_SOUND( "rosenberg/ro_pain6.wav" );
PRECACHE_SOUND( "rosenberg/ro_pain7.wav" );
PRECACHE_SOUND( "rosenberg/ro_pain8.wav" );
}
// every new scientist must call this, otherwise // every new scientist must call this, otherwise
// when a level is loaded, nobody will talk (time is reset to 0) // when a level is loaded, nobody will talk (time is reset to 0)
@ -698,28 +733,54 @@ void CScientist::TalkInit()
CTalkMonster::TalkInit(); CTalkMonster::TalkInit();
// scientists speach group names (group names are in sentences.txt) // scientists speach group names (group names are in sentences.txt)
if( FClassnameIs( pev, "monster_rosenberg" ) )
m_szGrp[TLK_ANSWER] = "SC_ANSWER"; {
m_szGrp[TLK_QUESTION] = "SC_QUESTION"; m_szGrp[TLK_ANSWER] = "RO_ANSWER";
m_szGrp[TLK_IDLE] = "SC_IDLE"; m_szGrp[TLK_QUESTION] = "RO_QUESTION";
m_szGrp[TLK_STARE] = "SC_STARE"; m_szGrp[TLK_IDLE] = "RO_IDLE";
m_szGrp[TLK_USE] = "SC_OK"; m_szGrp[TLK_STARE] = "RO_STARE";
m_szGrp[TLK_UNUSE] = "SC_WAIT"; m_szGrp[TLK_USE] = "RO_OK";
m_szGrp[TLK_STOP] = "SC_STOP"; m_szGrp[TLK_UNUSE] = "RO_WAIT";
m_szGrp[TLK_NOSHOOT] = "SC_SCARED"; m_szGrp[TLK_STOP] = "RO_STOP";
m_szGrp[TLK_HELLO] = "SC_HELLO"; m_szGrp[TLK_NOSHOOT] = "RO_SCARED";
m_szGrp[TLK_HELLO] = "RO_HELLO";
m_szGrp[TLK_PLHURT1] = "!SC_CUREA";
m_szGrp[TLK_PLHURT2] = "!SC_CUREB"; m_szGrp[TLK_PLHURT1] = "!RO_CUREA";
m_szGrp[TLK_PLHURT3] = "!SC_CUREC"; m_szGrp[TLK_PLHURT2] = "!RO_CUREB";
m_szGrp[TLK_PLHURT3] = "!RO_CUREC";
m_szGrp[TLK_PHELLO] = "SC_PHELLO";
m_szGrp[TLK_PIDLE] = "SC_PIDLE"; m_szGrp[TLK_PHELLO] = "RO_PHELLO";
m_szGrp[TLK_PQUESTION] = "SC_PQUEST"; m_szGrp[TLK_PIDLE] = "RO_PIDLE";
m_szGrp[TLK_SMELL] = "SC_SMELL"; m_szGrp[TLK_PQUESTION] = "RO_PQUEST";
m_szGrp[TLK_SMELL] = "RO_SMELL";
m_szGrp[TLK_WOUND] = "SC_WOUND";
m_szGrp[TLK_MORTAL] = "SC_MORTAL"; 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 // get voice for head
switch( pev->body % 3 ) switch( pev->body % 3 )
@ -744,8 +805,11 @@ int CScientist::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, flo
{ {
if( pevInflictor && pevInflictor->flags & FL_CLIENT ) if( pevInflictor && pevInflictor->flags & FL_CLIENT )
{ {
Remember( bits_MEMORY_PROVOKED ); if( !FClassnameIs( pev, "monster_rosenberg" ) )
StopFollowing( TRUE ); {
Remember( bits_MEMORY_PROVOKED );
StopFollowing( TRUE );
}
} }
// make sure friends talk about it if player hurts scientist... // make sure friends talk about it if player hurts scientist...
@ -770,29 +834,64 @@ int CScientist::ISoundMask( void )
//========================================================= //=========================================================
void CScientist::PainSound( void ) void CScientist::PainSound( void )
{ {
const char *pszSound;
if( gpGlobals->time < m_painTime ) if( gpGlobals->time < m_painTime )
return; return;
m_painTime = gpGlobals->time + RANDOM_FLOAT( 0.5f, 0.75f ); m_painTime = gpGlobals->time + RANDOM_FLOAT( 0.5f, 0.75f );
switch( RANDOM_LONG( 0, 4 ) ) if( FClassnameIs( pev, "monster_rosenberg" ) )
{ switch( RANDOM_LONG( 0, 8 ) )
case 0: {
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain1.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); case 0:
break; pszSound = "rosenberg/ro_pain0.wav";
case 1: break;
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain2.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); case 1:
break; pszSound = "rosenberg/ro_pain1.wav";
case 2: break;
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain3.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); case 2:
break; pszSound = "rosenberg/ro_pain2.wav";
case 3: break;
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain4.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); case 3:
break; pszSound = "rosenberg/ro_pain3.wav";
case 4: break;
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "scientist/sci_pain5.wav", 1, ATTN_NORM, 0, GetVoicePitch() ); case 4:
break; pszSound = "rosenberg/ro_pain4.wav";
} break;
case 5:
pszSound = "rosenberg/ro_pain5.wav";
break;
case 6:
pszSound = "rosenberg/ro_pain6.wav";
break;
case 7:
pszSound = "rosenberg/ro_pain7.wav";
break;
case 8:
pszSound = "rosenberg/ro_pain8.wav";
break;
}
else
switch( RANDOM_LONG( 0, 4 ) )
{
case 0:
pszSound = "scientist/sci_pain1.wav";
break;
case 1:
pszSound = "scientist/sci_pain2.wav";
break;
case 2:
pszSound = "scientist/sci_pain3.wav";
break;
case 3:
pszSound = "scientist/sci_pain4.wav";
break;
case 4:
pszSound = "scientist/sci_pain5.wav";
break;
}
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pszSound, 1, ATTN_NORM, 0, GetVoicePitch() );
} }
//========================================================= //=========================================================
@ -952,7 +1051,7 @@ Schedule_t *CScientist::GetSchedule( void )
} }
return GetScheduleOfType( SCHED_TARGET_FACE ); // Just face and follow. 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 if( HasConditions( bits_COND_NEW_ENEMY ) ) // I just saw something new and scary, react
return GetScheduleOfType( SCHED_FEAR ); // React to something scary return GetScheduleOfType( SCHED_FEAR ); // React to something scary

1
dlls/talkmonster.cpp

@ -882,6 +882,7 @@ int CTalkMonster::FOkToSpeak( void )
if( gpGlobals->time <= CTalkMonster::g_talkWaitTime ) if( gpGlobals->time <= CTalkMonster::g_talkWaitTime )
return FALSE; return FALSE;
// monster generic can speak always
if( pev->spawnflags & SF_MONSTER_GAG ) if( pev->spawnflags & SF_MONSTER_GAG )
return FALSE; return FALSE;

20
dlls/triggers.cpp

@ -2039,6 +2039,26 @@ void CTriggerGravity::GravityTouch( CBaseEntity *pOther )
pOther->pev->gravity = pev->gravity; 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*)( pActivator ) )->EnableControl( TRUE );
else
( (CBasePlayer*)( pActivator ) )->EnableControl( FALSE );
};
// this is a really bad idea. // this is a really bad idea.
class CTriggerChangeTarget : public CBaseDelay class CTriggerChangeTarget : public CBaseDelay
{ {

2
dlls/weapons.cpp

@ -296,6 +296,8 @@ void W_Precache( void )
// common world objects // common world objects
UTIL_PrecacheOther( "item_suit" ); UTIL_PrecacheOther( "item_suit" );
UTIL_PrecacheOther( "item_healthkit" ); UTIL_PrecacheOther( "item_healthkit" );
UTIL_PrecacheOther( "item_armorvest" );
UTIL_PrecacheOther( "item_helmet" );
UTIL_PrecacheOther( "item_battery" ); UTIL_PrecacheOther( "item_battery" );
UTIL_PrecacheOther( "item_antidote" ); UTIL_PrecacheOther( "item_antidote" );
UTIL_PrecacheOther( "item_security" ); UTIL_PrecacheOther( "item_security" );

Loading…
Cancel
Save