aboutsummaryrefslogtreecommitdiff
path: root/Northstar.Custom/mod/scripts/vscripts
diff options
context:
space:
mode:
authorBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2021-10-14 21:01:40 +0100
committerBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2021-10-14 21:01:40 +0100
commit9a2778eabc7ba968968e41dda9f03525d6c5383d (patch)
tree6d1c5dc64754d542d68a7f47742a701a4eec9308 /Northstar.Custom/mod/scripts/vscripts
parentc0a0c7e502f2bc99185d79a485b965f63de7a203 (diff)
downloadNorthstarMods-9a2778eabc7ba968968e41dda9f03525d6c5383d.tar.gz
NorthstarMods-9a2778eabc7ba968968e41dda9f03525d6c5383d.zip
oh fuck i forgot to commit for a while
Diffstat (limited to 'Northstar.Custom/mod/scripts/vscripts')
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/_bleedout_damage.gnut137
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut6
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/_custom_oob_timer.gnut7
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut10
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_gg.gnut2
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_hs.gnut191
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut6
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_kr.gnut2
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_hs.gnut91
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_hs.gnut47
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_bob.nut38
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_bob_temp_props.nut7
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/titan/sh_first_person_embark.gnut6
13 files changed, 536 insertions, 14 deletions
diff --git a/Northstar.Custom/mod/scripts/vscripts/_bleedout_damage.gnut b/Northstar.Custom/mod/scripts/vscripts/_bleedout_damage.gnut
new file mode 100644
index 000000000..8b21184ad
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/_bleedout_damage.gnut
@@ -0,0 +1,137 @@
+// note: this is technically vanilla content, since bleedout was shipped with retail, but it needs custom remote functions which would break vanilla compatiblity, so it's not in Northstar.CustomServers
+// idk why bleedout was even shipped in retail lmao
+global function BleedoutDamage_PreInit
+global function BleedoutDamage_Init
+global function SetShouldPlayerStartBleedoutFunc
+
+struct {
+ array<entity> bleedingPlayers // this is in _bleedout already, but it doesn't expose a way to track it, so we have to track it ourselves
+ bool functionref( entity, var ) shouldPlayerStartBleedoutFunc = null
+} file
+
+void function BleedoutDamage_PreInit()
+{
+ AddCallback_OnRegisteringCustomNetworkVars( Bleedout_RegisterRemoteFunctions )
+}
+
+void function Bleedout_RegisterRemoteFunctions()
+{
+ Remote_RegisterFunction( "ServerCallback_BLEEDOUT_StartFirstAidProgressBar" )
+ Remote_RegisterFunction( "ServerCallback_BLEEDOUT_StopFirstAidProgressBar" )
+ Remote_RegisterFunction( "ServerCallback_BLEEDOUT_ShowWoundedMarker" )
+ Remote_RegisterFunction( "ServerCallback_BLEEDOUT_HideWoundedMarker" )
+}
+
+// copied from sh_bleedout
+const float DEFAULT_BLEEDOUT_TIME = 30.0
+const float DEFAULT_FIRSTAID_TIME = 3.0
+const float DEFAULT_FIRSTAID_TIME_SELF = -1.0
+const float DEFAULT_FIRSTAID_HEAL_PERCENT = 1.0
+const float DEFAULT_AI_BLEEDING_PLAYER_MISS_CHANCE = 0.0
+const bool DEFAULT_FORCE_WEAPON_HOLSTER = false
+const bool DEFAULT_DEATH_ON_TEAM_BLEEDOUT = false
+
+void function BleedoutDamage_Init()
+{
+ AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_BLEEDOUT", "riff_player_bleedout", [ "Default", "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_BLEEDOUT", "player_bleedout_forceHolster", [ "Disabled", "Enabled" ], DEFAULT_FORCE_WEAPON_HOLSTER.tostring() )
+ AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_BLEEDOUT", "player_bleedout_forceDeathOnTeamBleedout", [ "Disabled", "Enabled" ], DEFAULT_DEATH_ON_TEAM_BLEEDOUT.tostring() )
+ AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_BLEEDOUT", "player_bleedout_bleedoutTime", DEFAULT_BLEEDOUT_TIME.tostring() )
+ AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_BLEEDOUT", "player_bleedout_firstAidTime", DEFAULT_FIRSTAID_TIME.tostring() )
+ AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_BLEEDOUT", "player_bleedout_firstAidTimeSelf", DEFAULT_FIRSTAID_TIME_SELF.tostring() )
+ AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_BLEEDOUT", "player_bleedout_firstAidHealPercent", DEFAULT_FIRSTAID_HEAL_PERCENT.tostring() )
+ AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_BLEEDOUT", "player_bleedout_aiBleedingPlayerMissChance", DEFAULT_AI_BLEEDING_PLAYER_MISS_CHANCE.tostring() )
+
+ #if CLIENT
+ // because playlist var overrides fucking suck, they aren't actually updated by this point
+ // client bleedout can be inited late enough that we can just init it on local player spawn
+ AddCallback_LocalClientPlayerSpawned( InitClientBleedoutForLocalPlayer )
+ #elseif SERVER
+ // sh_riff_settings should set this correctly on server
+ if ( !Riff_PlayerBleedout() )
+ return
+
+ AddDamageCallback( "player", HandleDamageForBleedout ) // do this irregardless of whether scripts inited, given it should always be used for bleedout
+ Bleedout_SetCallback_OnPlayerStartBleedout( OnPlayerBleedoutBegin ) // kinda sucks we have to use this callback since game scripts could be using it
+
+ // dont init if scripts already inited it manually
+ if ( !Bleedout_IsBleedoutLogicActive() )
+ {
+ InitSharedBleedoutWithPlaylistVars()
+ Bleedout_Init()
+ }
+ #endif
+}
+
+void function SetShouldPlayerStartBleedoutFunc( bool functionref( entity, var ) func )
+{
+ file.shouldPlayerStartBleedoutFunc = func
+}
+
+void function InitSharedBleedoutWithPlaylistVars()
+{
+ BleedoutShared_Init(
+ GetCurrentPlaylistVarFloat( "player_bleedout_bleedoutTime", DEFAULT_BLEEDOUT_TIME ),
+ GetCurrentPlaylistVarFloat( "player_bleedout_firstAidTime", DEFAULT_FIRSTAID_TIME ),
+ GetCurrentPlaylistVarFloat( "player_bleedout_firstAidTimeSelf", DEFAULT_FIRSTAID_TIME_SELF ),
+ GetCurrentPlaylistVarFloat( "player_bleedout_firstAidHealPercent", DEFAULT_FIRSTAID_HEAL_PERCENT ),
+ GetCurrentPlaylistVarFloat( "player_bleedout_aiBleedingPlayerMissChance", DEFAULT_AI_BLEEDING_PLAYER_MISS_CHANCE ),
+ GetCurrentPlaylistVarInt( "player_bleedout_forceHolster", int( DEFAULT_FORCE_WEAPON_HOLSTER ) ) == 1,
+ GetCurrentPlaylistVarInt( "player_bleedout_forceDeathOnTeamBleedout", int( DEFAULT_DEATH_ON_TEAM_BLEEDOUT ) ) == 1
+ )
+}
+
+#if CLIENT
+void function InitClientBleedoutForLocalPlayer( entity player )
+{
+ // dont init if bleedout is disabled or scripts already inited it
+ if ( !Riff_PlayerBleedout() || Bleedout_IsBleedoutLogicActive() )
+ return
+
+ InitSharedBleedoutWithPlaylistVars()
+ BleedoutClient_Init()
+}
+#endif
+
+#if SERVER
+void function HandleDamageForBleedout( entity player, var damageInfo )
+{
+ if ( IsInstantDeath( damageInfo ) || DamageInfo_GetForceKill( damageInfo ) || player.IsTitan() || file.bleedingPlayers.contains( player ) )
+ return
+
+ if ( file.shouldPlayerStartBleedoutFunc != null )
+ if ( !file.shouldPlayerStartBleedoutFunc( player, damageInfo ) )
+ return
+
+ // check if damage would kill player
+ if ( player.GetHealth() - DamageInfo_GetDamage( damageInfo ) <= 0 )
+ {
+ Bleedout_StartPlayerBleedout( player, DamageInfo_GetAttacker( damageInfo ) )
+ DamageInfo_SetDamage( damageInfo, 1 ) // prevent player from dying, but if we set it to 0, player won't receive any knockback from damage source
+ }
+}
+
+void function OnPlayerBleedoutBegin( entity player )
+{
+ file.bleedingPlayers.append( player )
+
+ // would prefer to use Bleedout_SetCallback_OnPlayerGiveFirstAid for this, but it doesn't expose the player that's receiving first aid for some reason
+ thread TrackPlayerBleedout( player )
+}
+
+void function TrackPlayerBleedout( entity player )
+{
+ player.EndSignal( "OnDeath" )
+ player.EndSignal( "OnDestroy" )
+
+ OnThreadEnd( function() : ( player )
+ {
+ file.bleedingPlayers.remove( file.bleedingPlayers.find( player ) )
+ })
+
+ WaitFrame() // wait a frame, since this gets called before this status effect is added
+
+ while ( StatusEffect_Get( player, eStatusEffect.bleedoutDOF ) != 0 )
+ WaitFrame()
+}
+#endif \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut b/Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut
index 8ebef0342..faa924804 100644
--- a/Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut
@@ -1,8 +1,10 @@
global function CustomAirAccelVars_Init
void function CustomAirAccelVars_Init()
-{
- AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_PILOT", "custom_air_accel_pilot", "500" ) // 500 is the default airaccel
+{
+ #if MP
+ AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_PILOT", "custom_air_accel_pilot", "500" ) // 500 is the default airaccel
+ #endif
#if SERVER
AddCallback_OnPlayerRespawned( ApplyCustomPlayerAirAccel )
diff --git a/Northstar.Custom/mod/scripts/vscripts/_custom_oob_timer.gnut b/Northstar.Custom/mod/scripts/vscripts/_custom_oob_timer.gnut
new file mode 100644
index 000000000..9689302c1
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/_custom_oob_timer.gnut
@@ -0,0 +1,7 @@
+global function CustomOOBTimer_Init
+
+void function CustomOOBTimer_Init()
+{
+ AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_MATCH", "oob_timer_enabled", [ "Disabled", "Enabled" ], "1" )
+ level.disableOutOfBounds <- GetCurrentPlaylistVarInt( "oob_timer_enabled", 1 ) == 0
+} \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut
index b59cd2dd4..00c193105 100644
--- a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut
@@ -27,7 +27,6 @@ void function GamemodeFastball_Init()
SetTimeoutWinnerDecisionFunc( FastballDecideWinner )
AddCallback_OnClientConnected( FastballInitPlayer )
- AddCallback_OnPlayerKilled( FastballOnPlayerKilled ) // move this to a system in _gamestate soon!!
// setup spawns
// first is a, second is b, third is c
@@ -164,15 +163,6 @@ function FastballOnPanelHacked( panel, player, success )
}
}
-void function FastballOnPlayerKilled( entity victim, entity attacker, var damageInfo )
-{
- if ( !victim.IsPlayer() || GetGameState() != eGameState.Playing )
- return
-
- if ( GetPlayerArrayOfTeam_Alive( victim.GetTeam() ).len() == 0 )
- SetWinner( GetOtherTeam( victim.GetTeam() ) )
-}
-
int function FastballDecideWinner()
{
int militiaPanels
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_gg.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_gg.gnut
index b9ee40f1f..e01780347 100644
--- a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_gg.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_gg.gnut
@@ -5,7 +5,7 @@ void function GamemodeGG_Init()
SetSpawnpointGamemodeOverride( FFA )
SetShouldUseRoundWinningKillReplay( true )
- Evac_SetEnabled( false )
+ ClassicMP_ForceDisableEpilogue( true )
SetLoadoutGracePeriodEnabled( false ) // prevent modifying loadouts with grace period
SetWeaponDropsEnabled( false )
Riff_ForceTitanAvailability( eTitanAvailability.Never )
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_hs.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_hs.gnut
new file mode 100644
index 000000000..bc65e0b6d
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_hs.gnut
@@ -0,0 +1,191 @@
+global function GamemodeHideAndSeek_Init
+
+struct {
+ entity intermissionCam
+ array<entity> droppodSpawns
+
+ float hidingTime
+ bool autobalance
+
+ float hidingStartTime
+} file
+
+void function GamemodeHideAndSeek_Init()
+{
+ SetSpawnpointGamemodeOverride( FFA )
+ Riff_ForceTitanAvailability( eTitanAvailability.Never )
+ Riff_ForceBoostAvailability( eBoostAvailability.Disabled )
+ SetRespawnsEnabled( false )
+ Riff_ForceSetEliminationMode( eEliminationMode.Pilots )
+
+ SetTimeoutWinnerDecisionFunc( HideAndSeekDecideWinner )
+ ClassicMP_SetCustomIntro( GamemodeHideAndSeekIntroSetup, 0.0 )
+
+ AddCallback_OnPlayerRespawned( SetupHideAndSeekPlayer )
+ AddCallback_OnPlayerKilled( TryNotifyLastPlayerAlive )
+ AddSpawnCallback( "info_intermission", SetIntermissionCam )
+ AddSpawnCallback( "info_spawnpoint_droppod_start", AddDroppodSpawn )
+
+ file.hidingTime = GetCurrentPlaylistVarFloat( "hideandseek_hiding_time", 60.0 )
+ file.autobalance = GetCurrentPlaylistVarInt( "hideandseek_balance_teams", 1 ) == 1
+}
+
+void function GamemodeHideAndSeekIntroSetup()
+{
+ AddCallback_GameStateEnter( eGameState.Prematch, HideAndSeekIntroPrematch )
+ AddCallback_OnClientConnected( AddPlayerToHideAndSeekIntro )
+}
+
+void function SetIntermissionCam( entity cam )
+{
+ file.intermissionCam = cam
+}
+
+void function AddDroppodSpawn( entity spawn )
+{
+ file.droppodSpawns.append( spawn )
+}
+
+void function AddPlayerToHideAndSeekIntro( entity player )
+{
+ if ( GetGameState() < eGameState.Prematch || Time() - file.hidingStartTime > file.hidingTime )
+ return
+
+ // seeker/hider autobalance
+ // try to have 1/6 of players be seekers
+ if ( file.autobalance )
+ {
+ int wantedSeekers = int( max( 1, GetPlayerArray().len() / 6 ) )
+
+ if ( GetPlayerArrayOfTeam( HIDEANDSEEK_TEAM_SEEKER ).len() < wantedSeekers )
+ SetTeam( player, HIDEANDSEEK_TEAM_SEEKER )
+ }
+
+ ScreenFadeFromBlack( player, 1.0, 0.75 )
+ Remote_CallFunction_NonReplay( player, "ServerCallback_ShowHideAndSeekCountdown", file.hidingStartTime + file.hidingTime )
+
+ if ( player.GetTeam() == HIDEANDSEEK_TEAM_HIDER )
+ {
+ player.kv.visibilityFlags = ENTITY_VISIBLE_TO_FRIENDLY
+ Highlight_ClearEnemyHighlight( player )
+
+ thread HiderIntroThread( player )
+ }
+ else
+ thread SeekerIntroThread( player )
+
+ thread DelayedRoleAnnounce( player )
+}
+
+void function HideAndSeekIntroPrematch()
+{
+ ClassicMP_OnIntroStarted()
+
+ file.hidingStartTime = Time()
+
+ foreach ( entity player in GetPlayerArray() )
+ AddPlayerToHideAndSeekIntro( player )
+
+ // this intro is mostly done in playing, so just finish the intro up now and we can do fully custom logic from here
+ WaitFrame()
+ ClassicMP_OnIntroFinished()
+
+ thread GlobalSeekerIntroThread()
+}
+
+void function HiderIntroThread( entity player )
+{
+ RespawnAsPilot( player )
+
+ wait ( file.hidingStartTime + file.hidingTime ) - Time()
+
+ player.kv.visibilityFlags = ENTITY_VISIBLE_TO_EVERYONE // make sure everyone can see us again
+}
+
+void function SeekerIntroThread( entity player )
+{
+ MuteHalfTime( player )
+
+ player.SetObserverModeStaticPosition( file.intermissionCam.GetOrigin() )
+ player.SetObserverModeStaticAngles( file.intermissionCam.GetAngles() )
+ player.StartObserverMode( OBS_MODE_STATIC_LOCKED )
+
+ wait ( file.hidingStartTime + file.hidingTime ) - Time()
+ UnMuteAll( player )
+}
+
+void function DelayedRoleAnnounce( entity player )
+{
+ wait 1.75
+ Remote_CallFunction_NonReplay( player, "ServerCallback_AnnounceHideAndSeekRole" )
+}
+
+void function GlobalSeekerIntroThread()
+{
+ wait file.hidingTime
+
+
+ PlayMusicToAll( eMusicPieceID.GAMEMODE_1 )
+ foreach ( entity hider in GetPlayerArrayOfTeam( HIDEANDSEEK_TEAM_HIDER ) )
+ Remote_CallFunction_NonReplay( hider, "ServerCallback_SeekersIncoming" )
+
+ array<entity> seekers = GetPlayerArrayOfTeam( HIDEANDSEEK_TEAM_SEEKER )
+ entity podSpawn = file.droppodSpawns.getrandom()
+ SpawnPlayersInDropPod( seekers, podSpawn.GetOrigin(), podSpawn.GetAngles() )
+
+ foreach ( entity seeker in seekers )
+ if ( IsValid( seeker ) )
+ Highlight_SetEnemyHighlight( seeker, "enemy_sonar" )
+}
+
+void function SetupHideAndSeekPlayer( entity player )
+{
+ foreach ( entity weapon in player.GetMainWeapons() )
+ player.TakeWeapon( weapon.GetWeaponClassName() )
+
+ player.TakeWeapon( player.GetOffhandWeapon( OFFHAND_ORDNANCE ).GetWeaponClassName() )
+
+ player.GiveWeapon( "mp_weapon_rocket_launcher" )
+ player.SetActiveWeaponByName( "mp_weapon_rocket_launcher" )
+
+ Highlight_SetFriendlyHighlight( player, "sp_friendly_pilot" )
+
+ if ( player.GetTeam() == HIDEANDSEEK_TEAM_HIDER )
+ {
+ player.TakeWeapon( player.GetMeleeWeapon().GetWeaponClassName() )
+
+ // set visibility flags if we're hiding, so seekers can't see us on intermission cam
+ if ( Time() - file.hidingStartTime < file.hidingTime )
+ player.kv.visiblityFlags = ENTITY_VISIBLE_TO_FRIENDLY
+
+ // remove red outline, ideally should work tm
+ Highlight_ClearEnemyHighlight( player )
+ }
+ else
+ player.TakeWeapon( "mp_weapon_grenade_sonar" ) // seekers should not have pulse blade
+}
+
+void function TryNotifyLastPlayerAlive( entity victim, entity attacker, var damageInfo )
+{
+ if ( victim.GetTeam() == HIDEANDSEEK_TEAM_HIDER )
+ {
+ array<entity> hiders = GetPlayerArrayOfTeam( HIDEANDSEEK_TEAM_HIDER )
+ if ( hiders.len() == 1 )
+ {
+ PlayMusicToAll( eMusicPieceID.GAMEMODE_2 )
+
+ // let them know they're the last hider
+ Remote_CallFunction_NonReplay( hiders[ 0 ], "ServerCallback_LastHiderAlive" )
+ StimPlayer( hiders[ 0 ], 9999.9 ) // can't do endless since we don't get the visual effect in endless
+
+ // tell seekers
+ foreach ( entity player in GetPlayerArrayOfTeam( HIDEANDSEEK_TEAM_SEEKER ) )
+ Remote_CallFunction_NonReplay( player, "ServerCallback_LastHiderAlive" )
+ }
+ }
+}
+
+int function HideAndSeekDecideWinner()
+{
+ return HIDEANDSEEK_TEAM_HIDER // on timeout, hiders always win
+} \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut
index 8706d53b1..b2e76aaf8 100644
--- a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut
@@ -13,6 +13,7 @@ void function GamemodeInfection_Init()
Riff_ForceTitanAvailability( eTitanAvailability.Never )
Riff_ForceBoostAvailability( eBoostAvailability.Disabled )
+ SetShouldPlayerStartBleedoutFunc( InfectionShouldPlayerStartBleedout )
AddCallback_OnClientConnected( InfectionInitPlayer )
AddCallback_OnPlayerKilled( InfectionOnPlayerKilled )
AddCallback_OnPlayerRespawned( RespawnInfected )
@@ -176,4 +177,9 @@ int function TimeoutCheckSurvivors()
return INFECTION_TEAM_SURVIVOR
return INFECTION_TEAM_INFECTED
+}
+
+bool function InfectionShouldPlayerStartBleedout( entity player, var damageInfo )
+{
+ return player.GetTeam() != INFECTION_TEAM_INFECTED
} \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_kr.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_kr.gnut
index cf9d6bc57..7a226e210 100644
--- a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_kr.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_kr.gnut
@@ -13,7 +13,7 @@ void function GamemodeKR_Init()
SetSpawnpointGamemodeOverride( FFA )
- Evac_SetEnabled( false )
+ ClassicMP_ForceDisableEpilogue( true )
Riff_ForceTitanAvailability( eTitanAvailability.Never )
Riff_ForceBoostAvailability( eBoostAvailability.Disabled )
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_hs.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_hs.gnut
new file mode 100644
index 000000000..8bfbb10e0
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_hs.gnut
@@ -0,0 +1,91 @@
+global function ClGamemodeHideAndSeek_Init
+global function ServerCallback_ShowHideAndSeekCountdown
+global function ServerCallback_AnnounceHideAndSeekRole
+global function ServerCallback_SeekersIncoming
+global function ServerCallback_LastHiderAlive
+
+struct {
+ var countdownRui
+} file
+
+void function ClGamemodeHideAndSeek_Init()
+{
+ ClGameState_RegisterGameStateAsset( $"ui/gamestate_info_lts.rpak" )
+
+ RegisterLevelMusicForTeam( eMusicPieceID.GAMEMODE_1, "music_mp_fd_midwave", HIDEANDSEEK_TEAM_SEEKER )
+ RegisterLevelMusicForTeam( eMusicPieceID.GAMEMODE_1, "music_skyway_01_intro", HIDEANDSEEK_TEAM_HIDER )
+
+ RegisterLevelMusicForTeam( eMusicPieceID.GAMEMODE_2, "music_skyway_04_smartpistolrun", TEAM_IMC )
+ RegisterLevelMusicForTeam( eMusicPieceID.GAMEMODE_2, "music_skyway_04_smartpistolrun", TEAM_MILITIA )
+}
+
+void function ServerCallback_ShowHideAndSeekCountdown( float endTime )
+{
+ file.countdownRui = CreateCockpitRui( $"ui/dropship_intro_countdown.rpak", 0 )
+ RuiSetResolutionToScreenSize( file.countdownRui )
+ RuiSetGameTime( file.countdownRui, "gameStartTime", endTime )
+}
+
+void function ServerCallback_AnnounceHideAndSeekRole()
+{
+ if ( GetLocalViewPlayer().GetTeam() == HIDEANDSEEK_TEAM_SEEKER )
+ {
+ AnnouncementData announcement = Announcement_Create( "#HIDEANDSEEK_YOU_ARE_SEEKER" )
+ Announcement_SetSubText( announcement, Localize( "#HIDEANDSEEK_SEEKER_DESC", GetCurrentPlaylistVarFloat( "hideandseek_hiding_time", 60.0 ).tostring() ) )
+ Announcement_SetTitleColor( announcement, <0,0,1> )
+ 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 )
+ }
+ else
+ {
+ AnnouncementData announcement = Announcement_Create( "#HIDEANDSEEK_YOU_ARE_HIDER" )
+ Announcement_SetSubText( announcement, "#HIDEANDSEEK_HIDER_DESC" )
+ Announcement_SetTitleColor( announcement, <0,0,1> )
+ 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_SeekersIncoming()
+{
+ AnnouncementData announcement = Announcement_Create( "#HIDEANDSEEK_SEEKERS_INCOMING" )
+ Announcement_SetSubText( announcement, "#HIDEANDSEEK_DONT_GET_FOUND" )
+ Announcement_SetTitleColor( announcement, <1,0,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_LastHiderAlive()
+{
+ if ( GetLocalViewPlayer().GetTeam() == HIDEANDSEEK_TEAM_SEEKER )
+ {
+ AnnouncementData announcement = Announcement_Create( Localize( "#HIDEANDSEEK_GET_LAST_HIDER", GetPlayerArrayOfTeam_Alive( HIDEANDSEEK_TEAM_HIDER )[ 0 ].GetPlayerName() ) )
+ Announcement_SetTitleColor( announcement, <1,0,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 )
+ }
+ else
+ {
+ AnnouncementData announcement = Announcement_Create( "#HIDEANDSEEK_YOU_ARE_LAST_HIDER" )
+ Announcement_SetSubText( announcement, "#HIDEANDSEEK_GOT_STIM" )
+ Announcement_SetTitleColor( announcement, <1,0,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 )
+ }
+}
+
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_hs.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_hs.gnut
new file mode 100644
index 000000000..f4269ac42
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_hs.gnut
@@ -0,0 +1,47 @@
+global function Sh_GamemodeHideAndSeek_Init
+
+global const string GAMEMODE_HIDEANDSEEK = "hs"
+global const int HIDEANDSEEK_TEAM_SEEKER = TEAM_IMC
+global const int HIDEANDSEEK_TEAM_HIDER = TEAM_MILITIA
+
+void function Sh_GamemodeHideAndSeek_Init()
+{
+ // create custom gamemode
+ AddCallback_OnCustomGamemodesInit( CreateGamemodeHideAndSeek )
+ AddCallback_OnRegisteringCustomNetworkVars( HideAndSeekRegisterNetworkVars )
+}
+
+void function CreateGamemodeHideAndSeek()
+{
+ GameMode_Create( GAMEMODE_HIDEANDSEEK )
+ GameMode_SetName( GAMEMODE_HIDEANDSEEK, "#GAMEMODE_hs" )
+ GameMode_SetDesc( GAMEMODE_HIDEANDSEEK, "#PL_hs_desc" )
+ GameMode_SetGameModeAnnouncement( GAMEMODE_HIDEANDSEEK, "ffa_modeDesc" )
+ GameMode_SetColor( GAMEMODE_HIDEANDSEEK, [147, 204, 57, 255] )
+
+ AddPrivateMatchMode( GAMEMODE_HIDEANDSEEK ) // add to private lobby modes
+ AddPrivateMatchModeSettingEnum( "#GAMEMODE_hs", "hideandseek_balance_teams", [ "Disabled", "Enabled" ], "1" )
+ AddPrivateMatchModeSettingArbitrary( "#GAMEMODE_hs", "hideandseek_hiding_time", "60" )
+
+ #if SERVER
+ GameMode_AddServerInit( GAMEMODE_HIDEANDSEEK, GamemodeHideAndSeek_Init )
+ GameMode_SetPilotSpawnpointsRatingFunc( GAMEMODE_HIDEANDSEEK, RateSpawnpoints_Generic )
+ GameMode_SetTitanSpawnpointsRatingFunc( GAMEMODE_HIDEANDSEEK, RateSpawnpoints_Generic )
+ #elseif CLIENT
+ GameMode_AddClientInit( GAMEMODE_HIDEANDSEEK, ClGamemodeHideAndSeek_Init )
+ #endif
+ #if !UI
+ GameMode_SetScoreCompareFunc( GAMEMODE_HIDEANDSEEK, CompareAssaultScore )
+ #endif
+}
+
+void function HideAndSeekRegisterNetworkVars()
+{
+ if ( GAMETYPE != GAMEMODE_HIDEANDSEEK )
+ return
+
+ Remote_RegisterFunction( "ServerCallback_ShowHideAndSeekCountdown" )
+ Remote_RegisterFunction( "ServerCallback_SeekersIncoming" )
+ Remote_RegisterFunction( "ServerCallback_LastHiderAlive" )
+ Remote_RegisterFunction( "ServerCallback_AnnounceHideAndSeekRole" )
+} \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_bob.nut b/Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_bob.nut
new file mode 100644
index 000000000..afd4fc371
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_bob.nut
@@ -0,0 +1,38 @@
+untyped
+global function CodeCallback_MapInit
+
+const float PLATFORM_TRAVEL_TIME = 20.0
+
+struct {
+ array<entity> platformMoverNodes
+ entity platformMover
+} file
+
+void function CodeCallback_MapInit()
+{
+ AddCallback_EntitiesDidLoad( BobMap_EntitiesDidLoad )
+}
+
+void function BobMap_EntitiesDidLoad()
+{
+ BobMap_InitTempProps()
+
+ file.platformMoverNodes = GetEntityLinkChain( GetEntByScriptName( "mp_bob_movingplatform_node_0" ) )
+ file.platformMover = GetEntByScriptName( "mp_bob_movingplatform" )
+ file.platformMover.SetOrigin( file.platformMoverNodes[ 0 ].GetOrigin() )
+
+ entity platformProp = CreatePropDynamic( file.platformMover.GetValueForModelKey(), file.platformMover.GetOrigin(), file.platformMover.GetAngles() )
+ platformProp.SetParent( file.platformMover )
+
+ thread MovingPlatformThink()
+}
+
+void function MovingPlatformThink()
+{
+ int currentNodeIdx = 0
+ while ( true )
+ {
+ file.platformMover.SetOrigin( file.platformMoverNodes[ currentNodeIdx % file.platformMoverNodes.len() ].GetOrigin() )
+ file.platformMover.MoveTo( file.platformMoverNodes[ ++currentNodeIdx % file.platformMoverNodes.len() ].GetOrigin(), PLATFORM_TRAVEL_TIME, 0, 0 )
+ }
+} \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_bob_temp_props.nut b/Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_bob_temp_props.nut
new file mode 100644
index 000000000..84ffe3e94
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_bob_temp_props.nut
@@ -0,0 +1,7 @@
+global function BobMap_InitTempProps
+
+void function BobMap_InitTempProps()
+{
+ PrecacheModel( $"models/vistas/planet_blue_sun.mdl" )
+ CreatePropDynamic( $"models/vistas/planet_blue_sun.mdl", GetEnt( "skybox_cam_level" ).GetOrigin(), GetEnt( "skybox_cam_level" ).GetAngles() )
+} \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/titan/sh_first_person_embark.gnut b/Northstar.Custom/mod/scripts/vscripts/titan/sh_first_person_embark.gnut
index 0c95ae4cd..0c47c0140 100644
--- a/Northstar.Custom/mod/scripts/vscripts/titan/sh_first_person_embark.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/titan/sh_first_person_embark.gnut
@@ -1,4 +1,5 @@
global function FirstPersonEmbark_Init
+global function FirstPersonEmbark_InitPlaylistVars
#if CLIENT
global function ServerCallback_HideHudForFPEmbark
@@ -24,6 +25,11 @@ void function FirstPersonEmbark_RegisterCustomNetworkFunctions()
Remote_RegisterFunction( "ServerCallback_HideHudForFPEmbark" )
}
+void function FirstPersonEmbark_InitPlaylistVars()
+{
+ AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_TITAN", "fp_embark_enabled", [ "Disabled", "Enabled" ], "0" )
+}
+
#if CLIENT
void function ServerCallback_HideHudForFPEmbark()
{