From dae4a32f1c4b0f04a50fa462d00ce6ebee92b2ee Mon Sep 17 00:00:00 2001 From: JMM889901 <41163714+JMM889901@users.noreply.github.com> Date: Sat, 22 Oct 2022 03:43:16 +0100 Subject: Halfway decent fix to allow changing of minimap size and zoom midgame (#265) * Add files via upload * Added Getter functions * typo lol * Update cl_minimap.gnut * Mode select updated RegisterPlaylistBannerImage and GetPlaylistBannerImage had initially been in another file but that file is not present in r2northstar/client, not much point adding the entirety of menu_playlist here since for a few lines, this also wont modify mixtape but i don't think mixtape menu is used anywhere in northstar * Added rui since basic image cant handle callsigns added ``` NextModeImageCallsign //For calling card icons { ControlName RuiPanel // xpos -12 ypos -12 wide 480 tall 240 visible 1 scaleImage 1 zpos 2 pin_to_sibling NextModeImageFrame pin_corner_to_sibling BOTTOM pin_to_sibling_corner BOTTOM rui "ui/callsign_icon_button.rpak" //For callsign mode images } ``` * Revert "Added rui since basic image cant handle callsigns" This reverts commit b2623ec41ca944fc0ac3386ae0346464da07a8b3. * Revert "Mode select updated" This reverts commit 2c6f430775c84ef252402b6b447b01fd394459a9. --- .../mod/scripts/vscripts/client/cl_minimap.gnut | 942 +++++++++++++++++++++ 1 file changed, 942 insertions(+) create mode 100644 Northstar.Client/mod/scripts/vscripts/client/cl_minimap.gnut (limited to 'Northstar.Client/mod/scripts/vscripts/client') 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 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 > 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", ) + 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", ) + 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", ) + 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", ) + 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( , radius, duration, , count, reverse ) + else + Minimap_Ping( , radius, duration, , reverse ) +} -- cgit v1.2.3 From ef8a419edea010f39c35b913626c35900f052e2b Mon Sep 17 00:00:00 2001 From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com> Date: Mon, 31 Oct 2022 23:16:58 +0000 Subject: restore hud_takesshots functionality to automatically take screenshots of scoreboard (#522) * restore hud_takesshots functionality to take screenshots of scoreboard automatically * fixup some formatting --- Northstar.Client/mod/scripts/vscripts/client/cl_gamestate.gnut | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Northstar.Client/mod/scripts/vscripts/client') 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() { -- cgit v1.2.3 From 7c30c44d2bfea9cf64a374f690a23a6e6eb1165b Mon Sep 17 00:00:00 2001 From: Respawn Date: Sat, 12 Nov 2022 23:08:24 +0100 Subject: Add cl_titan_cockpit.nut from englishclient_mp_common --- .../scripts/vscripts/client/cl_titan_cockpit.nut | 1652 ++++++++++++++++++++ 1 file changed, 1652 insertions(+) create mode 100644 Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut (limited to 'Northstar.Client/mod/scripts/vscripts/client') 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..828f3056 --- /dev/null +++ b/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut @@ -0,0 +1,1652 @@ +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 +#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 titanCockpitManagedRUIs + + string lastPilotSettings + + bool isFirstBoot = true + var scorchHotstreakRui +} 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 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 = + + instrument1Origin = instrument1Origin - cameraOrigin + vector instrument1Position = + 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 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 ) +} + +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 ) + string result = "#COCKPIT_EJECT_RARE_" + index + return result + } + + int index = RandomInt( COCKPIT_EJECT_COMMON_COUNT ) + string result = "#COCKPIT_EJECT_COMMON_" + index + return result +} + +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 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 mainWeapons = player.GetMainWeapons() + if ( mainWeapons.len() == 0 ) + return false + + entity primaryWeapon = mainWeapons[0] + return primaryWeapon.HasMod( "fd_hot_streak" ) +} -- cgit v1.2.3 From 74f0ee8b5807e2c46541cdbc3460165200051b07 Mon Sep 17 00:00:00 2001 From: JMM889901 <41163714+JMM889901@users.noreply.github.com> Date: Sat, 12 Nov 2022 14:15:03 +0000 Subject: Add eject quotes (#527) * Upload cl_titan_cockpit.nut * Add eject string in script * Moved to client * index issue + removed else so always returns * Apply suggestions from code review Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> * Rest of the suggestions because github makes me want to cry * Commit suggestions from review GitHub really hates batching suggestions Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> --- .../scripts/vscripts/client/cl_titan_cockpit.nut | 35 ++++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'Northstar.Client/mod/scripts/vscripts/client') diff --git a/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut b/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut index 828f3056..4df1af42 100644 --- a/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut +++ b/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut @@ -36,6 +36,11 @@ 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 @@ -71,6 +76,9 @@ struct bool isFirstBoot = true var scorchHotstreakRui + // Added by northstar + array moddedRareEjectMessages + array moddedCommonEjectMessages } file function ClTitanCockpit_Init() @@ -1007,6 +1015,16 @@ void function PlayerPressed_Eject( entity player ) 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 @@ -1016,14 +1034,19 @@ string function RollRandomEjectString() float randForType = RandomFloat( 1.0 ) if ( randForType < CHANCE_FOR_RARE ) { - int index = RandomInt( COCKPIT_EJECT_RARE_COUNT ) - string result = "#COCKPIT_EJECT_RARE_" + index - return result + 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 ) - string result = "#COCKPIT_EJECT_COMMON_" + index - return result + 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] + } 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 -- cgit v1.2.3 From 17d8f97607f51e75497ed413d0d80f8416a2b3e6 Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Mon, 14 Nov 2022 22:22:52 +0000 Subject: Add missing `unreachable` to stop compile error (#528) --- Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut | 1 + 1 file changed, 1 insertion(+) (limited to 'Northstar.Client/mod/scripts/vscripts/client') diff --git a/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut b/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut index 4df1af42..8261b3fd 100644 --- a/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut +++ b/Northstar.Client/mod/scripts/vscripts/client/cl_titan_cockpit.nut @@ -1047,6 +1047,7 @@ string function RollRandomEjectString() 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 -- cgit v1.2.3