From d579444d87117c9262142a3a6ef553a51d3a7735 Mon Sep 17 00:00:00 2001 From: x3Karma Date: Wed, 29 Dec 2021 12:35:57 +0800 Subject: Stop Pilots vs Pilots from scoring during the epilogue --- .../mod/scripts/vscripts/gamemodes/_gamemode_ps.nut | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut index 4e62e8c54..7e3e5ea2d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut @@ -10,6 +10,6 @@ void function GamemodePs_Init() void function GiveScoreForPlayerKill( entity victim, entity attacker, var damageInfo ) { - if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() ) + if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() && GetGameState() != eGameState.Epilogue ) AddTeamScore( attacker.GetTeam(), 1 ) -} \ No newline at end of file +} -- cgit v1.2.3 From 425336bbb830a2699e3b9b4eb11d71690bb26aac Mon Sep 17 00:00:00 2001 From: x3Karma Date: Wed, 29 Dec 2021 12:37:06 +0800 Subject: Stop Skirmish from scoring during the epilogue --- .../mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut index 5dd8a403b..fd5cbb146 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut @@ -9,7 +9,7 @@ void function GamemodeTdm_Init() void function GiveScoreForPlayerKill( entity victim, entity attacker, var damageInfo ) { - if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() ) + if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() && GetGameState() != eGameState.Epilogue ) AddTeamScore( attacker.GetTeam(), 1 ) } @@ -17,4 +17,4 @@ void function RateSpawnpoints_Directional( int checkclass, array spawnpo { // temp RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) -} \ No newline at end of file +} -- cgit v1.2.3 From e4e46b7c061599a040164776b9b7cd96c1f40fb6 Mon Sep 17 00:00:00 2001 From: x3Karma Date: Wed, 29 Dec 2021 12:37:07 +0800 Subject: Stop Skirmish from scoring during the epilogue --- .../mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut index 5dd8a403b..fd5cbb146 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut @@ -9,7 +9,7 @@ void function GamemodeTdm_Init() void function GiveScoreForPlayerKill( entity victim, entity attacker, var damageInfo ) { - if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() ) + if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() && GetGameState() != eGameState.Epilogue ) AddTeamScore( attacker.GetTeam(), 1 ) } @@ -17,4 +17,4 @@ void function RateSpawnpoints_Directional( int checkclass, array spawnpo { // temp RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) -} \ No newline at end of file +} -- cgit v1.2.3 From 4210b5684c11538db59df1cd4a77e99423df4f4d Mon Sep 17 00:00:00 2001 From: x3Karma Date: Wed, 29 Dec 2021 12:38:15 +0800 Subject: Stop Titan Brawl from scoring during the epilogue if tits turned on lol --- .../mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut index 9e5d95bac..82b673d2a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut @@ -69,8 +69,8 @@ void function PlayerWatchesTTDMIntroIntermissionCam( entity player ) void function AddTeamScoreForPlayerKilled( entity victim, entity attacker, var damageInfo ) { - if ( victim == attacker || !victim.IsPlayer() || !attacker.IsPlayer() ) + if ( victim == attacker || !victim.IsPlayer() || !attacker.IsPlayer() || GetGameState() != eGameState.Playing ) return AddTeamScore( GetOtherTeam( victim.GetTeam() ), 1 ) -} \ No newline at end of file +} -- cgit v1.2.3 From ecba9deb83af9b867bb3034f0235420c8f22cd18 Mon Sep 17 00:00:00 2001 From: x3Karma Date: Wed, 29 Dec 2021 12:47:56 +0800 Subject: Add Round Winning Kill Replay for Infection --- Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut index ee6c2c0a0..2e3f03ad9 100644 --- a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut +++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut @@ -10,6 +10,7 @@ void function GamemodeInfection_Init() SetSpawnpointGamemodeOverride( FFA ) SetLoadoutGracePeriodEnabled( false ) // prevent modifying loadouts with grace period SetWeaponDropsEnabled( false ) + SetShouldUseRoundWinningKillReplay( true ) Riff_ForceTitanAvailability( eTitanAvailability.Never ) Riff_ForceBoostAvailability( eBoostAvailability.Disabled ) ClassicMP_ForceDisableEpilogue( true ) @@ -188,4 +189,4 @@ int function TimeoutCheckSurvivors() bool function InfectionShouldPlayerStartBleedout( entity player, var damageInfo ) { return player.GetTeam() != INFECTION_TEAM_INFECTED -} \ No newline at end of file +} -- cgit v1.2.3 From 20898278b760a775d1c375b6340fe244db9a385f Mon Sep 17 00:00:00 2001 From: x3Karma Date: Thu, 30 Dec 2021 01:33:50 +0800 Subject: Add timeout checker for Skirmish, PvP and Titan Brawl --- _gamemode_ps.nut | 27 +++++++++++++++++ _gamemode_tdm.nut | 31 +++++++++++++++++++ _gamemode_ttdm.nut | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 _gamemode_ps.nut create mode 100644 _gamemode_tdm.nut create mode 100644 _gamemode_ttdm.nut diff --git a/_gamemode_ps.nut b/_gamemode_ps.nut new file mode 100644 index 000000000..7eec7c89f --- /dev/null +++ b/_gamemode_ps.nut @@ -0,0 +1,27 @@ +global function GamemodePs_Init + +void function GamemodePs_Init() +{ + Riff_ForceTitanAvailability( eTitanAvailability.Never ) + + AddCallback_OnPlayerKilled( GiveScoreForPlayerKill ) + ScoreEvent_SetupEarnMeterValuesForMixedModes() + SetTimeoutWinnerDecisionFunc( CheckScoreForDraw ) + +} + +void function GiveScoreForPlayerKill( entity victim, entity attacker, var damageInfo ) +{ + if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() || GetGameState() != eGameState.Playing ) + AddTeamScore( attacker.GetTeam(), 1 ) +} + +int function CheckScoreForDraw() +{ + if (GameRules_GetTeamScore(TEAM_IMC) > GameRules_GetTeamScore(TEAM_MILITIA)) + return TEAM_IMC + else if (GameRules_GetTeamScore(TEAM_MILITIA) > GameRules_GetTeamScore(TEAM_IMC)) + return TEAM_MILITIA + + return TEAM_UNASSIGNED +} \ No newline at end of file diff --git a/_gamemode_tdm.nut b/_gamemode_tdm.nut new file mode 100644 index 000000000..ba1807900 --- /dev/null +++ b/_gamemode_tdm.nut @@ -0,0 +1,31 @@ +global function GamemodeTdm_Init +global function RateSpawnpoints_Directional + +void function GamemodeTdm_Init() +{ + AddCallback_OnPlayerKilled( GiveScoreForPlayerKill ) + ScoreEvent_SetupEarnMeterValuesForMixedModes() + SetTimeoutWinnerDecisionFunc( CheckScoreForDraw ) +} + +void function GiveScoreForPlayerKill( entity victim, entity attacker, var damageInfo ) +{ + if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() || GetGameState() != eGameState.Playing ) + AddTeamScore( attacker.GetTeam(), 1 ) +} + +void function RateSpawnpoints_Directional( int checkclass, array spawnpoints, int team, entity player ) +{ + // temp + RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) +} + +int function CheckScoreForDraw() +{ + if (GameRules_GetTeamScore(TEAM_IMC) > GameRules_GetTeamScore(TEAM_MILITIA)) + return TEAM_IMC + else if (GameRules_GetTeamScore(TEAM_MILITIA) > GameRules_GetTeamScore(TEAM_IMC)) + return TEAM_MILITIA + + return TEAM_UNASSIGNED +} \ No newline at end of file diff --git a/_gamemode_ttdm.nut b/_gamemode_ttdm.nut new file mode 100644 index 000000000..c72fcb0dc --- /dev/null +++ b/_gamemode_ttdm.nut @@ -0,0 +1,87 @@ +global function GamemodeTTDM_Init + +const float TTDMIntroLength = 15.0 + +void function GamemodeTTDM_Init() +{ + Riff_ForceSetSpawnAsTitan( eSpawnAsTitan.Always ) + Riff_ForceTitanExitEnabled( eTitanExitEnabled.Never ) + TrackTitanDamageInPlayerGameStat( PGS_ASSAULT_SCORE ) + ScoreEvent_SetupEarnMeterValuesForMixedModes() + SetLoadoutGracePeriodEnabled( false ) + + ClassicMP_SetCustomIntro( TTDMIntroSetup, TTDMIntroLength ) + ClassicMP_ForceDisableEpilogue( true ) + SetTimeoutWinnerDecisionFunc( CheckScoreForDraw ) + + AddCallback_OnPlayerKilled( AddTeamScoreForPlayerKilled ) // dont have to track autotitan kills since you cant leave your titan in this mode + + // probably needs scoreevent earnmeter values +} + +void function TTDMIntroSetup() +{ + // this should show intermission cam for 15 sec in prematch, before spawning players as titans + AddCallback_GameStateEnter( eGameState.Prematch, TTDMIntroStart ) + AddCallback_OnClientConnected( TTDMIntroShowIntermissionCam ) +} + +void function TTDMIntroStart() +{ + thread TTDMIntroStartThreaded() +} + +void function TTDMIntroStartThreaded() +{ + ClassicMP_OnIntroStarted() + + foreach ( entity player in GetPlayerArray() ) + TTDMIntroShowIntermissionCam( player ) + + wait TTDMIntroLength + + ClassicMP_OnIntroFinished() +} + +void function TTDMIntroShowIntermissionCam( entity player ) +{ + if ( GetGameState() != eGameState.Prematch ) + return + + thread PlayerWatchesTTDMIntroIntermissionCam( player ) +} + +void function PlayerWatchesTTDMIntroIntermissionCam( entity player ) +{ + ScreenFadeFromBlack( player ) + + entity intermissionCam = GetEntArrayByClass_Expensive( "info_intermission" )[ 0 ] + + // the angle set here seems sorta inconsistent as to whether it actually works or just stays at 0 for some reason + player.SetObserverModeStaticPosition( intermissionCam.GetOrigin() ) + player.SetObserverModeStaticAngles( intermissionCam.GetAngles() ) + player.StartObserverMode( OBS_MODE_STATIC_LOCKED ) + + wait TTDMIntroLength + + RespawnAsTitan( player, false ) + TryGameModeAnnouncement( player ) +} + +void function AddTeamScoreForPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( victim == attacker || !victim.IsPlayer() || !attacker.IsPlayer() || GetGameState() != eGameState.Playing ) + return + + AddTeamScore( GetOtherTeam( victim.GetTeam() ), 1 ) +} + +int function CheckScoreForDraw() +{ + if (GameRules_GetTeamScore(TEAM_IMC) > GameRules_GetTeamScore(TEAM_MILITIA)) + return TEAM_IMC + else if (GameRules_GetTeamScore(TEAM_MILITIA) > GameRules_GetTeamScore(TEAM_IMC)) + return TEAM_MILITIA + + return TEAM_UNASSIGNED +} \ No newline at end of file -- cgit v1.2.3 From 7ed259a9a76dc2e90cc1934f688c949cc7e9edcc Mon Sep 17 00:00:00 2001 From: x3Karma Date: Thu, 30 Dec 2021 02:06:19 +0800 Subject: reset flags properly --- .../mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut index cef0af6bd..bba703588 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut @@ -25,6 +25,7 @@ void function GamemodeSpeedball_Init() AddCallback_OnTouchHealthKit( "item_flag", OnFlagCollected ) AddCallback_OnPlayerKilled( OnPlayerKilled ) SetTimeoutWinnerDecisionFunc( TimeoutCheckFlagHolder ) + AddCallback_OnRoundEndCleanup ( ResetFlag ) ClassicMP_SetCustomIntro( ClassicMP_DefaultNoIntro_Setup, ClassicMP_DefaultNoIntro_GetLength() ) ClassicMP_ForceDisableEpilogue( true ) @@ -127,4 +128,4 @@ int function TimeoutCheckFlagHolder() return TEAM_UNASSIGNED return file.flagCarrier.GetTeam() -} \ No newline at end of file +} -- cgit v1.2.3 From 188f820a1862ee671ccbf4541e74502864c34da4 Mon Sep 17 00:00:00 2001 From: x3Karma Date: Thu, 30 Dec 2021 04:37:26 +0800 Subject: Add files via upload --- _burnmeter.gnut | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 441 insertions(+) create mode 100644 _burnmeter.gnut diff --git a/_burnmeter.gnut b/_burnmeter.gnut new file mode 100644 index 000000000..8bfcab8ab --- /dev/null +++ b/_burnmeter.gnut @@ -0,0 +1,441 @@ +untyped + +global function BurnMeter_Init +global function ForceSetGlobalBurncardOverride +global function GetSelectedBurncardRefFromWeaponOrPlayer +global function RunBurnCardUseFunc +global function UseBurnCardWeapon +global function UseBurnCardWeaponInCriticalSection +global function BurnMeter_GiveRewardDirect +global function GetBurnCardWeaponSkin +global function InitBurnMeterPersistentData + +const float PHASE_REWIND_LENGTH = 2.0 +// taken from wraith portal in apex, assuming it's the same as tf2's +const float PHASE_REWIND_PATH_SNAPSHOT_INTERVAL = 0.1 +const int PHASE_REWIND_MAX_SNAPSHOTS = int( PHASE_REWIND_LENGTH / PHASE_REWIND_PATH_SNAPSHOT_INTERVAL ) + +const float AMPED_WEAPONS_LENGTH = 30.0 + +const int MAPHACK_PULSE_COUNT = 4 +const float MAPHACK_PULSE_DELAY = 2.0 + +struct { + string forcedGlobalBurncardOverride = "" +} file + +void function BurnMeter_Init() +{ + // turret precaches + // do we have to cache these on client? release builds sure don't + PrecacheModel( Dev_GetAISettingAssetByKeyField_Global( "npc_turret_sentry_burn_card_ap", "DefaultModelName" ) ) + PrecacheModel( Dev_GetAISettingAssetByKeyField_Global( "npc_turret_sentry_burn_card_at", "DefaultModelName" ) ) + + // setup burncard use funcs + BurnReward_GetByRef( "burnmeter_amped_weapons" ).rewardAvailableCallback = PlayerUsesAmpedWeaponsBurncard + BurnReward_GetByRef( "burnmeter_smart_pistol" ).rewardAvailableCallback = PlayerUsesSmartPistolBurncard + BurnReward_GetByRef( "burnmeter_emergency_battery" ).rewardAvailableCallback = PlayerUsesBatteryBurncard + BurnReward_GetByRef( "burnmeter_radar_jammer" ).rewardAvailableCallback = PlayerUsesRadarJammerBurncard + BurnReward_GetByRef( "burnmeter_maphack" ).rewardAvailableCallback = PlayerUsesMaphackBurncard + BurnReward_GetByRef( "burnmeter_phase_rewind" ).rewardAvailableCallback = PlayerUsesPhaseRewindBurncard + + // these ones aren't so important, they're either for fd ( unsupported rn ) or unused + //BurnReward_GetByRef( "burnmeter_harvester_shield" ).rewardAvailableCallback = + BurnReward_GetByRef( "burnmeter_rodeo_grenade" ).rewardAvailableCallback = PlayerUsesRodeoGrenadeBurncard + BurnReward_GetByRef( "burnmeter_nuke_titan" ).rewardAvailableCallback = PlayerUsesNukeTitanBurncard // unused in vanilla, fun though + + // setup player callbacks + AddCallback_GameStateEnter( eGameState.Playing, InitBurncardsForIntroPlayers ) + AddCallback_OnClientConnected( InitBurncardsForLateJoiner ) + + AddCallback_OnPlayerRespawned( StartPhaseRewindLifetime ) + AddCallback_OnTitanBecomesPilot( RemoveAmpedWeaponsForTitanPilot ) + + // necessary signals + RegisterSignal( "StopAmpedWeapons" ) +} + +void function ForceSetGlobalBurncardOverride( string ref ) +{ + file.forcedGlobalBurncardOverride = ref +} + +string function GetSelectedBurncardRefFromWeaponOrPlayer( entity weapon, entity player ) +{ + // determine the burncard we're using + // in actual gameplay, this will always be the player's selected burncard + // however, if we want to manually give burncards and such, we want to make sure they'll still work + // so some extra work goes into this + + string ref = GetSelectedBurnCardRef( player ) + + if ( file.forcedGlobalBurncardOverride.len() > 0 ) + ref = file.forcedGlobalBurncardOverride + + if ( IsValid( weapon ) ) + { + // determine via weapon mods, this assumes weapon mod names are the same as burn refs, which works in practice but is a bit weird + // this does crash with the burnmeter_doublexp mod, but who cares, it doesn't get hit normally + if ( weapon.GetWeaponClassName() == "mp_ability_burncardweapon" ) + { + foreach ( string mod in weapon.GetMods() ) + if ( mod.find( "burnmeter_" ) == 0 ) + return mod + } + // determine via weapon name in the case of stuff like holopilot etc + else + { + // unfortunately, we have to hardcode this, we don't have a way of getting refs directly from weapons other than the burncard weapon + // this should be modular at some point, wish we could just iterate over burncards and find ones with the current weapon, but this isn't possible + switch ( weapon.GetWeaponClassName() ) + { + case "mp_ability_holopilot_nova": + return "burnmeter_holopilot_nova" + + case "mp_weapon_arc_trap": + return "burnmeter_arc_trap" + + case "mp_weapon_frag_drone": + return "burnmeter_ticks" + + case "mp_weapon_hard_cover": + return "burnmeter_hard_cover" + + case "mp_ability_turretweapon": + // turret has 2 burncards, antititan and antipilot + if( weapon.HasMod( "burnmeter_at_turret_weapon" ) || weapon.HasMod( "burnmeter_at_turret_weapon_inf" ) ) + return "burnmeter_at_turret_weapon" + else + return "burnmeter_ap_turret_weapon" + + // note: cloak and stim both have burn_card_weapon_mod mods, but they aren't used and don't call burncard code at all, likely for tf1 infinite stim/cloak burncards? + + default: + print( "tried to use unknown burncard weapon " + weapon.GetWeaponClassName() ) + return "burnmeter_amped_weapons" + } + } + } + + return ref +} + +void function InitPlayerBurncards( entity player ) +{ + string ref = GetSelectedBurncardRefFromWeaponOrPlayer( null, player ) + BurnReward reward = BurnReward_GetByRef( ref ) + player.SetPlayerNetInt( TOP_INVENTORY_ITEM_BURN_CARD_ID, reward.id ) + + if ( IsAlive( player ) ) + thread PhaseRewindLifetime( player ) +} + +void function InitBurncardsForIntroPlayers() +{ + // gotta do this, since sh_burnmeter uses this netint + foreach ( entity player in GetPlayerArray() ) + InitPlayerBurncards( player ) +} + +void function InitBurncardsForLateJoiner( entity player ) +{ + // gotta do this, since sh_burnmeter uses this netint + if ( GetGameState() > eGameState.Prematch ) + InitPlayerBurncards( player ) +} + +void function StartPhaseRewindLifetime( entity player ) +{ + thread PhaseRewindLifetime( player ) +} + +void function PhaseRewindLifetime( entity player ) +{ + player.EndSignal( "OnDestroy" ) + player.EndSignal( "OnDeath" ) + + OnThreadEnd( function() : ( player ) + { + player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions.clear() + }) + + while ( true ) + { + PhaseRewindData rewindData + rewindData.origin = player.GetOrigin() + rewindData.angles = player.GetAngles() + rewindData.velocity = player.GetVelocity() + rewindData.wasInContextAction = player.ContextAction_IsActive() + rewindData.wasCrouched = player.IsCrouched() + + if ( player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions.len() >= PHASE_REWIND_MAX_SNAPSHOTS ) + { + // shift all snapshots left + for ( int i = 0; i < PHASE_REWIND_MAX_SNAPSHOTS - 1; i++ ) + player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions[ i ] = player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions[ i + 1 ] + + player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions[ PHASE_REWIND_MAX_SNAPSHOTS - 1 ] = rewindData + } + else + player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions.append( rewindData ) + + wait PHASE_REWIND_PATH_SNAPSHOT_INTERVAL + } +} + +void function RunBurnCardUseFunc( entity player, string itemRef ) +{ + void functionref( entity ) ornull func = BurnReward_GetByRef( itemRef ).rewardAvailableCallback + if ( func != null ) + ( expect void functionref( entity ) ( func ) )( player ) +} + +void function UseBurnCardWeapon( entity weapon, entity player ) +{ + string ref = GetSelectedBurncardRefFromWeaponOrPlayer( weapon, player ) + + Remote_CallFunction_Replay( player, "ServerCallback_RewardUsed", BurnReward_GetByRef( ref ).id ) + RunBurnCardUseFunc( player, ref ) + + // dont remove in RunBurnCardUseFunc because it can be called in non-burn_card_weapon_mod contexts + // TODO: currently not sure how burncards can be stacked ( max clipcount for all burncards is 1, so can't just set that ) + // if this gets figured out, add a conditional check here to prevent removes if they've got burncards left + if ( PlayerEarnMeter_IsRewardAvailable( player ) ) + PlayerEarnMeter_SetRewardUsed( player ) + + player.TakeWeapon( BurnReward_GetByRef( ref ).weaponName ) +} + +void function UseBurnCardWeaponInCriticalSection( entity weapon, entity ownerPlayer ) +{ + // ignoring critical section stuff, assuming it was necessary in tf1 where burncards were part of inventory, but not here + UseBurnCardWeapon( weapon, ownerPlayer ) +} + +void function BurnMeter_GiveRewardDirect( entity player, string itemRef ) +{ + +} + +int function GetBurnCardWeaponSkin( entity weapon ) +{ + return GetBoostSkin( GetSelectedBurncardRefFromWeaponOrPlayer( weapon, weapon.GetOwner() ) ) +} + +// stub +void function InitBurnMeterPersistentData( entity player ) +{} + + +// burncard use funcs + +void function PlayerUsesAmpedWeaponsBurncard( entity player ) +{ + thread PlayerUsesAmpedWeaponsBurncardThreaded( player ) +} + +void function PlayerUsesAmpedWeaponsBurncardThreaded( entity player ) +{ + array weapons = player.GetMainWeapons() + //weapons.extend( player.GetOffhandWeapons() ) // idk? unsure of vanilla behaviour here + foreach ( entity weapon in weapons ) + { + weapon.RemoveMod( "silencer" ) // both this and the burnmod will override firing fx, if a second one overrides this we crash + foreach ( string mod in GetWeaponBurnMods( weapon.GetWeaponClassName() ) ) + { + // catch incompatibilities just in case + try + { + weapon.AddMod( mod ) + } + catch( ex ) + { + weapons.removebyvalue( weapon ) + } + } + + // needed to display amped weapon time left + weapon.SetScriptFlags0( weapon.GetScriptFlags0() | WEAPONFLAG_AMPED ) + weapon.SetScriptTime0( Time() + AMPED_WEAPONS_LENGTH ) + } + + wait AMPED_WEAPONS_LENGTH + + // note: weapons may have been destroyed or picked up by other people by this point, so need to verify this + foreach ( entity weapon in weapons ) + { + if ( !IsValid( weapon ) ) + continue + + foreach ( string mod in GetWeaponBurnMods( weapon.GetWeaponClassName() ) ) + weapon.RemoveMod( mod ) + + weapon.SetScriptFlags0( weapon.GetScriptFlags0() & ~WEAPONFLAG_AMPED ) + } +} + +void function RemoveAmpedWeaponsForTitanPilot( entity player, entity titan ) +{ + foreach ( entity weapon in player.GetMainWeapons() ) + foreach ( string mod in GetWeaponBurnMods( weapon.GetWeaponClassName() ) ) + weapon.RemoveMod( mod ) +} + +void function PlayerUsesSmartPistolBurncard( entity player ) +{ + // take secondary weapon + array sidearms = player.GetMainWeapons() + if ( sidearms.len() > 1 ) + player.TakeWeaponNow( sidearms[ 1 ].GetWeaponClassName() ) // take secondary weapon + + player.GiveWeapon( "mp_weapon_smart_pistol" ) + player.SetActiveWeaponByName( "mp_weapon_smart_pistol" ) + + // do we need to track the player losing smart pistol, then give their old weapon back? idk not implementing for now, check later +} + +void function PlayerUsesBatteryBurncard( entity player ) +{ + Rodeo_GiveBatteryToPlayer( player ) +} + +void function PlayerUsesRadarJammerBurncard( entity player ) +{ + foreach ( entity otherPlayer in GetPlayerArray() ) + { + MessageToPlayer( otherPlayer, eEventNotifications.BurnMeter_RadarJammerUsed, player ) + + if ( otherPlayer.GetTeam() != player.GetTeam() ) + StatusEffect_AddTimed( otherPlayer, eStatusEffect.minimap_jammed, 1.0, RADAR_JAM_TIME, RADAR_JAM_TIME ) + } +} + +void function PlayerUsesMaphackBurncard( entity player ) +{ + thread PlayerUsesMaphackBurncardThreaded( player ) +} + +void function PlayerUsesMaphackBurncardThreaded( entity player ) +{ + player.EndSignal( "OnDestroy" ) + player.EndSignal( "OnDeath" ) + + // todo: potentially look into ScanMinimap in _passives for doing this better? boost is pretty likely based off it pretty heavily + for ( int i = 0; i < MAPHACK_PULSE_COUNT; i++ ) + { + EmitSoundOnEntityOnlyToPlayer( player, player, "Burn_Card_Map_Hack_Radar_Pulse_V1_1P" ) + + foreach ( entity otherPlayer in GetPlayerArray() ) + { + Remote_CallFunction_Replay( otherPlayer, "ServerCallback_SonarPulseFromPosition", player.GetOrigin().x, player.GetOrigin().y, player.GetOrigin().z, SONAR_GRENADE_RADIUS ) + + if ( otherPlayer.GetTeam() != player.GetTeam() ) + { + StatusEffect_AddTimed( otherPlayer, eStatusEffect.maphack_detected, 1.0, MAPHACK_PULSE_DELAY / 2, 0.0 ) + SonarStart( otherPlayer, player.GetOrigin(), player.GetTeam(), player ) + IncrementSonarPerTeam( player.GetTeam() ) + } + } + wait MAPHACK_PULSE_DELAY + foreach ( entity otherPlayer in GetPlayerArray() ) { + if ( otherPlayer.GetTeam() != player.GetTeam() ) { + SonarEnd (otherPlayer, player.GetTeam() ) + DecrementSonarPerTeam( player.GetTeam() ) + } + } + } +} + +void function PlayerUsesPhaseRewindBurncard( entity player ) +{ + thread PlayerUsesPhaseRewindBurncardThreaded( player ) +} + +void function PlayerUsesPhaseRewindBurncardThreaded( entity player ) +{ + player.EndSignal( "OnDestroy" ) + player.EndSignal( "OnDeath" ) + + entity mover = CreateScriptMover( player.GetOrigin(), player.GetAngles() ) + player.SetParent( mover, "REF" ) + + OnThreadEnd( function() : ( player, mover ) + { + CancelPhaseShift( player ) + player.DeployWeapon() + player.SetPredictionEnabled( true ) + player.ClearParent() + ViewConeFree( player ) + mover.Destroy() + }) + + array positions = clone player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions + + ViewConeZero( player ) + player.HolsterWeapon() + player.SetPredictionEnabled( false ) + PhaseShift( player, 0.0, positions.len() * PHASE_REWIND_PATH_SNAPSHOT_INTERVAL * 1.5 ) + + for ( int i = positions.len() - 1; i > -1; i-- ) + { + mover.NonPhysicsMoveTo( positions[ i ].origin, PHASE_REWIND_PATH_SNAPSHOT_INTERVAL, 0, 0 ) + mover.NonPhysicsRotateTo( positions[ i ].angles, PHASE_REWIND_PATH_SNAPSHOT_INTERVAL, 0, 0 ) + wait PHASE_REWIND_PATH_SNAPSHOT_INTERVAL + } + + // this isn't vanilla but it's cool lol, should prolly remove it tho + player.SetVelocity( -positions[ positions.len() - 1 ].velocity ) +} + +void function PlayerUsesNukeTitanBurncard( entity player ) +{ + thread PlayerUsesNukeBurncardThreaded( player ) +} + +void function PlayerUsesNukeBurncardThreaded( entity player ) +{ + // if this is given manually ( i.e. not the equipped burnreward in inventory ), this will run at bad times + // so do this check here, yes, this will cause people to lose their cards and get nothing, but better than free titan regens + if ( !BurnMeterPlayer_CanUseReward( player, BurnReward_GetByRef( "burnmeter_nuke_titan" ) ) ) + return + + float ownedFrac = PlayerEarnMeter_GetOwnedFrac( player ) + + // use player's titan loadout, but with warpfall so faster and no dome + TitanLoadoutDef titanLoadout = GetTitanLoadoutForPlayer( player ) + titanLoadout.passive3 = "pas_warpfall" + + thread CreateTitanForPlayerAndHotdrop( player, GetTitanReplacementPoint( player, false ) ) + + entity titan = player.GetPetTitan() + SetTeam( titan, TEAM_UNASSIGNED ) // make it so you can kill yourself lol + DoomTitan( titan ) + NPC_SetNuclearPayload( titan ) + // this should get run after the vanilla set_usable's event, so titan is never embarkable + // embarking a titan in this state WILL kill the server so uhh, pretty bad + AddAnimEvent( titan, "set_usable", void function( entity titan ) { titan.UnsetUsable() } ) + + titan.WaitSignal( "TitanHotDropComplete" ) + AutoTitan_SelfDestruct( titan ) + + while ( PlayerEarnMeter_GetMode( player ) == eEarnMeterMode.PET ) + WaitFrame() + + // restore original earnmeter values, no way to set earned that's exposed unfortunately + PlayerEarnMeter_SetOwnedFrac( player, ownedFrac ) +} + +void function PlayerUsesRodeoGrenadeBurncard( entity player ) +{ + player.SetPlayerNetInt( "numSuperRodeoGrenades", player.GetPlayerNetInt( "numSuperRodeoGrenades" ) + 1 ) +} + +// unused burncard that's mentioned in a few areas and has a validiation function in sh_burnmeter ( BurnMeter_SummonReaperCanUse ), thought it'd be neat to add it +void function PlayerUsesReaperfallBurncard( entity player ) +{ + Point spawnpoint = GetTitanReplacementPoint( player, false ) + entity reaper = CreateSuperSpectre( player.GetTeam(), spawnpoint.origin, spawnpoint.angles ) + DispatchSpawn( reaper ) + + thread SuperSpectre_WarpFall( reaper ) +} \ No newline at end of file -- cgit v1.2.3 From 07ccd9d1ddfde5f6f06c4cf75e1b3690c34b1f3d Mon Sep 17 00:00:00 2001 From: x3Karma Date: Thu, 30 Dec 2021 05:11:18 +0800 Subject: fixed map hack permanent sonar (real)!!! --- _burnmeter.gnut | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_burnmeter.gnut b/_burnmeter.gnut index 8bfcab8ab..3eb6bda6c 100644 --- a/_burnmeter.gnut +++ b/_burnmeter.gnut @@ -324,12 +324,12 @@ void function PlayerUsesMaphackBurncardThreaded( entity player ) for ( int i = 0; i < MAPHACK_PULSE_COUNT; i++ ) { EmitSoundOnEntityOnlyToPlayer( player, player, "Burn_Card_Map_Hack_Radar_Pulse_V1_1P" ) - + array aliveplayers = GetPlayerArray() foreach ( entity otherPlayer in GetPlayerArray() ) { Remote_CallFunction_Replay( otherPlayer, "ServerCallback_SonarPulseFromPosition", player.GetOrigin().x, player.GetOrigin().y, player.GetOrigin().z, SONAR_GRENADE_RADIUS ) - if ( otherPlayer.GetTeam() != player.GetTeam() ) + if ( otherPlayer.GetTeam() != player.GetTeam() && aliveplayers.find(otherPlayer) != -1 && aliveplayers.find(player) != -1 ) { StatusEffect_AddTimed( otherPlayer, eStatusEffect.maphack_detected, 1.0, MAPHACK_PULSE_DELAY / 2, 0.0 ) SonarStart( otherPlayer, player.GetOrigin(), player.GetTeam(), player ) @@ -338,7 +338,7 @@ void function PlayerUsesMaphackBurncardThreaded( entity player ) } wait MAPHACK_PULSE_DELAY foreach ( entity otherPlayer in GetPlayerArray() ) { - if ( otherPlayer.GetTeam() != player.GetTeam() ) { + if ( otherPlayer.GetTeam() != player.GetTeam() && aliveplayers.find(otherPlayer) != -1 && aliveplayers.find(player) != -1 ) { SonarEnd (otherPlayer, player.GetTeam() ) DecrementSonarPerTeam( player.GetTeam() ) } -- cgit v1.2.3