#include <amxmodx>
#include <cstrike>
#include <fakemeta_util>
#define MAX_PLAYERS 32
#define TASKID_REVIVE 1337
#define TASKID_RESPAWN 1338
#define TASKID_CHECKRE 1339
#define TASKID_CHECKST 13310
#define TASKID_ORIGIN 13311
#define TASKID_SETUSER 13312
#define pev_zorigin pev_fuser4
#define seconds(%1) ((1<<12) * (%1))
new SOUND_START[] = "items/medshot4.wav"
new SOUND_FINISHED[] = "items/smallmedkit2.wav"
new SOUND_FAILED[] = "items/medshotno1.wav"
new SOUND_EQUIP[] = "items/ammopickup2.wav"
enum
{
ICON_HIDE = 0,
ICON_SHOW,
ICON_FLASH
}
new bool:g_haskit[MAX_PLAYERS+1]
new Float:g_revive_delay[MAX_PLAYERS+1]
new Float:g_body_origin[MAX_PLAYERS+1][3]
new bool:g_wasducking[MAX_PLAYERS+1]
new g_msg_bartime
new g_msg_screenfade
new g_msg_statusicon
new g_msg_clcorpse
new cvar_revival_time
new cvar_revival_health
new cvar_revival_dis
new cvar_revival_cost
static const PLUGIN_NAME[] = "Revival Kit"
static const PLUGIN_AUTHOR[] = "Cheap_Suit"
static const PLUGIN_VERSION[] = "1.1"
public plugin_init()
{
register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
register_cvar(PLUGIN_NAME, PLUGIN_VERSION, FCVAR_SPONLY|FCVAR_SERVER)
register_clcmd("say /oye", "cmd_buyrkit")
register_clcmd("fuhuo", "cmd_buyrkit")
cvar_revival_time = register_cvar("amx_revkit_time", "6")
cvar_revival_health = register_cvar("amx_revkit_health", "75")
cvar_revival_dis = register_cvar("amx_revkit_distance", "70.0")
cvar_revival_cost = register_cvar("amx_revkit_cost", "1200")
g_msg_bartime = get_user_msgid("BarTime")
g_msg_clcorpse = get_user_msgid("ClCorpse")
g_msg_screenfade= get_user_msgid("ScreenFade")
g_msg_statusicon= get_user_msgid("StatusIcon")
register_message(g_msg_clcorpse, "message_clcorpse")
register_event("DeathMsg", "event_death", "a")
register_event("HLTV", "event_hltv", "a", "1=0", "2=0")
register_forward(FM_Touch, "fwd_touch")
register_forward(FM_EmitSound, "fwd_emitsound")
register_forward(FM_PlayerPostThink, "fwd_playerpostthink")
}
public plugin_precache()
{
precache_model("models/player/arctic/arctic.mdl")
precache_model("models/player/terror/terror.mdl")
precache_model("models/player/leet/leet.mdl")
precache_model("models/player/guerilla/guerilla.mdl")
precache_model("models/player/gign/gign.mdl")
precache_model("models/player/sas/sas.mdl")
precache_model("models/player/gsg9/gsg9.mdl")
precache_model("models/player/urban/urban.mdl")
precache_model("models/player/vip/vip.mdl")
precache_model(MODEL_RKIT)
precache_sound(SOUND_START)
precache_sound(SOUND_FINISHED)
precache_sound(SOUND_FAILED)
precache_sound(SOUND_EQUIP)
}
public cmd_buyrkit(id)
{
if(!is_user_alive(id))
client_print(id, print_chat, "You need to be alive.")
else if(g_haskit[id])
client_print(id, print_chat, "You already have a revival kit.")
else if(!cs_get_user_buyzone(id))
client_print(id, print_chat, "You need to be in the buyzone.")
else if(cs_get_user_money(id) < get_pcvar_num(cvar_revival_cost))
client_print(id, print_chat, " 不的钱不足(Cost:$%d)", get_pcvar_num(cvar_revival_cost))
else
{
g_haskit[id] = true
cs_set_user_money(id, cs_get_user_money(id) - get_pcvar_num(cvar_revival_cost))
client_print(id, print_chat, " 你拥有了一个救命包 对准尸体按E键进行复活。")
client_cmd(id, "spk %s", SOUND_EQUIP)
}
return PLUGIN_HANDLED
}
public message_clcorpse()
return PLUGIN_HANDLED
public client_connect(id)
{
g_haskit[id] = false
reset_player(id)
}
public event_hltv()
{
fm_remove_entity_name("fake_corpse")
fm_remove_entity_name("revival_kit")
set_task(1.0, "task_botbuy")
static players[32], num
get_players(players, num, "a")
for(new i = 0; i < num; ++i)
reset_player(players)
}
public task_botbuy()
{
static players[32], num
get_players(players, num, "ad")
for(new i = 0; i < num; ++i) if(!g_haskit[players])
cmd_buyrkit(players)
}
public reset_player(id)
{
remove_task(TASKID_REVIVE + id)
remove_task(TASKID_RESPAWN + id)
remove_task(TASKID_CHECKRE + id)
remove_task(TASKID_CHECKST + id)
remove_task(TASKID_ORIGIN + id)
remove_task(TASKID_SETUSER + id)
msg_bartime(id, 0)
g_revive_delay[id] = 0.0
g_wasducking[id] = false
g_body_origin[id] = Float:{0.0, 0.0, 0.0}
}
public client_disconnect(id)
{
new ent
while((ent = fm_find_ent_by_owner(ent, "fake_corpse", id)) != 0)
fm_remove_entity(ent)
}
public fwd_touch(kit, id)
{
if(!fm_is_valid_ent(kit))
return FMRES_IGNORED
if(!is_user_alive(id) || g_haskit[id])
return FMRES_IGNORED
new classname[32]
pev(kit, pev_classname, classname, 31)
if(equal(classname, "revival_kit"))
{
fm_remove_entity(kit)
g_haskit[id] = true
client_cmd(id, "spk %s", SOUND_EQUIP)
}
return FMRES_IGNORED
}
public fwd_playerpostthink(id)
{
if(!is_user_connected(id) || !g_haskit[id])
return FMRES_IGNORED
if(!is_user_alive(id))
{
msg_statusicon(id, ICON_HIDE)
return FMRES_IGNORED
}
new body = find_dead_body(id)
if(fm_is_valid_ent(body))
{
new lucky_bastard = pev(body, pev_owner)
if(!is_user_connected(lucky_bastard))
return FMRES_IGNORED
new lb_team = get_user_team(lucky_bastard)
new rev_team = get_user_team(id)
if(lb_team == 1 || lb_team == 2 && lb_team == rev_team)
msg_statusicon(id, ICON_FLASH)
}
else
msg_statusicon(id, ICON_SHOW)
return FMRES_IGNORED
}
public event_death()
{
new id = read_data(2)
reset_player(id)
if(g_haskit[id])
{
g_haskit[id] = false
drop_kit(id)
}
static Float:minsize[3]
pev(id, pev_mins, minsize)
if(minsize[2] == -18.0)
g_wasducking[id] = true
else
g_wasducking[id] = false
set_task(0.5, "task_check_dead_flag", id)
}
public drop_kit(id)
{
new Float:velocity[3]
velocity_by_aim(id, 34, velocity)
new Float:origin[3]
pev(id, pev_origin, origin)
origin[0] += velocity[0]
origin[1] += velocity[1]
new kit = fm_create_entity("info_target")
if(fm_is_valid_ent(kit))
{
set_pev(kit, pev_classname, "revival_kit")
engfunc(EngFunc_SetModel, kit, MODEL_RKIT)
engfunc(EngFunc_SetOrigin, kit, origin)
engfunc(EngFunc_SetSize, kit, Float:{-2.5, -2.5, -1.5}, Float:{2.5, 2.5, 1.5})
set_pev(kit, pev_solid, SOLID_TRIGGER)
set_pev(kit, pev_movetype, MOVETYPE_TOSS)
}
return PLUGIN_CONTINUE
}
public task_check_dead_flag(id)
{
if(!is_user_connected(id))
return
if(pev(id, pev_deadflag) == DEAD_DEAD)
create_fake_corpse(id)
else
set_task(0.5, "task_check_dead_flag", id)
}
public create_fake_corpse(id)
{
set_pev(id, pev_effects, EF_NODRAW)
static model[32]
cs_get_user_model(id, model, 31)
static player_model[64]
format(player_model, 63, "models/player/%s/%s.mdl", model, model)
static Float: player_origin[3]
pev(id, pev_origin, player_origin)
static Float:mins[3]
mins[0] = -16.0
mins[1] = -16.0
mins[2] = -34.0
static Float:maxs[3]
maxs[0] = 16.0
maxs[1] = 16.0
maxs[2] = 34.0
if(g_wasducking[id])
{
mins[2] /= 2
maxs[2] /= 2
}
static Float:player_angles[3]
pev(id, pev_angles, player_angles)
player_angles[2] = 0.0
new sequence = pev(id, pev_sequence)
new ent = fm_create_entity("info_target")
if(ent)
{
set_pev(ent, pev_classname, "fake_corpse")
engfunc(EngFunc_SetModel, ent, player_model)
engfunc(EngFunc_SetOrigin, ent, player_origin)
engfunc(EngFunc_SetSize, ent, mins, maxs)
set_pev(ent, pev_solid, SOLID_TRIGGER)
set_pev(ent, pev_movetype, MOVETYPE_TOSS)
set_pev(ent, pev_owner, id)
set_pev(ent, pev_angles, player_angles)
set_pev(ent, pev_sequence, sequence)
set_pev(ent, pev_frame, 9999.9)
}
}
public fwd_emitsound(id, channel, sound[])
{
if(!is_user_alive(id) || !g_haskit[id])
return FMRES_IGNORED
if(!equali(sound, "common/wpn_denyselect.wav"))
return FMRES_IGNORED
if(task_exists(TASKID_REVIVE + id))
return FMRES_IGNORED
if(!(fm_get_user_button(id) & IN_USE))
return FMRES_IGNORED
new body = find_dead_body(id)
if(!fm_is_valid_ent(body))
return FMRES_IGNORED
new lucky_bastard = pev(body, pev_owner)
new lb_team = get_user_team(lucky_bastard)
new rev_team = get_user_team(id)
if(lb_team != 1 && lb_team != 2 || lb_team != rev_team)
return FMRES_IGNORED
static name[32]
get_user_name(lucky_bastard, name, 31)
client_print(id, print_chat, "Reviving %s", name)
new revivaltime = get_pcvar_num(cvar_revival_time)
msg_bartime(id, revivaltime)
new Float:gametime = get_gametime()
g_revive_delay[id] = gametime + float(revivaltime) - 0.01
emit_sound(id, CHAN_AUTO, SOUND_START, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
set_task(0.0, "task_revive", TASKID_REVIVE + id)
return FMRES_SUPERCEDE
}
public task_revive(taskid)
{
new id = taskid - TASKID_REVIVE
if(!is_user_alive(id))
{
failed_revive(id)
return FMRES_IGNORED
}
if(!(fm_get_user_button(id) & IN_USE))
{
failed_revive(id)
return FMRES_IGNORED
}
new body = find_dead_body(id)
if(!fm_is_valid_ent(body))
{
failed_revive(id)
return FMRES_IGNORED
}
new lucky_bastard = pev(body, pev_owner)
if(!is_user_connected(lucky_bastard))
{
failed_revive(id)
return FMRES_IGNORED
}
new lb_team = get_user_team(lucky_bastard)
new rev_team = get_user_team(id)
if(lb_team != 1 && lb_team != 2 || lb_team != rev_team)
{
failed_revive(id)
return FMRES_IGNORED
}
static Float:velocity[3]
pev(id, pev_velocity, velocity)
velocity[0] = 0.0
velocity[1] = 0.0
set_pev(id, pev_velocity, velocity)
new Float:gametime = get_gametime()
if(g_revive_delay[id] < gametime)
{
if(findemptyloc(body, 10.0))
{
fm_remove_entity(body)
emit_sound(id, CHAN_AUTO, SOUND_FINISHED, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
set_task(0.1, "task_respawn", TASKID_RESPAWN + lucky_bastard)
}
else
failed_revive(id)
}
else
set_task(0.1, "task_revive", TASKID_REVIVE + id)
return FMRES_IGNORED
}
public failed_revive(id)
{
msg_bartime(id, 0)
emit_sound(id, CHAN_AUTO, SOUND_FAILED, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
public task_origin(taskid)
{
new id = taskid - TASKID_ORIGIN
engfunc(EngFunc_SetOrigin, id, g_body_origin[id])
static Float:origin[3]
pev(id, pev_origin, origin)
set_pev(id, pev_zorigin, origin[2])
set_task(0.1, "task_stuck_check", TASKID_CHECKST + id)
}
stock find_dead_body(id)
{
static Float:origin[3]
pev(id, pev_origin, origin)
new ent
static classname[32]
while((ent = fm_find_ent_in_sphere(ent, origin, get_pcvar_float(cvar_revival_dis))) != 0)
{
pev(ent, pev_classname, classname, 31)
if(equali(classname, "fake_corpse") && fm_is_ent_visible(id, ent))
return ent
}
return 0
}
stock msg_bartime(id, seconds)
{
if(is_user_bot(id))
return
message_begin(MSG_ONE, g_msg_bartime, _, id)
write_byte(seconds)
write_byte(0)
message_end()
}
stock msg_statusicon(id, status)
{
if(is_user_bot(id))
return
message_begin(MSG_ONE, g_msg_statusicon, _, id)
write_byte(status)
write_string("rescue")
write_byte(0)
write_byte(160)
write_byte(0)
message_end()
}
public task_respawn(taskid)
{
new id = taskid - TASKID_RESPAWN
set_pev(id, pev_deadflag, DEAD_RESPAWNABLE)
dllfunc(DLLFunc_Spawn, id)
set_pev(id, pev_iuser1, 0)
set_task(0.1, "task_check_respawn", TASKID_CHECKRE + id)
}
public task_check_respawn(taskid)
{
new id = taskid - TASKID_CHECKRE
if(pev(id, pev_iuser1))
set_task(0.1, "task_respawn", TASKID_RESPAWN + id)
else
set_task(0.1, "task_origin", TASKID_ORIGIN + id)
}
public task_stuck_check(taskid)
{
new id = taskid - TASKID_CHECKST
static Float:origin[3]
pev(id, pev_origin, origin)
if(origin[2] == pev(id, pev_zorigin))
set_task(0.1, "task_respawn", TASKID_RESPAWN + id)
else
set_task(0.1, "task_setplayer", TASKID_SETUSER + id)
}
public task_setplayer(taskid)
{
new id = taskid - TASKID_SETUSER
fm_strip_user_weapons(id)
fm_give_item(id, "weapon_knife")
fm_set_user_health(id, get_pcvar_num(cvar_revival_health))
message_begin(MSG_ONE,g_msg_screenfade, _, id)
write_short(seconds(2))
write_short(seconds(2))
write_short( SF_FADE_IN + SF_FADE_ONLYONE ) //flags
write_byte(0)
write_byte(0)
write_byte(0)
write_byte(255)
message_end()
}
stock bool:findemptyloc(ent, Float:radius)
{
if(!fm_is_valid_ent(ent))
return false
static Float:origin[3]
pev(ent, pev_origin, origin)
origin[2] += 2.0
new owner = pev(ent, pev_owner)
new num = 0, bool:found = false
while(num <= 100)
{
if(is_hull_vacant(origin))
{
g_body_origin[owner][0] = origin[0]
g_body_origin[owner][1] = origin[1]
g_body_origin[owner][2] = origin[2]
found = true
break
}
else
{
origin[0] += random_float(-radius, radius)
origin[1] += random_float(-radius, radius)
origin[2] += random_float(-radius, radius)
num++
}
}
return found
}
stock bool:is_hull_vacant(const Float:origin[3])
{
new tr = 0
engfunc(EngFunc_TraceHull, origin, origin, 0, HULL_HUMAN, 0, tr)
if(!get_tr2(tr, TR_StartSolid) && !get_tr2(tr, TR_AllSolid) && get_tr2(tr, TR_InOpen))
return true
return false
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1033\\ f0\\ fs16 \n\\ par }
*/