hnroc 发表于 2004-12-15 10:07:20

[应求]修改火箭筒插件for amx0.9.9

本人一直用的是amx,并未接触amxx,所以此插件只适用amx0.9.9,低版本或amxx不适用。通过yhnba23提供的火箭筒amxx源代码,做了点修改,实现以下功能:
1、每张地图只有3枚火箭筒,玩家在买完后就只能捡火箭筒;
2、火箭筒价格为10000;
3、玩家通过say /buygun命令来购买火箭筒;
4、买到火箭筒后,玩家可以按3号键切换出火箭筒,弹药为2发(每回合开始系统自动补满2发),当发射1发炮弹后,会有5秒的换弹药时间,如果此时间内切换到其他武器,那么换弹时间将重算。
5、当拥有火箭筒的玩家被杀后,会掉出火箭筒,其他没有火箭筒的玩家可以去捡,捡到的火箭筒弹药为1发,下回合开始才会有2发。
6、当拥有火箭筒的玩家退出游戏,那么多出来的火箭筒将被系统回收,其他玩家又可以买了,始终保持每张地图3枚火箭筒;
7、适用版本:CS1.6(至于1.5我没测试,估计应该可以,但amx必须是0.9.9);
8、要想在0.9.8下使用此插件,感觉好象也可以,但必须修改命令。

源代码如下:

// Update by hnroc

#include <amxmod>
#include <amxmisc>
#include <vexd_utilities>

new explosion, smoke, white
new fire
new bool:CanShoot
new Munni
new gunnum

public plugin_precache() {
   precache_model("models/w_rpg.mdl")
   precache_model("models/v_rpg.mdl")
   precache_model("models/p_rpg.mdl")
   precache_model("models/rpgrocket.mdl")

   precache_sound("weapons/rocketfire1.wav")
   precache_sound("weapons/nuke_fly.wav")
   precache_sound("weapons/mortarhit.wav")
   precache_sound("weapons/dryfire_rifle.wav")
   precache_sound("items/gunpickup2")

   explosion = precache_model("sprites/fexplo.spr")
   smoke= precache_model("sprites/steam1.spr")
   white = precache_model("sprites/white.spr")
}


public plugin_init() {
   register_plugin("Bazooka", "1.0", "hnroc")
   register_clcmd("say /buygun","buy_rocket",0,"buy rocket") //此命令为购买火箭筒命令,如果可能您可以把它做到某个菜单里,这里就没做那么多了。
   register_clcmd("fire", "fire_rocket", 0, "") //此命令为发射命令。
   register_cvar("amx_bazooka_ammo", "2") //此命令为弹药数,OP可以在amx.cfg里追加此命令就可以修改弹药(下同)。
   register_cvar("amx_bazooka_damageradius", "500") //此命令为爆炸范围,数值越大,范围越宽,原插件默认为1000,我认为这个范围太大了,容易误伤到自己。
   register_cvar("amx_bazooka_maxdamage", "150") //此命令为打中的伤害值,如果在旁边爆炸,根据远近伤害会逐渐减少。
   register_cvar("amx_bazooka_money", "10000") //此命令为火箭筒价格。
   register_cvar("amx_bazooka_num", "3") //此命令为每张地图允许使用的火箭筒数。
   gunnum=get_cvar_num("amx_bazooka_num")
   register_event("ResetHUD","new_round", "be")
   register_event("DeathMsg","death_msg","a")
   return PLUGIN_CONTINUE
}

public buy_rucket(id){
   new a=get_user_money(id)
   if(get_user_money(id)>a){
      if(gunnum>0){
         set_user_money(id,get_user_money(id)-a)
         gunnum=gunnum-1
         fire=true
         CanShoot=true
         Munni=get_cvar_num("amx_bazooka_ammo")
         new name
         get_user_name(id,name,31)
         client_print(0, print_center, ": %s buy A Rocket!",name) //这里我写的是英文,OP可以自行去汉化,意思:**购买火箭筒一枚!。
      }
      else{
         client_print(id, print_center, ": You can't buy Rocket because NO ROCKET!") // 由于没有火箭筒了,所以您不能买火箭筒!
      }
   }
   else{
      new name
      get_user_name(id,name,31)
      client_print(id, print_center, ": You have not enough MONEY(>%d) to buy Rocket!",name,a) //您没有足够的钱买火箭筒>10000
   }
   return PLUGIN_CONTINUE
}

public death_msg()
{
   new victim=read_data(2)
   if(fire){
      fire=false
      CanShoot=false
      ammo_hud(victim, 0)
      Munni=0
      client_cmd(victim,"bind MOUSE1 +attack")
      drop_fire(victim)
   }
}

