Код:
#include <amxmisc>
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <engine>
#include <xs>
#include <fun>
#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_logevent("event_round_start", 2, "1=Round_Start")
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("presents_max", "20")
//cvar_presents_time = register_cvar("presents_respawn", "40")
}
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))
{
set_es(es, ES_Effects, get_es(es, ES_Effects) | EF_NODRAW)
}
else if(is_user_alive(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
}
set_task(40.0, "spawn_supplybox", _, _, _, "b")
}
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
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:
{
client_cmd(id, "give_pkm")
}
case 1:
{
client_cmd(id, "give_pkm")
}
}
}
public 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®
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
}