Zh/Survival Gametype (L4D)

本文包括为创建生还者模式地图的基本指导。
== 开始生还者模式 ==
生存回合通过触发任何形式的恐慌事件开始。
任何能够告诉导演强制触发的实体都有效。比如、、、、，甚至是自动点唱机上的某首歌。
这与启动结局事件或高潮事件(crescendo event)的设置方法相同。
== 导航网格 ==
所有生还者模式地图都依赖于使用「Finale」或「Battlefield」以及可选的「Battlestation」属性在导航网格上定义生还者模式的游戏空间。
根据地图是专为生还者模式设计，还是在已经用于战役的地图中添加生还者模式，导航网格的设置方法有所不同。
=== 纯生还者模式地图 ===
仅用于支持生还者游戏模式的地图只需要三个：Player_Start、Battlefield 和 Finale。
# 进入，使用控制台命令nav_add_to_selected_set选择玩家起始点周围的区域，选择一个导航方块，或使用nav_begin_drag_selecting接着使用nav_end_drag_selecting进行框选多个方块。
# 使用控制台命令mark player_start标记为玩家起始区域。
# 使用控制台命令nav_select_radius 99999999999999选择整个导航网格并将其标记为Battlefield和NOT_CLEARABLE。
# 使用控制台命令nav_clear_selected_set取消整个导航网格的选择。
# 在生存开始触发器周围（或任何地方）选择几个导航网格方块，并将这些面标记为Finale。
# 使用控制台命令nav_save保存导航网格。
# 一旦确定导航网格完成，使用nav_analyze进行完整分析。
其他有用的属性：
*Battlestation - 使生还者机器人在战斗时保持靠近该区域。
*Obscured - 将一个区域标记为始终无法看到。非常有用，用来告诉导演可以在此区域自由生成感染者。
*No_Mobs - 强制导演在该导航区域内不生成任何普通感染者。适用于「竞技场类」地图，感染者应通过门进入。
=== 多模式地图 ===
现有的高潮事件或结局事件，如果使用了「Battlefield」或「Finale」导航属性，通常可以在不修改导航网格的情况下直接使用。
如果你的地图在合作模式地图中添加了生存部分，请添加一个，将生存区域以及感染者应该生成的区域围住。
将其命名为「survival_nav_battlefield」，并启用「Battlefield」和「Not_Clearable」标记。你还可以添加多个具有相同名称的「func_nav_attribute_region」实体，用于更多属性，如「Battlestation」，这是生还者机器人通常停留的区域。
要启用这些导航属性，你需要一个实体，强制生成一个带有输出「OnSurvivalPostIO」的实体。
	OnSurvivalPostIO	Point_template	ForceSpawn	<none>	0.0	No
这个point_template可以用来生成所有生还者模式所需的实体，如所有武器和阻挡路径的道具。
== info_survivor_position ==
生还者会在实体处生成。
不幸的是，结局地图使用相同的实体在生还者接近逃生车辆时将其「传送」走。如果你的生还者模式地图也是战役的结局，或者你的地图将info_survivor_position用于生存起点之外的其他用途，你需要删除这些实体。否则，玩家可能会生成到错误的位置。
通过实体删除额外的info_survivor_position实体，使用以下输出
	OnSurvival	救援中使用的 info_survivor_position 	kill	<none>	0.0	No
== 道具 ==
在L4D中，地图中放置的所有道具在生还者模式中都会生成，无论其他模式中允许的道具密度如何。如果你希望更改道具的放置或数量，可以使用info_gamemode来生成或删除道具。
在L4D2中，生还者模式下会删除所有道具生成。
为了生成道具，你必须为每个预定的生存道具命名。你可以将所有道具命名为相同的名称以便管理。
添加一个，为其指定一个唯一的名称，并在其「Template」行中列出所有生存道具的名称。
添加一个实体，并设置以下输出
	OnSurvivalPostIO	Point_template	ForceSpawn	<none>	0.0	No
== info_gamemode - 其他用途 ==
地图可以根据运行的游戏模式加载不同的实体。如前一节所述，L4D2中的生还者模式需要info_gamemode和point_template来生成任何生还者模式中的道具。
这两个实体还可以用于加载墙体、碰撞刷、、道具或任何其他类型的实体到你的生还者模式地图中。例如，添加屏障道具来阻止玩家进入结束地图的安全房间。
或者，你可以使用info_gamemode与配合，删除你不希望在生还者模式中出现的道具，如，它们在被射击时会提前启动生存回合。
== 任务文件和测试 ==
在你测试生还者模式地图之前，你必须将你的地图添加到任务文件的“生存”模式部分。
示例：
 "modes"
 {
 	"survival"
 	{
 		"1"
 		{
 		"Map" "mymap"
 		"DisplayName" "我的生还者模式地图"
 		"Image" "maps/preview_01"	
 		}
 	}
 }
地图可以通过主菜单加载到生还者模式，或者通过控制台使用命令“map mapname_here survival”加载。后者允许你在生还者模式下使用 sv_cheats 1。
== 通过Vscript更改默认设置 ==
生还者模式的大部分设置，甚至可以说是所有设置，都是一组控制台命令。这意味着我们几乎可以完全改变生还者模式的行为。
以下可以添加到任何的Vscript变量中。最好是。地图启动后，它将用你定义的设置替换所有默认设置。
// 生存控制变量
Convars.SetValue("director_survival_setup_time", 	 0) //默认值: 0 - 自动开始之前的设置时间限制。
Convars.SetValue("survival_boomer_limit_increase", 	 0) //默认值: 0 - 每个特殊波之后，增加最大Boomer数量。
Convars.SetValue("survival_charger_limit_increase", 	 0)	//默认值: 0 - 每个特殊波之后，增加最大Charger数量。
Convars.SetValue("survival_horde_stage_interval", 	60) //默认值: 60 - 军团攻击之间的间隔秒数。
Convars.SetValue("survival_horde_stage_interval_decay", 	 2) //默认值: 2 - 每次军团攻击后，将间隔减少的秒数。
Convars.SetValue("survival_hunter_limit_increase", 	 1) //默认值: 1 - 每个特殊波之后，增加最大Hunter数量。
Convars.SetValue("survival_jockey_limit_increase", 	 1) //默认值: 1 - 每个特殊波之后，增加最大Jockey数量。
Convars.SetValue("survival_lull_time", 	15) //默认值: 15 - 生存波之间的平静时长。
Convars.SetValue("survival_lull_time_increment", 	15) //默认值: 15 - 每波生存时，平静时长的增量。
Convars.SetValue("survival_lull_time_max", 	60) //默认值: 60 - 平静时长的最大值。
Convars.SetValue("survival_max_boomers", 	 2) //默认值: 2 - 同时存在的最大Boomer数量。
Convars.SetValue("survival_max_chargers", 	 2) //默认值: 2 - 同时存在的最大Charger数量。
Convars.SetValue("survival_max_hunters", 	 3) //默认值: 3 - 同时存在的最大Hunter数量。
Convars.SetValue("survival_max_jockeys", 	 2) //默认值: 2 - 同时存在的最大Jockey数量。
Convars.SetValue("survival_max_smokers", 	 4) //默认值: 4 - 同时存在的最大Smoker数量。
Convars.SetValue("survival_max_specials", 	 8) //默认值: 8 - 同时存在的最大特殊感染者数量。
Convars.SetValue("survival_max_spitters", 	 3) //默认值: 3 - 同时存在的最大Spitter数量。
Convars.SetValue("survival_round_restart_delay", 	15) //默认值: 15 - 失败后，重新开始这一轮的延迟秒数。
Convars.SetValue("survival_smoker_limit_increase", 	 1) //默认值: 1 - 每个特殊波之后，增加最大Smoker数量。
Convars.SetValue("survival_special_limit_increase", 	 1) //默认值: 1 - 每个特殊波之后，增加最大特殊感染者数量。
Convars.SetValue("survival_special_spawn_interval", 	20) //默认值: 20 - 特殊感染者生成波之间的间隔秒数。
Convars.SetValue("survival_special_spawn_interval_decay",	 1)	//默认值: 1 - 每个特殊波后，减少生成间隔的秒数。
Convars.SetValue("survival_special_stage_interval", 	60) //默认值: 60 - 在经过多少秒后，增加特殊感染者数量限制。
Convars.SetValue("survival_spitter_limit_increase", 	 1)	//默认值: 1 - 每个特殊波后，增加最大Spitter数量。
Convars.SetValue("survival_tank_multiple_spawn_delay", 	10) //默认值: 10 - 双重生成时，两只Tank之间的延迟。
Convars.SetValue("survival_tank_stage_interval", 	80) //默认值: 80 - Tank攻击之间的间隔秒数。
Convars.SetValue("survival_tank_stage_interval_decay", 	20) //默认值: 20 - 若干波后，减少Tank攻击间隔的秒数。
DirectorOptions <- {
// 故意留空。 
// 必须有以下的 Mutation15 相关内容才能生效。
}
// Mutation15 (对抗生存) 的控制台变量。只有在 Mutation15 激活时才会更改这些设置。
if ( Director.GetGameMode() == "mutation15" )
{ 
 DirectorOptions.ActiveChallenge <- 1; 
 DirectorOptions.cm_ProhibitBosses <- 0; 
 DirectorOptions.cm_CommonLimit <- 25; 
 DirectorOptions.cm_TankLimit <- 1; 
 DirectorOptions.ZombieTankHealth <- 2667; 
 // Mutation 15 会在 90 秒后强制启动生存计时器。但这只会触发“PanicEvent”输出。
 // 如果你的生存启动按钮也触发声音、粒子效果或其他事件，这些事件将不会被触发。
 // 要确保这些事件被触发，你必须使用以下函数来自动触发按钮。
 // 请注意，如果你的生存启动按钮有在计时器上触发“ForcePanicEvent”，你需要将其包含到计算中。
 // 举个例子，“SurvivalSetupTime”在 90 秒后触发。
 // “Survival_Start_relay”在 89 秒后触发，但还需要 1 秒延迟来强制触发 PanicEvent。因此两个 PanicEvent 会同时触发。
 
 DirectorOptions.SurvivalSetupTime <- 90; // 在 90 秒后触发 PanicEvent。
 function OnGameEvent_round_start_post_nav(params){
 DoEntFire("Survival_Start_relay", "trigger", "", 89, null, null) // 在 89 秒后触发此继电器。
 }
 Convars.SetValue("director_special_initial_spawn_delay_max", 10) // coop 默认: 60 - mutation15 默认: 10 
 Convars.SetValue("director_special_initial_spawn_delay_min", 2) // coop 默认: 30 - mutation15 默认: 2 
 Convars.SetValue("tongue_break_from_damage_amount", 300) // coop 默认: 50 - mutation15 默认: 300 
 Convars.SetValue("tongue_choke_damage_amount", 5) // coop 默认: 10 - mutation15 默认: 5 
 Convars.SetValue("tongue_dropping_to_ground_time", 0.5) // coop 默认: 2 - mutation15 默认: 0.5 
 Convars.SetValue("tongue_hit_delay", 15) // coop 默认: 20 - mutation15 默认: 15 
 Convars.SetValue("tongue_los_forgiveness_time", 1.5) // coop 默认: 1 - mutation15 默认: 1.5 
 Convars.SetValue("tongue_miss_delay", 3) // coop 默认: 15 - mutation15 默认: 3 
 Convars.SetValue("tongue_no_progress_choke_early_delay", 1.0) // coop 默认: 1.5 - mutation15 默认: 1.0 
 Convars.SetValue("z_ghost_los_expected_progress", 2000) // coop 默认: 1500 - mutation15 默认: 2000 
 Convars.SetValue("z_hunter_limit", 2) // coop 默认: 1 - mutation15 默认: 2 
 Convars.SetValue("z_jockey_ride_damage", 2) // coop 默认: 4 - mutation15 默认: 2 
 Convars.SetValue("z_jockey_ride_damage_interval", 0.5) // coop 默认: 1 - mutation15 默认: 0.5 
 Convars.SetValue("z_max_stagger_duration", 0.9) // coop 默认: 6 - mutation15 默认: 0.9 
 Convars.SetValue("z_pounce_damage_interrupt", 150) // coop 默认: 50 - mutation15 默认: 150 
 Convars.SetValue("z_pounce_stumble_radius", 160) // coop 默认: 0 - mutation15 默认: 160 
 Convars.SetValue("z_scrimmage_creep_delay", 0) // coop 默认: 30 - mutation15 默认: 0 
 Convars.SetValue("z_scrimmage_creep_rate", 100) // coop 默认: 30 - mutation15 默认: 100 
 Convars.SetValue("z_smoker_limit", 2) // coop 默认: 1 - mutation15 默认: 2 
 Convars.SetValue("z_spawn_safety_range", 200) // coop 默认: 550 - mutation15 默认: 200 
}
== 另请参阅 ==
* 
*