|
教程(一)深入研究message
在AMX AMXX的娱乐插件里,您是否曾经被光环,爆炸,闪电,激光,烟雾,火焰等等的效果震撼呢?您试否曾经见过您的屏幕突然变白,突然变黑,突然开始振颤,甚至您看到屏幕右上角一个活人把一个死人杀死若干次的标志呢?这些,全都离不开message(消息),
消息如此的有用处,大家可能还不太理解,简单的message_begin, message_end, write_byte, write_coord 等等命令如何实现这样的功能。下面我就来教大家,自认为message是AMX AMXX脚本编写最有用处的命令之一。
支持AMX AMXX
技术难度系数:★★★☆
理解难度系数:★★★★☆
深入研究message,我将这分成两部分。
第一部分,message对效果的操作和第二部分,message对事件的操作。
第一部分,message对效果的操作。学习这部分,您需要有一定英文基础,至少您应该会查英汉词典。在附件的const.h里用得着。
所谓对效果的操作,就是用message创建诸如爆炸,闪电等等效果。首先,我们先熟悉一下用message创建效果的通用格式
① 创建所有人都能看见的效果
- message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
- write_byte(效果索引号码)
- write_***
- ………
- message_end()
复制代码
② 创建只有一个人能看见的效果
- message_begin(MSG_ONE, SVC_TEMPENTITY,{0,0,0},玩家id)
- write_byte(效果索引号码)
- write_***
- ………
- message_end()
复制代码
通用格式就是这么两个,玩家id就是玩家索引号码,效果索引号码存在于附件const.h中。下面,我来举几个例子。
实战(一)创建爆炸效果。
我们打开const.h,稍向下翻,实体索引号码通常都是
并且,紧挨着他的下面通常有几行注释,以爆炸效果为例:(这个出自const.h)
- #define TE_EXPLOSION 3 // additive sprite, 2 dynamic lights, flickering particles, explosion sound, move vertically 8 pps
- // coord coord coord (position)
- // short (sprite index)
- // byte (scale in 0.1's)
- // byte (framerate)
- // byte (flags)
- //
- // The Explosion effect has some flags to control performance/aesthetic features:
- #define TE_EXPLFLAG_NONE 0 // all flags clear makes default Half-Life explosion
- #define TE_EXPLFLAG_NOADDITIVE 1 // sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite)
- #define TE_EXPLFLAG_NODLIGHTS 2 // do not render dynamic lights
- #define TE_EXPLFLAG_NOSOUND 4 // do not play client explosion sound
- #define TE_EXPLFLAG_NOPARTICLES 8 // do not draw particles
复制代码
其中出现#define TE_EXPLOSION 3,就是我说刚才说的形式,EXPLOSION(爆炸)是效果名,3是效果索引。但注意,下边还有什么 #define TE_EXPLFLAG_**** 数字 一些东西,这些就不是实体索引,因为紧挨着他们下边没有注释。
#define TE_EXPLOSION 3 下面的注释是非常有用的。我们来看看。
- // coord coord coord (position)
- // short (sprite index)
- // byte (scale in 0.1's)
- // byte (framerate)
- // byte (flags)
复制代码
这些注释告诉您,write_byte(效果索引) 下边该写什么,例如这里,//coord coord coord (position) 告诉您,write_byte(效果索引)下边应该写3个write_coord 表示创造爆炸效果的位置。//short (sprite index) 表示再写一个write_short表示spr索引,//byte (scale in 0.1's): 下边再写一个write_byte表示spr显示大小,按0.1倍计算,//byte (framerate) 下边再写一个write_byte表示每秒钟贞数,// byte(flages) 下边再写一个write_byte 表示标识。注意,这些的顺序是绝对不能颠倒的!然后,他就在下边给您解释标识如何使用:
- // The Explosion effect has some flags to control performance/aesthetic features:
- #define TE_EXPLFLAG_NONE 0 // all flags clear makes default Half-Life explosion
- #define TE_EXPLFLAG_NOADDITIVE 1 // sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite)
- #define TE_EXPLFLAG_NODLIGHTS 2 // do not render dynamic lights
- #define TE_EXPLFLAG_NOSOUND 4 // do not play client explosion sound
- #define TE_EXPLFLAG_NOPARTICLES 8 // do not draw particles
复制代码 这个就得您自己翻译了,所以我说,需要一定英文基础的。于是我们知道,创建正常的爆炸,标识为0就可以了。
于是,按照const.h里所给的格式,我们就可以写出以下内容:
- message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
- write_byte(3)
- write_coord()
- write_coord()
- write_coord()
- write_short()
- write_byte()
- write_byte()
- write_byte()
- message_end()
复制代码
当然,仅仅这样是不能创建效果的。因为,每个write_byte write_coord write_****(其他) 的后面必须含有一个值,下面,我先把spr索引讲一下。想获得spr索引,您必须作如下工作,申请储存spr索引的全局变量(就是在#include 区的下边输入new 变量名),我们不妨把变量名定为exp,然后,在插件plugin_precache过程中敲入exp = precache_model("sprites/zerogxplode.spr")这样,zerogxplode.spr(这是一个比较不错的爆炸spr文件)的spr索引就存储在了exp变量里。下面,我们开始完善这个message:
- message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
- write_byte(3)
- write_coord(x坐标)
- write_coord(y坐标)
- write_coord(z坐标)
- write_short( exp )
- write_byte(20)
- write_byte(10)
- write_byte(0)
- message_end()
复制代码
这样,一个爆炸效果将在坐标(x,y,z)处被创建,并以每秒10贞,2倍于自身spr大小的形式播放。为了让大家更完整的看到源代码,我把整个过程写出来,规则是这样:当玩家在控制台中输入expme,则自己瞄准的地方会产生一个爆炸效果,当然,是不伤人的。
- #include <amxmod>
- new exp //申请全局变量exp
- public plugin_init(){
- register_plugin(" 创建爆炸 ","0.1","Hydralisk") //注册插件
- register_clcmd("expme","h_expme") //注册控制台命令"expme", 当有人输入这个命令,则执行脚本中的 h_expme过程
- return PLUGIN_CONTINUE
- }
- public plugin_precache(){ //这个就是我刚才说的plugin_precache过程
- exp = precache_model("sprites/zerogxplode.spr") //预存储spr文件 zerogxplode.spr并将spr索引存储在exp变量里。
- }
- public h_expme(id){ //当有人输入"expme"时,这个过程将被触发,玩家的索引将被保存在头变量id里
- new ori[3] //申请3位数组变量ori
- get_user_origin(id,ori,3) //获取玩家正在瞄准的位置,并按 x坐标,y坐标,z坐标存储在ori变量里
- message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
- write_byte(3)
- write_coord(ori[0]) //x坐标
- write_coord(ori[1]) //y坐标
- write_coord(ori[2]) //z坐标
- write_short( exp ) //spr索引
- write_byte(20) //20×0.1 = 2倍于原spr文件 的爆炸的大小
- write_byte(10) //每秒钟播放贞数
- write_byte(0) //标识为:正常爆炸
- message_end()
- }
复制代码
第二部分,message对事件的操作。学习这部分,您最好也需要有一定的英文基础,不过本部分对英文的要求没有前面那部分对英文的要求那么多。如果您不会英文,也可以参看别人的源代码。
所谓对事件的操作,就是CS内部集成了很多事件,例如死亡消息DeathMsg(一个人把另外一个人打死后,屏幕右上角显示的消息)、屏幕震动ScreenShake、屏幕渐变ScreenFade(例如闪光弹爆炸后,玩家屏幕变成白色)、视场改变SetFov(例如AWP开镜后,远处的东西变大,就是改变了视场)、左侧图标StatusIcon(屏幕左侧“购物手推车”、“C4”、“人质释放点”、“VIP逃逸点”等图标都由此控制)……
其中绿色的部分为“事件名”,所有的CS事件名以及其内容都可以在nwb13曾经发的 【分享】关于事件等内容的参考资料 中找到。
我们先熟悉一下用message对事件操作的格式:
① 创建单人事件、
- message_begin(MSG_ONE,get_user_msgid("事件名"),{0,0,0}, 玩家id)
- write_...
- ….
- message_end()
复制代码
② 创建全局事件
- message_begin(MSG_ALL,get_user_msgid("事件名"))
- write_...
- ….
- message_end()
复制代码
所谓单人事件,就是这个事件是对单个人操作的事件。CS编写者定义事件的时候,已经确定了这个事件是单人事件还是全局事件。所以我们不能随便更改事件的性质,否则会引起服务器崩溃(“崩溃”只得是CS的服务器突然退出CS,对计算机没有太大影响)。我们一般可以凭感觉确定某一个事件是单人事件还是全局事件。例如,屏幕渐变,只对某个人的屏幕进行操作,使他的屏幕变白或者变黄或者变黑,所以这个事件就是单人事件;再例如,死亡消息,这个事件任何人都能看得到,所以这个事件就是一个全局事件。如果实在无法确认,那么就得自己试了。
下面我们举个例子,在这个例子中,当OP在控制台中输入"hy_fakekill 玩家名"<回车>后,那个被定义的玩家将会被OP“杀死”5次,其中用ak47爆头1次,m4a1杀死一次,刀爆头3次,当然,这个“杀死”不是真的杀死,那个玩家并不会死掉,只是屏幕的右上角显示被杀他被OP死5次。
首先,我们在前面所说的nwb13文章中的cs_event.xls文件中找到了DeathMsg的用法:
Message: DeathMsg
Argument Order: byte byte byte string
Description of Arguments: 1: Killer ID, 2: Victim ID, 3: Headshot, 4:Weapon Name
Message就是事件名, Argument Order 决定了message_begin和message_end之间的write_类型,Description of Arguments 表示第n个事件中的参数的作用。例如DeathMsg的事件内容为
- write_byte()
- write_byte()
- write_byte()
- write_string()
复制代码
第一个byte代表杀人者的ID,第二个byte代表受害者的ID,第三个byte代表是否爆头,第四个代表string是武器名称。这样,DeathMsg的内容就应该是:
- message_begin(MSG_ALL,get_user_msgid("DeathMsg"))
- write_byte(killer)
- write_byte(victim)
- write_byte(0) // 或者是1
- write_string("武器名")
- message_end()
复制代码
我们来把整个过程写完。
- #include <amxmod>
- #include <amxmisc>
- public plugin_init(){
- register_plugin("Kill","0.1","Hydralisk")
- register_clcmd("hy_fakekill","fakekill",ADMIN_LEVEL_D," <victim name or #id>")
- return PLUGIN_CONTINUE
- }
- public fakekill(id, level, cid){
- if (!cmd_access(id,level,cid,2)) return PLUGIN_HANDLED //检查执行权限
- new arg[33]
- read_argv(1,arg,32) // 获得 “玩家名” 参数
- new player = cmd_target(id,arg,3) // 获得 受害者的 id
- if (!player) return PLUGIN_HANDLED //检测是否有这个玩家
- // 开始操作事件
- message_begin(MSG_ALL,get_user_msgid("DeathMsg"))
- write_byte(id)
- write_byte(player)
- write_byte(1)
- write_string("ak47")
- message_end()
- message_begin(MSG_ALL,get_user_msgid("DeathMsg"))
- write_byte(id)
- write_byte(player)
- write_byte(0)
- write_string("m4a1")
- message_end()
- for (new i=0; i<3; i++){
- message_begin(MSG_ALL,get_user_msgid("DeathMsg"))
- write_byte(id)
- write_byte(player)
- write_byte(1)
- write_string("knife")
- message_end()
- }
- return PLUGIN_HANDLED
- }
复制代码
如果有语句不通、错别字、不理解的地方,敬请提出 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注个册吧
×
|