User:Dutchmega/code: Difference between revisions
No edit summary  | 
				 (→Is player AFK?:  Updated code)  | 
				||
| (6 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
I've got more of this stuff. Where should I put them all? Just here or... somewhere else... <sup>(Ha! you didn't expect the last 2 words, did you?)</sup>  | |||
== Making the antlion burn! ==  | == Making the antlion burn! ==  | ||
Add the following under <code>protected</code> in npc_antlion.h  | Add the following under <code>protected</code> in npc_antlion.h  | ||
| Line 15: | Line 18: | ||
}  | }  | ||
</pre>  | </pre>  | ||
== UTIL_LoadTexture ==  | == UTIL_LoadTexture ==  | ||
Here's a very handy function from the [[Plan_of_Attack|Plan Of Attack]] source.  | Here's a very handy function from the [[Plan_of_Attack|Plan Of Attack]] source.  | ||
<pre>  | <pre>  | ||
#ifdef CLIENT_DLL  | |||
int UTIL_LoadTexture(const char *szFile)  | int UTIL_LoadTexture(const char *szFile)  | ||
{  | {  | ||
	char szStr[256];  | 	char szStr[256];  | ||
| Line 45: | Line 47: | ||
	return iID;  | 	return iID;  | ||
}  | |||
#endif  | #endif  | ||
</pre>  | </pre>  | ||
| Line 85: | Line 85: | ||
Just don't forget to change the define everytime you release a new version  | Just don't forget to change the define everytime you release a new version  | ||
{{Note|add #include "version.h" to cdll_client_int.cpp and gameinterface.cpp.}}  | |||
== Improved lagcompensation code ==  | == Improved lagcompensation code ==  | ||
| Line 103: | Line 104: | ||
Also take a look at the code from [[SDK_Known_Issues_List#Sticky_Player_Collisions|Sticky Player Collisions]]  | Also take a look at the code from [[SDK_Known_Issues_List#Sticky_Player_Collisions|Sticky Player Collisions]]  | ||
==   | == PHP's substr ==  | ||
*   | By [[User:Vaber|Vaber]]:  | ||
*   | <pre>char * substr( char * dst, const char * src, signed int from, signed int to)  | ||
{  | |||
	if( (int)strlen( src ) < from )  | |||
	{  | |||
		strcpy( dst, src );  | |||
		return dst;  | |||
	}  | |||
	int ifrom = (from >= 0) ? from : ((int)strlen(src) + from);  | |||
* <  | 	int ito = (to >= 0) ? to : ((int)strlen(src) + to) - ifrom;  | ||
	int i = ifrom;  | |||
	int j = 0;  | |||
	for( ; i < ito + ifrom; i++, j++)  | |||
	{  | |||
		dst[ j ] = src[ i ];  | |||
	}  | |||
	dst[ j ] = 0;  | |||
	return dst;  | |||
}  | |||
char * substr( char * dst, const char * src, signed int pos )  | |||
{  | |||
	return substr( dst, src, pos, (int)strlen( src ) );  | |||
}</pre>  | |||
== UTIL_ModelToName ==  | |||
<pre>const char* UTIL_ModelToName(const char * modelName) {  | |||
	if ( Q_stristr(modelName, "combine_soldier") ) {  | |||
		return "Combine Soldier";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "combine_super_soldier") ) {  | |||
		return "Combine Elite";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "strider") ) {  | |||
		return "Strider";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "antlion_guard") ) {  | |||
		return "Antlionguard";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "antlion") ) {  | |||
		return "Antlion";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "headcrabblack") ) {  | |||
<  | 		return "Poison Headcrab";  | ||
	}  | |||
	else if ( Q_stristr(modelName, "headcrabclassic") ) {  | |||
		return "Headcrab";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "headcrab") ) {  | |||
		return "Fast Headcrab";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "zombie/poison") ) {  | |||
		return "Poison Zombie";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "zombie/fast") ) {  | |||
		return "Fast Zombie";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "zombie_soldier") ) {  | |||
		return "Zombine";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "zombie") ) {  | |||
		return "Zombie";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "Group01") ) {  | |||
		if( Q_stristr(modelName, "female") )  | |||
			return "Citizen Female";  | |||
		else if( Q_stristr(modelName, "male") )  | |||
			return "Citizen Male";  | |||
		return "Citizen";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "Group02") ) {  | |||
		if( Q_stristr(modelName, "female") )  | |||
			return "Refugee Female";  | |||
		else if( Q_stristr(modelName, "male") )  | |||
			return "Refugee Male";  | |||
		return "Refugee";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "Group03m") ) {  | |||
		if( Q_stristr(modelName, "female") )  | |||
			return "Rebel Female (Medic)";  | |||
		else if( Q_stristr(modelName, "male") )  | |||
			return "Rebel Male (Medic)";  | |||
		return "Rebel (Medic)";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "Group03") ) {  | |||
		if( Q_stristr(modelName, "female") )  | |||
			return "Rebel Female";  | |||
		else if( Q_stristr(modelName, "male") )  | |||
			return "Rebel Male";  | |||
		return "Rebel";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "barnacle") ) {  | |||
		return "Barnacle";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "icthyosaur") ) {  | |||
		return "Icthyosaur";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "manhack") ) {  | |||
		return "Combine Manhack";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "roller") ) {  | |||
		return "Combine Rollermine";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "police") ) {  | |||
		return "Combine Metrocop";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "turret") ) {  | |||
		return "Combine Turret";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "vortigaunt") ) {  | |||
		return "Vortigaunt";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "scanner") ) {  | |||
		return "Combine Scanner";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "dropship")  && !Q_stristr(modelName, "destroyed") ) {  | |||
		return "Combine Dropship";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "gunship")  && !Q_stristr(modelName, "destroyed") ) {  | |||
		return "Combine Gunship";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "helicopter")  && !Q_stristr(modelName, "destroyed") ) {  | |||
		return "Combine Helicopter";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "combine_mine01") ) {  | |||
		return "Combine Hopper";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "helicopter") ) {  | |||
		return "Combine Helicopter";  | |||
	}  | |||
	else if( Q_stristr(modelName, "alyx") && !Q_stristr(modelName, "gun") )  | |||
	{  | |||
		return "Alyx";  | |||
	}  | |||
	else if( Q_stristr(modelName, "breen.mdl") && !Q_stristr(modelName, "monitor") )  | |||
	{  | |||
		return "Breen";  | |||
	}  | |||
	else if( Q_stristr(modelName, "barney") && !Q_stristr(modelName, "helmet") )  | |||
	{  | |||
		return "Barney";  | |||
	}  | |||
	else if( Q_stristr(modelName, "kleiner") )  | |||
	{  | |||
		return "Kleiner";  | |||
	}  | |||
	else if( Q_stristr(modelName, "gman") )  | |||
	{  | |||
		return "G-Man";  | |||
	}  | |||
	else if( Q_stristr(modelName, "eli") && !Q_stristr(modelName, "_") ) // well, must be after hELIcopter :D  | |||
	{  | |||
		return "Eli";  | |||
	}  | |||
	else if ( Q_stristr(modelName, "dog.mdl") ) {  | |||
		return "Dog";  | |||
	}  | |||
	// APC as last, because it's only 3 letters  | |||
	else if ( Q_stristr(modelName, "apc") && !Q_stristr(modelName, "destroyed") ) {  | |||
		return "Combine APC";  | |||
	}  | |||
	return NULL;  | |||
}</pre>  | |||
== Is player AFK? ==  | |||
With this little code you can see which players are AFK. Nice for in the scoreboard.  | |||
Add to <code>multiplay_gamerules.cpp</code>:  | |||
<pre>ConVar	mp_afktime( "mp_afktime",  | |||
					  "20",  | |||
					  FCVAR_NOTIFY|FCVAR_REPLICATED,  | |||
					  "delay before setting unactive player as AFK" );</pre>  | |||
