Код:
#include < amxmodx >
#include < amxmisc >
#include < cstrike >
#include < engine >
#include < fakemeta >
#include < fakemeta_util >
#include < dhudmessage >
#include < hamsandwich >
#include < fun >
#include < xs >
#define PLUGIN "Knife Mod"
#define VERSION "1.2"
#define AUTHOR "OverGame"
#define KNIFE_GRAVITY 0.05
#define KNIFE_SPEED 310.0
#define SEC_DMG 2.0
#define PRIM_DMG 4.0
#define SEC_HEAD_DMG 6.0
#define PRIM_HEAD_DMG 10.0
#define KNIFE_KNOCK 4
#define BLOOD 3
#define RUYI_DAMAGE_SLASH 100.0
#define RUYI_DAMAGE_STAB 150.0
#define RUYI_RANGE_SLASH 70.0
#define RUYI_RANGE_STAB 80.0
#define RUYI_NEXTATTACK_SLASH 0.3
#define RUYI_NEXTATTACK_STAB 1.7
#pragma tabsize 0
new const fPrefix[] = "\d[Knife Mod]\r"
new const cPrefix[] = "!g[!tKnife Mod!g]!y"
new gMsg[255], Knife[64], g_has_ruyi[33], g_attack_type[33], aKnife[64], gMaxHP
const OFFSET_WEAPONOWNER = 41
const OFFSET_LINUX_WEAPONS = 4
#define weapon_name "weapon_knife"
static const v_knife[] = "models/knf_mod/v_spknife.mdl"
static const p_knife[] = "models/knf_mod/p_spknife.mdl"
static const v_knife2[] = "models/knf_mod/v_ruyi-stick.mdl"
static const p_knife2[] = "models/knf_mod/p_ruyi-stick.mdl"
static const v_knife3[] = "models/knf_mod/v_horseaxe.mdl"
static const p_knife3[] = "models/knf_mod/p_horseaxe.mdl"
static const SoundList[][] =
{
"knf_mod/deploy1.wav", // 0
"knf_mod/spknife_wall.wav", // 1
"knf_mod/spknife_slasha1_1.wav", // 2
"knf_mod/stab.wav", // 3
"knf_mod/knife.wav", // 4
"knf_mod/knife1.wav" // 5
}
new const ruyi_sound[][] =
{
"weapons/ruyi-stick_draw.wav",
"weapons/ruyi-stick_hit1.wav",
"weapons/ruyi-stick_slash2.wav",
"weapons/ruyi-stick_hit2.wav",
"weapons/ruyi-stick_hit_wall.wav",
"weapons/ruyi-stick_idle.wav",
"weapons/ruyi-stick_stab.wav"
}
enum
{
KNIFE_ANIM_IDLE = 0,
KNIFE_ANIM_SLASH1,
KNIFE_ANIM_SLASH2,
KNIFE_ANIM_DRAW,
KNIFE_ANIM_STAB_HIT,
KNIFE_ANIM_STAB_MISS,
KNIFE_ANIM_MIDSLASH1,
KNIFE_ANIM_MIDSLASH2
}
enum
{
ATTACK_SLASH = 1,
ATTACK_STAB,
}
new const WEAPONENTNAMES[][] = { "", "weapon_p228", "", "weapon_scout", "weapon_hegrenade", "weapon_xm1014", "weapon_c4", "weapon_mac10", "weapon_aug", "weapon_smokegrenade", "weapon_elite", "weapon_fiveseven", "weapon_ump45", "weapon_sg550", "weapon_p228", "weapon_famas", "weapon_usp", "weapon_glock18", "weapon_awp", "weapon_mp5navy", "weapon_m249",
"weapon_m3", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "weapon_flashbang", "weapon_deagle", "weapon_sg552",
"weapon_ak47", "weapon_knife", "weapon_p90" }
static const Blood[][] =
{
"sprites/blood.spr",
"sprites/bloodspray.spr"
}
static g_Blood[sizeof Blood]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_clcmd("say /vip_knife", "knife_menu")
register_clcmd("say_team /vip_knife", "knife_menu")
register_event("DeathMsg","EventDeath","a")
register_event("CurWeapon", "ChangeModel", "be", "1=1")
gMaxHP = register_cvar("knf_mod_max_health", "100")
register_forward(FM_CmdStart, "fw_CmdStart")
register_forward(FM_EmitSound, "fw_EmitSound")
register_forward(FM_TraceLine, "fw_TraceLine")
register_forward(FM_TraceHull, "fw_TraceHull")
RegisterHam(Ham_TakeDamage, "player", "TakeDamage_Pre", 0)
RegisterHam(Ham_TakeDamage, "player", "TakeDamage_Post", 1)
RegisterHam(Ham_Player_PreThink, "player", "PreThink")
register_forward(FM_EmitSound, "KnifeSound")
for (new i = 1; i < sizeof WEAPONENTNAMES; i++)
if (WEAPONENTNAMES[i][0]) RegisterHam(Ham_Item_Deploy, WEAPONENTNAMES[i], "fw_Item_Deploy_Post", 1)
RegisterHam(Ham_Weapon_PrimaryAttack, weapon_name, "fw_PriAttack_Post", 1)
RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack")
}
public client_putinserver(id)
{
Knife[id] = 0
aKnife[id] = 1
}
public ChangeModel(id)
{
if(!is_user_alive(id))
return
static weaponid
weaponid = read_data(2)
if(weaponid != CSW_KNIFE)
return
change(id)
}
public get_ruyi(id)
{
g_has_ruyi[id] = 1
g_attack_type[id] = 0
if(get_user_weapon(id) == CSW_KNIFE)
{
set_weapon_anim(id, KNIFE_ANIM_DRAW)
}
}
public EventDeath()
{
new iKiller = read_data(1)
new iVictim = read_data(2)
new iHead = read_data(3)
new gHP
if ( Knife[iKiller] != 3 ) return PLUGIN_HANDLED
set_dhudmessage(243, 180, 48, 0.57, 0.75, 0, 1.0, 1.0, 0.1, 0.1)
if( iHead && iKiller != iVictim && is_user_connected(iKiller) && is_user_connected(iVictim) )
{
format(gMsg, charsmax(gMsg), "+20 HP за убийство.")
gHP = 20
} else
if( iKiller != iVictim && is_user_connected(iKiller) && is_user_connected(iVictim) )
{
format(gMsg, charsmax(gMsg), "+10 HP за убийство.")
gHP = 10
}
if ( get_user_health(iKiller) <= get_pcvar_num(gMaxHP) )
{
set_user_health(iKiller, get_user_health(iKiller) + gHP)
}
show_dhudmessage(iKiller, gMsg)
return PLUGIN_CONTINUE
}
public KnifeSound(id, channel, sample[], Float:volume, Float:attn, flags, pitch)
{
if(!equal(sample, "weapons/knife_", 14) || Knife[id] != 1)
return FMRES_IGNORED
if(equal(sample[8], "knife_hitwall", 13))
PlaySound(id, 1)
else
if(equal(sample[8], "knife_hit", 9))
switch(random(2))
{
case 0:PlaySound(id, 4)
case 1:PlaySound(id, 5)
}
if(equal(sample[8], "knife_slash", 11)) PlaySound(id, 2)
if(equal(sample[8], "knife_stab", 10)) PlaySound(id, 3)
if(equal(sample[8], "knife_deploy", 12)) PlaySound(id, 0)
return FMRES_SUPERCEDE
}
public fw_Item_Deploy_Post(weapon_ent)
{
static owner
owner = fm_cs_get_weapon_ent_owner(weapon_ent)
if(g_has_ruyi[owner])
{
set_weapons_timeidle(owner, 1.7)
// set_player_nextattack(owner, 1.7)
}
}
public TakeDamage_Pre(victim, inflictor, attacker, Float:damage, damagetype)
{
if(!is_user_alive(attacker))
return HAM_IGNORED
if(!Knife[attacker] || get_user_weapon(attacker) != CSW_KNIFE)
return HAM_IGNORED
new hit, target
get_user_aiming(attacker, target, hit)
new bool:head = (hit == HIT_HEAD)
new Float:mult_dmg = 1.0
if(pev(attacker, pev_button, IN_ATTACK))
mult_dmg = head ? PRIM_HEAD_DMG : PRIM_DMG
else
mult_dmg = head ? SEC_HEAD_DMG : SEC_DMG
SetHamParamFloat(4, damage * mult_dmg)
return HAM_HANDLED
}
public fw_CmdStart(id, uc_handle, seed)
{
if (!is_user_alive(id))
return
if(get_user_weapon(id) != CSW_KNIFE)
return
if(!g_has_ruyi[id])
return
static ent
ent = find_ent_by_owner(-1, weapon_name, id)
if(!pev_valid(ent))
return
if(get_pdata_float(ent, 46, 4) > 0.0 || get_pdata_float(ent, 47, 4) > 0.0)
return
static CurButton
CurButton = get_uc(uc_handle, UC_Buttons)
if(CurButton & IN_ATTACK)
{
g_attack_type[id] = ATTACK_SLASH
} else {
g_attack_type[id] = ATTACK_STAB
}
}
public fw_PriAttack_Post(ent)
{
if(pev_valid(ent) != 2)
return HAM_IGNORED
new id
id = get_pdata_cbase(ent, 41 , 4)
if(!g_has_ruyi[id])
return HAM_IGNORED
set_weapons_timeidle(id, RUYI_NEXTATTACK_SLASH)
set_player_nextattack(id, RUYI_NEXTATTACK_SLASH)
return HAM_HANDLED
}
public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch)
{
if(!is_user_connected(id))
return FMRES_IGNORED
if(get_user_weapon(id) != CSW_KNIFE || !g_has_ruyi[id])
return FMRES_IGNORED
if(sample[8] == 'k' && sample[9] == 'n' && sample[10] == 'i')
{
if(sample[14] == 's' && sample[15] == 'l' && sample[16] == 'a')
{
emit_sound(id, channel, ruyi_sound[2], volume, attn, flags, pitch)
return FMRES_SUPERCEDE
}
if (sample[14] == 'h' && sample[15] == 'i' && sample[16] == 't') // hit
{
if (sample[17] == 'w')
{
emit_sound(id, channel, ruyi_sound[4], volume, attn, flags, pitch)
return FMRES_SUPERCEDE
} else {
emit_sound(id, channel, ruyi_sound[1], volume, attn, flags, pitch)
return FMRES_SUPERCEDE
}
}
if (sample[14] == 's' && sample[15] == 't' && sample[16] == 'a') // stab
{
emit_sound(id, channel, ruyi_sound[3], volume, attn, flags, pitch)
return FMRES_SUPERCEDE;
}
}
return FMRES_IGNORED
}
public fw_TraceLine(Float:vector_start[3], Float:vector_end[3], ignored_monster, id, handle)
{
if (!is_user_alive(id))
return FMRES_IGNORED
// if(zp_get_user_zombie(id))
// return FMRES_IGNORED
if(cs_get_user_team(id) == CS_TEAM_T)
return FMRES_IGNORED
if (get_user_weapon(id) != CSW_KNIFE)
return FMRES_IGNORED
if(!g_has_ruyi[id])
return FMRES_IGNORED
static Float:vecStart[3], Float:vecEnd[3], Float:v_angle[3], Float:v_forward[3], Float:view_ofs[3], Float:fOrigin[3]
pev(id, pev_origin, fOrigin)
pev(id, pev_view_ofs, view_ofs)
xs_vec_add(fOrigin, view_ofs, vecStart)
pev(id, pev_v_angle, v_angle)
engfunc(EngFunc_MakeVectors, v_angle)
get_global_vector(GL_v_forward, v_forward)
static Float:scalar
if(g_attack_type[id] == ATTACK_SLASH) scalar = RUYI_RANGE_SLASH
else if(g_attack_type[id] == ATTACK_STAB) scalar = RUYI_RANGE_SLASH
xs_vec_mul_scalar(v_forward, scalar, v_forward)
xs_vec_add(vecStart, v_forward, vecEnd)
engfunc(EngFunc_TraceLine, vecStart, vecEnd, ignored_monster, id, handle)
return FMRES_SUPERCEDE
}
public fw_TraceHull(Float:vector_start[3], Float:vector_end[3], ignored_monster, hull, id, handle)
{
if (!is_user_alive(id))
return FMRES_IGNORED
// if(zp_get_user_zombie(id))
// return FMRES_IGNORED
if(cs_get_user_team(id) == CS_TEAM_T)
return FMRES_IGNORED
if (get_user_weapon(id) != CSW_KNIFE)
return FMRES_IGNORED
if(!g_has_ruyi[id])
return FMRES_IGNORED
static Float:vecStart[3], Float:vecEnd[3], Float:v_angle[3], Float:v_forward[3], Float:view_ofs[3], Float:fOrigin[3]
pev(id, pev_origin, fOrigin)
pev(id, pev_view_ofs, view_ofs)
xs_vec_add(fOrigin, view_ofs, vecStart)
pev(id, pev_v_angle, v_angle)
engfunc(EngFunc_MakeVectors, v_angle)
get_global_vector(GL_v_forward, v_forward)
static Float:scalar
if(g_attack_type[id] == ATTACK_SLASH) scalar = RUYI_RANGE_SLASH
else if(g_attack_type[id] == ATTACK_STAB) scalar = RUYI_RANGE_SLASH
xs_vec_mul_scalar(v_forward, scalar, v_forward)
xs_vec_add(vecStart, v_forward, vecEnd)
engfunc(EngFunc_TraceHull, vecStart, vecEnd, ignored_monster, hull, id, handle)
return FMRES_SUPERCEDE
}
public fw_TraceAttack(Victim, Attacker, Float:Damage, Float:Direction[3], TraceHandle, DamageBit)
{
if(!is_user_alive(Attacker))
return HAM_IGNORED
if(get_user_weapon(Attacker) != CSW_KNIFE)
return HAM_IGNORED
if(!g_has_ruyi[Attacker])
return HAM_IGNORED
SetHamParamFloat(3, g_attack_type[Attacker] == ATTACK_SLASH ? RUYI_DAMAGE_SLASH : RUYI_DAMAGE_STAB)
return HAM_IGNORED
}
public TakeDamage_Post(victim, inflictor, attacker, Float:damage, damagetype)
{
if(!is_user_alive(attacker) || !is_user_alive(victim))
return HAM_IGNORED
if(!Knife[attacker] || get_user_weapon(attacker) != CSW_KNIFE)
return HAM_IGNORED
new Float:Origin[3], Float:Origin2[3], Float:Velocity[3]
pev(attacker, pev_origin, Origin)
pev(victim, pev_origin, Origin2)
xs_vec_sub(Origin2, Origin, Velocity)
xs_vec_normalize(Velocity, Velocity)
xs_vec_mul_scalar(Velocity, (KNIFE_KNOCK * 100.0), Velocity)
if(Velocity[2] <= 100.0)
Velocity[2] = random_float(150.0, 250.0)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BLOODSPRITE);
engfunc(EngFunc_WriteCoord, Origin2[0])
engfunc(EngFunc_WriteCoord, Origin2[1])
engfunc(EngFunc_WriteCoord, Origin2[2])
write_short(g_Blood[0])
write_short(g_Blood[1])
write_byte(77)
write_byte(BLOOD)
message_end()
set_pev(victim, pev_velocity, Velocity)
return HAM_HANDLED
}
public PreThink(id)
{
if(!is_user_alive(id)) return HAM_IGNORED
if ( Knife[id] == 1 )
{
if(get_user_weapon(id) != CSW_KNIFE)
{
set_pev(id, pev_gravity, get_cvar_float("knf1_gravity"))
set_pev(id, pev_maxspeed, get_cvar_float("knf1_speed"))
return HAM_IGNORED
}
set_pev(id, pev_gravity, KNIFE_GRAVITY)
set_pev(id, pev_maxspeed, KNIFE_SPEED)
} else
if ( Knife[id] == 2 )
{
set_user_maxspeed(id, 600.0)
set_user_gravity(id, 1.0)
}
return HAM_HANDLED
}
public active_knife(id)
{
aKnife[id] = 1
ChatColor(id, "%s Ножи перезарядились! Вы можете сменить нож.", cPrefix)
}
public knife_menu(id)
{
if ( aKnife[id] == 0 )
{
ChatColor(id, "%s Идет перезарядка... Обычно она идет!t 15!y сек. после выбора ножа.", cPrefix)
return PLUGIN_HANDLED
}
if(!(get_user_flags(id) & ADMIN_LEVEL_A))
{
ChatColor(id, "%s Данное меню доступно только для VIP игроков!", cPrefix)
return PLUGIN_HANDLED
}
static s_MenuItem[255]
formatex(s_MenuItem, charsmax(s_MenuItem), "%s Меню ножей", fPrefix)
new menu = menu_create(s_MenuItem, "knfm_handler" )
menu_additem(menu, "\yRobot Hands \d[Невесомость и Дамаг]","1")
menu_additem(menu, "\yRuyi Stick \d[Скорость и Дамаг]","2")
menu_additem(menu, "\yHorse Axe \d[Вампиризм]","3")
menu_setprop(menu, MPROP_BACKNAME, "Назад")
menu_setprop(menu, MPROP_NEXTNAME, "Далее")
menu_setprop(menu, MPROP_EXITNAME, "Выход")
menu_display(id,menu,0)
return PLUGIN_HANDLED
}
public knfm_handler(id, menu, item)
{
if(item == MENU_EXIT)
{
menu_destroy(menu)
return PLUGIN_HANDLED
}
new data[6], iName[64], access, callback
menu_item_getinfo(menu, item, access, data, 5, iName, 63, callback)
new key = str_to_num(data)
switch(key)
{
case 1:
{
formatex(gMsg, charsmax(gMsg), "%s Вы взяли!g Robot Hands.", cPrefix)
}
case 2:
{
formatex(gMsg, charsmax(gMsg), "%s Вы взяли!g Ruyi Stick.", cPrefix)
}
case 3:
{
formatex(gMsg, charsmax(gMsg), "%s Вы взяли!g Horse Axe.", cPrefix)
}
}
Knife[id] = key
aKnife[id] = 0
set_task(15.0, "active_knife", id)
change(id)
ChatColor(id, gMsg)
return PLUGIN_HANDLED
}
public plugin_precache()
{
precache_model(v_knife)
precache_model(p_knife)
precache_model(v_knife2)
precache_model(p_knife2)
precache_model(v_knife3)
precache_model(p_knife3)
static i
for(i = 0; i <= charsmax(SoundList); i++)
precache_sound(SoundList[i])
for(new i = 0; i < sizeof ruyi_sound; i++)
precache_sound(ruyi_sound[i])
for(i = 0; i <= charsmax(Blood); i++)
g_Blood[i] = precache_model(Blood[i])
}
change(id)
{
if ( Knife[id] == 1 )
{
set_pev(id, pev_viewmodel2, v_knife)
set_pev(id, pev_weaponmodel2, p_knife)
} else
if ( Knife[id] == 2 )
{
set_pev(id, pev_viewmodel2, v_knife2)
set_pev(id, pev_weaponmodel2, p_knife2)
} else
if ( Knife[id] == 3 )
{
set_pev(id, pev_viewmodel2, v_knife3)
set_pev(id, pev_weaponmodel2, p_knife3)
}
}
stock PlaySound(Ent, Sound)
engfunc(EngFunc_EmitSound, Ent, CHAN_WEAPON, SoundList[_:Sound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
stock fm_cs_get_weapon_ent_owner(ent)
{
return get_pdata_cbase(ent, OFFSET_WEAPONOWNER, OFFSET_LINUX_WEAPONS)
}
stock set_weapons_timeidle(id, Float:TimeIdle)
{
if(!is_user_alive(id))
return
new entwpn = fm_get_user_weapon_entity(id, CSW_KNIFE)
if (pev_valid(entwpn))
{
set_pdata_float(entwpn, 46, TimeIdle, 4)
set_pdata_float(entwpn, 47, TimeIdle, 4)
set_pdata_float(entwpn, 48, TimeIdle + 1.0, 4)
}
}
stock set_player_nextattack(id, Float:nexttime)
{
if(!is_user_alive(id))
return
const m_flNextAttack = 83
set_pdata_float(id, m_flNextAttack, nexttime, 5)
}
stock set_weapon_anim(id, anim)
{
if(!is_user_alive(id))
return
set_pev(id, pev_weaponanim, anim)
message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, _, id)
write_byte(anim)
write_byte(0)
message_end()
}
stock ChatColor(const id, const input[], any:...)
{
new count = 1, players[32]
static msg[188]
vformat(msg, 187, input, 3)
replace_all(msg, 187, "!g", "^4")
replace_all(msg, 187, "!y", "^1")
replace_all(msg, 187, "!t", "^3")
if (id) players[0] = id; else get_players(players, count, "ch")
{
for (new i = 0; i < count; i++)
{
if (is_user_connected(players[i]))
{
message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i]);
write_byte(players[i]);
write_string(msg);
message_end();
}
}
}
}