KF1 mod 开发教程
插件特殊函数
我们继续讨论插件 Mutator 类,先从源代码的角度来看
该类文件所在路径为:
KillingFloor \ Engine \ Classes
这里没有列出 KF1 的具体安装目录,只需要在游戏目录找到 Engine 文件夹。 Mutator.uc 文件有 300多行代码(包括空行),里面以函数居多 只有少量属性。

这里将列出三个比较特殊的函数,很容易对游戏进行修改:
这里只是列出简单的几个函数,实际上 Mutator 类还有很多修改游戏的方式。
修改玩家
插件类有一个 ModifyPlayer 函数,当你继承了插件类之后 就可以重写该函数。 如果不懂什么叫函数重写,请从编程基础中的“类的继承”主题开始了解。

以下代码将在玩家进入游戏时给予一把武器
并且是在每一个玩家出生时执行该函数:
function ModifyPlayer(Pawn Other)
{
	Other.GiveWeapon("KFMOD.SCARMK17AssaultRifle");
	Super.ModifyPlayer(Other);
}
当该函数调用时,玩家棋子 将作为参数传进来,然后就可以对其修改。 这里调用了 玩家棋子的给予武器函数,拿到了一把 SCAR, 然后 Super 访问超类函数,因为父类的同名函数 有些代码还要执行,从而实现多个插件同时运行的兼容性。

提示:由于C++有多继承的功能,所以没有 Super关键字;而虚幻脚本是单向继承。
Super.ModifyPlayer() 首先会尝试访问父类的 ModifyPlayer() 函数,如果该父类没有实现该函数 就再尝试访问 父类的父类 ModifyPlayer() 函数, 如果没有就一直向上找,找到为止。
插件消息函数
插件类有一个函数 Mutate,单词还是与 Mutator 有一点区别。 作用是接收用户命令参数,然后判断修改;实际上看代码更直观一点
function Mutate(string MutateString, PlayerController Sender)
{
	if (Caps(MutateString) == "HYPER")
	    Sender.Pawn.Health = 999;

	Super.Mutate(MutateString, Sender);
}
在玩家用控制台输入 mutate <字符串参数> 回车时 会调用该函数, 并将 <字符串参数> 作为第一个参数传入,第二参数即执行命令的玩家(发送命令的玩家控制器)

函数体中,将“参数字符串”转成大写 再进行比较,比较成功就给“玩家的棋子”设置血量为 999 最后再访问 超类同名函数,将参数按原顺序传递。

小提示:多插件是以链式引用的关系存储,这是《数据结构》中的一些概念。
游戏启动了一连串的插件时,程序会设置一个插件对象中的某个属性 指向了下一个插件对象,即链式引用。
检查替换
检查替换 理论上是在任何 Actor 物件生成时都调用,但为了留出节省性能的空间 只有 Actor 属性 bGameRelevant=true 时才会检查该 Actor物件,属性意思为“游戏相关”; 与游戏相关性不大的物件 就没必要检查了,省点性能开支。

以下代码在怪物进入游戏时 修改其血量:
function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{
	if (KFMonster(Other) != None)
	{
	    KFMonster(Other).Health = 1;
	}

	return Super.CheckReplacement(Other, bSuperRelevant);
}
Actor 物件类几乎是场景中任何对象的顶级基类,所以替换怪物时 要时刻判断着。 第一个参数 即当前对象,可以用类型转换 做判断,转换“怪物类”成功时执行相应代码, 如果转换失败就变成了 None 空对象。

第二个参数有点奇怪,至于做什么事情 要找到具体被调用处的上下文;由于代码中没有用到第二参数 并且分析代码要找一段时间,这里暂不考虑第二个参数的作用。

最后还要 return 一下,因为该函数有返回值,实际上永远返回 true 。


将代码写在自己的插件中,可以看到效果:
1、默认获得 Scar MK17
2、波浪键 ~ 控制台命令输入:HYPER,能获得 999 血量
3、所有怪物都只有1点血,即一碰就倒