Paranoia2/cl_dll/hud_msg.cpp
2020-08-31 19:50:41 +03:00

613 lines
15 KiB
C++

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// hud_msg.cpp
//
#include "hud.h"
#include "cl_util.h"
#include "parsemsg.h"
#include "r_efx.h"
#include "studio.h"
#include "gl_local.h"
#include "gl_studio.h"
#include "stringlib.h"
#include "gl_rpart.h"
//LRC - the fogging fog
float g_fFogColor[3];
float g_fStartDist;
float g_fEndDist;
//int g_iFinalStartDist; //for fading
int g_iFinalEndDist; //for fading
float g_fFadeDuration; //negative = fading out
extern engine_studio_api_t IEngineStudio;
extern float v_idlescale;
extern int g_iGunMode;
#define MAX_CLIENTS 32
void EV_HLDM_WaterSplash( float x, float y, float z, float ScaleSplash1, float ScaleSplash2 );
int CHud :: MsgFunc_WaterSplash( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
float X, Y, Z, ScaleSplash1, ScaleSplash2;
X = READ_COORD();
Y = READ_COORD();
Z = READ_COORD();
ScaleSplash1 = READ_COORD();
ScaleSplash2 = READ_COORD();
EV_HLDM_WaterSplash( X, Y, Z, ScaleSplash1, ScaleSplash2 );
return 1;
}
void EV_HLDM_NewExplode( float x, float y, float z, float ScaleExplode1 );
int CHud :: MsgFunc_NewExplode( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
float X, Y, Z, ScaleExplode1;
X = READ_COORD();
Y = READ_COORD();
Z = READ_COORD();
ScaleExplode1 = READ_COORD();
EV_HLDM_NewExplode( X, Y, Z, ScaleExplode1 );
return 1;
}
/// USER-DEFINED SERVER MESSAGE HANDLERS
int CHud :: MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf )
{
// clear all hud data
HUDLIST *pList = m_pHudList;
while ( pList )
{
if ( pList->p )
pList->p->Reset();
pList = pList->pNext;
}
// reset sensitivity
m_flMouseSensitivity = 0;
// reset concussion effect
m_iConcussionEffect = 0;
m_flLevelTime = -1.0f;
//LRC - reset fog
m_flBlurAmount = 0;
g_fStartDist = 0;
g_fEndDist = 0;
g_iGunMode = 0;
return 1;
}
void CAM_ToFirstPerson(void);
void CHud :: MsgFunc_ViewMode( const char *pszName, int iSize, void *pbuf )
{
CAM_ToFirstPerson();
}
void CHud :: MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf )
{
m_flLevelTime = -1.0f;
//LRC - clear the fog
g_fStartDist = 0;
g_fEndDist = 0;
m_iSkyMode = SKY_OFF; //LRC
// prepare all hud data
HUDLIST *pList = m_pHudList;
while (pList)
{
if ( pList->p )
pList->p->InitHUDData();
pList = pList->pNext;
}
g_iGunMode = 0;
}
//LRC
void CHud :: MsgFunc_SetFog( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
for ( int i = 0; i < 3; i++ )
g_fFogColor[ i ] = READ_BYTE();
g_fFadeDuration = READ_SHORT();
g_fStartDist = READ_SHORT();
if (g_fFadeDuration > 0)
{
// // fading in
// g_fStartDist = READ_SHORT();
g_iFinalEndDist = READ_SHORT();
// g_fStartDist = FOG_LIMIT;
g_fEndDist = FOG_LIMIT;
}
else if (g_fFadeDuration < 0)
{
// // fading out
// g_iFinalStartDist =
g_iFinalEndDist = g_fEndDist = READ_SHORT();
}
else
{
// g_fStartDist = READ_SHORT();
g_fEndDist = READ_SHORT();
}
}
//LRC
void CHud :: MsgFunc_KeyedDLight( const char *pszName, int iSize, void *pbuf )
{
// CONPRINT("MSG:KeyedDLight");
BEGIN_READ( pbuf, iSize );
// as-yet unused:
// float decay; // drop this each second
// float minlight; // don't add when contributing less
// qboolean dark; // subtracts light instead of adding (doesn't seem to do anything?)
int iKey = READ_BYTE();
dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight( iKey );
int bActive = READ_BYTE();
if (!bActive)
{
// die instantly
dl->die = gEngfuncs.GetClientTime();
}
else
{
// never die
dl->die = gEngfuncs.GetClientTime() + 1E6;
dl->origin[0] = READ_COORD();
dl->origin[1] = READ_COORD();
dl->origin[2] = READ_COORD();
dl->radius = READ_BYTE();
dl->color.r = READ_BYTE();
dl->color.g = READ_BYTE();
dl->color.b = READ_BYTE();
}
}
//LRC
void CHud :: MsgFunc_SetSky( const char *pszName, int iSize, void *pbuf )
{
// CONPRINT("MSG:SetSky");
BEGIN_READ( pbuf, iSize );
m_iSkyMode = READ_BYTE();
m_vecSkyPos.x = READ_COORD();
m_vecSkyPos.y = READ_COORD();
m_vecSkyPos.z = READ_COORD();
}
int CHud :: MsgFunc_GameMode(const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
m_Teamplay = READ_BYTE();
return 1;
}
int CHud :: MsgFunc_Damage(const char *pszName, int iSize, void *pbuf )
{
int armor, blood;
Vector from;
int i;
float count;
BEGIN_READ( pbuf, iSize );
armor = READ_BYTE();
blood = READ_BYTE();
for (i=0 ; i<3 ; i++)
from[i] = READ_COORD();
count = (blood * 0.5) + (armor * 0.5);
if (count < 10)
count = 10;
// TODO: kick viewangles, show damage visually
return 1;
}
int CHud :: MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
m_iConcussionEffect = READ_BYTE();
if (m_iConcussionEffect)
this->m_StatusIcons.EnableIcon("dmg_concuss",255,160,0);
else
this->m_StatusIcons.DisableIcon("dmg_concuss");
return 1;
}
// buz: gasmask message
int CHud :: MsgFunc_GasMask( const char *pszName, int iSize, void *pbuf )
{
studiohdr_t *pStudioHeader;
mstudioseqdesc_t *pseq;
BEGIN_READ( pbuf, iSize );
gHUD.m_pHeadShieldEnt->model = IEngineStudio.Mod_ForName( "models/v_gasmask.mdl", true );
if( g_fRenderInitialized && RENDER_GET_PARM( PARM_WIDESCREEN, 0 ))
gHUD.m_pHeadShieldEnt->curstate.fuser2 = 4.2f; // offset
else gHUD.m_pHeadShieldEnt->curstate.fuser2 = 4.8f; // offset
// 0 is OFF; 1 is ON; 2 is fast switch to ON
switch( READ_BYTE( ))
{
case 0:
m_iHeadShieldState = SHIELD_TURNING_OFF;
m_pHeadShieldEnt->curstate.animtime = gEngfuncs.GetClientTime();
m_pHeadShieldEnt->curstate.sequence = SHIELDANIM_HOLSTER;
// get animation length in seconds
pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata( gHUD.m_pHeadShieldEnt->model );
pseq = (mstudioseqdesc_t *)((byte *)pStudioHeader + pStudioHeader->seqindex) + SHIELDANIM_HOLSTER;
m_flHeadShieldSwitchTime = gEngfuncs.GetClientTime() + (pseq->numframes / pseq->fps);
break;
case 1:
m_iHeadShieldState = SHIELD_TURNING_ON;
m_pHeadShieldEnt->curstate.animtime = gEngfuncs.GetClientTime();
m_pHeadShieldEnt->curstate.sequence = SHIELDANIM_DRAW;
// get animation length in seconds
pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata( gHUD.m_pHeadShieldEnt->model );
pseq = (mstudioseqdesc_t *)((byte *)pStudioHeader + pStudioHeader->seqindex) + SHIELDANIM_DRAW;
m_flHeadShieldSwitchTime = gEngfuncs.GetClientTime() + (pseq->numframes / pseq->fps);
break;
case 2:
m_iHeadShieldState = SHIELD_ON;
m_pHeadShieldEnt->curstate.animtime = gEngfuncs.GetClientTime();
m_pHeadShieldEnt->curstate.sequence = SHIELDANIM_IDLE;
}
return 1;
}
int CHud::MsgFunc_HeadShield( const char *pszName, int iSize, void *pbuf )
{
studiohdr_t *pStudioHeader;
mstudioseqdesc_t *pseq;
BEGIN_READ( pbuf, iSize );
gHUD.m_pHeadShieldEnt->model = IEngineStudio.Mod_ForName( "models/v_headshield.mdl", true );
if( g_fRenderInitialized && RENDER_GET_PARM( PARM_WIDESCREEN, 0 ))
gHUD.m_pHeadShieldEnt->curstate.fuser2 = 5.0f; // offset
else gHUD.m_pHeadShieldEnt->curstate.fuser2 = 16.0f; // offset
// 0 is OFF; 1 is ON; 2 is fast switch to ON
switch( READ_BYTE( ))
{
case 0:
m_iHeadShieldState = SHIELD_TURNING_OFF;
m_pHeadShieldEnt->curstate.animtime = gEngfuncs.GetClientTime();
m_pHeadShieldEnt->curstate.sequence = SHIELDANIM_HOLSTER;
// get animation length in seconds
pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata( gHUD.m_pHeadShieldEnt->model );
pseq = (mstudioseqdesc_t *)((byte *)pStudioHeader + pStudioHeader->seqindex) + SHIELDANIM_HOLSTER;
m_flHeadShieldSwitchTime = gEngfuncs.GetClientTime() + (pseq->numframes / pseq->fps);
break;
case 1:
m_iHeadShieldState = SHIELD_TURNING_ON;
m_pHeadShieldEnt->curstate.animtime = gEngfuncs.GetClientTime();
m_pHeadShieldEnt->curstate.sequence = SHIELDANIM_DRAW;
// get animation length in seconds
pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata( gHUD.m_pHeadShieldEnt->model );
pseq = (mstudioseqdesc_t *)((byte *)pStudioHeader + pStudioHeader->seqindex) + SHIELDANIM_DRAW;
m_flHeadShieldSwitchTime = gEngfuncs.GetClientTime() + (pseq->numframes / pseq->fps);
break;
case 2:
m_iHeadShieldState = SHIELD_ON;
m_pHeadShieldEnt->curstate.animtime = gEngfuncs.GetClientTime();
m_pHeadShieldEnt->curstate.sequence = SHIELDANIM_IDLE;
}
return 1;
}
// buz: special tank message
int CHud :: MsgFunc_SpecTank( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
m_SpecTank_on = READ_BYTE();
if (m_SpecTank_on == 0) // turn off
return 1;
else if (m_SpecTank_on == 2) // only ammo update
{
m_SpecTank_Ammo = READ_LONG();
m_Ammo.m_fFade = 200.0f;
}
else // turn on
{
m_SpecTank_point.x = READ_COORD();
m_SpecTank_point.y = READ_COORD();
m_SpecTank_point.z = READ_COORD();
m_SpecTank_defYaw = READ_COORD();
m_SpecTank_coneHor = READ_COORD();
m_SpecTank_coneVer = READ_COORD();
m_SpecTank_distFwd = READ_COORD();
m_SpecTank_distUp = READ_COORD();
m_SpecTank_Ammo = READ_LONG();
}
return 1;
}
int CHud :: MsgFunc_MusicFade( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
MUSIC_FADE_VOLUME( (float)READ_SHORT() / 100.0f );
return 1;
}
int CHud :: MsgFunc_Particle( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
int entindex = READ_SHORT();
char *sz = READ_STRING();
int attachment = READ_BYTE();
UTIL_CreateAurora( GET_ENTITY( entindex ), sz, attachment );
return 1;
}
int CHud :: MsgFunc_DelParticle( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
int entindex = READ_SHORT();
UTIL_RemoveAurora( GET_ENTITY( entindex ));
return 1;
}
int CHud :: MsgFunc_RainData( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
ParseRain();
return 1;
}
int CHud :: MsgFunc_WeaponAnim( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
int sequence = READ_BYTE();
float framerate = READ_BYTE() * 0.125f;
UTIL_WeaponAnimation( sequence, framerate );
return 1;
}
int CHud :: MsgFunc_WeaponBody( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
GET_VIEWMODEL()->curstate.body = READ_BYTE();
return 1;
}
int CHud :: MsgFunc_WeaponSkin( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
GET_VIEWMODEL()->curstate.skin = READ_BYTE();
return 1;
}
// 3d skybox
int CHud :: MsgFunc_SkyMarker( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
tr.sky_origin.x = READ_COORD();
tr.sky_origin.y = READ_COORD();
tr.sky_origin.z = READ_COORD();
return 1;
}
// 3d skybox
int CHud :: MsgFunc_WorldMarker( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
tr.sky_world_origin.x = READ_COORD();
tr.sky_world_origin.y = READ_COORD();
tr.sky_world_origin.z = READ_COORD();
tr.sky_speed = READ_COORD();
Msg( "sky_speed: %g\n", tr.sky_speed );
return 1;
}
int CHud :: MsgFunc_CustomDecal( const char *pszName, int iSize, void *pbuf )
{
char name[80];
BEGIN_READ( pbuf, iSize );
Vector pos, normal;
pos.x = READ_COORD();
pos.y = READ_COORD();
pos.z = READ_COORD();
normal.x = READ_COORD() / 8192.0f;
normal.y = READ_COORD() / 8192.0f;
normal.z = READ_COORD() / 8192.0f;
int entityIndex = READ_SHORT();
int modelIndex = READ_SHORT();
Q_strncpy( name, READ_STRING(), sizeof( name ));
int flags = READ_BYTE();
float angle = READ_ANGLE();
CreateDecal( pos, normal, angle, name, flags, entityIndex, modelIndex );
return 1;
}
int CHud :: MsgFunc_StudioDecal( const char *pszName, int iSize, void *pbuf )
{
Vector vecEnd, vecNormal, vecScale = g_vecZero;
char name[80];
BEGIN_READ( pbuf, iSize );
vecEnd.x = READ_COORD();
vecEnd.y = READ_COORD();
vecEnd.z = READ_COORD();
vecNormal.x = READ_COORD() * 0.001f;
vecNormal.y = READ_COORD() * 0.001f;
vecNormal.z = READ_COORD() * 0.001f;
int entityIndex = READ_SHORT();
int modelIndex = READ_SHORT();
Q_strncpy( name, READ_STRING(), sizeof( name ));
int flags = READ_BYTE();
modelstate_t state;
state.sequence = READ_SHORT();
state.frame = READ_SHORT();
state.blending[0] = READ_BYTE();
state.blending[1] = READ_BYTE();
state.controller[0] = READ_BYTE();
state.controller[1] = READ_BYTE();
state.controller[2] = READ_BYTE();
state.controller[3] = READ_BYTE();
state.body = READ_BYTE();
state.skin = READ_BYTE();
int cacheID = READ_SHORT();
if( REMAIN_BYTES( ))
{
vecScale.x = READ_COORD() * 0.001f;
vecScale.y = READ_COORD() * 0.001f;
vecScale.z = READ_COORD() * 0.001f;
}
cl_entity_t *ent = GET_ENTITY( entityIndex );
if( !ent )
{
// something very bad happens...
ALERT( at_error, "StudioDecal: ent == NULL\n" );
return 1;
}
g_StudioRenderer.PushEntityState( ent );
g_StudioRenderer.ModelStateToEntity( ent, &state );
// restore model in case decalmessage was delivered early than delta-update
if( !ent->model && modelIndex != 0 )
ent->model = IEngineStudio.GetModelByIndex( modelIndex );
if( cacheID )
{
// tell the code about vertex lighting
SetBits( ent->curstate.iuser1, CF_STATIC_ENTITY );
ent->curstate.colormap = cacheID;
}
if( !RENDER_GET_PARM( PARM_CLIENT_ACTIVE, 0 ) && FBitSet( ent->curstate.iuser1, CF_STATIC_ENTITY ))
ent->curstate.startpos = vecScale; // restore scale here
if( !ent->model || ent->model->type != mod_studio )
return 1;
g_StudioRenderer.StudioDecalShoot( vecNormal, vecEnd, name, ent, flags, &state );
g_StudioRenderer.PopEntityState( ent );
return 1;
}
int CHud :: MsgFunc_PartEffect( const char *pszName, int iSize, void *pbuf )
{
char name[80];
BEGIN_READ( pbuf, iSize );
Vector pos, normal;
pos.x = READ_COORD();
pos.y = READ_COORD();
pos.z = READ_COORD();
normal.x = READ_COORD() / 8192.0f;
normal.y = READ_COORD() / 8192.0f;
normal.z = READ_COORD() / 8192.0f;
Q_strncpy( name, READ_STRING(), sizeof( name ));
g_pParticles.CreateEffect( name, pos, normal );
return 1;
}
int CHud :: MsgFunc_LevelTime( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
m_flLevelTime = READ_FLOAT();
return 1;
}
int CHud :: MsgFunc_BlurEffect( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
m_flBlurAmount = (float)READ_SHORT() / 10000.0f;
v_idlescale = m_flBlurAmount * 100.0f;
// reset blur on a next level
if( !RENDER_GET_PARM( PARM_CLIENT_ACTIVE, 0 ))
{
m_flBlurAmount = 0.0f;
v_idlescale = 0.0f;
}
return 1;
}