Rebase step 3: manually apply failed hunks

This commit is contained in:
Alibek Omarov 2024-04-03 21:32:11 +03:00
parent 988c6757dd
commit 568fd1b9c2
55 changed files with 2740 additions and 235 deletions

View File

@ -189,6 +189,9 @@ void CStudioModelRenderer::StudioCalcBoneQuaterion( int frame, float s, mstudiob
vec3_t angle1, angle2;
mstudioanimvalue_t *panimvalue;
if( panim == NULL )
return;
for( j = 0; j < 3; j++ )
{
if( panim->offset[j + 3] == 0 )

View File

@ -870,7 +870,7 @@ int CHudAmmo::Draw( float flTime )
if( m_fFade > 0 )
m_fFade -= ( (float)gHUD.m_flTimeDelta * 20.0f );
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
ScaleColors( r, g, b, a );
@ -898,7 +898,7 @@ int CHudAmmo::Draw( float flTime )
x += AmmoWidth / 2;
UnpackRGB( r,g,b, gHUD.uColor );
UnpackRGB( r,g,b, gHUD.uColor );
// draw the | bar
FillRGBA( x, y, iBarWidth, gHUD.m_iFontHeight, r, g, b, a );
@ -968,7 +968,7 @@ int DrawBar( int x, int y, int width, int height, float f )
width -= w;
}
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
FillRGBA( x, y, width, height, r, g, b, 128 );
@ -1036,7 +1036,7 @@ int CHudAmmo::DrawWList( float flTime )
{
int iWidth;
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
if( iActiveSlot == i )
a = 255;
@ -1087,7 +1087,7 @@ int CHudAmmo::DrawWList( float flTime )
if( !p || !p->iId )
continue;
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
// if active, then we must have ammo.
if( gpActiveSel == p )
@ -1124,7 +1124,7 @@ int CHudAmmo::DrawWList( float flTime )
else
{
// Draw Row of weapons.
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
for( int iPos = 0; iPos < MAX_WEAPON_POSITIONS; iPos++ )
{
@ -1135,7 +1135,7 @@ int CHudAmmo::DrawWList( float flTime )
if( gWR.HasAmmo( p ) )
{
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
a = 128;
}
else

View File

@ -60,7 +60,7 @@ int CHudAmmoSecondary::Draw( float flTime )
// draw secondary ammo icons above normal ammo readout
int a, x, y, r, g, b, AmmoWidth;
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
a = (int)Q_max( MIN_ALPHA, m_fFade );
if( m_fFade > 0 )
m_fFade -= ( (float)gHUD.m_flTimeDelta * 20.0f ); // slowly lower alpha to fade out icons

View File

@ -125,7 +125,7 @@ int HistoryResource::DrawAmmoHistory( float flTime )
HSPRITE *spr = gWR.GetAmmoPicFromWeapon( rgAmmoHistory[i].iId, rcPic );
int r, g, b;
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
float scale = ( rgAmmoHistory[i].DisplayTime - flTime ) * 80;
ScaleColors( r, g, b, Q_min( scale, 255 ) );
@ -152,7 +152,7 @@ int HistoryResource::DrawAmmoHistory( float flTime )
return 1; // we don't know about the weapon yet, so don't draw anything
int r, g, b;
UnpackRGB( r,g,b, RGB_YELLOWISH );
UnpackRGB( r,g,b, gHUD.uColor );
if( !gWR.HasAmmo( weap ) )
UnpackRGB( r, g, b, RGB_REDISH ); // if the weapon doesn't have ammo, display it as red
@ -174,7 +174,7 @@ int HistoryResource::DrawAmmoHistory( float flTime )
wrect_t rect = gHUD.GetSpriteRect( rgAmmoHistory[i].iId );
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
float scale = ( rgAmmoHistory[i].DisplayTime - flTime ) * 80;
ScaleColors( r, g, b, Q_min( scale, 255 ) );

View File

@ -80,7 +80,7 @@ int CHudBattery::Draw( float flTime )
rc = *m_prc2;
rc.top += m_iHeight * ( (float)( 100 - ( Q_min( 100, m_iBat ) ) ) * 0.01f ); // battery can go from 0 to 100 so * 0.01 goes from 0 to 1
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
if( !( gHUD.m_iWeaponBits & ( 1 << ( WEAPON_SUIT ) ) ) )
return 1;

View File

@ -71,6 +71,10 @@ void EV_SnarkFire( struct event_args_s *args );
void EV_TrainPitchAdjust( struct event_args_s *args );
void EV_VehiclePitchAdjust( event_args_t *args );
void EV_Vorti( struct event_args_s *args );
void EV_FireVorti( struct event_args_s *args );
void EV_SpinVorti( struct event_args_s *args );
}
#define VECTOR_CONE_1DEGREES Vector( 0.00873f, 0.00873f, 0.00873f )

View File

@ -122,7 +122,7 @@ int CHudFlashlight::Draw( float flTime )
if( m_flBat < 0.20f )
UnpackRGB( r,g,b, RGB_REDISH );
else
UnpackRGB( r,g,b, RGB_YELLOWISH );
UnpackRGB( r,g,b, gHUD.uColor );
ScaleColors( r, g, b, a );

View File

@ -167,7 +167,7 @@ void CHudHealth::GetPainColor( int &r, int &g, int &b )
#else
if( m_iHealth > 25 )
{
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
}
else
{
@ -178,6 +178,93 @@ void CHudHealth::GetPainColor( int &r, int &g, int &b )
#endif
}
void CHudHealth::DrawAlienHealthBar( void )
{
if ( m_HUD_alien == -1 )
return;
HSPRITE m_hSprite1;
HSPRITE m_hSprite2;
wrect_t *m_prc1;
wrect_t *m_prc2;
float m_fFade;
int m_iHeight, m_iWidth; // width of the battery innards
m_hSprite1 = m_hSprite2 = 0; // delaying get sprite handles until we know the sprites are loaded
m_prc1 = &gHUD.GetSpriteRect( m_HUD_alien /*HUD_suit_empty*/ );
m_prc2 = &gHUD.GetSpriteRect( m_HUD_alien /*HUD_suit_full*/ );
m_iHeight = m_prc2->bottom - m_prc1->top;
m_iWidth = m_prc2->right - m_prc1->left;
m_fFade = 0;
//=============================================
int r, g, b, x, y, a;
wrect_t rc;
rc = *m_prc2;
//rc.top += m_iHeight * ((float)(100-(min(100,m_iHealth))) * 0.01); // battery can go from 0 to 100 so * 0.01 goes from 0 to 1
rc.left += m_iWidth * ((float)(100-(min(100,m_iHealth))) * 0.005); // battery can go from 0 to 100 so * 0.01 goes from 0 to 1
rc.right -= m_iWidth * ((float)(100-(min(100,m_iHealth))) * 0.005); // battery can go from 0 to 100 so * 0.01 goes from 0 to 1
//UnpackRGB(r,g,b, gHUD.uColor);
r = 180;
g = 255;
b = 96;
// Has health changed? Flash the health #
if (m_fFade)
{
if (m_fFade > FADE_TIME)
m_fFade = FADE_TIME;
m_fFade -= (gHUD.m_flTimeDelta * 20);
if (m_fFade <= 0)
{
a = 128;
m_fFade = 0;
}
// Fade the health number back to dim
a = MIN_ALPHA + (m_fFade/FADE_TIME) * 128;
}
else
a = MIN_ALPHA;
ScaleColors(r, g, b, a );
int iOffset = (m_prc1->bottom - m_prc1->top)/6;
y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2;
x = ScreenWidth/2 - (m_prc1->right - m_prc1->left)/2;
// make sure we have the right sprite handles
if ( !m_hSprite1 )
m_hSprite1 = gHUD.GetSprite( m_HUD_alien );
if ( !m_hSprite2 )
m_hSprite2 = gHUD.GetSprite( m_HUD_alien );
SPR_Set(m_hSprite1, r, g, b );
//SPR_DrawAdditive( 0, x, y - iOffset, m_prc1);
SPR_DrawAdditive( 0, x - iOffset, y, m_prc1);
//if (rc.bottom > rc.top)
if (rc.right > rc.left)
{
SPR_Set(m_hSprite2, r, g, b );
//SPR_DrawAdditive( 0, x, y - iOffset + (rc.top - m_prc2->top), &rc);
SPR_DrawAdditive( 0, x - iOffset + (rc.left - m_prc2->left), y, &rc);
}
//x += (m_prc1->right - m_prc1->left);
x = 32;
x = gHUD.DrawHudNumber(x, y, DHN_3DIGITS | DHN_DRAWZERO, m_iHealth, r, g, b);
return; //1
}
int CHudHealth::Draw( float flTime )
{
int r, g, b;
@ -187,6 +274,12 @@ int CHudHealth::Draw( float flTime )
if( ( gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH ) || gEngfuncs.IsSpectateOnly() )
return 1;
if( m_iFlags & HUD_ALIEN )
{
DrawAlienHealthBar();
return 1;
}
if( !m_hSprite )
m_hSprite = LoadSprite( PAIN_NAME );
@ -233,7 +326,7 @@ int CHudHealth::Draw( float flTime )
int iHeight = gHUD.m_iFontHeight;
int iWidth = HealthWidth / 10;
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
FillRGBA( x, y, iWidth, iHeight, r, g, b, a );
}
@ -382,7 +475,7 @@ int CHudHealth::DrawDamage( float flTime )
if( !m_bitsDamage )
return 1;
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
a = (int)( fabs( sin( flTime * 2.0f ) ) * 256.0f );

View File

@ -105,11 +105,13 @@ public:
virtual int VidInit( void );
virtual int Draw( float fTime );
virtual void Reset( void );
void DrawAlienHealthBar( void );
int MsgFunc_Health( const char *pszName, int iSize, void *pbuf );
int MsgFunc_Damage( const char *pszName, int iSize, void *pbuf );
int m_iHealth;
int m_HUD_dmg_bio;
int m_HUD_cross;
int m_HUD_alien;
float m_fAttackFront, m_fAttackRear, m_fAttackLeft, m_fAttackRight;
void GetPainColor( int &r, int &g, int &b );
float m_fFade;

View File

@ -41,6 +41,10 @@ void EV_SnarkFire( struct event_args_s *args );
void EV_TrainPitchAdjust( struct event_args_s *args );
void EV_VehiclePitchAdjust( event_args_t *args );
void EV_Vorti( struct event_args_s *args );
void EV_FireVorti( struct event_args_s *args );
void EV_SpinVorti( struct event_args_s *args );
}
/*
@ -78,4 +82,7 @@ void Game_HookEvents( void )
gEngfuncs.pfnHookEvent( "events/tripfire.sc", EV_TripmineFire );
gEngfuncs.pfnHookEvent( "events/snarkfire.sc", EV_SnarkFire );
gEngfuncs.pfnHookEvent( "events/vehicle.sc", EV_VehiclePitchAdjust );
gEngfuncs.pfnHookEvent( "events/vorti.sc", EV_Vorti );
gEngfuncs.pfnHookEvent( "events/vortifire.sc", EV_FireVorti );
gEngfuncs.pfnHookEvent( "events/vortispin.sc", EV_SpinVorti );
}

View File

@ -609,6 +609,7 @@ void HUD_InitClientWeapons( void )
// Allocate slot(s) for each weapon that we are going to be predicting
HUD_PrepEntity( &g_Glock, &player );
HUD_PrepEntity( &g_Crowbar, &player );
HUD_PrepEntity( &g_VortiHands, &player );
HUD_PrepEntity( &g_Python, &player );
HUD_PrepEntity( &g_Mp5, &player );
HUD_PrepEntity( &g_Crossbow, &player );
@ -687,6 +688,9 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
case WEAPON_CROWBAR:
pWeapon = &g_Crowbar;
break;
case WEAPON_VORTI:
pWeapon = &g_VortiHands;
break;
case WEAPON_GLOCK:
pWeapon = &g_Glock;
break;

View File

@ -254,6 +254,24 @@ int __MsgFunc_VGUIMenu( const char *pszName, int iSize, void *pbuf )
return 0;
}
int __MsgFunc_Notepad( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if( gViewPort )
return gViewPort->MsgFunc_Notepad( pszName, iSize, pbuf );
#endif
return 0;
}
int __MsgFunc_SparePlayer( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if( gViewPort )
return gViewPort->MsgFunc_SparePlayer( pszName, iSize, pbuf );
#endif
return 0;
}
#if USE_VGUI && !USE_NOVGUI_MOTD
int __MsgFunc_MOTD(const char *pszName, int iSize, void *pbuf)
{
@ -451,6 +469,8 @@ void CHud::Init( void )
m_AmmoSecondary.Init();
m_TextMessage.Init();
m_StatusIcons.Init();
m_ModeIcon.Init();
m_AlienCrosshair.Init();
#if USE_VGUI
GetClientVoiceMgr()->Init(&g_VoiceStatusHelper, (vgui::Panel**)&gViewPort);
#endif
@ -523,6 +543,8 @@ void CHud::VidInit( void )
m_hsprLogo = 0;
m_hsprCursor = 0;
m_iLensIndex = 0;
if( ScreenWidth < 640 )
m_iRes = 320;
else
@ -659,6 +681,8 @@ void CHud::VidInit( void )
m_AmmoSecondary.VidInit();
m_TextMessage.VidInit();
m_StatusIcons.VidInit();
m_ModeIcon.VidInit();
m_AlienCrosshair.VidInit();
#if USE_VGUI
GetClientVoiceMgr()->VidInit();
#endif

View File

@ -581,6 +581,8 @@ private:
//
//-----------------------------------------------------
//
#define CAM_OFF 0
#define CAM_ON 1
class CHud
{
private:
@ -673,6 +675,8 @@ public:
CHudAmmoSecondary m_AmmoSecondary;
CHudTextMessage m_TextMessage;
CHudStatusIcons m_StatusIcons;
CHudModeIcon m_ModeIcon;
CHudAlienCrosshair m_AlienCrosshair;
#if !USE_VGUI || USE_NOVGUI_SCOREBOARD
CHudScoreboard m_Scoreboard;
#endif
@ -692,12 +696,17 @@ public:
// user messages
int _cdecl MsgFunc_Damage( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_DecayName( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_Logo( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_ResetHUD( const char *pszName, int iSize, void *pbuf );
void _cdecl MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf );
void _cdecl MsgFunc_ViewMode( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_LensFlare( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_AimFrame( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_Camera( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_ChangePlayer( const char *pszName, int iSize, void *pbuf );
// Screen information
SCREENINFO m_scrinfo;

View File

@ -87,16 +87,75 @@ void CHud::MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf )
pFlare = NULL; // Vit_amiN: clear egon's beam flare
}
int CHud::MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf )
void CHud::MsgFunc_Camera( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
m_Teamplay = READ_BYTE();
if( m_Teamplay )
ClientCmd( "richpresence_gamemode Teamplay\n" );
m_iCamMode = READ_BYTE();
m_vecCamPos.x = READ_COORD();
m_vecCamPos.y = READ_COORD();
m_vecCamPos.z = READ_COORD();
gHUD.DrawHudString( 100, 100, ScreenWidth, "Camera message received!", 255, 180, 0 );
}
int CHud::MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf )
{
gEngfuncs.pfnConsolePrint("--- MsgFunc_GameMode ---\n");
m_Teamplay = 0; //READ_BYTE();
BEGIN_READ( pbuf, iSize );
int bMode = READ_BYTE();
if ( bMode == 2 )
{
m_bAlienMode = true;
m_Health.m_iFlags |= HUD_ALIEN;
//m_TextMessage.m_iFlags |= HUD_ALIEN;
gEngfuncs.pfnConsolePrint("--- AlIEN SLAVE MODE ---\n");
}
else
ClientCmd( "richpresence_gamemode\n" );
ClientCmd( "richpresence_update\n" );
if ( bMode == 3 )
{
m_bAlienMode = false;
m_Health.m_iFlags &= ~HUD_ALIEN;
//m_TextMessage.m_iFlags &= ~HUD_ALIEN;
gEngfuncs.pfnConsolePrint("--- NORMAL MODE ---\n");
}
return 1;
}
int CHud::MsgFunc_DecayName( const char *spzName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
int iPlayerDecayId;
iPlayerDecayId = READ_BYTE();
char name[32];
sprintf( name, "Spare player" );
if ( iPlayerDecayId == 1 )
{
if ( m_bAlienMode )
sprintf( name, "X-8973" );
else
sprintf( name, "Gina" );
}
if ( iPlayerDecayId == 2 )
{
if ( m_bAlienMode )
sprintf( name, "R-4913" );
else
sprintf( name, "Colette" );
}
char buf[256];
sprintf(buf, "name \"%s\"\n", name);
gEngfuncs.pfnClientCmd(buf);
return 1;
}

View File

@ -12,6 +12,11 @@
* without written permission from Valve LLC.
*
****/
/***
*
* (C) 2008 Vyacheslav Dzhura
*
****/
//
// hud_redraw.cpp
//
@ -19,7 +24,11 @@
#include "hud.h"
#include "cl_util.h"
//#include "triangleapi.h"
#include "triangleapi.h"
#include "pmtrace.h"
#include "pm_defs.h"
#include "event_api.h"
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
@ -27,6 +36,9 @@
#define MAX_LOGO_FRAMES 56
extern vec3_t v_origin;
int g_iFrameSize;
int grgLogoFrame[MAX_LOGO_FRAMES] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 12, 11, 10, 9, 8, 14, 15,
@ -233,17 +245,18 @@ int CHud::Redraw( float flTime, int intermission )
while( pList )
{
if( !intermission )
if ( !m_bAlienMode )
{
if ( ( pList->p->m_iFlags & HUD_ACTIVE ) && !( m_iHideHUDDisplay & HIDEHUD_ALL ) )
pList->p->Draw( flTime );
}
else
{
// it's an intermission, so only draw hud elements that are set to draw during intermissions
if( pList->p->m_iFlags & HUD_INTERMISSION )
pList->p->Draw( flTime );
}
if ( !intermission )
{
if ( (pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL) )
pList->p->Draw(flTime);
}
else
{ // it's an intermission, so only draw hud elements that are set to draw during intermissions
if ( pList->p->m_iFlags & HUD_INTERMISSION )
pList->p->Draw( flTime );
}
} else
{ // alien mode!!!
if ( pList->p->m_iFlags & HUD_ALIEN )

View File

@ -1536,7 +1536,7 @@ void CHudSpectator::DrawOverviewEntities()
z = m_OverviewData.layersHeights[0] * zScale;
// get yellow/brown HUD color
UnpackRGB( ir, ig, ib, RGB_YELLOWISH );
UnpackRGB( ir, ig, ib, gHUD.uColor );
r = (float)ir / 255.0f;
g = (float)ig / 255.0f;
b = (float)ib / 255.0f;

View File

@ -37,6 +37,8 @@ int CHudMessage::Init( void )
HOOK_MESSAGE( HudText );
HOOK_MESSAGE( GameTitle );
iFlags |= HUD_ALIEN;
gHUD.AddHudElem( this );
Reset();

View File

@ -53,7 +53,7 @@ int CHudTrain::Draw( float fTime )
{
int r, g, b, x, y;
UnpackRGB( r, g, b, RGB_YELLOWISH );
UnpackRGB( r, g, b, gHUD.uColor );
SPR_Set( m_hSprite, r, g, b );
// This should show up to the right and part way up the armor number

View File

@ -58,6 +58,8 @@ class DragNDropPanel;
class CTransparentPanel;
class CClassMenuPanel;
class CTeamMenuPanel;
class CNotepad;
class CSparePlayerWindow;
class TeamFortressViewport;
char *GetVGUITGAName( const char *pszName );
@ -551,6 +553,8 @@ public:
int CreateCommandMenu( const char * menuFile, int direction, int yOffset, bool flatDesign, float flButtonSizeX, float flButtonSizeY, int xOffset );
void CreateScoreBoard( void );
void CreateNotepad( void );
void CreateSparePlayerWindow( void );
CommandButton * CreateCustomButton( char *pButtonText, char * pButtonName, int iYOffset );
CCommandMenu * CreateDisguiseSubmenu( CommandButton *pButton, CCommandMenu *pParentMenu, const char *commandText, int iYOffset, int iXOffset = 0 );
@ -616,6 +620,8 @@ public:
int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf );
int MsgFunc_Spectator( const char *pszName, int iSize, void *pbuf );
int MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf );
int MsgFunc_Notepad( const char *pszName, int iSize, void *pbuf );
int MsgFunc_SparePlayer( const char *pszName, int iSize, void *pbuf );
int MsgFunc_SpecFade( const char *pszName, int iSize, void *pbuf );
int MsgFunc_ResetFade( const char *pszName, int iSize, void *pbuf );

View File

@ -423,6 +423,26 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams )
vec3_t camAngles, camForward, camRight, camUp;
cl_entity_t *pwater;
// SKY START
static struct model_t *savedviewmodel;
//LRC - if this is the second pass through, then we've just drawn the sky, and now we're setting up the normal view.
if( pparams->nextView == 1 )
{
GrabCameraTexture();
view = gEngfuncs.GetViewModel();
view->model = savedviewmodel;
pparams->viewangles[0] = v_angles.x;
pparams->viewangles[1] = v_angles.y;
pparams->viewangles[2] = v_angles.z;
pparams->vieworg[0] = v_origin.x;
pparams->vieworg[1] = v_origin.y;
pparams->vieworg[2] = v_origin.z;
pparams->nextView = 0;
return;
}
// SKY END
if( gEngfuncs.IsSpectateOnly() )
{
ent = gEngfuncs.GetEntityByIndex( g_iUser2 );
@ -1347,21 +1367,23 @@ int V_FindViewModelByWeaponModel( int weaponindex )
{
static const char *modelmap[][2] =
{
{ "models/p_crossbow.mdl", "models/v_crossbow.mdl" },
{ "models/p_crowbar.mdl", "models/v_crowbar.mdl" },
{ "models/p_egon.mdl", "models/v_egon.mdl" },
{ "models/p_gauss.mdl", "models/v_gauss.mdl" },
{ "models/p_9mmhandgun.mdl", "models/v_9mmhandgun.mdl" },
{ "models/p_grenade.mdl", "models/v_grenade.mdl" },
{ "models/p_hgun.mdl", "models/v_hgun.mdl" },
{ "models/p_9mmAR.mdl", "models/v_9mmAR.mdl" },
{ "models/p_357.mdl", "models/v_357.mdl" },
{ "models/p_rpg.mdl", "models/v_rpg.mdl" },
{ "models/p_shotgun.mdl", "models/v_shotgun.mdl" },
{ "models/p_squeak.mdl", "models/v_squeak.mdl" },
{ "models/p_tripmine.mdl", "models/v_tripmine.mdl" },
{ "models/p_satchel_radio.mdl", "models/v_satchel_radio.mdl" },
{ "models/p_satchel.mdl", "models/v_satchel.mdl" },
{ "models/p_crossbow.mdl", "models/v_crossbow.mdl" },
{ "models/p_crowbar.mdl", "models/v_crowbar.mdl" },
{ "models/p_egon.mdl", "models/v_egon.mdl" },
{ "models/p_gauss.mdl", "models/v_gauss.mdl" },
{ "models/p_9mmhandgun.mdl", "models/v_9mmhandgun.mdl" },
{ "models/p_grenade.mdl", "models/v_grenade.mdl" },
{ "models/p_hgun.mdl", "models/v_hgun.mdl" },
{ "models/p_9mmAR.mdl", "models/v_9mmAR.mdl" },
{ "models/p_357.mdl", "models/v_357.mdl" },
{ "models/p_rpg.mdl", "models/v_rpg.mdl" },
{ "models/p_shotgun.mdl", "models/v_shotgun.mdl" },
{ "models/p_squeak.mdl", "models/v_squeak.mdl" },
{ "models/p_tripmine.mdl", "models/v_tripmine.mdl" },
{ "models/p_satchel_radio.mdl", "models/v_satchel_radio.mdl" },
{ "models/p_satchel.mdl", "models/v_satchel.mdl" },
{ "models/p_displacer.mdl", "models/v_displacer.mdl" },
{ "models/p_slave.mdl", "models/v_slave.mdl" },
{ NULL, NULL }
};

View File

@ -377,12 +377,12 @@ void CBarney::HandleAnimEvent( MonsterEvent_t *pEvent )
break;
case BARNEY_AE_DRAW:
// barney's bodygroup switches here so he can pull gun from holster
pev->body = BARNEY_BODY_GUNDRAWN;
SetBodygroup( GUN_GROUP, BARNEY_BODY_GUNDRAWN );
m_fGunDrawn = TRUE;
break;
case BARNEY_AE_HOLSTER:
// change bodygroup to replace gun in holster
pev->body = BARNEY_BODY_GUNHOLSTERED;
SetBodygroup( GUN_GROUP, BARNEY_BODY_GUNHOLSTERED );
m_fGunDrawn = FALSE;
break;
default:
@ -609,13 +609,13 @@ void CBarney::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir
void CBarney::Killed( entvars_t *pevAttacker, int iGib )
{
if( pev->body < BARNEY_BODY_GUNGONE )
if( GetBodygroup( GUN_GROUP ) < BARNEY_BODY_GUNGONE )
{
// drop the gun!
Vector vecGunPos;
Vector vecGunAngles;
pev->body = BARNEY_BODY_GUNGONE;
SetBodygroup( GUN_GROUP, BARNEY_BODY_GUNGONE );
GetAttachment( 0, vecGunPos, vecGunAngles );

View File

@ -186,7 +186,10 @@ void CMultiSource::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
}
// CONSIDER: a Use input to the multisource always toggles. Could check useType for ON/OFF/TOGGLE
m_rgTriggered[i - 1] ^= 1;
if( !FBitSet( pev->spawnflags, SF_MULTI_NO_TOGGLE ))
m_rgTriggered[i - 1] ^= 1;
else
m_rgTriggered[i-1] = 1;
//
if( IsTriggered( pActivator ) )
@ -1166,6 +1169,13 @@ void CMomentaryRotButton::Off( void )
{
pev->avelocity = g_vecZero;
m_lastUsed = 0;
if ( ( pev->angles == m_end ) && (!FStringNull( m_iszEndLockTarget )) )
{
FireTargets(STRING( m_iszEndLockTarget ), this, this, USE_TOGGLE, 0);
SetThink( NULL );
return;
}
if( FBitSet( pev->spawnflags, SF_PENDULUM_AUTO_RETURN ) && m_returnSpeed > 0 )
{
SetThink( &CMomentaryRotButton::Return );

View File

@ -39,6 +39,18 @@
#include "usercmd.h"
#include "netadr.h"
#include "pm_shared.h"
// START BOT
#include "bot.h"
void BotCreate(const char *skin, const char *name, const char skill);
extern int f_Observer; // flag for observer mode
extern int f_botskill; // default bot skill level
extern int f_botdontshoot; // flag to disable targeting other ots
extern respawn_t bot_respawn[32];
float bot_check_time = 10.0;
int min_bots = 0;
int max_bots = 0;
// END BOT
extern DLL_GLOBAL ULONG g_ulModelIndexPlayer;
extern DLL_GLOBAL BOOL g_fGameOver;
@ -64,7 +76,9 @@ void LinkUserMessages( void );
*/
void set_suicide_frame( entvars_t *pev )
{
if( !FStrEq( STRING( pev->model ), "models/player.mdl" ) )
if( !FStrEq( STRING( pev->model ), "models/player.mdl" )
|| !FStrEq( STRING( pev->model ), "models/player/dm_slave/dm_slave.mdl" )
|| !FStrEq( STRING( pev->model ), "models/ginacol.mdl" ))
return; // allready gibbed
//pev->frame = $deatha11;
@ -528,6 +542,66 @@ void ClientCommand( edict_t *pEntity )
{
Host_Say( pEntity, 0 );
}
else if ( FStrEq(pcmd, "changeplayer" ) ) // do Decay's player change (e.g. controllable-bot and vise-versa)
{
if (g_pGameRules->IsCoOp())
{
CDecayRules *g_pDecayRules;
g_pDecayRules = (CDecayRules*)g_pGameRules;
g_pDecayRules->ChangePlayer();
}
}
else if ( FStrEq(pcmd, "changeplayer2" ) ) // change player_index of active player to test Decay in SP mode
{
if (g_pGameRules->IsCoOp())
{
CDecayRules *g_pDecayRules;
g_pDecayRules = (CDecayRules*)g_pGameRules;
if (g_pDecayRules->pPlayers[0]->m_iDecayId == 1)
{
g_pDecayRules->pPlayers[0]->m_iDecayId = 2;
// if ( !FNullEnt( g_pDecayRules->pPlayers[1]->pev ))
// g_pDecayRules->pPlayers[1]->m_iDecayId = 1;
}
else
{
g_pDecayRules->pPlayers[0]->m_iDecayId = 1;
// if ( !FNullEnt( g_pDecayRules->pPlayers[1]->pev ))
// g_pDecayRules->pPlayers[1]->m_iDecayId = 2;
}
ALERT( at_console, "Player 1 index changed to %d\n", g_pDecayRules->pPlayers[0]->m_iDecayId );
//if ( !FNullEnt( g_pDecayRules->pPlayers[1]->pev ))
// ALERT( at_console, "Player 2 index changed to %d\n", g_pDecayRules->pPlayers[1]->m_iDecayId );
}
}
else if ( FStrEq( pcmd, "euukraine" ) )
{
if ( g_pGameRules->IsCoOp() )
{
bool bUnlockAlien = strcmp( CMD_ARGV(1), "visafree" ) == 0;
CDecayRules *g_pDecayRules;
g_pDecayRules = (CDecayRules*)g_pGameRules;
g_pDecayRules->unlockMissions( bUnlockAlien );
g_pDecayRules->statsSave();
}
}
else if ( FStrEq( pcmd, "test1" ) )
{
MESSAGE_BEGIN(MSG_ALL, SVC_INTERMISSION);
MESSAGE_END();
}
else if ( FStrEq(pcmd, "stripall" ) )
{
if (g_pGameRules->IsCoOp())
{
CDecayRules *g_pDecayRules;
g_pDecayRules = (CDecayRules*)g_pGameRules;
g_pDecayRules->pPlayers[0]->PackAllItems();
if ( !FNullEnt(g_pDecayRules->pPlayers[1]->pev) )
g_pDecayRules->pPlayers[1]->PackAllItems();
}
}
else if( FStrEq( pcmd, "say_team" ) )
{
Host_Say( pEntity, 1 );
@ -603,6 +677,81 @@ void ClientCommand( edict_t *pEntity )
{
GetClassPtr( (CBasePlayer *)pev )->SelectLastItem();
}
// ***************************
// START BOT
else if (FStrEq(pcmd, "addbot" ))
{
if (!IS_DEDICATED_SERVER())
{
//If user types "addbot" in console, add a bot with skin and name
if (!bSlaveCoop)
BotCreate("ginacol", "Colette", 0); // CMD_ARGV(1), CMD_ARGV(2), CMD_ARGV(3)
else
BotCreate("player/dm_slave/dm_slave", "R-4913", 0);
}
else
CLIENT_PRINTF( pEntity, print_console, "addbot not allowed from client!\n" );
}
else if (FStrEq(pcmd, "debugbot" ))
{
if (!bSlaveCoop)
BotCreate("ginacol", "Colette", 0); // CMD_ARGV(1), CMD_ARGV(2), CMD_ARGV(3)
else
BotCreate("player/dm_slave/dm_slave", "R-4913", 0);
}
/*
else if ( FStrEq(pcmd, "observer" ) )
{
if (!IS_DEDICATED_SERVER())
{
if (CMD_ARGC() > 1) // is there an argument to the command?
{
f_Observer = atoi( CMD_ARGV(1) ); // set observer flag
CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs("\"observer\" set to %d\n", (int)f_Observer) );
}
else
{
CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs("\"observer\" is %d\n", (int)f_Observer) );
}
}
else
CLIENT_PRINTF( pEntity, print_console, "observer not allowed from client!\n" );
}*/
else if ( FStrEq(pcmd, "botskill" ) )
{
if (!IS_DEDICATED_SERVER())
{
if (CMD_ARGC() > 1)
{
f_botskill = atoi( CMD_ARGV(1) ); // set default bot skill level
CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs("\"botskill\" set to %d\n", (int)f_botskill) );
}
else
{
CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs("\"botskill\" is %d\n", (int)f_botskill) );
}
}
else
CLIENT_PRINTF( pEntity, print_console, "botskill not allowed from client!\n" );
}
else if ( FStrEq(pcmd, "botdontshoot" ) )
{
if (!IS_DEDICATED_SERVER())
{
if (CMD_ARGC() > 1) // is there an argument to the command?
{
f_botdontshoot = atoi( CMD_ARGV(1) ); // set bot shoot flag
CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs("\"botdontshoot\" set to %d\n", (int)f_botdontshoot) );
}
else
{
CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs("\"botdontshoot\" is %d\n", (int)f_botdontshoot) );
}
}
else
CLIENT_PRINTF( pEntity, print_console, "botdontshoot not allowed from client!\n" );
}
// ***************************
else if( FStrEq( pcmd, "spectate" ) ) // clients wants to become a spectator
{
CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev );
@ -852,15 +1001,420 @@ void ParmsChangeLevel( void )
void StartFrame( void )
{
//ALERT( at_console, "SV_Physics( %g, frametime %g )\n", gpGlobals->time, gpGlobals->frametime );
// START BOT
static BOOL file_opened = FALSE;
static int length;
static char *pFileList, *aFileList;
static char cmd_line[80];
static char server_cmd[80];
static int index, i;
static float pause_time;
static float check_server_cmd = 0;
char *cmd, *arg1, *arg2, *arg3;
static float respawn_time = 0;
static float previous_time = 0.0;
char msg[120];
// END BOT
if( g_pGameRules )
// START BOT - thanks Jehannum!
// loop through all the players...
for ( i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *pPlayer;
pPlayer = UTIL_PlayerByIndex( i );
if (!pPlayer) // if invalid then continue with next index...
continue;
// check if this is a FAKECLIENT (i.e. is it a bot?)
if (FBitSet(pPlayer->pev->flags, FL_FAKECLIENT))
{
CBot *pBot = (CBot *)pPlayer;
// call the think function for the bot...
pBot->BotThink();
}
}
// END BOT
// START BOT
/*
if ((g_fGameOver) && (respawn_time < 1.0))
{
// if the game is over (time/frag limit) set the respawn time...
respawn_time = 5.0;
// check if any players are using the botcam...
for ( i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer;
pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );
if (!pPlayer)
continue; // if invalid then continue with next index...
if (pPlayer->pBotCam)
pPlayer->pBotCam->Disconnect();
}
}*/
// check if a map was changed via "map" without kicking bots...
if (previous_time > gpGlobals->time)
{
bot_check_time = gpGlobals->time + 10.0;
for (index = 0; index < 32; index++)
{
if ((bot_respawn[index].is_used) && // is this slot used?
(bot_respawn[index].state != BOT_NEED_TO_RESPAWN))
{
// bot has already been "kicked" by server so just set flag
bot_respawn[index].state = BOT_NEED_TO_RESPAWN;
// if the map was changed set the respawn time...
respawn_time = 5.0;
}
}
}
// is new game started and time to respawn bots yet?
if ((!g_fGameOver) && (respawn_time > 1.0) &&
(gpGlobals->time >= respawn_time))
{
int index = 0;
bot_check_time = gpGlobals->time + 5.0;
// find bot needing to be respawned...
while ((index < 32) &&
(bot_respawn[index].state != BOT_NEED_TO_RESPAWN))
index++;
if (index < 32)
{
bot_respawn[index].state = BOT_IS_RESPAWNING;
bot_respawn[index].is_used = FALSE; // free up this slot
// respawn 1 bot then wait a while (otherwise engine crashes)
BotCreate(bot_respawn[index].skin,
bot_respawn[index].name,
bot_respawn[index].skill);
respawn_time = gpGlobals->time + 1.0; // set next respawn time
}
else
{
respawn_time = 0.0;
}
}
// END BOT
if ( g_pGameRules )
{
g_pGameRules->Think();
//if (!botadded)
//{
// botadded = TRUE;
// BotCreate("ginacol", "Colette", "1");
//}
/*
// START BOT
if (!file_opened) // have we open bot.cfg file yet?
{
ALERT( at_console, "Executing bot.cfg\n" );
pFileList = (char *)LOAD_FILE_FOR_ME( "bot.cfg", &length);
file_opened = TRUE;
if (pFileList == NULL)
ALERT( at_console, "bot.cfg file not found\n" );
pause_time = gpGlobals->time;
index = 0;
cmd_line[index] = 0; // null out command line
}
// if the bot.cfg file is still open and time to execute command...
while ((pFileList && *pFileList) && (pause_time <= gpGlobals->time))
{
while (*pFileList == ' ') // skip any leading blanks
pFileList++;
while ((*pFileList != '\r') && (*pFileList != '\n') &&
(*pFileList != 0))
{
if (*pFileList == '\t') // convert tabs to spaces
*pFileList = ' ';
cmd_line[index] = *pFileList;
pFileList++;
while ((cmd_line[index] == ' ') && (*pFileList == ' '))
pFileList++; // skip multiple spaces
index++;
}
if (*pFileList == '\r')
{
pFileList++; // skip the carriage return
pFileList++; // skip the linefeed
}
else if (*pFileList == '\n')
{
pFileList++; // skip the newline
}
cmd_line[index] = 0; // terminate the command line
// copy the command line to a server command buffer...
strcpy(server_cmd, cmd_line);
strcat(server_cmd, "\n");
index = 0;
cmd = cmd_line;
arg1 = arg2 = arg3 = NULL;
// skip to blank or end of string...
while ((cmd_line[index] != ' ') && (cmd_line[index] != 0))
index++;
if (cmd_line[index] == ' ')
{
cmd_line[index++] = 0;
arg1 = &cmd_line[index];
// skip to blank or end of string...
while ((cmd_line[index] != ' ') && (cmd_line[index] != 0))
index++;
if (cmd_line[index] == ' ')
{
cmd_line[index++] = 0;
arg2 = &cmd_line[index];
// skip to blank or end of string...
while ((cmd_line[index] != ' ') && (cmd_line[index] != 0))
index++;
if (cmd_line[index] == ' ')
{
cmd_line[index++] = 0;
arg3 = &cmd_line[index];
}
}
}
index = 0; // reset for next input line
if ((cmd_line[0] == '#') || (cmd_line[0] == 0))
{
continue; // ignore comments or blank lines
}
else if (strcmp(cmd, "addbot") == 0)
{
BotCreate( arg1, arg2, arg3 );
// have to delay here or engine gives "Tried to write to
// uninitialized sizebuf_t" error and crashes...
pause_time = gpGlobals->time + 1;
break;
}
else if (strcmp(cmd, "botskill") == 0)
{
f_botskill = atoi( arg1 ); // set default bot skill level
}
else if (strcmp(cmd, "observer") == 0)
{
f_Observer = atoi( arg1 ); // set observer flag
}
else if (strcmp(cmd, "botdontshoot") == 0)
{
f_botdontshoot = atoi( arg1 ); // set bot shoot flag
}
else if (strcmp(cmd, "min_bots") == 0)
{
min_bots = atoi( arg1 );
if (min_bots < 0)
min_bots = 0;
if (IS_DEDICATED_SERVER())
{
sprintf(msg, "min_bots set to %d\n", min_bots);
printf(msg);
}
}
else if (strcmp(cmd, "max_bots") == 0)
{
max_bots = atoi( arg1 );
if (max_bots >= gpGlobals->maxClients)
max_bots = gpGlobals->maxClients - 1;
if (IS_DEDICATED_SERVER())
{
sprintf(msg, "max_bots set to %d\n", max_bots);
printf(msg);
}
}
else if (strcmp(cmd, "pause") == 0)
{
pause_time = gpGlobals->time + atoi( arg1 );
break;
}
else
{
sprintf(msg, "executing server command: %s\n", server_cmd);
ALERT( at_console, msg );
if (IS_DEDICATED_SERVER())
printf(msg);
SERVER_COMMAND(server_cmd);
}
}
// if bot.cfg file is open and reached end of file, then close and free it
if (pFileList && (*pFileList == 0))
{
FREE_FILE(aFileList);
pFileList = NULL;
}
*/
// if time to check for server commands then do so...
if (check_server_cmd <= gpGlobals->time)
{
check_server_cmd = gpGlobals->time + 1.0;
char *cvar_bot = (char *)CVAR_GET_STRING( "bot" );
if ( cvar_bot && cvar_bot[0] )
{
strcpy(cmd_line, cvar_bot);
index = 0;
cmd = cmd_line;
arg1 = arg2 = arg3 = NULL;
// skip to blank or end of string...
while ((cmd_line[index] != ' ') && (cmd_line[index] != 0))
index++;
if (cmd_line[index] == ' ')
{
cmd_line[index++] = 0;
arg1 = &cmd_line[index];
// skip to blank or end of string...
while ((cmd_line[index] != ' ') && (cmd_line[index] != 0))
index++;
if (cmd_line[index] == ' ')
{
cmd_line[index++] = 0;
arg2 = &cmd_line[index];
// skip to blank or end of string...
while ((cmd_line[index] != ' ') && (cmd_line[index] != 0))
index++;
if (cmd_line[index] == ' ')
{
cmd_line[index++] = 0;
arg3 = &cmd_line[index];
}
}
}
if (strcmp(cmd, "addbot") == 0)
{
printf("adding new bot...\n");
BotCreate( arg1, arg2, arg3 );
}
else if (strcmp(cmd, "botskill") == 0)
{
if (arg1 != NULL)
{
printf("setting botskill to %d\n", atoi( arg1 ));
f_botskill = atoi( arg1 ); // set default bot skill level
}
else
printf("botskill is %d\n", f_botskill);
}
else if (strcmp(cmd, "botdontshoot") == 0)
{
if (arg1 != NULL)
{
printf("setting botdontshoot to %d\n", atoi( arg1 ));
f_botdontshoot = atoi( arg1 ); // set bot shoot flag
}
else
printf("botdontshoot is %d\n", f_botdontshoot);
}
CVAR_SET_STRING("bot", "");
}
}
// END BOT
}
if( g_fGameOver )
{
return;
// START BOT
check_server_cmd = 0;
// END BOT
}
g_iSkillLevel = CVAR_GET_FLOAT("skill");
gpGlobals->teamplay = teamplay.value;
g_ulFrameCount++;
// START BOT
// check if time to see if a bot needs to be created...
if (bot_check_time < gpGlobals->time)
{
int count = 0;
bot_check_time = gpGlobals->time + 5.0;
for ( i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *pPlayer;
pPlayer = UTIL_PlayerByIndex( i );
if (!pPlayer)
continue; // if invalid then continue with next index...
if (pPlayer->pev->takedamage == DAMAGE_NO)
continue; // if bot was kicked, don't count as a player...
count++; // count the number of bots and players
}
// if there are currently less than the maximum number of "players"
// then add another bot using the default skill level...
if (count < max_bots)
{
BotCreate( NULL, NULL, NULL );
}
}
previous_time = gpGlobals->time; // keep track of last time in StartFrame()
// END BOT
}
void ClientPrecache( void )
@ -957,6 +1511,7 @@ void ClientPrecache( void )
PRECACHE_SOUND( "player/pl_pain7.wav" );
PRECACHE_MODEL( "models/player.mdl" );
PRECACHE_MODEL("models/player/dm_slave/dm_slave.mdl");
// hud sounds
PRECACHE_SOUND( "common/wpn_hudoff.wav" );
@ -973,6 +1528,49 @@ void ClientPrecache( void )
PRECACHE_SOUND( "player/geiger2.wav" );
PRECACHE_SOUND( "player/geiger1.wav" );
if (!IS_DEDICATED_SERVER())
{
//
// Decay bot sounds
//
PRECACHE_SOUND( GI_SND1 );
PRECACHE_SOUND( GI_SND2 );
PRECACHE_SOUND( GI_SND3 );
PRECACHE_SOUND( GI_SND4 );
PRECACHE_SOUND( GI_SND5 );
PRECACHE_SOUND( CO_SND1 );
PRECACHE_SOUND( CO_SND2 );
PRECACHE_SOUND( CO_SND3 );
PRECACHE_SOUND( CO_SND4 );
PRECACHE_SOUND( CO_SND5 );
//
// joy after successful enemy kill
//
PRECACHE_SOUND( CO_TNT1 );
PRECACHE_SOUND( CO_TNT2 );
PRECACHE_SOUND( CO_TNT3 );
PRECACHE_SOUND( CO_TNT4 );
PRECACHE_SOUND( CO_TNT5 );
PRECACHE_SOUND( GI_TNT1 );
PRECACHE_SOUND( GI_TNT2 );
PRECACHE_SOUND( GI_TNT3 );
PRECACHE_SOUND( GI_TNT4 );
PRECACHE_SOUND( GI_TNT5 );
PRECACHE_SOUND( USE_TEAMPLAY_SND );
PRECACHE_SOUND( USE_TEAMPLAY_LATER_SND );
PRECACHE_SOUND( USE_TEAMPLAY_ENEMY_SND );
//
// end of Decay bot sounds
//
}
if( giPrecacheGrunt )
UTIL_PrecacheOther( "monster_human_grunt" );
}

View File

@ -30,6 +30,7 @@
#include "weapons.h"
#include "func_break.h"
#include "game.h"
#include "gamerules.h"
extern DLL_GLOBAL Vector g_vecAttackDir;
extern DLL_GLOBAL int g_iSkillLevel;
@ -551,7 +552,10 @@ void CBaseMonster::CallGibMonster( void )
}
if( ShouldFadeOnDeath() && !fade )
{
UTIL_Remove( this );
// DECAY BOTAI FIX TODO: object gets removed here when killed with "blast" power
}
}
/*
@ -1480,6 +1484,12 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi
ClearMultiDamage();
gMultiDamage.type = DMG_BULLET | DMG_NEVERGIB;
//
// DECAY STATS!!! MISSES AND HITS GO THROUGH HERE
//
int ishotId = RANDOM_LONG(1, 1000);
g_pGameRules->BulletsFired( pevAttacker, cShots, iBulletType, ishotId );
for( ULONG iShot = 1; iShot <= cShots; iShot++ )
{
//Use player's random seed.
@ -1501,6 +1511,8 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi
{
CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit );
g_pGameRules->BulletHit( pEntity, pevAttacker, ishotId );
if( iDamage )
{
pEntity->TraceAttack( pevAttacker, iDamage, vecDir, &tr, DMG_BULLET | ( ( iDamage > 16 ) ? DMG_ALWAYSGIB : DMG_NEVERGIB ) );

View File

@ -544,43 +544,6 @@ void CController::StartTask( Task_t *pTask )
}
}
Vector Intersect( Vector vecSrc, Vector vecDst, Vector vecMove, float flSpeed )
{
Vector vecTo = vecDst - vecSrc;
float a = DotProduct( vecMove, vecMove ) - flSpeed * flSpeed;
float b = 0 * DotProduct( vecTo, vecMove ); // why does this work?
float c = DotProduct( vecTo, vecTo );
float t;
if( a == 0 )
{
t = c / ( flSpeed * flSpeed );
}
else
{
t = b * b - 4.0f * a * c;
t = sqrt( t ) / ( 2.0f * a );
float t1 = -b +t;
float t2 = -b -t;
if( t1 < 0 || t2 < t1 )
t = t2;
else
t = t1;
}
// ALERT( at_console, "Intersect %f\n", t );
if( t < 0.1f )
t = 0.1f;
if( t > 10.0f )
t = 10.0f;
Vector vecHit = vecTo + vecMove * t;
return vecHit.Normalize() * flSpeed;
}
int CController::LookupFloat()
{
if( m_velocity.Length() < 32.0f )
@ -642,7 +605,7 @@ void CController::RunTask( Task_t *pTask )
{
m_vecEstVelocity = m_vecEstVelocity * 0.8f;
}
vecDir = Intersect( vecSrc, m_hEnemy->BodyTarget( pev->origin ), m_vecEstVelocity, gSkillData.controllerSpeedBall );
vecDir = UTIL_Intersect( vecSrc, m_hEnemy->BodyTarget( pev->origin ), m_vecEstVelocity, gSkillData.controllerSpeedBall );
float delta = 0.03490f; // +-2 degree
vecDir = vecDir + Vector( RANDOM_FLOAT( -delta, delta ), RANDOM_FLOAT( -delta, delta ), RANDOM_FLOAT( -delta, delta ) ) * gSkillData.controllerSpeedBall;
@ -728,7 +691,7 @@ Schedule_t *CController::GetSchedule( void )
{
case MONSTERSTATE_COMBAT:
{
// Vector vecTmp = Intersect( Vector( 0, 0, 0 ), Vector( 100, 4, 7 ), Vector( 2, 10, -3 ), 20.0f );
// Vector vecTmp = UTIL_Intersect( Vector( 0, 0, 0 ), Vector( 100, 4, 7 ), Vector( 2, 10, -3 ), 20.0f );
// dead enemy
if( HasConditions( bits_COND_LIGHT_DAMAGE ) )

View File

@ -109,50 +109,6 @@ void CCrowbar::Holster( int skiplocal /* = 0 */ )
SendWeaponAnim( CROWBAR_HOLSTER );
}
void FindHullIntersection( const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity )
{
int i, j, k;
float distance;
float *minmaxs[2] = {mins, maxs};
TraceResult tmpTrace;
Vector vecHullEnd = tr.vecEndPos;
Vector vecEnd;
distance = 1e6f;
vecHullEnd = vecSrc + ( ( vecHullEnd - vecSrc ) * 2.0f );
UTIL_TraceLine( vecSrc, vecHullEnd, dont_ignore_monsters, pEntity, &tmpTrace );
if( tmpTrace.flFraction < 1.0f )
{
tr = tmpTrace;
return;
}
for( i = 0; i < 2; i++ )
{
for( j = 0; j < 2; j++ )
{
for( k = 0; k < 2; k++ )
{
vecEnd.x = vecHullEnd.x + minmaxs[i][0];
vecEnd.y = vecHullEnd.y + minmaxs[j][1];
vecEnd.z = vecHullEnd.z + minmaxs[k][2];
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, pEntity, &tmpTrace );
if( tmpTrace.flFraction < 1.0f )
{
float thisDistance = ( tmpTrace.vecEndPos - vecSrc ).Length();
if( thisDistance < distance )
{
tr = tmpTrace;
distance = thisDistance;
}
}
}
}
}
}
void CCrowbar::PrimaryAttack()
{
if( !Swing( 1 ) )

View File

@ -268,6 +268,7 @@ LINK_ENTITY_TO_CLASS( func_door, CBaseDoor )
// func_water - same as a door.
//
LINK_ENTITY_TO_CLASS( func_water, CBaseDoor )
LINK_ENTITY_TO_CLASS( func_lasermirror, CBaseDoor )
void CBaseDoor::Spawn()
{
@ -551,8 +552,21 @@ void CBaseDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use
{
m_hActivator = pActivator;
// if not ready to be used, ignore "use" command.
// Decay's changes - door should correctly receive USE_TYPE from trigger_relay
// close - godown
// open - goup
if( m_toggle_state == TS_AT_BOTTOM || ( FBitSet( pev->spawnflags, SF_DOOR_NO_AUTO_RETURN ) && m_toggle_state == TS_AT_TOP ) )
DoorActivate();
{
if ( (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN)) && useType != USE_TOGGLE )
{
if ( (( useType == USE_OFF ) && (m_toggle_state == TS_AT_TOP)) || (( useType == USE_ON ) && (m_toggle_state == TS_AT_BOTTOM)) )
DoorActivate();
}
else
DoorActivate();
}
}
//
@ -670,8 +684,10 @@ void CBaseDoor::DoorHitTop( void )
}
}
// Vyacheslav Dzhura TODO: think about logic here
// Fire the close target (if startopen is set, then "top" is closed) - netname is the close target
if( pev->netname && ( pev->spawnflags & SF_DOOR_START_OPEN ) )
//if ( pev->netname && m_toggle_state = TS_AT_BOTTOM )
FireTargets( STRING( pev->netname ), m_hActivator, this, USE_TOGGLE, 0 );
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished

View File

@ -23,14 +23,171 @@
#include "decals.h"
#include "func_break.h"
#include "shake.h"
#include "animation.h"
#include "gamerules.h"
//#include "monstermaker.h"
#define SF_GIBSHOOTER_REPEATABLE 1 // allows a gibshooter to be refired
#define SF_FUNNEL_REVERSE 1 // funnel effect repels particles instead of attracting them.
#define SF_MIRROR_FINAL 0x0001 // final part of the lasermirror chain
#define SF_MIRROR_FIREONCE 0x0002 // if global state is on, then fire our target only once
extern int gmsgLensFlare;
// Lightning target, just alias landmark
LINK_ENTITY_TO_CLASS( info_target, CPointEntity )
//==============================================================================
// Decay's displacer's teleport target entity
//==============================================================================
LINK_ENTITY_TO_CLASS( info_displacer_xen_target, CDisplacerTarget );
void CDisplacerTarget::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "player_index"))
{
m_iPlayerIndex = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
CPointEntity::KeyValue( pkvd );
}
//==============================================================================
// Decay's spawnflags setter helper entity
//==============================================================================
class CFlagHelper : public CPointEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
};
LINK_ENTITY_TO_CLASS( info_flaghelper, CFlagHelper );
void CFlagHelper::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( FStringNull( pev->target ) )
return;
CBaseEntity *pEnt = NULL;
pEnt = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ) );
if ( pEnt )
pEnt->pev->spawnflags = this->pev->spawnflags;
}
//==============================================================================
// Decay's cheat helper entity
//==============================================================================
class CCheatHelper : public CPointEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData *pkvd );
void CheckCode();
// consists of "udlr stcx" (up down left right square triangle circle (x)cross )
string_t m_sCheat1, target1;
string_t m_sCheat2, target2;
char m_sListener[16];
};
LINK_ENTITY_TO_CLASS( info_cheathelper, CCheatHelper );
void CCheatHelper::CheckCode()
{
int i = 0;
while ( ( i < 16 ) && ( m_sListener[i] == 0 ) )
i++;
if ( i == 16 )
return;
char m_sCurrentCheat[16];
memset( &m_sCurrentCheat, 0, sizeof(m_sCurrentCheat) );
memmove( m_sCurrentCheat, m_sListener+i, 16-i );
ALERT( at_console, "Current code: '%s'\n", m_sCurrentCheat );
char m_sCurrentCompareCheat[16];
//memset( &m_sCurrentCompareCheat, 0, sizeof(m_sCurrentCompareCheat) );
//strncpy( m_sCurrentCompareCheat, m_sCurrentCheat, strlen( STRING( m_sCheat1 ) ) );
if ( strstr( m_sCurrentCheat, STRING( m_sCheat1 ) ) )
// if ( strcmp( m_sCurrentCompareCheat, STRING( m_sCheat1 ) ) == 0 )
{
// cheat_bonus entered
if ( !FStringNull( target1 ) )
FireTargets( STRING( target1 ), this, this, USE_TOGGLE, 0.0 );
memset( &m_sListener, 0, sizeof(m_sListener) );
}
//memset( &m_sCurrentCompareCheat, 0, sizeof(m_sCurrentCompareCheat) );
//strncpy( m_sCurrentCompareCheat, m_sCurrentCheat, strlen( STRING( m_sCheat2 ) ) );
if ( strstr( m_sCurrentCheat, STRING( m_sCheat2 ) ) )
//if ( strcmp( m_sCurrentCompareCheat, STRING( m_sCheat2 ) ) == 0 )
{
// cheat_alien entered
CDecayRules *g_pDecayRules;
g_pDecayRules = (CDecayRules*)g_pGameRules;
g_pDecayRules->unlockMissions( true );
g_pDecayRules->statsSave();
if ( !FStringNull( target1 ) )
FireTargets( STRING( target2 ), this, this, USE_TOGGLE, 0.0 );
memset( &m_sListener, 0, sizeof(m_sListener) );
}
}
void CCheatHelper::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( FStringNull( pCaller->pev->targetname ) )
return;
static char sCallersCheat[32];
sprintf( sCallersCheat, "%s", STRING( pCaller->pev->targetname ));
// move all starting from 2 char to 1 char
memmove (m_sListener+1, m_sListener+2, 15);
m_sListener[15] = sCallersCheat[0];
CheckCode();
}
void CCheatHelper::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "cheat_bonus"))
{
m_sCheat1 = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
} else
if (FStrEq(pkvd->szKeyName, "cheat_alien"))
{
m_sCheat2 = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
} else
if (FStrEq(pkvd->szKeyName, "target1"))
{
target1 = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
} else
if (FStrEq(pkvd->szKeyName, "target2"))
{
target2 = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
CPointEntity::KeyValue( pkvd );
}
//==============================================================================
// Bubbling entity
//==============================================================================
class CBubbling : public CBaseEntity
{
public:
@ -3306,4 +3463,4 @@ void CEnvLaserMirror::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY
// char szMes[256];
// sprintf(szMes,"Server: <Origin - X: %f,Y: %f,Z: %f Index: %d>",pev->origin.x,pev->origin.y,pev->origin.z, entindex());
// ALERT( at_console, szMes );
}
}

