搜索
查看: 19993|回复: 116

【分享】火箭筒插件及制作心得 2005-2-10

[复制链接]
发表于 2005-2-10 15:38:17 | 显示全部楼层 |阅读模式 来自 陕西西安
其实这个插件以前有人发过的,下面是地址
amxx 1.0 的
http://www.dt-club.net/showthread.php?t=16486
amx 0.99的
http://www.dt-club.net/showthread.php?t=16771

但是今天给大家带来的是我修改了的,使之有了上面两种插件的功能
玩家可通 say /buy_bazooka 来购买火箭筒
可通过买主要武器的按键来买火箭筒的弹药进行弹药补充

通过半天的研究,发现这个fakemeta是个好东西啊,以下面的代码给大家讲讲
[PHP]/* AMX Mod X script

:: Adds a Bazooka to CS ::

Usage:
        Type amx_bazooka in the console to drop a bazooka (admin only)
Cvars:
        amx_bazooka_drop :: can a player drop his bazooka?? (default: 1)
        amx_bazooka_ammo :: how much ammo has the bazooka?? (default: 3)
        amx_bazooka_damageradius :: which damageradius should the bazooka have?? (default: 1000)
        amx_bazooka_maxdamage :: when you are in the center of the detonation, how much HP do you loose?? (default: 150)
Known bugs:
        When you spectate a person who has the bazooka in his/her hand and the
        round is over or you killed yourself with the bazooka then the model of
        your current weapon is the model of the bazooka but you don't have it.
        You have to select another weapon then your weaponmodel changed back.
Special thanks to:
        KaOs
        RadidEskimo
        Freecode
        EJL
        JTP10181
        PaintLancer
        Kaddar
        Vexd
        twistedeuphoria
        XxAvalanchexX
        pimp daddy
        Ronkkrop
*/
#include <amxmodx>
#include <fakemeta>
#include <engine>
#include <fun>
#include <cstrike>
#include <amxmisc>

new explosion, smoke, white //效果的一些变量
new g_bazooka_num //全局火箭筒数量
new bool:CanShoot[33] //是否可以发射火箭筒
new bool:buy_in_time //是否在购买时间内
new bool:have_bazooka[33] //玩家是否持有火箭筒
new Munni[33] //玩家的弹药数

public plugin_init() {
register_plugin("Bazooka", "0.8+", "More | nwb13")
register_clcmd("amx_bazooka", "drop_rpg", ADMIN_KICK, "") //管理员给与火箭筒的命令
//注册参数
register_cvar("amx_bazooka_drop", "1") //是否可以扔掉火箭筒
register_cvar("amx_bazooka_num", "4") //火箭筒存在的最大数量
register_cvar("amx_bazooka_ammo", "2") //火箭筒的弹药数量
register_cvar("amx_bazooka_damageradius", "1000") //火箭筒的伤害范围
register_cvar("amx_bazooka_maxdamage", "150") //火箭筒的伤害值
register_cvar("amx_bazooka_price", "10000") //火箭筒的价格
register_cvar("amx_bazooka_ammoprice", "1000") //弹药的价格
register_cvar("amx_bazooka_reloadtime", "4.0") //更换弹药的时间间隔
if (find_ent_by_class(-1, "func_bomb_target") == 0) { //检测地图里是否有埋雷点,有的话则跳过,没有则注册下面的命令
register_clcmd("say /buy_bazooka", "buy_bazooka") //玩家购买的命令
register_clcmd("buyammo1","buy_bazooka_ammo") //玩家购买弹药的命令
register_event("DeathMsg", "player_die", "a") //注册死亡事件
register_event("ResetHUD", "new_round", "b") //注册新开局事件
register_event("CurWeapon", "check_model", "be") //注册当前持有的武器事件
register_event("TextMsg","on_RoundRestart","a","2&#Game_will_restart_in") //注册游戏刷新事件
//register_event("TextMsg", "on_RoundRestart", "a", "2&#Game_C")

register_clcmd("drop", "handle_drop") //玩家仍武器的命令

register_forward(FM_PlayerPreThink, "forward_playerprethink") //注册一个函数和玩家的动作相关联
register_forward(FM_SetModel, "forward_setmodel") //注册一个函数和玩家的模型相关联
}
}

