[Half-Life AMXX] / grab_plus.sma Repository:
ViewVC logotype

Annotation of /grab_plus.sma

Parent Directory Parent Directory | Revision Log Revision Log


Revision 46 - (view) (download)

1 : ian 1 /*
2 : ian 46 Grab+ v1.2.5
3 :     Copyright (C) 2011 Ian (Juan) Cammarata
4 : ian 1
5 : ian 25 This program is free software: you can redistribute it and/or modify
6 :     it under the terms of the GNU Affero General Public License as
7 :     published by the Free Software Foundation, either version 3 of the
8 :     License, or (at your option) any later version.
9 : ian 1
10 : ian 25 This program is distributed in the hope that it will be useful,
11 :     but WITHOUT ANY WARRANTY; without even the implied warranty of
12 :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 :     GNU Affero General Public License for more details.
14 : ian 1
15 : ian 25 You should have received a copy of the GNU Affero General Public License
16 :     along with this program. If not, see <http://www.gnu.org/licenses/>.
17 : ian 1 --------------------------------------------------------------------------------
18 :    
19 :     http://ian.cammarata.us/projects/grab_plus
20 : ian 46 ?19 ?February, ?2011
21 : ian 1
22 :    
23 :     Description:
24 :     This is a remake from scratch of SpaceDude's Jedi Force Grab plugin. It has many additional features and optimizations, is less spammy, multilingual and requires fewer binds.
25 :    
26 :    
27 :     Features:
28 :     Multilingual
29 :     Screenfade to indicate grab activity instead of chat spam.
30 :     Can grab players off a ladder.
31 :     Automatically choke by holding down +pull while at min distance.
32 :     Choke with use key.
33 :     Throw with drop.
34 :     Can't have mutliple admins grabbing the same player.
35 :     Auto drop on death.
36 :     Grab entities other than players, such as bombs, weapons, and hostages.
37 :    
38 :    
39 :     Commands:
40 :    
41 :     +grab : Grab something for as long as you hold down the key.
42 :     grab_toggle : Same as +grab but toggles.
43 :     amx_grab <name> : Grab client by name or id and teleport them to you. Use +grab or grab_toggle key to release.
44 :    
45 :     +pull/+push (or invnext/invprev): Pulls/pushes the grabbed towards/away from you as you hold the button.
46 :    
47 : ian 10 +use : Chokes the grabbed (it damages the grabbed with 5 (cvar: gp_choke_dmg) hp per 1.5 (cvar: gp_choke_time) seconds)
48 :     drop - Throws the grabbed with 1500 velocity. (cvar: gp_throw_force)
49 : ian 1
50 :    
51 :     Cvars (First value is default):
52 :     gp_enabled <1|0> Enables all plugin functionality.
53 : ian 10 gp_players_only <0|1> Disables admins grabbing entities other than players.
54 : ian 1
55 :     gp_min_dist <90|...> Min distance between the grabber and grabbed.
56 : ian 10 gp_grab_force <8|...> Sets the amount of force used when grabbing players.
57 :     gp_throw_force <1500|...> Sets the power used when throwing players.
58 : ian 1 gp_speed <5|...> How fast the grabbed moves when using push and pull.
59 :    
60 : ian 10 gp_choke_time <1.5|...> Time frequency for choking.
61 :     gp_choke_dmg <5|...> Amount of damage done with each choke.
62 :     gp_auto_choke <1|0> Enable/disable choking automatically with +pull command.
63 : ian 1
64 : ian 10 gp_screen_fade <1|0> Enables/disables screenfade when grabbing.
65 : ian 9 gp_glow <1|0> Enables/disables glowing for grabbed objects.
66 : ian 1
67 : ian 9 gp_glow_r <50|0-255> Sets red amount for glow and screenfade.
68 :     gp_glow_g <0|0-255> Sets green amount for glow and screenfade.
69 :     gp_glow_b <0|0-255> Sets blue amount for glow and screenfade.
70 :     gp_glow_a <0|0-255> Sets alpha for glow and screenfade.
71 : ian 1
72 : ian 9
73 : ian 1 Notes:
74 :     Make sure you place the grab_plus.txt file in addons\amxmodx\data\lang
75 :    
76 :    
77 :     Credits:
78 : ian 5 Thanks to vittu for contributing code (changed all engine/fun module stuff to fakemeta).
79 :    
80 : ian 1 Thanks to all the coders who worked on the original Jedi Force Grab plugin for all their ideas:
81 :     SpaceDude
82 :     KCE
83 :     KRoTaL
84 :     BOB_SLAYER
85 :     kosmo111
86 :    
87 :    
88 :     Supported Languages:
89 :     1337 (100%) - Thanks to l337newb
90 :     Brazilian Portuguese (100%) - Thanks to Arion
91 :     Danish (100%) - Thanks to nellerbabz
92 :     Dutch (100%) - Thanks to BlackMilk
93 :     English (100%)
94 :     Finnish (100%) - Thanks to Pro Patria Finland
95 :     French (100%) - Thanks to connorr
96 :     German (100%) - Thanks to SchlumPF*
97 :     Russian (100%) - Thanks to `666
98 : ian 31 Spanish (100%) - Thanks to RenXO
99 : ian 1 Swedish (100%) - Thanks to Bend3r
100 :    
101 :    
102 :     Change Log:
103 :     Key (+ added | - removed | c changed | f fixed)
104 :    
105 : ian 46 v1.2.5 (Feb 19, 2011)
106 :     f: Applied fix mailed to me on Allied Modders site several years ago. (Maybe I should sign up for new mail notifications.)
107 :     Thanks to ConnorMcLeod
108 :    
109 : ian 39 v1.2.4 (Feb 18, 2007)
110 :     f: Killing player with choke in some mods bugged out really bad.
111 :    
112 : ian 28 v1.2.3 (Nov 21, 2007)
113 : ian 27 c: A few more small optimizations.
114 : ian 28 f: Bloodstream for choke wasn't aligned with player.
115 :     f: Bad message disconnect error when players were choked. ( stupid SVC_DAMAGE define )
116 : ian 27
117 : ian 20 v1.2.2 (Nov 16, 2007)
118 : ian 16 c: A few small code optimizations.
119 :    
120 : ian 15 v1.2.1 (Nov 12, 2007)
121 : ian 16 f: Eliminated two run time warnings in the player prethink function.
122 : ian 15
123 : ian 11 v1.2 (Nov 06, 2007)
124 : ian 10 +: Cvars gp_screen_fade and gp_glow to enable/disable these features.
125 : ian 5 +: Cvar gp_glow_a controls to control alpha of screenfade and glow.
126 : ian 10 +: Cvar gp_auto_choke to enable/disable choking automatically with +pull command.
127 : ian 11 c: Removed dependency of engine and fun modules. Thanks to vittu for doing most of the work.
128 : ian 10 c: Made cvar names more consistent by adding more underscores.
129 : ian 11 f: Fixed compile bug with amxx 1.8.0 (Compiles with 1.7.x as well).
130 : ian 5
131 : ian 1 v1.1 (Oct 16, 2007)
132 :     +: Grab a few types of entities other than players.
133 : ian 10 +: Cvar gp_players_only.
134 : ian 1
135 :     v1.0 (Oct 13, 2007)
136 :     !: Initial release
137 :    
138 :     */
139 :    
140 :     #include <amxmodx>
141 :     #include <amxmisc>
142 :     #include <fakemeta>
143 :    
144 : ian 39 new const VERSION[ ] = "1.2.4b1"
145 : ian 27 new const TRKCVAR[ ] = "grab_plus_version"
146 : ian 1 #define ADMIN ADMIN_LEVEL_A
147 :    
148 :     #define TSK_CHKE 50
149 :    
150 :     #define SF_FADEOUT 0
151 :    
152 :     new client_data[33][4]
153 :     #define GRABBED 0
154 :     #define GRABBER 1
155 :     #define GRAB_LEN 2
156 :     #define FLAGS 3
157 :    
158 : ian 46 #define m_bitsDamageType 76
159 :    
160 : ian 1 #define CDF_IN_PUSH (1<<0)
161 :     #define CDF_IN_PULL (1<<1)
162 :     #define CDF_NO_CHOKE (1<<2)
163 :    
164 :     //Cvar Pointers
165 : ian 10 new p_enabled, p_players_only
166 :     new p_throw_force, p_min_dist, p_speed, p_grab_force
167 :     new p_choke_time, p_choke_dmg, p_auto_choke
168 : ian 5 new p_glow_r, p_glow_b, p_glow_g, p_glow_a
169 :     new p_fade, p_glow
170 : ian 1
171 :     //Pseudo Constants
172 :     new MAXPLAYERS
173 : ian 27 new SVC_SCREENFADE, SVC_SCREENSHAKE, WTF_DAMAGE
174 : ian 1
175 :     public plugin_init( )
176 :     {
177 :     register_plugin( "Grab+", VERSION, "Ian Cammarata" )
178 : ian 27 register_cvar( TRKCVAR, VERSION, FCVAR_SERVER )
179 :     set_cvar_string( TRKCVAR, VERSION )
180 : ian 1
181 :     p_enabled = register_cvar( "gp_enabled", "1" )
182 : ian 10 p_players_only = register_cvar( "gp_players_only", "0" )
183 : ian 1
184 : ian 10 p_min_dist = register_cvar ( "gp_min_dist", "90" )
185 :     p_throw_force = register_cvar( "gp_throw_force", "1500" )
186 :     p_grab_force = register_cvar( "gp_grab_force", "8" )
187 : ian 1 p_speed = register_cvar( "gp_speed", "5" )
188 :    
189 : ian 10 p_choke_time = register_cvar( "gp_choke_time", "1.5" )
190 :     p_choke_dmg = register_cvar( "gp_choke_dmg", "5" )
191 :     p_auto_choke = register_cvar( "gp_auto_choke", "1" )
192 : ian 1
193 :     p_glow_r = register_cvar( "gp_glow_r", "50" )
194 :     p_glow_g = register_cvar( "gp_glow_g", "0" )
195 :     p_glow_b = register_cvar( "gp_glow_b", "0" )
196 : ian 5 p_glow_a = register_cvar( "gp_glow_a", "200" )
197 : ian 1
198 : ian 10 p_fade = register_cvar( "gp_screen_fade", "1" )
199 : ian 5 p_glow = register_cvar( "gp_glow", "1" )
200 :    
201 : ian 1 register_clcmd( "amx_grab", "force_grab", ADMIN, "Grab client & teleport to you." )
202 :     register_clcmd( "grab_toggle", "grab_toggle", ADMIN, "press once to grab and again to release" )
203 :     register_clcmd( "+grab", "grab", ADMIN, "bind a key to +grab" )
204 :     register_clcmd( "-grab", "unset_grabbed" )
205 :    
206 :     register_clcmd( "+push", "push", ADMIN, "bind a key to +push" )
207 :     register_clcmd( "-push", "push" )
208 :     register_clcmd( "+pull", "pull", ADMIN, "bind a key to +pull" )
209 :     register_clcmd( "-pull", "pull" )
210 :     register_clcmd( "push", "push2" )
211 :     register_clcmd( "pull", "pull2" )
212 :    
213 :     register_clcmd( "drop" ,"throw" )
214 :    
215 :     register_event( "DeathMsg", "DeathMsg", "a" )
216 :    
217 : ian 8 register_forward( FM_PlayerPreThink, "fm_player_prethink" )
218 :    
219 : ian 1 register_dictionary( "grab_plus.txt" )
220 :    
221 :     MAXPLAYERS = get_maxplayers()
222 :    
223 :     SVC_SCREENFADE = get_user_msgid( "ScreenFade" )
224 :     SVC_SCREENSHAKE = get_user_msgid( "ScreenShake" )
225 : ian 27 WTF_DAMAGE = get_user_msgid( "Damage" )
226 : ian 1 }
227 :    
228 :     public plugin_precache( )
229 :     {
230 :     precache_sound( "player/PL_PAIN2.WAV" )
231 :     }
232 :    
233 : ian 8 public fm_player_prethink( id )
234 : ian 1 {
235 : ian 27 new target
236 : ian 1 //Search for a target
237 :     if ( client_data[id][GRABBED] == -1 )
238 :     {
239 :     new Float:orig[3], Float:ret[3]
240 : ian 11 get_view_pos( id, orig )
241 :     ret = vel_by_aim( id, 9999 )
242 : ian 1
243 : ian 16 ret[0] += orig[0]
244 :     ret[1] += orig[1]
245 :     ret[2] += orig[2]
246 :    
247 : ian 27 target = traceline( orig, ret, id, ret )
248 : ian 1
249 :     if( 0 < target <= MAXPLAYERS )
250 :     {
251 : ian 15 if( is_grabbed( target, id ) ) return FMRES_IGNORED
252 : ian 1 set_grabbed( id, target )
253 :     }
254 : ian 10 else if( !get_pcvar_num( p_players_only ) )
255 : ian 1 {
256 :     new movetype
257 : ian 15 if( target && pev_valid( target ) )
258 : ian 1 {
259 :     movetype = pev( target, pev_movetype )
260 :     if( !( movetype == MOVETYPE_WALK || movetype == MOVETYPE_STEP || movetype == MOVETYPE_TOSS ) )
261 : ian 15 return FMRES_IGNORED
262 : ian 1 }
263 :     else
264 :     {
265 : ian 15 target = 0
266 : ian 5 new ent = engfunc( EngFunc_FindEntityInSphere, -1, ret, 12.0 )
267 : ian 1 while( !target && ent > 0 )
268 :     {
269 :     movetype = pev( ent, pev_movetype )
270 :     if( ( movetype == MOVETYPE_WALK || movetype == MOVETYPE_STEP || movetype == MOVETYPE_TOSS )
271 :     && ent != id )
272 :     target = ent
273 : ian 5 ent = engfunc( EngFunc_FindEntityInSphere, ent, ret, 12.0 )
274 : ian 1 }
275 :     }
276 :     if( target )
277 :     {
278 : ian 15 if( is_grabbed( target, id ) ) return FMRES_IGNORED
279 : ian 1 set_grabbed( id, target )
280 :     }
281 :     }
282 :     }
283 : ian 27
284 :     target = client_data[id][GRABBED]
285 : ian 1 //If they've grabbed something
286 : ian 27 if( target > 0 )
287 : ian 1 {
288 :     if( !pev_valid( target ) || ( pev( target, pev_health ) < 1 && pev( target, pev_max_health ) ) )
289 :     {
290 :     unset_grabbed( id )
291 : ian 15 return FMRES_IGNORED
292 : ian 1 }
293 :    
294 :     //Use key choke
295 :     if( pev( id, pev_button ) & IN_USE )
296 :     do_choke( id )
297 :    
298 :     //Push and pull
299 : ian 27 new cdf = client_data[id][FLAGS]
300 :     if ( cdf & CDF_IN_PULL )
301 : ian 1 do_pull( id )
302 : ian 27 else if ( cdf & CDF_IN_PUSH )
303 : ian 1 do_push( id )
304 :    
305 : ian 27 if( target > MAXPLAYERS ) grab_think( id )
306 : ian 1 }
307 :    
308 : ian 27 //If they're grabbed
309 :     target = client_data[id][GRABBER]
310 :     if( target > 0 ) grab_think( target )
311 :    
312 : ian 15 return FMRES_IGNORED
313 : ian 1 }
314 :    
315 : ian 27 public grab_think( id ) //id of the grabber
316 : ian 1 {
317 :     new target = client_data[id][GRABBED]
318 :    
319 :     //Keep grabbed clients from sticking to ladders
320 :     if( pev( target, pev_movetype ) == MOVETYPE_FLY && !(pev( target, pev_button ) & IN_JUMP ) ) client_cmd( target, "+jump;wait;-jump" )
321 :    
322 :     //Move targeted client
323 : ian 12 new Float:tmpvec[3], Float:tmpvec2[3], Float:torig[3], Float:tvel[3]
324 : ian 1
325 : ian 11 get_view_pos( id, tmpvec )
326 : ian 10
327 : ian 11 tmpvec2 = vel_by_aim( id, client_data[id][GRAB_LEN] )
328 : ian 10
329 : ian 1 torig = get_target_origin_f( target )
330 :    
331 : ian 10 new force = get_pcvar_num( p_grab_force )
332 : ian 1
333 : ian 16 tvel[0] = ( ( tmpvec[0] + tmpvec2[0] ) - torig[0] ) * force
334 :     tvel[1] = ( ( tmpvec[1] + tmpvec2[1] ) - torig[1] ) * force
335 :     tvel[2] = ( ( tmpvec[2] + tmpvec2[2] ) - torig[2] ) * force
336 : ian 1
337 : ian 5 set_pev( target, pev_velocity, tvel )
338 : ian 1 }
339 :    
340 :     stock Float:get_target_origin_f( id )
341 :     {
342 :     new Float:orig[3]
343 : ian 5 pev( id, pev_origin, orig )
344 : ian 1
345 :     //If grabbed is not a player, move origin to center
346 :     if( id > MAXPLAYERS )
347 :     {
348 :     new Float:mins[3], Float:maxs[3]
349 : ian 5 pev( id, pev_mins, mins )
350 :     pev( id, pev_maxs, maxs )
351 : ian 1
352 :     if( !mins[2] ) orig[2] += maxs[2] / 2
353 :     }
354 :    
355 :     return orig
356 :     }
357 :    
358 :     public grab_toggle( id, level, cid )
359 :     {
360 :     if( !client_data[id][GRABBED] ) grab( id, level, cid )
361 :     else unset_grabbed( id )
362 :    
363 :     return PLUGIN_HANDLED
364 :     }
365 :    
366 :     public grab( id, level, cid )
367 :     {
368 :     if( !cmd_access( id, level, cid, 1 ) || !get_pcvar_num( p_enabled ) ) return PLUGIN_HANDLED
369 :    
370 :     if ( !client_data[id][GRABBED] ) client_data[id][GRABBED] = -1
371 :     screenfade_in( id )
372 :    
373 :     return PLUGIN_HANDLED
374 :     }
375 :    
376 :     public screenfade_in( id )
377 :     {
378 : ian 5 if( get_pcvar_num( p_fade ) )
379 :     {
380 :     message_begin( MSG_ONE, SVC_SCREENFADE, _, id )
381 :     write_short( 10000 ) //duration
382 :     write_short( 0 ) //hold
383 :     write_short( SF_FADE_IN + SF_FADE_ONLYONE ) //flags
384 :     write_byte( get_pcvar_num( p_glow_r ) ) //r
385 :     write_byte( get_pcvar_num( p_glow_g ) ) //g
386 :     write_byte( get_pcvar_num( p_glow_b ) ) //b
387 :     write_byte( get_pcvar_num( p_glow_a ) / 2 ) //a
388 :     message_end( )
389 :     }
390 : ian 1 }
391 :    
392 :     public throw( id )
393 :     {
394 :     new target = client_data[id][GRABBED]
395 :     if( target > 0 )
396 :     {
397 : ian 11 set_pev( target, pev_velocity, vel_by_aim( id, get_pcvar_num(p_throw_force) ) )
398 : ian 1 unset_grabbed( id )
399 :     return PLUGIN_HANDLED
400 :     }
401 : ian 11
402 : ian 1 return PLUGIN_CONTINUE
403 :     }
404 :    
405 :     public unset_grabbed( id )
406 :     {
407 :     new target = client_data[id][GRABBED]
408 :     if( target > 0 && pev_valid( target ) )
409 :     {
410 : ian 5 set_pev( target, pev_renderfx, kRenderFxNone )
411 :     set_pev( target, pev_rendercolor, {255.0, 255.0, 255.0} )
412 :     set_pev( target, pev_rendermode, kRenderNormal )
413 :     set_pev( target, pev_renderamt, 16.0 )
414 :    
415 : ian 1 if( 0 < target <= MAXPLAYERS )
416 :     client_data[target][GRABBER] = 0
417 :     }
418 :     client_data[id][GRABBED] = 0
419 :    
420 : ian 5 if( get_pcvar_num( p_fade ) )
421 :     {
422 :     message_begin( MSG_ONE, SVC_SCREENFADE, _, id )
423 :     write_short( 10000 ) //duration
424 :     write_short( 0 ) //hold
425 :     write_short( SF_FADEOUT ) //flags
426 :     write_byte( get_pcvar_num( p_glow_r ) ) //r
427 :     write_byte( get_pcvar_num( p_glow_g ) ) //g
428 :     write_byte( get_pcvar_num( p_glow_b ) ) //b
429 :     write_byte( get_pcvar_num( p_glow_a ) / 2 ) //a
430 :     message_end( )
431 :     }
432 : ian 1 }
433 :    
434 :     //Grabs onto someone
435 :     public set_grabbed( id, target )
436 :     {
437 : ian 5 if( get_pcvar_num( p_glow ) )
438 :     {
439 :     new Float:color[3]
440 :     color[0] = get_pcvar_float( p_glow_r )
441 :     color[1] = get_pcvar_float( p_glow_g )
442 :     color[2] = get_pcvar_float( p_glow_b )
443 : ian 6 set_pev( target, pev_renderfx, kRenderFxGlowShell )
444 :     set_pev( target, pev_rendercolor, color )
445 :     set_pev( target, pev_rendermode, kRenderTransColor )
446 :     set_pev( target, pev_renderamt, get_pcvar_float( p_glow_a ) )
447 : ian 5 }
448 : ian 1
449 :     if( 0 < target <= MAXPLAYERS )
450 :     client_data[target][GRABBER] = id
451 :     client_data[id][FLAGS] = 0
452 :     client_data[id][GRABBED] = target
453 : ian 5 new Float:torig[3], Float:orig[3]
454 :     pev( target, pev_origin, torig )
455 :     pev( id, pev_origin, orig )
456 :     client_data[id][GRAB_LEN] = floatround( get_distance_f( torig, orig ) )
457 : ian 10 if( client_data[id][GRAB_LEN] < get_pcvar_num( p_min_dist ) ) client_data[id][GRAB_LEN] = get_pcvar_num( p_min_dist )
458 : ian 1 }
459 :    
460 :     public push( id )
461 :     {
462 :     client_data[id][FLAGS] ^= CDF_IN_PUSH
463 :     return PLUGIN_HANDLED
464 :     }
465 :    
466 :     public pull( id )
467 :     {
468 :     client_data[id][FLAGS] ^= CDF_IN_PULL
469 :     return PLUGIN_HANDLED
470 :     }
471 :    
472 :     public push2( id )
473 :     {
474 :     if( client_data[id][GRABBED] > 0 )
475 :     {
476 :     do_push( id )
477 :     return PLUGIN_HANDLED
478 :     }
479 :     return PLUGIN_CONTINUE
480 :     }
481 :    
482 :     public pull2( id )
483 :     {
484 :     if( client_data[id][GRABBED] > 0 )
485 :     {
486 :     do_pull( id )
487 :     return PLUGIN_HANDLED
488 :     }
489 :     return PLUGIN_CONTINUE
490 :     }
491 :    
492 :     public do_push( id )
493 :     if( client_data[id][GRAB_LEN] < 9999 )
494 :     client_data[id][GRAB_LEN] += get_pcvar_num( p_speed )
495 :    
496 :     public do_pull( id )
497 :     {
498 : ian 10 new mindist = get_pcvar_num( p_min_dist )
499 : ian 1 new len = client_data[id][GRAB_LEN]
500 :    
501 :     if( len > mindist )
502 :     {
503 :     len -= get_pcvar_num( p_speed )
504 :     if( len < mindist ) len = mindist
505 :     client_data[id][GRAB_LEN] = len
506 :     }
507 : ian 10 else if( get_pcvar_num( p_auto_choke ) )
508 :     do_choke( id )
509 : ian 1 }
510 :    
511 :     public do_choke( id )
512 :     {
513 :     new target = client_data[id][GRABBED]
514 : ian 28 if( client_data[id][FLAGS] & CDF_NO_CHOKE || id == target || target > MAXPLAYERS) return
515 : ian 1
516 : ian 10 new dmg = get_pcvar_num( p_choke_dmg )
517 : ian 28 new vec[3]
518 :     FVecIVec( get_target_origin_f( target ), vec )
519 : ian 1
520 :     message_begin( MSG_ONE, SVC_SCREENSHAKE, _, target )
521 :     write_short( 999999 ) //amount
522 :     write_short( 9999 ) //duration
523 :     write_short( 999 ) //frequency
524 :     message_end( )
525 :    
526 :     message_begin( MSG_ONE, SVC_SCREENFADE, _, target )
527 :     write_short( 9999 ) //duration
528 :     write_short( 100 ) //hold
529 :     write_short( SF_FADE_MODULATE ) //flags
530 :     write_byte( get_pcvar_num( p_glow_r ) ) //r
531 :     write_byte( get_pcvar_num( p_glow_g ) ) //g
532 :     write_byte( get_pcvar_num( p_glow_b ) ) //b
533 :     write_byte( 200 ) //a
534 :     message_end( )
535 :    
536 : ian 27 message_begin( MSG_ONE, WTF_DAMAGE, _, target )
537 : ian 1 write_byte( 0 ) //damage armor
538 :     write_byte( dmg ) //damage health
539 :     write_long( DMG_CRUSH ) //damage type
540 : ian 28 write_coord( vec[0] ) //origin[x]
541 :     write_coord( vec[1] ) //origin[y]
542 :     write_coord( vec[2] ) //origin[z]
543 : ian 1 message_end( )
544 :    
545 :     message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
546 :     write_byte( TE_BLOODSTREAM )
547 : ian 28 write_coord( vec[0] ) //pos.x
548 :     write_coord( vec[1] ) //pos.y
549 :     write_coord( vec[2] + 15 ) //pos.z
550 : ian 1 write_coord( random_num( 0, 255 ) ) //vec.x
551 :     write_coord( random_num( 0, 255 ) ) //vec.y
552 :     write_coord( random_num( 0, 255 ) ) //vec.z
553 :     write_byte( 70 ) //col index
554 :     write_byte( random_num( 50, 250 ) ) //speed
555 :     message_end( )
556 :    
557 : ian 46 //Thanks to ConnorMcLeod for making this block of code more proper
558 :     new Float:health
559 :     pev( target, pev_health , health)
560 :     health -= dmg
561 : ian 1 if( health < 1 ) dllfunc( DLLFunc_ClientKill, target )
562 : ian 39 else {
563 : ian 46 set_pev( target, pev_health, health )
564 :     set_pdata_int(target, m_bitsDamageType, DMG_CRUSH) // m_bitsDamageType = 76 // found by VEN
565 :     set_pev(target, pev_dmg_take, dmg)
566 :     set_pev(target, pev_dmg_inflictor, id)
567 : ian 39 }
568 : ian 1
569 :     client_data[id][FLAGS] ^= CDF_NO_CHOKE
570 : ian 10 set_task( get_pcvar_float( p_choke_time ), "clear_no_choke", TSK_CHKE + id )
571 : ian 1 }
572 :    
573 :     public clear_no_choke( tskid )
574 :     {
575 :     new id = tskid - TSK_CHKE
576 :     client_data[id][FLAGS] ^= CDF_NO_CHOKE
577 :     }
578 :    
579 :     //Grabs the client and teleports them to the admin
580 :     public force_grab(id, level, cid)
581 :     {
582 :     if( !cmd_access( id, level, cid, 1 ) || !get_pcvar_num( p_enabled ) ) return PLUGIN_HANDLED
583 :    
584 :     new arg[33]
585 :     read_argv( 1, arg, 32 )
586 :    
587 :     new targetid = cmd_target( id, arg, 1 )
588 :    
589 :     if( is_grabbed( targetid, id ) ) return PLUGIN_HANDLED
590 :     if( !is_user_alive( targetid ) )
591 :     {
592 :     client_print( id, print_console, "[AMXX] %L", id, "COULDNT" )
593 :     return PLUGIN_HANDLED
594 :     }
595 :    
596 :     //Safe to tp target to aim spot?
597 : ian 11 new Float:tmpvec[3], Float:orig[3], Float:torig[3], Float:trace_ret[3]
598 : ian 1 new bool:safe = false, i
599 :    
600 : ian 11 get_view_pos( id, orig )
601 :     tmpvec = vel_by_aim( id, get_pcvar_num( p_min_dist ) )
602 : ian 1
603 :     for( new j = 1; j < 11 && !safe; j++ )
604 :     {
605 : ian 16 torig[0] = orig[0] + tmpvec[i] * j
606 :     torig[1] = orig[1] + tmpvec[i] * j
607 :     torig[2] = orig[2] + tmpvec[i] * j
608 :    
609 : ian 11 traceline( tmpvec, torig, id, trace_ret )
610 : ian 5
611 : ian 1 if( get_distance_f( trace_ret, torig ) ) break
612 : ian 8
613 :     engfunc( EngFunc_TraceHull, torig, torig, 0, HULL_HUMAN, 0, 0 )
614 :     if ( !get_tr2( 0, TR_StartSolid ) && !get_tr2( 0, TR_AllSolid ) && get_tr2( 0, TR_InOpen ) )
615 :     safe = true
616 : ian 1 }
617 :    
618 :     //Still not safe? Then find another safe spot somewhere around the grabber
619 : ian 11 pev( id, pev_origin, orig )
620 : ian 1 new try[3]
621 :     orig[2] += 2
622 :     while( try[2] < 3 && !safe )
623 :     {
624 :     for( i = 0; i < 3; i++ )
625 :     switch( try[i] )
626 :     {
627 :     case 0 : torig[i] = orig[i] + ( i == 2 ? 80 : 40 )
628 :     case 1 : torig[i] = orig[i]
629 :     case 2 : torig[i] = orig[i] - ( i == 2 ? 80 : 40 )
630 :     }
631 :    
632 : ian 11 traceline( tmpvec, torig, id, trace_ret )
633 : ian 1
634 : ian 8 engfunc( EngFunc_TraceHull, torig, torig, 0, HULL_HUMAN, 0, 0 )
635 :     if ( !get_tr2( 0, TR_StartSolid ) && !get_tr2( 0, TR_AllSolid ) && get_tr2( 0, TR_InOpen )
636 :     && !get_distance_f( trace_ret, torig ) ) safe = true
637 : ian 5
638 : ian 1 try[0]++
639 :     if( try[0] == 3 )
640 :     {
641 :     try[0] = 0
642 :     try[1]++
643 :     if( try[1] == 3 )
644 :     {
645 :     try[1] = 0
646 :     try[2]++
647 :     }
648 :     }
649 :     }
650 :    
651 :     if( safe )
652 :     {
653 : ian 5 set_pev( targetid, pev_origin, torig )
654 : ian 1 set_grabbed( id, targetid )
655 :     screenfade_in( id )
656 :     }
657 :     else client_print( id, print_chat, "[AMXX] %L", id, "COULDNT" )
658 :    
659 :     return PLUGIN_HANDLED
660 :     }
661 :    
662 :     public is_grabbed( target, grabber )
663 :     {
664 :     for( new i = 1; i <= MAXPLAYERS; i++ )
665 :     if( client_data[i][GRABBED] == target )
666 :     {
667 :     client_print( grabber, print_chat, "[AMXX] %L", grabber, "ALREADY" )
668 :     unset_grabbed( grabber )
669 :     return true
670 :     }
671 :     return false
672 :     }
673 :    
674 :     public DeathMsg( )
675 :     kill_grab( read_data( 2 ) )
676 :    
677 :     public client_disconnect( id )
678 :     {
679 :     kill_grab( id )
680 :     return PLUGIN_CONTINUE
681 :     }
682 :    
683 :     public kill_grab( id )
684 :     {
685 :     //If given client has grabbed, or has a grabber, unset it
686 :     if( client_data[id][GRABBED] )
687 :     unset_grabbed( id )
688 :     else if( client_data[id][GRABBER] )
689 :     unset_grabbed( client_data[id][GRABBER] )
690 :     }
691 : ian 11
692 :     stock traceline( const Float:vStart[3], const Float:vEnd[3], const pIgnore, Float:vHitPos[3] )
693 :     {
694 :     engfunc( EngFunc_TraceLine, vStart, vEnd, 0, pIgnore, 0 )
695 :     get_tr2( 0, TR_vecEndPos, vHitPos )
696 :     return get_tr2( 0, TR_pHit )
697 :     }
698 :    
699 :     stock get_view_pos( const id, Float:vViewPos[3] )
700 :     {
701 : ian 27 new Float:vOfs[3]
702 : ian 11 pev( id, pev_origin, vViewPos )
703 : ian 27 pev( id, pev_view_ofs, vOfs )
704 : ian 16
705 : ian 27 vViewPos[0] += vOfs[0]
706 :     vViewPos[1] += vOfs[1]
707 :     vViewPos[2] += vOfs[2]
708 : ian 11 }
709 :    
710 :     stock Float:vel_by_aim( id, speed = 1 )
711 :     {
712 :     new Float:v1[3], Float:vBlah[3]
713 :     pev( id, pev_v_angle, v1 )
714 :     engfunc( EngFunc_AngleVectors, v1, v1, vBlah, vBlah )
715 : ian 16
716 :     v1[0] *= speed
717 :     v1[1] *= speed
718 :     v1[2] *= speed
719 :    
720 : ian 11 return v1
721 :     }

Contact
ViewVC Help
Powered by ViewVC 1.0.4