diff options
author | RoyalBlue1 <malte.hoermeyer@web.de> | 2022-05-30 05:01:33 +0200 |
---|---|---|
committer | RoyalBlue1 <malte.hoermeyer@web.de> | 2022-05-30 05:01:33 +0200 |
commit | c4a807ce87c9be6f6a453d1e8deb4876630531bf (patch) | |
tree | 4e9d6a864f5cd90b2f41f4d8b989c218f16c59b6 /Northstar.CustomServers/mod/scripts/vscripts/gamemodes | |
parent | 217f476f7aeeb0bb4a18a534075a979d8e95115b (diff) | |
download | NorthstarMods-c4a807ce87c9be6f6a453d1e8deb4876630531bf.tar.gz NorthstarMods-c4a807ce87c9be6f6a453d1e8deb4876630531bf.zip |
Split FD into multiple files
-added dummy wave creation function for all "vanilla" FD maps
-reworked event handling to support multiple event threads
-tracking more variables for end medals
-added debugging function to stationary firing positions
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/gamemodes')
3 files changed, 939 insertions, 739 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut index 7ace0591..f26cdf6e 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut @@ -1,79 +1,34 @@ global function GamemodeFD_Init global function RateSpawnpoints_FD global function startHarvester -global function createSmokeEvent -global function createArcTitanEvent -global function createWaitForTimeEvent -global function createSuperSpectreEvent -global function createDroppodGruntEvent -global function createNukeTitanEvent -global function createMortarTitanEvent -global function createGenericSpawnEvent -global function createGenericTitanSpawnWithAiSettingsEvent -global function createDroppodStalkerEvent -global function createDroppodSpectreMortarEvent -global function createWaitUntilAliveEvent -global function createCloakDroneEvent -global function CreateTickEvent -global function CreateToneSniperTitanEvent -global function CreateNorthstarSniperTitanEvent - -global struct SmokeEvent{ - vector position - float lifetime -} - -global struct SpawnEvent{ - vector origin - vector angles - string route //defines route taken by the ai - int skippedRouteNodes //defines how many route nodes will be skipped - int spawnType //Just used for Wave Info but can be used for spawn too should contain aid of spawned enemys - int spawnAmount //Just used for Wave Info but can be used for spawn too should contain amound of spawned enemys - string npcClassName - string aiSettings -} - -global struct WaitEvent{ - float amount -} +global function GetTargetNameForID -global struct SoundEvent{ - string soundEventName -} -global struct WaveEvent{ - void functionref(SmokeEvent,SpawnEvent,WaitEvent,SoundEvent) eventFunction - bool shouldThread - SmokeEvent smokeEvent - SpawnEvent spawnEvent - WaitEvent waitEvent - SoundEvent soundEvent -} struct player_struct_fd{ bool diedThisRound - float scoreThisRound + int scoreThisRound int totalMVPs - int mortarUnitsKilled //not implemented yet + int mortarUnitsKilled int moneySpend int coresUsed float longestTitanLife //not implemented yet int turretsRepaired //not implemented yet int moneyShared float timeNearHarvester //dont know how to track - float longestLife //not implemented yet + float longestLife int heals //dont know what to track - int titanKills //not implemented yet + int titanKills float damageDealt int harvesterHeals + float lastRespawn } global HarvesterStruct& fd_harvester global vector shopPosition -global array<array<WaveEvent> > waveEvents global table<string,array<vector> > routes - +global array<entity> routeNodes +global array<entity> spawnedNPCs @@ -81,12 +36,10 @@ global table<string,array<vector> > routes struct { array<entity> aiSpawnpoints array<entity> smokePoints - array<entity> routeNodes array<float> harvesterDamageSource bool havesterWasDamaged bool harvesterShieldDown float harvesterDamageTaken - array<entity> spawnedNPCs table<entity,player_struct_fd> players entity harvester_info }file @@ -105,26 +58,28 @@ void function GamemodeFD_Init() PlayerEarnMeter_SetEnabled(false) SetShouldUsePickLoadoutScreen( true ) - + //general Callbacks AddCallback_EntitiesDidLoad(LoadEntities) AddCallback_GameStateEnter(eGameState.Prematch,FD_createHarvester) AddCallback_GameStateEnter( eGameState.Playing,startMainGameLoop) - AddCallback_OnClientConnected(GamemodeFD_InitPlayer) - AddCallback_OnPlayerKilled(GamemodeFD_OnPlayerKilled) AddCallback_OnRoundEndCleanup(FD_NPCCleanup) - AddDamageByCallback("player",FD_DamageByPlayerCallback) + AddCallback_OnClientConnected(GamemodeFD_InitPlayer) + //Damage Callbacks + AddDamageByCallback("player",FD_DamageByPlayerCallback) AddDamageCallback( "player", DamageScaleByDifficulty ) AddDamageCallback( "npc_titan", DamageScaleByDifficulty ) AddDamageCallback( "npc_turret_sentry", DamageScaleByDifficulty ) + //Spawn Callbacks AddSpawnCallback( "npc_titan", HealthScaleByDifficulty ) AddSpawnCallback( "npc_super_spectre", HealthScaleByDifficulty ) - - - AddCallback_OnNPCKilled(OnNpcDeath) + AddSpawnCallback( "player", FD_PlayerRespawnCallback ) AddSpawnCallback("npc_turret_sentry", AddTurretSentry ) - SetUsedCoreCallback(FD_UsedCoreCallback) - + //death Callbacks + AddCallback_OnNPCKilled(OnNpcDeath) + AddCallback_OnPlayerKilled(GamemodeFD_OnPlayerKilled) + + //Command Callbacks AddClientCommandCallback("FD_ToggleReady",ClientCommandCallbackToggleReady) AddClientCommandCallback("FD_UseHarvesterShieldBoost",useShieldBoost) @@ -138,6 +93,11 @@ void function FD_BoostPurchaseCallback(entity player,BoostStoreData data) file.players[player].moneySpend += data.cost } +void function FD_PlayerRespawnCallback(entity player) +{ + if(player in file.players) + file.players[player].lastRespawn = Time() +} void function FD_TeamReserveDepositOrWithdrawCallback(entity player, string action,int amount) { @@ -153,6 +113,7 @@ void function FD_TeamReserveDepositOrWithdrawCallback(entity player, string acti } void function GamemodeFD_OnPlayerKilled(entity victim, entity attacker, var damageInfo) { + file.players[victim].longestLife = Time() - file.players[victim].lastRespawn file.players[victim].diedThisRound = true array<entity> militiaplayers = GetPlayerArrayOfTeam( TEAM_MILITIA ) int deaths = 0 @@ -193,12 +154,18 @@ void function GamemodeFD_InitPlayer(entity player) } void function OnNpcDeath( entity victim, entity attacker, var damageInfo ) -{ - int findIndex = file.spawnedNPCs.find( victim ) +{ + if(victim.IsTitan()&&attacker in file.players) + file.players[attacker].titanKills++ + int victimTypeID = FD_GetAITypeID_ByString(victim.GetTargetName()) + if(victimTypeID == eFD_AITypeIDs.TITAN_MORTAR||victimTypeID == eFD_AITypeIDs.SPECTRE_MORTAR) + if(attacker in file.players) + file.players[attacker].mortarUnitsKilled++ + int findIndex = spawnedNPCs.find( victim ) if ( findIndex != -1 ) { - file.spawnedNPCs.remove( findIndex ) - switch(FD_GetAITypeID_ByString(victim.GetTargetName())) //FD_GetAINetIndex_byAITypeID does not support all titan ids + spawnedNPCs.remove( findIndex ) + switch(victimTypeID) //FD_GetAINetIndex_byAITypeID does not support all titan ids { case(eFD_AITypeIDs.TITAN): case(eFD_AITypeIDs.RONIN): @@ -212,7 +179,7 @@ void function OnNpcDeath( entity victim, entity attacker, var damageInfo ) SetGlobalNetInt("FD_AICount_Titan",GetGlobalNetInt("FD_AICount_Titan")-1) break default: - string netIndex = FD_GetAINetIndex_byAITypeID(FD_GetAITypeID_ByString(victim.GetTargetName())) + string netIndex = GetAiNetIdFromTargetName(victim.GetTargetName()) if(netIndex != "") SetGlobalNetInt(netIndex,GetGlobalNetInt(netIndex)-1) } @@ -252,7 +219,7 @@ void function OnNpcDeath( entity victim, entity attacker, var damageInfo ) AddMoneyToPlayer( attacker , money ) attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, playerScore ) // seems to be how combat score is counted - + file.players[attacker].scoreThisRound += playerScore table<int, bool> alreadyAssisted foreach( DamageHistoryStruct attackerInfo in victim.e.recentDamageHistory ) { @@ -315,33 +282,7 @@ void function mainGameLoop() } -array<entity> function getRoute(string routeName) -{ - array<entity> ret - array<entity> currentNode = [] - foreach(entity node in file.routeNodes) - { - if(!node.HasKey("route_name")) - continue - if(node.kv.route_name==routeName) - { - currentNode = [node] - break - } - } - if(currentNode.len()==0) - { - printt("Route not found") - return [] - } - while(currentNode.len()!=0) - { - ret.append(currentNode[0]) - currentNode = currentNode[0].GetLinkEntArray() - } - return ret -} array<int> function getHighestEnemyAmountsForWave(int waveIndex) { @@ -537,18 +478,7 @@ bool function runWave(int waveIndex,bool shouldDoBuyTime) //main wave loop thread SetWaveStateReady() - foreach(WaveEvent event in waveEvents[waveIndex]) - { - - if(event.shouldThread) - thread event.eventFunction(event.smokeEvent,event.spawnEvent,event.waitEvent,event.soundEvent) - else - event.eventFunction(event.smokeEvent,event.spawnEvent,event.waitEvent,event.soundEvent) - if(!IsAlive(fd_harvester.harvester)) - break - - } - waitUntilLessThanAmountAlive_expensive(0) + executeWave() SetGlobalNetInt("FD_waveState",WAVE_STATE_COMPLETE) if(!IsAlive(fd_harvester.harvester)) { @@ -591,7 +521,7 @@ bool function runWave(int waveIndex,bool shouldDoBuyTime) else SetRoundBased(false) SetWinner(TEAM_IMC)//restart round - file.spawnedNPCs = [] // reset npcs count + spawnedNPCs = [] // reset npcs count return false } @@ -611,7 +541,7 @@ bool function runWave(int waveIndex,bool shouldDoBuyTime) AddPlayerScore(player,"FDTeamWave") } wait 1 - float highestScore = 0; + int highestScore = 0; entity highestScore_player = GetPlayerArray()[0] foreach(entity player in GetPlayerArray()) { @@ -631,6 +561,10 @@ bool function runWave(int waveIndex,bool shouldDoBuyTime) foreach(entity player in GetPlayerArray()) if(!file.havesterWasDamaged) AddPlayerScore(player,"FDTeamFlawlessWave") + + + + SetRoundBased(false) SetWinner(TEAM_MILITIA) PlayFactionDialogueToTeam( "fd_matchVictory", TEAM_MILITIA ) @@ -675,7 +609,7 @@ bool function runWave(int waveIndex,bool shouldDoBuyTime) EmitSoundOnEntityOnlyToPlayer(player,player,"HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_1P") } wait 1 - float highestScore = 0; + int highestScore = 0; entity highestScore_player = GetPlayerArray()[0] foreach(entity player in GetPlayerArray()) { @@ -730,6 +664,11 @@ void function SetWaveStateReady(){ SetGlobalNetInt("FD_waveState",WAVE_STATE_IN_PROGRESS) } +void function gameWonMedals(){ + table<string,entity> medals + //most mvps +} + void function OnHarvesterDamaged(entity harvester, var damageInfo) { @@ -971,7 +910,7 @@ void function FD_DamageByPlayerCallback(entity victim,var damageInfo) return float damage = DamageInfo_GetDamage(damageInfo) file.players[player].damageDealt += damage - file.players[player].scoreThisRound += damage //TODO NOT HOW SCORE WORKS + file.players[player].scoreThisRound += damage.tointeger() //TODO NOT HOW SCORE WORKS if(victim.IsTitan()) { //TODO Money and score for titan damage @@ -1133,7 +1072,7 @@ void function LoadEntities() AddStationaryAIPosition(info_target.GetOrigin(),int(info_target.kv.aiType)) break case"info_fd_route_node": - file.routeNodes.append(info_target) + routeNodes.append(info_target) break case"info_fd_smoke_screen": file.smokePoints.append(info_target) @@ -1146,67 +1085,7 @@ void function LoadEntities() initNetVars() } -void function singleNav_thread(entity npc, string routeName,int nodesToScip= 0,float nextDistance = 500.0) -{ - npc.EndSignal( "OnDeath" ) - npc.EndSignal( "OnDestroy" ) - - - - if(!npc.IsNPC()) - return - - - array<entity> routeArray = getRoute(routeName) - WaitFrame()//so other code setting up what happens on signals is run before this - if(routeArray.len()==0) - { - - npc.Signal("OnFailedToPath") - return - } - int scippedNodes = 0 - foreach(entity node in routeArray) - { - if(!IsAlive(fd_harvester.harvester)) - return - if(scippedNodes < nodesToScip) - { - scippedNodes++ - continue - } - npc.AssaultPoint(node.GetOrigin()) - npc.AssaultSetGoalRadius( 100 ) - int i = 0 - table result = npc.WaitSignal("OnFinishedAssault","OnFailedToPath") - if(result.signal == "OnFailedToPath") - break - } - npc.Signal("FD_ReachedHarvester") -} - -void function SquadNav_Thread( array<entity> npcs ,string routeName,int nodesToScip = 0,float nextDistance = 200.0) -{ - //TODO this function wont stop when noone alive anymore also it only works half of the time - - array<entity> routeArray = getRoute(routeName) - WaitFrame()//so other code setting up what happens on signals is run before this - if(routeArray.len()==0) - return - - int nodeIndex = 0 - foreach(entity node in routeArray) - { - if(!IsAlive(fd_harvester.harvester)) - return - if(nodeIndex++ < nodesToScip) - continue - - SquadAssaultOrigin(npcs,node.GetOrigin(),nextDistance) - - } -} bool function allPlayersReady() { @@ -1326,576 +1205,64 @@ string function GetTargetNameForID(int typeId) unreachable } -/****************************************************************************************************************\ -####### # # ####### # # ####### ##### ####### # # ####### ###### # ####### ####### ###### -# # # # ## # # # # # ## # # # # # # # # # # # -# # # # # # # # # # # # # # # # # # # # # # # -##### # # ##### # # # # # #### ##### # # # ##### ###### # # # # # ###### -# # # # # # # # # # # # # # # # # ####### # # # # # -# # # # # ## # # # # # ## # # # # # # # # # # -####### # ####### # # # ##### ####### # # ####### # # # # # ####### # # -\*****************************************************************************************************************/ - -WaveEvent function createSmokeEvent(vector position,float lifetime) -{ - WaveEvent event - event.eventFunction = spawnSmoke - event.shouldThread = true - event.smokeEvent.position = position - event.smokeEvent.lifetime = lifetime - return event -} - -WaveEvent function createArcTitanEvent(vector origin,vector angles,string route) -{ - WaveEvent event - event.eventFunction = spawnArcTitan - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_ARC - event.spawnEvent.spawnAmount = 1 - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - event.spawnEvent.route = route - return event -} - -WaveEvent function createSuperSpectreEvent(vector origin,vector angles,string route) -{ - WaveEvent event - event.eventFunction = spawnSuperSpectre - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.REAPER - event.spawnEvent.spawnAmount = 1 - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - event.spawnEvent.route = route - return event -} - -WaveEvent function createDroppodGruntEvent(vector origin,string route) -{ - WaveEvent event - event.eventFunction = spawnDroppodGrunts - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.GRUNT - event.spawnEvent.spawnAmount = 4 - event.spawnEvent.origin = origin - event.spawnEvent.route = route - return event -} - -WaveEvent function createDroppodStalkerEvent(vector origin,string route) -{ - WaveEvent event - event.eventFunction = spawnDroppodStalker - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.STALKER - event.spawnEvent.spawnAmount = 4 - event.spawnEvent.origin = origin - event.spawnEvent.route = route - return event -} - -WaveEvent function createDroppodSpectreMortarEvent(vector origin,string route) -{ - WaveEvent event - event.eventFunction = spawnDroppodSpectreMortar - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.SPECTRE_MORTAR - event.spawnEvent.spawnAmount = 4 - event.spawnEvent.origin = origin - event.spawnEvent.route = route - return event -} - -WaveEvent function createWaitForTimeEvent(float amount) -{ - WaveEvent event - event.shouldThread = false - event.eventFunction = waitForTime - event.waitEvent.amount = amount - return event -} - -WaveEvent function createWaitUntilAliveEvent(int amount) -{ - WaveEvent event - event.eventFunction = waitUntilLessThanAmountAliveEvent - event.shouldThread = false - event.waitEvent.amount = amount.tofloat() - return event -} - -WaveEvent function createGenericSpawnEvent(string npcClassName,vector origin,vector angles,string route,int spawnType,int spawnAmount) -{ - WaveEvent event - event.eventFunction = spawnGenericNPC - event.shouldThread = true - event.spawnEvent.npcClassName = npcClassName - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - event.spawnEvent.route = route - event.spawnEvent.spawnType = spawnType - event.spawnEvent.spawnAmount = spawnAmount - return event -} - -WaveEvent function createGenericTitanSpawnWithAiSettingsEvent(string npcClassName,string aiSettings,vector origin,vector angles,string route,int spawnType,int spawnAmount) -{ - WaveEvent event - event.eventFunction = spawnGenericNPCTitanwithSettings - event.shouldThread = true - event.spawnEvent.npcClassName = npcClassName - event.spawnEvent.aiSettings = aiSettings - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - event.spawnEvent.route = route - event.spawnEvent.spawnType = spawnType - event.spawnEvent.spawnAmount = spawnAmount - return event -} - -WaveEvent function createNukeTitanEvent(vector origin,vector angles,string route) -{ - WaveEvent event - event.eventFunction = spawnNukeTitan - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_NUKE - event.spawnEvent.spawnAmount = 1 - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - event.spawnEvent.route = route - return event -} - -WaveEvent function createMortarTitanEvent(vector origin,vector angles) -{ - WaveEvent event - event.eventFunction = spawnMortarTitan - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_MORTAR - event.spawnEvent.spawnAmount = 1 - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - return event -} - -WaveEvent function createCloakDroneEvent(vector origin,vector angles){ - WaveEvent event - event.eventFunction = fd_spawnCloakDrone - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.DRONE_CLOAK - event.spawnEvent.spawnAmount = 1 - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - return event -} - -WaveEvent function CreateTickEvent( vector origin, vector angles, int amount = 4, string route = "" ) -{ - WaveEvent event - event.eventFunction = SpawnTick - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.TICK - event.spawnEvent.spawnAmount = amount - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - return event -} - -WaveEvent function CreateNorthstarSniperTitanEvent(vector origin,vector angles) -{ - WaveEvent event - event.eventFunction = spawnSniperTitan - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_SNIPER - event.spawnEvent.spawnAmount = 1 - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - return event -} - -WaveEvent function CreateToneSniperTitanEvent(vector origin,vector angles) -{ - WaveEvent event - event.eventFunction = SpawnToneSniperTitan - event.shouldThread = true - event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_SNIPER - event.spawnEvent.spawnAmount = 1 - event.spawnEvent.origin = origin - event.spawnEvent.angles = angles - return event -} - -/************************************************************************************************************\ -####### # # ####### # # ####### ####### # # # # ##### ####### ### ####### # # ##### -# # # # ## # # # # # ## # # # # # # # ## # # # -# # # # # # # # # # # # # # # # # # # # # # # -##### # # ##### # # # # ##### # # # # # # # # # # # # # ##### -# # # # # # # # # # # # # # # # # # # # # # # -# # # # # ## # # # # # ## # # # # # # # ## # # -####### # ####### # # # # ##### # # ##### # ### ####### # # ##### -\************************************************************************************************************/ - -void function spawnSmoke(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - printt("smoke") - SmokescreenStruct smokescreen - smokescreen.smokescreenFX = $"P_smokescreen_FD" - smokescreen.isElectric = false - smokescreen.origin = smokeEvent.position + < 0 , 0, 150> - smokescreen.angles = <0,0,0> - smokescreen.lifetime = smokeEvent.lifetime - smokescreen.fxXYRadius = 150 - smokescreen.fxZRadius = 120 - smokescreen.fxOffsets = [ <120.0, 0.0, 0.0>,<0.0, 120.0, 0.0>, <0.0, 0.0, 0.0>,<0.0, -120.0, 0.0>,< -120.0, 0.0, 0.0>, <0.0, 100.0, 0.0>] - Smokescreen(smokescreen) - -} - -void function spawnArcTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity npc = CreateArcTitan(TEAM_IMC,spawnEvent.origin,spawnEvent.angles) - npc.DisableNPCFlag(NPC_ALLOW_INVESTIGATE | NPC_USE_SHOOTING_COVER|NPC_ALLOW_PATROL) - SetSpawnOption_Titanfall(npc) - SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons - SetSpawnOption_AISettings(npc,"npc_titan_stryder_leadwall_arc") - file.spawnedNPCs.append(npc) - DispatchSpawn(npc) - AddMinimapForTitans(npc) - npc.WaitSignal( "TitanHotDropComplete" ) - npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) - thread singleNav_thread(npc,spawnEvent.route) - thread EMPTitanThinkConstant(npc) -} - -void function waitForTime(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - float waitUntil = Time() + waitEvent.amount - while(Time()<waitUntil) - { - if(!IsAlive(fd_harvester.harvester)) - break - WaitFrame() +string function GetAiNetIdFromTargetName(string targetName) +{ + switch ( targetName ) + { + case "titan": + case "sniperTitan": + case "npc_titan_ogre_meteor_boss_fd": + case "npc_titan_ogre_meteor": + case "npc_titan_ogre_minigun_boss_fd": + case "npc_titan_ogre_minigun": + case "npc_titan_atlas_stickybomb_boss_fd": + case "npc_titan_atlas_stickybomb": + case "npc_titan_atlas_tracker_boss_fd": + case "npc_titan_atlas_tracker": + case "npc_titan_stryder_leadwall_boss_fd": + case "npc_titan_stryder_leadwall": + case "npc_titan_stryder_sniper_boss_fd": + case "npc_titan_stryder_sniper": + case "npc_titan_sniper": + case "npc_titan_sniper_tone": + case "npc_titan_atlas_vanguard_boss_fd": + case "npc_titan_atlas_vanguard": + return "FD_AICount_Titan" + case "empTitan": + case "npc_titan_arc": + return "FD_AICount_Titan_Arc" + case "mortarTitan": + case "npc_titan_mortar": + return "FD_AICount_Titan_Mortar" + case "nukeTitan": + case "npc_titan_nuke": + return "FD_AICount_Titan_Nuke" + case "npc_soldier": + case "grunt": + return "FD_AICount_Grunt" + case "spectre": + return "FD_AICount_Spectre" + case "mortar_spectre": + return "FD_AICount_Spectre_Mortar" + case "npc_stalker": + case "stalker": + return "FD_AICount_Stalker" + case "npc_super_spectre": + case "reaper": + return "FD_AICount_Reaper" + case "npc_drone": + case "drone": + return "FD_AICount_Drone" + case "cloakedDrone": + return "FD_AICount_Drone_Cloak" + case "tick": + return "FD_AICount_Ticks" } + printt("unknown target name ",targetName) + return "" } -void function waitUntilLessThanAmountAliveEvent(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - waitUntilLessThanAmountAlive(int(waitEvent.amount)) -} - -void function spawnSuperSpectre(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - - entity npc = CreateSuperSpectre(TEAM_IMC,spawnEvent.origin,spawnEvent.angles) - SetSpawnOption_AISettings(npc,"npc_super_spectre_fd") - file.spawnedNPCs.append(npc) - wait 4.7 - DispatchSpawn(npc) - AddMinimapForHumans(npc) - thread SuperSpectre_WarpFall(npc) - thread ReaperMinionLauncherThink(npc) - - SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) - -} - -void function spawnDroppodGrunts(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity pod = CreateDropPod( spawnEvent.origin, <0,0,0> ) - SetTeam( pod, TEAM_IMC ) - InitFireteamDropPod( pod ) - waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, <0,0,0> ) - - string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) - array<entity> guys - bool adychecked = false - - for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) - { - entity guy = CreateSoldier( TEAM_IMC, spawnEvent.origin,<0,0,0> ) - - SetTeam( guy, TEAM_IMC ) - guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) - guy.DisableNPCFlag( NPC_ALLOW_PATROL) - DispatchSpawn( guy ) - - guy.SetParent( pod, "ATTACH", true ) - SetSquad( guy, squadName ) - - SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.GRUNT)) - AddMinimapForHumans(guy) - file.spawnedNPCs.append(guy) - guys.append( guy ) - } - - ActivateFireteamDropPod( pod, guys ) - SquadNav_Thread(guys,spawnEvent.route) -} - -void function spawnDroppodStalker(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity pod = CreateDropPod( spawnEvent.origin, <0,0,0> ) - SetTeam( pod, TEAM_IMC ) - InitFireteamDropPod( pod ) - waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, <0,0,0> ) - - string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) - array<entity> guys - - for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) - { - entity guy = CreateStalker( TEAM_IMC, spawnEvent.origin,<0,0,0> ) - - SetTeam( guy, TEAM_IMC ) - guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) - guy.DisableNPCFlag( NPC_ALLOW_PATROL) - DispatchSpawn( guy ) - - SetSquad( guy, squadName ) - AddMinimapForHumans(guy) - SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.STALKER)) - guys.append( guy ) - } - - ActivateFireteamDropPod( pod, guys ) - SquadNav_Thread(guys,spawnEvent.route) - -} - -void function spawnDroppodSpectreMortar(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity pod = CreateDropPod( spawnEvent.origin, <0,0,0> ) - SetTeam( pod, TEAM_IMC ) - InitFireteamDropPod( pod ) - waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, <0,0,0> ) - - string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) - array<entity> guys - - for ( int i = 0; i < 4; i++ ) - { - entity guy = CreateSpectre( TEAM_IMC, spawnEvent.origin,<0,0,0> ) - - SetTeam( guy, TEAM_IMC ) - DispatchSpawn( guy ) - - SetSquad( guy, squadName ) - SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.SPECTRE_MORTAR)) - AddMinimapForHumans(guy) - guys.append( guy ) - } - - ActivateFireteamDropPod( pod, guys ) -} - -void function spawnGenericNPC(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity npc = CreateNPC( spawnEvent.npcClassName, TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) - DispatchSpawn(npc) -} - -void function spawnGenericNPCTitanwithSettings(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity npc = CreateNPCTitan( spawnEvent.npcClassName, TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) - if( spawnEvent.aiSettings == "npc_titan_atlas_tracker_fd_sniper" ) - SetTargetName( npc, "npc_titan_atlas_tracker" ) // required for client to create icons - SetSpawnOption_AISettings( npc, spawnEvent.aiSettings) - SetSpawnOption_Titanfall(npc) - DispatchSpawn(npc) - file.spawnedNPCs.append(npc) - AddMinimapForTitans(npc) - npc.WaitSignal( "TitanHotDropComplete" ) - npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) -} - -void function spawnNukeTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity npc = CreateNPCTitan("titan_ogre",TEAM_IMC, spawnEvent.origin, spawnEvent.angles) - SetSpawnOption_AISettings(npc,"npc_titan_ogre_minigun_nuke") - SetSpawnOption_Titanfall(npc) - SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons - npc.EnableNPCMoveFlag(NPCMF_WALK_ALWAYS) - DispatchSpawn(npc) - file.spawnedNPCs.append(npc) - AddMinimapForTitans(npc) - npc.WaitSignal( "TitanHotDropComplete" ) - npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) - thread singleNav_thread(npc,spawnEvent.route) - thread NukeTitanThink(npc,fd_harvester.harvester) - -} - -void function spawnMortarTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity npc = CreateNPCTitan("titan_atlas",TEAM_IMC, spawnEvent.origin, spawnEvent.angles) - SetSpawnOption_AISettings(npc,"npc_titan_atlas_tracker_mortar") - SetSpawnOption_Titanfall(npc) - SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons - DispatchSpawn(npc) - file.spawnedNPCs.append(npc) - AddMinimapForTitans(npc) - npc.WaitSignal( "TitanHotDropComplete" ) - npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) - thread MortarTitanThink(npc,fd_harvester.harvester) -} - -void function spawnSniperTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity npc = CreateNPCTitan("titan_stryder",TEAM_IMC, spawnEvent.origin, spawnEvent.angles) - SetSpawnOption_AISettings(npc,"npc_titan_stryder_sniper_fd") - SetSpawnOption_Titanfall(npc) - SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons - DispatchSpawn(npc) - file.spawnedNPCs.append(npc) - AddMinimapForTitans(npc) - npc.WaitSignal( "TitanHotDropComplete" ) - npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) - thread SniperTitanThink(npc,fd_harvester.harvester) - -} - -void function SpawnToneSniperTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity npc = CreateNPCTitan("titan_atlas",TEAM_IMC, spawnEvent.origin, spawnEvent.angles) - SetSpawnOption_AISettings(npc,"npc_titan_atlas_tracker_fd_sniper") - SetSpawnOption_Titanfall(npc) - SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons - DispatchSpawn( npc ) - file.spawnedNPCs.append(npc) - AddMinimapForTitans(npc) - npc.WaitSignal( "TitanHotDropComplete" ) - npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) - thread SniperTitanThink(npc,fd_harvester.harvester) - -} - -void function fd_spawnCloakDrone(SmokeEvent smokeEffect,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - entity npc = SpawnCloakDrone( TEAM_IMC, spawnEvent.origin, spawnEvent.angles, file.harvester_info.GetOrigin() ) - file.spawnedNPCs.append(npc) - SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) - AddMinimapForHumans(npc) -} - -void function SpawnTick(SmokeEvent smokeEffect,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) -{ - PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) - entity pod = CreateDropPod( spawnEvent.origin, <0,0,0> ) - SetTeam( pod, TEAM_IMC ) - InitFireteamDropPod( pod ) - waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, <0,0,0> ) - - string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) - array<entity> guys - - for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) - { - entity guy = CreateFragDrone( TEAM_IMC, spawnEvent.origin, <0,0,0> ) - - SetSpawnOption_AISettings(guy, "npc_frag_drone_fd") - SetTeam( guy, TEAM_IMC ) - guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE ) - guy.EnableNPCMoveFlag(NPCMF_WALK_ALWAYS | NPCMF_PREFER_SPRINT) - DispatchSpawn( guy ) - AddMinimapForHumans(guy) - SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.TICK)) - SetSquad( guy, squadName ) - - guys.append( guy ) - } - - ActivateFireteamDropPod( pod, guys ) - SquadNav_Thread(guys,spawnEvent.route) -} - -/****************************************************************************************\ -####### # # ####### # # ####### # # ####### # ###### ####### ###### -# # # # ## # # # # # # # # # # # -# # # # # # # # # # # # # # # # # -##### # # ##### # # # # ####### ##### # ###### ##### ###### -# # # # # # # # # # # # # # # # -# # # # # ## # # # # # # # # # -####### # ####### # # # # # ####### ####### # ####### # # -\****************************************************************************************/ - - -void function PingMinimap(float x, float y, float duration, float spreadRadius, float ringRadius, int colorIndex) -{ - foreach(entity player in GetPlayerArray()) - { - Remote_CallFunction_NonReplay(player, "ServerCallback_FD_PingMinimap", x, y, duration, spreadRadius, ringRadius, colorIndex) - } -} - -void function waitUntilLessThanAmountAlive(int amount) -{ - - int aliveTitans = file.spawnedNPCs.len() - while(aliveTitans>amount) - { - WaitFrame() - aliveTitans = file.spawnedNPCs.len() - if(!IsAlive(fd_harvester.harvester)) - break - } -} - -void function waitUntilLessThanAmountAlive_expensive(int amount) -{ - - array<entity> npcs = GetNPCArray() - int deduct = 0 - foreach (entity npc in npcs) - if (IsValid(GetPetTitanOwner( npc ))) - deduct++ - int aliveTitans = npcs.len() - deduct - while(aliveTitans>amount) - { - WaitFrame() - npcs = GetNPCArray() - deduct = 0 - foreach(entity npc in npcs) - if (IsValid(GetPetTitanOwner( npc ))) - deduct++ - aliveTitans = GetNPCArray().len() - deduct - if(!IsAlive(fd_harvester.harvester)) - break - } -} - -void function AddMinimapForTitans(entity titan) -{ - titan.Minimap_SetAlignUpright( true ) - titan.Minimap_AlwaysShow( TEAM_IMC, null ) - titan.Minimap_AlwaysShow( TEAM_MILITIA, null ) - titan.Minimap_SetHeightTracking( true ) - titan.Minimap_SetCustomState( eMinimapObject_npc_titan.AT_BOUNTY_BOSS ) -} - -// including drones -void function AddMinimapForHumans(entity human) -{ - human.Minimap_SetAlignUpright( true ) - human.Minimap_AlwaysShow( TEAM_IMC, null ) - human.Minimap_AlwaysShow( TEAM_MILITIA, null ) - human.Minimap_SetHeightTracking( true ) - human.Minimap_SetCustomState( eMinimapObject_npc.AI_TDM_AI ) -} void function AddTurretSentry(entity turret) { diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_events.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_events.nut new file mode 100644 index 00000000..5a8996ec --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_events.nut @@ -0,0 +1,736 @@ +global function createSmokeEvent +global function createArcTitanEvent +global function createWaitForTimeEvent +global function createSuperSpectreEvent +global function createDroppodGruntEvent +global function createNukeTitanEvent +global function createMortarTitanEvent +global function createGenericSpawnEvent +global function createGenericTitanSpawnWithAiSettingsEvent +global function createDroppodStalkerEvent +global function createDroppodSpectreMortarEvent +global function createWaitUntilAliveEvent +global function createCloakDroneEvent +global function CreateTickEvent +global function CreateToneSniperTitanEvent +global function CreateNorthstarSniperTitanEvent +global function executeWave + + +global struct SmokeEvent{ + vector position + float lifetime +} + +global struct SpawnEvent{ + vector origin + vector angles + string route //defines route taken by the ai + int skippedRouteNodes //defines how many route nodes will be skipped + int spawnType //Just used for Wave Info but can be used for spawn too should contain aid of spawned enemys + int spawnAmount //Just used for Wave Info but can be used for spawn too should contain amound of spawned enemys + string npcClassName + string aiSettings +} + +global struct WaitEvent{ + float amount +} + +global struct SoundEvent{ + string soundEventName +} + +global struct WaveEvent{ + void functionref(SmokeEvent,SpawnEvent,WaitEvent,SoundEvent) eventFunction + bool shouldThread + int executeOnThisCall //will actually be executed when called this many times + int timesExecuted + int nextEventIndex + SmokeEvent smokeEvent + SpawnEvent spawnEvent + WaitEvent waitEvent + SoundEvent soundEvent +} + + + + +global array<array<WaveEvent> > waveEvents + + + +void function executeWave() +{ + print("executeWave Start") + thread runEvents(0) + while(IsAlive(fd_harvester.harvester)&&(!allEventsExecuted(GetGlobalNetInt("FD_currentWave")))) + WaitFrame() + waitUntilLessThanAmountAlive(0) + waitUntilLessThanAmountAlive_expensive(0) +} + +bool function allEventsExecuted(int waveIndex) +{ + foreach(WaveEvent e in waveEvents[waveIndex]) + { + if(e.executeOnThisCall>e.timesExecuted) + return false + } + return true +} + +void function runEvents(int firstExecuteIndex) +{ + print("runEvents Start") + WaveEvent currentEvent = waveEvents[GetGlobalNetInt("FD_currentWave")][firstExecuteIndex] + + while(true) + { + currentEvent.timesExecuted++ + if(currentEvent.timesExecuted!=currentEvent.executeOnThisCall) + { + print("not on this call") + return + } + if(!IsAlive(fd_harvester.harvester)) + { + print("harvesterDead") + return + } + if(currentEvent.shouldThread) + { + print("execute with thread") + thread currentEvent.eventFunction(currentEvent.smokeEvent,currentEvent.spawnEvent,currentEvent.waitEvent,currentEvent.soundEvent) + } + else + { + print("execute without thread") + currentEvent.eventFunction(currentEvent.smokeEvent,currentEvent.spawnEvent,currentEvent.waitEvent,currentEvent.soundEvent) + } + if(currentEvent.nextEventIndex==0) + { + print("zero index") + return + } + currentEvent = waveEvents[GetGlobalNetInt("FD_currentWave")][currentEvent.nextEventIndex] + } + print("runEvents End") +} + + + + + + + + + + +/****************************************************************************************************************\ +####### # # ####### # # ####### ##### ####### # # ####### ###### # ####### ####### ###### +# # # # ## # # # # # ## # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # +##### # # ##### # # # # # #### ##### # # # ##### ###### # # # # # ###### +# # # # # # # # # # # # # # # # # ####### # # # # # +# # # # # ## # # # # # ## # # # # # # # # # # +####### # ####### # # # ##### ####### # # ####### # # # # # ####### # # +\*****************************************************************************************************************/ + +WaveEvent function createSmokeEvent(vector position,float lifetime,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnSmoke + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.smokeEvent.position = position + event.smokeEvent.lifetime = lifetime + return event +} + +WaveEvent function createArcTitanEvent(vector origin,vector angles,string route,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnArcTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_ARC + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + return event +} + +WaveEvent function createSuperSpectreEvent(vector origin,vector angles,string route,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnSuperSpectre + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.REAPER + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + return event +} + +WaveEvent function createDroppodGruntEvent(vector origin,string route,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnDroppodGrunts + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.GRUNT + event.spawnEvent.spawnAmount = 4 + event.spawnEvent.origin = origin + event.spawnEvent.route = route + return event +} + +WaveEvent function createDroppodStalkerEvent(vector origin,string route,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnDroppodStalker + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.STALKER + event.spawnEvent.spawnAmount = 4 + event.spawnEvent.origin = origin + event.spawnEvent.route = route + return event +} + +WaveEvent function createDroppodSpectreMortarEvent(vector origin,string route,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnDroppodSpectreMortar + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.SPECTRE_MORTAR + event.spawnEvent.spawnAmount = 4 + event.spawnEvent.origin = origin + event.spawnEvent.route = route + return event +} + +WaveEvent function createWaitForTimeEvent(float amount,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.shouldThread = false + event.eventFunction = waitForTime + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.waitEvent.amount = amount + return event +} + +WaveEvent function createWaitUntilAliveEvent(int amount,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = waitUntilLessThanAmountAliveEvent + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = false + event.waitEvent.amount = amount.tofloat() + return event +} + +WaveEvent function createGenericSpawnEvent(string npcClassName,vector origin,vector angles,string route,int spawnType,int spawnAmount,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnGenericNPC + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.npcClassName = npcClassName + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.spawnType = spawnType + event.spawnEvent.spawnAmount = spawnAmount + return event +} + +WaveEvent function createGenericTitanSpawnWithAiSettingsEvent(string npcClassName,string aiSettings,vector origin,vector angles,string route,int spawnType,int spawnAmount,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnGenericNPCTitanwithSettings + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.npcClassName = npcClassName + event.spawnEvent.aiSettings = aiSettings + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.spawnType = spawnType + event.spawnEvent.spawnAmount = spawnAmount + return event +} + +WaveEvent function createNukeTitanEvent(vector origin,vector angles,string route,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnNukeTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_NUKE + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + return event +} + +WaveEvent function createMortarTitanEvent(vector origin,vector angles,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnMortarTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_MORTAR + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + return event +} + +WaveEvent function createCloakDroneEvent(vector origin,vector angles,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = fd_spawnCloakDrone + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.DRONE_CLOAK + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + return event +} + +WaveEvent function CreateTickEvent( vector origin, vector angles, int amount, string route,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = SpawnTick + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TICK + event.spawnEvent.spawnAmount = amount + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + return event +} + +WaveEvent function CreateNorthstarSniperTitanEvent(vector origin,vector angles,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = spawnSniperTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_SNIPER + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + return event +} + +WaveEvent function CreateToneSniperTitanEvent(vector origin,vector angles,int nextEventIndex,int executeOnThisCall = 1) +{ + WaveEvent event + event.eventFunction = SpawnToneSniperTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_SNIPER + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + return event +} + +/************************************************************************************************************\ +####### # # ####### # # ####### ####### # # # # ##### ####### ### ####### # # ##### +# # # # ## # # # # # ## # # # # # # # ## # # # +# # # # # # # # # # # # # # # # # # # # # # # +##### # # ##### # # # # ##### # # # # # # # # # # # # # ##### +# # # # # # # # # # # # # # # # # # # # # # # +# # # # # ## # # # # # ## # # # # # # # ## # # +####### # ####### # # # # ##### # # ##### # ### ####### # # ##### +\************************************************************************************************************/ + +void function spawnSmoke(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + printt("smoke") + SmokescreenStruct smokescreen + smokescreen.smokescreenFX = $"P_smokescreen_FD" + smokescreen.isElectric = false + smokescreen.origin = smokeEvent.position + < 0 , 0, 150> + smokescreen.angles = <0,0,0> + smokescreen.lifetime = smokeEvent.lifetime + smokescreen.fxXYRadius = 150 + smokescreen.fxZRadius = 120 + smokescreen.fxOffsets = [ <120.0, 0.0, 0.0>,<0.0, 120.0, 0.0>, <0.0, 0.0, 0.0>,<0.0, -120.0, 0.0>,< -120.0, 0.0, 0.0>, <0.0, 100.0, 0.0>] + + +} + +void function spawnArcTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity npc = CreateArcTitan(TEAM_IMC,spawnEvent.origin,spawnEvent.angles) + npc.DisableNPCFlag(NPC_ALLOW_INVESTIGATE | NPC_USE_SHOOTING_COVER|NPC_ALLOW_PATROL) + SetSpawnOption_Titanfall(npc) + SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons + SetSpawnOption_AISettings(npc,"npc_titan_stryder_leadwall_arc") + spawnedNPCs.append(npc) + DispatchSpawn(npc) + AddMinimapForTitans(npc) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + npc.AssaultSetFightRadius(0) + thread singleNav_thread(npc,spawnEvent.route) + thread EMPTitanThinkConstant(npc) + +} + +void function waitForTime(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + float waitUntil = Time() + waitEvent.amount + while(Time()<waitUntil) + { + if(!IsAlive(fd_harvester.harvester)) + return + WaitFrame() + } +} + +void function waitUntilLessThanAmountAliveEvent(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + waitUntilLessThanAmountAlive(int(waitEvent.amount)) +} + +void function spawnSuperSpectre(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + + entity npc = CreateSuperSpectre(TEAM_IMC,spawnEvent.origin,spawnEvent.angles) + SetSpawnOption_AISettings(npc,"npc_super_spectre_fd") + spawnedNPCs.append(npc) + + wait 4.7 + DispatchSpawn(npc) + AddMinimapForHumans(npc) + thread SuperSpectre_WarpFall(npc) + thread ReaperMinionLauncherThink(npc) + + SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) +} + +void function spawnDroppodGrunts(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity pod = CreateDropPod( spawnEvent.origin, <0,0,0> ) + SetTeam( pod, TEAM_IMC ) + InitFireteamDropPod( pod ) + waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, <0,0,0> ) + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + array<entity> guys + bool adychecked = false + + for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) + { + entity guy = CreateSoldier( TEAM_IMC, spawnEvent.origin,<0,0,0> ) + + SetTeam( guy, TEAM_IMC ) + guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) + guy.DisableNPCFlag( NPC_ALLOW_PATROL) + DispatchSpawn( guy ) + + guy.SetParent( pod, "ATTACH", true ) + SetSquad( guy, squadName ) + + SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.GRUNT)) + AddMinimapForHumans(guy) + spawnedNPCs.append(guy) + guys.append( guy ) + } + + ActivateFireteamDropPod( pod, guys ) + thread SquadNav_Thread(guys,spawnEvent.route) +} + +void function spawnDroppodStalker(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity pod = CreateDropPod( spawnEvent.origin, <0,0,0> ) + SetTeam( pod, TEAM_IMC ) + InitFireteamDropPod( pod ) + waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, <0,0,0> ) + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + array<entity> guys + + for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) + { + entity guy = CreateStalker( TEAM_IMC, spawnEvent.origin,<0,0,0> ) + + SetTeam( guy, TEAM_IMC ) + guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) + guy.DisableNPCFlag( NPC_ALLOW_PATROL) + DispatchSpawn( guy ) + + SetSquad( guy, squadName ) + AddMinimapForHumans(guy) + SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.STALKER)) + guys.append( guy ) + } + + ActivateFireteamDropPod( pod, guys ) + thread SquadNav_Thread(guys,spawnEvent.route) + +} + +void function spawnDroppodSpectreMortar(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity pod = CreateDropPod( spawnEvent.origin, <0,0,0> ) + SetTeam( pod, TEAM_IMC ) + InitFireteamDropPod( pod ) + waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, <0,0,0> ) + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + array<entity> guys + + for ( int i = 0; i < 4; i++ ) + { + entity guy = CreateSpectre( TEAM_IMC, spawnEvent.origin,<0,0,0> ) + + SetTeam( guy, TEAM_IMC ) + DispatchSpawn( guy ) + + SetSquad( guy, squadName ) + SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.SPECTRE_MORTAR)) + AddMinimapForHumans(guy) + guys.append( guy ) + } + + ActivateFireteamDropPod( pod, guys ) +} + +void function spawnGenericNPC(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity npc = CreateNPC( spawnEvent.npcClassName, TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + DispatchSpawn(npc) +} + +void function spawnGenericNPCTitanwithSettings(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity npc = CreateNPCTitan( spawnEvent.npcClassName, TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + if( spawnEvent.aiSettings == "npc_titan_atlas_tracker_fd_sniper" ) + SetTargetName( npc, "npc_titan_atlas_tracker" ) // required for client to create icons + SetSpawnOption_AISettings( npc, spawnEvent.aiSettings) + SetSpawnOption_Titanfall(npc) + DispatchSpawn(npc) + spawnedNPCs.append(npc) + AddMinimapForTitans(npc) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) +} + +void function spawnNukeTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity npc = CreateNPCTitan("titan_ogre",TEAM_IMC, spawnEvent.origin, spawnEvent.angles) + SetSpawnOption_AISettings(npc,"npc_titan_ogre_minigun_nuke") + SetSpawnOption_Titanfall(npc) + SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons + npc.EnableNPCMoveFlag(NPCMF_WALK_ALWAYS) + npc.AssaultSetFightRadius(0) + DispatchSpawn(npc) + spawnedNPCs.append(npc) + AddMinimapForTitans(npc) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread singleNav_thread(npc,spawnEvent.route) + thread NukeTitanThink(npc,fd_harvester.harvester) + +} + +void function spawnMortarTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity npc = CreateNPCTitan("titan_atlas",TEAM_IMC, spawnEvent.origin, spawnEvent.angles) + SetSpawnOption_AISettings(npc,"npc_titan_atlas_tracker_mortar") + SetSpawnOption_Titanfall(npc) + SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons + DispatchSpawn(npc) + spawnedNPCs.append(npc) + AddMinimapForTitans(npc) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread MortarTitanThink(npc,fd_harvester.harvester) +} + +void function spawnSniperTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity npc = CreateNPCTitan("titan_stryder",TEAM_IMC, spawnEvent.origin, spawnEvent.angles) + SetSpawnOption_AISettings(npc,"npc_titan_stryder_sniper_fd") + SetSpawnOption_Titanfall(npc) + SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons + DispatchSpawn(npc) + spawnedNPCs.append(npc) + AddMinimapForTitans(npc) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread SniperTitanThink(npc,fd_harvester.harvester) + +} + +void function SpawnToneSniperTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity npc = CreateNPCTitan("titan_atlas",TEAM_IMC, spawnEvent.origin, spawnEvent.angles) + SetSpawnOption_AISettings(npc,"npc_titan_atlas_tracker_fd_sniper") + SetSpawnOption_Titanfall(npc) + SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) // required for client to create icons + DispatchSpawn( npc ) + npc.AssaultSetFightRadius(0) + spawnedNPCs.append(npc) + AddMinimapForTitans(npc) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread SniperTitanThink(npc,fd_harvester.harvester) +} + +void function fd_spawnCloakDrone(SmokeEvent smokeEffect,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + entity npc = SpawnCloakDrone( TEAM_IMC, spawnEvent.origin, spawnEvent.angles, fd_harvester.harvester.GetOrigin() ) + spawnedNPCs.append(npc) + SetTargetName( npc, GetTargetNameForID(spawnEvent.spawnType)) + AddMinimapForHumans(npc) +} + +void function SpawnTick(SmokeEvent smokeEffect,SpawnEvent spawnEvent,WaitEvent waitEvent,SoundEvent soundEvent) +{ + PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0) + entity pod = CreateDropPod( spawnEvent.origin, <0,0,0> ) + SetTeam( pod, TEAM_IMC ) + InitFireteamDropPod( pod ) + waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, <0,0,0> ) + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + array<entity> guys + + for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) + { + entity guy = CreateFragDrone( TEAM_IMC, spawnEvent.origin, <0,0,0> ) + + SetSpawnOption_AISettings(guy, "npc_frag_drone_fd") + SetTeam( guy, TEAM_IMC ) + guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE ) + guy.EnableNPCMoveFlag(NPCMF_WALK_ALWAYS | NPCMF_PREFER_SPRINT) + DispatchSpawn( guy ) + AddMinimapForHumans(guy) + SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.TICK)) + SetSquad( guy, squadName ) + + guys.append( guy ) + } + + ActivateFireteamDropPod( pod, guys ) + thread SquadNav_Thread(guys,spawnEvent.route) +} + + + +/****************************************************************************************\ +####### # # ####### # # ####### # # ####### # ###### ####### ###### +# # # # ## # # # # # # # # # # # +# # # # # # # # # # # # # # # # # +##### # # ##### # # # # ####### ##### # ###### ##### ###### +# # # # # # # # # # # # # # # # +# # # # # ## # # # # # # # # # +####### # ####### # # # # # ####### ####### # ####### # # +\****************************************************************************************/ + + +void function PingMinimap(float x, float y, float duration, float spreadRadius, float ringRadius, int colorIndex) +{ + foreach(entity player in GetPlayerArray()) + { + Remote_CallFunction_NonReplay(player, "ServerCallback_FD_PingMinimap", x, y, duration, spreadRadius, ringRadius, colorIndex) + } +} + +void function waitUntilLessThanAmountAlive(int amount) +{ + + int aliveTitans = spawnedNPCs.len() + while(aliveTitans>amount) + { + WaitFrame() + aliveTitans = spawnedNPCs.len() + if(!IsAlive(fd_harvester.harvester)) + return + } +} + +void function waitUntilLessThanAmountAlive_expensive(int amount) +{ + + array<entity> npcs = GetNPCArray() + int deduct = 0 + foreach (entity npc in npcs) + if (IsValid(GetPetTitanOwner( npc ))) + deduct++ + int aliveTitans = npcs.len() - deduct + while(aliveTitans>amount) + { + WaitFrame() + npcs = GetNPCArray() + deduct = 0 + foreach(entity npc in npcs) + if (IsValid(GetPetTitanOwner( npc ))) + deduct++ + aliveTitans = GetNPCArray().len() - deduct + if(!IsAlive(fd_harvester.harvester)) + return + } +} + +void function AddMinimapForTitans(entity titan) +{ + titan.Minimap_SetAlignUpright( true ) + titan.Minimap_AlwaysShow( TEAM_IMC, null ) + titan.Minimap_AlwaysShow( TEAM_MILITIA, null ) + titan.Minimap_SetHeightTracking( true ) + titan.Minimap_SetCustomState( eMinimapObject_npc_titan.AT_BOUNTY_BOSS ) +} + +// including drones +void function AddMinimapForHumans(entity human) +{ + human.Minimap_SetAlignUpright( true ) + human.Minimap_AlwaysShow( TEAM_IMC, null ) + human.Minimap_AlwaysShow( TEAM_MILITIA, null ) + human.Minimap_SetHeightTracking( true ) + human.Minimap_SetCustomState( eMinimapObject_npc.AI_TDM_AI ) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_nav.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_nav.nut new file mode 100644 index 00000000..1ca2bc16 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_nav.nut @@ -0,0 +1,97 @@ +global function singleNav_thread +global function SquadNav_Thread +global function getRoute + + + +void function singleNav_thread(entity npc, string routeName,int nodesToScip= 0,float nextDistance = 500.0) +{ + npc.EndSignal( "OnDeath" ) + npc.EndSignal( "OnDestroy" ) + + + + if(!npc.IsNPC()){ + return + } + + + + array<entity> routeArray = getRoute(routeName) + WaitFrame()//so other code setting up what happens on signals is run before this + if(routeArray.len()==0) + { + + npc.Signal("OnFailedToPath") + return + } + int scippedNodes = 0 + foreach(entity node in routeArray) + { + if(!IsAlive(fd_harvester.harvester)) + return + if(scippedNodes < nodesToScip) + { + scippedNodes++ + continue + } + npc.AssaultPoint(node.GetOrigin()) + npc.AssaultSetGoalRadius( 50 ) + int i = 0 + table result = npc.WaitSignal("OnFinishedAssault","OnFailedToPath") + if(result.signal == "OnFailedToPath") + break + } + npc.Signal("FD_ReachedHarvester") +} + +void function SquadNav_Thread( array<entity> npcs ,string routeName,int nodesToScip = 0,float nextDistance = 200.0) +{ + //TODO this function wont stop when noone alive anymore also it only works half of the time + + array<entity> routeArray = getRoute(routeName) + WaitFrame()//so other code setting up what happens on signals is run before this + if(routeArray.len()==0) + return + + int nodeIndex = 0 + foreach(entity node in routeArray) + { + if(!IsAlive(fd_harvester.harvester)) + return + if(nodeIndex++ < nodesToScip) + continue + + SquadAssaultOrigin(npcs,node.GetOrigin(),nextDistance) + + } + +} + +array<entity> function getRoute(string routeName) +{ + array<entity> ret + array<entity> currentNode = [] + foreach(entity node in routeNodes) + { + if(!node.HasKey("route_name")) + continue + if(node.kv.route_name==routeName) + { + currentNode = [node] + break + } + + } + if(currentNode.len()==0) + { + printt("Route not found") + return [] + } + while(currentNode.len()!=0) + { + ret.append(currentNode[0]) + currentNode = currentNode[0].GetLinkEntArray() + } + return ret +}
\ No newline at end of file |