faluco@1613: /** faluco@1613: * vim: set ts=4 : faluco@1613: * ============================================================================= faluco@1613: * SourceMod SDKTools Extension ds@1947: * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. faluco@1613: * ============================================================================= faluco@1613: * faluco@1613: * This program is free software; you can redistribute it and/or modify it under faluco@1613: * the terms of the GNU General Public License, version 3.0, as published by the faluco@1613: * Free Software Foundation. faluco@1613: * faluco@1613: * This program is distributed in the hope that it will be useful, but WITHOUT faluco@1613: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS faluco@1613: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more faluco@1613: * details. faluco@1613: * faluco@1613: * You should have received a copy of the GNU General Public License along with faluco@1613: * this program. If not, see . faluco@1613: * faluco@1613: * As a special exception, AlliedModders LLC gives you permission to link the faluco@1613: * code of this program (as well as its derivative works) to "Half-Life 2," the faluco@1613: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software faluco@1613: * by the Valve Corporation. You must obey the GNU General Public License in faluco@1613: * all respects for all other code used. Additionally, AlliedModders LLC grants faluco@1613: * this exception to all derivative works. AlliedModders LLC defines further faluco@1613: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), faluco@1613: * or . faluco@1613: * faluco@1613: * Version: $Id$ faluco@1613: */ faluco@1613: faluco@1613: #include "extension.h" faluco@1613: #include faluco@1613: faluco@1613: struct TeamInfo faluco@1613: { faluco@1613: const char *ClassName; faluco@1613: CBaseEntity *pEnt; faluco@1613: }; faluco@1613: faluco@1613: SourceHook::CVector g_Teams; faluco@1613: faluco@1613: bool FindTeamEntities(SendTable *pTable, const char *name) faluco@1613: { faluco@1997: if (strcmp(pTable->GetName(), name) == 0) faluco@1997: { faluco@1997: return true; faluco@1997: } faluco@1997: faluco@1613: int props = pTable->GetNumProps(); faluco@1613: SendProp *prop; faluco@1613: faluco@1613: for (int i=0; iGetProp(i); faluco@1613: if (prop->GetDataTable()) faluco@1613: { faluco@1613: if (FindTeamEntities(prop->GetDataTable(), name)) faluco@1613: { faluco@1613: return true; faluco@1613: } faluco@1613: } faluco@1613: } faluco@1613: faluco@1613: return false; faluco@1613: } faluco@1613: faluco@1993: void SDKTools::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax) faluco@1613: { faluco@1613: g_Teams.clear(); faluco@1613: g_Teams.resize(1); faluco@1613: faluco@1613: for (int i=0; iPEntityOfEntIndex(i); faluco@1613: if (!pEdict || pEdict->IsFree()) faluco@1613: { faluco@1613: continue; faluco@1613: } faluco@1613: if (!pEdict->GetNetworkable()) faluco@1613: { faluco@1613: continue; faluco@1613: } faluco@1613: faluco@1613: ServerClass *pClass = pEdict->GetNetworkable()->GetServerClass(); faluco@1613: if (FindTeamEntities(pClass->m_pTable, "DT_Team")) faluco@1613: { dvander@1673: SendProp *pTeamNumProp = g_pGameHelpers->FindInSendTable(pClass->GetName(), "m_iTeamNum"); dvander@1673: dvander@1673: if (pTeamNumProp != NULL) dvander@1673: { dvander@1673: int offset = pTeamNumProp->GetOffset(); dvander@1673: CBaseEntity *pEnt = pEdict->GetUnknown()->GetBaseEntity(); dvander@1673: int TeamIndex = *(int *)((unsigned char *)pEnt + offset); faluco@1613: dvander@1673: if (TeamIndex >= (int)g_Teams.size()) dvander@1673: { dvander@1673: g_Teams.resize(TeamIndex+1); dvander@1673: } dvander@1673: g_Teams[TeamIndex].ClassName = pClass->GetName(); dvander@1673: g_Teams[TeamIndex].pEnt = pEnt; faluco@1613: } faluco@1613: } faluco@1613: } faluco@1613: } faluco@1613: faluco@1613: static cell_t GetTeamCount(IPluginContext *pContext, const cell_t *params) faluco@1613: { faluco@1613: return g_Teams.size(); faluco@1613: } faluco@1613: dvander@2278: static int g_teamname_offset = -1; faluco@1613: static cell_t GetTeamName(IPluginContext *pContext, const cell_t *params) faluco@1613: { faluco@1613: int teamindex = params[1]; dvander@2274: if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName) faluco@1613: { dvander@2274: return pContext->ThrowNativeError("Team index %d is invalid", teamindex); ds@1952: } ds@1952: dvander@2278: if (g_teamname_offset == 0) dvander@2278: { dvander@2278: return pContext->ThrowNativeError("Team names are not available on this game."); faluco@1613: } faluco@1613: dvander@2278: if (g_teamname_offset == -1) dvander@2278: { dvander@2278: SendProp *prop = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_szTeamname"); dvander@2278: dvander@2278: if (prop == NULL) dvander@2278: { dvander@2278: g_teamname_offset = 0; dvander@2278: return pContext->ThrowNativeError("Team names are not available on this game."); dvander@2278: } dvander@2278: dvander@2278: g_teamname_offset = prop->GetOffset(); dvander@2278: } dvander@2278: dvander@2278: char *name = (char *)((unsigned char *)g_Teams[teamindex].pEnt + g_teamname_offset); faluco@1613: faluco@1613: pContext->StringToLocalUTF8(params[2], params[3], name, NULL); faluco@1613: faluco@1613: return 1; faluco@1613: } faluco@1613: faluco@1613: static cell_t GetTeamScore(IPluginContext *pContext, const cell_t *params) faluco@1613: { faluco@1613: int teamindex = params[1]; dvander@2274: if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName) faluco@1613: { dvander@2274: return pContext->ThrowNativeError("Team index %d is invalid", teamindex); faluco@1613: } faluco@1613: faluco@1613: static int offset = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_iScore")->GetOffset(); faluco@1613: faluco@1613: return *(int *)((unsigned char *)g_Teams[teamindex].pEnt + offset); faluco@1613: } faluco@1613: faluco@1613: static cell_t SetTeamScore(IPluginContext *pContext, const cell_t *params) faluco@1613: { faluco@1613: int teamindex = params[1]; dvander@2274: if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName) faluco@1613: { dvander@2274: return pContext->ThrowNativeError("Team index %d is invalid", teamindex); faluco@1613: } faluco@1613: faluco@1613: static int offset = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_iScore")->GetOffset(); faluco@1613: *(int *)((unsigned char *)g_Teams[teamindex].pEnt + offset) = params[2]; faluco@1613: faluco@1613: return 1; faluco@1613: } faluco@1613: faluco@1613: static cell_t GetTeamClientCount(IPluginContext *pContext, const cell_t *params) faluco@1613: { faluco@1613: int teamindex = params[1]; dvander@2274: if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName) faluco@1613: { dvander@2274: return pContext->ThrowNativeError("Team index %d is invalid", teamindex); faluco@1613: } faluco@1613: faluco@1613: SendProp *pProp = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "\"player_array\""); faluco@1613: ArrayLengthSendProxyFn fn = pProp->GetArrayLengthProxy(); faluco@1613: faluco@1613: return fn(g_Teams[teamindex].pEnt, 0); faluco@1613: } faluco@1613: faluco@1613: sp_nativeinfo_t g_TeamNatives[] = faluco@1613: { faluco@1613: {"GetTeamCount", GetTeamCount}, faluco@1613: {"GetTeamName", GetTeamName}, faluco@1613: {"GetTeamScore", GetTeamScore}, faluco@1613: {"SetTeamScore", SetTeamScore}, faluco@1613: {"GetTeamClientCount", GetTeamClientCount}, faluco@1613: {NULL, NULL} faluco@1613: };