[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 44 - (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 : ian 44
306 :     pev(index, pev_origin, origin);
307 : ian 17 pev(index, pev_mins, mins);
308 :     pev(index, pev_maxs, maxs);
309 :    
310 : ian 44 origin[0] += (mins[0] + maxs[0]) * 0.5;
311 :     origin[1] += (mins[1] + maxs[1]) * 0.5;
312 :     origin[2] += (mins[2] + maxs[2]) * 0.5;
313 : ian 17
314 :     return 1;
315 :     }
316 :    
317 :     // based on v3x's port, upgraded version returns number of removed entities
318 :     stock fm_remove_entity_name(const classname[]) {
319 :     new ent = -1, num = 0;
320 :     while ((ent = fm_find_ent_by_class(ent, classname)))
321 :     num += fm_remove_entity(ent);
322 :    
323 :     return num;
324 :     }
325 :    
326 :     stock fm_ViewContents(id) {
327 :     new origin[3], Float:Orig[3];
328 :     get_user_origin(id, origin, 3);
329 :     IVecFVec(origin, Orig);
330 :    
331 :     return fm_point_contents(Orig);
332 :     }
333 :    
334 :     stock fm_get_speed(entity) {
335 :     new Float:Vel[3];
336 :     pev(entity, pev_velocity, Vel);
337 :    
338 :     return floatround(vector_length(Vel));
339 :     }
340 :    
341 :     stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) {
342 :     new Float:RenderColor[3];
343 :     RenderColor[0] = float(r);
344 :     RenderColor[1] = float(g);
345 :     RenderColor[2] = float(b);
346 :    
347 :     set_pev(entity, pev_renderfx, fx);
348 :     set_pev(entity, pev_rendercolor, RenderColor);
349 :     set_pev(entity, pev_rendermode, render);
350 :     set_pev(entity, pev_renderamt, float(amount));
351 :    
352 :     return 1;
353 :     }
354 :    
355 :     stock fm_set_entity_flags(index, flag, onoff) {
356 :     new flags = pev(index, pev_flags);
357 :     if ((flags & flag) > 0)
358 :     return onoff == 1 ? 2 : 1 + 0 * set_pev(index, pev_flags, flags - flag);
359 :     else
360 :     return onoff == 0 ? 2 : 1 + 0 * set_pev(index, pev_flags, flags + flag);
361 :    
362 :     return 0;
363 :     }
364 :    
365 :     stock fm_set_entity_visibility(index, visible = 1) {
366 :     set_pev(index, pev_effects, visible == 1 ? pev(index, pev_effects) & ~EF_NODRAW : pev(index, pev_effects) | EF_NODRAW);
367 :    
368 :     return 1;
369 :     }
370 :    
371 :     #define fm_get_entity_visibility(%1) (!(pev(%1, pev_effects) & EF_NODRAW))
372 :     /* stock fm_get_entity_visibility(index)
373 :     return !(pev(index, pev_effects) & EF_NODRAW) */
374 :    
375 :     stock fm_set_user_velocity(entity, const Float:vector[3]) {
376 :     set_pev(entity, pev_velocity, vector);
377 :    
378 :     return 1;
379 :     }
380 :    
381 :     #define fm_get_user_velocity(%1,%2) pev(%1, pev_velocity, %2)
382 :     /* stock fm_get_user_velocity(entity, Float:vector[3])
383 :     return pev(entity, pev_velocity, vector) */
384 :    
385 :    
386 :     /* Fun functions */
387 :    
388 :     #define fm_get_client_listen(%1,%2) engfunc(EngFunc_GetClientListening, %1, %2)
389 :     /* stock fm_get_client_listen(receiver, sender)
390 :     return engfunc(EngFunc_GetClientListening, receiver, sender) */
391 :    
392 :     #define fm_set_client_listen(%1,%2,%3) engfunc(EngFunc_SetClientListening, %1, %2, %3)
393 :     /* stock fm_set_client_listen(receiver, sender, listen)
394 :     return engfunc(EngFunc_SetClientListening, receiver, sender, listen) */
395 :    
396 :     stock fm_get_user_godmode(index) {
397 :     new Float:val;
398 :     pev(index, pev_takedamage, val);
399 :    
400 :     return (val == DAMAGE_NO);
401 :     }
402 :    
403 :     stock fm_set_user_godmode(index, godmode = 0) {
404 :     set_pev(index, pev_takedamage, godmode == 1 ? DAMAGE_NO : DAMAGE_AIM);
405 :    
406 :     return 1;
407 :     }
408 :    
409 :     stock fm_set_user_armor(index, armor) {
410 :     set_pev(index, pev_armorvalue, float(armor));
411 :    
412 :     return 1;
413 :     }
414 :    
415 :     stock fm_set_user_health(index, health) {
416 :     health > 0 ? set_pev(index, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, index);
417 :    
418 :     return 1;
419 :     }
420 :    
421 :     stock fm_set_user_origin(index, /* const */ origin[3]) {
422 :     new Float:orig[3];
423 :     IVecFVec(origin, orig);
424 :    
425 :     return fm_entity_set_origin(index, orig);
426 :     }
427 :    
428 :     stock fm_set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) {
429 :     return fm_set_rendering(index, fx, r, g, b, render, amount);
430 :     }
431 :    
432 :     stock fm_give_item(index, const item[]) {
433 :     if (!equal(item, "weapon_", 7) && !equal(item, "ammo_", 5) && !equal(item, "item_", 5) && !equal(item, "tf_weapon_", 10))
434 :     return 0;
435 :    
436 :     new ent = fm_create_entity(item);
437 :     if (!pev_valid(ent))
438 :     return 0;
439 :    
440 :     new Float:origin[3];
441 :     pev(index, pev_origin, origin);
442 :     set_pev(ent, pev_origin, origin);
443 :     set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN);
444 :     dllfunc(DLLFunc_Spawn, ent);
445 :    
446 :     new save = pev(ent, pev_solid);
447 :     dllfunc(DLLFunc_Touch, ent, index);
448 :     if (pev(ent, pev_solid) != save)
449 :     return ent;
450 :    
451 :     engfunc(EngFunc_RemoveEntity, ent);
452 :    
453 :     return -1;
454 :     }
455 :    
456 :     stock fm_set_user_maxspeed(index, Float:speed = -1.0) {
457 :     engfunc(EngFunc_SetClientMaxspeed, index, speed);
458 :     set_pev(index, pev_maxspeed, speed);
459 :    
460 :     return 1;
461 :     }
462 :    
463 :     stock Float:fm_get_user_maxspeed(index) {
464 :     new Float:speed;
465 :     pev(index, pev_maxspeed, speed);
466 :    
467 :     return speed;
468 :     }
469 :    
470 :     stock fm_set_user_gravity(index, Float:gravity = 1.0) {
471 :     set_pev(index, pev_gravity, gravity);
472 :    
473 :     return 1;
474 :     }
475 :    
476 :     stock Float:fm_get_user_gravity(index) {
477 :     new Float:gravity;
478 :     pev(index, pev_gravity, gravity);
479 :    
480 :     return gravity;
481 :     }
482 :    
483 :     /* interferes with FM_Spawn enum, just use fm_DispatchSpawn
484 :     stock fm_spawn(entity) {
485 :     return dllfunc(DLLFunc_Spawn, entity)
486 :     }
487 :     */
488 :    
489 :     stock fm_set_user_noclip(index, noclip = 0) {
490 :     set_pev(index, pev_movetype, noclip == 1 ? MOVETYPE_NOCLIP : MOVETYPE_WALK);
491 :    
492 :     return 1;
493 :     }
494 :    
495 :     #define fm_get_user_noclip(%1) (pev(%1, pev_movetype) == MOVETYPE_NOCLIP)
496 :     /* stock fm_get_user_noclip(index)
497 :     return (pev(index, pev_movetype) == MOVETYPE_NOCLIP) */
498 :    
499 :     // note: get_user_weapon will still return former weapon index
500 :     stock fm_strip_user_weapons(index) {
501 :     new ent = fm_create_entity("player_weaponstrip");
502 :     if (!pev_valid(ent))
503 :     return 0;
504 :    
505 :     dllfunc(DLLFunc_Spawn, ent);
506 :     dllfunc(DLLFunc_Use, ent, index);
507 :     engfunc(EngFunc_RemoveEntity, ent);
508 :    
509 :     return 1;
510 :     }
511 :    
512 :     stock fm_set_user_frags(index, frags) {
513 :     set_pev(index, pev_frags, float(frags));
514 :    
515 :     return 1;
516 :     }
517 :    
518 :    
519 :     /* Cstrike functions */
520 :    
521 :     stock fm_cs_user_spawn(index) {
522 :     set_pev(index, pev_deadflag, DEAD_RESPAWNABLE);
523 :     dllfunc(DLLFunc_Spawn, index);
524 :     set_pev(index, pev_iuser1, 0);
525 :    
526 :     return 1;
527 :     }
528 :    
529 :    
530 :     /* Custom functions */
531 :    
532 :     // based on Basic-Master's set_keyvalue, upgraded version accepts an optional classname (a bit more efficient if it is passed)
533 :     stock fm_set_kvd(entity, const key[], const value[], const classname[] = "") {
534 :     if (classname[0])
535 :     set_kvd(0, KV_ClassName, classname);
536 :     else {
537 :     new class[32];
538 :     pev(entity, pev_classname, class, sizeof class - 1);
539 :     set_kvd(0, KV_ClassName, class);
540 :     }
541 :    
542 :     set_kvd(0, KV_KeyName, key);
543 :     set_kvd(0, KV_Value, value);
544 :     set_kvd(0, KV_fHandled, 0);
545 :    
546 :     return dllfunc(DLLFunc_KeyValue, entity, 0);
547 :     }
548 :    
549 :     stock fm_find_ent_by_integer(index, pev_field, value) {
550 :     static maxents;
551 :     if (!maxents)
552 :     maxents = global_get(glb_maxEntities);
553 :    
554 :     for (new i = index + 1; i < maxents; ++i) {
555 :     if (pev_valid(i) && pev(i, pev_field) == value)
556 :     return i;
557 :     }
558 :    
559 :     return 0;
560 :     }
561 :    
562 :     stock fm_find_ent_by_flags(index, pev_field, flags) {
563 :     static maxents;
564 :     if (!maxents)
565 :     maxents = global_get(glb_maxEntities);
566 :    
567 :     for (new i = index + 1; i < maxents; ++i) {
568 :     if (pev_valid(i) && (pev(i, pev_field) & flags) == flags)
569 :     return i;
570 :     }
571 :    
572 :     return 0;
573 :     }
574 :    
575 :     stock Float:fm_distance_to_box(const Float:point[3], const Float:mins[3], const Float:maxs[3]) {
576 :     new Float:dist[3];
577 :     for (new i = 0; i < 3; ++i) {
578 :     if (point[i] > maxs[i])
579 :     dist[i] = point[i] - maxs[i];
580 :     else if (mins[i] > point[i])
581 :     dist[i] = mins[i] - point[i];
582 :     }
583 :    
584 :     return vector_length(dist);
585 :     }
586 :    
587 :     stock Float:fm_boxes_distance(const Float:mins1[3], const Float:maxs1[3], const Float:mins2[3], const Float:maxs2[3]) {
588 :     new Float:dist[3];
589 :     for (new i = 0; i < 3; ++i) {
590 :     if (mins1[i] > maxs2[i])
591 :     dist[i] = mins1[i] - maxs2[i];
592 :     else if (mins2[i] > maxs1[i])
593 :     dist[i] = mins2[i] - maxs1[i];
594 :     }
595 :    
596 :     return vector_length(dist);
597 :     }
598 :    
599 :     stock Float:fm_distance_to_boxent(entity, boxent) {
600 :     new Float:point[3];
601 :     pev(entity, pev_origin, point);
602 :    
603 :     new Float:mins[3], Float:maxs[3];
604 :     pev(boxent, pev_absmin, mins);
605 :     pev(boxent, pev_absmax, maxs);
606 :    
607 :     return fm_distance_to_box(point, mins, maxs);
608 :     }
609 :    
610 :     stock Float:fm_boxents_distance(boxent1, boxent2) {
611 :     new Float:mins1[3], Float:maxs1[3];
612 :     pev(boxent1, pev_absmin, mins1);
613 :     pev(boxent1, pev_absmax, maxs1);
614 :    
615 :     new Float:mins2[3], Float:maxs2[3];
616 :     pev(boxent2, pev_absmin, mins2);
617 :     pev(boxent2, pev_absmax, maxs2);
618 :    
619 :     return fm_boxes_distance(mins1, maxs1, mins2, maxs2);
620 :     }
621 :    
622 :     // projects a center of a player's feet base (originally by P34nut, improved)
623 :     stock Float:fm_distance_to_floor(index, ignoremonsters = 1) {
624 :     new Float:start[3], Float:dest[3], Float:end[3];
625 :     pev(index, pev_origin, start);
626 :     dest[0] = start[0];
627 :     dest[1] = start[1];
628 :     dest[2] = -8191.0;
629 :    
630 :     engfunc(EngFunc_TraceLine, start, dest, ignoremonsters, index, 0);
631 :     get_tr2(0, TR_vecEndPos, end);
632 :    
633 :     pev(index, pev_absmin, start);
634 :     new Float:ret = start[2] - end[2];
635 :    
636 :     return ret > 0 ? ret : 0.0;
637 :     }
638 :    
639 :     // potential to crash (?) if used on weaponbox+weapon_* entity pair (use fm_remove_weaponbox instead)
640 :     stock fm_kill_entity(index) {
641 :     set_pev(index, pev_flags, pev(index, pev_flags) | FL_KILLME);
642 :    
643 :     return 1;
644 :     }
645 :    
646 :     // if weapon index isn't passed then assuming that it's the current weapon
647 :     stock fm_get_user_weapon_entity(id, wid = 0) {
648 :     new weap = wid, clip, ammo;
649 :     if (!weap && !(weap = get_user_weapon(id, clip, ammo)))
650 :     return 0;
651 :    
652 :     new class[32];
653 :     get_weaponname(weap, class, sizeof class - 1);
654 :    
655 :     return fm_find_ent_by_owner(-1, class, id);
656 :     }
657 :    
658 :     // only weapon index or its name can be passed, if neither is passed then the current gun will be stripped
659 :     stock bool:fm_strip_user_gun(index, wid = 0, const wname[] = "") {
660 :     new ent_class[32];
661 :     if (!wid && wname[0])
662 :     copy(ent_class, sizeof ent_class - 1, wname);
663 :     else {
664 :     new weapon = wid, clip, ammo;
665 :     if (!weapon && !(weapon = get_user_weapon(index, clip, ammo)))
666 :     return false;
667 :    
668 :     get_weaponname(weapon, ent_class, sizeof ent_class - 1);
669 :     }
670 :    
671 :     new ent_weap = fm_find_ent_by_owner(-1, ent_class, index);
672 :     if (!ent_weap)
673 :     return false;
674 :    
675 :     engclient_cmd(index, "drop", ent_class);
676 :    
677 :     new ent_box = pev(ent_weap, pev_owner);
678 :     if (!ent_box || ent_box == index)
679 :     return false;
680 :    
681 :     dllfunc(DLLFunc_Think, ent_box);
682 :    
683 :     return true;
684 :     }
685 :    
686 :     // only weapon index or its name can be passed, if neither is passed then the current gun will be transferred
687 :     stock bool:fm_transfer_user_gun(index1, index2, wid = 0, const wname[] = "") {
688 :     new ent_class[32];
689 :     if (!wid && wname[0])
690 :     copy(ent_class, sizeof ent_class - 1, wname);
691 :     else {
692 :     new weapon = wid, clip, ammo;
693 :     if (!weapon && !(weapon = get_user_weapon(index1, clip, ammo)))
694 :     return false;
695 :    
696 :     get_weaponname(weapon, ent_class, sizeof ent_class - 1);
697 :     }
698 :    
699 :     new ent_weap = fm_find_ent_by_owner(-1, ent_class, index1);
700 :     if (!ent_weap)
701 :     return false;
702 :    
703 :     engclient_cmd(index1, "drop", ent_class);
704 :    
705 :     new ent_box = pev(ent_weap, pev_owner);
706 :     if (!ent_box || ent_box == index1)
707 :     return false;
708 :    
709 :     set_pev(ent_box, pev_flags, pev(ent_box, pev_flags) | FL_ONGROUND);
710 :     dllfunc(DLLFunc_Touch, ent_box, index2);
711 :     if (pev(ent_weap, pev_owner) != index2)
712 :     return false;
713 :    
714 :     return true;
715 :     }
716 :    
717 :     stock bool:fm_is_ent_visible(index, entity, ignoremonsters = 0) {
718 :     new Float:start[3], Float:dest[3];
719 :     pev(index, pev_origin, start);
720 :     pev(index, pev_view_ofs, dest);
721 :     xs_vec_add(start, dest, start);
722 :    
723 :     pev(entity, pev_origin, dest);
724 :     engfunc(EngFunc_TraceLine, start, dest, ignoremonsters, index, 0);
725 :    
726 :     new Float:fraction;
727 :     get_tr2(0, TR_flFraction, fraction);
728 :     if (fraction == 1.0 || get_tr2(0, TR_pHit) == entity)
729 :     return true;
730 :    
731 :     return false;
732 :     }
733 :    
734 :     // ported from AMXX's core get_user_origin(..., 3) (suggested by Greenberet)
735 :     stock fm_get_aim_origin(index, Float:origin[3]) {
736 :     new Float:start[3], Float:view_ofs[3];
737 :     pev(index, pev_origin, start);
738 :     pev(index, pev_view_ofs, view_ofs);
739 :     xs_vec_add(start, view_ofs, start);
740 :    
741 :     new Float:dest[3];
742 :     pev(index, pev_v_angle, dest);
743 :     engfunc(EngFunc_MakeVectors, dest);
744 :     global_get(glb_v_forward, dest);
745 :     xs_vec_mul_scalar(dest, 9999.0, dest);
746 :     xs_vec_add(start, dest, dest);
747 :    
748 :     engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
749 :     get_tr2(0, TR_vecEndPos, origin);
750 :    
751 :     return 1;
752 :     }
753 :    
754 :     stock bool:fm_get_user_longjump(index) {
755 :     new value[2];
756 :     engfunc(EngFunc_GetPhysicsKeyValue, index, "slj", value, 1);
757 :     switch (value[0]) {
758 :     case '1': return true;
759 :     }
760 :    
761 :     return false;
762 :     }
763 :    
764 :     stock fm_set_user_longjump(index, bool:longjump = true, bool:tempicon = true) {
765 :     if (longjump == fm_get_user_longjump(index))
766 :     return;
767 :    
768 :     if (longjump) {
769 :     engfunc(EngFunc_SetPhysicsKeyValue, index, "slj", "1");
770 :     if (tempicon) {
771 :     static msgid_itempickup;
772 :     if (!msgid_itempickup)
773 :     msgid_itempickup = get_user_msgid("ItemPickup");
774 :    
775 :     message_begin(MSG_ONE, msgid_itempickup, _, index);
776 :     write_string("item_longjump");
777 :     message_end();
778 :     }
779 :     }
780 :     else
781 :     engfunc(EngFunc_SetPhysicsKeyValue, index, "slj", "0");
782 :     }
783 :    
784 :     #define WEAPON_SUIT 31
785 :    
786 :     stock bool:fm_get_user_suit(index) {
787 :     return bool:(!(!(pev(index, pev_weapons) & (1<<WEAPON_SUIT)))); // i'm not insane, this is a trick!
788 :     }
789 :    
790 :     stock fm_set_user_suit(index, bool:suit = true, bool:sound = true) {
791 :     new weapons = pev(index, pev_weapons);
792 :     if (!suit)
793 :     set_pev(index, pev_weapons, weapons & ~(1<<WEAPON_SUIT));
794 :     else if (!(weapons & (1<<WEAPON_SUIT))) {
795 :     set_pev(index, pev_weapons, weapons | (1<<WEAPON_SUIT));
796 :     if (sound)
797 :     emit_sound(index, CHAN_VOICE, "items/tr_kevlar.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
798 :     }
799 :     }
800 :    
801 :     #define FEV_RELIABLE (1<<1)
802 :     #define FEV_GLOBAL (1<<2)
803 :    
804 :     // removes all created decals and players' corpses from the world
805 :     // set a specific index to remove decals only for the given client
806 :     stock fm_cs_remove_decals(index = 0) {
807 :     static eventindex_decal_reset;
808 :     if (!eventindex_decal_reset)
809 :     eventindex_decal_reset = engfunc(EngFunc_PrecacheEvent, 1, "events/decal_reset.sc");
810 :    
811 :     new flags = FEV_RELIABLE;
812 :     if (!index)
813 :     flags |= FEV_GLOBAL;
814 :    
815 :     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);
816 :     }
817 :    
818 :     // checks whether the entity's classname is equal to the passed classname
819 :     stock bool:fm_is_ent_classname(index, const classname[]) {
820 :     if (!pev_valid(index))
821 :     return false;
822 :    
823 :     new class[32];
824 :     pev(index, pev_classname, class, sizeof class - 1);
825 :     if (equal(class, classname))
826 :     return true;
827 :    
828 :     return false;
829 :     }
830 :    
831 :     // 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
832 :     stock fm_user_kill(index, flag = 0) {
833 :     if (flag) {
834 :     new Float:frags;
835 :     pev(index, pev_frags, frags);
836 :     set_pev(index, pev_frags, ++frags);
837 :     }
838 :    
839 :     dllfunc(DLLFunc_ClientKill, index);
840 :    
841 :     return 1;
842 :     }
843 :    
844 :     // returns a degree angle between player-to-point and player's view vectors
845 :     stock Float:fm_get_view_angle_diff(index, const Float:point[3]) {
846 :     new Float:vec[3], Float:ofs[3], Float:aim[3];
847 :     pev(index, pev_origin, vec);
848 :     pev(index, pev_view_ofs, ofs);
849 :     xs_vec_add(vec, ofs, vec);
850 :     xs_vec_sub(point, vec, vec);
851 :     xs_vec_normalize(vec, vec);
852 :    
853 :     pev(index, pev_v_angle, aim);
854 :     engfunc(EngFunc_MakeVectors, aim);
855 :     global_get(glb_v_forward, aim);
856 :    
857 :     return xs_vec_angle(vec, aim);
858 :     }
859 :    
860 :     // gets a weapon type of the linked to weaponbox weapon_* entity
861 :     stock fm_get_weaponbox_type(entity) {
862 :     static max_clients, max_entities;
863 :     if (!max_clients)
864 :     max_clients = global_get(glb_maxClients);
865 :     if (!max_entities)
866 :     max_entities = global_get(glb_maxEntities);
867 :    
868 :     for (new i = max_clients + 1; i < max_entities; ++i) {
869 :     if (pev_valid(i) && entity == pev(i, pev_owner)) {
870 :     new wname[32];
871 :     pev(i, pev_classname, wname, sizeof wname - 1);
872 :     return get_weaponid(wname);
873 :     }
874 :     }
875 :    
876 :     return 0;
877 :     }
878 :    
879 :     // safe removal of weaponbox+weapon_* entity pair (delay =~= 0.03 second)
880 :     #define fm_remove_weaponbox(%1) dllfunc(DLLFunc_Think, %1)
881 :     /* stock fm_remove_weaponbox(entity)
882 :     return dllfunc(DLLFunc_Think, entity) */

Contact
ViewVC Help
Powered by ViewVC 1.0.4