public plugin_precache() {
precache_model("models/rpgrocket.mdl")
precache_model("models/w_rpg.mdl")
precache_model("models/v_rpg.mdl")
precache_model("models/p_rpg.mdl")
precache_sound("weapons/rocketfire1.wav")
precache_sound("weapons/nuke_fly.wav")
precache_sound("weapons/mortarhit.wav")
precache_sound("weapons/dryfire_rifle.wav")
explosion = precache_model("sprites/fexplo.spr")
smoke = precache_model("sprites/steam1.spr")
white = precache_model("sprites/white.spr")
}

public buy_bazooka(id){
if (!is_user_alive(id)){ //玩家是否死亡
client_print(id,print_chat,"[火箭筒]: 死亡的时候不能购买火箭筒.")
return PLUGIN_HANDLED
}
if (have_bazooka[id]){ //玩家是否拥有火箭筒
client_print(id,print_chat,"[火箭筒]: 你已经购买了火箭筒.")
return PLUGIN_HANDLED
}
if (!buy_in_time){ //是否在购买时间内
client_print(id,print_chat,"[火箭筒]: 你已经超过了购买时间, 下局再买吧.")
return PLUGIN_HANDLED
}
if(cs_get_user_money(id) >= get_cvar_num("amx_bazooka_price")){ //价格检测
if(g_bazooka_num >= get_cvar_num("amx_bazooka_num")){ //火箭筒数量检测
client_print(id,print_chat,"[火箭筒]: 火箭筒已经卖完了, 下局再买吧.")
return PLUGIN_HANDLED
}
cs_set_user_money(id,cs_get_user_money(id)-get_cvar_num("amx_bazooka_price"))
g_bazooka_num++
give_item(id, "weapon_c4") //这个就是火箭筒,只不过被改了模型外观,也就是为什么不能在放置C4的地图上玩火箭筒的原因
have_bazooka[id] = true
CanShoot[id] = true
Munni[id] = get_cvar_num("amx_bazooka_ammo")
new name[32]
get_user_name(id,name,31)
client_print(0, print_chat, "[火箭筒]: %s 购买了火箭筒!",name)
client_print(id, print_chat, "[火箭筒]: 您可按 ^"5^" 切换为火箭筒!",name)
}else{
client_print(id, print_chat, "[火箭筒]: 火箭筒价格为 $%d, 您没有足够的钱购买火箭筒!",get_cvar_num("amx_bazooka_price"))
}
return PLUGIN_HANDLED
}

public buy_bazooka_ammo(id){ //购买弹药
engclient_cmd(id,"buyammo1")
if (!is_user_alive(id)||!have_bazooka[id]||!is_user_connected(id)){ //检测玩家的状态
if (!buy_in_time) //检测时间
return PLUGIN_CONTINUE
return PLUGIN_CONTINUE
}
if(cs_get_user_money(id) >= get_cvar_num("amx_bazooka_ammoprice")){ /检测金钱
if (!buy_in_time) //检测时间
return PLUGIN_CONTINUE
if (Munni[id] >= get_cvar_num("amx_bazooka_ammo"))
return PLUGIN_CONTINUE
give_item(id, "item_longjump") //给与弹药,这是我自己加的,纯粹为了为了效果
Munni[id]++
cs_set_user_money(id,cs_get_user_money(id)-get_cvar_num("amx_bazooka_ammoprice"))
}
return PLUGIN_CONTINUE
}

