aboutsummaryrefslogtreecommitdiff
path: root/Northstar.Client/mod/scripts/vscripts
diff options
context:
space:
mode:
authorRoyalBlue1 <realEmail@veryRealURL.com>2023-01-15 15:59:08 +0100
committerRoyalBlue1 <realEmail@veryRealURL.com>2023-01-15 15:59:08 +0100
commitbb8671eefc562fa76e13559915ae1ad493d06802 (patch)
tree40ac781a3422083ef2358ddf38da43e64462bbd0 /Northstar.Client/mod/scripts/vscripts
parentcad416bc967bc4b902ff5808c0ae3281402d4895 (diff)
parent9bbe6832460aaabd96fef18d6e4ebb05779bb71d (diff)
downloadNorthstarMods-bb8671eefc562fa76e13559915ae1ad493d06802.tar.gz
NorthstarMods-bb8671eefc562fa76e13559915ae1ad493d06802.zip
Merge remote-tracking branch 'upsteam/main' into gamemode_fd
Diffstat (limited to 'Northstar.Client/mod/scripts/vscripts')
-rw-r--r--Northstar.Client/mod/scripts/vscripts/_custom_codecallbacks_client.gnut42
-rw-r--r--Northstar.Client/mod/scripts/vscripts/client/cl_gamestate.gnut8
-rw-r--r--Northstar.Client/mod/scripts/vscripts/client/cl_minimap.gnut942
-rw-r--r--Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut1676
-rw-r--r--Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut36
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut2
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut2
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut45
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/ui_mouse_capture.nut60
9 files changed, 2741 insertions, 72 deletions
diff --git a/Northstar.Client/mod/scripts/vscripts/_custom_codecallbacks_client.gnut b/Northstar.Client/mod/scripts/vscripts/_custom_codecallbacks_client.gnut
index 66a40cb0..277ed030 100644
--- a/Northstar.Client/mod/scripts/vscripts/_custom_codecallbacks_client.gnut
+++ b/Northstar.Client/mod/scripts/vscripts/_custom_codecallbacks_client.gnut
@@ -1,7 +1,10 @@
untyped
global function AddCallback_OnReceivedSayTextMessage
-global function NSSetupChathooksClient
+
+// this is global due to squirrel bridge v3 making native not be able to find non-global funcs properly
+// temp fix (surely it will get replaced), do not use this function please (although there isnt rly a downside to it?)
+global function CHudChat_ProcessMessageStartThread
global struct ClClient_MessageStruct {
string message
@@ -11,6 +14,7 @@ global struct ClClient_MessageStruct {
bool isDead
bool isWhisper
bool shouldBlock
+ bool noServerTag
}
struct {
@@ -18,6 +22,10 @@ struct {
} NsCustomCallbacksClient
void function OnReceivedMessage(ClClient_MessageStruct localMessage) {
+
+ if ( IsWatchingReplay() )
+ return
+
if (localMessage.player != null)
{
foreach (callbackFunc in NsCustomCallbacksClient.OnReceivedSayTextMessageCallbacks)
@@ -29,6 +37,7 @@ void function OnReceivedMessage(ClClient_MessageStruct localMessage) {
localMessage.isDead = returnStruct.isDead
localMessage.isWhisper = returnStruct.isWhisper
localMessage.shouldBlock = localMessage.shouldBlock || returnStruct.shouldBlock
+ localMessage.noServerTag = returnStruct.noServerTag
}
}
@@ -39,7 +48,13 @@ void function OnReceivedMessage(ClClient_MessageStruct localMessage) {
NSChatWriteRaw(1, "\n")
- if (localMessage.player == null) NSChatWrite(1, "\x1b[95m")
+ if (localMessage.player == null)
+ {
+ if (!localMessage.noServerTag || localMessage.isWhisper)
+ {
+ NSChatWrite(1, "\x1b[95m")
+ }
+ }
else
{
bool isFriendly = localMessage.player.GetTeam() == GetLocalClientPlayer().GetTeam()
@@ -54,15 +69,18 @@ void function OnReceivedMessage(ClClient_MessageStruct localMessage) {
if (localMessage.player == null)
{
- NSChatWriteRaw(1, Localize("#HUD_CHAT_SERVER_PREFIX") + " ")
+ if (!localMessage.noServerTag)
+ {
+ NSChatWriteRaw(1, Localize("#HUD_CHAT_SERVER_PREFIX") + " ")
+ }
}
- else {
+ else
+ {
NSChatWriteRaw(1, localMessage.playerName)
NSChatWriteRaw(1, ": ")
}
- NSChatWrite(1, "\x1b[0m")
-
+ if (localMessage.player != null || !localMessage.noServerTag || localMessage.isWhisper) NSChatWrite(1, "\x1b[0m")
NSChatWrite(1, localMessage.message)
}
@@ -87,16 +105,19 @@ void function CHudChat_OnReceivedSayTextMessageCallback(int fromPlayerIndex, str
fromPlayerName = fromPlayer.GetPlayerNameWithClanTag()
}
+ // Null player + isTeam == true: Server with no tag.
+
if (messageType == 0 || messageType == 1)
{
ClClient_MessageStruct localMessage
localMessage.message = message
localMessage.player = fromPlayer
localMessage.playerName = fromPlayerName
- localMessage.isTeam = isTeam
+ localMessage.isTeam = fromPlayer != null && isTeam
localMessage.isDead = isDead
localMessage.isWhisper = false
localMessage.shouldBlock = false
+ localMessage.noServerTag = fromPlayer == null && isTeam
OnReceivedMessage(localMessage)
return
}
@@ -107,10 +128,11 @@ void function CHudChat_OnReceivedSayTextMessageCallback(int fromPlayerIndex, str
localMessage.message = message
localMessage.player = fromPlayer
localMessage.playerName = fromPlayerName
- localMessage.isTeam = isTeam
+ localMessage.isTeam = fromPlayer != null && isTeam
localMessage.isDead = isDead
localMessage.isWhisper = true
localMessage.shouldBlock = false
+ localMessage.noServerTag = fromPlayer == null && isTeam
OnReceivedMessage(localMessage)
return
}
@@ -120,7 +142,3 @@ void function AddCallback_OnReceivedSayTextMessage( ClClient_MessageStruct funct
{
NsCustomCallbacksClient.OnReceivedSayTextMessageCallbacks.append(callbackFunc)
}
-
-void function NSSetupChathooksClient() {
- getroottable().rawset("CHudChat_ProcessMessageStartThread", CHudChat_ProcessMessageStartThread)
-}
diff --git a/Northstar.Client/mod/scripts/vscripts/client/cl_gamestate.gnut b/Northstar.Client/mod/scripts/vscripts/client/cl_gamestate.gnut
index 93be01ea..1baeae9f 100644
--- a/Northstar.Client/mod/scripts/vscripts/client/cl_gamestate.gnut
+++ b/Northstar.Client/mod/scripts/vscripts/client/cl_gamestate.gnut
@@ -1105,8 +1105,16 @@ void function DisplayPostMatchTop3()
RuiSetBool( rui, "isFriendly" + i, localTeam == players[i].GetTeam() )
}
}
+
+ if ( GetConVarBool( "hud_takesshots" ) )
+ thread TakeScoreboardScreenshot_Delayed()
}
+void function TakeScoreboardScreenshot_Delayed()
+{
+ wait 1.5
+ GetLocalClientPlayer().ClientCommand( "jpeg" )
+}
float function GetGameStartTime()
{
diff --git a/Northstar.Client/mod/scripts/vscripts/client/cl_minimap.gnut b/Northstar.Client/mod/scripts/vscripts/client/cl_minimap.gnut
new file mode 100644
index 00000000..4237a0be
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/client/cl_minimap.gnut
@@ -0,0 +1,942 @@
+global function ClMinimap_Init
+
+global function ClientCodeCallback_MinimapEntitySpawned
+
+global function Minimap_AddLayer
+global function Minimap_AddCustomLayer
+
+global function RegisterMinimapPackage
+
+global function Minimap_SetZoomScale
+global function Minimap_SetSizeScale
+global function Minimap_GetZoomScale
+global function Minimap_GetSizeScale
+global function Minimap_IsUsingLargeMinimap
+
+global function Minimap_Ping
+global function ServerCallback_PingMinimap
+
+global function Minimap_EnableDraw
+global function Minimap_DisableDraw
+
+#if DEV
+global function DumpMinimapHandles
+#endif
+
+struct {
+ var minimap_base
+ var minimap_wedges
+
+ int activeMinimapObjectCount
+
+ var minimap_you
+ var minimap_jammed_layer
+
+ var minimap_indicator
+
+ #if DEV
+ table< int, entity > minimapHandles
+ #endif
+
+ array<var> minimapOtherRuis
+
+ float threatMaxDist
+
+ float minimapZoomScale = 1
+ float minimapSizeScale = 1
+
+ bool minimapEnabled = true
+} file
+
+
+struct MinmapPackage
+{
+ asset minimapAsset = $""
+ void functionref( entity, var ) initFunction
+}
+
+table< string, array<MinmapPackage> > minimapAssetMap = {}
+
+const int OF_IS_VISIBLE = 1 << 0
+const int OF_TEAM_SAME = 1 << 1
+const int OF_TEAM_ENEMY = 1 << 2
+const int OF_IN_OUR_PARTY = 1 << 3
+const int OF_IS_OWNED_BY_US = 1 << 4
+const int OF_IS_PLAYER = 1 << 5
+const int OF_IS_NPC = 1 << 6
+const int OF_IS_TITAN = 1 << 7
+const int OF_ORIENT_UP = 1 << 8
+const int OF_NO_TEAM_COLOR = 1 << 9
+
+
+void function RegisterMinimapPackage( string entityClassname, int customStateIndex, asset minimapAsset, void functionref( entity, var ) initFunction )
+{
+ Assert ( (entityClassname in minimapAssetMap), "minimap is not currently setup to handle this type of entity: " + entityClassname )
+
+ MinmapPackage minimapPackage
+ minimapPackage.minimapAsset = minimapAsset
+ minimapPackage.initFunction = initFunction
+
+ switch ( entityClassname )
+ {
+ case "npc_soldier":
+ case "npc_spectre":
+ case "npc_stalker":
+ case "npc_drone":
+ case "npc_frag_drone":
+ case "npc_super_spectre":
+ case "npc_turret_sentry":
+ Assert( customStateIndex > 0 && customStateIndex < eMinimapObject_npc.COUNT )
+ minimapAssetMap[entityClassname].resize( eMinimapObject_npc.COUNT )
+ minimapAssetMap[entityClassname][customStateIndex] = minimapPackage
+ break
+ case "npc_titan":
+ Assert( customStateIndex > 0 && customStateIndex < eMinimapObject_npc_titan.COUNT )
+ minimapAssetMap[entityClassname].resize( eMinimapObject_npc_titan.COUNT )
+ minimapAssetMap[entityClassname][customStateIndex] = minimapPackage
+ break
+
+ case "prop_script":
+ Assert( customStateIndex > 0 && customStateIndex < eMinimapObject_prop_script.COUNT )
+ minimapAssetMap[entityClassname].resize( eMinimapObject_prop_script.COUNT )
+ minimapAssetMap[entityClassname][customStateIndex] = minimapPackage
+ break
+
+ case "info_hardpoint":
+ Assert( customStateIndex > 0 && customStateIndex < eMinimapObject_info_hardpoint.COUNT )
+ minimapAssetMap[entityClassname].resize( eMinimapObject_info_hardpoint.COUNT )
+ minimapAssetMap[entityClassname][customStateIndex] = minimapPackage
+ break
+
+ default:
+ Assert( false, "minimap is not currently setup to handle this type of entity: " + entityClassname )
+ }
+}
+
+void function RegisterDefaultMinimapPackage( string entityClassname, asset minimapAsset, void functionref( entity, var ) initFunction )
+{
+ Assert ( !(entityClassname in minimapAssetMap) )
+
+ MinmapPackage minimapPackage
+ minimapPackage.minimapAsset = minimapAsset
+ minimapPackage.initFunction = initFunction
+
+ minimapAssetMap[entityClassname] <- [minimapPackage]
+}
+
+void function ClMinimap_Init()
+{
+ RegisterDefaultMinimapPackage( "player", $"ui/minimap_player.rpak", MinimapPackage_PlayerInit )
+ RegisterDefaultMinimapPackage( "npc_titan", $"ui/minimap_object.rpak", MinimapPackage_NPCTitanInit )
+ RegisterDefaultMinimapPackage( "npc_soldier", $"ui/minimap_object.rpak", MinimapPackage_NPCHumanSizedInit )
+ RegisterDefaultMinimapPackage( "npc_spectre", $"ui/minimap_object.rpak", MinimapPackage_NPCHumanSizedInit )
+ RegisterDefaultMinimapPackage( "npc_stalker", $"ui/minimap_object.rpak", MinimapPackage_NPCHumanSizedInit )
+ RegisterDefaultMinimapPackage( "npc_super_spectre", $"ui/minimap_object.rpak", MinimapPackage_NPCHumanSizedInit )
+ RegisterDefaultMinimapPackage( "npc_drone_rocket", $"ui/minimap_object.rpak", MinimapPackage_NPCHumanSizedInit )
+ RegisterDefaultMinimapPackage( "npc_frag_drone", $"ui/minimap_object.rpak", MinimapPackage_NPCHumanSizedInit )
+ RegisterDefaultMinimapPackage( "npc_drone", $"ui/minimap_object.rpak", MinimapPackage_NPCHumanSizedInit )
+ RegisterDefaultMinimapPackage( "npc_dropship", $"ui/minimap_object.rpak", MinimapPackage_NPCDropShipInit )
+ RegisterDefaultMinimapPackage( "npc_turret_sentry", $"ui/minimap_object.rpak", MinimapPackage_NPCSentryTurretInit )
+ RegisterDefaultMinimapPackage( "prop_script", $"", MinimapPackage_DummyInit )
+ RegisterDefaultMinimapPackage( "item_titan_battery", $"ui/minimap_fw_battery.rpak", MinimapPackage_BatteryInit )
+ RegisterDefaultMinimapPackage( "item_flag", $"ui/minimap_object.rpak", MinimapPackage_FlagInit )
+ RegisterDefaultMinimapPackage( "item_bomb", $"ui/minimap_object.rpak", MinimapPackage_LTSBomb )
+ RegisterDefaultMinimapPackage( "info_hardpoint", $"", MinimapPackage_DummyInit )
+ RegisterDefaultMinimapPackage( "item_powerup", $"ui/minimap_object.rpak", MinimapPackage_PowerUp )
+
+ RegisterMinimapPackage( "npc_titan", eMinimapObject_npc_titan.AT_BOUNTY_BOSS, $"ui/minimap_object.rpak", MinimapPackage_BossTitanInit )
+
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.AT_DROPZONE_A, $"ui/minimap_obj_area.rpak", MinimapPackage_ATAreaInit )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.AT_DROPZONE_B, $"ui/minimap_obj_area.rpak", MinimapPackage_ATAreaInit )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.AT_DROPZONE_C, $"ui/minimap_obj_area.rpak", MinimapPackage_ATAreaInit )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.AT_BANK, $"ui/minimap_object.rpak", MinimapPackage_ATBank )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FW_BUILDSITE, $"ui/minimap_fw_build_site.rpak", MinimapPackage_FWBuildSite )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FW_BUILDSITE_TURRET, $"ui/minimap_fw_build_site.rpak", MinimapPackage_FWBuildSite )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FW_BUILDSITE_SHIELDED, $"ui/minimap_fw_build_site.rpak", MinimapPackage_FWBuildSite )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FD_HARVESTER, $"ui/minimap_obj_area.rpak", MinimapPackage_FDHarvester )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FD_LOADOUT_CHEST, $"ui/minimap_obj_area.rpak", MinimapPackage_FDLoadoutChest )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FD_BATTERY_EXCHANGE, $"ui/minimap_obj_area.rpak", MinimapPackage_FDBatteryExchange )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.BOOST_STORE, $"ui/minimap_obj_area.rpak", MinimapPackage_BoostStore )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FD_MORTAR_POSITION, $"ui/minimap_mortar_spectre.rpak", MinimapPackage_MortarPosition )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.ARC_TRAP, $"ui/minimap_obj_area.rpak", MinimapPackage_ArcTrap )
+
+ //RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FW_CAMP_A, $"ui/minimap_fw_camp.rpak", MinimapPackage_FWCampA )
+ //RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FW_CAMP_B, $"ui/minimap_fw_camp.rpak", MinimapPackage_FWCampB )
+ //RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.FW_CAMP_C, $"ui/minimap_fw_camp.rpak", MinimapPackage_FWCampC )
+
+ RegisterMinimapPackage( "info_hardpoint", eMinimapObject_info_hardpoint.HARDPOINT_A, $"ui/minimap_obj_area.rpak", MinimapPackage_HardpointA )
+ RegisterMinimapPackage( "info_hardpoint", eMinimapObject_info_hardpoint.HARDPOINT_B, $"ui/minimap_obj_area.rpak", MinimapPackage_HardpointB )
+ RegisterMinimapPackage( "info_hardpoint", eMinimapObject_info_hardpoint.HARDPOINT_C, $"ui/minimap_obj_area.rpak", MinimapPackage_HardpointC )
+
+ //if ( IsPlayingDemo() )
+ {
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.SPAWNZONE_IMC, $"ui/minimap_obj_area.rpak", MinimapPackage_SpawnZoneAreaInit )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.SPAWNZONE_MIL, $"ui/minimap_obj_area.rpak", MinimapPackage_SpawnZoneAreaInit )
+ }
+ //else
+ //{
+ // RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.SPAWNZONE_IMC, $"", MinimapPackage_SpawnZoneAreaInit )
+ // RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.SPAWNZONE_MIL, $"", MinimapPackage_SpawnZoneAreaInit )
+ //}
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.LTS_SITE_A, $"ui/minimap_object.rpak", MinimapPackage_LTSBombSiteA )
+ RegisterMinimapPackage( "prop_script", eMinimapObject_prop_script.LTS_SITE_B, $"ui/minimap_object.rpak", MinimapPackage_LTSBombSiteB )
+ /*
+ {
+ MinmapPackage atAreaPacakage
+ atAreaPacakage.minimapAsset = $"ui/minimap_obj_area.rpak"
+ atAreaPacakage.initFunction = MinimapPackage_ATAreaInit
+ MinmapPackage spawnZonePacakage
+ spawnZonePacakage.minimapAsset = $"ui/minimap_obj_area.rpak"
+ spawnZonePacakage.initFunction = MinimapPackage_SpawnZoneAreaInit
+ MinmapPackage fwBuildSitePackage
+ fwBuildSitePackage.minimapAsset = $"ui/minimap_fw_build_site.rpak"
+ fwBuildSitePackage.initFunction = MinimapPackage_FWBuildSite
+ MinmapPackage fwCampAPackage
+ fwCampAPackage.minimapAsset = $"ui/minimap_fw_camp.rpak"
+ fwCampAPackage.initFunction = MinimapPackage_FWCampA
+ MinmapPackage fwCampBPackage
+ fwCampBPackage.minimapAsset = $"ui/minimap_fw_camp.rpak"
+ fwCampBPackage.initFunction = MinimapPackage_FWCampB
+ MinmapPackage fwCampCPackage
+ fwCampCPackage.minimapAsset = $"ui/minimap_fw_camp.rpak"
+ fwCampCPackage.initFunction = MinimapPackage_FWCampC
+ minimapAssetMap["prop_script"] <-[blankPackage, atAreaPacakage, atAreaPacakage, atAreaPacakage, spawnZonePacakage, spawnZonePacakage,
+ fwCampAPackage, fwCampBPackage, fwCampCPackage,
+ fwBuildSitePackage, fwBuildSitePackage, fwBuildSitePackage ]
+ }
+*/
+
+ AddCreateCallback( "player", OnPlayerCreate )
+
+ float threatMaxDist = Minimap_GetFloatForKey( "threatMaxDist" )
+ float threatDistNear = Minimap_GetFloatForKey( "threatNearDist" )
+ float threatDistFar = Minimap_GetFloatForKey( "threatFarDist" )
+
+ if ( GameRules_GetGameMode() == FORT_WAR )
+ file.threatMaxDist = max( threatMaxDist, 2200 )
+ else
+ file.threatMaxDist = max( threatMaxDist, 1800 )
+
+ file.minimap_base = CreateCockpitRui( $"ui/minimap_base.rpak", MINIMAP_Z_BASE )
+
+ RuiSetFloat( file.minimap_base, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( file.minimap_base, "minimapSizeScale", file.minimapSizeScale )
+
+ file.minimap_wedges = CreateCockpitRui( $"ui/minimap_wedges.rpak", MINIMAP_Z_THREAT_WEDGES )
+
+ RuiSetFloat( file.minimap_wedges, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( file.minimap_wedges, "minimapSizeScale", file.minimapSizeScale )
+ RuiSetBool( file.minimap_wedges, "isVisible", file.minimapZoomScale == 1.0 )
+
+ file.minimap_you = CreateCockpitRui( $"ui/minimap_you.rpak", MINIMAP_Z_YOU )
+
+ RuiSetFloat( file.minimap_you, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( file.minimap_you, "minimapSizeScale", file.minimapSizeScale )
+
+ file.minimap_jammed_layer = null
+
+ file.minimap_indicator = CreateCockpitRui( $"ui/minimap_indicator.rpak", -1 )
+
+ RuiSetFloat( file.minimap_indicator, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( file.minimap_indicator, "minimapSizeScale", file.minimapSizeScale )
+
+ StatusEffect_RegisterEnabledCallback( eStatusEffect.minimap_jammed, MinimapJammed_Enabled )
+ StatusEffect_RegisterDisabledCallback( eStatusEffect.minimap_jammed, MinimapJammed_Disabled )
+ RegisterSignal( "LoopRadarJammerSounds" )
+}
+
+#if DEV
+void function DumpMinimapHandles()
+{
+ int index = 0
+ foreach ( handle, ent in file.minimapHandles )
+ {
+ printt( index, handle, ent )
+ ++index
+ }
+}
+#endif
+
+
+void function Minimap_DisableDraw()
+{
+ file.minimapEnabled = false
+
+ RuiSetDrawGroup( file.minimap_base, RUI_DRAW_NONE )
+ RuiSetDrawGroup( file.minimap_wedges, RUI_DRAW_NONE )
+ RuiSetDrawGroup( file.minimap_you, RUI_DRAW_NONE )
+ RuiSetDrawGroup( file.minimap_indicator, RUI_DRAW_NONE )
+
+ foreach ( var rui in file.minimapOtherRuis )
+ {
+ RuiSetDrawGroup( rui, RUI_DRAW_NONE )
+ }
+}
+
+void function Minimap_EnableDraw()
+{
+ file.minimapEnabled = true
+
+ RuiSetDrawGroup( file.minimap_base, RUI_DRAW_COCKPIT )
+ RuiSetDrawGroup( file.minimap_wedges, RUI_DRAW_COCKPIT )
+ RuiSetDrawGroup( file.minimap_you, RUI_DRAW_COCKPIT )
+ RuiSetDrawGroup( file.minimap_indicator, RUI_DRAW_COCKPIT )
+
+ foreach ( var rui in file.minimapOtherRuis )
+ {
+ RuiSetDrawGroup( rui, RUI_DRAW_COCKPIT )
+ }
+}
+
+
+void function ClientCodeCallback_MinimapEntitySpawned( entity ent )
+{
+ foreach ( callbackFunc in clGlobal.onMinimapEntSpawnedCallbacks )
+ {
+ callbackFunc( ent )
+ }
+
+ if ( ent == GetLocalViewPlayer() )
+ return
+
+ thread AddMinimapObject( ent )
+}
+
+
+asset function GetMinimapAsset( string className, int customState )
+{
+ if ( !(className in minimapAssetMap) )
+ return $""
+
+ if ( customState > minimapAssetMap[className].len() - 1 )
+ return $""
+
+ return minimapAssetMap[className][customState].minimapAsset
+}
+
+
+void function AddMinimapObject( entity ent ) //TODO: If we want radar jammer boost to hide friendly players we need to be able to get the rui handles back.
+{
+ Assert( IsValid( ent ) )
+
+ string className = expect string( ent.GetSignifierName() )
+ int customState = ent.Minimap_GetCustomState()
+
+ asset minimapAsset = GetMinimapAsset( className, customState )
+ if ( minimapAsset == $"" )
+ {
+ return
+ }
+
+ int zOrder = ent.Minimap_GetZOrder()
+ entity viewPlayer = GetLocalViewPlayer()
+
+ ent.SetDoDestroyCallback( true )
+
+ #if DEV
+ int eHandle = ent.Dev_GetEncodedEHandle()
+
+ {
+ array< int > eHandlesToRemove
+ foreach ( eHandleIter, entIter in file.minimapHandles )
+ {
+ if ( !IsValid( entIter ) )
+ {
+ eHandlesToRemove.append( eHandleIter )
+ }
+ }
+
+ foreach ( eHandleIter in eHandlesToRemove )
+ {
+ delete file.minimapHandles[eHandleIter]
+ }
+ }
+
+ if ( eHandle in file.minimapHandles )
+ {
+ // Should have been removed in above loop
+ Assert( IsValid( file.minimapHandles[eHandle] ) )
+
+ DumpMinimapHandles()
+ Assert( false, "Duplicate minimap entity added - " + ent )
+ }
+
+ file.minimapHandles[eHandle] <- ent
+ #endif
+
+ var rui = CreateCockpitRui( minimapAsset, MINIMAP_Z_BASE + zOrder )
+
+ //RuiTrackGameTime( rui, "lastFireTime", ent, RUI_TRACK_LAST_FIRED_TIME )
+
+ RuiTrackFloat3( rui, "playerPos", viewPlayer, RUI_TRACK_ABSORIGIN_FOLLOW )
+ RuiTrackFloat3( rui, "playerAngles", viewPlayer, RUI_TRACK_EYEANGLES_FOLLOW )
+
+ RuiTrackFloat3( rui, "objectPos", ent, RUI_TRACK_ABSORIGIN_FOLLOW )
+ RuiTrackFloat3( rui, "objectAngles", ent, RUI_TRACK_EYEANGLES_FOLLOW )
+ RuiTrackInt( rui, "objectFlags", ent, RUI_TRACK_MINIMAP_FLAGS )
+ RuiTrackInt( rui, "customState", ent, RUI_TRACK_MINIMAP_CUSTOM_STATE )
+ RuiSetFloat( rui, "displayDist", file.threatMaxDist )
+ RuiSetFloat( rui, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( rui, "minimapSizeScale", file.minimapSizeScale )
+
+ minimapAssetMap[className][customState].initFunction( ent, rui )
+
+ file.minimapOtherRuis.append( rui )
+
+ RuiSetDrawGroup( rui, file.minimapEnabled ? RUI_DRAW_COCKPIT : RUI_DRAW_NONE )
+ OnThreadEnd(
+ function() : ( rui )
+ {
+ file.minimapOtherRuis.removebyvalue( rui )
+ RuiDestroy( rui )
+ }
+ )
+
+ ent.EndSignal( "OnDestroy" )
+
+ if ( ent.IsPlayer() )
+ {
+ while ( IsValid( ent ) )
+ {
+ WaitSignal( ent, "SettingsChanged", "OnDeath" )
+ }
+ }
+ else
+ {
+ ent.WaitSignal( "OnDestroy" )
+ }
+}
+
+
+void function Minimap_PingCount( vector origin, float radius, float duration, vector color, int count, bool reverse = false )
+{
+ float delay = duration / count
+
+ while ( count )
+ {
+ count--
+
+ Minimap_Ping( origin, radius, delay + (delay * 0.25), color, reverse )
+ wait delay
+ }
+}
+
+
+void function Minimap_Ping( vector origin, float radius, float duration, vector color, bool reverse = false )
+{
+ entity viewPlayer = GetLocalViewPlayer()
+ int zOrder = viewPlayer.Minimap_GetZOrder()
+
+ if ( !file.minimapEnabled )
+ return
+
+ var rui = CreateCockpitRui( $"ui/minimap_ping.rpak", MINIMAP_Z_BASE + zOrder )
+
+ RuiTrackFloat3( rui, "playerPos", viewPlayer, RUI_TRACK_ABSORIGIN_FOLLOW )
+ RuiTrackFloat3( rui, "playerAngles", viewPlayer, RUI_TRACK_EYEANGLES_FOLLOW )
+
+ RuiSetFloat3( rui, "objColor", color )
+ RuiSetFloat3( rui, "objectPos", origin )
+ RuiSetFloat3( rui, "objectAngles", <0,0,0> )
+
+ RuiSetFloat( rui, "objectRadius", radius / ( file.threatMaxDist * file.minimapZoomScale ) )
+
+ RuiSetFloat( rui, "displayDist", file.threatMaxDist )
+ RuiSetFloat( rui, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( rui, "minimapSizeScale", file.minimapSizeScale )
+
+ RuiSetGameTime( rui, "startTime", Time() )
+ RuiSetGameTime( rui, "endTime", Time() + duration )
+
+ RuiSetBool( rui, "reverse", reverse )
+}
+
+
+
+var function Minimap_AddLayer( asset layerImage, bool isFriendly )
+{
+ entity player = GetLocalViewPlayer()
+
+ var rui = CreateCockpitRui( $"ui/minimap_layer.rpak", MINIMAP_Z_LAYER )
+
+ RuiTrackFloat3( rui, "playerPos", player, RUI_TRACK_ABSORIGIN_FOLLOW )
+ RuiTrackFloat3( rui, "playerAngles", player, RUI_TRACK_EYEANGLES_FOLLOW )
+
+ asset mapImage = Minimap_GetAssetForKey( "minimap" )
+ float mapCornerX = Minimap_GetFloatForKey( "pos_x" )
+ float mapCornerY = Minimap_GetFloatForKey( "pos_y" )
+ float displayDist = Minimap_GetFloatForKey( "displayDist" )
+ float threatDistNear = Minimap_GetFloatForKey( "threatNearDist" )
+ float threatDistFar = Minimap_GetFloatForKey( "threatFarDist" )
+
+ float mapScale = Minimap_GetFloatForKey( "scale" )
+
+ RuiSetImage( rui, "layerImage", layerImage )
+ RuiSetFloat3( rui, "mapCorner", <mapCornerX, mapCornerY, 0> )
+ RuiSetFloat( rui, "displayDist", file.threatMaxDist )
+ RuiSetFloat( rui, "mapScale", mapScale )
+ RuiSetFloat( rui, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( rui, "minimapSizeScale", file.minimapSizeScale )
+
+ RuiSetBool( rui, "isFriendly", isFriendly )
+
+ return rui
+}
+
+var function Minimap_AddCustomLayer( asset ruiAsset, int sortKey = MINIMAP_Z_LAYER )
+{
+ entity player = GetLocalViewPlayer()
+
+ var rui = CreateCockpitRui( ruiAsset, sortKey )
+
+ RuiTrackFloat3( rui, "playerPos", player, RUI_TRACK_ABSORIGIN_FOLLOW )
+ RuiTrackFloat3( rui, "playerAngles", player, RUI_TRACK_EYEANGLES_FOLLOW )
+
+ asset mapImage = Minimap_GetAssetForKey( "minimap" )
+ float mapCornerX = Minimap_GetFloatForKey( "pos_x" )
+ float mapCornerY = Minimap_GetFloatForKey( "pos_y" )
+ float displayDist = Minimap_GetFloatForKey( "displayDist" )
+ float threatDistNear = Minimap_GetFloatForKey( "threatNearDist" )
+ float threatDistFar = Minimap_GetFloatForKey( "threatFarDist" )
+
+ float mapScale = Minimap_GetFloatForKey( "scale" )
+
+ RuiSetFloat3( rui, "mapCorner", <mapCornerX, mapCornerY, 0> )
+ RuiSetFloat( rui, "displayDist", file.threatMaxDist )
+ RuiSetFloat( rui, "mapScale", mapScale )
+ RuiSetFloat( rui, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( rui, "minimapSizeScale", file.minimapSizeScale )
+
+ return rui
+}
+
+
+void function OnPlayerCreate( entity player )
+{
+ if ( player != GetLocalViewPlayer() )
+ return
+
+ RuiTrackFloat3( file.minimap_base, "playerPos", player, RUI_TRACK_ABSORIGIN_FOLLOW )
+ RuiTrackFloat3( file.minimap_base, "playerAngles", player, RUI_TRACK_EYEANGLES_FOLLOW )
+
+ RuiTrackInt( file.minimap_indicator, "indicatorId", player, RUI_TRACK_SCRIPT_NETWORK_VAR_INT, GetNetworkedVariableIndex( "indicatorId" ) )
+
+ asset mapImage = Minimap_GetAssetForKey( "minimap" )
+ float mapCornerX = Minimap_GetFloatForKey( "pos_x" )
+ float mapCornerY = Minimap_GetFloatForKey( "pos_y" )
+ float displayDist = Minimap_GetFloatForKey( "displayDist" )
+ float threatDistNear = Minimap_GetFloatForKey( "threatNearDist" )
+ float threatDistFar = Minimap_GetFloatForKey( "threatFarDist" )
+
+ float mapScale = Minimap_GetFloatForKey( "scale" )
+
+ RuiSetImage( file.minimap_base, "mapImage", mapImage )
+ RuiSetFloat3( file.minimap_base, "mapCorner", <mapCornerX, mapCornerY, 0> )
+ RuiSetFloat( file.minimap_base, "displayDist", file.threatMaxDist )
+ RuiSetFloat( file.minimap_base, "mapScale", mapScale )
+
+ RuiTrackFloat3( file.minimap_wedges, "playerPos", player, RUI_TRACK_ABSORIGIN_FOLLOW )
+ RuiTrackFloat3( file.minimap_wedges, "playerAngles", player, RUI_TRACK_EYEANGLES_FOLLOW )
+ RuiSetFloat3( file.minimap_wedges, "distances", <threatDistNear / file.threatMaxDist, 1.0 - (threatDistFar / file.threatMaxDist), 1.0> )
+ RuiSetBool( file.minimap_wedges, "isVisible", file.minimapZoomScale == 1.0 )
+
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeCenter", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_CENTER )
+
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeMid0", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_NEAR_N )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeMid1", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_NEAR_NE )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeMid2", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_NEAR_E )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeMid3", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_NEAR_SE )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeMid4", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_NEAR_S )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeMid5", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_NEAR_SW )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeMid6", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_NEAR_W )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeMid7", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_NEAR_NW )
+
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeOuter0", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_FAR_N )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeOuter1", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_FAR_NE )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeOuter2", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_FAR_E )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeOuter3", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_FAR_SE )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeOuter4", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_FAR_S )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeOuter5", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_FAR_SW )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeOuter6", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_FAR_W )
+ RuiTrackGameTime( file.minimap_wedges, "lastFireTimeOuter7", player, RUI_TRACK_MINIMAP_THREAT_SECTOR, MOTS_FAR_NW )
+
+
+ RuiSetFloat( file.minimap_wedges, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( file.minimap_wedges, "minimapSizeScale", file.minimapSizeScale )
+
+ RuiSetFloat( file.minimap_base, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( file.minimap_base, "minimapSizeScale", file.minimapSizeScale )
+
+ RuiTrackInt( file.minimap_you, "objectFlags", player, RUI_TRACK_MINIMAP_FLAGS )
+ RuiTrackInt( file.minimap_you, "customState", player, RUI_TRACK_MINIMAP_CUSTOM_STATE )
+
+}
+
+
+void function MinimapPackage_DummyInit( entity ent, var rui )
+{
+
+}
+
+void function MinimapPackage_PlayerInit( entity ent, var rui )
+{
+ RuiTrackGameTime( rui, "lastFireTime", ent, RUI_TRACK_LAST_FIRED_TIME )
+ if ( !IsFFAGame() ) //JFS: Too much work to get FFA to work correctly with Minimap logic, so disabling it for FFA
+ {
+ RuiTrackFloat( rui, "sonarDetectedFrac", ent, RUI_TRACK_STATUS_EFFECT_SEVERITY, eStatusEffect.sonar_detected )
+ RuiTrackFloat( rui, "maphackDetectedFrac", ent, RUI_TRACK_STATUS_EFFECT_SEVERITY, eStatusEffect.maphack_detected )
+ }
+}
+
+void function MinimapPackage_NPCTitanInit( entity ent, var rui )
+{
+ entity player = GetLocalClientPlayer()
+
+ RuiSetBool( rui, "useTeamColor", false )
+
+ RuiTrackGameTime( rui, "lastFireTime", ent, RUI_TRACK_LAST_FIRED_TIME )
+ if ( !IsFFAGame() ) //JFS: Too much work to get FFA to work correctly with Minimap logic, so disabling it for FFA
+ RuiTrackFloat( rui, "sonarDetectedFrac", ent, RUI_TRACK_STATUS_EFFECT_SEVERITY, eStatusEffect.sonar_detected )
+}
+
+void function MinimapPackage_NPCHumanSizedInit( entity ent, var rui )
+{
+ entity player = GetLocalClientPlayer()
+
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/minimap/compass_icon_small_dot" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"" )
+
+ //if ( ent == GetLocalClientPlayer().GetPetTitan() )
+ //{
+ // RuiSetBool( rui, "useTeamColor", false )
+ // RuiSetFloat3( rui, "iconColor", TEAM_COLOR_YOU / 255.0 )
+ //}
+ RuiTrackGameTime( rui, "lastFireTime", ent, RUI_TRACK_LAST_FIRED_TIME )
+ //if ( !IsFFAGame() ) //JFS: Too much work to get FFA to work correctly with Minimap logic, so disabling it for FFA
+ // RuiTrackFloat( rui, "sonarDetectedFrac", ent, RUI_TRACK_STATUS_EFFECT_SEVERITY, eStatusEffect.sonar_detected )
+}
+
+void function MinimapPackage_NPCDropShipInit( entity ent, var rui )
+{
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/scoreboard/status_evac" )
+}
+
+void function MinimapPackage_NPCSentryTurretInit( entity ent, var rui )
+{
+ RuiSetImage( rui, "defaultIcon", $"" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"" )
+}
+
+void function MinimapPackage_BossTitanInit( entity ent, var rui )
+{
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/gametype_icons/bounty_hunt/bh_titan" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"rui/hud/gametype_icons/bounty_hunt/bh_titan" )
+ RuiSetBool( rui, "useTeamColor", false )
+}
+
+void function MinimapPackage_BatteryInit( entity ent, var rui )
+{
+ entity player = GetLocalViewPlayer()
+ RuiTrackInt( rui, "batteryCount", player, RUI_TRACK_SCRIPT_NETWORK_VAR_INT, GetNetworkedVariableIndex( "batteryCount" ) )
+ RuiSetBool( rui, "useTeamColor", false )
+ RuiTrackFloat( rui, "batteryCarried", ent, RUI_TRACK_STATUS_EFFECT_SEVERITY, eStatusEffect.battery_carried )
+}
+
+void function MinimapPackage_ATAreaInit( entity ent, var rui )
+{
+ RuiTrackFloat( rui, "objectRadius", ent, RUI_TRACK_MINIMAP_SCALE )
+}
+
+void function MinimapPackage_ATBank( entity ent, var rui )
+{
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/gametype_icons/bounty_hunt/bh_bank_icon" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"rui/hud/gametype_icons/bounty_hunt/bh_bank_icon" )
+ RuiSetBool( rui, "useTeamColor", false )
+}
+
+void function MinimapPackage_SpawnZoneAreaInit( entity ent, var rui )
+{
+ RuiTrackFloat( rui, "objectRadius", ent, RUI_TRACK_MINIMAP_SCALE )
+ if ( !IsPlayingDemo() )
+ {
+ RuiSetImage( rui, "centerImage", $"" ) // hide diamond
+ RuiSetImage( rui, "clampedImage", $"rui/hud/gametype_icons/obj_foreground_diamond" )
+ }
+}
+
+void function MinimapPackage_FWBuildSite( entity ent, var rui )
+{
+ entity player = GetLocalViewPlayer()
+ RuiTrackInt( rui, "batteryCount", player, RUI_TRACK_SCRIPT_NETWORK_VAR_INT, GetNetworkedVariableIndex( "batteryCount" ) )
+ //RuiTrackFloat( rui, "objectRadius", ent, RUI_TRACK_MINIMAP_SCALE )
+}
+
+void function MinimapPackage_HardpointA( entity ent, var rui )
+{
+ RuiSetFloat( rui, "objectRadius", 0.001 )
+}
+
+void function MinimapPackage_HardpointB( entity ent, var rui )
+{
+ RuiSetFloat( rui, "objectRadius", 0.001 )
+}
+
+void function MinimapPackage_HardpointC( entity ent, var rui )
+{
+ RuiSetFloat( rui, "objectRadius", 0.001 )
+}
+
+void function MinimapPackage_FDHarvester( entity ent, var rui )
+{
+ RuiSetImage( rui, "centerImage", $"rui/hud/gametype_icons/fd/coop_harvester" )
+ RuiSetImage( rui, "clampedImage", $"rui/hud/gametype_icons/fd/coop_harvester" )
+ RuiSetFloat( rui, "objectRadius", 0.01 )
+ RuiSetBool( rui, "useOverrideColor", true )
+ RuiSetColorAlpha( rui, "overrideColor", <1.0,1.0,1.0>, 1.0 )
+}
+
+void function MinimapPackage_FDLoadoutChest( entity ent, var rui )
+{
+ RuiSetImage( rui, "centerImage", $"rui/hud/gametype_icons/fd/coop_ammo_locker_icon" )
+ RuiSetImage( rui, "clampedImage", $"rui/hud/gametype_icons/fd/coop_ammo_locker_icon" )
+ RuiSetFloat( rui, "objectRadius", 0.01 )
+ RuiSetBool( rui, "useOverrideColor", true )
+ RuiSetColorAlpha( rui, "overrideColor", <1.0,1.0,1.0>, 1.0 )
+}
+
+void function MinimapPackage_FDBatteryExchange( entity ent, var rui )
+{
+ RuiSetImage( rui, "centerImage", $"rui/hud/gametype_icons/bounty_hunt/bh_bank_icon" )
+ RuiSetImage( rui, "clampedImage", $"rui/hud/gametype_icons/bounty_hunt/bh_bank_icon" )
+ RuiSetFloat( rui, "objectRadius", 0.01 )
+ RuiSetBool( rui, "useOverrideColor", true )
+ RuiSetColorAlpha( rui, "overrideColor", <1.0,1.0,1.0>, 1.0 )
+}
+
+void function MinimapPackage_BoostStore( entity ent, var rui )
+{
+ RuiSetImage( rui, "centerImage", $"rui/hud/gametype_icons/bounty_hunt/bh_bonus_icon" )
+ RuiSetImage( rui, "clampedImage", $"rui/hud/gametype_icons/bounty_hunt/bh_bonus_icon" )
+ RuiSetFloat( rui, "objectRadius", 0.01 )
+ RuiSetBool( rui, "useOverrideColor", true )
+ RuiSetColorAlpha( rui, "overrideColor", <1.0,1.0,1.0>, 1.0 )
+}
+
+void function MinimapPackage_MortarPosition( entity ent, var rui )
+{
+ RuiSetImage( rui, "bgImage", $"rui/hud/gametype_icons/fd/fd_icon_spectre_mortar_bg" )
+ RuiSetImage( rui, "centerImage", $"rui/hud/gametype_icons/fd/fd_icon_spectre_mortar" )
+ RuiSetImage( rui, "clampedImage", $"rui/hud/gametype_icons/fd/fd_icon_spectre_mortar" )
+ RuiTrackFloat( rui, "arcPercent", ent, RUI_TRACK_SHIELD_FRACTION )
+}
+
+void function MinimapPackage_ArcTrap( entity ent, var rui )
+{
+ RuiSetImage( rui, "centerImage", $"rui/hud/minimap/compass_icon_arc_trap" )
+ RuiSetImage( rui, "clampedImage", $"" )
+ RuiTrackFloat( rui, "objectRadius", ent, RUI_TRACK_MINIMAP_SCALE )
+}
+
+void function MinimapPackage_FWCampA( entity ent, var rui )
+{
+ RuiTrackInt( rui, "alertLevel", null, RUI_TRACK_SCRIPT_NETWORK_VAR_GLOBAL_INT, GetNetworkedVariableIndex( "fwCampAlertA" ) )
+ RuiTrackFloat( rui, "objectRadius", ent, RUI_TRACK_MINIMAP_SCALE )
+}
+
+void function MinimapPackage_FWCampB( entity ent, var rui )
+{
+ RuiTrackInt( rui, "alertLevel", null, RUI_TRACK_SCRIPT_NETWORK_VAR_GLOBAL_INT, GetNetworkedVariableIndex( "fwCampAlertB" ) )
+ RuiTrackFloat( rui, "objectRadius", ent, RUI_TRACK_MINIMAP_SCALE )
+}
+
+void function MinimapPackage_FWCampC( entity ent, var rui )
+{
+ RuiTrackInt( rui, "alertLevel", null, RUI_TRACK_SCRIPT_NETWORK_VAR_GLOBAL_INT, GetNetworkedVariableIndex( "fwCampAlertC" ) )
+ RuiTrackFloat( rui, "objectRadius", ent, RUI_TRACK_MINIMAP_SCALE )
+}
+
+void function MinimapPackage_LTSBombSiteA( entity ent, var rui )
+{
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/gametype_icons/last_titan_standing/bomb_site_a_attacking" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"rui/hud/gametype_icons/last_titan_standing/bomb_site_a_attacking" )
+}
+
+void function MinimapPackage_LTSBombSiteB( entity ent, var rui )
+{
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/gametype_icons/last_titan_standing/bomb_site_b_attacking" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"rui/hud/gametype_icons/last_titan_standing/bomb_site_b_attacking" )
+}
+
+void function MinimapPackage_LTSBomb( entity ent, var rui )
+{
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/gametype_icons/last_titan_standing/bomb_neutral" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"rui/hud/gametype_icons/last_titan_standing/bomb_neutral" )
+ RuiSetBool( rui, "useTeamColor", false )
+}
+
+void function MinimapPackage_FlagInit( entity ent, var rui )
+{
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/gametype_icons/ctf/ctf_flag_neutral" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"rui/hud/gametype_icons/ctf/ctf_flag_neutral" )
+ RuiSetBool( rui, "useTeamColor", true )
+}
+
+void function MinimapPackage_PowerUp( entity ent, var rui )
+{
+ //Battery spawners are the only power ups in use atm. This would need to be updated if we use them differently.
+ RuiSetImage( rui, "defaultIcon", $"rui/hud/battery/battery_capture_friendly" )
+ RuiSetImage( rui, "clampedDefaultIcon", $"rui/hud/battery/battery_capture_friendly" )
+ RuiSetBool( rui, "useTeamColor", false )
+}
+
+
+void function MinimapJammed_Enabled( entity ent, int statusEffect, bool actuallyChanged )
+{
+ if ( !actuallyChanged )
+ return
+
+ if ( ent != GetLocalClientPlayer() )
+ return
+
+ thread LoopRadarJammerSounds( ent )
+ thread FadeOutStaticSoundAfterDelay( ent, BURN_METER_RADAR_JAMMER_PULSE_DURATION - BURN_METER_RADAR_JAMMER_EASE_OFF_TIME )
+
+ if ( file.minimap_jammed_layer != null )
+ RuiDestroy( file.minimap_jammed_layer )
+
+ file.minimap_jammed_layer = Minimap_AddCustomLayer( $"ui/minimap_jammer_layer.rpak", MINIMAP_Z_YOU + 1 )
+ if ( actuallyChanged )
+ RuiSetGameTime( file.minimap_jammed_layer, "startTime", Time() )
+
+ RuiSetFloat( file.minimap_jammed_layer, "minimapZoomScale", file.minimapZoomScale )
+ RuiSetFloat( file.minimap_jammed_layer, "minimapSizeScale", file.minimapSizeScale )
+ RuiTrackFloat( file.minimap_jammed_layer, "scriptAlphaVar", ent, RUI_TRACK_STATUS_EFFECT_SEVERITY, statusEffect )
+
+ RuiTrackFloat( file.minimap_wedges, "scriptInverseAlphaVar", ent, RUI_TRACK_STATUS_EFFECT_SEVERITY, statusEffect )
+
+}
+
+void function MinimapJammed_Disabled( entity ent, int statusEffect, bool actuallyChanged )
+{
+ if ( !actuallyChanged )
+ return
+
+ if ( ent != GetLocalClientPlayer() )
+ return
+
+ clGlobal.levelEnt.Signal( "LoopRadarJammerSounds" )
+
+ if ( file.minimap_jammed_layer != null )
+ {
+ RuiDestroy( file.minimap_jammed_layer )
+ file.minimap_jammed_layer = null
+ }
+}
+
+void function LoopRadarJammerSounds( entity ent )
+{
+ clGlobal.levelEnt.Signal( "LoopRadarJammerSounds" )
+ clGlobal.levelEnt.EndSignal( "LoopRadarJammerSounds" )
+ ent.EndSignal( "OnDeath" )
+
+ OnThreadEnd(
+ function() : ( ent )
+ {
+ StopSoundOnEntity( ent, "HUD_Boost_Card_Radar_Jammer_RedTextBeep_1P" )
+ }
+ )
+
+ float currentTime = Time()
+ float fractionalComponent = currentTime - floor( currentTime )
+ float timeToWait
+ if ( fractionalComponent <= 0.5 )
+ timeToWait = 0.5 - fractionalComponent
+ else
+ timeToWait = 1.5 - fractionalComponent
+
+ wait ( timeToWait ) //Red text flashes in with regards to game time, so we need to wait till the appropriate time (0.5) to play the next sound
+
+ while( true )
+ {
+ if ( IsValid( ent ) )
+ EmitSoundOnEntity( ent, "HUD_Boost_Card_Radar_Jammer_RedTextBeep_1P" )
+
+ wait 1.0 //This is dependent on the rui logic, and will need to be changed if the rui logic changes
+ }
+}
+
+void function FadeOutStaticSoundAfterDelay( entity ent, float delay )
+{
+ EmitSoundOnEntity( ent, "HUD_Boost_Card_Radar_Jammer_Signal_Static_1P" )
+
+ ent.EndSignal( "OnDeath" )
+
+ OnThreadEnd(
+ function() : ( ent )
+ {
+ clGlobal.levelEnt.Signal( "LoopRadarJammerSounds" ) //stop red text beeping sounds
+ if ( IsValid( ent ) )
+ StopSoundOnEntity( ent, "HUD_Boost_Card_Radar_Jammer_Signal_Static_1P" )
+
+ }
+ )
+ wait delay
+}
+void function Minimap_SetZoomScale( float scale )
+{
+ file.minimapZoomScale = scale
+ if(file.minimap_you != null)
+ RuiSetFloat( file.minimap_you, "minimapZoomScale", file.minimapZoomScale )
+ if(file.minimap_indicator != null)
+ RuiSetFloat( file.minimap_indicator, "minimapZoomScale", file.minimapZoomScale )
+ if(file.minimap_base != null)
+ RuiSetFloat( file.minimap_base, "minimapZoomScale", file.minimapZoomScale )
+
+ if ( file.minimap_wedges != null )
+ {
+ RuiSetBool( file.minimap_wedges, "isVisible", file.minimapZoomScale == 1.0 )
+ RuiSetFloat( file.minimap_wedges, "minimapZoomScale", file.minimapZoomScale )
+ }
+ foreach ( var rui in file.minimapOtherRuis )
+ {
+ RuiSetFloat( rui, "minimapZoomScale", file.minimapZoomScale )
+ }
+}
+
+void function Minimap_SetSizeScale( float scale )
+{
+ file.minimapSizeScale = scale
+ if(file.minimap_base != null)
+ RuiSetFloat( file.minimap_base, "minimapSizeScale", file.minimapSizeScale )
+ if(file.minimap_indicator != null)
+ RuiSetFloat( file.minimap_indicator, "minimapSizeScale", file.minimapSizeScale )
+ if(file.minimap_you != null)
+ RuiSetFloat( file.minimap_you, "minimapSizeScale", file.minimapSizeScale )
+ if(file.minimap_wedges != null)
+ RuiSetFloat( file.minimap_wedges, "minimapSizeScale", file.minimapSizeScale )
+ foreach ( var rui in file.minimapOtherRuis )
+ {
+ RuiSetFloat( rui, "minimapSizeScale", file.minimapSizeScale )
+ }
+
+}
+float function Minimap_GetZoomScale()
+{
+ return file.minimapZoomScale
+}
+float function Minimap_GetSizeScale()
+{
+ return file.minimapSizeScale
+}
+bool function Minimap_IsUsingLargeMinimap()
+{
+ return file.minimapSizeScale > 1.0
+}
+
+void function ServerCallback_PingMinimap( float originX, float originY, float originZ, float radius, float duration, float colorR, float colorG, float colorB, int count, bool reverse )
+{
+ if ( count > 1 )
+ thread Minimap_PingCount( <originX, originY, originZ>, radius, duration, <colorR, colorG, colorB>, count, reverse )
+ else
+ Minimap_Ping( <originX, originY, originZ>, radius, duration, <colorR, colorG, colorB>, reverse )
+}
diff --git a/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut b/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut
new file mode 100644
index 00000000..8261b3fd
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut
@@ -0,0 +1,1676 @@
+untyped
+
+global function ClTitanCockpit_Init
+
+global function ServerCallback_TitanEMP
+global function ServerCallback_TitanCockpitBoot
+global function TitanCockpit_DamageFeedback
+global function TitanCockpit_AddPlayer
+global function RegisterTitanBindings
+global function GetTitanBindings
+global function DeregisterTitanBindings
+global function ServerCallback_TitanEmbark
+global function ServerCallback_TitanDisembark
+global function PlayerPressed_EjectEnable // so can be called directly for debugging
+global function PlayerPressed_Eject // so can be called directly for debugging
+global function TitanCockpit_IsBooting
+global function ServerCallback_TitanCockpitEMP
+global function TitanCockpit_EMPFadeScale
+global function TitanCockpit_DoEMP
+global function TitanEMP_Internal
+global function ServerCallback_EjectConfirmed
+global function LinkCoreHint
+
+global function AddTitanCockpitManagedRUI
+global function UpdateTitanCockpitVisibility
+global function TitanCockpitDestroyRui
+global function TitanCockpitDoomedThink
+global function PlayerEjects
+global function IsDisplayingEjectInterface
+global function FlashCockpitLight
+global function PlayCockpitSparkFX
+
+global function FlashCockpitHealth
+
+global function UpdateEjectHud_SetButtonPressTime
+global function UpdateEjectHud_SetButtonPressCount
+
+global function SetUnlimitedDash
+
+// Added by northstar
+global function AddCommonEjectMessage
+global function AddRareEjectMessage
+
+#if MP
+global function NetworkedVarChangedCallback_UpdateVanguardRUICoreStatus
+global function DisplayFrontierRank
+#endif
+struct TitanCockpitManagedRUI
+{
+ bool exists = false
+ var functionref() create
+ void functionref() destroy
+ bool functionref() shouldCreate
+ int drawGroup = RUI_DRAW_COCKPIT
+}
+
+const TITAN_ALARM_SOUND = "titan_alarm"
+const TITAN_NUCLEAR_DEATH_ALARM = "titan_nuclear_death_alarm"
+const TITAN_EJECT_BOOST = "titan_eject_boost"
+const TITAN_EJECT_ASCENT = "player_eject_windrush"
+const TITAN_EJECT_APEX = "player_eject_apex_wind"
+const TITAN_EJECT_DESCENT = "player_fallingdescent_windrush"
+
+const EJECT_MIN_VELOCITY = 200.0
+const EJECT_MAX_VELOCITY = 1000.0
+
+struct
+{
+ var coreHintRui
+ var cockpitRui
+ var cockpitLowerRui
+ var cockpitAdditionalRui
+ array<TitanCockpitManagedRUI> titanCockpitManagedRUIs
+
+ string lastPilotSettings
+
+ bool isFirstBoot = true
+ var scorchHotstreakRui
+ // Added by northstar
+ array<string> moddedRareEjectMessages
+ array<string> moddedCommonEjectMessages
+} file
+
+function ClTitanCockpit_Init()
+{
+ if ( reloadingScripts )
+ return
+
+ RegisterSignal( "DisembarkCheck" )
+ RegisterSignal( "Rumble_Forward_End" )
+ RegisterSignal( "Rumble_Back_End" )
+ RegisterSignal( "Rumble_Left_End" )
+ RegisterSignal( "Rumble_Right_End" )
+ RegisterSignal( "EMP" )
+ RegisterSignal( "Ejecting" )
+ RegisterSignal( "TitanEMP_Internal" )
+ RegisterSignal( "TitanUnDoomed" )
+ RegisterSignal( "MonitorPlayerEjectAnimBeingStuck" )
+ RegisterSignal( "DisplayFrontierRank" )
+
+ PrecacheParticleSystem( $"xo_cockpit_spark_01" )
+
+ if ( !IsModelViewer() && !IsLobby() )
+ {
+ AddCreateCallback( "titan_cockpit", TitanCockpitInit )
+ }
+
+ if ( !reloadingScripts )
+ {
+ level.cockpitGeoRef <- null
+ }
+
+ AddPlayerFunc( TitanCockpit_AddPlayer )
+
+ AddCinematicEventFlagChangedCallback( CE_FLAG_TITAN_3P_CAM, CinematicEventFlagChanged )
+ AddCinematicEventFlagChangedCallback( CE_FLAG_INTRO, CinematicEventFlagChanged )
+
+ AddCallback_PlayerClassChanged( UpdateLastPlayerSettings )
+
+ AddTitanCockpitManagedRUI( Scorch_CreateHotstreakBar, Scorch_DestroyHotstreakBar, Scorch_ShouldCreateHotstreakBar, RUI_DRAW_COCKPIT ) //RUI_DRAW_HUD
+}
+
+void function UpdateLastPlayerSettings( entity player )
+{
+ if ( IsPilot( player ) )
+ file.lastPilotSettings = player.GetPlayerSettings()
+}
+
+TitanBindings function GetTitanBindings()
+{
+ TitanBindings Table
+ Table.PlayerPressed_Eject = PlayerPressed_Eject
+ Table.PlayerPressed_EjectEnable = PlayerPressed_EjectEnable
+ return Table
+}
+
+bool function RegisterTitanBindings( entity player, TitanBindings bind )
+{
+ if ( player != GetLocalViewPlayer() )
+ return false
+
+ if ( player != GetLocalClientPlayer() )
+ return false
+
+ RegisterConCommandTriggeredCallback( "+useAndReload", bind.PlayerPressed_Eject )
+ RegisterConCommandTriggeredCallback( "+use", bind.PlayerPressed_Eject )
+
+ RegisterConCommandTriggeredCallback( "+scriptCommand1", bind.PlayerPressed_EjectEnable )
+
+ return true
+}
+
+void function DeregisterTitanBindings( TitanBindings bind )
+{
+ DeregisterConCommandTriggeredCallback( "+useAndReload", bind.PlayerPressed_Eject )
+ DeregisterConCommandTriggeredCallback( "+use", bind.PlayerPressed_Eject )
+
+ if ( GetMapName() != "" )
+ {
+ DeregisterConCommandTriggeredCallback( "+scriptCommand1", bind.PlayerPressed_EjectEnable )
+ }
+}
+
+
+void function TitanCockpit_AddPlayer( entity player )
+{
+ if ( IsModelViewer() )
+ return
+
+ player.s.lastCockpitDamageSoundTime <- 0
+ player.s.inTitanCockpit <- false
+ player.s.lastDialogTime <- 0
+ player.s.titanCockpitDialogActive <- false
+ player.s.titanCockpitDialogAliasList <- []
+
+ player.s.hitVectors <- []
+}
+
+void function TitanCockpitInit( entity cockpit )
+{
+ entity player = GetLocalViewPlayer()
+ Assert( player.GetCockpit() == cockpit )
+
+ cockpit.s.ejectStartTime <- 0 // placed here to fix http://bugzilla.respawn.net/show_bug.cgi?id=156786
+
+ if ( !IsAlive( player ) )
+ return
+
+ if ( !IsTitanCockpitModelName( cockpit.GetModelName() ) || IsWatchingThirdPersonKillReplay() )
+ {
+ player.s.inTitanCockpit = false
+ return
+ }
+
+ if ( !player.s.inTitanCockpit )
+ TitanEmbarkDSP( 0.5 )
+
+ player.s.inTitanCockpit = true
+
+ // code aint callin this currently
+ CodeCallback_PlayerInTitanCockpit( GetLocalViewPlayer(), GetLocalViewPlayer() )
+
+ // move this
+ array<entity> targets = GetClientEntArrayBySignifier( "info_target" )
+ foreach ( target in targets )
+ {
+ if ( target.GetTargetName() != "cockpit_geo_ref" )
+ continue
+
+ level.cockpitGeoRef = target
+ }
+
+ entity cockpitParent = expect entity( level.cockpitGeoRef )
+
+ if ( !IsValid( cockpitParent ) )
+ cockpitParent = GetLocalViewPlayer()
+
+ cockpit.s.empInfo <- {}
+ cockpit.s.empInfo["xOffset"] <- 0
+ cockpit.s.empInfo["yOffset"] <- 0
+ cockpit.s.empInfo["startTime"] <- 0
+ cockpit.s.empInfo["duration"] <- 0
+ cockpit.s.empInfo["sub_count"] <- 0
+ cockpit.s.empInfo["sub_start"] <- 0
+ cockpit.s.empInfo["sub_duration"] <- 0
+ cockpit.s.empInfo["sub_pause"] <- 0
+ cockpit.s.empInfo["sub_alpha"] <- 0
+
+ cockpit.s.cockpitType <- 1
+ cockpit.s.FOV <- 70
+
+ cockpit.e.body = CreateCockpitBody( cockpit, player, cockpitParent )
+
+ thread TitanCockpitAnimThink( cockpit, cockpit.e.body )
+
+ if ( player.IsTitan() && IsAlive( player ) ) // pilot with titan cockpit gets thrown from titan
+ thread TitanCockpitDoomedThink( cockpit, player )
+
+ SetCockpitLightingEnabled( 0, true )
+ ShowRUIHUD( cockpit )
+}
+
+//bind r "script_client ReloadScripts();script_client GetLocalViewPlayer().GetCockpit().Destroy()"
+void function ShowRUIHUD( entity cockpit )
+{
+ // update topo positions
+ int cameraAttachId = cockpit.LookupAttachment( "CAMERA" )
+ vector cameraOrigin = cockpit.GetAttachmentOrigin( cameraAttachId )
+
+ int lowerScreenAttachId = cockpit.LookupAttachment( "COCKPIT_HUD_BOTTOM" )
+ vector lowerScreenOrigin = cockpit.GetAttachmentOrigin( lowerScreenAttachId )
+ vector lowerScreenAngles = cockpit.GetAttachmentAngles( lowerScreenAttachId )
+
+ int instrument1AttachId = cockpit.LookupAttachment( "COCKPIT_OBJ_1" )
+ vector instrument1Origin = cockpit.GetAttachmentOrigin( instrument1AttachId )
+ vector instrument1Angles = cockpit.GetAttachmentAngles( instrument1AttachId )
+
+ lowerScreenOrigin = lowerScreenOrigin - cameraOrigin
+ vector lowerScreenPosition = <lowerScreenOrigin.x, lowerScreenOrigin.y + TITAN_COCKPIT_LOWER_RUI_SCREEN_SQUARE_SIZE * .5, lowerScreenOrigin.z + (TITAN_COCKPIT_LOWER_RUI_SCREEN_SQUARE_SIZE) * .5>
+
+ instrument1Origin = instrument1Origin - cameraOrigin
+ vector instrument1Position = <instrument1Origin.x, instrument1Origin.y, instrument1Origin.z>
+ vector instrument1RightVector = AnglesToRight( instrument1Angles ) * -1
+ vector instrument1DownVector = AnglesToUp( instrument1Angles ) * -1
+
+ RuiTopology_UpdatePos( clGlobal.topoTitanCockpitLowerHud, lowerScreenPosition, <0, -TITAN_COCKPIT_LOWER_RUI_SCREEN_SQUARE_SIZE, 0>, <0, 0, -(TITAN_COCKPIT_LOWER_RUI_SCREEN_SQUARE_SIZE * TITAN_COCKPIT_LOWER_RUI_SCREEN_HEIGHT_SCALE)> )
+ RuiTopology_UpdatePos( clGlobal.topoTitanCockpitInstrument1, instrument1Position - (instrument1RightVector * TITAN_COCKPIT_INSTRUMENT1_RUI_SCREEN_SQUARE_SIZE * 0.5) - (instrument1DownVector * TITAN_COCKPIT_INSTRUMENT1_RUI_SCREEN_SQUARE_SIZE * 0.5), instrument1RightVector * TITAN_COCKPIT_INSTRUMENT1_RUI_SCREEN_SQUARE_SIZE, instrument1DownVector * TITAN_COCKPIT_INSTRUMENT1_RUI_SCREEN_SQUARE_SIZE )
+
+ // create ruis
+ entity player = GetLocalViewPlayer()
+
+ #if SP
+ file.coreHintRui = CreateTitanCockpitRui( $"ui/core_hint.rpak" )
+ #endif
+
+ file.cockpitRui = CreateTitanCockpitRui( $"ui/ajax_cockpit_base.rpak" )
+ RuiTrackFloat3( file.cockpitRui, "playerOrigin", player, RUI_TRACK_ABSORIGIN_FOLLOW )
+ RuiTrackFloat3( file.cockpitRui, "playerEyeAngles", player, RUI_TRACK_EYEANGLES_FOLLOW )
+ RuiTrackFloat( file.cockpitRui, "healthFrac", player, RUI_TRACK_HEALTH )
+ RuiTrackFloat( file.cockpitRui, "shieldFrac", player, RUI_TRACK_SHIELD_FRACTION )
+ RuiTrackFloat( file.cockpitRui, "dashFrac", player, RUI_TRACK_PLAYER_SUIT_POWER )
+ RuiSetFloat( file.cockpitRui, "ejectManualTimeOut", EJECT_FADE_TIME )
+ RuiSetFloat( file.cockpitRui, "ejectButtonTimeOut", TITAN_EJECT_MAX_PRESS_DELAY )
+ RuiSetGameTime( file.cockpitRui, "ejectManualStartTime", -60.0 )
+ RuiSetGameTime( file.cockpitRui, "ejectButtonPressTime", -60.0 )
+ #if MP
+ string titanName = GetTitanCharacterName( player )
+ if ( titanName == "vanguard" )
+ {
+ RuiSetString( file.cockpitRui, "titanInfo1", GetVanguardCoreString( player, 1 ) )
+ RuiSetString( file.cockpitRui, "titanInfo2", GetVanguardCoreString( player, 2 ) )
+ RuiSetString( file.cockpitRui, "titanInfo3", GetVanguardCoreString( player, 3 ) )
+ RuiSetString( file.cockpitRui, "titanInfo4", GetVanguardCoreString( player, 4 ) )
+ }
+
+ file.cockpitAdditionalRui = CreateTitanCockpitRui( $"ui/ajax_cockpit_fd.rpak" )
+ RuiSetFloat( file.cockpitAdditionalRui, "ejectManualTimeOut", EJECT_FADE_TIME )
+ RuiSetFloat( file.cockpitAdditionalRui, "ejectButtonTimeOut", TITAN_EJECT_MAX_PRESS_DELAY )
+ RuiSetGameTime( file.cockpitAdditionalRui, "ejectManualStartTime", -60.0 )
+
+ RuiSetDrawGroup( file.cockpitAdditionalRui, RUI_DRAW_NONE )
+ #endif
+
+#if SP
+ bool ejectIsAllowed = false
+#else
+ bool ejectIsAllowed = !TitanEjectIsDisabled()
+#endif
+ RuiSetBool( file.cockpitRui, "ejectIsAllowed", ejectIsAllowed )
+
+ string playerSettings = GetLocalViewPlayer().GetPlayerSettings()
+ float health = player.GetPlayerModHealth()
+ float healthPerSegment = GetPlayerSettingsFieldForClassName_HealthPerSegment( playerSettings )
+ RuiSetInt( file.cockpitRui, "numHealthSegments", int( health / healthPerSegment ) )
+ RuiTrackFloat( file.cockpitRui, "cockpitColor", player, RUI_TRACK_STATUS_EFFECT_SEVERITY, eStatusEffect.cockpitColor )
+
+ file.cockpitLowerRui = CreateTitanCockpitLowerRui( $"ui/ajax_cockpit_lower.rpak" )
+ RuiTrackFloat( file.cockpitLowerRui, "dashFrac", player, RUI_TRACK_PLAYER_SUIT_POWER )
+ RuiTrackFloat3( file.cockpitLowerRui, "playerEyeAngles", player, RUI_TRACK_EYEANGLES_FOLLOW )
+ RuiTrackFloat( file.cockpitLowerRui, "cockpitColor", player, RUI_TRACK_STATUS_EFFECT_SEVERITY, eStatusEffect.cockpitColor )
+
+ var instrument1Rui = CreateTitanCockpitInstrument1Rui( $"ui/ajax_cockpit_insturment1.rpak" )
+ RuiTrackFloat3( instrument1Rui, "playerEyeAngles", player, RUI_TRACK_EYEANGLES_FOLLOW )
+
+ int numDashPips = int( floor( 100 / GetSettingsForPlayer_DodgeTable( GetLocalViewPlayer() )["dodgePowerDrain"] ) )
+ RuiSetInt( file.cockpitRui, "numDashSegments", numDashPips )
+ RuiSetInt( file.cockpitLowerRui, "numDashSegments", numDashPips )
+
+ thread CockpitDoomedThink( cockpit )
+ thread TitanCockpitDestroyRuisOnDeath( cockpit )
+ thread TitanCockpitHealthChangedThink( cockpit, player )
+
+ #if MP
+ if ( GetCurrentPlaylistVarInt( "aegis_upgrades", 0 ) == 1 && !IsSpectating() && !IsWatchingKillReplay() )
+ thread DisplayFrontierRank( file.isFirstBoot )
+ #endif
+ file.isFirstBoot = false
+
+ UpdateTitanCockpitVisibility()
+}
+
+#if MP
+void function DisplayFrontierRank( bool isFirstBoot = true )
+{
+ GetLocalClientPlayer().Signal( "DisplayFrontierRank" )
+ GetLocalClientPlayer().EndSignal( "DisplayFrontierRank" )
+
+ wait 2.0
+
+ TitanLoadoutDef titanLoadout = GetTitanLoadoutFromPersistentData( GetLocalClientPlayer(), GetPersistentSpawnLoadoutIndex( GetLocalClientPlayer(), "titan" ) )
+ string titanClass = titanLoadout.titanClass
+
+ array<ItemDisplayData> titanUpgrades = FD_GetUpgradesForTitanClass( titanClass )
+ int maxActiveIndex
+ foreach ( index, item in titanUpgrades )
+ {
+ RuiSetImage( file.cockpitAdditionalRui, "upgradeIcon" + (index + 1), item.image )
+ RuiSetString( file.cockpitAdditionalRui, "upgradeName" + (index + 1), item.name )
+
+ if ( !IsSubItemLocked( GetLocalClientPlayer(), item.ref, item.parentRef ) )
+ maxActiveIndex++
+ }
+
+ RuiSetDrawGroup( file.cockpitAdditionalRui, RUI_DRAW_COCKPIT )
+
+ bool firstBootDisplay
+ if ( GameRules_GetGameMode() == FD )
+ firstBootDisplay = isFirstBoot || !GetGlobalNetBool( "FD_waveActive" )
+ else
+ firstBootDisplay = isFirstBoot
+
+ RuiSetBool( file.cockpitAdditionalRui, "isFirstBoot", firstBootDisplay )
+ RuiSetImage( file.cockpitAdditionalRui, "titanIcon", GetIconForTitanClass( titanClass ) )
+ RuiSetInt( file.cockpitAdditionalRui, "titanRank", FD_TitanGetLevel( GetLocalClientPlayer(), titanClass ) )
+ RuiSetInt( file.cockpitAdditionalRui, "maxActiveIndex", maxActiveIndex )
+ RuiSetGameTime( file.cockpitAdditionalRui, "updateTime", Time() )
+
+ EmitSoundOnEntity( GetLocalClientPlayer(), "UI_InGame_FD_MetaUpgradeAnnouncement" )
+
+ if ( firstBootDisplay )
+ {
+ wait 2.0
+
+ for ( int index = 0; index < maxActiveIndex; index++ )
+ {
+ EmitSoundOnEntity( GetLocalClientPlayer(), "UI_InGame_FD_MetaUpgradeTextAppear" )
+
+ wait 0.85
+
+ EmitSoundOnEntity( GetLocalClientPlayer(), "UI_InGame_FD_MetaUpgradeBarFill" )
+
+ wait 0.15
+ }
+ }
+ else
+ {
+ wait 0.5
+
+ for ( int index = 0; index < maxActiveIndex; index++ )
+ {
+ EmitSoundOnEntity( GetLocalClientPlayer(), "UI_InGame_FD_MetaUpgradeBarFill" )
+ wait 0.05
+ }
+ }
+}
+
+string function GetVanguardCoreString( entity player, int index )
+{
+ Assert( player.IsTitan() )
+
+ if ( !IsConnected() ) //Persistence isn't available when we disconnect
+ return ""
+
+ if ( player != GetLocalClientPlayer() ) //Client Persistence doesn't know about other players.
+ return ""
+
+ TitanLoadoutDef loadout = GetActiveTitanLoadout( player )
+
+ entity soul = player.GetTitanSoul()
+ if ( !IsValid( soul ) )
+ return ""
+
+ if ( index == 1 )
+ {
+ if ( soul.GetTitanSoulNetInt( "upgradeCount" ) >= 1 )
+ {
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE1_TITLE" ), Localize( GetItemName( loadout.passive4 ) ) )
+ }
+ else
+ {
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE1_TITLE" ), Localize( "#UPGRADE_IN_PROGRESS" ) )
+ }
+ }
+ if ( index == 2 )
+ {
+ if ( soul.GetTitanSoulNetInt( "upgradeCount" ) >= 2 )
+ {
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE2_TITLE" ), Localize( GetItemName( loadout.passive5 ) ) )
+ }
+ else
+ {
+ if ( soul.GetTitanSoulNetInt( "upgradeCount" ) >= 1 )
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE2_TITLE" ), Localize( "#UPGRADE_IN_PROGRESS" ) )
+ else
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE2_TITLE" ), Localize( "#UPGRADE_NOT_INSTALLED" ) )
+ }
+ }
+ if ( index == 3 )
+ {
+ if ( soul.GetTitanSoulNetInt( "upgradeCount" ) >= 3 )
+ {
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE3_TITLE" ), Localize( GetItemName( loadout.passive6 ) ) )
+ }
+ else
+ {
+ if ( soul.GetTitanSoulNetInt( "upgradeCount" ) >= 2 )
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE3_TITLE" ), Localize( "#UPGRADE_IN_PROGRESS" ) )
+ else
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE3_TITLE" ), Localize( "#UPGRADE_NOT_INSTALLED" ) )
+ }
+ }
+ if ( index == 4 )
+ {
+ printt( loadout.passive4 )
+ if ( loadout.passive4 == "pas_vanguard_core1" ) // Arc Rounds
+ {
+ entity offhandWeapon = player.GetOffhandWeapon( OFFHAND_RIGHT )
+ if ( IsValid( offhandWeapon ) && ( offhandWeapon.HasMod( "missile_racks" ) || offhandWeapon.HasMod( "upgradeCore_MissileRack_Vanguard" ) ) )
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE4_TITLE" ), Localize( "#GEAR_VANGUARD_CORE2" ) )
+ offhandWeapon = player.GetOffhandWeapon( OFFHAND_LEFT )
+ if ( IsValid( offhandWeapon ) && ( offhandWeapon.HasMod( "energy_transfer" ) || offhandWeapon.HasMod( "energy_field_energy_transfer" ) ) )
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE4_TITLE" ), Localize( "#GEAR_VANGUARD_CORE3" ) )
+ }
+ else if ( loadout.passive4 == "pas_vanguard_core2" ) // Missile Racks
+ {
+ entity weapon = player.GetMainWeapons()[0]
+ if ( IsValid( weapon ) && ( weapon.HasMod( "arc_rounds" ) || weapon.HasMod( "arc_rounds_with_battle_rifle" ) ) )
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE4_TITLE" ), Localize( "#GEAR_VANGUARD_CORE1" ) )
+ entity offhandWeapon = player.GetOffhandWeapon( OFFHAND_LEFT )
+ if ( IsValid( offhandWeapon ) && ( offhandWeapon.HasMod( "energy_transfer" ) || offhandWeapon.HasMod( "energy_field_energy_transfer" ) ) )
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE4_TITLE" ), Localize( "#GEAR_VANGUARD_CORE3" ) )
+ }
+ else if ( loadout.passive4 == "pas_vanguard_core3" ) // Energy Transfer
+ {
+ entity weapon = player.GetMainWeapons()[0]
+ if ( IsValid( weapon ) && ( weapon.HasMod( "arc_rounds" ) || weapon.HasMod( "arc_rounds_with_battle_rifle" ) ) )
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE4_TITLE" ), Localize( "#GEAR_VANGUARD_CORE1" ) )
+ entity offhandWeapon = player.GetOffhandWeapon( OFFHAND_RIGHT )
+ if ( IsValid( offhandWeapon ) && ( offhandWeapon.HasMod( "missile_racks" ) || offhandWeapon.HasMod( "upgradeCore_MissileRack_Vanguard" ) ) )
+ return Localize( "#TITAN_UPGRADE_STATUS_N_N", Localize( "#TITAN_UPGRADE4_TITLE" ), Localize( "#GEAR_VANGUARD_CORE2" ) )
+ }
+ return ""
+ }
+
+ unreachable
+}
+#endif
+
+void function SetUnlimitedDash( bool active )
+{
+ if ( file.cockpitLowerRui == null )
+ return
+
+ RuiSetBool( file.cockpitLowerRui, "hasUnlimitedDash", active )
+}
+
+void function UpdateEjectHud_SetManualEjectStartTime( entity player )
+{
+ float timeNow = Time()
+ player.p.ejectEnableTime = timeNow
+
+ if ( file.cockpitRui != null )
+ RuiSetGameTime( file.cockpitRui, "ejectManualStartTime", timeNow )
+
+ if ( file.cockpitAdditionalRui != null )
+ RuiSetGameTime( file.cockpitAdditionalRui, "ejectManualStartTime", timeNow )
+}
+
+void function UpdateEjectHud_SetButtonPressTime( entity player )
+{
+ float timeNow = Time()
+ player.p.ejectPressTime = timeNow
+
+ if ( file.cockpitRui != null )
+ RuiSetGameTime( file.cockpitRui, "ejectButtonPressTime", timeNow )
+
+ //if ( file.cockpitAdditionalRui != null )
+ // RuiSetGameTime( file.cockpitAdditionalRui, "ejectButtonPressTime", timeNow )
+}
+
+void function UpdateEjectHud_SetButtonPressCount( entity player, int buttonCount )
+{
+ player.p.ejectPressCount = buttonCount
+
+ if ( file.cockpitRui != null )
+ RuiSetInt( file.cockpitRui, "ejectButtonCount", buttonCount )
+
+ //if ( file.cockpitAdditionalRui != null )
+ // RuiSetInt( file.cockpitAdditionalRui, "ejectButtonCount", buttonCount )
+}
+
+void function UpdateTitanCockpitVisibility()
+{
+ entity player = GetLocalViewPlayer()
+ if ( !IsValid( player ) )
+ return
+
+ if ( Tone_ShouldCreateTrackerHud( player ) )
+ thread Tone_HudThink( player )
+ else
+ player.Signal( "StopToneHud" )
+
+ foreach ( managedRUI in file.titanCockpitManagedRUIs )
+ {
+ bool shouldCreate = managedRUI.shouldCreate()
+ if ( !managedRUI.exists && shouldCreate )
+ {
+ var rui = managedRUI.create()
+
+ bool found = false
+ foreach ( cockpitRui in player.p.titanCockpitRUIs )
+ {
+ if ( cockpitRui.rui == rui )
+ found = true
+ }
+ if ( !found )
+ {
+ TitanCockpitRUI tcRUI
+ tcRUI.rui = rui
+ tcRUI.drawGroup = managedRUI.drawGroup
+ player.p.titanCockpitRUIs.append( tcRUI )
+ }
+
+ managedRUI.exists = true
+ }
+ else if ( managedRUI.exists && !shouldCreate )
+ {
+ managedRUI.destroy()
+ managedRUI.exists = false
+ }
+ }
+
+ bool isVisible = true
+
+ int ceFlags = player.GetCinematicEventFlags()
+ if ( (ceFlags & CE_FLAG_INTRO) || (ceFlags & CE_FLAG_TITAN_3P_CAM) )
+ isVisible = false
+ if ( clGlobal.isSoloDialogMenuOpen )
+ isVisible = false
+
+ for ( int i = player.p.titanCockpitRUIs.len() - 1; i >= 0; i-- )
+ {
+ TitanCockpitRUI tcRUI = player.p.titanCockpitRUIs[ i ]
+ RuiSetDrawGroup( tcRUI.rui, isVisible ? tcRUI.drawGroup : RUI_DRAW_NONE )
+ }
+}
+
+void function AddTitanCockpitManagedRUI( var functionref() createFunc, void functionref() destroyFunc, bool functionref() shouldCreateFunc, int drawGroup )
+{
+ TitanCockpitManagedRUI managedRUI
+ managedRUI.create = createFunc
+ managedRUI.destroy = destroyFunc
+ managedRUI.shouldCreate = shouldCreateFunc
+ managedRUI.drawGroup = drawGroup
+
+ file.titanCockpitManagedRUIs.append( managedRUI )
+}
+
+void function CinematicEventFlagChanged( entity player )
+{
+ UpdateTitanCockpitVisibility()
+}
+
+void function CockpitDoomedThink( entity cockpit )
+{
+ entity player = GetLocalViewPlayer()
+ cockpit.EndSignal( "OnDestroy" )
+
+ while ( IsAlive( player ) )
+ {
+ entity soul = player.GetTitanSoul()
+ if ( !IsValid( soul ) ) //Defensive fix for bug 227087. Assumption is that the cockpit is likely to be destroyed soon if the soul is invalid.
+ return
+ if ( !soul.IsDoomed() )
+ player.WaitSignal( "Doomed" )
+
+ SetCockpitUIDoomedState( true )
+
+ if ( !IsValid( soul ) ) //Defensive fix for bug 227087. Assumption is that the cockpit is likely to be destroyed soon if the soul is invalid.
+ return
+ if ( soul.IsDoomed() )
+ player.WaitSignal( "TitanUnDoomed" )
+
+ SetCockpitUIDoomedState( false )
+ }
+}
+
+void function SetCockpitUIEjectingState( bool state )
+{
+ if ( file.cockpitRui != null )
+ RuiSetBool( file.cockpitRui, "isEjecting", state )
+
+ if ( file.cockpitAdditionalRui != null )
+ RuiSetBool( file.cockpitAdditionalRui, "isEjecting", state )
+
+ if ( file.cockpitLowerRui != null )
+ {
+ RuiSetBool( file.cockpitLowerRui, "isEjecting", state )
+ if ( state )
+ RuiSetString( file.cockpitLowerRui, "ejectPrompt", Localize( RollRandomEjectString() ) )
+ else
+ RuiSetString( file.cockpitLowerRui, "ejectPrompt", "" )
+ }
+}
+
+void function SetCockpitUIDoomedState( bool state )
+{
+ if ( file.cockpitRui != null )
+ RuiSetBool( file.cockpitRui, "isDoomed", state )
+
+ if ( file.cockpitAdditionalRui != null )
+ RuiSetBool( file.cockpitAdditionalRui, "isDoomed", state )
+}
+
+void function TitanCockpitDestroyRui( var ruiToDestroy )
+{
+ if ( ruiToDestroy == null )
+ return
+
+ entity player = GetLocalViewPlayer()
+
+ for ( int i = player.p.titanCockpitRUIs.len() - 1; i >= 0; i-- )
+ {
+ TitanCockpitRUI tcRUI = player.p.titanCockpitRUIs[ i ]
+ if ( tcRUI.rui == ruiToDestroy )
+ {
+ RuiDestroy( tcRUI.rui )
+ player.p.titanCockpitRUIs.remove( i )
+ }
+ }
+}
+
+void function TitanCockpitDestroyRuisOnDeath( entity cockpit )
+{
+ entity player = GetLocalViewPlayer()
+
+ OnThreadEnd(
+ function() : ( cockpit )
+ {
+ foreach ( managedRUI in file.titanCockpitManagedRUIs )
+ {
+ if ( managedRUI.exists )
+ {
+ managedRUI.destroy()
+ managedRUI.exists = false
+ }
+ }
+
+ entity player = GetLocalViewPlayer()
+ for ( int i = player.p.titanCockpitRUIs.len() - 1; i >= 0; i-- )
+ {
+ RuiDestroy( player.p.titanCockpitRUIs[ i ].rui )
+ player.p.titanCockpitRUIs.remove( i )
+ }
+
+ player = GetLocalClientPlayer()
+ if ( IsValid( player ) )
+ player.Signal( "DisplayFrontierRank" )
+ file.cockpitAdditionalRui = null
+ file.cockpitRui = null
+ file.cockpitLowerRui = null
+ file.coreHintRui = null
+ }
+ )
+
+ player.EndSignal( "OnDeath" )
+ cockpit.EndSignal( "OnDestroy" )
+ WaitForever()
+}
+
+function CockpitBodyThink( cockpit, cockpitBody )
+{
+ cockpitBody.EndSignal( "OnDestroy" )
+
+ cockpit.WaitSignal( "OnDestroy" )
+
+ cockpitBody.Destroy()
+}
+
+
+entity function CreateCockpitBody( entity cockpit, entity player, entity cockpitParent )
+{
+ #if SP
+ string bodySettings = DEFAULT_PILOT_SETTINGS
+ #else
+ string bodySettings = file.lastPilotSettings
+ if ( bodySettings == "" || bodySettings == "spectator" )
+ bodySettings = Loadouts_GetSetFileForRequestedClass( player )
+ if ( bodySettings == "" )
+ bodySettings = "pilot_base"
+ #endif
+
+ asset bodyModelName = GetPlayerSettingsAssetForClassName( bodySettings, "armsmodel" )
+ #if DEV
+ if ( bodySettings == "" )
+ {
+ CodeWarning( "Couldn't find armsmodel for set file: " + bodySettings )
+ }
+ #endif
+
+ entity cockpitBody = CreateClientSidePropDynamic( cockpitParent.GetOrigin(), Vector( 0, 0, 0 ), bodyModelName )
+ cockpitBody.EnableRenderWithCockpit()
+ cockpitBody.SetOrigin( cockpit.GetOrigin() )
+ cockpitBody.SetParent( cockpit )
+
+ thread CockpitBodyThink( cockpit, cockpitBody )
+
+ return cockpitBody
+}
+
+function TitanEmbarkDSP( transitionTime )
+{
+}
+
+function TitanDisembarkDSP( transitionTime )
+{
+}
+
+function TitanCockpit_EMPFadeScale( entity cockpit, elapsedMod = 0 )
+{
+ local fadeInTime = 0.0
+ local fadeOutTime = 1.5
+ local elapsedTime = Time() - cockpit.s.empInfo.startTime
+ elapsedTime += elapsedMod
+
+ // ToDo:
+ // Fade in/out from last frames amount so it doesnt pop
+ // Make strength var to control max fade ( less strength returns max of like 0.5 )
+
+ //------------------------
+ // EMP effect is finished
+ //------------------------
+
+ //printt( "elapsedTime:" + elapsedTime + " cockpit.s.empInfo.duration:" + cockpit.s.empInfo.duration + " fadeOutTime:" + fadeOutTime )
+ if ( elapsedTime < cockpit.s.empInfo.duration - fadeOutTime )
+ {
+ return 1.0
+ }
+
+
+ if ( elapsedTime >= fadeInTime + cockpit.s.empInfo.duration + fadeOutTime )
+ {
+ cockpit.s.empInfo.startTime = 0
+ return 0.0
+ }
+
+ //------------------------
+ // EMP effect is starting
+ //------------------------
+
+ if ( elapsedTime < fadeInTime )
+ {
+ return GraphCapped( elapsedTime, 0.0, fadeInTime, 0.0, 1.0 )
+ }
+
+ //----------------------
+ // EMP effect is ending
+ //----------------------
+
+ if ( elapsedTime > fadeInTime + cockpit.s.empInfo.duration )
+ {
+ cockpit.s.empInfo["sub_count"] = 0
+ return GraphCapped( elapsedTime, fadeInTime + cockpit.s.empInfo.duration, fadeInTime + cockpit.s.empInfo.duration + fadeOutTime, 1.0, 0.0 )
+ }
+
+ //---------------------
+ // EMP flicker effect
+ //---------------------
+
+ // Time to start a new flicker
+ if ( cockpit.s.empInfo["sub_start"] == 0 )
+ {
+ cockpit.s.empInfo["sub_start"] <- Time()
+ if ( cockpit.s.empInfo["sub_count"] == 0 )
+ cockpit.s.empInfo["sub_pause"] <- RandomFloatRange( 0.5, 1.5 )
+ else
+ cockpit.s.empInfo["sub_pause"] <- RandomFloat( 0.5 )
+ cockpit.s.empInfo["sub_duration"] <- RandomFloatRange( 0.1, 0.4 )
+ cockpit.s.empInfo["sub_alpha"] <- RandomFloatRange( 0.4, 0.9 )
+ cockpit.s.empInfo["sub_count"]++;
+ }
+ local flickerElapsedTime = Time() - cockpit.s.empInfo["sub_start"]
+
+ // Start a new flicker if the current one is finished
+ if ( flickerElapsedTime > cockpit.s.empInfo["sub_pause"] + cockpit.s.empInfo["sub_duration"] )
+ cockpit.s.empInfo["sub_start"] = 0
+
+ if ( flickerElapsedTime < cockpit.s.empInfo["sub_pause"] )
+ {
+ // Pause before the flicker
+ return 1.0
+ }
+ else if ( flickerElapsedTime < cockpit.s.empInfo["sub_pause"] + ( cockpit.s.empInfo["sub_duration"] / 2.0 ) )
+ {
+ // First half of the flicker
+ return GraphCapped( flickerElapsedTime, 0.0, cockpit.s.empInfo["sub_duration"] / 2.0, 1.0, cockpit.s.empInfo["sub_alpha"] )
+ }
+ else
+ {
+ // Second half of the flicker
+ return GraphCapped( flickerElapsedTime, cockpit.s.empInfo["sub_duration"] / 2.0, cockpit.s.empInfo["sub_duration"], cockpit.s.empInfo["sub_alpha"], 1.0 )
+ }
+}
+
+function ServerCallback_TitanCockpitEMP( duration )
+{
+ thread TitanCockpit_DoEMP( duration / 4 )
+}
+
+function TitanCockpit_DoEMP( duration )
+{
+ entity player = GetLocalViewPlayer()
+ entity cockpit = player.GetCockpit()
+
+ if ( !IsValid( cockpit ) )
+ return
+
+ if ( !player.IsTitan() )
+ return
+
+ if ( !player.s.inTitanCockpit )
+ return
+
+ Signal( player, "EMP" )
+ EndSignal( player, "EMP" )
+ player.EndSignal( "OnDestroy" )
+
+ // this needs tweaking... looks a bit artificial
+ ClientCockpitShake( 0.25, 3, 1.0, Vector( 0, 0, 1 ) ) // amplitude, frequency, duration, direction
+
+ thread PlayCockpitEMPLights( cockpit, duration )
+
+ // Start the screens and vdu power outages
+ cockpit.s.empInfo.xOffset = RandomFloatRange( 0.5, 0.75 )
+ cockpit.s.empInfo.yOffset = RandomFloatRange( 0.5, 0.75 )
+ if ( CoinFlip() )
+ cockpit.s.empInfo.xOffset *= -1
+ if ( CoinFlip() )
+ cockpit.s.empInfo.yOffset *= -1
+
+ cockpit.s.empInfo.startTime = Time()
+ cockpit.s.empInfo.duration = duration
+
+ EmitSoundOnEntity( player, EMP_IMPARED_SOUND )
+ wait duration
+ FadeOutSoundOnEntity( player, EMP_IMPARED_SOUND, 1.5 )
+}
+
+function PlayCockpitEMPLights( cockpit, duration )
+{
+ duration += 1.5 // blend out
+ local attachID
+ local origin
+ local angles
+ local fxLights = []
+
+ string tagName = "COCKPIT" // SCR_CL_BL"
+ attachID = cockpit.LookupAttachment( tagName )
+ origin = cockpit.GetAttachmentOrigin( attachID )
+ origin.z -= 25
+ angles = Vector( 0, 0, 0 )
+ local lightTable = {}
+ lightTable.light <- CreateClientSideDynamicLight( origin, angles, Vector( 0.0, 0.0, 0.0 ), 80.0 )
+ lightTable.modulate <- true
+ fxLights.append( lightTable )
+
+ wait 0.5
+
+ foreach ( fxLight in fxLights )
+ {
+ fxLight.light.SetCockpitLight( true )
+ }
+
+ local startTime = Time()
+ local rate = 1.2
+
+ local endTime = Time() + duration
+
+ while ( IsValid( cockpit ) )
+ {
+ if ( Time() > endTime )
+ break
+
+ float subtractColor = GraphCapped( Time(), endTime - 0.25, endTime, 1.0, 0.0 )
+ local pulseFrac = GetPulseFrac( rate, startTime )
+ pulseFrac *= subtractColor
+ //pulseFrac -= fadeInColor
+
+ foreach ( index, fxLight in fxLights )
+ {
+ Assert( fxLight.modulate )
+ fxLight.light.SetLightColor( Vector( pulseFrac, 0, 0 ) )
+
+ // the case where fxLight.modulate == false used to be handled by this script, which used undefined variable fadeInColor:
+ // fxLight.light.SetLightColor( Vector( fadeInColor, fadeInColor, fadeInColor ) )
+ }
+
+ WaitFrame()
+ }
+
+ foreach ( fxLight in fxLights )
+ {
+ fxLight.light.Destroy()
+ }
+}
+
+
+function TitanCockpit_IsBooting( cockpit )
+{
+ return cockpit.GetTimeInCockpit() < 1.3
+}
+
+function TitanCockpitAnimThink( cockpit, body )
+{
+ cockpit.SetOpenViewmodelOffset( 20.0, 0.0, 10.0 )
+ cockpit.Anim_NonScriptedPlay( "atpov_cockpit_hatch_close_idle" )
+
+ if ( body )
+ body.Anim_NonScriptedPlay( "atpov_cockpit_hatch_close_idle" )
+}
+
+
+bool function IsDisplayingEjectInterface( entity player )
+{
+ if ( !player.IsTitan() )
+ return false
+
+ if ( player.ContextAction_IsMeleeExecution() ) //Could just check for ContextAction_IsActive() if we need to be more general
+ return false
+
+ if ( !GetDoomedState( player ) && Time() - player.p.ejectEnableTime > EJECT_FADE_TIME )
+ return false
+
+ if ( Riff_TitanExitEnabled() == eTitanExitEnabled.Never || Riff_TitanExitEnabled() == eTitanExitEnabled.DisembarkOnly )
+ return false
+
+ //if ( !CanDisembark( player ) )
+ // return false
+
+ return true
+}
+
+void function PlayerPressed_Eject( entity player )
+{
+ if ( !IsDisplayingEjectInterface( player ) )
+ return
+
+ if ( Time() - player.p.ejectPressTime > TITAN_EJECT_MAX_PRESS_DELAY )
+ UpdateEjectHud_SetButtonPressCount( player, 0 )
+
+ if ( !IsAlive( player ) )
+ return
+
+ EmitSoundOnEntity( player, "titan_eject_xbutton" )
+ EmitSoundOnEntity( player, "hud_boost_card_radar_jammer_redtextbeep_1p" )
+ UpdateEjectHud_SetButtonPressTime( player )
+ UpdateEjectHud_SetButtonPressCount( player, (player.p.ejectPressCount + 1) )
+
+ player.ClientCommand( "TitanEject " + player.p.ejectPressCount )
+
+ entity cockpit = player.GetCockpit()
+ if ( player.p.ejectPressCount < 3 || cockpit.s.ejectStartTime )
+ return
+
+ PlayerEjects( player, cockpit )
+}
+
+void function AddCommonEjectMessage( string message )
+{
+ file.moddedCommonEjectMessages.append( message )
+}
+
+void function AddRareEjectMessage( string message )
+{
+ file.moddedRareEjectMessages.append( message )
+}
+
+string function RollRandomEjectString()
+{
+ const int COCKPIT_EJECT_COMMON_COUNT = 6
+ const int COCKPIT_EJECT_RARE_COUNT = 36
+ const float CHANCE_FOR_RARE = 0.15
+
+ float randForType = RandomFloat( 1.0 )
+ if ( randForType < CHANCE_FOR_RARE )
+ {
+ int index = RandomInt( COCKPIT_EJECT_RARE_COUNT + file.moddedRareEjectMessages.len() )
+ if ( index < COCKPIT_EJECT_RARE_COUNT )
+ return "#COCKPIT_EJECT_RARE_" + index
+ else
+ return file.moddedRareEjectMessages[index - COCKPIT_EJECT_RARE_COUNT]
+ }
+
+ int index = RandomInt( COCKPIT_EJECT_COMMON_COUNT + file.moddedCommonEjectMessages.len() )
+ if ( index < COCKPIT_EJECT_COMMON_COUNT )
+ return "#COCKPIT_EJECT_COMMON_" + index
+ else
+ return file.moddedCommonEjectMessages[index - COCKPIT_EJECT_COMMON_COUNT]
+
+ unreachable
+}
+
+void function PlayerEjects( entity player, entity cockpit ) //Note that this can be run multiple times in a frame, e.g. get damaged by 4 pellets of a shotgun that brings the Titan into a doomed state with auto eject. Not ideal
+{
+ // prevent animation from playing if player is in the middle of execution
+ if ( player.ContextAction_IsActive() && !player.ContextAction_IsBusy() )
+ return
+
+ player.Signal( "Ejecting" )
+
+ SetCockpitUIEjectingState( true )
+
+ local ejectAlarmSound
+ cockpit.s.ejectStartTime = Time()
+ string animationName
+ if ( GetNuclearPayload( player ) > 0 )
+ {
+ animationName = "atpov_cockpit_eject_nuclear"
+ cockpit.Anim_NonScriptedPlay( animationName )
+ if ( IsValid( cockpit.e.body ) )
+ cockpit.e.body.Anim_NonScriptedPlay( "atpov_cockpit_eject_nuclear" )
+ ejectAlarmSound = TITAN_NUCLEAR_DEATH_ALARM
+ }
+ else
+ {
+ animationName = "atpov_cockpit_eject"
+ cockpit.Anim_NonScriptedPlay( animationName )
+ if ( IsValid( cockpit.e.body ) )
+ cockpit.e.body.Anim_NonScriptedPlay( "atpov_cockpit_eject" )
+
+ ejectAlarmSound = TITAN_ALARM_SOUND
+ }
+
+ thread LightingUpdateAfterOpeningCockpit()
+ thread EjectAudioThink( player, ejectAlarmSound )
+
+ float animDuration = cockpit.GetSequenceDuration( animationName )
+
+ thread MonitorPlayerEjectAnimBeingStuck( player, animDuration )
+}
+
+void function MonitorPlayerEjectAnimBeingStuck( entity player, float duration )
+{
+ player.Signal( "MonitorPlayerEjectAnimBeingStuck" )
+ player.EndSignal( "MonitorPlayerEjectAnimBeingStuck" )
+ player.EndSignal( "OnDeath" )
+ player.EndSignal( "OnDestroy" )
+ player.EndSignal( "SettingsChanged" )
+
+
+ wait duration + 2.0 // 1s as a buffer
+
+ if ( player.IsTitan() )
+ {
+ entity cockpit = player.GetCockpit()
+ cockpit.Anim_NonScriptedPlay( "atpov_cockpit_hatch_close_idle" )
+ if ( IsValid( cockpit.e.body ) )
+ cockpit.e.body.Anim_NonScriptedPlay( "atpov_cockpit_hatch_close_idle" )
+
+ SetCockpitUIEjectingState( false )
+ }
+}
+
+function ServerCallback_EjectConfirmed()
+{
+ if ( !IsWatchingReplay() )
+ return
+
+ entity player = GetLocalViewPlayer()
+ entity cockpit = player.GetCockpit()
+
+ if ( !cockpit || !IsTitanCockpitModelName( cockpit.GetModelName() ) )
+ return
+
+ PlayerEjects( player, cockpit )
+}
+
+function EjectAudioThink( entity player, ejectAlarmSound = TITAN_ALARM_SOUND )
+{
+ EmitSoundOnEntity( player, ejectAlarmSound )
+ TitanCockpit_PlayDialog( player, "manualEjectNotice" )
+
+ player.EndSignal( "OnDeath" )
+
+ player.WaitSignal( "SettingsChanged" )
+
+ if ( player.GetPlayerClass() != "pilot" )
+ return
+
+ OnThreadEnd(
+ function() : ( player )
+ {
+ if ( !IsAlive( player ) )
+ {
+ StopSoundOnEntity( player, TITAN_EJECT_ASCENT )
+ StopSoundOnEntity( player, TITAN_EJECT_DESCENT )
+ }
+ else
+ {
+ FadeOutSoundOnEntity( player, TITAN_EJECT_ASCENT, 0.25 )
+ FadeOutSoundOnEntity( player, TITAN_EJECT_DESCENT, 0.25 )
+ }
+
+ StopSoundOnEntity( player, TITAN_EJECT_APEX )
+ }
+ )
+
+ EmitSoundOnEntity( player, TITAN_EJECT_BOOST )
+
+ float startTime = Time()
+ float duration = GetSoundDuration( TITAN_EJECT_ASCENT )
+ EmitSoundOnEntity( player, TITAN_EJECT_ASCENT )
+ float timeOut = duration - 0.25
+ vector velocity
+ float diff = 0.0
+
+ const int STAGE_ASCENT = 1
+ const int STAGE_APEX = 2
+ const int STAGE_DESCENT = 3
+
+ int ejectStage = STAGE_ASCENT
+
+ string currentSound = TITAN_EJECT_ASCENT
+
+ while ( diff < timeOut )
+ {
+ PerfStart( 127 )
+
+ diff = (Time() - startTime)
+
+ velocity = player.GetVelocity()
+ float length = Length( velocity )
+
+ if ( diff > 0.5 )
+ {
+ if ( player.IsOnGround() )
+ {
+ PerfEnd( 127 )
+ break
+ }
+ }
+
+ if ( ejectStage != STAGE_DESCENT && velocity.z < 0 )
+ {
+ FadeOutSoundOnEntity( player, TITAN_EJECT_ASCENT, 0.25 )
+ timeOut = GetSoundDuration( TITAN_EJECT_DESCENT )
+ EmitSoundOnEntity( player, TITAN_EJECT_DESCENT )
+ currentSound = TITAN_EJECT_DESCENT
+ ejectStage = STAGE_DESCENT
+ }
+ else if ( ejectStage == STAGE_ASCENT && length < 400 )
+ {
+ EmitSoundOnEntity( player, TITAN_EJECT_APEX )
+ ejectStage = STAGE_APEX
+ }
+
+ PerfEnd( 127 )
+
+ WaitFrame()
+ }
+}
+
+function LightingUpdateAfterOpeningCockpit()
+{
+ while ( true )
+ {
+ if ( !GetLocalViewPlayer().s.inTitanCockpit )
+ break
+ WaitFrame()
+ }
+
+ SetCockpitLightingEnabled( 0, false )
+}
+
+
+function TonemappingUpdateAfterOpeningCockpit() //Deprecated, no longer used
+{
+ local duration = 3
+ local tonemapMin = 2
+ local tonemapMax = 5
+
+ while ( true )
+ {
+ if ( !GetLocalViewPlayer().s.inTitanCockpit )
+ break
+ WaitFrame()
+ }
+
+ SetCockpitLightingEnabled( 0, false )
+
+ AutoExposureSetExposureCompensationBias( tonemapMax )
+ AutoExposureSnap()
+ wait( 0.1 )
+
+ TitanDisembarkDSP( 0.5 )
+
+ local startTime = Time()
+ while ( true )
+ {
+ local time = Time() - startTime
+ float factor = GraphCapped( time, 0, duration, 1, 0 )
+ factor = factor * factor * factor
+ local toneMapScale = tonemapMin + (tonemapMax - tonemapMin) * factor
+ AutoExposureSetExposureCompensationBias( toneMapScale )
+ AutoExposureSnap()
+ wait 0
+ if ( factor == 0 )
+ break
+ }
+
+ AutoExposureSetExposureCompensationBias( 0 )
+}
+
+function ServerCallback_TitanEmbark()
+{
+ TitanCockpit_PlayDialog( GetLocalViewPlayer(), "embark" )
+}
+
+function ServerCallback_TitanDisembark()
+{
+ entity player = GetLocalViewPlayer()
+
+ thread LightingUpdateAfterOpeningCockpit()
+
+ //HideFriendlyIndicatorAndCrosshairNames()
+
+ //PlayMusic( "Music_FR_Militia_PilotAction2" )
+}
+
+
+function PlayerPressed_QuickDisembark( player )
+{
+ player.ClientCommand( "TitanDisembark" )
+}
+
+void function PlayerPressed_EjectEnable( entity player )
+{
+ if ( !player.IsTitan() )
+ return
+
+ if ( !IsAlive( player ) )
+ return
+
+ if ( IsValid( player.GetParent() ) )
+ return
+
+ if ( TitanEjectIsDisabled() )
+ {
+ EmitSoundOnEntity( player, "CoOp_SentryGun_DeploymentDeniedBeep" )
+ SetTimedEventNotification( 1.5, "" )
+ SetTimedEventNotification( 1.5, "#NOTIFY_EJECT_DISABLED" )
+ return
+ }
+
+ if ( Riff_TitanExitEnabled() == eTitanExitEnabled.Never || Riff_TitanExitEnabled() == eTitanExitEnabled.DisembarkOnly )
+ return
+
+ //if ( !CanDisembark( player ) )
+ // return
+
+ if ( player.ContextAction_IsMeleeExecution() ) //Could just check for ContextAction_IsActive() if we need to be more general
+ return
+
+ if ( player.GetHealth() == 1 )
+ {
+ #if MP
+ if ( !FD_ReadyUpEnabled() )
+ #endif
+ {
+ player.ClientCommand( "TitanEject " + 3 )
+ return
+ }
+ }
+
+ EmitSoundOnEntity( player, "titan_eject_dpad" )
+ UpdateEjectHud_SetManualEjectStartTime( player )
+ player.Signal( "UpdateRodeoAlert" ) // need this to hide titan stomp hint
+}
+
+float function CalcJoltMagnitude( player, cockpit, joltDir, float damageAmount, damageType, int damageSourceID )
+{
+ const float COCKPIT_MAX_JOLT_DAMAGE = 2000.0
+
+ float resultRaw = damageAmount / COCKPIT_MAX_JOLT_DAMAGE
+ return clamp( resultRaw, 0.0, 1.0 )
+}
+
+function JoltCockpit( cockpit, player, joltDir, float damageAmount, damageType, damageSourceId )
+{
+ float severity = CalcJoltMagnitude( player, cockpit, joltDir, damageAmount, damageType, expect int( damageSourceId ) )
+ player.CockpitJolt( joltDir, severity )
+}
+
+function RandomizeDir( dir, randPitch = 0, randYaw = 0, basePitch = 0, baseYaw = 0 )
+{
+ local pitch = RandomFloatRange( -randPitch, randPitch )
+ local yaw = RandomFloatRange( -randYaw, randYaw )
+ local angles = VectorToAngles( dir )
+ angles = AnglesCompose( angles, Vector( pitch, yaw, 0 ) )
+ angles = AnglesCompose( angles, Vector( basePitch, baseYaw, 0 ) )
+ return AnglesToForward( angles )
+}
+
+function TitanCockpitDoomedThink( cockpit, player )
+{
+ cockpit.EndSignal( "OnDestroy" )
+
+ local titanSoul = player.GetTitanSoul()
+
+ if ( titanSoul == null || !titanSoul.IsDoomed() )
+ WaitSignal( player, "Doomed", "Ejecting" )
+
+ local color = Vector( 0.6, 0.06, 0 )
+ local radius = 70.0
+
+ FlashCockpitLight( cockpit, color, radius, -1 )
+}
+
+void function TitanCockpitHealthChangedThink( cockpit, entity player )
+{
+ cockpit.EndSignal( "OnDestroy" )
+
+ while ( true )
+ {
+ table results = WaitSignal( player, "HealthChanged" )
+
+ if ( !IsAlive( player ) )
+ continue
+
+ float oldHealthFrac = float( results.oldHealth ) / float( player.GetMaxHealth() )
+ float newHealthFrac = float( results.newHealth ) / float( player.GetMaxHealth() )
+
+ if ( oldHealthFrac > newHealthFrac )
+ {
+ var rui = RuiCreate( $"ui/ajax_cockpit_lost_health_segment.rpak", clGlobal.topoTitanCockpitHud, RUI_DRAW_COCKPIT, 10 )
+ RuiSetGameTime( rui, "startTime", Time() )
+ RuiSetFloat( rui, "oldHealthFrac", oldHealthFrac )
+ RuiSetFloat( rui, "newHealthFrac", newHealthFrac )
+
+ string playerSettings = GetLocalViewPlayer().GetPlayerSettings()
+ float health = player.GetPlayerModHealth()
+ float healthPerSegment = GetPlayerSettingsFieldForClassName_HealthPerSegment( playerSettings )
+ RuiSetInt( rui, "numHealthSegments", int( health / healthPerSegment ) )
+ }
+ }
+}
+
+
+function FlashCockpitLight( cockpit, color, radius, duration, tag = "SCR_CL_BL" )
+{
+ cockpit.EndSignal( "TitanUnDoomed" )
+ cockpit.EndSignal( "OnDestroy" )
+
+ local attachID = cockpit.LookupAttachment( tag )
+ local origin = cockpit.GetAttachmentOrigin( attachID )
+ local angles = Vector( 0, 0, 0 )
+
+ local fxLight = CreateClientSideDynamicLight( origin, angles, color, radius )
+ fxLight.SetCockpitLight( true )
+ fxLight.SetParent( cockpit )
+
+ OnThreadEnd(
+ function() : ( fxLight )
+ {
+ fxLight.Destroy()
+ }
+ )
+
+ local startTime = Time()
+ local rate = 3.0
+
+ while ( IsValid( cockpit ) && (Time() < startTime + duration || duration == -1 ) )
+ {
+ local pulseFrac = GetPulseFrac( rate, startTime )
+ pulseFrac += 0.5
+ fxLight.SetLightColor( Vector( color.x * pulseFrac, color.y * pulseFrac, color.z * pulseFrac ) )
+
+ WaitFrame()
+ }
+}
+
+function PlayCockpitSparkFX_Internal( cockpit, string tagName )
+{
+ expect entity( cockpit )
+
+ // this is called from a delaythread so needs valid check
+ if ( !IsValid( cockpit ) )
+ return
+
+ int attachID = cockpit.LookupAttachment( tagName )
+ if ( attachID == 0 )
+ {
+ tagName = CoinFlip() ? "FX_TL_PANEL" : "FX_TR_PANEL"
+ attachID = cockpit.LookupAttachment( tagName )
+ Assert( attachID, "Could not find fallback attachment index " + attachID + " for '" + tagName + "'' in model " + GetLocalViewPlayer().GetCockpit().GetModelName() )
+ }
+
+ int fxID = GetParticleSystemIndex( $"xo_cockpit_spark_01" )
+ int fxInstID = PlayFXOnTag( cockpit, fxID, attachID )
+
+ EffectSetIsWithCockpit( fxInstID, true )
+}
+
+function PlayCockpitSparkFX( cockpit, int sparkCount )
+{
+ const int TAG_COUNT = 6
+ const string[TAG_COUNT] cockpitFXEmitTags = [ "FX_TL_PANEL", "FX_TR_PANEL", "FX_TC_PANELA", "FX_TC_PANELB", "FX_BL_PANEL", "FX_BR_PANEL" ]
+ array<int> playlist = [0,1,2,3,4,5]
+ playlist.randomize()
+
+ for ( int idx = 0; idx < sparkCount; idx++ )
+ {
+ int lookup = (idx % TAG_COUNT)
+ int tagIndex = playlist[lookup]
+ string tagName = cockpitFXEmitTags[tagIndex]
+ PlayCockpitSparkFX_Internal( cockpit, tagName )
+ }
+}
+
+const int DAMAGE_PER_SPARK = 1000
+const int SPARK_MULTIPLIER = 3
+
+int function CalSparkCountForHit( entity player, float damageAmount, bool becameDoomed )
+{
+ if ( becameDoomed )
+ return 20
+ if ( damageAmount <= 0 )
+ return 0
+
+ int healthNow = player.GetHealth()
+ int healthPrev = healthNow + int( damageAmount )
+ int healthMax = player.GetMaxHealth()
+
+ bool isDoomed = GetDoomedState( player )
+ int sparksNow = (healthNow / DAMAGE_PER_SPARK)
+ int sparksPrev = (healthPrev / DAMAGE_PER_SPARK)
+ if ( (healthPrev == healthMax) && !isDoomed )
+ --sparksPrev // no spark on first damage
+
+ int delta = (sparksPrev - sparksNow)
+ if ( delta < 0 )
+ return 0
+
+ return (delta * SPARK_MULTIPLIER)
+}
+
+function TitanCockpit_DamageFeedback( entity player, cockpit, float damageAmount, damageType, damageOrigin, damageSourceId, bool doomedNow, int doomedDamage )
+{
+ RumbleForTitanDamage( damageAmount )
+
+ vector joltDir = Normalize( player.CameraPosition() - damageOrigin )
+ float joltDamage = doomedNow ? float( doomedDamage ) : damageAmount
+ JoltCockpit( cockpit, player, joltDir, joltDamage, damageType, damageSourceId )
+
+ bool isShieldHit = (damageType & DF_SHIELD_DAMAGE) ? true : false
+ if ( isShieldHit )
+ return
+
+ int sparkCount = CalSparkCountForHit( player, damageAmount, doomedNow );
+ //printt( "sparks: " + sparkCount + " dmg: " + damageAmount + " - " + player.GetHealth() + " / " + player.GetMaxHealth() )
+ PlayCockpitSparkFX( cockpit, sparkCount )
+}
+
+function ServerCallback_TitanCockpitBoot()
+{
+ thread ServerCallback_TitanCockpitBoot_Internal()
+}
+
+function ServerCallback_TitanCockpitBoot_Internal()
+{
+ AutoExposureSetExposureCompensationBias( -6 )
+ AutoExposureSnap()
+ wait 0.1
+ AutoExposureSetExposureCompensationBias( 0 )
+}
+
+function ServerCallback_TitanEMP( maxValue, duration, fadeTime, doFlash = true, doSound = true )
+{
+ thread TitanEMP_Internal( maxValue, duration, fadeTime, doFlash, doSound )
+}
+
+function TitanEMP_Internal( maxValue, duration, fadeTime, doFlash = true, doSound = true )
+{
+ entity player = GetLocalViewPlayer()
+
+ player.Signal( "TitanEMP_Internal" )
+ player.EndSignal( "TitanEMP_Internal" )
+
+ player.EndSignal( "OnDeath" )
+ player.EndSignal( "SettingsChanged" )
+
+ local angles = Vector( 0, -90, 90 )
+
+ local wide = 16
+ local tall = 9
+
+ float fovOffset = Graph( player.GetFOV(), 75, 120, 4, 2.5 )
+
+ local empVgui = CreateClientsideVGuiScreen( "vgui_titan_emp", VGUI_SCREEN_PASS_VIEWMODEL, Vector(0,0,0), Vector(0,0,0), wide, tall );
+
+ //empVgui.SetParent( player.GetViewModelEntity(), "CAMERA_BASE" )
+ empVgui.SetRefract( true ) // Force refract resolve before drawing vgui. (This can cost GPU!)
+ empVgui.SetParent( player )
+ empVgui.SetAttachOffsetOrigin( < fovOffset, wide / 2, -tall / 2 > )
+ empVgui.SetAttachOffsetAngles( angles )
+
+ empVgui.GetPanel().WarpEnable()
+
+ local EMPScreenFX = HudElement( "EMPScreenFX", empVgui.GetPanel() )
+ local EMPScreenFlash = HudElement( "EMPScreenFlash", empVgui.GetPanel() )
+
+ OnThreadEnd(
+ function() : ( player, empVgui )
+ {
+ empVgui.Destroy()
+ }
+ )
+
+ EMPScreenFX.Show()
+ EMPScreenFX.SetAlpha( maxValue * 255 )
+ EMPScreenFX.FadeOverTimeDelayed( 0, fadeTime, duration )
+
+ if ( doFlash )
+ {
+ EMPScreenFlash.Show()
+ EMPScreenFlash.SetAlpha( 255 )
+ EMPScreenFlash.FadeOverTimeDelayed( 0, fadeTime + duration, 0 )
+ }
+
+ if ( doSound )
+ {
+ EmitSoundOnEntity( player, EMP_IMPARED_SOUND )
+ wait duration
+ FadeOutSoundOnEntity( player, EMP_IMPARED_SOUND, fadeTime )
+ }
+
+ wait fadeTime
+}
+
+
+void function LinkCoreHint( entity soul )
+{
+ if ( file.coreHintRui == null )
+ return
+
+ RuiTrackFloat( file.coreHintRui, "coreFrac", soul, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( "coreAvailableFrac" ) )
+}
+
+
+void function FlashCockpitHealth( vector color )
+{
+ if ( file.cockpitRui == null )
+ return
+
+ RuiSetGameTime( file.cockpitRui, "startFlashTime", Time() )
+ RuiSetFloat3( file.cockpitRui, "flashColor", color )
+}
+
+void function UpdateHealthSegmentCount()
+{
+ if ( file.cockpitRui == null )
+ return
+
+ entity player = GetLocalViewPlayer()
+ string playerSettings = player.GetPlayerSettings()
+ float health = player.GetPlayerModHealth()
+ float healthPerSegment = GetPlayerSettingsFieldForClassName_HealthPerSegment( playerSettings )
+ RuiSetInt( file.cockpitRui, "numHealthSegments", int( health / healthPerSegment ) )
+}
+#if MP
+void function NetworkedVarChangedCallback_UpdateVanguardRUICoreStatus( entity soul, int oldValue, int newValue, bool actuallyChanged )
+{
+ if ( file.cockpitRui == null )
+ return
+
+ if ( actuallyChanged == false )
+ return
+
+ entity player = GetLocalViewPlayer()
+ if ( !IsValid( player ) || !player.IsTitan() )
+ return
+
+ UpdateHealthSegmentCount()
+
+ string titanName = GetTitanCharacterName( player )
+ if ( titanName == "vanguard" )
+ {
+ RuiSetString( file.cockpitRui, "titanInfo1", GetVanguardCoreString( player, 1 ) )
+ RuiSetString( file.cockpitRui, "titanInfo2", GetVanguardCoreString( player, 2 ) )
+ RuiSetString( file.cockpitRui, "titanInfo3", GetVanguardCoreString( player, 3 ) )
+ RuiSetString( file.cockpitRui, "titanInfo4", GetVanguardCoreString( player, 4 ) )
+ }
+}
+#endif
+
+var function Scorch_CreateHotstreakBar()
+{
+ Assert( file.scorchHotstreakRui == null )
+
+ file.scorchHotstreakRui = CreateFixedTitanCockpitRui( $"ui/scorch_hotstreak_bar.rpak" )
+
+ RuiTrackFloat( file.scorchHotstreakRui, "coreMeterMultiplier", GetLocalViewPlayer(), RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( "coreMeterModifier" ) )
+
+ return file.scorchHotstreakRui
+}
+
+void function Scorch_DestroyHotstreakBar()
+{
+ TitanCockpitDestroyRui( file.scorchHotstreakRui )
+ file.scorchHotstreakRui = null
+}
+
+bool function Scorch_ShouldCreateHotstreakBar()
+{
+ entity player = GetLocalViewPlayer()
+
+ if ( !IsAlive( player ) )
+ return false
+
+ array<entity> mainWeapons = player.GetMainWeapons()
+ if ( mainWeapons.len() == 0 )
+ return false
+
+ entity primaryWeapon = mainWeapons[0]
+ return primaryWeapon.HasMod( "fd_hot_streak" )
+}
diff --git a/Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut b/Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut
index 6d446654..0bcb7864 100644
--- a/Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut
+++ b/Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut
@@ -207,19 +207,9 @@
#endif // CLIENT && MP
#if UI
- struct
- {
- table MouseMovementCaptureFunctionsTable = {}
- } file
-
- const MOUSE_ROTATE_MULTIPLIER = 25.0
-
global function UpdateUIMapSupportsMenuModels
global function RunMenuClientFunction
global function UI_SetPresentationType
-
- global function AddMouseMovementCaptureHandler
- global function UICodeCallback_MouseMovementCapture
#endif // UI
global const STORE_BG_DEFAULT = 0
@@ -2897,30 +2887,4 @@
RunClientScript( "UpdateMenuToHarvester" )
}
}
-
- void function AddMouseMovementCaptureHandler( var menu, void functionref( int, int ) func )
- {
- file.MouseMovementCaptureFunctionsTable.rawset( menu, func )
- }
-
- void function UpdateMouseMovementCaptureFunctions( int deltaX, int deltaY )
- {
- var activeMenu = GetActiveMenu()
- if ( file.MouseMovementCaptureFunctionsTable.rawin( activeMenu ) )
- file.MouseMovementCaptureFunctionsTable.rawget( activeMenu )(deltaX, deltaY)
- }
-
- void function UICodeCallback_MouseMovementCapture( var capturePanel, int deltaX, int deltaY )
- {
- float screenScaleXModifier = 1920.0 / GetScreenSize()[0] // 1920 is base screen width
- float mouseXRotateDelta = deltaX * screenScaleXModifier * MOUSE_ROTATE_MULTIPLIER
- //printt( "deltaX:", deltaX, "deltaY:", deltaY )
-
- float screenScaleYModifier = 1080.0 / GetScreenSize()[1] // 1920 is base screen width
- float mouseYRotationDelta = deltaY * screenScaleYModifier * MOUSE_ROTATE_MULTIPLIER
-
- UpdateMouseMovementCaptureFunctions( deltaX, deltaY )
-
- RunMenuClientFunction( "UpdateMouseRotateDelta", mouseXRotateDelta, mouseYRotationDelta )
- }
#endif // UI
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut
index 930e472b..8e8071f5 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut
@@ -43,7 +43,7 @@ void function InitMapsMenu()
{
file.menu = GetMenu( "MapsMenu" )
- AddMouseMovementCaptureHandler( file.menu, UpdateMouseDeltaBuffer )
+ AddMouseMovementCaptureHandler( Hud_GetChild(file.menu, "MouseMovementCapture"), UpdateMouseDeltaBuffer )
AddMenuEventHandler( file.menu, eUIEvent.MENU_CLOSE, OnCloseMapsMenu )
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut
index 329ea73f..3f643aa3 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut
@@ -83,7 +83,7 @@ void function InitModMenu()
RuiSetImage( rui, "basicImage", $"ui/menu/common/dialog_error" )
}
- AddMouseMovementCaptureHandler( file.menu, UpdateMouseDeltaBuffer )
+ AddMouseMovementCaptureHandler( Hud_GetChild(file.menu, "MouseMovementCapture"), UpdateMouseDeltaBuffer )
// UI Events
AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnModMenuOpened )
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
index eb068374..03028255 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
@@ -38,7 +38,7 @@ enum sortingBy
PLAYERS,
MAP,
GAMEMODE,
- LATENCY
+ REGION
}
// Column sort direction, only one of these can be aplied at once
@@ -48,8 +48,8 @@ struct {
bool serverPlayers = true
bool serverMap = true
bool serverGamemode = true
- bool serverLatency = true
- // 0 = none; 1 = default; 2 = name; 3 = players; 4 = map; 5 = gamemode; 6 = latency
+ bool serverRegion = true
+ // 0 = none; 1 = default; 2 = name; 3 = players; 4 = map; 5 = gamemode; 6 = region
int sortingBy = 1
} filterDirection
@@ -61,7 +61,7 @@ struct serverStruct {
int serverPlayersMax
string serverMap
string serverGamemode
- int serverLatency
+ string serverRegion
}
struct {
@@ -87,7 +87,7 @@ struct {
array<var> serversProtected
array<var> serversMap
array<var> serversGamemode
- array<var> serversLatency
+ array<var> serversRegion
} file
@@ -142,7 +142,7 @@ void function InitServerBrowserMenu()
{
file.menu = GetMenu( "ServerBrowserMenu" )
- AddMouseMovementCaptureHandler( file.menu, UpdateMouseDeltaBuffer )
+ AddMouseMovementCaptureHandler( Hud_GetChild(file.menu, "MouseMovementCapture"), UpdateMouseDeltaBuffer )
// Get menu stuff
file.serverButtons = GetElementsByClassname( file.menu, "ServerButton" )
@@ -151,7 +151,7 @@ void function InitServerBrowserMenu()
file.serversProtected = GetElementsByClassname( file.menu, "ServerLock" )
file.serversMap = GetElementsByClassname( file.menu, "ServerMap" )
file.serversGamemode = GetElementsByClassname( file.menu, "ServerGamemode" )
- file.serversLatency = GetElementsByClassname( file.menu, "ServerLatency" )
+ file.serversRegion = GetElementsByClassname( file.menu, "Serverregion" )
filterArguments.filterMaps = [ "SWITCH_ANY" ]
Hud_DialogList_AddListItem( Hud_GetChild( file.menu, "SwtBtnSelectMap" ), "SWITCH_ANY", "0" )
@@ -194,7 +194,7 @@ void function InitServerBrowserMenu()
AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerPlayersTab"), UIE_CLICK, SortServerListByPlayers_Activate )
AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerMapTab"), UIE_CLICK, SortServerListByMap_Activate )
AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerGamemodeTab"), UIE_CLICK, SortServerListByGamemode_Activate )
- AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerLatencyTab"), UIE_CLICK, SortServerListByLatency_Activate )
+ AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerRegionTab"), UIE_CLICK, SortServerListByRegion_Activate )
AddButtonEventHandler( Hud_GetChild( file.menu, "SwtBtnSelectMap"), UIE_CHANGE, FilterAndUpdateList )
@@ -218,8 +218,6 @@ void function InitServerBrowserMenu()
Hud_SetText( Hud_GetChild( file.menu, "BtnServerDescription"), "" )
Hud_SetText( Hud_GetChild( file.menu, "BtnServerMods"), "" )
- // Unfinished features
- Hud_SetLocked( Hud_GetChild( file.menu, "BtnServerLatencyTab" ), true )
// Rui is a pain
RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnHideFull") ), "buttonText", "" )
@@ -675,9 +673,9 @@ void function FilterAndUpdateList( var n )
filterDirection.serverGamemode = !filterDirection.serverGamemode
SortServerListByGamemode_Activate(0)
break
- case sortingBy.LATENCY:
- filterDirection.serverLatency = !filterDirection.serverLatency
- SortServerListByLatency_Activate(0)
+ case sortingBy.REGION:
+ filterDirection.serverRegion = !filterDirection.serverRegion
+ SortServerListByRegion_Activate(0)
break
default:
printt( "How the f did you get here" )
@@ -715,7 +713,7 @@ void function WaitForServerListRequest()
Hud_SetText( file.playerCountLabels[ i ], "" )
Hud_SetText( file.serversMap[ i ], "" )
Hud_SetText( file.serversGamemode[ i ], "" )
- Hud_SetText( file.serversLatency[ i ], "" )
+ Hud_SetText( file.serversRegion[ i ], "" )
}
HideServerInfo()
@@ -756,6 +754,7 @@ void function FilterServerList()
tempServer.serverPlayersMax = NSGetServerMaxPlayerCount( i )
tempServer.serverMap = NSGetServerMap( i )
tempServer.serverGamemode = GetGameModeDisplayName( NSGetServerPlaylist ( i ) )
+ tempServer.serverRegion = NSGetServerRegion( i )
totalPlayers += tempServer.serverPlayers
@@ -786,6 +785,7 @@ void function FilterServerList()
sName.append( tempServer.serverGamemode.tolower() )
sName.append( Localize( tempServer.serverGamemode ).tolower() )
sName.append( NSGetServerDescription( i ).tolower() )
+ sName.append( NSGetServerRegion( i ).tolower() )
string sTerm = filterArguments.searchTerm.tolower()
@@ -821,7 +821,7 @@ void function UpdateShownPage()
Hud_SetText( file.playerCountLabels[ i ], "" )
Hud_SetText( file.serversMap[ i ], "" )
Hud_SetText( file.serversGamemode[ i ], "" )
- Hud_SetText( file.serversLatency[ i ], "" )
+ Hud_SetText( file.serversRegion[ i ], "" )
}
int j = file.serversArrayFiltered.len() > BUTTONS_PER_PAGE ? BUTTONS_PER_PAGE : file.serversArrayFiltered.len()
@@ -840,6 +840,7 @@ void function UpdateShownPage()
Hud_SetText( file.playerCountLabels[ i ], format( "%i/%i", file.serversArrayFiltered[ buttonIndex ].serverPlayers, file.serversArrayFiltered[ buttonIndex ].serverPlayersMax ) )
Hud_SetText( file.serversMap[ i ], GetMapDisplayName( file.serversArrayFiltered[ buttonIndex ].serverMap ) )
Hud_SetText( file.serversGamemode[ i ], file.serversArrayFiltered[ buttonIndex ].serverGamemode )
+ Hud_SetText( file.serversRegion[ i ], file.serversArrayFiltered[ buttonIndex ].serverRegion )
}
@@ -1161,10 +1162,10 @@ int function ServerSortLogic ( serverStruct a, serverStruct b )
bTemp = Localize( b.serverGamemode ).tolower()
direction = filterDirection.serverGamemode
break;
- case sortingBy.LATENCY:
- aTemp = a.serverLatency
- bTemp = b.serverLatency
- direction = filterDirection.serverLatency
+ case sortingBy.REGION:
+ aTemp = a.serverRegion
+ bTemp = b.serverRegion
+ direction = filterDirection.serverRegion
break;
default:
return 0
@@ -1238,13 +1239,13 @@ void function SortServerListByGamemode_Activate( var button )
UpdateShownPage()
}
-void function SortServerListByLatency_Activate( var button )
+void function SortServerListByRegion_Activate( var button )
{
- filterDirection.sortingBy = sortingBy.LATENCY
+ filterDirection.sortingBy = sortingBy.REGION
file.serversArrayFiltered.sort( ServerSortLogic )
- filterDirection.serverLatency = !filterDirection.serverLatency
+ filterDirection.serverRegion = !filterDirection.serverRegion
UpdateShownPage()
}
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/ui_mouse_capture.nut b/Northstar.Client/mod/scripts/vscripts/ui/ui_mouse_capture.nut
new file mode 100644
index 00000000..fa5c9217
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/ui_mouse_capture.nut
@@ -0,0 +1,60 @@
+untyped // untyped purely so I can index into a table with var
+
+global function AddMouseMovementCaptureHandler
+global function UICodeCallback_MouseMovementCapture
+
+struct
+{
+ // a table of capturePanels and menus, each of which contains an array of callbacks
+ table< var, array< void functionref( int deltaX, int deltaY ) > > mouseMovementCaptureCallbacks = {}
+} file
+
+// this function registers a callback (or "handler") function for a MouseMovementCapture menu panel
+// use this for scrollbars, sliders, etc.
+void function AddMouseMovementCaptureHandler( var capturePanelOrMenu, void functionref( int deltaX, int deltaY ) func )
+{
+ // if the capturePanel or menu already has an array in the table, we append to the array
+ // if not, we should create the array, [func] just turns func into an array
+ if ( capturePanelOrMenu in file.mouseMovementCaptureCallbacks )
+ file.mouseMovementCaptureCallbacks[capturePanelOrMenu].append( func )
+ else
+ file.mouseMovementCaptureCallbacks[capturePanelOrMenu] <- [func]
+}
+
+void function RunMouseMovementCallbacks( var capturePanelOrMenu, int deltaX, int deltaY )
+{
+ // check that the capturePanelOrMenu is in the table before trying anything stupid
+ if ( capturePanelOrMenu in file.mouseMovementCaptureCallbacks )
+ {
+ // iterate through the different callback functions
+ foreach ( void functionref( int deltaX, int deltaY ) callback in file.mouseMovementCaptureCallbacks[capturePanelOrMenu] )
+ {
+ // run the callback function
+ callback( deltaX, deltaY )
+ }
+ }
+}
+
+void function UICodeCallback_MouseMovementCapture( var capturePanel, int deltaX, int deltaY )
+{
+ // run callbacks for the capturePanel
+ RunMouseMovementCallbacks( capturePanel, deltaX, deltaY )
+
+ // get the current menu and run callbacks, this preserves backwards compatibility
+ RunMouseMovementCallbacks( GetActiveMenu(), deltaX, deltaY )
+
+ // everything below here originally existed in vanilla sh_menu_models.gnut and is meant to be used for like all of their rotation stuff
+ // its easier to move this here than to add a shared callback for all of the vanilla capture handlers (there are like >20)
+
+ // this const was moved instead of made global because it was literally only used in the code below
+ const MOUSE_ROTATE_MULTIPLIER = 25.0
+
+ float screenScaleXModifier = 1920.0 / GetScreenSize()[0] // 1920 is base screen width
+ float mouseXRotateDelta = deltaX * screenScaleXModifier * MOUSE_ROTATE_MULTIPLIER
+ //printt( "deltaX:", deltaX, "screenScaleModifier:", screenScaleModifier, "mouseRotateDelta:", mouseRotateDelta )
+
+ float screenScaleYModifier = 1080.0 / GetScreenSize()[1] // 1080 is base screen height
+ float mouseYRotationDelta = deltaY * screenScaleYModifier * MOUSE_ROTATE_MULTIPLIER
+
+ RunMenuClientFunction( "UpdateMouseRotateDelta", mouseXRotateDelta, mouseYRotationDelta )
+}