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>.
32 #include "extension.h"
35 #define SIZEOF_VARIANT_T 20
37 ICallWrapper *g_pAcceptInput = NULL;
38 unsigned char g_Variant_t[SIZEOF_VARIANT_T] = {0};
40 #define ENTINDEX_TO_CBASEENTITY(index, buffer) \
41 pEdict = engine->PEntityOfEntIndex(index); \
42 if (!pEdict || pEdict->IsFree()) \
44 return pContext->ThrowNativeError("Entity %d is not valid or is freed", index); \
46 pUnk = pEdict->GetUnknown(); \
49 return pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", index); \
51 buffer = pUnk->GetBaseEntity(); \
54 return pContext->ThrowNativeError("Entity %d is not a CBaseEntity", index); \
57 /* Hack to init the variant_t object for the first time */
58 class VariantFirstTimeInit
61 VariantFirstTimeInit()
63 *(unsigned int *)(&g_Variant_t[12]) = INVALID_EHANDLE_INDEX;
65 } g_VariantFirstTimeInit;
67 inline void _init_variant_t()
69 unsigned char *vptr = g_Variant_t;
72 vptr += sizeof(int)*3;
73 *(unsigned long *)vptr = INVALID_EHANDLE_INDEX;
74 vptr += sizeof(unsigned long);
75 *(fieldtype_t *)vptr = FIELD_VOID;
78 static cell_t AcceptEntityInput(IPluginContext *pContext, const cell_t *params)
83 if (!g_pGameConf->GetOffset("AcceptInput", &offset))
85 return pContext->ThrowNativeError("\"AcceptEntityInput\" not supported by this mod");
89 pass[0].type = PassType_Basic;
90 pass[0].flags = PASSFLAG_BYVAL;
91 pass[0].size = sizeof(const char *);
92 pass[1].type = pass[2].type = PassType_Basic;
93 pass[1].flags = pass[2].flags = PASSFLAG_BYVAL;
94 pass[1].size = pass[2].size = sizeof(CBaseEntity *);
95 pass[3].type = PassType_Object;
96 pass[3].flags = PASSFLAG_BYVAL|PASSFLAG_OCTOR|PASSFLAG_ODTOR|PASSFLAG_OASSIGNOP;
97 pass[3].size = SIZEOF_VARIANT_T;
98 pass[4].type = PassType_Basic;
99 pass[4].flags = PASSFLAG_BYVAL;
100 pass[4].size = sizeof(int);
101 pass[5].type = PassType_Basic;
102 pass[5].flags = PASSFLAG_BYVAL;
103 pass[5].size = sizeof(bool);
105 if (!(g_pAcceptInput=g_pBinTools->CreateVCall(offset, 0, 0, &pass[5], pass, 5)))
107 pContext->ThrowNativeError("\"AcceptEntityInput\" wrapper failed to initialized");
111 CBaseEntity *pActivator, *pCaller, *pDest;
113 IServerUnknown *pUnk;
116 unsigned char vstk[sizeof(void *) + sizeof(const char *) + sizeof(CBaseEntity *)*2 + SIZEOF_VARIANT_T + sizeof(int)];
117 unsigned char *vptr = vstk;
119 ENTINDEX_TO_CBASEENTITY(params[1], pDest);
120 pContext->LocalToString(params[2], &inputname);
125 ENTINDEX_TO_CBASEENTITY(params[3], pActivator);
131 ENTINDEX_TO_CBASEENTITY(params[4], pCaller);
134 *(void **)vptr = pDest;
135 vptr += sizeof(void *);
136 *(const char **)vptr = inputname;
137 vptr += sizeof(const char *);
138 *(CBaseEntity **)vptr = pActivator;
139 vptr += sizeof(CBaseEntity *);
140 *(CBaseEntity **)vptr = pCaller;
141 vptr += sizeof(CBaseEntity *);
142 memcpy(vptr, g_Variant_t, SIZEOF_VARIANT_T);
143 vptr += SIZEOF_VARIANT_T;
144 *(int *)vptr = params[5];
147 g_pAcceptInput->Execute(vstk, &ret);
151 return (ret) ? 1 : 0;
154 static cell_t SetVariantBool(IPluginContext *pContext, const cell_t *params)
156 unsigned char *vptr = g_Variant_t;
158 *(bool *)vptr = (params[1]) ? true : false;
159 vptr += sizeof(int)*3 + sizeof(unsigned long);
160 *(fieldtype_t *)vptr = FIELD_BOOLEAN;
165 static cell_t SetVariantString(IPluginContext *pContext, const cell_t *params)
168 unsigned char *vptr = g_Variant_t;
170 pContext->LocalToString(params[1], &str);
172 *(string_t *)vptr = MAKE_STRING(str);
173 vptr += sizeof(int)*3 + sizeof(unsigned long);
174 *(fieldtype_t *)vptr = FIELD_STRING;
179 static cell_t SetVariantInt(IPluginContext *pContext, const cell_t *params)
181 unsigned char *vptr = g_Variant_t;
183 *(int *)vptr = params[1];
184 vptr += sizeof(int)*3 + sizeof(unsigned long);
185 *(fieldtype_t *)vptr = FIELD_INTEGER;
190 static cell_t SetVariantFloat(IPluginContext *pContext, const cell_t *params)
192 unsigned char *vptr = g_Variant_t;
194 *(float *)vptr = sp_ctof(params[1]);
195 vptr += sizeof(int)*3 + sizeof(unsigned long);
196 *(fieldtype_t *)vptr = FIELD_FLOAT;
201 static cell_t SetVariantVector3D(IPluginContext *pContext, const cell_t *params)
204 unsigned char *vptr = g_Variant_t;
206 pContext->LocalToPhysAddr(params[1], &val);
208 *(float *)vptr = sp_ctof(val[0]);
209 vptr += sizeof(float);
210 *(float *)vptr = sp_ctof(val[1]);
211 vptr += sizeof(float);
212 *(float *)vptr = sp_ctof(val[2]);
213 vptr += sizeof(float) + sizeof(unsigned long);
214 *(fieldtype_t *)vptr = FIELD_VECTOR;
219 static cell_t SetVariantPosVector3D(IPluginContext *pContext, const cell_t *params)
222 unsigned char *vptr = g_Variant_t;
224 pContext->LocalToPhysAddr(params[1], &val);
226 *(float *)vptr = sp_ctof(val[0]);
227 vptr += sizeof(float);
228 *(float *)vptr = sp_ctof(val[1]);
229 vptr += sizeof(float);
230 *(float *)vptr = sp_ctof(val[2]);
231 vptr += sizeof(float) + sizeof(unsigned long);
232 *(fieldtype_t *)vptr = FIELD_POSITION_VECTOR;
237 static cell_t SetVariantColor(IPluginContext *pContext, const cell_t *params)
240 unsigned char *vptr = g_Variant_t;
242 pContext->LocalToPhysAddr(params[1], &val);
244 *(unsigned char *)vptr = val[0];
245 vptr += sizeof(unsigned char);
246 *(unsigned char *)vptr = val[1];
247 vptr += sizeof(unsigned char);
248 *(unsigned char *)vptr = val[2];
249 vptr += sizeof(unsigned char);
250 *(unsigned char *)vptr = val[3];
251 vptr += sizeof(unsigned char) + sizeof(int)*2 + sizeof(unsigned long);
252 *(fieldtype_t *)vptr = FIELD_COLOR32;
257 static cell_t SetVariantEntity(IPluginContext *pContext, const cell_t *params)
259 CBaseEntity *pEntity;
261 IServerUnknown *pUnk;
262 unsigned char *vptr = g_Variant_t;
265 ENTINDEX_TO_CBASEENTITY(params[1], pEntity);
266 bHandle = reinterpret_cast<IHandleEntity *>(pEntity)->GetRefEHandle();
268 vptr += sizeof(int)*3;
269 *(unsigned long *)vptr = (unsigned long)(bHandle.ToInt());
270 vptr += sizeof(unsigned long);
271 *(fieldtype_t *)vptr = FIELD_EHANDLE;
276 sp_nativeinfo_t g_EntInputNatives[] =
278 {"AcceptEntityInput", AcceptEntityInput},
279 {"SetVariantBool", SetVariantBool},
280 {"SetVariantString", SetVariantString},
281 {"SetVariantInt", SetVariantInt},
282 {"SetVariantFloat", SetVariantFloat},
283 {"SetVariantVector3D", SetVariantVector3D},
284 {"SetVariantPosVector3D", SetVariantPosVector3D},
285 {"SetVariantColor", SetVariantColor},
286 {"SetVariantEntity", SetVariantEntity},