[Half-Life AMXX] / include / fakemeta_util.inc Repository:
ViewVC logotype

Annotation of /include/fakemeta_util.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 17 - (view) (download)

1 : ian 17 /**
2 :     * This file provides various utility functions that use the Fakemeta module.
3 :     * This file is created and maintained by VEN.
4 :     * For support and issues, see:
5 :     * http://forums.alliedmods.net/showthread.php?t=28284
6 :     */
7 :    
8 :    
9 :     /* Fakemeta Utilities
10 :     *
11 :     * by VEN
12 :     *
13 :     * This file is provided as is (no warranties).
14 :     */
15 :    
16 :     #if !defined _fakemeta_included
17 :     #include <fakemeta>
18 :     #endif
19 :    
20 :     #if defined _fakemeta_util_included
21 :     #endinput
22 :     #endif
23 :     #define _fakemeta_util_included
24 :    
25 :     #include <xs>
26 :    
27 :    
28 :     /* Engine functions */
29 :    
30 :     #define fm_precache_generic(%1) engfunc(EngFunc_PrecacheGeneric, %1)
31 :     /* stock fm_precache_generic(const file[])
32 :     return engfunc(EngFunc_PrecacheGeneric, file) */
33 :    
34 :     #define fm_precache_event(%1,%2) engfunc(EngFunc_PrecacheEvent, %1, %2)
35 :     /* stock fm_precache_event(type, const name[])
36 :     return engfunc(EngFunc_PrecacheEvent, type, name) */
37 :    
38 :     // ported by v3x
39 :     #define fm_drop_to_floor(%1) engfunc(EngFunc_DropToFloor, %1)
40 :     /* stock fm_drop_to_floor(entity)
41 :     return engfunc(EngFunc_DropToFloor, entity) */
42 :    
43 :     #define fm_force_use(%1,%2) dllfunc(DLLFunc_Use, %2, %1)
44 :     /* stock fm_force_use(user, used)
45 :     return dllfunc(DLLFunc_Use, used, user) */
46 :    
47 :     #define fm_entity_set_size(%1,%2,%3) engfunc(EngFunc_SetSize, %1, %2, %3)
48 :     /* stock fm_entity_set_size(index, const Float:mins[3], const Float:maxs[3])
49 :     return engfunc(EngFunc_SetSize, index, mins, maxs) */
50 :    
51 :     #define fm_get_decal_index(%1) engfunc(EngFunc_DecalIndex, %1)
52 :     /* stock fm_get_decal_index(const decalname[])
53 :     return engfunc(EngFunc_DecalIndex, decalname) */
54 :    
55 :     stock Float:fm_entity_range(ent1, ent2) {
56 :     new Float:origin1[3], Float:origin2[3];
57 :     pev(ent1, pev_origin, origin1);
58 :     pev(ent2, pev_origin, origin2);
59 :    
60 :     return get_distance_f(origin1, origin2);
61 :     }
62 :    
63 :     // based on KoST's port, upgraded version fits into the macros
64 :     #define fm_create_entity(%1) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, %1))
65 :     /* stock fm_create_entity(const classname[])
66 :     return engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, classname)) */
67 :    
68 :     #define fm_find_ent_by_class(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "classname", %2)
69 :     /* stock fm_find_ent_by_class(index, const classname[])
70 :     return engfunc(EngFunc_FindEntityByString, index, "classname", classname) */
71 :    
72 :     stock fm_find_ent_by_owner(index, const classname[], owner, jghgtype = 0) {
73 :     new strtype[11] = "classname", ent = index;
74 :     switch (jghgtype) {
75 :     case 1: strtype = "target";
76 :     case 2: strtype = "targetname";
77 :     }
78 :    
79 :     while ((ent = engfunc(EngFunc_FindEntityByString, ent, strtype, classname)) && pev(ent, pev_owner) != owner) {}
80 :    
81 :     return ent;
82 :     }
83 :    
84 :     #define fm_find_ent_by_target(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "target", %2)
85 :     /* stock fm_find_ent_by_target(index, const target[])
86 :     return engfunc(EngFunc_FindEntityByString, index, "target", target) */
87 :    
88 :     #define fm_find_ent_by_tname(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "targetname", %2)
89 :     /* stock fm_find_ent_by_tname(index, const targetname[])
90 :     return engfunc(EngFunc_FindEntityByString, index, "targetname", targetname) */
91 :    
92 :     stock fm_find_ent_by_model(index, const classname[], const model[]) {
93 :     new ent = index, mdl[72];
94 :     while ((ent = fm_find_ent_by_class(ent, classname))) {
95 :     pev(ent, pev_model, mdl, sizeof mdl - 1);
96 :     if (equal(mdl, model))
97 :     return ent;
98 :     }
99 :    
100 :     return 0;
101 :     }
102 :    
103 :     #define fm_find_ent_in_sphere(%1,%2,%3) engfunc(EngFunc_FindEntityInSphere, %1, %2, %3)
104 :     /* stock fm_find_ent_in_sphere(index, const Float:origin[3], Float:radius)
105 :     return engfunc(EngFunc_FindEntityInSphere, index, origin, radius) */
106 :    
107 :     #define fm_call_think(%1) dllfunc(DLLFunc_Think, %1)
108 :     /* stock fm_call_think(entity)
109 :     return dllfunc(DLLFunc_Think, entity) */
110 :    
111 :     #define fm_is_valid_ent(%1) pev_valid(%1)
112 :     /* stock fm_is_valid_ent(index)
113 :     return pev_valid(index) */
114 :    
115 :     stock fm_entity_set_origin(index, const Float:origin[3]) {
116 :     new Float:mins[3], Float:maxs[3];
117 :     pev(index, pev_mins, mins);
118 :     pev(index, pev_maxs, maxs);
119 :     engfunc(EngFunc_SetSize, index, mins, maxs);
120 :    
121 :     return engfunc(EngFunc_SetOrigin, index, origin);
122 :     }
123 :    
124 :     #define fm_entity_set_model(%1,%2) engfunc(EngFunc_SetModel, %1, %2)
125 :     /* stock fm_entity_set_model(index, const model[])
126 :     return engfunc(EngFunc_SetModel, index, model) */
127 :    
128 :     // ported by v3x
129 :     #define fm_remove_entity(%1) engfunc(EngFunc_RemoveEntity, %1)
130 :     /* stock fm_remove_entity(index)
131 :     return engfunc(EngFunc_RemoveEntity, index) */
132 :    
133 :     #define fm_entity_count() engfunc(EngFunc_NumberOfEntities)
134 :     /* stock fm_entity_count()
135 :     return engfunc(EngFunc_NumberOfEntities) */
136 :    
137 :     #define fm_fake_touch(%1,%2) dllfunc(DLLFunc_Touch, %1, %2)
138 :     /* stock fm_fake_touch(toucher, touched)
139 :     return dllfunc(DLLFunc_Touch, toucher, touched) */
140 :    
141 :     #define fm_DispatchSpawn(%1) dllfunc(DLLFunc_Spawn, %1)
142 :     /* stock fm_DispatchSpawn(entity)
143 :     return dllfunc(DLLFunc_Spawn, entity) */
144 :    
145 :     // ported by v3x
146 :     #define fm_point_contents(%1) engfunc(EngFunc_PointContents, %1)
147 :     /* stock fm_point_contents(const Float:point[3])
148 :     return engfunc(EngFunc_PointContents, point) */
149 :    
150 :     stock fm_trace_line(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3]) {
151 :     engfunc(EngFunc_TraceLine, start, end, ignoreent == -1 ? 1 : 0, ignoreent, 0);
152 :    
153 :     new ent = get_tr2(0, TR_pHit);
154 :     get_tr2(0, TR_vecEndPos, ret);
155 :    
156 :     return pev_valid(ent) ? ent : 0;
157 :     }
158 :    
159 :     stock fm_trace_hull(const Float:origin[3], hull, ignoredent = 0, ignoremonsters = 0) {
160 :     new result = 0;
161 :     engfunc(EngFunc_TraceHull, origin, origin, ignoremonsters, hull, ignoredent > 0 ? ignoredent : 0, 0);
162 :    
163 :     if (get_tr2(0, TR_StartSolid))
164 :     result += 1;
165 :     if (get_tr2(0, TR_AllSolid))
166 :     result += 2;
167 :     if (!get_tr2(0, TR_InOpen))
168 :     result += 4;
169 :    
170 :     return result;
171 :     }
172 :    
173 :     stock fm_trace_normal(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3]) {
174 :     engfunc(EngFunc_TraceLine, start, end, 0, ignoreent, 0);
175 :     get_tr2(0, TR_vecPlaneNormal, ret);
176 :    
177 :     new Float:fraction;
178 :     get_tr2(0, TR_flFraction, fraction);
179 :     if (fraction >= 1.0)
180 :     return 0;
181 :    
182 :     return 1;
183 :     }
184 :    
185 :     // note that for CS planted C4 has a "grenade" classname as well
186 :     stock fm_get_grenade_id(id, model[], len, grenadeid = 0) {
187 :     new ent = fm_find_ent_by_owner(grenadeid, "grenade", id);
188 :     if (ent && len > 0)
189 :     pev(ent, pev_model, model, len);
190 :    
191 :     return ent;
192 :     }
193 :    
194 :     #define fm_halflife_time() get_gametime()
195 :     /* stock Float:fm_halflife_time()
196 :     return get_gametime() */
197 :    
198 :     #define fm_attach_view(%1,%2) engfunc(EngFunc_SetView, %1, %2)
199 :     /* stock fm_attach_view(index, entity)
200 :     return engfunc(EngFunc_SetView, index, entity) */
201 :    
202 :     stock fm_playback_event(flags, invoker, eventindex, Float:delay, const Float:origin[3], const Float:angles[3], Float:fparam1, Float:fparam2, iparam1, iparam2, bparam1, bparam2) {
203 :     return engfunc(EngFunc_PlaybackEvent, flags, invoker, eventindex, delay, origin, angles, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2);
204 :     }
205 :    
206 :     #define fm_eng_get_string(%1,%2,%3) engfunc(EngFunc_SzFromIndex, %1, %2, %3)
207 :     /* stock fm_eng_get_string(istring, string[], len)
208 :     return engfunc(EngFunc_SzFromIndex, istring, string, len) */
209 :    
210 :    
211 :     /* HLSDK functions */
212 :    
213 :     // the dot product is performed in 2d, making the view cone infinitely tall
214 :     stock bool:fm_is_in_viewcone(index, const Float:point[3]) {
215 :     new Float:angles[3];
216 :     pev(index, pev_angles, angles);
217 :     engfunc(EngFunc_MakeVectors, angles);
218 :     global_get(glb_v_forward, angles);
219 :     angles[2] = 0.0;
220 :    
221 :     new Float:origin[3], Float:diff[3], Float:norm[3];
222 :     pev(index, pev_origin, origin);
223 :     xs_vec_sub(point, origin, diff);
224 :     diff[2] = 0.0;
225 :     xs_vec_normalize(diff, norm);
226 :    
227 :     new Float:dot, Float:fov;
228 :     dot = xs_vec_dot(norm, angles);
229 :     pev(index, pev_fov, fov);
230 :     if (dot >= floatcos(fov * M_PI / 360))
231 :     return true;
232 :    
233 :     return false;
234 :     }
235 :    
236 :     stock bool:fm_is_visible(index, const Float:point[3], ignoremonsters = 0) {
237 :     new Float:start[3], Float:view_ofs[3];
238 :     pev(index, pev_origin, start);
239 :     pev(index, pev_view_ofs, view_ofs);
240 :     xs_vec_add(start, view_ofs, start);
241 :    
242 :     engfunc(EngFunc_TraceLine, start, point, ignoremonsters, index, 0);
243 :    
244 :     new Float:fraction;
245 :     get_tr2(0, TR_flFraction, fraction);
246 :     if (fraction == 1.0)
247 :     return true;
248 :    
249 :     return false;
250 :     }
251 :    
252 :    
253 :     /* Engine_stocks functions */
254 :    
255 :     stock fm_fakedamage(victim, const classname[], Float:takedmgdamage, damagetype) {
256 :     new class[] = "trigger_hurt";
257 :     new entity = fm_create_entity(class);
258 :     if (!entity)
259 :     return 0;
260 :    
261 :     new value[16];
262 :     float_to_str(takedmgdamage * 2, value, sizeof value - 1);
263 :     fm_set_kvd(entity, "dmg", value, class);
264 :    
265 :     num_to_str(damagetype, value, sizeof value - 1);
266 :     fm_set_kvd(entity, "damagetype", value, class);
267 :    
268 :     fm_set_kvd(entity, "origin", "8192 8192 8192", class);
269 :     fm_DispatchSpawn(entity);
270 :    
271 :     set_pev(entity, pev_classname, classname);
272 :     fm_fake_touch(entity, victim);
273 :     fm_remove_entity(entity);
274 :    
275 :     return 1;
276 :     }
277 :    
278 :     #define fm_find_ent(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "classname", %2)
279 :     /* stock fm_find_ent(index, const classname[])
280 :     return engfunc(EngFunc_FindEntityByString, index, "classname", classname) */
281 :    
282 :     #define fm_get_user_button(%1) pev(%1, pev_button)
283 :     /* stock fm_get_user_button(index)
284 :     return pev(index, pev_button) */
285 :    
286 :     #define fm_get_user_oldbutton(%1) pev(%1, pev_oldbuttons)
287 :     /* stock fm_get_user_oldbutton(index)
288 :     return pev(index, pev_oldbuttons) */
289 :    
290 :     #define fm_get_entity_flags(%1) pev(%1, pev_flags)
291 :     /* stock fm_get_entity_flags(index)
292 :     return pev(index, pev_flags) */
293 :    
294 :     #define fm_get_entity_distance(%1,%2) floatround(fm_entity_range(%1, %2))
295 :     /* stock fm_get_entity_distance(ent1, ent2)
296 :     return floatround(fm_entity_range(ent1, ent2)) */
297 :    
298 :     #define fm_get_grenade(%1) fm_get_grenade_id(%1, "", 0)
299 :     /* stock fm_get_grenade(id)
300 :     return fm_get_grenade_id(id, "", 0) */
301 :    
302 :     // optimization idea by Orangutanz
303 :     stock fm_get_brush_entity_origin(index, Float:origin[3]) {
304 :     new Float:mins[3], Float:maxs[3];
305 :     pev(index, pev_mins, mins);
306 :     pev(index, pev_maxs, maxs);
307 :    
308 :     origin[0] = (mins[0] + maxs[0]) * 0.5;
309 :     origin[1] = (mins[1] + maxs[1]) * 0.5;
310 :     origin[2] = (mins[2] + maxs[2]) * 0.5;
311 :    
312 :     return 1;
313 :     }
314 :    
315 :     // based on v3x's port, upgraded version returns number of removed entities
316 :     stock fm_remove_entity_name(const classname[]) {
317 :     new ent = -1, num = 0;
318 :     while ((ent = fm_find_ent_by_class(ent, classname)))
319 :     num += fm_remove_entity(ent);
320 :    
321 :     return num;
322 :     }
323 :    
324 :     stock fm_ViewContents(id) {
325 :     new origin[3], Float:Orig[3];
326 :     get_user_origin(id, origin, 3);
327 :     IVecFVec(origin, Orig);
328 :    
329 :     return fm_point_contents(Orig);
330 :     }
331 :    
332 :     stock fm_get_speed(entity) {
333 :     new Float:Vel[3];
334 :     pev(entity, pev_velocity, Vel);
335 :    
336 :     return floatround(vector_length(Vel));
337 :     }
338 :    
339 :     stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) {
340 :     new Float:RenderColor[3];
341 :     RenderColor[0] = float(r);
342 :     RenderColor[1] = float(g);
343 :     RenderColor[2] = float(b);
344 :    
345 :     set_pev(entity, pev_renderfx, fx);
346 :     set_pev(entity, pev_rendercolor, RenderColor);
347 :     set_pev(entity, pev_rendermode, render);
348 :     set_pev(entity, pev_renderamt, float(amount));
349 :    
350 :     return 1;
351 :     }
352 :    
353 :     stock fm_set_entity_flags(index, flag, onoff) {
354 :     new flags = pev(index, pev_flags);
355 :     if ((flags & flag) > 0)
356 :     return onoff == 1 ? 2 : 1 + 0 * set_pev(index, pev_flags, flags - flag);
357 :     else
358 :     return onoff == 0 ? 2 : 1 + 0 * set_pev(index, pev_flags, flags + flag);
359 :    
360 :     return 0;
361 :     }
362 :    
363 :     stock fm_set_entity_visibility(index, visible = 1) {
364 :     set_pev(index, pev_effects, visible == 1 ? pev(index, pev_effects) & ~EF_NODRAW : pev(index, pev_effects) | EF_NODRAW);
365 :    
366 :     return 1;
367 :     }
368 :    
369 :     #define fm_get_entity_visibility(%1) (!(pev(%1, pev_effects) & EF_NODRAW))
370 :     /* stock fm_get_entity_visibility(index)
371 :     return !(pev(index, pev_effects) & EF_NODRAW) */
372 :    
373 :     stock fm_set_user_velocity(entity, const Float:vector[3]) {
374 :     set_pev(entity, pev_velocity, vector);
375 :    
376 :     return 1;
377 :     }
378 :    
379 :     #define fm_get_user_velocity(%1,%2) pev(%1, pev_velocity, %2)
380 :     /* stock fm_get_user_velocity(entity, Float:vector[3])
381 :     return pev(entity, pev_velocity, vector) */
382 :    
383 :    
384 :     /* Fun functions */
385 :    
386 :     #define fm_get_client_listen(%1,%2) engfunc(EngFunc_GetClientListening, %1, %2)
387 :     /* stock fm_get_client_listen(receiver, sender)
388 :     return engfunc(EngFunc_GetClientListening, receiver, sender) */
389 :    
390 :     #define fm_set_client_listen(%1,%2,%3) engfunc(EngFunc_SetClientListening, %1, %2, %3)
391 :     /* stock fm_set_client_listen(receiver, sender, listen)
392 :     return engfunc(EngFunc_SetClientListening, receiver, sender, listen) */
393 :    
394 :     stock fm_get_user_godmode(index) {
395 :     new Float:val;
396 :     pev(index, pev_takedamage, val);
397 :    
398 :     return (val == DAMAGE_NO);
399 :     }
400 :    
401 :     stock fm_set_user_godmode(index, godmode = 0) {
402 :     set_pev(index, pev_takedamage, godmode == 1 ? DAMAGE_NO : DAMAGE_AIM);
403 :    
404 :     return 1;
405 :     }
406 :    
407 :     stock fm_set_user_armor(index, armor) {
408 :     set_pev(index, pev_armorvalue, float(armor));
409 :    
410 :     return 1;
411 :     }
412 :    
413 :     stock fm_set_user_health(index, health) {
414 :     health > 0 ? set_pev(index, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, index);
415 :    
416 :     return 1;
417 :     }
418 :    
419 :     stock fm_set_user_origin(index, /* const */ origin[3]) {
420 :     new Float:orig[3];
421 :     IVecFVec(origin, orig);
422 :    
423 :     return fm_entity_set_origin(index, orig);
424 :     }
425 :    
426 :     stock fm_set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) {
427 :     return fm_set_rendering(index, fx, r, g, b, render, amount);
428 :     }
429 :    
430 :     stock fm_give_item(index, const item[]) {
431 :     if (!equal(item, "weapon_", 7) && !equal(item, "ammo_", 5) && !equal(item, "item_", 5) && !equal(item, "tf_weapon_", 10))
432 :     return 0;
433 :    
434 :     new ent = fm_create_entity(item);
435 :     if (!pev_valid(ent))
436 :     return 0;
437 :    
438 :     new Float:origin[3];
439 :     pev(index, pev_origin, origin);
440 :     set_pev(ent, pev_origin, origin);
441 :     set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN);
442 :     dllfunc(DLLFunc_Spawn, ent);
443 :    
444 :     new save = pev(ent, pev_solid);
445 :     dllfunc(DLLFunc_Touch, ent, index);
446 :     if (pev(ent, pev_solid) != save)
447 :     return ent;
448 :    
449 :     engfunc(EngFunc_RemoveEntity, ent);
450 :    
451 :     return -1;
452 :     }
453 :    
454 :     stock fm_set_user_maxspeed(index, Float:speed = -1.0) {
455 :     engfunc(EngFunc_SetClientMaxspeed, index, speed);
456 :     set_pev(index, pev_maxspeed, speed);
457 :    
458 :     return 1;
459 :     }
460 :    
461 :     stock Float:fm_get_user_maxspeed(index) {
462 :     new Float:speed;
463 :     pev(index, pev_maxspeed, speed);
464 :    
465 :     return speed;
466 :     }
467 :    
468 :     stock fm_set_user_gravity(index, Float:gravity = 1.0) {
469 :     set_pev(index, pev_gravity, gravity);
470 :    
471 :     return 1;
472 :     }
473 :    
474 :     stock Float:fm_get_user_gravity(index) {
475 :     new Float:gravity;
476 :     pev(index, pev_gravity, gravity);
477 :    
478 :     return gravity;
479 :     }
480 :    
481 :     /* interferes with FM_Spawn enum, just use fm_DispatchSpawn
482 :     stock fm_spawn(entity) {
483 :     return dllfunc(DLLFunc_Spawn, entity)
484 :     }
485 :     */
486 :    
487 :     stock fm_set_user_noclip(index, noclip = 0) {
488 :     set_pev(index, pev_movetype, noclip == 1 ? MOVETYPE_NOCLIP : MOVETYPE_WALK);
489 :    
490 :     return 1;
491 :     }
492 :    
493 :     #define fm_get_user_noclip(%1) (pev(%1, pev_movetype) == MOVETYPE_NOCLIP)
494 :     /* stock fm_get_user_noclip(index)
495 :     return (pev(index, pev_movetype) == MOVETYPE_NOCLIP) */
496 :    
497 :     // note: get_user_weapon will still return former weapon index
498 :     stock fm_strip_user_weapons(index) {
499 :     new ent = fm_create_entity("player_weaponstrip");
500 :     if (!pev_valid(ent))
501 :     return 0;
502 :    
503 :     dllfunc(DLLFunc_Spawn, ent);
504 :     dllfunc(DLLFunc_Use, ent, index);
505 :     engfunc(EngFunc_RemoveEntity, ent);
506 :    
507 :     return 1;
508 :     }
509 :    
510 :     stock fm_set_user_frags(index, frags) {
511 :     set_pev(index, pev_frags, float(frags));
512 :    
513 :     return 1;
514 :     }
515 :    
516 :    
517 :     /* Cstrike functions */
518 :    
519 :     stock fm_cs_user_spawn(index) {
520 :     set_pev(index, pev_deadflag, DEAD_RESPAWNABLE);
521 :     dllfunc(DLLFunc_Spawn, index);
522 :     set_pev(index, pev_iuser1, 0);
523 :    
524 :     return 1;
525 :     }
526 :    
527 :    
528 :     /* Custom functions */
529 :    
530 :     // based on Basic-Master's set_keyvalue, upgraded version accepts an optional classname (a bit more efficient if it is passed)
531 :     stock fm_set_kvd(entity, const key[], const value[], const classname[] = "") {
532 :     if (classname[0])
533 :     set_kvd(0, KV_ClassName, classname);
534 :     else {
535 :     new class[32];
536 :     pev(entity, pev_classname, class, sizeof class - 1);
537 :     set_kvd(0, KV_ClassName, class);
538 :     }
539 :    
540 :     set_kvd(0, KV_KeyName, key);
541 :     set_kvd(0, KV_Value, value);
542 :     set_kvd(0, KV_fHandled, 0);
543 :    
544 :     return dllfunc(DLLFunc_KeyValue, entity, 0);
545 :     }
546 :    
547 :     stock fm_find_ent_by_integer(index, pev_field, value) {
548 :     static maxents;
549 :     if (!maxents)
550 :     maxents = global_get(glb_maxEntities);
551 :    
552 :     for (new i = index + 1; i < maxents; ++i) {
553 :     if (pev_valid(i) && pev(i, pev_field) == value)
554 :     return i;
555 :     }
556 :    
557 :     return 0;
558 :     }
559 :    
560 :     stock fm_find_ent_by_flags(index, pev_field, flags) {
561 :     static maxents;
562 :     if (!maxents)
563 :     maxents = global_get(glb_maxEntities);
564 :    
565 :     for (new i = index + 1; i < maxents; ++i) {
566 :     if (pev_valid(i) && (pev(i, pev_field) & flags) == flags)
567 :     return i;
568 :     }
569 :    
570 :     return 0;
571 :     }
572 :    
573 :     stock Float:fm_distance_to_box(const Float:point[3], const Float:mins[3], const Float:maxs[3]) {
574 :     new Float:dist[3];
575 :     for (new i = 0; i < 3; ++i) {
576 :     if (point[i] > maxs[i])
577 :     dist[i] = point[i] - maxs[i];
578 :     else if (mins[i] > point[i])
579 :     dist[i] = mins[i] - point[i];
580 :     }
581 :    
582 :     return vector_length(dist);
583 :     }
584 :    
585 :     stock Float:fm_boxes_distance(const Float:mins1[3], const Float:maxs1[3], const Float:mins2[3], const Float:maxs2[3]) {
586 :     new Float:dist[3];
587 :     for (new i = 0; i < 3; ++i) {
588 :     if (mins1[i] > maxs2[i])
589 :     dist[i] = mins1[i] - maxs2[i];
590 :     else if (mins2[i] > maxs1[i])
591 :     dist[i] = mins2[i] - maxs1[i];
592 :     }
593 :    
594 :     return vector_length(dist);
595 :     }
596 :    
597 :     stock Float:fm_distance_to_boxent(entity, boxent) {
598 :     new Float:point[3];
599 :     pev(entity, pev_origin, point);
600 :    
601 :     new Float:mins[3], Float:maxs[3];
602 :     pev(boxent, pev_absmin, mins);
603 :     pev(boxent, pev_absmax, maxs);
604 :    
605 :     return fm_distance_to_box(point, mins, maxs);
606 :     }
607 :    
608 :     stock Float:fm_boxents_distance(boxent1, boxent2) {
609 :     new Float:mins1[3], Float:maxs1[3];
610 :     pev(boxent1, pev_absmin, mins1);
611 :     pev(boxent1, pev_absmax, maxs1);
612 :    
613 :     new Float:mins2[3], Float:maxs2[3];
614 :     pev(boxent2, pev_absmin, mins2);
615 :     pev(boxent2, pev_absmax, maxs2);
616 :    
617 :     return fm_boxes_distance(mins1, maxs1, mins2, maxs2);
618 :     }
619 :    
620 :     // projects a center of a player's feet base (originally by P34nut, improved)
621 :     stock Float:fm_distance_to_floor(index, ignoremonsters = 1) {
622 :     new Float:start[3], Float:dest[3], Float:end[3];
623 :     pev(index, pev_origin, start);
624 :     dest[0] = start[0];
625 :     dest[1] = start[1];
626 :     dest[2] = -8191.0;
627 :    
628 :     engfunc(EngFunc_TraceLine, start, dest, ignoremonsters, index, 0);
629 :     get_tr2(0, TR_vecEndPos, end);
630 :    
631 :     pev(index, pev_absmin, start);
632 :     new Float:ret = start[2] - end[2];
633 :    
634 :     return ret > 0 ? ret : 0.0;
635 :     }
636 :    
637 :     // potential to crash (?) if used on weaponbox+weapon_* entity pair (use fm_remove_weaponbox instead)
638 :     stock fm_kill_entity(index) {
639 :     set_pev(index, pev_flags, pev(index, pev_flags) | FL_KILLME);
640 :    
641 :     return 1;
642 :     }
643 :    
644 :     // if weapon index isn't passed then assuming that it's the current weapon
645 :     stock fm_get_user_weapon_entity(id, wid = 0) {
646 :     new weap = wid, clip, ammo;
647 :     if (!weap && !(weap = get_user_weapon(id, clip, ammo)))
648 :     return 0;
649 :    
650 :     new class[32];
651 :     get_weaponname(weap, class, sizeof class - 1);
652 :    
653 :     return fm_find_ent_by_owner(-1, class, id);
654 :     }
655 :    
656 :     // only weapon index or its name can be passed, if neither is passed then the current gun will be stripped
657 :     stock bool:fm_strip_user_gun(index, wid = 0, const wname[] = "") {
658 :     new ent_class[32];
659 :     if (!wid && wname[0])
660 :     copy(ent_class, sizeof ent_class - 1, wname);
661 :     else {
662 :     new weapon = wid, clip, ammo;
663 :     if (!weapon && !(weapon = get_user_weapon(index, clip, ammo)))
664 :     return false;
665 :    
666 :     get_weaponname(weapon, ent_class, sizeof ent_class - 1);
667 :     }
668 :    
669 :     new ent_weap = fm_find_ent_by_owner(-1, ent_class, index);
670 :     if (!ent_weap)
671 :     return false;
672 :    
673 :     engclient_cmd(index, "drop", ent_class);
674 :    
675 :     new ent_box = pev(ent_weap, pev_owner);
676 :     if (!ent_box || ent_box == index)
677 :     return false;
678 :    
679 :     dllfunc(DLLFunc_Think, ent_box);
680 :    
681 :     return true;
682 :     }
683 :    
684 :     // only weapon index or its name can be passed, if neither is passed then the current gun will be transferred
685 :     stock bool:fm_transfer_user_gun(index1, index2, wid = 0, const wname[] = "") {
686 :     new ent_class[32];
687 :     if (!wid && wname[0])
688 :     copy(ent_class, sizeof ent_class - 1, wname);
689 :     else {
690 :     new weapon = wid, clip, ammo;
691 :     if (!weapon && !(weapon = get_user_weapon(index1, clip, ammo)))
692 :     return false;
693 :    
694 :     get_weaponname(weapon, ent_class, sizeof ent_class - 1);
695 :     }
696 :    
697 :     new ent_weap = fm_find_ent_by_owner(-1, ent_class, index1);
698 :     if (!ent_weap)
699 :     return false;
700 :    
701 :     engclient_cmd(index1, "drop", ent_class);
702 :    
703 :     new ent_box = pev(ent_weap, pev_owner);
704 :     if (!ent_box || ent_box == index1)
705 :     return false;
706 :    
707 :     set_pev(ent_box, pev_flags, pev(ent_box, pev_flags) | FL_ONGROUND);
708 :     dllfunc(DLLFunc_Touch, ent_box, index2);
709 :     if (pev(ent_weap, pev_owner) != index2)
710 :     return false;
711 :    
712 :     return true;
713 :     }
714 :    
715 :     stock bool:fm_is_ent_visible(index, entity, ignoremonsters = 0) {
716 :     new Float:start[3], Float:dest[3];
717 :     pev(index, pev_origin, start);
718 :     pev(index, pev_view_ofs, dest);
719 :     xs_vec_add(start, dest, start);
720 :    
721 :     pev(entity, pev_origin, dest);
722 :     engfunc(EngFunc_TraceLine, start, dest, ignoremonsters, index, 0);
723 :    
724 :     new Float:fraction;
725 :     get_tr2(0, TR_flFraction, fraction);
726 :     if (fraction == 1.0 || get_tr2(0, TR_pHit) == entity)
727 :     return true;
728 :    
729 :     return false;
730 :     }
731 :    
732 :     // ported from AMXX's core get_user_origin(..., 3) (suggested by Greenberet)
733 :     stock fm_get_aim_origin(index, Float:origin[3]) {
734 :     new Float:start[3], Float:view_ofs[3];
735 :     pev(index, pev_origin, start);
736 :     pev(index, pev_view_ofs, view_ofs);
737 :     xs_vec_add(start, view_ofs, start);
738 :    
739 :     new Float:dest[3];
740 :     pev(index, pev_v_angle, dest);
741 :     engfunc(EngFunc_MakeVectors, dest);
742 :     global_get(glb_v_forward, dest);
743 :     xs_vec_mul_scalar(dest, 9999.0, dest);
744 :     xs_vec_add(start, dest, dest);
745 :    
746 :     engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
747 :     get_tr2(0, TR_vecEndPos, origin);
748 :    
749 :     return 1;
750 :     }
751 :    
752 :     stock bool:fm_get_user_longjump(index) {
753 :     new value[2];
754 :     engfunc(EngFunc_GetPhysicsKeyValue, index, "slj", value, 1);
755 :     switch (value[0]) {
756 :     case '1': return true;
757 :     }
758 :    
759 :     return false;
760 :     }
761 :    
762 :     stock fm_set_user_longjump(index, bool:longjump = true, bool:tempicon = true) {
763 :     if (longjump == fm_get_user_longjump(index))
764 :     return;
765 :    
766 :     if (longjump) {
767 :     engfunc(EngFunc_SetPhysicsKeyValue, index, "slj", "1");
768 :     if (tempicon) {
769 :     static msgid_itempickup;
770 :     if (!msgid_itempickup)
771 :     msgid_itempickup = get_user_msgid("ItemPickup");
772 :    
773 :     message_begin(MSG_ONE, msgid_itempickup, _, index);
774 :     write_string("item_longjump");
775 :     message_end();
776 :     }
777 :     }
778 :     else
779 :     engfunc(EngFunc_SetPhysicsKeyValue, index, "slj", "0");
780 :     }
781 :    
782 :     #define WEAPON_SUIT 31
783 :    
784 :     stock bool:fm_get_user_suit(index) {
785 :     return bool:(!(!(pev(index, pev_weapons) & (1<<WEAPON_SUIT)))); // i'm not insane, this is a trick!
786 :     }
787 :    
788 :     stock fm_set_user_suit(index, bool:suit = true, bool:sound = true) {
789 :     new weapons = pev(index, pev_weapons);
790 :     if (!suit)
791 :     set_pev(index, pev_weapons, weapons & ~(1<<WEAPON_SUIT));
792 :     else if (!(weapons & (1<<WEAPON_SUIT))) {
793 :     set_pev(index, pev_weapons, weapons | (1<<WEAPON_SUIT));
794 :     if (sound)
795 :     emit_sound(index, CHAN_VOICE, "items/tr_kevlar.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
796 :     }
797 :     }
798 :    
799 :     #define FEV_RELIABLE (1<<1)
800 :     #define FEV_GLOBAL (1<<2)
801 :    
802 :     // removes all created decals and players' corpses from the world
803 :     // set a specific index to remove decals only for the given client
804 :     stock fm_cs_remove_decals(index = 0) {
805 :     static eventindex_decal_reset;
806 :     if (!eventindex_decal_reset)
807 :     eventindex_decal_reset = engfunc(EngFunc_PrecacheEvent, 1, "events/decal_reset.sc");
808 :    
809 :     new flags = FEV_RELIABLE;
810 :     if (!index)
811 :     flags |= FEV_GLOBAL;
812 :    
813 :     engfunc(EngFunc_PlaybackEvent, flags, index, eventindex_decal_reset, 0.0, Float:{0.0, 0.0, 0.0}, Float:{0.0, 0.0, 0.0}, 0.0, 0.0, 0, 0, 0, 0);
814 :     }
815 :    
816 :     // checks whether the entity's classname is equal to the passed classname
817 :     stock bool:fm_is_ent_classname(index, const classname[]) {
818 :     if (!pev_valid(index))
819 :     return false;
820 :    
821 :     new class[32];
822 :     pev(index, pev_classname, class, sizeof class - 1);
823 :     if (equal(class, classname))
824 :     return true;
825 :    
826 :     return false;
827 :     }
828 :    
829 :     // the same as AMXX's core user_kill but fixes the issue when the scoreboard doesn't update immediately if flag is set to 1
830 :     stock fm_user_kill(index, flag = 0) {
831 :     if (flag) {
832 :     new Float:frags;
833 :     pev(index, pev_frags, frags);
834 :     set_pev(index, pev_frags, ++frags);
835 :     }
836 :    
837 :     dllfunc(DLLFunc_ClientKill, index);
838 :    
839 :     return 1;
840 :     }
841 :    
842 :     // returns a degree angle between player-to-point and player's view vectors
843 :     stock Float:fm_get_view_angle_diff(index, const Float:point[3]) {
844 :     new Float:vec[3], Float:ofs[3], Float:aim[3];
845 :     pev(index, pev_origin, vec);
846 :     pev(index, pev_view_ofs, ofs);
847 :     xs_vec_add(vec, ofs, vec);
848 :     xs_vec_sub(point, vec, vec);
849 :     xs_vec_normalize(vec, vec);
850 :    
851 :     pev(index, pev_v_angle, aim);
852 :     engfunc(EngFunc_MakeVectors, aim);
853 :     global_get(glb_v_forward, aim);
854 :    
855 :     return xs_vec_angle(vec, aim);
856 :     }
857 :    
858 :     // gets a weapon type of the linked to weaponbox weapon_* entity
859 :     stock fm_get_weaponbox_type(entity) {
860 :     static max_clients, max_entities;
861 :     if (!max_clients)
862 :     max_clients = global_get(glb_maxClients);
863 :     if (!max_entities)
864 :     max_entities = global_get(glb_maxEntities);
865 :    
866 :     for (new i = max_clients + 1; i < max_entities; ++i) {
867 :     if (pev_valid(i) && entity == pev(i, pev_owner)) {
868 :     new wname[32];
869 :     pev(i, pev_classname, wname, sizeof wname - 1);
870 :     return get_weaponid(wname);
871 :     }
872 :     }
873 :    
874 :     return 0;
875 :     }
876 :    
877 :     // safe removal of weaponbox+weapon_* entity pair (delay =~= 0.03 second)
878 :     #define fm_remove_weaponbox(%1) dllfunc(DLLFunc_Think, %1)
879 :     /* stock fm_remove_weaponbox(entity)
880 :     return dllfunc(DLLFunc_Think, entity) */

Contact
ViewVC Help
Powered by ViewVC 1.0.4