本指南旨在深入研究《 Nexus: The Jupiter Incident》脚本的结构和功能。在这里,我将介绍所有已发现但未记录的函数;指出在最新版本中无法运行的函数和事件;说明官方指南中记录不完善或完全未记录的部分函数的工作特点。部分信息来源于相关 Wiki。我不拥有相关内容的著作权。此类内容已标注为引用或提供了指向原文的链接。
如果您对本指南有任何意见或修改建议,请告诉我。
所需内容和工具
要处理《 Nexus - The Jupiter Incident》的脚本,您需要3样东西:
用于处理脚本的文本编辑器
我推荐使用Notepad++。QuitMission()语法特点
- 仅在战役模组中生效
- 仅当通过uCamera_Enter或uCamera_PutInto函数进入战术模式时才稳定
- 无需调用uSetNextMission函数
- 需要手动调用GuiSelect(2)函数
- 不会触发MissionQuit事件,因此无法在剧情脚本中拦截该调用
isat
当调用函数的对象为子对象时返回1,否则返回0。uTypeObject:isat(uTypeObject)语法:支持的参数类型为任意uTypeObject,无特殊特性。uGetC返回作为指定对象子对象的对象。uTypeObject:uGetC(string)语法特点:无get别名:GetSceneObj get(string)语法特点:与GetSceneObj相同 makeMainShip未知语法:MakeMainShip(Ship, string)特点:未知 hacks通过地图菜单进入战术模式(战略模式)要使此hacks生效,我们需要为系统中所有所需对象将DetectionLevel设置为5(#UDET_SPYCAM)示例:RULEevent EpisodeStart condition ActEpisode=1 :action sel := GetFreeSel(); uSelect(sel, uGet("sys_sol"), S:celestial()|S:colony()); ExecList(sel,设置检测等级(#UDET_SPYCAM)); :结束 结束Microsoft Excel 用于方便编辑舰船和设备参数。也可以使用 LibreOffice Calc,但需要能适配其宏(比如我就没成功)。一套辅助模组。当然,它们不是必需的,你也可以创建自己的版本,但在本指南中我会经常提到它们,因此为了更好地理解流程,最好手头有这些模组。变量作用域及其可见性
作用域"D."
在手册中标注为对话作用域,但实际上无法正常工作。
作用域"T."
在手册中标注为战术子程序(Subroutines)作用域,能够正常运行,但并无实际用途,因为通过作用域"E."传递变量到子程序中会更为合适。
脚本结构此外,当存在条件时,'RULE'块可以采用以下语法:实际上,':else'部分的描述在官方指南中有提及,但不知为何在Wiki中缺失,且未在原始战役中使用。RULEevent DoSomething condition somevar=1 :action Debug("somevar eq 1"); :end :else Debug ("somevar not eq 1"); :end END 如果条件满足,将执行:action部分的命令;否则,执行:else块中的命令。此外,您还可以指定多个在RULE规则块中:action RULEevent DoSomething,条件somevar=1时:action执行Debug("somevar等于1");结束;否则执行Debug("somevar不等于1");结束。条件somevar2=1时:action执行Debug("somevar2等于1");结束;否则执行Debug("somevar2不等于1");结束。END。在这种情况下,将首先检查第一个条件并执行选定的主体,然后检查第二个条件。uTypeObject列表 可通过uType()函数检查的类型ID列表 uTypeidstring0entity/*1system/100effect/103nexus/106location/**200station/201asteroidfield/203fleet/204location/***205celestial/206navigationpoint/207ship/302device/305asteroidscene/310npc/400 * - 剧情仓库 ** - 彗星类天体 *** - Nexus传送门 示例:uSelect(0, uGetUniverse(), S:uType() = 207) 将返回所有导航点 未记录函数 uGetUniverse返回游戏主对象 语法 uGetUniverse()特点 无 uCamera_Enter启动程序进入带有动画的战术模式。
与uEnterMission不同,不需要单独的任务文件。
语法uCamera_Enter(uTypeObject)
支持的参数类型:
system/*
nexus/*
celesital/*
fleet/*
navigationpoint/*
asteroidfield/*
station/*
location/*
特点:
仅在战役模组中有效
模组中必须定义任务99
不需要调用uSetNextMission函数
在战术模式下不稳定。请谨慎使用。uCamera_PutInto:启动无动画进入战术模式的程序。
与uEnterMissionQuick不同,它不需要单独的任务文件。
语法:uCamera_PutInto(uTypeObject)
支持的参数类型:
system/*
nexus/*
celestial/*
fleet/*
navigationpoint/*
asteroidfield/*
station/*
location/*
特点:
仅在战役模组中有效
模组中必须定义任务99
无需调用uSetNextMission函数
在战术模式下不稳定,请谨慎使用。QuitMission 启动带有动画的战术模式退出程序。
与 uQuitMission 不同,它不需要参数。退出战术模式时不会显示任务总结界面,并且如果未调用 uSetNextMission 函数,也不会返回到主菜单。变量 U.ActMission 和 U.ActEpisode 不会递增。现在,在物体描述面板上会出现一个额外的按钮。点击该按钮将调用uCamera_Enter函数,我们就会进入战术模式。
在原版战役的第16关,我们可以看到安格拉德号进入虫洞时的跳跃动画。我想很多人都注意到这个动画在其他地方都无法运行。但事实并非完全如此。
在舰船类(文件Universe/tactics/tacticstypes.)ini文件中有HPRegen参数(该参数仅在安格拉德级中存在)。若此参数大于零,进入虫洞时将显示动画(此时只需设置0.001左右的值,即可避免破坏平衡)。此外,动画播放完毕后场景会被卸载,可放心在MissionQuit事件中使用uCamera_Enter或uCamera_PutInto函数来切换场景。您的模组结构
入口点
入口点是一个例程,调用它会初始化您的模组。对于脚本库,入口点将是主菜单(《 Nexus Black Ruller》脚本引擎的特点是会将所有必要的值以及脚本断点保存到存档中,因此在加载游戏时,我们会直接获得已初始化的脚本)。此外,需要特别说明的是,该模组必须是公司的修改版本,这样脚本库才能完全加载。此外,还需要以特定格式指向模组的主状态机,因此需要额外编写一个小函数来进行传递。清单
模组即战役模组
在模组目录中需创建Universe文件夹(若不存在),并在其中创建名为.campaign(点campaign)的空文件
“新游戏”按钮已指定为脚本库的入口点
在模组的Universe目录中需创建main.ini文件,其中应包含以下代码:
Title "My Mod"
MAINMENU
"Start It!""uCall(ModMain, 0)
"加载已保存游戏"loadgame
END
其中
Title - 您的模组名称
MAINMENU区块描述将出现在其中的所有按钮。
第一个参数是按钮文本,第二个是点击按钮时将触发的事件。
uCall(ModMain, 0) - 脚本库的入口点
存在格式正确的模组主状态机。模组主状态机是负责管理所有后续模组事件的状态机。在其中,你需要指定所有必要的逻辑、所有必要的转换等。本指南后续将详细介绍它。
此机器必须位于策略例程中。因此,你需要在模组的Universe目录中创建必要的子目录,即【Strategy Subroutines】。在该目录中,你需要创建一个Mod.ModName.ini格式的文件,其中ModName是你的模组名称。需要将状态机代码和例程放入此文件,该例程会将其指针传递到脚本库中。
RULEevent ModMain
:action
//获取主模组机器
e:mod := getMachine("/MdName");
//我们要使用脚本库,所以初始化它。
//作为参数,我们发送模组主机器
uCall(UniverseScriptLibrary, e:mod := p:mod);
:end
END
MACHINE "/ModName"
STATE _INIT_
RULEevent In
:action
//如果要使用某些模块。可以在此处包含它们。
_class := usl:localEvent(Use, e:module := "Class");
:end
END
END
STATE _MAIN_
RULEevent In
:action
//模组真正开始。所有人员已初始化,你可以做任何想做的事
:结束
结束
结束
结束
你的模块(可选模块)
内置模块“类别”然而,遗憾的是,这仅适用于nexusgate/*类型的对象,并且我们必须播放某个bink视频来完成场景的破坏(空白视频即可)。
面向对象脚本
已过时!该部分将在Universe Script Library 2.0发布后更新
在大型复杂模组中,需要使用具有相同函数和变量集但状态不同的对象。遗憾的是,原版游戏中并未提供此类功能,因此我编写了一个模块来扩展标准StateMachine的功能,并将其纳入uSL模组中。基本概念 类 - 通过uSL库的Class模块创建的StateMachine
引用 - 类实例的列表编号
实例 - 类的实例
对象 - 直接作为类的变量
定义 每个类可以有一个或多个实例,每个实例都有其独特的变量状态。可以通过类对象或__changeInstance方法访问实例。
宏 宏通过#include指令设置uSL/class/declaration
该宏告知游戏此状态机(StateMachine)为类。
它必须在定义MACHINE之后立即定义。
uSL/class/instance
该宏将方法定义为实例化方法。
它必须在定义RULE event之后立即指定。
uSL/class/end_instance
该宏定义实例化方法的结束。
它必须在定义:end之后立即指定。
uSL/class/end
该宏定义类的结束。它必须在所有方法之后指定。
示例类
MACHINE "uSL/Class/Example"
#include "uSL/class/declaration"
RULEevent __Constructor
#include "uSL/function/private"
:action
//初始化变量
var1 := 3;
var2 := 2;
var3 := 1;
//执行操作
:end
END
//此函数用于实例化
RULEevent __var
#include "uSL/function/private"
:action
if (!E.flag, E.flag := #uSL_CLASS_SETGET);
var1 := this:localEvent(__instvar, E.flag := P.flag; E.id := 1; E.value := var1);
var2 := this:localEvent(__instvar, E.flag := P.flag; E.id := 2; E.value := var2);
var3 := this:localEvent(__instvar, E.flag := P.flag; E.id := 3; E.value := var3);value := var3);
:end
END
//简单实例化函数
RULEevent ExampleFunc
#include "uSL/class/instance"
:action
var3:= var1+var2;
Return(var3);
:end
#include "uSL/class/end_instance"
END
#include "uSL/class/end"
END
使用示例
//创建Example类的第一个实例
object := U.uSL.Class:localEvent(New,E.class := "Example");
//获取此类的对象以进行后续操作
example:=U.uSL.Class:last;
//创建第二个实例
object2 := U.uSL.Class:localEvent(New, E.class := "Example");
//修改实例object2中变量var1的状态
example:var1:=4;
//为实例object调用方法
example:localEvent(ExampleFunc, E.ref := M.object);
//函数将返回5
//检查实例object2中的变量var3
Debug(example:var3);
//调用将返回1,因为类的主实例是object2
为object2调用函数
example:localEvent(ExampleFunc, E.ref:=M.object2);
//函数将返回6
//再次检查变量var3,确保其存储的值为7
调试(示例:var3);
//通过在参数中传递所需引用,更改类的实例
示例:本地事件(__changeInstance,E.ref:=M.object);
//确保var3现在存储的值为5
调试(示例:var3);
//删除已创建的类
U.uSL.Class:本地事件(删除, E.ref := M.object);
U.uSL.Class:本地事件(删除, E.ref := M.object2);
银河脚本库版本2
版本2库的工作方式将在下面描述。