有人可以教教我改吗
那sma的格式~:
可能会很长吧
但帮帮忙
谢谢各位有力的大大~
[code]/*|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|*
*
* [ZP] Extra Item - Bazooka 3.2 (by B!gBud)
*
* Allows Humans buy a Bazooka in Zombie Plague [4.0]
*
* CREDITS:
* KleeneX
* Bad_Bud
* MeRcyLeZZ
* mogel
*
* MODIFY:
* Jim (Taiwan)
*
* CVARS:
* zp_bazooka_toggle 1 // 0 = Plugin off / 1 = Plugin on
* zp_bazooka_keybind 0 // 0 = Use default key / 1 = User bind key
* zp_bazooka_oneround 1 // Only can use one round [ 0 = No / 1 = Yes ]
* zp_bazooka_rocket_give 2 // How much rocket can give when buy a bazooka
* zp_bazooka_rocket_num 2 // How much rocket can take at one time
* zp_bazooka_rocket_delay 12 // How long you got to wait to shoot the next rocket(in sec.)
* zp_bazooka_rocket_speed 1200 // Set the rocket Speed
* zp_bazooka_rocket_maxdmg 1500 // Set the max rocket Damage
* zp_bazooka_rocket_mindmg 100 // Set the min rocket Damage
* zp_bazooka_rocket_dmgradius 350 // Set the radius of a rocket explosion
* zp_bazooka_rocket_reloadtime 5.0 // Reload rocket time
* zp_bazooka_rocket_dmghuman 1 // Rocket explosion also can make damage for human
* zp_bazooka_kill_frags 1 // How much frags receive when killed a enemy
* zp_bazooka_tk_frags 1 // How much frags deduct when killed a teammate
* zp_bazooka_kill_ammopack 1 // How much ammopack receive when killed a enemy
* zp_bazooka_tk_ammopack 1 // How much ammopack deduct when killed a teammate
*
*|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|**|_/=\_|*/
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
#include <zombieplague>
// 插件主要资讯
#define PLUGIN_NAME "[ZP] Extra Item - Bazooka"
#define PLUGIN_VERSION "3.2"
#define PLUGIN_AUTHOR "B!gBud"
#define TASK_ID 9182
// Weapons Offsets (win32)
const OFFSET_FlNextPrimaryAttack = 46
const OFFSET_FlNextSecondaryAttack = 47
// Linux diff's
const OFFSET_LINUX_WEAPONS = 4 // weapon offsets are only 4 steps higher on Linux
// 特殊道具名称和价格
new const g_item_name[] = { "火箭筒" }; //特殊道具名称
new const g_item_cost = 1; //购买火箭筒一次要花多少子弹包
new const g_rocket_cost = 1; //购买一次火箭弹要花多少子弹包
new const g_rocket_buy_amount = 1; //购买一次火箭弹可得到多少枚补充
// 火箭筒模型和音效
new const BAZOOKA_P_MDL[] = { "models/zombie_plague/p_law.mdl" } //火箭筒的 p_ 模型
new const BAZOOKA_V_MDL[] = { "models/zombie_plague/v_law.mdl" } //火箭筒的 v_ 模型
new const BAZOOKA_W_MDL[] = { "models/zombie_plague/w_law.mdl" } //火箭筒的 w_ 模型
//new const ROCKET_MDL[] = { "models/rpgrocket.mdl" } //火箭弹的模型
new const ROCKET_MDL[] = { "models/zombie_plague/rpgrocket3.mdl" } //火箭弹的模型
new const KNIFE_P_MDL[] = { "models/p_knife.mdl" } //原始小刀的 p_ 模型
new const KNIFE_V_MDL[] = { "models/v_knife.mdl" } //原始小刀的 v_ 模型
new const GET_BAZOOKA_SOUND[] = { "items/gunpickup2.wav" } //取得火箭筒时的音效
new const SELECT_BAZOOKA_SOUND[] = { "common/wpn_hudon.wav" } //选择使用火箭筒时的音效
new const BAZOOKA_FIRE_SOUND[] = { "weapons/rocketfire1.wav" } //火箭筒发射火箭弹时的音效
new const BAZOOKA_OUTAMMO_SOUND[] = { "weapons/357_cock1.wav" } //火箭筒没装弹时击发的音效
new const BAZOOKA_RELOAD_SOUND[] = { "items/ammopickup1.wav" } //装填火箭弹时的音效
new const ROCKET_FLY_SOUND[] = { "weapons/nuke_fly.wav" } //火箭弹飞行时的音效
new const ROCKET_DETONATE_SOUND[] = { "weapons/mortarhit.wav" } //火箭弹引爆时的音效
new const BUY_ROCKET_SOUND[] = { "items/9mmclip2.wav" } //购买火箭弹时的音效
new const CANT_SHOOT_SOUND[] = { "common/wpn_denyselect.wav" } //火箭筒在无法射击的情况下所发出的警告声音
// 定义变数
new cvar_Toggle, cvar_KeyBind, cvar_OneRound
new cvar_RocketGive, cvar_RocketNum, cvar_RocketDelay, cvar_RocketSpeed
new cvar_MaxDamage, cvar_MinDamage, cvar_DamageRange
new cvar_ReloadTime, cvar_DamageHuman
new cvar_KilledFrags, cvar_TeamKillFrags, cvar_KilledAmmopack, cvar_TeamKillAmmopack
new explosion, trail, white, spark[3]
new g_item_bazooka
new Float:global_time
new bool:end_round
new maxplayers
new bool:has_bazooka[33], bool:activated[33]
new have_rocket_num[33]
new bool:rocket_ready[33], Float:rocket_ready_time[33]
new bool:reload_rocket[33]
new user_weapon[33]
new Float:show_msg_time[33]
#define Damage_Human_Multiplier 0.05 //对人类造成的伤害数值的乘数
#define Damage_Survivor_Multiplier 0.01 //对幸存者造成的伤害数值的乘数
#define Explosoin_Knockback_Power 500 //爆炸时震退效果的力量数值.(设定成 0 代表无震退效果)
public plugin_init()
{
register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
new ver[64]
format(ver, 63, "%s v%s", PLUGIN_NAME, PLUGIN_VERSION)
register_cvar("zp_extra_bazooka", ver, FCVAR_SERVER)
g_item_bazooka = zp_register_extra_item(g_item_name, g_item_cost, ZP_TEAM_HUMAN)
cvar_Toggle = register_cvar("zp_bazooka_toggle", "1") //火箭筒插件开关
cvar_KeyBind = register_cvar("zp_bazooka_keybind", "0") //火箭筒的切换使用键是否用自行 bind 设定
cvar_OneRound = register_cvar("zp_bazooka_oneround", "0") //只能在该回合使用
cvar_RocketGive = register_cvar("zp_bazooka_rocket_give", "2") //购买火箭筒后.同时给予多少枚火箭弹
cvar_RocketNum = register_cvar("zp_bazooka_rocket_num", "5") //一次最多能携带多少枚火箭弹
cvar_RocketDelay = register_cvar("zp_bazooka_rocket_delay", "12.0") //火箭弹发射后的引爆延迟时间
cvar_RocketSpeed = register_cvar("zp_bazooka_rocket_speed", "1500") //火箭弹的飞行速度
cvar_MaxDamage = register_cvar("zp_bazooka_rocket_maxdmg", "1500") //火箭弹爆炸时造成的最大伤害数值
cvar_MinDamage = register_cvar("zp_bazooka_rocket_mindmg", "100") //火箭弹爆炸时造成的最小伤害数值
cvar_DamageRange = register_cvar("zp_bazooka_rocket_dmgradius", "300") //火箭弹的爆炸伤害范围
cvar_ReloadTime = register_cvar("zp_bazooka_rocket_reloadtime", "8.0") //火箭弹装填的花费时间
cvar_DamageHuman = register_cvar("zp_bazooka_rocket_dmghuman", "1") //火箭弹爆炸也会对人类造成伤害
cvar_KilledFrags = register_cvar("zp_bazooka_kill_frags", "1") //用火箭筒杀死一个敌人能得到多少frag
cvar_TeamKillFrags = register_cvar("zp_bazooka_tk_frags", "1") //用火箭筒误杀一个队友会减去多少frag
cvar_KilledAmmopack = register_cvar("zp_bazooka_kill_ammopack", "1") //用火箭筒杀死一个敌人能得到多少子弹包
cvar_TeamKillAmmopack = register_cvar("zp_bazooka_tk_ammopack", "1") //用火箭筒误杀一个队友会减去多少子弹包
register_concmd("bazooka_act", "cmd_ActivatedBazooka", ADMIN_USER, "- activated Bazooka")
register_clcmd("say /buy_bazooka", "cmd_BuyBazooka")
register_clcmd("say_team /buy_bazooka", "cmd_BuyBazooka")
RegisterHam(Ham_Item_PostFrame, "weapon_knife", "fw_Item_PostFrame", 1)
register_forward(FM_StartFrame, "fw_StartFrame")
register_forward(FM_CmdStart, "fw_CmdStart")
register_forward(FM_Touch, "fw_Touch")
register_event("DeathMsg", "player_die", "a")
register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
register_event("TextMsg", "event_weapon_drop", "be", "2=#Weapon_Cannot_Be_Dropped")
register_message(get_user_msgid("WeapPickup"), "message_weappickup")
register_message(get_user_msgid("CurWeapon"), "message_cur_weapon")
maxplayers = get_maxplayers()
}
public plugin_precache()
{
precache_model(BAZOOKA_P_MDL)
precache_model(BAZOOKA_V_MDL)
precache_model(BAZOOKA_W_MDL)
precache_model(ROCKET_MDL)
precache_model(KNIFE_P_MDL)
precache_model(KNIFE_V_MDL)
precache_sound(GET_BAZOOKA_SOUND)
precache_sound(BAZOOKA_FIRE_SOUND)
precache_sound(BAZOOKA_OUTAMMO_SOUND)
precache_sound(BAZOOKA_RELOAD_SOUND)
precache_sound(ROCKET_FLY_SOUND)
precache_sound(ROCKET_DETONATE_SOUND)
precache_sound(BUY_ROCKET_SOUND)
precache_sound(CANT_SHOOT_SOUND)
explosion = precache_model("sprites/zerogxplode.spr")
trail = precache_model("sprites/smoke.spr")
white = precache_model("sprites/white.spr")
//spark = precache_model("sprites/muzzleflash.spr")
spark[0] = precache_model("sprites/muz2.spr")
spark[1] = precache_model("sprites/muz3.spr")
spark[2] = precache_model("sprites/muz8.spr")
}
public zp_extra_item_selected(id, itemid)
{
if (itemid == g_item_bazooka)
{
if (!get_pcvar_num(cvar_Toggle))
{
zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + g_item_cost)
client_print(id, print_chat, "[ZP] 火箭筒插件己关闭.")
return PLUGIN_CONTINUE;
}
if (has_bazooka[id])
{
zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + g_item_cost)
client_print(id, print_chat, "[ZP] 你已经有买火箭筒了.")
return PLUGIN_CONTINUE;
}
has_bazooka[id] = true
new rocket_give = get_pcvar_num(cvar_RocketGive)
new rocket_num = get_pcvar_num(cvar_RocketNum)
if (rocket_give <= rocket_num)
have_rocket_num[id] = rocket_give
else
have_rocket_num[id] = rocket_num
rocket_ready[id] = true
reload_rocket[id] = false
set_use_bazooka(id)
engfunc(EngFunc_EmitSound, id, CHAN_ITEM, GET_BAZOOKA_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
if (get_pcvar_num(cvar_KeyBind))
{
client_print(id, print_chat, "[ZP] 你已购买了火箭筒. (设定切换使用键 bind <key> bazooka_act)")
client_print(id, print_chat, "[ZP] 使用火箭筒时,按滑鼠'左键'攻击,按'R'买火箭弹.")
}
else
{
client_cmd(id, "bind F2 bazooka_act")
client_print(id, print_chat, "[ZP] 你已购买了火箭筒. (按'F2'可切换使用)")
client_print(id, print_chat, "[ZP] 使用火箭筒时,按滑鼠'左键'攻击,按'R'买火箭弹.")
}
}
return PLUGIN_CONTINUE;
}
public cmd_BuyBazooka(id)
{
if (!get_pcvar_num(cvar_Toggle))
{
client_print(id, print_center, "[ZP] 火箭筒插件己关闭.")
return PLUGIN_HANDLED;
}
if (!is_user_alive(id))
{
client_print(id, print_center, "[ZP] 你已经死掉了,不能购买火箭筒.")
return PLUGIN_HANDLED;
}
if (zp_get_user_zombie(id))
{
client_print(id, print_center, "[ZP] 你不是人类,不能购买火箭筒.")
return PLUGIN_HANDLED;
}
if (zp_get_user_survivor(id))
{
client_print(id, print_center, "[ZP] 你是幸存者,不能购买火箭筒.")
return PLUGIN_HANDLED;
}
if (has_bazooka[id])
{
client_print(id, print_center, "[ZP] 你已经有买火箭筒了.")
return PLUGIN_HANDLED;
}
new money = zp_get_user_ammo_packs(id)
if (money < g_item_cost)
{
client_print(id, print_center, "[ZP] 你没有足够的子弹包来购买火箭筒. (需要%d子弹包)", g_item_cost)
return PLUGIN_HANDLED;
}
zp_set_user_ammo_packs(id, money - g_item_cost)
has_bazooka[id] = true
new rocket_give = get_pcvar_num(cvar_RocketGive)
new rocket_num = get_pcvar_num(cvar_RocketNum)
if (rocket_give <= rocket_num)
have_rocket_num[id] = rocket_give
else
have_rocket_num[id] = rocket_num
rocket_ready[id] = true
reload_rocket[id] = false
set_use_bazooka(id)
engfunc(EngFunc_EmitSound, id, CHAN_ITEM, GET_BAZOOKA_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
if (get_pcvar_num(cvar_KeyBind))
{
client_print(id, print_chat, "[ZP] 你已购买了火箭筒. (设定切换使用键 bind <key> bazooka_act)")
client_print(id, print_chat, "[ZP] 使用火箭筒时,按滑鼠'左键'攻击,按'R'买火箭弹.")
}
else
{
client_cmd(id, "bind F2 bazooka_act")
client_print(id, print_chat, "[ZP] 你已购买了火箭筒. (按'F2'可切换使用)")
client_print(id, print_chat, "[ZP] 使用火箭筒时,按滑鼠'左键'攻击,按'R'买火箭弹.")
}
return PLUGIN_HANDLED;
}
public cmd_ActivatedBazooka(id)
{
if (!is_user_alive(id) || !has_bazooka[id])
return PLUGIN_CONTINUE;
client_print(id, print_center, "")
if (activated[id])
{
clear_show_rocket(id)
set_use_knife(id)
}
else
{
set_use_bazooka(id)
engfunc(EngFunc_EmitSound, id, CHAN_ITEM, SELECT_BAZOOKA_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
show_rocket_num(id)
}
return PLUGIN_CONTINUE;
}
public fw_Item_PostFrame(weapon)
{
if (!pev_valid(weapon))
return HAM_IGNORED;
static id
id = pev(weapon, pev_owner)
if (!is_user_alive(id) || !has_bazooka[id] || !activated[id])
return HAM_IGNORED;
set_weapon_next_pri_attack(weapon, 0.5)
set_weapon_next_sec_attack(weapon, 0.5)
return HAM_IGNORED;
}
public fw_StartFrame()
{
if (!get_pcvar_num(cvar_Toggle))
return;
global_time = get_gametime()
static id
for (id = 1; id <= 32; id++)
{
check_player(id)
}
}
public check_player(id)
{
if (!is_user_alive(id) || zp_get_user_zombie(id) || zp_get_user_survivor(id))
return PLUGIN_CONTINUE;
if (!has_bazooka[id])
return PLUGIN_CONTINUE;
if (is_use_shield(id))
{
drop_bazooka(id)
return PLUGIN_CONTINUE;
}
if (!activated[id])
return PLUGIN_CONTINUE;
if (!is_use_bazooka(id))
{
client_print(id, print_center, "")
clear_show_rocket(id)
activated[id] = false
reload_rocket[id] = false
return PLUGIN_CONTINUE;
}
if (!rocket_ready[id])
{
if (!reload_rocket[id])
{
if (have_rocket_num[id] > 0)
{
reload_rocket[id] = true
rocket_ready_time[id] = global_time + get_pcvar_float(cvar_ReloadTime)
}
}
else
{
if (global_time > rocket_ready_time[id])
{
SendWeaponAnim(id, 0)
engfunc(EngFunc_EmitSound, id, CHAN_WEAPON, BAZOOKA_RELOAD_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
client_print(id, print_center, "火箭弹已装填完成!")
rocket_ready[id] = true
reload_rocket[id] = false
}
}
}
if (show_msg_time[id] < global_time)
{
show_rocket_num(id)
show_msg_time[id] = global_time + 0.5
}
return PLUGIN_CONTINUE;
}
public fw_CmdStart(id, uc_handle, seed)
{
if (!is_user_alive(id) || !has_bazooka[id] || !activated[id])
return FMRES_IGNORED;
new button = get_uc(uc_handle, UC_Buttons)
new oldbutton = pev(id, pev_oldbuttons)
if ((button & IN_ATTACK) && !(oldbutton & IN_ATTACK))
fire_rocket(id)
if ((button & IN_RELOAD) && !(oldbutton & IN_RELOAD))
buy_rocket(id)
return FMRES_HANDLED;
}
public fw_Touch(ptr, ptd)
{
if (!pev_valid(ptr))
return FMRES_IGNORED;
new classname[32]
pev(ptr, pev_classname, classname, charsmax(classname))
if (equal(classname, "fake_bazooka"))
{
if (!pev_valid(ptd))
return FMRES_IGNORED;
if (!is_user_alive(ptd) || !(1 <= ptd <= maxplayers) || zp_get_user_zombie(ptd) || zp_get_user_survivor(ptd))
return FMRES_IGNORED;
if (has_bazooka[ptd])
return FMRES_IGNORED;
has_bazooka[ptd] = true
have_rocket_num[ptd] = pev(ptr, pev_iuser4)
rocket_ready[ptd] = (pev(ptr, pev_iuser3) == 1 ? true : false)
reload_rocket[ptd] = false
set_use_bazooka(ptd)
engfunc(EngFunc_EmitSound, ptd, CHAN_ITEM, GET_BAZOOKA_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
if (get_pcvar_num(cvar_KeyBind))
{
client_print(ptd, print_chat, "[ZP] 你捡起了一个火箭筒. (设定切换使用键 bind <key> bazooka_act)")
client_print(ptd, print_chat, "[ZP] 使用火箭筒时,按滑鼠'左键'攻击,按'R'买火箭弹.")
}
else
{
client_cmd(ptd, "bind F2 bazooka_act")
client_print(ptd, print_chat, "[ZP] 你捡起了一个火箭筒. (按'F2'可切换使用)")
client_print(ptd, print_chat, "[ZP] 使用火箭筒时,按滑鼠'左键'攻击,按'R'买火箭弹.")
}
engfunc(EngFunc_RemoveEntity, ptr)
}
else if (equal(classname, "fake_rocket"))
{
/*
if (pev_valid(ptd))
{
new classname2[32]
pev(ptd, pev_classname, classname2, charsmax(classname2))
if (equal(classname2, "func_breakable"))
fm_force_use(ptr, ptd)
}
*/
detonate_rocket(ptr)
}
return FMRES_IGNORED;
}
public event_weapon_drop(id)
{
if (!has_bazooka[id] || !activated[id])
return PLUGIN_CONTINUE;
new weapon, clip,ammo
weapon = get_user_weapon(id, clip, ammo)
if (weapon != CSW_KNIFE)
return PLUGIN_CONTINUE;
client_print(id, print_center, "")
drop_bazooka(id)
set_use_knife(id)
return PLUGIN_CONTINUE;
}
public message_weappickup(msg_id, msg_dest, id)
{
if (!is_user_alive(id) || !has_bazooka[id])
return PLUGIN_CONTINUE;
if (is_use_bazooka(id))
set_task(0.1, "reset_bazooka_activated", id)
return PLUGIN_CONTINUE;
}
public reset_bazooka_activated(id)
{
if (is_use_bazooka(id))
activated[id] = true
}
public message_cur_weapon(msg_id, msg_dest, id)
{
if (!is_user_alive(id) || !has_bazooka[id])
return PLUGIN_CONTINUE;
// Not an active weapon
if (get_msg_arg_int(1) != 1)
return PLUGIN_CONTINUE;
new weapon = get_msg_arg_int(2)
if (weapon != user_weapon[id])
{
user_weapon[id] = weapon
if (activated[id] && (weapon != CSW_KNIFE))
{
client_print(id, print_center, "")
clear_show_rocket(id)
reload_rocket[id] = false
activated[id] = false
}
}
return PLUGIN_CONTINUE;
}
public set_use_bazooka(id)
{
new weapon, clip, ammo
weapon = get_user_weapon(id, clip, ammo)
if (weapon != CSW_KNIFE)
{
engclient_cmd(id, "weapon_knife")
set_task(0.1, "set_use_bazooka", id)
return PLUGIN_CONTINUE;
}
set_pev(id, pev_viewmodel2, BAZOOKA_V_MDL)
set_pev(id, pev_weaponmodel2, BAZOOKA_P_MDL)
SendWeaponAnim(id, 0)
if (rocket_ready[id])
client_print(id, print_center, "火箭弹已备妥等待发射.")
activated[id] = true
new weapon_ent = fm_find_ent_by_owner(-1, "weapon_knife", id)
set_weapon_next_pri_attack(weapon_ent, 1.0)
set_weapon_next_sec_attack(weapon_ent, 1.0)
return PLUGIN_CONTINUE;
}
public set_use_knife(id)
{
set_pev(id, pev_viewmodel2, KNIFE_V_MDL)
set_pev(id, pev_weaponmodel2, KNIFE_P_MDL)
SendWeaponAnim(id, 3)
activated[id] = false
reload_rocket[id] = false
return PLUGIN_CONTINUE;
}
public fire_rocket(id)
{
if (!is_user_alive(id) || !has_bazooka[id] || !activated[id])
return PLUGIN_HANDLED;
if (!rocket_ready[id])
{
SendWeaponAnim(id, 0)
engfunc(EngFunc_EmitSound, id, CHAN_WEAPON, BAZOOKA_OUTAMMO_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
return PLUGIN_CONTINUE;
}
new view_dist = get_forward_view_dist(id)
if (view_dist < 100)
{
SendWeaponAnim(id, 0)
engfunc(EngFunc_EmitSound, id, CHAN_WEAPON, CANT_SHOOT_SOUND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
client_print(id, print_center, "视角前方距离太近,无法射击!")
return PLUGIN_CONTINUE;
}
SendWeaponAnim(id, 2)
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
if (!pev_valid(ent))
return PLUGIN_CONTINUE;
set_pev(ent, pev_classname, "fake_rocket")
set_pev(ent, pev_owner, id)
new Float:mins[3] = { -2.5, -2.5, -2.5 }
new Float:maxs[3] = { 2.5, 2.5, 2.5 };
engfunc(EngFunc_SetSize, ent, mins, maxs)
set_pev(ent, pev_solid, SOLID_BBOX)
set_pev(ent, pev_movetype, MOVETYPE_FLY)
new Float:origin[3], Float:aim_vector[3], Float:aim_origin[3]
pev(id, pev_origin, origin)
fm_get_aim_vector(id, 64, aim_vector, aim_origin)
xs_vec_add(origin, aim_vector, origin)
set_pev(ent, pev_origin, origin)
engfunc(EngFunc_SetModel, ent, ROCKET_MDL)
new Float:velocity[3], Float:angles[3], Float:temp
temp = vector_length(aim_vector)
temp = get_pcvar_float(cvar_RocketSpeed) / (temp > 0.0 ? temp : 1.0)
xs_vec_mul_scalar(aim_vector, temp, velocity)
set_pev(ent, pev_velocity, velocity)
vector_to_angle(velocity, angles)
set_pev(ent, pev_angles, angles)
set_pev(ent, pev_takedamage, 1.0)
//显示火箭弹飞行的尾部烟云拖曳效果
create_beam_follow(ent, spark[2], 2, 5, 220, 220, 220, 200)
create_beam_follow(ent, trail, 4, 5, 220, 220, 220, 200)
engfunc(EngFunc_EmitSound, id, CHAN_WEAPON, BAZOOKA_FIRE_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
new args[3]
args[0] = ent
args[1] = floatround(get_pcvar_float(cvar_RocketDelay) / 0.1) //设定火箭弹的引爆延迟时间(单位0.1秒)
args[2] = 0 // 播放火箭弹飞行声音用的时间变数
set_task(0.1, "rocket_fly", TASK_ID, args, sizeof args)
have_rocket_num[id]--
rocket_ready[id] = false
reload_rocket[id] = false
show_rocket_num(id)
return PLUGIN_CONTINUE;
}
public rocket_fly(args[3])
{
new ent = args[0]
if (!pev_valid(ent))
return;
if (end_round)
{
if (pev_valid(ent))
engfunc(EngFunc_RemoveEntity, ent)
return;
}
// 设定火箭弹飞行时的拖尾效果
//kill_beam(ent)
create_beam_follow(ent, spark[random_num(0,1)], 1, 5, 220, 220, 220, 200)
create_beam_follow(ent, trail, 1, 5, 220, 220, 220, 200)
if (args[1] <= 0)
{
detonate_rocket(ent)
return;
}
if (args[2] <= 0) // 设定每隔0.5秒播放一次火箭弹飞行的声音(单位0.1秒)
{
engfunc(EngFunc_EmitSound, args[0], CHAN_BODY, ROCKET_FLY_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
args[2] = 5
}
args[1]--
args[2]--
set_task(0.1, "rocket_fly", TASK_ID, args, sizeof args)
}
public detonate_rocket(entity)
{
if (!pev_valid(entity))
return PLUGIN_CONTINUE;
new Float:fOrigin[3], iOrigin[3]
pev(entity, pev_origin, fOrigin)
FVecIVec(fOrigin, iOrigin)
//输出爆炸声音和显示火光效果
create_explosion(iOrigin, explosion)
//显示火箭弹爆炸时的震波效果
create_beamcylinder(iOrigin, white)
engfunc(EngFunc_EmitSound, entity, CHAN_BODY, ROCKET_DETONATE_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
new owner = pev(entity, pev_owner)
if (!end_round)
rocket_radius_damage(owner, iOrigin)
engfunc(EngFunc_RemoveEntity, entity)
return PLUGIN_CONTINUE;
}
public buy_rocket(id)
{
if (!is_user_alive(id) || !has_bazooka[id] || !activated[id])
return PLUGIN_HANDLED;
SendWeaponAnim(id, 0)
new max_rocket_num = get_pcvar_num(cvar_RocketNum)
if (have_rocket_num[id] >= max_rocket_num)
{
client_print(id, print_chat, "[ZP] 你无法再携带更多的火箭弹!")
return PLUGIN_HANDLED;
}
new money = zp_get_user_ammo_packs(id)
if (money < g_rocket_cost)
{
client_print(id, print_chat, "[ZP] 你没有足够的子弹包来购买火箭弹. (需要%d子弹包)", g_rocket_cost)
return PLUGIN_HANDLED;
}
zp_set_user_ammo_packs(id, money - g_rocket_cost)
have_rocket_num[id] = min(have_rocket_num[id] + g_rocket_buy_amount, max_rocket_num)
engfunc(EngFunc_EmitSound, id, CHAN_ITEM, BUY_ROCKET_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
show_rocket_num(id)
return PLUGIN_HANDLED;
}
public show_rocket_num(id)
{
//set_hudmessage(255, 170, 0, 0.91, 0.91, _, _, 1.0, _, _, 4)
if (rocket_ready[id])
set_hudmessage(0, 200, 0, 0.01, 0.64, _, _, 0.8, _, _, 4)
else
set_hudmessage(200, 0, 0, 0.01, 0.64, _, _, 0.8, _, _, 4)
show_hudmessage(id, "火箭弹:%d枚", have_rocket_num[id])
}
public clear_show_rocket(id)
{
set_hudmessage(0, 0, 0, 0.01, 0.64, _, _, 0.8, _, _, 4)
show_hudmessage(id, " ")
}
public drop_bazooka(id)
{
if (!has_bazooka[id])
return PLUGIN_CONTINUE;
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
if (!pev_valid(ent))
return PLUGIN_CONTINUE;
set_pev(ent, pev_classname, "fake_bazooka")
set_pev(ent, pev_owner, id)
new Float:mins[3] = { -16.0, -16.0, -16.0 }
new Float:maxs[3] = { 16.0, 16.0, 16.0 }
engfunc(EngFunc_SetSize, ent, mins, maxs)
set_pev(ent, pev_solid, SOLID_TRIGGER)
set_pev(ent, pev_movetype, MOVETYPE_TOSS)
set_pev(ent, pev_iuser3, rocket_ready[id] ? 1 : 0)
set_pev(ent, pev_iuser4, have_rocket_num[id])
new Float:origin[3], Float:aim[3]
pev(id, pev_origin, origin)
velocity_by_aim(id, 64, aim)
origin[0] += aim[0]
origin[1] += aim[1]
set_pev(ent, pev_origin, origin)
engfunc(EngFunc_SetModel, ent, BAZOOKA_W_MDL)
clear_var_set(id)
if (!get_pcvar_num(cvar_KeyBind))
client_cmd(id, "unbind F2")
return PLUGIN_CONTINUE;
}
public remove_bazooka()
{
new ent = fm_find_ent_by_class(-1, "fake_bazooka")
while(ent)
{
engfunc(EngFunc_RemoveEntity, ent)
ent = fm_find_ent_by_class(ent, "fake_bazooka")
}
}
public zp_round_ended(winteam)
{
end_round = true
}
public zp_user_infected_pre(id, infector)
{
if (has_bazooka[id])
drop_bazooka(id)
}
public client_connect(id)
{
clear_var_set(id)
}
public client_disconnect(id)
{
clear_var_set(id)
}
public player_die()
{
new id = read_data(2)
if (!(1 <= id <= maxplayers))
return;
if (has_bazooka[id])
drop_bazooka(id)
}
public event_round_start()
{
end_round = false
if (get_pcvar_num(cvar_OneRound))
{
for (new i = 1; i <= 32; i++)
{
if (has_bazooka
)
{
if (!get_pcvar_num(cvar_KeyBind))
client_cmd(i, "unbind F2")
}
if (is_user_alive(i) && activated)
{
new weapon, clip, ammo
weapon = get_user_weapon(i, clip, ammo)
if (weapon == CSW_KNIFE)
set_use_knife(i)
}
clear_var_set(i)
}
}
remove_bazooka();
}
public clear_var_set(id)
{
has_bazooka[id] = false
activated[id] = false
have_rocket_num[id] = 0
rocket_ready[id] = false
reload_rocket[id] = false
user_weapon[id] = 0
}
stock rocket_radius_damage(attacker, origin[3])
{
new target_origin[3]
new max_dmgrange = get_pcvar_num(cvar_DamageRange)
for (new i = 1; i <= maxplayers; i++)
{
if (!is_user_alive(i))
continue;
if (!get_pcvar_num(cvar_DamageHuman) && !zp_get_user_zombie(i))
continue;
get_user_origin(i, target_origin)
new dist = get_distance(origin, target_origin)
if (dist > max_dmgrange)
continue;
new damage, temp
damage = get_pcvar_num(cvar_MaxDamage)
temp = damage - get_pcvar_num(cvar_MinDamage)
damage -= floatround(float(temp) * float(dist) / float(max_dmgrange))
new Float:fOrigin[3]
IVecFVec(target_origin, fOrigin)
particle_burst_effect(fOrigin)
new Float:fVelocity[3]
new power = Explosoin_Knockback_Power
if (power > 0)
{
get_speed_vector_point_entity(fOrigin, i, power, fVelocity)
set_pev(i, pev_velocity, fVelocity)
}
damage_user(i, attacker, damage, DMG_BLAST)
}
}
stock damage_user(victim, attacker, damage, damage_type)
{
if (!zp_get_user_zombie(victim))
{
if (zp_get_user_survivor(victim))
damage = floatround(float(damage) * Damage_Survivor_Multiplier)
else
damage = floatround(float(damage) * Damage_Human_Multiplier)
new armor = get_user_armor(victim)
if (armor > 0)
{
new Float:armor_dmg_multi = (3.0 / 4.0) //设定在护甲数值的减损和血量的减损,比例为(3:1)
new armor_damage = floatround(float(damage) * armor_dmg_multi)
if (armor >= armor_damage)
{
fm_set_user_armor(victim, armor - armor_damage)
damage -= armor_damage
}
else
{
fm_set_user_armor(victim, 0)
damage -= armor
}
}
}
if (damage < 0) damage = 0
new hp = get_user_health(victim)
if (hp > damage)
fm_fakedamage(victim, "Rocket", float(damage), damage_type)
else
log_kill(attacker, victim, 0, "Rocket")
}
stock log_kill(killer, victim, headshot, weapon[])
{
new killer_frags = get_user_frags(killer)
new killer_ammopack = zp_get_user_ammo_packs(killer)
set_msg_block(get_user_msgid("DeathMsg"), BLOCK_SET)
ExecuteHamB(Ham_Killed, victim, killer, 2) // set last param to 2 if you want victim to gib
set_msg_block(get_user_msgid("DeathMsg"), BLOCK_NOT)
SendDeathMsg(killer, victim, headshot, weapon)
if (get_user_team(killer) == get_user_team(victim))
{
killer_frags -= get_pcvar_num(cvar_TeamKillFrags)
killer_ammopack = max(killer_ammopack - get_pcvar_num(cvar_TeamKillAmmopack), 0)
}
else
{
killer_frags += get_pcvar_num(cvar_KilledFrags)
killer_ammopack += get_pcvar_num(cvar_KilledAmmopack)
}
fm_set_user_frags(killer, killer_frags)
zp_set_user_ammo_packs(killer, killer_ammopack)
FixDeadAttrib(victim)
Update_ScoreInfo(victim, get_user_frags(victim), get_user_deaths(victim))
FixDeadAttrib(killer)
Update_ScoreInfo(killer, get_user_frags(killer), get_user_deaths(killer))
new k_name[32], v_name[32], k_authid[32], v_authid[32], k_team[10], v_team[10]
get_user_name(killer, k_name, charsmax(k_name))
get_user_team(killer, k_team, charsmax(k_team))
get_user_authid(killer, k_authid, charsmax(k_authid))
get_user_name(victim, v_name, charsmax(v_name))
get_user_team(victim, v_team, charsmax(v_team))
get_user_authid(victim, v_authid, charsmax(v_authid))
log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"",
k_name, get_user_userid(killer), k_authid, k_team,
v_name, get_user_userid(victim), v_authid, v_team, weapon)
}
stock fm_find_ent_by_class(index, const classname[])
{
return engfunc(EngFunc_FindEntityByString, index, "classname", classname)
}
stock fm_fakedamage(victim, const classname[], Float:takedmgdamage, damagetype)
{
new class[] = "trigger_hurt";
new entity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, class));
if (!entity)
return 0;
new value[16];
float_to_str(takedmgdamage * 2, value, sizeof value - 1);
fm_set_kvd(entity, "dmg", value, class);
num_to_str(damagetype, value, sizeof value - 1);
fm_set_kvd(entity, "damagetype", value, class);
fm_set_kvd(entity, "origin", "8192 8192 8192", class);
dllfunc(DLLFunc_Spawn, entity);
set_pev(entity, pev_classname, classname);
dllfunc(DLLFunc_Touch, entity, victim);
engfunc(EngFunc_RemoveEntity, entity);
return 1;
}
stock fm_set_kvd(entity, const key[], const value[], const classname[] = "")
{
if (classname[0])
{
set_kvd(0, KV_ClassName, classname);
}
else
{
new class[32];
pev(entity, pev_classname, class, sizeof class - 1);
set_kvd(0, KV_ClassName, class);
}
set_kvd(0, KV_KeyName, key);
set_kvd(0, KV_Value, value);
set_kvd(0, KV_fHandled, 0);
return dllfunc(DLLFunc_KeyValue, entity, 0);
}
stock fm_set_user_armor(index, armor)
{
set_pev(index, pev_armorvalue, float(armor));
return 1;
}
stock fm_set_user_frags(index, frags)
{
set_pev(index, pev_frags, float(frags));
return 1;
}
/*
stock fm_force_use(user, used)
{
return dllfunc(DLLFunc_Use, used, user)
}
*/
stock fm_get_aim_vector(index, view_distance, Float:view_vector[3], Float:view_origin[3])
{
new Float:start[3], Float:view_ofs[3];
pev(index, pev_origin, start);
pev(index, pev_view_ofs, view_ofs);
xs_vec_add(start, view_ofs, start);
new Float:vector[3];
pev(index, pev_v_angle, vector);
engfunc(EngFunc_MakeVectors, vector);
global_get(glb_v_forward, vector);
xs_vec_mul_scalar(vector, float(view_distance), view_vector);
xs_vec_add(start, view_vector, view_origin);
return 1;
}
stock get_forward_view_dist(id)
{
new iOrigin1[3], iOrigin2[3]
get_user_origin(id, iOrigin1, 0)
get_user_origin(id, iOrigin2, 3)
new dist = get_distance(iOrigin1, iOrigin2)
return dist;
}
stock bool:is_use_shield(id)
{
new model[64]
pev(id, pev_viewmodel2, model, charsmax(model))
if (containi(model, "v_shield_") != -1)
return true;
return false;
}
stock bool:is_use_bazooka(id)
{
new model[64]
pev(id, pev_viewmodel2, model, charsmax(model))
if (equal(model[7], BAZOOKA_V_MDL[7]))
return true;
return false;
}
stock SendWeaponAnim(id, iAnim)
{
set_pev(id, pev_weaponanim, iAnim)
message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, _, id)
write_byte(iAnim)
write_byte(pev(id, pev_body))
message_end()
}
stock fm_find_ent_by_owner(entity, const classname[], owner)
{
while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", classname)) && (pev(entity, pev_owner) != owner)) {}
return entity;
}
stock set_weapon_next_pri_attack(entity, Float:time)
{
set_pdata_float(entity, OFFSET_FlNextPrimaryAttack, time, OFFSET_LINUX_WEAPONS)
}
stock set_weapon_next_sec_attack(entity, Float:time)
{
set_pdata_float(entity, OFFSET_FlNextSecondaryAttack, time, OFFSET_LINUX_WEAPONS)
}
stock get_speed_vector_point_entity(const Float:point[3], ent, speed, Float:new_velocity[3])
{
if(!pev_valid(ent))
return 0;
static Float:origin[3]
pev(ent, pev_origin, origin)
new_velocity[0] = origin[0] - point[0];
new_velocity[1] = origin[1] - point[1];
new_velocity[2] = origin[2] - point[2];
static Float:num
num = float(speed) / vector_length(new_velocity);
new_velocity[0] *= num;
new_velocity[1] *= num;
new_velocity[2] *= num;
return 1;
}
stock particle_burst_effect(const Float:originF[3])
{
// Particle burst
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_PARTICLEBURST) // TE id
engfunc(EngFunc_WriteCoord, originF[0]) // x
engfunc(EngFunc_WriteCoord, originF[1]) // y
engfunc(EngFunc_WriteCoord, originF[2]) // z
write_short(50) // radius
write_byte(70) // color
write_byte(3) // duration (will be randomized a bit)
message_end()
}
stock FixDeadAttrib(id) // Fix Dead Attrib on scoreboard
{
message_begin(MSG_BROADCAST, get_user_msgid("ScoreAttrib"))
write_byte(id) // id
write_byte(0) // attrib
message_end()
}
stock Update_ScoreInfo(id, frags, deaths) // Update Player's Frags and Deaths
{
// Update scoreboard with attacker's info
message_begin(MSG_BROADCAST, get_user_msgid("ScoreInfo"))
write_byte(id) // id
write_short(frags) // frags
write_short(deaths) // deaths
write_short(0) // class?
write_short(get_user_team(id)) // team
message_end()
}
stock SendDeathMsg(attacker, victim, headshot, const weapon[]) // Send Death Message
{
message_begin(MSG_BROADCAST, get_user_msgid("DeathMsg"))
write_byte(attacker) // killer
write_byte(victim) // victim
write_byte(headshot) // headshot flag [1 or 0]
write_string(weapon) // killer's weapon
message_end()
}
stock create_beam_follow(entity, sprite_id, life, width, red, green, blue, brightness)
{
//Entity add colored trail
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BEAMFOLLOW) // TE id (22)
write_short(entity) // entity
write_short(sprite_id) // sprite id
write_byte(life) // life
write_byte(width) // width
write_byte(red) // r
write_byte(green) // g
write_byte(blue) // b
write_byte(brightness) // brightness
message_end()
}
stock create_explosion(const position[3], sprite_id)
{
// Additive sprite, 2 dynamic lights, flickering particles, explosion sound, move vertically 8 pps
message_begin(MSG_BROADCAST, SVC_TEMPENTITY, position)
write_byte(TE_EXPLOSION) // TE id (3)
write_coord(position[0]) // position.x
write_coord(position[1]) // position.y
write_coord(position[2]) // position.z
write_short(sprite_id) // sprite index
write_byte(30) // scale in 0.1's
write_byte(15) // framerate
write_byte(0) // flags
message_end()
}
stock create_beamcylinder(const position[3], sprite_id)
{
// Cylinder that expands to max radius over lifetime
message_begin(MSG_ALL, SVC_TEMPENTITY, position)
write_byte(TE_BEAMCYLINDER) // TE id (21)
write_coord(position[0]) // position.x
write_coord(position[1]) // position.y
write_coord(position[2]) // position.z
write_coord(position[0]) // x axis
write_coord(position[1]) // y axis
//write_coord(position[2]+200) // z axis
write_coord(position[2]+get_pcvar_num(cvar_DamageRange)) // z axis
write_short(sprite_id) // sprite index
write_byte(0) // startframe
write_byte(1) // framerate
write_byte(6) // life
write_byte(8) // width
//write_byte(1) // noise
write_byte(0) // noise
write_byte(255) // red
write_byte(255) // green
write_byte(192) // blue
write_byte(128) // brightness
write_byte(5) // speed
message_end()
}
/*
stock kill_beam(entity)
{
// Kill all beams attached to entity
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_KILLBEAM) // TE id: 99
write_short(entity)
message_end()
}
*/[/code]