aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/mod
diff options
context:
space:
mode:
authorx3Karma <juliuslimck@gmail.com>2022-05-30 19:35:46 +0800
committerGitHub <noreply@github.com>2022-05-30 13:35:46 +0200
commit9103a2061ae36e8f8759b21576657c42a19cbc9b (patch)
treeed354a8cb940e3f1ea07c5aab0a7c30aafe2e271 /Northstar.CustomServers/mod
parent25bca6ab1b2610eb022b59704dcb5c1ecce90891 (diff)
downloadNorthstarMods-9103a2061ae36e8f8759b21576657c42a19cbc9b.tar.gz
NorthstarMods-9103a2061ae36e8f8759b21576657c42a19cbc9b.zip
[FD] Sniper Titans Changes (#373)
* Sniper Titans behavior update * RegisterSignal for Sniper Titans * End threads if Harvester is destroyed
Diffstat (limited to 'Northstar.CustomServers/mod')
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut161
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut1
2 files changed, 152 insertions, 10 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut
index f91699b4..1f27ff82 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut
@@ -3,15 +3,21 @@ untyped
global function MoveToSniperPosition
global function SniperTitanThink
-const float SNIPER_TITAN_POSITION_SEARCH_RANGE = 2048
+const float SNIPER_TITAN_POSITION_SEARCH_RANGE = 4120
+
+struct
+{
+ entity harvester
+} file
void function MoveToSniperPosition( entity titan, vector origin, entity target )
{
titan.EndSignal( "OnSyncedMeleeVictim" )
titan.EndSignal( "OnDeath" )
titan.EndSignal( "OnDestroy" )
+ file.harvester.EndSignal( "OnDeath" )
+ file.harvester.EndSignal( "OnDestroy" )
- titan.SetLookDistOverride( 320 )
titan.EnableNPCMoveFlag( NPCMF_PREFER_SPRINT )
float goalRadius = titan.GetMinGoalRadius()
@@ -23,7 +29,6 @@ void function MoveToSniperPosition( entity titan, vector origin, entity target )
return
local classname = titan.GetClassName()
- titan.DisableLookDistOverride()
titan.DisableNPCMoveFlag( NPCMF_PREFER_SPRINT )
}
)
@@ -38,21 +43,24 @@ void function MoveToSniperPosition( entity titan, vector origin, entity target )
printt( "Sniper titan moving toward his goal", dist, tries++ )
titan.AssaultPoint( origin )
titan.AssaultSetGoalRadius( goalRadius )
- titan.SetEnemy( target )
+ titan.AssaultSetFightRadius( 0 )
local result = WaitSignal( titan, "OnFinishedAssault", "OnEnterGoalRadius" )
+ printt( "Sniper titan done moving into position")
}
}
-void function SniperTitanThink( entity titan, entity generator )
+void function SniperTitanThink( entity titan, entity generator)
{
titan.EndSignal( "OnSyncedMeleeVictim" )
titan.EndSignal( "OnDeath" )
titan.EndSignal( "OnDestroy" )
+ file.harvester.EndSignal( "OnDeath" )
+ file.harvester.EndSignal( "OnDestroy" )
entity soul = titan.GetTitanSoul()
soul.EndSignal( "OnDestroy" )
- // titan.SetScriptName( "sniper_titan" )
+ titan.SetScriptName( "sniper_titan" )
WaitTillHotDropComplete( titan )
@@ -72,17 +80,150 @@ void function SniperTitanThink( entity titan, entity generator )
OnThreadEnd(
function() : ( sniperPosition )
{
- // release mortar position when dead
+ // release sniper position when dead
ReleaseStationaryAIPosition( sniperPosition )
}
)
-
+ file.harvester = generator
+ titan.SetEnemyChangeCallback( EnemyChanged )
+ thread CheckEnemy( titan )
while( true )
{
+ WaitFrame()
vector origin = sniperPosition.origin
- titan.SetEnemy( generator )
waitthread MoveToSniperPosition( titan, origin, generator )
- WaitForever()
+ thread SniperTitanAttack( titan, generator )
+
+ waitthread WaitForInterruption( titan )
+ }
+}
+// check if titan can see enemy
+void function CheckEnemy(entity titan)
+{
+ titan.EndSignal( "OnSyncedMeleeVictim" )
+ titan.EndSignal( "OnDeath" )
+ titan.EndSignal( "OnDestroy" )
+ file.harvester.EndSignal( "OnDeath" )
+ file.harvester.EndSignal( "OnDestroy" )
+
+ while (IsValid(titan))
+ {
+ wait 1
+ if (!IsValid(titan.GetEnemy()))
+ continue
+
+ if (!titan.CanSee(titan.GetEnemy()) && titan.GetEnemy() == file.harvester)
+ {
+ waitthread CreateSniperTarget( titan )
+ wait 1 // wait for 1 second so the signal doesn't get called too soon
+ table result = WaitSignal( titan, "SniperSwitchedEnemy" )
+ }
+ }
+}
+
+void function CreateSniperTarget(entity titan)
+{
+ titan.EndSignal( "OnSyncedMeleeVictim" )
+ titan.EndSignal( "OnDeath" )
+ titan.EndSignal( "OnDestroy" )
+ file.harvester.EndSignal( "OnDeath" )
+ file.harvester.EndSignal( "OnDestroy" )
+
+ vector origin = titan.EyePosition()
+ TraceResults result = TraceLine( origin, file.harvester.GetOrigin() + <0, 0, 250>, titan , TRACE_MASK_BLOCKLOS, TRACE_COLLISION_GROUP_NONE )
+ // check if the endPos is too near the titan
+ while (Distance(result.endPos, origin) < 200 || Distance(result.endPos, file.harvester.GetOrigin()) < 200)
+ {
+ wait 2.0
+ origin = titan.EyePosition()
+ result = TraceLine( origin, file.harvester.GetOrigin() + <0, 0, 250>, titan )
}
+ entity snipertarget = CreateEntity( "info_target" )
+ DispatchSpawn( snipertarget )
+ snipertarget.SetOrigin( result.endPos ) // in front of the harvester i hope
+ SetTeam( snipertarget, TEAM_MILITIA )
+ snipertarget.EnableAttackableByAI( 40, 0, AI_AP_FLAG_NONE )
+ titan.SetEnemy( snipertarget )
+ wait 1 // wait for 1 second so the signal doesn't get called too soon
+ titan.WaitSignal( "SniperSwitchedEnemy" )
+
+ OnThreadEnd(
+ function() : ( snipertarget )
+ {
+ if ( !IsValid( snipertarget ) )
+ return
+
+ snipertarget.Destroy()
+ }
+ )
+}
+
+void function EnemyChanged( entity titan )
+{
+ titan.Signal( "SniperSwitchedEnemy" )
+ entity enemy = titan.GetEnemy()
+ if ( !IsValid( enemy ) ) // if you have no enemy, focus on attacking the harvester
+ {
+ thread SniperTitanAttack( titan, file.harvester )
+ enemy = file.harvester
+ }
+}
+
+function SniperTitanAttack( entity titan, entity target )
+{
+ titan.EndSignal( "OnSyncedMeleeVictim" )
+ titan.EndSignal( "OnDeath" )
+ titan.EndSignal( "OnDestroy" )
+
+ OnThreadEnd(
+ function() : ( titan )
+ {
+ if ( !IsValid( titan ) )
+ return
+ }
+ )
+ titan.SetEnemy( target )
+}
+
+void function WaitForInterruption( entity titan )
+{
+ Assert( IsNewThread(), "Must be threaded off" )
+
+ titan.EndSignal( "OnSyncedMeleeVictim" )
+ titan.EndSignal( "OnDeath" )
+ titan.EndSignal( "OnDestroy" )
+ file.harvester.EndSignal( "OnDeath" )
+ file.harvester.EndSignal( "OnDestroy" )
+
+ entity soul = titan.GetTitanSoul()
+ soul.EndSignal( "OnDestroy" )
+
+ float playerProximityDistSqr = pow( 256, 2 )
+ float healthBreakOff = ( titan.GetHealth() + soul.GetShieldHealth() ) * 0.9
+
+ while( true )
+ {
+ if ( IsEnemyWithinDist( titan, playerProximityDistSqr ) )
+ break
+ if ( ( titan.GetHealth() + soul.GetShieldHealth() ) < healthBreakOff )
+ break
+ wait 1
+ }
+
+ titan.ClearEnemy()
+}
+
+bool function IsEnemyWithinDist( entity titan, float dist )
+{
+ vector origin = titan.GetOrigin()
+ array<entity> players = GetPlayerArrayOfEnemies_Alive( titan.GetTeam() )
+
+ foreach( player in players )
+ {
+ if ( DistanceSqr( player.GetOrigin(), origin ) < dist )
+ return true
+ }
+
+ return false
}
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut
index f26cdf6e..7bc180ed 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut
@@ -49,6 +49,7 @@ void function GamemodeFD_Init()
PrecacheModel( MODEL_ATTRITION_BANK )
PrecacheParticleSystem($"P_smokescreen_FD")
+ RegisterSignal( "SniperSwitchedEnemy" ) // for use in SniperTitanThink behavior.
RegisterSignal("FD_ReachedHarvester")
RegisterSignal("OnFailedToPath")