3 * ===============================================================
4 * SourceMod SDK Tools Extension
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * ===============================================================
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "extension.h"
25 #include "vcallbuilder.h"
28 List<ValveCall *> g_RegCalls;
30 inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags, unsigned int decflags=0)
32 info.decflags = decflags;
39 #define START_CALL() \
40 unsigned char *vptr = pCall->stk_get();
42 #define FINISH_CALL_SIMPLE(vret) \
43 pCall->call->Execute(vptr, vret); \
46 #define ENCODE_VALVE_PARAM(num, which, vnum) \
47 if (EncodeValveParam(pContext, \
50 &pCall->which[vnum], \
57 #define DECODE_VALVE_PARAM(num, which, vnum) \
58 if (DecodeValveParam(pContext, \
61 &pCall->which[vnum], \
68 bool CreateBaseCall(const char *name,
69 ValveCallType vcalltype,
70 const ValvePassInfo *retinfo,
71 const ValvePassInfo params[],
72 unsigned int numParams,
77 if (g_pGameConf->GetOffset(name, &offset))
79 call = CreateValveVCall(offset, vcalltype, retinfo, params, numParams);
82 g_RegCalls.push_back(call);
88 if (g_pGameConf->GetMemSig(name, &addr))
90 call = CreateValveCall(addr, vcalltype, retinfo, params, numParams);
93 g_RegCalls.push_back(call);
103 static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
105 static ValveCall *pCall = NULL;
108 ValvePassInfo pass[2];
109 InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, 0);
110 InitPass(pass[1], Valve_Bool, PassType_Basic, 0);
111 if (!CreateBaseCall("RemovePlayerItem", ValveCall_Player, &pass[1], &pass[0], 1, &pCall))
113 return pContext->ThrowNativeError("\"RemovePlayerItem\" not supported by this mod");
115 return pContext->ThrowNativeError("\"RemovePlayerItem\" wrapper failed to initialized");
121 DECODE_VALVE_PARAM(1, thisinfo, 0);
122 DECODE_VALVE_PARAM(2, vparams, 0);
123 FINISH_CALL_SIMPLE(&ret);
127 static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
129 static ValveCall *pCall = NULL;
132 ValvePassInfo pass[3];
133 InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
134 InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
135 InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
136 if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[2], pass, 2, &pCall))
138 return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod");
140 return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialized");
144 CBaseEntity *pEntity = NULL;
146 DECODE_VALVE_PARAM(1, thisinfo, 0);
147 DECODE_VALVE_PARAM(2, vparams, 0);
148 DECODE_VALVE_PARAM(3, vparams, 1);
149 FINISH_CALL_SIMPLE(&pEntity);
156 edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
162 return engine->IndexOfEdict(pEdict);
165 static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params)
167 static ValveCall *pCall = NULL;
170 ValvePassInfo pass[2];
171 InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
172 InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
173 if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall))
175 return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod");
177 return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized");
181 CBaseEntity *pEntity;
183 DECODE_VALVE_PARAM(1, thisinfo, 0);
184 DECODE_VALVE_PARAM(2, vparams, 0);
185 FINISH_CALL_SIMPLE(&pEntity);
192 edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
198 return engine->IndexOfEdict(pEdict);
201 static cell_t IgnitePlayer(IPluginContext *pContext, const cell_t *params)
203 static ValveCall *pCall = NULL;
206 ValvePassInfo pass[4];
207 InitPass(pass[0], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
208 InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
209 InitPass(pass[2], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
210 InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
211 if (!CreateBaseCall("Ignite", ValveCall_Entity, NULL, pass, 4, &pCall))
213 return pContext->ThrowNativeError("\"Ignite\" not supported by this mod");
215 return pContext->ThrowNativeError("\"Ignite\" wrapper failed to initialized");
220 DECODE_VALVE_PARAM(1, thisinfo, 0);
221 DECODE_VALVE_PARAM(2, vparams, 0);
222 DECODE_VALVE_PARAM(3, vparams, 1);
223 DECODE_VALVE_PARAM(4, vparams, 2);
224 DECODE_VALVE_PARAM(5, vparams, 3);
225 FINISH_CALL_SIMPLE(NULL);
230 static cell_t ExtinguishPlayer(IPluginContext *pContext, const cell_t *params)
232 static ValveCall *pCall = NULL;
235 if (!CreateBaseCall("Extinguish", ValveCall_Entity, NULL, NULL, 0, &pCall))
237 return pContext->ThrowNativeError("\"Extinguish\" not supported by this mod");
239 return pContext->ThrowNativeError("\"Extinguish\" wrapper failed to initialized");
244 DECODE_VALVE_PARAM(1, thisinfo, 0);
245 FINISH_CALL_SIMPLE(NULL);
250 static cell_t TeleportPlayer(IPluginContext *pContext, const cell_t *params)
252 static ValveCall *pCall = NULL;
255 ValvePassInfo pass[3];
256 InitPass(pass[0], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
257 InitPass(pass[1], Valve_QAngle, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
258 InitPass(pass[2], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
259 if (!CreateBaseCall("Teleport", ValveCall_Entity, NULL, pass, 3, &pCall))
261 return pContext->ThrowNativeError("\"Teleport\" not supported by this mod");
263 return pContext->ThrowNativeError("\"Teleport\" wrapper failed to initialized");
268 DECODE_VALVE_PARAM(1, thisinfo, 0);
269 DECODE_VALVE_PARAM(2, vparams, 0);
270 DECODE_VALVE_PARAM(3, vparams, 1);
271 DECODE_VALVE_PARAM(4, vparams, 2);
272 FINISH_CALL_SIMPLE(NULL);
277 static cell_t SetClientViewEntity(IPluginContext *pContext, const cell_t *params)
279 IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
282 return pContext->ThrowNativeError("Invalid client index %d", params[1]);
284 if (!player->IsInGame())
286 return pContext->ThrowNativeError("Client %d is not in game", params[1]);
289 edict_t *pEdict = engine->PEntityOfEntIndex(params[2]);
290 if (!pEdict || pEdict->IsFree())
292 return pContext->ThrowNativeError("Entity %d is not valid", params[2]);
295 engine->SetView(player->GetEdict(), pEdict);
300 sp_nativeinfo_t g_Natives[] =
302 {"ExtinguishPlayer", ExtinguishPlayer},
303 {"ExtinguishEntity", ExtinguishPlayer},
304 {"GivePlayerItem", GiveNamedItem},
305 {"GetPlayerWeaponSlot", GetPlayerWeaponSlot},
306 {"IgnitePlayer", IgnitePlayer},
307 {"IgniteEntity", IgnitePlayer},
308 {"RemovePlayerItem", RemovePlayerItem},
309 {"TeleportPlayer", TeleportPlayer},
310 {"TeleportEntity", TeleportPlayer},
311 {"SetClientViewEntity", SetClientViewEntity},