//=======================
// ClientFog
//=======================
extern int gmsgSetFog;
CClientFog *CClientFog::FogCreate( void )
{
CClientFog *pFog = GetClassPtr( (CClientFog *)NULL );
pFog->pev->classname = MAKE_STRING("env_fog");
pFog->Spawn();
return pFog;
}
void CClientFog :: KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "startdist"))
{
m_iStartDist = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "enddist"))
{
m_iEndDist = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
CBaseEntity::KeyValue( pkvd );
}
void CClientFog :: Spawn ( void )
{
pev->effects |= EF_NODRAW;
pev->nextthink = gpGlobals->time + 0.5;
SetThink( FogThink );
}
void CClientFog :: FogThink ( void )
{
MESSAGE_BEGIN( MSG_ALL, gmsgSetFog, NULL );
WRITE_SHORT ( pev->rendercolor.x );
WRITE_SHORT ( pev->rendercolor.y );
WRITE_SHORT ( pev->rendercolor.z );
WRITE_SHORT ( m_iStartDist );
WRITE_SHORT ( m_iEndDist );
MESSAGE_END();
}
LINK_ENTITY_TO_CLASS( env_fog, CClientFog );
TYPEDESCRIPTION CClientFog::m_SaveData[] =
{
DEFINE_FIELD( CClientFog, m_iStartDist, FIELD_INTEGER ),
DEFINE_FIELD( CClientFog, m_iEndDist,FIELD_INTEGER ),
};
IMPLEMENT_SAVERESTORE(CClientFog,CBaseEntity);
Thats it, we're done with effects.ccp, but we still need to add a bit of code in effects.h at the bottom before the #endif:
//=======================
// ClientFog
//=======================
class CClientFog : public CBaseEntity
{
public:
void Spawn( void );
void KeyValue( KeyValueData *pkvd );
void EXPORT FogThink( void );
float m_iStartDist;
float m_iEndDist;
virtual int Save( CSave &save; );
virtual int Restore( CRestore &restore; );
static TYPEDESCRIPTION m_SaveData[];
public:
static CClientFog *FogCreate( void );
};
So, we're done with this. Head over to player.cpp. Here, at the top we can see the following line: extern DLL_GLOBAL int g_iSkillLevel, gDisplayTitle; Now, lets add a bit of code that will check if a new level gets loaded. To do this, simply copy the following line and replace the old one with it:if ( m_fRespawned )
{
m_fRespawned = FALSE;
MESSAGE_BEGIN( MSG_ONE, gmsgSetFog, NULL, pev );
CBaseEntity *pEntity = NULL;
pEntity = UTIL_FindEntityByClassname( pEntity, "env_fog" );
if ( pEntity )
{
CClientFog *pFog = (CClientFog *)pEntity;
WRITE_SHORT ( pFog->pev->rendercolor.x );
WRITE_SHORT ( pFog->pev->rendercolor.y );
WRITE_SHORT ( pFog->pev->rendercolor.z );
WRITE_SHORT ( pFog->m_iStartDist );
WRITE_SHORT ( pFog->m_iEndDist );
}
MESSAGE_END();
}
if (gLevelLoaded)
{
MESSAGE_BEGIN( MSG_ONE, gmsgSetFog, NULL, pev );
CBaseEntity *pEntity = NULL;
pEntity = UTIL_FindEntityByClassname( pEntity, "env_fog" );
CClientFog *pFog = (CClientFog *)pEntity;
if ( pEntity )
{
CClientFog *pFog = (CClientFog *)pEntity;
WRITE_SHORT ( pFog->pev->rendercolor.x );
WRITE_SHORT ( pFog->pev->rendercolor.y );
WRITE_SHORT ( pFog->pev->rendercolor.z );
WRITE_SHORT ( pFog->m_iStartDist );
WRITE_SHORT ( pFog->m_iEndDist );
}
else
{
WRITE_SHORT ( 0 );
WRITE_SHORT ( 0 );
WRITE_SHORT ( 0 );
WRITE_SHORT ( 0 );
WRITE_SHORT ( 0 );
}
MESSAGE_END();
gLevelLoaded = FALSE;
}
Thats it! We're all done with player.cpp. Now, lets open up player.h and add a variable in class CBasePlayer : public CBaseMonster:int CHud :: MsgFunc_SetFog( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
FogColor.x = TransformColor ( READ_SHORT() );
FogColor.y = TransformColor ( READ_SHORT() );
FogColor.z = TransformColor ( READ_SHORT() );
g_iStartDist = READ_SHORT();
g_iEndDist = READ_SHORT();
return 1;
}
This reads the information sent by the server and sends it to triapi, where it will be used to set the fog. We'll need to add a new function called Transformcolor, so open up util.cpp and add this at the bottom:
float TransformColor ( float color )
{
float trns_clr;
if(color >= 0 ) trns_clr = color / 255.0f;
else trns_clr = 1.0;//default value
return trns_clr;
}
There should be an util.h in your client workspace, if not make a new one and add the following code:
/***
*
* 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.
*
****/
// Vector.h
// A subset of the extdll.h in the project HL Entity DLL
//
// Misc C-runtime library headers
#include "STDIO.H"
#include "STDLIB.H"
#include "MATH.H"
float TransformColor ( float color );
If there otherwise is, then simply add the Transformcolor function. Now, open up tri.cpp, and add the following code at the top
#include <windows.h>
#include <gl/gl.h>
Now, after the #define add the following code
extern float g_iFogColor[4];
extern float g_iStartDist;
extern float g_iEndDist;
extern int g_iWaterLevel;
extern vec3_t FogColor;
extern engine_studio_api_t IEngineStudio;
After the void Draw_Triangles( void ) function add the following two functions:
void BlackFog ( void )
{
static float fColorBlack[3] = {0,0,0};
bool bFog = g_iStartDist > 0 && g_iEndDist > 0;
if (bFog)
gEngfuncs.pTriAPI->Fog ( fColorBlack, g_iStartDist, g_iEndDist, bFog );
else
gEngfuncs.pTriAPI->Fog ( g_iFogColor, g_iStartDist, g_iEndDist, bFog );
}
void RenderFog ( void )
{
float g_iFogColor[4] = { FogColor.x, FogColor.y, FogColor.z, 1.0 };
bool bFog = g_iStartDist > 0 && g_iEndDist > 0;
if ( bFog )
{
if ( IEngineStudio.IsHardware() == 2 )
{
gEngfuncs.pTriAPI->Fog ( g_iFogColor, g_iStartDist, g_iEndDist, bFog );
}
else if ( IEngineStudio.IsHardware() == 1 )
{
glEnable(GL_FOG);
glFogi (GL_FOG_MODE, GL_LINEAR);
glFogfv (GL_FOG_COLOR, g_iFogColor);
glFogf (GL_FOG_DENSITY, 1.0f);
glHint (GL_FOG_HINT, GL_DONT_CARE);
glFogf (GL_FOG_START, g_iStartDist);
glFogf (GL_FOG_END, g_iEndDist);
}
}
}
In void DLLEXPORT HUD_DrawNormalTriangles( void ) add this:@PointClass size(-16 -16 -16, 16 16 16) = env_fog : "Client Fog"
[
startdist(string) : "Start Distance" : "1"
enddist(integer) : "End Distance" : 1500
rendercolor(color255) : "Fog Color (R G B)" : "0 0 0"
]
I'd like to say help to those who helped me with this code:You must log in to post a comment. You can login or register a new account.
cdll_int.h(38,13): error C2040: 'HSPRITE': 'int' differs in levels of indirection from 'HSPRITE__ *'
Any ideas as to what is causing that?
Probably replacing all instances of vec_3t with Vector and DotProduct with FDotProduct should do the trick
Hold on, it does. I'm blind
That is not true, latest version of HL engine still uses Legacy GL functions but has shader compatibility. The reason why this tutorial doesn't work is that the shaders DON'T know if
glEnable(GL_FOG)
is run, it just is impossible. To make this tutorial work, theoretically you should replaceglEnable(GL_FOG)
with something likeglUniform1i(glGetUniformLocation(SHADERID, "fogEnabled"), (int)true)
but I have ZERO clue on how to find SHADERID atm.There is also an alternative method, you will have to modify the shader code for your mod though; which should be in "Half-Life/platform/gl_shaders/fs_world.frag". Replace
uniform bool fogEnabled
withlayout(location = 0) uniform bool fogEnabled
. Now go back into your code and replace everyglEnable(GL_FOG)
withglUniform1i(0, (int)true)
and obviously replace everyglDisable(GL_FOG)
withglUniform1i(0, (int)false)
.(And yes, I don't know how to reply lol)
Suggested change, in
CBasePlayer::Precache
function, addm_bSendMessages
here: