diff --git a/keyvalues/playlists_v2.txt b/keyvalues/playlists_v2.txt new file mode 100644 index 0000000..7af17fd --- /dev/null +++ b/keyvalues/playlists_v2.txt @@ -0,0 +1,85 @@ +playlists +{ + Gamemodes + { + hh + { + inherit defaults + vars + { + name #PL_hh + lobbytitle #PL_hh_lobby + description #PL_hh_desc + hint #PL_hh_desc + abbreviation #PL_hh_abbr + image cp + + max_players 16 + max_teams 2 + classic_mp 1 + scorelimit 5 + timelimit 3 + roundtimelimit 3 + roundscorelimit 5 + + gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM + } + } + } + Playlists + { + hh + { + inherit defaults + vars + { + name #PL_hh + lobbytitle #PL_hh_lobby + description #PL_hh_desc + hint #PL_hh_desc + abbreviation #PL_hh_abbr + image cp + + max_players 16 + max_teams 2 + classic_mp 1 + scorelimit 5 + timelimit 3 + roundtimelimit 3 + roundscorelimit 5 + + gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM + } + gamemodes + { + hh + { + maps + { + mp_lf_stacks 1 + mp_lf_deck 1 + mp_lf_meadow 1 + mp_lf_traffic 1 + mp_lf_township 1 + mp_lf_uma 1 + mp_forwardbase_kodai 1 + mp_grave 1 + mp_homestead 1 + mp_thaw 1 + mp_black_water_canal 1 + mp_eden 1 + mp_drydock 1 + mp_crashsite3 1 + mp_complex3 1 + mp_angel_city 1 + mp_colony02 1 + mp_glitch 1 + mp_relic02 1 + mp_wargames 1 + mp_rise 1 + } + } + } + } + } +} \ No newline at end of file diff --git a/mod.json b/mod.json index 713638a..fa248d6 100644 --- a/mod.json +++ b/mod.json @@ -1,17 +1,32 @@ { - "Name": "Example.Mod", - "Description": "A cool mod that does cool stuff", - "Version": "1.0.0", - "DownloadLink": "https://northstar.thunderstore.io/package/download/Example/Mod/", + "Name": "GeckoEidechse.Headhunter", + "Description": "A variation of the Fastball gamemode", + "Version": "0.0.1", + "DownloadLink": "https://northstar.thunderstore.io/package/download/Example/Mod/", - "LoadPriority": 0, - "ConVars": [], - "Scripts": [{ - "Path": "example.nut", - "RunOn": "(CLIENT || SERVER) && MP", - "ClientCallback": { - "Before":"example_callback" - } - }], - "Localisation": [] + "LoadPriority": 3, + "RequiredOnClient": true, + "Scripts": [ + { + "Path": "gamemodes/sh_gamemode_hh.gnut", + "RunOn": "( CLIENT || SERVER ) && MP", + "ServerCallback": { + "Before": "HHMode_Init" + }, + "ClientCallback": { + "Before": "HHMode_Init" + } + }, + { + "Path": "gamemodes/cl_gamemode_hh.gnut", + "RunOn": "CLIENT && MP" + }, + { + "Path": "gamemodes/_gamemode_hh.gnut", + "RunOn": "SERVER && MP" + } + ], + "Localisation": [ + "resource/headhunter_localisation_%language%.txt" + ] } diff --git a/mod/resource/headhunter_localisation_english.txt b/mod/resource/headhunter_localisation_english.txt new file mode 100644 index 0000000..935e6fc Binary files /dev/null and b/mod/resource/headhunter_localisation_english.txt differ diff --git a/mod/scripts/vscripts/example.nut b/mod/scripts/vscripts/example.nut deleted file mode 100644 index 570a40a..0000000 --- a/mod/scripts/vscripts/example.nut +++ /dev/null @@ -1,3 +0,0 @@ -void function example_callback() { - print( "HEY YOU SHOULD CHANGE THIS" ) -} diff --git a/mod/scripts/vscripts/gamemodes/_gamemode_hh.gnut b/mod/scripts/vscripts/gamemodes/_gamemode_hh.gnut new file mode 100644 index 0000000..479b5c6 --- /dev/null +++ b/mod/scripts/vscripts/gamemodes/_gamemode_hh.gnut @@ -0,0 +1,291 @@ +untyped +global function GamemodeHH_Init + +const array btmaps = [ "mp_angel_city", "mp_colony02", "mp_thaw", "mp_glitch", "mp_wargames", "mp_drydock", "mp_eden", "mp_black_water_canal", "mp_grave", "mp_complex3", "mp_homestead", "mp_forwardbase_kodai", "mp_crashsite3", "mp_rise", "mp_relic02" ] + +struct { + bool hasmadespawns = false + array goals + array spawnoffsets = [ < 0, 50, 10 >, < 0, -50, 10 >, < 50, 0, 10 >, < -50, -0, 10 > ] // some sort of spawn checking (ray trace?) in the future +} file + +void function GamemodeHH_Init() +{ + // used for intro + if ( btmaps.contains( GetMapName() ) ) + { + PrecacheModel( $"models/titans/buddy/titan_buddy.mdl" ) + PrecacheParticleSystem( $"P_BT_eye_SM" ) + ClassicMP_SetCustomIntro( GamemodeFastballIntroSetup, 14.5 ) + AddBTSpawn() + } + + // used for respawn + PrecacheParticleSystem( $"P_pod_screen_lasers_OUT" ) + + SetShouldUseRoundWinningKillReplay( true ) + SetRoundBased( true ) + SetRespawnsEnabled( false ) + Riff_ForceTitanAvailability( eTitanAvailability.Never ) + Riff_ForceSetEliminationMode( eEliminationMode.Pilots ) + ScoreEvent_SetupEarnMeterValuesForMixedModes() + + ClassicMP_ForceDisableEpilogue( true ) + PrecacheModel( $"models/robots/mobile_hardpoint/mobile_hardpoint.mdl" ) + + AddCallback_OnPlayerKilled( OnPlayerKilled ) + AddCallback_GameStateEnter( eGameState.WinnerDetermined, RemoveBatts ) + AddCallback_GameStateEnter(eGameState.Playing, StartHHThink) + AddCallback_GameStateEnter( eGameState.Prematch, CreateEndgoals ) + SetTimeoutWinnerDecisionFunc( HeadhunterDecideWinner ) + + AddCallback_OnClientConnected( SetClientRui ) + + PilotBattery_SetMaxCount( 99 ) +} + +void function StartHHThink() { + thread HHThink() +} + +void function HHThink() { + while( true ) + { + foreach ( entity player in GetPlayerArray() ) + { + if ( !PlayerHasBattery( player ) ) + continue + foreach ( entity goal in file.goals ) + { + if ( DistanceSqr( player.GetOrigin(), goal.GetOrigin() ) <= 30000.0 ) + { + array possPlayers + foreach ( entity deadPlayer in GetPlayerArrayOfTeam( player.GetTeam() ) ) + if ( !IsAlive( deadPlayer ) ) + possPlayers.append( deadPlayer ) + if ( possPlayers.len() ) + { + entity chosen = possPlayers[ RandomInt( possPlayers.len() ) ] + if ( !IsAlive( chosen ) ) + { + chosen.SetOrigin( goal.GetOrigin() + file.spawnoffsets[ RandomInt( file.spawnoffsets.len() ) ] ) + chosen.RespawnPlayer( null ) + Remote_CallFunction_NonReplay( chosen, "ServerCallback_HeadhunterRespawnPlayer", player.GetEncodedEHandle() ) + StimPlayer( chosen, 2 ) + Rodeo_RemoveBatteryOffPlayer(player) + EmitSoundOnEntityOnlyToPlayer( player, player, "UI_TitanBattery_Pilot_Give_TitanBattery" ) + player.AddToPlayerGameStat( PGS_ASSAULT_SCORE, 1 ) + } + } + } + } + } + + wait 0.1 + } +} + +void function RemoveBatts() +{ + foreach ( entity player in GetPlayerArray() ) + Rodeo_RemoveAllBatteriesOffPlayer( player ) + foreach ( entity battery in GetEntArrayByClass_Expensive( "item_titan_battery" ) ) + battery.Destroy() +} + +void function OnPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() && GetGameState() == eGameState.Playing ) + { + entity batt = Rodeo_CreateBatteryPack() + batt.SetOrigin( victim.GetOrigin() + < 0, 0, batt.GetBoundingMaxs().z * 2 > ) + batt.SetVelocity( < 0, 0, 1 > ) + vector baseVelocity = victim.GetVelocity() + baseVelocity.z = 0 + batt.SetVelocity( baseVelocity + AnglesToForward( <0, RandomInt( 360.0 ), 0 > ) * 100 + <0,0,1> ) //stole from rodeo code + + SetTeam(batt, 0) + Highlight_SetNeutralHighlight( batt, "health_pickup" ) + } + + if ( victim.IsPlayer() && GetGameState() == eGameState.Playing ) //yoinked from lf + if ( GetPlayerArrayOfTeam_Alive( victim.GetTeam() ).len() == 1 ) + foreach ( entity player in GetPlayerArray() ) + Remote_CallFunction_NonReplay( player, "ServerCallback_HeadhunterLastPlayer", player.GetTeam() != victim.GetTeam() ) +} + +void function SetClientRui( entity player ) +{ + thread SetClientRuiThread(player) +} + +void function SetClientRuiThread(entity player) +{ + while ( !( file.goals.len() > 2 ) ) + wait 0.5 + + if ( !IsValid( player ) ) + return + + int k = 0 + while ( !( k > 2 ) ) + { + for ( int i; i < file.goals.len(); i++ ) + { + if ( !PlayerInRenderDistance( file.goals[i] ) ) // why the FUCK does this work + continue + Remote_CallFunction_NonReplay( player, "ServerCallback_HeadhunterUpdateRui", file.goals[i].GetEncodedEHandle(), i ) + k++ + } + wait 0.1 + } +} + +bool function PlayerInRenderDistance( entity origin ) +{ + if ( !IsValid( origin ) ) + return false + foreach ( entity player in GetPlayerArray() ) + { + if ( Distance( player.GetOrigin(), origin.GetOrigin() ) < 7500 ) + return true + } + return false +} + +void function CreateEndgoals() { + RemoveBatts() + + if (file.hasmadespawns) + return + + foreach (entity goal in file.goals) + if (IsValid(goal)) + goal.Destroy() + + file.goals.clear() + + foreach ( entity hardpoint in GetEntArrayByClass_Expensive( "info_hardpoint" ) ) + { + string gamemodeKey = "gamemode_cp" + if ( hardpoint.HasKey( gamemodeKey ) && (hardpoint.kv[gamemodeKey] == "0" || hardpoint.kv[gamemodeKey] == "") ) + { + hardpoint.Destroy() //respawn bros just put a shit ton of hardpoint spots outside of eden + continue + } + + entity Prop = CreateEntity( "prop_dynamic" ) + Prop.SetValueForModelKey( $"models/robots/mobile_hardpoint/mobile_hardpoint.mdl" ) + Prop.kv.solid = SOLID_VPHYSICS + Prop.kv.rendercolor = "81 130 151" + Prop.kv.contents = int(Prop.kv.contents) + Prop.SetAngles( Vector( 0, 0, 0 ) ) + Prop.SetBlocksRadiusDamage( true ) + SetTeam( Prop, 0) + file.goals.append(Prop) + Prop.SetOrigin( hardpoint.GetOrigin() + GetPointOffset(file.goals.len() - 1)) //ghetto ass spawn fix + DispatchSpawn( Prop ) + + Prop.SetTitle( "Goal") + Highlight_SetNeutralHighlight( Prop, "hunted_friendly" ) + } + file.hasmadespawns = true +} + +vector function GetPointOffset(int index) +{ + string mapname = GetMapName() + if (mapname == "mp_forwardbase_kodai" && index == 1) + return < -200, 25, 20> + if (mapname == "mp_grave" && index == 2) + return < -200, 0, 35> + if (mapname == "mp_grave" && index == 0) + return < 40, -20, -340> + if (mapname == "mp_homestead" && index == 0) + return < 20, -50, 0> + if (mapname == "mp_thaw" && index == 1) + return < 140, 0, 0> + if (mapname == "mp_black_water_canal" && index == 1) + return < 0, -50, 5> + if (mapname == "mp_drydock" && index == 0) + return < 0, 40, 0> + if (mapname == "mp_drydock" && index == 2) + return < 50, -50, 0> + if (mapname == "mp_angel_city" && index == 2) + return < 100, 0, 0> + if (mapname == "mp_angel_city" && index == 1) + return < 75, -75, 0> + if (mapname == "mp_colony02" && index == 2) + return < 0, 50, 0> + if (mapname == "mp_lf_meadow" && index == 2) + return <50, 0, 0> + if (mapname == "mp_lf_traffic" && index == 0) + return <0, 0, 15> + + return <0, 0, 0> +} + +int function HeadhunterDecideWinner() +{ + int militiaPlayers + int imcPlayers + + foreach ( entity player in GetPlayerArray() ) + { + if (IsAlive(player) && player.GetTeam() == TEAM_MILITIA) + militiaPlayers++ + else if (IsAlive(player) && player.GetTeam() == TEAM_IMC) + imcPlayers++ + } + + if ( militiaPlayers > imcPlayers ) + return TEAM_MILITIA + else if ( imcPlayers > militiaPlayers ) + return TEAM_IMC + + return TEAM_UNASSIGNED +} + +void function AddBTSpawn() { + FastballAddBuddySpawnForLevel( "mp_angel_city", TEAM_IMC, < 2281.39, -3333.06, 200.031 >, < 0, 91.23, 0 > ) + FastballAddBuddySpawnForLevel( "mp_angel_city", TEAM_MILITIA, < -4139.57, 4684.4, 41.0313 >, <0, -14.326, 0 > ) + + FastballAddBuddySpawnForLevel( "mp_thaw", TEAM_MILITIA, < 2049.29, -4085.22, -274.839 >, < 0, 89.2991, 0 > ) + FastballAddBuddySpawnForLevel( "mp_thaw", TEAM_IMC, < 834.484, 2664.28, -380.515 >, < 0.532141, -90.875, -0.542593 > ) + + FastballAddBuddySpawnForLevel( "mp_wargames", TEAM_MILITIA, < -4848.87, 682.17, -127.969 >, < 0, 0, 0 > ) + FastballAddBuddySpawnForLevel( "mp_wargames", TEAM_IMC, < 2960.78, 1229.36, -127.969 >, < 7.89891e-005, 146.505, 1.38387e-005 > ) + + FastballAddBuddySpawnForLevel( "mp_eden", TEAM_MILITIA, < -2404.4, 1738.07, 167.767 >, <0, -40.0894, 0> ) + FastballAddBuddySpawnForLevel( "mp_eden", TEAM_IMC, < 5248.01, 414.698, 77.1051 >, < 0, 180, 0 > ) + + FastballAddBuddySpawnForLevel( "mp_black_water_canal", TEAM_MILITIA, < 1222.88, -5050.63, -187.763 >, < 0, 45, 0 > ) + FastballAddBuddySpawnForLevel( "mp_black_water_canal", TEAM_IMC, < -235.375, 4736.75, -255.969 >, < 0, -90, 0 > ) + + FastballAddBuddySpawnForLevel( "mp_grave", TEAM_MILITIA, < 11026.8, -5163.18, 1885.64 >, < 0, 155.05, 0 > ) + FastballAddBuddySpawnForLevel( "mp_grave", TEAM_IMC, < -1952, -3120, 1993.33 >, < 0, 0, 0 > ) + + FastballAddBuddySpawnForLevel( "mp_complex3", TEAM_MILITIA, < -7800.67, -800.02, 560.02 >, < 0, 45.00, 0 > ) + FastballAddBuddySpawnForLevel( "mp_complex3", TEAM_IMC, < -795.621, -1516.19, 574.965>, < 0, -162, 0 > ) //bro bt be in the wall tho + + FastballAddBuddySpawnForLevel( "mp_forwardbase_kodai", TEAM_MILITIA, < -3200.00, 1461, 1000>, < 0, 0, 0 > ) + FastballAddBuddySpawnForLevel( "mp_forwardbase_kodai", TEAM_IMC, < 3000, 1243, 944 >, < 0, 180, 0 > ) + + FastballAddBuddySpawnForLevel( "mp_crashsite3", TEAM_MILITIA, < -6364.65, -1291.28, 822.02>, <0, -19.17, 0> ) + FastballAddBuddySpawnForLevel( "mp_crashsite3", TEAM_IMC, < -2455.29, 821.52, 539.21>, <0, -179.21, 0> ) + + FastballAddBuddySpawnForLevel( "mp_rise", TEAM_MILITIA, < -3885.97, 35.11, 704.03>, <0, 11.86, 0> ) + FastballAddBuddySpawnForLevel( "mp_rise", TEAM_IMC, < 2206.76, 1869.08, 453.9>, <0, -165.77, 0> ) + + FastballAddBuddySpawnForLevel( "mp_glitch", TEAM_MILITIA, < -4450, -629, 320 >, < 0, 0, 0 > ) + FastballAddBuddySpawnForLevel( "mp_glitch", TEAM_IMC, < 4100, 890, 320>, < 0, 180, 0 > ) + + FastballAddBuddySpawnForLevel( "mp_relic02", TEAM_MILITIA, < 4504, -3500, 150 >, < 0, -170, 0 > ) + FastballAddBuddySpawnForLevel( "mp_relic02", TEAM_IMC, < -4505, -3750, 367>, < 0, 10, 0 > ) + + FastballAddBuddySpawnForLevel( "mp_homestead", TEAM_MILITIA, < -3848.19.00, -2521, -25>, < 0, 0, 0 > ) + FastballAddBuddySpawnForLevel( "mp_homestead", TEAM_IMC, < 6000, 1560, -137 >, < 0, -150, 0 > ) + + FastballAddBuddySpawnForLevel( "mp_drydock", TEAM_MILITIA, < -4, -4350, 144 >, < 0, 80, 0 > ) + FastballAddBuddySpawnForLevel( "mp_drydock", TEAM_IMC, < 679, 4674, 200>, < 0, -90, 0 > ) +} diff --git a/mod/scripts/vscripts/gamemodes/cl_gamemode_hh.gnut b/mod/scripts/vscripts/gamemodes/cl_gamemode_hh.gnut new file mode 100644 index 0000000..138c17c --- /dev/null +++ b/mod/scripts/vscripts/gamemodes/cl_gamemode_hh.gnut @@ -0,0 +1,94 @@ +global function ClGamemodeHH_Init +global function ServerCallback_HeadhunterUpdateRui +global function ServerCallback_HeadhunterRespawnPlayer +global function ServerCallback_HeadhunterLastPlayer + +struct { + var panelARui + var panelBRui + var panelCRui +} file + +void function ClGamemodeHH_Init() +{ + ClGameState_RegisterGameStateAsset( $"ui/gamestate_info_lts.rpak" ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_INTRO, "Music_Beacon_14_BTThrowThruFirstCrane", TEAM_MILITIA ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_INTRO, "Music_Beacon_14_BTThrowThruFirstCrane", TEAM_MILITIA ) + + AddCallback_OnClientScriptInit( HeadhunterCreateRui ) + AddCallback_GameStateEnter( eGameState.Postmatch, DisplayPostMatchTop3 ) +} + +void function HeadhunterCreateRui( entity player ) +{ + file.panelARui = CreateCockpitRui( $"ui/cp_hardpoint_marker.rpak", 200 ) + file.panelBRui = CreateCockpitRui( $"ui/cp_hardpoint_marker.rpak", 200 ) + file.panelCRui = CreateCockpitRui( $"ui/cp_hardpoint_marker.rpak", 200 ) + +} + +void function ServerCallback_HeadhunterUpdateRui( int panelHandle, int id ) +{ + entity panel = GetEntityFromEncodedEHandle( panelHandle ) + var rui + if ( id == 0 ) + rui = file.panelARui + else if ( id == 1 ) + rui = file.panelBRui + else if ( id == 2 ) + rui = file.panelCRui + + RuiSetInt( rui, "hardpointId", id ) + RuiTrackFloat3( rui, "pos", panel, RUI_TRACK_OVERHEAD_FOLLOW ) + RuiSetInt( rui, "viewerTeam", GetLocalClientPlayer().GetTeam() ) + RuiTrackInt( rui, "hardpointTeamRelation", panel, RUI_TRACK_TEAM_RELATION_VIEWPLAYER ) + + RuiSetBool( rui, "isVisible", true ) +} + +void function ServerCallback_HeadhunterRespawnPlayer(int reviverEHandle) +{ + thread HeadhunterRespawnPlayerEffects_Threaded(GetEntityFromEncodedEHandle(reviverEHandle)) +} + +void function HeadhunterRespawnPlayerEffects_Threaded(entity reviver) +{ + entity player = GetLocalViewPlayer() + + while ( !IsAlive( player ) ) + WaitFrame() + + StartParticleEffectOnEntity( player.GetCockpit(), GetParticleSystemIndex( $"P_pod_screen_lasers_OUT" ), FX_PATTACH_ABSORIGIN_FOLLOW, -1 ) + + if (IsValid(reviver)) + { + string name = reviver.GetPlayerName() //they might be null after wait lol + wait 0.5 + AnnouncementData announcement = Announcement_Create( "#HH_RESPAWN" ) + Announcement_SetSubText( announcement, Localize( "#HH_RESPAWN_SUB", name )) + Announcement_SetTitleColor( announcement, <0,1,0> ) + Announcement_SetPurge( announcement, true ) + Announcement_SetPriority( announcement, 200 ) //Be higher priority than Titanfall ready indicator etc + Announcement_SetSoundAlias( announcement, SFX_HUD_ANNOUNCE_QUICK ) + Announcement_SetStyle( announcement, ANNOUNCEMENT_STYLE_QUICK ) + AnnouncementFromClass( GetLocalViewPlayer(), announcement ) + } +} + +void function ServerCallback_HeadhunterLastPlayer( bool isEnemy ) +{ + entity locPlayer = GetLocalClientPlayer() + if ( !IsValid( locPlayer ) ) + return + + if ( isEnemy ) + { + AnnouncementMessageSweep( GetLocalClientPlayer(), "#GAMEMODE_SPEEDBALL_LAST_ONE_LEFT_ENEMY", "", TEAM_COLOR_FRIENDLY ) + } + else + { + AnnouncementMessageSweep( GetLocalClientPlayer(), "#GAMEMODE_SPEEDBALL_LAST_ONE_LEFT", "", TEAM_COLOR_ENEMY ) + } + +} diff --git a/mod/scripts/vscripts/gamemodes/sh_gamemode_hh.gnut b/mod/scripts/vscripts/gamemodes/sh_gamemode_hh.gnut new file mode 100644 index 0000000..b52e0ac --- /dev/null +++ b/mod/scripts/vscripts/gamemodes/sh_gamemode_hh.gnut @@ -0,0 +1,46 @@ +globalize_all_functions + +global const string GAMEMODE_HH = "hh" + +void function HHMode_Init() +{ + AddCallback_OnCustomGamemodesInit( CreateGamemodeHH ) + AddCallback_OnRegisteringCustomNetworkVars( HHRegisterNetworkVars ) +} + + +void function CreateGamemodeHH() +{ + GameMode_Create( GAMEMODE_HH ) + GameMode_SetName( GAMEMODE_HH, "#GAMEMODE_HH" ) + GameMode_SetDesc( GAMEMODE_HH, "#PL_hh_desc" ) + GameMode_SetGameModeAnnouncement( GAMEMODE_HH, "grnc_modeDesc" ) + GameMode_SetDefaultTimeLimits( GAMEMODE_HH, 3, 0 ) + GameMode_SetDefaultScoreLimits( GAMEMODE_HH, 5, 0 ) + GameMode_AddScoreboardColumnData( GAMEMODE_HH, "#SCOREBOARD_REVIVES", PGS_ASSAULT_SCORE, 2 ) + GameMode_AddScoreboardColumnData( GAMEMODE_HH, "#SCOREBOARD_PILOT_KILLS", PGS_PILOT_KILLS, 2 ) + GameMode_AddScoreboardColumnData( GAMEMODE_HH, "#SCOREBOARD_DEATHS", PGS_DEATHS, 2 ) + GameMode_SetColor( GAMEMODE_HH, [147, 204, 57, 255] ) + + AddPrivateMatchMode( GAMEMODE_HH ) // add to private lobby modes + + #if SERVER + GameMode_AddServerInit( GAMEMODE_HH, GamemodeHH_Init ) + GameMode_SetPilotSpawnpointsRatingFunc( GAMEMODE_HH, RateSpawnpoints_Generic ) + GameMode_SetTitanSpawnpointsRatingFunc( GAMEMODE_HH, RateSpawnpoints_Generic ) + #elseif CLIENT + GameMode_AddClientInit( GAMEMODE_HH, ClGamemodeHH_Init ) + #endif + #if !UI + GameMode_SetScoreCompareFunc( GAMEMODE_HH, CompareAssaultScore ) + #endif +} + +void function HHRegisterNetworkVars() +{ + if ( GAMETYPE != GAMEMODE_HH ) + return + Remote_RegisterFunction( "ServerCallback_HeadhunterUpdateRui" ) + Remote_RegisterFunction( "ServerCallback_HeadhunterRespawnPlayer" ) + Remote_RegisterFunction( "ServerCallback_HeadhunterLastPlayer" ) +}