本帖最后由 Ngen 于 2018-9-18 13:42 编辑
五、在CNCSage引擎中Lua函数的参数使用规则: 关于CNC Sage引擎中非ExecuteAction和EvaluateCondition类函的Lua函数:这些函数只会引用table类型的Object参数(不像ExecuteAction类函数),所以一定要用GetObj.Table(Object)函数。注意在globals() table中有但没有在Lua注册过的Object不能被这些函数直接使用。 注3:所谓“在globals() table中有”就是说这个GameObject的本级(与kindof同级)属性值ForceLuaRegistration="True"或者这是在地编里放置的物体。而“在Lua注册”是指在AIUpdateModuleData 下的AILuaEventsList 有相关的EventList,不过这只是对KW而言,对于RA3并不能在AI段注册,而要在Behavior段用<LUAEventList>注册。
Object参数的类型: • Table类型参数: 这些Object存储在lua 的globals()这个table中(所有的lua函数和global变量也是)并且它们也都是table类型的值。这些Object的table类型值都有一个独特的以“OBJID”开头的标志值,所以我们可以容易地滤选它们。所有在GameObject的xml 中的AIUpdate模块中有AILuaEventsList描述的Object都会在globals()中有一个相应的table类型值。你可以在xml里用ForceLuaRegistration="True"来强行注册。 注4:同注3 • String类型参数: 所有Object都有多种和它们有关的string类型名字。这类的引用值可以在所有使用某Object作为参数的ExecuteAction和EvaluateCondition指令中用到。
其他参数类别: • 队伍名(Team names): 使用GetTeamName(Object),可以得到某单位的队伍名。 在MetaMod中队伍名取值范围是:ClientTeamName, NeutralTeam, CreepsTeam, CivilianTeam,ObserverTeam。 在MetaMod中含队伍名的table是:GlobalTeamTable, HumanPlayerTable,AIPlayerTable, AllTeamsTable。 需要实际队伍名值请看MetaMod的源码(scripts.lua)。 • 路径点在这两个table中:WaypointTable, WaypointDistanceTable • 区域名:在AreaTable 中(未过滤) • 布尔值(TRUE/FALSE):用0或者“0”代表否,用1或者“1”代表是。 • 下拉列表参数(通过使用n-1值,n为该参数在下拉列表中的序数):如果在地编里选择参数时有一个下拉列表,那么你就需要在相应的Lua中使用n-1作为数值或者string类型值。大部分下拉列表在MetaMod中已经用table引用了,直接使用table里的值就行。 • String类型值(字符串):在地编里能用文本框任意改的值在Lua中都可以使用string类型值作为参数。 • Real或者Double 类型值(实数或双精度实数):在Lua中你可以使用数字甚至带数字的字符串来表示real或者double类型值。 • Integer类型值(整数):除了与之相关的运算符之外似乎没有别的方法能使用整数。当读取进入电脑端时,Lua的电脑-代码接口会把所有在Lua代码中提及的数字都被完全地转化为double类型。 • 坐标系类型值:似乎Lua中不能用。 • Player类型值:在已知方法中没有一种能直接使用Player类型参数。从内部看Player类型参数引用时似乎是struct类型(结构体)。实际上Player类型参数由代码文件夹名和Player名组成,即是"WBScriptFolder/Playername"形式,举个例子:"Player_1/<This Player>"。好消息是在大多数执行代码中你可以用相应的team类型值代替。另一个能间接使用Player类型值的地方是是用SendScriptHostCodeMessage的方法法,这会在2.7地图整合指南那部分说。
ExecuteAction和EvaluateCondition系列函数: 这些是可用函数中最最有价值的。所有牛逼玩意都能用这些函数实现。广泛地使用这些函数是MetaMod的主要特点。ExecuteAction系列函数能让你使用大部分地编脚本功能,而EvaluateCondition系列函数则让你能使用大部分地编脚本的IF条件。 破游共包含677个ExecuteAction函数以及218个EvaluateCondition函数,这些你都能尝试使用。你可以在MetaMod的下载包里找到这些函数和所有内部指令的完整列表。 至于如何给这些函数找合适的参数: • 用MetaMod文件包里的ALL_SAGE_LUA_COMMANDS.txt列表,得到第一个参数。 • 也可以在scripts.ini中得到第一个参数,但有些参数在那是没有的。 • 使用地编的脚本编辑器菜单来查看所有参数的及其顺序。你可以输出一个脚本scb文件然后用编辑器打开来查看第一个参数,通常是一段用大写字母和下划线写的东西。你只需要加上引号就能在Lua里使用这个参数。 • ExecuteAction: 语法:ExecuteAction(command,parameter1,parameter2,...) 引用某Object时: 既能用string类型值也能用table类型值 • EvaluateCondition: 语法:EvaluateCondition(command,parameter1;parameter2,...) 引用某Object时:只能用string类型值,所以用GetObj.String函数以确保正确的值类型。 相关的运算符:使用“n-1”(n为运算符的序数)或者使用CompareTable["operator"] (运算符顺序: >, >= ,< ,<=, ==,~=)
注5:这里原文说得比较模糊,且RA3与KW地编区别比较大,很多有用的函数在ALL_SAGE_LUA_COMMANDS.txt里并不能找到,而且似乎RA3也没有scripts.ini文件,我简单说一下怎么利用RA3的地编中的脚本编辑器查找Lua函数的相关参数。首先打开地编脚本编辑器,编辑一段你喜欢的脚本,然后输出脚本(Export scripts),生成一个scb文件。用记事本或者UE打开这个文件,会发现一大堆乱码,但仔细搜索还是能发现几句人话。 例如这是“当选择航母时,航母对最近的T3单位使用EMP”这个脚本,可以看到NAMED_USE_COMMANDBUTTON_ON_NEAREST_KIND就是对最近单位用某个cmd的意思,这可以作为ExecuteAction函数的第一个参数写入Lua里,然后<This Object>是第二个参数,不过通常我们会用self来作为这类指涉单位的参数,以指涉在主函数里引用的【这个单位】,而Command_ActivateEMPCruiseMissleSpecialPower则是第三个参数,T3_UNIT就是第四个参数,因此这句可以写为ExecuteAction(“NAMED_USE_COMMANDBUTTON_ON_NEAREST_KIND”,self,“Command_ActivateEMPCruiseMissleSpecialPower”,”T3_UNIT”) 而它的条件则是一个EvaluateCondition函数,这个函数的第一个参数是TYPE_SELECTED,第二个参数是AlliedAntiStructureShip,于是整个函数写为EvaluateCondition(“TYPE_SELECTED”,”AlliedAntiStructureShip”) 所以整段脚本在Lua中的表达就是: If EvaluateCondition(“TYPE_SELECTED”,”AlliedAntiStructureShip”)==1 Then ExecuteAction(“NAMED_USE_COMMANDBUTTON_ON_NEAREST_KIND”,self,“Command_ActivateEMPCruiseMissleSpecialPower”,”T3_UNIT”) End 可以发现,这里面的参数顺序不一,脚本条件和执行的动作混杂在一起,怎么在其中区分出正确的参数还是要很考验各人的灵视的。
|