Zh/L4D2 Vscripts

求生之路2 是可以在游戏中的虚拟机里被运行的服务器端的脚本。它们使用语言编写, 这是一种类似于Lua的脚本编译语言. 
本页面内容由Dazai Nerau译自. 欢迎任何人补充新内容或者修改其中的错误.
== 用途 ==
=== ===
在求生之路2中的最通常的用处是用来指挥人工智能导演系统。 这些脚本的用途包括但不限于调整普通感染者的数量或者, 或者用以自定义诸如onslaughts和gauntlets之类的游戏事件, 甚至是复杂的尸潮事件和完全定制的
。 大多数官方活动也是通过这种方式制作的。导演脚本的主要工作是将导演系统所使用的各种变量的值覆盖写入DirectorOptions表.
一次只能运行一个导演脚本。执行新的导演脚本将终止先前运行的任何脚本并删除它在DirectorOptions表中设置的任何值。
=== 实体脚本 ===
另一个常见的用途是将脚本附加到实体上。 脚本提供了轻松便捷的途径以修改或读取大多数实体的属性，甚至可以写入新的。这便使得在Hammer中不可能实现的对实体I/O系统的复杂控制成为了可能。
任何实体都能运行脚本，并且拥有以0.1秒运行一次think函数的能力，也可以将脚本代码作为实体输出以执行.
一些实体还拥有VScripts的专用功能，最显著的例子是，它能将其他实体转换为完全可编程的定时按钮。
=== 全局脚本 ===
脚本也可以被设定成在地图加载时执行，基于特定的游戏模式或者可选的地图名。 这些脚本通常用于为创造剧本或者修改全局导演系统设置，当然也可以用于对地图的自定义。
全局脚本可以添加脚本钩子函数，这些函数会在游戏中的特定时间发生时被调用，比如当玩家/物件造成伤害。 
这些脚本有许多实用功能和功能，包括资源和建造系统，以及产生自定义尸潮。请阅读了解详情。
=== 其他用途 ===
总而言之，这些脚本拥有各种各样的超能力，包括从预编译的列表中或者程序性地，，自定义一个 ，
跨关卡地至硬盘，以及其他数不胜数的功能。
请阅读和了解详情。
== 脚本文件 ==
脚本以文本文件的形式被读取, 脚本的扩展名为.nut 和 .nuc , 其中 .nuc 是对纯文本形式的 .nut 的加密. 自定义脚本会从 \left 4 dead 2\left4dead2\scripts\vscripts\中被读取, 包括.vpk文件中的也是这样。
=== 位置 ===
;官方的 .nuc 脚本文件位于 scripts/vscripts 
*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. 你可以使用 对它们进行解码. 
Packages with deciphered official scripts are also available.
== 加载脚本 ==
VScripts以不同的方式加载，具体取决于它们的用途. 它们也可以通过在控制台手动输入script filename的方式加载.
=== 导演脚本 ===
;使用实体进行如下输入(inputs):
:BeginScript <script name>
::执行一个普通的导演脚本, 比如为了onslaught事件而设计的脚本.
:EndScript
::停止执行脚本并重置导演系统设置中的变量值.
:BeginScriptedPanicEvent <script name>
::执行一次脚本化的尸潮
=== 导演脚本（结局） ===
:<map name>_finale.nut会在结局地图加载时被自动读取. 这个脚本也可以因的使用而被触发, 或者通过玩家手动触发, 或者通过ForceFinaleStart这一输入触发.
:
所有的导演脚本存在于DirectorScript这一脚本域(script scope)之中.
=== 实体脚本 ===
;方式1：地图加载时自动读取
:通过设置实体中的Entity Scripts键值加载脚本
;方式2：手动加载
:使用 RunScriptFile这一输入
实体脚本位于_<unique ID>_<entity name>这一脚本域中
=== 全局脚本 ===
;方式1：通过模式指定脚本
:与同名的脚本将会自动运行. 比如运行一个地图 map <map name> mutation12 将会自动加载mutation12.nuc这一写实对抗脚本.
:全局脚本位于g_ModeScript这一脚本域中
;方式2：通过地图指定脚本(只在脚本化模式中有效)
:每个地图的脚本可以被在当地图运行指定模式时被创建和执行, 使用 <map name>_<mode name>.nut这一格式的指令, 比如, c1m4_atrium_mutation12.nut.
:它们位于g_MapScript这一脚本域中
== 脚本环境 ==
请阅读含有类(classes)和函数(functions)的以了解详情. 
当一个脚本被加载,它会被放入一个表,我们称之为脚本域(Script Scope).模式、地图和导演脚本会被放入设置域中,同时会为每个实体脚本生成独一无二的域. 有关更多信息，请参阅.
=== 表的结构 ===
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
== 实体脚本 ==
脚本域为 _<unique ID>_<entity name>
把一个脚本添加到一个服务器端的实体的Entity Scripts的键值中可以将其以实体脚本加载. 脚本会在实体产生时被执行,并加载到一个唯一的脚本域内，该范围由唯一标识符后跟实体名称或种类名组成. 
Think函数可以在 thinkfunction 中设置, 指定的脚本函数会以0.1秒一次的频率被执行. 函数也可以通过I/O系统以RunScriptCode function_name(argument, ...) 的形式手动调用.
实体脚本能够通过self引用到调用它们的实体,这使得脚本可以轻松地通过它的类方法(class methods)控制实体. 有些实体类还有可用的钩子函数(hook functions). 各种方法和钩子都可以在这里找到.
一些实体拥有额外的叫本宫拿:
* - 能通过方法或者钩子来控制按钮.
* - 能够一个一个叫做EntityGroup的数组传递过个实体的名字给脚本.
*
*
*
可以使用控制台命令ent_fire <name of entity> runscriptfile <relative vscript path>重新加载脚本. 这样做方便快捷，非常有用.
=== 交互===
任何脚本可以通过使用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 <- null;
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 对所有的实体(但少数实体并不支持这么做)进行输入. 那些代码会在该实体的脚本域中被执行.
== 全局脚本 ==
使用游戏模式命名脚本文件，命名特定于模式的脚本，并在每次以指定模式加载地图时执行该脚本文件。 如果存在模式脚本，则还可以加载具有地图名称后跟下划线和模式名称的地图特定脚本。
=== 脚本化模式 ===
添加模式脚本将为游戏模式启用脚本化模式。 这对于游戏中包含的基本游戏模式也同样生效。
脚本化模式将实用程序功能加载到g_ModeScript 域中, 禁用导演设置的MaxSpecials “2” 选项, 启用 和 脚本钩子函数. 它似乎破坏了黑暗狂欢节最后的坦克音乐.
=== 共享表 ===
;SessionState
:A table for storing session specific variables. Not preserved across level transitions.
;SessionOptions
:Base Director Options for the game mode.
=== 可用函数 ===
=== 模式脚本 ===
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. 
;脚本句柄（Script handle）
:具有C++实体对象的访问器和更改器的实体实例. 也叫HScript.
;脚本域（Script scope）
:存放一个VScript的变量、函数和类的表.
== 导演设置 ==
请阅读L4D2导演脚本了解详情.
== 第三方工具 ==
===VSLib===
VSLib (VScript Library) 是一个简单的，轻量级的L4D2的VScript的编译系统的库. 它通过为您处理大量繁琐的工作，大大简化了VScripts的编码. 它被用于几个流行的MOD比如Rayman1103's Admin System 和Stranded. 更多详情请阅.
== 推荐阅读 ==
*
*
*
*
*
*
*
*
*
*
*
== 外部链接 ==
;Alternative Tool
* (mediafire)L4D2 VScript Editor Beta 0.5 by Cynick:support nut (de)compile for l4d2
;Alternative Documentation
* Director Scripts - .nuc files (Steam forums)
* It's the vscript'ing documentation FAQ! (Steam forums)
* Tutorial - Writing a Mini Game - Tic Tac Toe - Part One (Steam Forums)
**Writing a Mini Game - Tic Tac Toe - Part One - Author's Website
**l4d2 - Vscript example - Tic-Tac-Toe - Video of early Prototype
**l4d2 - Vscript example - Tic-Tac-Toe - updated - Video of current version with "brutally misanthropic AI"
* Mutation scripts (Steam forums)
* Squirrel Binary for Windows
* Squirrel (programming language) - Wikipedia Article on Squirrel
* Squirrel: The Programming Language - Documentation and Sample Code
* The AI Systems of Left 4 Dead by Michael Booth (PDF)
* "Creating a "Money"/Point System" - Swarm Armory
;Deciphered Official Scripts:
*Version 2.1.3.6 and all mutations
*Version 2.0.8.4 (August 16, 2011)
+ =