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; iIsFree())
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;
dvander@2838:
dvander@2838: const char *tools_GetTeamName(int team)
dvander@2838: {
dvander@2838: if (size_t(team) >= g_Teams.size())
dvander@2838: return NULL;
dvander@2838: if (g_teamname_offset == 0)
dvander@2838: return NULL;
dvander@2838: if (g_teamname_offset == -1)
dvander@2838: {
dvander@2838: SendProp *prop = g_pGameHelpers->FindInSendTable(g_Teams[team].ClassName, "m_szTeamname");
dvander@2838: if (prop == NULL)
dvander@2838: {
dvander@2838: g_teamname_offset = 0;
dvander@2838: return NULL;
dvander@2838: }
dvander@2838: g_teamname_offset = prop->GetOffset();
dvander@2838: }
dvander@2838:
dvander@2838: return (const char *)((unsigned char *)g_Teams[team].pEnt + g_teamname_offset);
dvander@2838: }
dvander@2838:
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)
dvander@2274: return pContext->ThrowNativeError("Team index %d is invalid", teamindex);
ds@1952:
dvander@2278: if (g_teamname_offset == 0)
dvander@2278: return pContext->ThrowNativeError("Team names are not available on this game.");
dvander@2278:
dvander@2838: const char *name = tools_GetTeamName(teamindex);
dvander@2838: if (name == NULL)
dvander@2838: return pContext->ThrowNativeError("Team names are not available on this game.");
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();
skamonkey@3197:
skamonkey@3197: CBaseEntity *pTeam = g_Teams[teamindex].pEnt;
skamonkey@3197: *(int *)((unsigned char *)pTeam + offset) = params[2];
skamonkey@3197: gamehelpers->SetEdictStateChanged(pTeam, offset);
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: };