搜索
查看: 6053|回复: 23

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

[复制链接]
发表于 2004-12-15 10:07:20 | 显示全部楼层 |阅读模式 来自 中国–湖南–永州
本人一直用的是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[33]
new bool:CanShoot[33]
new Munni[33]
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[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_center, "[AMX]: %s buy A Rocket!",name) //这里我写的是英文,OP可以自行去汉化,意思:**购买火箭筒一枚!。
      }
      else{
         client_print(id, print_center, "[AMX]: You can't buy Rocket because NO ROCKET!") // 由于没有火箭筒了,所以您不能买火箭筒!
      }
   }
   else{
      new name[32]
      get_user_name(id,name,31)
      client_print(id, print_center, "[AMX]: 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[victim]){
      fire[victim]=false
      CanShoot[victim]=false
      ammo_hud(victim, 0)
      Munni[victim]=0
      client_cmd(victim,"bind MOUSE1 +attack")
      drop_fire(victim)
   }
}

public drop_fire(victim){
   new Float: Origin[3], Float: Velocity[3]
   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[3] = {-1.0, -1.0, -1.0}
   new Float:MaxBox[3] = {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[id]){
      CanShoot[id]=true
      Munni[id]=get_cvar_num("amx_bazooka_ammo")
   }
   else{
      CanShoot[id]=false
      Munni[id]=0
   }
   return PLUGIN_CONTINUE
}

public entity_touch(entity1, entity2){
   new Classname[32]
   Entvars_Get_String(entity1, EV_SZ_classname, Classname, 31)
   new Float: kOrigin[3]
   Entvars_Get_Vector(entity1, EV_VEC_origin, kOrigin)
   if(equal(Classname,"fire_pickup")){
      new Class2[32]
      Entvars_Get_String(entity2, EV_SZ_classname, Class2, 31)
      if(!fire[entity2]){
         fire[entity2]=true
         CanShoot[entity2]=true
         Munni[entity2]=1
         emit_sound(entity2, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
         RemoveEntity(entity1)
      }
   }
   new ClassNamee[32]
   if (entity1 > 0) {
      entity_get_string(entity1, EV_SZ_classname, ClassNamee, 31)
   }
   if (equal(ClassNamee, "rpgrocket")) {
      new Float:EndOrigin[3]
      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[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)  // 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[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(entity1)
   }
   return PLUGIN_CONTINUE
}

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

public fire_rocket(id) {
   if(!fire[id]) {
      return PLUGIN_HANDLED
   }
   if(!CanShoot[id]){
      emit_sound(id, CHAN_WEAPON, "weapons/dryfire_rifle.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
      return PLUGIN_HANDLED
   }
   CanShoot[id] = false
   new data[1]
   data[0] = id
   set_task(5.0, "rpg_reload", id+9477, data, 1)
   if (Munni[id] <= 0) {
      emit_sound(id, CHAN_WEAPON, "weapons/dryfire_rifle.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
      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, "rpgrocket")
   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)
   ammo_hud(id, 0)
   Munni[id]--
   ammo_hud(id, 1)
   return PLUGIN_HANDLED
}

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

public check_model(id) {
  new weaponid, clip, ammo
  weaponid = get_user_weapon(id, clip, ammo)
  if (weaponid == CSW_KNIFE && fire[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")
    client_cmd(id,"bind MOUSE1 fire")
    if(!CanShoot[id]){
      new data[1]
      data[0] = 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[id]){
      client_cmd(id,"bind MOUSE1 +attack")
      gunnum=gunnum+1
   }
}

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

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

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

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

本帖子中包含更多资源

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

×
发表于 2004-12-15 12:46:48 | 显示全部楼层 来自 中国–四川–南充
表示万分的感谢~ :76:

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

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

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

使用道具 举报

发表于 2004-12-15 13:59:37 | 显示全部楼层 来自 中国–四川–南充
有高人可以做把它转成AMMX1.0下用的吗?现在很多插件都需要AMMX1.0支持啊,特别是WAR3FT……,谢谢
回复

使用道具 举报

 楼主| 发表于 2004-12-15 14:21:31 | 显示全部楼层 来自 中国–湖南–永州
转成amxx?我对amxx不是很了解,从来就没用过啊,帮不了你了!主要是它的一些函数都变了,转起来比较麻烦。
回复

使用道具 举报

发表于 2004-12-15 14:34:22 | 显示全部楼层 来自 中国–四川–南充
没什么,非常的谢谢你的热心,这个插件我保留下了,作为学习之中也非常的好~

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

使用道具 举报

发表于 2004-12-15 19:57:41 | 显示全部楼层 来自 中国–重庆–重庆–渝中区
1.5用不起 :5:
回复

使用道具 举报

 楼主| 发表于 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回车。
回复

使用道具 举报

发表于 2004-12-16 12:22:24 | 显示全部楼层 来自 中国–重庆–重庆–渝中区
是这个插件不能运行 :5:

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

还是不行  说什么set_msg_block有问题
回复

使用道具 举报

 楼主| 发表于 2004-12-16 14:58:08 | 显示全部楼层 来自 中国–湖南–永州
Post by applesuperman
是这个插件不能运行 :5:

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

还是不行  说什么set_msg_block有问题


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

使用道具 举报

发表于 2004-12-16 18:24:37 | 显示全部楼层 来自 中国–重庆–重庆–渝中区
我自己建主机玩,在控制台上出现的

我传个图,谢谢

本帖子中包含更多资源

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

×
回复

使用道具 举报

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

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