// SPIDERMAN! - BASED ON SPACEDUDE'S NINJA HOOK
/* CVARS - copy and paste to shconfig.cfg
//Spiderman
spiderman_level 0
spiderman_moveacc 140 //How quickly he can move while on the hook
spiderman_reelspeed 400 //How fast hook line reels in
spiderman_hookstyle 2 //1=spacedude, 2=spacedude auto reel (spiderman), 3=cheap kids real (batgirl)
spiderman_teamcolored 1 //1=teamcolored web lines 0=white web lines
spiderman_maxhooks 60 //Max ammout of hooks allowed (-1 is an unlimited ammount)
*/
#include <superheromod>
// GLOBAL VARIABLES
#define HOOKBEAMLIFE 100
#define HOOK_DELTA_T 0.1 // units per second
new gHeroID
new const gHeroName[] = "Spider-Man"
new bool:gHooked[SH_MAXSLOTS+1]
new gHookLocation[SH_MAXSLOTS+1][3]
new gHookLength[SH_MAXSLOTS+1]
new Float:gHookCreated[SH_MAXSLOTS+1]
new gHooksLeft[SH_MAXSLOTS+1]
new const gSoundWeb[] = "bullchicken/bc_bite2.wav"
new gSpriteWeb
new pCvarMoveAcc, pCvarReelSpeed, pCvarHookStyle
new pCvarMaxHooks, pCvarTeamColored, pCvarSvGravity
//----------------------------------------------------------------------------------------------
public plugin_init()
{
// Plugin Info
register_plugin("SUPERHERO Spider-Man", SH_VERSION_STR, "{HOJ} Batman/JTP10181")
register_dictionary("sh_spiderman.txt")
// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
new pcvarLevel = register_cvar("spiderman_level", "0")
pCvarMoveAcc = register_cvar("spiderman_moveacc", "140")
pCvarReelSpeed = register_cvar("spiderman_reelspeed", "400")
pCvarHookStyle = register_cvar("spiderman_hookstyle", "2")
pCvarMaxHooks = register_cvar("spiderman_maxhooks", "60")
pCvarTeamColored = register_cvar("spiderman_teamcolored", "1")
// FIRE THE EVENTS TO CREATE THIS SUPERHERO!
gHeroID = sh_create_hero(gHeroName, pcvarLevel)
sh_set_hero_info(gHeroID, "Web Swing", "Shoot Web to Swing - Jump Reels In, Duck Reels Out")
sh_set_hero_bind(gHeroID)
pCvarSvGravity = get_cvar_pointer("sv_gravity")
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
precache_sound(gSoundWeb)
gSpriteWeb = precache_model("sprites/zbeam4.spr")
}
//----------------------------------------------------------------------------------------------
public sh_hero_init(id, heroID, mode)
{
if ( gHeroID != heroID ) return
if ( gHooked[id] ) spiderman_hook_off(id)
sh_debug_message(id, 1, "%s %s", gHeroName, mode ? "ADDED" : "DROPPED")
}
//----------------------------------------------------------------------------------------------
public sh_client_spawn(id)
{
gHooksLeft[id] = get_pcvar_num(pCvarMaxHooks)
if ( gHooked[id] ) spiderman_hook_off(id)
}
//----------------------------------------------------------------------------------------------
public sh_hero_key(id, heroID, key)
{
if ( gHeroID != heroID ) return
switch(key)
{
case SH_KEYDOWN: {
if ( sh_is_freezetime() || gHooked[id] || !is_user_alive(id) ) return
new hooksleft = gHooksLeft[id]
if ( hooksleft == 0 ) {
sh_sound_deny(id)
return
}
if ( hooksleft > 0 ) gHooksLeft[id] = --hooksleft
if ( -1 < hooksleft < 6 ) {
client_print(id, print_center, "[SH] %L", LANG_PLAYER, "SH_SPIDERMAN_YOU_LEFT", hooksleft, hooksleft == 1 ? "" : "s")
}
gHooked[id] = true
set_user_info(id, "ROPE", "1")
new parm[2], user_origin[3]
parm[0] = id
get_user_origin(id, user_origin)
//would a trace line be better?
get_user_origin(id, gHookLocation[id], 3)
gHookLength[id] = get_distance(gHookLocation[id], user_origin)
set_user_gravity(id, 0.001)
beamentpoint(id)
emit_sound(id, CHAN_STATIC, gSoundWeb, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
parm[1] = get_pcvar_num(pCvarHookStyle)
set_task(HOOK_DELTA_T, "spiderman_check_web", id, parm, 2, "b")
}
case SH_KEYUP: {
if ( gHooked[id] ) spiderman_hook_off(id)
}
}
}
//----------------------------------------------------------------------------------------------
public spiderman_check_web(parm[])
{
new id = parm[0]
//new style = parm[1]
switch(parm[1]) {
case 1: spiderman_physics(id, false)
case 2: spiderman_physics(id, true)
default: spiderman_cheapReel(id)
}
}
//----------------------------------------------------------------------------------------------
spiderman_physics(id, bool:autoReel)
{
if ( !gHooked[id] ) return
if ( !is_user_alive(id) ) {
spiderman_hook_off(id)
return
}
if ( gHookCreated[id] + HOOKBEAMLIFE/10 <= get_gametime() ) {
beamentpoint(id)
}
new user_origin[3], null[3], A[3], D[3], buttonadjust[3], buttonpress
new Float:vTowards_A, Float:DvTowards_A, Float:velocity[3]
get_user_origin(id, user_origin)
pev(id, pev_velocity, velocity)
buttonpress = pev(id, pev_button)
if ( buttonpress & IN_FORWARD ) ++buttonadjust[0]
if ( buttonpress & IN_BACK ) --buttonadjust[0]
if ( buttonpress & IN_MOVERIGHT ) ++buttonadjust[1]
if ( buttonpress & IN_MOVELEFT ) --buttonadjust[1]
if ( buttonpress & IN_JUMP ) ++buttonadjust[2]
if ( buttonpress & IN_DUCK ) --buttonadjust[2]
if ( buttonadjust[0] || buttonadjust[1] ) {
new user_look[3], move_direction[3]
get_user_origin(id, user_look, 2)
user_look[0] -= user_origin[0]
user_look[1] -= user_origin[1]
move_direction[0] = buttonadjust[0] * user_look[0] + user_look[1] * buttonadjust[1]
move_direction[1] = buttonadjust[0] * user_look[1] - user_look[0] * buttonadjust[1]
move_direction[2] = 0
new move_dist = get_distance(null, move_direction)
new Float:accel = get_pcvar_float(pCvarMoveAcc) * HOOK_DELTA_T
velocity[0] += move_direction[0] * accel / move_dist
velocity[1] += move_direction[1] * accel / move_dist
}
if ( buttonadjust[2] < 0 || (buttonadjust[2] && gHookLength[id] >= 60) ) {
gHookLength[id] -= floatround(buttonadjust[2] * get_pcvar_float(pCvarReelSpeed) * HOOK_DELTA_T)
}
else if ( autoReel && !(buttonpress&IN_DUCK) && gHookLength[id] >= 200) {
buttonadjust[2] += 1
gHookLength[id] -= floatround(buttonadjust[2] * get_pcvar_float(pCvarReelSpeed) * HOOK_DELTA_T)
}
A[0] = gHookLocation[id][0] - user_origin[0]
A[1] = gHookLocation[id][1] - user_origin[1]
A[2] = gHookLocation[id][2] - user_origin[2]
new distA = get_distance(null, A)
distA = distA ? distA : 1 // Avoid dividing by 0
vTowards_A = (velocity[0] * A[0] + velocity[1] * A[1] + velocity[2] * A[2]) / distA
DvTowards_A = float((get_distance(user_origin, gHookLocation[id]) - gHookLength[id]) * 4)
D[0] = A[0]*A[2] / distA
D[1] = A[1]*A[2] / distA
D[2] = -(A[1]*A[1] + A[0]*A[0]) / distA
new distD = get_distance(null, D)
if ( distD > 10 ) {
new Float:acceleration = ((-get_pcvar_num(pCvarSvGravity)) * D[2] / distD) * HOOK_DELTA_T
velocity[0] += (acceleration * D[0]) / distD
velocity[1] += (acceleration * D[1]) / distD
velocity[2] += (acceleration * D[2]) / distD
}
new Float:difference = DvTowards_A - vTowards_A
velocity[0] += (difference * A[0]) / distA
velocity[1] += (difference * A[1]) / distA
velocity[2] += (difference * A[2]) / distA
set_pev(id, pev_velocity, velocity)
}
//----------------------------------------------------------------------------------------------
spiderman_cheapReel(id)
{
// Cheat Web - just drags you where you shoot it...
if ( !gHooked[id] ) return
if ( !is_user_alive(id) ) {
spiderman_hook_off(id)
return
}
new user_origin[3]
new Float:velocity[3]
get_user_origin(id, user_origin)
new distance = get_distance(gHookLocation[id], user_origin)
if ( distance > 60 ) {
new Float:inverseTime = get_pcvar_float(pCvarReelSpeed) / distance
velocity[0] = (gHookLocation[id][0] - user_origin[0]) * inverseTime
velocity[1] = (gHookLocation[id][1] - user_origin[1]) * inverseTime
velocity[2] = (gHookLocation[id][2] - user_origin[2]) * inverseTime
}
set_pev(id, pev_velocity, velocity)
}
//----------------------------------------------------------------------------------------------
spiderman_hook_off(id)
{
gHooked[id] = false
set_user_info(id, "ROPE", "0")
killbeam(id)
if ( is_user_connected(id) ) sh_reset_min_gravity(id)
remove_task(id)
}
//----------------------------------------------------------------------------------------------
beamentpoint(id)
{
if ( !is_user_connected(id) ) return
new rgb[3] = {250, 250, 250}
if ( get_pcvar_num(pCvarTeamColored) )
{
switch(cs_get_user_team(id))
{
case CS_TEAM_T: rgb = {255, 0, 0}
case CS_TEAM_CT: rgb = {0, 0, 255}
}
}
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BEAMENTPOINT)
write_short(id)
write_coord(gHookLocation[id][0])
write_coord(gHookLocation[id][1])
write_coord(gHookLocation[id][2])
write_short(gSpriteWeb) // sprite index
write_byte(0) // start frame
write_byte(0) // framerate
write_byte(HOOKBEAMLIFE)// life
write_byte(10) // width
write_byte(0) // noise
write_byte(rgb[0]) // r, g, b
write_byte(rgb[1]) // r, g, b
write_byte(rgb[2]) // r, g, b
write_byte(150) // brightness
write_byte(0) // speed
message_end()
gHookCreated[id] = get_gametime()
}
//----------------------------------------------------------------------------------------------
killbeam(id)
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_KILLBEAM)
write_short(id)
message_end()
}
//----------------------------------------------------------------------------------------------
public sh_client_death(victim)
{
if ( victim < 1 || victim > sh_maxplayers() ) return
if ( gHooked[victim] ) spiderman_hook_off(victim)
}
//----------------------------------------------------------------------------------------------
public client_disconnected(id)
{
// stupid check but lets see
if ( id < 1 || id > sh_maxplayers() ) return
// Yeah don't want any left over residuals
remove_task(id)
}
//----------------------------------------------------------------------------------------------