aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut
diff options
context:
space:
mode:
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut')
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut1395
1 files changed, 1395 insertions, 0 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut
new file mode 100644
index 00000000..2ead1d30
--- /dev/null
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut
@@ -0,0 +1,1395 @@
+untyped
+
+global function Anim_Init
+
+global function FirstPersonSequence
+global function GetAnim
+global function HasAnim
+global function SetAnim
+global function PlayAnimTeleport
+global function GetAnimStartInfo
+
+global function PlayFPSAnim
+global function PlayFPSAnimShowProxy
+global function PlayFPSAnimTeleport
+global function PlayFPSAnimTeleportShowProxy
+
+global function PlayAnim
+global function PlayAnimGravity
+global function PlayAnimGravityClientSyncing
+global function PlayAnimRunGravity
+global function PlayAnimRun
+
+global function RunToAnimStart_Deprecated
+global function RunToAnimStartForced_Deprecated
+
+global function RunToAnimStartPos
+global function RunToAndPlayAnim
+global function RunToAndPlayAnimAndWait
+global function RunToAndPlayAnimGravity
+global function RunToAndPlayAnimGravityForced
+
+function Anim_Init()
+{
+ RegisterSignal( "NewViewAnim" )
+ RegisterSignal( "NewFirstPersonSequence" )
+ RegisterSignal( "ScriptAnimStop" )
+ RegisterSignal( "AnimEventKill" )
+
+ AddGlobalAnimEvent( "enable_weapon", GlobalAnimEvent_EnableWeapon )
+ AddGlobalAnimEvent( "disable_weapon", GlobalAnimEvent_DisableWeapon )
+ AddGlobalAnimEvent( "clear_parent", GlobalAnimEvent_ClearParent )
+ AddGlobalAnimEvent( "hide", GlobalAnimEvent_Hide )
+ AddGlobalAnimEvent( "show", GlobalAnimEvent_Show )
+ AddGlobalAnimEvent( "RecordOrigin", GlobalAnimEvent_RecordOrigin )
+ AddGlobalAnimEvent( "ShowFPSProxy", GlobalAnimEvent_ShowFPSProxy )
+ AddGlobalAnimEvent( "clear_anim_view_ent",GlobalAnimEvent_ClearAnimViewEntity )
+ AddGlobalAnimEvent( "scripted_death_to_ragdoll", GlobalAnimEvent_ScriptedDeathToRagdoll )
+ AddGlobalAnimEvent( "SetVelocity", GlobalAnimEvent_SetVelocity )
+ AddGlobalAnimEvent( "stance_kneel", GlobalAnimEvent_StanceKneel )
+ AddGlobalAnimEvent( "stance_kneeling", GlobalAnimEvent_StanceKneeling )
+ AddGlobalAnimEvent( "stance_stand", GlobalAnimEvent_StanceStand )
+ AddGlobalAnimEvent( "stance_standing", GlobalAnimEvent_StanceStanding )
+ AddGlobalAnimEvent( "enable_planting", GlobalAnimEvent_EnablePlanting )
+ AddGlobalAnimEvent( "kill", GlobalAnimEvent_Kill )
+ AddGlobalAnimEvent( "gib", GlobalAnimEvent_Gib )
+ AddGlobalAnimEvent( "titan_gib", GlobalAnimEvent_TitanGib )
+ AddGlobalAnimEvent( "EnableAimAssist", GlobalAnimEvent_EnableAimAssist )
+ AddGlobalAnimEvent( "DisableAimAssist", GlobalAnimEvent_DisableAimAssist )
+ AddGlobalAnimEvent( "give_ammo", GlobalAnimEvent_GiveAmmo )
+
+ #if SP
+ PrecacheWeapon( "mp_titanweapon_salvo_rockets" ) // used by bt_pod_fire_left/bt_pod_fire_right anim events. Only BT has these anim events.
+ AddGlobalAnimEvent( "bt_pod_fire_left", GlobalAnimEvent_BT_Pod_Left )
+ AddGlobalAnimEvent( "bt_pod_fire_right", GlobalAnimEvent_BT_Pod_Right )
+ #endif
+}
+
+void function GlobalAnimEvent_BT_Pod_Left( entity guy )
+{
+ BT_Pod( guy, "POD_L" )
+}
+
+void function GlobalAnimEvent_BT_Pod_Right( entity guy )
+{
+ BT_Pod( guy, "POD_R" )
+}
+
+void function BT_Pod( entity guy, string tag )
+{
+ entity oldOffhandWeapon = guy.GetOffhandWeapon( 0 )
+ guy.TakeOffhandWeapon( 0 )
+ guy.GiveOffhandWeapon( "mp_titanweapon_salvo_rockets", 0, [ "scripted_no_damage" ] )
+
+ //printt( tag )
+ entity newOffhandWeapon = guy.GetOffhandWeapon( 0 )
+ int attachID = guy.LookupAttachment( tag )
+ vector angles = guy.GetAttachmentAngles( attachID )
+ WeaponPrimaryAttackParams params
+ params.pos = guy.GetAttachmentOrigin( attachID )
+ params.dir = AnglesToForward( angles )
+ StartParticleEffectOnEntity( guy, GetParticleSystemIndex( $"P_muzzleflash_predator" ), FX_PATTACH_POINT_FOLLOW, attachID )
+
+ thread OnWeaponPrimaryAttack_titanweapon_salvo_rockets( newOffhandWeapon, params )
+
+ guy.TakeOffhandWeapon( 0 )
+
+ if ( oldOffhandWeapon )
+ guy.GiveOffhandWeapon( oldOffhandWeapon.GetWeaponClassName(), 0, oldOffhandWeapon.GetMods() )
+}
+
+void function GlobalAnimEvent_EnableWeapon( entity guy )
+{
+ if ( guy.IsPlayer() )
+ {
+ guy.EnableWeapon()
+ guy.EnableWeaponViewModel()
+ }
+ else
+ printt( "Warning: Tried to enable weapon on non player: " + guy )
+}
+
+void function GlobalAnimEvent_DisableWeapon( entity guy )
+{
+ if ( guy.IsPlayer() )
+ {
+ guy.DisableWeapon()
+ }
+ else
+ printt( "Warning: Tried to disable weapon on non player: " + guy )
+}
+
+void function GlobalAnimEvent_ClearParent( entity guy )
+{
+ guy.ClearParent()
+}
+
+void function GlobalAnimEvent_Hide( entity guy )
+{
+ guy.Hide()
+}
+
+void function GlobalAnimEvent_Show( entity guy )
+{
+ guy.Show()
+}
+
+void function GlobalAnimEvent_RecordOrigin( entity actor )
+{
+ if ( !actor.IsPlayer() )
+ return
+ if ( !( "recordedOrigin" in actor.s ) )
+ actor.s.recordedOrigin <- []
+
+ table record = {}
+ record.origin <- actor.GetOrigin()
+ record.time <- Time()
+
+ actor.s.recordedOrigin.append( record )
+}
+
+void function GlobalAnimEvent_ShowFPSProxy( entity player )
+{
+ if ( !player.IsPlayer() )
+ return
+ local viewmodel = player.GetFirstPersonProxy()
+ viewmodel.ShowFirstPersonProxy()
+}
+
+void function GlobalAnimEvent_ClearAnimViewEntity( entity player )
+{
+ if ( !player.IsPlayer() )
+ return
+ ClearPlayerAnimViewEntity( player, 1.0 )
+}
+
+void function GlobalAnimEvent_ScriptedDeathToRagdoll( entity ent )
+{
+ ent.Die()
+ ent.SetContinueAnimatingAfterRagdoll( true )
+ ent.BecomeRagdoll( Vector(0,0,0), false )
+}
+
+void function GlobalAnimEvent_SetVelocity( entity actor )
+{
+ if ( !actor.IsPlayer() )
+ return
+ local record = null
+
+ if ( ( "recordedOrigin" in actor.s ) && actor.s.recordedOrigin.len() )
+ record = actor.s.recordedOrigin[ actor.s.recordedOrigin.len() - 1 ]
+
+ Assert( record, "anim had AE_SV_VSCRIPT_CALLBACK: SetVelocity, but no AE_SV_VSCRIPT_CALLBACK:RecordOrigin" )
+
+ local dir = Normalize( actor.GetOrigin() - record.origin )
+ local distance = Distance( actor.GetOrigin(), record.origin )
+ local time = Time() - record.time
+ if ( time <= 0 )
+ time = 0.001 // timescale bug?
+ local speed = distance / time
+
+ actor.SetVelocity( dir * speed )
+}
+
+void function GlobalAnimEvent_StanceKneel( entity guy )
+{
+ Assert( guy.IsTitan() )
+ Assert( guy.IsNPC() )
+ SetStanceKneel( guy.GetTitanSoul() )
+}
+
+void function GlobalAnimEvent_StanceKneeling( entity guy )
+{
+ Assert( guy.IsTitan() )
+ Assert( guy.IsNPC() )
+ SetStanceKneeling( guy.GetTitanSoul() )
+}
+
+void function GlobalAnimEvent_StanceStand( entity guy )
+{
+ Assert( guy.IsTitan() )
+ Assert( guy.IsNPC() )
+ SetStanceStand( guy.GetTitanSoul() )
+}
+
+void function GlobalAnimEvent_StanceStanding( entity guy )
+{
+ Assert( guy.IsTitan() )
+ Assert( guy.IsNPC() )
+ SetStanceStanding( guy.GetTitanSoul() )
+}
+
+void function GlobalAnimEvent_EnablePlanting( entity guy )
+{
+ if ( guy.IsNPC() || guy.IsPlayer() )
+ guy.Anim_EnablePlanting()
+ else
+ printt( "Warning: Tried to enable planting on " + guy )
+}
+
+void function GlobalAnimEvent_Kill( entity guy )
+{
+ if ( IsAlive( guy ) )
+ {
+ Signal( guy, "AnimEventKill" )
+ guy.TakeDamage( guy.GetMaxHealth() + 1, null, null, { damageSourceId=damagedef_suicide } )
+ guy.BecomeRagdoll( Vector( 0, 0, 0 ), false )
+ }
+}
+
+void function GlobalAnimEvent_Gib( entity guy )
+{
+ if ( IsAlive( guy ) )
+ {
+ Signal( guy, "AnimEventKill" )
+ guy.Gib( <0,0,100> )
+ }
+}
+
+void function GlobalAnimEvent_TitanGib( entity guy )
+{
+ if ( IsAlive( guy ) )
+ {
+ PlayTitanDeathFxUp( guy )
+
+ local entKVs = guy.CreateTableFromModelKeyValues()
+ local hitData = entKVs["hit_data"]
+
+ foreach ( bodyGroupName, bodyGroupData in hitData )
+ {
+ if ( !("blank" in bodyGroupData) )
+ continue
+
+ local bodyGroupIndex = guy.FindBodyGroup( bodyGroupName )
+ local stateCount = guy.GetBodyGroupModelCount( bodyGroupIndex )
+ guy.SetBodygroup( bodyGroupIndex, stateCount - 1 )
+ }
+ }
+}
+
+
+void function GlobalAnimEvent_EnableAimAssist( entity guy )
+{
+ if ( IsAlive( guy ) )
+ {
+ guy.SetAimAssistAllowed( true )
+ }
+}
+
+void function GlobalAnimEvent_DisableAimAssist( entity guy )
+{
+ if ( IsAlive( guy ) )
+ {
+ guy.SetAimAssistAllowed( false )
+ }
+}
+
+void function GlobalAnimEvent_GiveAmmo( entity guy )
+{
+ if ( IsAlive( guy ) )
+ {
+ array<entity> weapons = guy.GetMainWeapons()
+ if ( weapons.len() > 0 )
+ {
+ entity weapon = weapons[0]
+ if ( IsValid( weapon ) )
+ {
+ weapon.SetWeaponPrimaryClipCount( weapon.GetWeaponPrimaryClipCountMax() )
+ }
+ }
+ }
+}
+
+
+function GetAnim( guy, animation )
+{
+ if ( !( "anims" in guy.s ) )
+ return animation
+
+ if ( !( animation in guy.s.anims ) )
+ return animation
+
+ return guy.s.anims[ animation ]
+}
+
+function HasAnim( guy, animation )
+{
+ if ( !( "anims" in guy.s ) )
+ return false
+
+ return animation in guy.s.anims
+}
+
+function SetAnim( guy, name, animation )
+{
+ if ( !( "anims" in guy.s ) )
+ guy.s.anims <- {}
+
+ Assert( !( name in guy.s.anims ), guy + " already has set anim " + name )
+
+ guy.s.anims[ name ] <- animation
+}
+
+AnimRefPoint function GetAnimStartInfo( entity ent, string animAlias, animref )
+{
+ string animData = expect string( GetAnim( ent, animAlias ) )
+ AnimRefPoint animStartInfo = ent.Anim_GetStartForRefPoint( animData, animref.GetOrigin(), animref.GetAngles() )
+
+ return animStartInfo
+}
+
+
+function GetRefPosition( reference )
+{
+ Assert( reference.HasKey( "model" ) && reference.GetValueForModelKey() != $"", "Tried to play an anim relative to " + reference + " but it has no model/ref attachment." )
+
+ local position = {}
+ local attach_id
+ attach_id = reference.LookupAttachment( "REF" )
+
+ if ( attach_id )
+ {
+ position.origin <- reference.GetAttachmentOrigin( attach_id )
+ position.angles <- reference.GetAttachmentAngles( attach_id )
+ }
+
+ return position
+}
+
+// play the anim
+function __PlayAnim( guy, animation_name, reference = null, optionalTag = null, blendTime = DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME )
+{
+ expect entity( guy )
+
+ Assert( IsValid_ThisFrame( guy ), "Invalid ent sent to PlayAnim " + animation_name )
+ local animation = GetAnim( guy, animation_name )
+
+ guy.SetNextThinkNow()
+
+ #if !DEV
+ if ( guy.IsNPC() && !guy.IsInterruptable() )
+ {
+ // better than nothing failsafe
+ guy.Signal( "OnAnimationInterrupted" )
+ guy.Signal( "OnAnimationDone" )
+ return
+ }
+ #endif
+
+ if ( guy.IsNPC() )
+ {
+ guy.EndSignal( "OnDeath" )
+ Assert( IsAlive( guy ), "Guy " + guy + " tried to play an anim, but it is not alive." )
+ }
+
+ if ( reference )
+ {
+ if ( reference == guy )
+ {
+ local position = GetRefPosition( reference )
+ local origin = position.origin
+ local angles = position.angles
+
+ if ( guy.IsNPC() )
+ guy.Anim_ScriptedPlayWithRefPoint( animation, origin, angles, blendTime )
+ else
+ guy.Anim_PlayWithRefPoint( animation, origin, angles, blendTime )
+
+ return
+ }
+
+ if ( optionalTag )
+ {
+ if ( typeof( reference ) == "vector" )
+ {
+ Assert( typeof( optionalTag ) == "vector", "Expected angles but got " + optionalTag )
+ if ( guy.IsNPC() )
+ guy.Anim_ScriptedPlayWithRefPoint( animation, reference, optionalTag, blendTime )
+ else
+ guy.Anim_PlayWithRefPoint( animation, reference, optionalTag, blendTime )
+ return
+ }
+
+ Assert( typeof( optionalTag ) == "string", "Passed invalid optional tag " + optionalTag )
+
+ if ( guy.GetParent() == reference )
+ {
+ if ( guy.IsNPC() )
+ guy.Anim_ScriptedPlay( animation )
+ else
+ guy.Anim_Play( animation )
+ }
+ else
+ {
+ local attachIndex = reference.LookupAttachment( optionalTag )
+ local origin = reference.GetAttachmentOrigin( attachIndex )
+ local angles = reference.GetAttachmentAngles( attachIndex )
+ if ( guy.IsNPC() )
+ {
+ //local origin = reference.GetOrigin()
+ //local angles = reference.GetAngles()
+ guy.Anim_ScriptedPlayWithRefPoint( animation, origin, angles, blendTime )
+ }
+ else
+ {
+ //local animStartPos = guy.Anim_GetStartForRefEntity_Old( animation, reference, optionalTag )
+ //local origin = animStartPos.origin
+ //local angles = animStartPos.angles
+ guy.Anim_PlayWithRefPoint( animation, origin, angles, blendTime )
+ }
+ }
+ return
+ }
+ }
+ else
+ {
+ Assert( optionalTag == null, "Reference was null, but optionalTag was not. Did you mean to set the tag?" )
+ }
+
+ if ( reference != null && guy.GetParent() == reference )
+ {
+ if ( guy.IsNPC() )
+ guy.Anim_ScriptedPlay( animation )
+ else
+ guy.Anim_Play( animation )
+
+ return
+ }
+
+ if ( !reference )
+ reference = guy
+
+ local origin = reference.GetOrigin()
+ local angles = reference.GetAngles()
+
+ if ( guy.IsNPC() )
+ guy.Anim_ScriptedPlayWithRefPoint( animation, origin, angles, blendTime )
+ else
+ guy.Anim_PlayWithRefPoint( animation, origin, angles, blendTime )
+
+}
+
+function TeleportToAnimStart( _guy, animation_name, reference, optionalTag = null, smooth = false )
+{
+ entity guy = expect entity( _guy )
+
+ Assert( reference, "NO reference" )
+ string animation = expect string( GetAnim( guy, animation_name ) )
+ AnimRefPoint animStartPos
+
+ if ( optionalTag )
+ {
+ if ( typeof( reference ) == "vector" )
+ {
+ Assert( typeof( optionalTag ) == "vector", "Expected angles but got " + optionalTag )
+ animStartPos = guy.Anim_GetStartForRefPoint( animation, reference, optionalTag )
+ }
+ else
+ {
+ animStartPos = guy.Anim_GetStartForRefEntity( animation, reference, optionalTag )
+ }
+ }
+ else
+ {
+ //printt( "Reference is " + reference )
+ //printt( "guy is " + guy )
+ //printt( "animation is " + animation )
+ local origin = reference.GetOrigin()
+ local angles = reference.GetAngles()
+ animStartPos = guy.Anim_GetStartForRefPoint( animation, origin, angles )
+ }
+ //Assert( animStartPos, "No animStartPos for " + animation + " on " + guy )
+
+ // hack! shouldn't need to do this
+ animStartPos.origin = ClampToWorldspace( animStartPos.origin )
+
+ if ( guy.GetParent() )
+ {
+ if ( smooth )
+ {
+ guy.SetAbsOriginSmooth( animStartPos.origin )
+ guy.SetAbsAnglesSmooth( animStartPos.angles )
+ }
+ else
+ {
+ guy.SetAbsOrigin( animStartPos.origin )
+ guy.SetAbsAngles( animStartPos.angles )
+ }
+ }
+ else
+ {
+ guy.SetOrigin( animStartPos.origin )
+ guy.SetAngles( animStartPos.angles )
+ }
+}
+
+// wait till arrive at goal and animation is done
+function RunToAndPlayAnimAndWait( entity guy, string animation_name, reference, bool doArrival = false, optionalTag = null )
+{
+ bool savedEnableFriendlyFollower = guy.ai.enableFriendlyFollower
+ guy.ai.enableFriendlyFollower = false
+
+ local allowFlee = guy.GetNPCFlag( NPC_ALLOW_FLEE )
+ local allowHandSignal = guy.GetNPCFlag( NPC_ALLOW_HAND_SIGNALS )
+ guy.DisableNPCFlag( NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
+
+ __RunToAndPlayAnim( guy, animation_name, reference, doArrival, optionalTag )
+
+ guy.WaitSignal( "OnFinishedAssault" )
+ WaittillAnimDone( guy )
+
+ guy.SetNPCFlag( NPC_ALLOW_FLEE, allowFlee )
+ guy.ai.enableFriendlyFollower = savedEnableFriendlyFollower
+}
+
+// wait till arrive at goal and start animation but don't wait until animation is done
+function RunToAndPlayAnim( entity guy, string animation_name, reference, bool doArrival = false, optionalTag = null )
+{
+ bool savedEnableFriendlyFollower = guy.ai.enableFriendlyFollower
+ guy.ai.enableFriendlyFollower = false
+
+ local allowFlee = guy.GetNPCFlag( NPC_ALLOW_FLEE )
+ local allowHandSignal = guy.GetNPCFlag( NPC_ALLOW_HAND_SIGNALS )
+ guy.DisableNPCFlag( NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
+
+ __RunToAndPlayAnim( guy, animation_name, reference, doArrival, optionalTag )
+
+ guy.WaitSignal( "OnFinishedAssault" )
+
+ guy.SetNPCFlag( NPC_ALLOW_FLEE, allowFlee )
+ guy.ai.enableFriendlyFollower = savedEnableFriendlyFollower
+}
+
+function RunToAndPlayAnimGravity( entity guy, string animation_name, reference, bool doArrival = false, optionalTag = null )
+{
+ local allowFlee = guy.GetNPCFlag( NPC_ALLOW_FLEE )
+ local allowHandSignal = guy.GetNPCFlag( NPC_ALLOW_HAND_SIGNALS )
+ guy.DisableNPCFlag( NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
+
+ float arrivalTolerance = guy.AssaultGetArrivalTolerance()
+ __RunToAndPlayAnim( guy, animation_name, reference, doArrival, optionalTag )
+
+ guy.WaitSignal( "OnFinishedAssault" )
+ guy.Anim_EnablePlanting()
+ WaittillAnimDone( guy )
+
+ guy.AssaultSetArrivalTolerance( arrivalTolerance )
+
+ guy.SetNPCFlag( NPC_ALLOW_HAND_SIGNALS, allowHandSignal )
+}
+
+
+function RunToAndPlayAnimGravityForced( entity guy, string animation_name, reference, bool doArrival = false, optionalTag = null )
+{
+ bool savedEnableFriendlyFollower = guy.ai.enableFriendlyFollower
+ guy.ai.enableFriendlyFollower = false
+
+ local allowFlee = guy.GetNPCFlag( NPC_ALLOW_FLEE )
+ local allowHandSignal = guy.GetNPCFlag( NPC_ALLOW_HAND_SIGNALS )
+ guy.DisableNPCFlag( NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
+
+ float arrivalTolerance = guy.AssaultGetArrivalTolerance()
+ __RunToAndPlayAnim( guy, animation_name, reference, doArrival, optionalTag )
+
+ guy.WaitSignal( "OnFinishedAssault" )
+ guy.Anim_EnablePlanting()
+ WaittillAnimDone( guy )
+
+ guy.AssaultSetArrivalTolerance( arrivalTolerance )
+
+ guy.SetNPCFlag( NPC_ALLOW_HAND_SIGNALS, allowHandSignal )
+ guy.ai.enableFriendlyFollower = savedEnableFriendlyFollower
+}
+
+function __RunToAndPlayAnim( entity guy, string animation_name, reference, bool doArrival, optionalTag )
+{
+ Assert( IsAlive( guy ) )
+ guy.Anim_Stop() // in case we were doing an anim already
+ guy.EndSignal( "OnDeath" )
+
+ string animation = expect string( GetAnim( guy, animation_name ) )
+ local origin, angles
+
+ if ( optionalTag )
+ {
+ if ( typeof( reference ) == "vector" )
+ {
+ Assert( typeof( optionalTag ) == "vector", "Expected angles but got " + optionalTag )
+ origin = reference
+ angles = optionalTag
+ }
+ else
+ {
+ local attach_id = reference.LookupAttachment( optionalTag )
+ origin = reference.GetAttachmentOrigin( attach_id )
+ angles = reference.GetAttachmentAngles( attach_id )
+ }
+ }
+ else
+ {
+ Assert( typeof( reference ) != "vector", "Expected an entity, but got an origin with no angles" )
+ origin = reference.GetOrigin()
+ angles = reference.GetAngles()
+ }
+
+ guy.AssaultPointToAnim( origin, angles, animation, doArrival, 4.0 )
+}
+
+// run to the place to start the anim, then play it
+function RunToAnimStart_Deprecated( guy, animation_name, reference = null, optionalTag = null )
+{
+ expect entity( guy )
+
+ Assert( IsAlive( guy ) )
+ guy.Anim_Stop() // in case we were doing an anim already
+ guy.EndSignal( "OnDeath" )
+
+ local allowFlee = guy.GetNPCFlag( NPC_ALLOW_FLEE )
+ local allowHandSignal = guy.GetNPCFlag( NPC_ALLOW_HAND_SIGNALS )
+
+ guy.DisableNPCFlag( NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
+
+ local animation = GetAnim( guy, animation_name )
+ local animStartPos
+
+ if ( optionalTag )
+ {
+ if ( typeof( reference ) == "vector" )
+ {
+ Assert( typeof( optionalTag ) == "vector", "Expected angles but got " + optionalTag )
+ animStartPos = guy.Anim_GetStartForRefPoint_Old( animation, reference, optionalTag )
+ }
+ else
+ {
+ animStartPos = guy.Anim_GetStartForRefEntity_Old( animation, reference, optionalTag )
+ }
+ }
+ else
+ {
+ local origin = reference.GetOrigin()
+ local angles = reference.GetAngles()
+ animStartPos = guy.Anim_GetStartForRefPoint_Old( animation, origin, angles )
+ }
+
+ guy.AssaultPoint( animStartPos.origin )
+ guy.WaitSignal( "OnFinishedAssault" )
+
+ guy.SetNPCFlag( NPC_ALLOW_FLEE, allowFlee )
+ guy.SetNPCFlag( NPC_ALLOW_HAND_SIGNALS, allowHandSignal )
+
+ local dist = Distance( animStartPos.origin, guy.GetOrigin() )
+ if ( dist > 8 )
+ {
+ //DebugDrawLine( animStartPos.origin, guy.GetOrigin(), 255, 150, 0, true, 60 )
+ printt( guy, " was ", dist, " units away from where he wanted to end his scripted sequence" )
+ }
+// printt( guy + " finished assault at dist ", Distance( animStartPos.origin, guy.GetOrigin() ) )
+// Assert( Distance( animStartPos.origin, guy.GetOrigin() ) < 32, guy + " finished assault but was " + ( Distance( animStartPos.origin, guy.GetOrigin() ) ) + " away from where he should have ended up." )
+}
+
+// only use this if you are OK with a frame pause before the start of the animation
+void function RunToAnimStartPos( entity guy, string animation_name, reference = null, bool doArrival = false, optionalTag = null )
+{
+ Assert( IsAlive( guy ) )
+ guy.Anim_Stop() // in case we were doing an anim already
+ guy.EndSignal( "OnDeath" )
+
+ local allowFlee = guy.GetNPCFlag( NPC_ALLOW_FLEE )
+ local allowHandSignal = guy.GetNPCFlag( NPC_ALLOW_HAND_SIGNALS )
+ local allowArrivals = guy.GetNPCMoveFlag( NPCMF_DISABLE_ARRIVALS )
+
+ if ( !doArrival )
+ {
+ // guy.DisableArrivalOnce( true )
+ guy.EnableNPCMoveFlag( NPCMF_DISABLE_ARRIVALS )
+ }
+
+ guy.DisableNPCFlag( NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
+
+ local animation = GetAnim( guy, animation_name )
+ local animStartPos
+
+ if ( optionalTag )
+ {
+ if ( typeof( reference ) == "vector" )
+ {
+ Assert( typeof( optionalTag ) == "vector", "Expected angles but got " + optionalTag )
+ animStartPos = guy.Anim_GetStartForRefPoint_Old( animation, reference, optionalTag )
+ }
+ else
+ {
+ animStartPos = guy.Anim_GetStartForRefEntity_Old( animation, reference, optionalTag )
+ vector ornull clampedPos = NavMesh_ClampPointForAI( animStartPos.origin, guy )
+ if ( clampedPos != null )
+ animStartPos.origin = clampedPos
+ }
+ }
+ else
+ {
+ local origin = reference.GetOrigin()
+ local angles = reference.GetAngles()
+ animStartPos = guy.Anim_GetStartForRefPoint_Old( animation, origin, angles )
+ }
+
+ var fightRadius = guy.AssaultGetFightRadius()
+ var arrivalTolerance = guy.AssaultGetArrivalTolerance()
+ float runtoRadius = 61.16
+ guy.AssaultSetFightRadius( runtoRadius )
+ guy.AssaultSetArrivalTolerance( runtoRadius )
+
+ bool savedEnableFriendlyFollower = guy.ai.enableFriendlyFollower
+ guy.ai.enableFriendlyFollower = false
+
+ guy.AssaultPoint( animStartPos.origin )
+
+ //DebugDrawLine( guy.GetOrigin(), animStartPos.origin, 255, 0, 0, true, 20.0 )
+ //DebugDrawAngles( animStartPos.origin, animStartPos.angles )
+ //thread DebugAssaultEnt( guy, assaultEnt )
+ WaitSignal( guy, "OnFinishedAssault" )
+
+ //in case the scripter reset during run, we want to honor the intended change
+ if ( guy.AssaultGetFightRadius() == runtoRadius )
+ guy.AssaultSetFightRadius( fightRadius )
+
+ if ( guy.AssaultGetArrivalTolerance() == runtoRadius )
+ guy.AssaultSetArrivalTolerance( arrivalTolerance )
+
+ guy.SetNPCFlag( NPC_ALLOW_FLEE, allowFlee )
+ guy.SetNPCFlag( NPC_ALLOW_HAND_SIGNALS, allowHandSignal )
+ guy.SetNPCMoveFlag( NPCMF_DISABLE_ARRIVALS, allowArrivals )
+
+ guy.ai.enableFriendlyFollower = savedEnableFriendlyFollower
+}
+
+///////////////////////////////////////////////////////////////////
+// Deprecated, use RunToAndPlayAnim, otherwise there will be a gap between arriving at position and playing the animation
+function RunToAnimStartForced_Deprecated( entity guy, string animation_name, reference = null, optionalTag = null, bool disableArrival = true, disableAssaultAngles = false )
+{
+ Assert( IsAlive( guy ) )
+ guy.Anim_Stop() // in case we were doing an anim already
+ guy.EndSignal( "OnDeath" )
+
+ local allowFlee = guy.GetNPCFlag( NPC_ALLOW_FLEE )
+ local allowHandSignal = guy.GetNPCFlag( NPC_ALLOW_HAND_SIGNALS )
+ local allowArrivals = guy.GetNPCMoveFlag( NPCMF_DISABLE_ARRIVALS )
+
+ if ( disableArrival )
+ {
+ // guy.DisableArrivalOnce( true )
+ guy.EnableNPCMoveFlag( NPCMF_DISABLE_ARRIVALS )
+ }
+
+ guy.DisableNPCFlag( NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
+
+ local animation = GetAnim( guy, animation_name )
+ local animStartPos
+
+ if ( optionalTag )
+ {
+ if ( typeof( reference ) == "vector" )
+ {
+ Assert( typeof( optionalTag ) == "vector", "Expected angles but got " + optionalTag )
+ animStartPos = guy.Anim_GetStartForRefPoint_Old( animation, reference, optionalTag )
+ }
+ else
+ {
+ animStartPos = guy.Anim_GetStartForRefEntity_Old( animation, reference, optionalTag )
+ vector ornull clampedPos = NavMesh_ClampPointForAI( animStartPos.origin, guy )
+ if ( clampedPos != null )
+ animStartPos.origin = clampedPos
+ }
+ }
+ else
+ {
+ local origin = reference.GetOrigin()
+ local angles = reference.GetAngles()
+ animStartPos = guy.Anim_GetStartForRefPoint_Old( animation, origin, angles )
+ }
+
+ var fightRadius = guy.AssaultGetFightRadius()
+ var arrivalTolerance = guy.AssaultGetArrivalTolerance()
+ float runtoRadius = 61.16
+ guy.AssaultSetFightRadius( runtoRadius )
+ guy.AssaultSetArrivalTolerance( runtoRadius )
+
+ bool savedEnableFriendlyFollower = guy.ai.enableFriendlyFollower
+ guy.ai.enableFriendlyFollower = false
+
+ guy.AssaultPoint( animStartPos.origin )
+ if ( !disableAssaultAngles )
+ guy.AssaultSetAngles( animStartPos.angles, true )
+
+ //DebugDrawLine( guy.GetOrigin(), animStartPos.origin, 255, 0, 0, true, 20.0 )
+ //DebugDrawAngles( animStartPos.origin, animStartPos.angles )
+ //thread DebugAssaultEnt( guy, assaultEnt )
+ WaitSignal( guy, "OnFinishedAssault" )
+
+/*
+ if ( !disableAssaultAngles )
+ guy.AssaultSetAngles( animStartPos.angles, true )
+
+ guy.AssaultPointToAnim( animStartPos.origin, animation, 4.0 )
+ WaittillAnimDone( guy )
+// guy.WaitSignal( "OnFinishedAssault" )
+
+*/
+ //in case the scripter reset during run, we want to honor the intended change
+ if ( guy.AssaultGetFightRadius() == runtoRadius )
+ guy.AssaultSetFightRadius( fightRadius )
+
+ if ( guy.AssaultGetArrivalTolerance() == runtoRadius )
+ guy.AssaultSetArrivalTolerance( arrivalTolerance )
+
+ guy.SetNPCFlag( NPC_ALLOW_FLEE, allowFlee )
+ guy.SetNPCFlag( NPC_ALLOW_HAND_SIGNALS, allowHandSignal )
+ guy.SetNPCMoveFlag( NPCMF_DISABLE_ARRIVALS, allowArrivals )
+
+ guy.ai.enableFriendlyFollower = savedEnableFriendlyFollower
+}
+
+void function ShowEnt( entity viewmodel )
+{
+ if ( IsValid_ThisFrame( viewmodel ) )
+ viewmodel.ShowFirstPersonProxy()
+}
+
+// anim teleport
+function PlayAnimTeleport( guy, animation_name, reference = null, optionalTag = null, initialTime = -1.0, smooth = false )
+{
+ if ( type( guy ) == "array" || type( guy ) == "table" )
+ {
+ Assert( reference, "NO reference" )
+ local firstEnt = null
+ foreach ( ent in guy )
+ {
+ if ( !firstEnt )
+ firstEnt = ent
+
+ TeleportToAnimStart( ent, animation_name, reference, optionalTag, smooth )
+ __PlayAnim( ent, animation_name, reference, optionalTag, 0 )
+ if ( initialTime > 0.0 )
+ guy.Anim_SetInitialTime( initialTime )
+ }
+
+ WaittillAnimDone( expect entity( firstEnt ) )
+ }
+ else
+ {
+ if ( !reference )
+ reference = guy
+
+ TeleportToAnimStart( guy, animation_name, reference, optionalTag, smooth )
+ __PlayAnim( guy, animation_name, reference, optionalTag, 0 )
+ if ( initialTime > 0.0 )
+ guy.Anim_SetInitialTime( initialTime )
+ WaittillAnimDone( expect entity( guy ) )
+ }
+}
+
+// play the anim
+function PlayAnim( guy, animation_name, reference = null, optionalTag = null, blendTime = DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME, initialTime = -1.0 )
+{
+ if ( type( guy ) == "array" )
+ {
+ foreach ( ent in guy )
+ {
+ __PlayAnim( ent, animation_name, reference, optionalTag, blendTime )
+ if ( initialTime > 0.0 )
+ guy.Anim_SetInitialTime( initialTime )
+ }
+
+ WaittillAnimDone( expect entity( guy[0] ) )
+ }
+ else
+ {
+ __PlayAnim( guy, animation_name, reference, optionalTag, blendTime )
+ if ( initialTime > 0.0 )
+ guy.Anim_SetInitialTime( initialTime )
+ WaittillAnimDone( expect entity( guy ) )
+ }
+}
+
+// play the anim
+function PlayAnimRun( entity guy, string animation_name, reference, bool doArrival, optionalTag = null, blendTime = DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME )
+{
+ RunToAndPlayAnim( guy, animation_name, reference, doArrival, optionalTag )
+ WaitSignal( guy, "OnFinishedAssault" )
+ WaittillAnimDone( guy )
+}
+
+function PlayAnimRunGravity( entity guy, string animation_name, reference, bool doArrival, optionalTag = null, blendTime = DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME )
+{
+ RunToAndPlayAnim( guy, animation_name, reference, doArrival, optionalTag )
+ WaitSignal( guy, "OnFinishedAssault" )
+ guy.Anim_EnablePlanting()
+ WaittillAnimDone( guy )
+}
+
+function PlayAnimGravityClientSyncing( guy, animation_name, reference = null, optionalTag = null, blendTime = DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME )
+{
+ __PlayAnim( guy, animation_name, reference, optionalTag, blendTime )
+ guy.Anim_EnablePlanting()
+ WaittillAnimDone( expect entity( guy ) )
+}
+
+function PlayAnimGravity( guy, animation_name, reference = null, optionalTag = null, blendTime = DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME )
+{
+ __PlayAnim( guy, animation_name, reference, optionalTag, blendTime )
+ guy.Anim_EnablePlanting()
+ WaittillAnimDone( expect entity( guy ) )
+}
+
+
+function CalcSequenceBlendTime( FirstPersonSequenceStruct sequence, entity player, entity ent = null )
+{
+ if ( sequence.blendTime != CALCULATE_SEQUENCE_BLEND_TIME )
+ return
+
+ sequence.blendTime = 0
+ if ( ent && sequence.thirdPersonAnim != "" )
+ {
+ local start
+ if ( sequence.attachment != "" )
+ {
+ start = player.Anim_GetStartForRefEntity_Old( sequence.thirdPersonAnim, ent, sequence.attachment )
+ }
+ else
+ {
+ start = {}
+ start.origin <- ent.GetOrigin()
+ start.angles <- ent.GetAngles()
+ }
+
+ if ( sequence.teleport )
+ {
+ player.SetAbsOrigin( start.origin )
+ player.SetAbsAngles( start.angles )
+ }
+ else
+ {
+ local dist = Distance( player.GetOrigin(), start.origin )
+ sequence.blendTime = GraphCapped( dist, 0, 350, 0.25, 0.9 )
+ }
+ }
+}
+
+void function PlayFPSAnim( entity player, string anim3rd, string anim1st = "", entity ref = null, string optionalTag = "", void functionref(entity) animView = null, float blendTime = DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME, float initialTime = 0.0 )
+{
+ bool teleport = false
+ bool hideProxy = true
+ __PlayFPSAnimInternal( player, anim3rd, anim1st, ref, optionalTag, animView, blendTime, initialTime, teleport, hideProxy )
+}
+
+void function PlayFPSAnimShowProxy( entity player, string anim3rd, string anim1st = "", entity ref = null, string optionalTag = "", void functionref(entity) animView = null, float blendTime = DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME, float initialTime = 0.0 )
+{
+ bool teleport = false
+ bool hideProxy = false
+ __PlayFPSAnimInternal( player, anim3rd, anim1st, ref, optionalTag, animView, blendTime, initialTime, teleport, hideProxy )
+}
+
+void function PlayFPSAnimTeleport( entity player, string anim3rd, string anim1st = "", entity ref = null, string optionalTag = "", void functionref(entity) animView = null, float initialTime = 0.0 )
+{
+ bool teleport = true
+ bool hideProxy = true
+ float blendTime = 0.0
+ __PlayFPSAnimInternal( player, anim3rd, anim1st, ref, optionalTag, animView, blendTime, initialTime, teleport, hideProxy )
+}
+
+void function PlayFPSAnimTeleportShowProxy( entity player, string anim3rd, string anim1st = "", entity ref = null, string optionalTag = "", void functionref(entity) animView = null, float initialTime = 0.0 )
+{
+ bool teleport = true
+ bool hideProxy = false
+ float blendTime = 0.0
+ __PlayFPSAnimInternal( player, anim3rd, anim1st, ref, optionalTag, animView, blendTime, initialTime, teleport, hideProxy )
+}
+
+void function __PlayFPSAnimInternal( entity player, string anim3rd, string anim1st, entity ref, string optionalTag, void functionref(entity) animView, float blendTime, float initialTime, bool teleport, bool hideProxy )
+{
+ if ( animView == null )
+ animView = ViewConeRampFree
+
+ FirstPersonSequenceStruct sequence
+
+ sequence.firstPersonAnim = anim1st
+ sequence.thirdPersonAnim = anim3rd
+ sequence.attachment = optionalTag
+ sequence.viewConeFunction = animView
+ sequence.setInitialTime = initialTime
+ sequence.blendTime = blendTime
+ sequence.teleport = teleport
+ sequence.hideProxy = hideProxy
+
+ //hard coded in this function
+ sequence.noParent = true
+
+ FirstPersonSequence( sequence, player, ref )
+}
+
+void function FirstPersonSequence( FirstPersonSequenceStruct sequence, entity player, entity ent = null )
+{
+ player.Signal( "NewFirstPersonSequence" )
+ player.EndSignal( "NewFirstPersonSequence" )
+ player.EndSignal( "ScriptAnimStop" )
+
+ player.SetVelocity( <0,0,0> ) // fix this
+ if ( player.IsPlayer() && sequence.snapPlayerFeetToEyes )
+ {
+ player.SnapFeetToEyes()
+ }
+
+ //figure out if we have/should do a first person sequence and handle Spawn slots.
+ bool doFirstPersonAnim = sequence.firstPersonAnim != ""
+
+ entity firstPersonProxy
+ if ( doFirstPersonAnim )
+ {
+ Assert( player.IsPlayer(), player + " is not a player" )
+ firstPersonProxy = player.GetFirstPersonProxy()
+ if ( !IsValid( firstPersonProxy ) || !EntHasModelSet( firstPersonProxy ) )
+ {
+ doFirstPersonAnim = false;
+ }
+ }
+
+ if ( doFirstPersonAnim )
+ {
+ firstPersonProxy.ShowFirstPersonProxy()
+
+ if ( sequence.renderWithViewModels )
+ firstPersonProxy.RenderWithViewModels( true )
+ else
+ firstPersonProxy.RenderWithViewModels( false )
+
+ firstPersonProxy.ClearParent()
+ firstPersonProxy.SetAbsOrigin( player.GetOrigin() )
+ firstPersonProxy.SetAbsAngles( player.GetAngles() )
+
+ // Set anim view entity *after* setting the proxy's origin so that we calculate our initial view offset correctly (for lerping)
+ SetPlayerAnimViewEntity( player, firstPersonProxy )
+ firstPersonProxy.SetNextThinkNow()
+ SetForceDrawWhileParented( firstPersonProxy, true )
+ }
+ else if ( sequence.thirdPersonCameraAttachments.len() > 0 )
+ {
+ if ( player.IsPlayer() )
+ {
+ entity fpProxy = player.GetFirstPersonProxy() //Shouldn't ever need to show the first person proxy when doing thirdPersonCameraAttachments; hide it explicitly here to stop it from showing up when chaining animations
+ if ( IsValid( fpProxy ) )
+ fpProxy.HideFirstPersonProxy()
+
+ if ( sequence.thirdPersonCameraEntity )
+ {
+ SetPlayerAnimViewEntity( player, sequence.thirdPersonCameraEntity )
+ }
+ else
+ {
+ SetPlayerAnimViewEntity( player, player )
+ }
+
+ player.AnimViewEntity_SetThirdPersonCameraAttachments( sequence.thirdPersonCameraAttachments )
+ if ( sequence.thirdPersonCameraVisibilityChecks )
+ {
+ player.AnimViewEntity_EnableThirdPersonCameraVisibilityChecks()
+ }
+ }
+ }
+ else
+ {
+ if ( player.IsPlayer() )
+ {
+ ClearPlayerAnimViewEntity( player )
+ }
+ }
+
+ entity soul
+
+ if ( ent )
+ {
+ // the entity we are animating relative to may change during the animation
+ if ( IsSoul( ent ) )
+ {
+ soul = ent
+ ent = soul.GetTitan()
+ if ( !IsValid( ent ) )
+ return
+ }
+ else if ( HasSoul( ent ) )
+ {
+ soul = ent.GetTitanSoul()
+ }
+ }
+
+ CalcSequenceBlendTime( sequence, player, ent )
+
+ if ( player.IsPlayer() )
+ {
+ if ( sequence.teleport )
+ {
+ player.AnimViewEntity_SetLerpInTime( 0.0 )
+ player.PlayerCone_SetLerpTime( 0.0 )
+ player.SnapToAbsOrigin( player.GetOrigin() )
+ }
+ else
+ {
+ if ( sequence.noViewLerp || (sequence.blendTime <= 0.0) )
+ {
+ player.AnimViewEntity_SetLerpInTime( 0.0 )
+ player.PlayerCone_SetLerpTime( 0.0 )
+ }
+ else
+ {
+ player.AnimViewEntity_SetLerpInTime( sequence.blendTime )
+ player.PlayerCone_SetLerpTime( sequence.blendTime )
+ }
+ }
+
+ if ( sequence.thirdPersonCameraAttachments.len() == 0 )
+ {
+ if ( sequence.firstPersonBlendOutTime >= 0.0 )
+ {
+ player.AnimViewEntity_SetLerpOutTime( sequence.firstPersonBlendOutTime )
+ }
+ else
+ {
+ player.AnimViewEntity_SetLerpOutTime( 0.4 )
+ }
+ }
+
+ if ( !doFirstPersonAnim || !sequence.playerPushable )
+ {
+ player.SnapFeetToEyes()
+ }
+ }
+
+ if ( ent && !sequence.noParent )
+ {
+ local optionalTag
+ if ( sequence.attachment != "" )
+ {
+ optionalTag = sequence.attachment
+ }
+ else
+ {
+ optionalTag = ""
+ }
+
+ if ( player.GetParent() != ent )
+ {
+ // you could be parenting from one tag to another but we don't do
+ // that anywhere currently, and if we want to do it we can do some
+ // special stuff
+ player.SetParent( ent, optionalTag, false, sequence.blendTime )
+ }
+ }
+
+ if ( doFirstPersonAnim )
+ {
+ if ( sequence.teleport )
+ {
+ firstPersonProxy.SnapToAbsOrigin( player.GetOrigin() )
+ }
+
+ if ( sequence.playerPushable )
+ {
+ firstPersonProxy.SetParent( player, "", false )
+ }
+ else
+ {
+ firstPersonProxy.SetToSameParentAs( player )
+ }
+ }
+
+ if ( sequence.relativeAnim != "" )
+ {
+ if ( sequence.teleport )
+ {
+ thread PlayAnimGravityClientSyncing( ent, sequence.relativeAnim, null, null, 0.0 )
+ }
+ else
+ {
+ thread PlayAnimGravityClientSyncing( ent, sequence.relativeAnim )
+ }
+
+ if ( sequence.setInitialTime != 0.0 )
+ ent.Anim_SetInitialTime( sequence.setInitialTime )
+ }
+
+ if ( doFirstPersonAnim )
+ {
+ if ( ent )
+ {
+ thread PlayAnim( firstPersonProxy, sequence.firstPersonAnim, ent, sequence.attachment, sequence.blendTime )
+ }
+ else if ( sequence.playerPushable )
+ {
+ firstPersonProxy.Anim_Play( sequence.firstPersonAnim )
+ firstPersonProxy.Anim_DisableUpdatePosition()
+ }
+ else if ( sequence.gravity )
+ {
+ thread PlayAnimGravityClientSyncing( firstPersonProxy, sequence.firstPersonAnim, sequence.origin, sequence.angles, sequence.blendTime )
+ }
+ else
+ {
+ thread PlayAnim( firstPersonProxy, sequence.firstPersonAnim, sequence.origin, sequence.angles, sequence.blendTime )
+ }
+
+ // BROKEN - Anim_EnablePlanting() only works on players and NPCs
+ // if ( sequence.enablePlanting )
+ // {
+ // viewmodel.Anim_EnablePlanting()
+ // }
+
+ if ( sequence.setInitialTime != 0.0 )
+ {
+ firstPersonProxy.Anim_SetInitialTime( sequence.setInitialTime )
+ }
+
+ if ( sequence.useAnimatedRefAttachment )
+ {
+ firstPersonProxy.Anim_EnableUseAnimatedRefAttachmentInsteadOfRootMotion()
+ }
+
+ if ( sequence.hideProxy )
+ {
+ firstPersonProxy.HideFirstPersonProxy()
+ }
+ }
+
+ if ( sequence.thirdPersonAnim != "" )
+ {
+ if ( ent )
+ {
+ thread PlayAnim( player, sequence.thirdPersonAnim, ent, sequence.attachment, sequence.blendTime )
+ }
+ else if ( player.IsPlayer() && sequence.playerPushable )
+ {
+ player.Anim_Play( sequence.thirdPersonAnim )
+ player.Anim_DisableUpdatePosition()
+ }
+ else if ( sequence.gravity )
+ {
+ thread PlayAnimGravityClientSyncing( player, sequence.thirdPersonAnim, sequence.origin, sequence.angles, sequence.blendTime )
+ }
+ else
+ {
+ thread PlayAnim( player, sequence.thirdPersonAnim, sequence.origin, sequence.angles, sequence.blendTime )
+ }
+
+ if ( sequence.enablePlanting )
+ player.Anim_EnablePlanting()
+
+ if ( sequence.viewConeFunction != null )
+ {
+ if ( sequence.thirdPersonCameraAttachments.len() == 0 )
+ {
+ sequence.viewConeFunction( player )
+ }
+ }
+
+ if ( sequence.setInitialTime != 0.0 )
+ player.Anim_SetInitialTime( sequence.setInitialTime )
+
+ if ( sequence.useAnimatedRefAttachment )
+ player.Anim_EnableUseAnimatedRefAttachmentInsteadOfRootMotion()
+
+ WaittillAnimDone( player )
+ }
+
+ if ( doFirstPersonAnim && IsValid( firstPersonProxy ) && firstPersonProxy.Anim_IsActive() && !firstPersonProxy.IsSequenceFinished() )
+ {
+ WaittillAnimDone( firstPersonProxy )
+ }
+
+ if ( !IsValid( player ) )
+ return
+
+ if ( player.IsPlayer() )
+ {
+ if ( !IsAlive( player ) )
+ return
+
+ if ( IsDisconnected( player ) )
+ return
+ }
+ else
+ if ( player.IsNPC() )
+ {
+ if ( !IsAlive( player ) )
+ return
+ }
+
+ // time passed
+ if ( soul )
+ {
+ if ( !IsValid( soul ) )
+ return
+
+ ent = soul.GetTitan()
+ if ( !IsAlive( ent ) )
+ return
+ }
+
+ if ( sequence.thirdPersonAnimIdle != "" )
+ {
+ //thread PlayAnim( player, sequence.thirdPersonAnimIdle, ent, sequence.attachment, 0 )
+ if ( ent )
+ {
+ thread PlayAnim( player, sequence.thirdPersonAnimIdle, ent, sequence.attachment, sequence.blendTime )
+ }
+ else if ( player.IsPlayer() && sequence.playerPushable )
+ {
+ player.Anim_Play( sequence.thirdPersonAnimIdle )
+ player.Anim_DisableUpdatePosition()
+ }
+ else
+ {
+ thread PlayAnim( player, sequence.thirdPersonAnimIdle, sequence.origin, sequence.angles, sequence.blendTime )
+ }
+ }
+
+ if ( sequence.firstPersonAnimIdle != "" )
+ {
+ firstPersonProxy = player.GetFirstPersonProxy()
+ firstPersonProxy.ShowFirstPersonProxy()
+
+ if ( IsValid( firstPersonProxy ) && EntHasModelSet( firstPersonProxy ) ) //JFS: Defensive fix for player not having view models sometimes
+ {
+ if ( sequence.renderWithViewModels )
+ firstPersonProxy.RenderWithViewModels( true )
+ else
+ firstPersonProxy.RenderWithViewModels( false )
+
+ SetPlayerAnimViewEntity( player, firstPersonProxy )
+ firstPersonProxy.SetNextThinkNow()
+
+ firstPersonProxy.SetAbsOrigin( player.GetOrigin() )
+ firstPersonProxy.SetAbsAngles( player.GetAngles() )
+
+ firstPersonProxy.Anim_Play( sequence.firstPersonAnimIdle )
+
+ if ( sequence.playerPushable )
+ {
+ firstPersonProxy.SetParent( player, "", false )
+ firstPersonProxy.Anim_DisableUpdatePosition()
+ }
+ else
+ {
+ firstPersonProxy.SetToSameParentAs( player )
+ }
+ }
+ }
+
+ if ( sequence.thirdPersonAnimIdle != "" && sequence.firstPersonAnimIdle != "" )
+ {
+ if ( sequence.viewConeFunction != null )
+ sequence.viewConeFunction( player )
+ }
+}
+
+
+function ClampPlayerViewCone( player )
+{
+ player.EndSignal( "OnDeath" )
+ player.PlayerCone_SetLerpTime( 0.0 )
+} \ No newline at end of file