Parent Directory | Revision Log
Revision 1 - (view) (download)
1 : | ian | 1 | /* |
2 : | Grab+ v1.1 | ||
3 : | Copyright (C) 2007 Ian (Juan) Cammarata | ||
4 : | |||
5 : | This program is free software; you can redistribute it and/or modify it under | ||
6 : | the terms of the GNU General Public License as published by the Free Software | ||
7 : | Foundation; either version 2 of the License, or (at your option) any later | ||
8 : | version. | ||
9 : | |||
10 : | This program is distributed in the hope that it will be useful, but WITHOUT ANY | ||
11 : | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
12 : | PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
13 : | |||
14 : | You should have received a copy of the GNU General Public License along with | ||
15 : | this program; go to http://www.opensource.org/licenses/gpl-license.php | ||
16 : | -------------------------------------------------------------------------------- | ||
17 : | |||
18 : | http://ian.cammarata.us/projects/grab_plus | ||
19 : | Oct 16 21:03 | ||
20 : | |||
21 : | |||
22 : | Description: | ||
23 : | 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. | ||
24 : | |||
25 : | |||
26 : | See it in Action: | ||
27 : | http://www.game-monitor.com/search.php?search=grab_plus_version&type=variable&game=all&location=all | ||
28 : | |||
29 : | |||
30 : | Features: | ||
31 : | Multilingual | ||
32 : | Screenfade to indicate grab activity instead of chat spam. | ||
33 : | Can grab players off a ladder. | ||
34 : | Automatically choke by holding down +pull while at min distance. | ||
35 : | Choke with use key. | ||
36 : | Throw with drop. | ||
37 : | Can't have mutliple admins grabbing the same player. | ||
38 : | Auto drop on death. | ||
39 : | Grab entities other than players, such as bombs, weapons, and hostages. | ||
40 : | |||
41 : | |||
42 : | Commands: | ||
43 : | |||
44 : | +grab : Grab something for as long as you hold down the key. | ||
45 : | grab_toggle : Same as +grab but toggles. | ||
46 : | amx_grab <name> : Grab client by name or id and teleport them to you. Use +grab or grab_toggle key to release. | ||
47 : | |||
48 : | +pull/+push (or invnext/invprev): Pulls/pushes the grabbed towards/away from you as you hold the button. | ||
49 : | |||
50 : | +use : Chokes the grabbed (it damages the grabbed with 5 (cvar: gp_chokedmg) hp per 1.5 (cvar: gp_choketime) seconds) | ||
51 : | drop - Throws the grabbed with 1500 velocity. (cvar: gp_throwforce) | ||
52 : | |||
53 : | |||
54 : | Cvars (First value is default): | ||
55 : | gp_enabled <1|0> Enables all plugin functionality. | ||
56 : | gp_playersonly <0|1> Disables admins grabbing entities other than players. | ||
57 : | |||
58 : | gp_min_dist <90|...> Min distance between the grabber and grabbed. | ||
59 : | gp_grabforce <8|...> Sets the amount of force used when grabbing players. | ||
60 : | gp_throwforce <1500|...> Sets the power used when throwing players. | ||
61 : | gp_speed <5|...> How fast the grabbed moves when using push and pull. | ||
62 : | |||
63 : | gp_choketime <1.5|...> Time frequency for choking. | ||
64 : | gp_chokedmg <5|...> Amount of damage done with each choke. | ||
65 : | |||
66 : | gp_glow_r <50|0-255> Sets red amount for glow. | ||
67 : | gp_glow_g <0|0-255> Sets green amount for glow. | ||
68 : | gp_glow_b <0|0-255> Sets blue amount for glow. | ||
69 : | |||
70 : | |||
71 : | Notes: | ||
72 : | Make sure you place the grab_plus.txt file in addons\amxmodx\data\lang | ||
73 : | |||
74 : | |||
75 : | Credits: | ||
76 : | Thanks to all the coders who worked on the original Jedi Force Grab plugin for all their ideas: | ||
77 : | SpaceDude | ||
78 : | KCE | ||
79 : | KRoTaL | ||
80 : | BOB_SLAYER | ||
81 : | kosmo111 | ||
82 : | |||
83 : | |||
84 : | Supported Languages: | ||
85 : | 1337 (100%) - Thanks to l337newb | ||
86 : | Brazilian Portuguese (100%) - Thanks to Arion | ||
87 : | Danish (100%) - Thanks to nellerbabz | ||
88 : | Dutch (100%) - Thanks to BlackMilk | ||
89 : | English (100%) | ||
90 : | Finnish (100%) - Thanks to Pro Patria Finland | ||
91 : | French (100%) - Thanks to connorr | ||
92 : | German (100%) - Thanks to SchlumPF* | ||
93 : | Russian (100%) - Thanks to `666 | ||
94 : | Spanish (100%) - Hope these don't suck. | ||
95 : | Swedish (100%) - Thanks to Bend3r | ||
96 : | |||
97 : | |||
98 : | Change Log: | ||
99 : | Key (+ added | - removed | c changed | f fixed) | ||
100 : | |||
101 : | v1.1 (Oct 16, 2007) | ||
102 : | +: Grab a few types of entities other than players. | ||
103 : | +: Cvar gp_playersonly. | ||
104 : | |||
105 : | v1.0 (Oct 13, 2007) | ||
106 : | !: Initial release | ||
107 : | |||
108 : | */ | ||
109 : | |||
110 : | #include <amxmodx> | ||
111 : | #include <amxmisc> | ||
112 : | #include <fun> | ||
113 : | #include <engine> | ||
114 : | #include <fakemeta> | ||
115 : | |||
116 : | #define VERSION "1.1" | ||
117 : | #define ADMIN ADMIN_LEVEL_A | ||
118 : | |||
119 : | #define TSK_CHKE 50 | ||
120 : | |||
121 : | #define SF_FADEOUT 0 | ||
122 : | |||
123 : | new client_data[33][4] | ||
124 : | #define GRABBED 0 | ||
125 : | #define GRABBER 1 | ||
126 : | #define GRAB_LEN 2 | ||
127 : | #define FLAGS 3 | ||
128 : | |||
129 : | #define CDF_IN_PUSH (1<<0) | ||
130 : | #define CDF_IN_PULL (1<<1) | ||
131 : | #define CDF_NO_CHOKE (1<<2) | ||
132 : | |||
133 : | //Cvar Pointers | ||
134 : | new p_enabled, p_playersonly | ||
135 : | new p_throwforce, p_mindist, p_speed, p_grabforce | ||
136 : | new p_choketime, p_chokedmg | ||
137 : | new p_glow_r, p_glow_b, p_glow_g | ||
138 : | |||
139 : | //Pseudo Constants | ||
140 : | new MAXPLAYERS | ||
141 : | new SVC_SCREENFADE, SVC_SCREENSHAKE, SVC_DAMAGE | ||
142 : | |||
143 : | |||
144 : | public plugin_init( ) | ||
145 : | { | ||
146 : | register_plugin( "Grab+", VERSION, "Ian Cammarata" ) | ||
147 : | register_cvar( "grab_plus_version", VERSION, FCVAR_SERVER ) | ||
148 : | set_cvar_string( "grab_plus_version", VERSION ) | ||
149 : | |||
150 : | p_enabled = register_cvar( "gp_enabled", "1" ) | ||
151 : | p_playersonly = register_cvar( "gp_playersonly", "0" ) | ||
152 : | |||
153 : | p_mindist = register_cvar ( "gp_min_dist", "90" ) | ||
154 : | p_throwforce = register_cvar( "gp_throwforce", "1500" ) | ||
155 : | p_grabforce = register_cvar( "gp_grabforce", "8" ) | ||
156 : | p_speed = register_cvar( "gp_speed", "5" ) | ||
157 : | |||
158 : | p_choketime = register_cvar( "gp_choketime", "1.5" ) | ||
159 : | p_chokedmg = register_cvar( "gp_chokedmg", "5" ) | ||
160 : | |||
161 : | p_glow_r = register_cvar( "gp_glow_r", "50" ) | ||
162 : | p_glow_g = register_cvar( "gp_glow_g", "0" ) | ||
163 : | p_glow_b = register_cvar( "gp_glow_b", "0" ) | ||
164 : | |||
165 : | register_clcmd( "amx_grab", "force_grab", ADMIN, "Grab client & teleport to you." ) | ||
166 : | register_clcmd( "grab_toggle", "grab_toggle", ADMIN, "press once to grab and again to release" ) | ||
167 : | register_clcmd( "+grab", "grab", ADMIN, "bind a key to +grab" ) | ||
168 : | register_clcmd( "-grab", "unset_grabbed" ) | ||
169 : | |||
170 : | register_clcmd( "+push", "push", ADMIN, "bind a key to +push" ) | ||
171 : | register_clcmd( "-push", "push" ) | ||
172 : | register_clcmd( "+pull", "pull", ADMIN, "bind a key to +pull" ) | ||
173 : | register_clcmd( "-pull", "pull" ) | ||
174 : | register_clcmd( "push", "push2" ) | ||
175 : | register_clcmd( "pull", "pull2" ) | ||
176 : | |||
177 : | register_clcmd( "drop" ,"throw" ) | ||
178 : | |||
179 : | register_event( "DeathMsg", "DeathMsg", "a" ) | ||
180 : | |||
181 : | register_dictionary( "grab_plus.txt" ) | ||
182 : | |||
183 : | MAXPLAYERS = get_maxplayers() | ||
184 : | |||
185 : | SVC_SCREENFADE = get_user_msgid( "ScreenFade" ) | ||
186 : | SVC_SCREENSHAKE = get_user_msgid( "ScreenShake" ) | ||
187 : | SVC_DAMAGE = get_user_msgid( "Damage" ) | ||
188 : | |||
189 : | return PLUGIN_CONTINUE | ||
190 : | } | ||
191 : | |||
192 : | public plugin_precache( ) | ||
193 : | { | ||
194 : | precache_sound( "player/PL_PAIN2.WAV" ) | ||
195 : | return PLUGIN_CONTINUE | ||
196 : | } | ||
197 : | |||
198 : | public client_PreThink( id ) | ||
199 : | { | ||
200 : | //Search for a target | ||
201 : | if ( client_data[id][GRABBED] == -1 ) | ||
202 : | { | ||
203 : | new Float:orig[3], Float:ret[3] | ||
204 : | entity_get_vector( id, EV_VEC_origin, orig ) | ||
205 : | entity_get_vector( id, EV_VEC_view_ofs, ret ) | ||
206 : | |||
207 : | for( new i = 0; i < 3; i++ ) orig[i] += ret[i] | ||
208 : | velocity_by_aim( id, 1, ret ) | ||
209 : | for( new i = 0; i < 3; i++ ) ret[i] = orig[i] + ( ret[i] * 9999 ) | ||
210 : | |||
211 : | new target = trace_line( id, orig, ret, ret ) | ||
212 : | |||
213 : | if( 0 < target <= MAXPLAYERS ) | ||
214 : | { | ||
215 : | if( is_grabbed( target, id ) ) return PLUGIN_CONTINUE | ||
216 : | set_grabbed( id, target ) | ||
217 : | } | ||
218 : | else if( !get_pcvar_num( p_playersonly ) ) | ||
219 : | { | ||
220 : | new movetype | ||
221 : | if( target ) | ||
222 : | { | ||
223 : | movetype = pev( target, pev_movetype ) | ||
224 : | if( !( movetype == MOVETYPE_WALK || movetype == MOVETYPE_STEP || movetype == MOVETYPE_TOSS ) ) | ||
225 : | return PLUGIN_CONTINUE | ||
226 : | } | ||
227 : | else | ||
228 : | { | ||
229 : | new ent = find_ent_in_sphere( -1, ret, 12.0) | ||
230 : | while( !target && ent > 0 ) | ||
231 : | { | ||
232 : | movetype = pev( ent, pev_movetype ) | ||
233 : | if( ( movetype == MOVETYPE_WALK || movetype == MOVETYPE_STEP || movetype == MOVETYPE_TOSS ) | ||
234 : | && ent != id ) | ||
235 : | target = ent | ||
236 : | ent = find_ent_in_sphere( ent, ret, 12.0) | ||
237 : | } | ||
238 : | } | ||
239 : | if( target ) | ||
240 : | { | ||
241 : | if( is_grabbed( target, id ) ) return PLUGIN_CONTINUE | ||
242 : | set_grabbed( id, target ) | ||
243 : | } | ||
244 : | } | ||
245 : | } | ||
246 : | //If they've grabbed something | ||
247 : | if( client_data[id][GRABBED] > 0 ) | ||
248 : | { | ||
249 : | new target = client_data[id][GRABBED] | ||
250 : | if( !pev_valid( target ) || ( pev( target, pev_health ) < 1 && pev( target, pev_max_health ) ) ) | ||
251 : | { | ||
252 : | unset_grabbed( id ) | ||
253 : | return PLUGIN_CONTINUE | ||
254 : | } | ||
255 : | |||
256 : | //Use key choke | ||
257 : | if( pev( id, pev_button ) & IN_USE ) | ||
258 : | do_choke( id ) | ||
259 : | |||
260 : | //Push and pull | ||
261 : | if ( client_data[id][FLAGS] & CDF_IN_PULL ) | ||
262 : | do_pull( id ) | ||
263 : | else if ( client_data[id][FLAGS] & CDF_IN_PUSH ) | ||
264 : | do_push( id ) | ||
265 : | |||
266 : | grab_think( id ) | ||
267 : | } | ||
268 : | if( client_data[id][GRABBER] > 0 ) grab_think( client_data[id][GRABBER] ) | ||
269 : | |||
270 : | return PLUGIN_CONTINUE | ||
271 : | } | ||
272 : | |||
273 : | public grab_think ( id ) | ||
274 : | { | ||
275 : | new target = client_data[id][GRABBED] | ||
276 : | |||
277 : | //Keep grabbed clients from sticking to ladders | ||
278 : | if( pev( target, pev_movetype ) == MOVETYPE_FLY && !(pev( target, pev_button ) & IN_JUMP ) ) client_cmd( target, "+jump;wait;-jump" ) | ||
279 : | |||
280 : | //Move targeted client | ||
281 : | new Float:tmpvec[3], Float:tmpvec2[3], Float:dest[3], Float:torig[3], Float:tvel[3] | ||
282 : | new len = client_data[id][GRAB_LEN] | ||
283 : | |||
284 : | entity_get_vector( id, EV_VEC_origin, dest ) | ||
285 : | entity_get_vector( id, EV_VEC_view_ofs, tmpvec ) | ||
286 : | velocity_by_aim( id, len, tmpvec2 ) | ||
287 : | torig = get_target_origin_f( target ) | ||
288 : | |||
289 : | new force = get_pcvar_num( p_grabforce ) | ||
290 : | |||
291 : | for( new i = 0; i < 3; i++ ) | ||
292 : | { | ||
293 : | dest[i] += tmpvec[i] + tmpvec2[i] | ||
294 : | tvel[i] = ( dest[i] - torig[i] ) * force | ||
295 : | } | ||
296 : | |||
297 : | entity_set_vector( target, EV_VEC_velocity, tvel ) | ||
298 : | } | ||
299 : | |||
300 : | stock Float:get_target_origin_f( id ) | ||
301 : | { | ||
302 : | new Float:orig[3] | ||
303 : | entity_get_vector( id, EV_VEC_origin, orig ) | ||
304 : | |||
305 : | //If grabbed is not a player, move origin to center | ||
306 : | if( id > MAXPLAYERS ) | ||
307 : | { | ||
308 : | new Float:mins[3], Float:maxs[3] | ||
309 : | entity_get_vector( id, EV_VEC_mins, mins ) | ||
310 : | entity_get_vector( id, EV_VEC_maxs, maxs ) | ||
311 : | |||
312 : | if( !mins[2] ) orig[2] += maxs[2] / 2 | ||
313 : | } | ||
314 : | |||
315 : | return orig | ||
316 : | } | ||
317 : | |||
318 : | public grab_toggle( id, level, cid ) | ||
319 : | { | ||
320 : | if( !client_data[id][GRABBED] ) grab( id, level, cid ) | ||
321 : | else unset_grabbed( id ) | ||
322 : | |||
323 : | return PLUGIN_HANDLED | ||
324 : | } | ||
325 : | |||
326 : | public grab( id, level, cid ) | ||
327 : | { | ||
328 : | if( !cmd_access( id, level, cid, 1 ) || !get_pcvar_num( p_enabled ) ) return PLUGIN_HANDLED | ||
329 : | |||
330 : | if ( !client_data[id][GRABBED] ) client_data[id][GRABBED] = -1 | ||
331 : | screenfade_in( id ) | ||
332 : | |||
333 : | return PLUGIN_HANDLED | ||
334 : | } | ||
335 : | |||
336 : | public screenfade_in( id ) | ||
337 : | { | ||
338 : | message_begin( MSG_ONE, SVC_SCREENFADE, _, id ) | ||
339 : | write_short( 10000 ) //duration | ||
340 : | write_short( 0 ) //hold | ||
341 : | write_short( SF_FADE_IN + SF_FADE_ONLYONE ) //flags | ||
342 : | write_byte( get_pcvar_num( p_glow_r ) ) //r | ||
343 : | write_byte( get_pcvar_num( p_glow_g ) ) //g | ||
344 : | write_byte( get_pcvar_num( p_glow_b ) ) //b | ||
345 : | write_byte( 127 ) //a | ||
346 : | message_end( ) | ||
347 : | } | ||
348 : | |||
349 : | public throw( id ) | ||
350 : | { | ||
351 : | new target = client_data[id][GRABBED] | ||
352 : | if( target > 0 ) | ||
353 : | { | ||
354 : | new Float:pVelocity[3] | ||
355 : | velocity_by_aim( id, get_pcvar_num(p_throwforce), pVelocity ) | ||
356 : | entity_set_vector( target, EV_VEC_velocity, pVelocity ) | ||
357 : | unset_grabbed( id ) | ||
358 : | return PLUGIN_HANDLED | ||
359 : | } | ||
360 : | return PLUGIN_CONTINUE | ||
361 : | } | ||
362 : | |||
363 : | public unset_grabbed( id ) | ||
364 : | { | ||
365 : | new target = client_data[id][GRABBED] | ||
366 : | if( target > 0 && pev_valid( target ) ) | ||
367 : | { | ||
368 : | set_rendering( target ) | ||
369 : | if( 0 < target <= MAXPLAYERS ) | ||
370 : | client_data[target][GRABBER] = 0 | ||
371 : | } | ||
372 : | client_data[id][GRABBED] = 0 | ||
373 : | |||
374 : | message_begin( MSG_ONE, SVC_SCREENFADE, _, id ) | ||
375 : | write_short( 10000 ) //duration | ||
376 : | write_short( 0 ) //hold | ||
377 : | write_short( SF_FADEOUT ) //flags | ||
378 : | write_byte( get_pcvar_num( p_glow_r ) ) //r | ||
379 : | write_byte( get_pcvar_num( p_glow_g ) ) //g | ||
380 : | write_byte( get_pcvar_num( p_glow_b ) ) //b | ||
381 : | write_byte( 127 ) //a | ||
382 : | message_end( ) | ||
383 : | } | ||
384 : | |||
385 : | //Grabs onto someone | ||
386 : | public set_grabbed( id, target ) | ||
387 : | { | ||
388 : | set_rendering( target, | ||
389 : | kRenderFxGlowShell, | ||
390 : | get_pcvar_num( p_glow_r ), | ||
391 : | get_pcvar_num( p_glow_g ), | ||
392 : | get_pcvar_num( p_glow_b ), | ||
393 : | kRenderTransColor, | ||
394 : | 255 ) | ||
395 : | |||
396 : | if( 0 < target <= MAXPLAYERS ) | ||
397 : | client_data[target][GRABBER] = id | ||
398 : | client_data[id][FLAGS] = 0 | ||
399 : | client_data[id][GRABBED] = target | ||
400 : | client_data[id][GRAB_LEN] = floatround( entity_range( target, id ) ) | ||
401 : | if( client_data[id][GRAB_LEN] < get_pcvar_num( p_mindist ) ) client_data[id][GRAB_LEN] = get_pcvar_num( p_mindist ) | ||
402 : | } | ||
403 : | |||
404 : | public push( id ) | ||
405 : | { | ||
406 : | client_data[id][FLAGS] ^= CDF_IN_PUSH | ||
407 : | return PLUGIN_HANDLED | ||
408 : | } | ||
409 : | |||
410 : | public pull( id ) | ||
411 : | { | ||
412 : | client_data[id][FLAGS] ^= CDF_IN_PULL | ||
413 : | return PLUGIN_HANDLED | ||
414 : | } | ||
415 : | |||
416 : | public push2( id ) | ||
417 : | { | ||
418 : | if( client_data[id][GRABBED] > 0 ) | ||
419 : | { | ||
420 : | do_push( id ) | ||
421 : | return PLUGIN_HANDLED | ||
422 : | } | ||
423 : | return PLUGIN_CONTINUE | ||
424 : | } | ||
425 : | |||
426 : | public pull2( id ) | ||
427 : | { | ||
428 : | if( client_data[id][GRABBED] > 0 ) | ||
429 : | { | ||
430 : | do_pull( id ) | ||
431 : | return PLUGIN_HANDLED | ||
432 : | } | ||
433 : | return PLUGIN_CONTINUE | ||
434 : | } | ||
435 : | |||
436 : | public do_push( id ) | ||
437 : | if( client_data[id][GRAB_LEN] < 9999 ) | ||
438 : | client_data[id][GRAB_LEN] += get_pcvar_num( p_speed ) | ||
439 : | |||
440 : | public do_pull( id ) | ||
441 : | { | ||
442 : | new mindist = get_pcvar_num( p_mindist ) | ||
443 : | new len = client_data[id][GRAB_LEN] | ||
444 : | |||
445 : | if( len > mindist ) | ||
446 : | { | ||
447 : | len -= get_pcvar_num( p_speed ) | ||
448 : | if( len < mindist ) len = mindist | ||
449 : | client_data[id][GRAB_LEN] = len | ||
450 : | } | ||
451 : | else do_choke( id ) | ||
452 : | } | ||
453 : | |||
454 : | public do_choke( id ) | ||
455 : | { | ||
456 : | new target = client_data[id][GRABBED] | ||
457 : | if( client_data[id][FLAGS] & CDF_NO_CHOKE || id == target || target > MAXPLAYERS) return | ||
458 : | |||
459 : | new dmg = get_pcvar_num( p_chokedmg ) | ||
460 : | new Float:vec[3] | ||
461 : | get_target_origin_f( target ) | ||
462 : | |||
463 : | message_begin( MSG_ONE, SVC_SCREENSHAKE, _, target ) | ||
464 : | write_short( 999999 ) //amount | ||
465 : | write_short( 9999 ) //duration | ||
466 : | write_short( 999 ) //frequency | ||
467 : | message_end( ) | ||
468 : | |||
469 : | message_begin( MSG_ONE, SVC_SCREENFADE, _, target ) | ||
470 : | write_short( 9999 ) //duration | ||
471 : | write_short( 100 ) //hold | ||
472 : | write_short( SF_FADE_MODULATE ) //flags | ||
473 : | write_byte( get_pcvar_num( p_glow_r ) ) //r | ||
474 : | write_byte( get_pcvar_num( p_glow_g ) ) //g | ||
475 : | write_byte( get_pcvar_num( p_glow_b ) ) //b | ||
476 : | write_byte( 200 ) //a | ||
477 : | message_end( ) | ||
478 : | |||
479 : | message_begin( MSG_ONE, SVC_DAMAGE, _, target ) | ||
480 : | write_byte( 0 ) //damage armor | ||
481 : | write_byte( dmg ) //damage health | ||
482 : | write_long( DMG_CRUSH ) //damage type | ||
483 : | write_coord( floatround( vec[0] ) ) //origin[x] | ||
484 : | write_coord( floatround( vec[1] ) ) //origin[y] | ||
485 : | write_coord( floatround( vec[2] ) ) //origin[z] | ||
486 : | message_end( ) | ||
487 : | |||
488 : | message_begin( MSG_BROADCAST, SVC_TEMPENTITY ) | ||
489 : | write_byte( TE_BLOODSTREAM ) | ||
490 : | write_coord( floatround( vec[0] ) ) //pos.x | ||
491 : | write_coord( floatround( vec[1] ) ) //pos.y | ||
492 : | write_coord( floatround( vec[2] ) + 15 ) //pos.z | ||
493 : | write_coord( random_num( 0, 255 ) ) //vec.x | ||
494 : | write_coord( random_num( 0, 255 ) ) //vec.y | ||
495 : | write_coord( random_num( 0, 255 ) ) //vec.z | ||
496 : | write_byte( 70 ) //col index | ||
497 : | write_byte( random_num( 50, 250 ) ) //speed | ||
498 : | message_end( ) | ||
499 : | |||
500 : | new health = pev( target, pev_health ) - dmg | ||
501 : | set_pev( target, pev_health, float( health ) ) | ||
502 : | if( health < 1 ) dllfunc( DLLFunc_ClientKill, target ) | ||
503 : | |||
504 : | emit_sound( target, CHAN_BODY, "player/PL_PAIN2.WAV", VOL_NORM, ATTN_NORM, 0, PITCH_NORM ) | ||
505 : | |||
506 : | client_data[id][FLAGS] ^= CDF_NO_CHOKE | ||
507 : | set_task( get_pcvar_float( p_choketime ), "clear_no_choke", TSK_CHKE + id ) | ||
508 : | } | ||
509 : | |||
510 : | public clear_no_choke( tskid ) | ||
511 : | { | ||
512 : | new id = tskid - TSK_CHKE | ||
513 : | client_data[id][FLAGS] ^= CDF_NO_CHOKE | ||
514 : | } | ||
515 : | |||
516 : | //Grabs the client and teleports them to the admin | ||
517 : | public force_grab(id, level, cid) | ||
518 : | { | ||
519 : | if( !cmd_access( id, level, cid, 1 ) || !get_pcvar_num( p_enabled ) ) return PLUGIN_HANDLED | ||
520 : | |||
521 : | new arg[33] | ||
522 : | read_argv( 1, arg, 32 ) | ||
523 : | |||
524 : | new targetid = cmd_target( id, arg, 1 ) | ||
525 : | |||
526 : | if( is_grabbed( targetid, id ) ) return PLUGIN_HANDLED | ||
527 : | if( !is_user_alive( targetid ) ) | ||
528 : | { | ||
529 : | client_print( id, print_console, "[AMXX] %L", id, "COULDNT" ) | ||
530 : | return PLUGIN_HANDLED | ||
531 : | } | ||
532 : | |||
533 : | //Safe to tp target to aim spot? | ||
534 : | new Float:tmpvec[3], Float:tmpvec2[3], Float:orig[3], Float:torig[3], Float:trace_ret[3] | ||
535 : | new bool:safe = false, i | ||
536 : | |||
537 : | entity_get_vector( id, EV_VEC_origin, orig ) | ||
538 : | entity_get_vector( id, EV_VEC_view_ofs, tmpvec ) | ||
539 : | for( i = 0; i < 3; i++ ) tmpvec[i] += orig[i] | ||
540 : | velocity_by_aim( id, get_pcvar_num( p_mindist ), tmpvec2 ) | ||
541 : | |||
542 : | for( new j = 1; j < 11 && !safe; j++ ) | ||
543 : | { | ||
544 : | for( i = 0; i < 3; i++ ) | ||
545 : | torig[i] = tmpvec[i] + tmpvec2[i] * j | ||
546 : | |||
547 : | trace_line( id, tmpvec, torig, trace_ret ) | ||
548 : | if( get_distance_f( trace_ret, torig ) ) break | ||
549 : | if( !trace_hull( torig, HULL_HUMAN ) ) safe = true | ||
550 : | } | ||
551 : | |||
552 : | //Still not safe? Then find another safe spot somewhere around the grabber | ||
553 : | new try[3] | ||
554 : | orig[2] += 2 | ||
555 : | while( try[2] < 3 && !safe ) | ||
556 : | { | ||
557 : | for( i = 0; i < 3; i++ ) | ||
558 : | switch( try[i] ) | ||
559 : | { | ||
560 : | case 0 : torig[i] = orig[i] + ( i == 2 ? 80 : 40 ) | ||
561 : | case 1 : torig[i] = orig[i] | ||
562 : | case 2 : torig[i] = orig[i] - ( i == 2 ? 80 : 40 ) | ||
563 : | } | ||
564 : | |||
565 : | trace_line( id, tmpvec, torig, trace_ret ) | ||
566 : | if( !trace_hull( torig, HULL_HUMAN ) && !get_distance_f( trace_ret, torig ) ) safe = true | ||
567 : | |||
568 : | try[0]++ | ||
569 : | if( try[0] == 3 ) | ||
570 : | { | ||
571 : | try[0] = 0 | ||
572 : | try[1]++ | ||
573 : | if( try[1] == 3 ) | ||
574 : | { | ||
575 : | try[1] = 0 | ||
576 : | try[2]++ | ||
577 : | } | ||
578 : | } | ||
579 : | } | ||
580 : | |||
581 : | if( safe ) | ||
582 : | { | ||
583 : | entity_set_vector( targetid, EV_VEC_origin, torig ) | ||
584 : | set_grabbed( id, targetid ) | ||
585 : | screenfade_in( id ) | ||
586 : | } | ||
587 : | else client_print( id, print_chat, "[AMXX] %L", id, "COULDNT" ) | ||
588 : | |||
589 : | return PLUGIN_HANDLED | ||
590 : | } | ||
591 : | |||
592 : | public is_grabbed( target, grabber ) | ||
593 : | { | ||
594 : | for( new i = 1; i <= MAXPLAYERS; i++ ) | ||
595 : | if( client_data[i][GRABBED] == target ) | ||
596 : | { | ||
597 : | client_print( grabber, print_chat, "[AMXX] %L", grabber, "ALREADY" ) | ||
598 : | unset_grabbed( grabber ) | ||
599 : | return true | ||
600 : | } | ||
601 : | return false | ||
602 : | } | ||
603 : | |||
604 : | public DeathMsg( ) | ||
605 : | kill_grab( read_data( 2 ) ) | ||
606 : | |||
607 : | public client_disconnect( id ) | ||
608 : | { | ||
609 : | kill_grab( id ) | ||
610 : | return PLUGIN_CONTINUE | ||
611 : | } | ||
612 : | |||
613 : | public kill_grab( id ) | ||
614 : | { | ||
615 : | //If given client has grabbed, or has a grabber, unset it | ||
616 : | if( client_data[id][GRABBED] ) | ||
617 : | unset_grabbed( id ) | ||
618 : | else if( client_data[id][GRABBER] ) | ||
619 : | unset_grabbed( client_data[id][GRABBER] ) | ||
620 : | } |
Contact | ViewVC Help |
Powered by ViewVC 1.0.4 |