求生之路2 脚本 是可以在游戏中的虚拟机里被运行的服务器端的脚本。它们使用Squirrel语言编写, 这是一种类似于Lua的脚本编译语言.
本页面内容由Dazai Nerau译自英文版页面. 欢迎任何人补充新内容或者修改其中的错误.
用途
VScripts在求生之路2中的最通常的用处是用来指挥人工智能导演系统。 这些脚本的用途包括但不限于调整普通感染者的数量或者禁止BOSS感染者的产生, 或者用以自定义诸如onslaughts和gauntlets之类的游戏事件, 甚至是复杂的尸潮事件和完全定制的
自定义结局。 大多数官方活动也是通过这种方式制作的。导演脚本的主要工作是将导演系统所使用的各种变量的值覆盖写入DirectorOptions表.
一次只能运行一个导演脚本。执行新的导演脚本将终止先前运行的任何脚本并删除它在DirectorOptions表中设置的任何值。
另一个常见的用途是将脚本附加到实体上。 脚本提供了轻松便捷的途径以修改或读取大多数实体的属性,甚至可以写入新的KeyValues(键值)。这便使得在Hammer中不可能实现的对实体I/O系统的复杂控制成为了可能。
任何实体都能运行脚本,并且拥有以0.1秒运行一次think函数的能力,也可以将脚本代码作为实体输出以执行.
一些实体还拥有VScripts的专用功能,最显著的例子是point_script_use_target,它能将其他实体转换为完全可编程的定时按钮。
脚本也可以被设定成在地图加载时执行,基于特定的游戏模式或者可选的地图名。 这些脚本通常用于为突变模式创造剧本或者修改全局导演系统设置,当然也可以用于对地图的自定义。
全局脚本可以添加脚本钩子函数,这些函数会在游戏中的特定时间发生时被调用,比如当玩家/物件造成伤害。
这些脚本有许多实用功能和功能,包括资源和建造系统,以及产生自定义尸潮。请阅读EMS教程了解详情。
其他用途
总而言之,这些脚本拥有各种各样的超能力,包括从预编译的列表中或者程序性地产生实体,产生感染者,自定义一个 HUD系统,
跨关卡地存储数据至硬盘,以及其他数不胜数的功能。
脚本文件
脚本以文本文件的形式被读取, 脚本的扩展名为.nut 和 .nuc , 其中 .nuc 是对纯文本形式的 .nut 的加密. 自定义脚本会从 \left 4 dead 2\left4dead2\scripts\vscripts\中被读取, 包括.vpk文件中的也是这样。
位置
官方的 .nuc 脚本文件位于 scripts/vscripts
Note:使用诸如GCFScape的第三方程序浏览和解包VPK
left 4 dead 2\left4dead2\pak01_dir.vpk
left 4 dead 2\left4dead2_dlc1\pak01_dir.vpk
April 22, 2010 The Passing update
left 4 dead 2\left4dead2_dlc2\pak01_dir.vpk
October 5, 2010 The Sacrifice update
left 4 dead 2\left4dead2_dlc3\pak01_dir.vpk
March 22, 2011 Cold Stream Beta / L4D1 Transition Project update
left 4 dead 2\update\pak01_dir.vpk
This is where mutations were updated/replaced bi-weekly.
left 4 dead 2\sdk_content\scripting\scripts\vscripts\
Plaintext versions of many of the scripts introduced in the EMS update.
解密NUC文件
.nuc 文件是经过ICE加密的 .nut 文件. 其秘钥是 SDhfi878. 你可以使用 VICE 对它们进行解码.
加载脚本
VScripts以不同的方式加载,具体取决于它们的用途. 它们也可以通过在控制台手动输入script filename的方式加载.
导演脚本
使用info_director实体进行如下输入(inputs)
BeginScript
执行一个普通的导演脚本, 比如为了onslaught事件而设计的脚本.
EndScript
停止执行脚本并重置导演系统设置中的变量值.
BeginScriptedPanicEvent
执行一次脚本化的尸潮
Note:如果脚本位于子目录中,则与BeginScriptedPanicEvent一起使用的脚本将无法工作,即使你能在其他脚本的上下文中使用子目录. 它们必须位于vscripts文件夹下,否则它们只会简单地以1个阶段1秒的延迟运作.
导演脚本(结局)
_finale.nut会在结局地图加载时被自动读取. 这个脚本也可以因trigger_finale的使用而被触发, 或者通过玩家手动触发, 或者通过ForceFinaleStart这一输入触发.
To do:trigger_finale 还有一个指定结局脚本的选项,但它似乎不起作用.
所有的导演脚本存在于DirectorScript这一脚本域(script scope)之中.
实体脚本
方式1:地图加载时自动读取
通过设置实体中的Entity Scripts键值加载脚本
方式2:手动加载
使用 RunScriptFile这一输入
实体脚本位于__这一脚本域中
全局脚本
方式1:通过模式指定脚本
与游戏模式同名的脚本将会自动运行. 比如运行一个地图 map mutation12 将会自动加载mutation12.nuc这一写实对抗脚本.
全局脚本位于g_ModeScript这一脚本域中
Note:给一个模式添加脚本就意味着该模式成为脚本化模式(scripted mode).
方式2:通过地图指定脚本(只在脚本化模式中有效)
每个地图的脚本可以被在当地图运行指定模式时被创建和执行, 使用 _.nut这一格式的指令, 比如, c1m4_atrium_mutation12.nut.
它们位于g_MapScript这一脚本域中
脚本环境
请阅读含有类(classes)和函数(functions)的L4D2脚本函数列表以了解详情.
当一个脚本被加载,它会被放入一个表,我们称之为脚本域(Script Scope).模式、地图和导演脚本会被放入设置域中,同时会为每个实体脚本生成独一无二的域. 有关更多信息,请参阅Vscript的基本原理.
表的结构
DirectorScript = // Base Director Scope.
{
DirectorOptions // Base DirectorOptions table.
MapScript = // Map Script scope.
{
BaseScriptedDOTable // Hardcoded DirectorOptions.
ChallengeScript = // Mode Script scope.
{
MutationState // Initial values for SessionState.
MutationOptions // Initial values for SessionOptions.
}
LocalScript =// Script Scope Director Scripts are placed in.
{
DirectorOptions // DirectorOptions for current Director Script (like onslaughts). Only availabe when a script is active.
}
MapOptions // Initial values for SessionOptions.
MapState // Initial values for SessionState.
}
}
g_MapScript // Global reference to the Map Script scope (DirectorScript.MapScript).
g_ModeScript // Global reference to the Mode Script scope (DirectorScript.MapScript.ChallengeScript).
g_rr// Scope holding the Response Rule system.
g_RoundState// TODO
SessionOptions //Global Director options (Scripted mode only).
SessionState //State variables for game modes (Scripted mode only).
委托
一些表已经设置了委托, 所以如果一个键值缺省, 就会从其父表中读取该值.
表的委托长成这样:(右边是父表)
The Director Scope
(DirectorScript.MapScript.ChallengeScript; DirectorScript.MapScript.LocalScript) < DirectorScript.MapScript < DirectorScript
DirectorOptions
DirectorScript.MapScript.LocalScript.DirectorOptions (When Director Script active) < DirectorScript.MapScript.ChallengeScript.DirectorOptions (Scripted mode only) < DirectorScript.DirectorOptions
实体脚本
脚本域为 __
把一个脚本添加到一个服务器端的实体的Entity Scripts的键值中可以将其以实体脚本加载. 脚本会在实体产生时被执行,并加载到一个唯一的脚本域内,该范围由唯一标识符后跟实体名称或种类名组成.
Think函数可以在 thinkfunction 键值中设置, 指定的脚本函数会以0.1秒一次的频率被执行. 函数也可以通过I/O系统以RunScriptCode function_name(argument, ...) 的形式手动调用.
实体脚本能够通过self引用到调用它们的实体,这使得脚本可以轻松地通过它的类方法(class methods)控制实体. 有些实体类还有可用的钩子函数(hook functions). 各种方法和钩子都可以在这里找到.
一些实体拥有额外的叫本宫拿:
可以使用控制台命令ent_fire runscriptfile 重新加载脚本. 这样做方便快捷,非常有用.
任何脚本可以通过使用EntFire() and DoEntFire() 来触发地图实体的输出. 由于activator 和 caller 声明在 DoEntFire() 中是句柄, 所以可以直接通过 "!self" or "!activator" 关键字来触发实体, 即便你不知道它们的名字, 只要实体的句柄是有效的.
EntFire( "church_bell_relay", "Trigger", 0 ); // Fires an output to the Trigger input of the named entity.
player
while(player = Entities.FindByClassname(player, "player")) // Iterate through the script handles of the players.
{
DoEntFire("!self", "speakresponseconcept", "PlayerLaugh", 0, null, player); // Make each player laugh.
}
相反, CBaseEntity::ConnectOutput() 和 DisconnectOutput() 可以被用来在指定的实体输出被触发时调用脚本函数. 值得一提, 可以从I/O系统中运行任意的VScript代码,通过使用 RunScriptCode 对所有的实体(但少数实体并不支持这么做)进行输入. 那些代码会在该实体的脚本域中被执行.
Warning:切勿在任何Hammer输出中使用双引号, 因为它会破坏地图文件. 这意味着无法通过RunScriptCode 传递字符串.
全局脚本
使用游戏模式命名脚本文件,命名特定于模式的脚本,并在每次以指定模式加载地图时执行该脚本文件。 如果存在模式脚本,则还可以加载具有地图名称后跟下划线和模式名称的地图特定脚本。
To do:添加有关加载到这些功能和实用程序功能的信息.
脚本化模式
添加模式脚本将为游戏模式启用脚本化模式。 这对于游戏中包含的基本游戏模式也同样生效。
脚本化模式将实用程序功能加载到g_ModeScript 域中, 禁用导演设置的MaxSpecials “2” 选项, 启用 游戏事件回调 和 脚本钩子函数. 它似乎破坏了黑暗狂欢节最后的坦克音乐.
To do:启用脚本化模式是否会产生其他后果?
共享表
SessionState
A table for storing session specific variables. Not preserved across level transitions.
SessionOptions
Base Director Options for the game mode.
可用函数
To do:Document the available utility features.
模式脚本
Use script scope g_ModeScript
表
MutationState
Initial values for the SessionState table.
MutationOptions
Initial values for the SessionOptions table.
地图脚本
Use script scope g_MapScript
表
MapState
Map specific values for the SessionState table.
MapOptions
Map specific values for the SessionOptions table.
术语
导演设置(DirectorOptions)
一个控制人工智能导演系统的行为的由命名变量组成的表。
实体句柄(Entity handle)
也被称为EHANDLE. To do:类似一种指向实体的指针.
脚本句柄(Script handle)
具有C++实体对象的访问器和更改器的实体实例. 也叫HScript.
脚本域(Script scope)
存放一个VScript的变量、函数和类的表.
导演设置
请阅读L4D2导演脚本了解详情.
第三方工具
VSLib
VSLib (VScript Library) 是一个简单的,轻量级的L4D2的VScript的编译系统的库. 它通过为您处理大量繁琐的工作,大大简化了VScripts的编码. 它被用于几个流行的MOD比如Rayman1103's Admin System 和Stranded. 更多详情请阅VSLib.
推荐阅读
外部链接
Alternative Tool
Alternative Documentation
Deciphered Official Scripts
+
=