aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/shared/gamerules_register.cpp
blob: 8f83ec9f4019dab6b2dd73515f0bdf70a6c84a6c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================//

#include "cbase.h"
#include "gamerules_register.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

// ------------------------------------------------------------------------------------------ //
// CGameRulesRegister implementation.
// ------------------------------------------------------------------------------------------ //

CGameRulesRegister* CGameRulesRegister::s_pHead = NULL;


CGameRulesRegister::CGameRulesRegister( const char *pClassName, CreateGameRulesFn fn )
{
	m_pClassName = pClassName;
	m_pFn = fn;
	
	m_pNext = s_pHead;	// Add us to the global list.
	s_pHead = this;
}

void CGameRulesRegister::CreateGameRules()
{
	m_pFn();
}

CGameRulesRegister* CGameRulesRegister::FindByName( const char *pName )
{
	for ( CGameRulesRegister *pCur=s_pHead; pCur; pCur=pCur->m_pNext )
	{
		if ( Q_stricmp( pName, pCur->m_pClassName ) == 0 )
			return pCur;
	}
	return NULL;
}


// ------------------------------------------------------------------------------------------ //
// Functions to dispatch the messages to create the game rules object on the client.
// ------------------------------------------------------------------------------------------ //
#define GAMERULES_STRINGTABLE_NAME		"GameRulesCreation"

#ifdef CLIENT_DLL
	#include "networkstringtable_clientdll.h"

	INetworkStringTable *g_StringTableGameRules = NULL;

	void OnGameRulesCreationStringChanged( void *object, INetworkStringTable *stringTable, int stringNumber, const char *newString, void const *newData )
	{
		// The server has created a new CGameRules object.
		delete g_pGameRules;
		g_pGameRules = NULL;

		const char *pClassName = (const char*)newData;
		CGameRulesRegister *pReg = CGameRulesRegister::FindByName( pClassName );
		if ( !pReg )
		{
			Error( "OnGameRulesCreationStringChanged: missing gamerules class '%s' on the client", pClassName );
		}

		// Create the new game rules object.
		pReg->CreateGameRules();

		if ( !g_pGameRules )
		{
			Error( "OnGameRulesCreationStringChanged: game rules entity (%s) not created", pClassName );
		}
	}

	// On the client, we respond to string table changes on the server.
	void InstallStringTableCallback_GameRules()
	{
		if ( !g_StringTableGameRules )
		{
			g_StringTableGameRules = networkstringtable->FindTable( GAMERULES_STRINGTABLE_NAME );
			if ( g_StringTableGameRules )
			{
				g_StringTableGameRules->SetStringChangedCallback( NULL, OnGameRulesCreationStringChanged );
			}
		}
	}

#else
	#include "networkstringtable_gamedll.h"

	INetworkStringTable *g_StringTableGameRules = NULL;

	void CreateNetworkStringTables_GameRules()
	{
		// Create the string tables
		g_StringTableGameRules = networkstringtable->CreateStringTable( GAMERULES_STRINGTABLE_NAME, 1 );

#ifdef CSTRIKE_DLL
		void CreateBlackMarketString( void );
		CreateBlackMarketString();
#endif
	}

	void CreateGameRulesObject( const char *pClassName )
	{
		// Delete the old game rules object.
		delete g_pGameRules;
		g_pGameRules = NULL;

		// Create a new game rules object.
		CGameRulesRegister *pReg = CGameRulesRegister::FindByName( pClassName );
		if ( !pReg )
			Error( "InitGameRules: missing gamerules class '%s' on the server", pClassName );
	
		pReg->CreateGameRules();
		if ( !g_pGameRules )
		{
			Error( "InitGameRules: game rules entity (%s) not created", pClassName );
		}

		// Make sure the client gets notification to make a new game rules object.
		Assert( g_StringTableGameRules );
		g_StringTableGameRules->AddString( true, "classname", strlen( pClassName ) + 1, pClassName );

		if ( g_pGameRules )
		{
			g_pGameRules->CreateCustomNetworkStringTables();
		}
	}			

#endif