From 9a2778eabc7ba968968e41dda9f03525d6c5383d Mon Sep 17 00:00:00 2001 From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com> Date: Thu, 14 Oct 2021 21:01:40 +0100 Subject: oh fuck i forgot to commit for a while --- .../mod/scripts/vscripts/_bleedout_damage.gnut | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 Northstar.Custom/mod/scripts/vscripts/_bleedout_damage.gnut (limited to 'Northstar.Custom/mod/scripts/vscripts/_bleedout_damage.gnut') 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 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 -- cgit v1.2.3