[sprite] Что выбрать?

Сообщения
775
Реакции
292
Помог
11 раз(а)
Всем салют. Возник вопрос, что лучше выбрать?

Есть плагин - Bomb Site Helper
Его суть это показывать где находится бомбплейс.
1659362670668.png
И есть плугин [CSO] SupplyBox by Opo4

Там показывает спрайт нахождения презента

1659362866167.png
1659362893864.png

Конечно второй вариант смотрится бомбовски. Первый сделан через PreThink второй через AddToFullPack.
И так, суть вопроса в том, какой метод выбрать или есть метод лучше? (Нужен именно спрайт, который будет показывать место объекта (объект может быть не статичным))

Код:
#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <xs>
#include <csx>
#include <reapi>

#define PLUGIN    "Bombsite Helper"
#define AUTHOR    "kiki - hlmod.hu"
#define VERSION    "1.3"

new Float:g_locations[MAX_PLAYERS+1][3]
new const g_sprite1[] = "sprites/bombsite/bomba.spr";
new const g_sprite2[] = "sprites/laserbeam.spr"
new g_line, g_iconid, g_maxplayers, g_bombsitenum, g_hostagepos, g_hostagek, g_bombplanted, g_userteam;
new r,g,b, helpt, type;

new bool:is_help_sprite[33], bool:is_help_line[33], bool:is_help_radar[33];

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR)

    register_clcmd("say /bsh", "bsh_menu");
    register_clcmd("say_team /bsh", "bsh_menu");
    
    r = register_cvar("bsh_line_red", "0");
    g = register_cvar("bsh_line_green", "255");
    b = register_cvar("bsh_line_blue", "0");
    
    g_hostagepos = get_user_msgid("HostagePos")
    g_hostagek = get_user_msgid("HostageK")
    g_maxplayers = get_maxplayers()
    
    register_event("HLTV", "event_new_round", "a", "1=0", "2=0")
    register_forward(FM_PlayerPreThink,"PreThink");
    // RegisterHookChain(RG_CBasePlayer_TakeDamage, "TakeDamage", .post = true);
    RegisterHookChain(RG_CBasePlayer_Killed, "CBasePlayer_Killed", .post = false)
}

public plugin_precache()
{   
    g_iconid = precache_model(g_sprite1)
    g_line = precache_model(g_sprite2);
}


public event_new_round()
{
    g_bombplanted = false
}

public bomb_planted(planter)
{
    g_bombplanted = true
}

// public TakeDamage(const pevVictim, pevInflictor, pevAttacker, Float:flDamage, bitsDamageType)
// {
    // if(!is_user_connected(pevVictim) || !is_user_connected(pevAttacker)) return   
    
// }
public CBasePlayer_Killed(const pPlayer, const pevAttacker, const iGib)
{
    if (!is_user_connected(pPlayer))
        return
    
    if(get_entvar(pPlayer, var_deadflag) == DEAD_DYING)
    {
        set_task(2.3,"radar",_,_,_,"b")
        set_task(0.1,"task",_,_,_,"b")
        g_locations[pPlayer]
    }
}


public task()
{
    new Players[32]
    new playerCount, i, player
    get_players(Players, playerCount, "ach")
    for (i=0; i<playerCount; i++)
    {
        player = Players[i]
        if(is_help_line[player])
        {   
            new orig[3];
            get_user_origin(player, orig, 0)
            for(new i = 1; i < MaxClients; i++)
            {
                make_line(player,orig,g_locations[i],55)
            }
        }
    }
}

public PreThink(id)
{
    if(is_help_sprite[id])
    {   
        for(new i = 0; i < g_bombsitenum; i++)
        {
            create_icon_origin(id, g_locations[i], g_iconid)
        }
    }
}

public radar()
{
    for (new id=1;id<=g_maxplayers;id++)
    {
        if (is_user_alive(id) && (is_help_radar[id]))
        {
            g_userteam = get_user_team(id)   
            if(g_userteam==2 || (g_userteam==1 && !g_bombplanted))
            {
                for(new i=0;i<g_bombsitenum;i++)
                { 
                    message_begin(MSG_ONE_UNRELIABLE, g_hostagepos, {0,0,0}, id)
                    write_byte(id)
                    write_byte(i+20)
                    write_coord(floatround(g_locations[i][0]))
                    write_coord(floatround(g_locations[i][1]))
                    write_coord(floatround(g_locations[i][2]))
                    message_end()
                    
                    message_begin(MSG_ONE_UNRELIABLE, g_hostagek, {0,0,0}, id)
                    write_byte(i+20)
                    message_end()
                }
            }
        }
    }
}