View File

@ -325,4 +325,105 @@ public:
string_t m_iszSpriteName;
Vector m_firePosition;
};
class CFuncFrame : public CBaseEntity
{
public:
void Spawn( void );
void KeyValue( KeyValueData *pkvd );
int m_iKind;
};
#define SF_AUTO_FIREONCE 0x0001
class CEnvWarpBall : public CBaseEntity
{
public:
void KeyValue( KeyValueData *pkvd );
void Precache( void );
void Spawn( void ) { Precache(); }
void Think( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
static CEnvWarpBall *WarpBallCreate();
//string_t m_iszMonsterClassname; // classname of the monster(s) that will be created.
string_t m_iszWarpTarget;
};
class CDisplacerTarget : public CPointEntity
{
public:
void KeyValue( KeyValueData *pkvd );
int m_iPlayerIndex;
};
class CObjModel : public CBaseEntity
{
public:
void Spawn( void );
void Precache( void );
void KeyValue( KeyValueData *pkvd);
int m_iSkin, m_iScale, m_iBody, m_iBodyGroup, m_iSequence;
float SetBoneController(int iController, float flValue );
void ObjModelInit( const char *pModelName, int skin, int scale, int body, int bodygroup );
static CObjModel *ObjModelCreate( const char *pModelName, int skin, int scale, int body, int bodygroup );
};
class CEnvLaserMirror : public CBaseEntity
{
public:
virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DIRECTIONAL_USE; }
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void Precache( void );
void Spawn( void );
void KeyValue( KeyValueData *pkvd );
void CheckTargets(bool DoActivate);
int m_iszTargetUnlocked;
int m_iszTargetLocked;
bool bStateOn;
string_t m_globalstate;
int m_iUseStateMode;
int m_iSearchDistance;
byte bUsedCount;
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
};
class CEnvMirroredLaser : public CBaseEntity
{
public:
CBeam *pBeam[15]; // 15 reflections max
CEnvLaserMirror *pMirrors[15];
int iBeamCount;
int iMirrorCount;
bool bActive;
//Vector m_vecDir;
Vector m_vecEnd;
int iMaxStep;
int m_iSearchDistance;
int m_iPrimarySearchDistance;
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
//void Activate( void );
void Spawn( void );
void RebuildPath( void );
void EXPORT ThinkOn( void );
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void ReColorLasers( void );
};
#endif //EFFECTS_H

View File

@ -44,7 +44,7 @@ cvar_t decalfrequency = { "decalfrequency","30", FCVAR_SERVER };
cvar_t teamlist = { "mp_teamlist","hgrunt;scientist", FCVAR_SERVER };
cvar_t teamoverride = { "mp_teamoverride","1" };
cvar_t defaultteam = { "mp_defaultteam","0" };
cvar_t allowmonsters = { "mp_allowmonsters","0", FCVAR_SERVER };
cvar_t allowmonsters = { "mp_allowmonsters","1", FCVAR_SERVER };
cvar_t bhopcap = { "mp_bhopcap", "1", FCVAR_SERVER };
cvar_t allow_spectators = { "allow_spectators", "0", FCVAR_SERVER }; // 0 prevents players from being spectators

View File

@ -317,6 +317,14 @@ CGameRules *InstallGameRules( void )
{
SERVER_COMMAND( "exec game.cfg\n" );
SERVER_EXECUTE();
ALERT( at_console, "Installing game rule... ");
// ALERT( at_console, "Priest damaged - took %f hit points!\n", flDamage);
if (bDecay)
{
// Decay game rules
return new CDecayRules;
}
if( !gpGlobals->deathmatch )
{

View File

@ -163,6 +163,13 @@ public:
// Immediately end a multiplayer game
virtual void EndMultiplayerGame( void ) {}
virtual BOOL IsBustingGame( void ){ return FALSE; };
// Decay stats
virtual void MonsterKilled( entvars_t *pKiller, entvars_t *pVictim ) = 0;
virtual void PlayerDamaged( CBasePlayer *pPlayer, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) = 0;
virtual void BulletsFired( entvars_t *pevAttacker, ULONG cShots, int iBulletType, int iShotId ) {};
virtual void BulletHit( CBaseEntity *pEntity, entvars_t *pevAttacker, int iShotId ) {};
virtual void savePlayerStats( int playerId, int finalGrade, int damageGrade, int killsGrade, int accuracyGrade ) {};
};
extern CGameRules *InstallGameRules( void );
@ -402,5 +409,142 @@ protected:
float m_flEgonBustingCheckTime;
};
//=========================================================
// CDecayRules - rules for the cooperative Half-Life
// game (Decay)
//=========================================================
typedef struct
{
int kills;
int damage;
int shots;
int hits;
int lastShotId;
int magicWord1;
bool lastShotCounted;
int magicWord2;
float accuracy;
int gradeKills;
int gradeDamage;
int gradeAccuracy;
int gradeFinal;
} t_playerStats;
class CDecayRules : public CGameRules
{
public:
CDecayRules ( void );
// GR_Think
virtual void Think( void );
virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity );
virtual BOOL FAllowFlashlight( void ) { return TRUE; };
virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );
virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon );
// Functions to verify the single/multiplayer status of a game
virtual BOOL IsMultiplayer( void );
virtual BOOL IsDeathmatch( void );
virtual BOOL IsCoOp( void );
// Client connection/disconnection
virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] );
virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating
virtual void ClientDisconnected( edict_t *pClient );
// Client damage rules
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer );
// Client spawn/respawn control
virtual void PlayerSpawn( CBasePlayer *pPlayer );
virtual void PlayerThink( CBasePlayer *pPlayer );
virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer );
virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer );
virtual BOOL AllowAutoTargetCrosshair( void );
// Client kills/scoring
virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled );
virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor );
virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor );
// Weapon retrieval
virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); // The player is touching an CBasePlayerItem, do I give it to him?
virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );
// Weapon spawn/respawn control
virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon );
virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon );
virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon );
virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon );
// Item retrieval
virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem );
virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem );
// Item spawn/respawn control
virtual int ItemShouldRespawn( CItem *pItem );
virtual float FlItemRespawnTime( CItem *pItem );
virtual Vector VecItemRespawnSpot( CItem *pItem );
// Ammo retrieval
virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount );
// Ammo spawn/respawn control
virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo );
virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo );
virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo );
// Healthcharger respawn control
virtual float FlHealthChargerRechargeTime( void );
// What happens to a dead player's weapons
virtual int DeadPlayerWeapons( CBasePlayer *pPlayer );
// What happens to a dead player's ammo
virtual int DeadPlayerAmmo( CBasePlayer *pPlayer );
// Monsters
virtual BOOL FAllowMonsters( void );
// Teamplay stuff
virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";};
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
// Decay stuff
// kicks player from server withing several seconds
void RemoveNewPlayer( int PlayerIdInArray );
void unlockMissions( bool unlockAlien = false );
//edict_t *pLoopBack;
int PlayersCount;
CBasePlayer *pPlayers[8]; // was array of 2
t_playerStats pStats[8];
bool m_bAlienMode;
void ChangePlayer();
void SetAlienMode( bool bMode );
int getDecayMapId();
char *getDecayNextMap();
char *getDecayMapName( int mapId );
char getGradeChar( int grade );
void printXmlPlayerStats( FILE *fp, t_playerStats playerStats, bool bBest, int playerId );
void statsExportXml();
void statsLoad();
void statsSave();
virtual void MonsterKilled( entvars_t *pKiller, entvars_t *pVictim );
virtual void PlayerDamaged( CBasePlayer *pPlayer, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
virtual void BulletsFired( entvars_t *pevAttacker, ULONG cShots, int iBulletType, int iShotId );
virtual void BulletHit( CBaseEntity *pEntity, entvars_t *pevAttacker, int iShotId );
virtual void savePlayerStats( int playerId, int finalGrade, int damageGrade, int killsGrade, int accuracyGrade );
virtual void UpdateGameMode( CBasePlayer *pPlayer );
virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer );
};
extern DLL_GLOBAL CGameRules *g_pGameRules;
#endif // GAMERULES_H

View File

@ -28,6 +28,11 @@
#include "gamerules.h"
#include "weapons.h"
#include "game.h"
#include "actanimating.h"
#include "effects.h"
#define CHARGER_ACTIVE 0
#define CHARGER_EMPTY 1
class CRecharge : public CBaseToggle
{
@ -663,4 +668,4 @@ void CMdlCharger::TurnOff(void)
m_pBeam = NULL;
SetUse( NULL );
SetSequence( seqCharge_RetractArm );
}
}

View File

@ -23,6 +23,8 @@
#include "items.h"
#include "gamerules.h"
#include "game.h"
#include "actanimating.h"
//#include "effects.h"
extern int gmsgItemPickup;
@ -757,4 +759,4 @@ void CMdlWallHealth::TurnOff( void )
pFluidTank->SetSequence( seq_ToRest );
SetUse( NULL );
SetSequence( seq_RetractArm );
}
}

View File

