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>.
33 #include "CellRecipientFilter.h"
34 #include <IForwardSys.h>
36 SH_DECL_HOOK5_void(IVEngineServer, PlaybackTempEntity, SH_NOATTRIB, 0, IRecipientFilter &, float, const void *, const SendTable *, int);
38 CellRecipientFilter g_TERecFilter;
39 TempEntityInfo *g_CurrentTE = NULL;
40 int g_TEPlayers[SM_MAXPLAYERS+1];
41 bool tenatives_initialized = false;
43 /*************************
45 * Temp Entity Hook Class *
47 **************************/
49 void TempEntHooks::Initialize()
51 m_TEHooks = adtfactory->CreateBasicTrie();
52 plsys->AddPluginsListener(this);
53 tenatives_initialized = true;
56 void TempEntHooks::Shutdown()
58 if (!tenatives_initialized)
63 plsys->RemovePluginsListener(this);
64 SourceHook::List<TEHookInfo *>::iterator iter;
65 for (iter=m_HookInfo.begin(); iter!=m_HookInfo.end(); iter++)
75 tenatives_initialized = false;
78 void TempEntHooks::OnPluginUnloaded(IPlugin *plugin)
80 SourceHook::List<TEHookInfo *>::iterator iter = m_HookInfo.begin();
81 IPluginContext *pContext = plugin->GetBaseContext();
83 /* For each hook list... */
84 while (iter != m_HookInfo.end())
86 SourceHook::List<IPluginFunction *>::iterator f_iter = (*iter)->lst.begin();
88 /* Find the hooks on the given temp entity */
89 while (f_iter != (*iter)->lst.end())
91 /* If it matches, remove it and dec the ref count */
92 if ((*f_iter)->GetParentContext() == pContext)
94 f_iter = (*iter)->lst.erase(f_iter);
103 /* If there are no more hooks left, we can safely
104 * remove it from the cache and remove its list.
106 if ((*iter)->lst.size() == 0)
108 m_TEHooks->Delete((*iter)->te->GetName());
110 iter = m_HookInfo.erase(iter);
119 void TempEntHooks::_IncRefCounter()
121 if (m_HookCount++ == 0)
123 SH_ADD_HOOK(IVEngineServer, PlaybackTempEntity, engine, SH_MEMBER(this, &TempEntHooks::OnPlaybackTempEntity), false);
127 void TempEntHooks::_DecRefCounter()
129 if (--m_HookCount == 0)
131 SH_REMOVE_HOOK(IVEngineServer, PlaybackTempEntity, engine, SH_MEMBER(this, &TempEntHooks::OnPlaybackTempEntity), false);
135 size_t TempEntHooks::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter)
137 size_t size = static_cast<size_t>(pFilter->GetRecipientCount());
139 for (size_t i=0; i<size; i++)
142 #if SOURCE_ENGINE == SE_DOTA
143 index = pFilter->GetRecipientIndex(i).Get();
145 index = pFilter->GetRecipientIndex(i);
153 bool TempEntHooks::AddHook(const char *name, IPluginFunction *pFunc)
157 if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
159 pInfo->lst.push_back(pFunc);
162 if (!(te=g_TEManager.GetTempEntityInfo(name)))
167 pInfo = new TEHookInfo;
169 pInfo->lst.push_back(pFunc);
171 m_TEHooks->Insert(name, reinterpret_cast<void *>(pInfo));
172 m_HookInfo.push_back(pInfo);
180 bool TempEntHooks::RemoveHook(const char *name, IPluginFunction *pFunc)
184 if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
186 SourceHook::List<IPluginFunction *>::iterator iter;
187 if ((iter=pInfo->lst.find(pFunc)) != pInfo->lst.end())
189 pInfo->lst.erase(iter);
190 if (pInfo->lst.empty())
192 m_HookInfo.remove(pInfo);
193 m_TEHooks->Delete(name);
207 void TempEntHooks::OnPlaybackTempEntity(IRecipientFilter &filter, float delay, const void *pSender, const SendTable *pST, int classID)
210 const char *name = g_TEManager.GetNameFromThisPtr(const_cast<void *>(pSender));
212 if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
214 SourceHook::List<IPluginFunction *>::iterator iter;
215 IPluginFunction *pFunc;
217 cell_t res = static_cast<ResultType>(Pl_Continue);
219 TempEntityInfo *oldinfo = g_CurrentTE;
220 g_CurrentTE = pInfo->te;
221 size = _FillInPlayers(g_TEPlayers, &filter);
223 for (iter=pInfo->lst.begin(); iter!=pInfo->lst.end(); iter++)
226 pFunc->PushString(name);
227 pFunc->PushArray(g_TEPlayers, size);
228 pFunc->PushCell(size);
229 pFunc->PushFloat(delay);
230 pFunc->Execute(&res);
232 if (res != Pl_Continue)
234 g_CurrentTE = oldinfo;
235 RETURN_META(MRES_SUPERCEDE);
239 g_CurrentTE = oldinfo;
240 RETURN_META(MRES_IGNORED);
244 /**********************
246 * Temp Entity Natives *
248 ***********************/
250 TempEntHooks s_TempEntHooks;
252 static cell_t smn_TEStart(IPluginContext *pContext, const cell_t *params)
254 if (!g_TEManager.IsAvailable())
256 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
260 pContext->LocalToString(params[1], &name);
262 g_CurrentTE = g_TEManager.GetTempEntityInfo(name);
265 return pContext->ThrowNativeError("Invalid TempEntity name: \"%s\"", name);
271 static cell_t smn_TEWriteNum(IPluginContext *pContext, const cell_t *params)
273 if (!g_TEManager.IsAvailable())
275 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
279 return pContext->ThrowNativeError("No TempEntity call is in progress");
283 pContext->LocalToString(params[1], &prop);
285 if (!g_CurrentTE->TE_SetEntData(prop, params[2]))
287 return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
293 static cell_t smn_TEReadNum(IPluginContext *pContext, const cell_t *params)
295 if (!g_TEManager.IsAvailable())
297 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
301 return pContext->ThrowNativeError("No TempEntity call is in progress");
306 pContext->LocalToString(params[1], &prop);
308 if (!g_CurrentTE->TE_GetEntData(prop, &val))
310 return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
316 static cell_t smn_TE_WriteFloat(IPluginContext *pContext, const cell_t *params)
318 if (!g_TEManager.IsAvailable())
320 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
324 return pContext->ThrowNativeError("No TempEntity call is in progress");
328 pContext->LocalToString(params[1], &prop);
330 if (!g_CurrentTE->TE_SetEntDataFloat(prop, sp_ctof(params[2])))
332 return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
338 static cell_t smn_TE_ReadFloat(IPluginContext *pContext, const cell_t *params)
340 if (!g_TEManager.IsAvailable())
342 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
346 return pContext->ThrowNativeError("No TempEntity call is in progress");
351 pContext->LocalToString(params[1], &prop);
353 if (!g_CurrentTE->TE_GetEntDataFloat(prop, &val))
355 return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
361 static cell_t smn_TEWriteVector(IPluginContext *pContext, const cell_t *params)
363 if (!g_TEManager.IsAvailable())
365 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
369 return pContext->ThrowNativeError("No TempEntity call is in progress");
373 pContext->LocalToString(params[1], &prop);
376 pContext->LocalToPhysAddr(params[2], &addr);
377 float vec[3] = {sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2])};
379 if (!g_CurrentTE->TE_SetEntDataVector(prop, vec))
381 return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
387 static cell_t smn_TEReadVector(IPluginContext *pContext, const cell_t *params)
389 if (!g_TEManager.IsAvailable())
391 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
395 return pContext->ThrowNativeError("No TempEntity call is in progress");
399 pContext->LocalToString(params[1], &prop);
403 pContext->LocalToPhysAddr(params[2], &addr);
405 if (!g_CurrentTE->TE_GetEntDataVector(prop, vec))
407 return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
410 addr[0] = sp_ftoc(vec[0]);
411 addr[1] = sp_ftoc(vec[1]);
412 addr[2] = sp_ftoc(vec[2]);
417 static cell_t smn_TEWriteFloatArray(IPluginContext *pContext, const cell_t *params)
419 if (!g_TEManager.IsAvailable())
421 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
425 return pContext->ThrowNativeError("No TempEntity call is in progress");
429 pContext->LocalToString(params[1], &prop);
432 pContext->LocalToPhysAddr(params[2], &addr);
434 if (!g_CurrentTE->TE_SetEntDataFloatArray(prop, addr, params[3]))
436 return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
442 static cell_t smn_TESend(IPluginContext *pContext, const cell_t *params)
444 if (!g_TEManager.IsAvailable())
446 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
450 return pContext->ThrowNativeError("No TempEntity call is in progress");
454 unsigned int numClients;
456 IGamePlayer *pPlayer = NULL;
458 pContext->LocalToPhysAddr(params[1], &cl_array);
459 numClients = params[2];
461 /* Client validation */
462 for (unsigned int i = 0; i < numClients; i++)
464 client = cl_array[i];
465 pPlayer = playerhelpers->GetGamePlayer(client);
469 return pContext->ThrowNativeError("Client index %d is invalid", client);
470 } else if (!pPlayer->IsInGame()) {
471 return pContext->ThrowNativeError("Client %d is not connected", client);
475 g_TERecFilter.Reset();
476 g_TERecFilter.Initialize(cl_array, numClients);
478 g_CurrentTE->Send(g_TERecFilter, sp_ctof(params[3]));
484 static cell_t smn_TEIsValidProp(IPluginContext *pContext, const cell_t *params)
486 if (!g_TEManager.IsAvailable())
488 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
492 return pContext->ThrowNativeError("No TempEntity call is in progress");
496 pContext->LocalToString(params[1], &prop);
498 return g_CurrentTE->IsValidProp(prop) ? 1 : 0;
501 static cell_t smn_AddTempEntHook(IPluginContext *pContext, const cell_t *params)
504 IPluginFunction *pFunc;
506 if (!g_TEManager.IsAvailable())
508 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
511 pContext->LocalToString(params[1], &name);
512 pFunc = pContext->GetFunctionById(params[2]);
515 return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
518 if (!s_TempEntHooks.AddHook(name, pFunc))
520 return pContext->ThrowNativeError("Invalid TempEntity name: \"%s\"", name);
526 static cell_t smn_RemoveTempEntHook(IPluginContext *pContext, const cell_t *params)
529 IPluginFunction *pFunc;
531 if (!g_TEManager.IsAvailable())
533 return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
536 pContext->LocalToString(params[1], &name);
537 pFunc = pContext->GetFunctionById(params[2]);
540 return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
543 if (!s_TempEntHooks.RemoveHook(name, pFunc))
545 return pContext->ThrowNativeError("Invalid hooked TempEntity name or function");
551 sp_nativeinfo_t g_TENatives[] =
553 {"TE_Start", smn_TEStart},
554 {"TE_WriteNum", smn_TEWriteNum},
555 {"TE_ReadNum", smn_TEReadNum},
556 {"TE_WriteFloat", smn_TE_WriteFloat},
557 {"TE_ReadFloat", smn_TE_ReadFloat},
558 {"TE_WriteVector", smn_TEWriteVector},
559 {"TE_ReadVector", smn_TEReadVector},
560 {"TE_WriteAngles", smn_TEWriteVector},
561 {"TE_Send", smn_TESend},
562 {"TE_IsValidProp", smn_TEIsValidProp},
563 {"TE_WriteFloatArray", smn_TEWriteFloatArray},
564 {"AddTempEntHook", smn_AddTempEntHook},
565 {"RemoveTempEntHook", smn_RemoveTempEntHook},