From 207facbc402f5639cbcd31f079214351ef605cf2 Mon Sep 17 00:00:00 2001 From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com> Date: Tue, 22 Jun 2021 14:30:49 +0100 Subject: initial commit after moving to new repo --- .../scripts/vscripts/_bobtestingfunctions_mp.gnut | 239 +++++++ .../scripts/vscripts/_bobtestingfunctions_sp.gnut | 13 + .../scripts/vscripts/lobby/sh_lobby.gnut | 356 ++++++++++ .../scripts/vscripts/mp/levels/mp_box.nut | 24 + .../scripts/vscripts/mp/sh_revive.gnut | 19 + .../scripts/vscripts/sh_bleedout_test.gnut | 34 + .../vscripts/sh_bobtestingfunctions_mp.gnut | 128 ++++ .../scripts/vscripts/sh_northstar_utils.gnut | 49 ++ bobthebob.testing/scripts/vscripts/ui/menu_dev.nut | 707 ++++++++++++++++++++ .../scripts/vscripts/ui/menu_map_select.nut | 200 ++++++ .../scripts/vscripts/ui/menu_mode_select.nut | 138 ++++ .../scripts/vscripts/ui/menu_team_titan_select.nut | 722 +++++++++++++++++++++ 12 files changed, 2629 insertions(+) create mode 100644 bobthebob.testing/scripts/vscripts/_bobtestingfunctions_mp.gnut create mode 100644 bobthebob.testing/scripts/vscripts/_bobtestingfunctions_sp.gnut create mode 100644 bobthebob.testing/scripts/vscripts/lobby/sh_lobby.gnut create mode 100644 bobthebob.testing/scripts/vscripts/mp/levels/mp_box.nut create mode 100644 bobthebob.testing/scripts/vscripts/mp/sh_revive.gnut create mode 100644 bobthebob.testing/scripts/vscripts/sh_bleedout_test.gnut create mode 100644 bobthebob.testing/scripts/vscripts/sh_bobtestingfunctions_mp.gnut create mode 100644 bobthebob.testing/scripts/vscripts/sh_northstar_utils.gnut create mode 100644 bobthebob.testing/scripts/vscripts/ui/menu_dev.nut create mode 100644 bobthebob.testing/scripts/vscripts/ui/menu_map_select.nut create mode 100644 bobthebob.testing/scripts/vscripts/ui/menu_mode_select.nut create mode 100644 bobthebob.testing/scripts/vscripts/ui/menu_team_titan_select.nut (limited to 'bobthebob.testing/scripts') diff --git a/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_mp.gnut b/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_mp.gnut new file mode 100644 index 000000000..b782243a4 --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_mp.gnut @@ -0,0 +1,239 @@ +untyped +globalize_all_functions + +void function SvTestingMPInit() +{ + Bleedout_Init() + AddCallback_EntitiesDidLoad( CreateSpawns ) +} + +void function CreateSpawns() +{ + //thread CreateSpawns_Threaded() +} + +void function CreateSpawns_Threaded() +{ + WaitEndFrame() // wait for spawns to get cleared, game ctds if we don't do this + entity validSpawn = GetEntArrayByClass_Expensive( "info_spawnpoint_human" )[ 0 ] + + for ( int i = 0; i < 50; i++ ) + { + entity newSpawn = CreateEntity( "info_spawnpoint_human" ) + newSpawn.SetOrigin( validSpawn.GetOrigin() ) + DispatchSpawn( newSpawn ) + } +} + +void function TestSpawnpoints( bool titan = false ) +{ + entity player = GetPlayerArray()[0] + array spawnpoints + if ( !titan ) + spawnpoints = SpawnPoints_GetPilotStart( player.GetTeam() ) + else + spawnpoints = SpawnPoints_GetTitanStart( player.GetTeam() ) + + SpawnPoints_InitRatings( player, player.GetTeam() ) + + foreach ( entity spawnpoint in spawnpoints ) + spawnpoint.CalculateRating( titan ? TD_TITAN : TD_PILOT, player.GetTeam(), RandomFloat( 7.0 ) - 3.5, RandomFloat( 7.0 ) - 3.5 ) + + if ( !titan ) + { + SpawnPoints_SortPilotStart() + spawnpoints = SpawnPoints_GetPilotStart( player.GetTeam() ) + } + else + { + SpawnPoints_SortTitanStart() + spawnpoints = SpawnPoints_GetTitanStart( player.GetTeam() ) + } + + entity chosenPoint + foreach ( entity spawnpoint in spawnpoints ) + if ( IsSpawnpointValid( spawnpoint, player.GetTeam() ) ) + { + chosenPoint = spawnpoint + break + } + + player.SetOrigin( chosenPoint.GetOrigin() ) + player.SetAngles( chosenPoint.GetAngles() ) + + //SpawnPoints_DiscardRatings() // somehow the game seems to call this automatically so unneeded +} + +bool function IsSpawnpointValid( entity spawnpoint, int team ) +{ + if ( GameModeRemove( spawnpoint ) ) + return false + + // ultra temp + print( spawnpoint.GetTeam() ) + if ( spawnpoint.GetTeam() == 0 ) + return false + + if ( spawnpoint.GetTeam() > 0 && spawnpoint.GetTeam() != team ) + return false + + + + return true +} + +void function TestScoreEvent( entity player, int id ) +{ + ScoreEvent event = ScoreEvent_FromId( id ) + + Remote_CallFunction_NonReplay( player, "ServerCallback_ScoreEvent", id, event.pointValue, event.displayType, player.GetEncodedEHandle(), event.earnMeterOwnValue, event.earnMeterEarnValue ) +} + +void function TestDrop( entity player ) +{ + thread CreateTitanForPlayerAndHotdrop( player, GetTitanReplacementPoint( player, false ) ) +} + +void function WarpThroughSpawnpoints( string modeOverride = "" ) +{ + if ( !modeOverride.len() ) + modeOverride = GAMETYPE + + entity player = GetPlayerArray()[0] + + array spawnpoints = GetEntArrayByClass_Expensive( "info_hardpoint" ) //SpawnPoints_GetPilot() + foreach ( entity spawnpoint in spawnpoints ) + { + //string gamemodeKey = "gamemode_" + modeOverride + //if ( spawnpoint.HasKey( gamemodeKey ) && ( spawnpoint.kv[ gamemodeKey ] == "0" || spawnpoint.kv[ gamemodeKey ] == "" ) ) + // continue + // + //if ( !spawnpoint.HasKey( gamemodeKey ) ) + // continue + + if ( spawnpoint.HasKey( "hardpointGroup" ) ) + print( spawnpoint.kv.hardpointGroup ) + + player.SetOrigin( spawnpoint.GetOrigin() ) + player.SetAngles( spawnpoint.GetAngles() ) + + wait 0.5 + } +} + +void function AttemptSpawnBuddyTitan() +{ + PrecacheModel( $"models/titans/buddy/titan_buddy.mdl" ) + PrecacheModel( $"models/weapons/arms/buddypov.mdl" ) + + entity player = GetPlayerArray()[0] + entity titan = CreateNPCTitan( "titan_buddy", player.GetTeam(), player.GetOrigin(), <0, 0, 0> ) + SetSpawnOption_AISettings( titan, "npc_titan_buddy" ) + SetSpawnOption_Weapon( titan, "mp_titanweapon_xo16_vanguard", [ ] ) + + DispatchSpawn( titan ) + + player.SetPetTitan( titan ) + titan.SetOwner( player ) + titan.SetUsable() +} + + +void function SetPlayerCameraToHead() +{ + entity viewControl = CreateEntity( "point_viewcontrol" ) + viewControl.kv.spawnflags = 56 + DispatchSpawn( viewControl ) + + viewControl.SetParent( GetPlayerArray()[0], "headshot" ) + viewControl.SetOrigin( < 4, 0, 1 > ) + viewControl.SetAngles( < 0, 0, 0 > ) + GetPlayerArray()[0].SetViewEntity( viewControl, true ) +} + +void function CreateTestControlPanel() +{ + entity player = GetPlayerArray()[0] + + entity panel = CreateEntity( "prop_control_panel" ) + panel.SetValueForModelKey( $"models/communication/terminal_usable_imc_01.mdl" ) + panel.SetOrigin( player.GetOrigin() ) + panel.SetAngles( player.GetAngles() ) + panel.kv.solid = SOLID_VPHYSICS + SetTargetName( panel, "cpanel" ) + DispatchSpawn( panel ) + + panel.SetModel( $"models/communication/terminal_usable_imc_01.mdl" ) + panel.s.onPlayerFinishesUsing_func = TestOnPanelHacked + +} + +function TestOnPanelHacked( panel, player, success ) +{ + expect entity( panel ) + expect entity( player ) + expect bool( success ) + + if ( !success ) + return + + print( panel + " was hacked by " + player ) + PanelFlipsToPlayerTeamAndUsableByEnemies( panel, player ) +} + +void function TestFastball() +{ + PrecacheModel( $"models/titans/buddy/titan_buddy.mdl" ) + RegisterSignal( "fastball_start_throw" ) + RegisterSignal( "fastball_release" ) + PrecacheParticleSystem( $"P_BT_eye_SM" ) + + entity player = GetPlayerArray()[0] + + entity prop = CreatePropDynamic( $"models/titans/buddy/titan_buddy.mdl", player.GetOrigin(), player.GetAngles() ) + thread PlayAnim( prop, "bt_beacon_fastball_throw_end" ) + + player.ContextAction_SetFastball() + FirstPersonSequenceStruct throwSequence + throwSequence.attachment = "REF" + throwSequence.useAnimatedRefAttachment = true + throwSequence.hideProxy = true + throwSequence.firstPersonAnim = "ptpov_beacon_fastball_throw_end" + //throwSequence.thirdPersonAnim = "pt_beacon_fastball_throw_end" + throwSequence.firstPersonBlendOutTime = 0.0 + + thread FirstPersonSequence( throwSequence, player, prop ) + player.HolsterWeapon() + + EmitSoundOnEntityOnlyToPlayer( player, player, "Music_Beacon_14_BTThrowThruFirstCrane" ) + + prop.WaitSignal( "fastball_start_throw" ) + float duration = EmitSoundOnEntity( prop, "diag_sp_spoke1_BE117_04_01_mcor_bt" ) // trust me + vector eyeAngles = player.EyeAngles() + + // particle effect + StartParticleEffectOnEntity( prop, GetParticleSystemIndex( $"P_BT_eye_SM" ), FX_PATTACH_POINT_FOLLOW, prop.LookupAttachment( "EYEGLOW" ) ) + wait duration + + prop.WaitSignal( "fastball_release" ) + player.ContextAction_ClearFastball() + player.ClearParent() + ClearPlayerAnimViewEntity( player ) + player.SetVelocity( AnglesToForward( eyeAngles ) * 1250 ) + player.DeployWeapon() + + wait 0.5 + prop.Destroy() +} + +void function TestPlanetExplosion() // won't look good until we can load textures from rpak for these models +{ + PrecacheModel( $"models/vistas/planet_ex_static.mdl" ) + PrecacheModel( $"models/vistas/planet_explosion_animated.mdl" ) + + entity cam = GetEnt( "skybox_cam_level" ) + cam.SetOrigin( < 7000, 7000, 7000 > ) // arbitrary point + CreatePropDynamic( $"models/vistas/planet_ex_static.mdl", cam.GetOrigin(), cam.GetAngles() ) + entity explosion = CreatePropDynamic( $"models/vistas/planet_explosion_animated.mdl", cam.GetOrigin(), cam.GetAngles() ) + thread PlayAnim( explosion, "planet_ex_ending" ) +} \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_sp.gnut b/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_sp.gnut new file mode 100644 index 000000000..2ad814fe2 --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_sp.gnut @@ -0,0 +1,13 @@ +globalize_all_functions + +void function TestPlanetExplosion() +{ + PrecacheModel( $"models/vistas/planet_ex_static.mdl" ) + PrecacheModel( $"models/vistas/planet_explosion_animated.mdl" ) + + entity cam = GetEnt( "skybox_cam_level" ) + cam.SetOrigin( < 7000, 7000, 7000 > ) // arbitrary point + CreatePropDynamic( $"models/vistas/planet_ex_static.mdl", cam.GetOrigin(), cam.GetAngles() ) + entity explosion = CreatePropDynamic( $"models/vistas/planet_explosion_animated.mdl", cam.GetOrigin(), cam.GetAngles() ) + thread PlayAnim( explosion, "planet_ex_ending" ) +} \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/lobby/sh_lobby.gnut b/bobthebob.testing/scripts/vscripts/lobby/sh_lobby.gnut new file mode 100644 index 000000000..24436017f --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/lobby/sh_lobby.gnut @@ -0,0 +1,356 @@ +globalize_all_functions + +const string PRIVATE_MATCH_PLAYLIST = "private_match" + +struct { + array modes = [ // default modes in vanilla + "aitdm", + "tdm", + "cp", + "at", + "ctf", + "lts", + "ps", + "speedball", + "mfd", + "ttdm", + "fd_easy", + "fd_normal", + "fd_hard", + "fd_master", + "fd_insane" + ] + + array maps = [ // default maps in vanilla + "mp_forwardbase_kodai", + "mp_grave", + "mp_homestead", + "mp_thaw", + "mp_black_water_canal", + "mp_eden", + "mp_drydock", + "mp_crashsite3", + "mp_complex3", + "mp_angel_city", + "mp_colony02", + "mp_glitch", + "mp_relic02", + "mp_wargames", + "mp_rise", + "mp_lf_stacks", + "mp_lf_deck", + "mp_lf_meadow", + "mp_lf_traffic", + "mp_lf_township", + "mp_lf_uma" + ] +} file + +void function AddPrivateMatchMode( string mode ) +{ + if ( !file.modes.contains( mode ) ) + file.modes.append( mode ) + + #if CLIENT + // call this on ui too so the client and ui states are the same + RunUIScript( "AddPrivateMatchMode", mode ) + #endif +} + +void function AddPrivateMatchMap( string map ) +{ + if ( !file.maps.contains( map ) ) + file.maps.append( map ) + + #if CLIENT + // call this on ui too so the client and ui states are the same + RunUIScript( "AddPrivateMatchMap", map ) + #endif +} + +array function GetPrivateMatchModes() +{ + //array modesArray + // + //int numModes = GetPlaylistGamemodesCount( PRIVATE_MATCH_PLAYLIST ) + //for ( int modeIndex = 0; modeIndex < numModes; modeIndex++ ) + //{ + // modesArray.append( GetPlaylistGamemodeByIndex( PRIVATE_MATCH_PLAYLIST, modeIndex ) ) + //} + + //return modesArray + + return file.modes +} + +int function GetPrivateMatchModeIndex( string modeName ) +{ + //int indexForName = 0 + // + //int numModes = GetPlaylistGamemodesCount( PRIVATE_MATCH_PLAYLIST ) + //for ( int modeIndex = 0; modeIndex < numModes; modeIndex++ ) + //{ + // if ( GetPlaylistGamemodeByIndex( PRIVATE_MATCH_PLAYLIST, modeIndex ) != modeName ) + // continue + // + // indexForName = modeIndex; + // break + //} + // + //return indexForName + + return file.modes.find( modeName ) +} + + +array function GetPrivateMatchMapsForMode( string modeName ) +{ + //array mapsArray + // + //int modeIndex = GetPrivateMatchModeIndex( modeName ) + //int numMaps = GetPlaylistGamemodeByIndexMapsCount( PRIVATE_MATCH_PLAYLIST, modeIndex ) + //for ( int mapIndex = 0; mapIndex < numMaps; mapIndex++ ) + //{ + // mapsArray.append( GetPlaylistGamemodeByIndexMapByIndex( PRIVATE_MATCH_PLAYLIST, modeIndex, mapIndex ) ) + //} + // + //return mapsArray + + array maps + + // use the private match playlist for this if the gamemode is in it already + int privatePlaylistModeIndex = GetPrivateMatchModeIndex( modeName ) + if ( privatePlaylistModeIndex < GetPlaylistGamemodesCount( PRIVATE_MATCH_PLAYLIST ) ) + { + for ( int i = 0; i < GetPlaylistGamemodeByIndexMapsCount( PRIVATE_MATCH_PLAYLIST, privatePlaylistModeIndex ); i++ ) + maps.append( GetPlaylistGamemodeByIndexMapByIndex( PRIVATE_MATCH_PLAYLIST, privatePlaylistModeIndex, i ) ) + } + else + { + int numMaps = GetPlaylistGamemodeByIndexMapsCount( modeName, 0 ) + for ( int i = 0; i < numMaps; i++ ) + maps.append( GetPlaylistGamemodeByIndexMapByIndex( modeName, 0, i ) ) + } + + return maps +} + +// never called +/*array function GetPrivateMatchModesForMap( string mapName ) +{ + array modesArray + + int numModes = GetPlaylistGamemodesCount( PRIVATE_MATCH_PLAYLIST ) + for ( int modeIndex = 0; modeIndex < numModes; modeIndex++ ) + { + int numMaps = GetPlaylistGamemodeByIndexMapsCount( PRIVATE_MATCH_PLAYLIST, modeIndex ) + for ( int mapIndex = 0; mapIndex < numMaps; mapIndex++ ) + { + if ( GetPlaylistGamemodeByIndexMapByIndex( PRIVATE_MATCH_PLAYLIST, modeIndex, mapIndex ) != mapName ) + continue + + modesArray.append( GetPlaylistGamemodeByIndex( PRIVATE_MATCH_PLAYLIST, modeIndex ) ) + } + } + + return modesArray +}*/ + + +string function GetPrivateMatchMapForIndex( int index ) +{ + array mapsArray = GetPrivateMatchMaps() + + if ( index >= mapsArray.len() ) + return "" + + return mapsArray[index] +} + +string function GetPrivateMatchModeForIndex( int index ) +{ + array modesArray = GetPrivateMatchModes() + + if ( index >= modesArray.len() ) + return "" + + return modesArray[index] +} + +int function GetPrivateMatchMapIndex( string mapName ) +{ + array mapsArray = GetPrivateMatchMaps() + for ( int index = 0; index < mapsArray.len(); index++ ) + { + if ( mapsArray[index] == mapName ) + return index + } + + return 0 +} +/* +int function GetPrivateMatchModeIndex( string modeName ) +{ + array modesArray = GetPrivateMatchModes() + for ( int index = 0; index < modesArray.len(); index++ ) + { + if ( modesArray[index] == modeName ) + return index + } + + return 0 +} +*/ + +array function GetPrivateMatchMaps() +{ + //array mapsArray + // + //int numModes = GetPlaylistGamemodesCount( PRIVATE_MATCH_PLAYLIST ) + //for ( int modeIndex = 0; modeIndex < numModes; modeIndex++ ) + //{ + // int numMaps = GetPlaylistGamemodeByIndexMapsCount( PRIVATE_MATCH_PLAYLIST, modeIndex ) + // for ( int mapIndex = 0; mapIndex < numMaps; mapIndex++ ) + // { + // string mapName = GetPlaylistGamemodeByIndexMapByIndex( PRIVATE_MATCH_PLAYLIST, modeIndex, mapIndex ) + // if ( mapsArray.contains( mapName ) ) + // continue + // + // mapsArray.append( mapName ) + // } + //} + // + //return mapsArray + + return file.maps +} + + + +array function GetPlaylistMaps( string playlistName ) +{ + array mapsArray + + int numModes = GetPlaylistGamemodesCount( playlistName ) + for ( int modeIndex = 0; modeIndex < numModes; modeIndex++ ) + { + int numMaps = GetPlaylistGamemodeByIndexMapsCount( playlistName, modeIndex ) + for ( int mapIndex = 0; mapIndex < numMaps; mapIndex++ ) + { + string mapName = GetPlaylistGamemodeByIndexMapByIndex( playlistName, modeIndex, mapIndex ) + if ( mapsArray.contains( mapName ) ) + continue + + mapsArray.append( mapName ) + } + } + + return mapsArray +} + + +bool function MapSettings_SupportsTitans( string mapName ) +{ + if ( mapName.find( "mp_lf_") != null ) + return false + + if ( mapName.find( "coliseum" ) != null ) + return false; + + return true +} + +bool function MapSettings_SupportsAI( string mapName ) +{ + if ( mapName.find( "mp_lf_") != null ) + return false + + if ( mapName.find( "coliseum" ) != null ) + return false; + + return true +} + + +bool function ModeSettings_RequiresTitans( string modeName ) +{ + switch ( modeName ) + { + case "lts": + return true + } + + return false +} + +bool function ModeSettings_RequiresAI( string modeName ) +{ + switch ( modeName ) + { + case "aitdm": + case "at": + return true + } + + return false +} + +#if !CLIENT +string function PrivateMatch_GetSelectedMap() +{ + var mapIndex = level.ui.privatematch_map + string mapName = GetPrivateMatchMapForIndex( expect int(mapIndex) ) + + return mapName +} + + +string function PrivateMatch_GetSelectedMode() +{ + var modeIndex = level.ui.privatematch_mode + string modeName = GetPrivateMatchModeForIndex( expect int(modeIndex) ) + + return modeName +} +#endif + +bool function PrivateMatch_IsValidMapModeCombo( string mapName, string modeName ) +{ + array mapsForMode = GetPrivateMatchMapsForMode( modeName ) + + return mapsForMode.contains( mapName ) +} + +// end private match stuff + +int function Player_GetMaxMatchmakingDelay( entity player ) +{ + // return GetCurrentPlaylistVarInt( "matchmaking_delay", 0 ) + return 300 +} + +int function Player_GetRemainingMatchmakingDelay( entity player ) +{ + int lastLeaveTime = player.GetPersistentVarAsInt( PERSISTENCE_LAST_LEAVE_TIME ) + + return Player_GetMaxMatchmakingDelay( player ) - (GetCurrentTimeForPersistence() - lastLeaveTime) +} + +int function Player_NextAvailableMatchmakingTime( entity player ) +{ + #if MP + int lastLeaveTime = player.GetPersistentVarAsInt( PERSISTENCE_LAST_LEAVE_TIME ) + if ( GetCurrentTimeForPersistence() - lastLeaveTime < Player_GetMaxMatchmakingDelay( player ) ) + { + return Player_GetRemainingMatchmakingDelay( player ) + } + #endif + + return 0 +} + +int function GetCurrentTimeForPersistence() +{ + // Returns the unix timestap offset to the timezone we want to use + return GetUnixTimestamp() + DAILY_RESET_TIME_ZONE_OFFSET * SECONDS_PER_HOUR +} diff --git a/bobthebob.testing/scripts/vscripts/mp/levels/mp_box.nut b/bobthebob.testing/scripts/vscripts/mp/levels/mp_box.nut new file mode 100644 index 000000000..aa94be52f --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/mp/levels/mp_box.nut @@ -0,0 +1,24 @@ +/*global function CodeCallback_MapInit +global function SpawnGamemodeObjects + +void function CodeCallback_MapInit() +{ + AddCallback_EntitiesDidLoad( SpawnGamemodeObjects ) +} + +void function SpawnGamemodeObjects() +{ + thread SpawnGamemodeObjects_Threaded() + +} + +void function SpawnGamemodeObjects_Threaded() +{ + WaitEndFrame() + entity liveFireFlagSpawn = CreateEntity( "script_ref" ) + liveFireFlagSpawn.kv.editorclass = "info_speedball_flag" + liveFireFlagSpawn.kv.origin = < 0.0, -382.0, 60.0 > + liveFireFlagSpawn.kv.angles = < 0, 0, 0 > + DispatchSpawn( liveFireFlagSpawn ) + liveFireFlagSpawn.kv.editorclass = "info_speedball_flag" +}*/ \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/mp/sh_revive.gnut b/bobthebob.testing/scripts/vscripts/mp/sh_revive.gnut new file mode 100644 index 000000000..8caa2a821 --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/mp/sh_revive.gnut @@ -0,0 +1,19 @@ +#if SERVER +global const REVIVE_ENABLED = true // currently not used anywhere +global function ReviveEnabled + +bool function ReviveEnabled() +{ + return GetCurrentPlaylistVarInt( "player_revive_enabled", 0 ) == 1 +} +#elseif true +global const REVIVE_ENABLED = false // currently not used anywhere +global function ReviveEnabled + +bool function ReviveEnabled() +{ + // client version of this doesn't work lol + return false + //return GetCurrentPlaylistVarInt( "player_revive_enabled", 0 ) == 1 +} +#endif \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/sh_bleedout_test.gnut b/bobthebob.testing/scripts/vscripts/sh_bleedout_test.gnut new file mode 100644 index 000000000..42727adc4 --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/sh_bleedout_test.gnut @@ -0,0 +1,34 @@ +global function BleedoutTest_Init + +void function BleedoutTest_Init() +{ + return // not in use rn + + AddCallback_OnRegisteringCustomNetworkVars( RegisterBleedoutVars ) + + BleedoutShared_Init( 30.0, 3.0, -1.0, 1.0, 0.0, false, false ) + + #if SERVER + Bleedout_Init() + if ( ReviveEnabled() ) + AddCallback_OnPlayerKilled( StartRevive ) + #elseif CLIENT + BleedoutClient_Init() + #endif +} + +#if SERVER +void function StartRevive( entity victim, entity attacker, var damageInfo ) +{ + DeathPackage_PlayerRevive( victim ) + thread PlayerRevivesOrBleedsOut( victim ) +} +#endif + +void function RegisterBleedoutVars() +{ + Remote_RegisterFunction( "ServerCallback_BLEEDOUT_StartFirstAidProgressBar" ) + Remote_RegisterFunction( "ServerCallback_BLEEDOUT_StopFirstAidProgressBar" ) + Remote_RegisterFunction( "ServerCallback_BLEEDOUT_ShowWoundedMarker" ) + Remote_RegisterFunction( "ServerCallback_BLEEDOUT_HideWoundedMarker" ) +} \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/sh_bobtestingfunctions_mp.gnut b/bobthebob.testing/scripts/vscripts/sh_bobtestingfunctions_mp.gnut new file mode 100644 index 000000000..124c7a541 --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/sh_bobtestingfunctions_mp.gnut @@ -0,0 +1,128 @@ +globalize_all_functions + +void function DumpPdefEnum( string pdefEnum ) +{ + for ( int i = 0; i < PersistenceGetEnumCount( pdefEnum ); i++ ) + print( PersistenceGetEnumItemNameForIndex( pdefEnum, i ) ) +} + +void function ListPlayers() +{ + foreach ( entity player in GetPlayerArray() ) + { + if ( player == null ) + continue + + print( "player " + player.GetPlayerName() + ": G" + player.GetGen() + "." + player.GetLevel() ) + } +} + +void function DumpPdefTable() +{ + foreach ( key0, value0 in shGlobalMP.playerStatVars ) + { + foreach ( key1, value1 in value0 ) + { + foreach ( key2, statData in value1 ) + { + print ( statData.statVar ) + } + } + } +} + +void function DumpModels() +{ + for ( int i = 0; i < 2048; i++ ) + if ( GetEntByIndex( i ) != null && GetEntByIndex( i ).GetModelName() != $"?" ) + print( i + ": " + GetEntByIndex( i ).GetModelName() ) +} + +void function DumpScoreEvents() +{ + int i = 0; + while ( true ) + { + ScoreEvent event + try event = ScoreEvent_FromId( i ) catch ( exception ) break + + print( "event " + i + ":" ) + print( "name: " + event.name ) + print( "splashText: " + event.splashText ) + + // get string representation of displaytype + // if squirrel has a better way to do this i don't know it + string displayType + + if ( event.displayType & eEventDisplayType.HIDDEN ) + displayType += "HIDDEN, " + if ( event.displayType & eEventDisplayType.CENTER ) + displayType += "CENTER, " + if ( event.displayType & eEventDisplayType.MEDAL ) + displayType += "MEDAL, " + if ( event.displayType & eEventDisplayType.CALLINGCARD ) + displayType += "CALLINGCARD, " + if ( event.displayType & eEventDisplayType.ATTRITION ) + displayType += "ATTRITION, " + if ( event.displayType & eEventDisplayType.BIG ) + displayType += "BIG, " + if ( event.displayType & eEventDisplayType.GAMEMODE ) + displayType += "GAMEMODE, " + if ( event.displayType & eEventDisplayType.CHALLENGE ) + displayType += "CHALLENGE, " + if ( event.displayType & eEventDisplayType.MEDAL_FORCED ) + displayType += "MEDAL_FORCED, " + if ( event.displayType & eEventDisplayType.SHOW_SCORE ) + displayType += "SHOW_SCORE, " + + print( "displayType: " + displayType ) + print( " " ) // newline + + i++ + } + + print( "got " + i + " events!" ) +} + +void function DumpConversations() +{ + foreach ( string k, v in GetConversationToIndexTable() ) + print( k ) +} + +#if CLIENT +void function TestMarkRUI() +{ + var rui = CreateCockpitRui( $"ui/speedball_flag_marker.rpak", 200 ) + RuiSetBool( rui, "isVisible", true ) + RuiSetFloat3( rui, "pos", GetLocalViewPlayer().GetOrigin() ) + RuiSetBool( rui, "playerIsCarrying", false ) + RuiSetInt( rui, "teamRelation", TEAM_IMC ) + RuiSetBool( rui, "isCarried", false ) +} + +void function TestObjectiveRUIHunted() +{ + var rui = CreateCockpitRui( $"ui/hunted_objective.rpak", 200 ) + RuiSetGameTime( rui, "startTime", Time() ) + RuiSetGameTime( rui, "endTime", Time() + 20.0 ) + RuiSetString( rui, "objectiveTitleText", "#HUNTED_OBJECTIVE_TITLE" ) + RuiSetFloat( rui, "blingDuration", 5.0 ) + RuiSetBool( rui, "showAll", true ) +} + +void function TestObjectiveRUIFW() +{ + var rui = CreateCockpitRui( $"ui/fw_objective_text.rpak" ) + RuiSetString( rui, "objective", "deez nuts" ) + + float time = Time() + 10.0 + while ( time > Time() ) + { + RuiSetString( rui, "objective", "deez nuts " + ( time - Time() ) ) + WaitFrame() + } + + RuiDestroy( rui ) +} +#endif \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/sh_northstar_utils.gnut b/bobthebob.testing/scripts/vscripts/sh_northstar_utils.gnut new file mode 100644 index 000000000..15eed9b21 --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/sh_northstar_utils.gnut @@ -0,0 +1,49 @@ +globalize_all_functions + +enum eNorthstarLobbyType +{ + PrivateMatchLobby, // normal vanilla private lobby + IntermissionLobby, // similar to tf1's intermission lobby, chooses next map automatically + CompetitiveLobby // similar to vanilla privates, but with ready up system +} + +// whether the server is a modded, northstar server +bool function IsNorthstarServer() +{ + bool isModded = true // TEMP for testing + try + { + // need this in a trycatch because the var might not exist atm + isModded = GetConVarInt( "northstar_is_modded_server" ) == 1 + } catch ( ex ) {} + + return isModded +} + +// whether the game should return to the lobby on GameRules_EndMatch() +bool function ShouldReturnToLobby() +{ + bool shouldReturnToLobby = false + try + { + // need this in a trycatch because the var might not exist atm + shouldReturnToLobby = GetConVarInt( "northstar_should_return_to_lobby" ) == 1 + } catch ( ex ) {} + + return shouldReturnToLobby +} + +int function GetNorthstarLobbyType() +{ + if ( !IsNorthstarServer() ) + return eNorthstarLobbyType.PrivateMatchLobby + + int lobbyType = eNorthstarLobbyType.PrivateMatchLobby + try + { + // need this in a trycatch because the var might not exist atm + lobbyType = GetConVarInt( "northstar_lobby_type" ) + } catch ( ex ) {} + + return lobbyType +} \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/ui/menu_dev.nut b/bobthebob.testing/scripts/vscripts/ui/menu_dev.nut new file mode 100644 index 000000000..d9b9234b4 --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/ui/menu_dev.nut @@ -0,0 +1,707 @@ +untyped + +global function InitDevMenu +global function GetActionBlocks +global function SetDevMenu_SinglePlayer +global function SetupDevCommand // for dev +global function SetupDevFunc // for dev +global function SetDevMenu_SpawnNPCWithWeapon +global function RepeatLastDevCommand +global function SetDevMenu_ArmedNPC +global function UpdatePrecachedSPWeapons + +struct DevCommand +{ + string label + string command + var opParm + void functionref( var ) func + bool storeAsLastCommand = true +} + + +struct +{ + void functionref() devMenuFunc + void functionref( var ) devMenuFuncWithOpParm + var devMenuOpParm + array buttons + array actionBlocks + array devCommands + DevCommand& lastDevCommand + bool lastDevCommandAssigned + bool precachedWeapons +} file + +void function OnOpenDevMenu() +{ + file.devMenuFunc = null + file.devMenuFuncWithOpParm = null + file.devMenuOpParm = null + if ( IsMultiplayer() ) + SetDevMenu_MP() + else + SetDevMenu_Default() +} + +void function InitDevMenu() +{ + var menu = GetMenu( "DevMenu" ) + + AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnOpenDevMenu ) + + + AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT" ) + AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + + OnOpenDevMenu() + + file.buttons = GetElementsByClassname( menu, "DevButtonClass" ) + foreach ( button in file.buttons ) + { + Hud_AddEventHandler( button, UIE_CLICK, OnDevButton_Activate ) + + RuiSetString( Hud_GetRui( button ), "buttonText", "" ) + Hud_SetEnabled( button, false ) + } + +} + +function UpdateDevMenuButtons() +{ + file.devCommands.clear() + if ( developer() == 0 ) + return + + if ( file.devMenuOpParm != null ) + file.devMenuFuncWithOpParm( file.devMenuOpParm ) + else + file.devMenuFunc() + + foreach ( index, button in file.buttons ) + { + int buttonID = int( Hud_GetScriptID( button ) ) + + if ( buttonID < file.devCommands.len() ) + { + RuiSetString( Hud_GetRui( button ), "buttonText", file.devCommands[buttonID].label ) + Hud_SetEnabled( button, true ) + } + else + { + RuiSetString( Hud_GetRui( button ), "buttonText", "" ) + Hud_SetEnabled( button, false ) + } + } +} + +void function SetDevMenu_Default() +{ + file.devMenuFunc = SetupDefaultDevCommands + UpdateDevMenuButtons() +} + + +void function SetDevMenu_MP() +{ + file.devMenuFunc = SetupDefaultDevCommandsMP + UpdateDevMenuButtons() +} + +void function ChangeToThisMenu( void functionref() menuFunc ) +{ + file.devMenuFunc = menuFunc + file.devMenuFuncWithOpParm = null + file.devMenuOpParm = null + UpdateDevMenuButtons() +} + +void function ChangeToThisMenu_WithOpParm( void functionref( var ) menuFuncWithOpParm, opParm = null ) +{ + file.devMenuFunc = null + file.devMenuFuncWithOpParm = menuFuncWithOpParm + file.devMenuOpParm = opParm + UpdateDevMenuButtons() +} + +void function SetDevMenu_SinglePlayer( var _ ) +{ + CloseAllInGameMenus() + AdvanceMenu( GetMenu( "SinglePlayerDevMenu" ), true ) +} + +void function SetupDefaultDevCommands() +{ + SetupDevFunc( "Frontier Defense", SetDevMenu_FrontierDefense ) + // SetupDevFunc( "Difficulty", SetDevMenu_Difficulty ) + SetupDevFunc( "Single Player", SetDevMenu_SinglePlayer ) + if ( GetStartPointsForMap( GetActiveLevel() ).len() ) + { + SetupDevFunc( "Start Points", SetDevMenu_StartPoints ) + } + SetupDevFunc( "Level Commands", SetDevMenu_LevelCommands ) + + SetupRepeatLastDevCommand() + SetupDevFunc( "Spawn IMC NPC", SetDevMenu_AISpawn, 2 ) + SetupDevFunc( "Spawn IMC Boss Titan", SetDevMenu_BossTitans ) + SetupDevFunc( "Spawn Militia NPC", SetDevMenu_AISpawn, 3 ) + SetupDevFunc( "Spawn Team 4 NPC", SetDevMenu_AISpawn, 4 ) + + if ( IsSingleplayer() ) + { + SetupDevCommand( "Spawn BT", "script thread DEV_SpawnBTAtCrosshair( false )" ) + SetupDevCommand( "Hotdrop BT", "script thread DEV_SpawnBTAtCrosshair( true )" ) + } + + SetupDevFunc( "Spawn Titan Weapon", SetDevMenu_TitanWeapons ) + SetupDevFunc( "Spawn Pilot Weapons", SetDevMenu_PilotWeapons ) + SetupDevFunc( "Spawn Pilot Offhands", SetDevMenu_PilotOffhands ) + + SetupDevFunc( "AI Commands", SetDevMenu_AICommands ) + SetupDevCommand( "Toggle Model Viewer", "script thread ToggleModelViewer()" ) + SetupDevCommand( "AI Titan Duel", "script DEV_AITitanDuel()" ) + SetupDevCommand( "Free Titans for everybody", "script GiveAllTitans()" ) + + if ( IsSingleplayer() ) + { + SetupDevCommand( "Checkpoint", "script CheckPoint_Forced()" ) + SetupDevCommand( "Test Next Checkpoint Spawnpoint", "script TestDevSpawnPoint()" ) + } + + SetupDevCommand( "Disable NPCs", "script disable_npcs()" ) + // SetupDevCommand( "Disable New NPCs", "script disable_new_npcs()" ) + + if ( IsMultiplayer() ) + { + SetupDevCommand( "Swap the teams", "script teamswap()" ) + SetupDevCommand( "Force time limit", "script ForceTimeLimitDone()" ) + SetupDevCommand( "Force My Team Win", "script_client GetLocalClientPlayer().ClientCommand(\"ForceMyTeamWin\")" ) + SetupDevCommand( "Force My Team Lose", "script_client GetLocalClientPlayer().ClientCommand(\"ForceMyTeamLose\")" ) + SetupDevCommand( "Force Match End", "script ForceMatchEnd()" ) + SetupDevCommand( "Force Draw", "script ForceDraw()" ) + } + + SetupDevCommand( "Toggle Friendly Highlights", "script DEV_ToggleFriendlyHighlight()" ) + SetupDevCommand( "Export precache script", "script_ui Dev_CommandLineAddParm( \"-autoprecache\", \"\" ); script_ui Dev_CommandLineRemoveParm( \"" + STARTPOINT_DEV_STRING + "\" ); reload" ) + // SetupDevCommand( "Toggle Blood Spray Decals", "script_client BloodSprayDecals_Toggle()" ) + + //SetupDevCommand( "PlaySpyglassVDU", "script ForcePlayConversationToAll(\"SpyglassVDU\")" ) + //SetupDevCommand( "PlayGravesVDU", "script ForcePlayConversationToAll(\"GravesVDU\")" ) + //SetupDevCommand( "PlayBliskVDU", "script ForcePlayConversationToAll(\"BliskVDU\")" ) + //SetupDevCommand( "PlaySarahVDU", "script ForcePlayConversationToAll(\"SarahVDU\")" ) + //SetupDevCommand( "PlayMacVDU", "script ForcePlayConversationToAll(\"MacVDU\")" ) + //SetupDevCommand( "PlayBishVDU", "script ForcePlayConversationToAll(\"BishVDU\")" ) + //SetupDevCommand( "PlayMCORGruntBattleRifleVDU", "script ForcePlayConversationToAll(\"MCORGruntBattleRifleVDU\")" ) + //SetupDevCommand( "PlayMCORGruntAntiTitanVDU", "script ForcePlayConversationToAll(\"MCORGruntAntiTitanVDU\")" ) + //SetupDevCommand( "PlayIMCSoldierBattleRifleVDU", "script ForcePlayConversationToAll(\"IMCSoldierBattleRifleVDU\")" ) + SetupDevCommand( "Doom my titan", "script_client GetLocalViewPlayer().ClientCommand( \"DoomTitan\" )" ) + SetupDevCommand( "DoF debug (ads)", "script_client ToggleDofDebug()" ) + + SetupDevCommand( "ToggleTitanCallInEffects", "script FlagToggle( \"EnableIncomingTitanDropEffects\" )" ) + //SetupDevCommand( "TrailerTitanDrop", "script_client GetLocalViewPlayer().ClientCommand( \"TrailerTitanDrop\" )" ) + //SetupDevCommand( "AI Chatter: aichat_callout_pilot_dev", "script playconvtest(\"aichat_callout_pilot_dev\")" ) + SetupDevCommand( "Spawn IMC grunt", "SpawnViewGrunt " + TEAM_IMC ) + SetupDevCommand( "Spawn Militia grunt", "SpawnViewGrunt " + TEAM_MILITIA ) + SetupDevCommand( "Enable titan-always-executes-titan", "script FlagSet( \"ForceSyncedMelee\" )" ) + //SetupDevCommand( "Display Embark times", "script DebugEmbarkTimes()" ) + SetupDevCommand( "Kill All Titans", "script killtitans()" ) + SetupDevCommand( "Kill All Minions", "script killminions()" ) + if ( IsSingleplayer() ) + SetupDevCommand( "Kill All Enemies", "script KillAllBadguys()" ) + + SetupDevCommand( "Export leveled_weapons.def / r2_weapons.fgd", "script thread LeveledWeaponDump()" ) + + + if ( IsMultiplayer() ) + { + SetupDevCommand( "Summon Players to player 0", "script summonplayers()" ) + SetupDevCommand( "Display Titanfall spots", "script thread ShowAllTitanFallSpots()" ) + SetupDevCommand( "Toggle check inside Titanfall Blocker", "script thread DevCheckInTitanfallBlocker()" ) + SetupDevCommand( "Simulate Game Scoring", "script thread SimulateGameScore()" ) + SetupDevCommand( "Test Dropship Intro Spawns with Bots", "script thread DebugTestDropshipStartSpawnsForAll()" ) + SetupDevCommand( "Preview Dropship Spawn at this location", "script SetCustomPlayerDropshipSpawn()" ) + SetupDevCommand( "Test Dropship Spawn at this location", "script thread DebugTestCustomDropshipSpawn()" ) + SetupDevCommand( "Max Activity (Pilots)", "script SetMaxActivityMode(1)" ) + SetupDevCommand( "Max Activity (Titans)", "script SetMaxActivityMode(2)" ) + SetupDevCommand( "Max Activity (Conger Mode)", "script SetMaxActivityMode(4)" ) + SetupDevCommand( "Max Activity (Disabled)", "script SetMaxActivityMode(0)" ) + } + else + { + SetupDevCommand( "Reset Collectibles Progress (level)", "script Dev_ResetCollectiblesProgress_Level()" ) + SetupDevCommand( "Reset Collectibles Progress (all)", "script ResetCollectiblesProgress_All()" ) + + SetupDevCommand( "BT Loadouts - Reset", "script SetBTLoadoutsUnlockedBitfield( 1 )" ) + SetupDevCommand( "BT Loadouts - Unlock All", "script SetBTLoadoutsUnlockedBitfield( 65535 )" ) + SetupDevCommand( "BT Loadouts - Spawn Unlock Pickup", "script SPTitanLoadout_SpawnAtCrosshairDEV( -1 )" ) + } + + SetupDevCommand( "Toggle Skybox View", "script thread ToggleSkyboxView()" ) + //SetupDevCommand( "Toggle Bubble Shield", "ToggleBubbleShield" ) + //SetupDevCommand( "Toggle Grenade Indicators", "script_client ToggleGrenadeIndicators()" ) + SetupDevCommand( "Toggle HUD", "ToggleHUD" ) + SetupDevCommand( "Toggle Offhand Low Recharge", "ToggleOffhandLowRecharge" ) + SetupDevCommand( "Map Metrics Toggle", "script_client GetLocalClientPlayer().ClientCommand( \"toggle map_metrics 0 1 2 3\" )" ) + SetupDevCommand( "Toggle Pain Death sound debug", "script TogglePainDeathDebug()" ) + SetupDevCommand( "Jump Randomly Forever", "script_client thread JumpRandomlyForever()" ) +} + + +void function SetupDefaultDevCommandsMP() +{ + SetupRepeatLastDevCommand() + + SetupDevFunc( "Frontier Defense", SetDevMenu_FrontierDefense ) + + SetupDevFunc( "Spawn IMC NPC", SetDevMenu_AISpawn, 2 ) + SetupDevFunc( "Spawn IMC Boss Titan", SetDevMenu_BossTitans ) + SetupDevFunc( "Spawn Militia NPC", SetDevMenu_AISpawn, 3 ) + SetupDevFunc( "Spawn Team 4 NPC", SetDevMenu_AISpawn, 4 ) + + SetupDevFunc( "Spawn Titan Weapon", SetDevMenu_TitanWeapons ) + SetupDevFunc( "Spawn Pilot Weapons", SetDevMenu_PilotWeapons ) + SetupDevFunc( "Spawn Pilot Offhands", SetDevMenu_PilotOffhands ) + + SetupDevFunc( "AI Commands", SetDevMenu_AICommands ) + SetupDevCommand( "Toggle Model Viewer", "script thread ToggleModelViewer()" ) + SetupDevCommand( "AI Titan Duel", "script DEV_AITitanDuel()" ) + SetupDevCommand( "Free Titans for everybody", "script GiveAllTitans()" ) + + SetupDevCommand( "Disable NPCs", "script disable_npcs()" ) + // SetupDevCommand( "Disable New NPCs", "script disable_new_npcs()" ) + + SetupDevCommand( "Swap the teams", "script teamswap()" ) + SetupDevCommand( "Force time limit", "script ForceTimeLimitDone()" ) + SetupDevCommand( "Force My Team Win", "script_client GetLocalClientPlayer().ClientCommand(\"ForceMyTeamWin\")" ) + SetupDevCommand( "Force My Team Lose", "script_client GetLocalClientPlayer().ClientCommand(\"ForceMyTeamLose\")" ) + SetupDevCommand( "Force Match End", "script ForceMatchEnd()" ) + SetupDevCommand( "Force Draw", "script ForceDraw()" ) + + SetupDevCommand( "Toggle Friendly Highlights", "script DEV_ToggleFriendlyHighlight()" ) + SetupDevCommand( "Export precache script", "script_ui Dev_CommandLineAddParm( \"-autoprecache\", \"\" ); script_ui Dev_CommandLineRemoveParm( \"" + STARTPOINT_DEV_STRING + "\" ); reload" ) + + SetupDevCommand( "Doom my titan", "script_client GetLocalViewPlayer().ClientCommand( \"DoomTitan\" )" ) + SetupDevCommand( "DoF debug (ads)", "script_client ToggleDofDebug()" ) + + SetupDevCommand( "ToggleTitanCallInEffects", "script FlagToggle( \"EnableIncomingTitanDropEffects\" )" ) + + SetupDevCommand( "Spawn IMC grunt", "SpawnViewGrunt " + TEAM_IMC ) + SetupDevCommand( "Spawn Militia grunt", "SpawnViewGrunt " + TEAM_MILITIA ) + + SetupDevCommand( "Enable titan-always-executes-titan", "script FlagSet( \"ForceSyncedMelee\" )" ) + + SetupDevCommand( "Kill All Titans", "script killtitans()" ) + SetupDevCommand( "Kill All Minions", "script killminions()" ) + + SetupDevCommand( "Export leveled_weapons.def / r2_weapons.fgd", "script thread LeveledWeaponDump()" ) + + SetupDevCommand( "Summon Players to player 0", "script summonplayers()" ) + SetupDevCommand( "Display Titanfall spots", "script thread ShowAllTitanFallSpots()" ) + SetupDevCommand( "Toggle check inside Titanfall Blocker", "script thread DevCheckInTitanfallBlocker()" ) + SetupDevCommand( "Simulate Game Scoring", "script thread SimulateGameScore()" ) + SetupDevCommand( "Test Dropship Intro Spawns with Bots", "script thread DebugTestDropshipStartSpawnsForAll()" ) + SetupDevCommand( "Preview Dropship Spawn at this location", "script SetCustomPlayerDropshipSpawn()" ) + SetupDevCommand( "Test Dropship Spawn at this location", "script thread DebugTestCustomDropshipSpawn()" ) + SetupDevCommand( "Max Activity (Pilots)", "script SetMaxActivityMode(1)" ) + SetupDevCommand( "Max Activity (Titans)", "script SetMaxActivityMode(2)" ) + SetupDevCommand( "Max Activity (Conger Mode)", "script SetMaxActivityMode(4)" ) + SetupDevCommand( "Max Activity (Disabled)", "script SetMaxActivityMode(0)" ) + + SetupDevCommand( "Toggle Skybox View", "script thread ToggleSkyboxView()" ) + SetupDevCommand( "Toggle HUD", "ToggleHUD" ) + SetupDevCommand( "Toggle Offhand Low Recharge", "ToggleOffhandLowRecharge" ) + SetupDevCommand( "Map Metrics Toggle", "script_client GetLocalClientPlayer().ClientCommand( \"toggle map_metrics 0 1 2 3\" )" ) + SetupDevCommand( "Toggle Pain Death sound debug", "script TogglePainDeathDebug()" ) + SetupDevCommand( "Jump Randomly Forever", "script_client thread JumpRandomlyForever()" ) +} + + +void function SetupRepeatLastDevCommand() +{ + DevCommand cmd + cmd.label = "Repeat Last Dev Command" + cmd.func = RepeatLastDevCommand + cmd.storeAsLastCommand = false + + file.devCommands.append( cmd ) +} + +void function SetDevMenu_LevelCommands( var _ ) +{ + ChangeToThisMenu( SetupLevelDevCommands ) +} + +void function SetupLevelDevCommands() +{ + string activeLevel = GetActiveLevel() + if ( activeLevel == "" ) + return + + switch ( activeLevel ) + { + case "mp_titan_rodeo": + SetupDevCommand( "Atlas titans", "script thread TitanTypes( \"titan_atlas_stickybomb\")" ) + SetupDevCommand( "Ogre titans", "script thread TitanTypes( \"titan_ogre_meteor\")" ) + SetupDevCommand( "Stryder titans", "script thread TitanTypes( \"titan_stryder_leadwall\")" ) + break + + case "model_viewer": + SetupDevCommand( "Toggle Rebreather Masks", "script ToggleRebreatherMasks()" ) + break + + case "sp_grunt_arena": + SetupDevCommand( "Toggle health pickups", "script ToggleHealthRegen(); reload" ) + break + } +} + +void function SetDevMenu_SpawnNPCWithWeapon( var parms ) +{ + ChangeToThisMenu_WithOpParm( SetupMenu_SpawnNPCWithWeapons, parms ) +} + + +void function SetDevMenu_StartPoints( var _ ) +{ + string currentMap = GetActiveLevel() + array foundStartPoints = GetStartPointsForMap( currentMap ) +// foreach ( index, startPointEnum in foundStartPoints ) +// { +// table parms = { currentMap = currentMap, startPointEnum = startPointEnum } +// SetupDevCommand( "#" + startPointEnum, SetDevMenu_SelectStartPointDifficulty, parms ) +// //SetupDevCommand( "#" + startPointEnum, "script PickStartPoint( \"" + currentMap + "\", \"" + startPointEnum + "\" )" ) +// } + + CloseAllInGameMenus() + AdvanceMenu( GetMenu( "SinglePlayerDevMenu" ), true ) + DisplayStartPointButtons( currentMap, foundStartPoints ) +} + + +void function SetDevMenu_ActionBlocks() +{ + ChangeToThisMenu( SetupActionBlocks ) +} + +function DefineActionBlocks() +{ + file.actionBlocks = [] + + /* [Menu name] [action block name] [owner] [description] [load commands] */ + AddActionBlock( "Week 1", "Timed Switch Panel Run", "Sean", "Test your wallrunning abilities by jumping on timed platforms", "playlist Load a map on the command line; map sp_platform_test01" ) + AddActionBlock( "Week 1", "Energon Room", "Mackey", "Combat test arena. Collect all Energon Spheres to win", "playlist Load a map on the command line; map sp_abmac1" ) + AddActionBlock( "Week 1", "Titan Buddy + Turret Columns", "Carlos", null, "playlist Load a map on the command line; map carlos_test" ) + AddActionBlock( "Week 1", "Titan Maze", "Soupy", null, "playlist Load a map on the command line; map sp_act-block_maze" ) + AddActionBlock( "Week 1", "Catch me if you Can", "Chin", "Catch up to a moving pilot and kill him to win", "launchplaylist catchmeifyoucan" ) + AddActionBlock( "Week 1", "Jumping Puzzles", "ChadG", "Various pilot jumping puzzles with moving platforms", "playlist Load a map on the command line; mp_gamemode at; map mp_chad" ) + AddActionBlock( "Week 1", "FLANKER BOOST loadout basics", "Brent", "Non-wallrunning pilot jumping basics", "playlist Load a map on the command line; mp_gamemode at; map mp_ab_test" ) + AddActionBlock( "Week 1", "Flee Titan Attack by wallrunning", "Roger", null, "playlist Load a map on the command line; map sp_ab_flee" ) + AddActionBlock( "Week 1", "Protect Grunt squad from Mortar fire", "Roger", null, "playlist Load a map on the command line; map sp_ab_vortex" ) + AddActionBlock( "Week 1", "Catch me if you Can Part 2", "Soupy", null, "playlist catchmeifyoucan;mp_gamemode ps; map mp_catchme" ) + AddActionBlock( "Week 2", "Environment Puzzles", "ChadG", "Get your titan to the exit by solving some puzzles", "playlist Load a map on the command line; mp_gamemode at; map mp_chad2" ) +// AddActionBlock( "Week 2", "Fun House - survive to the end", "Mo", null, "playlist Load a map on the command line; map mp_ab_funhouse" ) + AddActionBlock( "Week 2", "Assassin Arena - boss fight with the Assassin", "Mo", null, "playlist Load a map on the command line; map sp_ab_assassin" ) + AddActionBlock( "Week 2", "Creature Ship", "LumberJake", "Explore a crashed ship with mysterious cargo", "playlist Load a map on the command line; mp_gamemode at; map mp_actionblockjake01" ) + AddActionBlock( "Week 2", "Titan/Pilot Puzzles", "RyanR", "Get your titan to the green room", "playlist Load a map on the command line; mp_gamemode at; map mp_ryanr_actionblock_01" ) + AddActionBlock( "Week 2", "Titan/Pilot Core Combat", "Carlos", null, "playlist Load a map on the command line; map sp_ammo_pickup" ) + AddActionBlock( "Week 2", "Titan Overwatch", "Roger", "Your sniping titan will cover you as you advance to the bunker", "playlist Load a map on the command line; map sp_ab_titanbuddy" ) + AddActionBlock( "Week 2", "Rodeo Express", "Chin", "Use your titan to get you through a pilot hazard area", "playlist lava; mp_gamemode at; map mp_chin_rodeo_express" ) + AddActionBlock( "Week 2", "Wallrun Gauntlet", "McCord", "Wallrun through the geo and don't fall to your death", "playlist Load a map on the command line; map sp_zipline_action_block01" ) + AddActionBlock( "Week 2", "Titan Mortar Targeting Test", "Soupy", null, "playlist Load a map on the command line; map sp_mortar_targeting_test" ) + AddActionBlock( "Week 2", "Tremors", "David", null, "playlist Load a map on the command line; map sp_tremors" ) + AddActionBlock( "Week 2", "Titan Combat Blok", "Mackey", "Combat arena. Kill all enemies.", "playlist Load a map on the command line; map sp_abmac3" ) + AddActionBlock( "Week 2", "Smart Targeted Switch Panels", "Sean", "Wallrun from wall to wall while activating switches", "playlist Load a map on the command line; map sp_platform_test02" ) + AddActionBlock( "Week 3", "Combat Canyon", "Mo", "Kill enemies in the canyon and extract", "playlist Load a map on the command line; map sp_ab_ski" ) + AddActionBlock( "Week 3", "Titan v Titan", "Roger", "Test Titan vs Titan combat against various titan AI", "playlist Load a map on the command line; map sp_ab_tvt" ) + AddActionBlock( "Week 3", "Train Raid", "ChadG", "Board a speeding train and hack the explosives on board", "playlist Load a map on the command line; map sp_ab_trainride01" ) + AddActionBlock( "Week 3", "Super Spectre Bros", "David", "Survive 6 waves against super spectres", "playlist Load a map on the command line; map mp_ab_super_spectre_bros" ) + AddActionBlock( "Week 4", "Nightshot", "David", "Help your titan buddy hunt in the dark.", "playlist Load a map on the command line; map sp_ab_nightshot" ) + //AddActionBlock( "Week 4", "Space Battle", "Mo", "Pilot a ship in space. \n -Play with Always run OFF. \n -Use low sensitivity. \n -Use bug_reproNum 1 to invert flight controls.\n -Use bug_reproNum 2 for PRO flight controls. (free look) \n -Use bug_reproNum 3 for inverted PRO flight controls.", "playlist Load a map on the command line; map sp_ab_week4" ) + AddActionBlock( "Week 4", "Buddy Fight", "Mackey", "Arena fight with buddy Titan", "playlist Load a map on the command line; map sp_buddy_fight" ) + AddActionBlock( "Week 4", "Fastball Special", "Slayback/McCord", "Use a new Titan ability to hurl yourself to new heights.", "playlist Load a map on the command line; map sp_fastball" ) + AddActionBlock( "Week 4", "Time Travel Mechanic", "LumberJake", "Travel back and forth through time to complete your mission.", "playlist Load a map on the command line; map sp_actionblockjake02" ) + AddActionBlock( "Week 5", "Titan Ability: Death Blossom", "Mo", "Use Up on D-Pad to use Death Blossom\n\nUse your new ability to defeat the enemies", "playlist Load a map on the command line; bug_reproNum 0; map sp_ab_blossom" ) + AddActionBlock( "Week 5", "Titan Ability: Arc Blast", "Mo", "Use Down on D-Pad to use Arc Blast\n\nUse your new ability to defeat the enemies", "playlist Load a map on the command line; bug_reproNum 1; map sp_ab_blossom" ) + AddActionBlock( "Week 5", "Titan Abilities: Death Blossom + Arc Blast", "Mo", "D-Pad Up = Death Blossom\nD-Pad Down = Arc Blast\n\nUse your new abilities to defeat the enemies", "playlist Load a map on the command line; bug_reproNum 2; map sp_ab_blossom" ) + AddActionBlock( "Week 5", "Time Stasis Gun", "LumberJake", "Titan freezes enemies allowing the Pilot \nto do a one-shot kill", "playlist Load a map on the command line; map sp_actionblockjake03" ) + AddActionBlock( "Week 5", "Fastball Mortar Battle", "McCord/Slayback", "Freeform Buddy Titan arena battle. \n - Fastball Special \n - Mortar Crews \n - Buddy Hibernation \n - Harvester Defense", "playlist Load a map on the command line; map sp_ab_mortar_battle01" ) + AddActionBlock( "Week 5", "Zipline Gun", "ChadG", "Create permanent ziplines in the map", "playlist Load a map on the command line; mp_gamemode tdm; bug_reproNum 1234; map mp_angel_city" ) + AddActionBlock( "Week 6", "Titan Hulk", "David", "Buddy Titan hulks out and throws things.", "playlist Load a map on the command line; map sp_ab_titan_thrower" ) + AddActionBlock( "Week 6", "Player & Titan vs Enemy Titan", "Roger", "Bare bones Pilot & Auto Titan vs Enemy Titan", "playlist Load a map on the command line; map sp_ab_ptvt" ) + AddActionBlock( "Week 6", "Pilot Stasis Gun", "Soupy", "Pilot has a Stasis gun to help a friendly Titan out", "playlist Load a map on the command line; map sp_ab_synergy" ) + AddActionBlock( "Week 6", "Acid Rain", "LumberJake", "- Destroy 3 harvesters in a poison rain storm\n- Avoid poison rain by staying in your Titan or indoors\n- Collect powerups to get rain immunity", "map sp_actionblockjake04" ) + AddActionBlock( "Week 6", "Freeform Hallway Fight", "McCord/Slayback", "Move through the tight hallways with your Titan Buddy.", "playlist Load a map on the command line; map sp_ab_hallway_fight01" ) + AddActionBlock( "Week 6", "Stealth Town", "Carlos", "Stealth through a group of enemy titans", "playlist Load a map on the command line; map sp_titan_stealth" ) + AddActionBlock( "Week 6", "Titan Attack Command", "Mo", "Command your buddy titan to attack a position.", "playlist Load a map on the command line; map sp_ab_break" ) + AddActionBlock( "Week 7", "SP Shell", "Chad/McCord", "", "playlist Load a map on the command line; map sp_shell1" ) + AddActionBlock( "Week 7", "Smart Pistol Progression", "Soupy", "Try different smart pistol mods in different combat situations", "playlist Load a map on the command line; map sp_ab_smart_pistol_ramp" ) +} + + +function AddActionBlock( subMenu, actionBlockName, owner, description, command ) +{ + local subMenuIndex = null + foreach( i, Table in file.actionBlocks ) + { + if ( Table.name == subMenu ) + subMenuIndex = i + } + if ( subMenuIndex == null ) + { + file.actionBlocks.append( { name = subMenu, actionBlocks = [] } ) + subMenuIndex = file.actionBlocks.len() - 1 + } + + local Table = {} + Table.name <- actionBlockName + Table.owner <- owner + Table.description <- description + Table.command <- command + + file.actionBlocks[ subMenuIndex ].actionBlocks.append( Table ) +} + +function GetActionBlocks() +{ + DefineActionBlocks() + return file.actionBlocks +} + +void function SetupActionBlocks() +{ + DefineActionBlocks() + + // For the in-game dev menu we only add the current week of action blocks + foreach ( week, actionBlock in file.actionBlocks ) + { + SetupDevFunc( "Week " + ( week + 1 ), SetDevMenu_Week, week ) + } +} + +void function SetDevMenu_Week( var week ) +{ + ChangeToThisMenu_WithOpParm( SetupActionBlocksByWeek, week ) +} + +void function SetupActionBlocksByWeek( var week ) +{ + foreach ( actionBlock in file.actionBlocks[ week ].actionBlocks ) + { + SetupDevCommand( actionBlock.name + " - " + actionBlock.owner, expect string( actionBlock.command ) ) + } +} + +void function SetDevMenu_AICommands( var _ ) +{ + ChangeToThisMenu( SetupAIDevCommands ) +} + +void function SetDevMenu_AISpawn( var enemy ) +{ +#if DEV + InitNpcSettingsFileNamesForDevMenu() + ChangeToThisMenu_WithOpParm( SetupSpawnAIButtons, enemy ) +#endif +} + +void function SetDevMenu_BossTitans( var _ ) +{ +#if DEV + InitNpcSettingsFileNamesForDevMenu() + ChangeToThisMenu( SetupSpawnBossTitans ) +#endif +} + +void function SetDevMenu_FrontierDefense( var _ ) +{ + #if DEV + thread ChangeToThisMenu( SetupFrontierDefense ) + #endif +} + +void function SetDevMenu_TitanWeapons( var _ ) +{ +#if DEV + thread ChangeToThisMenu_PrecacheWeapons( SetupTitanWeapon ) +#endif +} + +void function SetDevMenu_ArmedNPC( var data ) +{ +#if DEV + thread ChangeToThisMenu_PrecacheWeapons_WithOpParm( SetupSpawnArmedNPC, data ) +#endif +} + +void function SetDevMenu_PilotWeapons( var _ ) +{ +#if DEV + thread ChangeToThisMenu_PrecacheWeapons_WithOpParm( SetupPilotWeaponsFromFields, "not_set" ) +#endif +} + +void function SetDevMenu_PilotOffhands( var _ ) +{ +#if DEV + thread ChangeToThisMenu_PrecacheWeapons_WithOpParm( SetupPilotWeaponsFromFields, "offhand" ) +#endif +} + +void function ChangeToThisMenu_PrecacheWeapons( void functionref() menuFunc ) +{ + waitthread PrecacheWeaponsIfNecessary() + + file.devMenuFunc = menuFunc + file.devMenuFuncWithOpParm = null + file.devMenuOpParm = null + UpdateDevMenuButtons() +} + +void function ChangeToThisMenu_PrecacheWeapons_WithOpParm( void functionref( var ) menuFuncWithOpParm, opParm = null ) +{ + waitthread PrecacheWeaponsIfNecessary() + + file.devMenuFunc = null + file.devMenuFuncWithOpParm = menuFuncWithOpParm + file.devMenuOpParm = opParm + UpdateDevMenuButtons() +} + +void function PrecacheWeaponsIfNecessary() +{ + if ( file.precachedWeapons ) + return + + file.precachedWeapons = true + CloseAllInGameMenus() + + DisablePrecacheErrors() + wait 0.1 + ClientCommand( "script PrecacheSPWeapons()" ) + wait 0.1 + ClientCommand( "script_client PrecacheSPWeapons()" ) + wait 0.1 + RestorePrecacheErrors() + + AdvanceMenu( GetMenu( "DevMenu" ) ) +} + +void function UpdatePrecachedSPWeapons() +{ + file.precachedWeapons = IsMultiplayer() +} + +void function SetupMenu_SpawnNPCWithWeapons( parms ) +{ + string weaponCapacity = expect string( parms.weaponCapacity ) + string baseClass = expect string( parms.baseClass ) + string aiSettings = expect string( parms.aiSettings ) + int team = expect int( parms.team ) + + array itemTypes + switch ( weaponCapacity ) + { + case "PilotMainWeapons": + itemTypes = [ eItemTypes.PILOT_PRIMARY, eItemTypes.PILOT_SECONDARY ] + break + + case "TitanMainWeapons": + itemTypes = [ eItemTypes.TITAN_PRIMARY ] + break + + default: + Assert( 0, "Unknown weapon capacity " + weaponCapacity ) + break + } + + array itemNames + foreach ( itemType in itemTypes ) + { + array items = GetAllItemRefsOfType( itemType ) + foreach ( item in items ) + { + itemNames.append( item ) + } + } + + foreach ( ref in itemNames ) + { + string weaponName = expect string( GetWeaponInfoFileKeyField_GlobalNotNull( ref, "printname" ) ) + + string cmd = "thread DEV_SpawnNPCWithWeaponAtCrosshair( \"" + baseClass + "\", \"" + aiSettings + "\", " + team + ", \"" + ref + "\" )" + SetupDevCommand( weaponName, "script " + cmd ) + } +} + +void function SetupAIDevCommands() +{ +} + +void function SetDevMenu_titanSelection( var _ ) +{ + ChangeToThisMenu( SetupTitanSelection ) +} + +void function SetupTitanSelection() +{ +} + +void function SetupDevCommand( string label, string command ) +{ + DevCommand cmd + cmd.label = label + cmd.command = command + + file.devCommands.append( cmd ) +} + +void function SetupDevFunc( string label, void functionref( var ) func, var opParm = null ) +{ + DevCommand cmd + cmd.label = label + cmd.func = func + cmd.opParm = opParm + + file.devCommands.append( cmd ) +} + +function OnDevButton_Activate( button ) +{ + //if ( level.ui.disableDev ) + //{ + // CodeWarning( "Dev commands disabled on matchmaking servers." ) + // return + //} + + int buttonID = int( Hud_GetScriptID( button ) ) + DevCommand cmd = file.devCommands[buttonID] + + RunDevCommand( cmd ) +} + +void function RunDevCommand( DevCommand cmd ) +{ + if ( cmd.storeAsLastCommand ) + { + file.lastDevCommand = cmd + file.lastDevCommandAssigned = true + } + + if ( cmd.command != "" ) + { + ClientCommand( cmd.command ) + CloseAllInGameMenus() + } + else + { + cmd.func( cmd.opParm ) + } +} + +void function RepeatLastDevCommand( var _ ) +{ + if ( !file.lastDevCommandAssigned ) + return + + RunDevCommand( file.lastDevCommand ) +} \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/ui/menu_map_select.nut b/bobthebob.testing/scripts/vscripts/ui/menu_map_select.nut new file mode 100644 index 000000000..7263a9faf --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/ui/menu_map_select.nut @@ -0,0 +1,200 @@ +untyped + + +global function MenuMapSelect_Init + +global function InitMapsMenu + +const int MAPS_PER_PAGE = 21 + +const MAP_LIST_VISIBLE_ROWS = 21 +const MAP_LIST_SCROLL_SPEED = 0 + +struct { + var menu = null + array buttons + int numMapButtonsOffScreen + int mapListScrollState = 0 +} file + +// note: this does have a scrolling system in vanilla, but it's honestly really weird and jank and i don't like it +// so for parity with menu_mode_select i'm removing it in favour of a page system + +function MenuMapSelect_Init() +{ + RegisterSignal( "OnCloseMapsMenu" ) +} + +void function InitMapsMenu() +{ + file.menu = GetMenu( "MapsMenu" ) + var menu = file.menu + + AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnOpenMapsMenu ) + AddMenuEventHandler( menu, eUIEvent.MENU_CLOSE, OnCloseMapsMenu ) + + AddEventHandlerToButtonClass( menu, "MapButtonClass", UIE_GET_FOCUS, MapButton_Focused ) + AddEventHandlerToButtonClass( menu, "MapButtonClass", UIE_LOSE_FOCUS, MapButton_LostFocus ) + AddEventHandlerToButtonClass( menu, "MapButtonClass", UIE_CLICK, MapButton_Activate ) + //AddEventHandlerToButtonClass( menu, "MapListScrollUpClass", UIE_CLICK, OnMapListScrollUp_Activate ) + //AddEventHandlerToButtonClass( menu, "MapListScrollDownClass", UIE_CLICK, OnMapListScrollDown_Activate ) + + AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT" ) + AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + + file.buttons = GetElementsByClassname( menu, "MapButtonClass" ) + + AddMenuFooterOption( menu, BUTTON_SHOULDER_LEFT, "#PRIVATE_MATCH_PAGE_PREV", "#PRIVATE_MATCH_PAGE_PREV", CycleModesBack, IsNorthstarServer ) + AddMenuFooterOption( menu, BUTTON_SHOULDER_RIGHT, "#PRIVATE_MATCH_PAGE_NEXT", "#PRIVATE_MATCH_PAGE_NEXT", CycleModesForward, IsNorthstarServer ) +} + +void function OnOpenMapsMenu() +{ + array buttons = file.buttons + array mapsArray = GetPrivateMatchMaps() + + file.numMapButtonsOffScreen = int( max( mapsArray.len() - MAP_LIST_VISIBLE_ROWS, 0 ) ) +// Assert( file.numMapButtonsOffScreen >= 0 ) + + foreach ( button in buttons ) + { + int buttonID = int( Hud_GetScriptID( button ) ) + + if ( buttonID >= 0 && buttonID < mapsArray.len() ) + { + string name = mapsArray[buttonID] + SetButtonRuiText( button, GetMapDisplayName( name ) ) + Hud_SetEnabled( button, true ) + + if ( IsItemInEntitlementUnlock( name ) && IsValid( GetUIPlayer() ) ) + { + if ( IsItemLocked( GetUIPlayer(), name ) && GetCurrentPlaylistVarInt( name + "_available" , 0 ) == 0 ) + { + SetButtonRuiText( button, Localize( "#MAP_LOCKED", Localize( GetMapDisplayName( name ) ) ) ) + } + } + + bool mapSupportsMode = PrivateMatch_IsValidMapModeCombo( name, PrivateMatch_GetSelectedMode() ) + Hud_SetLocked( button, !mapSupportsMode ) + + if ( !mapSupportsMode ) + SetButtonRuiText( button, Localize( "#PRIVATE_MATCH_UNAVAILABLE", Localize( GetMapDisplayName( name ) ) ) ) + } + else + { + SetButtonRuiText( button, "" ) + Hud_SetEnabled( button, false ) + } + + if ( buttonID == level.ui.privatematch_map ) + { + printt( buttonID, mapsArray[buttonID] ) + Hud_SetFocused( button ) + } + } + + //RegisterButtonPressedCallback( MOUSE_WHEEL_UP, OnMapListScrollUp_Activate ) + //RegisterButtonPressedCallback( MOUSE_WHEEL_DOWN, OnMapListScrollDown_Activate ) +} + +void function OnCloseMapsMenu() +{ + //DeregisterButtonPressedCallback( MOUSE_WHEEL_UP, OnMapListScrollUp_Activate ) + //DeregisterButtonPressedCallback( MOUSE_WHEEL_DOWN, OnMapListScrollDown_Activate ) + + Signal( uiGlobal.signalDummy, "OnCloseMapsMenu" ) +} + +void function MapButton_Focused( var button ) +{ + int buttonID = int( Hud_GetScriptID( button ) ) + + var menu = file.menu + var nextMapImage = Hud_GetChild( menu, "NextMapImage" ) + var nextMapName = Hud_GetChild( menu, "NextMapName" ) + var nextMapDesc = Hud_GetChild( menu, "NextMapDesc" ) + + array mapsArray = GetPrivateMatchMaps() + string mapName = mapsArray[buttonID] + + asset mapImage = GetMapImageForMapName( mapName ) + RuiSetImage( Hud_GetRui( nextMapImage ), "basicImage", mapImage ) + Hud_SetText( nextMapName, GetMapDisplayName( mapName ) ) + + string modeName = PrivateMatch_GetSelectedMode() + bool mapSupportsMode = PrivateMatch_IsValidMapModeCombo( mapName, modeName ) + if ( !mapSupportsMode ) + Hud_SetText( nextMapDesc, Localize( "#PRIVATE_MATCH_MAP_NO_MODE_SUPPORT", Localize( GetMapDisplayName( mapName ) ), Localize( GetGameModeDisplayName( modeName ) ) ) ) + else + Hud_SetText( nextMapDesc, GetMapDisplayDesc( mapName ) ) + + // Update window scrolling if we highlight a map not in view + int minScrollState = int( clamp( buttonID - (MAP_LIST_VISIBLE_ROWS - 1), 0, file.numMapButtonsOffScreen ) ) + int maxScrollState = int( clamp( buttonID, 0, file.numMapButtonsOffScreen ) ) + + if ( file.mapListScrollState < minScrollState ) + file.mapListScrollState = minScrollState + if ( file.mapListScrollState > maxScrollState ) + file.mapListScrollState = maxScrollState + + UpdateMapListScroll() +} + +void function MapButton_LostFocus( var button ) +{ + HandleLockedCustomMenuItem( file.menu, button, [], true ) +} + +void function MapButton_Activate( var button ) +{ + if ( Hud_IsLocked( button ) ) + { + return + } + + if ( !AmIPartyLeader() && GetPartySize() > 1 ) + return + + array mapsArray = GetPrivateMatchMaps() + int mapID = int( Hud_GetScriptID( button ) ) + string mapName = mapsArray[mapID] + + printt( mapName, mapID ) + + ClientCommand( "SetCustomMap " + mapName ) + CloseActiveMenu() +} + + +void function OnMapListScrollUp_Activate( var button ) +{ + file.mapListScrollState-- + if ( file.mapListScrollState < 0 ) + file.mapListScrollState = 0 + + UpdateMapListScroll() +} + +void function OnMapListScrollDown_Activate( var button ) +{ + file.mapListScrollState++ + if ( file.mapListScrollState > file.numMapButtonsOffScreen ) + file.mapListScrollState = file.numMapButtonsOffScreen + + UpdateMapListScroll() +} + +function UpdateMapListScroll() +{ + array buttons = file.buttons + local basePos = buttons[0].GetBasePos() + local offset = buttons[0].GetHeight() * file.mapListScrollState + + buttons[0].SetPos( basePos[0], basePos[1] - offset ) +} + +void function CycleModesBack( var button ) +{} + +void function CycleModesForward( var button ) +{} diff --git a/bobthebob.testing/scripts/vscripts/ui/menu_mode_select.nut b/bobthebob.testing/scripts/vscripts/ui/menu_mode_select.nut new file mode 100644 index 000000000..4e0ecef5b --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/ui/menu_mode_select.nut @@ -0,0 +1,138 @@ +global function InitModesMenu + +struct { + int currentModePage + +} file + +const int MODES_PER_PAGE = 15 + +void function InitModesMenu() +{ + var menu = GetMenu( "ModesMenu" ) + + AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnOpenModesMenu ) + + AddEventHandlerToButtonClass( menu, "ModeButton", UIE_GET_FOCUS, ModeButton_GetFocus ) + AddEventHandlerToButtonClass( menu, "ModeButton", UIE_CLICK, ModeButton_Click ) + + AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT" ) + AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + + AddMenuFooterOption( menu, BUTTON_SHOULDER_LEFT, "#PRIVATE_MATCH_PAGE_PREV", "#PRIVATE_MATCH_PAGE_PREV", CycleModesBack, IsNorthstarServer ) + AddMenuFooterOption( menu, BUTTON_SHOULDER_RIGHT, "#PRIVATE_MATCH_PAGE_NEXT", "#PRIVATE_MATCH_PAGE_NEXT", CycleModesForward, IsNorthstarServer ) +} + +void function OnOpenModesMenu() +{ + UpdateVisibleModes() + + if ( level.ui.privatematch_mode == 0 ) // set to the first mode if there's no mode focused + Hud_SetFocused( GetElementsByClassname( GetMenu( "ModesMenu" ), "ModeButton" )[ 0 ] ) +} + +void function UpdateVisibleModes() +{ + // ensures that we only ever show enough buttons for the number of modes we have + array buttons = GetElementsByClassname( GetMenu( "ModesMenu" ), "ModeButton" ) + foreach ( var button in buttons ) + { + Hud_SetEnabled( button, false ) + Hud_SetVisible( button, false ) + } + + array modesArray = GetPrivateMatchModes() + for ( int i = 0; i < MODES_PER_PAGE; i++ ) + { + if ( i + ( file.currentModePage * MODES_PER_PAGE ) >= modesArray.len() ) + break + + int modeIndex = i + ( file.currentModePage * MODES_PER_PAGE ) + SetButtonRuiText( buttons[ i ], GetGameModeDisplayName( modesArray[ modeIndex ] ) ) + Hud_SetEnabled( buttons[ i ], true ) + Hud_SetVisible( buttons[ i ], true ) + Hud_SetLocked( buttons[ i ], false ) + + if ( !PrivateMatch_IsValidMapModeCombo( PrivateMatch_GetSelectedMap(), modesArray[ modeIndex ] ) && !IsNorthstarServer() ) + { + Hud_SetLocked( buttons[ i ], true ) + SetButtonRuiText( buttons[ i ], Localize( "#PRIVATE_MATCH_UNAVAILABLE", Localize( GetGameModeDisplayName( modesArray[ modeIndex ] ) ) ) ) + } + } +} + +void function ModeButton_GetFocus( var button ) +{ + int modeId = int( Hud_GetScriptID( button ) ) + ( file.currentModePage * MODES_PER_PAGE ) + + var menu = GetMenu( "ModesMenu" ) + var nextModeImage = Hud_GetChild( menu, "NextModeImage" ) + var nextModeIcon = Hud_GetChild( menu, "ModeIconImage" ) + var nextModeName = Hud_GetChild( menu, "NextModeName" ) + var nextModeDesc = Hud_GetChild( menu, "NextModeDesc" ) + + array modesArray = GetPrivateMatchModes() + + if ( modeId > modesArray.len() ) + return + + string modeName = modesArray[modeId] + + asset playlistImage = GetPlaylistImage( modeName ) + RuiSetImage( Hud_GetRui( nextModeImage ), "basicImage", playlistImage ) + RuiSetImage( Hud_GetRui( nextModeIcon ), "basicImage", GetPlaylistThumbnailImage( modeName ) ) + Hud_SetText( nextModeName, GetGameModeDisplayName( modeName ) ) + + string mapName = PrivateMatch_GetSelectedMap() + bool mapSupportsMode = PrivateMatch_IsValidMapModeCombo( mapName, modeName ) + if ( !mapSupportsMode && !IsNorthstarServer() ) + Hud_SetText( nextModeDesc, Localize( "#PRIVATE_MATCH_MODE_NO_MAP_SUPPORT", Localize( GetGameModeDisplayName( modeName ) ), Localize( GetMapDisplayName( mapName ) ) ) ) + else if ( IsFDMode( modeName ) ) // HACK! + Hud_SetText( nextModeDesc, Localize( "#FD_PLAYERS_DESC", Localize( GetGameModeDisplayHint( modeName ) ) ) ) + else + Hud_SetText( nextModeDesc, GetGameModeDisplayHint( modeName ) ) +} + +void function ModeButton_Click( var button ) +{ + // this never activates on custom servers, but keeping it for parity with official + if ( !AmIPartyLeader() && GetPartySize() > 1 ) + return + + if ( Hud_IsLocked( button ) ) + return + + int mapID = int( Hud_GetScriptID( button ) ) + ( file.currentModePage * MODES_PER_PAGE ) + + var menu = GetMenu( "MapsMenu" ) + + array modesArray = GetPrivateMatchModes() + string modeName = modesArray[mapID] + + // on modded servers set us to the first map for that mode automatically + // need this for coliseum mainly which is literally impossible to select without this + if ( IsNorthstarServer() && !PrivateMatch_IsValidMapModeCombo( PrivateMatch_GetSelectedMap(), modesArray[ mapID ] ) ) + ClientCommand( "SetCustomMap " + GetPrivateMatchMapsForMode( modeName )[ 0 ] ) + + // set it + ClientCommand( "PrivateMatchSetMode " + modeName ) + CloseActiveMenu() +} + +void function CycleModesBack( var button ) +{ + if ( file.currentModePage == 0 ) + return + + file.currentModePage-- + UpdateVisibleModes() +} + +void function CycleModesForward( var button ) +{ + if ( ( file.currentModePage + 1 ) * MODES_PER_PAGE >= GetPrivateMatchModes().len() ) + return + + file.currentModePage++ + UpdateVisibleModes() +} \ No newline at end of file diff --git a/bobthebob.testing/scripts/vscripts/ui/menu_team_titan_select.nut b/bobthebob.testing/scripts/vscripts/ui/menu_team_titan_select.nut new file mode 100644 index 000000000..92bb849eb --- /dev/null +++ b/bobthebob.testing/scripts/vscripts/ui/menu_team_titan_select.nut @@ -0,0 +1,722 @@ +global function InitTeamTitanSelectMenu +global function TeamTitanSelectMenuIsOpen +global function ServerCallback_OpenTeamTitanMenu +global function ServerCallback_CloseTeamTitanMenu +global function ServerCallback_UpdateTeamTitanMenuTime +global function ServerCallback_RegisterTeamTitanMenuButtons +global function TTSUpdateDoubleXP +global function TTSUpdateDoubleXPStatus +global function TTSMenuModeFD +global function TTSMenuModeDefault +global function TTSMenu_UpdateGameMode +global function EnableDoubleXP + +const float SELECT_DELAY = 0.2 + +enum eTTSMenuMode +{ + DEFAULT, + FD +} + +struct +{ + var menu + bool allowManualClose = false + bool isReady = false + bool menuOpened = false + bool allowSelection = false + + array titanButtons + array titanUpgradeButtons + var editButton + var readyPanel + var cover + var doubleXPButton + var chatBox + + bool buttonsRegistered = false + + int menuMode + + float nextAllowSoundTime = 0.0 +} file + +void function InitTeamTitanSelectMenu() +{ + file.menu = GetMenu( "TeamTitanSelectMenu" ) + + AddMenuEventHandler( file.menu, eUIEvent.MENU_NAVIGATE_BACK, OnTeamTitanSelectMenu_NavigateBack ) + AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnTeamTitanSelectMenu_Open ) + AddMenuEventHandler( file.menu, eUIEvent.MENU_SHOW, OnTeamTitanSelectMenu_Open ) + AddMenuEventHandler( file.menu, eUIEvent.MENU_HIDE, OnTeamTitanSelectMenu_Hide ) + AddMenuEventHandler( file.menu, eUIEvent.MENU_CLOSE, OnTeamTitanSelectMenu_Close ) + + RegisterSignal( "TTSMenuClosed" ) + RegisterSignal( "Delayed_RequestTitanLoadout" ) + + float margin = 10.0 + float totalWidth = 0.0 + for ( int i=0; i 5 ) + file.allowSelection = true + + thread UpdateSubText( Time() + endTime ) +} + +void function ServerCallback_OpenTeamTitanMenu( float endTime ) +{ + if ( TeamTitanSelectMenuIsOpen() ) + return + + if ( uiGlobal.activeMenu != null ) + CloseAllMenus() + + RunClientScript( "PlayTTSMusic" ) + + file.allowManualClose = false + file.allowSelection = true + file.isReady = true // set to true so selection mode kicks in + thread MenuFadeIn() + BeginSelectionMode() + AdvanceMenu( file.menu ) + thread UpdateSubText( Time() + endTime ) +} + +void function MenuFadeIn() +{ + Hud_SetEnabled( file.cover, true ) + Hud_SetAlpha( file.cover, 255 ) + Hud_Show( file.cover ) + wait 1.0 + Hud_FadeOverTime( file.cover, 0, 1.0 ) + wait 1.0 + Hud_Hide( file.cover ) + Hud_SetEnabled( file.cover, false ) +} + +void function UpdateSubText( float endTime ) +{ + EndSignal( uiGlobal.signalDummy, "TTSMenuClosed" ) + + var subText = Hud_GetChild( file.menu, "MenuSubTitle" ) + var rui = Hud_GetRui( file.readyPanel ) + RuiSetBool( rui, "isReady", true ) + + thread Countdown( endTime ) + while ( Time() < endTime ) + { + int countdownTime = int( ceil( endTime - Time() ) ) + Hud_SetText( subText, Localize( "#MENU_STARTS_IN", countdownTime ) ) + RuiSetInt( rui, "timer", countdownTime ) + WaitFrame() + } + + Hud_SetText( subText, Localize( "#MENU_STARTS_IN", 0 ) ) + RuiSetInt( rui, "timer", 0 ) +} + +void function Countdown( float endTime ) +{ + EndSignal( uiGlobal.signalDummy, "TTSMenuClosed" ) + + float countdownTime = 5.0 + float startCountdownTime = endTime - countdownTime + + if ( Time() > startCountdownTime ) + return + + wait startCountdownTime - Time() + + while ( Time() < endTime ) + { + EmitUISound( "UI_InGame_MarkedForDeath_CountdownToMarked" ) + wait 1.0 + } + + file.allowSelection = false + BeginEditMode(null) + + Hud_SetAlpha( file.cover, 0 ) + Hud_SetEnabled( file.cover, true ) + Hud_Show( file.cover ) + Hud_FadeOverTime( file.cover, 255, 1.0 ) + + float soundTime = DoPrematchWarpSound() ? PICK_LOADOUT_SOUND_TIME : 1.5 + wait soundTime + + thread ServerCallback_CloseTeamTitanMenu() +} + +void function ServerCallback_CloseTeamTitanMenu() +{ + if ( TeamTitanSelectMenuIsOpen() ) + { + file.allowManualClose = true + UI_SetPresentationType( ePresentationType.INACTIVE ) + CloseAllMenus() + OnTeamTitanSelectMenu_Close() + } +} + +void function OnTeamTitanSelectMenu_NavigateBack() +{ + if ( file.allowManualClose ) + { + CloseActiveMenu() + return + } + + if ( file.isReady && file.allowSelection ) + { + BeginSelectionMode() + return + } + + LeaveDialog() + return +} + +void function TTSMenu_UpdateGameMode( string modeName ) +{ + var title = Hud_GetChild( file.menu, "MenuTitle" ) + Hud_SetText( title, Localize( modeName ) ) +} + +void function ServerCallback_RegisterTeamTitanMenuButtons() +{ + RegisterButtonCallbacks() +} + +void function RegisterButtonCallbacks() +{ + if ( file.buttonsRegistered ) + return + + file.buttonsRegistered = true + RegisterButtonPressedCallback( BUTTON_BACK, EnableDoubleXP ) + RegisterButtonPressedCallback( KEY_RSHIFT, EnableDoubleXP ) +} + +void function OnTeamTitanSelectMenu_Open() +{ + file.menuOpened = true + + var dataTable = GetDataTable( $"datatable/titan_properties.rpak" ) + int loadoutIconCol = GetDataTableColumnByName( dataTable, "loadoutIconFD" ) + int titanCol = GetDataTableColumnByName( dataTable, "titanRef" ) + + entity player = GetUIPlayer() + + var nextMapImage = Hud_GetChild( file.menu, "NextMapImage" ) + string mapName = GetActiveLevel() + asset mapImage = GetMapImageForMapName( mapName ) + + RefreshCreditsAvailable() + + RuiSetImage( Hud_GetRui( nextMapImage ), "basicImage", mapImage ) + Hud_Show( nextMapImage ) + Hud_SetText( Hud_GetChild( file.menu, "NextMapName" ), GetMapDisplayName( mapName ) ) + Hud_Show( Hud_GetChild( file.menu, "NextMapName" ) ) + + var buttonToFocus + + for ( int i=0; i titanUpgrades = FD_GetUpgradesForTitanClass( loadout.titanClass ) + + if ( file.menuMode == eTTSMenuMode.FD ) + { + RuiSetString( rui, "titanLevelString", Localize( "#FD_TITAN_LEVEL", titanLevel ) ) + RuiSetString( rui, "titanRole", Localize( "#FD_ROLE", Localize(role) ) ) + + foreach ( index, item in titanUpgrades ) + { + var button = file.titanUpgradeButtons[index] + var upgradeRui = Hud_GetRui( button ) + + bool locked = IsSubItemLocked( GetUIPlayer(), item.ref, item.parentRef ) + + if ( locked ) + RuiSetImage( upgradeRui, "buttonImage", expect asset( item.i.lockedImage ) ) + else + RuiSetImage( upgradeRui, "buttonImage", item.image ) + + Hud_SetLocked( button, locked ) + } + } + + if ( !Hud_IsLocked( button ) ) + { + uiGlobal.titanSpawnLoadoutIndex = scriptID + thread Delayed_RequestTitanLoadout( uiGlobal.titanSpawnLoadoutIndex ) + SetLabelRuiText( Hud_GetChild( file.menu, "TitanSelectTitle" ), "#MENU_TITAN_SELECT" ) + } + else + { + RuiSetString( rui, "titanLevelString", GetItemUnlockReqText( loadout.titanClass ) ) + } + + SetLabelRuiText( Hud_GetChild( file.menu, "TitanSelectTitle" ), GetTitanAvailableText( player, loadout.titanClass) ) + + RunMenuClientFunction( "UpdateTitanModel", scriptID ) + RunClientScript( "TTS_UpdateLocalPlayerTitan", loadout.setFile, loadout.primary, loadout.passive1, loadout.passive2 ) +} + +string function GetTitanAvailableText( entity player, string titanClass ) +{ + int titanAvailableState = GetTitanLoadAvailableState( player, titanClass ) + + if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_AVAILABLE ) + return "#MENU_TITAN_SELECT_HINT" + + if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_LEVELREQUIRED || titanAvailableState == TITAN_CLASS_LOCK_STATE_LEVELRECOMMENDED ) + { + int difficultyLevel = GetCurrentPlaylistVarInt( "fd_difficulty", 0 ) + int requiredTitanLevel = 0 + switch ( difficultyLevel ) + { + case eFDDifficultyLevel.EASY: + if ( GetItemUnlockType( "fd_easy" ) == eUnlockType.STAT ) + requiredTitanLevel = int( GetStatUnlockStatVal( "fd_easy" ) ) + break + case eFDDifficultyLevel.NORMAL: + if ( GetItemUnlockType( "fd_normal" ) == eUnlockType.STAT ) + requiredTitanLevel = int( GetStatUnlockStatVal( "fd_normal" ) ) + break + case eFDDifficultyLevel.HARD: + if ( GetItemUnlockType( "fd_hard" ) == eUnlockType.STAT ) + requiredTitanLevel = int( GetStatUnlockStatVal( "fd_hard" ) ) + break + case eFDDifficultyLevel.MASTER: + if ( GetItemUnlockType( "fd_master" ) == eUnlockType.STAT ) + requiredTitanLevel = int( GetStatUnlockStatVal( "fd_master" ) ) + break + case eFDDifficultyLevel.INSANE: + if ( GetItemUnlockType( "fd_insane" ) == eUnlockType.STAT ) + requiredTitanLevel = int( GetStatUnlockStatVal( "fd_insane" ) ) + break + } + + if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_LEVELREQUIRED ) + return Localize( "#MENU_TITAN_SELECT_LEVELREQUIRED", requiredTitanLevel ) + else + return Localize( "#MENU_TITAN_SELECT_LEVELRECOMMENDED", requiredTitanLevel ) + } + + if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_INUSE ) + return "#MENU_TITAN_SELECT_INUSE" + + if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_LOCKED ) + return "#MENU_TITAN_SELECT_LOCKED" + + return "#MENU_TITAN_SELECT_HINT" +} + +void function Delayed_RequestTitanLoadout( int index ) +{ + Signal( uiGlobal.signalDummy, "Delayed_RequestTitanLoadout" ) + EndSignal( uiGlobal.signalDummy, "Delayed_RequestTitanLoadout" ) + wait 0.5 + ClientCommand( "RequestTitanLoadout " + uiGlobal.titanSpawnLoadoutIndex ) +} + +void function TitanUpgradeButton_OnFocused( var button ) +{ + if ( file.menuMode == eTTSMenuMode.DEFAULT ) + return + + int scriptID = int( Hud_GetScriptID( button ) ) + TitanLoadoutDef loadout = GetCachedTitanLoadout( uiGlobal.titanSpawnLoadoutIndex ) + array titanUpgrades = FD_GetUpgradesForTitanClass( loadout.titanClass ) + + ItemDisplayData item = titanUpgrades[ scriptID ] + var panel = Hud_GetChild( file.menu, "UpgradeName" ) + Hud_Show( panel ) + var rui = Hud_GetRui( panel ) + RuiSetString( rui, "upgradeName", item.name ) + RuiSetString( rui, "upgradeDesc", item.desc ) + RuiSetBool( rui, "isLocked", IsSubItemLocked( GetUIPlayer(), item.ref, item.parentRef ) ) +} + +void function TitanUpgradeButton_OnLoseFocus( var button ) +{ + Hud_Hide( Hud_GetChild( file.menu, "UpgradeName" ) ) +} + +void function BeginEditMode( var button ) +{ + if ( file.isReady ) + return + + file.isReady = true + + EmitUISound( "UI_InGame_FD_TitanSelected" ) + SetLabelRuiText( Hud_GetChild( file.menu, "TitanSelectTitle" ), "#MENU_TITAN_SELECTED" ) + Hud_Hide( Hud_GetChild( file.menu, "TitanSelectTitle" ) ) + Hud_Show( file.readyPanel ) + var rui = Hud_GetRui( file.readyPanel ) + RuiSetBool( rui, "isReady", true ) + + foreach ( b in file.titanButtons ) + { + Hud_Hide( b ) + } + + //Hud_Show( file.editButton ) + //Hud_SetFocused( file.editButton ) + Hud_SetFocused( file.titanUpgradeButtons[0] ) + + TitanLoadoutDef loadout = GetCachedTitanLoadout( uiGlobal.titanSpawnLoadoutIndex ) + string primeTitanString = "" + + if ( loadout.isPrime == "titan_is_prime" ) + primeTitanString = "_prime" + + string modifiedAlias = "diag_gs_titan" + loadout.titanClass + primeTitanString + "_embark" + EmitUISound( modifiedAlias ) + + if ( uiGlobal.activeMenu == file.menu ) + UI_SetPresentationType( ePresentationType.TITAN_CENTER_SELECTED ) + + Signal( uiGlobal.signalDummy, "Delayed_RequestTitanLoadout" ) + ClientCommand( "RequestTitanLoadout " + uiGlobal.titanSpawnLoadoutIndex ) + RunMenuClientFunction( "UpdateTitanModel", uiGlobal.titanSpawnLoadoutIndex ) + + var subText = Hud_GetChild( file.menu, "MenuSubTitle" ) + // Hud_Hide( subText ) +} + +void function BeginSelectionMode() +{ + if ( !file.isReady ) + return + + file.isReady = false + //Hud_Hide( file.editButton ) + + SetLabelRuiText( Hud_GetChild( file.menu, "TitanSelectTitle" ), "#MENU_TITAN_SELECT_HINT" ) + Hud_Show( Hud_GetChild( file.menu, "TitanSelectTitle" ) ) + Hud_Hide( file.readyPanel ) + var rui = Hud_GetRui( file.readyPanel ) + RuiSetBool( rui, "isReady", false ) + + Hud_SetFocused( FindValidTitanButton() ) + + for ( int i=0; i