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(ref, buffer) \
41 buffer = gamehelpers->ReferenceToEntity(ref); \
44 return pContext->ThrowNativeError("Entity %d (%d) is not a CBaseEntity", gamehelpers->ReferenceToIndex(ref), ref); \
47 /* Hack to init the variant_t object for the first time */
48 class VariantFirstTimeInit
51 VariantFirstTimeInit()
53 *(unsigned int *)(&g_Variant_t[12]) = INVALID_EHANDLE_INDEX;
55 } g_VariantFirstTimeInit;
57 inline void _init_variant_t()
59 unsigned char *vptr = g_Variant_t;
62 vptr += sizeof(int)*3;
63 *(unsigned long *)vptr = INVALID_EHANDLE_INDEX;
64 vptr += sizeof(unsigned long);
65 *(fieldtype_t *)vptr = FIELD_VOID;
68 static cell_t AcceptEntityInput(IPluginContext *pContext, const cell_t *params)
73 if (!g_pGameConf->GetOffset("AcceptInput", &offset))
75 return pContext->ThrowNativeError("\"AcceptEntityInput\" not supported by this mod");
79 pass[0].type = PassType_Basic;
80 pass[0].flags = PASSFLAG_BYVAL;
81 pass[0].size = sizeof(const char *);
82 pass[1].type = pass[2].type = PassType_Basic;
83 pass[1].flags = pass[2].flags = PASSFLAG_BYVAL;
84 pass[1].size = pass[2].size = sizeof(CBaseEntity *);
85 pass[3].type = PassType_Object;
86 pass[3].flags = PASSFLAG_BYVAL|PASSFLAG_OCTOR|PASSFLAG_ODTOR|PASSFLAG_OASSIGNOP;
87 pass[3].size = SIZEOF_VARIANT_T;
88 pass[4].type = PassType_Basic;
89 pass[4].flags = PASSFLAG_BYVAL;
90 pass[4].size = sizeof(int);
91 pass[5].type = PassType_Basic;
92 pass[5].flags = PASSFLAG_BYVAL;
93 pass[5].size = sizeof(bool);
95 if (!(g_pAcceptInput=g_pBinTools->CreateVCall(offset, 0, 0, &pass[5], pass, 5)))
97 pContext->ThrowNativeError("\"AcceptEntityInput\" wrapper failed to initialized");
101 CBaseEntity *pActivator, *pCaller, *pDest;
104 unsigned char vstk[sizeof(void *) + sizeof(const char *) + sizeof(CBaseEntity *)*2 + SIZEOF_VARIANT_T + sizeof(int)];
105 unsigned char *vptr = vstk;
107 ENTINDEX_TO_CBASEENTITY(params[1], pDest);
108 pContext->LocalToString(params[2], &inputname);
113 ENTINDEX_TO_CBASEENTITY(params[3], pActivator);
119 ENTINDEX_TO_CBASEENTITY(params[4], pCaller);
122 *(void **)vptr = pDest;
123 vptr += sizeof(void *);
124 *(const char **)vptr = inputname;
125 vptr += sizeof(const char *);
126 *(CBaseEntity **)vptr = pActivator;
127 vptr += sizeof(CBaseEntity *);
128 *(CBaseEntity **)vptr = pCaller;
129 vptr += sizeof(CBaseEntity *);
130 memcpy(vptr, g_Variant_t, SIZEOF_VARIANT_T);
131 vptr += SIZEOF_VARIANT_T;
132 *(int *)vptr = params[5];
135 g_pAcceptInput->Execute(vstk, &ret);
139 return (ret) ? 1 : 0;
142 static cell_t SetVariantBool(IPluginContext *pContext, const cell_t *params)
144 unsigned char *vptr = g_Variant_t;
146 *(bool *)vptr = (params[1]) ? true : false;
147 vptr += sizeof(int)*3 + sizeof(unsigned long);
148 *(fieldtype_t *)vptr = FIELD_BOOLEAN;
153 static cell_t SetVariantString(IPluginContext *pContext, const cell_t *params)
156 unsigned char *vptr = g_Variant_t;
158 pContext->LocalToString(params[1], &str);
160 *(string_t *)vptr = MAKE_STRING(str);
161 vptr += sizeof(int)*3 + sizeof(unsigned long);
162 *(fieldtype_t *)vptr = FIELD_STRING;
167 static cell_t SetVariantInt(IPluginContext *pContext, const cell_t *params)
169 unsigned char *vptr = g_Variant_t;
171 *(int *)vptr = params[1];
172 vptr += sizeof(int)*3 + sizeof(unsigned long);
173 *(fieldtype_t *)vptr = FIELD_INTEGER;
178 static cell_t SetVariantFloat(IPluginContext *pContext, const cell_t *params)
180 unsigned char *vptr = g_Variant_t;
182 *(float *)vptr = sp_ctof(params[1]);
183 vptr += sizeof(int)*3 + sizeof(unsigned long);
184 *(fieldtype_t *)vptr = FIELD_FLOAT;
189 static cell_t SetVariantVector3D(IPluginContext *pContext, const cell_t *params)
192 unsigned char *vptr = g_Variant_t;
194 pContext->LocalToPhysAddr(params[1], &val);
196 *(float *)vptr = sp_ctof(val[0]);
197 vptr += sizeof(float);
198 *(float *)vptr = sp_ctof(val[1]);
199 vptr += sizeof(float);
200 *(float *)vptr = sp_ctof(val[2]);
201 vptr += sizeof(float) + sizeof(unsigned long);
202 *(fieldtype_t *)vptr = FIELD_VECTOR;
207 static cell_t SetVariantPosVector3D(IPluginContext *pContext, const cell_t *params)
210 unsigned char *vptr = g_Variant_t;
212 pContext->LocalToPhysAddr(params[1], &val);
214 *(float *)vptr = sp_ctof(val[0]);
215 vptr += sizeof(float);
216 *(float *)vptr = sp_ctof(val[1]);
217 vptr += sizeof(float);
218 *(float *)vptr = sp_ctof(val[2]);
219 vptr += sizeof(float) + sizeof(unsigned long);
220 *(fieldtype_t *)vptr = FIELD_POSITION_VECTOR;
225 static cell_t SetVariantColor(IPluginContext *pContext, const cell_t *params)
228 unsigned char *vptr = g_Variant_t;
230 pContext->LocalToPhysAddr(params[1], &val);
232 *(unsigned char *)vptr = val[0];
233 vptr += sizeof(unsigned char);
234 *(unsigned char *)vptr = val[1];
235 vptr += sizeof(unsigned char);
236 *(unsigned char *)vptr = val[2];
237 vptr += sizeof(unsigned char);
238 *(unsigned char *)vptr = val[3];
239 vptr += sizeof(unsigned char) + sizeof(int)*2 + sizeof(unsigned long);
240 *(fieldtype_t *)vptr = FIELD_COLOR32;
245 static cell_t SetVariantEntity(IPluginContext *pContext, const cell_t *params)
247 CBaseEntity *pEntity;
248 unsigned char *vptr = g_Variant_t;
251 ENTINDEX_TO_CBASEENTITY(params[1], pEntity);
252 bHandle = reinterpret_cast<IHandleEntity *>(pEntity)->GetRefEHandle();
254 vptr += sizeof(int)*3;
255 *(unsigned long *)vptr = (unsigned long)(bHandle.ToInt());
256 vptr += sizeof(unsigned long);
257 *(fieldtype_t *)vptr = FIELD_EHANDLE;
262 sp_nativeinfo_t g_EntInputNatives[] =
264 {"AcceptEntityInput", AcceptEntityInput},
265 {"SetVariantBool", SetVariantBool},
266 {"SetVariantString", SetVariantString},
267 {"SetVariantInt", SetVariantInt},
268 {"SetVariantFloat", SetVariantFloat},
269 {"SetVariantVector3D", SetVariantVector3D},
270 {"SetVariantPosVector3D", SetVariantPosVector3D},
271 {"SetVariantColor", SetVariantColor},
272 {"SetVariantEntity", SetVariantEntity},