AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   [Half-life] "Bodyque" entity (https://forums.alliedmods.net/showthread.php?t=118163)

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 
0SUCTION_SOUND_NUM; ++i)
        
precache_sound(SUCTION_FILE[i])
}

public 
plugin_init() {
    
register_plugin(PLUGIN_NAMEPLUGIN_VERSIONPLUGIN_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_NAMECVAR_TOTAL_JUICE_DEF)
    
g_pcvar_suction_amount register_cvar(CVAR_SUCTION_AMOUNT_NAMECVAR_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_FindEntityByStringent"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(idchannelsound[]) {
    if (!
id /*|| !equali(sound, USE_SOUND)*/ || !is_user_alive(id) || !(pev(idpev_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(idFORMULA_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"idparam2"b")

    return 
FMRES_SUPERCEDE
}

public 
task_drink_juice(param[2]) {
    new 
id param[0]
    new 
corpse param[1]

    if (
is_user_alive(id) && (pev(idpev_button) & IN_USE) && can_drink(idcorpse)) {
        new 
Float:health
        pev
(idpev_healthhealth)
        
suction_sound(id)
        new 
amount get_pcvar_num(g_pcvar_suction_amount)
        
set_pev(idpev_healthhealth amount)
        
g_juice[corpse] -= amount
    
}

    if (
g_msgid_bartime2)
        
msg_bartime2(id00)

    
remove_task(id)
}

can_drink(idcorpse 0) {
    new 
origin[3], Float:fcorpsepos[3]
    
get_user_origin(idorigin)
    for (new 
0<= MAX_PLAYERS; ++i) {
        new 
ent = -1
        ent 
engfunc(EngFunc_FindEntityByStringent"classname""bodyque")
        
//while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "bodyque")) != 0)
        //{
        
if(!pev_valid(ent))
            continue;
            
        if (
g_juice[ent] <= || get_distance(origing_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(idCHAN_AUTOSUCTION_FILE[random(SUCTION_SOUND_NUM)], VOL_NORMATTN_NORM0PITCH_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(indexpev_originorigin)
    
pev(indexpev_view_ofsview_ofs)
    
xs_vec_add(originview_ofseyespos)

    
engfunc(EngFunc_TraceLineeyespospoint0index)

    new 
Float:fraction
    global_get
(glb_trace_fractionfraction)
    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(indexFloat:vec_c[3]) {
    new 
Float:vec_a[3], Float:vec_b[3], viewend[3]
    new 
Float:origin[3], Float:view_ofs[3]
    
pev(indexpev_originorigin)
    
pev(indexpev_view_ofsview_ofs)
    
xs_vec_add(originview_ofsvec_a)

    
get_user_origin(indexviewend3)
    
fm_IVecFVec(viewendvec_b)

    new 
Float:get_distance_f(vec_bvec_c)
    new 
Float:get_distance_f(vec_avec_c)
    new 
Float:get_distance_f(vec_avec_b)

    return 
floatacos((b*c*a*a) / (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(indexpev_absminmins)
    
pev(indexpev_absmaxmaxs)

    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] = {0010}, 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 04; ++i) {
        
start[index[i]] = value[i]
        
dest[index[i]] = value[i]
        
engfunc(EngFunc_TraceLinestartdest0index)
        
global_get(glb_trace_endposend)
        if (
end[2] > ret)
            
ret end[2]
    }

    
ret mins[2] - ret

    
return ret ret 0.0
}

// used to indicate the amount of the corpse's sucked out juice
stock msg_bartime2(indexscalestart_percent) {
    
message_begin(MSG_ONEg_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.:(

Arkshine 02-08-2010 08:46

Re: [Half-life] "Bodyque" entity
 
And what is the problem exactly ? You throw a code and say it it fails, ok, but povide more informations.

Anggara_nothing 02-08-2010 08:50

Re: [Half-life] "Bodyque" entity
 
The problem is player can't eat dead body.
Press "e" (use) button and nothing happen. :(


All times are GMT -4. The time now is 07:19.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.