Код
#include <amxmisc>
#include <amxmodx>
#include <fakemeta>
#include <zombieplague>
#include <hamsandwich>
#include <xs>
#include <fun>
#define MAX_ITEMS_MAP 64
#define MAX_SPAWN_ROUND 3
#define write_coord_f(%1) engfunc(EngFunc_WriteCoord, %1)
new g_total_supplyboxes
new Float:g_spawns[MAX_ITEMS_MAP][3]
new g_total_spawned
new g_spawned[MAX_ITEMS_MAP]
new sprite
new Float:g_delay[33]
new g_entity_box[1025]
new g_mapfile[64]
new const g_model_box[] = "models/w_1.mdl"
new const g_sound_spawn[] = "ZMDark/supplybox_resp.wav"
new const g_sound_get[] = "ZMDark/supplybox_dro.wav"
new cvar_time, cvar_max_boxes_round, cvar_updatedelay, cvar_maxdistance, cvar_scale, cvar_z
const KEYSMENU = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MEN
U_KEY_8|MENU_KEY_9|MENU_KEY_0
public plugin_precache()
{
register_plugin("[ZP] Supplyboxes", "1.0", "PomanoB & PRoSToTeM@")
precache_model(g_model_box)
precache_sound(g_sound_spawn)
precache_sound(g_sound_get)
sprite = precache_model("sprites/ZMDark/supl.spr")
}
public plugin_init()
{
register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
register_forward(FM_Touch, "fw_TouchSupplybox")
register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")
register_clcmd("say /menu", "show_menu_supplybox", ADMIN_CFG, " - display item's menu")
register_menu("Menu Place Supplybox", KEYSMENU, "menu_supplybox")
cvar_time = register_cvar("zp_sb_time", "10.0") //через сколько подарки будут возраждены
cvar_max_boxes_round = register_cvar("zp_sb_max_round", "11") //Сколько подарков может отображаться в раунде текущем
cvar_updatedelay = register_cvar("zp_sb_update_delay", "0.2") //Регулируйте значение мигания спрайт-эффекта
cvar_maxdistance = register_cvar("zp_sb_max_distance", "5000") //Думаю, понял
cvar_scale = register_cvar("zp_sb_scale", "0.001") //Масштаб спрайта или размер. Регулируйте во время игры
cvar_z = register_cvar("zp_sb_z", "30.0")
}
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)
}
static s
s = 0
if(g_total_spawned == get_pcvar_num(cvar_max_boxes_round))
{
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_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_TOSS)
g_entity_box[entity] = supplybox
g_spawned[supplybox] = true
}
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, 5))
{
case 0:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("\rСкилл-7"), 1)
}
case 1:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("\rАк-47 Драгон"), 1)
}
case 2:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("\rБазука"), 1)
}
case 3:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("\rCV-47"), 1)
}
case 4:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("Автомат Гитара"), 1)
}
case 5:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("\rКрасная машина"), 1)
}
case 6:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("\rQBB-95 автомат"), 1)
}
case 7:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("\rПулемет MG36"), 1)
}
case 8:
{
zp_force_buy_extra_item(id, zp_get_extra_item_id("\rKSG-12 дробовик"), 1)
}
case 9:
{
zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + 50)
}
case 10:
{
set_user_health(id, get_user_health(id) + 100)
}
case 11:
{
set_pev(id, pev_armorvalue, pev(id, pev_armorvalue) + 100.0)
}
}
}
public fw_PlayerPreThink(id)
{
if(!is_user_alive(id) || zp_get_user_zombie(id) || zp_get_user_survivor(id)) return
if((g_delay[id] + get_pcvar_float(cvar_updatedelay)) > get_gametime())
return
g_delay[id] = get_gametime()
static Float:user_origin[3]
pev(id, pev_origin, user_origin)
static entity; entity = -1
while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", "supplybox")))
{
static Float:entity_origin[3]
pev(entity, pev_origin, entity_origin)
entity_origin[2] += get_pcvar_float(cvar_z)
if((get_distance_f(user_origin, entity_origin) > get_pcvar_num(cvar_maxdistance))
|| !fm_is_in_viewcone(id, entity_origin))
continue
static Float:fMiddle[3], Float:fHitPoint[3]
xs_vec_sub(entity_origin, user_origin, fMiddle)
fm_trace_line(-1, user_origin, entity_origin, fHitPoint)
static Float:fWallOffset[3], Float:fDistanceToWall
fDistanceToWall = vector_distance(user_origin, fHitPoint) - 10.0
normalize(fMiddle, fWallOffset, fDistanceToWall)
static Float:fSpriteOffset[3]
xs_vec_add(fWallOffset, user_origin, fSpriteOffset)
message_begin(MSG_ONE, SVC_TEMPENTITY, _, id)
write_byte(TE_SPRITE)
write_coord_f(fSpriteOffset[0])
write_coord_f(fSpriteOffset[1])
write_coord_f(fSpriteOffset[2])
write_short(sprite)
write_byte(floatround(fDistanceToWall * get_pcvar_float(cvar_scale)))
write_byte(125)
message_end()
}
}
public show_menu_supplybox(id)
{
static menu[250]
formatex(menu, charsmax(menu), "\yМеню подарков^n^n\y1.\w Добавить подарок^n\y2.\r Удалить все подарки^n^n\y0.\w Выход")
show_menu(id, KEYSMENU, menu, -1, "Menu Place Supplybox")
}
public menu_supplybox(id, key)
{
switch (key)
{
case 0:
{
if (g_total_supplyboxes >= MAX_ITEMS_MAP)
client_print(id, print_chat, "Max Item's for Map!")
else
add_box(id)
}
case 1:
delete_all_boxes()
}
if (key == 0 || key == 1)
show_menu_supplybox(id)
return PLUGIN_HANDLED
}
public add_box(id)
{
static origin[3], Float:g_origin[3]
get_user_origin(id, origin, 3)
IVecFVec(origin, g_origin)
static file, buffer[128]; file = fopen(g_mapfile, "at")
formatex(buffer, charsmax(buffer), "%f %f %f^n", g_origin[0], g_origin[1], g_origin[2])
fputs(file, buffer)
g_spawns[g_total_supplyboxes][0] = g_origin[0]
g_spawns[g_total_supplyboxes][1] = g_origin[1]
g_spawns[g_total_supplyboxes][2] = g_origin[2]
fclose(file)
g_total_supplyboxes++
}
public delete_all_boxes()
{
g_total_supplyboxes = 0
static ent;ent = -1
while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "supplybox")))
{
engfunc(EngFunc_RemoveEntity, ent)
g_spawned[g_entity_box[ent]] = false
g_total_spawned--
}
delete_file(g_mapfile)
}
public zp_round_started()
{
set_task(get_pcvar_float(cvar_time), "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)
// origin
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;
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
*/