public drop_fire(victim){
   new Float: Origin, Float: Velocity
   Entvars_Get_Vector(victim, EV_VEC_origin, Origin)
   new dropgun = CreateEntity("info_target")
   Entvars_Set_String(dropgun, EV_SZ_classname, "fire_pickup")
   ENT_SetModel(dropgun, "models/w_rpg.mdl")
   new Float:MinBox = {-1.0, -1.0, -1.0}
   new Float:MaxBox = {1.0, 1.0, 1.0}
   Entvars_Set_Vector(dropgun, EV_VEC_mins, MinBox)
   Entvars_Set_Vector(dropgun, EV_VEC_maxs, MaxBox)
   ENT_SetOrigin(dropgun, Origin)
   Entvars_Set_Int(dropgun, EV_INT_effects, 32)
   Entvars_Set_Int(dropgun, EV_INT_solid, 1)
   Entvars_Set_Int(dropgun, EV_INT_movetype, 6)
   Entvars_Set_Edict(dropgun, EV_ENT_owner, victim)
   VelocityByAim(victim, 50 , Velocity)
   Entvars_Set_Vector(dropgun, EV_VEC_velocity ,Velocity)
   return PLUGIN_HANDLED
}

public new_round(id){
   if(fire){
      CanShoot=true
      Munni=get_cvar_num("amx_bazooka_ammo")
   }
   else{
      CanShoot=false
      Munni=0
   }
   return PLUGIN_CONTINUE
}

public entity_touch(entity1, entity2){
   new Classname
   Entvars_Get_String(entity1, EV_SZ_classname, Classname, 31)
   new Float: kOrigin
   Entvars_Get_Vector(entity1, EV_VEC_origin, kOrigin)
   if(equal(Classname,"fire_pickup")){
      new Class2
      Entvars_Get_String(entity2, EV_SZ_classname, Class2, 31)
      if(!fire){
         fire=true
         CanShoot=true
         Munni=1
         emit_sound(entity2, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
         RemoveEntity(entity1)
      }
   }
   new ClassNamee
   if (entity1 > 0) {
      entity_get_string(entity1, EV_SZ_classname, ClassNamee, 31)
   }
   if (equal(ClassNamee, "rpgrocket")) {
      new Float:EndOrigin
      entity_get_vector(entity1, EV_VEC_origin, EndOrigin)
      emit_sound(entity1, CHAN_WEAPON, "weapons/mortarhit.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
      emit_sound(entity1, 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))
      write_coord(floatround(EndOrigin))
      write_coord(floatround(EndOrigin) + 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))
      write_coord(floatround(EndOrigin))
      write_coord(floatround(EndOrigin) + 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, distance, damage
      for (new i = 1; i < 32; i++) {
         if (is_user_alive(i) == 1) {
            get_user_origin(i, PlayerPos)
            new NonFloatEndOrigin
            NonFloatEndOrigin = floatround(EndOrigin)
            NonFloatEndOrigin = floatround(EndOrigin)
            NonFloatEndOrigin = floatround(EndOrigin)
            distance = get_distance(PlayerPos, NonFloatEndOrigin)
            if (distance <= damageradius) {// Schadensradius
               message_begin(MSG_ONE, get_user_msgid("ScreenShake"), {0,0,0}, i)// Schtteln
               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(entity1, 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"))// 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)
                        if(get_user_money(attacker)>15700)
                           set_user_money(attacker,16000)
                        else
                           set_user_money(attacker,get_user_money(attacker)+300)
                     }
                  }
                  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, "You injured a teammate!")
                           }
                           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, "You killed a teammate!")
                           }
                        }
                     }
                  }
               }
            }
         }
      }
      message_begin(MSG_BROADCAST, SVC_TEMPENTITY)// Druckwelle
      write_byte(21)
      write_coord(floatround(EndOrigin))
      write_coord(floatround(EndOrigin))
      write_coord(floatround(EndOrigin))
      write_coord(floatround(EndOrigin))
      write_coord(floatround(EndOrigin))
      write_coord(floatround(EndOrigin) + 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(entity1)
   }
   return PLUGIN_CONTINUE
}

// 由于原插件中的发射程序在amx下好象无法进行编译,所以我想了个方法,当玩家切换到火箭筒时,系统自行把mouse1绑定为fire,这样玩家按鼠标左键时就能发射火箭了,当切换到其他武器时,系统又把mouse1绑定为+attack,但此设置有个BUG,对于个别不是用mouse1开火的玩家此设置不起作用,如果您知道怎么修改请指教一二。

