Moderator elections are being held. See Valve Developer Community:Moderator elections for more details.
Users who would like to run for moderator must be autoconfirmed and have at least 100 edits. Users can check their own edit count at Special:Preferences.
Users who would like to run for moderator must be autoconfirmed and have at least 100 edits. Users can check their own edit count at Special:Preferences.
L4D2 Level Design/Custom Finale/zh
语言子页面
该子页面用于在 L4D2 Level Design/Custom Finale 页面上以 中文 (Chinese) 显示内容。
如果你已编辑本语言子页面,不要忘记通过点击右边的按钮刷新根页面。否则,内容不会更新。
本页面由大康翻译于2022年1月2日。部分内容由机器翻译。
Contents
- 1 组成内容
- 2 牺牲结局
- 3 解密的官方结局脚本
- 3.1 c1m4_atrium_finale.nuc
- 3.2 c1m4_finale_wave_1.nuc
- 3.3 c1m4_delay.nuc
- 3.4 c2m5_concert_finale.nuc
- 3.5 c3m4_plantation_finale.nuc
- 3.6 c4m5_milltown_escape_finale.nuc
- 3.7 c6m3_port_finale.nuc
- 3.8 c7m3_port_finale.nuc
- 3.9 c8m5_rooftop_finale.nuc
- 3.10 c9m2_lots_finale.nuc
- 3.11 c10m5_houseboat_finale.nuc
- 3.12 c11m5_runway_finale.nuc
- 3.13 c12m5_cornfield_finale.nuc
- 3.14 c14m1_lighthouse_finale.nuc
- 3.15 c14m2_lighthouse_finale.nuc
- 3.16 director_gauntlet.nuc (为所有长途救援结局共享)
- 4 另请参阅
自定义结局会自动从包含阶段列表的脚本(VScript)中读取:<地图名称>_finale.nut。该系统具有在满足任意条件(即终极感染者、Aztec tomb puzzles、feats of strength 等)时增强结局阶段的能力。一旦所有阶段都完成,trigger_finale 会触发 FinaleEscapeStarted 输出。
自定义结局地图包括 c2m5_concert、c3m4_plantation、c4m5_milltown_escape、c7m3_port,假设求生之路1的结局也一样(毫不留情已被确认是使用自定义结局的)。官方地图不使用Standard
(标准) 结局类型。
组成内容
地图
最起码,所有需要改变的是 trigger_finale 的 Finale Type (结局类型),从Standard
到Custom
。你还应该考虑其他选项和细节:
- 除非通过脚本 EntFire(直接或间接)或简单地在游戏中使用 I/O 为导演提供输入 EndCustomScriptedStage,否则猛攻(Onslaught)阶段类型不会结束。
- info_director: 在自定义结局事件时,OnCustomPanicStageFinished, OnPanicEventFinished (也许只是为了渐强事件),和 OnUserDefinedScriptEvent(1-4) 输出可用,链接到 vscript 阶段状态或方法,如 .UserDefinedEvent1()-.UserDefinedEvent4().
- trigger_finale: AdvanceFinaleState 输入可用。
脚本
正如 L4D2 脚本文章中所讨论的,有四种阶段类型、附加的自定义结局特定导演选项和可用的特殊功能。
以下是带有附加注释的自定义结局脚本:
c2m5_concert_finale.nut
//-----------------------------------------------------------------------------
// 阶段类型的列举
ERROR <- -1 //这个枚举并不总是使用,但到底是什么!
PANIC <- 0
TANK <- 1
DELAY <- 2
ONSLAUGHT <- 3
//-----------------------------------------------------------------------------
// 将提供给 DirectorOptions 的表的初始化
SharedOptions <-
{
A_CustomFinale_StageCount = 9 //阶段数。也被导演VS评分用了??
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 1 //1 个尸潮
A_CustomFinale2 = PANIC
A_CustomFinaleValue2 = 1
A_CustomFinale3 = DELAY
A_CustomFinaleValue3 = 15 //15秒的延迟
A_CustomFinale4 = TANK
A_CustomFinaleValue4 = 1 //1 TANK
A_CustomFinaleMusic4 = "" //自定义音乐条目在脚本中关闭,在游戏中播放
A_CustomFinale5 = DELAY
A_CustomFinaleValue5 = 15
A_CustomFinale6 = PANIC
A_CustomFinaleValue6 = 2
A_CustomFinale7 = DELAY
A_CustomFinaleValue7 = 10
A_CustomFinale8 = TANK
A_CustomFinaleValue8 = 1
A_CustomFinaleMusic8 = ""
A_CustomFinale9 = DELAY
A_CustomFinaleValue9 = RandomInt( 5, 10 ) //5-10 秒之间的随机延迟
// 其他导演选项
PreferredMobDirection = SPAWN_LARGE_VOLUME
PreferredSpecialDirection = SPAWN_LARGE_VOLUME
ShouldConstrainLargeVolumeSpawn = false
ZombieSpawnRange = 3000
SpecialRespawnInterval = 20
}
InitialPanicOptions <- //与阶段 1 的 SharedOptions 分开的表
{
ShouldConstrainLargeVolumeSpawn = true
}
PanicOptions <- //一般的尸潮选项
{
CommonLimit = 25
}
TankOptions <- //TANK 阶段时使用的另一个单独的表
{
ShouldAllowSpecialsWithTank = true
SpecialRespawnInterval = 30
}
DirectorOptions <- clone SharedOptions //DirectorOptions 使用 SharedOptions
{
}
//-----------------------------------------------------------------------------
// 经常用于将表复制到另一个表
function AddTableToTable( dest, src )
{
foreach( key, val in src )
{
dest[key] <- val
}
}
//-----------------------------------------------------------------------------
// 使用自定义逻辑操作 DirectorOptions
// 在这种情况下,DirectorOptions 仅在新阶段开始时更改
function OnBeginCustomFinaleStage( num, type ) //特殊功能,当每个新的结局阶段开始时
{
if ( developer() > 0 ) //如果开发者模式打开,-dev
{
printl("========================================================");
printl( "Beginning custom finale stage " + num + " of type " + type );
}
//设置/确定 WAVEOPTIONS
local waveOptions = null
if ( num == 1 ) //如果第一阶段(假设是 PANIC)
{
waveOptions = InitialPanicOptions
}
else if ( type == PANIC ) //一般的尸潮(又名“恐慌事件”,"Panic Event")事件
{
waveOptions = PanicOptions
/* Change MegaMobSize if MegaMobMinSize is available in PanicOptions is available.
Was this ever used?? */
if ( "MegaMobMinSize" in PanicOptions )
{
waveOptions.MegaMobSize <- RandomInt( PanicOptions.MegaMobMinSize, MegaMobMaxSize )
}
}
else if ( type == TANK ) //TANK 时间!
{
waveOptions = TankOptions
}
//---------------------------------
// 完成确定 WAVEOPTIONS。现在,实际转到 DirectorOptions
MapScript.DirectorOptions.clear() //清除所有 DirectorOptions 表的值
AddTableToTable( MapScript.DirectorOptions, SharedOptions ); //返回到 SharedOptions
if ( waveOptions != null ) //最后添加依赖于阶段的选项(WAVEOPTIONS)
{
AddTableToTable( MapScript.DirectorOptions, waveOptions );
}
//---------------------------------
if ( developer() > 0 ) //更多开发输出 (-dev)
{
Msg( "\n*****\nMapScript.DirectorOptions:\n" );
foreach( key, value in MapScript.DirectorOptions )
{
Msg( " " + key + " = " + value + "\n" );
}
if ( LocalScript.rawin( "DirectorOptions" ) ) //RAWIN 检查 DirectorOptions 是否存在
{
Msg( "\n*****\nLocalScript.DirectorOptions:\n" );
foreach( key, value in LocalScript.DirectorOptions )
{
Msg( " " + key + " = " + value + "\n" );
}
}
printl("========================================================");
}
}
|
牺牲结局
牺牲结局基于自定义结局,并在牺牲更新中引入了额外的硬编码修改。
![Blank image.png](/w/images/b/ba/Blank_image.png)
c7m3_port_finale.nut
这比其他自定义结局更复杂,但本质上是为了自定义体验。该脚本表明牺牲结局类型主要取决于新的游戏内实体和实体功能。
//-----------------------------------------------------
// This script handles the logic for the Port / Bridge
// finale in the River Campaign.
//
//-----------------------------------------------------
Msg("Initiating c7m3_port_finale script\n");
//-----------------------------------------------------
// Enumerations
ERROR <- -1
PANIC <- 0
TANK <- 1
DELAY <- 2
//-----------------------------------------------------
// This keeps track of the number of times the generator button has been pressed.
// Init to 1, since one button press has been used to start the finale and run
// this script.
ButtonPressCount <- 1
// This stores the stage number that we last
// played the "Press the Button!" VO
LastVOButtonStageNumber <- 0
// We use this to keep from running a bunch of queued advances really quickly.
// Init to true because we are starting a finale from a button press in the pre-finale script
// see GeneratorButtonPressed in c7m3_port.nut
PendingWaitAdvance <- true
// We use three generator button presses to push through
// 8 stages. We have to queue up state advances
// depending on the state of the finale when buttons are pressed
QueuedDelayAdvances <- 0
// Tracking current finale states
CurrentFinaleStageNumber <- ERROR
CurrentFinaleStageType <- ERROR
// The finale is 3 phases.
// We randomize the event types in the first two
local RandomFinaleStage1 = 0
local RandomFinaleStage2 = 0
local RandomFinaleStage4 = 0
local RandomFinaleStage5 = 0
// PHASE 1 EVENTS
if ( RandomInt( 1, 100 ) < 50 )
{
RandomFinaleStage1 = PANIC
RandomFinaleStage2 = TANK
}
else
{
RandomFinaleStage1 = TANK
RandomFinaleStage2 = PANIC
}
// PHASE 2 EVENTS
if ( RandomInt( 1, 100 ) < 50 )
{
RandomFinaleStage4 = PANIC
RandomFinaleStage5 = TANK
}
else
{
RandomFinaleStage4 = TANK
RandomFinaleStage5 = PANIC
}
// We want to give the survivors a little of extra time to
// get on their feet before the escape, since you have to fight through
// the sacrifice.
PreEscapeDelay <- 0
if ( Director.GetGameMode() == "coop" )
{
PreEscapeDelay <- 5
}
else if ( Director.GetGameMode() == "versus" )
{
PreEscapeDelay <- 15
}
DirectorOptions <-
{
A_CustomFinale_StageCount = 8
// PHASE 1
A_CustomFinale1 = RandomFinaleStage1
A_CustomFinaleValue1 = 1
A_CustomFinale2 = RandomFinaleStage2
A_CustomFinaleValue2 = 1
A_CustomFinale3 = DELAY
A_CustomFinaleValue3 = 9999
// PHASE 2
A_CustomFinale4 = RandomFinaleStage4
A_CustomFinaleValue4 = 1
A_CustomFinale5 = RandomFinaleStage5
A_CustomFinaleValue5 = 1
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = 9999
// PHASE 3
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 1
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = PreEscapeDelay
TankLimit = 4
WitchLimit = 0
CommonLimit = 20
HordeEscapeCommonLimit = 15
EscapeSpawnTanks = false
//SpecialRespawnInterval = 80
}
function OnBeginCustomFinaleStage( num, type )
{
printl( "*!* Beginning custom finale stage " + num + " of type " + type );
printl( "*!* PendingWaitAdvance " + PendingWaitAdvance + ", QueuedDelayAdvances " + QueuedDelayAdvances );
// Store off the state...
CurrentFinaleStageNumber = num
CurrentFinaleStageType = type
// Acknowledge the state advance
PendingWaitAdvance = false
}
function GeneratorButtonPressed()
{
printl( "*!* GeneratorButtonPressed finale stage " + CurrentFinaleStageNumber + " of type " +CurrentFinaleStageType );
printl( "*!* PendingWaitAdvance " + PendingWaitAdvance + ", QueuedDelayAdvances " + QueuedDelayAdvances );
ButtonPressCount++
local ImmediateAdvances = 0
if ( CurrentFinaleStageNumber == 1 || CurrentFinaleStageNumber == 4 )
{
// First stage of a phase, so next stage is an "action" stage too.
// Advance to next action stage, and then queue an advance to the
// next delay.
QueuedDelayAdvances++
ImmediateAdvances = 1
}
else if ( CurrentFinaleStageNumber == 2 || CurrentFinaleStageNumber == 5 )
{
// Second stage of a phase, so next stage is a "delay" stage.
// We need to immediately advance past the delay and into an action state.
//QueuedDelayAdvances++ // NOPE!
ImmediateAdvances = 2
}
else if ( CurrentFinaleStageNumber == 3 || CurrentFinaleStageNumber == 6 )
{
// Wait states... (very long delay)
// Advance immediately into an action state
//QueuedDelayAdvances++
ImmediateAdvances = 1
}
else if ( CurrentFinaleStageNumber == -1 ||
CurrentFinaleStageNumber == 0 )
{
// the finale is *just* about to start...
// we can get this if all the buttons are hit at once at the beginning
// Just queue a wait advance
QueuedDelayAdvances++
ImmediateAdvances = 0
}
else
{
printl( "*!* Unhandled generator button press! " );
}
if ( ImmediateAdvances > 0 )
{
EntFire( "generator_start_model", "Enable" )
if ( ImmediateAdvances == 1 )
{
printl( "*!* GeneratorButtonPressed Advancing State ONCE");
EntFire( "generator_start_model", "AdvanceFinaleState" )
}
else if ( ImmediateAdvances == 2 )
{
printl( "*!* GeneratorButtonPressed Advancing State TWICE");
EntFire( "generator_start_model", "AdvanceFinaleState" )
EntFire( "generator_start_model", "AdvanceFinaleState" )
}
EntFire( "generator_start_model", "Disable" )
PendingWaitAdvance = true
}
}
function Update() //Called every 0.100 seconds
{
// Should we advance the finale state?
// 1. If we are in a DELAY state
// 2. And we have queued advances....
// 3. And we have not just tried to advance the advance the state....
if ( CurrentFinaleStageType == DELAY && QueuedDelayAdvances > 0 && !PendingWaitAdvance )
{
// If things are calm (relatively), jump to the next state
if ( !Director.IsTankInPlay() && !Director.IsAnySurvivorInCombat() )
{
if ( Director.GetPendingMobCount() < 1 && Director.GetCommonInfectedCount() < 5 )
{
printl( "*!* Update Advancing State finale stage " + CurrentFinaleStageNumber + " of type " +CurrentFinaleStageType );
printl( "*!* PendingWaitAdvance " + PendingWaitAdvance + ", QueuedDelayAdvances " + QueuedDelayAdvances );
QueuedDelayAdvances--
EntFire( "generator_start_model", "Enable" )
EntFire( "generator_start_model", "AdvanceFinaleState" )
EntFire( "generator_start_model", "Disable" )
PendingWaitAdvance = true
}
}
}
// Should we fire the director event to play the "Press the button!" Nag VO?
// If we are on an infinite delay stage...
if ( CurrentFinaleStageType == DELAY && CurrentFinaleStageNumber > 1 && CurrentFinaleStageNumber < 7 )
{
// 1. We have not nagged for this stage yet
// 2. There are button presses remaining
if ( CurrentFinaleStageNumber != LastVOButtonStageNumber && ButtonPressCount < 3 )
{
// We are not about to process a wait advance..
if ( QueuedDelayAdvances == 0 && !PendingWaitAdvance )
{
// If things are pretty calm, run the event
if ( Director.GetPendingMobCount() < 1 && Director.GetCommonInfectedCount() < 1 )
{
if ( !Director.IsTankInPlay() && !Director.IsAnySurvivorInCombat() )
{
printl( "*!* Update firing event 1 (VO Prompt)" )
LastVOButtonStageNumber = CurrentFinaleStageNumber
Director.UserDefinedEvent1()
}
}
}
}
}
}
function EnableEscapeTanks()
// This is called in-game via logic_relay at info_director
// enable the escape tanks at a different time.
// Input: Runscriptcode
// Parm: DirectorScript.MapScript.LocalScript.EnableEscapeTanks()
{
printl( "*!* EnableEscapeTanks finale stage " + CurrentFinaleStageNumber + " of type " +CurrentFinaleStageType );
//Msg( "\n*****\nMapScript.DirectorOptions:\n" );
//foreach( key, value in MapScript.DirectorOptions )
//{
// Msg( " " + key + " = " + value + "\n" );
//}
MapScript.DirectorOptions.EscapeSpawnTanks <- true
}
|
解密的官方结局脚本
这是所有的结局脚本,于 2021 年 8 月 2 日解密。
这些尚未修改以提供任何附加信息,某些部分可能会造成混淆。
c1m4_atrium_finale.nuc
Msg("----------------------FINALE SCRIPT------------------\n")
//-----------------------------------------------------
PANIC <- 0
TANK <- 1
DELAY <- 2
ONSLAUGHT <- 3
//-----------------------------------------------------
SharedOptions <-
{
A_CustomFinale1 = ONSLAUGHT
A_CustomFinaleValue1 = ""
A_CustomFinale2 = PANIC
A_CustomFinaleValue2 = 1
A_CustomFinale3 = ONSLAUGHT
A_CustomFinaleValue3 = "c1m4_delay"
A_CustomFinale4 = PANIC
A_CustomFinaleValue4 = 1
A_CustomFinale5 = ONSLAUGHT
A_CustomFinaleValue5 = "c1m4_delay"
A_CustomFinale6 = TANK
A_CustomFinaleValue6 = 1
A_CustomFinale7 = ONSLAUGHT
A_CustomFinaleValue7 = "c1m4_delay"
A_CustomFinale8 = PANIC
A_CustomFinaleValue8 = 1
A_CustomFinale9 = ONSLAUGHT
A_CustomFinaleValue9 = "c1m4_delay"
A_CustomFinale10 = PANIC
A_CustomFinaleValue10 = 1
A_CustomFinale11 = ONSLAUGHT
A_CustomFinaleValue11 = "c1m4_delay"
A_CustomFinale12 = PANIC
A_CustomFinaleValue12 = 1
A_CustomFinale13 = ONSLAUGHT
A_CustomFinaleValue13 = "c1m4_delay"
A_CustomFinale14 = TANK
A_CustomFinaleValue14 = 1
A_CustomFinale15 = ONSLAUGHT
A_CustomFinaleValue15 = "c1m4_delay"
A_CustomFinale16 = PANIC
A_CustomFinaleValue16 = 1
A_CustomFinale17 = ONSLAUGHT
A_CustomFinaleValue17 = "c1m4_delay"
A_CustomFinale18 = PANIC
A_CustomFinaleValue18 = 1
A_CustomFinale19 = ONSLAUGHT
A_CustomFinaleValue19 = "c1m4_delay"
A_CustomFinale20 = PANIC
A_CustomFinaleValue20 = 1
A_CustomFinale21 = ONSLAUGHT
A_CustomFinaleValue21 = "c1m4_delay"
A_CustomFinale22 = TANK
A_CustomFinaleValue22 = 1
A_CustomFinale23 = ONSLAUGHT
A_CustomFinaleValue23 = "c1m4_delay"
A_CustomFinale24 = PANIC
A_CustomFinaleValue24 = 1
A_CustomFinale25 = ONSLAUGHT
A_CustomFinaleValue25 = "c1m4_delay"
A_CustomFinale26 = PANIC
A_CustomFinaleValue26 = 1
A_CustomFinale27 = ONSLAUGHT
A_CustomFinaleValue27 = "c1m4_delay"
A_CustomFinale28 = PANIC
A_CustomFinaleValue28 = 1
A_CustomFinale29 = ONSLAUGHT
A_CustomFinaleValue29 = "c1m4_delay"
A_CustomFinale30 = PANIC
A_CustomFinaleValue30 = 1
A_CustomFinale31 = ONSLAUGHT
A_CustomFinaleValue31 = "c1m4_delay"
//-----------------------------------------------------
PreferredMobDirection = SPAWN_LARGE_VOLUME
PreferredSpecialDirection = SPAWN_LARGE_VOLUME
// BoomerLimit = 0
// SmokerLimit = 2
// HunterLimit = 1
// SpitterLimit = 1
// JockeyLimit = 0
// ChargerLimit = 1
ProhibitBosses = true
ZombieSpawnRange = 3000
MobRechargeRate = 0.5
HordeEscapeCommonLimit = 15
BileMobSize = 15
MusicDynamicMobSpawnSize = 8
MusicDynamicMobStopSize = 2
MusicDynamicMobScanStopSize = 1
}
InitialOnslaughtOptions <-
{
LockTempo = 0
IntensityRelaxThreshold = 1.1
RelaxMinInterval = 2
RelaxMaxInterval = 4
SustainPeakMinTime = 25
SustainPeakMaxTime = 30
MobSpawnMinTime = 4
MobSpawnMaxTime = 8
MobMinSize = 2
MobMaxSize = 6
CommonLimit = 5
SpecialRespawnInterval = 100
}
PanicOptions <-
{
MegaMobSize = 0 // randomized in OnBeginCustomFinaleStage
MegaMobMinSize = 20
MegaMobMaxSize = 40
CommonLimit = 15
SpecialRespawnInterval = 40
}
TankOptions <-
{
ShouldAllowMobsWithTank = true
ShouldAllowSpecialsWithTank = true
MobSpawnMinTime = 10
MobSpawnMaxTime = 20
MobMinSize = 3
MobMaxSize = 5
CommonLimit = 7
SpecialRespawnInterval = 60
}
DirectorOptions <- clone SharedOptions
{
}
//-----------------------------------------------------
// number of cans needed to escape.
NumCansNeeded <- 13
// fewer cans in single player since bots don't help much
if ( Director.IsSinglePlayerGame() )
{
NumCansNeeded <- 8
}
// duration of delay stage.
DelayMin <- 10
DelayMax <- 20
// Number of touches and/or pours allowed before a delay is aborted.
DelayPourThreshold <- 1
DelayTouchedOrPouredThreshold <- 2
// Once the delay is aborted, amount of time before it progresses to next stage.
AbortDelayMin <- 1
AbortDelayMax <- 3
// Number of touches and pours it takes to transition out of c1m4_finale_wave_1
GimmeThreshold <- 4
// console overrides
if ( Director.IsPlayingOnConsole() )
{
DelayMin <- 20
DelayMax <- 30
// Number of touches and/or pours allowed before a delay is aborted.
DelayPourThreshold <- 2
DelayTouchedOrPouredThreshold <- 4
TankOptions.ShouldAllowSpecialsWithTank = false
}
//-----------------------------------------------------
// INIT
//-----------------------------------------------------
GasCansTouched <- 0
GasCansPoured <- 0
DelayTouchedOrPoured <- 0
DelayPoured <- 0
EntFire( "timer_delay_end", "LowerRandomBound", DelayMin )
EntFire( "timer_delay_end", "UpperRandomBound", DelayMax )
EntFire( "timer_delay_abort", "LowerRandomBound", AbortDelayMin )
EntFire( "timer_delay_abort", "UpperRandomBound", AbortDelayMax )
// this is too late. Moved to c1m4_atrium.nut
//EntFire( "progress_display", "SetTotalItems", NumCansNeeded )
function AbortDelay(){} // only defined during a delay, in c1m4_delay.nut
function EndDelay(){} // only defined during a delay, in c1m4_delay.nut
NavMesh.UnblockRescueVehicleNav()
//-----------------------------------------------------
function GasCanTouched()
{
GasCansTouched++
Msg(" Touched: " + GasCansTouched + "\n")
EvalGasCansPouredOrTouched()
}
function GasCanPoured()
{
GasCansPoured++
DelayPoured++
Msg(" Poured: " + GasCansPoured + "\n")
if ( GasCansPoured == NumCansNeeded )
{
Msg(" needed: " + NumCansNeeded + "\n")
EntFire( "relay_car_ready", "trigger" )
}
EvalGasCansPouredOrTouched()
}
function EvalGasCansPouredOrTouched()
{
TouchedOrPoured <- GasCansPoured + GasCansTouched
Msg(" Poured or touched: " + TouchedOrPoured + "\n")
DelayTouchedOrPoured++
Msg(" DelayTouchedOrPoured: " + DelayTouchedOrPoured + "\n")
Msg(" DelayPoured: " + DelayPoured + "\n")
if (( DelayTouchedOrPoured >= DelayTouchedOrPouredThreshold ) || ( DelayPoured >= DelayPourThreshold ))
{
AbortDelay()
}
switch( TouchedOrPoured )
{
case GimmeThreshold:
EntFire( "@director", "EndCustomScriptedStage" )
break
}
}
//-----------------------------------------------------
function AddTableToTable( dest, src )
{
foreach( key, val in src )
{
dest[key] <- val
}
}
function OnBeginCustomFinaleStage( num, type )
{
printl( "Beginning custom finale stage " + num + " of type " + type );
local waveOptions = null
if ( num == 1 )
{
waveOptions = InitialOnslaughtOptions
}
else if ( type == PANIC )
{
waveOptions = PanicOptions
waveOptions.MegaMobSize = PanicOptions.MegaMobMinSize + rand()%( PanicOptions.MegaMobMaxSize - PanicOptions.MegaMobMinSize )
Msg("*************************" + waveOptions.MegaMobSize + "\n")
}
else if ( type == TANK )
{
waveOptions = TankOptions
}
//---------------------------------
MapScript.DirectorOptions.clear()
AddTableToTable( MapScript.DirectorOptions, SharedOptions );
if ( waveOptions != null )
{
AddTableToTable( MapScript.DirectorOptions, waveOptions );
}
Director.ResetMobTimer()
if ( developer() > 0 )
{
Msg( "\n*****\nMapScript.DirectorOptions:\n" );
foreach( key, value in MapScript.DirectorOptions )
{
Msg( " " + key + " = " + value + "\n" );
}
if ( LocalScript.rawin( "DirectorOptions" ) )
{
Msg( "\n*****\nLocalScript.DirectorOptions:\n" );
foreach( key, value in LocalScript.DirectorOptions )
{
Msg( " " + key + " = " + value + "\n" );
}
}
}
}
//-----------------------------------------------------
if ( Director.GetGameModeBase() == "versus" )
{
SharedOptions.ProhibitBosses = false
}
|
c1m4_finale_wave_1.nuc
Msg("Atrium Finale Wave " + ( CurrentWave + 1 ) + "\n");
|
c1m4_delay.nuc
Msg("**Delay started**\n")
DirectorOptions <-
{
MobMinSize = 2
MobMaxSize = 3
BoomerLimit = 0
SmokerLimit = 0
HunterLimit = 0
SpitterLimit = 0
JockeyLimit = 0
ChargerLimit = 0
MinimumStageTime = 15
CommonLimit = 5
}
Director.ResetMobTimer()
// start the delay timer
EntFire( "timer_delay_end", "enable" )
//reset
DelayTouchedOrPoured <- 0
DelayPoured <- 0
//-------------------------------------------------
// abort the delay if a survivor picks up or pours a gas can
function AbortDelay()
{
Msg("**Delay aborted early**\n")
EntFire( "timer_delay_abort", "enable" )
}
function EndDelay()
{
Msg("**Delay ended**\n")
EntFire( "timer_delay_end", "Disable" )
EntFire( "timer_delay_end", "ResetTimer" )
EntFire( "timer_delay_abort", "Disable" )
EntFire( "timer_delay_abort", "ResetTimer" )
EntFire( "@director", "EndCustomScriptedStage" )
}
|
c2m5_concert_finale.nuc
//-----------------------------------------------------------------------------
PANIC <- 0
TANK <- 1
DELAY <- 2
ONSLAUGHT <- 3
//-----------------------------------------------------------------------------
SharedOptions <-
{
A_CustomFinale_StageCount = 9
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 1
A_CustomFinale2 = PANIC
A_CustomFinaleValue2 = 1
A_CustomFinale3 = DELAY
A_CustomFinaleValue3 = 15
A_CustomFinale4 = TANK
A_CustomFinaleValue4 = 1
A_CustomFinaleMusic4 = ""
A_CustomFinale5 = DELAY
A_CustomFinaleValue5 = 15
A_CustomFinale6 = PANIC
A_CustomFinaleValue6 = 2
A_CustomFinale7 = DELAY
A_CustomFinaleValue7 = 10
A_CustomFinale8 = TANK
A_CustomFinaleValue8 = 1
A_CustomFinaleMusic8 = ""
A_CustomFinale9 = DELAY
A_CustomFinaleValue9 = RandomInt( 5, 10 )
PreferredMobDirection = SPAWN_LARGE_VOLUME
PreferredSpecialDirection = SPAWN_LARGE_VOLUME
ShouldConstrainLargeVolumeSpawn = false
ZombieSpawnRange = 3000
SpecialRespawnInterval = 20
}
InitialPanicOptions <-
{
ShouldConstrainLargeVolumeSpawn = true
}
PanicOptions <-
{
CommonLimit = 25
}
TankOptions <-
{
ShouldAllowSpecialsWithTank = true
SpecialRespawnInterval = 30
}
DirectorOptions <- clone SharedOptions
{
}
//-----------------------------------------------------------------------------
function AddTableToTable( dest, src )
{
foreach( key, val in src )
{
dest[key] <- val
}
}
//-----------------------------------------------------------------------------
function OnBeginCustomFinaleStage( num, type )
{
if ( developer() > 0 )
{
printl("========================================================");
printl( "Beginning custom finale stage " + num + " of type " + type );
}
local waveOptions = null
if ( num == 1 )
{
waveOptions = InitialPanicOptions
}
else if ( type == PANIC )
{
waveOptions = PanicOptions
if ( "MegaMobMinSize" in PanicOptions )
{
waveOptions.MegaMobSize <- RandomInt( PanicOptions.MegaMobMinSize, MegaMobMaxSize )
}
}
else if ( type == TANK )
{
waveOptions = TankOptions
}
//---------------------------------
MapScript.DirectorOptions.clear()
AddTableToTable( MapScript.DirectorOptions, SharedOptions );
if ( waveOptions != null )
{
AddTableToTable( MapScript.DirectorOptions, waveOptions );
}
//---------------------------------
if ( developer() > 0 )
{
Msg( "\n*****\nMapScript.DirectorOptions:\n" );
foreach( key, value in MapScript.DirectorOptions )
{
Msg( " " + key + " = " + value + "\n" );
}
if ( LocalScript.rawin( "DirectorOptions" ) )
{
Msg( "\n*****\nLocalScript.DirectorOptions:\n" );
foreach( key, value in LocalScript.DirectorOptions )
{
Msg( " " + key + " = " + value + "\n" );
}
}
printl("========================================================");
}
}
|
c3m4_plantation_finale.nuc
//-----------------------------------------------------
local PANIC = 0
local TANK = 1
local DELAY = 2
//-----------------------------------------------------
DirectorOptions <-
{
//-----------------------------------------------------
A_CustomFinale_StageCount = 8
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 2
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = 12
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = 12
A_CustomFinale5 = PANIC
A_CustomFinaleValue5 = 2
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = 15
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 2
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = 10
SpecialRespawnInterval = 55
//-----------------------------------------------------
}
|
c4m5_milltown_escape_finale.nuc
//-----------------------------------------------------
local PANIC = 0
local TANK = 1
local DELAY = 2
//-----------------------------------------------------
// default finale patten - for reference only
/*
CustomFinale1 <- PANIC
CustomFinaleValue1 <- 2
CustomFinale2 <- DELAY
CustomFinaleValue2 <- 10
CustomFinale3 <- TANK
CustomFinaleValue3 <- 1
CustomFinale4 <- DELAY
CustomFinaleValue4 <- 10
CustomFinale5 <- PANIC
CustomFinaleValue5 <- 2
CustomFinale6 <- DELAY
CustomFinaleValue6 <- 10
CustomFinale7 <- TANK
CustomFinaleValue7 <- 1
CustomFinale8 <- DELAY
CustomFinaleValue8 <- 2
*/
DirectorOptions <-
{
//-----------------------------------------------------
// 3 waves of mobs in between tanks
A_CustomFinale_StageCount = 8
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 1
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = 10
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = 10
A_CustomFinale5 = PANIC
A_CustomFinaleValue5 = 1
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = 10
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 1
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = 15
HordeEscapeCommonLimit = 15
CommonLimit = 20
SpecialRespawnInterval = 80
}
if ( "DirectorOptions" in LocalScript && "ProhibitBosses" in LocalScript.DirectorOptions )
{
delete LocalScript.DirectorOptions.ProhibitBosses
}
/*
*/
|
c6m3_port_finale.nuc
Msg("----------------------FINALE SCRIPT------------------\n")
//-----------------------------------------------------
PANIC <- 0
TANK <- 1
DELAY <- 2
ONSLAUGHT <- 3
//-----------------------------------------------------
SharedOptions <-
{
A_CustomFinale1 = ONSLAUGHT
A_CustomFinaleValue1 = ""
A_CustomFinale2 = PANIC
A_CustomFinaleValue2 = 1
A_CustomFinale3 = ONSLAUGHT
A_CustomFinaleValue3 = "c1m4_delay"
A_CustomFinale4 = PANIC
A_CustomFinaleValue4 = 1
A_CustomFinale5 = ONSLAUGHT
A_CustomFinaleValue5 = "c1m4_delay"
A_CustomFinale6 = TANK
A_CustomFinaleValue6 = 1
A_CustomFinale7 = ONSLAUGHT
A_CustomFinaleValue7 = "c1m4_delay"
A_CustomFinale8 = PANIC
A_CustomFinaleValue8 = 1
A_CustomFinale9 = ONSLAUGHT
A_CustomFinaleValue9 = "c1m4_delay"
A_CustomFinale10 = PANIC
A_CustomFinaleValue10 = 1
A_CustomFinale11 = ONSLAUGHT
A_CustomFinaleValue11 = "c1m4_delay"
A_CustomFinale12 = PANIC
A_CustomFinaleValue12 = 1
A_CustomFinale13 = ONSLAUGHT
A_CustomFinaleValue13 = "c1m4_delay"
A_CustomFinale14 = TANK
A_CustomFinaleValue14 = 2
A_CustomFinale15 = ONSLAUGHT
A_CustomFinaleValue15 = "c1m4_delay"
A_CustomFinale16 = PANIC
A_CustomFinaleValue16 = 1
A_CustomFinale17 = ONSLAUGHT
A_CustomFinaleValue17 = "c1m4_delay"
A_CustomFinale18 = PANIC
A_CustomFinaleValue18 = 1
A_CustomFinale19 = ONSLAUGHT
A_CustomFinaleValue19 = "c1m4_delay"
A_CustomFinale20 = PANIC
A_CustomFinaleValue20 = 1
A_CustomFinale21 = ONSLAUGHT
A_CustomFinaleValue21 = "c1m4_delay"
A_CustomFinale22 = TANK
A_CustomFinaleValue22 = 1
A_CustomFinale23 = ONSLAUGHT
A_CustomFinaleValue23 = "c1m4_delay"
A_CustomFinale24 = PANIC
A_CustomFinaleValue24 = 1
A_CustomFinale25 = ONSLAUGHT
A_CustomFinaleValue25 = "c1m4_delay"
A_CustomFinale26 = PANIC
A_CustomFinaleValue26 = 1
A_CustomFinale27 = ONSLAUGHT
A_CustomFinaleValue27 = "c1m4_delay"
A_CustomFinale28 = PANIC
A_CustomFinaleValue28 = 1
A_CustomFinale29 = ONSLAUGHT
A_CustomFinaleValue29 = "c1m4_delay"
A_CustomFinale30 = PANIC
A_CustomFinaleValue30 = 1
A_CustomFinale31 = ONSLAUGHT
A_CustomFinaleValue31 = "c1m4_delay"
A_CustomFinale32 = TANK
A_CustomFinaleValue32 = 2
A_CustomFinale33 = ONSLAUGHT
A_CustomFinaleValue33 = "c1m4_delay"
A_CustomFinale34 = PANIC
A_CustomFinaleValue34 = 1
A_CustomFinale35 = ONSLAUGHT
A_CustomFinaleValue35 = "c1m4_delay"
A_CustomFinale36 = PANIC
A_CustomFinaleValue36 = 1
A_CustomFinale37 = ONSLAUGHT
A_CustomFinaleValue37 = "c1m4_delay"
A_CustomFinale38 = PANIC
A_CustomFinaleValue38 = 1
A_CustomFinale39 = ONSLAUGHT
A_CustomFinaleValue39 = "c1m4_delay"
A_CustomFinale40 = PANIC
A_CustomFinaleValue40 = 1
A_CustomFinale41 = ONSLAUGHT
A_CustomFinaleValue41 = "c1m4_delay"
A_CustomFinale42 = TANK
A_CustomFinaleValue42 = 1
A_CustomFinale43 = ONSLAUGHT
A_CustomFinaleValue43 = "c1m4_delay"
A_CustomFinale44 = PANIC
A_CustomFinaleValue44 = 1
A_CustomFinale45 = ONSLAUGHT
A_CustomFinaleValue45 = "c1m4_delay"
A_CustomFinale46 = PANIC
A_CustomFinaleValue46 = 1
A_CustomFinale47 = ONSLAUGHT
A_CustomFinaleValue47 = "c1m4_delay"
A_CustomFinale48 = PANIC
A_CustomFinaleValue48 = 1
A_CustomFinale49 = ONSLAUGHT
A_CustomFinaleValue49 = "c1m4_delay"
A_CustomFinale50 = PANIC
A_CustomFinaleValue50 = 1
A_CustomFinale51 = ONSLAUGHT
A_CustomFinaleValue51 = "c1m4_delay"
//-----------------------------------------------------
PreferredMobDirection = SPAWN_LARGE_VOLUME
PreferredSpecialDirection = SPAWN_LARGE_VOLUME
// BoomerLimit = 0
// SmokerLimit = 2
// HunterLimit = 1
// SpitterLimit = 1
// JockeyLimit = 0
// ChargerLimit = 1
ProhibitBosses = true
ZombieSpawnRange = 3000
MobRechargeRate = 0.5
HordeEscapeCommonLimit = 15
BileMobSize = 15
SpecialRespawnInterval = 20
MusicDynamicMobSpawnSize = 8
MusicDynamicMobStopSize = 2
MusicDynamicMobScanStopSize = 1
}
InitialOnslaughtOptions <-
{
LockTempo = 0
IntensityRelaxThreshold = 1.1
RelaxMinInterval = 2
RelaxMaxInterval = 4
SustainPeakMinTime = 25
SustainPeakMaxTime = 30
MobSpawnMinTime = 4
MobSpawnMaxTime = 8
MobMinSize = 2
MobMaxSize = 6
CommonLimit = 5
SpecialRespawnInterval = 100
}
PanicOptions <-
{
MegaMobSize = 0 // randomized in OnBeginCustomFinaleStage
MegaMobMinSize = 20
MegaMobMaxSize = 40
MaxSpecials = 5
BoomerLimit = 1
SmokerLimit = 2
HunterLimit = 2
SpitterLimit = 1
JockeyLimit = 1
ChargerLimit = 1
CommonLimit = 25
SpecialRespawnInterval = 25
}
TankOptions <-
{
ShouldAllowMobsWithTank = true
ShouldAllowSpecialsWithTank = true
MobSpawnMinTime = 20
MobSpawnMaxTime = 40
MobMinSize = 3
MobMaxSize = 5
MaxSpecials = 3
CommonLimit = 5
SpecialRespawnInterval = 50
}
DirectorOptions <- clone SharedOptions
{
}
//-----------------------------------------------------
// number of cans needed to escape.
NumCansNeeded <- 16
// fewer cans in single player since bots don't help much
if ( Director.IsSinglePlayerGame() )
{
NumCansNeeded <- 10
}
// duration of delay stage.
DelayMin <- 10
DelayMax <- 20
// Number of touches and/or pours allowed before a delay is aborted.
DelayPourThreshold <- 1
DelayTouchedOrPouredThreshold <- 2
// Once the delay is aborted, amount of time before it progresses to next stage.
AbortDelayMin <- 1
AbortDelayMax <- 3
// Number of touches and pours it takes to transition out of c1m4_finale_wave_1
GimmeThreshold <- 4
// console overrides
if ( Director.IsPlayingOnConsole() )
{
DelayMin <- 20
DelayMax <- 30
// Number of touches and/or pours allowed before a delay is aborted.
DelayPourThreshold <- 2
DelayTouchedOrPouredThreshold <- 4
TankOptions.ShouldAllowSpecialsWithTank = false
}
//-----------------------------------------------------
// INIT
//-----------------------------------------------------
GasCansTouched <- 0
GasCansPoured <- 0
DelayTouchedOrPoured <- 0
DelayPoured <- 0
EntFire( "timer_delay_end", "LowerRandomBound", DelayMin )
EntFire( "timer_delay_end", "UpperRandomBound", DelayMax )
EntFire( "timer_delay_abort", "LowerRandomBound", AbortDelayMin )
EntFire( "timer_delay_abort", "UpperRandomBound", AbortDelayMax )
// this is too late. Moved to c1m4_atrium.nut
//EntFire( "progress_display", "SetTotalItems", NumCansNeeded )
function AbortDelay(){} // only defined during a delay, in c1m4_delay.nut
function EndDelay(){} // only defined during a delay, in c1m4_delay.nut
NavMesh.UnblockRescueVehicleNav()
//-----------------------------------------------------
function GasCanTouched()
{
GasCansTouched++
Msg(" Touched: " + GasCansTouched + "\n")
EvalGasCansPouredOrTouched()
}
function GasCanPoured()
{
GasCansPoured++
DelayPoured++
Msg(" Poured: " + GasCansPoured + "\n")
if ( GasCansPoured == NumCansNeeded )
{
Msg(" needed: " + NumCansNeeded + "\n")
EntFire( "relay_car_ready", "trigger" )
}
EvalGasCansPouredOrTouched()
}
function EvalGasCansPouredOrTouched()
{
TouchedOrPoured <- GasCansPoured + GasCansTouched
Msg(" Poured or touched: " + TouchedOrPoured + "\n")
DelayTouchedOrPoured++
Msg(" DelayTouchedOrPoured: " + DelayTouchedOrPoured + "\n")
Msg(" DelayPoured: " + DelayPoured + "\n")
if (( DelayTouchedOrPoured >= DelayTouchedOrPouredThreshold ) || ( DelayPoured >= DelayPourThreshold ))
{
AbortDelay()
}
switch( TouchedOrPoured )
{
case GimmeThreshold:
EntFire( "@director", "EndCustomScriptedStage" )
break
}
}
//-----------------------------------------------------
function AddTableToTable( dest, src )
{
foreach( key, val in src )
{
dest[key] <- val
}
}
function OnBeginCustomFinaleStage( num, type )
{
printl( "Beginning custom finale stage " + num + " of type " + type );
local waveOptions = null
if ( num == 1 )
{
waveOptions = InitialOnslaughtOptions
}
else if ( type == PANIC )
{
waveOptions = PanicOptions
waveOptions.MegaMobSize = PanicOptions.MegaMobMinSize + rand()%( PanicOptions.MegaMobMaxSize - PanicOptions.MegaMobMinSize )
Msg("*************************" + waveOptions.MegaMobSize + "\n")
}
else if ( type == TANK )
{
waveOptions = TankOptions
EntFire( "bonus_relay", "Trigger", 0 )
}
// give out items at certain stages
if ( num == 3 || num == 7 || num == 15 || num == 23 )
{
Director.L4D1SurvivorGiveItem()
}
//---------------------------------
MapScript.DirectorOptions.clear()
AddTableToTable( MapScript.DirectorOptions, SharedOptions );
if ( waveOptions != null )
{
AddTableToTable( MapScript.DirectorOptions, waveOptions );
}
Director.ResetMobTimer()
if ( developer() > 0 )
{
Msg( "\n*****\nMapScript.DirectorOptions:\n" );
foreach( key, value in MapScript.DirectorOptions )
{
Msg( " " + key + " = " + value + "\n" );
}
if ( LocalScript.rawin( "DirectorOptions" ) )
{
Msg( "\n*****\nLocalScript.DirectorOptions:\n" );
foreach( key, value in LocalScript.DirectorOptions )
{
Msg( " " + key + " = " + value + "\n" );
}
}
}
}
//-----------------------------------------------------
if ( Director.GetGameModeBase() == "versus" )
{
SharedOptions.ProhibitBosses = false
}
|
c7m3_port_finale.nuc
//-----------------------------------------------------
// This script handles the logic for the Port / Bridge
// finale in the River Campaign.
//
//-----------------------------------------------------
Msg("Initiating c7m3_port_finale script\n");
//-----------------------------------------------------
ERROR <- -1
PANIC <- 0
TANK <- 1
DELAY <- 2
//-----------------------------------------------------
// This keeps track of the number of times the generator button has been pressed.
// Init to 1, since one button press has been used to start the finale and run
// this script.
ButtonPressCount <- 1
// This stores the stage number that we last
// played the "Press the Button!" VO
LastVOButtonStageNumber <- 0
// We use this to keep from running a bunch of queued advances really quickly.
// Init to true because we are starting a finale from a button press in the pre-finale script
// see GeneratorButtonPressed in c7m3_port.nut
PendingWaitAdvance <- true
// We use three generator button presses to push through
// 8 stages. We have to queue up state advances
// depending on the state of the finale when buttons are pressed
QueuedDelayAdvances <- 0
// Tracking current finale states
CurrentFinaleStageNumber <- ERROR
CurrentFinaleStageType <- ERROR
// The finale is 3 phases.
// We randomize the event types in the first two
local RandomFinaleStage1 = 0
local RandomFinaleStage2 = 0
local RandomFinaleStage4 = 0
local RandomFinaleStage5 = 0
// PHASE 1 EVENTS
if ( RandomInt( 1, 100 ) < 50 )
{
RandomFinaleStage1 = PANIC
RandomFinaleStage2 = TANK
}
else
{
RandomFinaleStage1 = TANK
RandomFinaleStage2 = PANIC
}
// PHASE 2 EVENTS
if ( RandomInt( 1, 100 ) < 50 )
{
RandomFinaleStage4 = PANIC
RandomFinaleStage5 = TANK
}
else
{
RandomFinaleStage4 = TANK
RandomFinaleStage5 = PANIC
}
// We want to give the survivors a little of extra time to
// get on their feet before the escape, since you have to fight through
// the sacrifice.
PreEscapeDelay <- 0
if ( Director.GetGameModeBase() == "coop" || Director.GetGameModeBase() == "realism" )
{
PreEscapeDelay <- 5
}
else if ( Director.GetGameModeBase() == "versus" )
{
PreEscapeDelay <- 15
}
DirectorOptions <-
{
A_CustomFinale_StageCount = 8
// PHASE 1
A_CustomFinale1 = RandomFinaleStage1
A_CustomFinaleValue1 = 1
A_CustomFinale2 = RandomFinaleStage2
A_CustomFinaleValue2 = 1
A_CustomFinale3 = DELAY
A_CustomFinaleValue3 = 9999
// PHASE 2
A_CustomFinale4 = RandomFinaleStage4
A_CustomFinaleValue4 = 1
A_CustomFinale5 = RandomFinaleStage5
A_CustomFinaleValue5 = 1
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = 9999
// PHASE 3
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 1
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = PreEscapeDelay
TankLimit = 4
WitchLimit = 0
CommonLimit = 20
HordeEscapeCommonLimit = 15
EscapeSpawnTanks = false
//SpecialRespawnInterval = 80
}
function OnBeginCustomFinaleStage( num, type )
{
printl( "*!* Beginning custom finale stage " + num + " of type " + type );
printl( "*!* PendingWaitAdvance " + PendingWaitAdvance + ", QueuedDelayAdvances " + QueuedDelayAdvances );
// Store off the state...
CurrentFinaleStageNumber = num
CurrentFinaleStageType = type
// Acknowledge the state advance
PendingWaitAdvance = false
}
function GeneratorButtonPressed()
{
printl( "*!* GeneratorButtonPressed finale stage " + CurrentFinaleStageNumber + " of type " +CurrentFinaleStageType );
printl( "*!* PendingWaitAdvance " + PendingWaitAdvance + ", QueuedDelayAdvances " + QueuedDelayAdvances );
ButtonPressCount++
local ImmediateAdvances = 0
if ( CurrentFinaleStageNumber == 1 || CurrentFinaleStageNumber == 4 )
{
// First stage of a phase, so next stage is an "action" stage too.
// Advance to next action stage, and then queue an advance to the
// next delay.
QueuedDelayAdvances++
ImmediateAdvances = 1
}
else if ( CurrentFinaleStageNumber == 2 || CurrentFinaleStageNumber == 5 )
{
// Second stage of a phase, so next stage is a "delay" stage.
// We need to immediately advance past the delay and into an action state.
//QueuedDelayAdvances++ // NOPE!
ImmediateAdvances = 2
}
else if ( CurrentFinaleStageNumber == 3 || CurrentFinaleStageNumber == 6 )
{
// Wait states... (very long delay)
// Advance immediately into an action state
//QueuedDelayAdvances++
ImmediateAdvances = 1
}
else if ( CurrentFinaleStageNumber == -1 ||
CurrentFinaleStageNumber == 0 )
{
// the finale is *just* about to start...
// we can get this if all the buttons are hit at once at the beginning
// Just queue a wait advance
QueuedDelayAdvances++
ImmediateAdvances = 0
}
else
{
printl( "*!* Unhandled generator button press! " );
}
if ( ImmediateAdvances > 0 )
{
EntFire( "generator_start_model", "Enable" )
if ( ImmediateAdvances == 1 )
{
printl( "*!* GeneratorButtonPressed Advancing State ONCE");
EntFire( "generator_start_model", "AdvanceFinaleState" )
}
else if ( ImmediateAdvances == 2 )
{
printl( "*!* GeneratorButtonPressed Advancing State TWICE");
EntFire( "generator_start_model", "AdvanceFinaleState" )
EntFire( "generator_start_model", "AdvanceFinaleState" )
}
EntFire( "generator_start_model", "Disable" )
PendingWaitAdvance = true
}
}
function Update()
{
// Should we advance the finale state?
// 1. If we're in a DELAY state
// 2. And we have queued advances....
// 3. And we haven't just tried to advance the advance the state....
if ( CurrentFinaleStageType == DELAY && QueuedDelayAdvances > 0 && !PendingWaitAdvance )
{
// If things are calm (relatively), jump to the next state
if ( !Director.IsTankInPlay() && !Director.IsAnySurvivorInCombat() )
{
if ( Director.GetPendingMobCount() < 1 && Director.GetCommonInfectedCount() < 5 )
{
printl( "*!* Update Advancing State finale stage " + CurrentFinaleStageNumber + " of type " +CurrentFinaleStageType );
printl( "*!* PendingWaitAdvance " + PendingWaitAdvance + ", QueuedDelayAdvances " + QueuedDelayAdvances );
QueuedDelayAdvances--
EntFire( "generator_start_model", "Enable" )
EntFire( "generator_start_model", "AdvanceFinaleState" )
EntFire( "generator_start_model", "Disable" )
PendingWaitAdvance = true
}
}
}
// Should we fire the director event to play the "Press the button!" Nag VO?
// If we're on an infinite delay stage...
if ( CurrentFinaleStageType == DELAY && CurrentFinaleStageNumber > 1 && CurrentFinaleStageNumber < 7 )
{
// 1. We haven't nagged for this stage yet
// 2. There are button presses remaining
if ( CurrentFinaleStageNumber != LastVOButtonStageNumber && ButtonPressCount < 3 )
{
// We're not about to process a wait advance..
if ( QueuedDelayAdvances == 0 && !PendingWaitAdvance )
{
// If things are pretty calm, run the event
if ( Director.GetPendingMobCount() < 1 && Director.GetCommonInfectedCount() < 1 )
{
if ( !Director.IsTankInPlay() && !Director.IsAnySurvivorInCombat() )
{
printl( "*!* Update firing event 1 (VO Prompt)" )
LastVOButtonStageNumber = CurrentFinaleStageNumber
Director.UserDefinedEvent1()
}
}
}
}
}
}
function EnableEscapeTanks()
{
printl( "*!* EnableEscapeTanks finale stage " + CurrentFinaleStageNumber + " of type " +CurrentFinaleStageType );
//Msg( "\n*****\nMapScript.DirectorOptions:\n" );
//foreach( key, value in MapScript.DirectorOptions )
//{
// Msg( " " + key + " = " + value + "\n" );
//}
MapScript.DirectorOptions.EscapeSpawnTanks <- true
}
|
c8m5_rooftop_finale.nuc
//-----------------------------------------------------
//
//
//-----------------------------------------------------
Msg("Initiating c8m5_rooftop_finale script\n");
//-----------------------------------------------------
ERROR <- -1
PANIC <- 0
TANK <- 1
DELAY <- 2
SCRIPTED <- 3
//-----------------------------------------------------
StageDelay <- 0
PreEscapeDelay <- 0
if ( Director.GetGameModeBase() == "coop" || Director.GetGameModeBase() == "realism" )
{
StageDelay <- 5
PreEscapeDelay <- 5
}
else if ( Director.GetGameModeBase() == "versus" )
{
StageDelay <- 10
PreEscapeDelay <- 15
}
DirectorOptions <-
{
A_CustomFinale_StageCount = 8
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 2
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = StageDelay
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = StageDelay
A_CustomFinale5 = PANIC
A_CustomFinaleValue5 = 2
A_CustomFinaleMusic5 = "Event.FinaleWave4"
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = StageDelay
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 1
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = PreEscapeDelay
TankLimit = 1
WitchLimit = 0
CommonLimit = 20
HordeEscapeCommonLimit = 15
EscapeSpawnTanks = false
//SpecialRespawnInterval = 80
MusicDynamicMobSpawnSize = 8
MusicDynamicMobStopSize = 2
MusicDynamicMobScanStopSize = 1
}
function EnableEscapeTanks()
{
printl( "Chase Tanks Enabled!" );
MapScript.DirectorOptions.EscapeSpawnTanks <- true
}
function OnBeginCustomFinaleStage( num, type )
{
//printl( "Beginning custom finale stage " + num + " of type " + type );
if ( type == 2 )
EntFire( "pilot", "SpeakResponseConcept", "hospital_radio_intransit" );
}
|
c9m2_lots_finale.nuc
//-----------------------------------------------------
//
//
//-----------------------------------------------------
Msg("Initiating c9m2_lots_finale script\n");
//-----------------------------------------------------
ERROR <- -1
PANIC <- 0
TANK <- 1
DELAY <- 2
SCRIPTED <- 3
//-----------------------------------------------------
StageDelay <- 0
PreEscapeDelay <- 0
if ( Director.GetGameModeBase() == "coop" || Director.GetGameModeBase() == "realism" )
{
StageDelay <- 5
PreEscapeDelay <- 5
}
else if ( Director.GetGameModeBase() == "versus" )
{
StageDelay <- 10
PreEscapeDelay <- 15
}
DirectorOptions <-
{
A_CustomFinale_StageCount = 8
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 2
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = StageDelay
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = StageDelay
A_CustomFinale5 = PANIC
A_CustomFinaleValue5 = 2
A_CustomFinaleMusic5 = "Event.FinaleWave4"
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = StageDelay
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 1
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = PreEscapeDelay
TankLimit = 1
WitchLimit = 0
CommonLimit = 20
HordeEscapeCommonLimit = 15
EscapeSpawnTanks = false
//SpecialRespawnInterval = 80
MusicDynamicMobSpawnSize = 8
MusicDynamicMobStopSize = 2
MusicDynamicMobScanStopSize = 1
}
function EnableEscapeTanks()
{
printl( "Chase Tanks Enabled!" );
MapScript.DirectorOptions.EscapeSpawnTanks <- true
}
|
c10m5_houseboat_finale.nuc
//-----------------------------------------------------
//
//
//-----------------------------------------------------
Msg("Initiating c10m5_houseboat_finale script\n");
//-----------------------------------------------------
ERROR <- -1
PANIC <- 0
TANK <- 1
DELAY <- 2
SCRIPTED <- 3
//-----------------------------------------------------
StageDelay <- 0
PreEscapeDelay <- 0
if ( Director.GetGameModeBase() == "coop" || Director.GetGameModeBase() == "realism" )
{
StageDelay <- 5
PreEscapeDelay <- 5
}
else if ( Director.GetGameModeBase() == "versus" )
{
StageDelay <- 10
PreEscapeDelay <- 15
}
DirectorOptions <-
{
A_CustomFinale_StageCount = 8
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 2
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = StageDelay
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = StageDelay
A_CustomFinale5 = PANIC
A_CustomFinaleValue5 = 2
A_CustomFinaleMusic5 = "Event.FinaleWave4"
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = StageDelay
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 1
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = PreEscapeDelay
TankLimit = 1
WitchLimit = 0
CommonLimit = 20
HordeEscapeCommonLimit = 15
EscapeSpawnTanks = false
//SpecialRespawnInterval = 80
MusicDynamicMobSpawnSize = 8
MusicDynamicMobStopSize = 2
MusicDynamicMobScanStopSize = 1
}
function EnableEscapeTanks()
{
printl( "Chase Tanks Enabled!" );
MapScript.DirectorOptions.EscapeSpawnTanks <- true
}
function OnBeginCustomFinaleStage( num, type )
{
//printl( "Beginning custom finale stage " + num + " of type " + type );
if ( type == 2 )
EntFire( "orator_boat_radio", "SpeakResponseConcept", "boat_radio_intransit" );
}
|
c11m5_runway_finale.nuc
//-----------------------------------------------------
//
//
//-----------------------------------------------------
Msg("Initiating c11m5_runway_finale script\n");
//-----------------------------------------------------
ERROR <- -1
PANIC <- 0
TANK <- 1
DELAY <- 2
SCRIPTED <- 3
//-----------------------------------------------------
StageDelay <- 0
PreEscapeDelay <- 0
if ( Director.GetGameModeBase() == "coop" || Director.GetGameModeBase() == "realism" )
{
StageDelay <- 5
PreEscapeDelay <- 5
}
else if ( Director.GetGameModeBase() == "versus" )
{
StageDelay <- 10
PreEscapeDelay <- 15
}
DirectorOptions <-
{
A_CustomFinale_StageCount = 8
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 2
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = StageDelay
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = StageDelay
A_CustomFinale5 = PANIC
A_CustomFinaleValue5 = 2
A_CustomFinaleMusic5 = "Event.FinaleWave4"
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = StageDelay
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 1
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = PreEscapeDelay
TankLimit = 1
WitchLimit = 0
CommonLimit = 20
HordeEscapeCommonLimit = 15
EscapeSpawnTanks = false
//SpecialRespawnInterval = 80
MusicDynamicMobSpawnSize = 8
MusicDynamicMobStopSize = 2
MusicDynamicMobScanStopSize = 1
}
function EnableEscapeTanks()
{
printl( "Chase Tanks Enabled!" );
MapScript.DirectorOptions.EscapeSpawnTanks <- true
}
function OnBeginCustomFinaleStage( num, type )
{
//printl( "Beginning custom finale stage " + num + " of type " + type );
if ( type == 2 )
EntFire( "orator_plane_radio", "SpeakResponseConcept", "plane_radio_intransit" );
}
|
c12m5_cornfield_finale.nuc
//-----------------------------------------------------
//
//
//-----------------------------------------------------
Msg("Initiating c12m5_cornfield_finale script\n");
//-----------------------------------------------------
ERROR <- -1
PANIC <- 0
TANK <- 1
DELAY <- 2
SCRIPTED <- 3
//-----------------------------------------------------
StageDelay <- 0
PreEscapeDelay <- 0
if ( Director.GetGameModeBase() == "coop" || Director.GetGameModeBase() == "realism" )
{
StageDelay <- 5
PreEscapeDelay <- 5
}
else if ( Director.GetGameModeBase() == "versus" )
{
StageDelay <- 10
PreEscapeDelay <- 15
}
DirectorOptions <-
{
A_CustomFinale_StageCount = 8
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 2
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = StageDelay
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = StageDelay
A_CustomFinale5 = PANIC
A_CustomFinaleValue5 = 2
A_CustomFinaleMusic5 = "Event.FinaleWave4"
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = StageDelay
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 1
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = PreEscapeDelay
TankLimit = 1
WitchLimit = 0
CommonLimit = 20
HordeEscapeCommonLimit = 15
EscapeSpawnTanks = false
//SpecialRespawnInterval = 80
MusicDynamicMobSpawnSize = 8
MusicDynamicMobStopSize = 2
MusicDynamicMobScanStopSize = 1
}
function EnableEscapeTanks()
{
printl( "Chase Tanks Enabled!" );
MapScript.DirectorOptions.EscapeSpawnTanks <- true
}
function OnBeginCustomFinaleStage( num, type )
{
//printl( "Beginning custom finale stage " + num + " of type " + type );
if ( type == 2 )
EntFire( "orator_farm_radio", "SpeakResponseConcept", "farm_radio_intransit" );
}
|
c14m1_lighthouse_finale.nuc
Msg("----------------------FINALE SCRIPT------------------\n")
StageDelay <- 0
PreEscapeDelay <- 0
if ( Director.GetGameModeBase() == "coop" || Director.GetGameModeBase() == "realism" )
{
StageDelay <- 5
PreEscapeDelay <- 5
}
else if ( Director.GetGameModeBase() == "versus" )
{
StageDelay <- 10
PreEscapeDelay <- 15
}
//-----------------------------------------------------
PANIC <- 0
TANK <- 1
DELAY <- 2
ONSLAUGHT <- 3
//-----------------------------------------------------
DirectorOptions <-
{
A_CustomFinale_StageCount = 14
A_CustomFinale1 = ONSLAUGHT
A_CustomFinaleValue1 = "c14m1_gauntlet"
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = StageDelay
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = StageDelay
A_CustomFinale5 = PANIC
A_CustomFinaleValue5 = 2
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = StageDelay
A_CustomFinale7 = ONSLAUGHT
A_CustomFinaleValue7 = "c14m1_gauntlet"
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = StageDelay
A_CustomFinale9 = TANK
A_CustomFinaleValue9 = 1
A_CustomFinale10 = DELAY
A_CustomFinaleValue10 = StageDelay
A_CustomFinale11 = PANIC
A_CustomFinaleValue11 = 2
A_CustomFinale12 = DELAY
A_CustomFinaleValue12 = StageDelay
A_CustomFinale13 = TANK
A_CustomFinaleValue13 = 2
A_CustomFinaleMusic13 = "Event.TankMidpoint_Metal"
A_CustomFinale14 = DELAY
A_CustomFinaleValue14 = PreEscapeDelay
//-----------------------------------------------------
ProhibitBosses = true
}
//-----------------------------------------------------
// number of cans needed to escape.
NumCansNeeded <- 8
// fewer cans in single player since bots don't help much
/*if ( Director.IsSinglePlayerGame() )
{
NumCansNeeded <- 6
}*/
//-----------------------------------------------------
// INIT
//-----------------------------------------------------
GasCansTouched <- 0
GasCansPoured <- 0
//NavMesh.UnblockRescueVehicleNav()
//-----------------------------------------------------
function GasCanTouched()
{
GasCansTouched++
Msg(" Touched: " + GasCansTouched + "\n")
EvalGasCansPouredOrTouched()
}
function GasCanPoured()
{
GasCansPoured++
Msg(" Poured: " + GasCansPoured + "\n")
if ( GasCansPoured == NumCansNeeded )
{
Msg(" needed: " + NumCansNeeded + "\n")
EntFire( "relay_generator_ready", "Trigger" )
}
EvalGasCansPouredOrTouched()
}
function EvalGasCansPouredOrTouched()
{
TouchedOrPoured <- GasCansPoured + GasCansTouched
Msg(" Poured or touched: " + TouchedOrPoured + "\n")
}
//-----------------------------------------------------
function OnBeginCustomFinaleStage( num, type )
{
printl( "Beginning custom finale stage " + num + " of type " + type );
if ( num == 7 )
{
EntFire( "relay_lighthouse_off", "Trigger" );
}
}
|
c14m2_lighthouse_finale.nuc
Msg("Initiating c14m2_lighthouse_finale script\n");
StageDelay <- 15
PreEscapeDelay <- 10
//-----------------------------------------------------
PANIC <- 0
TANK <- 1
DELAY <- 2
ONSLAUGHT <- 3
//-----------------------------------------------------
DirectorOptions <-
{
A_CustomFinale_StageCount = 8
A_CustomFinale1 = PANIC
A_CustomFinaleValue1 = 2
A_CustomFinale2 = DELAY
A_CustomFinaleValue2 = StageDelay
A_CustomFinale3 = TANK
A_CustomFinaleValue3 = 1
A_CustomFinale4 = DELAY
A_CustomFinaleValue4 = StageDelay
A_CustomFinale5 = ONSLAUGHT
A_CustomFinaleValue5 = "c14m2_gauntlet"
A_CustomFinale6 = DELAY
A_CustomFinaleValue6 = StageDelay
A_CustomFinale7 = TANK
A_CustomFinaleValue7 = 2
A_CustomFinaleMusic7 = "Event.TankMidpoint_Metal"
A_CustomFinale8 = DELAY
A_CustomFinaleValue8 = PreEscapeDelay
//-----------------------------------------------------
ProhibitBosses = true
HordeEscapeCommonLimit = 20
EscapeSpawnTanks = false
}
local difficulty = Convars.GetStr( "z_difficulty" ).tolower();
if ( Director.GetGameModeBase() == "versus" )
{
DirectorOptions.rawdelete("A_CustomFinaleMusic7");
DirectorOptions.A_CustomFinale_StageCount = 11;
DirectorOptions.A_CustomFinale6 = ONSLAUGHT;
DirectorOptions.A_CustomFinaleValue6 = "c14m2_gauntlet_vs";
DirectorOptions.A_CustomFinale7 = ONSLAUGHT;
DirectorOptions.A_CustomFinaleValue7 = "c14m2_gauntlet_vs";
DirectorOptions.A_CustomFinale8 = ONSLAUGHT;
DirectorOptions.A_CustomFinaleValue8 = "c14m2_gauntlet_vs";
DirectorOptions.A_CustomFinale9 <- DELAY;
DirectorOptions.A_CustomFinaleValue9 <- StageDelay;
DirectorOptions.A_CustomFinale10 <- TANK;
DirectorOptions.A_CustomFinaleValue10 <- 1;
DirectorOptions.A_CustomFinaleMusic10 <- "Event.TankMidpoint_Metal";
DirectorOptions.A_CustomFinale11 <- DELAY;
DirectorOptions.A_CustomFinaleValue11 <- PreEscapeDelay;
difficulty = "normal";
}
else
{
if ( difficulty == "hard" || difficulty == "impossible" )
{
DirectorOptions.rawdelete("A_CustomFinaleMusic7");
DirectorOptions.A_CustomFinale_StageCount = 12;
DirectorOptions.A_CustomFinaleValue7 = 1;
DirectorOptions.A_CustomFinaleValue8 = StageDelay;
DirectorOptions.A_CustomFinale9 <- PANIC;
DirectorOptions.A_CustomFinaleValue9 <- 2;
DirectorOptions.A_CustomFinale10 <- DELAY;
DirectorOptions.A_CustomFinaleValue10 <- StageDelay;
DirectorOptions.A_CustomFinale11 <- TANK;
DirectorOptions.A_CustomFinaleValue11 <- 2;
DirectorOptions.A_CustomFinaleMusic11 <- "Event.TankMidpoint_Metal"
DirectorOptions.A_CustomFinale12 <- DELAY;
DirectorOptions.A_CustomFinaleValue12 <- PreEscapeDelay;
}
}
//-----------------------------------------------------
function SpawnScavengeCans( difficulty )
{
local function SpawnCan( gascan )
{
local can_origin = gascan.GetOrigin();
local can_angles = gascan.GetAngles();
gascan.Kill();
local kvs =
{
angles = can_angles.ToKVString()
body = 0
disableshadows = 1
glowstate = 3
model = "models/props_junk/gascan001a.mdl"
skin = 2
weaponskin = 2
solid = 0
spawnflags = 2
targetname = "scavenge_gascans"
origin = can_origin.ToKVString()
connections =
{
OnItemPickedUp =
{
cmd1 = "director�RunScriptCode�DirectorScript.MapScript.LocalScript.GasCanTouched()�0�-1"
//Editors Note: These � characters will not copy over properly. Websites cannot display them.
//In Notepad++ replace them by selecting them, holding down ALT and entering 027 on Numblock. You'll get a black ESC character.
}
}
}
local can_spawner = SpawnEntityFromTable( "weapon_scavenge_item_spawn", kvs );
if ( can_spawner )
DoEntFire( "!self", "SpawnItem", "", 0, null, can_spawner );
}
switch( difficulty )
{
case "impossible":
{
local gascan = null;
while ( gascan = Entities.FindByName( gascan, "gascans_finale_expert" ) )
{
if ( gascan.IsValid() )
SpawnCan( gascan );
}
}
case "hard":
{
local gascan = null;
while ( gascan = Entities.FindByName( gascan, "gascans_finale_advanced" ) )
{
if ( gascan.IsValid() )
SpawnCan( gascan );
}
}
case "normal":
{
local gascan = null;
while ( gascan = Entities.FindByName( gascan, "gascans_finale_normal" ) )
{
if ( gascan.IsValid() )
SpawnCan( gascan );
}
}
case "easy":
{
local gascan = null;
while ( gascan = Entities.FindByName( gascan, "gascans_finale_easy" ) )
{
if ( gascan.IsValid() )
SpawnCan( gascan );
}
break;
}
default:
break;
}
EntFire( "gascans_finale_*", "Kill" );
}
// number of cans needed to escape.
NumCansNeeded <- 8
switch( difficulty )
{
case "easy":
{
NumCansNeeded = 6;
EntFire( "relay_outro_easy", "Enable" );
break;
}
case "normal":
{
NumCansNeeded = 8;
EntFire( "relay_outro_normal", "Enable" );
break;
}
case "hard":
{
NumCansNeeded = 10;
EntFire( "relay_outro_advanced", "Enable" );
break;
}
case "impossible":
{
NumCansNeeded = 12;
EntFire( "relay_outro_expert", "Enable" );
break;
}
default:
break;
}
EntFire( "progress_display", "SetTotalItems", NumCansNeeded );
EntFire( "radio", "AddOutput", "FinaleEscapeStarted director:RunScriptCode:DirectorScript.MapScript.LocalScript.DirectorOptions.TankLimit <- 3:0:-1" );
local c14m2_tankspawntime = 0.0;
local c14m2_tankspawner = null;
while ( c14m2_tankspawner = Entities.FindByClassname( c14m2_tankspawner, "commentary_zombie_spawner" ) )
{
if ( c14m2_tankspawner.IsValid() )
{
c14m2_tankspawner.ValidateScriptScope();
local spawnerScope = c14m2_tankspawner.GetScriptScope();
spawnerScope.SpawnedTankTime <- 0.0;
spawnerScope.InputSpawnZombie <- function()
{
if ( (caller) && (caller.GetName() == "escapetanktrigger") )
{
if ( !c14m2_tankspawntime )
c14m2_tankspawntime = Time();
}
if ( SpawnedTankTime )
{
if ( Time() - c14m2_tankspawntime < 1 )
return false;
else
{
delete this.SpawnedTankTime;
delete this.InputSpawnZombie;
return true;
}
}
SpawnedTankTime = Time();
return true;
}
}
}
//-----------------------------------------------------
// INIT
//-----------------------------------------------------
GasCansTouched <- 0
GasCansPoured <- 0
ScavengeCansPoured <- 0
ScavengeCansNeeded <- 2
local EscapeStage = DirectorOptions.A_CustomFinale_StageCount;
//-----------------------------------------------------
function GasCanTouched()
{
GasCansTouched++;
if ( developer() > 0 )
Msg(" Touched: " + GasCansTouched + "\n");
}
function GasCanPoured()
{
GasCansPoured++;
ScavengeCansPoured++;
if ( developer() > 0 )
Msg(" Poured: " + GasCansPoured + "\n");
if ( GasCansPoured == 1 )
EntFire( "explain_fuel_generator", "Kill" );
else if ( GasCansPoured == NumCansNeeded )
{
if ( developer() > 0 )
Msg(" needed: " + NumCansNeeded + "\n");
EntFire( "relay_generator_ready", "Trigger", "", 0.1 );
EntFire( "weapon_scavenge_item_spawn", "TurnGlowsOff" );
EntFire( "weapon_scavenge_item_spawn", "Kill" );
EntFire( "director", "EndCustomScriptedStage", "", 5 );
}
if ( Director.GetGameModeBase() == "versus" && ScavengeCansPoured == 2 && GasCansPoured < NumCansNeeded )
{
ScavengeCansPoured = 0;
EntFire( "radio", "AdvanceFinaleState" );
}
}
//-----------------------------------------------------
function OnBeginCustomFinaleStage( num, type )
{
if ( developer() > 0 )
printl( "Beginning custom finale stage " + num + " of type " + type );
if ( num == 4 )
{
EntFire( "relay_boat_coming2", "Trigger" );
// Delay lasts 10 seconds, next stage turns off lights immediately
EntFire( "lighthouse_light", "SetPattern", "mmamammmmammamamaaamammma", 7.0 );
EntFire( "lighthouse_light", "SetPattern", "", 9.5 );
EntFire( "lighthouse_light", "TurnOff", "", 10 );
EntFire( "spotlight_beams", "LightOff", "", 7.0 );
EntFire( "spotlight_glow", "HideSprite", "", 7.0 );
EntFire( "brush_light", "Enable", "", 7.0 );
EntFire( "spotlight_beams", "LightOn", "", 7.5 );
EntFire( "spotlight_glow", "ShowSprite", "", 7.5 );
EntFire( "brush_light", "Disable", "", 7.5 );
EntFire( "spotlight_beams", "LightOff", "", 8.0 );
EntFire( "spotlight_glow", "HideSprite", "", 8.0 );
EntFire( "brush_light", "Enable", "", 8.0 );
EntFire( "spotlight_beams", "LightOn", "", 8.5 );
EntFire( "spotlight_glow", "ShowSprite", "", 8.5 );
EntFire( "brush_light", "Disable", "", 8.5 );
}
else if ( num == 5 )
{
EntFire( "relay_lighthouse_off", "Trigger" );
SpawnScavengeCans( difficulty );
}
else if ( num == EscapeStage )
EntFire( "relay_start_boat", "Trigger" );
}
function GetCustomScriptedStageProgress( defvalue )
{
local progress = ScavengeCansPoured.tofloat() / ScavengeCansNeeded.tofloat();
if ( developer() > 0 )
Msg( "Progress was " + defvalue + ", now: " + ScavengeCansPoured + " poured / " + ScavengeCansNeeded + " needed = " + progress + "\n" );
return progress;
}
|
director_gauntlet.nuc (为所有长途救援结局共享)
Msg("Initiating Gauntlet\n");
DirectorOptions <-
{
PanicForever = true
PausePanicWhenRelaxing = true
IntensityRelaxThreshold = 0.99
RelaxMinInterval = 25
RelaxMaxInterval = 35
RelaxMaxFlowTravel = 400
LockTempo = 0
SpecialRespawnInterval = 20
PreTankMobMax = 20
ZombieSpawnRange = 3000
ZombieSpawnInFog = true
MobSpawnSize = 5
CommonLimit = 5
GauntletMovementThreshold = 500.0
GauntletMovementTimerLength = 5.0
GauntletMovementBonus = 2.0
GauntletMovementBonusMax = 30.0
// length of bridge to test progress against.
BridgeSpan = 20000
MobSpawnMinTime = 5
MobSpawnMaxTime = 5
MobSpawnSizeMin = 5
MobSpawnSizeMax = 20
minSpeed = 50
maxSpeed = 200
speedPenaltyZAdds = 15
CommonLimitMax = 30
function RecalculateLimits()
{
//Increase common limit based on progress
local progressPct = ( Director.GetFurthestSurvivorFlow() / BridgeSpan )
if ( progressPct < 0.0 ) progressPct = 0.0;
if ( progressPct > 1.0 ) progressPct = 1.0;
MobSpawnSize = MobSpawnSizeMin + progressPct * ( MobSpawnSizeMax - MobSpawnSizeMin )
//Increase common limit based on speed
local speedPct = ( Director.GetAveragedSurvivorSpeed() - minSpeed ) / ( maxSpeed - minSpeed );
if ( speedPct < 0.0 ) speedPct = 0.0;
if ( speedPct > 1.0 ) speedPct = 1.0;
MobSpawnSize = MobSpawnSize + speedPct * ( speedPenaltyZAdds );
CommonLimit = MobSpawnSize * 1.5
if ( CommonLimit > CommonLimitMax ) CommonLimit = CommonLimitMax;
}
}
function Update()
{
DirectorOptions.RecalculateLimits();
}
|
另请参阅
介绍
文档
其他
← 求生之路2关卡设计/长途救援结局 | Return to 求生之路2关卡设计 |