AMXXPawn public关键字

1. 使用public创建变量

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.inc文件中关于访问amxmodx公共变量的native函数:

/// 搜索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与其它声明说明符组合:

声明说明符组合 全局变量特性 批注
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不能放最前面

2. 使用public创建函数

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_系列函数,可以执行其他插件的公共函数.

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函数,要我们告知公共函数名称,对方模块/插件会在事件触发之前/之后执行。

下面简单列举一部分:

amxmodx.inc

/// 延时执行指定公共函数 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);

fakemeta.inc

/// 监听某个游戏事件,选择在之前或之后触发指定公共函数 native register_forward(_forwardType,const _function[],_post=0);

hamsandwich.inc

/// 监听某种类名实体的某个事件,选择在之前或之后触发指定公共函数 native HamHook:RegisterHam(Ham:function, const EntityClass[], const Callback[], Post=0, bool:specialbot = false); /// 监听某种实体的某个事件,选择在之前或之后触发指定公共函数 native HamHook:RegisterHamFromEntity(Ham:function, EntityId, const Callback[], Post=0);