public fire_rocket(id) { //火箭筒开火
if (Munni[id] <= 0) { //弹药检测
        client_print(id,print_center,"火箭筒的弹药用光了")
        emit_sound(id, CHAN_WEAPON, "weapons/dryfire_rifle.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
        return PLUGIN_HANDLED
}
if (!CanShoot[id] && Munni[id] > 0){
        client_print(id, print_center, "火箭筒还没有装填完毕")
        return PLUGIN_HANDLED
}
new Float:StartOrigin[3], Float:Angle[3]
new PlayerOrigin[3]
get_user_origin(id, PlayerOrigin, 1) //获得玩家的当前坐标作为子弹的初始位置
StartOrigin[0] = float(PlayerOrigin[0])
StartOrigin[1] = float(PlayerOrigin[1])
StartOrigin[2] = float(PlayerOrigin[2])
entity_get_vector(id, EV_VEC_v_angle, Angle) //获得玩家的瞄准角度
Angle[0] = Angle[0] * -1.0
new RocketEnt = create_entity("info_target") //建立子弹
entity_set_string(RocketEnt, EV_SZ_classname, "bazooka_rocket")
entity_set_model(RocketEnt, "models/rpgrocket.mdl") //子弹的模型
entity_set_origin(RocketEnt, StartOrigin) //子弹的位置
entity_set_vector(RocketEnt, EV_VEC_angles, Angle) //子弹的角度
new Float:MinBox[3] = {-1.0, -1.0, -1.0}
new Float:MaxBox[3] = {1.0, 1.0, 1.0}
entity_set_vector(RocketEnt, EV_VEC_mins, MinBox)
entity_set_vector(RocketEnt, EV_VEC_maxs, MaxBox)
entity_set_int(RocketEnt, EV_INT_solid, 2)
entity_set_int(RocketEnt, EV_INT_movetype, 5)
entity_set_edict(RocketEnt, EV_ENT_owner, id) //子弹的主人
new Float:Velocity[3]
VelocityByAim(id, 1000, Velocity) //子弹的终点坐标
entity_set_vector(RocketEnt, EV_VEC_velocity, Velocity)
emit_sound(RocketEnt, CHAN_WEAPON, "weapons/rocketfire1.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
emit_sound(RocketEnt, CHAN_VOICE, "weapons/nuke_fly.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
CanShoot[id] = false
client_print(id,print_center,"正在重新装填火箭筒")
new data[1]
data[0] = id
set_task(get_cvar_float("amx_bazooka_reloadtime"), "bazooka_reload", id+9477, data, 1) //作切换弹药,虽然表面上看不见,呵呵
ammo_hud(id, 0)
Munni[id]-- //弹药减少
return PLUGIN_HANDLED
}

public bazooka_reload(data[]) { //弹药重装填
if (is_user_alive(data[0]) && have_bazooka[data[0]]){
        client_print(data[0],print_center,"装填火箭筒完毕")
        CanShoot[data[0]] = true
        ammo_hud(data[0], 1)
}
}

public pfn_touch(ptr, ptd) { //当两目标接触时,注意:cs里所有的东西都可以看成是目标
new ClassName[32]
if (ptr > 0) {
        entity_get_string(ptr, EV_SZ_classname, ClassName, 31) //目标1 的名字
}
if (equal(ClassName, "bazooka_rocket")) {
        new Float:EndOrigin[3]
        entity_get_vector(ptr, EV_VEC_origin, EndOrigin) //获得当前的坐标
        emit_sound(ptr, CHAN_WEAPON, "weapons/mortarhit.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
        emit_sound(ptr, CHAN_VOICE, "weapons/mortarhit.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
        //以下是爆炸的效果
        message_begin(MSG_BROADCAST, SVC_TEMPENTITY) // Feuerball
        write_byte(17)
        write_coord(floatround(EndOrigin[0]))
        write_coord(floatround(EndOrigin[1]))
        write_coord(floatround(EndOrigin[2]) + 128)
        write_short(explosion)
        write_byte(60)
        write_byte(255)
        message_end()
        message_begin(MSG_BROADCAST, SVC_TEMPENTITY) // Rauchwolke
        write_byte(5)
        write_coord(floatround(EndOrigin[0]))
        write_coord(floatround(EndOrigin[1]))
        write_coord(floatround(EndOrigin[2]) + 256)
        write_short(smoke)
        write_byte(125)
        write_byte(5)
        message_end()
        new maxdamage = get_cvar_num("amx_bazooka_maxdamage")
        new damageradius = get_cvar_num("amx_bazooka_damageradius")
        new PlayerPos[3], distance, damage
        for (new i = 1; i < 32; i++) { //检测有多少玩家在伤害范围内
         if (is_user_alive(i) == 1) {
                get_user_origin(i, PlayerPos)
                new NonFloatEndOrigin[3]
                NonFloatEndOrigin[0] = floatround(EndOrigin[0])
                NonFloatEndOrigin[1] = floatround(EndOrigin[1])
                NonFloatEndOrigin[2] = floatround(EndOrigin[2])
                distance = get_distance(PlayerPos, NonFloatEndOrigin)
                if (distance <= damageradius) { // Schadensradius
                 message_begin(MSG_ONE, get_user_msgid("ScreenShake"), {0,0,0}, i) // 屏幕震动效果
                 write_short(1<<14)
                 write_short(1<<14)
                 write_short(1<<14)
                 message_end()
                 damage = maxdamage - floatround(floatmul(float(maxdamage), floatdiv(float(distance), float(damageradius)))) //视距离远近作伤害值判断
                 new attacker = entity_get_edict(ptr, EV_ENT_owner) //获得攻击者

                 if (!get_user_godmode(i)) { //玩家是否在无敌状态
                        if (get_user_team(attacker) != get_user_team(i)) { //攻击者和受伤者的队伍检测
                         if (damage < get_user_health(i)) { //如伤害小于生命值则扣除对应的伤害
                                set_user_health(i, get_user_health(i) - damage)
                         }
                         else { //否则玩家死亡
                                set_msg_block(get_user_msgid("DeathMsg"), BLOCK_SET)
                                user_kill(i, 1)
                                set_msg_block(get_user_msgid("DeathMsg"), BLOCK_NOT)
                                message_begin(MSG_BROADCAST, get_user_msgid("DeathMsg")) // 做一个假的死亡信息
                                write_byte(attacker) // 攻击者
                                write_byte(i) // 受害者
                                write_byte(0) // 是否爆头
                                write_string("bazooka") //使用的武器
                                message_end()
                                set_user_frags(attacker, get_user_frags(attacker) + 1) //玩家的得分
                         }
                        }
                        else { //下面和上面基本相同,就不再说明了
                         if (attacker == i) {
                                if (damage < get_user_health(i)) {
                                 set_user_health(i, get_user_health(i) - damage)
                                }
                                else {
                                 set_msg_block(get_user_msgid("DeathMsg"), BLOCK_SET)
                                 user_kill(i, 1)
                                 set_msg_block(get_user_msgid("DeathMsg"), BLOCK_NOT)
                                 message_begin(MSG_BROADCAST, get_user_msgid("DeathMsg")) // Kill-Log oben rechts
                                 write_byte(attacker) // Attacker
                                 write_byte(i) // Victim
                                 write_byte(0) // Headshot
                                 write_string("bazooka")
                                 message_end()
                                 set_user_frags(attacker, get_user_frags(attacker) - 1)
                                }
                         }
                         else {
                                if (get_cvar_num("mp_friendlyfire")) {
                                 if (damage < get_user_health(i)) {
                                        set_user_health(i, get_user_health(i) - damage)
                                        client_print(attacker, print_center, "你伤害了自己的队友!")
                                 }
                                 else {
                                        set_msg_block(get_user_msgid("DeathMsg"), BLOCK_SET)
                                        user_kill(i, 1)
                                        set_msg_block(get_user_msgid("DeathMsg"), BLOCK_NOT)
                                        message_begin(MSG_BROADCAST, get_user_msgid("DeathMsg")) // Kill-Log oben rechts
                                        write_byte(attacker) // Attacker
                                        write_byte(i) // Victim
                                        write_byte(0) // Headshot
                                        write_string("bazooka")
                                        message_end()
                                        set_user_frags(attacker, get_user_frags(attacker) - 1)
                                        client_print(attacker, print_center, "你杀害了自己的队友!")
                                 }
                                }
                         }
                        }
                 }
                }
         }
        }
        message_begin(MSG_BROADCAST, SVC_TEMPENTITY) // Druckwelle
        write_byte(21)
        write_coord(floatround(EndOrigin[0]))
        write_coord(floatround(EndOrigin[1]))
        write_coord(floatround(EndOrigin[2]))
        write_coord(floatround(EndOrigin[0]))
        write_coord(floatround(EndOrigin[1]))
        write_coord(floatround(EndOrigin[2]) + 320)
        write_short(white)
        write_byte(0)
        write_byte(0)
        write_byte(16)
        write_byte(128)
        write_byte(0)
        write_byte(255)
        write_byte(255)
        write_byte(192)
        write_byte(128)
        write_byte(0)
        message_end()
        remove_entity(ptr) //删除目标1
}
if (equal(ClassName, "bazooka_droped")) { //检测玩家是否接触到了地上的火箭筒
        new Picker[32]
        if (ptd > 0) {
         entity_get_string(ptd, EV_SZ_classname, Picker, 31)
        }
        if (equal(Picker, "player")) { //检测目标2是否是游戏中的玩家
         give_item(ptd, "weapon_c4") //给与火箭筒,其实就是c4,模型不同而已
         Munni[ptd] = entity_get_int(ptr, EV_INT_iuser1) // 获得武器的残余弹药
         CanShoot[ptd] = true
         have_bazooka[ptd] = true
         remove_entity(ptr) // 删除目标1
        }
}
}

public drop_rpg(id, level, cid) { //管理员给与火箭筒
if (!cmd_access(id, level, cid, 1)) {
        return PLUGIN_HANDLED
}
if (find_ent_by_class(-1, "func_bomb_target") != 0) { //检测地图
        client_print(id, print_console, "你不能在埋包的地图上丢弃你的火箭筒!!")
        return PLUGIN_HANDLED
}
if(g_bazooka_num >= get_cvar_num("amx_bazooka_num")){ /检测火箭筒的数量
        client_print(id,print_chat,"[火箭筒]: 已经有 %d 个火箭筒了, 达到最大数量!", g_bazooka_num)
        return PLUGIN_HANDLED
}
new Float:PlayerOrigin[3], Float:End[3], Float:Return[3], Float:TraceDirection[3]
//以下大家可以和上面的对照,意思是一样的
entity_get_vector(id, EV_VEC_origin, PlayerOrigin)
VelocityByAim(id, 64, TraceDirection)
End[0] = TraceDirection[0] + PlayerOrigin[0]
End[1] = TraceDirection[1] + PlayerOrigin[1]
End[2] = TraceDirection[2] + PlayerOrigin[2]
trace_line(id, PlayerOrigin, End, Return)
Return[2] = PlayerOrigin[2]
new RPG = create_entity("info_target")
entity_set_string(RPG, EV_SZ_classname, "bazooka_droped")
entity_set_model(RPG, "models/w_rpg.mdl")
entity_set_origin(RPG, Return)
new Float:MinBox[3] = {-16.0, -16.0, 0.0}
new Float:MaxBox[3] = {16.0, 16.0, 16.0}
entity_set_vector(RPG, EV_VEC_mins, MinBox)
entity_set_vector(RPG, EV_VEC_maxs, MaxBox)
entity_set_int(RPG, EV_INT_solid, 1)
entity_set_int(RPG, EV_INT_movetype, 6)
entity_set_int(RPG, EV_INT_iuser1, get_cvar_num("amx_bazooka_ammo")) // Schuss im Raketenwerfer
g_bazooka_num++
return PLUGIN_HANDLED
}

//到了最有意思的部分了
public forward_playerprethink(id) { //实时检测玩家的动作
if (is_user_alive(id)) {
if (entity_get_int(id, EV_INT_button) & IN_ATTACK) { //是否是开火的动作
new weaponid, clip, ammo
weaponid = get_user_weapon(id, clip, ammo)
if (weaponid == CSW_C4 && have_bazooka[id]) { //检测是否是火箭筒
        if (CanShoot[id]) {
         fire_rocket(id) //火箭筒开火
         //client_print(id, print_center, "")
         return FMRES_IGNORED
        }
}
}
}
return FMRES_IGNORED
}

//这段同样和有意思
public forward_setmodel(entity, model[]) { //设置玩家的模型
if (!is_valid_ent(entity)) {
        return FMRES_IGNORED
}
if (equal(model, "models/w_backpack.mdl")) {
        //client_print(0, print_center, "")
        new ClassName[32]
        entity_get_string(entity, EV_SZ_classname, ClassName, 31)
        if (equal(ClassName, "weaponbox")) { //为了检测玩家的背上是否出现了C4包
         remove_entity(entity) //移除这个包的效果
         return FMRES_SUPERCEDE
        }
}
return FMRES_IGNORED
}

//这段是作者的小聪明,呵呵,用火箭筒的模型替换C4的模型
public check_model(id) { //当切换武器时执行这段代码
new weaponid, clip, ammo
weaponid = get_user_weapon(id, clip, ammo)
if (weaponid == CSW_C4 && have_bazooka[id]) {
        ammo_hud(id, 1)
        entity_set_string(id, EV_SZ_viewmodel, "models/v_rpg.mdl") //别人看到的样子
        entity_set_string(id, EV_SZ_weaponmodel, "models/p_rpg.mdl") //自己屏幕上看到的样子
        if(!CanShoot[id]){ //检测火箭筒是否装填完毕
         new data[1]
         data[0] = id
         set_task(get_cvar_float("amx_bazooka_reloadtime"), "bazooka_reload", id+9477, data, 1)
        }
}
else {
        ammo_hud(id, 0)
        if (task_exists(id+9477)){
         remove_task(id+9477)
         client_print(id,print_center,"")
        }
}
return PLUGIN_HANDLED
}

public client_connect(id) { //玩家连接入游戏的时候变量复位
have_bazooka[id] = false
CanShoot[id] = false
Munni[id] = 0
return PLUGIN_CONTINUE
}

public client_disconnect(id) { //玩家离开的时候对火箭筒数量检测
if (have_bazooka[id])
g_bazooka_num--
return PLUGIN_CONTINUE
}

ammo_hud(id, show) { //对玩家显示弹药量
new AmmoHud[33]
format(AmmoHud, 32, "弹药量: %i", Munni[id])
if (show) {
        message_begin(MSG_ONE, get_user_msgid("StatusText"), {0,0,0}, id)
        write_byte(0)
        write_string(AmmoHud)
        message_end()
}
else {
        message_begin(MSG_ONE, get_user_msgid("StatusText"), {0,0,0}, id)
        write_byte(0)
        write_string("")
        message_end()
}
}

public player_die() { //玩家死亡的时候
new victim
victim = read_data(2)
ammo_hud(victim, 0)
//Munni[victim] = 0
if (have_bazooka[victim]) //玩家是否持有火箭筒,有的话则掉落(其实不是掉落,是重新建立一个目标)
        drop_rpg_from_player(victim)
}

public on_RoundRestart(){ //刷新游戏的时候,对购买时间的影响
if (task_exists(9476))
remove_task(9476)
return PLUGIN_CONTINUE
}

public cant_buy()
buy_in_time = false

public new_round() { //新开局
buy_in_time = true
g_bazooka_num = 0
new TempRPG = find_ent_by_class(-1, "bazooka_droped")
while (TempRPG > 0) {
remove_entity(TempRPG) //删除留在地上的火箭筒
TempRPG = find_ent_by_class(TempRPG, "bazooka_droped")
}
new pln,plid[32]
get_players(plid,pln,"")
for (new i=0; i < pln; i++) //检测当前有多少玩家拥有火箭筒
if (have_bazooka[plid])
         g_bazooka_num++
set_task(get_cvar_float("mp_buytime")*60.0,"cant_buy",9476)
return PLUGIN_HANDLED
}

public handle_drop(id) { //玩家仍武器时的检测
if (read_argc() > 1) {
        new weapon[17]
        read_argv(1, weapon, 16)
        if (equal(weapon, "weapon_c4")) {
         new weapons[32], count
         get_user_weapons(id, weapons, count)
         for (new i = 0; i < count; i++) {
                if (weapons == CSW_C4) {
                 if (get_cvar_num("amx_bazooka_drop") == 1) {
                        drop_rpg_from_player(id)
                 }
                 else {
                        client_print(id, print_center, "这个武器是不能丢弃的")
                        return PLUGIN_HANDLED
                 }
                }
         }
        }
}
else {
        new weaponid, clip, ammo
        weaponid = get_user_weapon(id, clip, ammo)
        if (weaponid == CSW_C4 && have_bazooka[id]) {
         if (get_cvar_num("amx_bazooka_drop") == 1) {
                drop_rpg_from_player(id)
         }
         else {
                client_print(id, print_center, "这个武器是不能丢弃的")
                return PLUGIN_HANDLED
         }
        }
}
return PLUGIN_CONTINUE
}

//所谓扔掉武器的实质就是重生,呵呵,还是和上面的对照来看,说明就不重复写了
public drop_rpg_from_player(id) {
new Float:PlayerOrigin[3], Float:End[3], Float:Return[3], Float:TraceDirection[3], Float:Angles[3]
entity_get_vector(id, EV_VEC_origin, PlayerOrigin)
entity_get_vector(id, EV_VEC_angles, Angles)
VelocityByAim(id, 96, TraceDirection)
End[0] = TraceDirection[0] + PlayerOrigin[0]
End[1] = TraceDirection[1] + PlayerOrigin[1]
End[2] = TraceDirection[2] + PlayerOrigin[2]
trace_line(id, PlayerOrigin, End, Return)
Return[2] = PlayerOrigin[2]
new RPG = create_entity("info_target") //建立新目标
entity_set_string(RPG, EV_SZ_classname, "bazooka_droped")
entity_set_model(RPG, "models/w_rpg.mdl")
entity_set_origin(RPG, Return)
Angles[0] = 0.0
Angles[2] = 0.0
entity_set_vector(RPG, EV_VEC_angles, Angles)
new Float:MinBox[3] = {-16.0, -16.0, 0.0}
new Float:MaxBox[3] = {16.0, 16.0, 16.0}
entity_set_vector(RPG, EV_VEC_mins, MinBox)
entity_set_vector(RPG, EV_VEC_maxs, MaxBox)
entity_set_int(RPG, EV_INT_solid, 1)
entity_set_int(RPG, EV_INT_movetype, 6)
entity_set_int(RPG, EV_INT_iuser1, Munni[id])
Munni[id] = 0 //把玩家以前弹药复位
have_bazooka[id] = false
return PLUGIN_HANDLED
}
[/PHP]

对比一下hornc的版本,他使用的是替换玩家的匕首,这样每张地图上都可以有火箭筒了,但是又来了新问题:玩家不能扔掉火箭筒了。由于hornc采用0.99的版本,所以不能使用fakemeta模块,这就使得插件不能对玩家的按键命令做判断,这也就是为什么hornc的版本里要强制给玩家绑定发射命令,但是这样也有个缺点,如玩家持有火箭筒时离开了游戏代码中想给玩家恢复原来的命令是不可能执行到的,应为此时玩家已经离开了游戏,我曾经也犯过这个错误,是给魔兽插件修改代码时测试发现的。

hornc用替换匕首的方法虽然可行但是人物模型上却有问题了,应为玩家使用匕首时的模型两手是分开的,且右手偏下,造成看起来玩家拿着火箭筒朝地上看,世界上不可能有完美的东西,我修改的也是一样,我的版本里的问题是,当玩家是右手持枪时,换c4出来会拿在左手,所以模型替换后,你会发现后箭筒是左手拿,弄的左右混淆,呵呵,这个有待大家继续研究了。

最后一些体会,看了好几个大插件的代码后,的确很有启示,例如死亡竞赛和这个的共同之处:物品的实现方式不是我们本来想的那样,都是重新生成的,给人的感觉都是假的,还有那个金钱无限的插件也是一样,给人假的视觉效果,呵呵,感觉写插件和造假一样了。最后就是物品的实现可以不择手段,呵呵,这个大家多看看代码就明白了。

今天就写这么多了,最后提供个我修改版本的代码,需要的下载附件,我接触插件的时间也不是很长,文中若有错误之处欢迎指正,最后希望对大家能有提示,为大家认识插件能指条路,以后就要靠自己了,希望更多人能投入插件的编写行列。

ps:作为CHM小组的一员,给大家说一句,如果你有能力,可以和我们联系,欢迎加入CHM小组

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注个册吧

×
 楼主| 发表于 2005-2-10 15:42:58 | 显示全部楼层 来自 陕西西安
为了写这个,花了我不少时间,设为资历帖是为了让资深的会员才能看见
如果你为了能看到帖子来灌水,那后果自负,请不要怪我,谢谢合作!
回复

使用道具 举报

发表于 2005-2-10 15:45:43 | 显示全部楼层 来自 香港
火箭筒插件....所有玩家都可以用XI?
回复

使用道具 举报

 楼主| 发表于 2005-2-10 15:51:10 | 显示全部楼层 来自 陕西西安
是的,默认最多可以有4个玩家购买
回复

使用道具 举报

发表于 2005-2-10 15:57:12 | 显示全部楼层 来自 湖南株洲
怎么要50呢?少一点吧
回复

使用道具 举报

 楼主| 发表于 2005-2-10 16:01:43 | 显示全部楼层 来自 陕西西安
Post by A082
怎么要50呢?少一点吧

你马上就可以看到了,努力吧,你看到后不会觉得失望的,我想那时你也就不会觉得50算高了
回复

使用道具 举报

发表于 2005-2-10 16:28:24 | 显示全部楼层 来自 福建厦门
fakemeta可能作很多东西的。我原来一直想怎么样让awp不能一枪毙命,结果也是用fakemeta解决的。
回复

使用道具 举报

 楼主| 发表于 2005-2-10 16:33:13 | 显示全部楼层 来自 陕西西安
Post by larnk
fakemeta可能作很多东西的。我原来一直想怎么样让awp不能一枪毙命,结果也是用fakemeta解决的。

的确,fakemeta扩展了不少,十分实用
回复

使用道具 举报

发表于 2005-2-10 17:38:10 | 显示全部楼层 来自 吉林长春
可惜amxx1.0还不稳定,性能连amxx0.2也不如,唉…………
回复

使用道具 举报

发表于 2005-2-10 20:43:50 | 显示全部楼层 来自 湖南株洲
Post by larnk
fakemeta可能作很多东西的。我原来一直想怎么样让awp不能一枪毙命,结果也是用fakemeta解决的。

能否传一下你的AWP不一枪毙命插件?
回复

使用道具 举报

游客
回复
您需要登录后才可以回帖 登录 | 注个册吧

快速回复 返回顶部 返回列表