diff options
Diffstat (limited to 'Northstar.CustomServers/scripts/vscripts/ai/_ai_nuke_titans.gnut')
-rw-r--r-- | Northstar.CustomServers/scripts/vscripts/ai/_ai_nuke_titans.gnut | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_nuke_titans.gnut b/Northstar.CustomServers/scripts/vscripts/ai/_ai_nuke_titans.gnut new file mode 100644 index 000000000..0d4b43c92 --- /dev/null +++ b/Northstar.CustomServers/scripts/vscripts/ai/_ai_nuke_titans.gnut @@ -0,0 +1,129 @@ +untyped + +global function NukeTitanThink + +global function AutoTitan_SelfDestruct + +const NUKE_TITAN_PLAYER_DETECT_RANGE = 500 +const NUKE_TITAN_RANGE_CHECK_SLEEP_SECS = 1.0 + +void function AutoTitan_SelfDestruct( entity titan ) +{ + if ( titan.ContextAction_IsBusy() ) + titan.ContextAction_ClearBusy() + + thread TitanEjectPlayer( titan ) +} + +void function NukeTitanThink( entity titan, entity generator ) +{ + //Function assumes that given Titan is spawned as npc_titan_ogre_meteor_nuke. Changing the Titan's AISettings post-spawn + //disrupts the Titan's titanfall animations and can result in the Titan landing outside the level. + NPC_SetNuclearPayload( titan ) + AddEntityCallback_OnPostDamaged( titan, AutoTitan_NuclearPayload_PostDamageCallback ) + + WaitTillHotDropComplete( titan ) + + thread NukeTitanSeekOutGenerator( titan, generator ) +} + + +void function NukeTitanSeekOutGenerator( entity titan, entity generator ) +{ + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + titan.EndSignal( "Doomed" ) + + WaitSignal( titan, "FD_ReachedHarvester", "OnFailedToPath" ) + + float goalRadius = 100 + float checkRadiusSqr = 400 * 400 + + //array<vector> pos = NavMesh_RandomPositions( generator.GetOrigin(), HULL_TITAN, 5, 250, 350 ) + array<vector> pos = NavMesh_GetNeighborPositions( generator.GetOrigin(), HULL_TITAN, 5 ) + pos = ArrayClosestVector( pos, titan.GetOrigin() ) + + array<vector> validPos + foreach ( point in pos ) + { + if ( DistanceSqr( generator.GetOrigin(), point ) <= checkRadiusSqr && NavMesh_IsPosReachableForAI( titan, point ) ) + { + validPos.append( point ) + //DebugDrawSphere( point, 32, 255, 0, 0, true, 60 ) + } + } + + int posLen = validPos.len() + while( posLen >= 1 ) + { + titan.SetEnemy( generator ) + thread AssaultOrigin( titan, validPos[0], goalRadius ) + titan.AssaultSetFightRadius( goalRadius ) + + wait 0.5 + + if ( DistanceSqr( titan.GetOrigin(), generator.GetOrigin() ) > checkRadiusSqr ) + continue + + break + } + + thread AutoTitan_SelfDestruct( titan ) +} + +// intercept damage to nuke titans in damage callback so we can nuke them before death 100% of the time +void function AutoTitan_NuclearPayload_PostDamageCallback( entity titan, var damageInfo ) +{ + if ( !IsAlive( titan ) ) + return + + entity titanOwner = titan.GetBossPlayer() + if ( IsValid( titanOwner ) ) + { + Assert( titanOwner.IsPlayer() ) + Assert( GetPlayerTitanInMap( titanOwner ) == titan ) + return + } + + int nuclearPayload = NPC_GetNuclearPayload( titan ) + if ( nuclearPayload == 0 ) + return + + if ( !GetDoomedState( titan ) ) + return + + if ( titan.GetTitanSoul().IsEjecting() ) + return + + // Nuke eject as soon as the titan enters doom state. + if ( !( "doomedStateNukeTriggerHealth" in titan.s ) ) + { + titan.s.doomedStateNukeTriggerHealth <- titan.GetMaxHealth() + } + + if ( titan.GetHealth() > titan.s.doomedStateNukeTriggerHealth ) + { + //printt( "titan health:", titan.GetHealth(), "health to nuke:", titan.s.doomedStateNukeTriggerHealth ) + return + } + + printt( "NUKE TITAN DOOMED TRIGGER HEALTH REACHED, NUKING! Health:", titan.s.doomedStateNukeTriggerHealth ) + + thread AutoTitan_SelfDestruct( titan ) +} + +function AutoTitan_CanDoRangeCheck( autoTitan ) +{ + if ( !( "nextPlayerTitanRangeCheckTime" in autoTitan.s ) ) + autoTitan.s.nextPlayerTitanRangeCheckTime <- -1 + + if ( Time() < autoTitan.s.nextPlayerTitanRangeCheckTime ) + { + return false + } + else + { + autoTitan.s.nextPlayerTitanRangeCheckTime = Time() + NUKE_TITAN_RANGE_CHECK_SLEEP_SECS + return true + } +} |