diff options
author | RoyalBlue1 <realEmail@veryRealURL.com> | 2023-01-15 15:59:08 +0100 |
---|---|---|
committer | RoyalBlue1 <realEmail@veryRealURL.com> | 2023-01-15 15:59:08 +0100 |
commit | bb8671eefc562fa76e13559915ae1ad493d06802 (patch) | |
tree | 40ac781a3422083ef2358ddf38da43e64462bbd0 /Northstar.Client/mod/scripts/vscripts | |
parent | cad416bc967bc4b902ff5808c0ae3281402d4895 (diff) | |
parent | 9bbe6832460aaabd96fef18d6e4ebb05779bb71d (diff) | |
download | NorthstarMods-bb8671eefc562fa76e13559915ae1ad493d06802.tar.gz NorthstarMods-bb8671eefc562fa76e13559915ae1ad493d06802.zip |
Merge remote-tracking branch 'upsteam/main' into gamemode_fd
Diffstat (limited to 'Northstar.Client/mod/scripts/vscripts')
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 ) +} |