AMXX-BG.INFO toolsx.inc Raw include

toolsx.inc

Original include source with line numbers.

Back Download .inc
1 /*
2 Tools X v0.1
3 Copyright (c) SAMURAI
4
5 */
6
7
8 #if !defined _fakemeta_included
9 #include <fakemeta>
10 #endif
11
12 #if defined toolsx_included
13 #endinput
14 #endif
15 #define toolsx_included
16
17
18 #define FFADE_IN 0x0000
19 #define FFADE_OUT 0x0001
20 #define FFADE_MODULATE 0x0002
21 #define FFADE_STAYOUT 0x0004
22
23
24 stock bool:is_aiming_at_hostage(index)
25 {
26 new target, temp, classname[32];
27
28 get_user_aiming(index, target, temp);
29
30 pev(target, pev_classname, classname, 31);
31
32 if ( equal(classname, "hostage_entity") )
33 return true;
34
35 return false;
36 }
37
38
39 stock bool:is_aiming_at_sky(index)
40 {
41 new target, temp;
42
43 get_user_aiming(index,target,temp);
44
45 if( engfunc(EngFunc_PointContents,target) == CONTENTS_SKY)
46 return true;
47
48 return false;
49 }
50
51
52 stock bool:is_aiming_at_water(index)
53 {
54 new target, temp;
55
56 get_user_aiming(index,target,temp);
57
58 if( engfunc(EngFunc_PointContents,target) == CONTENTS_WATER)
59 return true;
60
61 return false;
62 }
63
64
65 stock bool:is_nothing_above_index(index)
66 {
67 new Float:origin[1], Float:origin[2]
68 origin2 = origin1;
69
70 pev(index,pev_origin,origin1);
71
72
73 new ptr;
74 engfunc(EngFunc_TraceLine,origin1,origin2,IGNORE_MONSTERS,index,ptr);
75
76 new Float:flFraction;
77 get_tr2(ptr,TR_flFraction,flFraction);
78
79 if(flFraction == 1.0)
80 return true;
81
82 return false;
83
84 }
85
86
87 stock bool:is_nothing_solid_abv_index(index)
88 {
89 new Float:origin[1], Float:origin[2]
90 pev(index,pev_origin,origin1);
91
92 origin2 = origin1;
93
94 new ptr;
95 engfunc(EngFunc_TraceLine,origin1,origin2,IGNORE_MONSTERS,index,ptr);
96
97 new hit = get_tr2(ptr,TR_pHit);
98
99 if(hit > 0 && pev_valid(hit))
100 {
101 new classname[6];
102 pev(hit,pev_classname,classname,5);
103
104
105 if(!equal(classname,"func_"))
106 return true;
107 }
108
109
110 return false;
111
112 }
113
114 /* ==================================
115 tlx_distance_to_sky
116 is fm_distance_to_floor stock from
117 fakemeta util with changed dest.z
118 value
119 ===================================*/
120 stock Float:tlx_distance_to_sky(id)
121 {
122 new Float:origin_start[3], Float:origin_end[3];
123 pev(id, pev_origin, origin_start);
124
125 new Float:f_dest[3];
126
127 f_dest[0] = origin_start[0];
128 f_dest[1] = origin_start[1];
129 f_dest[2] = 8191.0;
130
131 engfunc(EngFunc_TraceLine, origin_start, f_dest, IGNORE_MONSTERS, id, 0);
132 get_tr2(0, TR_vecEndPos, origin_end);
133
134 pev(id, pev_absmin, origin_start);
135 new Float:ret = origin_start[2] - origin_end[2];
136
137 return ret > 0 ? ret : 0.0;
138 }
139
140
141 /*
142 //=====================================================================================================================
143 tlx_create_explosion
144
145 Example usage : tlx_create_explosion(origin, MSG_BROADCAST, SVC_TEMPENTITY, sprite index, 20, 40, 2)
146
147 // for desType are available:
148 MSG_BROADCAST // Unreliable to all
149 MSG_ONE // Reliable to one (msg_entity)
150 MSG_ALL // Reliable to all
151 MSG_INIT // Write to the init string
152 MSG_PVS // Ents in PVS of org
153 MSG_PAS // Ents in PAS of org
154 MSG_PVS_R // Reliable to PVS
155 MSG_PAS_R // Reliable to PAS
156 MSG_ONE_UNRELIABLE // Send to one client, but don't put in reliable stream, put in unreliable datagram (could be dropped)
157 MSG_SPEC // Sends to all spectator proxies
158
159 For msgType are available:
160 SVC_TEMPENTITY 23
161 SVC_INTERMISSION 30
162 SVC_CDTRACK 32
163 SVC_WEAPONANIM 35
164 SVC_ROOMTYPE 37
165 SVC_ADDANGLE 38 // [vec3] add this angle to the view angle
166 SVC_NEWUSERMSG 39
167 SVC_HLTV 50
168
169
170 ========================================================================================================================*/
171 stock tlx_create_explosion(Float:origin[3], destType, msgType, sprite, scale, framerate, flags )
172 {
173
174
175 message_begin(destType, msgType);
176 write_byte(TE_EXPLOSION);
177 write_coord(floatround(origin[0]));
178 write_coord(floatround(origin[1]));
179 write_coord(floatround(origin[2]));
180 write_short(sprite);
181 write_byte(scale);
182 write_byte(framerate);
183 write_byte(flags);
184 message_end();
185
186 }
187
188
189
190 stock fade_units_to_seconds(num)
191 {
192 return ((1<<12) * (num));
193 }
194
195
196
197 /*=========================================================================================================================
198 tlx_flash_player
199
200 Ex to use:
201
202 tlx_flash_player(id, MSG_ONE, 3, 5, FADE_OUT, 255, 0, 255, 200)
203
204 // for desType are available:
205 MSG_BROADCAST // Unreliable to all
206 MSG_ONE // Reliable to one (msg_entity)
207 MSG_ALL // Reliable to all
208 MSG_INIT // Write to the init string
209 MSG_PVS // Ents in PVS of org
210 MSG_PAS // Ents in PAS of org
211 MSG_PVS_R // Reliable to PVS
212 MSG_PAS_R // Reliable to PAS
213 MSG_ONE_UNRELIABLE // Send to one client, but don't put in reliable stream, put in unreliable datagram (could be dropped)
214 MSG_SPEC // Sends to all spectator proxies
215
216
217 For flags you can use:
218 FFADE_IN Just here so we don't pass 0 into the function
219 FFADE_OUT Fade out (not in)
220 FFADE_MODULATE Modulate (don't blend)
221 FFADE_STAYOUT Ignores the duration, stays faded out until new ScreenFade message received
222
223 ===========================================================================================================================*/
224 stock tlx_flash_player(index, destType, iDuration, iHoldTime, iFlags, r, g, b, alpha)
225 {
226
227 if(!is_user_alive(index))
228 return 0;
229
230
231 message_begin( destType,get_user_msgid("ScreenFade"), {0,0,0}, index );
232 write_short(fade_units_to_seconds(iDuration));
233 write_short(fade_units_to_seconds(iHoldTime));
234 write_short(iFlags);
235 write_short(r);
236 write_short(g);
237 write_short(b);
238 write_byte(alpha);
239 message_end();
240
241 return 1;
242
243
244 }
245
246
247 /*========================================================================================================================
248 shake_player_screen
249
250
251 ex to use:
252 shake_player_screen(id, MSG_ONE, 20, 5, 6)
253
254 // for desType are available:
255 MSG_BROADCAST // Unreliable to all
256 MSG_ONE // Reliable to one (msg_entity)
257 MSG_ALL // Reliable to all
258 MSG_INIT // Write to the init string
259 MSG_PVS // Ents in PVS of org
260 MSG_PAS // Ents in PAS of org
261 MSG_PVS_R // Reliable to PVS
262 MSG_PAS_R // Reliable to PAS
263 MSG_ONE_UNRELIABLE // Send to one client, but don't put in reliable stream, put in unreliable datagram (could be dropped)
264 MSG_SPEC // Sends to all spectator proxies
265
266 ===================================================================================================================*/
267 stock shake_player_screen(index, destType, iAmplitude, iDuration, iFrequency)
268 {
269
270
271 if(!is_user_alive(index))
272 return 0;
273
274 message_begin( destType,get_user_msgid("ScreenShake"), {0,0,0}, index );
275
276 write_short(fade_units_to_seconds(iAmplitude));
277 write_short(fade_units_to_seconds(iDuration));
278 write_short(fade_units_to_seconds(iFrequency));
279
280 message_end();
281
282 return 1;
283
284 }
285
286
287
288 stock tlx_VectorInverse(Float:vector[3])
289 {
290 vector[0] *= -1
291
292 vector[1] *= -1
293
294 vector[2] *= -1
295 }
296
297
298 stock tlx_VectorScale(const Float:in[3], Float:scale, Float:out[3])
299 {
300
301 out[0] = in[0] * scale;
302
303 out[1] = in[1] * scale;
304
305 out[2] = in[2] * scale;
306
307 }
308
309
310
311 stock Float:tlx_VectorNormalize(Float:vector[3])
312 {
313
314 new Float:length, Float:ilength;
315
316 length = vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2];
317 length = floatsqroot(length);
318
319 if (length)
320 {
321 ilength = 1 / length;
322 vector[0] *= ilength;
323 vector[1] *= ilength;
324 vector[2] *= ilength;
325 }
326
327 return length;
328
329 }
330
331
332 stock tlx_VectorMA(Float:vecA[3], Float:scale, Float:vecB[3], Float:vecC[3])
333 {
334
335 vecC[0] = vecA[0] + scale * vecB[0];
336
337 vecC[1] = vecA[1] + scale * vecB[1];
338
339 vecC[2] = vecA[2] + scale * vecB[2];
340
341 }
342
343
344
345
346 /*======================================================================
347 HUD_GetHullBounds
348 Engine calls this to enumerate player collision hulls, for prediction.
349 Return 0 if the hullnumber doesn't exist.
350 ==================================================================== */
351 stock tlx_GetHullBounds(hullnumber, Float:mins[3], Float:maxs[3] )
352 {
353 new iret = 0;
354
355 switch ( hullnumber )
356 {
357 case 0:
358 {
359 // normal
360 mins = Float:{-16.0, -16.0, -36.0 }
361 maxs = Float:{ 16.0, 16.0, 36.0 }
362 iret = 1;
363 }
364
365
366 case 1:
367 {
368 // Crouched player
369 mins = Float:{-16.0, -16.0, -18.0 }
370 maxs = Float:{ 16.0, 16.0, 18.0 }
371 iret = 1;
372 }
373
374
375 case 2:
376 {
377 // Point base hull
378 mins = Float:{0.0, 0.0, 0.0 }
379 maxs = Float:{0.0, 0.0, 0.0 }
380 iret = 1;
381 }
382
383
384 }
385
386 return iret;
387 }
388
389
390 stock Float:tlx_fvectorProduct(Float:Vec1[3],Float:Vec2[3])
391 {
392 return Vec1[0]*Vec2[0]+Vec1[1]*Vec2[1]+Vec1[2]*Vec2[2];
393 }
394
395
396
397 stock tlx_vectorProduct(Vec1[3], Vec2[3])
398 {
399 return Vec1[0]*Vec2[0]+Vec1[1]*Vec2[1]+Vec1[2]*Vec2[2];
400 }
401
402
403
404 /*
405 =================
406 tlx_VectorAvg
407 stock by Emp`
408 =================
409 */
410 stock tlx_VectorAvg( a[], num )
411 {
412 new sum = 0;
413 for(new i = 0; i<num; i++)
414 sum += a[i]
415
416 return ( sum / num );
417 }
418
419
420 /*
421 =================
422 EV_IsPlayer
423
424 Is the entity's index in the player range?
425 =================
426 */
427 stock bool:tlx_EV_IsPlayer(index)
428 {
429 if( index >= 1 && index <= get_maxplayers() )
430 return true;
431
432 return false;
433 }
434
435
436
437 /*====================================
438 VectorCompare
439
440 ====================================*/
441 stock tlx_VectorCompare(const Float:v1[3], const Float:v2[3])
442 {
443 new i;
444
445 for (i=0 ; i<3 ; i++)
446 if (v1[i] != v2[i])
447 return 0;
448
449 return 1;
450 }
451
452
453
454 stock Float:tlx_VectorClear(Float:a[3])
455 {
456 a[0] = 0.0;
457 a[1] = 0.0;
458 a[2] = 0.0;
459
460 return a;
461 }
462
463
464
465 /*
466 ==============================
467 CrossProduct
468
469 ==============================
470 */
471 stock tlx_CrossProduct(const Float:v1[3], const Float:v2[3], Float:cross[3])
472 {
473 cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
474
475 cross[1] = v1[2] * v2[0] - v1[0] * v2[2];
476
477 cross[2] = v1[0] * v2[1] - v1[1] * v2[0];
478 }
479
480
481
482
483 /*
484 ==================================
485 ConcatTransforms
486
487 ==================================
488 */
489 stock tlx_ConcatTransforms(Float:in1[3][4], Float:in2[3][4], Float:out[3][4])
490 {
491 out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
492 in1[0][2] * in2[2][0];
493
494 out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
495 in1[0][2] * in2[2][1];
496
497 out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
498 in1[0][2] * in2[2][2];
499
500 out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] +
501 in1[0][2] * in2[2][3] + in1[0][3];
502
503 out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
504 in1[1][2] * in2[2][0];
505
506 out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
507 in1[1][2] * in2[2][1];
508
509 out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
510 in1[1][2] * in2[2][2];
511
512 out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] +
513 in1[1][2] * in2[2][3] + in1[1][3];
514
515 out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
516 in1[2][2] * in2[2][0];
517
518 out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
519 in1[2][2] * in2[2][1];
520
521 out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
522 in1[2][2] * in2[2][2];
523
524 out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] +
525 in1[2][2] * in2[2][3] + in1[2][3];
526 }
527
528
529
530 stock tlx_AddVectors(Float:vec1[3] ,Float:vec2[3], Float:ret[3])
531 {
532 ret = vec1;
533
534 ret[0] += vec2[0];
535
536 ret[1] += vec2[1];
537
538 ret[2] += vec2[2];
539 }
540
541
542 stock tlx_SubtractVectors(Float:vec1[3], Float:vec2[3], Float:ret[3])
543 {
544 ret = vec1;
545
546 ret[0] -= vec2[0];
547
548 ret[1] -= vec2[1];
549
550 ret[2] -= vec2[2];
551 }
552
553
554 stock Float:tlx_AngleDiff(Float:destAngle, Float:srcAngle )
555 {
556 new Float:delta;
557
558 delta = destAngle - srcAngle;
559
560 if ( destAngle > srcAngle )
561 {
562 if ( delta >= 180 )
563 delta -= 360;
564 }
565
566 else
567 {
568 if ( delta <= -180 )
569 delta += 360;
570 }
571
572 return delta;
573 }
574
575
576
577 //=========================================================
578 // StudioFrameAdvance - advance the animation frame up to the current time
579 // if an flInterval is passed in, only advance animation that number of seconds
580 // by Avalanche
581 //=========================================================
582 stock Float:tlx_StudioFrameAdvance(ent,Float:flInterval)
583 {
584 new Float:time = get_gametime(), Float:animtime;
585 pev(ent,pev_animtime,animtime);
586
587 if(flInterval == 0.0)
588 {
589 flInterval = (time - animtime);
590 if(flInterval <= 0.001)
591 {
592 set_pev(ent,pev_animtime,time);
593 return 0.0;
594 }
595 }
596 if(!animtime)
597 flInterval = 0.0;
598
599
600 new Float:framerate, Float:frame;
601 pev(ent,pev_framerate,framerate);
602 pev(ent,pev_frame,frame);
603
604 frame += flInterval * 15.0 * framerate; // *m_flFrameRate = 15.0
605 set_pev(ent,pev_frame,frame);
606 set_pev(ent,pev_animtime,time);
607
608 if(frame < 0.0 || frame >= 256.0)
609 {
610 new m_fSequenceLoops = 1; // HACK
611 if(m_fSequenceLoops)
612 set_pev(ent,pev_frame,frame - (float(floatround(frame / 256.0)) * 256.0));
613 else
614 set_pev(ent,pev_frame,(frame < 0.0) ? 0.0 : 255.0);
615 set_pev(ent,pev_iuser3); // just in case it wasn't caught in GetEvents
616 }
617
618 return flInterval;
619 }
620
621
622
623 // tlx_EntitiesInBox
624 // collect entities in a box
625 // by Avalanche
626 stock tlx_EntitiesInBox(pList[],listMax,Float:mins[3],Float:maxs[3],flagMask)
627 {
628 new count = 0;
629 new maxEntities = global_get(glb_maxEntities);
630
631 static Float:absmax[3], Float:absmin[3];
632
633 new i;
634 for(i=1;i<maxEntities;i++)
635 {
636 if(!pev_valid(i)) // Not in use
637 continue;
638
639 if(flagMask && !(pev(i,pev_flags) & flagMask) ) // Does it meet the criteria?
640 continue;
641
642 pev(i,pev_absmax,absmax);
643 pev(i,pev_absmin,absmin);
644
645 if(mins[0] > absmax[0] ||
646 mins[1] > absmax[1] ||
647 mins[2] > absmax[2] ||
648 maxs[0] < absmin[0] ||
649 maxs[1] < absmin[1] ||
650 maxs[2] < absmin[2] )
651 continue;
652
653 pList[count++] = i;
654
655 if(count >= listMax)
656 return count;
657 }
658
659 return count;
660 }
661
662
663
664 stock tlx_MonstersInSphere(pList[], listMax, Float:center[3], Float:radius)
665 {
666 new maxEntities = global_get(glb_maxEntities);
667
668 new count = 0;
669 new i = 1;
670
671 new Float:radiusSquared = radius * radius;
672 new Float:distance, Float:delta;
673
674 for(i = 1; i < maxEntities; i++)
675 {
676 if ( !pev_valid(i) ) // Not in use
677 continue;
678
679 if ( !(pev(i,pev_flags & (FL_CLIENT|FL_MONSTER)))) // Not a client/monster ?
680 continue;
681
682 // Use origin for X & Y since they are centered for all monsters
683 // Now X
684 new x_origin[3];
685 pev(i,pev_origin,x_origin);
686
687 delta = center[0] - x_origin[0];
688 delta *= delta;
689
690 if ( delta > radiusSquared )
691 continue;
692
693 distance = delta;
694
695 // Now Y
696 delta = center[1] - x_origin[1];
697 delta *= delta;
698
699 distance += delta;
700
701 if ( distance > radiusSquared )
702 continue;
703
704 // Now Z
705 new Float:absmin[3], Float:absmax[3];
706 pev(i,pev_absmin,absmin);
707 pev(i,pev_absmax,absmax);
708
709 delta = center[2] - (absmin[2] + absmax[2]) * 0.5;
710 delta *= delta;
711
712 distance += delta;
713 if ( distance > radiusSquared )
714 continue;
715
716
717 pList[count++] = i;
718
719 if ( count >= listMax )
720 return count;
721 }
722
723
724 return count;
725 }
726
727
728 stock Float:tlx_Approach(Float:target, Float:value, Float:speed)
729 {
730 new Float:delta = target - value;
731
732 if ( delta > speed )
733 value += speed;
734
735 else if ( delta < -speed )
736 value -= speed;
737
738 else
739 value = target;
740
741 return value;
742 }
743
744
745
746 stock Float:tlx_AngleDistance(Float:next, Float:cur)
747 {
748 new Float:delta = next - cur;
749
750 if ( delta < -180 )
751 delta += 360;
752
753 else if ( delta > 180 )
754 delta -= 360;
755
756 return delta;
757 }
758
759
760
761 stock Float:tlx_SplineFraction(Float:value, Float:scale)
762 {
763 value = scale * value;
764
765 new Float:valueSquared = value * value;
766
767 // Nice little ease-in, ease-out spline-like curve
768 return 3 * valueSquared - 2 * valueSquared * value;
769 }
770
771
772 //=========================================================
773 // func_ladder - makes an area vertically negotiable
774 //=========================================================
775 stock tlx_CLadder(ent)
776 {
777 if(!pev_valid(ent))
778 return 0;
779
780 set_pev(ent,pev_solid,SOLID_NOT);
781 set_pev(ent,pev_skin,CONTENTS_LADDER);
782
783 static tlx_pfloat_poin;
784
785 if(!tlx_pfloat_poin)
786 tlx_pfloat_poin = get_cvar_pointer("showtriggers");
787
788 if(get_pcvar_float(tlx_pfloat_poin) == 0)
789 {
790 set_pev(ent,pev_rendermode,kRenderTransTexture);
791 set_pev(ent,pev_renderamt,0);
792 }
793
794
795 // pev->effects &= ~EF_NODRAW;
796 set_pev(ent,pev_effects, ~EF_NODRAW);
797
798 return 1;
799 }
800
801
802
803 // =========================================================
804 // STOCK by Wilson 29 ID / P34nut
805 // returns 1 if the two vectors are equal
806 // it traces a line and returns 1 if it is a clear
807 // returns 0 if there is something in the way
808 // =========================================================
809 stock tlx_clear_path( id, Float:fDist, Float:fZOffset )
810 {
811
812 new Float:fStartOrigin[3], Float:fAngle[3], Float:fSize[3];
813 pev(id, pev_origin, fStartOrigin);
814 pev(id, pev_v_angle, fAngle);
815 pev(id, pev_size, fSize);
816
817 // Adjust for Z Offset
818 fStartOrigin[2] += fZOffset;
819
820 new Float:fEndOrigin[3];
821 fEndOrigin[0] = fStartOrigin[0] + floatcos(fAngle[1], degrees) * (fDist + fSize[0]);
822 fEndOrigin[1] = fStartOrigin[1] + floatsin(fAngle[1], degrees) * (fDist + fSize[1]);
823 fEndOrigin[2] = (fStartOrigin[2] - floatsin(fAngle[0], degrees) * (fDist + fSize[2])) + 5;
824
825 new Float:fStop[3];
826
827 fm_trace_line( id, fStartOrigin, fEndOrigin, fStop );
828
829 return tlx_VectorCompare(fEndOrigin, fStop);
830 }
831
832
833
834 // fm_trace_line from Fakemeta Util by VEN
835 // required for tlx_clear_path
836 stock fm_trace_line(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3])
837 {
838 engfunc(EngFunc_TraceLine, start, end, ignoreent == -1 ? 1 : 0, ignoreent, 0)
839
840 new ent = get_tr2(0, TR_pHit)
841 get_tr2(0, TR_vecEndPos, ret)
842
843 return pev_valid(ent) ? ent : 0
844 }
845
846
847
848
849