public make_line(id,start[3],Float:end[3],brightness){
    message_begin(MSG_ONE_UNRELIABLE ,SVC_TEMPENTITY,{0,0,0},id) //message begin
    write_byte(0)
    write_coord(start[0]) // start position
    write_coord(start[1])
    write_coord(start[2])
    write_coord(floatround(end[0])) // end position
    write_coord(floatround(end[1]))
    write_coord(floatround(end[2]))
    write_short(g_line) // sprite index
    write_byte(3) // starting frame
    write_byte(0) // frame rate in 0.1's
    write_byte(1) // life in 0.1's
    write_byte(10) // line width in 0.1's
    write_byte(0) // noise amplitude in 0.01's
    write_byte(get_pcvar_num(r))
    write_byte(get_pcvar_num(g))
    write_byte(get_pcvar_num(b))
    write_byte(brightness) // brightness)
    write_byte(0) // scroll speed in 0.1's
    message_end()
}

create_icon_origin(id, Float:origin[3], sprite)
{
    new Float:fMyOrigin[3]
    entity_get_vector(id, EV_VEC_origin, fMyOrigin)
    
    new Float:fTargetOrigin[3]
    fTargetOrigin = origin
    fTargetOrigin[2] += 40.0
    
    if (!is_in_viewcone(id, fTargetOrigin)) return;
    
    new Float:fMiddle[3], Float:fHitPoint[3]
    xs_vec_sub(fTargetOrigin, fMyOrigin, fMiddle)
    trace_line(-1, fMyOrigin, fTargetOrigin, fHitPoint)
    
    new Float:fWallOffset[3], Float:fDistanceToWall
    fDistanceToWall = vector_distance(fMyOrigin, fHitPoint) - 10.0
    normalize(fMiddle, fWallOffset, fDistanceToWall)
    
    new Float:fSpriteOffset[3]
    xs_vec_add(fWallOffset, fMyOrigin, fSpriteOffset)
    new Float:fScale
    fScale = 0.01 * fDistanceToWall
    
    new scale = floatround(fScale)
    
    te_sprite(id, fSpriteOffset, sprite, scale, 255)
}

te_sprite(id, Float:origin[3], sprite, scale, brightness) // By sontung0
{   
    message_begin(MSG_ONE, SVC_TEMPENTITY, _, id)
    write_byte(TE_SPRITE)
    write_coord(floatround(origin[0]))
    write_coord(floatround(origin[1]))
    write_coord(floatround(origin[2]))
    write_short(sprite)
    write_byte(scale)
    write_byte(brightness)
    message_end()
}

normalize(Float:fIn[3], Float:fOut[3], Float:fMul) // By sontung0
{
    new Float:fLen = xs_vec_len(fIn)
    xs_vec_copy(fIn, fOut)
    
    fOut[0] /= fLen, fOut[1] /= fLen, fOut[2] /= fLen
    fOut[0] *= fMul, fOut[1] *= fMul, fOut[2] *= fMul
}
Код:
#include <amxmisc>
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <engine>
#include <xs>
#include <fun>
#include <zombieplague>

#define    MAX_ITEMS_MAP 64
#define MAX_SPAWN_ROUND 3
#define write_coord_f(%1)    engfunc(EngFunc_WriteCoord, %1)

#define SPRITE

//
#if defined SPRITE
#define METR_UNITS 39.37

#define Z_AXIS 35.0

#define MIN_SCALE 0.5
#define MIN_SCALE_F 0.5
#define MAX_SCALE 0.5
#endif

//

new g_total_supplyboxes
new Float:g_spawns[MAX_ITEMS_MAP][3]
new g_total_spawned
new g_spawned[MAX_ITEMS_MAP]
new g_entity_box[1025]

new g_mapfile[64]
new const g_model_box[] = "models/presents/presents_cso.mdl"
new const g_sound_spawn[] = "supplyboxes/presents_respawn.wav"
new const g_sound_get[] = "supplyboxes/presents_get.wav"

new cvar_presents_max

public plugin_precache()
{
    precache_model(g_model_box)
    precache_sound(g_sound_spawn)
    precache_sound(g_sound_get)
    #if defined SPRITE
    precache_model("sprites/supl_new.spr")
    #endif
}

public plugin_init()
{
    register_plugin("[ZP] Addon: Presents", "1.0", "Opo4uMapy")

    register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
    
    register_forward(FM_Touch, "fw_TouchSupplybox")
    #if defined SPRITE
    register_forward(FM_AddToFullPack, "fm_fullpack", 1)
    register_forward(FM_CheckVisibility, "check_visible")
    #endif

    cvar_presents_max = register_cvar("zp_presents_max", "20")
    //cvar_presents_time = register_cvar("zp_presents_respawn", "60.0")
}


public check_visible(ent, pSet)
{
    if(!pev_valid(ent))
    return FMRES_IGNORED
    
    static classname[32]
    pev(ent, pev_classname, classname, 31)
    
    if(!equal(classname, "spritebox"))
    return FMRES_IGNORED
    
    forward_return(FMV_CELL, 1)
    
    return FMRES_SUPERCEDE
    
}
#if defined SPRITE
public fm_fullpack(es, e, ent, host, hostflags, player, pSet)
{
    if(!is_user_connected(host))
        return FMRES_IGNORED

    if(!is_user_alive(host))
        return FMRES_IGNORED
    
    if(!pev_valid(ent))
        return FMRES_IGNORED
    
    static classname[32]
    pev(ent, pev_classname, classname, 31)
    
    if(!equal(classname, "spritebox"))
        return FMRES_IGNORED

    if(!pev_valid(ent))
        return FMRES_IGNORED

    if(!is_user_alive(host) || zp_get_user_zombie(host) || zp_get_user_nemesis(host) || zp_get_user_survivor(host))
    {
        set_es(es, ES_Effects, get_es(es, ES_Effects) | EF_NODRAW)
    }
    else if(is_user_alive(host) && !zp_get_user_zombie(host) && !zp_get_user_nemesis(host) && !zp_get_user_survivor(host))
    {
        set_es(es, ES_Effects, get_es(es, ES_Effects) & ~EF_NODRAW)
    }

    static ptr
    
    ptr = create_tr2()
    static Float:start[3], Float:end[3], Float:fVecEnd[3], Float:vNormal[3]
    
    pev(host, pev_origin, start)
    pev(ent, pev_origin, end)
    
    engfunc(EngFunc_TraceLine, start, end, IGNORE_MONSTERS, ent, ptr)
    new Float:fFraction;
    get_tr2(ptr, TR_flFraction, fFraction);       

    get_tr2(ptr, TR_vecEndPos, fVecEnd)
    get_tr2(ptr, TR_vecPlaneNormal, vNormal)

    xs_vec_mul_scalar(vNormal, 7.0, vNormal)

    xs_vec_add(fVecEnd, vNormal, vNormal)
    
    set_es(es, ES_Origin, vNormal)
    new Float:dist, Float:scale
    
    pev(ent, pev_origin, start)
    pev(host, pev_origin, end)
    dist = get_distance_f(start, end)

    if(dist<=METR_UNITS*100.0 && pev_valid(pev(ent, pev_iuser1)))
    {
        if(dist > 1.0) set_es(es, ES_Frame, float(101 - floatround(dist/METR_UNITS)) )
        else set_es(es, ES_Frame, 0.0 )

        dist = get_distance_f(fVecEnd, end)
        scale = 10.0 / dist
    
        if(scale > MAX_SCALE)    // Max Scale
        scale = MAX_SCALE

        if(fFraction != 1.0) {   
            if(scale < MIN_SCALE_F)    // Min Scale
            scale = MIN_SCALE_F
        }
        else {
            if(scale < MIN_SCALE)    // Min Scale
            scale = MIN_SCALE
        }
        
        set_es(es, ES_Scale, scale)
    }
    else
    {
        set_es(es, ES_Effects, get_es(es, ES_Effects) | EF_NODRAW)
        remove_entity(ent)
    }
    
    free_tr2(ptr)
    
    return FMRES_IGNORED
    
}
#endif
public supl() spawn_supplybox()


