From 3d1dcd78a3ff6cec030faa0844f6a30e1bee1933 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 24 May 2026 13:00:53 +0200 Subject: [PATCH] #SPAWN - fix SpawnOnRunway if definitely requested (SP only!) --- Moose Development/Moose/Core/Base.lua | 2 +- Moose Development/Moose/Core/Spawn.lua | 10 ++++-- Moose Development/Moose/Ops/TARS.lua | 43 ++++++++++++++------------ 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/Moose Development/Moose/Core/Base.lua b/Moose Development/Moose/Core/Base.lua index 81cf8892d..95d8858b7 100644 --- a/Moose Development/Moose/Core/Base.lua +++ b/Moose Development/Moose/Core/Base.lua @@ -855,7 +855,7 @@ end -- @param DCS#Time EventTime The time stamp of the event. -- @param DCS#Object Initiator The initiating object of the event. function BASE:CreateEventTakeoff( EventTime, Initiator ) - self:F( { EventTime, Initiator } ) + --self:F( { EventTime, Initiator } ) local Event = { id = world.event.S_EVENT_TAKEOFF, diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index 6a88872b6..3e5ffea8a 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -2331,9 +2331,15 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT Takeoff = GROUP.Takeoff.Air spawnonground = false - else + else + if not Takeoff == GROUP.Takeoff.Runway then self:E( string.format( "WARNING: Group %s has no parking spots at %s ==> No emergency air start or uncontrolled spawning ==> No spawn!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) ) return nil + else + Takeoff = GROUP.Takeoff.Runway + spawnonground = false + self:E( string.format( "WARNING: Group %s set to runway spawning at %s, this only works in Single Player!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) ) + end end end @@ -2392,7 +2398,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT else - -- Spawn in air as requested initially. Original template orientation is perserved, altitude is already correctly set. + -- Spawn in air as requested initially. Original template orientation is preserved, altitude is already correctly set. SpawnTemplate.units[UnitID].x = TX SpawnTemplate.units[UnitID].y = TY SpawnTemplate.units[UnitID].alt = PointVec3.y diff --git a/Moose Development/Moose/Ops/TARS.lua b/Moose Development/Moose/Ops/TARS.lua index f83ecd070..00390cc13 100644 --- a/Moose Development/Moose/Ops/TARS.lua +++ b/Moose Development/Moose/Ops/TARS.lua @@ -118,21 +118,21 @@ TARS_SESSION.debugunitsearch = false -- your mission before loading. -- -- ## Player workflow --- 1. Spawn into a recon-capable slot and open the **F10 › Task TARS** radio menu. +-- 1. Spawn into a recon-capable slot and open the **F10 › Task TARS** radio menu. -- 2. Select **TARS validation** on the ground. The system checks your loadout and --- reports the platform's altitude band, FOV, and available film. --- The validation item then disappears once approved. --- 3. Take off. **Start filming / STB & Resume / Stop filming** appear in the menu. --- 4. Select **TARS mode : Start filming** to begin recording. --- 5. Fly over enemy units within the sensor's altitude/attitude envelope. --- Each detected unit is confirmed in the HUD (`+1 Captured target`). --- 6. Use **TARS mode : STB & Resume** to pause (e.g. to refuel). --- Film resumes automatically on the next takeoff if the loadout is still valid. --- 7. Select **TARS mode : Stop filming** or let the film timer expire. --- 8. Land at an allied airbase or FARP within `TARS.landingDistance` metres. +-- reports the platform's altitude band, FOV, and available film. +-- The validation item then disappears once approved. +-- 3. Take off. **Start filming / STB & Resume / Stop filming** appear in the menu. +-- 4. Select **TARS mode : Start filming** to begin recording. +-- 5. Fly over enemy units within the sensor's altitude/attitude envelope. +-- Each detected unit is confirmed in the HUD (`+1 Captured target`). +-- 6. Use **TARS mode : STB & Resume** to pause (e.g. to refuel). +-- Film resumes automatically on the next takeoff if the loadout is still valid. +-- 7. Select **TARS mode : Stop filming** or let the film timer expire. +-- 8. Land at an allied airbase or FARP within `TARS.landingDistance` metres. -- The film controls disappear. After `landingDelay + debriefDelay` seconds the --- intel marks appear on the F10 map and scoring credits are awarded. --- After the debrief the **TARS validation** item reappears for the next sortie. +-- intel marks appear on the F10 map and scoring credits are awarded. +-- After the debrief the **TARS validation** item reappears for the next sortie. -- -- ## Localization -- @@ -274,7 +274,7 @@ TARS = {} -- @field #string playerName Player display name. --- Frozen target snapshot. --- @type TARS.Snapshot +-- @type TARS.Snapshot #TARS.Snapshot -- @field Wrapper.Unit#UNIT unit MOOSE UNIT wrapper or STATIC wrapper. -- @field DCS#Object dcsObj Raw DCS object reference. -- @field #number category `Object.Category.*` of the detected object. @@ -294,7 +294,7 @@ TARS = {} ------------------------------------------------- --- @field #string version -TARS.version = "v2.3.1" +TARS.version = "v2.3.2" --- Active locale. -- @field #string locale @@ -1804,7 +1804,7 @@ function TARS:_OnEventBirth(EventData) if not unit then return end local instance = self:GetInstance(unit:GetName()) if instance then instance:Delete() end - local playerName = unit:GetPlayerName() + local playerName = EventData.IniPlayerName --unit:GetPlayerName() if not playerName then return end local pName = playerName timer.scheduleFunction(function() @@ -1818,6 +1818,7 @@ end -- @param #TARS self -- @param Core.Event#EVENTDATA EventData function TARS:_OnEventEngineStartup(EventData) + if EventData.IniPlayerName == nil then return end local unit = EventData.IniUnit if not unit or not unit:GetPlayerName() then return end local pName = unit:GetPlayerName() @@ -1835,7 +1836,7 @@ function TARS:_OnEventDead(EventData) local unit = EventData.IniUnit if not unit then return end local name = unit:GetName() - local playerName = unit:GetPlayerName() or unit:GetName() + local playerName = EventData.IniPlayerName --unit:GetPlayerName() or unit:GetName() if TARS.groundMenus[playerName] then self:RemoveGroundMenu(playerName) end if self.detectedTargets[name] then local markID = self.marks.blue[name] or self.marks.red[name] @@ -1852,7 +1853,7 @@ end function TARS:_OnEventPlayerLeaveUnit(EventData) local unit = EventData.IniUnit if not unit then return end - local playerName = unit:GetPlayerName() or unit:GetName() + local playerName = EventData.IniPlayerName --unit:GetPlayerName() or unit:GetName() if TARS.groundMenus[playerName] then self:RemoveGroundMenu(playerName) end end @@ -1863,11 +1864,12 @@ end -- @param Core.Event#EVENTDATA EventData function TARS:_OnEventTakeOff(EventData) self:T(self.lid.."_OnEventTakeOff") + if EventData.IniPlayerName == nil then return end local unit = EventData.IniUnit if not unit then return end local instance = self:GetInstance(unit:GetName()) local now = timer.getTime() - + -- Branch 1: auto-resume after ground STB if instance and instance.capturing then if instance.lastTakeoffTime and (now - instance.lastTakeoffTime) < 5 then return end @@ -1903,7 +1905,8 @@ function TARS:_OnEventTakeOff(EventData) if instance and instance.lastTakeoffTime and (now - instance.lastTakeoffTime) < 5 then return end - local playerName = unit:GetPlayerName() or unit:GetName() + local playerName = EventData.IniPlayerName --unit:GetPlayerName() or unit:GetName() + if playerName == nil then return end local groundData = TARS.groundMenus[playerName] if not (groundData and groundData.approved) then return end