diff --git a/FAF_Coop_Fort_Clarke_Assault/FAF_Coop_Fort_Clarke_Assault_CustomFunctions.lua b/FAF_Coop_Fort_Clarke_Assault/FAF_Coop_Fort_Clarke_Assault_CustomFunctions.lua index 2fb1ae0..0f90c27 100644 --- a/FAF_Coop_Fort_Clarke_Assault/FAF_Coop_Fort_Clarke_Assault_CustomFunctions.lua +++ b/FAF_Coop_Fort_Clarke_Assault/FAF_Coop_Fort_Clarke_Assault_CustomFunctions.lua @@ -29,31 +29,40 @@ function CarrierAI(platoon) if numCarriers <= numPositions then for i = 1, numCarriers do ForkThread(function(i) + local carrier = carriers[i] IssueMove( {carriers[i]}, movePositions[i] ) - while (carriers[i] and not carriers[i].Dead and carriers[i]:IsUnitState('Moving')) do + while (not carrier.Dead and carrier:IsUnitState('Moving')) do WaitSeconds(.5) end + + if carrier.Dead then + return + end - local location - for num, loc in aiBrain.PBM.Locations do - if loc.LocationType == data.Location .. i then - location = loc + for _, location in aiBrain.PBM.Locations do + if location.LocationType == data.Location .. i then + location.PrimaryFactories.Air = factory break end end - if not carriers[i].Dead then - location.PrimaryFactories.Air = carriers[i] - end - - while (carriers[i] and not carriers[i].Dead) do - if table.getn(carriers[i]:GetCargo()) > 0 and carriers[i]:IsIdleState() then - IssueClearCommands(carriers[i]) - IssueTransportUnload({carriers[i]}, carriers[i]:GetPosition()) + carrier:ForkThread(function(self) + local factory = self.ExternalFactory + + while true do + if table.getn(self:GetCargo()) > 0 and factory:IsIdleState() then + IssueClearCommands({self}) + IssueTransportUnload({self}, carrier:GetPosition()) + + repeat + WaitSeconds(3) + until not self:IsUnitState("TransportUnloading") + end + + WaitSeconds(1) end - WaitSeconds(1) - end + end) end, i) end else diff --git a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_CustomFunctions.lua b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_CustomFunctions.lua index e66264a..70cc2f6 100644 --- a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_CustomFunctions.lua +++ b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_CustomFunctions.lua @@ -53,30 +53,40 @@ function CarrierAI(platoon) for i = 1, numCarriers do ForkThread(function(i) - IssueMove({carriers[i]}, movePositions[i]) + local carrier = carriers[i] + IssueMove({carrier}, movePositions[i]) - while not carriers[i].Dead and carriers[i]:IsUnitState('Moving') do + while not carrier.Dead and carrier:IsUnitState('Moving') do WaitSeconds(.5) end - if carriers[i].Dead then + if carrier.Dead then return end - for num, loc in aiBrain.PBM.Locations do - if loc.LocationType == data.Location .. i then - loc.PrimaryFactories.Air = carriers[i] + for _, location in aiBrain.PBM.Locations do + if location.LocationType == data.Location .. i then + location.PrimaryFactories.Air = carrier.ExternalFactory break end end - while not carriers[i].Dead do - if table.getn(carriers[i]:GetCargo()) > 0 and carriers[i]:IsIdleState() then - IssueClearCommands({carriers[i]}) - IssueTransportUnload({carriers[i]}, carriers[i]:GetPosition()) + carrier:ForkThread(function(self) + local factory = self.ExternalFactory + + while true do + if table.getn(self:GetCargo()) > 0 and factory:IsIdleState() then + IssueClearCommands({self}) + IssueTransportUnload({self}, carrier:GetPosition()) + + repeat + WaitSeconds(3) + until not self:IsUnitState("TransportUnloading") + end + + WaitSeconds(1) end - WaitSeconds(1) - end + end) end, i) end end @@ -671,6 +681,7 @@ local minASFs = 25 function AtlantisThread(platoon) local brain = platoon:GetBrain() local atlantis = platoon:GetPlatoonUnits()[1] + local factory = atlantis.ExternalFactory local rect = ScenarioUtils.AreaToRect('M3_Atlantis_Guard_Area') local targetCats = categories.AIR * categories.MOBILE * categories.EXPERIMENTAL @@ -711,9 +722,9 @@ function AtlantisThread(platoon) end local function deployASFs() - if atlantis:IsUnitState('Building') then - IssueStop({atlantis}) - IssueClearCommands({atlantis}) + if factory:IsUnitState('Building') then + IssueStop({factory}) + IssueClearCommands({factory}) end platoon:UnloadUnitsAtLocation(categories.uea0303, platoon:GetPlatoonPosition()) @@ -735,7 +746,7 @@ function AtlantisThread(platoon) local toBuild = maxASFs[Difficulty] - numASFsInPlatoon - cargo --LOG("Atlantis checking to build ASFs, needing: " .. toBuild) if toBuild > 0 then - IssueBuildFactory({atlantis}, 'uea0303', toBuild) + IssueBuildFactory({factory}, 'uea0303', toBuild) end end @@ -752,7 +763,7 @@ function AtlantisThread(platoon) end end - if atlantis:IsIdleState() then + if atlantis:IsIdleState() and factory:IsIdleState() then buildASFs() end diff --git a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m1orderai.lua b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m1orderai.lua index df2fe68..c6ddf8d 100644 --- a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m1orderai.lua +++ b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m1orderai.lua @@ -16,26 +16,35 @@ function OrderCarrierFactory() -- Adding build location for AI ArmyBrains[Order]:PBMAddBuildLocation('M1_Order_Carrier_Start_Marker', 150, 'AircraftCarrier1') - local Carrier = ScenarioInfo.M1_Order_Carrier - if not Carrier then - return - end + local carrier = ScenarioInfo.M1_Order_Carrier - for num, loc in ArmyBrains[Order].PBM.Locations do - if loc.LocationType == 'AircraftCarrier1' then - loc.PrimaryFactories.Air = Carrier + for _, location in ArmyBrains[Order].PBM.Locations do + if location.LocationType == 'AircraftCarrier1' then + location.PrimaryFactories.Air = carrier.ExternalFactory OrderCarrierAttacks() break end end + + IssueClearFactoryCommands({carrier.ExternalFactory}) + IssueFactoryRallyPoint({carrier.ExternalFactory}, ScenarioUtils.MarkerToPosition("Naval Rally Point 08")) - while ScenarioInfo.MissionNumber == 1 and not Carrier.Dead do - if Carrier:IsIdleState() and Carrier:GetCargo()[1] then - IssueClearCommands({Carrier}) - IssueTransportUnload({Carrier}, Carrier:GetPosition()) + carrier.ReleaseUnitsThread = carrier:ForkThread(function(self) + local factory = self.ExternalFactory + + while true do + if table.getn(self:GetCargo()) > 0 and factory:IsIdleState() then + IssueClearCommands({self}) + IssueTransportUnload({self}, ScenarioUtils.MarkerToPosition("Naval Rally Point 08")) + + repeat + WaitSeconds(3) + until not self:IsUnitState("TransportUnloading") + end + + WaitSeconds(1) end - WaitSeconds(1) - end + end) end -- Platoons built by carrier @@ -75,13 +84,18 @@ end function OrderTempestFactory() ArmyBrains[Order]:PBMAddBuildLocation('M1_Order_Tempest_Start_Marker', 150, 'Tempest1') - for num, loc in ArmyBrains[Order].PBM.Locations do - if loc.LocationType == 'Tempest1' then - loc.PrimaryFactories.Sea = ScenarioInfo.M1_Order_Tempest + local tempest = ScenarioInfo.M1_Order_Tempest + + for _, location in ArmyBrains[Order].PBM.Locations do + if location.LocationType == 'Tempest1' then + location.PrimaryFactories.Sea = tempest.ExternalFactory OrderTempestAttacks() - return + break end end + + IssueClearFactoryCommands({tempest.ExternalFactory}) + IssueFactoryRallyPoint({tempest.ExternalFactory}, ScenarioUtils.MarkerToPosition("Naval Rally Point 08")) end function OrderTempestAttacks() @@ -101,9 +115,8 @@ function OrderTempestAttacks() PlatoonType = 'Sea', RequiresConstruction = true, LocationType = 'Tempest1', - PlatoonAIFunction = {ThisFile, 'MoveAndGivePlatoonToPlayer'}, + PlatoonAIFunction = {ThisFile, 'GivePlatoonToPlayerAndPatrol'}, PlatoonData = { - MoveRoute = {'Rally Point 05'}, PatrolChain = 'M1_Oder_Naval_Def_Chain', }, } @@ -139,40 +152,15 @@ function GivePlatoonToPlayer(platoon) end end -function MoveAndGivePlatoonToPlayer(platoon) +function GivePlatoonToPlayerAndPatrol(platoon) local givenUnits = {} local data = platoon.PlatoonData if not data then - error('*MoveAndGivePlatoonToPlayer: PlatoonData not defined', 2) - elseif not (data.MoveRoute or data.MoveChain) then - error('*MoveAndGivePlatoonToPlayer: MoveToRoute or MoveChain not defined', 2) + error('*GivePlatoonToPlayerAndPatrol: PlatoonData not defined', 2) end - local movePositions = {} - if data.MoveChain then - movePositions = ScenarioUtils.ChainToPositions(data.MoveChain) - else - for _, v in data.MoveRoute do - if type(v) == 'string' then - table.insert(movePositions, ScenarioUtils.MarkerToPosition(v)) - else - table.insert(movePositions, v) - end - end - end - - for _, v in movePositions do - platoon:MoveToLocation(v, false) - end - - WaitSeconds(1) - for _, unit in platoon:GetPlatoonUnits() do - while (not unit.Dead and unit:IsUnitState('Moving')) do - WaitSeconds(1) - end - local tempUnit = ScenarioFramework.GiveUnitToArmy(unit, 'Player1') table.insert(givenUnits, tempUnit) end diff --git a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2cybranai.lua b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2cybranai.lua index 3407085..9d7c23c 100644 --- a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2cybranai.lua +++ b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2cybranai.lua @@ -626,23 +626,27 @@ function CybranM2IslandBaseCarrierAttacks() local units = ArmyBrains[Cybran]:GetListOfUnits(categories.CARRIER, false) for i = 1, 2 do local carrier = units[i] - carrier:SetCustomName('Carrier' .. i) - local location - for num, loc in ArmyBrains[Cybran].PBM.Locations do - if loc.LocationType == 'M2_Cybran_Carrier_' .. i then - location = loc + for _, location in ArmyBrains[Cybran].PBM.Locations do + if location.LocationType == 'M2_Cybran_Carrier_' .. i then + location.PrimaryFactories.Air = carrier.ExternalFactory break end end - location.PrimaryFactories.Air = carrier - - ForkThread(function() - while carrier and not carrier:IsDead() do - if table.getn(carrier:GetCargo()) > 0 and carrier:IsIdleState() then - IssueClearCommands({carrier}) - IssueTransportUnload({carrier}, carrier:GetPosition()) + + carrier:ForkThread(function(self) + local factory = self.ExternalFactory + + while true do + if table.getn(self:GetCargo()) > 0 and factory:IsIdleState() then + IssueClearCommands({self}) + IssueTransportUnload({self}, carrier:GetPosition()) + + repeat + WaitSeconds(3) + until not self:IsUnitState("TransportUnloading") end + WaitSeconds(1) end end) diff --git a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2orderai.lua b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2orderai.lua index d3ec6d6..f521915 100644 --- a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2orderai.lua +++ b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2orderai.lua @@ -2,6 +2,7 @@ local BaseManager = import('/lua/ai/opai/basemanager.lua') local CustomFunctions = '/maps/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_CustomFunctions.lua' local SPAIFileName = '/lua/ScenarioPlatoonAI.lua' local ScenarioPlatoonAI = import(SPAIFileName) +local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua') local ThisFile = '/maps/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_m2orderai.lua' --------- @@ -401,26 +402,36 @@ end ----------- -- Carriers ----------- -function OrderM2CarriersAI(unit) +function OrderM2CarriersAI(carrier) ArmyBrains[Order]:PBMAddBuildLocation('M2_Order_Carrier_Marker_2', 40, 'M2_Order_Carrier_2') - if unit and not unit.Dead then - for num, loc in ArmyBrains[Order].PBM.Locations do - if loc.LocationType == 'M2_Order_Carrier_2' then - loc.PrimaryFactories.Air = unit - OrderM2CarrierAttacks() - break - end + for _, location in ArmyBrains[Order].PBM.Locations do + if location.LocationType == 'M2_Order_Carrier_2' then + location.PrimaryFactories.Air = carrier.ExternalFactory + OrderM2CarrierAttacks() + break end + end + + IssueClearFactoryCommands({carrier.ExternalFactory}) + IssueFactoryRallyPoint({carrier.ExternalFactory}, ScenarioUtils.MarkerToPosition("Rally Point 00")) + + carrier.ReleaseUnitsThread = carrier:ForkThread(function(self) + local factory = self.ExternalFactory + + while true do + if table.getn(self:GetCargo()) > 0 and factory:IsIdleState() then + IssueClearCommands({self}) + IssueTransportUnload({self}, carrier:GetPosition()) - while not unit.Dead do - if unit:IsIdleState() and unit:GetCargo()[1] then - IssueClearCommands({unit}) - IssueTransportUnload({unit}, unit:GetPosition()) + repeat + WaitSeconds(3) + until not self:IsUnitState("TransportUnloading") end + WaitSeconds(1) end - end + end) end function OrderM2CarrierAttacks() @@ -582,18 +593,19 @@ end ---------- -- Tempest ---------- -function OrderM2TempestAI(unit) +function OrderM2TempestAI(tempest) ArmyBrains[Order]:PBMAddBuildLocation('M2_Order_Starting_Tempest', 60, 'M2_Tempest1') - if unit and not unit.Dead then - for num, loc in ArmyBrains[Order].PBM.Locations do - if loc.LocationType == 'M2_Tempest1' then - loc.PrimaryFactories.Sea = unit - OrderM2TempestAttacks() - break - end + for _, location in ArmyBrains[Order].PBM.Locations do + if location.LocationType == 'M2_Tempest1' then + location.PrimaryFactories.Sea = tempest.ExternalFactory + OrderM2TempestAttacks() + break end end + + IssueClearFactoryCommands({tempest.ExternalFactory}) + IssueFactoryRallyPoint({tempest.ExternalFactory}, ScenarioUtils.MarkerToPosition("Naval Rally Point 00")) end function OrderM2TempestAttacks() diff --git a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_save.lua b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_save.lua index a1a49b3..3e11737 100644 --- a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_save.lua +++ b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_save.lua @@ -3382,10 +3382,10 @@ Scenario = { ['orientation'] = VECTOR3( 0, -0, 0 ), ['position'] = VECTOR3( 2055.5, 23.7891, 1284.5 ), }, - ['Rally Point 05'] = { + ['Naval Rally Point 08'] = { ['hint'] = BOOLEAN( true ), ['color'] = STRING( 'FF808000' ), - ['type'] = STRING( 'Rally Point' ), + ['type'] = STRING( 'Naval Rally Point' ), ['prop'] = STRING( '/env/common/props/markers/M_Defensive_prop.bp' ), ['orientation'] = VECTOR3( 0, -0, 0 ), ['position'] = VECTOR3( 2215.5, 17.5, 2221.5 ), diff --git a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_script.lua b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_script.lua index 0c0719d..715e735 100644 --- a/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_script.lua +++ b/FAF_Coop_Novax_Station_Assault/FAF_Coop_Novax_Station_Assault_script.lua @@ -176,10 +176,10 @@ function OnPopulate(scenario) -- Move Carrier to starting position together with the fleet IssueMove({ScenarioInfo.M1_Order_Carrier}, ScenarioUtils.MarkerToPosition('M1_Order_Carrier_Start_Marker')) - IssueMove(ScenarioInfo.M1_Carrier_Fleet, ScenarioUtils.MarkerToPosition('Rally Point 05')) + IssueMove(ScenarioInfo.M1_Carrier_Fleet, ScenarioUtils.MarkerToPosition('Naval Rally Point 08')) ForkThread(function() - while (ScenarioInfo.M1_Order_Carrier and not ScenarioInfo.M1_Order_Carrier.Dead and ScenarioInfo.M1_Order_Carrier:IsUnitState('Moving')) do + while (not ScenarioInfo.M1_Order_Carrier.Dead and ScenarioInfo.M1_Order_Carrier:IsUnitState('Moving')) do WaitSeconds(.5) end @@ -236,7 +236,7 @@ function OnPopulate(scenario) IssueMove({ScenarioInfo.M1_Order_Tempest}, ScenarioUtils.MarkerToPosition('M1_Order_Tempest_Start_Marker')) ForkThread(function() - while (ScenarioInfo.M1_Order_Tempest and not ScenarioInfo.M1_Order_Tempest.Dead and ScenarioInfo.M1_Order_Tempest:IsUnitState('Moving')) do + while (not ScenarioInfo.M1_Order_Tempest.Dead and ScenarioInfo.M1_Order_Tempest:IsUnitState('Moving')) do WaitSeconds(.5) end @@ -675,7 +675,7 @@ function M1SubmarineAttack() ScenarioFramework.PlatoonMoveRoute(ScenarioInfo.SubmarinePlatoon, {'M1_UEF_Submarine_Marker'}) -- Attack tempest if carries is dead - if ScenarioInfo.M1_Order_Carrier and not ScenarioInfo.M1_Order_Carrier.Dead then + if not ScenarioInfo.M1_Order_Carrier.Dead then ScenarioInfo.SubmarinePlatoon:AttackTarget(ScenarioInfo.M1_Order_Carrier) else ScenarioInfo.SubmarinePlatoon:AttackTarget(ScenarioInfo.M1_Order_Tempest) @@ -737,6 +737,8 @@ function IntroMission2() ArmyBrains[Order]:PBMRemoveBuildLocation(nil, 'AircraftCarrier1') ArmyBrains[Order]:PBMRemoveBuildLocation(nil, 'Tempest1') + ScenarioInfo.M1_Order_Carrier.ReleaseUnitsThread:Destroy() + -- Move Carrier, Tempest and Sonar close to the island, make sure they won't die when moving local data = { ['M2_Order_Carrier_Marker_2'] = ScenarioInfo.M1_Order_Carrier, @@ -746,6 +748,9 @@ function IntroMission2() for marker, unit in data do if unit and not unit.Dead then IssueClearCommands({unit}) + if unit.ExternalFactory then + IssueClearCommands({unit.ExternalFactory}) + end IssueMove({unit}, ScenarioUtils.MarkerToPosition(marker)) unit:SetCanTakeDamage(false) end @@ -836,7 +841,7 @@ function IntroMission2() counter = counter + 1 end - while (ScenarioInfo.M1_Order_Tempest and not ScenarioInfo.M1_Order_Tempest.Dead and ScenarioInfo.M1_Order_Tempest:IsUnitState('Moving')) do + while (not ScenarioInfo.M1_Order_Tempest.Dead and ScenarioInfo.M1_Order_Tempest:IsUnitState('Moving')) do WaitSeconds(.5) end @@ -845,33 +850,40 @@ function IntroMission2() -- If there are any units left in the carrier, make them patrol once carrier arrives to the island ForkThread(function() + local carrier = ScenarioInfo.M1_Order_Carrier WaitSeconds(1) -- This makes sure that the carrier gets moving before we start the check below - while (ScenarioInfo.M1_Order_Carrier and not ScenarioInfo.M1_Order_Carrier.Dead and ScenarioInfo.M1_Order_Carrier:IsUnitState('Moving')) do + while (not carrier.Dead and carrier:IsUnitState('Moving')) do WaitSeconds(.5) end - if ScenarioInfo.M1_Order_Carrier and not ScenarioInfo.M1_Order_Carrier.Dead then - if table.getn(ScenarioInfo.M1_Order_Carrier:GetCargo()) > 0 then - IssueClearCommands({ScenarioInfo.M1_Order_Carrier}) - IssueTransportUnload({ScenarioInfo.M1_Order_Carrier}, ScenarioInfo.M1_Order_Carrier:GetPosition()) + if carrier.Dead then + return + end - -- Just to be sure all units are out - WaitSeconds(5) + if table.getn(carrier:GetCargo()) > 0 then + IssueClearCommands({carrier}) + IssueTransportUnload({carrier}, carrier:GetPosition()) - local plat = ArmyBrains[Order]:MakePlatoon('', '') - for _, unit in ArmyBrains[Order]:GetListOfUnits(categories.AIR * categories.MOBILE, false) do - ArmyBrains[Order]:AssignUnitsToPlatoon(plat, {unit}, 'Attack', 'NoFormation') - IssueClearCommands({unit}) - ScenarioFramework.GroupPatrolRoute({unit}, ScenarioPlatoonAI.GetRandomPatrolRoute(ScenarioUtils.ChainToPositions('M2_Order_Base_AirDef_Chain'))) - end + -- Just to be sure all units are out + repeat + WaitSeconds(3) + until carrier.Dead or not carrier:IsUnitState("TransportUnloading") + + local plat = ArmyBrains[Order]:MakePlatoon('', '') + for _, unit in ArmyBrains[Order]:GetListOfUnits(categories.AIR * categories.MOBILE, false) do + ArmyBrains[Order]:AssignUnitsToPlatoon(plat, {unit}, 'Attack', 'NoFormation') + IssueClearCommands({unit}) + ScenarioFramework.GroupPatrolRoute({unit}, ScenarioPlatoonAI.GetRandomPatrolRoute(ScenarioUtils.ChainToPositions('M2_Order_Base_AirDef_Chain'))) end end - M2OrderAI.OrderM2CarriersAI(ScenarioInfo.M1_Order_Carrier) + if not carrier.Dead then + M2OrderAI.OrderM2CarriersAI(carrier) + end end) - if Difficulty <= 2 and ScenarioInfo.M1_Order_Sonar and not ScenarioInfo.M1_Order_Sonar.Dead then + if Difficulty <= 2 and not ScenarioInfo.M1_Order_Sonar.Dead then -- Make T3 Sonar Patrol, rebuild if killed local platoon = ArmyBrains[Order]:MakePlatoon('', '') ArmyBrains[Order]:AssignUnitsToPlatoon(platoon, {ScenarioInfo.M1_Order_Sonar}, 'Attack', 'NoFormation') diff --git a/FAF_Coop_Operation_Ioz_Shavoh_Kael/UEFaiP3.lua b/FAF_Coop_Operation_Ioz_Shavoh_Kael/UEFaiP3.lua index 7df015e..76a5b8f 100644 --- a/FAF_Coop_Operation_Ioz_Shavoh_Kael/UEFaiP3.lua +++ b/FAF_Coop_Operation_Ioz_Shavoh_Kael/UEFaiP3.lua @@ -28,45 +28,45 @@ function M3UEFFatboyBaseAI() P3UBase1:StartNonZeroBase({{5, 7, 9}, {2, 3, 4}}) P3UBase1:SetMaximumConstructionEngineers(5) P3UBase1:AddBuildGroup('P3UDefense1', 90) - - if Difficulty == 3 then - ArmyBrains[UEF]:PBMSetCheckInterval(6) - end - local M2_Fatboy1 = ScenarioInfo.M2_Fatboy1 + local M2_Fatboy = ScenarioInfo.M2_Fatboy + if M2_Fatboy.Dead then + return + end for _, location in ArmyBrains[UEF].PBM.Locations do if location.LocationType == 'P3UEFFatboybase1' then - location.PrimaryFactories.Land = M2_Fatboy1.ExternalFactory - M3UEFFatboyattacks1() + location.PrimaryFactories.Land = M2_Fatboy.ExternalFactory break end end - IssueClearFactoryCommands({M2_Fatboy1.ExternalFactory}) - IssueFactoryRallyPoint({M2_Fatboy1.ExternalFactory}, ScenarioUtils.MarkerToPosition("Rally Point 19")) + IssueClearFactoryCommands({M2_Fatboy.ExternalFactory}) + IssueFactoryRallyPoint({M2_Fatboy.ExternalFactory}, ScenarioUtils.MarkerToPosition('Rally Point 19')) + + M3UEFFatboyattacks1() end function M3UEFFatboyBase2AI() P3UBase3:InitializeDifficultyTables(ArmyBrains[UEF], 'P3UEFFatboybase2', 'P3UB2MK2', 20, {P3USbase3 = 100}) P3UBase3:StartNonZeroBase({{2, 3, 4}, {2, 3, 4}}) - if Difficulty == 3 then - ArmyBrains[UEF]:PBMSetCheckInterval(6) - end - local M2_Fatboy2 = ScenarioInfo.M2_Fatboy2 + if M2_Fatboy2.Dead then + return + end for _, location in ArmyBrains[UEF].PBM.Locations do if location.LocationType == 'P3UEFFatboybase2' then location.PrimaryFactories.Land = M2_Fatboy2.ExternalFactory - M3UEFFatboyattacks2() break end end IssueClearFactoryCommands({M2_Fatboy2.ExternalFactory}) - IssueFactoryRallyPoint({M2_Fatboy2.ExternalFactory}, ScenarioUtils.MarkerToPosition("Rally Point 21")) + IssueFactoryRallyPoint({M2_Fatboy2.ExternalFactory}, ScenarioUtils.MarkerToPosition('Rally Point 21')) + + M3UEFFatboyattacks2() end function M3UEFAtlantisBaseAI() @@ -95,7 +95,7 @@ function M3UEFAtlantisBaseAI() if table.getn(self:GetCargo()) > 0 and factory:IsIdleState() then IssueClearCommands({self}) IssueTransportUnload({self}, ScenarioUtils.MarkerToPosition('Rally Point 20')) - + repeat WaitSeconds(3) until not self:IsUnitState("TransportUnloading") diff --git a/FAF_Coop_Operation_Trident/FAF_Coop_Operation_Trident_UEFAI.lua b/FAF_Coop_Operation_Trident/FAF_Coop_Operation_Trident_UEFAI.lua index 05304d7..c96c896 100644 --- a/FAF_Coop_Operation_Trident/FAF_Coop_Operation_Trident_UEFAI.lua +++ b/FAF_Coop_Operation_Trident/FAF_Coop_Operation_Trident_UEFAI.lua @@ -195,24 +195,33 @@ function M2UEFAtlantisBaseAI() WaitSeconds(1) -- Mark it as a primary factory so it produces air units - local Carrier = ScenarioInfo.M2Atlantis - local location - for num, loc in ArmyBrains[UEF].PBM.Locations do - if loc.LocationType == 'M2_UEF_Sea_Base' then - location = loc + local carrier = ScenarioInfo.M2Atlantis + local factory = carrier.ExternalFactory + + for _, location in ArmyBrains[UEF].PBM.Locations do + if location.LocationType == 'M2_UEF_Sea_Base' then + location.PrimaryFactories.Air = factory break end end - location.PrimaryFactories.Air = Carrier -- Gotta release the units once the platoon is built - while Carrier and not Carrier.Dead do - if table.getn(Carrier:GetCargo()) > 0 and Carrier:IsIdleState() then - IssueClearCommands({Carrier}) - IssueTransportUnload({Carrier}, ScenarioUtils.MarkerToPosition('Rally Point 06')) + carrier.ReleaseUnitsThread = carrier:ForkThread(function(self) + local factory = self.ExternalFactory + + while true do + if table.getn(self:GetCargo()) > 0 and factory:IsIdleState() then + IssueClearCommands({self}) + IssueTransportUnload({self}, ScenarioUtils.MarkerToPosition('Rally Point 06')) + + repeat + WaitSeconds(3) + until not self:IsUnitState("TransportUnloading") + end + + WaitSeconds(1) end - WaitSeconds(1) - end + end) end ) end diff --git a/FAF_Coop_Operation_Trident/FAF_Coop_Operation_Trident_script.lua b/FAF_Coop_Operation_Trident/FAF_Coop_Operation_Trident_script.lua index 704634d..b4fcb18 100644 --- a/FAF_Coop_Operation_Trident/FAF_Coop_Operation_Trident_script.lua +++ b/FAF_Coop_Operation_Trident/FAF_Coop_Operation_Trident_script.lua @@ -603,7 +603,7 @@ function StartMission1() ScenarioFramework.CreateTimerTrigger(M1LaunchAeonAttack, 25*60) -- Taunts - SetupUEFM1Taunts() + ForkThread(SetupUEFM1Taunts) end function MissionNameAnnouncement() @@ -1455,10 +1455,13 @@ function SetupUEFM1Taunts() -- UEF taunt, when Player1 is spotted UEFTM:AddIntelCategoryTaunt('M1UEFDialogue', ArmyBrains[UEF], ArmyBrains[Player1], categories.ALLUNITS) - -- When player's ACU takes damage - if not SkipNIS1 then - UEFTM:AddDamageTaunt('TAUNT1', ScenarioInfo.Player1ACU, 0.2) + -- Player's ACU is given from the AI after it's dropped, so gotta wait for it to actually exist + while not ScenarioInfo.Player1ACU do + WaitSeconds(1) end + + -- When player's ACU takes damage + UEFTM:AddDamageTaunt('TAUNT1', ScenarioInfo.Player1ACU, 0.2) -- On losing first defensive structures UEFTM:AddUnitsKilledTaunt('TAUNT2', ArmyBrains[UEF], categories.STRUCTURE * categories.DEFENSE, 1) diff --git a/FAF_Coop_Prothyon_16/FAF_Coop_Prothyon_16_CustomFunctions.lua b/FAF_Coop_Prothyon_16/FAF_Coop_Prothyon_16_CustomFunctions.lua index 158587f..6048f6d 100644 --- a/FAF_Coop_Prothyon_16/FAF_Coop_Prothyon_16_CustomFunctions.lua +++ b/FAF_Coop_Prothyon_16/FAF_Coop_Prothyon_16_CustomFunctions.lua @@ -2,7 +2,6 @@ local ScenarioFramework = import('/lua/ScenarioFramework.lua') local ScenarioPlatoonAI = import('/lua/ScenarioPlatoonAI.lua') local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua') --- TODO: Create new build location with carrier. function CarrierAI(platoon) platoon:Stop() local aiBrain = platoon:GetBrain() @@ -10,61 +9,69 @@ function CarrierAI(platoon) local carriers = platoon:GetPlatoonUnits() local movePositions = {} - if(data) then - if(data.MoveRoute or data.MoveChain) then - if data.MoveChain then - movePositions = ScenarioUtils.ChainToPositions(data.MoveChain) - else - for k, v in data.MoveRoute do - if type(v) == 'string' then - table.insert(movePositions, ScenarioUtils.MarkerToPosition(v)) - else - table.insert(movePositions, v) - end - end - end + if not data then + error('*Carrier AI ERROR: PlatoonData not defined', 2) + elseif not (data.MoveRoute or data.MoveChain) then + error('*Carrier AI ERROR: MoveToRoute or MoveChain not defined', 2) + end + - local numCarriers = table.getn(carriers) - local numPositions = table.getn(movePositions) - - if numCarriers <= numPositions then - for i = 1, numCarriers do - ForkThread(function(i) - IssueMove( {carriers[i]}, movePositions[i] ) - - while (carriers[i] and not carriers[i]:IsDead() and carriers[i]:IsUnitState('Moving')) do - WaitSeconds(.5) - end - - local location - for num, loc in aiBrain.PBM.Locations do - if loc.LocationType == data.Location .. i then - location = loc - break - end - end - - if not carriers[i]:IsDead() then - location.PrimaryFactories.Air = carriers[i] - end - - while (carriers[i] and not carriers[i]:IsDead()) do - if table.getn(carriers[i]:GetCargo()) > 0 and carriers[i]:IsIdleState() then - IssueClearCommands(carriers[i]) - IssueTransportUnload({carriers[i]}, carriers[i]:GetPosition()) - end - WaitSeconds(1) - end - end, i) - end + if data.MoveChain then + movePositions = ScenarioUtils.ChainToPositions(data.MoveChain) + else + for k, v in data.MoveRoute do + if type(v) == 'string' then + table.insert(movePositions, ScenarioUtils.MarkerToPosition(v)) else - error('*Carrier AI ERROR: Less mvoe positions than carriers', 2) + table.insert(movePositions, v) end - else - error('*Carrier AI ERROR: MoveToRoute or MoveChain not defined', 2) end - else - error('*Carrier AI ERROR: PlatoonData not defined', 2) + end + + local numCarriers = table.getn(carriers) + local numPositions = table.getn(movePositions) + + if numPositions < numCarriers then + error('*Carrier AI ERROR: Less mvoe positions than carriers', 2) + end + + for i = 1, numCarriers do + ForkThread(function(i) + local carrier = carriers[i] + IssueMove({carrier}, movePositions[i]) + + while (not carrier:IsDead() and carrier:IsUnitState('Moving')) do + WaitSeconds(.5) + end + + if carrier.Dead then + return + end + + for _, location in aiBrain.PBM.Locations do + if location.LocationType == data.Location .. i then + location.PrimaryFactories.Air = carrier.ExternalFactory + break + end + end + + carrier:ForkThread(function(self) + local factory = self.ExternalFactory + + while true do + if table.getn(self:GetCargo()) > 0 and factory:IsIdleState() then + IssueClearCommands({self}) + IssueTransportUnload({self}, carrier:GetPosition()) + + repeat + WaitSeconds(3) + until not self:IsUnitState("TransportUnloading") + end + + WaitSeconds(1) + end + end) + end, i) end end diff --git a/SCCA_Coop_R06/SCCA_Coop_R06_script.lua b/SCCA_Coop_R06/SCCA_Coop_R06_script.lua index a58a619..54ef9cb 100644 --- a/SCCA_Coop_R06/SCCA_Coop_R06_script.lua +++ b/SCCA_Coop_R06/SCCA_Coop_R06_script.lua @@ -759,34 +759,6 @@ function StartMission2() -- M2P1 Objective Reminder ScenarioFramework.CreateTimerTrigger(M2P1Reminder, ObjectiveReminderTime) - -- Moved to part 1 for convenience - --[[local num = {5, 6, 7} - --------------------------------------------------- - -- Secondary Objective 2 - Build SMDs - -- Reward for completion: Cybran T3 Heavy Artillery - --------------------------------------------------- - ScenarioInfo.M2S1 = Objectives.ArmyStatCompare( - 'secondary', -- type - 'incomplete', -- complete - OpStrings.OpC06_M2S1_Title, -- title - LOCF(OpStrings.OpC06_M2S1_Desc, num[Difficulty]), -- description - 'build', -- action - { -- target - Armies = {'HumanPlayers'}, - StatName = 'Units_Active', - CompareOp = '>=', - Value = num[Difficulty], - Category = (categories.urb4302), - ShowProgress = true, - } - ) - ScenarioInfo.M2S1:AddResultCallback( - function(result) - if result then - ScenarioFramework.RemoveRestrictionForAllHumans(categories.urb2302, true) -- Cybran Long Range Heavy Artillery - end - end - )]] end function GateBuilt()