public plugin_cfg()
{
    new g_map[32]
    get_mapname(g_map, charsmax(g_map))
    formatex(g_mapfile, charsmax(g_mapfile), "addons/amxmodx/configs/supplyboxes/%s.cfg", g_map)
    load_spawns()
}

public event_round_start()
{
    g_total_spawned = 0
    static entity; entity = -1
    while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", "supplybox")))
    {
        engfunc(EngFunc_RemoveEntity, entity)
        g_spawned[g_entity_box[entity]] = false
    }
}

public spawn_supplybox()
{
        if (!g_total_supplyboxes)
                return

        new i[MAX_SPAWN_ROUND + 1]
        static j, q, b
        b = 0
        j = random_num(1, MAX_SPAWN_ROUND)

        for(q = 1; q <= j; q++)
        {
                i[q] = random_num(0, g_total_supplyboxes)

                while(g_spawned[i[q]])
                {
                        b++
                        if (b >= 100)
                                return

                        i[q] = random_num(0, g_total_supplyboxes - 1)

                }

                static s
                s = 0

                if(g_total_spawned == get_pcvar_num(cvar_presents_max))
                {
                        static entity; entity = -1
                        while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", "supplybox")) && !s)
                        {
                                engfunc(EngFunc_RemoveEntity, entity)
                                g_spawned[g_entity_box[entity]] = false
                                s = 1
                                g_total_spawned--
                        }
                }

                place_box(i[q])
                g_total_spawned++
        }
        for(q = 1; q <= 32; q++)
        {
                if(is_user_connected(q))
                {
                        client_cmd(q, "spk sound/%s", g_sound_spawn)
                        client_print(q, print_center, "Подарки доставлены!", q)
                }
        }
}

public place_box(supplybox)
{
    static entity; entity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
    
    set_pev(entity, pev_classname, "supplybox")
    set_pev(entity, pev_origin, g_spawns[supplybox])

    engfunc(EngFunc_SetModel, entity, g_model_box)
    set_pev(entity, pev_body, random_num(1, 2))

    set_pev(entity, pev_mins, Float:{-10.0,-10.0,0.0})
    set_pev(entity, pev_maxs, Float:{10.0,10.0,25.0})
    set_pev(entity, pev_size, Float:{-10.0,-10.0,0.0,10.0,10.0,25.0})
    engfunc(EngFunc_SetSize, entity, Float:{-10.0,-10.0,0.0}, Float:{10.0,10.0,25.0})

    set_pev(entity, pev_solid, SOLID_TRIGGER)
    set_pev(entity, pev_movetype, MOVETYPE_NOCLIP)
    drop_to_floor( entity )
    g_entity_box[entity] = supplybox
    g_spawned[supplybox] = true

    #if defined SPRITE
    spawn_sprite(entity)
    #endif

}
#if defined SPRITE
public spawn_sprite(id)
{
    static ent, Float:orig[3]

    pev(id, pev_origin, orig)

    ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))

    if(!pev_valid(ent))
        return

    orig[2] += Z_AXIS

    set_pev(ent, pev_classname, "spritebox")
    set_pev(ent, pev_origin, orig)
    set_pev(id, pev_iuser1, ent)
    set_pev(ent, pev_iuser1, id)

    engfunc(EngFunc_SetModel, ent, "sprites/supl_new.spr")
    fm_set_rendering(ent, kRenderFxNone, 0, 0, 0, kRenderTransAdd, 240)
    set_pev(ent, pev_solid, SOLID_NOT)
    set_pev(ent, pev_movetype, MOVETYPE_NONE)
    
}
#endif

public fw_TouchSupplybox(entity, id)
{
    if(!pev_valid(entity))
        return HAM_IGNORED
    
    if(!is_user_alive(id) || zp_get_user_zombie(id) || zp_get_user_survivor(id))
        return HAM_IGNORED
    
    static classname[64]
    pev(entity, pev_classname, classname, charsmax(classname))
    
    if(!equal(classname, "supplybox"))
        return HAM_IGNORED
    
    give_present(id)
    engfunc(EngFunc_RemoveEntity, entity)
    g_spawned[g_entity_box[entity]] = false
    g_total_spawned--
    engfunc(EngFunc_EmitSound, id, CHAN_ITEM, g_sound_get, 1.0, ATTN_NORM, 0, PITCH_NORM)
    static g_name[64]
    get_user_name(id, g_name, charsmax(g_name))
    static i
    for(i = 1; i <= 32; i++)
    {
        if(is_user_connected(i))
        {
            client_print(i, print_center, "Игрок %s нашел подарок!", g_name, i)
        }
    }

    return HAM_IGNORED
}

