diff options
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hotdrop.gnut')
-rw-r--r-- | Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hotdrop.gnut | 778 |
1 files changed, 778 insertions, 0 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hotdrop.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hotdrop.gnut new file mode 100644 index 000000000..e3410de8a --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hotdrop.gnut @@ -0,0 +1,778 @@ +untyped + +global function TitanHotdrop_Init + +global function TitanHotDrop +global function PlayersTitanHotdrops +global function NPCTitanHotdrops +global function NPCPrespawnWarpfallSequence +global function WaitTillHotDropComplete +global function OnTitanHotdropImpact +global function PlayHotdropImpactFX +global function TitanTestDropPoint +global function EdgeTraceDropPoint + + +global function GetHotDropImpactTime + +global function ModifyOriginForDrop + +global function NearTitanfallBlocker + +global function DevCheckInTitanfallBlocker + +global function DrawTitanfallBlockers + +global function DropPodFindDropNodes + +global function PlayDeathFromTitanFallSounds + +global const HOTDROP_FP_WARP = $"P_warpjump_FP" +global const HOTDROP_TRAIL_FX = $"hotdrop_hld_warp" +global int BUBBLE_SHIELD_FX_PARTICLE_SYSTEM_INDEX + +function TitanHotdrop_Init() +{ + + RegisterSignal( "titan_impact" ) + RegisterSignal( "TitanHotDropComplete" ) + RegisterSignal( "BubbleShieldStatusUpdate" ) + + PrecacheEffect( HOTDROP_TRAIL_FX ) + PrecacheEffect( HOTDROP_FP_WARP ) + + AddDamageCallbackSourceID( damagedef_titan_fall, TitanFall_DamagedPlayerOrNPC ) + + PrecacheImpactEffectTable( HOTDROP_IMPACT_FX_TABLE ) + + PrecacheModel( $"models/fx/xo_shield.mdl" ) + PrecacheModel( $"models/fx/xo_shield_wall.mdl" ) + BUBBLE_SHIELD_FX_PARTICLE_SYSTEM_INDEX = PrecacheParticleSystem( $"P_shield_hld_01_CP" ) + + BubbleShield_Init() +} + +void function TitanHotDrop( entity titan, string animation, vector origin, vector angles, entity player, entity camera ) +{ + Assert( titan.IsTitan(), titan + " is not a titan" ) + + titan.EndSignal( "OnDeath" ) + + HideName( titan ) + + array<entity> cleanup = [] // ents that will be deleted upon completion + + OnThreadEnd( + function() : ( cleanup, titan, player, camera ) + { + printt( "Post impact,anim is done" ) + if ( IsValid( titan ) ) + { + delete titan.s.hotDropPlayer + titan.e.isHotDropping = false + titan.Signal( "TitanHotDropComplete" ) + if ( !IsFFAGame() ) + titan.Minimap_DisplayDefault( titan.GetTeam(), null ) + } + + if ( IsValid( camera ) ) + camera.ClearParent() + + foreach ( entity ent in cleanup ) + { + if ( IsValid_ThisFrame( ent ) ) + { + // Delay enough seconds to allow titan hot drop smokeTrail FX to play fully + ent.Kill_Deprecated_UseDestroyInstead() + } + } + + if ( IsValid( player ) ) + ScreenFadeFromBlack( player, 0.2, 0.2 ) + } + ) + + titan.s.hotDropPlayer <- player + titan.e.isHotDropping = true + + origin += Vector(0,0,8 ) // work around for currently busted animation + + entity ref = CreateScriptRef() + ref.SetOrigin( origin ) + ref.SetAngles( angles ) + ref.Show() + cleanup.append( ref ) + + // add smoke fx + + TitanHotDrop_Smoke( cleanup, titan, titan.GetBossPlayer() ) + +// "Titan_1P_Warpfall_Hotdrop" - for first person drops while inside the titan dropping into the level +// "Titan_1P_Warpfall_Start" - for first person warp calls, starting right on the button press +// "Titan_1P_Warpfall_WarpToLanding" - for first person from the visual of the titan appearing and falling +// "Titan_3P_Warpfall_Start" - for any 3P other player or NPC when they call in a warp, starting right on their button press +// "Titan_3P_Warpfall_WarpToLanding" - for any 3P other player or NPC from the visual of the titan appearing and falling + int teamNum = TEAM_UNASSIGNED + if ( IsValid( player ) ) + teamNum = player.GetTeam(); + + EmitSoundAtPositionOnlyToPlayer( teamNum, origin, player, "Titan_1P_Warpfall_Hotdrop" ) + EmitSoundAtPositionOnlyToPlayer( teamNum, origin, player, "Titan_1P_Warpfall_Start" ) + EmitSoundAtPositionExceptToPlayer( teamNum, origin, player, "Titan_3P_Warpfall_Start" ) + EmitSoundAtPositionExceptToPlayer( teamNum, origin, player, "Titan_3P_Warpfall_WarpToLanding" ) + + float duration = titan.GetSequenceDuration( animation ) + + Minimap_PingForTeam( titan.GetTeam(), origin, 64.0, duration, TEAM_COLOR_FRIENDLY / 255.0, 4, false ) + if ( !IsFFAGame() ) + titan.Minimap_Hide( titan.GetTeam(), null ) + + titan.NotSolid(); + thread PlayAnimTeleport( titan, animation, ref ) + titan.EndSignal( "OnAnimationDone" ) + + if ( player ) + { + player.PlayerCone_SetMinYaw( -70 ) + player.PlayerCone_SetMaxYaw( 70 ) + player.PlayerCone_SetMinPitch( -90 ) + player.PlayerCone_SetMaxPitch( 90 ) + } + + titan.WaitSignal( "titan_impact" ) + player.ClearHotDropImpactTime() +// wait duration - 1.25 + + titan.Solid(); + + ShowName( titan ) + + vector sourcePosition = origin + sourcePosition.z = sourcePosition.z + 5.0 + + Explosion_DamageDefSimple( + damagedef_titan_hotdrop, + origin, + titan, // attacker + titan, // inflictor + origin ) + + float zoomTime = 2.0 + float rotateTime = 0.5 + + //printt( "Post impact, before anim is done" ) + + if ( IsValid( camera ) ) + { + camera.ClearParent() + + entity mover = CreateExpensiveScriptMover() + mover.SetOrigin( camera.GetOrigin() ) + mover.SetAngles( camera.GetAngles() ) + camera.SetParent( mover ) + + mover.NonPhysicsMoveTo( titan.GetWorldSpaceCenter(), zoomTime, zoomTime * 0.4, zoomTime * 0.4 ) + cleanup.append( mover ) + + wait 0.5 + + ScreenFadeToBlackForever( player, 0.8 ) + + wait 0.6 + + mover.RotateTo( angles, rotateTime, rotateTime*0.2, rotateTime*0.2 ) + } + + WaittillAnimDone( titan ) +} + +entity function TitanHotDrop_Smoke( array<entity> cleanup, entity titan, entity player ) +{ + entity smokeTrail = CreateEntity( "info_particle_system" ) + if ( IsValid( player ) ) + { + smokeTrail.SetOwner( player ) + smokeTrail.kv.VisibilityFlags = ENTITY_VISIBLE_TO_OWNER + } + + smokeTrail.SetValueForEffectNameKey( HOTDROP_TRAIL_FX ) // HOTDROP_FP_WARP + smokeTrail.kv.start_active = 1 + DispatchSpawn( smokeTrail ) + smokeTrail.SetParent( titan, "HATCH_HEAD" ) + cleanup.append( smokeTrail ) + + + smokeTrail = CreateEntity( "info_particle_system" ) + if ( IsValid( player ) ) + { + smokeTrail.SetOwner( player ) + smokeTrail.kv.VisibilityFlags = (ENTITY_VISIBLE_TO_FRIENDLY | ENTITY_VISIBLE_TO_ENEMY) //owner cant see + } + + smokeTrail.SetValueForEffectNameKey( HOTDROP_TRAIL_FX ) // HOTDROP_FP_WARP + smokeTrail.kv.start_active = 1 + DispatchSpawn( smokeTrail ) + smokeTrail.SetParent( titan, "HATCH_HEAD" ) + cleanup.append( smokeTrail ) + + return smokeTrail +} + +void function PlayersTitanHotdrops( entity titan, vector origin, vector angles, entity player, string animation ) +{ + titan.EndSignal( "OnDeath" ) + titan.s.disableAutoTitanConversation <- true // refactor: Should be created on spawn, and always exist -mackey + + OnThreadEnd( + function() : ( titan, player ) + { + if ( !IsValid( titan ) ) + return + + // removed so that model highlight always works for you autotitan +// titan.DisableRenderAlways() + + delete titan.s.hotDropPlayer + titan.e.isHotDropping = false + titan.Signal( "TitanHotDropComplete" ) + DeleteAnimEvent( titan, "titan_impact" ) + DeleteAnimEvent( titan, "second_stage" ) + DeleteAnimEvent( titan, "set_usable" ) + } + ) + + HideName( titan ) + titan.s.hotDropPlayer <- player + titan.e.isHotDropping = true + titan.UnsetUsable() //Stop titan embark before it lands + AddAnimEvent( titan, "titan_impact", OnTitanHotdropImpact ) + AddAnimEvent( titan, "second_stage", OnReplacementTitanSecondStage, origin ) + AddAnimEvent( titan, "set_usable", SetTitanUsableByOwner ) + + string sfxFirstPerson + string sfxThirdPerson + + switch ( animation ) + { + case "at_hotdrop_drop_2knee_turbo_upgraded": + sfxFirstPerson = "Titan_1P_Warpfall_WarpToLanding_fast" + sfxThirdPerson = "Titan_3P_Warpfall_WarpToLanding_fast" + break + + case "bt_hotdrop_skyway": + sfxFirstPerson = "titan_hot_drop_turbo_begin" + sfxThirdPerson = "titan_hot_drop_turbo_begin_3P" + break + + case "at_hotdrop_drop_2knee_turbo": + sfxFirstPerson = "titan_hot_drop_turbo_begin" + sfxThirdPerson = "titan_hot_drop_turbo_begin_3P" + break + + default: + Assert( 0, "Unknown anim " + animation ) + } + + float impactTime = GetHotDropImpactTime( titan, animation ) + Attachment result = titan.Anim_GetAttachmentAtTime( animation, "OFFSET", impactTime ) + vector maxs = titan.GetBoundingMaxs() + vector mins = titan.GetBoundingMins() + int mask = titan.GetPhysicsSolidMask() + origin = ModifyOriginForDrop( origin, mins, maxs, result.position, mask ) + + titan.SetInvulnerable() //Make Titan invulnerable until bubble shield is up. Cleared in OnTitanHotdropImpact + + if ( SoulHasPassive( titan.GetTitanSoul(), ePassives.PAS_BUBBLESHIELD ) ) + { + delaythread( impactTime ) CreateBubbleShield( titan, origin, angles ) + } + else if ( SoulHasPassive( titan.GetTitanSoul(), ePassives.PAS_WARPFALL ) ) + { + angles = AnglesCompose( angles, Vector( 0.0, 180.0, 0.0) ) + } + + //DrawArrow( origin, angles, 10, 150 ) + // HACK: not really a hack, but this could be optimized to only render always for a given client + titan.EnableRenderAlways() + + int teamNum = TEAM_UNASSIGNED + if ( IsValid( player ) ) + teamNum = player.GetTeam() + + EmitDifferentSoundsAtPositionForPlayerAndWorld( sfxFirstPerson, sfxThirdPerson, origin, player, teamNum ) + + SetStanceKneel( titan.GetTitanSoul() ) + + waitthread PlayAnimTeleport( titan, animation, origin, angles ) + + TitanCanStand( titan ) + if ( !titan.GetCanStand() ) + { + titan.SetOrigin( origin ) + titan.SetAngles( angles ) + } + + titan.ClearInvulnerable() //Make Titan vulnerable again once he's landed + + if ( !Flag( "DisableTitanKneelingEmbark" ) ) + { + if ( IsValid( GetEmbarkPlayer( titan ) ) ) + { + titan.SetTouchTriggers( true ) //Hack, potential fix for triggers bug. See bug 212751 + //A player is trying to get in before the hotdrop animation has finished + //Wait until the embark animation has finished + WaittillAnimDone( titan ) + return + } + + titan.s.standQueued = false // SetStanceKneel should set this + SetStanceKneel( titan.GetTitanSoul() ) + thread PlayAnim( titan, "at_MP_embark_idle_blended" ) + } +} + +float function GetHotDropImpactTime( entity titan, string animation ) +{ + float impactTime = titan.GetScriptedAnimEventCycleFrac( animation, "titan_impact" ) + if ( impactTime < 0.0 ) + impactTime = titan.GetScriptedAnimEventCycleFrac( animation, "signal:titan_impact" ) + + Assert( impactTime > -1.0, "No event titan_impact in " + animation ) + + float duration = titan.GetSequenceDuration( animation ) + + impactTime *= duration + + return impactTime +} + +function NPCTitanHotdrops( entity titan, bool standImmediately, string titanfallAnim = "at_hotdrop_drop_2knee_turbo" ) +{ + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + + titan.e.isHotDropping = true + titan.s.bubbleShieldStatus <- 0 + + titan.SetEfficientMode( true ) + titan.SetTouchTriggers( false ) + titan.SetAimAssistAllowed( false ) + + float impactTime = GetHotDropImpactTime( titan, titanfallAnim ) + vector origin = titan.GetOrigin() + vector angles = titan.GetAngles() + + #if GRUNTCHATTER_ENABLED + GruntChatter_TryIncomingSpawn( titan, origin ) + #endif + + #if MP + TryAnnounceTitanfallWarningToEnemyTeam( titan.GetTeam(), origin ) + #endif + + if ( NPCShouldDoBubbleShieldAfterHotdrop( titan ) ) + { + titan.SetNoTarget( true ) + thread CreateGenericBubbleShield_Delayed( titan, origin, angles, impactTime - 0.1 ) + } + + waitthread PlayersTitanHotdrops( titan, origin, angles, null, titanfallAnim ) + + if ( standImmediately ) + { + SetStanceStand( titan.GetTitanSoul() ) + waitthread PlayAnimGravity( titan, "at_hotdrop_quickstand" ) + } + + titan.SetEfficientMode( false ) + titan.SetTouchTriggers( true ) + titan.SetAimAssistAllowed( true ) + + titan.e.isHotDropping = false + titan.Signal( "TitanHotDropComplete" ) + + titan.SetNoTarget( false ) + + while( titan.s.bubbleShieldStatus == 1 ) + titan.WaitSignal( "BubbleShieldStatusUpdate" ) +} + +void function NPCPrespawnWarpfallSequence( string aiSettings, vector spawnOrigin, vector spawnAngle ) +{ + string animation = "at_hotdrop_drop_2knee_turbo_upgraded" +// string settings = GetTitanForPlayer( player ).titanSetFile + string playerSettings = expect string( Dev_GetAISettingByKeyField_Global( aiSettings, "npc_titan_player_settings" ) ) + asset model = GetPlayerSettingsAssetForClassName( playerSettings, "bodymodel" ) + Attachment warpAttach = GetAttachmentAtTimeFromModel( model, animation, "offset", spawnOrigin, spawnAngle, 0 ) + + entity fakeTitan = CreatePropDynamic( model ) + float impactTime = GetHotDropImpactTime( fakeTitan, animation ) + + #if SP //MP AI already call DisableTitanfallForLifetimeOfEntityNearOrigin() in SpawnNeutralAI()/SpawnTeamAI() functions. Pretty sure can just remove this for SP too + thread TemporarilyDisableTitanfallAroundRadius( spawnOrigin, 72, WARPFALL_SOUND_DELAY + WARPFALL_FX_DELAY ) //TODO: Look into getting rid of this. Doesn't play well with DisableTitanfallForLifetimeOfEntityNearOrigin. Only used in Beacon + #endif + + fakeTitan.Kill_Deprecated_UseDestroyInstead() + + EmitSoundAtPosition( TEAM_UNASSIGNED, spawnOrigin, "Titan_3P_Warpfall_CallIn" ) + + wait WARPFALL_SOUND_DELAY + + // "Titan_1P_Warpfall_Start" - for first person warp calls, starting right on the button press + // "Titan_3P_Warpfall_Start" - for any 3P other player or NPC when they call in a warp, starting right on their button press + EmitSoundAtPosition( TEAM_UNASSIGNED, spawnOrigin, "Titan_3P_Warpfall_Start" ) + + PlayFX( TURBO_WARP_FX, warpAttach.position + Vector(0,0,-104), warpAttach.angle ) + + wait WARPFALL_FX_DELAY +} + +void function WaitTillHotDropComplete( entity titan ) +{ + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + + // waits for him to drop in from the sky AND stand up + if ( titan.e.isHotDropping ) + WaitSignal( titan, "TitanHotDropComplete" ) +} + +function CreateGenericBubbleShield_Delayed( entity titan, vector origin, vector angles, float delay = 0.0 ) +{ + titan.EndSignal( "OnDestroy" ) + + if ( delay > 0 ) + wait delay + + titan.s.bubbleShieldStatus = 1 + CreateGenericBubbleShield( titan, origin, angles ) + titan.s.bubbleShieldStatus = 0 + titan.Signal( "BubbleShieldStatusUpdate" ) +} + + +vector function ModifyOriginForDrop( vector origin, vector mins, vector maxs, vector resultPos, int mask ) +{ + TraceResults trace = TraceHull( resultPos + Vector(0,0,20), resultPos + Vector(0,0,-20), mins, maxs, null, mask, TRACE_COLLISION_GROUP_NONE ) + float zDif = trace.endPos.z - resultPos.z + origin.z += zDif + origin.z += 3.0 + + return origin +} + +void function OnReplacementTitanSecondStage( entity titan ) +{ + vector origin = expect vector( GetOptionalAnimEventVar( titan, "second_stage" ) ) + + string sfxFirstPerson = "titan_drop_pod_turbo_landing" + string sfxThirdPerson = "titan_drop_pod_turbo_landing_3P" + entity player = titan.GetBossPlayer() + EmitDifferentSoundsAtPositionForPlayerAndWorld( sfxFirstPerson, sfxThirdPerson, origin, player, titan.GetTeam() ) +} + +void function OnTitanHotdropImpact( entity titan ) +{ + ShowName( titan ) + PlayHotdropImpactFX( titan ) + titan.Signal( "ClearDisableTitanfall" ) +} + +function SetTitanUsable( titan ) +{ + titan.SetUsableByGroup( "friendlies pilot" ) +} + +void function SetTitanUsableByOwner( entity titan ) +{ + titan.SetUsableByGroup( "owner pilot" ) +} + +function PlayHotdropImpactFX( titan ) +{ + expect entity( titan ) + if ( !IsAlive( titan ) || !titan.IsTitan() ) + return + + local origin = titan.GetOrigin() + + Explosion_DamageDefSimple( + damagedef_titan_fall, + origin, + titan, // attacker + titan, // inflictor + origin ) + + + CreateShake( titan.GetOrigin(), 16, 150, 2, 1500 ) + // No Damage - Only Force + // Push players + // Push radially - not as a sphere + // Test LOS before pushing + int flags = 15 + vector impactOrigin = titan.GetOrigin() + Vector( 0,0,10 ) + float impactRadius = 512 + CreatePhysExplosion( impactOrigin, impactRadius, PHYS_EXPLOSION_LARGE, flags ) +} + +function NearTitanfallBlocker( baseOrigin ) +{ + foreach ( hardpoint in level.testHardPoints ) + { + local hpOrigin = hardpoint.GetOrigin() + hpOrigin.z -= 100 // why are hardpoints not really at the origin? + if ( Distance( hpOrigin, baseOrigin ) < SAFE_TITANFALL_DISTANCE ) + return true + } + + foreach ( flagSpawnPoint in level.testFlagSpawnPoints ) + { + local fspOrigin = flagSpawnPoint.GetOrigin() + if ( Distance( fspOrigin, baseOrigin ) < SAFE_TITANFALL_DISTANCE_CTF ) + return true + } + + foreach ( blocker in level.titanfallBlockers ) + { + if ( Distance2D( baseOrigin, blocker.origin ) > blocker.radius ) + continue + + if ( baseOrigin.z < blocker.origin.z ) + continue + + if ( baseOrigin.z > blocker.maxHeight ) + continue + + return true + } + + return false +} + +function DevCheckInTitanfallBlocker() +{ + if ( "toggleBlocker" in svGlobal.levelEnt.s ) + { + svGlobal.levelEnt.s.toggleBlocker.Kill_Deprecated_UseDestroyInstead() + delete svGlobal.levelEnt.s.toggleBlocker + return + } + + svGlobal.levelEnt.s.toggleBlocker <- CreateScriptRef() + svGlobal.levelEnt.s.toggleBlocker.EndSignal( "OnDestroy" ) + + entity player = GetPlayerArray()[0] + for ( ;; ) + { + printt( "Inside Titanfall blocker: " + NearTitanfallBlocker( player.GetOrigin() ) ) + DrawTitanfallBlockers() + wait 0.5 + } +} + +function DrawTitanfallBlockers() +{ + foreach ( hardpoint in level.testHardPoints ) + { + vector hpOrigin = expect entity( hardpoint ).GetOrigin() + DebugDrawCircle( hpOrigin, Vector(0,0,0), SAFE_TITANFALL_DISTANCE, 255, 255, 0, true, 1.0 ) + } + + foreach ( flagSpawnPoint in level.testFlagSpawnPoints ) + { + vector fspOrigin = expect entity( flagSpawnPoint ).GetOrigin() + DebugDrawCircle( fspOrigin, Vector(0,0,0), SAFE_TITANFALL_DISTANCE_CTF, 255, 255, 0, true, 1.0 ) + } + + foreach ( blocker in level.titanfallBlockers ) + { + DebugDrawCircle( expect vector( blocker.origin ), Vector(0,0,0), expect float( blocker.radius ), 255, 255, 0, true, 1.0 ) + vector org = Vector( blocker.origin.x, blocker.origin.y, blocker.maxHeight ) + DebugDrawCircle( org, Vector(0,0,0), expect float( blocker.radius ), 255, 255, 0, true, 1.0 ) + } +} + + + +bool function EdgeTraceDropPoint( vector dropPoint ) +{ + local offsetArray = [ + Vector( 64,64,0 ), + Vector( -64,64,0 ), + Vector( 64,-64,0 ), + Vector( -64,-64,0 ), + ] + local maxDif = 48 + local mask = TRACE_MASK_TITANSOLID | TRACE_MASK_PLAYERSOLID | TRACE_MASK_SOLID | TRACE_MASK_NPCSOLID + local totalDif = 0 + + foreach ( offset in offsetArray ) + { + local startPos = dropPoint + Vector( 0, 0, 64 ) + offset + local endPos = dropPoint + Vector( 0, 0, -64 ) + offset + TraceResults result = TraceLine( startPos, endPos, null, mask, TRACE_COLLISION_GROUP_NONE ) + local dif = fabs( result.endPos.z - dropPoint.z ) + totalDif += dif + + if ( dif > maxDif ) + { + //DebugDrawLine( startPos, result.endPos, 200, 50, 50, true, 3 ) + return false + } + //DebugDrawLine( startPos, result.endPos, 50, 50, 200, true, 3 ) + } + + if ( totalDif > ( maxDif * 2 ) ) + { + // this should catch cases where a small item like a box or barrel stops the hull collision trace above the ground. + return false + } + + return true +} + + +bool function DropPodFindDropNodes( FlightPath flightPath, vector origin, float yaw ) +{ + if ( NearTitanfallBlocker( origin ) ) + return false + + //level.drawAnalysisPreview = true + if ( !TitanTestDropPoint( origin, flightPath ) ) + return false + + return EdgeTraceDropPoint( origin ) +} + +bool function TitanTestDropPoint( vector start, FlightPath flightPath ) +{ + local draw = level.drawAnalysisPreview + local end = start + Vector(0,0,8000) + + TraceResults result = TraceHull( start, end, flightPath.mins, flightPath.maxs, null, flightPath.traceMask, TRACE_COLLISION_GROUP_NONE ) + if ( result.startSolid ) + { + if ( draw ) + { + DrawArrow( start, Vector(0,0,0), 5.0, 80 ) + DebugDrawLine( start, result.endPos, 0, 255, 0, true, 5.0 ) + DebugDrawLine( result.endPos, end, 255, 0, 0, true, 5.0 ) + //local newstart = start + Vector(0,0,150) + //local reresult = TraceHull( newstart, start, flightPath.mins, flightPath.maxs, null, flightPath.traceMask, TRACE_COLLISION_GROUP_NONE ) + //printt( "surface " + reresult.surfaceName ) + //DebugDrawLine( newstart, reresult.endPos, 155, 0, 0, true, ANALYSIS_PREVIEW_TIME ) + //DrawArrow( reresult.endPos, Vector(0,0,0), ANALYSIS_PREVIEW_TIME, 15 ) + // +// //DrawArrow( start, Vector(0,0,0), ANALYSIS_PREVIEW_TIME, 15 ) + //DebugDrawLine( start, result.endPos, 255, 0, 0, true, ANALYSIS_PREVIEW_TIME ) + //printt( "length " + Length( start - result.endPos ) ) + } + return false + } + + if ( result.fraction < 1 ) + { + if ( result.hitSky ) + { + if ( draw ) + { + DebugDrawLine( start, end, 0, 0, 255, true, ANALYSIS_PREVIEW_TIME ) + //DrawArrow( start, Vector(0,0,0), 1.0, 100 ) + } + return true + } + +// if ( draw ) +// DebugDrawLine( orgs[i-1] + Vector(10,10,10), orgs[i]+ Vector(10,10,10), 255, 255, 0, true, ANALYSIS_PREVIEW_TIME ) + + // some fudge factor + if ( Distance( result.endPos, end ) > 16 ) + { + if ( draw ) + { + local offset = Vector(-0.1, -0.1, 0 ) + DebugDrawLine( start + offset, result.endPos + offset, 0, 255, 0, true, ANALYSIS_PREVIEW_TIME ) + DebugDrawLine( result.endPos + offset, end + offset, 255, 0, 0, true, ANALYSIS_PREVIEW_TIME ) + //DebugDrawLine( start, end, 255, 0, 0, true, ANALYSIS_PREVIEW_TIME ) + } + return false + } + } + +// DebugDrawLine( orgs[i-1], orgs[i], 0, 255, 0, true, ANALYSIS_PREVIEW_TIME ) + + if ( draw ) + DebugDrawLine( start, end, 0, 255, 0, true, 0.2 ) + return true +} + + + + + +void function TitanFall_DamagedPlayerOrNPC( entity ent, var damageInfo ) +{ + if ( !ent.IsPlayer() ) + return + + if ( !ent.IsTitan() ) + return + + vector damageOrigin = DamageInfo_GetDamagePosition( damageInfo ) + vector entityOrigin = ent.GetOrigin() + local distance = Distance( entityOrigin, damageOrigin ) + + // on top of them, let the titans fall where they may + if ( distance < TITANFALL_INNER_RADIUS ) + return + + if ( IsTitanWithinBubbleShield( ent ) ) + { + DamageInfo_SetDamage( damageInfo, 0 ) + return + } + + vector pushVector = Normalize( entityOrigin - damageOrigin ) + + vector traceEndOrigin = damageOrigin + (pushVector * TITANFALL_OUTER_RADIUS) + TraceResults traceResult = TraceHull( damageOrigin, traceEndOrigin, ent.GetBoundingMins(), ent.GetBoundingMins(), ent, TRACE_MASK_NPCSOLID_BRUSHONLY, TRACE_COLLISION_GROUP_NONE ) + + // no room to push them + if ( traceResult.fraction < 0.85 ) + return + + DamageInfo_ScaleDamage( damageInfo, 0.15 ) + + ent.SetVelocity( pushVector * 400 ) + ent.SetStaggering() +} + +function PlayDeathFromTitanFallSounds( player ) +{ + if ( player.IsTitan() ) + { + //printt( "Playing titanfall_on_titan at: "+ player.GetOrigin() ) + EmitSoundAtPosition( TEAM_UNASSIGNED, player.GetOrigin(), "titanfall_on_titan" ) + } + else + { + //printt( "Playing titanfall_on_human at " + player.GetOrigin() ) + EmitSoundAtPosition( TEAM_UNASSIGNED, player.GetOrigin(), "titanfall_on_human" ) + } +} + +bool function NPCShouldDoBubbleShieldAfterHotdrop( entity titan ) +{ + if ( titan.HasKey( "script_hotdrop" ) ) + { + switch ( titan.kv.script_hotdrop ) + { + case "4": + case "3": + printt( "DROP WITH NO BUBBLE" ) + return false + } + } + + return true +}
\ No newline at end of file |