Open <code>player.cpp</code> and add after the includes:  | |||
<pre>extern ConVar mp_afktime;</pre>  | |||
Add to <code>CBasePlayer::CBasePlayer</code>:  | |||
<pre>m_fLastActive = 0.0f;  | |||
m_bAFK = false;</pre>  | |||
And add to the top of the function <code>CBasePlayer::PostThink</code>:  | |||
<pre>  | |||
if( m_nButtons == 0 )  | |||
{  | |||
	int diff1 = gpGlobals->curtime - m_fLastActive;  | |||
	int diff2 = gpGlobals->curtime - m_fLastPlayerTalkTime;  | |||
	if( diff1 > mp_afktime.GetInt() && diff2 > mp_afktime.GetInt() )  | |||
		m_bAFK = true;  | |||
}  | |||
else   | |||
{   | |||
	m_fLastActive = gpGlobals->curtime;   | |||
	m_bAFK = false;  | |||
}  | |||
</pre>  | |||
Also add to <code>player.h</code>:  | |||
<pre>  | |||
float m_fLastActive;  | |||
bool m_bAFK;  | |||
bool IsAFK() { return m_bAFK; }</pre>  | |||
Latest revision as of 04:50, 7 October 2006
I've got more of this stuff. Where should I put them all? Just here or... somewhere else... (Ha! you didn't expect the last 2 words, did you?)
Making the antlion burn!
Add the following under protected in npc_antlion.h
virtual	bool		AllowedToIgnite( void ) { return true; }
Well, now the damh thing burns but it doesn't visually respond to it. You can use the drown-animation: Add the following piece of code to the top of the function GatherConditions():
if( IsOnFire() )
{
	SetCondition( COND_ANTLION_IN_WATER );
}
UTIL_LoadTexture
Here's a very handy function from the Plan Of Attack source.
#ifdef CLIENT_DLL
int UTIL_LoadTexture(const char *szFile)
{
	char szStr[256];
	// try to pull it
	int iID = vgui::surface()->DrawGetTextureId(szFile);
	// did we get it?
	if(iID >= 0)
		return iID;
	// does the file exist?
	Q_snprintf(szStr, sizeof(szStr), "materials/%s.vmt", szFile);
	if(!vgui::filesystem()->FileExists(szStr))
	{
		DevMsg("UTIL_LoadTexture: texture %s does not exist!\n", szFile);
		return -1;
	}
	// create the new texture
	iID = vgui::surface()->CreateNewTextureID();
	vgui::surface()->DrawSetTextureFile(iID, szFile, true, false);
	return iID;
}
#endif
Disallow players connecting to a server with a different version
Add the file version.h to your game_shared and add it to both projects. Content:
#define VERSION "0.01"
Then add to cdll_client_int.cpp:
void cl_versionCallback_f( ConVar *var, char const *pOldString )
{
	if( Q_stricmp( var->GetString(), var->GetDefault() ) ) var->Revert();
}
static ConVar	cl_version	( "cl_version", VERSION, FCVAR_USERINFO|FCVAR_CLIENTDLL, "The version of this mod",
				cl_versionCallback_f );