@ -1000,6 +1000,9 @@ void CHGrunt::Spawn()
m_HackedGunPos = Vector( 0, 0, 55 );
SetBodygroup( LODS_GROUP, 0 );
SetBodygroup( HEAD_GROUP, HEAD_GRUNT );
if( pev->weapons == 0 )
{
// initialize to original values

View File

@ -192,15 +192,28 @@ class CItemSuit : public CItem
{
PRECACHE_MODEL( "models/w_suit.mdl" );
}
void KeyValue(KeyValueData *pkvd)
{
if (FStrEq(pkvd->szKeyName, "skin"))
{
pev->skin = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
CBaseEntity::KeyValue( pkvd );
}
BOOL MyTouch( CBasePlayer *pPlayer )
{
if( pPlayer->pev->weapons & ( 1<<WEAPON_SUIT ) )
return FALSE;
if( pev->spawnflags & SF_SUIT_SHORTLOGON )
EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A0" ); // short version of suit logon,
else
EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_AAx" ); // long version of suit logon
if (!g_startSuit)
{
if( pev->spawnflags & SF_SUIT_SHORTLOGON )
EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A0" ); // short version of suit logon,
else
EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_AAx" ); // long version of suit logon
}
pPlayer->pev->weapons |= ( 1 << WEAPON_SUIT );
return TRUE;
@ -344,3 +357,426 @@ class CItemLongJump : public CItem
};
LINK_ENTITY_TO_CLASS( item_longjump, CItemLongJump )
//
// Decay's item_slave_collar for mission ht11lasers (Gamma labs)
//
class CItemSlaveCollar : public CBaseEntity
{
public:
void Spawn( void );
void Precache( void );
void EXPORT Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT ZapThink( void );
void EXPORT OffThink( void );
bool m_bIsOn;
int m_iBeams;
CBeam *m_pBeam[8]; // ISLAVE_MAX_BEAMS
Vector m_vecDir;
Vector m_vecEnd;
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
};
LINK_ENTITY_TO_CLASS( item_slave_collar, CItemSlaveCollar );
TYPEDESCRIPTION CItemSlaveCollar::m_SaveData[] =
{
DEFINE_FIELD( CItemSlaveCollar, m_bIsOn, FIELD_BOOLEAN ),
DEFINE_ARRAY( CItemSlaveCollar, m_pBeam, FIELD_CLASSPTR, 8 ),
DEFINE_FIELD( CItemSlaveCollar, m_iBeams, FIELD_INTEGER),
DEFINE_FIELD( CItemSlaveCollar, m_vecDir, FIELD_VECTOR),
DEFINE_FIELD( CItemSlaveCollar, m_vecEnd, FIELD_VECTOR),
};
IMPLEMENT_SAVERESTORE( CItemSlaveCollar, CBaseEntity );
void CItemSlaveCollar::Spawn( void )
{
Precache();
SET_MODEL(ENT(pev), "models/collar_test.mdl");
UTIL_MakeAimVectors( pev->angles );
m_vecDir = gpGlobals->v_forward;
m_vecEnd = pev->origin + m_vecDir * 2048;
for ( m_iBeams = 0; m_iBeams < 2; m_iBeams++ )
{
m_pBeam[m_iBeams] = CBeam::BeamCreate( "sprites/lgtning.spr", 50 );
m_pBeam[m_iBeams]->pev->effects |= EF_NODRAW;
}
if (FBitSet(pev->spawnflags, 1)) // Start on
{
m_bIsOn = true;
SetThink(ZapThink); // start zapping
pev->nextthink = gpGlobals->time;
}
}
void CItemSlaveCollar::Precache( void )
{
PRECACHE_MODEL( "models/collar_test.mdl" );
PRECACHE_SOUND( "weapons/electro4.wav" );
PRECACHE_SOUND( "debris/zap4.wav" );
}
void CItemSlaveCollar::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( useType == USE_TOGGLE )
m_bIsOn = !m_bIsOn;
if ( useType == USE_ON )
m_bIsOn = true;
if ( useType == USE_OFF )
m_bIsOn = false;
if ( m_bIsOn )
SetThink( ZapThink );
else
SetThink( OffThink );
pev->nextthink = gpGlobals->time + 0.01;
}
void CItemSlaveCollar::OffThink( void )
{
for ( m_iBeams = 0; m_iBeams < 2; m_iBeams++ )
{
m_pBeam[m_iBeams]->pev->effects |= EF_NODRAW;
}
}
void CItemSlaveCollar::ZapThink( void )
{
// create alien slave beam here
//ALERT( at_console, "ZapThink!\n" );
TraceResult tr;
UTIL_TraceLine( pev->origin, m_vecEnd, ignore_monsters, ENT( pev ), &tr ); // dont_ignore_monsters
float m_flBeamLength = tr.flFraction;
UTIL_EmitAmbientSound( ENT(pev), tr.vecEndPos, "debris/zap4.wav", 0.5, ATTN_NORM, 0, RANDOM_LONG( 140, 160 ) );
Vector vecTmpEnd = pev->origin + m_vecDir * 2048 * m_flBeamLength;
tr.vecEndPos.z += 50;
UTIL_Sparks( tr.vecEndPos );
//if ( !tr.pHit )
DecalGunshot( &tr, BULLET_PLAYER_CROWBAR );
//UTIL_DecalTrace( &tr, DECAL_BIGSHOT1 + RANDOM_LONG(0,4) );
for ( m_iBeams = 0; m_iBeams < 2; m_iBeams++ )
{
m_pBeam[m_iBeams]->pev->effects &= ~EF_NODRAW;
m_pBeam[m_iBeams]->PointEntInit( vecTmpEnd, entindex() );
m_pBeam[m_iBeams]->SetEndAttachment( m_iBeams + 1 );
m_pBeam[m_iBeams]->SetStartPos( tr.vecEndPos );
m_pBeam[m_iBeams]->SetColor( 180, 255, 96 );
m_pBeam[m_iBeams]->SetBrightness( 255 );
m_pBeam[m_iBeams]->SetNoise( 20 );
/*
pEntity = CBaseEntity::Instance(tr.pHit);
if (pEntity != NULL && pEntity->pev->takedamage)
{
pEntity->TraceAttack( pev, gSkillData.slaveDmgZap, vecAim, &tr, DMG_SHOCK );
}
*/
}
UTIL_EmitAmbientSound( ENT(pev), tr.vecEndPos, "weapons/electro4.wav", 0.5, ATTN_NORM, 0, RANDOM_LONG( 140, 160 ) );
pev->nextthink = gpGlobals->time + 5;
}
//
// Decay's focus emitter code below
//
//
// Decay's item_focusemitter for mission ht12fubar (Gamma labs)
//
class CFocusEmitter : public CActAnimating
{
public:
void Spawn( void );
void Precache( void );
void EXPORT Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT EmitterThink( void );
void EXPORT DyingThink( void );
void KeyValue(KeyValueData *pkvd);
void LookAt( Vector inputangles );
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
void Killed( entvars_t *pevAttacker, int iGib );
bool m_bIsOn;
Vector m_vecDir;
Vector m_vecEnd;
Vector m_angGun;
int m_iszDeployedTarget;
int m_iszDeathTarget;
int m_iszLaserTarget;
CBeam *bWhiteBeam;
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
};
LINK_ENTITY_TO_CLASS( item_focusemitter, CFocusEmitter );
TYPEDESCRIPTION CFocusEmitter::m_SaveData[] =
{
DEFINE_FIELD( CFocusEmitter, m_bIsOn, FIELD_BOOLEAN ),
DEFINE_FIELD( CFocusEmitter, m_vecDir, FIELD_VECTOR),
DEFINE_FIELD( CFocusEmitter, m_vecEnd, FIELD_VECTOR),
DEFINE_FIELD( CFocusEmitter, m_iszDeployedTarget, FIELD_INTEGER),
DEFINE_FIELD( CFocusEmitter, m_iszDeathTarget, FIELD_INTEGER),
DEFINE_FIELD( CFocusEmitter, m_iszLaserTarget, FIELD_INTEGER),
DEFINE_FIELD( CFocusEmitter, bWhiteBeam, FIELD_CLASSPTR ),
};
IMPLEMENT_SAVERESTORE( CFocusEmitter, CBaseEntity );
void CFocusEmitter::KeyValue(KeyValueData *pkvd)
{
if (FStrEq(pkvd->szKeyName, "deploy_target"))
{
m_iszDeployedTarget = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
if (FStrEq(pkvd->szKeyName, "death_target"))
{
m_iszDeathTarget = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
if (FStrEq(pkvd->szKeyName, "lasertarget"))
{
m_iszLaserTarget = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
CBaseEntity::KeyValue( pkvd );
}
void CFocusEmitter::Spawn( void )
{
Precache();
SET_MODEL(ENT(pev), "models/focus_emitter.mdl");
pev->takedamage = DAMAGE_YES;
pev->health = 150*4; // 4 HVR shots
pev->solid = SOLID_BBOX;
pev->flags |= FL_MONSTER;
UTIL_SetSize( pev, Vector(-30,-30,0), Vector(30,30,700));
SetBodygroup( 1, 2 );
SetSequence( seqEmitterClosed );
SetThink( EmitterThink );
pev->nextthink = gpGlobals->time;
CBaseEntity *LasTarget;
LasTarget = UTIL_FindEntityByTargetname( NULL, STRING( m_iszLaserTarget ));
if (!LasTarget)
LasTarget = this;
bWhiteBeam = CBeam::BeamCreate( "sprites/lgtning.spr", 50 );
bWhiteBeam->PointEntInit( LasTarget->pev->origin, entindex( ) );
bWhiteBeam->SetEndAttachment( 2 );
bWhiteBeam->SetColor( 255, 255, 255 );
bWhiteBeam->SetScrollRate( 35 );
bWhiteBeam->SetNoise( 3 );
bWhiteBeam->pev->effects |= EF_NODRAW;
if (FBitSet(pev->spawnflags, 1)) // Start on
{
m_bIsOn = true;
SetSequence( seqEmitterIdleOpen );
bWhiteBeam->pev->effects &= ~EF_NODRAW;
pev->nextthink = gpGlobals->time;
}
}
void CFocusEmitter::Precache( void )
{
PRECACHE_MODEL( "models/focus_emitter.mdl" );
PRECACHE_MODEL( "sprites/lgtning.spr" );
PRECACHE_SOUND( "debris/beamstart4.wav" );
}
void CFocusEmitter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (m_bIsOn)
return;
SetSequence( seqEmitterDeploy );
m_bIsOn = true;
}
void CFocusEmitter::EmitterThink( void )
{
StudioFrameAdvance();
pev->nextthink = gpGlobals->time + 0.1;
//CBaseEntity *pPlayer;
//pPlayer = UTIL_FindEntityByClassname( NULL, "player" );
//if (pPlayer)
// LookAt( pPlayer->pev->origin );
switch( GetSequence() )
{
case seqEmitterClosed: // 0 - still
break;
case seqEmitterDeploy: // 1 - slosh
if ( m_fSequenceFinished )
{
SetSequence( seqEmitterIdleOpen );
FireTargets( STRING( m_iszDeployedTarget ), this, this, USE_ON, 1.0 );
bWhiteBeam->pev->effects &= ~EF_NODRAW;
UTIL_EmitAmbientSound( ENT(pev), pev->origin, "debris/beamstart4.wav", 0.5, ATTN_NORM, 0, RANDOM_LONG( 140, 160 ) );
UTIL_ScreenFadeAll( Vector( 255, 255, 255), 1.0, 0.1, 150, 0 );
}
break;
case seqEmitterIdleOpen:
if (pev->health < 150*3)
SetSequence( seqEmitterBroken1);
break;
case seqEmitterBroken1:
if (pev->health < 150*2)
SetSequence( seqEmitterBroken2);
break;
case seqEmitterBroken2: // 2 - to rest
//if (pev->health = 0)
// SetSequence( seqEmitterDeath );
break;
case seqEmitterDeath:
// random explosions
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_EXPLOSION); // This just makes a dynamic light now
WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -150, 150 ));
WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -150, 150 ));
WRITE_COORD( pev->origin.z + RANDOM_FLOAT( -150, -50 ));
WRITE_SHORT( g_sModelIndexFireball );
WRITE_BYTE( RANDOM_LONG(0,29) + 30 ); // scale * 10
WRITE_BYTE( 12 ); // framerate
WRITE_BYTE( TE_EXPLFLAG_NONE );
MESSAGE_END();
if ( m_fSequenceFinished )
{
SetThink( DyingThink );
pev->nextthink = gpGlobals->time + 0.1;
}
break;
default:
break;
}
}
void CFocusEmitter::DyingThink( void )
{
// lots of smoke
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_SMOKE );
WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -150, 150 ) );
WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -150, 150 ) );
WRITE_COORD( pev->origin.z + 200 + RANDOM_FLOAT( -150, -50 ) );
WRITE_SHORT( g_sModelIndexSmoke );
WRITE_BYTE( 50 ); // scale * 10
WRITE_BYTE( 10 ); // framerate
MESSAGE_END();
pev->nextthink = gpGlobals->time + 0.1;
}
void CFocusEmitter :: Killed( entvars_t *pevAttacker, int iGib )
{
pev->health = 0;
pev->takedamage = DAMAGE_NO;
bWhiteBeam->pev->effects |= EF_NODRAW;
FireTargets( STRING( m_iszDeathTarget ), this, this, USE_TOGGLE, 1.0 );
SetSequence( seqEmitterDeath );
pev->nextthink = gpGlobals->time + 0.1;
//m_flDieCounter = gpGlobals->time + 2.5;
//FireTargets( STRING(m_iszDeathTarget), this, this, USE_TOGGLE, 1.0 );
}
void CFocusEmitter::LookAt( Vector inputangles )
{
UTIL_MakeAimVectors( pev->angles );
Vector posGun, angGun;
GetAttachment( 2, posGun, angGun );
Vector vecTarget = (inputangles - posGun).Normalize( );
Vector vecOut;
vecOut.x = DotProduct( gpGlobals->v_forward, vecTarget );
vecOut.y = -DotProduct( gpGlobals->v_right, vecTarget );
vecOut.z = DotProduct( gpGlobals->v_up, vecTarget );
Vector angles = UTIL_VecToAngles (vecOut);
angles.x = -angles.x;
if (angles.x > 180)
angles.x = angles.x - 360;
if (angles.x < -180)
angles.x = angles.x + 360;
m_angGun.x = angles.x;
m_angGun.y = angles.y;
/*
if (angles.x > m_angGun.x)
m_angGun.x = min( angles.x, m_angGun.x + 12 );
if (angles.x < m_angGun.x)
m_angGun.x = max( angles.x, m_angGun.x - 12 );
if (angles.y > m_angGun.y)
m_angGun.y = min( angles.y, m_angGun.y + 12 );
if (angles.y < m_angGun.y)
m_angGun.y = max( angles.y, m_angGun.y - 12 );
*/
m_angGun.y = SetBoneController( 0, m_angGun.y );
m_angGun.x = SetBoneController( 1, m_angGun.x );
}
int CFocusEmitter :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
{
if (pevInflictor->owner == edict())
return 0;
if (bitsDamageType & DMG_BLAST)
{
flDamage *= 2;
}
// ALERT( at_console, "%.0f\n", flDamage );
return CBaseEntity::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
}
//
// Emitter target
//
class CEmitterTarget : public CBaseEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
};
void CEmitterTarget :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
// TODO: find emitter, call LookAt(this)
CFocusEmitter *pEmitter; // = NULL;
pEmitter = (CFocusEmitter*)UTIL_FindEntityByClassname( NULL, "item_focusemitter" );
if (pEmitter)
pEmitter->LookAt( pev->origin );
FireTargets( STRING(pev->target), this, this, USE_TOGGLE, 0.0 );
ALERT( at_console, "info_emittertarget called Use! Firing %s\n", STRING(pev->target) );
}
LINK_ENTITY_TO_CLASS( info_emittertarget, CEmitterTarget );

View File

@ -16,6 +16,8 @@
#if !defined(ITEMS_H)
#define ITEMS_H
extern BOOL g_startSuit;
class CItem : public CBaseEntity
{
public:

View File

@ -22,46 +22,15 @@
#include "cbase.h"
#include "monsters.h"
#include "saverestore.h"
// Monstermaker spawnflags
#define SF_MONSTERMAKER_START_ON 1 // start active ( if has targetname )
#define SF_MONSTERMAKER_CYCLIC 4 // drop one monster every time fired.
#define SF_MONSTERMAKER_MONSTERCLIP 8 // Children are blocked by monsterclip
#include "monstermaker.h"
#include "effects.h"
//=========================================================
// MonsterMaker - this ent creates monsters during the game.
//=========================================================
class CMonsterMaker : public CBaseMonster
{
public:
void Spawn( void );
void Precache( void );
void KeyValue( KeyValueData* pkvd);
void EXPORT ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT CyclicUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT MakerThink( void );
void DeathNotice( entvars_t *pevChild );// monster maker children use this to tell the monster maker that they have died.
void MakeMonster( void );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
string_t m_iszMonsterClassname;// classname of the monster(s) that will be created.
int m_cNumMonsters;// max number of monsters this ent can create
int m_cLiveChildren;// how many monsters made by this monster maker that are currently alive
int m_iMaxLiveChildren;// max number of monsters that this maker may have out at one time.
float m_flGround; // z coord of the ground under me, used to make sure no monsters are under the maker when it drops a new child
BOOL m_fActive;
BOOL m_fFadeChildren;// should we make the children fadeout?
};
LINK_ENTITY_TO_CLASS( monstermaker, CMonsterMaker )
LINK_ENTITY_TO_CLASS( env_warpball, CMonsterMaker )
TYPEDESCRIPTION CMonsterMaker::m_SaveData[] =
{
@ -83,9 +52,10 @@ void CMonsterMaker::KeyValue( KeyValueData *pkvd )
if( FStrEq( pkvd->szKeyName, "monstercount" ) )
{
m_cNumMonsters = atoi( pkvd->szValue );
m_cTotalMonstersCount = m_cNumMonsters;
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "m_imaxlivechildren" ) )
else if ( FStrEq(pkvd->szKeyName, "m_imaxlivechildren") || FStrEq(pkvd->szKeyName, "maxlivechildren"))
{
m_iMaxLiveChildren = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
@ -135,7 +105,7 @@ void CMonsterMaker::Spawn()
SetUse( &CMonsterMaker::ToggleUse );// so can be turned on/off
}
if( FBitSet( pev->spawnflags, SF_MONSTERMAKER_START_ON ) )
if( !m_fIsWarpBall && FBitSet( pev->spawnflags, SF_MONSTERMAKER_START_ON ))
{
// start making monsters as soon as monstermaker spawns
m_fActive = TRUE;
@ -200,18 +170,38 @@ void CMonsterMaker::MakeMonster( void )
return;
}
bool bFoundTarget = false;
Vector DesiredOrigin;
Vector DesiredAngles;
if (!FStringNull( m_iszWarpTarget ))
{
m_pGoalEnt = UTIL_FindEntityByTargetname( NULL, STRING( m_iszWarpTarget ) );
if (m_pGoalEnt)
{
DesiredOrigin = m_pGoalEnt->pev->origin;
DesiredAngles = m_pGoalEnt->pev->angles;
bFoundTarget = true;
}
}
if (!bFoundTarget)
{
DesiredOrigin = pev->origin;
DesiredAngles = pev->angles;
}
if( !m_flGround )
{
// set altitude. Now that I'm activated, any breakables, etc should be out from under me.
TraceResult tr;
UTIL_TraceLine( pev->origin, pev->origin - Vector( 0, 0, 2048 ), ignore_monsters, ENT( pev ), &tr );
UTIL_TraceLine( DesiredOrigin, DesiredOrigin - Vector ( 0, 0, 2048 ), ignore_monsters, ENT(pev), &tr );
m_flGround = tr.vecEndPos.z;
}
Vector mins = pev->origin - Vector( 34, 34, 0 );
Vector maxs = pev->origin + Vector( 34, 34, 0 );
maxs.z = pev->origin.z;
Vector mins = DesiredOrigin - Vector( 34, 34, 0 );
Vector maxs = DesiredOrigin + Vector( 34, 34, 0 );
maxs.z = DesiredOrigin.z;
mins.z = m_flGround;
CBaseEntity *pList[2];
@ -219,9 +209,31 @@ void CMonsterMaker::MakeMonster( void )
if( count )
{
// don't build a stack of monsters!
return;
bool bAllDead = true;
for ( int i = 0; i < count; i++ )
{
if ( pList[i]->IsAlive() ) // Don't count dead monsters
bAllDead = false;
}
// don't build a stack of monsters if there are alive monsters nearby!
if (!bAllDead)
return;
}
// If env_warpball then create teleport effect
if ( m_fIsWarpBall == true)
{
CEnvWarpBall *pWarpBall = CEnvWarpBall::WarpBallCreate();
pWarpBall->pev->origin = DesiredOrigin;
pWarpBall->pev->angles = DesiredAngles;
SetBits( pWarpBall->pev->spawnflags, SF_AUTO_FIREONCE );
pWarpBall->Use( this, this, USE_ON, 1);
// if monstermaker is a warpball and doesn't have children class specified, play effect only
if (FStringNull(m_iszMonsterClassname))
return;
}
pent = CREATE_NAMED_ENTITY( m_iszMonsterClassname );
if( FNullEnt( pent ) )
@ -333,3 +345,18 @@ void CMonsterMaker::DeathNotice( entvars_t *pevChild )
pevChild->owner = NULL;
}
}
void CMonsterMaker :: MonsterMakerInit( const char* ChildName, int MaxLiveChildren, int NumMonsters )
{
m_cNumMonsters = NumMonsters;
m_iMaxLiveChildren = MaxLiveChildren;
m_iszMonsterClassname = MAKE_STRING( ChildName );
Spawn();
}
CMonsterMaker *CMonsterMaker::MonsterMakerCreate( const char* ChildName, int MaxLiveChildren, int NumMonsters )
{
CMonsterMaker *pMonsterMaker = GetClassPtr( (CMonsterMaker *)NULL );
pMonsterMaker->MonsterMakerInit( ChildName, MaxLiveChildren, NumMonsters );
return pMonsterMaker;
}

View File

@ -74,6 +74,7 @@ static CMultiplayGameMgrHelper g_GameMgrHelper;
//*********************************************************
CHalfLifeMultiplay::CHalfLifeMultiplay()
{
ALERT( at_console, "Half-Life multiplayer\n");
#if !NO_VOICEGAMEMGR
g_VoiceGameMgr.Init( &g_GameMgrHelper, gpGlobals->maxClients );
#endif

View File

@ -1059,9 +1059,9 @@ void CFuncTrackTrain::StopSound( void )
PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0,
g_vecZero, g_vecZero, 0.0, 0.0, us_encode, 0, 1, 0 );
/*
/* was commented before */
STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noise ) );
*/
EMIT_SOUND_DYN( ENT( pev ), CHAN_ITEM, "plats/ttrain_brake1.wav", m_flVolume, ATTN_NORM, 0, 100 );
}

View File

@ -45,6 +45,8 @@ extern DLL_GLOBAL BOOL g_fDrawLines;
int gEvilImpulse101;
extern DLL_GLOBAL int g_iSkillLevel, gDisplayTitle;
extern bool bSlaveCoop;
BOOL gInitHUD = TRUE;
extern void CopyToBodyQue( entvars_t *pev);
@ -236,6 +238,16 @@ void LinkUserMessages( void )
gmsgStatusText = REG_USER_MSG( "StatusText", -1 );
gmsgStatusValue = REG_USER_MSG( "StatusValue", 3 );
gmsgLensFlare = REG_USER_MSG( "LensFlare", 1 ); //for sun effect
gmsgAimFrame = REG_USER_MSG( "AimFrame", 14 ); //for selection frame
gmsgNotepad = REG_USER_MSG( "Notepad", -1 );
gmsgChangeMode = REG_USER_MSG( "ChangeMode", 1 );
gmsgChangePlayer = REG_USER_MSG( "ChangePlr", 1 );
gmsgCamera = REG_USER_MSG( "Camera", 7 );
gmsgSparePlayer = REG_USER_MSG( "SparePlayer", 1 );
gmsgAlienState = REG_USER_MSG ( "AlienState", 1 );
gmsgUpdateDecayPlayerName = REG_USER_MSG( "DecayName", 1 );
}
LINK_ENTITY_TO_CLASS( player, CBasePlayer )
@ -431,6 +443,9 @@ void CBasePlayer::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector ve
int CBasePlayer::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
{
// DECAY STATS
g_pGameRules->PlayerDamaged( this, pevAttacker, flDamage, bitsDamageType );
// have suit diagnose the problem - ie: report damage type
int bitsDamage = bitsDamageType;
int ffound = TRUE;
@ -811,6 +826,134 @@ void CBasePlayer::PackDeadPlayerItems( void )
RemoveAllItems( TRUE );// now strip off everything that wasn't handled by the code above.
}
void CBasePlayer::PackAllItems( void )
{
int iWeaponRules;
int iAmmoRules;
int i;
CBasePlayerWeapon *rgpPackWeapons[ 20 ];// 20 hardcoded for now. How to determine exactly how many weapons we have?
int iPackAmmo[ MAX_AMMO_SLOTS + 1];
int iPW = 0;// index into packweapons array
int iPA = 0;// index into packammo array
memset(rgpPackWeapons, NULL, sizeof(rgpPackWeapons) );
memset(iPackAmmo, -1, sizeof(iPackAmmo) );
// get the game rules
/*iWeaponRules = g_pGameRules->DeadPlayerWeapons( this );
iAmmoRules = g_pGameRules->DeadPlayerAmmo( this );
if ( iWeaponRules == GR_PLR_DROP_GUN_NO && iAmmoRules == GR_PLR_DROP_AMMO_NO )
{
// nothing to pack. Remove the weapons and return. Don't call create on the box!
RemoveAllItems( TRUE );
return;
}*/
iWeaponRules = GR_PLR_DROP_GUN_ALL;
iAmmoRules = GR_PLR_DROP_AMMO_ALL;
// go through all of the weapons and make a list of the ones to pack
for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ )
{
if ( m_rgpPlayerItems[ i ] )
{
// there's a weapon here. Should I pack it?
CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[ i ];
while ( pPlayerItem )
{
switch( iWeaponRules )
{
case GR_PLR_DROP_GUN_ACTIVE:
if ( m_pActiveItem && pPlayerItem == m_pActiveItem )
{
// this is the active item. Pack it.
rgpPackWeapons[ iPW++ ] = (CBasePlayerWeapon *)pPlayerItem;
}
break;
case GR_PLR_DROP_GUN_ALL:
rgpPackWeapons[ iPW++ ] = (CBasePlayerWeapon *)pPlayerItem;
break;
default:
break;
}
pPlayerItem = pPlayerItem->m_pNext;
}
}
}
// now go through ammo and make a list of which types to pack.
if ( iAmmoRules != GR_PLR_DROP_AMMO_NO )
{
for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ )
{
if ( m_rgAmmo[ i ] > 0 )
{
// player has some ammo of this type.
switch ( iAmmoRules )
{
case GR_PLR_DROP_AMMO_ALL:
iPackAmmo[ iPA++ ] = i;
break;
case GR_PLR_DROP_AMMO_ACTIVE:
if ( m_pActiveItem && i == m_pActiveItem->PrimaryAmmoIndex() )
{
// this is the primary ammo type for the active weapon
iPackAmmo[ iPA++ ] = i;
}
else if ( m_pActiveItem && i == m_pActiveItem->SecondaryAmmoIndex() )
{
// this is the secondary ammo type for the active weapon
iPackAmmo[ iPA++ ] = i;
}
break;
default:
break;
}
}
}
}
// create a box to pack the stuff into.
CWeaponBox *pWeaponBox = (CWeaponBox *)CBaseEntity::Create( "weaponbox", pev->origin + gpGlobals->v_forward * 2, pev->angles, edict() );
pWeaponBox->pev->angles.x = 0;// don't let weaponbox tilt.
pWeaponBox->pev->angles.z = 0;
pWeaponBox->SetThink( CWeaponBox::Kill );
pWeaponBox->pev->nextthink = gpGlobals->time + 120;
// back these two lists up to their first elements
iPA = 0;
iPW = 0;
// pack the ammo
while ( iPackAmmo[ iPA ] != -1 )
{
pWeaponBox->PackAmmo( MAKE_STRING( CBasePlayerItem::AmmoInfoArray[ iPackAmmo[ iPA ] ].pszName ), m_rgAmmo[ iPackAmmo[ iPA ] ] );
iPA++;
}
// now pack all of the items in the lists
while ( rgpPackWeapons[ iPW ] )
{
// weapon unhooked from the player. Pack it into der box.
pWeaponBox->PackWeapon( rgpPackWeapons[ iPW ] );
iPW++;
}
pWeaponBox->pev->velocity = pev->velocity * 1.2;// weaponbox has player's velocity, then some.
RemoveAllItems( FALSE );// now strip off everything that wasn't handled by the code above.
}
void CBasePlayer::RemoveAllItems( BOOL removeSuit )
{
int i;
@ -964,6 +1107,7 @@ void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim )
int animDesired;
float speed;
char szAnim[64];
int m_iMode;
speed = pev->velocity.Length2D();
@ -973,6 +1117,7 @@ void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim )
playerAnim = PLAYER_IDLE;
}
m_iMode = MODE_STAND;
switch( playerAnim )
{
case PLAYER_JUMP:
@ -1089,6 +1234,7 @@ void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim )
if( FBitSet( pev->flags, FL_DUCKING ) )
{
m_iMode = MODE_CROUCH;
if( speed == 0 )
{
pev->gaitsequence = LookupActivity( ACT_CROUCHIDLE );
@ -1101,6 +1247,7 @@ void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim )
}
else if( speed > 220 )
{
m_iMode = MODE_RUN;
pev->gaitsequence = LookupActivity( ACT_RUN );
}
else if( speed > 0 )
@ -1113,6 +1260,12 @@ void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim )
pev->gaitsequence = LookupSequence( "deep_idle" );
}
MESSAGE_BEGIN( MSG_ONE, gmsgChangeMode, NULL, pev);
WRITE_BYTE( m_iMode );
MESSAGE_END();
//ALERT( at_console, "Set mode to %d\n", m_iMode );
// Already using the desired animation?
if( pev->sequence == animDesired )
return;
@ -1655,6 +1808,10 @@ void CBasePlayer::Jump()
// ClearBits( pev->flags, FL_ONGROUND ); // don't stairwalk
MESSAGE_BEGIN( MSG_ONE, gmsgChangeMode, NULL, pev);
WRITE_BYTE( MODE_JUMP );
MESSAGE_END();
SetAnimation( PLAYER_JUMP );
if( m_fLongJump &&
@ -1777,6 +1934,9 @@ void CBasePlayer::UpdateStatusBar()
char sbuf0[SBAR_STRING_SIZE];
char sbuf1[ SBAR_STRING_SIZE ];
//Vyacheslav Dzhura: in Decay we need no StatusBar, just exit from here
//return;
strcpy( sbuf0, m_SbarString0 );
strcpy( sbuf1, m_SbarString1 );
@ -2883,6 +3043,17 @@ ReturnSpot:
return pSpot->edict();
}
inline char *GET_INFOBUFFER( edict_t *e )
{
return (*g_engfuncs.pfnGetInfoKeyBuffer)( e );
}
inline void SET_CLIENT_KEY_VALUE( int clientIndex, char *infobuffer,
char *key, char *value )
{
(*g_engfuncs.pfnSetClientKeyValue)( clientIndex, infobuffer, key, value );
}
void CBasePlayer::Spawn( void )
{
m_flStartCharge = gpGlobals->time;
@ -2925,7 +3096,11 @@ void CBasePlayer::Spawn( void )
m_iStepLeft = 0;
m_flFieldOfView = 0.5f;// some monsters use this to determine whether or not the player is looking at them.
m_bloodColor = BLOOD_COLOR_RED;
if ( !bSlaveCoop )
m_bloodColor = BLOOD_COLOR_RED;
else
m_bloodColor = BLOOD_COLOR_YELLOW;
m_flNextAttack = UTIL_WeaponTimeBase();
StartSneaking();
@ -2938,7 +3113,11 @@ void CBasePlayer::Spawn( void )
g_pGameRules->SetDefaultPlayerTeam( this );
g_pGameRules->GetPlayerSpawnSpot( this );
SET_MODEL( ENT( pev ), "models/player.mdl" );
if ( !bSlaveCoop )
SET_MODEL(ENT(pev), "models/player.mdl");
else
SET_MODEL(ENT(pev), "models/player/dm_slave/dm_slave.mdl");
g_ulModelIndexPlayer = pev->modelindex;
pev->sequence = LookupActivity( ACT_IDLE );
@ -2977,6 +3156,79 @@ void CBasePlayer::Spawn( void )
m_flNextChatTime = gpGlobals->time;
g_pGameRules->PlayerSpawn( this );
//
// Decay: set head\skin for Decay players
// MOVED TO DECAY_GAMERULES.CPP
char *infobuffer = GET_INFOBUFFER( edict( ) );
int clientIndex = entindex( );
if (!bSlaveCoop)
SET_CLIENT_KEY_VALUE( clientIndex, infobuffer, "model", "ginacol" );
else
SET_CLIENT_KEY_VALUE( clientIndex, infobuffer, "model", "player/dm_slave/dm_slave" );
// model parts:
// 0: body 0: body
// 1: head 0: Colette
// 1: Gina
// ****** HEADS CHANGE *********
//for ( int i = 0; i < 2; i++ )
{
this->SetBodygroup( 0, 0 );
if ( this->m_iDecayId == 1 )
{
this->SetBodygroup( 1, 1 );
this->pev->skin = 1;
} else
if ( this->m_iDecayId == 2 )
{
this->SetBodygroup( 1, 0 );
this->pev->skin = 0;
}
}
//
// Decay: update HUD color to match player (Silver for Gina, Orange for Colette)
//
if ( gmsgChangePlayer != 0)
{
//MESSAGE_BEGIN( MSG_ALL, gmsgChangePlayer );
MESSAGE_BEGIN( MSG_ONE, gmsgChangePlayer, NULL, this->edict() );
WRITE_BYTE( m_iDecayId );
MESSAGE_END();
} else
ALERT( at_console, "Message gmsgChangePlayer not found in client.dll!\n" );
ALERT( at_console, "(CBasePlayer::Spawn) m_iDecay = %d\n", this->m_iDecayId );
/*if (this->m_iDecayId >= 3)
{
MESSAGE_BEGIN( MSG_ONE, gmsgSparePlayer, NULL,
//GetClassPtr((CBasePlayer *)this->pev)->pev
this->edict() );
WRITE_BYTE( 0 );
MESSAGE_END();
}*/
//
// end of Decay stuff
//
CBaseEntity *pWeaponEntity = NULL;
if ( ( g_startSuit ) && ( !bSlaveCoop ) ) //if this flag is activated, then start level with suit and activate game_player_equip entity
{
GiveNamedItem( "item_suit" );
while ( pWeaponEntity = UTIL_FindEntityByClassname( pWeaponEntity, "game_player_equip" ))
{
pWeaponEntity->Touch( this );
}
}
}
void CBasePlayer::Precache( void )
@ -3066,7 +3318,10 @@ int CBasePlayer::Restore( CRestore &restore )
pev->fixangle = TRUE; // turn this way immediately
// Copied from spawn() for now
m_bloodColor = BLOOD_COLOR_RED;
if ( !bSlaveCoop )
m_bloodColor = BLOOD_COLOR_RED;
else
m_bloodColor = BLOOD_COLOR_YELLOW;
g_ulModelIndexPlayer = pev->modelindex;
@ -3781,7 +4036,7 @@ int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem, bool bCallHolster )
if( m_pActiveItem == pItem )
{
ResetAutoaim();
if( bCallHolster )
if( bCallHolster || !(pev->flags & FL_IMMUNE_WATER) )
pItem->Holster();
m_pActiveItem = NULL;
pev->viewmodel = 0;
@ -4201,11 +4456,15 @@ void CBasePlayer::UpdateClientData( void )
SendAmmoUpdate();
// Update all the items
// Update all the items (weapon slots)
for( int i = 0; i < MAX_ITEM_TYPES; i++ )
{
if( m_rgpPlayerItems[i] ) // each item updates it's successors
{
//ALERT( at_console, "updating item %d! ", i );
//ALERT( at_console, "%s\n", m_rgpPlayerItems[i]->pszName );
m_rgpPlayerItems[i]->UpdateClientData( this );
}
}
// Cache and client weapon change

View File

@ -27,18 +27,36 @@
#include "animation.h"
#include "soundent.h"
//
// Model bodies
//
#define LOD_COUNT 1 // IMPORTANT: 4 for original Decay; 5 for Half-Life PS2
#define BODY_GROUP 0
#define BODY_LOD0 0
#define HEAD_GROUP 1
#define NUM_SCIENTIST_HEADS 4 // four heads available for scientist model
static cvar_t *g_psv_override_scientist_mdl;
enum
{
HEAD_GLASSES = 0,
HEAD_EINSTEIN = 1,
HEAD_LUTHER = 2,
HEAD_SLICK = 3
HEAD_GLASSES = 0 * LOD_COUNT,
HEAD_EINSTEIN = 1 * LOD_COUNT,
HEAD_LUTHER = 2 * LOD_COUNT,
HEAD_SLICK = 3 * LOD_COUNT
};
#define NEEDLE_GROUP 2
#define NEEDLE_ON 1
#define NEEDLE_OFF 0
//
// Schedules
//
enum
{
SCHED_HIDE = LAST_TALKMONSTER_SCHEDULE + 1,
@ -112,12 +130,13 @@ public:
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
float m_painTime;
CUSTOM_SCHEDULES
private:
const char *GetScientistModel( void );
float m_painTime;
float m_healTime;
float m_fearTime;
};
@ -465,7 +484,7 @@ void CScientist::StartTask( Task_t *pTask )
//if( FOkToSpeak() )
Talk( 2 );
m_hTalkTarget = m_hTargetEnt;
PlaySentence( "SC_HEAL", 2, VOL_NORM, ATTN_IDLE );
PlaySentence( m_szGrp[TLK_HEAL], 2, VOL_NORM, ATTN_IDLE );
TaskComplete();
break;
case TASK_SCREAM:
@ -486,9 +505,9 @@ void CScientist::StartTask( Task_t *pTask )
//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 );
PlaySentence( m_szGrp[TLK_PLFEAR], 5, VOL_NORM, ATTN_NORM );
else
PlaySentence( "SC_FEAR", 5, VOL_NORM, ATTN_NORM );
PlaySentence( m_szGrp[TLK_FEAR], 5, VOL_NORM, ATTN_NORM );
}
TaskComplete();
break;
@ -637,14 +656,18 @@ void CScientist::HandleAnimEvent( MonsterEvent_t *pEvent )
break;
case SCIENTIST_AE_NEEDLEON:
{
int oldBody = pev->body;
pev->body = ( oldBody % NUM_SCIENTIST_HEADS ) + NUM_SCIENTIST_HEADS * 1;
//int oldBody = pev->body;
//pev->body = ( oldBody % NUM_SCIENTIST_HEADS ) + NUM_SCIENTIST_HEADS * 1;
SetBodygroup( NEEDLE_GROUP, NEEDLE_ON );
}
break;
case SCIENTIST_AE_NEEDLEOFF:
{
int oldBody = pev->body;
pev->body = ( oldBody % NUM_SCIENTIST_HEADS ) + NUM_SCIENTIST_HEADS * 0;
//int oldBody = pev->body;
//pev->body = ( oldBody % NUM_SCIENTIST_HEADS ) + NUM_SCIENTIST_HEADS * 0;
SetBodygroup( NEEDLE_GROUP, NEEDLE_OFF );
}
break;
default:
@ -661,8 +684,14 @@ void CScientist::Spawn( void )
if( pev->body == -1 )
{
// -1 chooses a random head
pev->body = RANDOM_LONG( 0, NUM_SCIENTIST_HEADS - 1 );// pick a head, any head
//pev->body = RANDOM_LONG( 0, NUM_SCIENTIST_HEADS - 1 );// pick a head, any head
SetBodygroup( HEAD_GROUP, RANDOM_LONG(0, NUM_SCIENTIST_HEADS-1) * LOD_COUNT );
} else
{
SetBodygroup( HEAD_GROUP, pev->body * LOD_COUNT );
}
SetBodygroup( BODY_GROUP, BODY_LOD0 );
Precache();
@ -685,7 +714,7 @@ void CScientist::Spawn( void )
pev->skin = 0;
// Luther is black, make his hands black
if( pev->body == HEAD_LUTHER )
if( GetBodygroup( HEAD_GROUP ) == HEAD_LUTHER )
pev->skin = 1;
MonsterInit();
@ -741,7 +770,7 @@ void CScientist::TalkInit()
m_szGrp[TLK_MORTAL] = "SC_MORTAL";
// get voice for head
switch( pev->body % NUM_SCIENTIST_HEADS )
switch ( GetBodygroup( HEAD_GROUP ) )
{
default:
case HEAD_GLASSES:
@ -1164,11 +1193,15 @@ void CDeadScientist::Spawn()
if( pev->body == -1 )
{
// -1 chooses a random head
pev->body = RANDOM_LONG( 0, NUM_SCIENTIST_HEADS - 1 );// pick a head, any head
SetBodygroup( HEAD_GROUP, RANDOM_LONG(0, NUM_SCIENTIST_HEADS-1) * LOD_COUNT );
} else
{
SetBodygroup( HEAD_GROUP, pev->body * LOD_COUNT );
}
SetBodygroup( BODY_GROUP, BODY_LOD0 );
// Luther is black, make his hands black
if( pev->body == HEAD_LUTHER )
if( GetBodygroup( HEAD_GROUP ) == HEAD_LUTHER )
pev->skin = 1;
else
pev->skin = 0;
@ -1269,11 +1302,15 @@ void CSittingScientist::Spawn()
if( pev->body == -1 )
{
// -1 chooses a random head
pev->body = RANDOM_LONG( 0, NUM_SCIENTIST_HEADS - 1 );// pick a head, any head
SetBodygroup( HEAD_GROUP, RANDOM_LONG(0, NUM_SCIENTIST_HEADS-1) * LOD_COUNT );
} else
{
SetBodygroup( HEAD_GROUP, pev->body * LOD_COUNT );
}
SetBodygroup( BODY_GROUP, BODY_LOD0 );
// Luther is black, make his hands black
if( pev->body == HEAD_LUTHER )
if( GetBodygroup( HEAD_GROUP ) == HEAD_LUTHER )
pev->skin = 1;
m_baseSequence = LookupSequence( "sitlookleft" );
@ -1704,4 +1741,4 @@ void CRosenberg :: TalkInit()
int CRosenberg::FIdleSpeak( void )
{
return -1;
}
}

View File

@ -278,7 +278,7 @@ int CCineMonster::FindEntity( void )
m_hTargetEnt = pTarget;
return TRUE;
}
ALERT( at_console, "Found %s, but can't play!\n", STRING( m_iszEntity ) );
ALERT( at_console, "(%s::FindEntity) Found %s, but can't play!\n", STRING(pev->targetname), STRING( m_iszEntity ) );
}
pentTarget = FIND_ENTITY_BY_TARGETNAME( pentTarget, STRING( m_iszEntity ) );
pTarget = NULL;

View File

@ -35,6 +35,7 @@ extern int gmsgMOTD;
//=========================================================
CHalfLifeRules::CHalfLifeRules( void )
{
ALERT( at_console, "Generic Half-Life singleplayer\n");
SERVER_COMMAND( "exec spserver.cfg\n" );
RefreshSkillData();
}

View File

@ -627,6 +627,10 @@ void CAmbientGeneric::ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller,
UTIL_EmitAmbientSound( ENT( pev ), pev->origin, szSoundFile, ( m_dpv.vol * 0.01f ), m_flAttenuation, 0, m_dpv.pitch );
// Decay: subtitles code
if ( FBitSet ( pev->spawnflags, AMBIENT_SHOWMESSAGE ) )
UTIL_ShowMessageAll( STRING(pev->message) ); //strings code
pev->nextthink = gpGlobals->time + 0.1f;
}
}

View File

@ -66,6 +66,7 @@ private:
// These are the new entry points to entities.
LINK_ENTITY_TO_CLASS( info_player_deathmatch, CBaseDMStart )
LINK_ENTITY_TO_CLASS( info_player_start, CPointEntity )
LINK_ENTITY_TO_CLASS( info_player_coop, CPointEntity ) // for Decay to spawn players properly
LINK_ENTITY_TO_CLASS( info_landmark, CPointEntity )
void CBaseDMStart::KeyValue( KeyValueData *pkvd )

View File

@ -61,6 +61,11 @@ typedef enum
TLK_WOUND,
TLK_MORTAL,
// added for Decay
TLK_HEAL,
TLK_PLFEAR,
TLK_FEAR,
TLK_CGROUPS // MUST be last entry
} TALKGROUPNAMES;

View File

