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"
33 #include <sh_vector.h>
37 const char *ClassName;
41 SourceHook::CVector<TeamInfo> g_Teams;
43 bool FindTeamEntities(SendTable *pTable, const char *name)
45 if (strcmp(pTable->GetName(), name) == 0)
50 int props = pTable->GetNumProps();
53 for (int i=0; i<props; i++)
55 prop = pTable->GetProp(i);
56 if (prop->GetDataTable())
58 if (FindTeamEntities(prop->GetDataTable(), name))
68 void SDKTools::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
73 for (int i=0; i<edictCount; i++)
75 edict_t *pEdict = engine->PEntityOfEntIndex(i);
76 if (!pEdict || pEdict->IsFree())
80 if (!pEdict->GetNetworkable())
85 ServerClass *pClass = pEdict->GetNetworkable()->GetServerClass();
86 if (FindTeamEntities(pClass->m_pTable, "DT_Team"))
88 SendProp *pTeamNumProp = g_pGameHelpers->FindInSendTable(pClass->GetName(), "m_iTeamNum");
90 if (pTeamNumProp != NULL)
92 int offset = pTeamNumProp->GetOffset();
93 CBaseEntity *pEnt = pEdict->GetUnknown()->GetBaseEntity();
94 int TeamIndex = *(int *)((unsigned char *)pEnt + offset);
96 if (TeamIndex >= (int)g_Teams.size())
98 g_Teams.resize(TeamIndex+1);
100 g_Teams[TeamIndex].ClassName = pClass->GetName();
101 g_Teams[TeamIndex].pEnt = pEnt;
107 static cell_t GetTeamCount(IPluginContext *pContext, const cell_t *params)
109 return g_Teams.size();
112 static int g_teamname_offset = -1;
113 static cell_t GetTeamName(IPluginContext *pContext, const cell_t *params)
115 int teamindex = params[1];
116 if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
118 return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
121 if (g_teamname_offset == 0)
123 return pContext->ThrowNativeError("Team names are not available on this game.");
126 if (g_teamname_offset == -1)
128 SendProp *prop = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_szTeamname");
132 g_teamname_offset = 0;
133 return pContext->ThrowNativeError("Team names are not available on this game.");
136 g_teamname_offset = prop->GetOffset();
139 char *name = (char *)((unsigned char *)g_Teams[teamindex].pEnt + g_teamname_offset);
141 pContext->StringToLocalUTF8(params[2], params[3], name, NULL);
146 static cell_t GetTeamScore(IPluginContext *pContext, const cell_t *params)
148 int teamindex = params[1];
149 if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
151 return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
154 static int offset = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_iScore")->GetOffset();
156 return *(int *)((unsigned char *)g_Teams[teamindex].pEnt + offset);
159 static cell_t SetTeamScore(IPluginContext *pContext, const cell_t *params)
161 int teamindex = params[1];
162 if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
164 return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
167 static int offset = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_iScore")->GetOffset();
168 *(int *)((unsigned char *)g_Teams[teamindex].pEnt + offset) = params[2];
173 static cell_t GetTeamClientCount(IPluginContext *pContext, const cell_t *params)
175 int teamindex = params[1];
176 if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
178 return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
181 SendProp *pProp = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "\"player_array\"");
182 ArrayLengthSendProxyFn fn = pProp->GetArrayLengthProxy();
184 return fn(g_Teams[teamindex].pEnt, 0);
187 sp_nativeinfo_t g_TeamNatives[] =
189 {"GetTeamCount", GetTeamCount},
190 {"GetTeamName", GetTeamName},
191 {"GetTeamScore", GetTeamScore},
192 {"SetTeamScore", SetTeamScore},
193 {"GetTeamClientCount", GetTeamClientCount},