| Anggara_nothing |
02-08-2010 08:39 |
[Half-life] "Bodyque" entity
PHP Code:
#include <amxmodx> #include <fakemeta> #include <xs>
// plugin's main information #define PLUGIN_NAME "Juicy Corpse" #define PLUGIN_VERSION "0.3" #define PLUGIN_AUTHOR "VEN"
// OPTIONS BELOW
// max. allowed distance from a hungry person to a juicy corpse #define MAX_DISTANCE 70
// max. allowed angle difference between hungry person's view vector and corpse's position #define MAX_VIEWANGLE_DIFF 35
// suction time interval (float seconds) #define SUCTION_INTERVAL 1.0
// suction sound files, can be changed to the custom (will be precached) #define SUCTION_SOUND_NUM 7 new SUCTION_FILE[SUCTION_SOUND_NUM][] = { "barnacle/bcl_bite3.wav", "barnacle/bcl_chew1.wav", "barnacle/bcl_chew2.wav", "barnacle/bcl_chew3.wav", "bullchicken/bc_bite1.wav", "bullchicken/bc_bite2.wav", "bullchicken/bc_bite3.wav" }
// name of the CVAR which controls total amount of a corpse's juice #define CVAR_TOTAL_JUICE_NAME "jc_total_juice"
// default value of the "jc_total_juice" CVAR #define CVAR_TOTAL_JUICE_DEF "25"
// name of the CVAR which controls amount of restored health per suction #define CVAR_SUCTION_AMOUNT_NAME "jc_suction_amount"
// default value of the "jc_suction_amount" CVAR #define CVAR_SUCTION_AMOUNT_DEF "3"
// OPTIONS ABOVE
// calculates how much time required to suck out the full juice amount // parameter1: suction amount; parameter2: total juice #define FORMULA_TOTAL_SUCTION_TIME(%1,%2) floatround((SUCTION_INTERVAL / (%1)) * (%2))
// calculates the sucked out juice percent depending on the current juice amount // parameter1: juice amount; parameter2: total juice #define FORMULA_SUCKED_OUT_PERCENT(%1,%2) floatround((100.0 * ((%2) - (%1))) / (%2))
//#define fm_find_ent_by_class(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "classname", %2)
// few HLSDK constants #define IN_USE (1<<5) #define DEAD_DEAD 2
// use sound //new USE_SOUND[] = "common/wpn_denyselect.wav"
// used to retrieve corpse's position more accurately #define DEAD_FLAG_CHECK_INTERVAL 1.0 #define DEAD_FLAG_CHECK_MAX_TIME 3.0
#define MAX_PLAYERS 32 new g_origin[40][3] new g_juice[40]
new g_pcvar_total_juice new g_pcvar_suction_amount
new g_msgid_bartime2
// precaching suction sounds public plugin_precache() { for (new i = 0; i < SUCTION_SOUND_NUM; ++i) precache_sound(SUCTION_FILE[i]) }
public plugin_init() { register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
register_event("ResetHUD", "event_hud_reset", "be") register_event("DeathMsg", "event_death", "a") //set_msg_block(get_user_msgid("ClCorpse"),BLOCK_SET)
register_forward(FM_EmitSound, "forward_emit_sound")
g_pcvar_total_juice = register_cvar(CVAR_TOTAL_JUICE_NAME, CVAR_TOTAL_JUICE_DEF) g_pcvar_suction_amount = register_cvar(CVAR_SUCTION_AMOUNT_NAME, CVAR_SUCTION_AMOUNT_DEF)
g_msgid_bartime2 = get_user_msgid("BarTime2") }
/* *************************************************** Base **************************************************** */
public event_hud_reset(id) { g_juice[id] = 0 }
public event_death() { new id = read_data(2)
if (task_exists(id)) remove_task(id)
set_task(DEAD_FLAG_CHECK_INTERVAL, "task_dead_flag_check", id, _, _, "b") }
public client_disconnect(id) { g_juice[id] = 0
if (task_exists(id)) remove_task(id) }
public task_dead_flag_check(id) { new ent = -1 ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "bodyque") //if ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "bodyque")) != 0) //{ //if (++g_juice[ent] * DEAD_FLAG_CHECK_INTERVAL > DEAD_FLAG_CHECK_MAX_TIME) { //get_user_origin(id, g_origin[id]) if(!pev_valid(ent)) return; pev(ent,pev_origin,g_origin[ent]) client_print(id,print_console,"dead body x %d",g_origin[ent][0]) //set_pev(ent,pev_origin,g_origin[ent]) client_print(id,print_console,"dead body y %d",g_origin[ent][1]) client_print(id,print_console,"dead body z %d",g_origin[ent][2])
//new Float:mins[3] //pev(ent, pev_mins, mins) //g_origin[ent][2] = g_origin[ent][2] + 2 - floatround(fm_distance_to_foothold(ent) - mins[2]) g_juice[ent] = get_pcvar_num(g_pcvar_total_juice) remove_task(id) //} //} }
public forward_emit_sound(id, channel, sound[]) { if (!id /*|| !equali(sound, USE_SOUND)*/ || !is_user_alive(id) || !(pev(id, pev_button) & IN_USE) || task_exists(id)) return FMRES_IGNORED
new corpse = can_drink(id) if (!corpse) return FMRES_IGNORED
if (g_msgid_bartime2) { new total = get_pcvar_num(g_pcvar_total_juice) msg_bartime2(id, FORMULA_TOTAL_SUCTION_TIME(get_pcvar_num(g_pcvar_suction_amount), total), FORMULA_SUCKED_OUT_PERCENT(g_juice[corpse], total)) }
suction_sound(id)
new param[2] param[0] = id param[1] = corpse set_task(SUCTION_INTERVAL, "task_drink_juice", id, param, 2, "b")
return FMRES_SUPERCEDE }
public task_drink_juice(param[2]) { new id = param[0] new corpse = param[1]
if (is_user_alive(id) && (pev(id, pev_button) & IN_USE) && can_drink(id, corpse)) { new Float:health pev(id, pev_health, health) suction_sound(id) new amount = get_pcvar_num(g_pcvar_suction_amount) set_pev(id, pev_health, health + amount) g_juice[corpse] -= amount }
if (g_msgid_bartime2) msg_bartime2(id, 0, 0)
remove_task(id) }
can_drink(id, corpse = 0) { new origin[3], Float:fcorpsepos[3] get_user_origin(id, origin) for (new i = 0; i <= MAX_PLAYERS; ++i) { new ent = -1 ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "bodyque") //while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "bodyque")) != 0) //{ if(!pev_valid(ent)) continue; if (g_juice[ent] <= 0 || get_distance(origin, g_origin[ent]) > MAX_DISTANCE) continue fm_IVecFVec(g_origin[ent], fcorpsepos) //if (!fm_is_visible(id, fcorpsepos) || get_view_angle_diff(id, fcorpsepos) > MAX_VIEWANGLE_DIFF) // continue
if (!corpse || corpse != 0) return 1 //} }
return 0 }
suction_sound(id) { emit_sound(id, CHAN_AUTO, SUCTION_FILE[random(SUCTION_SOUND_NUM)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM) }
/* ************************************************** Stocks *************************************************** */
// copies integer vector to a float vector stock fm_IVecFVec(const IVec[3], Float:FVec[3]) { FVec[0] = float(IVec[0]) FVec[1] = float(IVec[1]) FVec[2] = float(IVec[2])
return 1 }
// check whether no obstacles between eyes and given point stock bool:fm_is_visible(index, const Float:point[3]) { new Float:origin[3], Float:view_ofs[3], Float:eyespos[3] pev(index, pev_origin, origin) pev(index, pev_view_ofs, view_ofs) xs_vec_add(origin, view_ofs, eyespos)
engfunc(EngFunc_TraceLine, eyespos, point, 0, index)
new Float:fraction global_get(glb_trace_fraction, fraction) if (fraction == 1.0) return true
return false }
// returns a float degree angle between view vector and given point stock Float:get_view_angle_diff(index, Float:vec_c[3]) { new Float:vec_a[3], Float:vec_b[3], viewend[3] new Float:origin[3], Float:view_ofs[3] pev(index, pev_origin, origin) pev(index, pev_view_ofs, view_ofs) xs_vec_add(origin, view_ofs, vec_a)
get_user_origin(index, viewend, 3) fm_IVecFVec(viewend, vec_b)
new Float:a = get_distance_f(vec_b, vec_c) new Float:b = get_distance_f(vec_a, vec_c) new Float:c = get_distance_f(vec_a, vec_b)
return floatacos((b*b + c*c - a*a) / (2 * b * c), _:degrees) }
// returns a float distance to the further/current foothold // will not work if all points of the further/current contact base's horizontal plane is fully projects to the player's feet base stock Float:fm_distance_to_foothold(index) { new Float:mins[3], Float:maxs[3] pev(index, pev_absmin, mins) pev(index, pev_absmax, maxs)
new Float:start[3] start[1] = mins[1] start[2] = mins[2] + 10
new Float:dest[3], Float:end[3] dest[1] = mins[1] dest[2] = -8191.0
new index[4] = {0, 0, 1, 0}, Float:value[4] value[0] = mins[0] value[1] = maxs[0] value[2] = maxs[1] value[3] = mins[0] new Float:ret = -8191.0
for (new i = 0; i < 4; ++i) { start[index[i]] = value[i] dest[index[i]] = value[i] engfunc(EngFunc_TraceLine, start, dest, 0, index) global_get(glb_trace_endpos, end) if (end[2] > ret) ret = end[2] }
ret = mins[2] - ret
return ret > 0 ? ret : 0.0 }
// used to indicate the amount of the corpse's sucked out juice stock msg_bartime2(index, scale, start_percent) { message_begin(MSG_ONE, g_msgid_bartime2, _, index) write_short(scale) write_short(start_percent) message_end() }
/* **************************************************** EOF **************************************************** */
I want player can eat dead body (bodyque entity), but i failed. :cry:
I need help.:(
|