|
dvander@954
|
1 |
#include "extension.h" |
|
dvander@954
|
2 |
#include "vcallbuilder.h" |
|
dvander@954
|
3 |
#include "vnatives.h" |
|
dvander@954
|
4 |
|
|
dvander@954
|
5 |
List<ValveCall *> g_RegCalls; |
|
dvander@954
|
6 |
|
|
dvander@985
|
7 |
inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags, unsigned int decflags=0) |
|
dvander@954
|
8 |
{ |
|
dvander@985
|
9 |
info.decflags = decflags; |
|
dvander@954
|
10 |
info.encflags = 0; |
|
dvander@954
|
11 |
info.flags = flags; |
|
dvander@954
|
12 |
info.type = type; |
|
dvander@954
|
13 |
info.vtype = vtype; |
|
dvander@954
|
14 |
} |
|
dvander@954
|
15 |
|
|
dvander@954
|
16 |
#define START_CALL() \ |
|
dvander@954
|
17 |
unsigned char *vptr = pCall->stk_get(); |
|
dvander@954
|
18 |
|
|
dvander@954
|
19 |
#define FINISH_CALL_SIMPLE(vret) \ |
|
dvander@954
|
20 |
pCall->call->Execute(vptr, vret); \ |
|
dvander@954
|
21 |
pCall->stk_put(vptr); |
|
dvander@954
|
22 |
|
|
dvander@954
|
23 |
#define ENCODE_VALVE_PARAM(num, which, vnum) \ |
|
dvander@954
|
24 |
if (EncodeValveParam(pContext, \ |
|
dvander@954
|
25 |
params[num], \ |
|
dvander@987
|
26 |
pCall, \ |
|
dvander@954
|
27 |
&pCall->which[vnum], \ |
|
dvander@987
|
28 |
vptr) \ |
|
dvander@954
|
29 |
== Data_Fail) \ |
|
dvander@954
|
30 |
{ \ |
|
dvander@954
|
31 |
return 0; \ |
|
dvander@954
|
32 |
} |
|
dvander@954
|
33 |
|
|
dvander@954
|
34 |
#define DECODE_VALVE_PARAM(num, which, vnum) \ |
|
dvander@954
|
35 |
if (DecodeValveParam(pContext, \ |
|
dvander@954
|
36 |
params[num], \ |
|
dvander@987
|
37 |
pCall, \ |
|
dvander@954
|
38 |
&pCall->which[vnum], \ |
|
dvander@987
|
39 |
vptr) \ |
|
dvander@954
|
40 |
== Data_Fail) \ |
|
dvander@954
|
41 |
{ \ |
|
dvander@954
|
42 |
return 0; \ |
|
dvander@954
|
43 |
} |
|
dvander@954
|
44 |
|
|
dvander@954
|
45 |
bool CreateBaseCall(const char *name, |
|
dvander@954
|
46 |
ValveCallType vcalltype, |
|
dvander@954
|
47 |
const ValvePassInfo *retinfo, |
|
dvander@954
|
48 |
const ValvePassInfo params[], |
|
dvander@954
|
49 |
unsigned int numParams, |
|
dvander@954
|
50 |
ValveCall **vaddr) |
|
dvander@954
|
51 |
{ |
|
dvander@954
|
52 |
int offset; |
|
dvander@954
|
53 |
ValveCall *call; |
|
dvander@954
|
54 |
if (g_pGameConf->GetOffset(name, &offset)) |
|
dvander@954
|
55 |
{ |
|
dvander@954
|
56 |
call = CreateValveVCall(offset, vcalltype, retinfo, params, numParams); |
|
dvander@954
|
57 |
if (call) |
|
dvander@954
|
58 |
{ |
|
dvander@954
|
59 |
g_RegCalls.push_back(call); |
|
dvander@954
|
60 |
} |
|
dvander@954
|
61 |
*vaddr = call; |
|
dvander@954
|
62 |
return true; |
|
dvander@954
|
63 |
} else { |
|
dvander@954
|
64 |
void *addr; |
|
dvander@954
|
65 |
if (g_pGameConf->GetMemSig(name, &addr)) |
|
dvander@954
|
66 |
{ |
|
dvander@954
|
67 |
call = CreateValveCall(addr, vcalltype, retinfo, params, numParams); |
|
dvander@954
|
68 |
if (call) |
|
dvander@954
|
69 |
{ |
|
dvander@954
|
70 |
g_RegCalls.push_back(call); |
|
dvander@954
|
71 |
} |
|
dvander@954
|
72 |
*vaddr = call; |
|
dvander@954
|
73 |
return true; |
|
dvander@954
|
74 |
} |
|
dvander@954
|
75 |
} |
|
dvander@954
|
76 |
return false; |
|
dvander@954
|
77 |
} |
|
dvander@954
|
78 |
|
|
dvander@954
|
79 |
|
|
dvander@954
|
80 |
static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params) |
|
dvander@954
|
81 |
{ |
|
dvander@954
|
82 |
static ValveCall *pCall = NULL; |
|
dvander@954
|
83 |
if (!pCall) |
|
dvander@954
|
84 |
{ |
|
dvander@954
|
85 |
ValvePassInfo pass[2]; |
|
dvander@954
|
86 |
InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, 0); |
|
dvander@954
|
87 |
InitPass(pass[1], Valve_Bool, PassType_Basic, 0); |
|
dvander@954
|
88 |
if (!CreateBaseCall("RemovePlayerItem", ValveCall_Player, &pass[1], &pass[0], 1, &pCall)) |
|
dvander@954
|
89 |
{ |
|
dvander@954
|
90 |
return pContext->ThrowNativeError("\"RemovePlayerItem\" not supported by this mod"); |
|
dvander@954
|
91 |
} else if (!pCall) { |
|
dvander@954
|
92 |
return pContext->ThrowNativeError("\"RemovePlayerItem\" wrapper failed to initialized"); |
|
dvander@954
|
93 |
} |
|
dvander@954
|
94 |
} |
|
dvander@954
|
95 |
|
|
dvander@954
|
96 |
bool ret; |
|
dvander@954
|
97 |
START_CALL(); |
|
dvander@954
|
98 |
DECODE_VALVE_PARAM(1, thisinfo, 0); |
|
dvander@954
|
99 |
DECODE_VALVE_PARAM(2, vparams, 0); |
|
dvander@954
|
100 |
FINISH_CALL_SIMPLE(&ret); |
|
dvander@954
|
101 |
return ret ? 1 : 0; |
|
dvander@954
|
102 |
} |
|
dvander@954
|
103 |
|
|
dvander@954
|
104 |
static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params) |
|
dvander@954
|
105 |
{ |
|
dvander@954
|
106 |
static ValveCall *pCall = NULL; |
|
dvander@954
|
107 |
if (!pCall) |
|
dvander@954
|
108 |
{ |
|
dvander@954
|
109 |
ValvePassInfo pass[3]; |
|
dvander@954
|
110 |
InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); |
|
dvander@954
|
111 |
InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); |
|
dvander@954
|
112 |
InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); |
|
dvander@954
|
113 |
if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[2], pass, 2, &pCall)) |
|
dvander@954
|
114 |
{ |
|
dvander@954
|
115 |
return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod"); |
|
dvander@954
|
116 |
} else if (!pCall) { |
|
dvander@954
|
117 |
return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialized"); |
|
dvander@954
|
118 |
} |
|
dvander@954
|
119 |
} |
|
dvander@954
|
120 |
|
|
dvander@954
|
121 |
CBaseEntity *pEntity = NULL; |
|
dvander@954
|
122 |
START_CALL(); |
|
dvander@954
|
123 |
DECODE_VALVE_PARAM(1, thisinfo, 0); |
|
dvander@954
|
124 |
DECODE_VALVE_PARAM(2, vparams, 0); |
|
dvander@954
|
125 |
DECODE_VALVE_PARAM(3, vparams, 1); |
|
dvander@954
|
126 |
FINISH_CALL_SIMPLE(&pEntity); |
|
dvander@954
|
127 |
|
|
dvander@954
|
128 |
if (pEntity == NULL) |
|
dvander@954
|
129 |
{ |
|
dvander@954
|
130 |
return -1; |
|
dvander@954
|
131 |
} |
|
dvander@954
|
132 |
|
|
dvander@954
|
133 |
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); |
|
dvander@954
|
134 |
if (!pEdict) |
|
dvander@954
|
135 |
{ |
|
dvander@954
|
136 |
return -1; |
|
dvander@954
|
137 |
} |
|
dvander@954
|
138 |
|
|
dvander@954
|
139 |
return engine->IndexOfEdict(pEdict); |
|
dvander@954
|
140 |
} |
|
dvander@954
|
141 |
|
|
dvander@954
|
142 |
static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params) |
|
dvander@954
|
143 |
{ |
|
dvander@954
|
144 |
static ValveCall *pCall = NULL; |
|
dvander@954
|
145 |
if (!pCall) |
|
dvander@954
|
146 |
{ |
|
dvander@954
|
147 |
ValvePassInfo pass[2]; |
|
dvander@954
|
148 |
InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); |
|
dvander@954
|
149 |
InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); |
|
dvander@954
|
150 |
if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall)) |
|
dvander@954
|
151 |
{ |
|
dvander@954
|
152 |
return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod"); |
|
dvander@954
|
153 |
} else if (!pCall) { |
|
dvander@954
|
154 |
return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized"); |
|
dvander@954
|
155 |
} |
|
dvander@954
|
156 |
} |
|
dvander@954
|
157 |
|
|
dvander@954
|
158 |
CBaseEntity *pEntity; |
|
dvander@954
|
159 |
START_CALL(); |
|
dvander@954
|
160 |
DECODE_VALVE_PARAM(1, thisinfo, 0); |
|
dvander@954
|
161 |
DECODE_VALVE_PARAM(2, vparams, 0); |
|
dvander@954
|
162 |
FINISH_CALL_SIMPLE(&pEntity); |
|
dvander@954
|
163 |
|
|
dvander@954
|
164 |
if (pEntity == NULL) |
|
dvander@954
|
165 |
{ |
|
dvander@954
|
166 |
return -1; |
|
dvander@954
|
167 |
} |
|
dvander@954
|
168 |
|
|
dvander@954
|
169 |
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); |
|
dvander@954
|
170 |
if (!pEdict) |
|
dvander@954
|
171 |
{ |
|
dvander@954
|
172 |
return -1; |
|
dvander@954
|
173 |
} |
|
dvander@954
|
174 |
|
|
dvander@954
|
175 |
return engine->IndexOfEdict(pEdict); |
|
dvander@954
|
176 |
} |
|
dvander@954
|
177 |
|
|
dvander@955
|
178 |
static cell_t IgnitePlayer(IPluginContext *pContext, const cell_t *params) |
|
dvander@955
|
179 |
{ |
|
dvander@955
|
180 |
static ValveCall *pCall = NULL; |
|
dvander@955
|
181 |
if (!pCall) |
|
dvander@955
|
182 |
{ |
|
dvander@955
|
183 |
ValvePassInfo pass[4]; |
|
dvander@955
|
184 |
InitPass(pass[0], Valve_Float, PassType_Float, PASSFLAG_BYVAL); |
|
dvander@955
|
185 |
InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); |
|
dvander@955
|
186 |
InitPass(pass[2], Valve_Float, PassType_Float, PASSFLAG_BYVAL); |
|
dvander@955
|
187 |
InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); |
|
dvander@980
|
188 |
if (!CreateBaseCall("Ignite", ValveCall_Entity, NULL, pass, 4, &pCall)) |
|
dvander@955
|
189 |
{ |
|
dvander@955
|
190 |
return pContext->ThrowNativeError("\"Ignite\" not supported by this mod"); |
|
dvander@955
|
191 |
} else if (!pCall) { |
|
dvander@955
|
192 |
return pContext->ThrowNativeError("\"Ignite\" wrapper failed to initialized"); |
|
dvander@955
|
193 |
} |
|
dvander@955
|
194 |
} |
|
dvander@955
|
195 |
|
|
dvander@955
|
196 |
START_CALL(); |
|
dvander@955
|
197 |
DECODE_VALVE_PARAM(1, thisinfo, 0); |
|
dvander@955
|
198 |
DECODE_VALVE_PARAM(2, vparams, 0); |
|
dvander@955
|
199 |
DECODE_VALVE_PARAM(3, vparams, 1); |
|
dvander@955
|
200 |
DECODE_VALVE_PARAM(4, vparams, 2); |
|
dvander@955
|
201 |
DECODE_VALVE_PARAM(5, vparams, 3); |
|
dvander@955
|
202 |
FINISH_CALL_SIMPLE(NULL); |
|
dvander@955
|
203 |
|
|
dvander@955
|
204 |
return 1; |
|
dvander@955
|
205 |
} |
|
dvander@955
|
206 |
|
|
dvander@955
|
207 |
static cell_t ExtinguishPlayer(IPluginContext *pContext, const cell_t *params) |
|
dvander@955
|
208 |
{ |
|
dvander@955
|
209 |
static ValveCall *pCall = NULL; |
|
dvander@955
|
210 |
if (!pCall) |
|
dvander@955
|
211 |
{ |
|
dvander@980
|
212 |
if (!CreateBaseCall("Extinguish", ValveCall_Entity, NULL, NULL, 0, &pCall)) |
|
dvander@955
|
213 |
{ |
|
dvander@955
|
214 |
return pContext->ThrowNativeError("\"Extinguish\" not supported by this mod"); |
|
dvander@955
|
215 |
} else if (!pCall) { |
|
dvander@955
|
216 |
return pContext->ThrowNativeError("\"Extinguish\" wrapper failed to initialized"); |
|
dvander@955
|
217 |
} |
|
dvander@955
|
218 |
} |
|
dvander@955
|
219 |
|
|
dvander@955
|
220 |
START_CALL(); |
|
dvander@955
|
221 |
DECODE_VALVE_PARAM(1, thisinfo, 0); |
|
dvander@955
|
222 |
FINISH_CALL_SIMPLE(NULL); |
|
dvander@955
|
223 |
|
|
dvander@955
|
224 |
return 1; |
|
dvander@955
|
225 |
} |
|
dvander@955
|
226 |
|
|
dvander@955
|
227 |
static cell_t TeleportPlayer(IPluginContext *pContext, const cell_t *params) |
|
dvander@955
|
228 |
{ |
|
dvander@955
|
229 |
static ValveCall *pCall = NULL; |
|
dvander@955
|
230 |
if (!pCall) |
|
dvander@955
|
231 |
{ |
|
dvander@955
|
232 |
ValvePassInfo pass[3]; |
|
dvander@985
|
233 |
InitPass(pass[0], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); |
|
dvander@985
|
234 |
InitPass(pass[1], Valve_QAngle, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); |
|
dvander@985
|
235 |
InitPass(pass[2], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); |
|
dvander@980
|
236 |
if (!CreateBaseCall("Teleport", ValveCall_Entity, NULL, pass, 3, &pCall)) |
|
dvander@955
|
237 |
{ |
|
dvander@955
|
238 |
return pContext->ThrowNativeError("\"Teleport\" not supported by this mod"); |
|
dvander@955
|
239 |
} else if (!pCall) { |
|
dvander@955
|
240 |
return pContext->ThrowNativeError("\"Teleport\" wrapper failed to initialized"); |
|
dvander@955
|
241 |
} |
|
dvander@955
|
242 |
} |
|
dvander@955
|
243 |
|
|
dvander@955
|
244 |
START_CALL(); |
|
dvander@955
|
245 |
DECODE_VALVE_PARAM(1, thisinfo, 0); |
|
dvander@955
|
246 |
DECODE_VALVE_PARAM(2, vparams, 0); |
|
dvander@955
|
247 |
DECODE_VALVE_PARAM(3, vparams, 1); |
|
dvander@955
|
248 |
DECODE_VALVE_PARAM(4, vparams, 2); |
|
dvander@955
|
249 |
FINISH_CALL_SIMPLE(NULL); |
|
dvander@955
|
250 |
|
|
dvander@955
|
251 |
return 1; |
|
dvander@955
|
252 |
} |
|
dvander@955
|
253 |
|
|
dvander@954
|
254 |
sp_nativeinfo_t g_Natives[] = |
|
dvander@954
|
255 |
{ |
|
dvander@955
|
256 |
{"ExtinguishPlayer", ExtinguishPlayer}, |
|
dvander@980
|
257 |
{"ExtinguishEntity", ExtinguishPlayer}, |
|
dvander@954
|
258 |
{"GivePlayerItem", GiveNamedItem}, |
|
dvander@954
|
259 |
{"GetPlayerWeaponSlot", GetPlayerWeaponSlot}, |
|
dvander@955
|
260 |
{"IgnitePlayer", IgnitePlayer}, |
|
dvander@980
|
261 |
{"IgniteEntity", IgnitePlayer}, |
|
dvander@955
|
262 |
{"RemovePlayerItem", RemovePlayerItem}, |
|
dvander@955
|
263 |
{"TeleportPlayer", TeleportPlayer}, |
|
dvander@980
|
264 |
{"TeleportEntity", TeleportPlayer}, |
|
dvander@954
|
265 |
{NULL, NULL}, |
|
dvander@954
|
266 |
}; |
|
dvander@980
|
267 |
|