@sogouwap
2017-06-04T17:12:55.000000Z
字数 4915
阅读 5491
前言
本教程由小灰编写,这是普通难度的教程
适用于对插件学习一段时间后
再阅读
我们的QQ群:139659650
点击上述列表中
未打钩
旁边的切换按钮,以切换学习等级。
这个教程学习下来需要多少时间?
你需要花一些时间直到你掌握它,并且每天都要坚持编写代码。根据理解力的不同,需要的时间也不一样(三个月,六个月,或一个星期)
我需要准备什么样的系统?
你需要 Windows 7/8/10 或者 Windows XP 系统。
在插件中我们可以做上一些指定的条件来完成判断,根据判断结果来实现不同的功能
代码为 if (条件)
,其中条件是我们需要填写的内容,我们还可以在通过这个判断后添加 return
,让其代码不往下执行
示例并实践:
(调用模块: amxmodx.inc)
需要用到的代码是 is_user_alive(index)
返回值:如果存活返回1,否则 返回0
这里,我们还需要一个基础代码 if ( )
,中文是如果的意思,其中括号填入 需要判断的条件
index
代表目标索引,意义为我们需要判断谁。
示例:
if( is_user_alive(id) ) //如果玩家存活
{
}
如果我们需要判断这个玩家是否已经死亡,这里我们需要学到 !
反义标识(惊叹号),在判断条件的前面加入。
示例:
if(!is_user_alive(id)) //如果玩家已经死亡
{
}
(调用模块: amxmodx.inc)
我们可以判断玩家的当前手上的武器
武器对应ID我们需要参考 编译器/include/amxconst.inc
文件中。在此文件中有一个代码部分叫 CSW_
,这就是武器CSW ID号,比如: 武器 AK47
的 CSW_是 CSW_AK47
判断玩家持有的武器,我们需要用到 get_user_weapon(index)
该代码可以获取玩家持有的武器 CSW序号
,在这里我们 可以通过两个 判断符
来实现判断
== //绝对等于
!= //不等于
我们分别来看示例以及说明:
==
)他由两个等号组成(注意中间没有空格),我们需要做的是 在条件和判断中间加上 ==
即可
示例:
if( get_user_weapon(id) == CSW_AK47)
{
client_print(id, print_chat, "Your are Weapon AK47")
}
这样我们就判断了 ,如果玩家手上当前持有的是CSW_AK47 那么继续括号中的 client_print
函数内容(发送信息给索引目标)
!=
)在一些情况下,我们可能需要判断 如果玩家手上的武器不是那个武器,这种情况下我们需要用到不等于 !=
来实现目的,和绝对等于一样,插入的代码位置不变化
示例:
if(get_user_weapon(id) != CSW_AK47) //如果玩家手上的武器不是AK47
{
client_print(id, print_chat, "i Current Weapon Not Using Ak47")
}
(调用模块: amxmodx.inc)
在一些情况下,我们需要判断 目标 索引(index)
所属的当前阵营是什么
这时候我们需要用到的代码是 get_user_team(index)
该代码的返回值不止一个,他们分别是:
返回 0 //玩家没有选择阵营
返回 1 //阵营是T阵营
返回 2 //阵营是CT阵营
返回 3 //阵营是观察者
和 判断玩家持有武器
一样,我们需要添加代码的也是 ==
或者 !=
示例:(如果玩家是CT阵营)
if( get_user_team(id) == 2)
{
}
有时候我们需要判断多个条件,这时候我们就需要用到多重判断。
将的表达式代码 &&(并且)
或 ||(或者)
添加到两个条件中来实现多重判断。(需要添加到两个条件中间)
像这种有目标指向性的思路,一般有两种或者多种写法。
比如: (CT或者T) 或者 (不是观察者 并且 不是没有选择阵营)
if( get_user_team(id) == 1 || get_user_team(id) == 2)
{
}
if(get_user_team(id) != 0 && get_user_team(id) != 3)
{
}
以上两种示例,都可达成共同的目的,可根据个人习惯来改变写法
被定义的变量后面有 []
并且里面含有数值的代码称之为 数组,比如:
thismodel[33]
数组默认中是没有数值的,也就是
0
我们可以在后期给数组定义上去,其中 [ ]
中的内容代表需要给谁定义,也就是 索引(index)
。
比如玩家数量最大是 32
,我们就需要在数组中写上 33
,需要预留一位才行。
示例:
iSave[33]
数组可以帮我们做许多事情,比如 开关
现在,我们来讲一下 `开关` 的写法
听上去是个很常见的东西,可是在代码中是怎么样的呢
开关:可以打开也可以关闭。
即:触发一次打开
再触发一次关闭
首先我们定义,开关数组
new swtich[33]
然后开始写开关,首先我们判断 如果该数组是 0
的话
示例:
if(switch[id] )
{
}
是 0
话怎么样?这种情况下我们就需要动脑子了,仔细想想就明白了:思路 — 如果是0改成1,如果是1改成0
那么代码就是这样的:
if(!switch[id])
{
switch[id] = 1
}
清晰易懂对吧?那么现在已经实现了 如果关闭就打开
,那接下来的应该就是 如果打开就关闭
示例:
if(!switch[id])
{
switch[id] = 1
}
if(switch[id])
{
switch[id] = 0
}
如果我们以如上的代码思路来写,我们会遇到一个问题
是什么问题呢?我们翻译一下代码
如果关闭就打开
如果打开就关闭
这样乍看上去好像没什么不对,但是这里就是一个逻辑问题了,这种开关做上去就会出现这种问题:一旦开关刚刚打开马上就被关闭了
这种情况肯定是我们不想遇到的吧。那么应该怎么解决呢?
这里我们可以用到 else if
或者 else
来完成目的。
这两个的写法几乎一样,他和 双重if
的区别 是 只会被执行一次,而不是多次触发
if(!switch[id])
{
switch[id] = 1
}
else if(switch[id])
{
switch[id] = 0
}
if(!switch[id])
{
switch[id] = 1
}
else
{
switch[id] = 0
}
这样我们就完成开关了
else if
和else
这两种有额外的搭配写法,这里暂时不说
有一些情况下我们需要做一种特殊效果,他带有一种随机性
,可以由插件自身来决定是否 可以继续执行
随机值分三种:
random(2) //随机整数:最大值
random_num(1, 2) //随机整数:(最小值, 最大值)
random_float(20.0, 140.0) //随机浮点数(最小值,最大值), 括号中需要填写浮点数
那么我们应该如何搭配呢?
示例: (1)
if( random_num( 20, 60 ) > 45)
{
//如果在 (20, 60) 之间的随机结果大于 45
}
示例:(2)
if( random(25) == 14)
{
//如果在 (0, 40) 之间的随机结果刚好等于 14
}
注意:
random(最大值)
中的最小值取0
在代码中可以将 一个值
表示为 另一个值
例如:我们可以定义 ABC = 1
,或 ABC = 一串信息
#define ABC 123 //定义(标识,数据)
那这有什么用?
示例:
#include <amxmodx>
#define ShowInfo "这是一些信息"
public Show_Print(id)
{
client_print(id, print_chat, "ShowInfo: %s", ShowInfo)
}
小技巧:
在定义 #define 的时候,可以加上" "
来让识别率变得更高
我们可以获取游戏时间
(即:我们在游戏中呆了多久时间,按秒
计算)。并且使用游戏时间可以帮助我们解决许多问题
代码是 : get_gametime()
,获取到的值是浮点数
比如我们在游戏中玩了 5分钟
,那么通过 get_gametime()
获取到的值就是 300.0
秒
我们甚至还可以配合 数组
存储来完成不可思议的效果
示例:
#include <amxmodx>
new Float:SaveTime[33]
public plugin_init()
{
register_plugin("插件演示", "1.0", "Hui")
register_clcmd("say /test", "func_test")
}
public test(id)
{
new Float:LeftTime = SaveTime[id] - get_gametime()
if(LeftTime > 0.0)
{
client_print(id, print_chat, "冷却时间剩余: %.0f秒", LeftTime)
}
SaveTime[id] = get_gametime() + 2.0
}
小技巧:
我们可以通过游戏时间
来判断是否大于或小于等于,
如果是小于或等于
即代表时间到了,反之 就代表时间还没到。
if( SaveTime[id] <= get_gametime() )
{
//时间到了
}
else
{
//时间没到
}
我们可以为客户端注册一些命令,以触发一些特定函数
注册的代码为 register_clcmd("注册什么命令", "触发什么函数")
示例:
public plugin_init()
{
register_clcmd("say /abc", "the_func")
}
public the_func(id)
{
client_print(id, print_chat, "触发函数成功")
}
上例中即代表 按控制台输入 `say /abc` 触发了 `the_func` 函数
注意:
1. 当所填写的被触发函数名
不存在的时候,插件会出现runtime error
错误(因为找不到被触发函数,所以插件不会继续正常工作)
2. 在注册什么命令
的地方必须添加""
引号包围起来
3. 在注册什么命令
的地方设定的命令即控制台
输入的命令。若是需要按Y键
输入的命令则需要将命令最前面改为say
4. 若是一个之前被其他插件注册过的命令,却又重新注册一遍,此时你注册的新命令将不会工作,而只能使用之前被插件注册过的命令(简单说:无法在已经注册过的命令上重新注册一遍)
我们可以让客户端执行一些指定的命令,比如丢弃武器 drop
, 切换到指定武器,甚至还可以 让玩家发送一些Y键的文字信息
让对方说话,如果不爽对方还可以让对方客户端强制退出游戏。
可是,这一切应该怎么实现?
这里我们需要用到 client_cmd
这个代码
他由三个参数组成:
1. 让谁执行命令(index索引)
2. 执行的命令是什么
3. 附加的获取方式
一般我们用不到 参数3
, 写法如下
示例:
client_cmd(id, "drop") //让玩家执行控制台的drop命令(丢弃武器,默认G键)
那如果配合参数3应该怎么用?
一般我们用参数3是用来获取的一些数据,比如说:
//踢出这个ID的玩家
client_cmd(id, "kick #%d", get_user_userid(id))
注意:
1.client_cmd
只能给有效的客户端玩家执行,如果给非玩家(比如地图本身)那么就会出现控制台错误,无效的实体。