public fire_rocket(id) {
   if(!fire) {
      return PLUGIN_HANDLED
   }
   if(!CanShoot){
      emit_sound(id, CHAN_WEAPON, "weapons/dryfire_rifle.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
      return PLUGIN_HANDLED
   }
   CanShoot = false
   new data
   data = id
   set_task(5.0, "rpg_reload", id+9477, data, 1)
   if (Munni <= 0) {
      emit_sound(id, CHAN_WEAPON, "weapons/dryfire_rifle.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
      return PLUGIN_HANDLED
   }
   new Float:StartOrigin, Float:Angle
   new PlayerOrigin
   get_user_origin(id, PlayerOrigin, 1)
   StartOrigin = float(PlayerOrigin)
   StartOrigin = float(PlayerOrigin)
   StartOrigin = float(PlayerOrigin)
   entity_get_vector(id, EV_VEC_v_angle, Angle)
   Angle = Angle * -1.0
   new RocketEnt = create_entity("info_target")
   entity_set_string(RocketEnt, EV_SZ_classname, "rpgrocket")
   entity_set_model(RocketEnt, "models/rpgrocket.mdl")
   entity_set_origin(RocketEnt, StartOrigin)
   entity_set_vector(RocketEnt, EV_VEC_angles, Angle)
   new Float:MinBox = {-1.0, -1.0, -1.0}
   new Float:MaxBox = {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
   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)
   ammo_hud(id, 0)
   Munni--
   ammo_hud(id, 1)
   return PLUGIN_HANDLED
}

public rpg_reload(data[]) {
   CanShoot] = true
   ammo_hud(data, 1)
}

public check_model(id) {
new weaponid, clip, ammo
weaponid = get_user_weapon(id, clip, ammo)
if (weaponid == CSW_KNIFE && fire) {
    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")
    client_cmd(id,"bind MOUSE1 fire")
    if(!CanShoot){
      new data
      data = id
      set_task(5.0, "rpg_reload", id+9477, data, 1)
    }
}
else {
    ammo_hud(id, 0)
    client_cmd(id,"bind MOUSE1 +attack")
    remove_task(id+9477)
}
return PLUGIN_CONTINUE
}

public client_disconnect(id){
   if(fire){
      client_cmd(id,"bind MOUSE1 +attack")
      gunnum=gunnum+1
   }
}

public client_connect(id) {
   fire=false
   CanShoot=false
   Munni=0
}

ammo_hud(id, show) {
new AmmoHud
if(CanShoot){
   if(Munni>0){
      format(AmmoHud, 32, "Ammunition: %i(fire)", Munni)
   }
   else{
      format(AmmoHud, 32, "Ammunition: %i(No Ammo)", Munni)
   }
}
else if(Munni>0){
   format(AmmoHud, 32, "Ammunition: %i(reloading)", Munni)
}
else{
   format(AmmoHud, 32, "Ammunition: %i(No Ammo)", Munni)
}
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()
}
}

安装方法:把解压后的目录拷贝至相应的服务器目录下即可,而.amx文件要安装在amx目录下的plugins里,并在plugins.cfg里添加相应的.amx文件。

这里还有个BUG,当切换至火箭筒后,如果此玩家还买了手雷,闪光,烟雾2种以上,当他在手拿火箭筒时,想切换到手雷或其他雷时候,在选择雷时会有选择,常规方法是需要按下鼠标左键,而此时系统已经把mouse1绑定为fire,所以结果会在切换雷时变为发射火箭筒了,解决办法就是绑定其他发射键,OP可以根据需要自己决定处理。

yhnba23 发表于 2004-12-15 12:46:48

表示万分的感谢~ :76:

但楼主说此插件,只能运行在AMX0.9.9环境下。但是我一直用的AMMX1.0,我也会下载后测试的,希望给点机会吧~,多谢了~

经测试,不能使用在AMMX1.0环境下 :1:

麻烦一下,可以转成AMMX1.0插件吗?

yhnba23 发表于 2004-12-15 13:59:37

有高人可以做把它转成AMMX1.0下用的吗?现在很多插件都需要AMMX1.0支持啊,特别是WAR3FT……,谢谢

hnroc 发表于 2004-12-15 14:21:31

转成amxx?我对amxx不是很了解,从来就没用过啊,帮不了你了!主要是它的一些函数都变了,转起来比较麻烦。

yhnba23 发表于 2004-12-15 14:34:22

没什么,非常的谢谢你的热心,这个插件我保留下了,作为学习之中也非常的好~

至于转AMMX就希望其他高人吧~

applesuperman 发表于 2004-12-15 19:57:41

1.5用不起 :5:

hnroc 发表于 2004-12-16 10:09:42

Post by applesuperman
1.5用不起 :5:

又看了下程序,一时笔误,现在重新修改上传了,你在试试(一定要是amx0.9.9)。如果还不行,你就这样测试下:
先使money<10000,然后执行say /buygun,看有无提示;如有,使钱>10000,再执行say /buygun,看有无提示;如有,切换3号键盘看有无火箭筒;如有,按鼠标左键发射,看有无炮弹发射并在远出爆炸,有就正常。
上面在哪里出现无提示或无任何反应请告诉我(全部为默认情况下),说明下这里的say /buygun命令,指玩家按y然后输/buygun回车,并非按y后输入say /buygun回车。

applesuperman 发表于 2004-12-16 12:22:24

是这个插件不能运行 :5:

我再试试这个新的 :cry2:
楼主真是好银啊

还是不行说什么set_msg_block有问题

hnroc 发表于 2004-12-16 14:58:08

Post by applesuperman
是这个插件不能运行 :5:

我再试试这个新的 :cry2:
楼主真是好银啊

还是不行说什么set_msg_block有问题

请把提示写完全,你说的这个提示在哪个环节出的?

applesuperman 发表于 2004-12-16 18:24:37

我自己建主机玩,在控制台上出现的

我传个图,谢谢
页: [1] 2 3
查看完整版本: [应求]修改火箭筒插件for amx0.9.9