aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut
diff options
context:
space:
mode:
Diffstat (limited to 'Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut')
-rw-r--r--Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut999
1 files changed, 0 insertions, 999 deletions
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut b/Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut
deleted file mode 100644
index 2e565142..00000000
--- a/Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut
+++ /dev/null
@@ -1,999 +0,0 @@
-untyped
-
-
-global function CodeCallback_Init
-global function CodeCallback_DamagePlayerOrNPC
-global function GameModeRulesShouldGiveTimerCredit
-global function SetGameModeRulesShouldGiveTimerCredit
-global function SetGameModeRulesEarnMeterOnDamage
-global function GetDamageOrigin
-global function CodeCallBack_ShouldTriggerSniperCam
-global function CodeCallback_ForceAIMissPlayer
-global function CodeCallback_OnTouchHealthKit
-global function CodeCallback_OnPlayerGrappled
-global function CodeCallback_OnProjectileGrappled
-global function DamageInfo_ScaleDamage
-global function CodeCallback_CheckPassThroughAddsMods
-global function SetTitanMeterGainScale
-
-#if MP
-global function CodeCallback_OnServerAnimEvent
-#endif
-
-struct AccumulatedDamageData
-{
- float accumulatedDamage
- float lastDamageTime
-}
-
-struct
-{
- float titanMeterGainScale = 0.0001
- bool functionref( entity, entity, var ) ShouldGiveTimerCreditGameModeRules
- void functionref( entity, entity, TitanDamage, float ) earnMeterOnDamageGameModeRulesCallback
-
- table<entity, AccumulatedDamageData> playerAccumulatedDamageData
-} file
-
-void function CodeCallback_Init()
-{
- file.ShouldGiveTimerCreditGameModeRules = ShouldGiveTimerCredit_Default
- file.earnMeterOnDamageGameModeRulesCallback = GameModeRulesEarnMeterOnDamage_Default
- RegisterSignal( "DamagedPlayerOrNPC" )
- RegisterSignal( "UpdateAccumulatedDamageAfterDelay" )
-
- AddCallback_OnClientConnected( OnClientConnected )
-}
-
-void function OnClientConnected( entity player )
-{
- AccumulatedDamageData damageData
- file.playerAccumulatedDamageData[player] <- damageData
-}
-
-// TODO: Get an equivalent callback happening on the client, so we can stop using ServerCallback_PlayerTookDamage which is always out of date to some degree.
-void function CodeCallback_DamagePlayerOrNPC( entity ent, var damageInfo )
-{
- bool entIsPlayer = ent.IsPlayer()
- bool entIsTitan = ent.IsTitan()
- bool entIsNPC = ent.IsNPC()
-
- entity attacker = DamageInfo_GetAttacker( damageInfo )
- entity inflictor = DamageInfo_GetInflictor( damageInfo )
-
- bool attackerIsPlayer = false
- bool attackerIsTitan = false
- bool attackerIsNPC = false
-
- if ( IsValid( attacker ) )
- {
- attackerIsPlayer = attacker.IsPlayer()
- attackerIsTitan = attacker.IsTitan()
- attackerIsNPC = attacker.IsNPC()
- }
-
- // Set damage source correctly when npc grunts or titans try to melee us
- if ( attackerIsNPC && DamageInfo_GetCustomDamageType( damageInfo ) & DF_MELEE )
- {
- if ( IsValid( attacker ) )
- {
- if ( attackerIsTitan )
- {
- DamageInfo_SetDamageSourceIdentifier( damageInfo, eDamageSourceId.auto_titan_melee )
- }
- else if ( IsSpectre( attacker ) )
- {
- DamageInfo_SetDamageSourceIdentifier( damageInfo, eDamageSourceId.spectre_melee )
- }
- else if ( IsProwler( attacker ) )
- {
- DamageInfo_SetDamageSourceIdentifier( damageInfo, eDamageSourceId.prowler_melee )
- }
- else if ( IsSuperSpectre( attacker ) )
- {
- DamageInfo_SetDamageSourceIdentifier( damageInfo, eDamageSourceId.super_spectre_melee )
- }
- else
- {
- DamageInfo_SetDamageSourceIdentifier( damageInfo, eDamageSourceId.grunt_melee )
- }
- }
- }
-
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( "CodeCallback_DamagePlayerOrNPC ent:", ent )
- printt( " Attacker:", DamageInfo_GetAttacker( damageInfo ) )
- printt( " Inflictor:", DamageInfo_GetInflictor( damageInfo ) )
- printt( " Distance:", DamageInfo_GetDistFromAttackOrigin( damageInfo ) )
- printt( " Original damage:", DamageInfo_GetDamage( damageInfo ) )
- printt( " Hitbox:", DamageInfo_GetHitBox( damageInfo ) )
- int sourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- printt( " SourceID:", sourceID )
- if ( sourceID == -1 )
- printt( " SourceID: From Code (npc melee, etc)" )
- else
- printt( " SourceID:", GetObitFromDamageSourceID( sourceID ) )
-
- PrintDamageFlags( DamageInfo_GetCustomDamageType( damageInfo ) )
- #endif
-
- if ( !ScriptCallback_ShouldEntTakeDamage( ent, damageInfo ) )
- {
- // EMP triggers on damage, but in some cases players are invlunerable (embark, disembark, etc...)
- if ( entIsPlayer && DamageInfo_GetDamageSourceIdentifier( damageInfo ) in level._empForcedCallbacks )
- {
- if ( ShouldPlayEMPEffectEvenWhenDamageIsZero( ent, attacker ) )
- EMP_DamagedPlayerOrNPC( ent, damageInfo )
- }
-
- DamageInfo_SetDamage( damageInfo, 0 )
- return
- }
-
- if ( ( IsAirDrone( ent ) ) && ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) in level._empForcedCallbacks ) )
- {
- EMP_DamagedPlayerOrNPC( ent, damageInfo )
- DamageInfo_SetDamage( damageInfo, 0 )
- return
- }
-
- if ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) == damagedef_titan_step )
- HandleFootstepDamage( ent, damageInfo )
-
- // HACK helps trap/grenade weapons do damage to the correct entities (player who deployed it as well as the team opposite his)
- if ( IsValid( inflictor ) && "originalOwner" in inflictor.s )
- {
- local ogOwner = inflictor.s.originalOwner
- if ( IsValid( ogOwner ) )
- {
- // if the victim is the guy who damaged the trap, and he is not the ogOwner...
- if ( ent == attacker && ent != ogOwner )
- {
- // HACK to do this legit we need DamageInfo_SetAttacker( damageInfo )
- // victim should take damage from the original owner instead of the satchel attacker so he gets a kill credit
- ent.TakeDamage( DamageInfo_GetDamage( damageInfo ), ogOwner, inflictor, { weapon = DamageInfo_GetWeapon( damageInfo ), origin = DamageInfo_GetDamagePosition( damageInfo ), force = DamageInfo_GetDamageForce( damageInfo ), scriptType = DamageInfo_GetCustomDamageType( damageInfo ), damageSourceId = DamageInfo_GetDamageSourceIdentifier( damageInfo ) } )
-
- // now zero out the normal damage and return
- DamageInfo_SetDamage( damageInfo, 0 )
- return
- }
- }
- }
-
- if ( IsValid( inflictor ) )
- {
- if ( inflictor.IsProjectile() && entIsPlayer )
- {
- if ( inflictor.proj.damageScale != 1.0 )
- {
- DamageInfo_ScaleDamage( damageInfo, inflictor.proj.damageScale )
- }
-
- // Don't take damage from projectiles created before you where spawned.
- if ( inflictor.GetProjectileCreationTime() < ent.s.respawnTime && ( Time() - ent.s.respawnTime ) < 2.0 )
- {
- DamageInfo_SetDamage( damageInfo, 0 )
- return
- }
- }
-
- if ( inflictor.e.onlyDamageEntitiesOnce == true || inflictor.e.onlyDamageEntitiesOncePerTick == true )
- {
- Assert( !inflictor.e.damagedEntities.contains(ent) )
- inflictor.e.damagedEntities.append( ent )
- }
- }
-
- // Round damage to nearest full value
- DamageInfo_SetDamage( damageInfo, floor( DamageInfo_GetDamage( damageInfo ) + 0.5 ) )
- if ( DamageInfo_GetDamage( damageInfo ) <= 0 )
- return
-
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( " rounded damage amount:", DamageInfo_GetDamage( damageInfo ) )
- #endif
-
- HandleLocationBasedDamage( ent, damageInfo )
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( " after location based damage:", DamageInfo_GetDamage( damageInfo ) )
- #endif
-
- //PROTO Defensive AI Chip. Ideally less invisible gameplay, but something that can combo with other chips.
- if ( ent.IsTitan() && entIsNPC )
- {
- entity soul = ent.GetTitanSoul()
- if ( IsValid( soul ) && SoulHasPassive( soul, ePassives.PAS_GUARDIAN_CHIP ) )
- {
- DamageInfo_SetDamage( damageInfo, DamageInfo_GetDamage( damageInfo ) * 0.8 )
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( "After guardian chip :", DamageInfo_GetDamage( damageInfo ) )
- #endif
- }
- }
-
- RunClassDamageCallbacks( ent, damageInfo )
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( " after class damage callbacks:", DamageInfo_GetDamage( damageInfo ) )
- #endif
- if ( DamageInfo_GetDamage( damageInfo ) == 0 )
- return
-
- // use AddDamageByCallback( "classname", function ) to registed functions
- if ( IsValid( attacker ) )
- {
- if ( attackerIsTitan )
- {
- entity soul = attacker.GetTitanSoul()
- if ( IsValid( soul ) )
- {
- float damageAmpScale = 1.0 + StatusEffect_Get( soul, eStatusEffect.titan_damage_amp )
- if ( damageAmpScale != 1.0 )
- DamageInfo_ScaleDamage( damageInfo, damageAmpScale )
- }
- }
-
- string attackerClassName = attacker.GetClassName()
- if ( attackerClassName in svGlobal.damageByCallbacks )
- {
- foreach ( callbackFunc in svGlobal.damageByCallbacks[attackerClassName] )
- {
- callbackFunc( ent, damageInfo )
- if ( DamageInfo_GetDamage( damageInfo ) == 0 )
- return
- }
- }
- }
-
- float damageMultiplier = 1.0 + StatusEffect_Get( ent, eStatusEffect.damage_received_multiplier )
- if ( damageMultiplier != 1.0 )
- DamageInfo_ScaleDamage( damageInfo, damageMultiplier )
-
- // Added via AddEntityCallback_OnDamaged
- foreach ( callbackFunc in ent.e.entDamageCallbacks )
- {
- callbackFunc( ent, damageInfo )
- }
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( " after AddEntityCallback_OnDamaged callbacks:", DamageInfo_GetDamage( damageInfo ) )
- #endif
-
- // use AddDamageCallbackSourceID( "classname", function ) to registed functions
- int damageSourceId = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- if ( damageSourceId in shGlobal.damageSourceIdCallbacks )
- {
- foreach ( callbackFunc in shGlobal.damageSourceIdCallbacks[ damageSourceId ] )
- {
- callbackFunc( ent, damageInfo )
- }
- }
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( " after damageSourceID callbacks:", DamageInfo_GetDamage( damageInfo ) )
- #endif
- if ( DamageInfo_GetDamage( damageInfo ) == 0 )
- return
-
- RunClassDamageFinalCallbacks( ent, damageInfo )
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( " after class damage final callbacks:", DamageInfo_GetDamage( damageInfo ) )
- #endif
- if ( DamageInfo_GetDamage( damageInfo ) == 0 )
- return
-
- if ( DamageInfo_GetCustomDamageType( damageInfo ) & DF_DOOMED_HEALTH_LOSS )
- DamageInfo_AddDamageFlags( damageInfo, DAMAGEFLAG_NOPAIN )
-
- float savedDamage = DamageInfo_GetDamage( damageInfo )
-
- TitanDamage titanDamage
- if ( entIsPlayer )
- {
- PlayerTookDamage( ent, damageInfo, attacker, inflictor, damageSourceId, titanDamage )
- if ( DamageInfo_GetDamage( damageInfo ) == 0 && entIsTitan )
- {
- EarnMeterDamageConversion( damageInfo, attacker, ent, 0, titanDamage )
- return
- }
-
- if ( attackerIsPlayer )
- PlayerDamageFeedback( ent, damageInfo )
- savedDamage = DamageInfo_GetDamage( damageInfo )
-
- if ( !entIsTitan )
- ent.SetCloakFlicker( 0.5, 0.65 )
- }
- else
- {
- Assert( entIsNPC )
- bool clearedDamage
- if ( ent.ai.buddhaMode )
- {
- float currentDamage = DamageInfo_GetDamage( damageInfo )
- int remainingHealth = ent.GetHealth()
-
- if ( currentDamage >= remainingHealth - ( DOOMED_MIN_HEALTH + 1 ) )
- {
- currentDamage = max( remainingHealth - ( DOOMED_MIN_HEALTH + 1 ), 0 )
- DamageInfo_SetDamage( damageInfo, currentDamage )
- clearedDamage = currentDamage == 0
- }
- }
-
- if ( !clearedDamage )
- {
- if ( entIsTitan )
- {
- Titan_NPCTookDamage( ent, damageInfo, titanDamage )
- savedDamage = DamageInfo_GetDamage( damageInfo )
- }
- else
- {
- Generic_NPCTookDamage( ent, damageInfo, titanDamage )
- }
- }
-
- if ( attackerIsPlayer )
- PlayerDamageFeedback( ent, damageInfo )
- }
-
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( " After player damage mod:", DamageInfo_GetDamage( damageInfo ) )
- #endif
-
- #if VERBOSE_DAMAGE_PRINTOUTS
- if ( titanDamage.shieldDamage > 0 )
- printt( " Shield Damage:", titanDamage.shieldDamage )
- #endif
-
- // Added via AddEntityCallback_OnPostDamaged
- foreach ( callbackFunc in ent.e.entPostDamageCallbacks )
- {
- callbackFunc( ent, damageInfo )
- }
-
- UpdateLastDamageTime( ent )
-
- //pain sounds _base_gametype.nut, death sounds in _death_package.nut
- UpdateDamageState( ent, damageInfo )
- HandlePainSounds( ent, damageInfo )
-
- UpdateAttackerInfo( ent, attacker, savedDamage )
-
- if ( !(DamageInfo_GetCustomDamageType( damageInfo ) & DF_DOOMED_HEALTH_LOSS) )
- {
- if ( attackerIsPlayer )
- {
- if ( entIsTitan )
- {
- PlayerDealtTitanDamage( attacker, ent, savedDamage, damageInfo )
-
- entity entSoul = ent.GetTitanSoul()
- if ( attacker.p.currentTargetPlayerOrSoul_Ent != entSoul )
- {
- attacker.p.currentTargetPlayerOrSoul_Ent = ent.GetTitanSoul()
-
- TitanVO_TellPlayersThatAreAlsoFightingThisTarget( attacker, entSoul )
- }
- attacker.p.currentTargetPlayerOrSoul_LastHitTime = Time()
- }
- else if ( entIsPlayer )
- {
- attacker.p.currentTargetPlayerOrSoul_Ent = ent
- attacker.p.currentTargetPlayerOrSoul_LastHitTime = Time()
- }
- }
- }
-
- EarnMeterDamageConversion( damageInfo, attacker, ent, savedDamage, titanDamage )
-
- if ( entIsTitan )
- {
- TitanDamageFlinch( ent, damageInfo )
-
- if ( TitanDamageRewardsTitanCoreTime() && entIsPlayer && attacker.GetTeam() != ent.GetTeam() )
- AddCreditToTitanCoreBuilderForTitanDamageReceived( ent, savedDamage )
- }
-
- if ( entIsPlayer && !entIsTitan )
- PilotDamageFlinch( ent, damageInfo )
-
- #if VERBOSE_DAMAGE_PRINTOUTS
- printt( " final damage done:", DamageInfo_GetDamage( damageInfo ) )
- printt( " health: " + ent.GetHealth() )
- #endif
-
- RunClassPostDamageCallbacks( ent, damageInfo )
-
- #if SERVER && MP
- Stats_OnPlayerDidDamage( ent, damageInfo )
- PIN_DamageDone( attacker, ent, DamageInfo_GetDamage( damageInfo ) )
- #endif
-
- attacker.Signal( "DamagedPlayerOrNPC" )
-}
-
-void function EarnMeterDamageConversion( var damageInfo, entity attacker, entity ent, float savedDamage, TitanDamage titanDamage )
-{
- if ( !(DamageInfo_GetCustomDamageType( damageInfo ) & DF_DOOMED_HEALTH_LOSS) )
- {
- bool shouldGiveTimerCredit = file.ShouldGiveTimerCreditGameModeRules( attacker, ent, damageInfo )
- if ( attacker.IsPlayer() )
- {
- float titanSpawnDelay = GetTitanBuildTime( attacker )
- float timerCredit = 0.0
-
- if ( shouldGiveTimerCredit )
- {
- file.earnMeterOnDamageGameModeRulesCallback( attacker, ent, titanDamage, savedDamage )
-
- // Timer Credit seems unused. Need to investigate if all DecrementBuildTimer functions are worthless.
- if ( titanSpawnDelay && IsAlive( ent ) && GetCurrentPlaylistVarInt( "titan_build_credit_enabled", 1 ) == 1 )
- {
- if ( ent.IsTitan() )
- {
- timerCredit = GetCurrentPlaylistVarFloat( "titan_kill_credit", 0.5 )
- if ( PlayerHasServerFlag( attacker, SFLAG_HUNTER_TITAN ) )
- timerCredit *= 2.0
- }
- else
- {
- if ( ent.IsPlayer() )
- {
- timerCredit = GetCurrentPlaylistVarFloat( "player_kill_credit", 0.5 )
- if ( PlayerHasServerFlag( attacker, SFLAG_HUNTER_PILOT ) )
- timerCredit *= 2.5
- }
- else
- {
- if ( IsGrunt( ent ) )
- {
- timerCredit = GetCurrentPlaylistVarFloat( "ai_kill_credit", 0.5 )
- if ( PlayerHasServerFlag( attacker, SFLAG_HUNTER_GRUNT ) )
- timerCredit *= 2.5
- }
- else
- if ( IsSpectre( ent ) )
- {
- timerCredit = GetCurrentPlaylistVarFloat( "spectre_kill_credit", 0.5 )
- if ( PlayerHasServerFlag( attacker, SFLAG_HUNTER_SPECTRE ) )
- timerCredit *= 2.5
- }
- else
- if ( IsTurret( ent ) )
- {
-
- timerCredit = GetCurrentPlaylistVarFloat( "megaturret_kill_credit", 0.5 )
- //No 2x burn card for shooting mega turret
- }
- #if HAS_EVAC
- else
- if ( IsEvacDropship( ent ) )
- {
- timerCredit = GetCurrentPlaylistVarFloat( "evac_dropship_kill_credit", 0.5 )
- }
- #endif
- }
- }
-
- float dealtDamage = min( ent.GetHealth(), (savedDamage + titanDamage.shieldDamage) )
- timerCredit = timerCredit * (dealtDamage / ent.GetMaxHealth().tofloat())
- }
-
- if ( IsPilot( attacker ) && PlayerHasPassive( attacker, ePassives.PAS_AT_HUNTER ) )
- timerCredit *= 1.1
-
- if ( timerCredit && (!TitanDamageRewardsTitanCoreTime() || !attacker.IsTitan() ) )
- DecrementBuildTimer( attacker, timerCredit )
- }
- }
-
- if ( shouldGiveTimerCredit //Primary Check
- && TitanDamageRewardsTitanCoreTime() //Playlist var check
- && ent.IsTitan()
- && attacker.IsTitan()
- && attacker.GetTeam() != ent.GetTeam()
- && !attacker.ContextAction_IsMeleeExecution() // Some melee executions deal A LOT of damage
- )
- AddCreditToTitanCoreBuilderForTitanDamageInflicted( attacker, savedDamage + titanDamage.shieldDamage )
- }
-}
-
-
-bool function ShouldUseNonTitanHeavyArmorDamageScale( entity victim )
-{
- if ( (victim.GetArmorType() != ARMOR_TYPE_HEAVY) )
- return false
-
- if ( victim.IsTitan() )
- return false
-
- if ( IsDropship( victim ) )
- return false
-
- return true
-}
-
-void function GameModeRulesEarnMeterOnDamage_Default( entity attacker, entity victim, TitanDamage titanDamage, float savedDamage )
-{
- #if MP
- if ( victim.IsTitan() && !attacker.IsTitan() && !IsValid( attacker.GetPetTitan() ) )
- {
- float damage = min( victim.GetHealth(), (savedDamage + titanDamage.shieldDamage) )
- float meterAmount = damage * file.titanMeterGainScale
- if ( PlayerHasPassive( attacker, ePassives.PAS_AT_HUNTER ) )
- meterAmount *= 1.1
- PlayerEarnMeter_AddOwnedFrac( attacker, meterAmount )
-
- AccumulatedDamageData damageData = file.playerAccumulatedDamageData[attacker]
- damageData.lastDamageTime = Time()
- damageData.accumulatedDamage += meterAmount
-
- if ( damageData.accumulatedDamage >= 0.01 )
- {
- attacker.Signal( "UpdateAccumulatedDamageAfterDelay" )
- AddPlayerScore( attacker, "DamageTitan", null, "", int( damageData.accumulatedDamage * 100 ) )
- damageData.accumulatedDamage = 0
- }
- else
- {
- thread UpdateAccumulatedDamageAfterDelay( attacker )
- }
- }
- #endif
-}
-
-void function SetTitanMeterGainScale( float scalar )
-{
- file.titanMeterGainScale = scalar
-}
-
-#if MP
-void function UpdateAccumulatedDamageAfterDelay( entity attacker )
-{
- attacker.EndSignal( "OnDeath" )
- attacker.Signal( "UpdateAccumulatedDamageAfterDelay" )
- attacker.EndSignal( "UpdateAccumulatedDamageAfterDelay" )
-
- wait 0.25
-
- AccumulatedDamageData damageData = file.playerAccumulatedDamageData[attacker]
-
- if ( damageData.accumulatedDamage == 0 )
- return
-
- AddPlayerScore( attacker, "DamageTitan", null, "", int( max( damageData.accumulatedDamage * 100, 1 ) ) )
- damageData.accumulatedDamage = 0
-}
-#endif
-
-void function SetGameModeRulesEarnMeterOnDamage( void functionref( entity, entity, TitanDamage, float ) rules )
-{
- file.earnMeterOnDamageGameModeRulesCallback = rules
-}
-
-bool function ShouldGiveTimerCredit_Default( entity player, entity victim, var damageInfo )
-{
- if ( player == victim )
- return false
-
- if ( player.IsTitan() && !IsCoreAvailable( player ) )
- return false
-
- if ( GAMETYPE == FREE_AGENCY && !player.IsTitan() )
- return false
-
- int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- switch ( damageSourceID )
- {
- case eDamageSourceId.mp_titancore_flame_wave:
- case eDamageSourceId.mp_titancore_flame_wave_secondary:
- case eDamageSourceId.mp_titancore_salvo_core:
- case damagedef_titan_fall:
- case damagedef_nuclear_core:
- return false
- }
-
- return true
-}
-
-bool function GameModeRulesShouldGiveTimerCredit( entity player, entity victim, var damageInfo )
-{
- return file.ShouldGiveTimerCreditGameModeRules( player, victim, damageInfo )
-}
-
-void function SetGameModeRulesShouldGiveTimerCredit( bool functionref( entity, entity, var ) rules )
-{
- file.ShouldGiveTimerCreditGameModeRules = rules
-}
-
-function TitanDamageFlinch( entity ent, damageInfo )
-{
- if ( DamageInfo_GetCustomDamageType( damageInfo ) & DF_DOOMED_HEALTH_LOSS )
- return
-
- if ( TitanStagger( ent, damageInfo ) )
- return
-
- if ( DamageInfo_GetDamage( damageInfo ) >= TITAN_ADDITIVE_FLINCH_DAMAGE_THRESHOLD )
- AddFlinch( ent, damageInfo )
-}
-
-function PilotDamageFlinch( entity ent, damageInfo )
-{
- //if ( DamageInfo_GetCustomDamageType( damageInfo ) & DF_DOOMED_HEALTH_LOSS )
- // return
-
- float damage = DamageInfo_GetDamage( damageInfo )
- if ( damage >= 5 )
- AddFlinch( ent, damageInfo )
-}
-
-vector function GetDamageOrigin( damageInfo, entity victim = null )
-{
- int damageSourceId = DamageInfo_GetDamageSourceIdentifier( damageInfo )
-
- entity inflictor = DamageInfo_GetInflictor( damageInfo )
-
- if ( inflictor == svGlobal.worldspawn )
- return DamageInfo_GetDamagePosition( damageInfo )
-
- vector damageOrigin = IsValid( inflictor ) ? inflictor.GetOrigin() : DamageInfo_GetDamagePosition( damageInfo )
-
- switch ( damageSourceId )
- {
- case eDamageSourceId.mp_weapon_satchel:
- case eDamageSourceId.mp_weapon_proximity_mine:
- case eDamageSourceId.mp_titanweapon_arc_pylon:
- break
-
- case damagedef_nuclear_core:
- case eDamageSourceId.mp_titanability_smoke:
- //if ( IsValid( victim ) && victim.IsPlayer() && IsValid( victim.GetTitanSoulBeingRodeoed() ) )
- {
- damageOrigin += (RandomVecInDome( Vector( 0, 0, -1 ) ) * 300.0)
- damageOrigin += Vector( 0, 0, 128 )
- }
- break
-
- case eDamageSourceId.switchback_trap:
- if ( IsValid( victim ) && victim.IsPlayer() )
- damageOrigin = victim.EyePosition() + (RandomVecInDome( Vector( 0, 0, -1 ) ) * 300.0)
- break
-
- default:
- if ( DamageInfo_GetAttacker( damageInfo ) )
- {
- inflictor = DamageInfo_GetAttacker( damageInfo )
- damageOrigin = inflictor.GetWorldSpaceCenter()
- }
- break
- }
-
- return damageOrigin
-}
-
-/*
-function TrackDPS( ent )
-{
- ent.s.dpsTracking <- {}
- ent.s.dpsTracking.damage <- 0
-
- local startTime = Time()
-
- ent.WaitSignal( "Doomed" )
-
- local duration = Time() - startTime
-
- printt( "DPS:", ent.s.dpsTracking.damage / duration, duration )
-
- delete ent.s.dpsTracking
-}
-
-function UpdateDPS( ent, damageInfo )
-{
- if ( GetDoomedState( ent ) )
- return
-
- if ( !( "dpsTracking" in ent.s ) )
- thread TrackDPS( ent )
-
- ent.s.dpsTracking.damage += DamageInfo_GetDamage( damageInfo )
-}
-*/
-
-
-void function PlayerTookDamage( entity player, var damageInfo, entity attacker, entity inflictor, int damageSourceId, TitanDamage titanDamage )
-{
- int hitBox = DamageInfo_GetHitBox( damageInfo )
-
- bool critHit = false
-
- if ( CritWeaponInDamageInfo( damageInfo ) )
- critHit = IsCriticalHit( attacker, player, hitBox, DamageInfo_GetDamage( damageInfo ), DamageInfo_GetDamageType( damageInfo ) )
-
- if ( critHit )
- DamageInfo_AddCustomDamageType( damageInfo, DF_CRITICAL )
-
- array<string> weaponMods = GetWeaponModsFromDamageInfo( damageInfo )
-
- local eModSourceID = null
- foreach ( mod in weaponMods )
- {
- local modSourceID = GetModSourceID( mod )
- if ( modSourceID != null && modSourceID in modNameStrings )
- eModSourceID = modSourceID
- }
-
- if ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) == eDamageSourceId.fall )
- DamageInfo_SetForceKill( damageInfo, true )
-
- bool isTitan = player.IsTitan()
-
- if ( isTitan )
- Titan_PlayerTookDamage( player, damageInfo, attacker, critHit, titanDamage )
- else
- Wallrun_PlayerTookDamage( player, damageInfo, attacker )
-
- float damageAmount = DamageInfo_GetDamage( damageInfo )
- bool isKillShot = (damageAmount >= player.GetHealth())
- int damageType = DamageInfo_GetCustomDamageType( damageInfo )
- if ( isKillShot )
- damageType = (damageType | DF_KILLSHOT)
-
- if ( isTitan && (DamageInfo_GetDamage( damageInfo ) == 0) )
- {
- if ( titanDamage.doomedNow ) // to make kill card come up for you even if you have auto-eject. In Titan_PlayerTookDamage we set damage to 0 if you have Auto-Eject and are doomed
- TellClientPlayerTookDamage( player, damageInfo, attacker, eModSourceID, damageType, damageSourceId, titanDamage )
- }
-
- vector attackerOrigin = Vector( 0, 0, 0 )
- if ( IsValid( attacker ) )
- attackerOrigin = attacker.GetOrigin()
-
- if ( IsAlive( player ) )
- {
- float storeTime = MAX_DAMAGE_HISTORY_TIME
- entity storeEnt
- if ( isTitan )
- {
- storeEnt = player.GetTitanSoul()
- }
- else
- {
- storeEnt = player
- if ( IsSingleplayer() )
- storeTime = 30.0
- }
-
- StoreDamageHistoryAndUpdate( storeEnt, storeTime, DamageInfo_GetDamage( damageInfo ), attackerOrigin, damageType, damageSourceId, attacker, weaponMods )
- }
-
- if ( !(DamageInfo_GetCustomDamageType( damageInfo ) & DF_DOOMED_HEALTH_LOSS) )
- TellClientPlayerTookDamage( player, damageInfo, attacker, eModSourceID, damageType, damageSourceId, titanDamage )
-}
-
-function TellClientPlayerTookDamage( entity player, damageInfo, entity attacker, eModSourceID, int damageType, int damageSourceId, TitanDamage titanDamage )
-{
- if ( !player.hasConnected )
- return
-
- local attackerEHandle = IsValid( attacker ) ? attacker.GetEncodedEHandle() : null
- local weaponEHandle = IsValid( DamageInfo_GetWeapon( damageInfo ) ) ? DamageInfo_GetWeapon( damageInfo ).GetEncodedEHandle() : null
- local damageOrigin = GetDamageOrigin( damageInfo, player )
-
- if ( player.IsTitan() )
- Remote_CallFunction_Replay( player, "ServerCallback_TitanTookDamage", DamageInfo_GetDamage( damageInfo ), damageOrigin.x, damageOrigin.y, damageOrigin.z, damageType, damageSourceId, attackerEHandle, eModSourceID, titanDamage.doomedNow, titanDamage.doomedDamage )
- else
- Remote_CallFunction_Replay( player, "ServerCallback_PilotTookDamage", DamageInfo_GetDamage( damageInfo ), damageOrigin.x, damageOrigin.y, damageOrigin.z, damageType, damageSourceId, attackerEHandle, eModSourceID )
-}
-
-// This only handles damage events. Whizbys can still cause snipercam to trigger without passing through this check.
-function CodeCallBack_ShouldTriggerSniperCam( damageInfo )
-{
- switch ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) )
- {
- case damagedef_titan_step:
- case eDamageSourceId.super_electric_smoke_screen:
- return false
- }
-
- return true
-}
-
-bool function CodeCallback_ForceAIMissPlayer( entity npc, entity player )
-{
- return SPMP_Callback_ForceAIMissPlayer( npc, player )
-}
-
-bool function CodeCallback_OnTouchHealthKit( entity player, entity ent )
-{
- string entityClassName = ent.GetClassName()
-
- Assert( entityClassName in svGlobal.onTouchHealthKitCallbacks )
-
- array<bool functionref( entity player, entity healthpack )> callbackFuncs = svGlobal.onTouchHealthKitCallbacks[ entityClassName ]
- foreach ( callbackFunc in callbackFuncs )
- {
- bool result = callbackFunc( player, ent )
- if ( result )
- return result
- }
-
- return false
-}
-
-bool function ShouldPlayEMPEffectEvenWhenDamageIsZero( entity ent, entity attacker )
-{
- if ( ent.IsTitan() && IsTitanWithinBubbleShield( ent ) )
- return false
-
- if ( !IsValid( attacker ) )
- return true
-
- if ( attacker.GetTeam() != ent.GetTeam() )
- return true
-
- return false
-}
-
-void function CodeCallback_OnPlayerGrappled( entity player, entity victim )
-{
- if ( victim.GetTeam() != player.GetTeam() )
- {
- if ( victim.p.lastGrappledTime + TITAN_GRAPPLE_DEBOUNCE_TIME < Time() )
- {
- if ( player.IsTitan() )
- {
- victim.TakeDamage( TITAN_GRAPPLE_DAMAGE, player, player, { origin = victim.EyePosition(), scriptType = DF_GIB, damageSourceId = eDamageSourceId.titan_grapple } )
-
- if ( victim.IsTitan() )
- {
- entity soul = victim.GetTitanSoul()
- if ( soul == null )
- soul = victim
-
- float fadeTime = 0.5
- StatusEffect_AddTimed( soul, eStatusEffect.dodge_speed_slow, 0.75, 0.9 + fadeTime, fadeTime )
- StatusEffect_AddTimed( soul, eStatusEffect.move_slow, 0.75, 0.9 + fadeTime, fadeTime )
- }
- }
-
- if ( victim.IsPlayer() )
- {
- if ( player.IsTitan() )
- MessageToPlayer( victim, eEventNotifications.Grapple_WasGrappled_ByTitan )
- else
- MessageToPlayer( victim, eEventNotifications.Grapple_WasGrappled_ByPilot )
- }
- }
-
- victim.p.lastGrappledTime = Time()
- }
-}
-
-void function CodeCallback_OnProjectileGrappled( entity player, entity projectile )
-{
-
-}
-
-void function DamageInfo_ScaleDamage( var damageInfo, float scalar )
-{
- DamageInfo_SetDamage( damageInfo, DamageInfo_GetDamage( damageInfo ) * scalar )
-}
-
-string function CodeCallback_CheckPassThroughAddsMods( entity player, entity hitEnt, string currWeaponName )
-{
- if ( !IsValid( player ) )
- return ""
-
- if ( StatusEffect_Get( hitEnt, eStatusEffect.pass_through_amps_weapon ) > 0 )
- {
- array<string> mods = GetWeaponBurnMods( currWeaponName )
- if ( mods.len() > 0 )
- return mods[0]
- }
- return ""
-}
-
-void function Generic_NPCTookDamage( entity npc, damageInfo, TitanDamage titanDamage )
-{
- Assert( !npc.IsTitan() )
- Assert( DamageInfo_GetDamage( damageInfo ) > 0 )
- Assert( IsAlive( npc ) )
-
- bool critHit = false
- if ( CritWeaponInDamageInfo( damageInfo ) )
- critHit = IsCriticalHit( DamageInfo_GetAttacker( damageInfo ), npc, DamageInfo_GetHitBox( damageInfo ), DamageInfo_GetDamage( damageInfo ), DamageInfo_GetDamageType( damageInfo ) )
-
- if ( critHit )
- DamageInfo_AddCustomDamageType( damageInfo, DF_CRITICAL )
-
- titanDamage.shieldDamage = NPCShieldHealthUpdate( npc, damageInfo, critHit )
-}
-
-
-int function NPCShieldHealthUpdate( entity npc, damageInfo, bool critHit )
-{
- if ( npc.GetShieldHealth() <= 0 )
- return 0
-
- if ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) == damagedef_suicide )
- return 0
-
- if ( DamageInfo_GetForceKill( damageInfo ) )
- {
- npc.SetShieldHealth( 0 )
- return 0
- }
- else if ( DamageInfo_GetCustomDamageType( damageInfo ) & DF_BYPASS_SHIELD )
- {
- return 0
- }
-
- DamageInfo_AddCustomDamageType( damageInfo, DF_SHIELD_DAMAGE )
- return int( ShieldModifyDamage( npc, damageInfo ) )
-}
-
-#if MP
-// taken from sp/sh_sp_dialogue.gnut, with some sp-exclusive stuff removed
-
-// called by code when an animation does { event AE_SV_VSCRIPT_CALLBACK FrameNumber "some string" }
-// and by a script function OnFootstep, apparently.
-void function CodeCallback_OnServerAnimEvent( entity ent, string eventName )
-{
- PerfStart( PerfIndexServer.CB_OnServerAnimEvent )
- if ( HasAnimEvent( ent, eventName ) )
- thread RunAnimEventCallbacks( ent, eventName )
-
- if ( eventName in svGlobal.globalAnimEventCallbacks )
- {
- thread svGlobal.globalAnimEventCallbacks[ eventName ]( ent )
- PerfEnd( PerfIndexServer.CB_OnServerAnimEvent )
- return
- }
-
-
- // couldn't find this eventName on the ent or the global anim events,
- // so try breaking it down. If we didn't find it, it means
- // script needs to handle the event, even if it is just to
- // do nothing with it
-
- array<string> tokens = split( eventName, ":" )
- string tokenName = tokens[0]
-
- switch ( tokenName )
- {
- case "worldsound":
- GlobalAnimEventWithStringParameter_WorldSound( ent, tokens[1] )
- break
-
- case "signal":
- SendSignalFromTokens( ent, tokens )
- break
-
- case "flagset":
- GlobalAnimEventWithStringParameter_FlagSet( ent, tokens[1] )
- break
-
- //case "dialogue":
- // // Make sure that animation triggered dialogue uses the correct priority and skips the queue
- // string name = tokens[1]
- // Assert( file.registeredDialogIDs.find( name ) >= 0, "Dialogue line " + name + " is not registered" )
- // int aliasID = file.registeredDialogIDs.find( name )
- // DialogueData data = file.registeredDialog[ aliasID ]
- // Assert( data.priority == PRIORITY_NO_QUEUE, "Dialogue " + name + " triggered via qc must use PRIORITY_NO_QUEUE" )
- // thread PlayDialogue( name, ent )
- // break
-
- case "fireViperSalvo":
- int value = tokens[1].tointeger()
- ent.Signal( "fireSalvo", { num = value } )
- break
-
- //case "conversation":
- // thread PlayerConversation( tokens[1], GetPlayerArray()[0], ent )
- // break
- }
-
- PerfEnd( PerfIndexServer.CB_OnServerAnimEvent )
-}
-#endif // #if MP \ No newline at end of file