diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index 803744936..ce72e1258 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -471,6 +471,121 @@ do -- COORDINATE return x - Precision <= self.x and x + Precision >= self.x and z - Precision <= self.z and z + Precision >= self.z end + --- + --Box volume scanning function matching MOOSE COORDINATE:ScanObjects() structure + --For use as COORDINATE:ScanObjectsSquare(sideLength, scanunits, scanstatics, scanscenery) + --Creates a cubic search volume with the COORDINATE as the lower-left (southwest) corner. + --Perfect for grid-based map scanning: increment X and Z by sideLength for next grid cell. + -- @param #COORDINATE self + -- @param #number radius (Optional) Scan radius in meters. Default 100 m. + -- @param #boolean scanunits (Optional) If true scan for units. Default true. + -- @param #boolean scanstatics (Optional) If true scan for static objects. Default true. + -- @param #boolean scanscenery (Optional) If true scan for scenery objects. Default false. + -- @return #boolean True if units were found. + -- @return #boolean True if statics were found. + -- @return #boolean True if scenery objects were found. + -- @return #table Table of MOOSE @{Wrapper.Unit#UNIT} objects found. + -- @return #table Table of DCS static objects found. + -- @return #table Table of DCS scenery objects found. + function COORDINATE:ScanObjectsSquare(sideLength, scanunits, scanstatics, scanscenery) + self:F(string.format("Scanning cube volume (lower-left corner) with side length %.1f m.", sideLength)) + + local CornerVec3 = self:GetVec3() + local CenterY = CornerVec3.y + + local MinVec3 = { + x = CornerVec3.x, + y = CenterY - (sideLength / 2), + z = CornerVec3.z + } + local MaxVec3 = { + x = CornerVec3.x + sideLength, + y = CenterY + (sideLength / 2), + z = CornerVec3.z + sideLength + } + + local BoxSearch = { + id = world.VolumeType.BOX, + params = { + min = MinVec3, + max = MaxVec3, + } + } + + -- Defaults + if scanunits==nil then + scanunits=true + end + if scanstatics==nil then + scanstatics=true + end + if scanscenery==nil then + scanscenery=false + end + + -- {Object.Category.UNIT, Object.Category.STATIC, Object.Category.SCENERY} + local scanobjects={} + if scanunits then + table.insert(scanobjects, Object.Category.UNIT) + end + if scanstatics then + table.insert(scanobjects, Object.Category.STATIC) + end + if scanscenery then + table.insert(scanobjects, Object.Category.SCENERY) + end + + -- Found stuff. + local Units = {} + local Statics = {} + local Scenery = {} + local gotstatics=false + local gotunits=false + local gotscenery=false + + local function EvaluateZone( ZoneObject ) + + if ZoneObject then + + -- Get category of scanned object. + local ObjectCategory = ZoneObject:getCategory() + + -- Check for unit or static objects + if (ObjectCategory == Object.Category.UNIT and ZoneObject:isExist()) then + + table.insert(Units, ZoneObject) + gotunits=true + + elseif (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then + + table.insert(Statics, ZoneObject) + gotstatics=true + + elseif ObjectCategory == Object.Category.SCENERY then + + table.insert(Scenery, ZoneObject) + gotscenery=true + + end + + end + + return true + end + + -- Search the world. + world.searchObjects(scanobjects, BoxSearch, EvaluateZone) + + for _,unit in pairs(Units) do + if not unit:isExist() then + gotunits=false + end + end + + return gotunits, gotstatics, gotscenery, Units, Statics, Scenery + end + + --- Scan/find objects (units, statics, scenery) within a certain radius around the coordinate using the world.searchObjects() DCS API function. -- @param #COORDINATE self -- @param #number radius (Optional) Scan radius in meters. Default 100 m. diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 73324b79d..ddf836bb5 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -8113,11 +8113,12 @@ end -- @param #string Type Type of this zone, #CTLD.CargoZoneType -- @param #number Color Smoke/Flare color e.g. #SMOKECOLOR.Red -- @param #string Active Is this zone currently active? --- @param #string HasBeacon Does this zone have a beacon if it is active? --- @param #number Shiplength Length of Ship for shipzones --- @param #number Shipwidth Width of Ship for shipzones +-- @param #string (Optional) HasBeacon Does this zone have a beacon if it is active? +-- @param #number (Optional) Shiplength Length of Ship for shipzones +-- @param #number (Optional) Shipwidth Width of Ship for shipzones +-- @param #table (Optional) BeaconFrequencies PreSet Frequencies in MHz (Million(!) Hertz), table of values , e.g. `{FM=0.124,UHF=215,VHF=110}` -- @return #CTLD self -function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon, Shiplength, Shipwidth) +function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon, Shiplength, Shipwidth, BeaconFrequencies) self:T(self.lid .. " AddCTLDZone") local zone = ZONE:FindByName(Name) @@ -8156,6 +8157,11 @@ function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon, Shiplength, Ship ctldzone.fmbeacon = self:_GetFMBeacon(Name) ctldzone.uhfbeacon = self:_GetUHFBeacon(Name) ctldzone.vhfbeacon = self:_GetVHFBeacon(Name) + if BeaconFrequencies then + ctldzone.fmbeacon.frequency = BeaconFrequencies.FM or ctldzone.fmbeacon.frequency + ctldzone.vhfbeacon.frequency = BeaconFrequencies.VHF or ctldzone.vhfbeacon.frequency + ctldzone.uhfbeacon.frequency = BeaconFrequencies.UHF or ctldzone.uhfbeacon.frequency + end else ctldzone.fmbeacon = nil ctldzone.uhfbeacon = nil @@ -8369,7 +8375,7 @@ function CTLD:_AddRadioBeacon(Name, Sound, Mhz, Modulation, IsShip, IsDropped) else local ZoneCoord = Zone:GetCoordinate() local ZoneVec3 = ZoneCoord:GetVec3() or {x=0,y=0,z=0} - local Frequency = Mhz * 1000000 -- Freq in Hert + local Frequency = Mhz * 1000000 -- Freq in Hertz local Sound = self.RadioPath..Sound trigger.action.radioTransmission(Sound, ZoneVec3, Modulation, false, Frequency, 1000, Name..math.random(1,10000)) -- Beacon in MP only runs for 30secs straightt self:T2(string.format("Beacon added | Name = %s | Sound = %s | Vec3 = {x=%d, y=%d, z=%d} | Freq = %f | Modulation = %d (0=AM/1=FM)",Name,Sound,ZoneVec3.x,ZoneVec3.y,ZoneVec3.z,Mhz,Modulation))