Update CS:GO team score gamedata.
3 * =============================================================================
4 * SourceMod SDKTools Extension
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "extension.h"
34 #include <sh_vector.h>
38 const char *ClassName;
44 SourceHook::CVector<TeamInfo> g_Teams;
46 void InitTeamNatives()
51 int edictCount = gpGlobals->maxEntities;
53 for (int i=0; i<edictCount; i++)
55 edict_t *pEdict = PEntityOfEntIndex(i);
56 if (!pEdict || pEdict->IsFree())
60 if (!pEdict->GetNetworkable())
65 ServerClass *pClass = pEdict->GetNetworkable()->GetServerClass();
66 if (FindNestedDataTable(pClass->m_pTable, "DT_Team"))
68 SendProp *pTeamNumProp = g_pGameHelpers->FindInSendTable(pClass->GetName(), "m_iTeamNum");
70 if (pTeamNumProp != NULL)
72 int offset = pTeamNumProp->GetOffset();
73 CBaseEntity *pEnt = pEdict->GetUnknown()->GetBaseEntity();
74 int TeamIndex = *(int *)((unsigned char *)pEnt + offset);
76 if (TeamIndex >= (int)g_Teams.size())
78 g_Teams.resize(TeamIndex+1);
80 g_Teams[TeamIndex].ClassName = pClass->GetName();
81 g_Teams[TeamIndex].pEnt = pEnt;
87 static cell_t GetTeamCount(IPluginContext *pContext, const cell_t *params)
89 return g_Teams.size();
92 static int g_teamname_offset = -1;
94 const char *tools_GetTeamName(int team)
96 if (size_t(team) >= g_Teams.size())
98 if (g_teamname_offset == 0)
100 if (g_teamname_offset == -1)
102 SendProp *prop = g_pGameHelpers->FindInSendTable(g_Teams[team].ClassName, "m_szTeamname");
105 g_teamname_offset = 0;
108 g_teamname_offset = prop->GetOffset();
111 return (const char *)((unsigned char *)g_Teams[team].pEnt + g_teamname_offset);
114 static cell_t GetTeamName(IPluginContext *pContext, const cell_t *params)
116 int teamindex = params[1];
117 if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
118 return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
120 if (g_teamname_offset == 0)
121 return pContext->ThrowNativeError("Team names are not available on this game.");
123 const char *name = tools_GetTeamName(teamindex);
125 return pContext->ThrowNativeError("Team names are not available on this game.");
127 pContext->StringToLocalUTF8(params[2], params[3], name, NULL);
132 static cell_t GetTeamScore(IPluginContext *pContext, const cell_t *params)
134 int teamindex = params[1];
135 if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
137 return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
142 m_iScore = g_pGameConf->GetKeyValue("m_iScore");
145 return pContext->ThrowNativeError("Failed to get m_iScore key");
149 static int offset = -1;
153 SendProp *prop = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, m_iScore);
156 return pContext->ThrowNativeError("Failed to get m_iScore prop");
158 offset = prop->GetOffset();
162 return *(int *)((unsigned char *)g_Teams[teamindex].pEnt + offset);
165 static cell_t SetTeamScore(IPluginContext *pContext, const cell_t *params)
167 if (!g_pSM->IsMapRunning())
169 return pContext->ThrowNativeError("Cannot set team score when no map is running");
172 int teamindex = params[1];
173 if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
175 return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
178 if (m_iScore == NULL)
180 m_iScore = g_pGameConf->GetKeyValue("m_iScore");
181 if (m_iScore == NULL)
183 return pContext->ThrowNativeError("Failed to get m_iScore key");
187 static int offset = -1;
191 SendProp *prop = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, m_iScore);
194 return pContext->ThrowNativeError("Failed to get m_iScore prop");
196 offset = prop->GetOffset();
199 CBaseEntity *pTeam = g_Teams[teamindex].pEnt;
200 *(int *)((unsigned char *)pTeam + offset) = params[2];
202 edict_t *pEdict = gameents->BaseEntityToEdict(pTeam);
203 gamehelpers->SetEdictStateChanged(pEdict, offset);
208 static cell_t GetTeamClientCount(IPluginContext *pContext, const cell_t *params)
210 int teamindex = params[1];
211 if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
213 return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
216 SendProp *pProp = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "\"player_array\"");
217 ArrayLengthSendProxyFn fn = pProp->GetArrayLengthProxy();
219 return fn(g_Teams[teamindex].pEnt, 0);
222 sp_nativeinfo_t g_TeamNatives[] =
224 {"GetTeamCount", GetTeamCount},
225 {"GetTeamName", GetTeamName},
226 {"GetTeamScore", GetTeamScore},
227 {"SetTeamScore", SetTeamScore},
228 {"GetTeamClientCount", GetTeamClientCount},