public give_present(id)
{
    switch (random_num(0, 1))    // Кейсы от 0 до 1. Если призов больше пишем к примеру от 0 до 2 и т.д
    {
        case 0:
        {
            zp_force_buy_extra_item(id, zp_get_extra_item_id("Dual Infinity Final"), 1)
        }
        case 1:
        {
            zp_force_buy_extra_item(id, zp_get_extra_item_id("Skull-1"), 1)
        }
    }
}

public zp_round_started()
{
    set_task(40.0, "spawn_supplybox", _, _, _, "b")
}

public zp_round_ended()
{
    remove_task()
}

stock load_spawns()
{
    g_total_supplyboxes = 0
    if (file_exists(g_mapfile))
    {
        static supdata[3][6], file, linedata[128];file = fopen(g_mapfile,"rt")
        
        while (file && !feof(file))
        {
            fgets(file, linedata, charsmax(linedata))
            
            if(!linedata[0] || str_count(linedata,' ') < 2) continue
            
            parse(linedata,supdata[0],5,supdata[1],5,supdata[2],5)

            g_spawns[g_total_supplyboxes][0] = floatstr(supdata[0])
            g_spawns[g_total_supplyboxes][1] = floatstr(supdata[1])
            g_spawns[g_total_supplyboxes][2] = floatstr(supdata[2])
            
            place_box(g_total_supplyboxes)
            
            g_total_supplyboxes++
        }
        if (file) fclose(file)
    }
}

stock normalize(Float:fIn[3], Float:fOut[3], Float:fMul)
{
    static Float:fLen;fLen = xs_vec_len(fIn)
    xs_vec_copy(fIn, fOut)
    
    fOut[0] /= fLen, fOut[1] /= fLen, fOut[2] /= fLen
    fOut[0] *= fMul, fOut[1] *= fMul, fOut[2] *= fMul
}

stock str_count(const str[], searchchar)
{
    new count, i, len = strlen(str)
    
    for (i = 0; i <= len; i++)
    {
        if(str[i] == searchchar)
            count++
    }
    
    return count;
}

stock bool:fm_is_in_viewcone(index, const Float:point[3])
{
    new Float:angles[3];
    pev(index, pev_angles, angles);
    engfunc(EngFunc_MakeVectors, angles);
    global_get(glb_v_forward, angles);
    angles[2] = 0.0;

    new Float:origin[3], Float:diff[3], Float:norm[3];
    pev(index, pev_origin, origin);
    xs_vec_sub(point, origin, diff);
    diff[2] = 0.0;
    xs_vec_normalize(diff, norm);

    new Float:dot, Float:fov;
    dot = xs_vec_dot(norm, angles);
    pev(index, pev_fov, fov);
    if (dot >= floatcos(fov * M_PI / 360))
        return true;

    return false;
}

stock fm_trace_line(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3])
{
    engfunc(EngFunc_TraceLine, start, end, ignoreent == -1 ? 1 : 0, ignoreent, 0);

    new ent = get_tr2(0, TR_pHit);
    get_tr2(0, TR_vecEndPos, ret);

    return pev_valid(ent) ? ent : 0;
}


stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
{
    new Float:RenderColor[3]
    RenderColor[0] = float(r)
    RenderColor[1] = float(g)
    RenderColor[2] = float(b)

    set_pev(entity, pev_renderfx, fx)
    set_pev(entity, pev_rendercolor, RenderColor)
    set_pev(entity, pev_rendermode, render)
    set_pev(entity, pev_renderamt, float(amount))

    return 1
}
 

Download all Attachments

Сообщения
494
Реакции
340
Помог
11 раз(а)
Через fullpack визуальная составляющая в разы лучше, собственно, как и количество вызовов этого хука в отличие от think'a.
Хотя сам код второго варианта неплохо было бы актуализировать под современные реалии.
Ну а если боишься прироста загруженности ЦП в парочку процентов - используй первый вариант.
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу