From 0ed0ef8308b33cec72056a05ef7611645fde44a7 Mon Sep 17 00:00:00 2001 From: Coopyy Date: Thu, 13 Jan 2022 18:21:21 -0600 Subject: Add Gamemode: Sticks & Stones (#107) * added Sticks and Stones Co-authored-by: Barichello --- .../scripts/vscripts/gamemodes/_gamemode_sns.gnut | 144 +++++++++++++++++++++ .../vscripts/gamemodes/cl_gamemode_sns.gnut | 55 ++++++++ .../vscripts/gamemodes/sh_gamemode_sns.gnut | 51 ++++++++ 3 files changed, 250 insertions(+) create mode 100644 Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_sns.gnut create mode 100644 Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_sns.gnut create mode 100644 Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_sns.gnut (limited to 'Northstar.Custom/mod') diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_sns.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_sns.gnut new file mode 100644 index 000000000..f3b7d2eee --- /dev/null +++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_sns.gnut @@ -0,0 +1,144 @@ +global function SNS_Init + +struct { + string score_leader_highlight = "enemy_boss_bounty" // highlight effect applied to person in 1st place + string offhand_weapon = "mp_weapon_thermite_grenade" // offhand weapon + + bool reset_pulse_blade_cooldown_on_pulse_blade_kill = true + + int wme_kill_value = 10 + int offhand_kill_value = 10 + int reset_kill_value = 5 + int melee_kill_value = 5 +} file + + +void function SNS_Init() +{ + SetShouldUseRoundWinningKillReplay( true ) + ClassicMP_ForceDisableEpilogue( true ) + SetLoadoutGracePeriodEnabled( false ) // prevent modifying loadouts with grace period + SetWeaponDropsEnabled( false ) + Riff_ForceTitanAvailability( eTitanAvailability.Never ) + Riff_ForceBoostAvailability( eBoostAvailability.Disabled ) + + AddCallback_OnPlayerKilled( OnPlayerKilled ) + AddCallback_OnPlayerRespawned( OnPlayerRespawned ) + AddCallback_GameStateEnter( eGameState.WinnerDetermined, OnWinnerDetermined ) +} + +void function OnPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() && GetGameState() == eGameState.Playing ) + { + SetRoundWinningKillReplayAttacker(attacker) + if ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) == eDamageSourceId.mp_weapon_grenade_sonar || DamageInfo_GetDamageSourceIdentifier( damageInfo ) == eDamageSourceId.human_execution) + { + if (victim == GetWinningPlayer()) + { + foreach ( entity otherPlayer in GetPlayerArray() ) + { + if (otherPlayer == victim) + continue + Remote_CallFunction_NonReplay( otherPlayer, "ServerCallback_AnnounceKillLeaderBankrupt", victim.GetEncodedEHandle(), attacker.GetEncodedEHandle() ) + } + } + if (file.reset_pulse_blade_cooldown_on_pulse_blade_kill) + { + attacker.TakeWeaponNow( "mp_weapon_grenade_sonar" ) // resets cooldown if you kill with it + attacker.GiveOffhandWeapon( "mp_weapon_grenade_sonar", OFFHAND_LEFT ) + } + + EmitSoundOnEntityOnlyToPlayer( attacker, attacker, "UI_CTF_3P_TeamGrabFlag" ) + bankrupt(victim, attacker) + + AddTeamScore( attacker.GetTeam(), file.reset_kill_value ) + attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, file.reset_kill_value ) + attacker.AddToPlayerGameStat( PGS_TITAN_KILLS, 1 ) + } + else if ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) == eDamageSourceId.melee_pilot_emptyhanded ) + { + AddTeamScore( attacker.GetTeam(), file.melee_kill_value ) + attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, file.melee_kill_value ) + } + else if ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) == eDamageSourceId.mp_weapon_wingman_n ) + { + AddTeamScore( attacker.GetTeam(), file.wme_kill_value ) + attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, file.wme_kill_value ) + } + else + { + AddTeamScore( attacker.GetTeam(), file.offhand_kill_value ) + attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, file.offhand_kill_value ) + } + + if (attacker == GetWinningPlayer()) + SetHighlight( attacker ) + } +} + +void function bankrupt(entity player, entity attacker) { + while (GameRules_GetTeamScore(player.GetTeam()) > 0) { + AddTeamScore( player.GetTeam(), -1 ) + } + player.SetPlayerGameStat( PGS_ASSAULT_SCORE, 0) + + Remote_CallFunction_NonReplay( player , "ServerCallback_AnnounceBankrupt", attacker.GetEncodedEHandle() ) + EmitSoundOnEntityOnlyToPlayer( player, player, "UI_InGame_MarkedForDeath_PlayerMarked" ) +} + +void function OnWinnerDetermined() +{ + SetRespawnsEnabled( false ) + SetKillcamsEnabled( false ) +} + +void function OnPlayerRespawned( entity player ) +{ + foreach ( entity weapon in player.GetMainWeapons() ) + player.TakeWeaponNow( weapon.GetWeaponClassName() ) + + foreach ( entity weapon in player.GetOffhandWeapons() ) + player.TakeWeaponNow( weapon.GetWeaponClassName() ) + + array mods = ["sns", "pas_fast_ads", "tactical_cdr_on_kill", "pas_run_and_gun", "pas_fast_swap"] + player.GiveWeapon( "mp_weapon_wingman_n", mods) + player.GiveOffhandWeapon( "melee_pilot_emptyhanded", OFFHAND_MELEE ) + player.GiveOffhandWeapon( file.offhand_weapon, OFFHAND_RIGHT ) + player.GiveOffhandWeapon( "mp_weapon_grenade_sonar", OFFHAND_LEFT ) + + if (player == GetWinningPlayer()) + SetHighlight( player ) + + thread OnPlayerRespawned_Threaded( player ) +} + +void function OnPlayerRespawned_Threaded( entity player ) +{ + // bit of a hack, need to rework earnmeter code to have better support for completely disabling it + // rn though this just waits for earnmeter code to set the mode before we set it back + WaitFrame() + if ( IsValid( player ) ) + PlayerEarnMeter_SetMode( player, eEarnMeterMode.DISABLED ) +} + +entity function GetWinningPlayer() +{ + entity bestplayer + + foreach ( entity player in GetPlayerArray() ) { + if (bestplayer == null) + bestplayer = player + + if (GameRules_GetTeamScore(player.GetTeam()) > GameRules_GetTeamScore(bestplayer.GetTeam())) + bestplayer = player + } + + return bestplayer +} + +void function SetHighlight(entity player) { + foreach ( entity player in GetPlayerArray() ) + Highlight_ClearEnemyHighlight(player) + Highlight_SetEnemyHighlight( player, file.score_leader_highlight ) +} \ No newline at end of file diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_sns.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_sns.gnut new file mode 100644 index 000000000..f91c42556 --- /dev/null +++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_sns.gnut @@ -0,0 +1,55 @@ +global function ClGameModeSNS_Init +global function ServerCallback_AnnounceKillLeaderBankrupt +global function ServerCallback_AnnounceBankrupt + +void function ClGameModeSNS_Init() +{ + ClGameState_RegisterGameStateAsset( $"ui/gamestate_info_ffa.rpak" ) + + // add music for mode, this is copied directly from the ffa/fra music registered in cl_music.gnut + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_INTRO, "music_mp_freeagents_intro", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_INTRO, "music_mp_freeagents_intro", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_WIN, "music_mp_freeagents_outro_win", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_WIN, "music_mp_freeagents_outro_win", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_DRAW, "music_mp_freeagents_outro_lose", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_DRAW, "music_mp_freeagents_outro_lose", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_LOSS, "music_mp_freeagents_outro_lose", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_LOSS, "music_mp_freeagents_outro_lose", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_THREE_MINUTE, "music_mp_freeagents_almostdone", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_THREE_MINUTE, "music_mp_freeagents_almostdone", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_LAST_MINUTE, "music_mp_freeagents_lastminute", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_LAST_MINUTE, "music_mp_freeagents_lastminute", TEAM_MILITIA ) + AddCallback_GameStateEnter( eGameState.Postmatch, DisplayPostMatchTop3 ) +} + +void function ServerCallback_AnnounceKillLeaderBankrupt( int leaderEHandle, int killerEHandle ) +{ + entity player = GetEntityFromEncodedEHandle( leaderEHandle ) + entity killer = GetEntityFromEncodedEHandle( killerEHandle ) + AnnouncementData announcement = Announcement_Create( "#SNS_LEADER_BANKRUPT" ) + Announcement_SetSubText( announcement, Localize( "#SNS_LEADER_BANKRUPT_SUB", player.GetPlayerName(), killer.GetPlayerName())) + Announcement_SetTitleColor( announcement, <1,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_AnnounceBankrupt(int killerEHandle) +{ + entity killer = GetEntityFromEncodedEHandle( killerEHandle ) + AnnouncementData announcement = Announcement_Create( "#SNS_BANKRUPT" ) + Announcement_SetSubText( announcement, Localize( "#SNS_BANKRUPT_SUB", killer.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 ) +} \ No newline at end of file diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_sns.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_sns.gnut new file mode 100644 index 000000000..b3d2c2da3 --- /dev/null +++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_sns.gnut @@ -0,0 +1,51 @@ +globalize_all_functions + +global array consoleVars; +global const string GAMEMODE_SNS = "sns" + +void function SNSMode_Init() +{ + AddCallback_OnCustomGamemodesInit( CreateGamemodeSNS ) + AddCallback_OnRegisteringCustomNetworkVars( SNSRegisterNetworkVars ) +} + + +void function CreateGamemodeSNS() +{ + GameMode_Create( GAMEMODE_SNS ) + GameMode_SetName( GAMEMODE_SNS, "#GAMEMODE_SNS" ) + GameMode_SetDesc( GAMEMODE_SNS, "#PL_sns_desc" ) + GameMode_SetGameModeAnnouncement( GAMEMODE_SNS, "ffa_modeDesc" ) + GameMode_SetDefaultTimeLimits( GAMEMODE_SNS, 15, 0.0 ) + GameMode_AddScoreboardColumnData( GAMEMODE_SNS, "#SCOREBOARD_SCORE", PGS_ASSAULT_SCORE, 2 ) + GameMode_AddScoreboardColumnData( GAMEMODE_SNS, "#SCOREBOARD_PILOT_KILLS", PGS_PILOT_KILLS, 2 ) + GameMode_AddScoreboardColumnData( GAMEMODE_SNS, "#SCOREBOARD_BANKRUPTS", PGS_TITAN_KILLS, 2 ) + GameMode_SetColor( GAMEMODE_SNS, [147, 204, 57, 255] ) + + AddPrivateMatchMode( GAMEMODE_SNS ) // add to private lobby modes + + GameMode_SetDefaultScoreLimits( GAMEMODE_SNS, 300, 0 ) + + #if SERVER + GameMode_AddServerInit( GAMEMODE_SNS, SNS_Init ) + GameMode_AddServerInit( GAMEMODE_SNS, GamemodeFFAShared_Init ) + GameMode_SetPilotSpawnpointsRatingFunc( GAMEMODE_SNS, RateSpawnpoints_Generic ) + GameMode_SetTitanSpawnpointsRatingFunc( GAMEMODE_SNS, RateSpawnpoints_Generic ) + #elseif CLIENT + GameMode_AddClientInit( GAMEMODE_SNS, ClGameModeSNS_Init ) + GameMode_AddClientInit( GAMEMODE_SNS, GamemodeFFAShared_Init ) + GameMode_AddClientInit( GAMEMODE_SNS, ClGamemodeFFA_Init ) + #endif + #if !UI + GameMode_SetScoreCompareFunc( GAMEMODE_SNS, CompareAssaultScore ) + GameMode_AddSharedInit( GAMEMODE_SNS, GamemodeFFA_Dialogue_Init ) + #endif +} + +void function SNSRegisterNetworkVars() +{ + if ( GAMETYPE != GAMEMODE_SNS ) + return + Remote_RegisterFunction( "ServerCallback_AnnounceBankrupt" ) + Remote_RegisterFunction( "ServerCallback_AnnounceKillLeaderBankrupt" ) +} \ No newline at end of file -- cgit v1.2.3