Код
#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
#include <zombieplague>
#include <fun>
#include <xs>
#include <zp50_class_survivor>
#include <amx_settings_api>
#include <cs_ham_bots_api>
#include <zp50_core>
#define LIBRARY_NEMESIS "zp50_class_nemesis"
#include <zp50_class_nemesis>
#include <zp50_colorchat>
#include <zp50_class_zombie>
// Classic Zombie Attributes
new const zclass_name[] = { "Классик" }
new const zclass_info[] = { "Сбалансированный" }
new const zclass_model[] = { "classic" }
new const zclass_clawmodel[] = { "v_classic.mdl" }
const zclass_health = 6000
const zclass_speed = 240
const Float:zclass_gravity = 0.8
const Float:zclass_knockback = 1.80
new g_zclass_classic
// Settings file
new const ZP_SETTINGS_FILE[] = "zombie.ini"
new const sound_classic_burn[][] = { "burn/burn_011.wav" , "burn/burn_021.wav" }
#define SOUND_MAX_LENGTH 64
#define SPRITE_MAX_LENGTH 64
new Array:g_sound_classic_burn
// Explosion radius for custom grenades
const Float:NADE_EXPLOSION_RADIUS = 240.0
// HACK: pev_ field used to store custom nade types and their values
const PEV_NADE_TYPE = pev_flTimeStepSound
const NADE_TYPE_NAPALM = 2222
#define TASK_BURN 100
#define ID_BURN (taskid - TASK_BURN)
#define MAXPLAYERS 32
// Custom Forwards
enum _:TOTAL_FORWARDS
{
FW_USER_BURN_PRE = 0
}
new g_Forwards[TOTAL_FORWARDS]
new g_ForwardResult
new g_MsgDamage
new g_BurningDuration[MAXPLAYERS+1]
new g_flameSpr, g_smokeSpr
new cvar_grenade_fire_duration, cvar_grenade_fire_damage, cvar_grenade_fire_slowdown, cvar_grenade_fire_hudicon
new get_class_classic[33]
public plugin_precache()
{
g_zclass_classic = zp_register_zombie_class(zclass_name, zclass_info, zclass_model, zclass_clawmodel, zclass_health, zclass_speed, zclass_gravity, zclass_knockback)
g_sound_classic_burn = ArrayCreate(SOUND_MAX_LENGTH, 1)
amx_load_setting_string_arr(ZP_SETTINGS_FILE, "Sounds", "CLASSIC BURN", g_sound_classic_burn)
// If we couldn't load custom sounds from file, use and save default ones
new index
if (ArraySize(g_sound_classic_burn) == 0)
{
for (index = 0; index < sizeof sound_classic_burn; index++)
ArrayPushString(g_sound_classic_burn, sound_classic_burn[index])
// Save to external file
amx_save_setting_string_arr(ZP_SETTINGS_FILE, "Sounds", "CLASSIC BURN", g_sound_classic_burn)
}
// Precache sounds
new sound[SOUND_MAX_LENGTH]
for (index = 0; index < ArraySize(g_sound_classic_burn); index++)
{
ArrayGetString(g_sound_classic_burn, index, sound, charsmax(sound))
precache_sound(sound)
}
}
public plugin_init()
{
register_forward(FM_EmitSound, "fw_EmitSound")
RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
RegisterHamBots(Ham_Killed, "fw_PlayerKilled")
g_Forwards[FW_USER_BURN_PRE] = CreateMultiForward("zp_fw_grenade_fire_pre", ET_CONTINUE, FP_CELL)
}
public plugin_natives()
{
register_library("zp50_grenade_fire")
register_native("zp_grenade_fire_get", "native_grenade_fire_get")
register_native("zp_grenade_fire_set", "native_grenade_fire_set")
set_module_filter("module_filter")
set_native_filter("native_filter")
}
public native_grenade_fire_get(plugin_id, num_params)
{
new id = get_param(1)
if (!is_user_alive(id))
{
log_error(AMX_ERR_NATIVE, "[ZP] Invalid Player (%d)", id)
return false;
}
return task_exists(id+TASK_BURN);
}
public native_grenade_fire_set(plugin_id, num_params)
{
new id = get_param(1)
if (!is_user_alive(id))
{
log_error(AMX_ERR_NATIVE, "[ZP] Invalid Player (%d)", id)
return false;
}
new set = get_param(2)
// End fire
if (!set)
{
// Not burning
if (!task_exists(id+TASK_BURN))
return true;
// Get player origin
static origin[3]
get_user_origin(id, origin)
// Smoke sprite
message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
write_byte(TE_SMOKE) // TE id
write_coord(origin[0]) // x
write_coord(origin[1]) // y
write_coord(origin[2]-50) // z
write_short(g_smokeSpr) // sprite
write_byte(random_num(15, 20)) // scale
write_byte(random_num(10, 20)) // framerate
message_end()
// Task not needed anymore
remove_task(id+TASK_BURN)
return true;
}
// Set on fire
return set_on_fire(id);
}
public module_filter(const module[])
{
if (equal(module, LIBRARY_NEMESIS))
return PLUGIN_HANDLED;
return PLUGIN_CONTINUE;
}
public native_get_user_classic_class(id)
{
return get_class_classic[id];
return task_exists(id+TASK_BURN);
}
// Ham Player Killed Forward
public fw_PlayerKilled(victim, attacker, shouldgib)
{
// Stop burning
remove_task(victim+TASK_BURN)
g_BurningDuration[victim] = 0
}
public client_disconnect(id)
{
// Stop burning
remove_task(id+TASK_BURN)
g_BurningDuration[id] = 0
}
// Burning Flames
public burning_flame(taskid)
{
// Get player origin and flags
static origin[3]
get_user_origin(ID_BURN, origin)
new flags = pev(ID_BURN, pev_flags)
// In water or burning stopped
if ((flags & FL_INWATER) || g_BurningDuration[ID_BURN] < 1)
{
// Smoke sprite
message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
write_byte(TE_SMOKE) // TE id
write_coord(origin[0]) // x
write_coord(origin[1]) // y
write_coord(origin[2]-50) // z
write_short(g_smokeSpr) // sprite
write_byte(random_num(15, 20)) // scale
write_byte(random_num(10, 20)) // framerate
message_end()
// Task not needed anymore
remove_task(taskid)
return;
}
// Nemesis Class loaded?
if (!LibraryExists(LIBRARY_NEMESIS, LibType_Library) || !zp_class_nemesis_get(ID_BURN))
{
// Randomly play burning zombie scream sounds
if (random_num(1, 20) == 1)
{
static sound[SOUND_MAX_LENGTH]
ArrayGetString(g_sound_classic_burn, random_num(0, ArraySize(g_sound_classic_burn) - 1), sound, charsmax(sound))
emit_sound(ID_BURN, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
}
// Fire slow down
if ((flags & FL_ONGROUND) && get_pcvar_float(cvar_grenade_fire_slowdown) > 0.0)
{
static Float:velocity[3]
pev(ID_BURN, pev_velocity, velocity)
xs_vec_mul_scalar(velocity, get_pcvar_float(cvar_grenade_fire_slowdown), velocity)
set_pev(ID_BURN, pev_velocity, velocity)
}
}
// Get player's health
new health = get_user_health(ID_BURN)
// Take damage from the fire
if (health - floatround(get_pcvar_float(cvar_grenade_fire_damage), floatround_ceil) > 0)
set_user_health(ID_BURN, health - floatround(get_pcvar_float(cvar_grenade_fire_damage), floatround_ceil))
// Flame sprite
message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
write_byte(TE_SPRITE) // TE id
write_coord(origin[0]+random_num(-5, 5)) // x
write_coord(origin[1]+random_num(-5, 5)) // y
write_coord(origin[2]+random_num(-10, 10)) // z
write_short(g_flameSpr) // sprite
write_byte(random_num(5, 10)) // scale
write_byte(200) // brightness
message_end()
// Decrease burning duration counter
g_BurningDuration[ID_BURN]--
}
public zp_fw_core_infect_post(id, attacker)
{
remove_task(id+TASK_BURN)
// Nemesis Class loaded?
if (!LibraryExists(LIBRARY_NEMESIS, LibType_Library) || !zp_class_nemesis_get(id))
{
// Idle sounds?
if (zp_core_is_zombie(id) && zp_get_user_zombie_class(id) == g_zclass_classic)
{
set_task(0.2, "burning_flame", id+TASK_BURN, _, _, "b")
}
}
}
// Ham Grenade Think Forward
public fw_ThinkGrenade(entity)
{
// Invalid entity
if (!pev_valid(entity)) return HAM_IGNORED;
// Get damage time of grenade
static Float:dmgtime
pev(entity, pev_dmgtime, dmgtime)
// Check if it's time to go off
if (dmgtime > get_gametime())
return HAM_IGNORED;
// Not a napalm grenade
if (pev(entity, PEV_NADE_TYPE) != NADE_TYPE_NAPALM)
return HAM_IGNORED;
// Get rid of the grenade
engfunc(EngFunc_RemoveEntity, entity)
return HAM_SUPERCEDE;
}
set_on_fire(id)
{
// Allow other plugins to decide whether player should be burned or not
ExecuteForward(g_Forwards[FW_USER_BURN_PRE], g_ForwardResult, id)
if (g_ForwardResult >= PLUGIN_HANDLED)
return false;
// Heat icon?
if (get_pcvar_num(cvar_grenade_fire_hudicon))
{
message_begin(MSG_ONE_UNRELIABLE, g_MsgDamage, _, id)
write_byte(0) // damage save
write_byte(0) // damage take
write_long(DMG_BURN) // damage type
write_coord(0) // x
write_coord(0) // y
write_coord(0) // z
message_end()
}
// Reduced duration for Nemesis
if (LibraryExists(LIBRARY_NEMESIS, LibType_Library) && zp_class_nemesis_get(id))
{
// fire duration (nemesis)
g_BurningDuration[id] += get_pcvar_num(cvar_grenade_fire_duration)
}
else
{
// fire duration (zombie)
g_BurningDuration[id] += get_pcvar_num(cvar_grenade_fire_duration) * 5
}
// Set burning task on id
remove_task(id+TASK_BURN)
set_task(0.2, "burning_flame", id+TASK_BURN, _, _, "b")
return true;
}
public zp_fw_core_cure_post(id, attacker)
{
// Stop burning
remove_task(id+TASK_BURN)
g_BurningDuration[id] = 0
}