mirror of https://github.com/FWGS/hlsdk-xash3d
Rebase step 2: add changes automatically patched by diffing HLSDK 2.3 and Decay trees
This commit is contained in:
parent
dd15f7a392
commit
988c6757dd
|
@ -898,7 +898,7 @@ int CHudAmmo::Draw( float flTime )
|
|||
|
||||
x += AmmoWidth / 2;
|
||||
|
||||
UnpackRGB( r,g,b, RGB_YELLOWISH );
|
||||
UnpackRGB( r,g,b, gHUD.uColor );
|
||||
|
||||
// draw the | bar
|
||||
FillRGBA( x, y, iBarWidth, gHUD.m_iFontHeight, r, g, b, a );
|
||||
|
|
|
@ -79,6 +79,15 @@ void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking);
|
|||
void DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf );
|
||||
void DLLEXPORT HUD_MobilityInterface( mobile_engfuncs_t *gpMobileEngfuncs );
|
||||
}
|
||||
/*
|
||||
// SCREEN GLOW
|
||||
extern bool InitScreenGlow();
|
||||
extern void RenderScreenGlow();
|
||||
*/
|
||||
// CAMERA EFFECT
|
||||
extern bool InitCameraEffect();
|
||||
extern void RenderCameraEffect();
|
||||
extern void GrabCameraTexture();
|
||||
|
||||
/*
|
||||
================================
|
||||
|
@ -302,6 +311,14 @@ redraw the HUD.
|
|||
|
||||
int DLLEXPORT HUD_Redraw( float time, int intermission )
|
||||
{
|
||||
// check if we are in OpenGl mode
|
||||
if (IEngineStudio.IsHardware() == 1)
|
||||
{
|
||||
//RenderScreenGlow(); // SCREEN GLOW
|
||||
if (gHUD.m_iCamMode == CAM_ON)
|
||||
RenderCameraEffect();
|
||||
}
|
||||
|
||||
gHUD.Redraw( time, intermission );
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -1696,6 +1696,287 @@ void EV_SnarkFire( event_args_t *args )
|
|||
// SQUEAK END
|
||||
//======================
|
||||
|
||||
//======================
|
||||
// VORTI START
|
||||
//======================
|
||||
|
||||
enum vorti_e {
|
||||
SLAVE_IDLE1 = 0,
|
||||
SLAVE_IDLE2,
|
||||
SLAVE_ATTACK1HIT,
|
||||
SLAVE_ATTACK1MISS,
|
||||
SLAVE_ATTACK2MISS,
|
||||
SLAVE_ATTACK2HIT,
|
||||
SLAVE_ATTACK3MISS,
|
||||
SLAVE_ATTACK3HIT,
|
||||
|
||||
SLAVE_CHARGE,
|
||||
SLAVE_CHARGE_LOOP,
|
||||
SLAVE_ZAP,
|
||||
SLAVE_RETURN
|
||||
};
|
||||
|
||||
int g_iVortSwing;
|
||||
|
||||
//Only predict the miss sounds, hit sounds are still played
|
||||
//server side, so players don't get the wrong idea.
|
||||
void EV_Vorti( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t velocity;
|
||||
|
||||
idx = args->entindex;
|
||||
VectorCopy( args->origin, origin );
|
||||
|
||||
//Play Swing sound
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "zombie/claw_miss1.wav", 1, ATTN_NORM, 0, PITCH_NORM);
|
||||
|
||||
if ( EV_IsLocal( idx ) )
|
||||
{
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( SLAVE_ATTACK1MISS, 1 );
|
||||
|
||||
switch( (g_iVortSwing++) % 3 )
|
||||
{
|
||||
case 0:
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation ( SLAVE_ATTACK1MISS, 1 ); break;
|
||||
case 1:
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation ( SLAVE_ATTACK2MISS, 1 ); break;
|
||||
case 2:
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation ( SLAVE_ATTACK3MISS, 1 ); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
float r = 255.0f;
|
||||
float g = 180.0f;
|
||||
float b = 96.0f;
|
||||
|
||||
R_BeamEntPoint:
|
||||
int startEnt,
|
||||
float * end,
|
||||
int modelIndex,
|
||||
float life,
|
||||
float width,
|
||||
float amplitude,
|
||||
float brightness,
|
||||
float speed,
|
||||
int startFrame,
|
||||
float framerate,
|
||||
float r, float g, float b
|
||||
|
||||
pVortiBeam = gEngfuncs.pEfxAPI->R_BeamEntPoint ( idx | 0x1000, tr.endpos, iBeamModelIndex,
|
||||
99999, ///life
|
||||
2.0, //width
|
||||
0.4, // ampl
|
||||
64 / 255, //bright
|
||||
55, //speed
|
||||
0, 0,
|
||||
r, g, b );
|
||||
*/
|
||||
|
||||
//#define SND_CHANGE_PITCH (1<<7) // duplicated in protocol.h change sound pitch
|
||||
|
||||
void EV_SpinVorti( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t velocity;
|
||||
int iSoundState = 0;
|
||||
|
||||
int pitch;
|
||||
|
||||
idx = args->entindex;
|
||||
VectorCopy( args->origin, origin );
|
||||
VectorCopy( args->angles, angles );
|
||||
VectorCopy( args->velocity, velocity );
|
||||
|
||||
pitch = args->iparam1;
|
||||
|
||||
//iSoundState = args->bparam1 ? SND_CHANGE_PITCH : 0;
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "debris/zap1.wav", 1.0, ATTN_NORM, iSoundState, pitch );
|
||||
}
|
||||
|
||||
/*
|
||||
==============================
|
||||
EV_StopPreviousGauss
|
||||
|
||||
==============================
|
||||
*/
|
||||
void EV_StopPreviousVorti( int idx )
|
||||
{
|
||||
// Make sure we don't have a gauss spin event in the queue for this guy
|
||||
gEngfuncs.pEventAPI->EV_KillEvents( idx, "events/vortispin.sc" );
|
||||
gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_WEAPON, "debris/zap1.wav" );
|
||||
}
|
||||
|
||||
void EV_FireVorti( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t velocity;
|
||||
float flDamage = args->fparam1;
|
||||
int primaryfire = args->bparam1;
|
||||
|
||||
int m_fPrimaryFire = args->bparam1;
|
||||
int m_iWeaponVolume = GAUSS_PRIMARY_FIRE_VOLUME;
|
||||
vec3_t vecSrc;
|
||||
vec3_t vecDest;
|
||||
edict_t *pentIgnore;
|
||||
pmtrace_t tr, beam_tr;
|
||||
float flMaxFrac = 1.0;
|
||||
int nTotal = 0;
|
||||
int fHasPunched = 0;
|
||||
int fFirstBeam = 1;
|
||||
int nMaxHits = 1;
|
||||
physent_t *pEntity;
|
||||
int m_iBeam, m_iGlow, m_iBalls;
|
||||
vec3_t up, right, forward;
|
||||
|
||||
idx = args->entindex;
|
||||
VectorCopy( args->origin, origin );
|
||||
VectorCopy( args->angles, angles );
|
||||
VectorCopy( args->velocity, velocity );
|
||||
|
||||
if ( args->bparam2 )
|
||||
{
|
||||
EV_StopPreviousVorti( idx );
|
||||
return;
|
||||
}
|
||||
|
||||
//Con_Printf( "Firing vorti with %f\n", flDamage );
|
||||
EV_GetGunPosition( args, vecSrc, origin );
|
||||
|
||||
m_iBeam = gEngfuncs.pEventAPI->EV_FindModelIndex( "sprites/lgtning.spr" );
|
||||
m_iBalls = m_iGlow = gEngfuncs.pEventAPI->EV_FindModelIndex( "sprites/hotglow.spr" );
|
||||
|
||||
AngleVectors( angles, forward, right, up );
|
||||
|
||||
VectorMA( vecSrc, 8192, forward, vecDest );
|
||||
|
||||
if ( EV_IsLocal( idx ) )
|
||||
{
|
||||
V_PunchAxis( 0, -2.0 );
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( SLAVE_ZAP, 2 );
|
||||
|
||||
if ( m_fPrimaryFire == false )
|
||||
g_flApplyVel = flDamage;
|
||||
|
||||
}
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/electro4.wav", 0.5 + flDamage * (1.0 / 400.0), ATTN_NORM, 0, 85 + gEngfuncs.pfnRandomLong( 0, 0x1f ) );
|
||||
|
||||
while (flDamage > 10 && nMaxHits > 0)
|
||||
{
|
||||
nMaxHits--;
|
||||
|
||||
gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true );
|
||||
|
||||
// Store off the old count
|
||||
gEngfuncs.pEventAPI->EV_PushPMStates();
|
||||
|
||||
// Now add in all of the players.
|
||||
gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 );
|
||||
|
||||
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
|
||||
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecDest, PM_STUDIO_BOX, -1, &tr );
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PopPMStates();
|
||||
|
||||
if ( tr.allsolid )
|
||||
break;
|
||||
|
||||
if ( EV_IsLocal( idx ) )
|
||||
{
|
||||
// Add muzzle flash to current weapon model
|
||||
EV_MuzzleFlash();
|
||||
}
|
||||
fFirstBeam = 0;
|
||||
|
||||
gEngfuncs.pEfxAPI->R_BeamEntPoint(
|
||||
idx | 0x1000,
|
||||
tr.endpos,
|
||||
m_iBeam,
|
||||
0.3,
|
||||
3.0,
|
||||
0.5, // noise
|
||||
1.0,
|
||||
55,
|
||||
0,
|
||||
0,
|
||||
0.5, 1, 0//180, 255, 96
|
||||
);
|
||||
|
||||
gEngfuncs.pEfxAPI->R_BeamEntPoint(
|
||||
idx | 0x2000,
|
||||
tr.endpos,
|
||||
m_iBeam,
|
||||
0.3,
|
||||
3.0,
|
||||
0.5, // noise
|
||||
1.0,
|
||||
55,
|
||||
0,
|
||||
0,
|
||||
0.5, 1, 0//180, 255, 96
|
||||
);
|
||||
|
||||
pEntity = gEngfuncs.pEventAPI->EV_GetPhysent( tr.ent );
|
||||
if ( pEntity == NULL )
|
||||
break;
|
||||
|
||||
if ( pEntity->solid == SOLID_BSP )
|
||||
{
|
||||
float n;
|
||||
|
||||
pentIgnore = NULL;
|
||||
|
||||
n = -DotProduct( tr.plane.normal, forward );
|
||||
|
||||
// tunnel
|
||||
EV_HLDM_DecalGunshot( &tr, BULLET_MONSTER_12MM );
|
||||
|
||||
//gEngfuncs.pEfxAPI->R_TempSprite( tr.endpos, vec3_origin, 1.0, m_iGlow, kRenderGlow, kRenderFxNoDissipation, flDamage / 255.0, 6.0, FTENT_FADEOUT );
|
||||
|
||||
//gEngfuncs.pEfxAPI->R_FunnelSprite( tr.endpos, m_iGlow, false );
|
||||
gEngfuncs.pEfxAPI->R_SparkShower( tr.endpos );
|
||||
|
||||
// limit it to one hole punch
|
||||
if (fHasPunched)
|
||||
{
|
||||
break;
|
||||
}
|
||||
fHasPunched = 1;
|
||||
|
||||
{
|
||||
// slug doesn't punch through ever with primary
|
||||
// fire, so leave a little glowy bit and make some balls
|
||||
//gEngfuncs.pEfxAPI->R_TempSprite( tr.endpos, vec3_origin, 0.2, m_iGlow, kRenderGlow, kRenderFxNoDissipation, 200.0 / 255.0, 0.3, FTENT_FADEOUT );
|
||||
|
||||
vec3_t fwd;
|
||||
VectorAdd( tr.endpos, tr.plane.normal, fwd );
|
||||
//gEngfuncs.pEfxAPI->R_Sprite_Trail( TE_SPRITETRAIL, tr.endpos, fwd, m_iBalls, 8, 0.6, gEngfuncs.pfnRandomFloat( 10, 20 ) / 100.0, 100,
|
||||
// 255, 200 );
|
||||
}
|
||||
|
||||
flDamage = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAdd( tr.endpos, forward, vecSrc );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//======================
|
||||
// VORTI END
|
||||
//======================
|
||||
|
||||
void EV_TrainPitchAdjust( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
|
|
|
@ -88,8 +88,9 @@ int CHudHealth::VidInit( void )
|
|||
{
|
||||
m_hSprite = 0;
|
||||
|
||||
m_HUD_dmg_bio = gHUD.GetSpriteIndex( "dmg_bio" ) + 1;
|
||||
m_HUD_dmg_bio = gHUD.GetSpriteIndex( "dmg_bio" );// + 1;
|
||||
m_HUD_cross = gHUD.GetSpriteIndex( "cross" );
|
||||
m_HUD_alien = gHUD.GetSpriteIndex( "islave_health" );
|
||||
|
||||
giDmgHeight = gHUD.GetSpriteRect( m_HUD_dmg_bio ).right - gHUD.GetSpriteRect( m_HUD_dmg_bio ).left;
|
||||
giDmgWidth = gHUD.GetSpriteRect( m_HUD_dmg_bio ).bottom - gHUD.GetSpriteRect( m_HUD_dmg_bio ).top;
|
||||
|
|
|
@ -330,6 +330,7 @@ void CBasePlayerItem::Drop( void ) { }
|
|||
void CBasePlayerItem::Kill( void ) { }
|
||||
void CBasePlayerItem::Holster( int skiplocal ) { }
|
||||
void CBasePlayerItem::AttachToPlayer ( CBasePlayer *pPlayer ) { }
|
||||
void CBasePlayerItem::KeyValue( KeyValueData *pkvd ) { }
|
||||
int CBasePlayerWeapon::AddDuplicate( CBasePlayerItem *pOriginal ) { return 0; }
|
||||
int CBasePlayerWeapon::AddToPlayer( CBasePlayer *pPlayer ) { return FALSE; }
|
||||
int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) { return 0; }
|
||||
|
|
|
@ -55,6 +55,7 @@ vec3_t previousorigin;
|
|||
// HLDM Weapon placeholder entities.
|
||||
CGlock g_Glock;
|
||||
CCrowbar g_Crowbar;
|
||||
CVortiHands g_VortiHands;
|
||||
CPython g_Python;
|
||||
CMP5 g_Mp5;
|
||||
CCrossbow g_Crossbow;
|
||||
|
@ -725,6 +726,7 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
|
|||
case WEAPON_SNARK:
|
||||
pWeapon = &g_Snark;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Store pointer to our destination entity_state_t so we can get our origin, etc. from it
|
||||
|
|
|
@ -139,6 +139,33 @@ int __MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf )
|
|||
return gHUD.MsgFunc_GameMode( pszName, iSize, pbuf );
|
||||
}
|
||||
|
||||
int __MsgFunc_DecayName(const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
return gHUD.MsgFunc_DecayName( pszName, iSize, pbuf );
|
||||
}
|
||||
|
||||
int __MsgFunc_LensFlare(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
return gHUD.MsgFunc_LensFlare(pszName, iSize, pbuf );
|
||||
}
|
||||
|
||||
int __MsgFunc_AimFrame(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
return gHUD.MsgFunc_AimFrame(pszName, iSize, pbuf );
|
||||
}
|
||||
|
||||
int __MsgFunc_ChangePlr(const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
gHUD.MsgFunc_ChangePlayer(pszName, iSize, pbuf );
|
||||
return 1;
|
||||
}
|
||||
|
||||
int __MsgFunc_Camera(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
gHUD.MsgFunc_Camera( pszName, iSize, pbuf );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TFFree Command Menu
|
||||
void __CmdFunc_OpenCommandMenu( void )
|
||||
{
|
||||
|
@ -331,6 +358,8 @@ void CHud::Init( void )
|
|||
HOOK_MESSAGE( ViewMode );
|
||||
HOOK_MESSAGE( SetFOV );
|
||||
HOOK_MESSAGE( Concuss );
|
||||
HOOK_MESSAGE( Camera );
|
||||
HOOK_MESSAGE( DecayName );
|
||||
|
||||
// TFFree CommandMenu
|
||||
HOOK_COMMAND( "+commandmenu", OpenCommandMenu );
|
||||
|
@ -364,8 +393,14 @@ void CHud::Init( void )
|
|||
HOOK_MESSAGE( ResetFade );
|
||||
#endif
|
||||
|
||||
HOOK_MESSAGE( LensFlare );
|
||||
HOOK_MESSAGE( AimFrame );
|
||||
HOOK_MESSAGE( ChangePlr );
|
||||
|
||||
// VGUI Menus
|
||||
HOOK_MESSAGE( VGUIMenu );
|
||||
HOOK_MESSAGE( Notepad );
|
||||
HOOK_MESSAGE( SparePlayer );
|
||||
|
||||
CVAR_CREATE( "hud_classautokill", "1", FCVAR_ARCHIVE | FCVAR_USERINFO ); // controls whether or not to suicide immediately on TF class switch
|
||||
CVAR_CREATE( "hud_takesshots", "0", FCVAR_ARCHIVE ); // controls whether or not to automatically take screenshots at the end of a round
|
||||
|
@ -373,6 +408,8 @@ void CHud::Init( void )
|
|||
|
||||
m_iLogo = 0;
|
||||
m_iFOV = 0;
|
||||
m_iLensIndex = 0;
|
||||
m_iFrameIndex = 0;
|
||||
|
||||
CVAR_CREATE( "zoom_sensitivity_ratio", "1.2", FCVAR_ARCHIVE );
|
||||
CVAR_CREATE( "cl_autowepswitch", "1", FCVAR_ARCHIVE | FCVAR_USERINFO );
|
||||
|
@ -475,6 +512,9 @@ void CHud::VidInit( void )
|
|||
m_scrinfo.iSize = sizeof(m_scrinfo);
|
||||
GetScreenInfo( &m_scrinfo );
|
||||
|
||||
// Set HUD color
|
||||
uColor = RGB_YELLOWISH;
|
||||
|
||||
// ----------
|
||||
// Load Sprites
|
||||
// ---------
|
||||
|
@ -590,6 +630,20 @@ void CHud::VidInit( void )
|
|||
|
||||
m_iFontHeight = m_rgrcRects[m_HUD_number_0].bottom - m_rgrcRects[m_HUD_number_0].top;
|
||||
|
||||
//load sprites for lens flare effect and for selection frame
|
||||
for (int i=0;i<9;i++)
|
||||
{
|
||||
m_hsprLens[i] = NULL;
|
||||
|
||||
char szName[32];
|
||||
sprintf(szName, "sprites/lens_%d.spr",i);
|
||||
if (m_hsprLens[i] == 0)
|
||||
m_hsprLens[i] = LoadSprite(szName);
|
||||
}
|
||||
m_hsprFrame = LoadSprite("sprites/bracket.spr");
|
||||
m_iFrameSize = SPR_Width(m_hsprFrame,0);
|
||||
pFrameTexture = gEngfuncs.GetSpritePointer( m_hsprFrame );
|
||||
|
||||
m_Ammo.VidInit();
|
||||
m_Health.VidInit();
|
||||
m_Spectator.VidInit();
|
||||
|
@ -626,6 +680,46 @@ int CHud::MsgFunc_Logo( const char *pszName, int iSize, void *pbuf )
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CHud::MsgFunc_LensFlare(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
|
||||
m_iLensIndex = READ_BYTE();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHud::MsgFunc_AimFrame(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
|
||||
m_iFrameIndex = READ_BYTE();
|
||||
m_iFrameKind = READ_BYTE();
|
||||
|
||||
m_vAimFrameCoords.x = READ_COORD();
|
||||
m_vAimFrameCoords.y = READ_COORD();
|
||||
m_vAimFrameCoords.z = READ_COORD();
|
||||
|
||||
m_vAimFrameMaxs.x = READ_COORD();
|
||||
m_vAimFrameMaxs.y = READ_COORD();
|
||||
m_vAimFrameMaxs.z = READ_COORD();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHud::MsgFunc_ChangePlayer(const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
int m_iDecayId = READ_BYTE();
|
||||
|
||||
if (m_iDecayId == 1)
|
||||
uColor = RGB_SILVERISH;
|
||||
else
|
||||
uColor = RGB_YELLOWISH;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
float g_lastFOV = 0.0;
|
||||
|
||||
/*
|
||||
|
|
71
cl_dll/hud.h
71
cl_dll/hud.h
|
@ -25,6 +25,7 @@
|
|||
#define RGB_YELLOWISH 0x00FFA000 //255,160,0
|
||||
#define RGB_REDISH 0x00FF1010 //255,160,0
|
||||
#define RGB_GREENISH 0x0000A000 //0,160,0
|
||||
#define RGB_SILVERISH 0x00D4D4D4 //
|
||||
|
||||
#include "wrect.h"
|
||||
#include "cl_dll.h"
|
||||
|
@ -58,6 +59,7 @@ typedef struct cvar_s cvar_t;
|
|||
|
||||
#define HUD_ACTIVE 1
|
||||
#define HUD_INTERMISSION 2
|
||||
#define HUD_ALIEN 4
|
||||
|
||||
#define MAX_PLAYER_NAME_LENGTH 32
|
||||
|
||||
|
@ -421,6 +423,54 @@ private:
|
|||
int m_iWidth; // width of the battery innards
|
||||
};
|
||||
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
//
|
||||
|
||||
class CHudModeIcon: public CHudBase
|
||||
{
|
||||
public:
|
||||
int Init( void );
|
||||
int VidInit( void );
|
||||
int Draw(float flTime);
|
||||
void Reset( void );
|
||||
int MsgFunc_ChangeMode(const char *pszName, int iSize, void *pbuf );
|
||||
|
||||
private:
|
||||
HSPRITE m_hSpriteStand;
|
||||
HSPRITE m_hSpriteRun;
|
||||
HSPRITE m_hSpriteCrouch;
|
||||
HSPRITE m_hSpriteJump;
|
||||
HSPRITE m_hActiveSprite;
|
||||
|
||||
wrect_t *m_prcStand;
|
||||
wrect_t *m_prcRun;
|
||||
wrect_t *m_prcCrouch;
|
||||
wrect_t *m_prcJump;
|
||||
wrect_t *m_prcActiveRect;
|
||||
|
||||
int m_fMode;
|
||||
};
|
||||
|
||||
class CHudAlienCrosshair: public CHudBase
|
||||
{
|
||||
public:
|
||||
int Init( void );
|
||||
int VidInit( void );
|
||||
int Draw(float flTime);
|
||||
void Reset( void );
|
||||
int MsgFunc_AlienState(const char *pszName, int iSize, void *pbuf );
|
||||
|
||||
private:
|
||||
HSPRITE m_hCrosshair[4];
|
||||
wrect_t *m_prcCrosshair[4];
|
||||
|
||||
HSPRITE m_hActiveSprite;
|
||||
wrect_t *m_prcActiveRect;
|
||||
|
||||
int m_iState;
|
||||
};
|
||||
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
//
|
||||
|
@ -542,7 +592,16 @@ private:
|
|||
int m_iSpriteCountAllRes;
|
||||
float m_flMouseSensitivity;
|
||||
int m_iConcussionEffect;
|
||||
HSPRITE m_hsprLens[9];//lens flare sprite data
|
||||
HSPRITE m_hsprFrame;
|
||||
int m_iLensIndex;
|
||||
int m_iFrameIndex;//index of entity to draw frame around
|
||||
int m_iFrameKind; //frame hint index in names array
|
||||
int m_iFrameSize;
|
||||
const model_s *pFrameTexture;//frame texture for tri_api
|
||||
|
||||
//vec3_t m_vAimFrameCoords; //for selection frame
|
||||
//vec3_t m_vAimFrameMaxs; //for selection frame
|
||||
public:
|
||||
HSPRITE m_hsprCursor;
|
||||
float m_flTime; // the current client time
|
||||
|
@ -557,6 +616,17 @@ public:
|
|||
int m_iRes;
|
||||
cvar_t *m_pCvarStealMouse;
|
||||
cvar_t *m_pCvarDraw;
|
||||
Vector m_vecCamPos; // CAM
|
||||
int m_iCamMode; // CAM
|
||||
unsigned long uColor;
|
||||
|
||||
// TEXTURES
|
||||
unsigned int g_uiScreenTex;
|
||||
unsigned int g_uiGlowTex;
|
||||
unsigned int g_uiCameraTex;
|
||||
|
||||
vec3_t m_vAimFrameCoords; //for selection frame
|
||||
vec3_t m_vAimFrameMaxs; //for selection frame
|
||||
|
||||
int m_iFontHeight;
|
||||
int DrawHudNumber( int x, int y, int iFlags, int iNumber, int r, int g, int b );
|
||||
|
@ -635,6 +705,7 @@ public:
|
|||
int m_iWeaponBits;
|
||||
int m_fPlayerDead;
|
||||
int m_iIntermission;
|
||||
bool m_bAlienMode;
|
||||
|
||||
// sprite indexes
|
||||
int m_HUD_number_0;
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
/***
|
||||
*
|
||||
* (C) 2008 Vyacheslav Dzhura
|
||||
*
|
||||
****/
|
||||
//
|
||||
// hud_msg.cpp
|
||||
//
|
||||
|
|
|
@ -94,6 +94,80 @@ void CHud::Think( void )
|
|||
}
|
||||
}
|
||||
|
||||
void ReturnFrameHint(char* szHint,int Id)
|
||||
{
|
||||
switch(Id){
|
||||
case 0:
|
||||
sprintf(szHint,"Button");
|
||||
break;
|
||||
case 1:
|
||||
sprintf(szHint,"Object");
|
||||
break;
|
||||
case 2:
|
||||
sprintf(szHint,"Item");
|
||||
break;
|
||||
case 3:
|
||||
sprintf(szHint,"File");
|
||||
break;
|
||||
case 4:
|
||||
sprintf(szHint,"Documents");
|
||||
break;
|
||||
case 5:
|
||||
sprintf(szHint,"Book");
|
||||
break;
|
||||
case 6:
|
||||
sprintf(szHint,"Monitor");
|
||||
break;
|
||||
case 7:
|
||||
sprintf(szHint,"Computer");
|
||||
break;
|
||||
case 8:
|
||||
sprintf(szHint,"Compact Disc");
|
||||
break;
|
||||
case 9:
|
||||
sprintf(szHint,"Extinguisher");
|
||||
break;
|
||||
case 10:
|
||||
sprintf(szHint,"Security Card");
|
||||
break;
|
||||
case 11:
|
||||
sprintf(szHint,"Key");
|
||||
break;
|
||||
case 12:
|
||||
sprintf(szHint,"Syringe");
|
||||
break;
|
||||
case 13:
|
||||
sprintf(szHint,"Cleansuit");
|
||||
break;
|
||||
case 14:
|
||||
sprintf(szHint,"Wrench");
|
||||
break;
|
||||
case 15:
|
||||
sprintf(szHint,"Retinal Scanner");
|
||||
break;
|
||||
case 16:
|
||||
sprintf(szHint,"Health Charger");
|
||||
break;
|
||||
case 17:
|
||||
sprintf(szHint,"HEV Charger");
|
||||
break;
|
||||
default:
|
||||
sprintf(szHint,"Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
void DrawFrameCorner(int x,int y,int u1,int u2,int u3,int u4,int v1,int v2,int v3,int v4)
|
||||
{
|
||||
gEngfuncs.pTriAPI->TexCoord2f( u1, v1 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( x, y, 0.0 );
|
||||
gEngfuncs.pTriAPI->TexCoord2f( u2, v2 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( x, y+g_iFrameSize, 0.0 );
|
||||
gEngfuncs.pTriAPI->TexCoord2f( u3, v3 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( x+g_iFrameSize, y+g_iFrameSize, 0.0 );
|
||||
gEngfuncs.pTriAPI->TexCoord2f( u4, v4 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( x+g_iFrameSize, y, 0.0 );
|
||||
}
|
||||
|
||||
// Redraw
|
||||
// step through the local data, placing the appropriate graphics & text as appropriate
|
||||
// returns 1 if they've changed, 0 otherwise
|
||||
|
@ -170,6 +244,12 @@ int CHud::Redraw( float flTime, int intermission )
|
|||
if( pList->p->m_iFlags & HUD_INTERMISSION )
|
||||
pList->p->Draw( flTime );
|
||||
}
|
||||
} else
|
||||
{ // alien mode!!!
|
||||
if ( pList->p->m_iFlags & HUD_ALIEN )
|
||||
if ( (pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL) )
|
||||
pList->p->Draw( flTime );
|
||||
}
|
||||
|
||||
pList = pList->pNext;
|
||||
}
|
||||
|
@ -196,6 +276,137 @@ int CHud::Redraw( float flTime, int intermission )
|
|||
SPR_DrawAdditive( i, x, y, NULL );
|
||||
}
|
||||
|
||||
// draw selection frame around entity
|
||||
if (m_iFrameIndex !=0)
|
||||
{
|
||||
vec3_t v_center, v_maxs;
|
||||
|
||||
gEngfuncs.pTriAPI->WorldToScreen(m_vAimFrameCoords,v_center);
|
||||
gEngfuncs.pTriAPI->WorldToScreen(m_vAimFrameMaxs,v_maxs);
|
||||
|
||||
v_center[0] = XPROJECT(v_center[0]);
|
||||
v_center[1] = YPROJECT(v_center[1]);
|
||||
v_center[2] = 0.0f;
|
||||
v_maxs[0] = XPROJECT(v_maxs[0]);
|
||||
v_maxs[1] = YPROJECT(v_maxs[1]);
|
||||
v_maxs[2] = 0.0f;
|
||||
|
||||
g_iFrameSize = m_iFrameSize;
|
||||
|
||||
gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)pFrameTexture, 0 );
|
||||
gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd );
|
||||
gEngfuncs.pTriAPI->Begin( TRI_QUADS );
|
||||
|
||||
if (v_center[0]>v_maxs[0])
|
||||
{
|
||||
//right bottom
|
||||
DrawFrameCorner(v_center[0],v_center[1],1,1,0,0,1,0,0,1);
|
||||
//left bottom
|
||||
DrawFrameCorner(v_center[0]-(v_center[0]-v_maxs[0]),v_center[1],1,0,0,1,0,0,1,1);
|
||||
//left up
|
||||
DrawFrameCorner(v_maxs[0], v_maxs[1],0,0,1,1,0,1,1,0);
|
||||
//left right
|
||||
DrawFrameCorner(v_maxs[0]+(v_center[0]-v_maxs[0]),v_maxs[1],0,1,1,0,1,1,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//right bottom
|
||||
DrawFrameCorner(v_center[0],v_center[1],1,0,0,1,0,0,1,1);
|
||||
//left bottom
|
||||
DrawFrameCorner(v_center[0]-(v_center[0]-v_maxs[0]),v_center[1],1,1,0,0,1,0,0,1);
|
||||
//left up
|
||||
DrawFrameCorner(v_maxs[0],v_maxs[1],0,1,1,0,1,1,0,0);
|
||||
//left right
|
||||
DrawFrameCorner(v_maxs[0]+(v_center[0]-v_maxs[0]),v_maxs[1],0,0,1,1,0,1,1,0);
|
||||
}
|
||||
gEngfuncs.pTriAPI->End();
|
||||
gEngfuncs.pTriAPI->RenderMode( kRenderNormal );
|
||||
|
||||
//to make that working, modify in decay.dll player.cpp blank message value of frame kind to -1
|
||||
//if (!m_iFrameKind==-1)
|
||||
if (m_iFrameKind != -1)
|
||||
{
|
||||
char szMes[25];
|
||||
ReturnFrameHint(szMes,m_iFrameKind);
|
||||
gHUD.DrawHudString( v_maxs[0]+5, v_maxs[1]+4, ScreenWidth, szMes, 255, 180, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
char szMes[255];
|
||||
if ( m_bAlienMode )
|
||||
sprintf( szMes, "Alien slave (vortigaunt) mode on" );
|
||||
else
|
||||
sprintf( szMes, "Normal mode" );
|
||||
*/
|
||||
|
||||
//ReturnFrameHint(szMes,m_iFrameKind);
|
||||
// gHUD.DrawHudString( 10, 10, 512, szMes, 255, 180, 0 );
|
||||
|
||||
//draw sun
|
||||
if (m_iLensIndex !=0)
|
||||
{
|
||||
vec3_t screen,ors;
|
||||
float tN[9];
|
||||
tN[0]=1.0;
|
||||
tN[1]=0.8;
|
||||
tN[2]=0.7;
|
||||
tN[3]=0.5;
|
||||
tN[4]=0.4;
|
||||
tN[5]=0.25;
|
||||
tN[6]=0.1;
|
||||
tN[7]=-0.1;
|
||||
tN[8]=-0.2;
|
||||
|
||||
cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_iLensIndex);
|
||||
if (ent)
|
||||
{
|
||||
vec3_t forward, right, up;
|
||||
AngleVectors ( ent->angles, forward, right, up );//get f/r/u vectors
|
||||
|
||||
pmtrace_t tr;
|
||||
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
|
||||
gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)&v_origin, v_origin + (forward+up)/2 * 8192, PM_GLASS_IGNORE, -1, &tr );
|
||||
//pmtrace_t tr = *(gEngfuncs.PM_TraceLine( (float *)&v_origin, v_origin + (forward+up)/2 * 8192, 0, 2, -1 )); // PM_GLASS_IGNORE
|
||||
if (gEngfuncs.PM_PointContents( tr.endpos, NULL )!=CONTENTS_SKY)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!gEngfuncs.pTriAPI->WorldToScreen(tr.endpos,ors))
|
||||
{
|
||||
int LWidth, LHeight;
|
||||
LWidth = NULL;
|
||||
LHeight = NULL;
|
||||
|
||||
ors[0] = XPROJECT(ors[0]);
|
||||
ors[1] = YPROJECT(ors[1]);
|
||||
ors[2] = 0.0f;
|
||||
|
||||
if (ors[0]<0 || ors[0]>ScreenWidth) return 0;
|
||||
if (ors[1]<0 || ors[1]>ScreenHeight) return 0;
|
||||
|
||||
for (int i=0;i<9;i++)
|
||||
{
|
||||
if (i!=0)
|
||||
SPR_Set(m_hsprLens[i], 50, 50, 50); //was 250
|
||||
else
|
||||
SPR_Set(m_hsprLens[i], 100, 100, 100); //make sun brighter then other lens
|
||||
LWidth = SPR_Width(m_hsprLens[i],0);
|
||||
LHeight = SPR_Height(m_hsprLens[i],0);
|
||||
|
||||
screen=ors;
|
||||
screen[0] = ScreenWidth/2+(screen[0]-ScreenWidth/2)*tN[i];
|
||||
screen[1] = ScreenHeight/2+(screen[1]-ScreenHeight/2)*tN[i];
|
||||
screen[0] = screen[0]-(LWidth/2);
|
||||
screen[1] = screen[1]-(LHeight/2);
|
||||
|
||||
SPR_DrawAdditive(0, screen[0],screen[1], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if( g_iVisibleMouse )
|
||||
{
|
||||
|
|
|
@ -1106,8 +1106,9 @@ float already_chosen_map;
|
|||
#define MENU_CLASSHELP 6
|
||||
#define MENU_CLASSHELP2 7
|
||||
#define MENU_REPEATHELP 8
|
||||
|
||||
#define MENU_SPECHELP 9
|
||||
#define MENU_NOTEPAD 10
|
||||
#define MENU_SPAREPLAYERWINDOW 11
|
||||
|
||||
|
||||
#define MENU_SPY 12
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
// Triangle rendering, if any
|
||||
|
||||
#include <windows.h>
|
||||
//#include <gl/gl.h>
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
|
||||
// Triangle rendering apis are in gEngfuncs.pTriAPI
|
||||
|
||||
//#include "com_model.h"
|
||||
#include "const.h"
|
||||
#include "entity_state.h"
|
||||
#include "cl_entity.h"
|
||||
|
|
|
@ -269,7 +269,7 @@ CSchemeManager::CSchemeManager( int xRes, int yRes )
|
|||
}
|
||||
if ( !pScheme->fontName[0] )
|
||||
{
|
||||
strcpy( pScheme->fontName, "Arial" );
|
||||
strcpy( pScheme->fontName, "Trebuchet MS" ); // Vyacheslav Dzhura: was Arial
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ buildDefaultFont:
|
|||
{
|
||||
currentScheme = 0;
|
||||
strcpy( tmpSchemes[0].schemeName, "Default Scheme" );
|
||||
strcpy( tmpSchemes[0].fontName, "Arial" );
|
||||
strcpy( tmpSchemes[0].fontName, "Trebuchet MS" ); //Hoaxer: was Arial
|
||||
tmpSchemes[0].fontSize = 0;
|
||||
tmpSchemes[0].fgColor[0] = tmpSchemes[0].fgColor[1] = tmpSchemes[0].fgColor[2] = tmpSchemes[0].fgColor[3] = 255;
|
||||
tmpSchemes[0].armedFgColor[0] = tmpSchemes[0].armedFgColor[1] = tmpSchemes[0].armedFgColor[2] = tmpSchemes[0].armedFgColor[3] = 255;
|
||||
|
|
|
@ -513,6 +513,8 @@ TeamFortressViewport::TeamFortressViewport( int x, int y, int wide, int tall ) :
|
|||
m_pSpectatorPanel = NULL;
|
||||
m_pCurrentMenu = NULL;
|
||||
m_pCurrentCommandMenu = NULL;
|
||||
m_pNotepad = NULL;
|
||||
m_pSparePlayerWindow = NULL;
|
||||
|
||||
Initialize();
|
||||
addInputSignal( new CViewPortInputHandler );
|
||||
|
@ -567,6 +569,8 @@ TeamFortressViewport::TeamFortressViewport( int x, int y, int wide, int tall ) :
|
|||
App::getInstance()->setScheme( pScheme );
|
||||
|
||||
// VGUI MENUS
|
||||
CreateNotepad();
|
||||
CreateSparePlayerWindow();
|
||||
CreateTeamMenu();
|
||||
CreateClassMenu();
|
||||
CreateSpectatorMenu();
|
||||
|
@ -618,6 +622,14 @@ void TeamFortressViewport::Initialize( void )
|
|||
// Spectator menu doesn't need initializing
|
||||
m_pSpectatorPanel->setVisible( false );
|
||||
}
|
||||
if (m_pNotepad)
|
||||
{
|
||||
m_pNotepad->Initialize();
|
||||
}
|
||||
if (m_pSparePlayerWindow)
|
||||
{
|
||||
m_pSparePlayerWindow->Initialize();
|
||||
}
|
||||
|
||||
// Make sure all menus are hidden
|
||||
HideVGUIMenu();
|
||||
|
@ -1461,6 +1473,29 @@ CMenuPanel *TeamFortressViewport::CreateTextWindow( int iTextToShow )
|
|||
|
||||
//================================================================
|
||||
// VGUI Menus
|
||||
void TeamFortressViewport::DisplayNotepad( char* szText, int iTitle )
|
||||
{
|
||||
// Don't open window in demo playback
|
||||
if ( gEngfuncs.pDemoAPI->IsPlayingback() )
|
||||
return;
|
||||
|
||||
if (m_pCurrentMenu)
|
||||
{
|
||||
CMenuPanel *pMenu = m_pCurrentMenu;
|
||||
while (pMenu != NULL)
|
||||
{
|
||||
if (pMenu->GetMenuID() == MENU_NOTEPAD )
|
||||
return;
|
||||
pMenu = pMenu->GetNextMenu();
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(m_pNotepad->szText, szText);
|
||||
sprintf(m_pNotepad->szTitle,"#NotepadHeader%i",iTitle);
|
||||
|
||||
ShowNotepad();
|
||||
}
|
||||
|
||||
void TeamFortressViewport::ShowVGUIMenu( int iMenu )
|
||||
{
|
||||
CMenuPanel *pNewMenu = NULL;
|
||||
|
@ -1513,6 +1548,10 @@ void TeamFortressViewport::ShowVGUIMenu( int iMenu )
|
|||
case MENU_CLASS:
|
||||
pNewMenu = ShowClassMenu();
|
||||
break;
|
||||
//case MENU_NOTEPAD:
|
||||
// m_pNotepad->Reset();
|
||||
// pNewMenu = m_pNotepad;
|
||||
// break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -1613,6 +1652,63 @@ void TeamFortressViewport::CreateTeamMenu()
|
|||
m_pTeamMenu->setVisible( false );
|
||||
}
|
||||
|
||||
//======================================================================================
|
||||
// NOTEPAD
|
||||
//======================================================================================
|
||||
// Bring up the Notepad
|
||||
void TeamFortressViewport::ShowNotepad()
|
||||
{
|
||||
if (m_pNotepad)
|
||||
{
|
||||
m_pNotepad->SetMenuID( MENU_NOTEPAD );
|
||||
m_pNotepad->SetActive( true );
|
||||
m_pNotepad->setParent( this );
|
||||
|
||||
m_pCurrentMenu = m_pNotepad;
|
||||
m_pCurrentMenu->Reset();
|
||||
m_pCurrentMenu->Open();
|
||||
}
|
||||
UpdateCursorState();
|
||||
}
|
||||
|
||||
void TeamFortressViewport::ShowSparePlayerWindow()
|
||||
{
|
||||
if (m_pSparePlayerWindow)
|
||||
{
|
||||
m_pSparePlayerWindow->SetMenuID( MENU_SPAREPLAYERWINDOW );
|
||||
m_pSparePlayerWindow->SetActive( true );
|
||||
m_pSparePlayerWindow->setParent( this );
|
||||
|
||||
m_pCurrentMenu = m_pSparePlayerWindow;
|
||||
m_pCurrentMenu->Reset();
|
||||
m_pCurrentMenu->Open();
|
||||
}
|
||||
UpdateCursorState();
|
||||
}
|
||||
|
||||
bool TeamFortressViewport::IsNotepadVisible( void )
|
||||
{
|
||||
if (m_pNotepad)
|
||||
return m_pNotepad->isVisible();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TeamFortressViewport::CreateNotepad()
|
||||
{
|
||||
// Create the panel
|
||||
m_pNotepad = new CNotepad(100, false, 0, 0, ScreenWidth, ScreenHeight);
|
||||
m_pNotepad->setParent( this );
|
||||
m_pNotepad->setVisible( false );
|
||||
}
|
||||
|
||||
void TeamFortressViewport::CreateSparePlayerWindow( void )
|
||||
{
|
||||
m_pSparePlayerWindow = new CSparePlayerWindow(100, false, 0, 0, ScreenWidth, ScreenHeight);
|
||||
m_pSparePlayerWindow->setParent( this );
|
||||
m_pSparePlayerWindow->setVisible( false );
|
||||
}
|
||||
|
||||
//======================================================================================
|
||||
// CLASS MENU
|
||||
//======================================================================================
|
||||
|
@ -1990,6 +2086,33 @@ int TeamFortressViewport::MsgFunc_VGUIMenu( const char *pszName, int iSize, void
|
|||
return 1;
|
||||
}
|
||||
|
||||
int TeamFortressViewport::MsgFunc_Notepad( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
|
||||
char* szText;
|
||||
int iTitle;
|
||||
|
||||
szText = READ_STRING();
|
||||
iTitle = READ_BYTE();
|
||||
|
||||
DisplayNotepad( szText, iTitle );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TeamFortressViewport::MsgFunc_SparePlayer( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
|
||||
int iPlayerId;
|
||||
|
||||
iPlayerId = READ_BYTE();
|
||||
ShowSparePlayerWindow();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TeamFortressViewport::MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
if( m_iGotAllMOTD )
|
||||
|
|
|
@ -575,6 +575,12 @@ public:
|
|||
void HideScoreBoard( void );
|
||||
bool IsScoreBoardVisible( void );
|
||||
|
||||
void ShowNotepad( void );
|
||||
bool IsNotepadVisible( void );
|
||||
void DisplayNotepad( char* szText, int iTitle );
|
||||
|
||||
void ShowSparePlayerWindow( void );
|
||||
|
||||
bool AllowedToPrintText( void );
|
||||
|
||||
void ShowVGUIMenu( int iMenu );
|
||||
|
@ -634,6 +640,8 @@ public:
|
|||
CClassMenuPanel *m_pClassMenu;
|
||||
ScorePanel *m_pScoreBoard;
|
||||
SpectatorPanel *m_pSpectatorPanel;
|
||||
CNotepad *m_pNotepad;
|
||||
CSparePlayerWindow *m_pSparePlayerWindow;
|
||||
char m_szServerName[ MAX_SERVERNAME_LENGTH ];
|
||||
};
|
||||
|
||||
|
@ -1661,6 +1669,48 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class CSparePlayerWindow : public CMenuPanel
|
||||
{
|
||||
public:
|
||||
CTransparentPanel *m_pWindow;
|
||||
TextPanel *m_pMemo;
|
||||
Label *m_pTitle;
|
||||
CImageLabel *m_pImage;
|
||||
|
||||
char szText[256];
|
||||
char szTitle[256];
|
||||
public:
|
||||
CSparePlayerWindow(int iTrans, int iRemoveMe, int x,int y,int wide,int tall);
|
||||
|
||||
virtual bool SlotInput( int iSlot );
|
||||
virtual void Open( void );
|
||||
virtual void Update( void );
|
||||
|
||||
virtual void Initialize( void );
|
||||
};
|
||||
|
||||
class CNotepad : public CMenuPanel
|
||||
{
|
||||
public:
|
||||
ScrollPanel *m_pScrollPanel;
|
||||
CTransparentPanel *m_pNotepadWindow;
|
||||
TextPanel *m_pBriefing;
|
||||
CommandButton *m_pCancelButton;
|
||||
Label *m_pTitle;
|
||||
CImageLabel *m_pImage;
|
||||
|
||||
char szText[256];
|
||||
char szTitle[256];
|
||||
public:
|
||||
CNotepad(int iTrans, int iRemoveMe, int x,int y,int wide,int tall);
|
||||
|
||||
virtual bool SlotInput( int iSlot );
|
||||
virtual void Open( void );
|
||||
virtual void Update( void );
|
||||
|
||||
virtual void Initialize( void );
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Specific Menus to handle old HUD sections
|
||||
class CHealthPanel : public DragNDropPanel
|
||||
|
|
|
@ -63,6 +63,7 @@ void VectorAngles( const float *forward, float *angles );
|
|||
#include "com_model.h"
|
||||
|
||||
extern engine_studio_api_t IEngineStudio;
|
||||
extern void GrabCameraTexture();
|
||||
|
||||
/*
|
||||
The view is allowed to move slightly from it's true position for bobbing,
|
||||
|
@ -435,6 +436,15 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams )
|
|||
// view is the weapon model (only visible from inside body)
|
||||
view = gEngfuncs.GetViewModel();
|
||||
|
||||
//SKY START
|
||||
//LRC - don't show weapon models when we're drawing the sky.
|
||||
if (gHUD.m_iCamMode == CAM_ON)
|
||||
{
|
||||
savedviewmodel = view->model;
|
||||
view->model = NULL;
|
||||
}
|
||||
//SKY END
|
||||
|
||||
// transform the view offset by the model's matrix to get the offset from
|
||||
// model origin for the view
|
||||
bob = V_CalcBob( pparams );
|
||||
|
@ -780,6 +790,18 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams )
|
|||
lasttime = pparams->time;
|
||||
|
||||
v_origin = pparams->vieworg;
|
||||
|
||||
// SKY START
|
||||
// LRC - override the view position if we're drawing a sky, rather than the player's view
|
||||
if (gHUD.m_iCamMode == CAM_ON && pparams->nextView == 0)
|
||||
{
|
||||
pparams->vieworg[0] = gHUD.m_vecCamPos.x;
|
||||
pparams->vieworg[1] = gHUD.m_vecCamPos.y;
|
||||
pparams->vieworg[2] = gHUD.m_vecCamPos.z;
|
||||
//pparams->viewangles[0]
|
||||
pparams->nextView = 1;
|
||||
}
|
||||
// SKY END
|
||||
}
|
||||
|
||||
void V_SmoothInterpolateAngles( float * startAngle, float * endAngle, float * finalAngle, float degreesPerSec )
|
||||
|
|
|
@ -36,9 +36,11 @@
|
|||
#define BARNEY_AE_SHOOT ( 3 )
|
||||
#define BARNEY_AE_HOLSTER ( 4 )
|
||||
|
||||
#define GUN_GROUP 1
|
||||
|
||||
#define BARNEY_BODY_GUNHOLSTERED 0
|
||||
#define BARNEY_BODY_GUNDRAWN 1
|
||||
#define BARNEY_BODY_GUNGONE 2
|
||||
#define BARNEY_BODY_GUNDRAWN 1 * 3 // * 3 for Decay
|
||||
#define BARNEY_BODY_GUNGONE 2 * 3 // because of LODS
|
||||
|
||||
class CBarney : public CTalkMonster
|
||||
{
|
||||
|
@ -406,7 +408,8 @@ void CBarney::Spawn()
|
|||
m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
pev->body = 0; // gun in holster
|
||||
//pev->body = 0; // gun in holster
|
||||
SetBodygroup( GUN_GROUP, 0 );
|
||||
m_fGunDrawn = FALSE;
|
||||
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
|
||||
|
|
|
@ -156,6 +156,7 @@ void CMultiSource::KeyValue( KeyValueData *pkvd )
|
|||
}
|
||||
|
||||
#define SF_MULTI_INIT 1
|
||||
#define SF_MULTI_NO_TOGGLE 2
|
||||
|
||||
void CMultiSource::Spawn()
|
||||
{
|
||||
|
@ -964,6 +965,7 @@ public:
|
|||
vec3_t m_start;
|
||||
vec3_t m_end;
|
||||
int m_sounds;
|
||||
string_t m_iszEndLockTarget;
|
||||
};
|
||||
|
||||
TYPEDESCRIPTION CMomentaryRotButton::m_SaveData[] =
|
||||
|
@ -974,6 +976,7 @@ TYPEDESCRIPTION CMomentaryRotButton::m_SaveData[] =
|
|||
DEFINE_FIELD( CMomentaryRotButton, m_start, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( CMomentaryRotButton, m_end, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( CMomentaryRotButton, m_sounds, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMomentaryRotButton, m_iszEndLockTarget, FIELD_STRING ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CMomentaryRotButton, CBaseToggle )
|
||||
|
@ -1028,6 +1031,11 @@ void CMomentaryRotButton::KeyValue( KeyValueData *pkvd )
|
|||
m_sounds = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "endlocktarget"))
|
||||
{
|
||||
m_iszEndLockTarget = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseToggle::KeyValue( pkvd );
|
||||
}
|
||||
|
@ -1042,6 +1050,14 @@ void CMomentaryRotButton::PlaySound( void )
|
|||
// current, not future position.
|
||||
void CMomentaryRotButton::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
// Vyacheslav Dzhura: in Decay there are momentary buttons with MASTER field
|
||||
if (!UTIL_IsMasterTriggered(m_sMaster, pActivator))
|
||||
{
|
||||
// play button locked sound
|
||||
// PlayLockSounds(pev, &m_ls, TRUE, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
pev->ideal_yaw = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles, m_start ) / m_flMoveDistance;
|
||||
|
||||
UpdateAllButtons( pev->ideal_yaw, 1 );
|
||||
|
@ -1092,6 +1108,19 @@ void CMomentaryRotButton::UpdateSelf( float value )
|
|||
{
|
||||
pev->avelocity = g_vecZero;
|
||||
pev->angles = m_end;
|
||||
|
||||
// Vyacheslav Dzhura: off the button if we have locked target specified
|
||||
/* if (!FStringNull( m_iszEndLockTarget ))
|
||||
{
|
||||
//CBaseEntity *m_pGoalEnt;
|
||||
//m_pGoalEnt = UTIL_FindEntityByTargetname( NULL, STRING( m_iszEndLockTarget ) );
|
||||
//if (m_pGoalEnt)
|
||||
//{
|
||||
FireTargets(STRING( m_iszEndLockTarget ), this, this, USE_TOGGLE, 0);
|
||||
SetThink( Off );
|
||||
//}
|
||||
}*/
|
||||
|
||||
return;
|
||||
}
|
||||
else if( m_direction < 0 && value <= 0.0f )
|
||||
|
@ -1145,6 +1174,8 @@ void CMomentaryRotButton::Off( void )
|
|||
}
|
||||
else
|
||||
SetThink( NULL );
|
||||
|
||||
// if (m_flMoveDistance
|
||||
}
|
||||
|
||||
void CMomentaryRotButton::Return( void )
|
||||
|
|
|
@ -93,6 +93,8 @@ typedef void(CBaseEntity::*BASEPTR)( void );
|
|||
typedef void(CBaseEntity::*ENTITYFUNCPTR)( CBaseEntity *pOther );
|
||||
typedef void(CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
extern BOOL g_startSuit;
|
||||
|
||||
// For CLASSIFY
|
||||
#define CLASS_NONE 0
|
||||
#define CLASS_MACHINE 1
|
||||
|
@ -118,6 +120,7 @@ class CBasePlayerItem;
|
|||
class CSquadMonster;
|
||||
|
||||
#define SF_NORESPAWN ( 1 << 30 )// !!!set this bit on guns and stuff that should never respawn.
|
||||
#define SF_SPECIFICPLAYER 256 // Decay's flag which indicates that trigger should check player activator's index
|
||||
|
||||
//
|
||||
// EHANDLE. Safe way to point to CBaseEntities who may die between frames
|
||||
|
@ -414,7 +417,7 @@ void PlayLockSounds( entvars_t *pev, locksound_t *pls, int flocked, int fbutton
|
|||
// MultiSouce
|
||||
//
|
||||
|
||||
#define MAX_MULTI_TARGETS 16 // maximum number of targets a single multi_manager entity may be assigned.
|
||||
#define MAX_MULTI_TARGETS 32 // was 16 - maximum number of targets a single multi_manager entity may be assigned.
|
||||
#define MS_MAX_TARGETS 32
|
||||
|
||||
class CMultiSource : public CPointEntity
|
||||
|
@ -523,6 +526,8 @@ public:
|
|||
Vector m_vecFinalDest;
|
||||
Vector m_vecFinalAngle;
|
||||
|
||||
int m_iPlayerIndex; // Decay's player index
|
||||
|
||||
int m_bitsDamageInflict; // DMG_ damage type that the door or tigger does
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
|
@ -797,5 +802,7 @@ public:
|
|||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
|
||||
bool m_bSlaveCoop;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -53,6 +53,8 @@ extern cvar_t allow_spectators;
|
|||
extern cvar_t multibyte_only;
|
||||
|
||||
extern int g_teamplay;
|
||||
BOOL botadded = false;
|
||||
extern bool bSlaveCoop;
|
||||
|
||||
void LinkUserMessages( void );
|
||||
|
||||
|
@ -82,6 +84,43 @@ called when a player connects to a server
|
|||
*/
|
||||
BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] )
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
// check if this is NOT a bot joining the server...
|
||||
if (strcmp(pszAddress, "127.0.0.1") != 0)
|
||||
{
|
||||
// don't try to add bots for 30 seconds, give client time to get added
|
||||
bot_check_time = gpGlobals->time + 30.0;
|
||||
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
if (bot_respawn[i].is_used) // count the number of bots in use
|
||||
count++;
|
||||
}
|
||||
|
||||
// if there are currently more than the minimum number of bots running
|
||||
// then kick one of the bots off the server...
|
||||
if ((min_bots != 0) && (count > min_bots))
|
||||
{
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
if (bot_respawn[i].is_used) // is this slot used?
|
||||
{
|
||||
char cmd[40];
|
||||
|
||||
sprintf(cmd, "kick \"%s\"\n", bot_respawn[i].name);
|
||||
|
||||
bot_respawn[i].state = BOT_IDLE;
|
||||
|
||||
SERVER_COMMAND(cmd); // kick the bot using (kick "name")
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return g_pGameRules->ClientConnected( pEntity, pszName, pszAddress, szRejectReason );
|
||||
|
||||
// a client connecting during an intermission can cause problems
|
||||
|
@ -690,11 +729,14 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer )
|
|||
}
|
||||
else
|
||||
{
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%i>\" changed name to \"%s\"\n",
|
||||
// TODO: crashes here when changing name during gameplay
|
||||
UTIL_LogPrintf( "\"%s\" changed name to \"%s\"\n",
|
||||
//UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n",
|
||||
STRING( pEntity->v.netname ),
|
||||
GETPLAYERUSERID( pEntity ),
|
||||
GETPLAYERAUTHID( pEntity ),
|
||||
GETPLAYERUSERID( pEntity ),
|
||||
// GETPLAYERUSERID( pEntity ),
|
||||
// GETPLAYERAUTHID( pEntity ),
|
||||
//GETPLAYERUSERID( pEntity ),
|
||||
// g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ),
|
||||
g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) );
|
||||
}
|
||||
}
|
||||
|
@ -947,7 +989,7 @@ const char *GetGameDescription()
|
|||
if( g_pGameRules ) // this function may be called before the world has spawned, and the game rules initialized
|
||||
return g_pGameRules->GetGameDescription();
|
||||
else
|
||||
return "Half-Life";
|
||||
return "Decay";
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -579,6 +579,9 @@ void CBaseMonster::Killed( entvars_t *pevAttacker, int iGib )
|
|||
// Make sure this condition is fired too (TakeDamage breaks out before this happens on death)
|
||||
SetConditions( bits_COND_LIGHT_DAMAGE );
|
||||
|
||||
// DECAY STATS: tell game rules about killed monster
|
||||
g_pGameRules->MonsterKilled( pevAttacker, &this->edict()->v );
|
||||
|
||||
// tell owner ( if any ) that we're dead.This is mostly for MonsterMaker functionality.
|
||||
CBaseEntity *pOwner = CBaseEntity::Instance( pev->owner );
|
||||
if( pOwner )
|
||||
|
|
1081
dlls/effects.cpp
1081
dlls/effects.cpp
File diff suppressed because it is too large
Load Diff
|
@ -59,6 +59,7 @@ const char *CBreakable::pSpawnObjects[] =
|
|||
"weapon_satchel", // 19
|
||||
"weapon_snark", // 20
|
||||
"weapon_hornetgun", // 21
|
||||
"weapon_displacer", // 22
|
||||
};
|
||||
|
||||
void CBreakable::KeyValue( KeyValueData* pkvd )
|
||||
|
|
|
@ -32,6 +32,7 @@ DLL_GLOBAL CGameRules *g_pGameRules = NULL;
|
|||
extern DLL_GLOBAL BOOL g_fGameOver;
|
||||
extern int gmsgDeathMsg; // client dll messages
|
||||
extern int gmsgMOTD;
|
||||
extern bool bDecay;
|
||||
|
||||
int g_teamplay = 0;
|
||||
|
||||
|
|
|
@ -252,6 +252,13 @@ public:
|
|||
// Teamplay stuff
|
||||
virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";};
|
||||
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
|
||||
|
||||
// Decay stats
|
||||
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 ) {};
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
|
@ -355,6 +362,13 @@ public:
|
|||
// Immediately end a multiplayer game
|
||||
virtual void EndMultiplayerGame( void ) { GoToIntermission(); }
|
||||
|
||||
// Decay stats
|
||||
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 ) {};
|
||||
|
||||
protected:
|
||||
virtual void ChangeLevel( void );
|
||||
virtual void GoToIntermission( void );
|
||||
|
|
|
@ -89,6 +89,7 @@ void CRecharge::Spawn()
|
|||
|
||||
pev->solid = SOLID_BSP;
|
||||
pev->movetype = MOVETYPE_PUSH;
|
||||
pev->skin = CHARGER_ACTIVE;
|
||||
|
||||
UTIL_SetOrigin( pev, pev->origin ); // set size and link into world
|
||||
UTIL_SetSize( pev, pev->mins, pev->maxs );
|
||||
|
@ -192,3 +193,474 @@ void CRecharge::Off( void )
|
|||
else
|
||||
SetThink( &CBaseEntity::SUB_DoNothing );
|
||||
}
|
||||
|
||||
//
|
||||
// NEW MODEL WALL HEV CHARGER AS SEEN IN PLAYSTATION(R)2 VERSION OF HALF-LIFE
|
||||
//
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Wall mounted HEV charger
|
||||
//-------------------------------------------------------------
|
||||
|
||||
#define seqCharge_Still 0
|
||||
#define seqCharge_Deploy 1
|
||||
#define seqCharge_RetractArm 2
|
||||
#define seqCharge_GiveShot 3
|
||||
#define seqCharge_RetractShot 4
|
||||
#define seqCharge_PrepShot 5
|
||||
#define seqCharge_ShotIdle 6
|
||||
#define seqCharge_Inactive 0
|
||||
|
||||
#define CHARGER_AWAKE_DISTANCE 64
|
||||
|
||||
class CMdlChargerGlass : public CActAnimating
|
||||
{
|
||||
public:
|
||||
void Spawn( );
|
||||
void Precache( void );
|
||||
static CMdlChargerGlass *CreateChargerGlass( edict_t *pOwner, const Vector &position );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( item_rechargeglass, CMdlChargerGlass );
|
||||
|
||||
CMdlChargerGlass *CMdlChargerGlass::CreateChargerGlass( edict_t *pOwner, const Vector &position )
|
||||
{
|
||||
CMdlChargerGlass *pGlass = GetClassPtr( (CMdlChargerGlass *)NULL );
|
||||
pGlass->pev->classname = MAKE_STRING( "item_rechargeglass" );
|
||||
pGlass->pev->origin = position;
|
||||
pGlass->pev->owner = pOwner;
|
||||
pGlass->Spawn();
|
||||
|
||||
return pGlass;
|
||||
}
|
||||
|
||||
void CMdlChargerGlass::Precache()
|
||||
{
|
||||
PRECACHE_MODEL("models/hev_glass.mdl" );
|
||||
}
|
||||
|
||||
void CMdlChargerGlass::Spawn()
|
||||
{
|
||||
Precache( );
|
||||
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
|
||||
UTIL_SetSize(pev, pev->mins, pev->maxs);
|
||||
SET_MODEL(ENT(pev), "models/hev_glass.mdl" );
|
||||
|
||||
pev->rendermode = kRenderTransTexture;
|
||||
pev->renderamt = 192;
|
||||
}
|
||||
|
||||
class CMdlCharger : public CActAnimating
|
||||
{
|
||||
public:
|
||||
void Spawn( );
|
||||
void Precache( void );
|
||||
void EXPORT Off(void);
|
||||
void EXPORT Recharge(void);
|
||||
void EXPORT ChargerThink( void );
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
virtual int ObjectCaps( void ) { return (CActAnimating :: ObjectCaps() | FCAP_CONTINUOUS_USE) & ~FCAP_ACROSS_TRANSITION; }
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
void UpdateArm();
|
||||
void UpdateFluidTank();
|
||||
void TurnOff();
|
||||
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
float m_flNextCharge, m_flStopCharge;
|
||||
int m_iReactivate ; // DeathMatch Delay until reactvated
|
||||
int m_iJuice;
|
||||
int m_iOn; // 0 = off, 1 = startup, 2 = going
|
||||
float m_flSoundTime;
|
||||
float m_flDegree;
|
||||
bool m_bStartUsing;
|
||||
int m_iRotValue;
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
CMdlChargerGlass *pGlass;
|
||||
CBeam *m_pBeam;
|
||||
};
|
||||
|
||||
TYPEDESCRIPTION CMdlCharger::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CMdlCharger, m_flNextCharge, FIELD_TIME),
|
||||
DEFINE_FIELD( CMdlCharger, m_flStopCharge, FIELD_TIME),
|
||||
DEFINE_FIELD( CMdlCharger, m_iReactivate, FIELD_INTEGER),
|
||||
DEFINE_FIELD( CMdlCharger, m_iJuice, FIELD_INTEGER),
|
||||
DEFINE_FIELD( CMdlCharger, m_iOn, FIELD_INTEGER),
|
||||
DEFINE_FIELD( CMdlCharger, m_iRotValue, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMdlCharger, m_flSoundTime, FIELD_TIME),
|
||||
DEFINE_FIELD( CMdlCharger, m_flDegree, FIELD_TIME),
|
||||
DEFINE_FIELD( CMdlCharger, m_bStartUsing, FIELD_BOOLEAN),
|
||||
DEFINE_FIELD( CMdlCharger, pGlass, FIELD_CLASSPTR ),
|
||||
DEFINE_FIELD( CMdlCharger, pEntity, FIELD_CLASSPTR ),
|
||||
};
|
||||
//FIXED: caused bugs after load because of incorrectly specified derivied class
|
||||
IMPLEMENT_SAVERESTORE( CMdlCharger, CActAnimating );
|
||||
|
||||
LINK_ENTITY_TO_CLASS(item_recharge, CMdlCharger);
|
||||
|
||||
void CMdlCharger::KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if ( FStrEq(pkvd->szKeyName, "style") ||
|
||||
FStrEq(pkvd->szKeyName, "height") ||
|
||||
FStrEq(pkvd->szKeyName, "value1") ||
|
||||
FStrEq(pkvd->szKeyName, "value2") ||
|
||||
FStrEq(pkvd->szKeyName, "value3"))
|
||||
{
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "dmdelay"))
|
||||
{
|
||||
m_iReactivate = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CActAnimating::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CMdlCharger::Spawn()
|
||||
{
|
||||
Precache( );
|
||||
|
||||
pev->solid = SOLID_BBOX; //BBOX;
|
||||
pev->movetype = MOVETYPE_NONE; //NONE; //PUSH;
|
||||
// UTIL_SetSize( pev, Vector(-7,-6,-27), Vector(7,6,27) ); //size(-20 -6 -27,20 6 27)
|
||||
|
||||
UTIL_SetOrigin(pev, pev->origin); // set size and link into world
|
||||
UTIL_SetSize(pev, pev->mins, pev->maxs);
|
||||
SET_MODEL(ENT(pev), "models/hev.mdl" );
|
||||
m_iJuice = gSkillData.suitchargerCapacity;
|
||||
pev->frame = 0;
|
||||
InitBoneControllers();
|
||||
|
||||
m_pBeam = CBeam::BeamCreate("sprites/lgtning.spr", 200);
|
||||
m_pBeam->EntsInit( entindex( ), entindex( ) );
|
||||
m_pBeam->SetStartAttachment( 3 ); // 2
|
||||
m_pBeam->SetEndAttachment( 4 ); // 3
|
||||
m_pBeam->SetColor( 0, 255, 0 );
|
||||
m_pBeam->SetNoise( 10 );
|
||||
m_pBeam->SetBrightness( 150 );
|
||||
m_pBeam->SetWidth( 5 );
|
||||
m_pBeam->SetScrollRate( 35 );
|
||||
|
||||
pGlass = CMdlChargerGlass::CreateChargerGlass(edict(), pev->origin);
|
||||
pGlass->pev->angles = pev->angles;
|
||||
|
||||
int YVal = pev->angles.y;
|
||||
switch (YVal)
|
||||
{
|
||||
case 180:
|
||||
m_iRotValue = 0;
|
||||
break;
|
||||
case 270:
|
||||
m_iRotValue = -90;
|
||||
break;
|
||||
case 0:
|
||||
m_iRotValue = -180;
|
||||
break;
|
||||
case 90:
|
||||
m_iRotValue = -270;
|
||||
break;
|
||||
}
|
||||
|
||||
// controller is -90...90
|
||||
|
||||
// -90...90 - ang 180 use 0
|
||||
// 0..180 - ang 270 use -90
|
||||
// 90..270 - ang 0 use -180
|
||||
// 180..360 - ang 90 use -270
|
||||
|
||||
SetSequence( seqCharge_Inactive );
|
||||
|
||||
SetThink(ChargerThink);
|
||||
|
||||
if (g_pGameRules->IsCoOp() )
|
||||
{
|
||||
CDecayRules *g_pDecayRules;
|
||||
g_pDecayRules = (CDecayRules*)g_pGameRules;
|
||||
|
||||
if ( g_pDecayRules->m_bAlienMode == true )
|
||||
{
|
||||
SetThink( NULL );
|
||||
SetUse( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
void CMdlCharger::Precache()
|
||||
{
|
||||
PRECACHE_SOUND("items/suitcharge1.wav");
|
||||
PRECACHE_SOUND("items/suitchargeno1.wav");
|
||||
PRECACHE_SOUND("items/suitchargeok1.wav");
|
||||
PRECACHE_MODEL("models/hev.mdl");
|
||||
UTIL_PrecacheOther("item_rechargeglass");
|
||||
}
|
||||
|
||||
void CMdlCharger::UpdateFluidTank( void )
|
||||
{
|
||||
// controllers 1 and 2 - 0..360
|
||||
m_flDegree += 7;
|
||||
if (m_flDegree > 360 )
|
||||
m_flDegree = m_flDegree - 360;
|
||||
|
||||
SetBoneController( 1, m_flDegree );
|
||||
SetBoneController( 2, -m_flDegree );
|
||||
}
|
||||
|
||||
void CMdlCharger::ChargerThink( void )
|
||||
{
|
||||
//ALERT( at_console, "seq %d, on %d, juice %d\n", GetSequence(), m_iOn, m_iJuice );
|
||||
|
||||
StudioFrameAdvance();
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
float flDist;
|
||||
|
||||
if (m_bStartUsing == true)
|
||||
if (m_flStopCharge >= gpGlobals->time)
|
||||
{
|
||||
SetSequence( seqCharge_RetractShot );
|
||||
//pFluidTank->SetSequence( seqCharge_ToRest );
|
||||
m_flStopCharge = 0;
|
||||
}
|
||||
|
||||
switch( GetSequence() )
|
||||
{
|
||||
case seqCharge_Inactive: // inactive
|
||||
{
|
||||
if (pev->skin == CHARGER_EMPTY) // we're in "off" state
|
||||
{
|
||||
SetThink( NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
// iterate on all entities in the vicinity.
|
||||
CBaseEntity *pTmpEntity = NULL;
|
||||
while ((pTmpEntity = UTIL_FindEntityInSphere( pTmpEntity, pev->origin, CHARGER_AWAKE_DISTANCE )) != NULL)
|
||||
{
|
||||
if (pTmpEntity->IsPlayer())
|
||||
{
|
||||
pEntity = pTmpEntity;
|
||||
if (( pev->origin - pEntity->pev->origin).Length() <= CHARGER_AWAKE_DISTANCE )
|
||||
{
|
||||
SetSequence( seqCharge_Deploy );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case seqCharge_Deploy: // arm awakens
|
||||
UpdateArm();
|
||||
if ( m_fSequenceFinished )
|
||||
SetSequence( seqCharge_PrepShot );
|
||||
break;
|
||||
|
||||
case seqCharge_PrepShot: // we are waiting for player to use charger
|
||||
flDist = ( pev->origin - pEntity->pev->origin).Length();
|
||||
//ALERT( at_console, "dist = %f\n", flDist );
|
||||
|
||||
if ( flDist > CHARGER_AWAKE_DISTANCE )
|
||||
{
|
||||
SetSequence( seqCharge_RetractArm );
|
||||
break;
|
||||
}
|
||||
UpdateArm();
|
||||
// can be interruped from USE function which activates seqCharge_GiveShot
|
||||
|
||||
break;
|
||||
|
||||
case seqCharge_RetractArm:
|
||||
if ( m_fSequenceFinished )
|
||||
{
|
||||
SetSequence( seqCharge_Inactive );
|
||||
pEntity = NULL;
|
||||
} else
|
||||
UpdateArm(); // possible fix???
|
||||
break;
|
||||
|
||||
case seqCharge_RetractShot: // stopped using
|
||||
m_bStartUsing = false;
|
||||
if ( m_fSequenceFinished )
|
||||
SetSequence( seqCharge_PrepShot );
|
||||
break;
|
||||
|
||||
case seqCharge_GiveShot: // started using
|
||||
m_bStartUsing = false;
|
||||
if ( m_fSequenceFinished )
|
||||
{
|
||||
m_bStartUsing = true;
|
||||
SetSequence( seqCharge_ShotIdle );
|
||||
}
|
||||
break;
|
||||
|
||||
case seqCharge_ShotIdle: // in use
|
||||
// give health here while USE is pressed
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CMdlCharger::UpdateArm()
|
||||
{
|
||||
if ( FNullEnt( pEntity->pev ) )
|
||||
return;
|
||||
|
||||
Vector vecTarget = (pev->origin - pEntity->pev->origin).Normalize( ); // TODO: CRASH HERE, because pEntity is NULL (0x00)
|
||||
Vector angles = UTIL_VecToAngles (vecTarget);
|
||||
//ALERT( at_console, "angles = %f, %f, %f - %f\n", angles.x, angles.y, angles.z, angles.y / 180 );
|
||||
if (angles.y > 180)
|
||||
angles.y = angles.y - 360;
|
||||
if (angles.y < -180)
|
||||
angles.y = angles.y + 360;
|
||||
|
||||
// 180 - 100
|
||||
// 90 - X (50)
|
||||
// 50 = 90 * 100 / 180
|
||||
// percent = desired degree * 100 / 180
|
||||
// percent = desired degree / 180
|
||||
|
||||
// controller is -90...90
|
||||
// -90...90 - 180 use 0
|
||||
// 0..180 - 270 use -90
|
||||
// 90..270 - 0 use -180
|
||||
// 180..360(0) - 90 use
|
||||
|
||||
// pos = (end - start) * scalar + start
|
||||
// pos = 180 * scalar - 90
|
||||
SetBoneController(3, angles.y + m_iRotValue); //- 90); // +25 to the right
|
||||
}
|
||||
|
||||
void CMdlCharger::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
// Make sure that we have a caller
|
||||
if (!pActivator)
|
||||
return;
|
||||
|
||||
// if it's not a player, ignore
|
||||
if ( !pActivator->IsPlayer() )
|
||||
return;
|
||||
|
||||
if (pev->skin == CHARGER_EMPTY) // already off
|
||||
return;
|
||||
|
||||
// if there is no juice left, turn it off
|
||||
if (m_iJuice <= 0)
|
||||
{
|
||||
TurnOff();
|
||||
return;
|
||||
}
|
||||
|
||||
// if the player doesn't have the suit, or there is no juice left, make the deny noise
|
||||
if ((m_iJuice <= 0) || (!(pActivator->pev->weapons & (1<<WEAPON_SUIT))))
|
||||
{
|
||||
if (m_flSoundTime <= gpGlobals->time)
|
||||
{
|
||||
m_flSoundTime = gpGlobals->time + 0.62;
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/suitchargeno1.wav", 0.85, ATTN_NORM );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//pFluidTank->StartUse();
|
||||
pev->nextthink = gpGlobals->time + 0.25; // pev->ltime
|
||||
SetThink(Off);
|
||||
|
||||
// start the give shot sequence and do not use until it's finished
|
||||
if (GetSequence() != seqCharge_GiveShot)
|
||||
if ( m_bStartUsing == false )
|
||||
{
|
||||
//if ( GetSequence() != seqCharge_PrepShot )
|
||||
// return; // can't start using until arm fully deployed from charger
|
||||
|
||||
SetSequence( seqCharge_GiveShot );
|
||||
return;
|
||||
}
|
||||
|
||||
// Time to recharge yet?
|
||||
if (m_flNextCharge >= gpGlobals->time)
|
||||
return;
|
||||
|
||||
// Play the on sound or the looping charging sound
|
||||
if (!m_iOn)
|
||||
{
|
||||
m_iOn++;
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/suitchargeno1.wav", 0.85, ATTN_NORM );
|
||||
m_flSoundTime = 0.56 + gpGlobals->time;
|
||||
}
|
||||
if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->time))
|
||||
{
|
||||
m_iOn++;
|
||||
EMIT_SOUND(ENT(pev), CHAN_STATIC, "items/suitcharge1.wav", 0.85, ATTN_NORM );
|
||||
}
|
||||
|
||||
// charge the player
|
||||
if (pActivator->pev->armorvalue < 100)
|
||||
{
|
||||
m_iJuice--;
|
||||
pActivator->pev->armorvalue += 1;
|
||||
//pFluidTank->StartUse();
|
||||
|
||||
if (pActivator->pev->armorvalue > 100)
|
||||
pActivator->pev->armorvalue = 100;
|
||||
}
|
||||
|
||||
UpdateFluidTank();
|
||||
|
||||
// govern the rate of charge
|
||||
m_flNextCharge = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
void CMdlCharger::Recharge(void)
|
||||
{
|
||||
//if (pev->skin == CHARGER_EMPTY)
|
||||
// return;
|
||||
|
||||
//EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", 1.0, ATTN_NORM );
|
||||
m_iJuice = gSkillData.suitchargerCapacity;
|
||||
pev->skin = CHARGER_ACTIVE; // set the active skin
|
||||
SetThink( ChargerThink );
|
||||
}
|
||||
|
||||
void CMdlCharger::Off(void)
|
||||
{
|
||||
m_flStopCharge = gpGlobals->time + 0.25;
|
||||
SetThink( ChargerThink );
|
||||
pev->nextthink = gpGlobals->time + 0.01;
|
||||
|
||||
// Stop looping sound.
|
||||
if (m_iOn > 1)
|
||||
STOP_SOUND( ENT(pev), CHAN_STATIC, "items/suitcharge1.wav" );
|
||||
|
||||
m_iOn = 0;
|
||||
|
||||
if ((!m_iJuice) && ( ( m_iReactivate = g_pGameRules->FlHEVChargerRechargeTime() ) > 0) )
|
||||
{
|
||||
pev->nextthink = pev->ltime + m_iReactivate;
|
||||
SetThink( Recharge );
|
||||
}
|
||||
//else
|
||||
// SetThink( SUB_DoNothing );
|
||||
|
||||
SetSequence( seqCharge_RetractShot );
|
||||
}
|
||||
|
||||
void CMdlCharger::TurnOff(void)
|
||||
{
|
||||
pev->skin = CHARGER_EMPTY;
|
||||
UTIL_Remove( m_pBeam );
|
||||
m_pBeam = NULL;
|
||||
SetUse( NULL );
|
||||
SetSequence( seqCharge_RetractArm );
|
||||
}
|
|
@ -252,3 +252,509 @@ void CWallHealth::Off( void )
|
|||
else
|
||||
SetThink( &CBaseEntity::SUB_DoNothing );
|
||||
}
|
||||
|
||||
//
|
||||
// NEW MODEL WALL HEALTH AS SEEN IN PLAYSTATION(R)2 VERSION OF HALF-LIFE
|
||||
//
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Wall mounted health kit
|
||||
//-------------------------------------------------------------
|
||||
|
||||
#define seq_Still 0
|
||||
#define seq_Deploy 1
|
||||
#define seq_RetractArm 2
|
||||
#define seq_GiveShot 3
|
||||
#define seq_RetractShot 4
|
||||
#define seq_PrepShot 5
|
||||
#define seq_ShotIdle 6
|
||||
#define seq_Inactive 7
|
||||
|
||||
#define seq_Slosh 1
|
||||
#define seq_ToRest 2
|
||||
|
||||
#define CHARGER_AWAKE_DISTANCE 64
|
||||
|
||||
class CMdlWallHealthTank : public CActAnimating
|
||||
{
|
||||
public:
|
||||
void Spawn( );
|
||||
void Precache( void );
|
||||
void Update( int m_iJuice );
|
||||
void EXPORT TankThink( void );
|
||||
void StartUse( void );
|
||||
int m_iJuice;
|
||||
static CMdlWallHealthTank *CreateFluidTank( edict_t *pOwner, const Vector &position );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( item_healthchargertank, CMdlWallHealthTank );
|
||||
|
||||
CMdlWallHealthTank *CMdlWallHealthTank::CreateFluidTank( edict_t *pOwner, const Vector &position )
|
||||
{
|
||||
CMdlWallHealthTank *pHealthTank = GetClassPtr( (CMdlWallHealthTank *)NULL );
|
||||
pHealthTank->pev->classname = MAKE_STRING( "item_healthchargertank" );
|
||||
pHealthTank->pev->origin = position;
|
||||
pHealthTank->pev->owner = pOwner;
|
||||
pHealthTank->Spawn();
|
||||
|
||||
return pHealthTank;
|
||||
}
|
||||
|
||||
void CMdlWallHealthTank::Precache()
|
||||
{
|
||||
PRECACHE_MODEL("models/health_charger_both.mdl" );
|
||||
}
|
||||
|
||||
void CMdlWallHealthTank::Spawn()
|
||||
{
|
||||
Precache( );
|
||||
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
|
||||
UTIL_SetSize(pev, pev->mins, pev->maxs);
|
||||
SET_MODEL(ENT(pev), "models/health_charger_both.mdl" );
|
||||
|
||||
pev->rendermode = kRenderTransTexture;
|
||||
pev->renderamt = 192;
|
||||
SetBoneController( 0, 0 ); // -11 to 0 (empty to full)
|
||||
|
||||
SetSequence( seq_Still );
|
||||
SetThink( TankThink );
|
||||
|
||||
if (g_pGameRules->IsCoOp() )
|
||||
{
|
||||
CDecayRules *g_pDecayRules;
|
||||
g_pDecayRules = (CDecayRules*)g_pGameRules;
|
||||
|
||||
if ( g_pDecayRules->m_bAlienMode == true )
|
||||
{
|
||||
SetThink( NULL );
|
||||
SetUse( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
void CMdlWallHealthTank::Update(int m_iJuice)
|
||||
{
|
||||
SetBoneController( 0, -(10 - (m_iJuice / gSkillData.healthchargerCapacity * 10)) ); // -11 to 0 (empty to full)
|
||||
}
|
||||
|
||||
void CMdlWallHealthTank::StartUse()
|
||||
{
|
||||
if (GetSequence() != seq_Slosh )
|
||||
SetSequence( seq_Slosh );
|
||||
}
|
||||
|
||||
void CMdlWallHealthTank::TankThink()
|
||||
{
|
||||
StudioFrameAdvance();
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
switch( GetSequence() )
|
||||
{
|
||||
case seq_Still: // 0 - still
|
||||
break;
|
||||
case seq_Slosh: // 1 - slosh
|
||||
if ( m_fSequenceFinished )
|
||||
SetSequence( seq_Slosh );
|
||||
break;
|
||||
case seq_ToRest: // 2 - to rest
|
||||
if ( m_fSequenceFinished )
|
||||
SetSequence( seq_Still );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define HEALTHSTATION_FULL 0
|
||||
#define HEALTHSTATION_EMPTY 1
|
||||
|
||||
class CMdlWallHealth : public CActAnimating
|
||||
{
|
||||
public:
|
||||
void Spawn( );
|
||||
void Precache( void );
|
||||
void EXPORT Off(void);
|
||||
void EXPORT Recharge(void);
|
||||
void EXPORT ChargerThink( void );
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
virtual int ObjectCaps( void ) { return (CActAnimating :: ObjectCaps() | FCAP_CONTINUOUS_USE) & ~FCAP_ACROSS_TRANSITION; }
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
void UpdateArm();
|
||||
void UpdateFluidTank();
|
||||
void TurnOff();
|
||||
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
float m_flNextCharge, m_flStopCharge;
|
||||
int m_iReactivate ; // DeathMatch Delay until reactvated
|
||||
int m_iJuice;
|
||||
int m_iOn; // 0 = off, 1 = startup, 2 = going
|
||||
float m_flSoundTime;
|
||||
bool m_bStartUsing;
|
||||
int m_iRotValue;
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
CMdlWallHealthTank *pFluidTank;
|
||||
};
|
||||
|
||||
TYPEDESCRIPTION CMdlWallHealth::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CMdlWallHealth, m_flNextCharge, FIELD_TIME),
|
||||
DEFINE_FIELD( CMdlWallHealth, m_flStopCharge, FIELD_TIME),
|
||||
DEFINE_FIELD( CMdlWallHealth, m_iReactivate, FIELD_INTEGER),
|
||||
DEFINE_FIELD( CMdlWallHealth, m_iJuice, FIELD_INTEGER),
|
||||
DEFINE_FIELD( CMdlWallHealth, m_iOn, FIELD_INTEGER),
|
||||
DEFINE_FIELD( CMdlWallHealth, m_iRotValue, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMdlWallHealth, m_flSoundTime, FIELD_TIME),
|
||||
DEFINE_FIELD( CMdlWallHealth, m_bStartUsing, FIELD_BOOLEAN),
|
||||
DEFINE_FIELD( CMdlWallHealth, pFluidTank, FIELD_CLASSPTR ),
|
||||
DEFINE_FIELD( CMdlWallHealth, pEntity, FIELD_CLASSPTR ),
|
||||
};
|
||||
//FIXED: caused bugs after load because of incorrectly specified derivied class
|
||||
IMPLEMENT_SAVERESTORE( CMdlWallHealth, CActAnimating );
|
||||
|
||||
LINK_ENTITY_TO_CLASS(item_healthcharger, CMdlWallHealth);
|
||||
|
||||
void CMdlWallHealth::KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if ( FStrEq(pkvd->szKeyName, "style") ||
|
||||
FStrEq(pkvd->szKeyName, "height") ||
|
||||
FStrEq(pkvd->szKeyName, "value1") ||
|
||||
FStrEq(pkvd->szKeyName, "value2") ||
|
||||
FStrEq(pkvd->szKeyName, "value3"))
|
||||
{
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "dmdelay"))
|
||||
{
|
||||
m_iReactivate = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CActAnimating::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CMdlWallHealth::Spawn()
|
||||
{
|
||||
Precache( );
|
||||
|
||||
pev->solid = SOLID_BBOX;
|
||||
pev->movetype = MOVETYPE_NONE; //PUSH;
|
||||
// UTIL_SetSize( pev, Vector(-7,-6,-27), Vector(7,6,27) ); //size(-20 -6 -27,20 6 27)
|
||||
|
||||
UTIL_SetOrigin(pev, pev->origin); // set size and link into world
|
||||
UTIL_SetSize(pev, pev->mins, pev->maxs);
|
||||
SET_MODEL(ENT(pev), "models/health_charger_body.mdl" );
|
||||
m_iJuice = gSkillData.healthchargerCapacity;
|
||||
pev->frame = 0;
|
||||
pev->skin = HEALTHSTATION_FULL;
|
||||
InitBoneControllers();
|
||||
|
||||
pFluidTank = CMdlWallHealthTank::CreateFluidTank( edict(), pev->origin);
|
||||
//pFluidTank->pev->origin = pev->origin;
|
||||
pFluidTank->pev->angles = pev->angles;
|
||||
|
||||
int YVal = pev->angles.y;
|
||||
switch (YVal)
|
||||
{
|
||||
case 180:
|
||||
m_iRotValue = 0;
|
||||
break;
|
||||
case 270:
|
||||
m_iRotValue = -90;
|
||||
break;
|
||||
case 0:
|
||||
m_iRotValue = -180;
|
||||
break;
|
||||
case 90:
|
||||
m_iRotValue = -270;
|
||||
break;
|
||||
}
|
||||
|
||||
// controller is -90...90
|
||||
|
||||
// -90...90 - ang 180 use 0
|
||||
// 0..180 - ang 270 use -90
|
||||
// 90..270 - ang 0 use -180
|
||||
// 180..360 - ang 90 use -270
|
||||
|
||||
SetSequence( seq_Inactive );
|
||||
SetThink(ChargerThink);
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
void CMdlWallHealth::Precache()
|
||||
{
|
||||
PRECACHE_SOUND("items/medshot4.wav");
|
||||
PRECACHE_SOUND("items/medshotno1.wav");
|
||||
PRECACHE_SOUND("items/medcharge4.wav");
|
||||
PRECACHE_MODEL("models/health_charger_body.mdl" );
|
||||
UTIL_PrecacheOther("item_healthchargertank");
|
||||
}
|
||||
|
||||
void CMdlWallHealth::UpdateFluidTank( void )
|
||||
{
|
||||
pFluidTank->Update( m_iJuice );
|
||||
/*
|
||||
-11 - 0
|
||||
0 - 100
|
||||
|
||||
m_iJuice - X
|
||||
gSkillData.healthchargerCapacity - 100
|
||||
|
||||
25 - 50 (?)
|
||||
50 - 100
|
||||
25:50*100
|
||||
|
||||
m_iJuice div gSkillData.healthchargerCapacity * 100
|
||||
-(10 - (m_iJuice div gSkillData.healthchargerCapacity * 10))
|
||||
*/
|
||||
}
|
||||
|
||||
void CMdlWallHealth::ChargerThink( void )
|
||||
{
|
||||
//ALERT( at_console, "WallHealth thinks!\n" );
|
||||
//ALERT( at_console, "next = %f prev = %f\n", m_flNextCharge, m_flStopCharge );
|
||||
//ALERT( at_console, "seq %d, on %d, juice %d\n", GetSequence(), m_iOn, m_iJuice );
|
||||
|
||||
StudioFrameAdvance();
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
Vector posGun, angGun;
|
||||
Vector vecTarget, vecOut, angles;
|
||||
float flDist;
|
||||
|
||||
if (m_bStartUsing == true)
|
||||
if (m_flStopCharge >= gpGlobals->time)
|
||||
{
|
||||
SetSequence( seq_RetractShot );
|
||||
pFluidTank->SetSequence( seq_ToRest );
|
||||
m_flStopCharge = 0;
|
||||
}
|
||||
|
||||
switch( GetSequence() )
|
||||
{
|
||||
case seq_Inactive: // inactive
|
||||
{
|
||||
if (pev->skin == HEALTHSTATION_EMPTY) // we're in "off" state
|
||||
{
|
||||
SetThink( NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
// iterate on all entities in the vicinity.
|
||||
CBaseEntity *pTmpEntity = NULL;
|
||||
while ((pTmpEntity = UTIL_FindEntityInSphere( pTmpEntity, pev->origin, CHARGER_AWAKE_DISTANCE )) != NULL)
|
||||
{
|
||||
if (pTmpEntity->IsPlayer())
|
||||
{
|
||||
pEntity = pTmpEntity;
|
||||
if (( pev->origin - pEntity->pev->origin).Length() <= CHARGER_AWAKE_DISTANCE )
|
||||
{
|
||||
SetSequence( seq_Deploy );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case seq_Deploy: // arm awakens
|
||||
UpdateArm();
|
||||
if ( m_fSequenceFinished )
|
||||
SetSequence( seq_PrepShot );
|
||||
break;
|
||||
|
||||
case seq_PrepShot: // we are waiting for player to use charger
|
||||
flDist = ( pev->origin - pEntity->pev->origin).Length(); // CRASH IS HERE!!!!!!
|
||||
//ALERT( at_console, "dist = %f\n", flDist );
|
||||
|
||||
if ( flDist > CHARGER_AWAKE_DISTANCE )
|
||||
{
|
||||
SetSequence( seq_RetractArm );
|
||||
break;
|
||||
}
|
||||
UpdateArm();
|
||||
// can be interruped from USE function which activates seq_GiveShot
|
||||
|
||||
break;
|
||||
|
||||
case seq_RetractArm:
|
||||
if ( m_fSequenceFinished )
|
||||
{
|
||||
SetSequence( seq_Inactive );
|
||||
pEntity = NULL;
|
||||
} else
|
||||
UpdateArm(); // possible fix???
|
||||
break;
|
||||
|
||||
case seq_RetractShot: // stopped using
|
||||
m_bStartUsing = false;
|
||||
if ( m_fSequenceFinished )
|
||||
SetSequence( seq_PrepShot );
|
||||
break;
|
||||
|
||||
case seq_GiveShot: // started using
|
||||
m_bStartUsing = false;
|
||||
if ( m_fSequenceFinished )
|
||||
{
|
||||
m_bStartUsing = true;
|
||||
SetSequence( seq_ShotIdle );
|
||||
}
|
||||
break;
|
||||
|
||||
case seq_ShotIdle: // in use
|
||||
// give health here while USE is pressed
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CMdlWallHealth::UpdateArm()
|
||||
{
|
||||
Vector vecTarget = (pev->origin - pEntity->pev->origin).Normalize( );
|
||||
Vector angles = UTIL_VecToAngles (vecTarget);
|
||||
//ALERT( at_console, "angles = %f, %f, %f - %f\n", angles.x, angles.y, angles.z, angles.y / 180 );
|
||||
if (angles.y > 180)
|
||||
angles.y = angles.y - 360;
|
||||
if (angles.y < -180)
|
||||
angles.y = angles.y + 360;
|
||||
|
||||
// 180 - 100
|
||||
// 90 - X (50)
|
||||
// 50 = 90 * 100 / 180
|
||||
// percent = desired degree * 100 / 180
|
||||
// percent = desired degree / 180
|
||||
|
||||
// controller is -90...90
|
||||
// -90...90 - 180 use 0
|
||||
// 0..180 - 270 use -90
|
||||
// 90..270 - 0 use -180
|
||||
// 180..360(0) - 90 use
|
||||
|
||||
// pos = (end - start) * scalar + start
|
||||
// pos = 180 * scalar - 90
|
||||
SetBoneController(0, angles.y + m_iRotValue); //- 90); // +25 to the right
|
||||
}
|
||||
|
||||
void CMdlWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
// Make sure that we have a caller
|
||||
if (!pActivator)
|
||||
return;
|
||||
|
||||
// if it's not a player, ignore
|
||||
if ( !pActivator->IsPlayer() )
|
||||
return;
|
||||
|
||||
if (pev->skin == HEALTHSTATION_EMPTY) // already off
|
||||
return;
|
||||
|
||||
// if there is no juice left, turn it off
|
||||
if (m_iJuice <= 0)
|
||||
{
|
||||
TurnOff(); // do we need it there or in Off() ?
|
||||
return;
|
||||
}
|
||||
|
||||
// if the player doesn't have the suit, or there is no juice left, make the deny noise
|
||||
if ((m_iJuice <= 0) || (!(pActivator->pev->weapons & (1<<WEAPON_SUIT))))
|
||||
{
|
||||
if (m_flSoundTime <= gpGlobals->time)
|
||||
{
|
||||
m_flSoundTime = gpGlobals->time + 0.62;
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshotno1.wav", 1.0, ATTN_NORM );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pFluidTank->StartUse();
|
||||
pev->nextthink = gpGlobals->time + 0.25; // pev->ltime
|
||||
SetThink(Off);
|
||||
|
||||
// start the give shot sequence and do not use until it's finished
|
||||
if (GetSequence() != seq_GiveShot)
|
||||
if ( m_bStartUsing == false )
|
||||
{
|
||||
SetSequence( seq_GiveShot );
|
||||
return;
|
||||
}
|
||||
|
||||
// Time to recharge yet?
|
||||
if (m_flNextCharge >= gpGlobals->time)
|
||||
return;
|
||||
|
||||
// Play the on sound or the looping charging sound
|
||||
if (!m_iOn)
|
||||
{
|
||||
m_iOn++;
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", 1.0, ATTN_NORM );
|
||||
m_flSoundTime = 0.56 + gpGlobals->time;
|
||||
}
|
||||
if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->time))
|
||||
{
|
||||
m_iOn++;
|
||||
EMIT_SOUND(ENT(pev), CHAN_STATIC, "items/medcharge4.wav", 1.0, ATTN_NORM );
|
||||
}
|
||||
|
||||
// charge the player
|
||||
if ( pActivator->TakeHealth( 1, DMG_GENERIC ) )
|
||||
{
|
||||
m_iJuice--;
|
||||
//pFluidTank->StartUse();
|
||||
}
|
||||
|
||||
UpdateFluidTank();
|
||||
|
||||
// govern the rate of charge
|
||||
m_flNextCharge = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
void CMdlWallHealth::Recharge(void)
|
||||
{
|
||||
//if (pev->skin == HEALTHSTATION_EMPTY)
|
||||
// return;
|
||||
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", 1.0, ATTN_NORM );
|
||||
m_iJuice = gSkillData.healthchargerCapacity;
|
||||
pev->skin = HEALTHSTATION_FULL; // set the active skin
|
||||
SetThink( ChargerThink );
|
||||
}
|
||||
|
||||
void CMdlWallHealth::Off(void)
|
||||
{
|
||||
m_flStopCharge = gpGlobals->time + 0.25;
|
||||
SetThink( ChargerThink );
|
||||
pev->nextthink = gpGlobals->time + 0.01;
|
||||
|
||||
// Stop looping sound.
|
||||
if (m_iOn > 1)
|
||||
STOP_SOUND( ENT(pev), CHAN_STATIC, "items/medcharge4.wav" );
|
||||
|
||||
m_iOn = 0;
|
||||
|
||||
if ((!m_iJuice) && ( ( m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime() ) > 0) )
|
||||
{
|
||||
pev->nextthink = pev->ltime + m_iReactivate;
|
||||
SetThink(Recharge);
|
||||
}
|
||||
//else
|
||||
// SetThink( SUB_DoNothing );
|
||||
}
|
||||
|
||||
void CMdlWallHealth::TurnOff( void )
|
||||
{
|
||||
pev->skin = HEALTHSTATION_EMPTY;
|
||||
pFluidTank->SetSequence( seq_ToRest );
|
||||
SetUse( NULL );
|
||||
SetSequence( seq_RetractArm );
|
||||
}
|
|
@ -53,7 +53,7 @@ extern DLL_GLOBAL int g_iSkillLevel;
|
|||
#define GRUNT_ATTN ATTN_NORM // attenutation of grunt sentences
|
||||
#define HGRUNT_LIMP_HEALTH 20
|
||||
#define HGRUNT_DMG_HEADSHOT ( DMG_BULLET | DMG_CLUB ) // damage types that can kill a grunt with a single headshot.
|
||||
#define HGRUNT_NUM_HEADS 2 // how many grunt heads are there?
|
||||
#define HGRUNT_NUM_HEADS 4 // how many grunt heads are there?
|
||||
#define HGRUNT_MINIMUM_HEADSHOT_DAMAGE 15 // must do at least this much damage in one shot to head to score a headshot kill
|
||||
#define HGRUNT_SENTENCE_VOLUME (float)0.35 // volume of grunt sentences
|
||||
|
||||
|
@ -62,15 +62,18 @@ extern DLL_GLOBAL int g_iSkillLevel;
|
|||
#define HGRUNT_GRENADELAUNCHER ( 1 << 2)
|
||||
#define HGRUNT_SHOTGUN ( 1 << 3)
|
||||
|
||||
#define LODS_GROUP 0
|
||||
#define HEAD_GROUP 1
|
||||
#define HEAD_GRUNT 0
|
||||
#define HEAD_COMMANDER 1
|
||||
#define HEAD_SHOTGUN 2
|
||||
#define HEAD_M203 3
|
||||
#define GUN_GROUP 2
|
||||
|
||||
#define HEAD_GRUNT 0
|
||||
#define HEAD_COMMANDER 1// * 3
|
||||
#define HEAD_SHOTGUN 2// * 3
|
||||
#define HEAD_M203 3// * 3
|
||||
|
||||
#define GUN_MP5 0
|
||||
#define GUN_SHOTGUN 1
|
||||
#define GUN_NONE 2
|
||||
#define GUN_SHOTGUN 1// * 3
|
||||
#define GUN_NONE 2// * 3
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
|
|
|
@ -28,6 +28,15 @@
|
|||
#include "skill.h"
|
||||
#include "items.h"
|
||||
#include "gamerules.h"
|
||||
#include "decals.h"
|
||||
#include "actanimating.h"
|
||||
|
||||
#define seqEmitterClosed 0
|
||||
#define seqEmitterDeploy 1
|
||||
#define seqEmitterIdleOpen 2
|
||||
#define seqEmitterBroken1 3
|
||||
#define seqEmitterBroken2 4
|
||||
#define seqEmitterDeath 5
|
||||
|
||||
extern int gmsgItemPickup;
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ TYPEDESCRIPTION CMonsterMaker::m_SaveData[] =
|
|||
DEFINE_FIELD( CMonsterMaker, m_iMaxLiveChildren, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_fActive, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_fFadeChildren, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_fIsWarpBall, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_cTotalMonstersCount, FIELD_INTEGER ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CMonsterMaker, CBaseMonster )
|
||||
|
@ -93,14 +95,33 @@ void CMonsterMaker::KeyValue( KeyValueData *pkvd )
|
|||
m_iszMonsterClassname = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "warptarget") || FStrEq(pkvd->szKeyName, "makertarget") || FStrEq(pkvd->szKeyName, "warp_target") )
|
||||
{
|
||||
m_iszWarpTarget = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "monsterspawnflags") ) // monsterspawnflags
|
||||
{
|
||||
m_iChildrenSpawnflags = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
// radius
|
||||
// damage_delay
|
||||
else
|
||||
CBaseMonster::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CMonsterMaker::Spawn()
|
||||
{
|
||||
//ALERT( at_console, "CMonsterMaker::Spawn\n");
|
||||
m_fIsWarpBall = !strcmp(STRING(pev->classname), "env_warpball");
|
||||
|
||||
pev->solid = SOLID_NOT;
|
||||
|
||||
// for WarpBall to function correctly - it's spawnflag is another then same in monstermaker
|
||||
if ( m_fIsWarpBall && FBitSet ( pev->spawnflags, SF_WARPBALL_ONCE )) // flag bit 1
|
||||
SetBits ( pev->spawnflags, SF_MONSTERMAKER_FIREONCE ); // flag bit 16
|
||||
|
||||
m_cLiveChildren = 0;
|
||||
Precache();
|
||||
if( !FStringNull( pev->targetname ) )
|
||||
|
@ -149,9 +170,20 @@ void CMonsterMaker::Spawn()
|
|||
|
||||
void CMonsterMaker::Precache( void )
|
||||
{
|
||||
//ALERT( at_console, "%s::Precache\n", STRING(pev->classname));
|
||||
|
||||
CBaseMonster::Precache();
|
||||
|
||||
if (m_fIsWarpBall)
|
||||
{
|
||||
m_flDelay = 5;
|
||||
UTIL_PrecacheOther( "effect_warpball" );
|
||||
}
|
||||
|
||||
if (FStringNull( m_iszMonsterClassname ) != true)
|
||||
UTIL_PrecacheOther( STRING( m_iszMonsterClassname ) );
|
||||
else
|
||||
ALERT( at_console, "CMonsterMaker without a children name!\n");
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -206,8 +238,9 @@ void CMonsterMaker::MakeMonster( void )
|
|||
}
|
||||
|
||||
pevCreate = VARS( pent );
|
||||
pevCreate->origin = pev->origin;
|
||||
pevCreate->angles = pev->angles;
|
||||
pevCreate->origin = DesiredOrigin;
|
||||
pevCreate->angles = DesiredAngles;
|
||||
pevCreate->spawnflags = m_iChildrenSpawnflags;
|
||||
SetBits( pevCreate->spawnflags, SF_MONSTER_FALL_TO_GROUND );
|
||||
|
||||
// Children hit monsterclip brushes
|
||||
|
@ -228,10 +261,21 @@ void CMonsterMaker::MakeMonster( void )
|
|||
|
||||
if( m_cNumMonsters == 0 )
|
||||
{
|
||||
// Disable this forever. Don't kill it because it still gets death notices
|
||||
// FIXME: do we need this comment? "Disable this forever. Don't kill it because it still gets death notices"
|
||||
//m_cNumMonsters = m_cTotalMonstersCount;
|
||||
//m_fActive = FALSE;
|
||||
SetThink( NULL );
|
||||
SetUse( NULL );
|
||||
}
|
||||
|
||||
if ( !FBitSet ( pev->spawnflags, SF_MONSTERMAKER_CYCLIC ) )
|
||||
{
|
||||
if ( FBitSet ( pev->spawnflags, SF_MONSTERMAKER_FIREONCE ) )
|
||||
{
|
||||
//ALERT( at_console, "Removing MakeMonster\n");
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -270,6 +314,8 @@ void CMonsterMaker::ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, US
|
|||
//=========================================================
|
||||
void CMonsterMaker::MakerThink( void )
|
||||
{
|
||||
//ALERT( at_console, "CMonsterMaker::MakerThink\n");
|
||||
|
||||
pev->nextthink = gpGlobals->time + m_flDelay;
|
||||
|
||||
MakeMonster();
|
||||
|
|
124
dlls/player.cpp
124
dlls/player.cpp
|
@ -67,6 +67,11 @@ extern CGraph WorldGraph;
|
|||
#define FLASH_DRAIN_TIME 1.2f //100 units/3 minutes
|
||||
#define FLASH_CHARGE_TIME 0.2f // 100 units/20 seconds (seconds per unit)
|
||||
|
||||
#define MODE_STAND 0
|
||||
#define MODE_RUN 1
|
||||
#define MODE_CROUCH 2
|
||||
#define MODE_JUMP 3
|
||||
|
||||
// Global Savedata for player
|
||||
TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] =
|
||||
{
|
||||
|
@ -116,6 +121,7 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] =
|
|||
DEFINE_FIELD( CBasePlayer, m_pTank, FIELD_EHANDLE ),
|
||||
DEFINE_FIELD( CBasePlayer, m_iHideHUD, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CBasePlayer, m_iFOV, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CBasePlayer, m_iDecayId, FIELD_INTEGER ),
|
||||
|
||||
//DEFINE_FIELD( CBasePlayer, m_fDeadTime, FIELD_FLOAT ), // only used in multiplayer games
|
||||
//DEFINE_FIELD( CBasePlayer, m_fGameHUDInitialized, FIELD_INTEGER ), // only used in multiplayer games
|
||||
|
@ -3440,7 +3446,15 @@ void CBasePlayer::ForceClientDllUpdate( void )
|
|||
m_fInitHUD = TRUE; // Force HUD gmsgResetHUD message
|
||||
memset( m_rgAmmoLast, 0, sizeof( m_rgAmmoLast )); // a1ba: Force update AmmoX
|
||||
|
||||
|
||||
int gmsgLensFlare = 0;
|
||||
int gmsgAimFrame = 0;
|
||||
int gmsgNotepad = 0;
|
||||
int gmsgChangeMode = 0;
|
||||
int gmsgCamera = 0;
|
||||
int gmsgChangePlayer = 0;
|
||||
int gmsgSparePlayer = 0;
|
||||
int gmsgAlienState = 0;
|
||||
int gmsgUpdateDecayPlayerName = 0;
|
||||
|
||||
// Now force all the necessary messages
|
||||
// to be sent.
|
||||
|
@ -4363,6 +4377,7 @@ Vector CBasePlayer::GetAutoaimVector( float flDelta )
|
|||
// ALERT( at_console, "%f %f\n", angles.x, angles.y );
|
||||
|
||||
UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim );
|
||||
//AutoaimFrame(vecSrc, flDist, flDelta); //draw selection frame around objects
|
||||
return gpGlobals->v_forward;
|
||||
}
|
||||
|
||||
|
@ -4495,6 +4510,94 @@ void CBasePlayer::ResetAutoaim()
|
|||
m_fOnTarget = FALSE;
|
||||
}
|
||||
|
||||
void CBasePlayer :: AutoaimFrame( Vector &vecSrc, float flDist, float flDelta )
|
||||
{
|
||||
edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex( 1 );
|
||||
CBaseEntity *pEntity;
|
||||
float bestdot;
|
||||
Vector bestdir;
|
||||
TraceResult tr;
|
||||
|
||||
MESSAGE_BEGIN( MSG_ALL, gmsgAimFrame);
|
||||
WRITE_BYTE( 0 );
|
||||
WRITE_BYTE( 0.0 );
|
||||
WRITE_COORD( 0.0 );
|
||||
WRITE_COORD( 0.0 );
|
||||
WRITE_COORD( 0.0 );
|
||||
WRITE_COORD( 0.0 );
|
||||
WRITE_COORD( 0.0 );
|
||||
WRITE_COORD( 0.0 );
|
||||
MESSAGE_END();
|
||||
|
||||
UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim );
|
||||
|
||||
// try all possible entities
|
||||
bestdot = flDelta; // +- 10 degrees
|
||||
|
||||
UTIL_TraceLine( vecSrc, vecSrc + bestdir * flDist, dont_ignore_monsters, edict(), &tr );
|
||||
for ( int i = 1; i < gpGlobals->maxEntities; i++, pEdict++ )
|
||||
{
|
||||
Vector center;
|
||||
Vector dir;
|
||||
float dot;
|
||||
|
||||
if ( pEdict->free ) // Not in use
|
||||
continue;
|
||||
|
||||
if (pEdict == edict())
|
||||
continue;
|
||||
|
||||
if ( !g_pGameRules->ShouldAutoAim( this, pEdict ) )
|
||||
continue;
|
||||
|
||||
pEntity = Instance( pEdict );
|
||||
if (pEntity == NULL)
|
||||
continue;
|
||||
|
||||
center = pEntity->BodyTarget( vecSrc );
|
||||
|
||||
dir = (center - vecSrc).Normalize( );
|
||||
|
||||
// make sure it's in front of the player
|
||||
if (DotProduct (dir, gpGlobals->v_forward ) < 0)
|
||||
continue;
|
||||
|
||||
dot = fabs( DotProduct (dir, gpGlobals->v_right ) )
|
||||
+ fabs( DotProduct (dir, gpGlobals->v_up ) ) * 0.5;
|
||||
|
||||
// tweek for distance
|
||||
dot *= 1.0 + 0.2 * ((center - vecSrc).Length() / flDist);
|
||||
|
||||
if (dot > bestdot)
|
||||
continue; // to far to turn
|
||||
|
||||
UTIL_TraceLine( vecSrc, center, dont_ignore_monsters, edict(), &tr );
|
||||
if (tr.flFraction != 1.0 && tr.pHit != pEdict)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!FClassnameIs(pEntity->pev,"func_frame")) continue;
|
||||
|
||||
CFuncFrame* pFrame = (CFuncFrame*)CBaseEntity::Instance(pEdict);
|
||||
//ALERT( at_console, "Kind is %d\n", pFrame->m_iKind);
|
||||
|
||||
if ((vecSrc-center).Length() < 200) //was 50
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_ALL, gmsgAimFrame);
|
||||
WRITE_BYTE( pEntity->entindex() );
|
||||
WRITE_BYTE( pFrame->m_iKind );
|
||||
WRITE_COORD( pEntity->pev->mins.x );
|
||||
WRITE_COORD( pEntity->pev->mins.y );
|
||||
WRITE_COORD( pEntity->pev->mins.z );
|
||||
WRITE_COORD( pEntity->pev->maxs.x );
|
||||
WRITE_COORD( pEntity->pev->maxs.y );
|
||||
WRITE_COORD( pEntity->pev->maxs.z );
|
||||
MESSAGE_END();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
SetCustomDecalFrames
|
||||
|
@ -4713,9 +4816,25 @@ BOOL CBasePlayer::SwitchWeapon( CBasePlayerItem *pWeapon )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Set Decay's player index
|
||||
//=========================================================
|
||||
void CBasePlayer::SetDecayPlayerIndex( int Id )
|
||||
{
|
||||
m_iDecayId = Id;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Dead HEV suit prop
|
||||
//=========================================================
|
||||
|
||||
#define PLAYER_LODS 4
|
||||
|
||||
#define HEAD_GROUP 1
|
||||
#define HEAD_GORDON 0
|
||||
#define HEAD_HELMET 1
|
||||
|
||||
|
||||
class CDeadHEV : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
|
@ -4763,7 +4882,8 @@ void CDeadHEV::Spawn( void )
|
|||
pev->effects = 0;
|
||||
pev->yaw_speed = 8;
|
||||
pev->sequence = 0;
|
||||
pev->body = 1;
|
||||
//pev->body = 1;
|
||||
SetBodygroup( HEAD_GROUP, HEAD_HELMET * PLAYER_LODS );
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
|
||||
pev->sequence = LookupSequence( m_szPoses[m_iPose] );
|
||||
|
|
|
@ -226,7 +226,9 @@ public:
|
|||
virtual int Restore( CRestore &restore );
|
||||
void RenewItems(void);
|
||||
void PackDeadPlayerItems( void );
|
||||
void PackAllItems( void );
|
||||
void RemoveAllItems( BOOL removeSuit );
|
||||
void SetDecayPlayerIndex( int Id );
|
||||
BOOL SwitchWeapon( CBasePlayerItem *pWeapon );
|
||||
|
||||
// JOHN: sends custom messages if player HUD data has changed (eg health, ammo)
|
||||
|
@ -298,6 +300,7 @@ public:
|
|||
void ResetAutoaim( void );
|
||||
Vector GetAutoaimVector( float flDelta );
|
||||
Vector AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta );
|
||||
void AutoaimFrame( Vector &vecSrc, float flDist, float flDelta ); // Draw selection frame around objects
|
||||
|
||||
void ForceClientDllUpdate( void ); // Forces all client .dll specific data to be resent to client.
|
||||
|
||||
|
@ -325,6 +328,7 @@ public:
|
|||
void SetPrefsFromUserinfo( char *infobuffer );
|
||||
|
||||
float m_flNextChatTime;
|
||||
int m_iDecayId; // Decay player index
|
||||
|
||||
int m_iAutoWepSwitch;
|
||||
|
||||
|
|
|
@ -1466,3 +1466,242 @@ int CSittingScientist::FIdleSpeak( void )
|
|||
CTalkMonster::g_talkWaitTime = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Doctor Keller
|
||||
// monster_wheelchair
|
||||
//=========================================================
|
||||
|
||||
class CWheelChairScientist : public CScientist // kdb: changed from public CBaseMonster so he can speak
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
int FIdleSpeak( void );
|
||||
void PainSound( void );
|
||||
void TalkInit( void );
|
||||
BOOL CanHeal( void );
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_wheelchair, CWheelChairScientist );
|
||||
|
||||
void CWheelChairScientist :: Spawn( )
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL(ENT(pev), "models/wheelchair_sci.mdl");
|
||||
|
||||
UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->health = gSkillData.barneyHealth;
|
||||
pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin.
|
||||
m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
pev->body = 0; // gun in holster
|
||||
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
|
||||
|
||||
MonsterInit();
|
||||
SetUse( FollowerUse );
|
||||
}
|
||||
|
||||
void CWheelChairScientist :: Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL("models/wheelchair_sci.mdl");
|
||||
|
||||
PRECACHE_SOUND("keller/dk_pain1.wav");
|
||||
PRECACHE_SOUND("keller/dk_pain2.wav");
|
||||
PRECACHE_SOUND("keller/dk_pain3.wav");
|
||||
PRECACHE_SOUND("keller/dk_pain4.wav");
|
||||
PRECACHE_SOUND("keller/dk_pain5.wav");
|
||||
PRECACHE_SOUND("keller/dk_pain6.wav");
|
||||
PRECACHE_SOUND("keller/dk_pain7.wav");
|
||||
|
||||
PRECACHE_SOUND("wheelchair/wheelchair_jog.wav");
|
||||
PRECACHE_SOUND("wheelchair/wheelchair_run.wav");
|
||||
PRECACHE_SOUND("wheelchair/wheelchair_walk.wav");
|
||||
|
||||
TalkInit();
|
||||
CTalkMonster::Precache();
|
||||
}
|
||||
|
||||
int CWheelChairScientist :: FIdleSpeak( void )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL CWheelChairScientist :: CanHeal( void )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CWheelChairScientist :: PainSound( void )
|
||||
{
|
||||
if (gpGlobals->time < m_painTime )
|
||||
return;
|
||||
|
||||
m_painTime = gpGlobals->time + RANDOM_FLOAT(0.5, 0.75);
|
||||
|
||||
switch (RANDOM_LONG(0,6))
|
||||
{
|
||||
case 0: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "keller/dk_pain1.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 1: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "keller/dk_pain2.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 2: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "keller/dk_pain3.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 3: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "keller/dk_pain4.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 4: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "keller/dk_pain5.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 5: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "keller/dk_pain6.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 6: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "keller/dk_pain7.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
}
|
||||
}
|
||||
|
||||
void CWheelChairScientist :: TalkInit()
|
||||
{
|
||||
CTalkMonster::TalkInit();
|
||||
|
||||
// Keller's speach group names (group names are in sentences.txt)
|
||||
|
||||
m_szGrp[TLK_ANSWER] = NULL;
|
||||
m_szGrp[TLK_QUESTION] = NULL;
|
||||
m_szGrp[TLK_IDLE] = "DK_IDLE";
|
||||
m_szGrp[TLK_STARE] = "DK_STARE";
|
||||
m_szGrp[TLK_HELLO] = "DK_HELLO";
|
||||
|
||||
m_szGrp[TLK_FEAR] = "DK_FEAR";
|
||||
m_szGrp[TLK_PLFEAR] = "DK_PLFEAR";
|
||||
m_szGrp[TLK_HEAL] = NULL;
|
||||
|
||||
m_szGrp[TLK_USE] = "DK_OK";
|
||||
m_szGrp[TLK_UNUSE] = "DK_WAIT";
|
||||
m_szGrp[TLK_STOP] = "DK_STOP";
|
||||
m_szGrp[TLK_NOSHOOT] = "DK_SCARED";
|
||||
|
||||
m_szGrp[TLK_PLHURT1] = NULL;
|
||||
m_szGrp[TLK_PLHURT2] = NULL;
|
||||
m_szGrp[TLK_PLHURT3] = NULL;
|
||||
|
||||
m_szGrp[TLK_WOUND] = NULL;
|
||||
m_szGrp[TLK_MORTAL] = NULL;
|
||||
|
||||
// get voice for head
|
||||
m_voicePitch = 100;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Doctor Rosenberg
|
||||
// monster_rosenberg
|
||||
//=========================================================
|
||||
|
||||
class CRosenberg : public CScientist // kdb: changed from public CBaseMonster so he can speak
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void PainSound( void );
|
||||
void TalkInit( void );
|
||||
int FIdleSpeak( void );
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_rosenberg, CRosenberg );
|
||||
|
||||
void CRosenberg :: Spawn( )
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL(ENT(pev), "models/scientist_rosenberg.mdl");
|
||||
|
||||
UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->health = gSkillData.barneyHealth+10;
|
||||
pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin.
|
||||
m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
|
||||
|
||||
SetBodygroup( BODY_GROUP, BODY_LOD0 );
|
||||
SetBodygroup( HEAD_GROUP, 0 );
|
||||
|
||||
MonsterInit();
|
||||
SetUse( FollowerUse );
|
||||
}
|
||||
|
||||
void CRosenberg :: Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL("models/scientist_rosenberg.mdl");
|
||||
|
||||
PRECACHE_SOUND("rosenberg/ro_pain0.wav");
|
||||
PRECACHE_SOUND("rosenberg/ro_pain1.wav");
|
||||
PRECACHE_SOUND("rosenberg/ro_pain2.wav");
|
||||
PRECACHE_SOUND("rosenberg/ro_pain3.wav");
|
||||
PRECACHE_SOUND("rosenberg/ro_pain4.wav");
|
||||
PRECACHE_SOUND("rosenberg/ro_pain5.wav");
|
||||
PRECACHE_SOUND("rosenberg/ro_pain6.wav");
|
||||
PRECACHE_SOUND("rosenberg/ro_pain7.wav");
|
||||
PRECACHE_SOUND("rosenberg/ro_pain8.wav");
|
||||
|
||||
TalkInit();
|
||||
CTalkMonster::Precache();
|
||||
}
|
||||
|
||||
void CRosenberg :: PainSound( void )
|
||||
{
|
||||
if (gpGlobals->time < m_painTime )
|
||||
return;
|
||||
|
||||
m_painTime = gpGlobals->time + RANDOM_FLOAT(0.5, 0.75);
|
||||
|
||||
switch (RANDOM_LONG(0,8))
|
||||
{
|
||||
case 0: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain0.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 1: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain1.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 2: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain2.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 3: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain3.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 4: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain4.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 5: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain5.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 6: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain6.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 7: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain7.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
case 8: EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "rosenberg/ro_pain8.wav", 1, ATTN_NORM, 0, GetVoicePitch()); break;
|
||||
}
|
||||
}
|
||||
|
||||
void CRosenberg :: TalkInit()
|
||||
{
|
||||
CTalkMonster::TalkInit();
|
||||
|
||||
// Rosenberg's speach group names (group names are in sentences.txt)
|
||||
|
||||
m_szGrp[TLK_ANSWER] = NULL;
|
||||
m_szGrp[TLK_QUESTION] = NULL;
|
||||
m_szGrp[TLK_IDLE] = NULL;
|
||||
m_szGrp[TLK_STARE] = NULL;
|
||||
m_szGrp[TLK_HELLO] = NULL;
|
||||
|
||||
m_szGrp[TLK_FEAR] = "RO_FEAR";
|
||||
m_szGrp[TLK_PLFEAR] = "RO_PLFEAR";
|
||||
m_szGrp[TLK_HEAL] = "RO_HEAL";
|
||||
|
||||
m_szGrp[TLK_USE] = "RO_OK";
|
||||
m_szGrp[TLK_UNUSE] = "RO_WAIT";
|
||||
m_szGrp[TLK_STOP] = "RO_STOP";
|
||||
m_szGrp[TLK_NOSHOOT] = "RO_SCARED";
|
||||
|
||||
m_szGrp[TLK_PLHURT1] = "!RO_CUREA";
|
||||
m_szGrp[TLK_PLHURT2] = "!RO_CUREB";
|
||||
m_szGrp[TLK_PLHURT3] = "!RO_CUREC";
|
||||
|
||||
m_szGrp[TLK_WOUND] = "RO_WOUND";
|
||||
m_szGrp[TLK_MORTAL] = "RO_MORTAL";
|
||||
|
||||
// get voice for head
|
||||
m_voicePitch = 100;
|
||||
}
|
||||
|
||||
int CRosenberg::FIdleSpeak( void )
|
||||
{
|
||||
return -1;
|
||||
}
|
|
@ -342,6 +342,7 @@ TYPEDESCRIPTION CBaseToggle::m_SaveData[] =
|
|||
DEFINE_FIELD( CBaseToggle, m_vecFinalAngle, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( CBaseToggle, m_sMaster, FIELD_STRING),
|
||||
DEFINE_FIELD( CBaseToggle, m_bitsDamageInflict, FIELD_INTEGER ), // damage type inflicted
|
||||
DEFINE_FIELD( CBaseToggle, m_iPlayerIndex, FIELD_INTEGER ), // Decay's player index
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CBaseToggle, CBaseAnimating )
|
||||
|
|
|
@ -56,6 +56,8 @@ const char *CTalkMonster::m_szFriends[TLK_CFRIENDS] =
|
|||
"monster_barney",
|
||||
"monster_scientist",
|
||||
"monster_sitting_scientist",
|
||||
"monster_rosenberg",
|
||||
"monster_wheelchair"
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define bit_saidHeard (1<<6)
|
||||
#define bit_saidSmelled (1<<7)
|
||||
|
||||
#define TLK_CFRIENDS 3
|
||||
#define TLK_CFRIENDS 5
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@ extern DLL_GLOBAL BOOL g_fGameOver;
|
|||
|
||||
CHalfLifeTeamplay::CHalfLifeTeamplay()
|
||||
{
|
||||
ALERT( at_console, "Half-Life multiplayer teamplay\n");
|
||||
m_DisableDeathMessages = FALSE;
|
||||
m_DisableDeathPenalty = FALSE;
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
#include "saverestore.h"
|
||||
#include "trains.h" // trigger_camera has train functionality
|
||||
#include "gamerules.h"
|
||||
#include "shake.h" // trigger_enddecay fading constants
|
||||
#include "effects.h" // env_render can use instance of CEnvMirroredLaser
|
||||
#include "triggers.h"
|
||||
#include "shellapi.h"
|
||||
|
||||
#define SF_TRIGGER_PUSH_START_OFF 2//spawnflag that makes trigger_push spawn turned OFF
|
||||
#define SF_TRIGGER_HURT_TARGETONCE 1// Only fire hurt target once
|
||||
|
@ -34,8 +38,14 @@
|
|||
#define SF_TRIGGER_HURT_NO_CLIENTS 8//spawnflag that makes trigger_push spawn turned OFF
|
||||
#define SF_TRIGGER_HURT_CLIENTONLYFIRE 16// trigger hurt will only fire its target if it is hurting a client
|
||||
#define SF_TRIGGER_HURT_CLIENTONLYTOUCH 32// only clients may touch this trigger.
|
||||
#define SF_MM_KILLTARGETS 2
|
||||
|
||||
// to help trigger entites define who is standing inside
|
||||
#define PF_PLAYER1 1
|
||||
#define PF_PLAYER2 2
|
||||
|
||||
extern DLL_GLOBAL BOOL g_fGameOver;
|
||||
extern bool bDecay;
|
||||
|
||||
extern void SetMovedir(entvars_t* pev);
|
||||
extern Vector VecBModelOrigin( entvars_t* pevBModel );
|
||||
|
@ -457,6 +467,7 @@ void CMultiManager::ManagerReport( void )
|
|||
#define SF_RENDER_MASKMODE ( 1 << 2 )
|
||||
#define SF_RENDER_MASKCOLOR ( 1 << 3 )
|
||||
|
||||
// TODO: it is rather slow using NETNAME to set renderfx, need to make list of those entities on level load
|
||||
class CRenderFxManager : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
|
@ -492,6 +503,38 @@ void CRenderFxManager::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T
|
|||
if( !FBitSet( pev->spawnflags, SF_RENDER_MASKCOLOR ) )
|
||||
pevTarget->rendercolor = pev->rendercolor;
|
||||
}
|
||||
} else
|
||||
if (!FStringNull(pev->netname))
|
||||
{
|
||||
edict_t* pentTarget = NULL;
|
||||
while ( 1 )
|
||||
{
|
||||
pentTarget = FIND_ENTITY_BY_NETNAME(pentTarget, STRING(pev->netname));
|
||||
if (FNullEnt(pentTarget))
|
||||
break;
|
||||
|
||||
// other env_renders also have netname specified, and we must not touch them, so:
|
||||
// if classname<>env_render then
|
||||
// do smthng
|
||||
if (FClassnameIs(pentTarget, "env_render"))
|
||||
break;
|
||||
|
||||
entvars_t *pevTarget = VARS( pentTarget );
|
||||
if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKFX ) )
|
||||
pevTarget->renderfx = pev->renderfx;
|
||||
if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKAMT ) )
|
||||
pevTarget->renderamt = pev->renderamt;
|
||||
if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKMODE ) )
|
||||
pevTarget->rendermode = pev->rendermode;
|
||||
if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKCOLOR ) )
|
||||
pevTarget->rendercolor = pev->rendercolor;
|
||||
|
||||
if (FClassnameIs(pentTarget, "env_mirroredlaser"))
|
||||
{
|
||||
CEnvMirroredLaser* pLaser = (CEnvMirroredLaser*)CBaseEntity::Instance(pentTarget);
|
||||
pLaser->ReColorLasers();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -552,6 +595,11 @@ void CBaseTrigger::KeyValue( KeyValueData *pkvd )
|
|||
m_bitsDamageInflict = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "player_index"))
|
||||
{
|
||||
m_iPlayerIndex = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseToggle::KeyValue( pkvd );
|
||||
}
|
||||
|
@ -1496,6 +1544,17 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||
}
|
||||
//ALERT( at_console, "Level touches %d levels\n", ChangeList( levels, 16 ) );
|
||||
ALERT( at_console, "CHANGE LEVEL: %s %s\n", st_szNextMap, st_szNextSpot );
|
||||
|
||||
/*
|
||||
Vyacheslav Dzhura: 8/9/2008
|
||||
DONE: COMMENTED - EXPERIMENTAL!!!!!!!!
|
||||
*/
|
||||
if ( g_pGameRules->IsCoOp )
|
||||
{
|
||||
char cmd[128];
|
||||
sprintf( cmd, "changelevel %s %s\n", st_szNextMap, st_szNextSpot );
|
||||
SERVER_COMMAND( cmd );
|
||||
} else
|
||||
CHANGE_LEVEL( st_szNextMap, st_szNextSpot );
|
||||
}
|
||||
|
||||
|
@ -1962,6 +2021,25 @@ LINK_ENTITY_TO_CLASS( trigger_endsection, CTriggerEndSection )
|
|||
|
||||
void CTriggerEndSection::EndSectionUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
char szFilename[MAX_PATH];
|
||||
GET_GAME_DIR( szFilename );
|
||||
strcat( szFilename, "\\manual\\credits.xml" );
|
||||
|
||||
char szFilename2[MAX_PATH];
|
||||
GET_GAME_DIR( szFilename2 );
|
||||
strcat( szFilename2, "\\manual" );
|
||||
|
||||
int i;
|
||||
|
||||
for( i = 0; i < strlen( szFilename ); i++)
|
||||
if ( szFilename[i] == '/' ) szFilename[i] = '\\';
|
||||
|
||||
for( i = 0; i < strlen( szFilename2 ); i++)
|
||||
if ( szFilename2[i] == '/' ) szFilename2[i] = '\\';
|
||||
|
||||
if (!IS_DEDICATED_SERVER())
|
||||
ShellExecute( GetActiveWindow(), "open", "iexplore", szFilename, szFilename2, SW_MAXIMIZE);
|
||||
|
||||
// Only save on clients
|
||||
if( pActivator && !pActivator->IsNetClient() )
|
||||
return;
|
||||
|
@ -2386,3 +2464,592 @@ void CTriggerCamera::Move()
|
|||
float fraction = 2 * gpGlobals->frametime;
|
||||
pev->velocity = ( ( pev->movedir * pev->speed ) * fraction ) + ( pev->velocity * ( 1 - fraction ) );
|
||||
}
|
||||
|
||||
//
|
||||
// TRIGGER_ENDDECAY
|
||||
//
|
||||
|
||||
class CTriggerEndDecay : public CBaseTrigger
|
||||
{
|
||||
//private:
|
||||
// int m_iPhase;
|
||||
public:
|
||||
void Spawn( void );
|
||||
void EXPORT EndDecayTouch( CBaseEntity *pOther );
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void EXPORT EndDecayUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void EXPORT EndDecayThink( void );
|
||||
|
||||
bool bIsFinal;
|
||||
bool bUsed;
|
||||
t_playerStats stats[3];
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_enddecay, CTriggerEndDecay );
|
||||
|
||||
void CTriggerEndDecay::Spawn( void )
|
||||
{
|
||||
bUsed = false;
|
||||
|
||||
if ( g_pGameRules->IsDeathmatch() )
|
||||
{
|
||||
REMOVE_ENTITY( ENT(pev) );
|
||||
return;
|
||||
}
|
||||
|
||||
InitTrigger();
|
||||
|
||||
SetThink( SUB_DoNothing );
|
||||
SetUse ( EndDecayUse );
|
||||
// If it is a "use only" trigger, then don't set the touch function.
|
||||
if ( ! (pev->spawnflags & SF_ENDSECTION_USEONLY) )
|
||||
SetTouch( EndDecayTouch );
|
||||
}
|
||||
/*
|
||||
|
||||
MOVED TO: decay_gamerules.cpp
|
||||
|
||||
char getGradeChar( int grade )
|
||||
{
|
||||
char gradeChar;
|
||||
switch ( grade )
|
||||
{
|
||||
case 3:
|
||||
gradeChar = 'D';
|
||||
break;
|
||||
case 2:
|
||||
gradeChar = 'C';
|
||||
break;
|
||||
case 1:
|
||||
gradeChar = 'B';
|
||||
break;
|
||||
case 0:
|
||||
gradeChar = 'A';
|
||||
break;
|
||||
default:
|
||||
gradeChar = 'D';
|
||||
break;
|
||||
}
|
||||
return gradeChar;
|
||||
}
|
||||
*/
|
||||
void CTriggerEndDecay::EndDecayUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
// Only save on clients
|
||||
//if ( pActivator && !pActivator->IsNetClient() )
|
||||
// return;
|
||||
|
||||
SetUse( NULL );
|
||||
|
||||
/*while (pActivator = UTIL_FindEntityByClassname(pActivator, "player"))
|
||||
{
|
||||
((CBasePlayer *)((CBaseEntity *)pActivator))->EnableControl(FALSE);
|
||||
}*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
CDecayRules *g_pDecayRules = (CDecayRules*)g_pGameRules;
|
||||
|
||||
// our players should have DecayId of 1 or 2, so "loop" between these two numbers only
|
||||
if ( this->bIsFinal == true )
|
||||
{
|
||||
int damageGrade;
|
||||
int killsGrade;
|
||||
int accuracyGrade;
|
||||
|
||||
char gradeChar[8];
|
||||
memset( gradeChar, 0, sizeof( gradeChar ) );
|
||||
|
||||
damageGrade = killsGrade = accuracyGrade = 3; // by default "D" to all categories
|
||||
|
||||
for (int i = 1; i <= 2; i++ )
|
||||
{
|
||||
t_playerStats *curStats = &g_pDecayRules->pStats[i];
|
||||
|
||||
// compute accuracy
|
||||
if ( ( curStats->shots * 100 ) != 0 )
|
||||
curStats->accuracy = (float)curStats->hits / (float)curStats->shots * 100;
|
||||
else
|
||||
curStats->accuracy = 0;
|
||||
|
||||
// go through grade values for C,B,A
|
||||
for (int j = 2; j >= 0; j-- )
|
||||
{
|
||||
if ( curStats->damage <= stats[j].damage )
|
||||
damageGrade = j;
|
||||
if ( curStats->kills >= stats[j].kills )
|
||||
killsGrade = j;
|
||||
|
||||
if ( curStats->accuracy >= stats[j].accuracy )
|
||||
accuracyGrade = j;
|
||||
}
|
||||
|
||||
if ( curStats->accuracy == 0 ) // not a single shot!!!
|
||||
accuracyGrade = 3;
|
||||
|
||||
int finalGrade = ( damageGrade + killsGrade + accuracyGrade ) / 3;
|
||||
g_pDecayRules->savePlayerStats( i, finalGrade, damageGrade, killsGrade, accuracyGrade );
|
||||
gradeChar[i] = g_pDecayRules->getGradeChar( finalGrade );
|
||||
}
|
||||
|
||||
char buf[256];
|
||||
sprintf( buf, "Player 1 grade: %c\nPlayer 2 grade: %c", gradeChar[1], gradeChar[2] );
|
||||
UTIL_ShowMessageAll( buf );
|
||||
}
|
||||
|
||||
UTIL_ScreenFadeAll( Vector(0, 0, 0), 7, 3, 255, FFADE_OUT );
|
||||
UTIL_ShowMessageAll( STRING(pev->message) );
|
||||
|
||||
pev->nextthink = gpGlobals->time + 7;
|
||||
SetThink( EndDecayThink );
|
||||
}
|
||||
|
||||
void CTriggerEndDecay::EndDecayThink( void )
|
||||
{
|
||||
|
||||
//********************************************************************************
|
||||
// Theoretically we should go there after level-end dialog which should be called
|
||||
// from client.dll from EndDecayUse, then player should choose next mission, read
|
||||
// it's briefing and continue game on that level, or restart current or exit the
|
||||
// game. Callback is done via console commands which are intercepted in this dll
|
||||
// in clien.cpp file which then could call methods of this trigger_enddecay
|
||||
//********************************************************************************
|
||||
|
||||
if ( bUsed == true )
|
||||
return;
|
||||
/*
|
||||
if ( pev->spawnflags & 2 )
|
||||
{
|
||||
bUsed = true;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
static char szNextMap[128];
|
||||
sprintf( szNextMap, "null" );
|
||||
|
||||
if (g_pGameRules->IsCoOp())
|
||||
{
|
||||
CDecayRules *g_pDecayRules = (CDecayRules*)g_pGameRules;
|
||||
sprintf( szNextMap, g_pDecayRules->getDecayNextMap() );
|
||||
}
|
||||
|
||||
//if ( pev->message )
|
||||
// g_engfuncs.pfnEndSection(STRING(pev->message));
|
||||
|
||||
bool bHasNextMap = ( strcmp( szNextMap, "null" ) != 0 );
|
||||
|
||||
|
||||
if ( this->bIsFinal )
|
||||
{
|
||||
if ( ( bHasNextMap == true ) && ( pev->spawnflags & 2 ) == false )
|
||||
CHANGE_LEVEL( szNextMap, NULL );
|
||||
else
|
||||
{
|
||||
if ( ( pev->spawnflags & 2 ) == false )
|
||||
{
|
||||
if ( pev->message )
|
||||
g_engfuncs.pfnEndSection(STRING(pev->message));
|
||||
else
|
||||
g_engfuncs.pfnEndSection( "Decay" );
|
||||
} // else map should be ended somehow via it's entities login
|
||||
}
|
||||
} else
|
||||
{
|
||||
// do restart of server
|
||||
char cmd[128];
|
||||
sprintf( cmd, "restart\n" );
|
||||
SERVER_COMMAND( cmd );
|
||||
}
|
||||
|
||||
/*
|
||||
if ( ( strcmp( szNextMap, "null" ) != 0 ) && ( this->bIsFinal == true ) )
|
||||
CHANGE_LEVEL( szNextMap, NULL );
|
||||
else {
|
||||
int mapId = g_pDecayRules->getDecayMapId();
|
||||
|
||||
if ( ( mapId == 11 ) || ( mapId == 12 ) ) // do not restart server for dy_outro or dy_alien
|
||||
{
|
||||
if ( pev->message )
|
||||
g_engfuncs.pfnEndSection(STRING(pev->message));
|
||||
else
|
||||
g_engfuncs.pfnEndSection( "Decay" );
|
||||
} else
|
||||
{
|
||||
// do restart of server
|
||||
char cmd[128];
|
||||
sprintf( cmd, "restart\n" );
|
||||
SERVER_COMMAND( cmd );
|
||||
}
|
||||
}
|
||||
*/
|
||||
// TODO: send here message to client.dll to popup level stats dialog
|
||||
// TODO: do we need this here?
|
||||
// pev->nextthink = gpGlobals->time + 10.0;
|
||||
// SetThink( SUB_DoNothing );
|
||||
bUsed = true;
|
||||
//UTIL_Remove( this );
|
||||
}
|
||||
|
||||
void CTriggerEndDecay::EndDecayTouch( CBaseEntity *pOther )
|
||||
{
|
||||
// Only save on clients
|
||||
if ( !pOther->IsNetClient() )
|
||||
return;
|
||||
|
||||
SetTouch( NULL );
|
||||
Use( pOther, pOther, USE_ON, 1 );
|
||||
// same as use below
|
||||
}
|
||||
|
||||
void CTriggerEndDecay :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "success"))
|
||||
{
|
||||
if (atoi( pkvd->szValue ) == 1)
|
||||
this->bIsFinal = true;
|
||||
else
|
||||
this->bIsFinal = false;
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
|
||||
//
|
||||
// WOUNDS (DAMAGE)
|
||||
//
|
||||
if (FStrEq(pkvd->szKeyName, "woundsa"))
|
||||
{
|
||||
this->stats[0].damage = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
|
||||
if (FStrEq(pkvd->szKeyName, "woundsb"))
|
||||
{
|
||||
this->stats[1].damage = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
if (FStrEq(pkvd->szKeyName, "woundsc"))
|
||||
{
|
||||
this->stats[2].damage = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
|
||||
//
|
||||
// KILLS
|
||||
//
|
||||
if (FStrEq(pkvd->szKeyName, "killsa"))
|
||||
{
|
||||
this->stats[0].kills = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
if (FStrEq(pkvd->szKeyName, "killsb"))
|
||||
{
|
||||
this->stats[1].kills = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
if (FStrEq(pkvd->szKeyName, "killsc"))
|
||||
{
|
||||
this->stats[2].kills = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
|
||||
//
|
||||
// ACCURACY
|
||||
//
|
||||
if (FStrEq(pkvd->szKeyName, "accuracya"))
|
||||
{
|
||||
this->stats[0].accuracy = atof( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
if (FStrEq(pkvd->szKeyName, "accuracyb"))
|
||||
{
|
||||
this->stats[1].accuracy = atof( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
if (FStrEq(pkvd->szKeyName, "accuracyc"))
|
||||
{
|
||||
this->stats[2].accuracy = atof( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
|
||||
if (FStrEq(pkvd->szKeyName, "section"))
|
||||
{
|
||||
// m_iszSectionName = ALLOC_STRING( pkvd->szValue );
|
||||
// Store this in message so we don't have to write save/restore for this ent
|
||||
pev->message = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseTrigger::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
//
|
||||
// TRIGGER_PLAYERFREEZE (based on code from Spirit of Half-Life SDK)
|
||||
//
|
||||
|
||||
class CPlayerFreeze: public CBaseDelay
|
||||
{
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void Think( void );
|
||||
EHANDLE m_hActivator;
|
||||
};
|
||||
|
||||
void CPlayerFreeze::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
CBasePlayer *client;
|
||||
client = NULL;
|
||||
while ( ((client = (CBasePlayer*)UTIL_FindEntityByClassname( client, "player" )) != NULL) && (!FNullEnt(client->edict())) )
|
||||
{
|
||||
if ( !client->pev )
|
||||
continue;
|
||||
|
||||
// if ( client->edict() == pEntity )
|
||||
// continue;
|
||||
|
||||
// if ( !(client->IsNetClient()) ) // Not a client ? (should never be true)
|
||||
// continue;
|
||||
|
||||
if (client->pev->flags & FL_FROZEN)
|
||||
client->EnableControl(TRUE);
|
||||
else
|
||||
client->EnableControl(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
pActivator = UTIL_FindEntityByClassname(NULL, "player");
|
||||
if (pActivator->pev->flags & FL_FROZEN)
|
||||
((CBasePlayer *)((CBaseEntity *)pActivator))->EnableControl(TRUE);
|
||||
else
|
||||
((CBasePlayer *)((CBaseEntity *)pActivator))->EnableControl(FALSE);
|
||||
*/
|
||||
|
||||
/*if (pActivator && pActivator->pev->flags & FL_CLIENT)
|
||||
{
|
||||
if (pActivator->pev->flags & FL_FROZEN)
|
||||
{
|
||||
// unfreeze him
|
||||
((CBasePlayer *)((CBaseEntity *)pActivator))->EnableControl(TRUE);
|
||||
m_hActivator = NULL;
|
||||
SetThink( SUB_DoNothing );
|
||||
}
|
||||
else
|
||||
{
|
||||
// freeze him
|
||||
((CBasePlayer *)((CBaseEntity *)pActivator))->EnableControl(FALSE);
|
||||
if (m_flDelay)
|
||||
{
|
||||
m_hActivator = pActivator;
|
||||
pev->nextthink = gpGlobals->time + m_flDelay;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void CPlayerFreeze::Think ( void )
|
||||
{
|
||||
Use(m_hActivator, this, USE_ON, 0);
|
||||
}
|
||||
|
||||
LINK_ENTITY_TO_CLASS( trigger_playerfreeze, CPlayerFreeze );
|
||||
|
||||
//
|
||||
// trigger_random
|
||||
//
|
||||
|
||||
class CTriggerRandom : public CBaseDelay
|
||||
{
|
||||
public:
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void Spawn( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
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_iRandomRange;
|
||||
float m_flProbability;
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_random, CTriggerRandom );
|
||||
|
||||
TYPEDESCRIPTION CTriggerRandom::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CTriggerRandom, m_iRandomRange, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CTriggerRandom, m_flProbability, FIELD_FLOAT ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE(CTriggerRandom,CBaseDelay);
|
||||
|
||||
void CTriggerRandom::KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "randomrange"))
|
||||
{
|
||||
m_iRandomRange = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
} else
|
||||
if (FStrEq(pkvd->szKeyName, "probability"))
|
||||
{
|
||||
m_flProbability = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseDelay::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
|
||||
void CTriggerRandom::Spawn( void )
|
||||
{
|
||||
}
|
||||
|
||||
void CTriggerRandom::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
int FireId = RANDOM_LONG(0, m_iRandomRange-1); // was 1, m_iRandomRange
|
||||
//SUB_UseTargets( this, USE_ON, 0 );
|
||||
|
||||
char m_iszFireTarget[60];
|
||||
sprintf( m_iszFireTarget, "%s%d", STRING( pev->target ), FireId);
|
||||
|
||||
CBaseEntity *pEnt = NULL;
|
||||
bool bFoundRandomTarget = false;
|
||||
while ((pEnt = UTIL_FindEntityByTargetname( pEnt, m_iszFireTarget )) != NULL)
|
||||
{
|
||||
pEnt->Use( pActivator, pCaller, useType, value );
|
||||
bFoundRandomTarget = true;
|
||||
}
|
||||
|
||||
if ( !bFoundRandomTarget )
|
||||
ALERT( at_console, "Randomly found entity `%s` not found!\n", m_iszFireTarget );
|
||||
|
||||
/*
|
||||
CBaseEntity *pTarget = UTIL_FindEntityByTargetname( NULL, m_iszFireTarget );
|
||||
if ( pTarget )
|
||||
pTarget->Use( pActivator, pCaller, useType, value );
|
||||
else
|
||||
ALERT( at_console, "Randomly found entity %s not found!\n", m_iszFireTarget );
|
||||
*/
|
||||
|
||||
//if ( pev->spawnflags & SF_RELAY_FIREONCE )
|
||||
// UTIL_Remove( this );
|
||||
}
|
||||
|
||||
//
|
||||
// trigger_bit and trigger_bit_counter (used in ht11lasers)
|
||||
//
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool Bits[8];
|
||||
} TBitArray;
|
||||
|
||||
TBitArray ByteToArray(byte Number)
|
||||
{
|
||||
int i;
|
||||
byte fl = 1;
|
||||
TBitArray MyArr;
|
||||
for (i = 0; i < 8; i++, fl = fl << 1) {
|
||||
MyArr.Bits[i] = Number & fl;
|
||||
}
|
||||
return MyArr;
|
||||
}
|
||||
|
||||
byte ArrayToByte(TBitArray A)
|
||||
{
|
||||
int i;
|
||||
byte fl = 1;
|
||||
byte Result;
|
||||
for (i = 0; i < 8; i++, fl = fl << 1) {
|
||||
if (A.Bits[i]) {
|
||||
Result = Result | fl;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
class CTriggerBit : public CBaseDelay
|
||||
{
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_bit, CTriggerBit );
|
||||
|
||||
void CTriggerBit::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
SUB_UseTargets( this, USE_TOGGLE, 1.0 );
|
||||
}
|
||||
|
||||
class CTriggerBitCounter : public CBaseDelay
|
||||
{
|
||||
public:
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
//void Spawn( void );
|
||||
//void Precache( void );
|
||||
void Think( void );
|
||||
|
||||
// use code, which will operates the bits
|
||||
// use activators skin field as bit which we need to toggle
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
||||
|
||||
int m_iTriggerMask;
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_bit_counter, CTriggerBitCounter );
|
||||
|
||||
TYPEDESCRIPTION CTriggerBitCounter::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CTriggerBitCounter, m_iTriggerMask, FIELD_INTEGER ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE(CTriggerBitCounter, CBaseDelay);
|
||||
|
||||
void CTriggerBitCounter::KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "triggermask"))
|
||||
{
|
||||
m_iTriggerMask = atoi( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseDelay::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CTriggerBitCounter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
//uncommentme
|
||||
//ALERT( at_console, "trigger_bit_counter used! bit id received %d\n", pActivator->pev->skin );
|
||||
|
||||
int m_iDesiredBit = pActivator->pev->skin;
|
||||
ASSERT( m_iDesiredBit<=8 );
|
||||
|
||||
TBitArray MyArr = ByteToArray( pev->skin );
|
||||
MyArr.Bits[m_iDesiredBit-1] = !MyArr.Bits[m_iDesiredBit-1];
|
||||
pev->skin = ArrayToByte(MyArr);
|
||||
if ( pev->skin == m_iTriggerMask )
|
||||
{
|
||||
ALERT( at_console, "trigger_bit_counter used! bit id received %d target %s\n", pActivator->pev->skin, STRING(pev->target) );
|
||||
SUB_UseTargets( this, USE_ON, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void CTriggerBitCounter::Think( void )
|
||||
{
|
||||
/* if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON )
|
||||
{
|
||||
SUB_UseTargets( this, triggerType, 0 );
|
||||
if ( pev->spawnflags & SF_AUTO_FIREONCE )
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -75,6 +75,93 @@ void U_Srand( unsigned int seed )
|
|||
glSeed = seed_table[seed & 0xff];
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_Intersect - moved here from controller.cpp and priest.cpp
|
||||
=====================
|
||||
*/
|
||||
|
||||
Vector UTIL_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 * a * c;
|
||||
t = sqrt( t ) / (2.0 * 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.1)
|
||||
t = 0.1;
|
||||
if (t > 10.0)
|
||||
t = 10.0;
|
||||
|
||||
Vector vecHit = vecTo + vecMove * t;
|
||||
return vecHit.Normalize( ) * flSpeed;
|
||||
}
|
||||
|
||||
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);
|
||||
UTIL_TraceLine( vecSrc, vecHullEnd, dont_ignore_monsters, pEntity, &tmpTrace );
|
||||
if ( tmpTrace.flFraction < 1.0 )
|
||||
{
|
||||
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.0 )
|
||||
{
|
||||
float thisDistance = (tmpTrace.vecEndPos - vecSrc).Length();
|
||||
if ( thisDistance < distance )
|
||||
{
|
||||
tr = tmpTrace;
|
||||
distance = thisDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_SharedRandomLong
|
||||
|
|
|
@ -408,6 +408,7 @@ extern DLL_GLOBAL const Vector g_vecZero;
|
|||
#define AMBIENT_SOUND_LARGERADIUS 8
|
||||
#define AMBIENT_SOUND_START_SILENT 16
|
||||
#define AMBIENT_SOUND_NOT_LOOPING 32
|
||||
#define AMBIENT_SHOWMESSAGE 512 // Decay: strings code
|
||||
|
||||
#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements
|
||||
|
||||
|
|
|
@ -396,6 +396,7 @@ TYPEDESCRIPTION CBasePlayerItem::m_SaveData[] =
|
|||
DEFINE_FIELD( CBasePlayerItem, m_iId, FIELD_INTEGER ),
|
||||
// DEFINE_FIELD( CBasePlayerItem, m_iIdPrimary, FIELD_INTEGER ),
|
||||
// DEFINE_FIELD( CBasePlayerItem, m_iIdSecondary, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CBasePlayerItem, DecayPlayerIndex, FIELD_INTEGER ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CBasePlayerItem, CBaseAnimating )
|
||||
|
@ -1228,6 +1229,7 @@ TYPEDESCRIPTION CWeaponBox::m_SaveData[] =
|
|||
DEFINE_ARRAY( CWeaponBox, m_rgiszAmmo, FIELD_STRING, MAX_AMMO_SLOTS ),
|
||||
DEFINE_ARRAY( CWeaponBox, m_rgpPlayerItems, FIELD_CLASSPTR, MAX_ITEM_TYPES ),
|
||||
DEFINE_FIELD( CWeaponBox, m_cAmmoTypes, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CWeaponBox, m_iPlayerIndex, FIELD_INTEGER ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CWeaponBox, CBaseEntity )
|
||||
|
@ -1264,6 +1266,9 @@ void CWeaponBox::Spawn( void )
|
|||
{
|
||||
Precache();
|
||||
|
||||
if (!m_iPlayerIndex)
|
||||
m_iPlayerIndex = 0;
|
||||
|
||||
pev->movetype = MOVETYPE_TOSS;
|
||||
pev->solid = SOLID_TRIGGER;
|
||||
|
||||
|
@ -1334,6 +1339,13 @@ void CWeaponBox::Touch( CBaseEntity *pOther )
|
|||
}
|
||||
|
||||
CBasePlayer *pPlayer = (CBasePlayer *)pOther;
|
||||
|
||||
if (m_iPlayerIndex != 0)
|
||||
{
|
||||
if (pPlayer->m_iDecayId != this->m_iPlayerIndex)
|
||||
return;
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
// dole out ammo
|
||||
|
|
|
@ -78,6 +78,8 @@ public:
|
|||
#define WEAPON_TRIPMINE 13
|
||||
#define WEAPON_SATCHEL 14
|
||||
#define WEAPON_SNARK 15
|
||||
#define WEAPON_DISPLACER 16
|
||||
#define WEAPON_VORTI 17
|
||||
|
||||
#define WEAPON_ALLWEAPONS (~(1<<WEAPON_SUIT))
|
||||
|
||||
|
@ -149,6 +151,7 @@ public:
|
|||
#define TRIPMINE_DEFAULT_GIVE 1
|
||||
#define SNARK_DEFAULT_GIVE 5
|
||||
#define HIVEHAND_DEFAULT_GIVE 8
|
||||
#define DISPLACER_DEFAULT_GIVE 60
|
||||
|
||||
// The amount of ammo given to a player by an ammo item.
|
||||
#define AMMO_URANIUMBOX_GIVE 20
|
||||
|
@ -258,9 +261,12 @@ public:
|
|||
CBasePlayer *m_pPlayer;
|
||||
CBasePlayerItem *m_pNext;
|
||||
int m_iId; // WEAPON_???
|
||||
int DecayPlayerIndex;
|
||||
|
||||
virtual int iItemSlot( void ) { return 0; } // return 0 to MAX_ITEMS_SLOTS, used in hud
|
||||
|
||||
virtual void KeyValue( KeyValueData* pkvd); // to read player_index property
|
||||
|
||||
int iItemPosition( void ) { return ItemInfoArray[ m_iId ].iPosition; }
|
||||
const char *pszAmmo1( void ) { return ItemInfoArray[ m_iId ].pszAmmo1; }
|
||||
int iMaxAmmo1( void ) { return ItemInfoArray[ m_iId ].iMaxAmmo1; }
|
||||
|
@ -448,6 +454,7 @@ public:
|
|||
int m_rgAmmo[MAX_AMMO_SLOTS];// ammo quantities
|
||||
|
||||
int m_cAmmoTypes;// how many ammo types packed into this box (if packed by a level designer)
|
||||
int m_iPlayerIndex; // Decay: player who can pickup this weaponbox 0 - both 1 - Gina 2 - Colette
|
||||
};
|
||||
|
||||
#if CLIENT_DLL
|
||||
|
@ -520,6 +527,49 @@ private:
|
|||
unsigned short m_usCrowbar;
|
||||
};
|
||||
|
||||
class CVortiHands : public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
int iItemSlot( void ) { return 1; }
|
||||
void EXPORT SwingAgain( void );
|
||||
void EXPORT Smack( void );
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void );
|
||||
void WeaponIdle( void );
|
||||
|
||||
void StartFire( void );
|
||||
void Fire( Vector vecOrigSrc, Vector vecDir, float flDamage );
|
||||
|
||||
float GetFullChargeTime( void );
|
||||
int Swing( int fFirst );
|
||||
BOOL Deploy( void );
|
||||
void Holster( int skiplocal = 0 );
|
||||
|
||||
// was this weapon just fired primary or secondary?
|
||||
// we need to know so we can pick the right set of effects.
|
||||
BOOL m_fPrimaryFire;
|
||||
int m_iSwing;
|
||||
int m_iSoundState; // don't save this
|
||||
TraceResult m_trHit;
|
||||
|
||||
virtual BOOL UseDecrement( void )
|
||||
{
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
unsigned short m_usVorti;
|
||||
unsigned short m_usVortiFire;
|
||||
unsigned short m_usVortiSpin;
|
||||
};
|
||||
|
||||
class CPython : public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -41,6 +41,8 @@ extern CBaseEntity *g_pLastSpawn;
|
|||
DLL_GLOBAL edict_t *g_pBodyQueueHead;
|
||||
CGlobalState gGlobalState;
|
||||
extern DLL_GLOBAL int gDisplayTitle;
|
||||
bool bDecay = false;
|
||||
bool bSlaveCoop = false;
|
||||
|
||||
extern void W_Precache( void );
|
||||
|
||||
|
@ -477,6 +479,23 @@ void CWorld::Precache( void )
|
|||
|
||||
g_pGameRules = InstallGameRules();
|
||||
|
||||
if (bDecay)
|
||||
{
|
||||
if (m_bSlaveCoop) // if was initialized using KeyValue call
|
||||
bSlaveCoop = m_bSlaveCoop;
|
||||
else // otherwise NULL, thus no alien mode
|
||||
bSlaveCoop = false;
|
||||
|
||||
CDecayRules *g_pDecayRules;
|
||||
g_pDecayRules = (CDecayRules*)g_pGameRules;
|
||||
g_pDecayRules->SetAlienMode( bSlaveCoop );
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
pEntity = CBaseEntity::Create( "trigger_autobot", g_vecZero, g_vecZero, edict() );
|
||||
if ( !pEntity )
|
||||
ALERT( at_aiconsole, "Autobot entity was not created!\n");
|
||||
}
|
||||
|
||||
//!!!UNDONE why is there so much Spawn code in the Precache function? I'll just keep it here
|
||||
|
||||
///!!!LATER - do we want a sound ent in deathmatch? (sjb)
|
||||
|
@ -713,6 +732,30 @@ void CWorld::KeyValue( KeyValueData *pkvd )
|
|||
}
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "startsuit") )
|
||||
{
|
||||
if ( atoi(pkvd->szValue) )
|
||||
{
|
||||
g_startSuit = atoi(pkvd->szValue);
|
||||
}
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "decay") )
|
||||
{
|
||||
if ( atoi(pkvd->szValue) )
|
||||
{
|
||||
bDecay = atoi(pkvd->szValue);
|
||||
}
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "slavecoop") )
|
||||
{
|
||||
if ( atoi(pkvd->szValue) )
|
||||
{
|
||||
m_bSlaveCoop = atoi(pkvd->szValue);
|
||||
}
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseEntity::KeyValue( pkvd );
|
||||
}
|
||||
|
|
|
@ -278,7 +278,6 @@ void CXenTree::Spawn( void )
|
|||
SET_MODEL( ENT( pev ), "models/tree.mdl" );
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
pev->solid = SOLID_BBOX;
|
||||
|
||||
pev->takedamage = DAMAGE_YES;
|
||||
|
||||
UTIL_SetSize( pev, Vector( -30, -30, 0 ), Vector( 30, 30, 188 ) );
|
||||
|
|
|
@ -1969,6 +1969,15 @@ void PM_UnDuck( void )
|
|||
newOrigin[i] += ( pmove->player_mins[1][i] - pmove->player_mins[0][i] );
|
||||
}
|
||||
}
|
||||
*/
|
||||
if ( pmove->onground != -1 && pmove->flags & FL_DUCKING && pmove->bInDuck == false)
|
||||
{
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
newOrigin[i] += ( pmove->player_mins[1][i] - pmove->player_mins[0][i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
trace = pmove->PM_PlayerTrace( newOrigin, newOrigin, PM_NORMAL, -1 );
|
||||
|
||||
|
|
Loading…
Reference in New Issue