Then open GameInterface.cpp and find the function ClientConnect()
Replace the contents of that function with this:
	// DM: Get the version of the client and compare it with the server's version
	const char* version = engine->GetClientConVarValue( engine->IndexOfEdict( pEdict ), "cl_version" );
	if (stricmp(VERSION, version) == 0)
	{
		return g_pGameRules->ClientConnected( pEdict, pszName, pszAddress, reject, maxrejectlen );
		// Aka true
	}
	else
	{
		char string [256];
		Q_snprintf( string, sizeof(string), "The server runs a different version (%s)", VERSION);
		Q_strcpy( reject, string ); 
		maxrejectlen = strlen(string);
		return false;
	}
Just don't forget to change the define everytime you release a new version
Improved lagcompensation code
Open dlls/player_lagcompensation.cpp and replace, around line 369
// lost track, too much difference return;
with
// DM: Some small improvements for lagcompensation // From Plan of Attack-source // did we found a context smaller then target time ? if ( record->m_flSimulationTime <= flTargetTime ) break; // hurra, stop // store this position for the next time through the loop prevOrg = record->m_vecOrigin; // go one step back curr = track->Next( curr );
Also take a look at the code from Sticky Player Collisions
PHP's substr
By Vaber:
char * substr( char * dst, const char * src, signed int from, signed int to)
{
	if( (int)strlen( src ) < from )
	{
		strcpy( dst, src );
		return dst;
	}
	int ifrom = (from >= 0) ? from : ((int)strlen(src) + from);
	int ito = (to >= 0) ? to : ((int)strlen(src) + to) - ifrom;
	int i = ifrom;
	int j = 0;
	for( ; i < ito + ifrom; i++, j++)
	{
		dst[ j ] = src[ i ];
	}
	dst[ j ] = 0;
	return dst;
}
char * substr( char * dst, const char * src, signed int pos )
{
	return substr( dst, src, pos, (int)strlen( src ) );
}
UTIL_ModelToName
const char* UTIL_ModelToName(const char * modelName) {
	if ( Q_stristr(modelName, "combine_soldier") ) {
		return "Combine Soldier";
	}
	else if ( Q_stristr(modelName, "combine_super_soldier") ) {
		return "Combine Elite";
	}
	else if ( Q_stristr(modelName, "strider") ) {
		return "Strider";
	}
	else if ( Q_stristr(modelName, "antlion_guard") ) {
		return "Antlionguard";
	}
	else if ( Q_stristr(modelName, "antlion") ) {
		return "Antlion";
	}
	else if ( Q_stristr(modelName, "headcrabblack") ) {
		return "Poison Headcrab";
	}
	else if ( Q_stristr(modelName, "headcrabclassic") ) {
		return "Headcrab";
	}
	else if ( Q_stristr(modelName, "headcrab") ) {
		return "Fast Headcrab";
	}
	else if ( Q_stristr(modelName, "zombie/poison") ) {
		return "Poison Zombie";
	}
	else if ( Q_stristr(modelName, "zombie/fast") ) {
		return "Fast Zombie";
	}
	else if ( Q_stristr(modelName, "zombie_soldier") ) {
		return "Zombine";
	}
	else if ( Q_stristr(modelName, "zombie") ) {
		return "Zombie";
	}
	else if ( Q_stristr(modelName, "Group01") ) {
		if( Q_stristr(modelName, "female") )
			return "Citizen Female";
		else if( Q_stristr(modelName, "male") )
			return "Citizen Male";
		
		return "Citizen";
	}
	else if ( Q_stristr(modelName, "Group02") ) {
		if( Q_stristr(modelName, "female") )
			return "Refugee Female";
		else if( Q_stristr(modelName, "male") )
			return "Refugee Male";
		
		return "Refugee";
	}
	else if ( Q_stristr(modelName, "Group03m") ) {
		if( Q_stristr(modelName, "female") )
			return "Rebel Female (Medic)";
		else if( Q_stristr(modelName, "male") )
			return "Rebel Male (Medic)";
		
		return "Rebel (Medic)";
	}
	else if ( Q_stristr(modelName, "Group03") ) {
		if( Q_stristr(modelName, "female") )
			return "Rebel Female";
		else if( Q_stristr(modelName, "male") )
			return "Rebel Male";
		
		return "Rebel";
	}
	else if ( Q_stristr(modelName, "barnacle") ) {
		return "Barnacle";
	}
	else if ( Q_stristr(modelName, "icthyosaur") ) {
		return "Icthyosaur";
	}
	else if ( Q_stristr(modelName, "manhack") ) {
		return "Combine Manhack";
	}
	else if ( Q_stristr(modelName, "roller") ) {
		return "Combine Rollermine";
	}
	else if ( Q_stristr(modelName, "police") ) {
		return "Combine Metrocop";
	}
	else if ( Q_stristr(modelName, "turret") ) {
		return "Combine Turret";
	}
	else if ( Q_stristr(modelName, "vortigaunt") ) {
		return "Vortigaunt";
	}
	else if ( Q_stristr(modelName, "scanner") ) {
		return "Combine Scanner";
	}
	else if ( Q_stristr(modelName, "dropship")  && !Q_stristr(modelName, "destroyed") ) {
		return "Combine Dropship";
	}
	else if ( Q_stristr(modelName, "gunship")  && !Q_stristr(modelName, "destroyed") ) {
		return "Combine Gunship";
	}
	else if ( Q_stristr(modelName, "helicopter")  && !Q_stristr(modelName, "destroyed") ) {
		return "Combine Helicopter";
	}
	else if ( Q_stristr(modelName, "combine_mine01") ) {
		return "Combine Hopper";
	}
	else if ( Q_stristr(modelName, "helicopter") ) {
		return "Combine Helicopter";
	}
	else if( Q_stristr(modelName, "alyx") && !Q_stristr(modelName, "gun") )
	{
		return "Alyx";
	}
	else if( Q_stristr(modelName, "breen.mdl") && !Q_stristr(modelName, "monitor") )
	{
		return "Breen";
	}
	else if( Q_stristr(modelName, "barney") && !Q_stristr(modelName, "helmet") )
	{
		return "Barney";
	}
	else if( Q_stristr(modelName, "kleiner") )
	{
		return "Kleiner";
	}
	else if( Q_stristr(modelName, "gman") )
	{
		return "G-Man";
	}
	else if( Q_stristr(modelName, "eli") && !Q_stristr(modelName, "_") ) // well, must be after hELIcopter :D
	{
		return "Eli";
	}
	else if ( Q_stristr(modelName, "dog.mdl") ) {
		return "Dog";
	}
	// APC as last, because it's only 3 letters
	else if ( Q_stristr(modelName, "apc") && !Q_stristr(modelName, "destroyed") ) {
		return "Combine APC";
	}
	
	return NULL;
}
Is player AFK?
With this little code you can see which players are AFK. Nice for in the scoreboard.
Add to multiplay_gamerules.cpp:
ConVar mp_afktime( "mp_afktime", "20", FCVAR_NOTIFY|FCVAR_REPLICATED, "delay before setting unactive player as AFK" );
Open player.cpp and add after the includes:
extern ConVar mp_afktime;
Add to CBasePlayer::CBasePlayer:
m_fLastActive = 0.0f; m_bAFK = false;
And add to the top of the function CBasePlayer::PostThink:
if( m_nButtons == 0 )
{
	int diff1 = gpGlobals->curtime - m_fLastActive;
	int diff2 = gpGlobals->curtime - m_fLastPlayerTalkTime;
	if( diff1 > mp_afktime.GetInt() && diff2 > mp_afktime.GetInt() )
		m_bAFK = true;
}
else 
{ 
	m_fLastActive = gpGlobals->curtime; 
	m_bAFK = false;
}
Also add to player.h:
float m_fLastActive;
bool m_bAFK;
bool IsAFK() { return m_bAFK; }