og-r1delta-core/scripts/vscripts/mp/_simulation.nut

493 lines
No EOL
14 KiB
Text

const FX_POD_GLOWLIGHT = "P_pod_door_glow_FP"
const FX_POD_DLIGHT_CONSOLE1 = "P_pod_Dlight_console1"
const FX_POD_DLIGHT_CONSOLE2 = "P_pod_Dlight_console2"
const FX_POD_DLIGHT_BACKLIGHT_SIDE = "P_pod_Dlight_backlight_side"
const FX_POD_DLIGHT_BACKLIGHT_TOP = "P_pod_Dlight_backlight_top"
PrecacheParticleSystem( FX_POD_GLOWLIGHT )
PrecacheParticleSystem( FX_POD_DLIGHT_CONSOLE1 )
PrecacheParticleSystem( FX_POD_DLIGHT_CONSOLE2 )
PrecacheParticleSystem( FX_POD_DLIGHT_BACKLIGHT_SIDE )
PrecacheParticleSystem( FX_POD_DLIGHT_BACKLIGHT_TOP )
function main()
{
if ( reloadingScripts )
return
AddDeathCallback( "npc_soldier", Simulation_GroundTroopsDeathCallback )
AddDeathCallback( "npc_spectre", Simulation_GroundTroopsDeathCallback )
AddDeathCallback( "npc_marvin", Simulation_GroundTroopsDeathCallback )
AddDeathCallback( "player", Simulation_GroundTroopsDeathCallback )
Globalize( Simulation_GroundTroopsDeathCallback )
}
function Simulation_GroundTroopsDeathCallback( guy, damageInfo )
{
EmitSoundAtPosition( guy.GetOrigin(), "Object_Dissolve" )
if ( ShouldDoDissolveDeath( guy, damageInfo ) )
guy.Dissolve( ENTITY_DISSOLVE_CHAR, Vector( 0, 0, 0 ), 0 )
}
function ShouldDoDissolveDeath( guy, damageInfo )
{
if ( !guy.IsPlayer() )
return true
// can't dissolve players when they're not playing the game, otherwise when the game starts again they're invisible
local gs = GetGameState()
if ( gs != eGameState.Playing && gs != eGameState.SuddenDeath && gs != eGameState.Epilogue )
{
printt( "Skipping player dissolve death because game is not active ( player:", guy, ")" )
return false
}
return true
}
function TrainingPod_ViewConeLock_Shared( player )
{
player.PlayerCone_FromAnim()
player.PlayerCone_SetMinYaw( -25 )
player.PlayerCone_SetMaxYaw( 25 )
player.PlayerCone_SetMinPitch( -30 )
}
function TrainingPod_ViewConeLock_PodOpen( player )
{
TrainingPod_ViewConeLock_Shared( player )
player.PlayerCone_SetMaxPitch( 35 )
}
function TrainingPod_ViewConeLock_PodClosed( player )
{
TrainingPod_ViewConeLock_Shared( player )
player.PlayerCone_SetMaxPitch( 30 )
}
function TrainingPod_ViewConeLock_SemiStrict( player )
{
player.PlayerCone_FromAnim()
player.PlayerCone_SetMinYaw( -10 )
player.PlayerCone_SetMaxYaw( 10 )
player.PlayerCone_SetMinPitch( -10 )
player.PlayerCone_SetMaxPitch( 10 )
}
function TrainingPod_ViewConeLock_Strict( player )
{
player.PlayerCone_FromAnim()
player.PlayerCone_SetMinYaw( 0 )
player.PlayerCone_SetMaxYaw( 0 )
player.PlayerCone_SetMinPitch( 0 )
player.PlayerCone_SetMaxPitch( 0 )
}
function TrainingPod_SetupInteriorDLights( pod )
{
local map = []
map.append( { scriptAlias = "console1", fxName = FX_POD_DLIGHT_CONSOLE1, attachName = "light_console1" } )
map.append( { scriptAlias = "console2", fxName = FX_POD_DLIGHT_CONSOLE2, attachName = "light_console2" } )
map.append( { scriptAlias = "backlight_side_L", fxName = FX_POD_DLIGHT_BACKLIGHT_SIDE, attachName = "light_back1" } )
map.append( { scriptAlias = "backlight_side_R", fxName = FX_POD_DLIGHT_BACKLIGHT_SIDE, attachName = "light_back2" } )
map.append( { scriptAlias = "backlight_top", fxName = FX_POD_DLIGHT_BACKLIGHT_TOP, attachName = "light_backtop" } )
pod.s.dLightMappings <- map
}
function TrainingPod_TurnOnInteriorDLight( scriptAlias, pod )
{
local fxName
local attachName
foreach ( mapping in pod.s.dLightMappings )
{
if ( mapping.scriptAlias == scriptAlias )
{
fxName = mapping.fxName
attachName = mapping.attachName
break
}
}
Assert( fxName && attachName )
local fxHandle = PlayLoopFXOnEntity( fxName, pod, attachName )
pod.s.dLights.append( fxHandle )
}
function TrainingPod_KillInteriorDLights_Delayed( pod, delay )
{
if ( IsTrainingLevel() )
{
level.player.EndSignal( "OnDestroy" )
level.player.EndSignal( "Disconnected" )
level.ent.EndSignal( "ModuleChanging" )
}
pod.EndSignal( "OnDestroy" )
wait delay
TrainingPod_KillInteriorDLights( pod )
}
function TrainingPod_KillInteriorDLights( pod )
{
foreach ( fxHandle in pod.s.dLights )
{
if ( !IsValid_ThisFrame( fxHandle ) )
continue
KillFX( fxHandle )
}
pod.s.dLights = []
}
function TrainingPod_SnapLaserEmittersToAttachPoints( pod )
{
foreach ( emitter in pod.s.laserEmitters )
{
local attachID = pod.LookupAttachment( emitter.s.attachName )
local attachOrg = pod.GetAttachmentOrigin( attachID )
local attachAng = pod.GetAttachmentAngles( attachID )
emitter.ClearParent()
emitter.SetOrigin( attachOrg ) // HACK set this to ANYTHING (even 0, 0, 0) and the position is correct, otherwise it's offset from the attachpoint when parented
emitter.SetParent( pod, emitter.s.attachName )
}
}
function TrainingPod_InteriorFX_CommonSetup( pod )
{
if ( pod.s.laserEmitters.len() )
{
TrainingPod_KillLasers( pod )
TrainingPod_ResetLaserEmitterRotation( pod )
}
TrainingPod_KillGlowFX( pod )
}
function TrainingPod_KillLasers( pod, doEndCap = false )
{
foreach ( emitter in pod.s.laserEmitters )
{
if ( IsValid_ThisFrame( emitter.s.fxHandle ) )
{
if ( !doEndCap )
{
//printt( "killing laser FX", emitter.s.fxHandle )
KillFX( emitter.s.fxHandle )
}
else
{
//printt( "killing laser FX with endcap", emitter.s.fxHandle )
KillFXWithEndcap( emitter.s.fxHandle )
}
}
emitter.s.fxHandle = null
}
}
function TrainingPod_ResetLaserEmitterRotation( pod )
{
if ( !( "laserEmitters" in pod.s ) )
return
foreach ( emitter in pod.s.laserEmitters )
{
//reset to start position
emitter.RotateTo( emitter.s.ogAng, 0.05 )
}
}
function TrainingPod_KillGlowFX( pod )
{
foreach ( fxHandle in pod.s.glowLightFXHandles )
{
if ( !IsValid_ThisFrame( fxHandle ) )
continue
KillFX( fxHandle )
}
pod.s.glowLightFXHandles = []
}
function TrainingPod_GlowLightsArraySetup( pod )
{
local rows = []
// rows are set up bottom to top
// lights are set up outside to in (in = door close seam; opposite for each side)
// process two rows per loop (one for each door side)
local row = []
row.append( [ "fx_glow_L_door012", "fx_glow_L_door013" ] )
row.append( [ "fx_glow_R_door014", "fx_glow_R_door013" ] )
rows.append( row )
local row = []
row.append( [ "fx_glow_L_door014", "fx_glow_L_door011" ] )
row.append( [ "fx_glow_R_door012", "fx_glow_R_door011" ] )
rows.append( row )
local row = []
row.append( [ "fx_glow_L_door09", "fx_glow_L_door010" ] )
row.append( [ "fx_glow_R_door09", "fx_glow_R_door010" ] )
rows.append( row )
local row = []
row.append( [ "fx_glow_L_door07", "fx_glow_L_door08" ] )
row.append( [ "fx_glow_R_door07", "fx_glow_R_door08" ] )
rows.append( row )
local row = []
row.append( [ "fx_glow_L_door05", "fx_glow_L_door06" ] )
row.append( [ "fx_glow_R_door05", "fx_glow_R_door06" ] )
rows.append( row )
local row = []
row.append( [ "fx_glow_L_door03", "fx_glow_L_door04" ] )
row.append( [ "fx_glow_R_door03", "fx_glow_R_door04" ] )
rows.append( row )
local row = []
row.append( [ "fx_glow_L_door01", "fx_glow_L_door02" ] )
row.append( [ "fx_glow_R_door01", "fx_glow_R_door02" ] )
rows.append( row )
if ( GetMapName() == "mp_wargames" )
pod.s.trainingPodGlowLightRows = rows
else
level.trainingPodGlowLightRows = rows
}
function TrainingPod_GlowLightsTurnOn( pod, lightWait, rowWait )
{
//local startTime = Time()
local lightRows = GetMapName() == "mp_wargames" ? pod.s.trainingPodGlowLightRows : level.trainingPodGlowLightRows
// light up one light on each side at a time
foreach ( row in lightRows )
{
local loopTime = Time()
// assume both sides have same number of lights
local numLights = row[ 0 ].len()
for ( local i = 0; i < numLights; i++ )
{
foreach ( side in row )
{
local attachName = side[ i ]
local fxHandle = PlayLoopFXOnEntity( FX_POD_GLOWLIGHT, pod, attachName )
pod.s.glowLightFXHandles.append( fxHandle )
}
if ( lightWait > 0 )
wait lightWait
}
if ( rowWait > 0)
wait rowWait
}
//printt( "glow lights turn on took", Time() - startTime, "secs" )
}
// ==============================================================
// MP Exclusive
// ==============================================================
if ( !IsTrainingLevel() )
{
function Intro_PlayersStartFirstPersonSequence()
{
foreach ( player in level.playersWatchingIntro )
thread Intro_StartPlayerFirstPersonSequence( player )
}
function PlayPodGamemodeVoicelines( playFallbackGenVoiceline = true )
{
foreach ( player in level.playersWatchingIntro )
{
local genIdx = player.GetGen()
local origin = player.GetOrigin()
//printt( "$$$$ Player", player, "genIdx:", genIdx )
// GetGen 1 = gen 2
// GetGen 9 = gen 10
if ( genIdx > 0 && genIdx <= 9 )
{
local gen = genIdx + 1
Assert( gen >= 2 && gen <= 10 ) // make sure we have an alias to play
// "Gen [x] Pilot on deck." (w variants)
local genAlias = "diag_dlc1_WG_pilot_onboard_gen" + gen
EmitSoundAtPositionOnlyToPlayer( origin, player, genAlias )
}
else
{
if ( playFallbackGenVoiceline )
{
// "Welcome back."
EmitSoundAtPositionOnlyToPlayer( origin, player, "diag_dlc1_WG129_01_01_neut_tutai" )
}
}
}
wait 2.75
if ( GetMapName() == "mp_npe" )
{
switch ( GameRules.GetGameMode() )
{
case LAST_TITAN_STANDING:
case WINGMAN_LAST_TITAN_STANDING:
case TITAN_BRAWL:
case TITAN_MFD:
case TITAN_MFD_PRO:
case TITAN_BRAWL_AUTO:
// Now beginning Titan training.
EmitSoundToIntroPlayers( "diag_tut_npeLevel_NP275_01_01_neut_tutai" )
wait 3
break
default:
// "Prepare for combat."
EmitSoundToIntroPlayers( "diag_dlc1_WG_pod_getready" )
wait 2.4
break
}
}
else
{
// "Prepare for combat."
EmitSoundToIntroPlayers( "diag_dlc1_WG_pod_getready" )
wait 2.4
}
local modeAliases = {}
modeAliases[ ATTRITION ] <- "diag_dlc1_WG136_01_01_neut_tutai" // "Attrition."
modeAliases[ TEAM_DEATHMATCH ] <- "diag_dlc1_WG137_01_01_neut_tutai" // "Pilot Hunter."
modeAliases[ SCAVENGER ] <- "diag_dlc1_WG137_01_01_neut_tutai"
modeAliases[ CAPTURE_POINT ] <- "diag_dlc1_WG138_01_01_neut_tutai" // "Hardpoint Domination."
modeAliases[ LAST_TITAN_STANDING ] <- "diag_dlc1_WG139_01_01_neut_tutai" // "Last Titan Standing."
modeAliases[ "lts_ffa" ] <- "diag_dlc1_WG139_01_01_neut_tutai" // "Last Titan Standing."
modeAliases[ WINGMAN_LAST_TITAN_STANDING ] <- "diag_dlc1_WG142_01_01_neut_tutai" // "Wingman Last Titan Standing."
modeAliases[ CAPTURE_THE_FLAG ] <- "diag_dlc1_WG140_01_01_neut_tutai" // "Capture The Flag."
modeAliases[ CAPTURE_THE_FLAG_PRO ] <- "diag_dlc1_WG140_01_01_neut_tutai"
modeAliases[ PILOT_SKIRMISH ] <- "diag_dlc1_WG232_01_01_neut_tutai"
modeAliases[ MARKED_FOR_DEATH ] <- "diag_dlc1_WG236_01_01_neut_tutai"
modeAliases[ MARKED_FOR_DEATH_PRO ] <- "diag_dlc1_WG237_01_01_neut_tutai"
modeAliases[ TITAN_BRAWL ] <- "diag_dlc1_WG137_01_01_neut_tutai"
modeAliases[ TITAN_MFD ] <- "diag_dlc1_WG236_01_01_neut_tutai"
modeAliases[ TITAN_MFD_PRO ] <- "diag_dlc1_WG237_01_01_neut_tutai"
// make sure we have VO for the game mode
local mode = GameRules.GetGameMode()
local modeAlias
if ( !( mode in modeAliases ) )
{
modeAlias = modeAliases[ TEAM_DEATHMATCH ]
printt( "Couldn't find alias VO for gamemode", mode,". Defaulting to pilot hunter." )
//printt( "Couldn't find alias VO for gamemode", mode,", finishing training pod VO early." )
//return
}
else
{
modeAlias = modeAliases[ mode ]
}
// "Simulation mode is:"
EmitSoundToIntroPlayers( "diag_dlc1_WG135_01_01_neut_tutai" )
wait 1.5
EmitSoundToIntroPlayers( modeAlias )
}
function EmitSoundToIntroPlayers( alias )
{
foreach ( player in level.playersWatchingIntro )
if ( IsValid( player ) )
EmitSoundAtPositionOnlyToPlayer( player.GetOrigin(), player, alias )
}
function EmitSoundOnlyToIntroPlayers( alias, team = null )
{
foreach ( player in level.playersWatchingIntro )
{
if ( !IsValid( player ) )
continue
if ( team && player.GetTeam() != team )
continue
printt( "Emitting sound on player", player )
EmitSoundOnEntityOnlyToPlayer( player, player, alias )
}
}
function FadeOutSoundOnIntroPlayers( alias, fadeTime )
{
foreach ( player in level.playersWatchingIntro )
if ( IsValid( player ) )
FadeOutSoundOnEntity( player, alias, fadeTime )
}
function TeleportPlayerToRealStartSpawn( player )
{
player.EndSignal( "Disconnected" )
if ( IsRoundBased() && GetRoundsPlayed() > 0 )
return // subsequent rounds don't do custom intro so gamestate scripts can handle spawning
if ( ShouldIntroSpawnAsTitan() )
{
// spawn as a titan
player.SetPlayerSettings( "spectator" )
TitanPlayerHotDropsIntoLevel( player )
}
else
{
// spawn as a pilot
local spawnpoint = FindStartSpawnPoint( player )
spawnpoint.s.inUse = true // this makes subsequent players not choose the same spawn point
OnThreadEnd(
function() : ( spawnpoint )
{
if ( IsValid( spawnpoint ) )
spawnpoint.s.inUse = false
}
)
WaitEndFrame() // let the last function's OnThreadEnd clear parent before setting origin
Assert( player.GetParent() == null, "ERROR Can't teleport player to real start spawn because he's still parented to entity: " + player.GetParent() )
thread TeleportPlayer_MaterializeSFX( player, 0.4 )
player.SetOrigin( spawnpoint.GetOrigin() )
player.SetAngles( spawnpoint.GetAngles() )
//printt( player, "teleported to real start spawn,", "origin:", spawnpoint.GetOrigin(), "angles:", spawnpoint.GetAngles() )
}
}
function TeleportPlayer_MaterializeSFX( player, delay = 0.0 )
{
player.EndSignal( "Disconnected" )
if ( delay > 0.0 )
wait delay
EmitSoundOnEntityOnlyToPlayer( player, player, "Wargames_Materialize" )
}
}
main()