73 |
|
|
74 |
|
|
75 |
Credits: |
Credits: |
76 |
|
Thanks to vittu for contributing code (changed all engine/fun module stuff to fakemeta). |
77 |
|
|
78 |
Thanks to all the coders who worked on the original Jedi Force Grab plugin for all their ideas: |
Thanks to all the coders who worked on the original Jedi Force Grab plugin for all their ideas: |
79 |
SpaceDude |
SpaceDude |
80 |
KCE |
KCE |
100 |
Change Log: |
Change Log: |
101 |
Key (+ added | - removed | c changed | f fixed) |
Key (+ added | - removed | c changed | f fixed) |
102 |
|
|
103 |
|
v1.2 (Nov ??, 2007) |
104 |
|
+: Cvars gp_screenfade and gp_glow to enable/disable these features. |
105 |
|
+: Cvar gp_glow_a controls to control alpha of screenfade and glow. |
106 |
|
c: Removed dependency of engine and fun modules. Thanks to vittu for doing all the work. |
107 |
|
f: Fixed compile bug with amxx 1.8.0 (Compiles with 1.7x as well). |
108 |
|
|
109 |
v1.1 (Oct 16, 2007) |
v1.1 (Oct 16, 2007) |
110 |
+: Grab a few types of entities other than players. |
+: Grab a few types of entities other than players. |
111 |
+: Cvar gp_playersonly. |
+: Cvar gp_playersonly. |
117 |
|
|
118 |
#include <amxmodx> |
#include <amxmodx> |
119 |
#include <amxmisc> |
#include <amxmisc> |
|
#include <fun> |
|
|
#include <engine> |
|
120 |
#include <fakemeta> |
#include <fakemeta> |
121 |
|
|
122 |
#define VERSION "1.1" |
#define VERSION "1.2b1" |
123 |
#define ADMIN ADMIN_LEVEL_A |
#define ADMIN ADMIN_LEVEL_A |
124 |
|
|
125 |
#define TSK_CHKE 50 |
#define TSK_CHKE 50 |
126 |
|
|
127 |
|
#define SVC_DAMAGE 19 |
128 |
#define SF_FADEOUT 0 |
#define SF_FADEOUT 0 |
129 |
|
|
130 |
new client_data[33][4] |
new client_data[33][4] |
141 |
new p_enabled, p_playersonly |
new p_enabled, p_playersonly |
142 |
new p_throwforce, p_mindist, p_speed, p_grabforce |
new p_throwforce, p_mindist, p_speed, p_grabforce |
143 |
new p_choketime, p_chokedmg |
new p_choketime, p_chokedmg |
144 |
new p_glow_r, p_glow_b, p_glow_g |
new p_glow_r, p_glow_b, p_glow_g, p_glow_a |
145 |
|
new p_fade, p_glow |
146 |
|
|
147 |
//Pseudo Constants |
//Pseudo Constants |
148 |
new MAXPLAYERS |
new MAXPLAYERS |
149 |
new SVC_SCREENFADE, SVC_SCREENSHAKE, SVC_DAMAGE |
new SVC_SCREENFADE, SVC_SCREENSHAKE |
|
|
|
150 |
|
|
151 |
public plugin_init( ) |
public plugin_init( ) |
152 |
{ |
{ |
168 |
p_glow_r = register_cvar( "gp_glow_r", "50" ) |
p_glow_r = register_cvar( "gp_glow_r", "50" ) |
169 |
p_glow_g = register_cvar( "gp_glow_g", "0" ) |
p_glow_g = register_cvar( "gp_glow_g", "0" ) |
170 |
p_glow_b = register_cvar( "gp_glow_b", "0" ) |
p_glow_b = register_cvar( "gp_glow_b", "0" ) |
171 |
|
p_glow_a = register_cvar( "gp_glow_a", "200" ) |
172 |
|
|
173 |
|
p_fade = register_cvar( "gp_screenfade", "1" ) |
174 |
|
p_glow = register_cvar( "gp_glow", "1" ) |
175 |
|
|
176 |
register_clcmd( "amx_grab", "force_grab", ADMIN, "Grab client & teleport to you." ) |
register_clcmd( "amx_grab", "force_grab", ADMIN, "Grab client & teleport to you." ) |
177 |
register_clcmd( "grab_toggle", "grab_toggle", ADMIN, "press once to grab and again to release" ) |
register_clcmd( "grab_toggle", "grab_toggle", ADMIN, "press once to grab and again to release" ) |
195 |
|
|
196 |
SVC_SCREENFADE = get_user_msgid( "ScreenFade" ) |
SVC_SCREENFADE = get_user_msgid( "ScreenFade" ) |
197 |
SVC_SCREENSHAKE = get_user_msgid( "ScreenShake" ) |
SVC_SCREENSHAKE = get_user_msgid( "ScreenShake" ) |
|
SVC_DAMAGE = get_user_msgid( "Damage" ) |
|
198 |
|
|
199 |
return PLUGIN_CONTINUE |
return PLUGIN_CONTINUE |
200 |
} |
} |
211 |
if ( client_data[id][GRABBED] == -1 ) |
if ( client_data[id][GRABBED] == -1 ) |
212 |
{ |
{ |
213 |
new Float:orig[3], Float:ret[3] |
new Float:orig[3], Float:ret[3] |
214 |
entity_get_vector( id, EV_VEC_origin, orig ) |
pev( id, pev_origin, orig ) |
215 |
entity_get_vector( id, EV_VEC_view_ofs, ret ) |
pev( id, pev_view_ofs, ret ) |
216 |
|
|
217 |
for( new i = 0; i < 3; i++ ) orig[i] += ret[i] |
for( new i = 0; i < 3; i++ ) orig[i] += ret[i] |
218 |
velocity_by_aim( id, 1, ret ) |
engfunc( EngFunc_GetAimVector, id, 1, ret ) |
219 |
for( new i = 0; i < 3; i++ ) ret[i] = orig[i] + ( ret[i] * 9999 ) |
for( new i = 0; i < 3; i++ ) ret[i] = orig[i] + ( ret[i] * 9999 ) |
220 |
|
|
221 |
new target = trace_line( id, orig, ret, ret ) |
new tr = 0 |
222 |
|
engfunc( EngFunc_TraceLine, orig, ret, 0, id, tr ) |
223 |
|
new target = get_tr2( tr, TR_pHit ) |
224 |
|
get_tr2( tr, TR_vecEndPos, ret ) |
225 |
|
|
226 |
if( 0 < target <= MAXPLAYERS ) |
if( 0 < target <= MAXPLAYERS ) |
227 |
{ |
{ |
239 |
} |
} |
240 |
else |
else |
241 |
{ |
{ |
242 |
new ent = find_ent_in_sphere( -1, ret, 12.0) |
new ent = engfunc( EngFunc_FindEntityInSphere, -1, ret, 12.0 ) |
243 |
while( !target && ent > 0 ) |
while( !target && ent > 0 ) |
244 |
{ |
{ |
245 |
movetype = pev( ent, pev_movetype ) |
movetype = pev( ent, pev_movetype ) |
246 |
if( ( movetype == MOVETYPE_WALK || movetype == MOVETYPE_STEP || movetype == MOVETYPE_TOSS ) |
if( ( movetype == MOVETYPE_WALK || movetype == MOVETYPE_STEP || movetype == MOVETYPE_TOSS ) |
247 |
&& ent != id ) |
&& ent != id ) |
248 |
target = ent |
target = ent |
249 |
ent = find_ent_in_sphere( ent, ret, 12.0) |
ent = engfunc( EngFunc_FindEntityInSphere, ent, ret, 12.0 ) |
250 |
} |
} |
251 |
} |
} |
252 |
if( target ) |
if( target ) |
294 |
new Float:tmpvec[3], Float:tmpvec2[3], Float:dest[3], Float:torig[3], Float:tvel[3] |
new Float:tmpvec[3], Float:tmpvec2[3], Float:dest[3], Float:torig[3], Float:tvel[3] |
295 |
new len = client_data[id][GRAB_LEN] |
new len = client_data[id][GRAB_LEN] |
296 |
|
|
297 |
entity_get_vector( id, EV_VEC_origin, dest ) |
pev( id, pev_origin, dest ) |
298 |
entity_get_vector( id, EV_VEC_view_ofs, tmpvec ) |
pev( id, pev_view_ofs, tmpvec ) |
299 |
velocity_by_aim( id, len, tmpvec2 ) |
engfunc(EngFunc_GetAimVector, id, len, tmpvec2) |
300 |
torig = get_target_origin_f( target ) |
torig = get_target_origin_f( target ) |
301 |
|
|
302 |
new force = get_pcvar_num( p_grabforce ) |
new force = get_pcvar_num( p_grabforce ) |
307 |
tvel[i] = ( dest[i] - torig[i] ) * force |
tvel[i] = ( dest[i] - torig[i] ) * force |
308 |
} |
} |
309 |
|
|
310 |
entity_set_vector( target, EV_VEC_velocity, tvel ) |
set_pev( target, pev_velocity, tvel ) |
311 |
} |
} |
312 |
|
|
313 |
stock Float:get_target_origin_f( id ) |
stock Float:get_target_origin_f( id ) |
314 |
{ |
{ |
315 |
new Float:orig[3] |
new Float:orig[3] |
316 |
entity_get_vector( id, EV_VEC_origin, orig ) |
pev( id, pev_origin, orig ) |
317 |
|
|
318 |
//If grabbed is not a player, move origin to center |
//If grabbed is not a player, move origin to center |
319 |
if( id > MAXPLAYERS ) |
if( id > MAXPLAYERS ) |
320 |
{ |
{ |
321 |
new Float:mins[3], Float:maxs[3] |
new Float:mins[3], Float:maxs[3] |
322 |
entity_get_vector( id, EV_VEC_mins, mins ) |
pev( id, pev_mins, mins ) |
323 |
entity_get_vector( id, EV_VEC_maxs, maxs ) |
pev( id, pev_maxs, maxs ) |
324 |
|
|
325 |
if( !mins[2] ) orig[2] += maxs[2] / 2 |
if( !mins[2] ) orig[2] += maxs[2] / 2 |
326 |
} |
} |
348 |
|
|
349 |
public screenfade_in( id ) |
public screenfade_in( id ) |
350 |
{ |
{ |
351 |
|
if( get_pcvar_num( p_fade ) ) |
352 |
|
{ |
353 |
message_begin( MSG_ONE, SVC_SCREENFADE, _, id ) |
message_begin( MSG_ONE, SVC_SCREENFADE, _, id ) |
354 |
write_short( 10000 ) //duration |
write_short( 10000 ) //duration |
355 |
write_short( 0 ) //hold |
write_short( 0 ) //hold |
357 |
write_byte( get_pcvar_num( p_glow_r ) ) //r |
write_byte( get_pcvar_num( p_glow_r ) ) //r |
358 |
write_byte( get_pcvar_num( p_glow_g ) ) //g |
write_byte( get_pcvar_num( p_glow_g ) ) //g |
359 |
write_byte( get_pcvar_num( p_glow_b ) ) //b |
write_byte( get_pcvar_num( p_glow_b ) ) //b |
360 |
write_byte( 127 ) //a |
write_byte( get_pcvar_num( p_glow_a ) / 2 ) //a |
361 |
message_end( ) |
message_end( ) |
362 |
} |
} |
363 |
|
} |
364 |
|
|
365 |
public throw( id ) |
public throw( id ) |
366 |
{ |
{ |
368 |
if( target > 0 ) |
if( target > 0 ) |
369 |
{ |
{ |
370 |
new Float:pVelocity[3] |
new Float:pVelocity[3] |
371 |
velocity_by_aim( id, get_pcvar_num(p_throwforce), pVelocity ) |
engfunc( EngFunc_GetAimVector, id, get_pcvar_num( p_throwforce ), pVelocity ) |
372 |
entity_set_vector( target, EV_VEC_velocity, pVelocity ) |
set_pev( target, pev_velocity, pVelocity ) |
373 |
unset_grabbed( id ) |
unset_grabbed( id ) |
374 |
return PLUGIN_HANDLED |
return PLUGIN_HANDLED |
375 |
} |
} |
381 |
new target = client_data[id][GRABBED] |
new target = client_data[id][GRABBED] |
382 |
if( target > 0 && pev_valid( target ) ) |
if( target > 0 && pev_valid( target ) ) |
383 |
{ |
{ |
384 |
set_rendering( target ) |
set_pev( target, pev_renderfx, kRenderFxNone ) |
385 |
|
set_pev( target, pev_rendercolor, {255.0, 255.0, 255.0} ) |
386 |
|
set_pev( target, pev_rendermode, kRenderNormal ) |
387 |
|
set_pev( target, pev_renderamt, 16.0 ) |
388 |
|
|
389 |
if( 0 < target <= MAXPLAYERS ) |
if( 0 < target <= MAXPLAYERS ) |
390 |
client_data[target][GRABBER] = 0 |
client_data[target][GRABBER] = 0 |
391 |
} |
} |
392 |
client_data[id][GRABBED] = 0 |
client_data[id][GRABBED] = 0 |
393 |
|
|
394 |
|
if( get_pcvar_num( p_fade ) ) |
395 |
|
{ |
396 |
message_begin( MSG_ONE, SVC_SCREENFADE, _, id ) |
message_begin( MSG_ONE, SVC_SCREENFADE, _, id ) |
397 |
write_short( 10000 ) //duration |
write_short( 10000 ) //duration |
398 |
write_short( 0 ) //hold |
write_short( 0 ) //hold |
400 |
write_byte( get_pcvar_num( p_glow_r ) ) //r |
write_byte( get_pcvar_num( p_glow_r ) ) //r |
401 |
write_byte( get_pcvar_num( p_glow_g ) ) //g |
write_byte( get_pcvar_num( p_glow_g ) ) //g |
402 |
write_byte( get_pcvar_num( p_glow_b ) ) //b |
write_byte( get_pcvar_num( p_glow_b ) ) //b |
403 |
write_byte( 127 ) //a |
write_byte( get_pcvar_num( p_glow_a ) / 2 ) //a |
404 |
message_end( ) |
message_end( ) |
405 |
} |
} |
406 |
|
} |
407 |
|
|
408 |
//Grabs onto someone |
//Grabs onto someone |
409 |
public set_grabbed( id, target ) |
public set_grabbed( id, target ) |
410 |
{ |
{ |
411 |
set_rendering( target, |
if( get_pcvar_num( p_glow ) ) |
412 |
kRenderFxGlowShell, |
{ |
413 |
get_pcvar_num( p_glow_r ), |
new Float:color[3] |
414 |
get_pcvar_num( p_glow_g ), |
color[0] = get_pcvar_float( p_glow_r ) |
415 |
get_pcvar_num( p_glow_b ), |
color[1] = get_pcvar_float( p_glow_g ) |
416 |
kRenderTransColor, |
color[2] = get_pcvar_float( p_glow_b ) |
417 |
255 ) |
set_pev(target, pev_renderfx, kRenderFxGlowShell) |
418 |
|
set_pev(target, pev_rendercolor, color) |
419 |
|
set_pev(target, pev_rendermode, kRenderTransColor) |
420 |
|
set_pev(target, pev_renderamt, get_pcvar_float( p_glow_b ) ) |
421 |
|
} |
422 |
|
|
423 |
if( 0 < target <= MAXPLAYERS ) |
if( 0 < target <= MAXPLAYERS ) |
424 |
client_data[target][GRABBER] = id |
client_data[target][GRABBER] = id |
425 |
client_data[id][FLAGS] = 0 |
client_data[id][FLAGS] = 0 |
426 |
client_data[id][GRABBED] = target |
client_data[id][GRABBED] = target |
427 |
client_data[id][GRAB_LEN] = floatround( entity_range( target, id ) ) |
new Float:torig[3], Float:orig[3] |
428 |
|
pev( target, pev_origin, torig ) |
429 |
|
pev( id, pev_origin, orig ) |
430 |
|
client_data[id][GRAB_LEN] = floatround( get_distance_f( torig, orig ) ) |
431 |
if( client_data[id][GRAB_LEN] < get_pcvar_num( p_mindist ) ) client_data[id][GRAB_LEN] = get_pcvar_num( p_mindist ) |
if( client_data[id][GRAB_LEN] < get_pcvar_num( p_mindist ) ) client_data[id][GRAB_LEN] = get_pcvar_num( p_mindist ) |
432 |
} |
} |
433 |
|
|
564 |
new Float:tmpvec[3], Float:tmpvec2[3], Float:orig[3], Float:torig[3], Float:trace_ret[3] |
new Float:tmpvec[3], Float:tmpvec2[3], Float:orig[3], Float:torig[3], Float:trace_ret[3] |
565 |
new bool:safe = false, i |
new bool:safe = false, i |
566 |
|
|
567 |
entity_get_vector( id, EV_VEC_origin, orig ) |
pev( id, pev_origin, orig ) |
568 |
entity_get_vector( id, EV_VEC_view_ofs, tmpvec ) |
pev( id, pev_view_ofs, tmpvec ) |
569 |
for( i = 0; i < 3; i++ ) tmpvec[i] += orig[i] |
for( i = 0; i < 3; i++ ) tmpvec[i] += orig[i] |
570 |
velocity_by_aim( id, get_pcvar_num( p_mindist ), tmpvec2 ) |
engfunc( EngFunc_GetAimVector, id, get_pcvar_num( p_mindist ), tmpvec2 ) |
571 |
|
|
572 |
for( new j = 1; j < 11 && !safe; j++ ) |
for( new j = 1; j < 11 && !safe; j++ ) |
573 |
{ |
{ |
574 |
for( i = 0; i < 3; i++ ) |
for( i = 0; i < 3; i++ ) |
575 |
torig[i] = tmpvec[i] + tmpvec2[i] * j |
torig[i] = tmpvec[i] + tmpvec2[i] * j |
576 |
|
|
577 |
trace_line( id, tmpvec, torig, trace_ret ) |
new tr = 0 |
578 |
|
engfunc( EngFunc_TraceLine, tmpvec, torig, 0, id, tr ) |
579 |
|
get_tr2( tr, TR_vecEndPos, trace_ret ) |
580 |
|
|
581 |
if( get_distance_f( trace_ret, torig ) ) break |
if( get_distance_f( trace_ret, torig ) ) break |
582 |
if( !trace_hull( torig, HULL_HUMAN ) ) safe = true |
if( !_trace_hull( torig, HULL_HUMAN ) ) safe = true |
583 |
} |
} |
584 |
|
|
585 |
//Still not safe? Then find another safe spot somewhere around the grabber |
//Still not safe? Then find another safe spot somewhere around the grabber |
595 |
case 2 : torig[i] = orig[i] - ( i == 2 ? 80 : 40 ) |
case 2 : torig[i] = orig[i] - ( i == 2 ? 80 : 40 ) |
596 |
} |
} |
597 |
|
|
598 |
trace_line( id, tmpvec, torig, trace_ret ) |
new tr2 = 0 |
599 |
if( !trace_hull( torig, HULL_HUMAN ) && !get_distance_f( trace_ret, torig ) ) safe = true |
engfunc( EngFunc_TraceLine, tmpvec, torig, 0, id, tr2 ) |
600 |
|
get_tr2( tr2, TR_vecEndPos, trace_ret ) |
601 |
|
|
602 |
|
if( !_trace_hull( torig, HULL_HUMAN ) && !get_distance_f( trace_ret, torig ) ) safe = true |
603 |
|
|
604 |
try[0]++ |
try[0]++ |
605 |
if( try[0] == 3 ) |
if( try[0] == 3 ) |
616 |
|
|
617 |
if( safe ) |
if( safe ) |
618 |
{ |
{ |
619 |
entity_set_vector( targetid, EV_VEC_origin, torig ) |
set_pev( targetid, pev_origin, torig ) |
620 |
set_grabbed( id, targetid ) |
set_grabbed( id, targetid ) |
621 |
screenfade_in( id ) |
screenfade_in( id ) |
622 |
} |
} |
654 |
else if( client_data[id][GRABBER] ) |
else if( client_data[id][GRABBER] ) |
655 |
unset_grabbed( client_data[id][GRABBER] ) |
unset_grabbed( client_data[id][GRABBER] ) |
656 |
} |
} |
657 |
|
|
658 |
|
//Complements of vittu |
659 |
|
//Complements of fakemeta_util, cause i was too lazy to add this in as not a function |
660 |
|
_trace_hull(const Float:origin[3], hull, ignoredent = 0, ignoremonsters = 0) { |
661 |
|
new result = 0; |
662 |
|
engfunc(EngFunc_TraceHull, origin, origin, ignoremonsters, hull, ignoredent > 0 ? ignoredent : 0, 0); |
663 |
|
|
664 |
|
if (get_tr2(0, TR_StartSolid)) |
665 |
|
result += 1; |
666 |
|
if (get_tr2(0, TR_AllSolid)) |
667 |
|
result += 2; |
668 |
|
if (!get_tr2(0, TR_InOpen)) |
669 |
|
result += 4; |
670 |
|
|
671 |
|
return result; |
672 |
|
} |