@ -104,11 +104,109 @@ void CFrictionModifier::KeyValue( KeyValueData *pkvd )
CBaseEntity::KeyValue( pkvd );
}
// This trigger will fire when the level spawns (or respawns if not fire once)
// This trigger will fire when the client spawns in game world, just after the HUD INIT
// It will check a global state before firing. It supports delay and killtargets
#define SF_AUTO_FIREONCE 0x0001
class CPlayerSpawnTrigger : public CBaseDelay
{
public:
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void Spawn( void );
int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
private:
int m_globalstate;
int m_iPlayerIndex;
USE_TYPE triggerType;
};
LINK_ENTITY_TO_CLASS( trigger_clientspawn, CPlayerSpawnTrigger );
TYPEDESCRIPTION CPlayerSpawnTrigger::m_SaveData[] =
{
DEFINE_FIELD( CPlayerSpawnTrigger, m_globalstate, FIELD_STRING ),
DEFINE_FIELD( CPlayerSpawnTrigger, m_iPlayerIndex, FIELD_INTEGER ),
DEFINE_FIELD( CPlayerSpawnTrigger, triggerType, FIELD_INTEGER ),
};
IMPLEMENT_SAVERESTORE(CPlayerSpawnTrigger, CBaseDelay);
void CPlayerSpawnTrigger::Spawn( void )
{
}
void CPlayerSpawnTrigger::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "globalstate"))
{
m_globalstate = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "player_index"))
{
m_iPlayerIndex = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "triggerstate"))
{
int type = atoi( pkvd->szValue );
switch( type )
{
case 0:
triggerType = USE_OFF;
break;
case 2:
triggerType = USE_TOGGLE;
break;
default:
triggerType = USE_ON;
break;
}
pkvd->fHandled = TRUE;
}
else
CBaseDelay::KeyValue( pkvd );
}
void CPlayerSpawnTrigger::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON )
{
if ( pev->spawnflags & SF_SPECIFICPLAYER )
{
if ( pActivator )
if (pActivator->IsPlayer())
{
CBasePlayer *g_pPlayer;
g_pPlayer = (CBasePlayer*)pActivator;
if (m_iPlayerIndex != 0)
{ // check if Gina or Colette
if (g_pPlayer->m_iDecayId != m_iPlayerIndex)
return;
}
}
}
SUB_UseTargets( this, triggerType, 0 );
if ( pev->spawnflags & SF_AUTO_FIREONCE )
UTIL_Remove( this );
}
}
// This trigger will fire when the level spawns (or respawns if not fire once)
// It will check a global state before firing. It supports delay and killtargets
class CAutoTrigger : public CBaseDelay
{
public:
@ -173,7 +271,7 @@ void CAutoTrigger::Spawn( void )
void CAutoTrigger::Precache( void )
{
pev->nextthink = gpGlobals->time + 0.1f;
pev->nextthink = gpGlobals->time + 0.1f; // m_flDelay used automatically in SUB_UseTargets
}
void CAutoTrigger::Think( void )
@ -186,6 +284,137 @@ void CAutoTrigger::Think( void )
}
}
//
// This trigger will fire when the level spawns (or respawns if not fire once)
// It will check a global state before firing. It supports delay and killtargets
//
class CTriggerAutoBot : public CBaseDelay
{
public:
void KeyValue( KeyValueData *pkvd );
void Spawn( void );
void Precache( void );
void Think( void );
int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
};
LINK_ENTITY_TO_CLASS( trigger_autobot, CTriggerAutoBot );
void CTriggerAutoBot::KeyValue( KeyValueData *pkvd )
{
CBaseDelay::KeyValue( pkvd );
}
void CTriggerAutoBot::Spawn( void )
{
Precache();
}
void CTriggerAutoBot::Precache( void )
{
pev->nextthink = gpGlobals->time + 9.0;
}
void CTriggerAutoBot::Think( void )
{
if (!bDecay)
return;
if (!g_pGameRules->IsCoOp())
return;
CDecayRules *g_pDecayRules;
g_pDecayRules = (CDecayRules*)g_pGameRules;
if (g_pDecayRules->PlayersCount == 1)
{
char cmd[40];
sprintf(cmd, "addbot\n" );
SERVER_COMMAND(cmd);
}
UTIL_Remove( this );
}
//
// fade screen and call endsection upon level spawn if mission is locked
//
LINK_ENTITY_TO_CLASS( trigger_lockedmission, CTriggerLockedMission );
void CTriggerLockedMission::Spawn( void )
{
pev->nextthink = 0;
pev->message = ALLOC_STRING( "DYLOCKED" );
m_flDelay = 7;
}
void CTriggerLockedMission::Lock( void )
{
CBasePlayer *client;
client = NULL;
while ( ((client = (CBasePlayer*)UTIL_FindEntityByClassname( client, "player" )) != NULL) && (!FNullEnt(client->edict())) )
{
if ( !client->pev )
continue;
if ( !(client->IsNetClient()) ) // Not a client ? (should never be true)
continue;
client->EnableControl(FALSE);
}
UTIL_ScreenFadeAll( Vector(0, 0, 0), 7, 3, 255, FFADE_OUT );
UTIL_ShowMessageAll( STRING(pev->message) );
pev->nextthink = gpGlobals->time + 7;
}
void CTriggerLockedMission::Think( void )
{
if ( pev->message )
g_engfuncs.pfnEndSection(STRING(pev->message));
else
g_engfuncs.pfnEndSection( "Decay" );
}
//
// trigger for kicking the players (bots)
//
LINK_ENTITY_TO_CLASS( trigger_kicker, CTriggerKicker );
void CTriggerKicker::Spawn( void )
{
pev->nextthink = 0;
m_flDelay = 3;
}
void CTriggerKicker::KickPlayer( CBasePlayer *pKickMe )
{
ALERT( at_console, "Going to kick spare player %s!\n", STRING( pKickMe->pev->netname) );
pPlayerToKick = pKickMe;
pev->nextthink = gpGlobals->time + m_flDelay;
// TODO: send message to player to display Decay Spare player screen here?
}
void CTriggerKicker::Think( void )
{
if (!bDecay)
return;
if (!g_pGameRules->IsCoOp())
return;
char cmd[128];
sprintf(cmd, "kick \"%s\"\n", STRING(pPlayerToKick->pev->netname) );
SERVER_COMMAND(cmd);
UTIL_Remove( this );
}
// end of kicker code
#define SF_RELAY_FIREONCE 0x0001
class CTriggerRelay : public CBaseDelay
@ -385,7 +614,19 @@ void CMultiManager::ManagerThink( void )
time = gpGlobals->time - m_startTime;
while( m_index < m_cTargets && m_flTargetDelay[m_index] <= time )
{
FireTargets( STRING( m_iTargetName[m_index] ), m_hActivator, this, USE_TOGGLE, 0 );
if ( pev->spawnflags & SF_MM_KILLTARGETS )
{
CBaseEntity *pEntity = NULL;
while (pEntity = UTIL_FindEntityByTargetname(pEntity, STRING( m_iTargetName[ m_index ] )))
{
//ALERT( at_console, "Killing %s...\n", STRING( m_iTargetName[ m_index ] ) );
UTIL_Remove( pEntity );
}
} else
{
FireTargets( STRING( m_iTargetName[ m_index ] ), m_hActivator, this, USE_TOGGLE, 0 );
}
m_index++;
}
@ -482,6 +723,11 @@ void CRenderFxManager::Spawn( void )
pev->solid = SOLID_NOT;
}
inline edict_t *FIND_ENTITY_BY_NETNAME(edict_t *entStart, const char *pszName)
{
return FIND_ENTITY_BY_STRING(entStart, "netname", pszName);
}
void CRenderFxManager::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if( !FStringNull( pev->target ) )
@ -541,6 +787,10 @@ void CRenderFxManager::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T
class CBaseTrigger : public CBaseToggle
{
public:
int m_iPlayersInside; //TODO: implement saverestore
byte m_bCurrentPlayer, m_bPreviousPlayer;
float m_flLastTouch;
void EXPORT TeleportTouch( CBaseEntity *pOther );
void KeyValue( KeyValueData *pkvd );
void EXPORT MultiTouch( CBaseEntity *pOther );
@ -612,6 +862,7 @@ public:
};
LINK_ENTITY_TO_CLASS( trigger_hurt, CTriggerHurt )
LINK_ENTITY_TO_CLASS( trigger_new_hurt, CTriggerHurt )
//
// trigger_monsterjump
@ -911,6 +1162,30 @@ void CTriggerHurt::RadiationThink( void )
//
void CBaseTrigger::ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
//Decay's trigger_new_hurt used only mission ht04dampen
bool m_bIsNewHurt = !strcmp(STRING(pev->classname), "trigger_new_hurt");
if ( m_bIsNewHurt )
{
bool m_bIsOn = ( pev->solid == SOLID_TRIGGER );
if ( useType == USE_TOGGLE )
m_bIsOn = !m_bIsOn;
if ( useType == USE_ON )
m_bIsOn = true;
if ( useType == USE_OFF )
m_bIsOn = false;
if ( m_bIsOn )
{
pev->solid = SOLID_TRIGGER;
gpGlobals->force_retouch++;
} else
pev->solid = SOLID_NOT;
UTIL_SetOrigin( pev, pev->origin );
return;
}
if( pev->solid == SOLID_NOT )
{
// if the trigger is off, turn it on
@ -1144,6 +1419,17 @@ void CTriggerOnce::Spawn( void )
void CBaseTrigger::MultiTouch( CBaseEntity *pOther )
{
if (pOther->IsPlayer())
{
CBasePlayer *g_pPlayer;
g_pPlayer = (CBasePlayer*)pOther;
//uncommentme
//ALERT( at_console, "(%s) inside %d need %d\n", STRING(pev->targetname), g_pPlayer->m_iDecayId, m_iPlayerIndex );
//DECAY debug:
//ALERT( at_console, "trigger %s targets %s\n", STRING(pev->targetname), STRING(pev->target) );
}
entvars_t *pevToucher;
pevToucher = pOther->pev;
@ -1163,7 +1449,60 @@ void CBaseTrigger::MultiTouch( CBaseEntity *pOther )
return; // not facing the right way
}
#endif
// Decay's specific player check
// DONE: bug found - when player 1 enters trigger, then exists and player 2 enters trigger
// it acts as if they both where here! :) How to solve that???
if ( pev->spawnflags & SF_SPECIFICPLAYER )
{
if (pOther->IsPlayer())
{
CBasePlayer *g_pPlayer;
g_pPlayer = (CBasePlayer*)pOther;
if (m_iPlayerIndex != 0)
{ // check if Gina or Colette
if (g_pPlayer->m_iDecayId != m_iPlayerIndex)
return;
} else
{ // check if both are inside
m_bPreviousPlayer = m_bCurrentPlayer;
m_bCurrentPlayer = g_pPlayer->m_iDecayId;
SetBits( m_iPlayersInside, g_pPlayer->m_iDecayId);
byte m_bAnotherPlayer;
if ( m_bCurrentPlayer == 1)
m_bAnotherPlayer = 2;
else
m_bAnotherPlayer = 1;
if (m_flLastTouch < gpGlobals->time - 0.1)
ClearBits( m_iPlayersInside, m_bAnotherPlayer );
m_flLastTouch = gpGlobals->time;
//m_iPlayersInside = m_iPlayersInside & g_pPlayer->m_iDecayId;
if (!(m_iPlayersInside & PF_PLAYER1) || !(m_iPlayersInside & PF_PLAYER2))
return;
/*if ( m_bCurrentPlayer == m_bPreviousPlayer )
{
ClearBits( m_iPlayersInside, m_bAnotherPlayer );
return;
}*/
}
//m_flWait = -1;
}
}
ActivateMultiTrigger( pOther );
//if ( pev->spawnflags & SF_SPECIFICPLAYER )
// if (m_iPlayerIndex == 0)
// m_iPlayersInside = 0;
//if ( pev->spawnflags & SF_SPECIFICPLAYER )
// SetTouch( NULL );
m_iPlayersInside = 0;
}
}
@ -1239,10 +1578,15 @@ void CBaseTrigger::CounterUse( CBaseEntity *pActivator, CBaseEntity *pCaller, US
m_cTriggersLeft--;
m_hActivator = pActivator;
ALERT( at_console, "(trigger_counter::%s) used, left: %d\n", STRING( this->pev->classname ), m_cTriggersLeft );
if( m_cTriggersLeft < 0 )
return;
BOOL fTellActivator =
if (m_cTriggersLeft != 0)
return;
/*BOOL fTellActivator =
( m_hActivator != 0 ) &&
m_hActivator->IsPlayer() &&
!FBitSet( pev->spawnflags, SPAWNFLAG_NOMESSAGE );
@ -1272,9 +1616,22 @@ void CBaseTrigger::CounterUse( CBaseEntity *pActivator, CBaseEntity *pCaller, US
// !!!UNDONE: I don't think we want these Quakesque messages
if( fTellActivator )
ALERT( at_console, "Sequence completed!" );
ALERT( at_console, "Sequence completed!" );*/
ActivateMultiTrigger( m_hActivator );
ALERT( at_console, "(trigger_counter::%s) sequence done! Firing %s\n", STRING( this->pev->classname ), STRING( this->pev->target ) );
if ( m_hActivator ) // Vyacheslav Dzhura: trigger_counter issue - access violation when counter activated by func_breakable
ActivateMultiTrigger( m_hActivator );
else
ActivateMultiTrigger( pCaller );
if (m_iszKillTarget)
{
ALERT(at_console, "%s\n", STRING( m_iszKillTarget ));
CBaseEntity *pEntity = NULL;
pEntity = UTIL_FindEntityByTargetname(pEntity, STRING( m_iszKillTarget ));
UTIL_Remove( pEntity );
}
}
/*QUAKED trigger_counter (.5 .5 .5) ? nomessage
@ -1926,9 +2283,24 @@ void CBaseTrigger::TeleportTouch( CBaseEntity *pOther )
}
}
pentTarget = FIND_ENTITY_BY_TARGETNAME( pentTarget, STRING( pev->target ) );
if( FNullEnt( pentTarget ) )
return;
if ( pev->spawnflags & SF_SPECIFICPLAYER )
{
if (pOther->IsPlayer())
{
CBasePlayer *g_pPlayer;
g_pPlayer = (CBasePlayer*)pOther;
if (m_iPlayerIndex != 0)
{ // check if Gina or Colette
if (g_pPlayer->m_iDecayId != m_iPlayerIndex)
return;
} // Vyacheslav Dzhura: no need in "else", check if both are inside can't be applied for teleport
}
}
pentTarget = FIND_ENTITY_BY_TARGETNAME( pentTarget, STRING(pev->target) );
if (FNullEnt(pentTarget))
return;
Vector tmp = VARS( pentTarget )->origin;
@ -2048,8 +2420,29 @@ void CTriggerEndSection::EndSectionUse( CBaseEntity *pActivator, CBaseEntity *pC
if( pev->message )
{
g_engfuncs.pfnEndSection( STRING( pev->message ) );
if (!IS_DEDICATED_SERVER())
g_engfuncs.pfnEndSection(STRING(pev->message));
else
{
//
// FOR DEDICATED SERVER, SKIP TO THE FIRST MISSION
//
static char szNextMap[128];
sprintf( szNextMap, "null" );
if (g_pGameRules->IsCoOp())
{
CDecayRules *g_pDecayRules = (CDecayRules*)g_pGameRules;
sprintf( szNextMap, g_pDecayRules->getDecayMapName( 1 ) );
}
bool bHasNextMap = ( strcmp( szNextMap, "null" ) != 0 );
if ( bHasNextMap )
CHANGE_LEVEL( szNextMap, NULL );
}
}
UTIL_Remove( this );
}

View File

@ -940,7 +940,10 @@ void CBaseTurret::TurretDeath( void )
else
m_vecGoalAngles.x = -90;
SetTurretAnim( TURRET_ANIM_DIE );
SetTurretAnim( TURRET_ANIM_DIE );
// fixed for Decay - miniturrets now process TriggerConditions \ TriggerTargets
FCheckAITrigger();
EyeOn();
}

View File

@ -567,8 +567,11 @@ private:
void UTIL_SetGroupTrace( int groupmask, int op );
void UTIL_UnsetGroupTrace( void );
Vector UTIL_Intersect( Vector vecSrc, Vector vecDst, Vector vecMove, float flSpeed );
int UTIL_SharedRandomLong( unsigned int seed, int low, int high );
float UTIL_SharedRandomFloat( unsigned int seed, float low, float high );
float UTIL_WeaponTimeBase( void );
void FindHullIntersection( const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity );
#endif // UTIL_H

View File

@ -320,6 +320,11 @@ void W_Precache( void )
// 9mm ammo box
UTIL_PrecacheOther( "ammo_9mmbox" );
// displacer
UTIL_PrecacheOtherWeapon( "weapon_displacer" );
UTIL_PrecacheOtherWeapon( "weapon_vorti" );
#if !OEM_BUILD && !HLDEMO_BUILD
// python
UTIL_PrecacheOtherWeapon( "weapon_357" );
@ -428,11 +433,33 @@ void CBasePlayerItem::SetObjectCollisionBox( void )
pev->absmax = pev->origin + Vector( 24, 24, 16 );
}
void CBasePlayerItem :: KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "player_index"))
{
DecayPlayerIndex = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
{
CBaseDelay::KeyValue( pkvd );
}
}
//=========================================================
// Sets up movetype, size, solidtype for a new weapon.
//=========================================================
void CBasePlayerItem::FallInit( void )
{
if (pev->spawnflags & 1)
{
pev->solid = SOLID_TRIGGER;
UTIL_SetOrigin( pev, pev->origin );// link into world.
SetTouch (DefaultTouch);
SetThink (NULL);
return;
}
pev->movetype = MOVETYPE_TOSS;
pev->solid = SOLID_BBOX;
@ -826,7 +853,15 @@ int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer )
}
if( m_pNext )
m_pNext->UpdateClientData( pPlayer );
{
if ( m_pNext->m_iId >= 0 )
m_pNext->UpdateClientData( pPlayer );
else
{
ALERT( at_console, "'%s'->m_pNext sends to invalid class!\n", this->pszName );
return 0;
}
}
return 1;
}
@ -1246,7 +1281,14 @@ void CWeaponBox::Precache( void )
//=========================================================
void CWeaponBox::KeyValue( KeyValueData *pkvd )
{
if( m_cAmmoTypes < MAX_AMMO_SLOTS )
if ( FStrEq(pkvd->szKeyName, "player_index") )
{
m_iPlayerIndex = atoi( pkvd->szValue );
pkvd->fHandled = true;
return;
}
if (( m_cAmmoTypes < MAX_AMMO_SLOTS ) && (!FStrEq(pkvd->szKeyName, "player_index")))
{
PackAmmo( ALLOC_STRING( pkvd->szKeyName ), atoi( pkvd->szValue ) );
m_cAmmoTypes++;// count this new ammo type.

View File

@ -102,6 +102,7 @@ public:
#define SNARK_WEIGHT 5
#define SATCHEL_WEIGHT -10
#define TRIPMINE_WEIGHT -10
#define DISPLACER_WEIGHT 20
// weapon clip/carry ammo capacities
#define URANIUM_MAX_CARRY 100
@ -134,6 +135,7 @@ public:
#define SATCHEL_MAX_CLIP WEAPON_NOCLIP
#define TRIPMINE_MAX_CLIP WEAPON_NOCLIP
#define SNARK_MAX_CLIP WEAPON_NOCLIP
#define DISPLACER_MAX_CLIP WEAPON_NOCLIP
// the default amount of ammo that comes with each gun when it spawns
#define GLOCK_DEFAULT_GIVE 17
@ -1051,4 +1053,65 @@ public:
private:
unsigned short m_usSnarkFire;
};
class CTeleBall: public CBaseMonster
{
public:
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
void Spawn( void );
void Precache( void );
void PlayEffect( Vector Origin, CBaseEntity *pEntity);
void EXPORT TeleportThink( void );//think when fly
void EXPORT TeleportKill( void ); //think when kill
void EXPORT TeleportTouch( CBaseEntity *pOther ); //touch 'n kill
CBeam *pBeam[5];
int ring_sprite;
Vector m_vecIdeal ;
EHANDLE m_hTouch ;
};
class CDisplacer : public CBasePlayerWeapon
{
public:
void Spawn( void );
void Precache( void );
int iItemSlot( ) { return 5; } //slot 5
int GetItemInfo(ItemInfo *p);
void PrimaryAttack( void );
void SecondaryAttack( void );
int AddToPlayer( CBasePlayer *pPlayer );
void Holster( int skiplocal = 0 );
void Reload( void );
void WeaponIdle( void );
void PlayEffect( Vector Origin);
BOOL Deploy( void );
void EXPORT SpinupThink( void );
void EXPORT FireThink( void );
BOOL PlayEmptySound( void );
/*
virtual BOOL UseDecrement( void )
{
#if defined( CLIENT_WEAPONS )
return TRUE;
#else
return FALSE;
#endif
}*/
private:
CBeam *pBeam;
};
#endif // WEAPONS_H

View File

@ -451,6 +451,7 @@ LINK_ENTITY_TO_CLASS( worldspawn, CWorld )
#define SF_WORLD_FORCETEAM 0x0004 // Force teams
extern DLL_GLOBAL BOOL g_fGameOver;
BOOL g_startSuit; // When level starts player will automatically receive a suit and game_player_equip will be targeted
void CWorld::Spawn( void )
{
@ -626,18 +627,19 @@ void CWorld::Precache( void )
// g-cont. moved here to right restore global WaveHeight on save\restore level
CVAR_SET_FLOAT( "sv_wateramp", pev->scale );
//ALERT( at_console, "Chapter title variable set to: '%s'\n", STRING(pev->netname) );
if( pev->netname )
{
ALERT( at_aiconsole, "Chapter title: %s\n", STRING( pev->netname ) );
CBaseEntity *pEntity = CBaseEntity::Create( "env_message", g_vecZero, g_vecZero, NULL );
CBaseEntity *pEntity = CBaseEntity::Create( "env_message", g_vecZero, g_vecZero, edict() );
if( pEntity )
{
pEntity->SetThink( &CBaseEntity::SUB_CallUseToggle );
pEntity->pev->message = pev->netname;
pev->netname = 0;
pEntity->pev->nextthink = gpGlobals->time + 0.3f;
pEntity->pev->nextthink = gpGlobals->time + 1.3f;
pEntity->pev->spawnflags = SF_MESSAGE_ONCE;
}
} else ALERT( at_aiconsole, "Chapter title message entity was not created!\n");
}
if( pev->spawnflags & SF_WORLD_DARK )

View File

@ -17,11 +17,12 @@
#include "cbase.h"
#include "animation.h"
#include "effects.h"
#include "actanimating.h"
#define XEN_PLANT_GLOW_SPRITE "sprites/flare3.spr"
#define XEN_PLANT_HIDE_TIME 5
class CActAnimating : public CBaseAnimating
/*class CActAnimating : public CBaseAnimating
{
public:
void SetActivity( Activity act );
@ -55,6 +56,7 @@ void CActAnimating::SetActivity( Activity act )
ResetSequenceInfo();
}
}
*/
class CXenPLight : public CActAnimating
{

View File

@ -1962,6 +1962,7 @@ void PM_UnDuck( void )
VectorCopy( pmove->origin, newOrigin );
/*
if( pmove->onground != -1 )
{
for( i = 0; i < 3; i++ )