public关键字可用于声明、定义全局变量,点击查看:变量指南
代码示例:
#include <amxmodx>
// 声明、定义仅当前插件可用的全局变量,并让AMX Mod X插件平台创建一个同名公共变量
public gDataVal = 1024;
public plugin_init()
{
// 同时修改插件私有变量gDataVal和公共变量gDataVal的值
set_xvar_num(get_xvar_id("gDataVal"), 2048);
}
单独使用public声明全局变量几乎与new相同,仅多出一个特性:
AMX Mod X 插件平台会额外创建一个同名的单值公共变量。
所有插件都必须使用下列函数才能访问amxmodx公共变量:
/// 搜索amxmodx公共变量名称,返回值:-1=无,其他=变量索引
native get_xvar_id(const name[]);
/// 搜索amxmodx公共变量名称,返回值:0=无,1=有
native xvar_exists(const name[]);
/// 根据amxmodx公共变量索引取值,并添加_标签(不会改变数值)
native get_xvar_num(id);
/// 根据amxmodx公共变量索引取值,并添加Float标签(不会改变数值)
native Float:get_xvar_float(id);
/// 根据amxmodx公共变量索引赋值,新值需要拥有_标签
native set_xvar_num(id, value = 0);
/// 根据amxmodx公共变量索引赋值,新值需要拥有Float标签
native set_xvar_float(id, Float:value = 0.0);
声明全局变量时无法执行运行时代码,所以我们不可能提前确定一个公共变量是否存在。
如此一来,就有可能与其它插件竞争同一个公共变量的控制权。
AMX Mod X对public变量声明语句的设计可以说是非常失败,非常反直觉,尽量不要使用public创建变量。
反正本来就需要使用native函数获取变量值,不如直接创建native函数,用于访问自己插件内的某个私有变量。
如此一来,函数和变量的一切行为都在自己的掌控之下。
| 声明说明符组合 | 全局变量特性 | 批注 |
|---|---|---|
| public | 储存在数据段 插件私有 生成AMX平台公共变量 |
|
| new public | 储存在数据段(重复) 插件私有(重复) 生成AMX平台公共变量 |
无变化,无意义 建议删除无意义的new |
| public stock stock public |
储存在数据段(重复) 插件私有(重复) 生成AMX平台公共变量 |
无变化,无意义 建议删除无意义的stock |
| public const | 储存在数据段 插件私有 生成AMX平台公共变量 只读 |
私有变量只读 公共变量可读写 |
| new public stock new stock public |
储存在数据段(重复) 插件私有(重复) 生成AMX平台公共变量 |
无变化,无意义 建议删除无意义的new和stock |
| new public const new const public |
储存在数据段 插件私有 生成AMX平台公共变量 只读 |
私有变量只读 公共变量可读写 建议删除无意义的new |
| public stock const public const stock stock public const stock const public |
储存在数据段(重复) 插件私有(重复) 生成AMX平台公共变量 只读 |
私有变量只读 公共变量可读写 建议删除无意义的stock |
| new public stock const new public const stock new stock public const new stock const public new const public stock new const stock public |
储存在数据段(重复) 插件私有(重复) 生成AMX平台公共变量 只读 |
私有变量只读 公共变量可读写 建议删除无意义的new和stock 组合时const不能放最前面 |
public关键字可用于声明、定义公共函数。
每个插件源码都必须拥有至少一个公共函数,否则无法编译。
AMX Mod X 核心模块会在执行forward函数时,执行所有插件定义的同名公共函数。
所以,我们通常会用公共函数实现plugin_precache或plugin_init这两个forward函数的定义。
#include <amxmodx> // 引用关于forward函数的声明
// 插件缓存函数:载入地图后,缓存资源文件时执行
public plugin_precache()
{
register_plugin("测试插件1", "1.0.0", "插件作者");
}
// 插件初始化函数:缓存资源文件结束后执行
public plugin_init()
{
server_print("[AMXX] 随便做点什么 !");
}
除了利用forward函数触发我们的公共函数,还可以用native函数,引导其他模块/插件来执行我们的公共函数。
amxmodx.inc文件中,提供了callfunc_系列函数,可以执行其他插件的公共函数.
/// 根据公共函数名和插件文件名,准备开始函数调用
native callfunc_begin(const func[], const plugin[] = "");
/// 根据公共函数索引和插件索引,准备开始函数调用
native callfunc_begin_i(func, plugin = -1);
/// 根据公共函数名和插件索引,获取公共函数索引
native get_func_id(const funcName[], pluginId = -1);
/// 注册插件信息,返回插件索引
native register_plugin(const plugin_name[], const version[], const author[], const url[] = "", const description[] = "");
/// 准备好后,填入一个带有_标签的、按值传递的单值参数
native callfunc_push_int(value);
/// 准备好后,填入一个带有Float标签的、按值传递的单值参数
native callfunc_push_float(Float:value);
/// 准备好后,填入一个带有_标签的、按引用传递的单值参数
native callfunc_push_intrf(&value);
/// 准备好后,填入一个带有Float标签的、按引用传递的单值参数
native callfunc_push_floatrf(&Float:value);
/// 准备好后,填入一个带有_标签的字符串,参数2决定是否保存函数对字符串的更改
native callfunc_push_str(const VALUE[], bool:copyback = true);
/// 准备好后,填入一个带有_标签的数组,参数2决定填入多少元素,参数3决定是否保存函数对数组的更改
native callfunc_push_array(const VALUE[], array_size, bool:copyback = true);
/// 填好所有参数后,完成对该函数的调用
native callfunc_end();
除此以外,还有很多监听事件相关的native函数,要我们告知公共函数名称,对方模块/插件会在事件触发之前/之后执行。
下面简单列举一部分:
/// 延时执行指定公共函数
native set_task(Float:time, const function[], id = 0, const any:parameter[] = "", len = 0, const flags[] = "", repeat = 0);
/// 监听到某个消息后执行指定公共函数
native register_event(const event[], const function[], const flags[], const cond[] = "", ...);
/// 监听到客户端发送命令被公布之前,执行指定公共函数
native register_clcmd(const client_cmd[], const function[], flags = -1, const info[] = "", FlagManager = -1, bool:info_ml = false);
/// 监听到控制台命令被公布之前,执行指定公共函数
native register_concmd(const cmd[], const function[], flags = -1, const info[] = "", FlagManager = -1, bool:info_ml = false);
/// 监听到服务端发送命令被公布之前,执行指定公共函数
native register_srvcmd(const server_cmd[], const function[], flags = -1, const info[] = "", bool:info_ml = false);
/// 监听某个游戏事件,选择在之前或之后触发指定公共函数
native register_forward(_forwardType,const _function[],_post=0);
/// 监听某种类名实体的某个事件,选择在之前或之后触发指定公共函数
native HamHook:RegisterHam(Ham:function, const EntityClass[], const Callback[], Post=0, bool:specialbot = false);
/// 监听某种实体的某个事件,选择在之前或之后触发指定公共函数
native HamHook:RegisterHamFromEntity(Ham:function, EntityId, const Callback[], Post=0);