From 2eeca4451c593109cb9bc36a03c4acd8f08614d3 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 20 Feb 2024 14:31:53 +0100 Subject: [PATCH] SPAWN/DATABASE * Try to ensure unique Link16 STN/SADL octal IDs * Added `SPAWN:InitSTN(Octal)` and `SPAWN:InitSADL(Octal)` --- Moose Development/Moose/Core/Database.lua | 93 ++++++++++++++++++++++- Moose Development/Moose/Core/Spawn.lua | 86 ++++++++++++++++----- 2 files changed, 158 insertions(+), 21 deletions(-) diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 14b99fc76..8ffedba7b 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -37,6 +37,8 @@ -- @field #table Templates Templates: Units, Groups, Statics, ClientsByName, ClientsByID. -- @field #table CLIENTS Clients. -- @field #table STORAGES DCS warehouse storages. +-- @field #table STNS Used Link16 octal numbers for F16/15/18/AWACS planes. +-- @field #table SADL Used Link16 octal numbers for A10/C-II planes. -- @extends Core.Base#BASE --- Contains collections of wrapper objects defined within MOOSE that reflect objects within the simulator. @@ -93,6 +95,8 @@ DATABASE = { OPSZONES = {}, PATHLINES = {}, STORAGES = {}, + STNS={}, + SADL={}, } local _DATABASECoalition = @@ -1029,10 +1033,23 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category self.Templates.ClientsByName[UnitTemplate.name].CountryID = CountryID self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate end + + if UnitTemplate.AddPropAircraft then + if UnitTemplate.AddPropAircraft.STN_L16 then + local stn = UTILS.OctalToDecimal(UnitTemplate.AddPropAircraft.STN_L16) + self.STNS[stn] = UnitTemplate.name + self:I("Register STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name) + end + if UnitTemplate.AddPropAircraft.SADL_TN then + local sadl = UTILS.OctalToDecimal(UnitTemplate.AddPropAircraft.SADL_TN) + self.SADL[sadl] = UnitTemplate.name + self:I("Register SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name) + end + end UnitNames[#UnitNames+1] = self.Templates.Units[UnitTemplate.name].UnitName end - + -- Debug info. self:T( { Group = self.Templates.Groups[GroupTemplateName].GroupName, Coalition = self.Templates.Groups[GroupTemplateName].CoalitionID, @@ -1043,6 +1060,80 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category ) end +--- Get next (consecutive) free STN as octal number. +-- @param #DATABASE self +-- @param #number octal Starting octal. +-- @param #string unitname Name of the associated unit. +-- @return #number Octal +function DATABASE:GetNextSTN(octal,unitname) + local first = UTILS.OctalToDecimal(octal) + if self.STNS[first] == unitname then return octal end + local nextoctal = 77777 + local found = false + if 32767-first < 10 then + first = 0 + end + for i=first+1,32767 do + if self.STNS[i] == nil then + found = true + nextoctal = UTILS.DecimalToOctal(i) + self.STNS[i] = unitname + self:T("Register STN "..tostring(nextoctal).." for ".. unitname) + break + end + end + if not found then + self:E(string.format("WARNING: No next free STN past %05d found!",octal)) + -- cleanup + local NewSTNS = {} + for _id,_name in pairs(self.STNS) do + if self.UNITS[_name] ~= nil then + NewSTNS[_id] = _name + end + end + self.STNS = nil + self.STNS = NewSTNS + end + return nextoctal +end + +--- Get next (consecutive) free SADL as octal number. +-- @param #DATABASE self +-- @param #number octal Starting octal. +-- @param #string unitname Name of the associated unit. +-- @return #number Octal +function DATABASE:GetNextSADL(octal,unitname) + local first = UTILS.OctalToDecimal(octal) + if self.SADL[first] == unitname then return octal end + local nextoctal = 7777 + local found = false + if 4095-first < 10 then + first = 0 + end + for i=first+1,4095 do + if self.STNS[i] == nil then + found = true + nextoctal = UTILS.DecimalToOctal(i) + self.SADL[i] = unitname + self:T("Register SADL "..tostring(nextoctal).." for ".. unitname) + break + end + end + if not found then + self:E(string.format("WARNING: No next free SADL past %04d found!",octal)) + -- cleanup + local NewSTNS = {} + for _id,_name in pairs(self.SADL) do + if self.UNITS[_name] ~= nil then + NewSTNS[_id] = _name + end + end + self.SADL = nil + self.SADL = NewSTNS + end + return nextoctal +end + --- Get group template. -- @param #DATABASE self -- @param #string GroupName Group name. diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index c34c8ccbd..97d30dfe5 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -780,6 +780,34 @@ function SPAWN:InitSkill( Skill ) return self end +--- [Airplane - F15/16/18/AWACS/B1B/Tanker only] Set the STN Link16 starting number of the Group; each unit of the spawned group will have a consecutive STN set. +-- @param #SPAWN self +-- @param #number Octal The octal number (digits 1..7, max 5 digits, i.e. 77777) to set the STN to. Every STN needs to be unique! +-- @return #SPAWN self +function SPAWN:InitSTN(Octal) + self:F( { Octal = Octal } ) + self.SpawnInitSTN = Octal or 77777 + local num = UTILS.OctalToDecimal(Octal) + if _DATABASE.STNS[num] ~= nil then + self:E("WARNING - STN already assigned: "..tostring(Octal).." is used for ".._DATABASE.STNS[Octal]) + end + return self +end + +--- [Airplane - A10-C II only] Set the SADL TN starting number of the Group; each unit of the spawned group will have a consecutive SADL set. +-- @param #SPAWN self +-- @param #number Octal The octal number (digits 1..7, max 4 digits, i.e. 7777) to set the SADL to. Every SADL needs to be unique! +-- @return #SPAWN self +function SPAWN:InitSADL(Octal) + self:F( { Octal = Octal } ) + self.SpawnInitSADL = Octal or 7777 + local num = UTILS.OctalToDecimal(Octal) + if _DATABASE.SADL[num] ~= nil then + self:E("WARNING - SADL already assigned: "..tostring(Octal).." is used for ".._DATABASE.SADL[Octal]) + end + return self +end + --- Sets the radio communication on or off. Same as checking/unchecking the COMM box in the mission editor. -- @param #SPAWN self -- @param #number switch If true (or nil), enables the radio communication. If false, disables the radio for the spawned group. @@ -3400,30 +3428,48 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) -- R2.2 local AddProps = SpawnTemplate.units[UnitID].AddPropAircraft if AddProps then if SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 then - -- 4 digit octal with leading 0 - if tonumber(SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16) ~= nil then - local octal = SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 - local decimal = UTILS.OctalToDecimal(octal)+UnitID-1 - SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 = string.format("%05d",UTILS.DecimalToOctal(decimal)) - else -- ED bug - chars in here - local STN = math.floor(UTILS.RandomGaussian(4088/2,nil,1000,4088)) - STN = STN+UnitID-1 - local OSTN = UTILS.DecimalToOctal(STN) - SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 = string.format("%05d",OSTN) + if self.SpawnInitSTN then + local octal = self.SpawnInitSTN + if UnitID > 1 then + octal = _DATABASE:GetNextSTN(self.SpawnInitSTN,SpawnTemplate.units[UnitID].name) + end + SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 = string.format("%05d",octal) + else + -- 5 digit octal with leading 0 + if tonumber(SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16) ~= nil then + local octal = SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 + local num = UTILS.OctalToDecimal(octal) + if _DATABASE.STNS[num] ~= nil or UnitID > 1 then -- STN taken or next unit + octal = _DATABASE:GetNextSTN(octal,SpawnTemplate.units[UnitID].name) + end + SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 = string.format("%05d",octal) + else -- ED bug - chars in here + local OSTN = _DATABASE:GetNextSTN(1,SpawnTemplate.units[UnitID].name) + SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 = string.format("%05d",OSTN) + end end end -- A10CII if SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN then - -- 3 digit octal with leading 0 - if tonumber(SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN) ~= nil then - local octal = SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN - local decimal = UTILS.OctalToDecimal(octal)+UnitID-1 - SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN = string.format("%04d",UTILS.DecimalToOctal(decimal)) - else -- ED bug - chars in here - local STN = math.floor(UTILS.RandomGaussian(504/2,nil,100,504)) - STN = STN+UnitID-1 - local OSTN = UTILS.DecimalToOctal(STN) - SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN = string.format("%04d",OSTN) + -- 4 digit octal with leading 0 + if self.SpawnInitSADL then + local octal = self.SpawnInitSADL + if UnitID > 1 then + octal = _DATABASE:GetNextSADL(self.SpawnInitSADL,SpawnTemplate.units[UnitID].name) + end + SpawnTemplate.units[UnitID].AddPropAircraft.STN_L16 = string.format("%04d",octal) + else + if tonumber(SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN) ~= nil then + local octal = SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN + local num = UTILS.OctalToDecimal(octal) + if _DATABASE.SADL[num] ~= nil or UnitID > 1 then -- SADL taken or next unit + octal = _DATABASE:GetNextSADL(self.SpawnInitSADL,SpawnTemplate.units[UnitID].name) + end + SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN = string.format("%04d",octal) + else -- ED bug - chars in here + local OSTN = _DATABASE:GetNextSADL(1,SpawnTemplate.units[UnitID].name) + SpawnTemplate.units[UnitID].AddPropAircraft.SADL_TN = string.format("%04d",OSTN) + end end end -- VoiceCallsignNumber