1.1 --- a/extensions/tf2/extension.cpp Thu Apr 03 23:57:54 2008 +0000
1.2 +++ b/extensions/tf2/extension.cpp Fri Apr 04 22:37:14 2008 +0000
1.3 @@ -1,7 +1,7 @@
1.4 /**
1.5 * vim: set ts=4 :
1.6 * =============================================================================
1.7 - * SourceMod Counter-Strike:Source Extension
1.8 + * SourceMod Team Fortress 2 Extension
1.9 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.10 * =============================================================================
1.11 *
1.12 @@ -30,8 +30,10 @@
1.13 */
1.14
1.15 #include "extension.h"
1.16 +#include "util.h"
1.17 #include "RegNatives.h"
1.18 #include "iplayerinfo.h"
1.19 +#include "sm_trie_tpl.h"
1.20
1.21 /**
1.22 * @file extension.cpp
1.23 @@ -46,12 +48,35 @@
1.24
1.25 SMEXT_LINK(&g_TF2Tools);
1.26
1.27 -SendProp *playerSharedOffset;
1.28 +CGlobalVars *gpGlobals = NULL;
1.29 +
1.30 +sm_sendprop_info_t *playerSharedOffset;
1.31
1.32 extern sp_nativeinfo_t g_TFNatives[];
1.33
1.34 +int g_resourceEntity;
1.35 +
1.36 +SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int , int);
1.37 +
1.38 bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late)
1.39 {
1.40 + ServerClass *sc = UTIL_FindServerClass("CTFPlayer");
1.41 + if (sc == NULL)
1.42 + {
1.43 + snprintf(error, maxlength, "Could not find CTFPlayer server class");
1.44 +
1.45 + return false;
1.46 + }
1.47 +
1.48 + playerSharedOffset = new sm_sendprop_info_t;
1.49 +
1.50 + if (!UTIL_FindDataTable(sc->m_pTable, "DT_TFPlayerShared", playerSharedOffset, 0))
1.51 + {
1.52 + snprintf(error, maxlength, "Could not find DT_TFPlayerShared data table");
1.53 +
1.54 + return false;
1.55 + }
1.56 +
1.57 sharesys->AddDependency(myself, "bintools.ext", true, true);
1.58
1.59 char conf_error[255];
1.60 @@ -67,8 +92,6 @@
1.61 sharesys->AddNatives(myself, g_TFNatives);
1.62 sharesys->RegisterLibrary(myself, "tf2");
1.63
1.64 - playerSharedOffset = gamehelpers->FindInSendTable("CTFPlayer", "DT_TFPlayerShared");
1.65 -
1.66 playerhelpers->RegisterCommandTargetProcessor(this);
1.67
1.68 return true;
1.69 @@ -78,13 +101,20 @@
1.70 {
1.71 GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
1.72
1.73 + gpGlobals = ismm->GetCGlobals();
1.74 +
1.75 + SH_ADD_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_STATIC(OnServerActivate), true);
1.76 +
1.77 return true;
1.78 }
1.79
1.80 void TF2Tools::SDK_OnUnload()
1.81 {
1.82 + SH_REMOVE_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_STATIC(OnServerActivate), true);
1.83 +
1.84 g_RegNatives.UnregisterAll();
1.85 gameconfs->CloseGameConfigFile(g_pGameConf);
1.86 + playerhelpers->UnregisterCommandTargetProcessor(this);
1.87 }
1.88
1.89 void TF2Tools::SDK_OnAllLoaded()
1.90 @@ -114,23 +144,11 @@
1.91 g_RegNatives.UnregisterAll();
1.92 }
1.93
1.94 -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
1.95 +void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
1.96 {
1.97 - va_list ap;
1.98 - va_start(ap, fmt);
1.99 - size_t len = vsnprintf(buffer, maxlength, fmt, ap);
1.100 - va_end(ap);
1.101 + g_resourceEntity = FindResourceEntity();
1.102 +}
1.103
1.104 - if (len >= maxlength)
1.105 - {
1.106 - buffer[maxlength - 1] = '\0';
1.107 - return (maxlength - 1);
1.108 - }
1.109 - else
1.110 - {
1.111 - return len;
1.112 - }
1.113 -}
1.114
1.115 bool TF2Tools::ProcessCommandTarget(cmd_target_info_t *info)
1.116 {
1.117 @@ -227,3 +245,83 @@
1.118 return true;
1.119 }
1.120
1.121 +int FindResourceEntity()
1.122 +{
1.123 + return FindEntityByNetClass(-1, "CTFPlayerResource");
1.124 +}
1.125 +
1.126 +
1.127 +int FindEntityByNetClass(int start, const char *classname)
1.128 +{
1.129 + edict_t *current;
1.130 +
1.131 + for (int i = ((start != -1) ? start : 0); i < gpGlobals->maxEntities; i++)
1.132 + {
1.133 + current = engine->PEntityOfEntIndex(i);
1.134 + if (current == NULL)
1.135 + {
1.136 + continue;
1.137 + }
1.138 +
1.139 + IServerNetworkable *network = current->GetNetworkable();
1.140 +
1.141 + if (network == NULL)
1.142 + {
1.143 + continue;
1.144 + }
1.145 +
1.146 + ServerClass *sClass = network->GetServerClass();
1.147 + const char *name = sClass->GetName();
1.148 +
1.149 +
1.150 + if (strcmp(name, classname) == 0)
1.151 + {
1.152 + return i;
1.153 + }
1.154 + }
1.155 +
1.156 + return -1;
1.157 +}
1.158 +
1.159 +TFClassType ClassnameToType(const char *classname)
1.160 +{
1.161 + static KTrie<TFClassType> trie;
1.162 + static bool filled = false;
1.163 +
1.164 + if (!filled)
1.165 + {
1.166 + trie.insert("scout", TFClass_Scout);
1.167 + trie.insert("scout", TFClass_Scout);
1.168 + trie.insert("sniper", TFClass_Sniper);
1.169 + trie.insert("soldier", TFClass_Soldier);
1.170 + trie.insert("demoman", TFClass_DemoMan);
1.171 + trie.insert("demo", TFClass_DemoMan);
1.172 + trie.insert("medic", TFClass_Medic);
1.173 + trie.insert("heavy", TFClass_Heavy);
1.174 + trie.insert("hwg", TFClass_Heavy);
1.175 + trie.insert("pyro", TFClass_Pyro);
1.176 + trie.insert("spy", TFClass_Spy);
1.177 + trie.insert("engineer", TFClass_Engineer);
1.178 + trie.insert("engy", TFClass_Engineer);
1.179 +
1.180 + filled = true;
1.181 + }
1.182 +
1.183 + TFClassType *value;
1.184 +
1.185 + if (!(value = trie.retrieve(classname)))
1.186 + {
1.187 + return TFClass_Unknown;
1.188 + }
1.189 +
1.190 + return *value;
1.191 +}
1.192 +
1.193 +
1.194 +
1.195 +/**
1.196 + * A picture of a blue crab given to me as a gift and stored here for safe keeping
1.197 + *
1.198 + * http://www.democracycellproject.net/blog/archives/Clown%20car.jpg
1.199 + */
1.200 +