1.1 --- a/extensions/sdktools/vnatives.cpp Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,830 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod SDKTools Extension
1.8 - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include <stdlib.h>
1.36 -#include <sh_string.h>
1.37 -#include "extension.h"
1.38 -#include "vcallbuilder.h"
1.39 -#include "vnatives.h"
1.40 -#include "vhelpers.h"
1.41 -#include "vglobals.h"
1.42 -#include "CellRecipientFilter.h"
1.43 -
1.44 -SourceHook::List<ValveCall *> g_RegCalls;
1.45 -SourceHook::List<ICallWrapper *> g_CallWraps;
1.46 -
1.47 -inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags, unsigned int decflags=0)
1.48 -{
1.49 - info.decflags = decflags;
1.50 - info.encflags = 0;
1.51 - info.flags = flags;
1.52 - info.type = type;
1.53 - info.vtype = vtype;
1.54 -}
1.55 -
1.56 -#define START_CALL() \
1.57 - unsigned char *vptr = pCall->stk_get();
1.58 -
1.59 -#define FINISH_CALL_SIMPLE(vret) \
1.60 - pCall->call->Execute(vptr, vret); \
1.61 - pCall->stk_put(vptr);
1.62 -
1.63 -#define ENCODE_VALVE_PARAM(num, which, vnum) \
1.64 - if (EncodeValveParam(pContext, \
1.65 - params[num], \
1.66 - pCall, \
1.67 - &pCall->which[vnum], \
1.68 - vptr) \
1.69 - == Data_Fail) \
1.70 - { \
1.71 - return 0; \
1.72 - }
1.73 -
1.74 -#define DECODE_VALVE_PARAM(num, which, vnum) \
1.75 - if (DecodeValveParam(pContext, \
1.76 - params[num], \
1.77 - pCall, \
1.78 - &pCall->which[vnum], \
1.79 - vptr) \
1.80 - == Data_Fail) \
1.81 - { \
1.82 - return 0; \
1.83 - }
1.84 -
1.85 -bool CreateBaseCall(const char *name,
1.86 - ValveCallType vcalltype,
1.87 - const ValvePassInfo *retinfo,
1.88 - const ValvePassInfo params[],
1.89 - unsigned int numParams,
1.90 - ValveCall **vaddr)
1.91 -{
1.92 - int offset;
1.93 - ValveCall *call;
1.94 - if (g_pGameConf->GetOffset(name, &offset))
1.95 - {
1.96 - call = CreateValveVCall(offset, vcalltype, retinfo, params, numParams);
1.97 - if (call)
1.98 - {
1.99 - g_RegCalls.push_back(call);
1.100 - }
1.101 - *vaddr = call;
1.102 - return true;
1.103 - } else {
1.104 - void *addr;
1.105 - if (g_pGameConf->GetMemSig(name, &addr))
1.106 - {
1.107 - call = CreateValveCall(addr, vcalltype, retinfo, params, numParams);
1.108 - if (call)
1.109 - {
1.110 - g_RegCalls.push_back(call);
1.111 - }
1.112 - *vaddr = call;
1.113 - return true;
1.114 - }
1.115 - }
1.116 - return false;
1.117 -}
1.118 -
1.119 -static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
1.120 -{
1.121 - static ValveCall *pCall = NULL;
1.122 - if (!pCall)
1.123 - {
1.124 - ValvePassInfo pass[2];
1.125 - InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
1.126 - InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.127 - if (!CreateBaseCall("RemovePlayerItem", ValveCall_Player, &pass[1], pass, 1, &pCall))
1.128 - {
1.129 - return pContext->ThrowNativeError("\"RemovePlayerItem\" not supported by this mod");
1.130 - } else if (!pCall) {
1.131 - return pContext->ThrowNativeError("\"RemovePlayerItem\" wrapper failed to initialized");
1.132 - }
1.133 - }
1.134 -
1.135 - bool ret;
1.136 - START_CALL();
1.137 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.138 - DECODE_VALVE_PARAM(2, vparams, 0);
1.139 - FINISH_CALL_SIMPLE(&ret);
1.140 - return ret ? 1 : 0;
1.141 -}
1.142 -
1.143 -static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
1.144 -{
1.145 - static ValveCall *pCall = NULL;
1.146 - if (!pCall)
1.147 - {
1.148 - ValvePassInfo pass[3];
1.149 - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
1.150 - InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
1.151 - InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
1.152 - if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[2], pass, 2, &pCall))
1.153 - {
1.154 - return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod");
1.155 - } else if (!pCall) {
1.156 - return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialized");
1.157 - }
1.158 - }
1.159 -
1.160 - CBaseEntity *pEntity = NULL;
1.161 - START_CALL();
1.162 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.163 - DECODE_VALVE_PARAM(2, vparams, 0);
1.164 - DECODE_VALVE_PARAM(3, vparams, 1);
1.165 - FINISH_CALL_SIMPLE(&pEntity);
1.166 -
1.167 - if (pEntity == NULL)
1.168 - {
1.169 - return -1;
1.170 - }
1.171 -
1.172 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
1.173 - if (!pEdict)
1.174 - {
1.175 - return -1;
1.176 - }
1.177 -
1.178 - return engine->IndexOfEdict(pEdict);
1.179 -}
1.180 -
1.181 -static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params)
1.182 -{
1.183 - static ValveCall *pCall = NULL;
1.184 - if (!pCall)
1.185 - {
1.186 - ValvePassInfo pass[2];
1.187 - InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
1.188 - InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
1.189 - if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall))
1.190 - {
1.191 - return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod");
1.192 - } else if (!pCall) {
1.193 - return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized");
1.194 - }
1.195 - }
1.196 -
1.197 - CBaseEntity *pEntity;
1.198 - START_CALL();
1.199 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.200 - DECODE_VALVE_PARAM(2, vparams, 0);
1.201 - FINISH_CALL_SIMPLE(&pEntity);
1.202 -
1.203 - if (pEntity == NULL)
1.204 - {
1.205 - return -1;
1.206 - }
1.207 -
1.208 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
1.209 - if (!pEdict)
1.210 - {
1.211 - return -1;
1.212 - }
1.213 -
1.214 - return engine->IndexOfEdict(pEdict);
1.215 -}
1.216 -
1.217 -static cell_t IgniteEntity(IPluginContext *pContext, const cell_t *params)
1.218 -{
1.219 - static ValveCall *pCall = NULL;
1.220 - if (!pCall)
1.221 - {
1.222 - ValvePassInfo pass[4];
1.223 - InitPass(pass[0], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
1.224 - InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.225 - InitPass(pass[2], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
1.226 - InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.227 - if (!CreateBaseCall("Ignite", ValveCall_Entity, NULL, pass, 4, &pCall))
1.228 - {
1.229 - return pContext->ThrowNativeError("\"Ignite\" not supported by this mod");
1.230 - } else if (!pCall) {
1.231 - return pContext->ThrowNativeError("\"Ignite\" wrapper failed to initialized");
1.232 - }
1.233 - }
1.234 -
1.235 - START_CALL();
1.236 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.237 - DECODE_VALVE_PARAM(2, vparams, 0);
1.238 - DECODE_VALVE_PARAM(3, vparams, 1);
1.239 - DECODE_VALVE_PARAM(4, vparams, 2);
1.240 - DECODE_VALVE_PARAM(5, vparams, 3);
1.241 - FINISH_CALL_SIMPLE(NULL);
1.242 -
1.243 - return 1;
1.244 -}
1.245 -
1.246 -static cell_t ExtinguishEntity(IPluginContext *pContext, const cell_t *params)
1.247 -{
1.248 - static ValveCall *pCall = NULL;
1.249 - if (!pCall)
1.250 - {
1.251 - if (!CreateBaseCall("Extinguish", ValveCall_Entity, NULL, NULL, 0, &pCall))
1.252 - {
1.253 - return pContext->ThrowNativeError("\"Extinguish\" not supported by this mod");
1.254 - } else if (!pCall) {
1.255 - return pContext->ThrowNativeError("\"Extinguish\" wrapper failed to initialized");
1.256 - }
1.257 - }
1.258 -
1.259 - START_CALL();
1.260 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.261 - FINISH_CALL_SIMPLE(NULL);
1.262 -
1.263 - return 1;
1.264 -}
1.265 -
1.266 -static cell_t TeleportEntity(IPluginContext *pContext, const cell_t *params)
1.267 -{
1.268 - static ValveCall *pCall = NULL;
1.269 - if (!pCall)
1.270 - {
1.271 - ValvePassInfo pass[3];
1.272 - InitPass(pass[0], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
1.273 - InitPass(pass[1], Valve_QAngle, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
1.274 - InitPass(pass[2], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
1.275 - if (!CreateBaseCall("Teleport", ValveCall_Entity, NULL, pass, 3, &pCall))
1.276 - {
1.277 - return pContext->ThrowNativeError("\"Teleport\" not supported by this mod");
1.278 - } else if (!pCall) {
1.279 - return pContext->ThrowNativeError("\"Teleport\" wrapper failed to initialized");
1.280 - }
1.281 - }
1.282 -
1.283 - START_CALL();
1.284 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.285 - DECODE_VALVE_PARAM(2, vparams, 0);
1.286 - DECODE_VALVE_PARAM(3, vparams, 1);
1.287 - DECODE_VALVE_PARAM(4, vparams, 2);
1.288 - FINISH_CALL_SIMPLE(NULL);
1.289 -
1.290 - return 1;
1.291 -}
1.292 -
1.293 -#if defined ORANGEBOX_BUILD
1.294 -/* :TODO: This is Team Fortress 2 specific */
1.295 -static cell_t ForcePlayerSuicide(IPluginContext *pContext, const cell_t *params)
1.296 -{
1.297 - static ValveCall *pCall = NULL;
1.298 - if (!pCall)
1.299 - {
1.300 - ValvePassInfo pass[2];
1.301 - InitPass(pass[0], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.302 - InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.303 - if (!CreateBaseCall("CommitSuicide", ValveCall_Player, NULL, pass, 2, &pCall))
1.304 - {
1.305 - return pContext->ThrowNativeError("\"CommitSuicide\" not supported by this mod");
1.306 - }
1.307 - else if (!pCall)
1.308 - {
1.309 - return pContext->ThrowNativeError("\"CommitSuicide\" wrapper failed to initialized");
1.310 - }
1.311 - }
1.312 -
1.313 - START_CALL();
1.314 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.315 - *(bool *)(vptr + 4) = false;
1.316 - *(bool *)(vptr + 5) = false;
1.317 - FINISH_CALL_SIMPLE(NULL);
1.318 -
1.319 - return 1;
1.320 -}
1.321 -#else
1.322 -static cell_t ForcePlayerSuicide(IPluginContext *pContext, const cell_t *params)
1.323 -{
1.324 - static ValveCall *pCall = NULL;
1.325 - if (!pCall)
1.326 - {
1.327 - if (!CreateBaseCall("CommitSuicide", ValveCall_Player, NULL, NULL, 0, &pCall))
1.328 - {
1.329 - return pContext->ThrowNativeError("\"CommitSuicide\" not supported by this mod");
1.330 - } else if (!pCall) {
1.331 - return pContext->ThrowNativeError("\"CommitSuicide\" wrapper failed to initialized");
1.332 - }
1.333 - }
1.334 -
1.335 - START_CALL();
1.336 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.337 - FINISH_CALL_SIMPLE(NULL);
1.338 -
1.339 - return 1;
1.340 -}
1.341 -#endif
1.342 -
1.343 -static cell_t SetClientViewEntity(IPluginContext *pContext, const cell_t *params)
1.344 -{
1.345 - IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
1.346 - if (player == NULL)
1.347 - {
1.348 - return pContext->ThrowNativeError("Invalid client index %d", params[1]);
1.349 - }
1.350 - if (!player->IsInGame())
1.351 - {
1.352 - return pContext->ThrowNativeError("Client %d is not in game", params[1]);
1.353 - }
1.354 -
1.355 - edict_t *pEdict = engine->PEntityOfEntIndex(params[2]);
1.356 - if (!pEdict || pEdict->IsFree())
1.357 - {
1.358 - return pContext->ThrowNativeError("Entity %d is not valid", params[2]);
1.359 - }
1.360 -
1.361 - engine->SetView(player->GetEdict(), pEdict);
1.362 -
1.363 - return 1;
1.364 -}
1.365 -
1.366 -static SourceHook::String *g_lightstyle[MAX_LIGHTSTYLES] = {NULL};
1.367 -static cell_t SetLightStyle(IPluginContext *pContext, const cell_t *params)
1.368 -{
1.369 - int style = params[1];
1.370 - if (style >= MAX_LIGHTSTYLES)
1.371 - {
1.372 - return pContext->ThrowNativeError("Light style %d is invalid (range: 0-%d)", style, MAX_LIGHTSTYLES - 1);
1.373 - }
1.374 -
1.375 - if (g_lightstyle[style] == NULL)
1.376 - {
1.377 - /* We allocate and never free this because the Engine wants to hold onto it :\
1.378 - * in theory we could hook light style and know whether we're supposed to free
1.379 - * this or not on shutdown, but for ~4K of memory MAX, it doesn't seem worth it yet.
1.380 - * So, it's a :TODO:!
1.381 - */
1.382 - g_lightstyle[style] = new SourceHook::String();
1.383 - }
1.384 -
1.385 - char *str;
1.386 - pContext->LocalToString(params[2], &str);
1.387 -
1.388 - g_lightstyle[style]->assign(str);
1.389 -
1.390 - engine->LightStyle(style, g_lightstyle[style]->c_str());
1.391 -
1.392 - return 1;
1.393 -}
1.394 -
1.395 -static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params)
1.396 -{
1.397 - static bool s_slap_supported = false;
1.398 - static bool s_slap_setup = false;
1.399 - static ICallWrapper *s_teleport = NULL;
1.400 - static int s_health_offs = 0;
1.401 - static int s_sound_count = 0;
1.402 - static int s_frag_offs = 0;
1.403 -
1.404 - if (!s_slap_setup)
1.405 - {
1.406 - int tries = 0;
1.407 -
1.408 - s_slap_setup = true;
1.409 -
1.410 - if (IsTeleportSupported())
1.411 - {
1.412 - tries++;
1.413 - }
1.414 - if (IsGetVelocitySupported())
1.415 - {
1.416 - tries++;
1.417 - }
1.418 -
1.419 - /* Setup health */
1.420 - if (g_pGameConf->GetOffset("m_iHealth", &s_health_offs) && s_health_offs)
1.421 - {
1.422 - tries++;
1.423 - }
1.424 -
1.425 - if (tries == 3)
1.426 - {
1.427 - s_slap_supported = true;
1.428 -
1.429 - const char *key;
1.430 - if ((key = g_pGameConf->GetKeyValue("SlapSoundCount")) != NULL)
1.431 - {
1.432 - s_sound_count = atoi(key);
1.433 - }
1.434 - }
1.435 - }
1.436 -
1.437 - if (!s_slap_supported)
1.438 - {
1.439 - return pContext->ThrowNativeError("This function is not supported on this mod");
1.440 - }
1.441 -
1.442 - /* First check if the client is valid */
1.443 - int client = params[1];
1.444 - IGamePlayer *player = playerhelpers->GetGamePlayer(client);
1.445 - if (!player)
1.446 - {
1.447 - return pContext->ThrowNativeError("Client %d is not valid", client);
1.448 - } else if (!player->IsInGame()) {
1.449 - return pContext->ThrowNativeError("Client %d is not in game", client);
1.450 - }
1.451 -
1.452 - edict_t *pEdict = player->GetEdict();
1.453 - CBaseEntity *pEntity = pEdict->GetUnknown()->GetBaseEntity();
1.454 -
1.455 - /* See if we should be taking away health */
1.456 - bool should_slay = false;
1.457 - if (params[2])
1.458 - {
1.459 - int *health = (int *)((char *)pEntity + s_health_offs);
1.460 - if (*health - params[2] <= 0)
1.461 - {
1.462 - *health = 1;
1.463 - should_slay = true;
1.464 - } else {
1.465 - *health -= params[2];
1.466 - }
1.467 - }
1.468 -
1.469 - /* Teleport in a random direction - thank you, Mani!*/
1.470 - Vector velocity;
1.471 - GetVelocity(pEntity, &velocity, NULL);
1.472 - velocity.x += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1);
1.473 - velocity.y += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1);
1.474 - velocity.z += rand() % 200 + 100;
1.475 - Teleport(pEntity, NULL, NULL, &velocity);
1.476 -
1.477 - /* Play a random sound */
1.478 - if (params[3] && s_sound_count > 0)
1.479 - {
1.480 - char name[48];
1.481 - const char *sound_name;
1.482 - cell_t player_list[256], total_players = 0;
1.483 - int maxClients = playerhelpers->GetMaxClients();
1.484 -
1.485 - int r = (rand() % s_sound_count) + 1;
1.486 - snprintf(name, sizeof(name), "SlapSound%d", r);
1.487 -
1.488 - if ((sound_name = g_pGameConf->GetKeyValue(name)) != NULL)
1.489 - {
1.490 - IGamePlayer *other;
1.491 - for (int i=1; i<=maxClients; i++)
1.492 - {
1.493 - other = playerhelpers->GetGamePlayer(i);
1.494 - if (other->IsInGame())
1.495 - {
1.496 - player_list[total_players++] = i;
1.497 - }
1.498 - }
1.499 -
1.500 - const Vector & pos = pEdict->GetCollideable()->GetCollisionOrigin();
1.501 - CellRecipientFilter rf;
1.502 - rf.SetToReliable(true);
1.503 - rf.Initialize(player_list, total_players);
1.504 - engsound->EmitSound(rf, client, CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
1.505 - }
1.506 - }
1.507 -
1.508 - if (!s_frag_offs)
1.509 - {
1.510 - const char *frag_prop = g_pGameConf->GetKeyValue("m_iFrags");
1.511 - if (frag_prop)
1.512 - {
1.513 - datamap_t *pMap = gamehelpers->GetDataMap(pEntity);
1.514 - typedescription_t *pType = gamehelpers->FindInDataMap(pMap, frag_prop);
1.515 - if (pType != NULL)
1.516 - {
1.517 - s_frag_offs = pType->fieldOffset[TD_OFFSET_NORMAL];
1.518 - }
1.519 - }
1.520 - if (!s_frag_offs)
1.521 - {
1.522 - s_frag_offs = -1;
1.523 - }
1.524 - }
1.525 -
1.526 - int old_frags = 0;
1.527 - if (s_frag_offs > 0)
1.528 - {
1.529 - old_frags = *(int *)((char *)pEntity + s_frag_offs);
1.530 - }
1.531 -
1.532 - /* Force suicide */
1.533 - if (should_slay)
1.534 - {
1.535 - pluginhelpers->ClientCommand(pEdict, "kill\n");
1.536 - }
1.537 -
1.538 - if (s_frag_offs > 0)
1.539 - {
1.540 - *(int *)((char *)pEntity + s_frag_offs) = old_frags;
1.541 - }
1.542 -
1.543 - return 1;
1.544 -}
1.545 -
1.546 -static cell_t GetClientEyePosition(IPluginContext *pContext, const cell_t *params)
1.547 -{
1.548 - IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
1.549 - if (player == NULL)
1.550 - {
1.551 - return pContext->ThrowNativeError("Invalid client index %d", params[1]);
1.552 - }
1.553 - if (!player->IsInGame())
1.554 - {
1.555 - return pContext->ThrowNativeError("Client %d is not in game", params[1]);
1.556 - }
1.557 -
1.558 - Vector pos;
1.559 - serverClients->ClientEarPosition(player->GetEdict(), &pos);
1.560 -
1.561 - cell_t *addr;
1.562 - pContext->LocalToPhysAddr(params[2], &addr);
1.563 - addr[0] = sp_ftoc(pos.x);
1.564 - addr[1] = sp_ftoc(pos.y);
1.565 - addr[2] = sp_ftoc(pos.z);
1.566 -
1.567 - return 1;
1.568 -}
1.569 -
1.570 -static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params)
1.571 -{
1.572 - int client = params[1];
1.573 - IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
1.574 -
1.575 - if (!pPlayer)
1.576 - {
1.577 - return pContext->ThrowNativeError("Invalid client index %d", client);
1.578 - }
1.579 - else if (!pPlayer->IsInGame())
1.580 - {
1.581 - return pContext->ThrowNativeError("Client %d is not in game", client);
1.582 - }
1.583 -
1.584 - edict_t *pEdict = pPlayer->GetEdict();
1.585 - CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL;
1.586 -
1.587 - /* We always set the angles for backwards compatibility --
1.588 - * The original function had no return value.
1.589 - */
1.590 - QAngle angles;
1.591 - bool got_angles = false;
1.592 -
1.593 - if (pEntity != NULL)
1.594 - {
1.595 - got_angles = GetEyeAngles(pEntity, &angles);
1.596 - }
1.597 -
1.598 - cell_t *addr;
1.599 - pContext->LocalToPhysAddr(params[2], &addr);
1.600 - addr[0] = sp_ftoc(angles.x);
1.601 - addr[1] = sp_ftoc(angles.y);
1.602 - addr[2] = sp_ftoc(angles.z);
1.603 -
1.604 - return got_angles ? 1 : 0;
1.605 -}
1.606 -
1.607 -static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
1.608 -{
1.609 - static ValveCall *pCall = NULL;
1.610 - if (!pCall)
1.611 - {
1.612 - ValvePassInfo pass[3];
1.613 - InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL|VDECODE_FLAG_ALLOWWORLD);
1.614 - InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
1.615 - InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
1.616 - if (!CreateBaseCall("FindEntityByClassname", ValveCall_EntityList, &pass[2], pass, 2, &pCall))
1.617 - {
1.618 - return pContext->ThrowNativeError("\"FindEntityByClassname\" not supported by this mod");
1.619 - } else if (!pCall) {
1.620 - return pContext->ThrowNativeError("\"FindEntityByClassname\" wrapper failed to initialized");
1.621 - }
1.622 - }
1.623 -
1.624 - CBaseEntity *pEntity;
1.625 - START_CALL();
1.626 - *(void **)vptr = g_EntList;
1.627 - DECODE_VALVE_PARAM(1, vparams, 0);
1.628 - DECODE_VALVE_PARAM(2, vparams, 1);
1.629 - FINISH_CALL_SIMPLE(&pEntity);
1.630 -
1.631 - if (pEntity == NULL)
1.632 - {
1.633 - return -1;
1.634 - }
1.635 -
1.636 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
1.637 - if (!pEdict)
1.638 - {
1.639 - return -1;
1.640 - }
1.641 -
1.642 - return engine->IndexOfEdict(pEdict);
1.643 -}
1.644 -
1.645 -static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params)
1.646 -{
1.647 - static ValveCall *pCall = NULL;
1.648 - if (!pCall)
1.649 - {
1.650 - ValvePassInfo pass[3];
1.651 - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
1.652 - InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
1.653 - InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
1.654 - if (!CreateBaseCall("CreateEntityByName", ValveCall_Static, &pass[2], pass, 2, &pCall))
1.655 - {
1.656 - return pContext->ThrowNativeError("\"CreateEntityByName\" not supported by this mod");
1.657 - } else if (!pCall) {
1.658 - return pContext->ThrowNativeError("\"CreateEntityByName\" wrapper failed to initialized");
1.659 - }
1.660 - }
1.661 -
1.662 - CBaseEntity *pEntity = NULL;
1.663 - START_CALL();
1.664 - DECODE_VALVE_PARAM(1, vparams, 0);
1.665 - DECODE_VALVE_PARAM(2, vparams, 1);
1.666 - FINISH_CALL_SIMPLE(&pEntity);
1.667 -
1.668 - if (pEntity == NULL)
1.669 - {
1.670 - return -1;
1.671 - }
1.672 -
1.673 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
1.674 - if (!pEdict)
1.675 - {
1.676 - return -1;
1.677 - }
1.678 -
1.679 - return engine->IndexOfEdict(pEdict);
1.680 -}
1.681 -
1.682 -static cell_t DispatchSpawn(IPluginContext *pContext, const cell_t *params)
1.683 -{
1.684 - static ValveCall *pCall = NULL;
1.685 - if (!pCall)
1.686 - {
1.687 - ValvePassInfo pass[2];
1.688 - InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
1.689 - InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
1.690 - if (!CreateBaseCall("DispatchSpawn", ValveCall_Static, &pass[1], pass, 1, &pCall))
1.691 - {
1.692 - return pContext->ThrowNativeError("\"DispatchSpawn\" not supported by this mod");
1.693 - } else if (!pCall) {
1.694 - return pContext->ThrowNativeError("\"DispatchSpawn\" wrapper failed to initialized");
1.695 - }
1.696 - }
1.697 -
1.698 - int ret;
1.699 - START_CALL();
1.700 - DECODE_VALVE_PARAM(1, vparams, 0);
1.701 - FINISH_CALL_SIMPLE(&ret);
1.702 -
1.703 - return (ret == -1) ? 0 : 1;
1.704 -}
1.705 -
1.706 -static cell_t DispatchKeyValue(IPluginContext *pContext, const cell_t *params)
1.707 -{
1.708 - static ValveCall *pCall = NULL;
1.709 - if (!pCall)
1.710 - {
1.711 - ValvePassInfo pass[3];
1.712 - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
1.713 - InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
1.714 - InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.715 - if (!CreateBaseCall("DispatchKeyValue", ValveCall_Entity, &pass[2], pass, 2, &pCall))
1.716 - {
1.717 - return pContext->ThrowNativeError("\"DispatchKeyValue\" not supported by this mod");
1.718 - } else if (!pCall) {
1.719 - return pContext->ThrowNativeError("\"DispatchKeyValue\" wrapper failed to initialized");
1.720 - }
1.721 - }
1.722 -
1.723 - bool ret;
1.724 - START_CALL();
1.725 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.726 - DECODE_VALVE_PARAM(2, vparams, 0);
1.727 - DECODE_VALVE_PARAM(3, vparams, 1);
1.728 - FINISH_CALL_SIMPLE(&ret);
1.729 -
1.730 - return (ret) ? 1 : 0;
1.731 -}
1.732 -
1.733 -static cell_t DispatchKeyValueFloat(IPluginContext *pContext, const cell_t *params)
1.734 -{
1.735 - static ValveCall *pCall = NULL;
1.736 - if (!pCall)
1.737 - {
1.738 - ValvePassInfo pass[3];
1.739 - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
1.740 - InitPass(pass[1], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
1.741 - InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.742 - if (!CreateBaseCall("DispatchKeyValueFloat", ValveCall_Entity, &pass[2], pass, 2, &pCall))
1.743 - {
1.744 - return pContext->ThrowNativeError("\"DispatchKeyValueFloat\" not supported by this mod");
1.745 - } else if (!pCall) {
1.746 - return pContext->ThrowNativeError("\"DispatchKeyValueFloat\" wrapper failed to initialized");
1.747 - }
1.748 - }
1.749 -
1.750 - bool ret;
1.751 - START_CALL();
1.752 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.753 - DECODE_VALVE_PARAM(2, vparams, 0);
1.754 - DECODE_VALVE_PARAM(3, vparams, 1);
1.755 - FINISH_CALL_SIMPLE(&ret);
1.756 -
1.757 - return (ret) ? 1 : 0;
1.758 -}
1.759 -
1.760 -static cell_t DispatchKeyValueVector(IPluginContext *pContext, const cell_t *params)
1.761 -{
1.762 - static ValveCall *pCall = NULL;
1.763 - if (!pCall)
1.764 - {
1.765 - ValvePassInfo pass[3];
1.766 - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
1.767 -#if defined ORANGEBOX_BUILD
1.768 - InitPass(pass[1], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL);
1.769 -#else
1.770 - InitPass(pass[1], Valve_Vector, PassType_Object, PASSFLAG_BYVAL|PASSFLAG_OCTOR|PASSFLAG_OASSIGNOP);
1.771 -#endif
1.772 - InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
1.773 - if (!CreateBaseCall("DispatchKeyValueVector", ValveCall_Entity, &pass[2], pass, 2, &pCall))
1.774 - {
1.775 - return pContext->ThrowNativeError("\"DispatchKeyValueVector\" not supported by this mod");
1.776 - } else if (!pCall) {
1.777 - return pContext->ThrowNativeError("\"DispatchKeyValueVector\" wrapper failed to initialized");
1.778 - }
1.779 - }
1.780 -
1.781 - bool ret;
1.782 - START_CALL();
1.783 - DECODE_VALVE_PARAM(1, thisinfo, 0);
1.784 - DECODE_VALVE_PARAM(2, vparams, 0);
1.785 - DECODE_VALVE_PARAM(3, vparams, 1);
1.786 - FINISH_CALL_SIMPLE(&ret);
1.787 -
1.788 - return (ret) ? 1 : 0;
1.789 -}
1.790 -
1.791 -static cell_t sm_GetClientAimTarget(IPluginContext *pContext, const cell_t *params)
1.792 -{
1.793 - int client = params[1];
1.794 - IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
1.795 -
1.796 - if (!pPlayer)
1.797 - {
1.798 - return pContext->ThrowNativeError("Invalid client index %d", client);
1.799 - }
1.800 - else if (!pPlayer->IsInGame())
1.801 - {
1.802 - return pContext->ThrowNativeError("Client %d is not in game", client);
1.803 - }
1.804 -
1.805 - return GetClientAimTarget(pPlayer->GetEdict(), params[2] ? true : false);
1.806 -}
1.807 -
1.808 -sp_nativeinfo_t g_Natives[] =
1.809 -{
1.810 - {"ExtinguishPlayer", ExtinguishEntity},
1.811 - {"ExtinguishEntity", ExtinguishEntity},
1.812 - {"ForcePlayerSuicide", ForcePlayerSuicide},
1.813 - {"GivePlayerItem", GiveNamedItem},
1.814 - {"GetPlayerWeaponSlot", GetPlayerWeaponSlot},
1.815 - {"IgnitePlayer", IgniteEntity},
1.816 - {"IgniteEntity", IgniteEntity},
1.817 - {"RemovePlayerItem", RemovePlayerItem},
1.818 - {"TeleportPlayer", TeleportEntity},
1.819 - {"TeleportEntity", TeleportEntity},
1.820 - {"SetClientViewEntity", SetClientViewEntity},
1.821 - {"SetLightStyle", SetLightStyle},
1.822 - {"SlapPlayer", SlapPlayer},
1.823 - {"GetClientEyePosition", GetClientEyePosition},
1.824 - {"GetClientEyeAngles", GetClientEyeAngles},
1.825 - {"FindEntityByClassname", FindEntityByClassname},
1.826 - {"CreateEntityByName", CreateEntityByName},
1.827 - {"DispatchSpawn", DispatchSpawn},
1.828 - {"DispatchKeyValue", DispatchKeyValue},
1.829 - {"DispatchKeyValueFloat", DispatchKeyValueFloat},
1.830 - {"DispatchKeyValueVector", DispatchKeyValueVector},
1.831 - {"GetClientAimTarget", sm_GetClientAimTarget},
1.832 - {NULL, NULL},
1.833 -};