mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge remote-tracking branch 'origin/master' into branch
# Conflicts: # Moose Development/Moose/Utilities/Utils.lua
This commit is contained in:
commit
c75022038c
@ -1054,6 +1054,7 @@ end
|
|||||||
--- NOTE: This is not a spawn randomizer.
|
--- NOTE: This is not a spawn randomizer.
|
||||||
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area.
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area.
|
||||||
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
-- @param #SPAWN self
|
||||||
-- @param #boolean OnOff Enable/disable the feature.
|
-- @param #boolean OnOff Enable/disable the feature.
|
||||||
-- @param #number MaxRadius (Optional) Max radius to search for valid ground locations in meters. Default is double the max radius of the units.
|
-- @param #number MaxRadius (Optional) Max radius to search for valid ground locations in meters. Default is double the max radius of the units.
|
||||||
-- @param #number Spacing (Optional) Minimum spacing between units in meters. Default is 5% of the search radius or 5 meters, whichever is larger.
|
-- @param #number Spacing (Optional) Minimum spacing between units in meters. Default is 5% of the search radius or 5 meters, whichever is larger.
|
||||||
|
|||||||
@ -378,6 +378,20 @@ function SPAWNSTATIC:InitLinkToUnit(Unit, OffsetX, OffsetY, OffsetAngle)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Uses Disposition and other fallback logic to find a better and valid ground spawn position.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to a find clear ground location avoiding trees, water, roads, runways, map scenery, other statics and other units in the area.
|
||||||
|
--- Uses the initial position if it's a valid location.
|
||||||
|
-- @param #SPAWNSTATIC self
|
||||||
|
-- @param #boolean OnOff Enable/disable the feature.
|
||||||
|
-- @param #number MaxRadius (Optional) Max radius to search for a valid ground location in meters. Default is 10 times the max radius of the static.
|
||||||
|
-- @return #SPAWNSTATIC self
|
||||||
|
function SPAWNSTATIC:InitValidateAndRepositionStatic(OnOff, MaxRadius)
|
||||||
|
self.ValidateAndRepositionStatic = OnOff
|
||||||
|
self.ValidateAndRepositionStaticMaxRadius = MaxRadius
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Allows to place a CallFunction hook when a new static spawns.
|
--- Allows to place a CallFunction hook when a new static spawns.
|
||||||
-- The provided method will be called when a new group is spawned, including its given parameters.
|
-- The provided method will be called when a new group is spawned, including its given parameters.
|
||||||
-- The first parameter of the SpawnFunction is the @{Wrapper.Static#STATIC} that was spawned.
|
-- The first parameter of the SpawnFunction is the @{Wrapper.Static#STATIC} that was spawned.
|
||||||
@ -544,6 +558,14 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
|||||||
-- Add static to the game.
|
-- Add static to the game.
|
||||||
local Static=nil --DCS#StaticObject
|
local Static=nil --DCS#StaticObject
|
||||||
|
|
||||||
|
if self.ValidateAndRepositionStatic then
|
||||||
|
local validPos = UTILS.ValidateAndRepositionStatic(CountryID, Template.category, Template.type, Template, Template.shape_name, self.ValidateAndRepositionStaticMaxRadius)
|
||||||
|
if validPos then
|
||||||
|
Template.x = validPos.x
|
||||||
|
Template.y = validPos.y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if self.InitFarp then
|
if self.InitFarp then
|
||||||
|
|
||||||
local TemplateGroup={}
|
local TemplateGroup={}
|
||||||
|
|||||||
@ -4872,3 +4872,160 @@ function UTILS.FindNearestPointOnCircle(Vec1,Radius,Vec2)
|
|||||||
return {x=qx, y=qy}
|
return {x=qx, y=qy}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
-- @param #table Positions A table of DCS#Vec2 or DCS#Vec3, can be a units table from the group template.
|
||||||
|
-- @param DCS#Vec2 Anchor (Optional) DCS#Vec2 or DCS#Vec3 as anchor point to calculate offset of the units.
|
||||||
|
-- @param #number MaxRadius (Optional) Max radius to search for valid ground locations in meters. Default is double the max radius of the units.
|
||||||
|
-- @param #number Spacing (Optional) Minimum spacing between units in meters. Default is 5% of the search radius or 5 meters, whichever is larger.
|
||||||
|
function UTILS.ValidateAndRepositionGroundUnits(Positions, Anchor, MaxRadius, Spacing)
|
||||||
|
local units = Positions
|
||||||
|
Anchor = Anchor or UTILS.GetCenterPoint(units)
|
||||||
|
local gPos = { x = Anchor.x, y = Anchor.z or Anchor.y }
|
||||||
|
local maxRadius = 0
|
||||||
|
local unitCount = 0
|
||||||
|
for _, unit in pairs(units) do
|
||||||
|
local pos = { x = unit.x, y = unit.z or unit.y }
|
||||||
|
local dist = UTILS.VecDist2D(pos, gPos)
|
||||||
|
if dist > maxRadius then
|
||||||
|
maxRadius = dist
|
||||||
|
end
|
||||||
|
unitCount = unitCount + 1
|
||||||
|
end
|
||||||
|
maxRadius = MaxRadius or math.max(maxRadius * 2, 10)
|
||||||
|
local spacing = Spacing or math.max(maxRadius * 0.05, 5)
|
||||||
|
if unitCount > 0 and maxRadius > 5 then
|
||||||
|
local spots = UTILS.GetSimpleZones(UTILS.Vec2toVec3(gPos), maxRadius, spacing, 1000)
|
||||||
|
if spots and #spots > 0 then
|
||||||
|
local validSpots = {}
|
||||||
|
for _, spot in pairs(spots) do -- Disposition sometimes returns points on roads, hence this filter.
|
||||||
|
if land.getSurfaceType(spot) == land.SurfaceType.LAND then
|
||||||
|
table.insert(validSpots, spot)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
spots = validSpots
|
||||||
|
end
|
||||||
|
|
||||||
|
local step = spacing
|
||||||
|
for _, unit in pairs(units) do
|
||||||
|
local pos = { x = unit.x, y = unit.z or unit.y }
|
||||||
|
local isOnLand = land.getSurfaceType(pos) == land.SurfaceType.LAND
|
||||||
|
local isValid = false
|
||||||
|
if spots and #spots > 0 then
|
||||||
|
local si = 1
|
||||||
|
local sid = 0
|
||||||
|
local closestDist = 100000000
|
||||||
|
local closestSpot
|
||||||
|
for _, spot in pairs(spots) do
|
||||||
|
local dist = UTILS.VecDist2D(pos, spot)
|
||||||
|
if dist < closestDist then
|
||||||
|
closestDist = dist
|
||||||
|
closestSpot = spot
|
||||||
|
sid = si
|
||||||
|
end
|
||||||
|
si = si + 1
|
||||||
|
end
|
||||||
|
if closestSpot then
|
||||||
|
if closestDist >= spacing then
|
||||||
|
pos = closestSpot
|
||||||
|
end
|
||||||
|
isValid = true
|
||||||
|
table.remove(spots, sid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Failsafe calculation
|
||||||
|
if not isValid and not isOnLand then
|
||||||
|
|
||||||
|
local h = UTILS.HdgTo(pos, gPos)
|
||||||
|
local retries = 0
|
||||||
|
while not isValid and retries < 500 do
|
||||||
|
|
||||||
|
local dist = UTILS.VecDist2D(pos, gPos)
|
||||||
|
pos = UTILS.Vec2Translate(pos, step, h)
|
||||||
|
|
||||||
|
local skip = false
|
||||||
|
for _, unit2 in pairs(units) do
|
||||||
|
if unit ~= unit2 then
|
||||||
|
local pos2 = { x = unit2.x, y = unit2.z or unit2.y }
|
||||||
|
local dist2 = UTILS.VecDist2D(pos, pos2)
|
||||||
|
if dist2 < 12 then
|
||||||
|
isValid = false
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not skip and dist > step and land.getSurfaceType(pos) == land.SurfaceType.LAND then
|
||||||
|
isValid = true
|
||||||
|
break
|
||||||
|
elseif dist <= step then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
retries = retries + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isValid then
|
||||||
|
unit.x = pos.x
|
||||||
|
if unit.z then
|
||||||
|
unit.z = pos.y
|
||||||
|
else
|
||||||
|
unit.y = pos.y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
-- @param #table Positions A table of DCS#Vec2 or DCS#Vec3, can be a units table from the group template.
|
||||||
|
-- @param DCS#Vec2 Position DCS#Vec2 or DCS#Vec3 initial spawn location.
|
||||||
|
-- @param #number MaxRadius (Optional) Max radius to search for valid ground locations in meters. Default is double the max radius of the static.
|
||||||
|
-- @return DCS#Vec2 Initial Position if it's valid, else a valid spawn position. nil if no valid position found.
|
||||||
|
function UTILS.ValidateAndRepositionStatic(Country, Category, Type, Position, ShapeName, MaxRadius)
|
||||||
|
local coord = COORDINATE:NewFromVec2(Position)
|
||||||
|
local st = SPAWNSTATIC:NewFromType(Type, Category, Country)
|
||||||
|
if ShapeName then
|
||||||
|
st:InitShape(ShapeName)
|
||||||
|
end
|
||||||
|
local sName = "s-"..timer.getTime().."-"..math.random(1,10000)
|
||||||
|
local tempStatic = st:SpawnFromCoordinate(coord, 0, sName)
|
||||||
|
if tempStatic then
|
||||||
|
local sRadius = tempStatic:GetBoundingRadius(2) or 3
|
||||||
|
tempStatic:Destroy()
|
||||||
|
sRadius = sRadius * 0.5
|
||||||
|
MaxRadius = MaxRadius or math.max(sRadius * 10, 100)
|
||||||
|
local positions = UTILS.GetSimpleZones(coord:GetVec3(), MaxRadius, sRadius, 20)
|
||||||
|
if positions and #positions > 0 then
|
||||||
|
local closestSpot
|
||||||
|
local closestDist = math.huge
|
||||||
|
for _, spot in pairs(positions) do -- Disposition sometimes returns points on roads, hence this filter.
|
||||||
|
if land.getSurfaceType(spot) == land.SurfaceType.LAND then
|
||||||
|
local dist = UTILS.VecDist2D(Position, spot)
|
||||||
|
if dist < closestDist then
|
||||||
|
closestDist = dist
|
||||||
|
closestSpot = spot
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if closestSpot then
|
||||||
|
if closestDist >= sRadius then
|
||||||
|
return closestSpot
|
||||||
|
else
|
||||||
|
return Position
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|||||||
@ -703,55 +703,56 @@ AIRBASE.SouthAtlantic={
|
|||||||
|
|
||||||
--- Airbases of the Sinai map:
|
--- Airbases of the Sinai map:
|
||||||
--
|
--
|
||||||
-- * AIRBASE.Sinai.Abu_Rudeis
|
-- * AIRBASE.SinaiMap.Abu_Rudeis
|
||||||
-- * AIRBASE.Sinai.Abu_Suwayr
|
-- * AIRBASE.SinaiMap.Abu_Suwayr
|
||||||
-- * AIRBASE.Sinai.Al_Bahr_al_Ahmar
|
-- * AIRBASE.SinaiMap.Al_Bahr_al_Ahmar
|
||||||
-- * AIRBASE.Sinai.Al_Ismailiyah
|
-- * AIRBASE.SinaiMap.Al_Ismailiyah
|
||||||
-- * AIRBASE.Sinai.Al_Khatatbah
|
-- * AIRBASE.SinaiMap.Al_Khatatbah
|
||||||
-- * AIRBASE.Sinai.Al_Mansurah
|
-- * AIRBASE.SinaiMap.Al_Mansurah
|
||||||
-- * AIRBASE.Sinai.Al_Rahmaniyah_Air_Base
|
-- * AIRBASE.SinaiMap.Al_Rahmaniyah_Air_Base
|
||||||
-- * AIRBASE.Sinai.As_Salihiyah
|
-- * AIRBASE.SinaiMap.As_Salihiyah
|
||||||
-- * AIRBASE.Sinai.AzZaqaziq
|
-- * AIRBASE.SinaiMap.AzZaqaziq
|
||||||
-- * AIRBASE.Sinai.Baluza
|
-- * AIRBASE.SinaiMap.Baluza
|
||||||
-- * AIRBASE.Sinai.Ben_Gurion
|
-- * AIRBASE.SinaiMap.Ben_Gurion
|
||||||
-- * AIRBASE.Sinai.Beni_Suef
|
-- * AIRBASE.SinaiMap.Beni_Suef
|
||||||
-- * AIRBASE.Sinai.Bilbeis_Air_Base
|
-- * AIRBASE.SinaiMap.Bilbeis_Air_Base
|
||||||
-- * AIRBASE.Sinai.Bir_Hasanah
|
-- * AIRBASE.SinaiMap.Bir_Hasanah
|
||||||
-- * AIRBASE.Sinai.Birma_Air_Base
|
-- * AIRBASE.SinaiMap.Birma_Air_Base
|
||||||
-- * AIRBASE.Sinai.Borg_El_Arab_International_Airport
|
-- * AIRBASE.SinaiMap.Borg_El_Arab_International_Airport
|
||||||
-- * AIRBASE.Sinai.Cairo_International_Airport
|
-- * AIRBASE.SinaiMap.Cairo_International_Airport
|
||||||
-- * AIRBASE.Sinai.Cairo_West
|
-- * AIRBASE.SinaiMap.Cairo_West
|
||||||
-- * AIRBASE.Sinai.Difarsuwar_Airfield
|
-- * AIRBASE.SinaiMap.Damascus_Intl
|
||||||
-- * AIRBASE.Sinai.El_Arish
|
-- * AIRBASE.SinaiMap.Difarsuwar_Airfield
|
||||||
-- * AIRBASE.Sinai.El_Gora
|
-- * AIRBASE.SinaiMap.El_Arish
|
||||||
-- * AIRBASE.Sinai.El_Minya
|
-- * AIRBASE.SinaiMap.El_Gora
|
||||||
-- * AIRBASE.Sinai.Fayed
|
-- * AIRBASE.SinaiMap.El_Minya
|
||||||
-- * AIRBASE.Sinai.Gebel_El_Basur_Air_Base
|
-- * AIRBASE.SinaiMap.Fayed
|
||||||
-- * AIRBASE.Sinai.Hatzerim
|
-- * AIRBASE.SinaiMap.Gebel_El_Basur_Air_Base
|
||||||
-- * AIRBASE.Sinai.Hatzor
|
-- * AIRBASE.SinaiMap.Hatzerim
|
||||||
-- * AIRBASE.Sinai.Hurghada_International_Airport
|
-- * AIRBASE.SinaiMap.Hatzor
|
||||||
-- * AIRBASE.Sinai.Inshas_Airbase
|
-- * AIRBASE.SinaiMap.Hurghada_International_Airport
|
||||||
-- * AIRBASE.Sinai.Jiyanklis_Air_Base
|
-- * AIRBASE.SinaiMap.Inshas_Airbase
|
||||||
-- * AIRBASE.Sinai.Kedem
|
-- * AIRBASE.SinaiMap.Jiyanklis_Air_Base
|
||||||
-- * AIRBASE.Sinai.Kibrit_Air_Base
|
-- * AIRBASE.SinaiMap.Kedem
|
||||||
-- * AIRBASE.Sinai.Kom_Awshim
|
-- * AIRBASE.SinaiMap.Kibrit_Air_Base
|
||||||
-- * AIRBASE.Sinai.Melez
|
-- * AIRBASE.SinaiMap.Kom_Awshim
|
||||||
-- * AIRBASE.Sinai.Mezzeh_Air_Base
|
-- * AIRBASE.SinaiMap.Melez
|
||||||
-- * AIRBASE.Sinai.Nevatim
|
-- * AIRBASE.SinaiMap.Mezzeh_Air_Base
|
||||||
-- * AIRBASE.Sinai.Ovda
|
-- * AIRBASE.SinaiMap.Nevatim
|
||||||
-- * AIRBASE.Sinai.Palmachim
|
-- * AIRBASE.SinaiMap.Ovda
|
||||||
-- * AIRBASE.Sinai.Quwaysina
|
-- * AIRBASE.SinaiMap.Palmachim
|
||||||
-- * AIRBASE.Sinai.Rafic_Hariri_Intl
|
-- * AIRBASE.SinaiMap.Quwaysina
|
||||||
-- * AIRBASE.Sinai.Ramat_David
|
-- * AIRBASE.SinaiMap.Rafic_Hariri_Intl
|
||||||
-- * AIRBASE.Sinai.Ramon_Airbase
|
-- * AIRBASE.SinaiMap.Ramat_David
|
||||||
-- * AIRBASE.Sinai.Ramon_International_Airport
|
-- * AIRBASE.SinaiMap.Ramon_Airbase
|
||||||
-- * AIRBASE.Sinai.Sde_Dov
|
-- * AIRBASE.SinaiMap.Ramon_International_Airport
|
||||||
-- * AIRBASE.Sinai.Sharm_El_Sheikh_International_Airport
|
-- * AIRBASE.SinaiMap.Sde_Dov
|
||||||
-- * AIRBASE.Sinai.St_Catherine
|
-- * AIRBASE.SinaiMap.Sharm_El_Sheikh_International_Airport
|
||||||
-- * AIRBASE.Sinai.Tabuk
|
-- * AIRBASE.SinaiMap.St_Catherine
|
||||||
-- * AIRBASE.Sinai.Tel_Nof
|
-- * AIRBASE.SinaiMap.Tabuk
|
||||||
-- * AIRBASE.Sinai.Wadi_Abu_Rish
|
-- * AIRBASE.SinaiMap.Tel_Nof
|
||||||
-- * AIRBASE.Sinai.Wadi_al_Jandali
|
-- * AIRBASE.SinaiMap.Wadi_Abu_Rish
|
||||||
|
-- * AIRBASE.SinaiMap.Wadi_al_Jandali
|
||||||
--
|
--
|
||||||
-- @field Sinai
|
-- @field Sinai
|
||||||
AIRBASE.Sinai = {
|
AIRBASE.Sinai = {
|
||||||
@ -773,6 +774,7 @@ AIRBASE.Sinai = {
|
|||||||
["Borg_El_Arab_International_Airport"] = "Borg El Arab International Airport",
|
["Borg_El_Arab_International_Airport"] = "Borg El Arab International Airport",
|
||||||
["Cairo_International_Airport"] = "Cairo International Airport",
|
["Cairo_International_Airport"] = "Cairo International Airport",
|
||||||
["Cairo_West"] = "Cairo West",
|
["Cairo_West"] = "Cairo West",
|
||||||
|
["Damascus_Intl"] = "Damascus Intl",
|
||||||
["Difarsuwar_Airfield"] = "Difarsuwar Airfield",
|
["Difarsuwar_Airfield"] = "Difarsuwar Airfield",
|
||||||
["El_Arish"] = "El Arish",
|
["El_Arish"] = "El Arish",
|
||||||
["El_Gora"] = "El Gora",
|
["El_Gora"] = "El Gora",
|
||||||
|
|||||||
@ -3202,6 +3202,7 @@ end
|
|||||||
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
--- Uses UTILS.ValidateAndRepositionGroundUnits.
|
--- Uses UTILS.ValidateAndRepositionGroundUnits.
|
||||||
|
-- @param #GROUP self
|
||||||
-- @param #boolean Enabled Enable/disable the feature.
|
-- @param #boolean Enabled Enable/disable the feature.
|
||||||
function GROUP:SetValidateAndRepositionGroundUnits(Enabled)
|
function GROUP:SetValidateAndRepositionGroundUnits(Enabled)
|
||||||
self.ValidateAndRepositionGroundUnits = Enabled
|
self.ValidateAndRepositionGroundUnits = Enabled
|
||||||
|
|||||||
@ -1948,6 +1948,7 @@ end
|
|||||||
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
--- Uses UTILS.ValidateAndRepositionGroundUnits.
|
--- Uses UTILS.ValidateAndRepositionGroundUnits.
|
||||||
|
-- @param #UNIT self
|
||||||
-- @param #boolean Enabled Enable/disable the feature.
|
-- @param #boolean Enabled Enable/disable the feature.
|
||||||
function UNIT:SetValidateAndRepositionGroundUnits(Enabled)
|
function UNIT:SetValidateAndRepositionGroundUnits(Enabled)
|
||||||
self.ValidateAndRepositionGroundUnits = Enabled
|
self.ValidateAndRepositionGroundUnits = Enabled
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user