1.1 --- a/extensions/sdktools/vnatives.cpp Tue May 24 20:36:09 2011 -0400
1.2 +++ b/extensions/sdktools/vnatives.cpp Wed May 25 08:27:27 2011 -0400
1.3 @@ -40,6 +40,7 @@
1.4 #include <inetchannel.h>
1.5 #include <iclient.h>
1.6 #include "iserver.h"
1.7 +#include <iserverentity.h>
1.8
1.9 SourceHook::List<ValveCall *> g_RegCalls;
1.10 SourceHook::List<ICallWrapper *> g_CallWraps;
1.11 @@ -630,6 +631,66 @@
1.12 return got_angles ? 1 : 0;
1.13 }
1.14
1.15 +#if SOURCE_ENGINE >= SE_ORANGEBOX
1.16 +static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
1.17 +{
1.18 + char *searchname;
1.19 + CBaseEntity *pEntity;
1.20 +
1.21 + if (params[1] == -1)
1.22 + {
1.23 + pEntity = (CBaseEntity *)servertools->FirstEntity();
1.24 + }
1.25 + else
1.26 + {
1.27 + pEntity = gamehelpers->ReferenceToEntity(params[1]);
1.28 + if (!pEntity)
1.29 + {
1.30 + return pContext->ThrowNativeError("Entity %d (%d) is invalid",
1.31 + gamehelpers->ReferenceToIndex(params[1]),
1.32 + params[1]);
1.33 + }
1.34 + }
1.35 +
1.36 + pContext->LocalToString(params[2], &searchname);
1.37 +
1.38 + char buffer[128];
1.39 + const char *classname = buffer;
1.40 + int lastcharpos;
1.41 + bool ismatch = false;
1.42 +
1.43 + while (pEntity)
1.44 + {
1.45 + if (!servertools->GetKeyValue(pEntity, "classname", buffer, sizeof(buffer)))
1.46 + {
1.47 + pEntity = (CBaseEntity *)servertools->NextEntity(pEntity);
1.48 + continue;
1.49 + }
1.50 +
1.51 + lastcharpos = strlen(searchname);
1.52 + if (searchname[lastcharpos-1] == '*')
1.53 + {
1.54 + if (strncasecmp(searchname, classname, lastcharpos-1) == 0)
1.55 + {
1.56 + ismatch = true;
1.57 + }
1.58 + }
1.59 + else if (strcasecmp(searchname, classname) == 0)
1.60 + {
1.61 + ismatch = true;
1.62 + }
1.63 +
1.64 + if (ismatch)
1.65 + {
1.66 + return gamehelpers->EntityToBCompatRef(pEntity);
1.67 + }
1.68 +
1.69 + pEntity = (CBaseEntity *)servertools->NextEntity(pEntity);
1.70 + }
1.71 +
1.72 + return -1;
1.73 +}
1.74 +#else
1.75 static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
1.76 {
1.77 static ValveCall *pCall = NULL;
1.78 @@ -656,33 +717,14 @@
1.79
1.80 return gamehelpers->EntityToBCompatRef(pEntity);
1.81 }
1.82 +#endif
1.83
1.84 -#if SOURCE_ENGINE >= SE_LEFT4DEAD
1.85 +#if SOURCE_ENGINE >= SE_ORANGEBOX
1.86 static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params)
1.87 {
1.88 - static ValveCall *pCall = NULL;
1.89 - if (!pCall)
1.90 - {
1.91 - ValvePassInfo pass[4];
1.92 - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
1.93 - InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
1.94 - InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.95 - InitPass(pass[3], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
1.96 - if (!CreateBaseCall("CreateEntityByName", ValveCall_Static, &pass[3], pass, 3, &pCall))
1.97 - {
1.98 - return pContext->ThrowNativeError("\"CreateEntityByName\" not supported by this mod");
1.99 - } else if (!pCall) {
1.100 - return pContext->ThrowNativeError("\"CreateEntityByName\" wrapper failed to initialize");
1.101 - }
1.102 - }
1.103 -
1.104 - CBaseEntity *pEntity = NULL;
1.105 - START_CALL();
1.106 - DECODE_VALVE_PARAM(1, vparams, 0);
1.107 - DECODE_VALVE_PARAM(2, vparams, 1);
1.108 - *(bool *)(vptr + 8) = true;
1.109 - FINISH_CALL_SIMPLE(&pEntity);
1.110 -
1.111 + char *classname;
1.112 + pContext->LocalToString(params[1], &classname);
1.113 + CBaseEntity *pEntity = (CBaseEntity *)servertools->CreateEntityByName(classname);
1.114 return gamehelpers->EntityToBCompatRef(pEntity);
1.115 }
1.116 #else
1.117 @@ -713,32 +755,18 @@
1.118 }
1.119 #endif
1.120
1.121 -#if SOURCE_ENGINE >= SE_LEFT4DEAD2
1.122 +#if SOURCE_ENGINE >= SE_ORANGEBOX
1.123 static cell_t DispatchSpawn(IPluginContext *pContext, const cell_t *params)
1.124 {
1.125 - static ValveCall *pCall = NULL;
1.126 - if (!pCall)
1.127 + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(params[1]);
1.128 + if (!pEntity)
1.129 {
1.130 - ValvePassInfo pass[3];
1.131 - InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
1.132 - InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.133 - InitPass(pass[2], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
1.134 - if (!CreateBaseCall("DispatchSpawn", ValveCall_Static, &pass[2], pass, 2, &pCall))
1.135 - {
1.136 - return pContext->ThrowNativeError("\"DispatchSpawn\" not supported by this mod");
1.137 - } else if (!pCall) {
1.138 - return pContext->ThrowNativeError("\"DispatchSpawn\" wrapper failed to initialize");
1.139 - }
1.140 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", gamehelpers->ReferenceToIndex(params[1]), params[1]);
1.141 }
1.142
1.143 - int ret;
1.144 - START_CALL();
1.145 - DECODE_VALVE_PARAM(1, vparams, 0);
1.146 - /* All X-refs to DispatchSpawn I checked use true - Unsure of what it does */
1.147 - *(bool *)(vptr + 4) = true;
1.148 - FINISH_CALL_SIMPLE(&ret);
1.149 + servertools->DispatchSpawn(pEntity);
1.150
1.151 - return (ret == -1) ? 0 : 1;
1.152 + return 1;
1.153 }
1.154 #else
1.155 static cell_t DispatchSpawn(IPluginContext *pContext, const cell_t *params)
1.156 @@ -766,6 +794,23 @@
1.157 }
1.158 #endif
1.159
1.160 +#if SOURCE_ENGINE >= SE_ORANGEBOX
1.161 +static cell_t DispatchKeyValue(IPluginContext *pContext, const cell_t *params)
1.162 +{
1.163 + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(params[1]);
1.164 + if (!pEntity)
1.165 + {
1.166 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", gamehelpers->ReferenceToIndex(params[1]), params[1]);
1.167 + }
1.168 +
1.169 + char *key;
1.170 + char *value;
1.171 + pContext->LocalToString(params[2], &key);
1.172 + pContext->LocalToString(params[3], &value);
1.173 +
1.174 + return (servertools->SetKeyValue(pEntity, key, value) ? 1 : 0);
1.175 +}
1.176 +#else
1.177 static cell_t DispatchKeyValue(IPluginContext *pContext, const cell_t *params)
1.178 {
1.179 static ValveCall *pCall = NULL;
1.180 @@ -792,7 +837,25 @@
1.181
1.182 return ret ? 1 : 0;
1.183 }
1.184 +#endif
1.185
1.186 +#if SOURCE_ENGINE >= SE_ORANGEBOX
1.187 +static cell_t DispatchKeyValueFloat(IPluginContext *pContext, const cell_t *params)
1.188 +{
1.189 + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(params[1]);
1.190 + if (!pEntity)
1.191 + {
1.192 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", gamehelpers->ReferenceToIndex(params[1]), params[1]);
1.193 + }
1.194 +
1.195 + char *key;
1.196 + pContext->LocalToString(params[2], &key);
1.197 +
1.198 + float value = sp_ctof(params[3]);
1.199 +
1.200 + return (servertools->SetKeyValue(pEntity, key, value) ? 1 : 0);
1.201 +}
1.202 +#else
1.203 static cell_t DispatchKeyValueFloat(IPluginContext *pContext, const cell_t *params)
1.204 {
1.205 static ValveCall *pCall = NULL;
1.206 @@ -819,7 +882,31 @@
1.207
1.208 return ret ? 1 : 0;
1.209 }
1.210 +#endif
1.211
1.212 +#if SOURCE_ENGINE >= SE_ORANGEBOX
1.213 +static cell_t DispatchKeyValueVector(IPluginContext *pContext, const cell_t *params)
1.214 +{
1.215 + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(params[1]);
1.216 + if (!pEntity)
1.217 + {
1.218 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", gamehelpers->ReferenceToIndex(params[1]), params[1]);
1.219 + }
1.220 +
1.221 + char *key;
1.222 + pContext->LocalToString(params[2], &key);
1.223 +
1.224 + cell_t *vec;
1.225 + pContext->LocalToPhysAddr(params[3], &vec);
1.226 +
1.227 + const Vector *v = new Vector(
1.228 + sp_ctof(vec[0]),
1.229 + sp_ctof(vec[1]),
1.230 + sp_ctof(vec[2]));
1.231 +
1.232 + return (servertools->SetKeyValue(pEntity, key, *v) ? 1 : 0);
1.233 +}
1.234 +#else
1.235 static cell_t DispatchKeyValueVector(IPluginContext *pContext, const cell_t *params)
1.236 {
1.237 static ValveCall *pCall = NULL;
1.238 @@ -850,6 +937,7 @@
1.239
1.240 return ret ? 1 : 0;
1.241 }
1.242 +#endif
1.243
1.244 static cell_t sm_GetClientAimTarget(IPluginContext *pContext, const cell_t *params)
1.245 {