mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 1.1.10
Quad Zones improvements Semaphore stubs
This commit is contained in:
parent
8f225cc30a
commit
3de20ed5f1
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
cfxOwnedZones = {}
|
cfxOwnedZones = {}
|
||||||
cfxOwnedZones.version = "1.2.2"
|
cfxOwnedZones.version = "1.2.3"
|
||||||
cfxOwnedZones.verbose = false
|
cfxOwnedZones.verbose = false
|
||||||
cfxOwnedZones.announcer = true
|
cfxOwnedZones.announcer = true
|
||||||
cfxOwnedZones.name = "cfxOwnedZones"
|
cfxOwnedZones.name = "cfxOwnedZones"
|
||||||
@ -47,6 +47,7 @@ cfxOwnedZones.name = "cfxOwnedZones"
|
|||||||
- no cfxGroundTroop bug (no delay)
|
- no cfxGroundTroop bug (no delay)
|
||||||
1.2.1 - fix in load to correctly re-establish all attackers for subsequent save
|
1.2.1 - fix in load to correctly re-establish all attackers for subsequent save
|
||||||
1.2.2 - redCap! and blueCap!
|
1.2.2 - redCap! and blueCap!
|
||||||
|
1.2.3 - fix for persistence bug when not using conquered flag
|
||||||
|
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
@ -901,7 +902,9 @@ function cfxOwnedZones.saveData()
|
|||||||
zoneData.defenderData = dcsCommon.clone(theZone.defenderData)
|
zoneData.defenderData = dcsCommon.clone(theZone.defenderData)
|
||||||
dcsCommon.synchGroupData(zoneData.defenderData)
|
dcsCommon.synchGroupData(zoneData.defenderData)
|
||||||
end
|
end
|
||||||
zoneData.conquered = cfxZones.getFlagValue(theZone.conqueredFlag, theZone)
|
if theZone.conqueredFlag then
|
||||||
|
zoneData.conquered = cfxZones.getFlagValue(theZone.conqueredFlag, theZone)
|
||||||
|
end
|
||||||
zoneData.owner = theZone.owner
|
zoneData.owner = theZone.owner
|
||||||
zoneData.state = theZone.state -- will prevent immediate spawn
|
zoneData.state = theZone.state -- will prevent immediate spawn
|
||||||
-- since new zones are spawned with 'init'
|
-- since new zones are spawned with 'init'
|
||||||
@ -972,7 +975,9 @@ function cfxOwnedZones.loadData()
|
|||||||
end
|
end
|
||||||
theZone.owner = zData.owner
|
theZone.owner = zData.owner
|
||||||
theZone.state = zData.state
|
theZone.state = zData.state
|
||||||
cfxZones.setFlagValue(theZone.conqueredFlag, zData.conquered, theZone)
|
if zData.conquered then
|
||||||
|
cfxZones.setFlagValue(theZone.conqueredFlag, zData.conquered, theZone)
|
||||||
|
end
|
||||||
-- update mark in map
|
-- update mark in map
|
||||||
cfxOwnedZones.drawZoneInMap(theZone)
|
cfxOwnedZones.drawZoneInMap(theZone)
|
||||||
else
|
else
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
cfxZones = {}
|
cfxZones = {}
|
||||||
cfxZones.version = "2.9.1"
|
cfxZones.version = "2.9.2"
|
||||||
|
|
||||||
-- cf/x zone management module
|
-- cf/x zone management module
|
||||||
-- reads dcs zones and makes them accessible and mutable
|
-- reads dcs zones and makes them accessible and mutable
|
||||||
@ -109,6 +109,11 @@ cfxZones.version = "2.9.1"
|
|||||||
- 2.9.1 - new evalRemainder()
|
- 2.9.1 - new evalRemainder()
|
||||||
- pollFlag supports +/- for immediate numbers, flags, number flags in parantheses
|
- pollFlag supports +/- for immediate numbers, flags, number flags in parantheses
|
||||||
- stronger guards in hasProperty
|
- stronger guards in hasProperty
|
||||||
|
- 2.9.2 - new createRandomPointInPolyZone()
|
||||||
|
- createRandomZoneInZone uses createRandomPointInPolyZone
|
||||||
|
- new createRandomPointInZone()
|
||||||
|
- new randomPointInZone()
|
||||||
|
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
cfxZones.verbose = false
|
cfxZones.verbose = false
|
||||||
@ -207,7 +212,7 @@ function cfxZones.readFromDCS(clearfirst)
|
|||||||
local upperName = newZone.name:upper()
|
local upperName = newZone.name:upper()
|
||||||
|
|
||||||
-- location as 'point'
|
-- location as 'point'
|
||||||
-- WARNING: zones locs are 2D (x,y) pairs, whily y in DCS is altitude.
|
-- WARNING: zones locs are 2D (x,y) pairs, while y in DCS is altitude.
|
||||||
-- so we need to change (x,y) into (x, 0, z). Since Zones have no
|
-- so we need to change (x,y) into (x, 0, z). Since Zones have no
|
||||||
-- altitude (they are an infinite cylinder) this works. Remember to
|
-- altitude (they are an infinite cylinder) this works. Remember to
|
||||||
-- drop y from zone calculations to see if inside.
|
-- drop y from zone calculations to see if inside.
|
||||||
@ -229,10 +234,12 @@ function cfxZones.readFromDCS(clearfirst)
|
|||||||
elseif zoneType == 2 then
|
elseif zoneType == 2 then
|
||||||
-- polyZone
|
-- polyZone
|
||||||
newZone.isPoly = true
|
newZone.isPoly = true
|
||||||
newZone.radius = dcsZone.radius -- radius is still written in DCS, may change later
|
newZone.radius = dcsZone.radius -- radius is still written in DCS, may change later. The radius has no meaning and is the last radius written before zone changed to poly.
|
||||||
|
-- note that newZone.point is only inside the tone for
|
||||||
|
-- convex polys, and DML only correctly works with convex polys
|
||||||
-- now transfer all point in the poly
|
-- now transfer all point in the poly
|
||||||
-- note: DCS in 2.7 misspells vertices as 'verticies'
|
-- note: DCS in 2.7 misspells vertices as 'verticies'
|
||||||
-- correct vor this
|
-- correct for this
|
||||||
local verts = {}
|
local verts = {}
|
||||||
if dcsZone.verticies then verts = dcsZone.verticies
|
if dcsZone.verticies then verts = dcsZone.verticies
|
||||||
else
|
else
|
||||||
@ -242,7 +249,7 @@ function cfxZones.readFromDCS(clearfirst)
|
|||||||
|
|
||||||
for v=1, #verts do
|
for v=1, #verts do
|
||||||
local dcsPoint = verts[v]
|
local dcsPoint = verts[v]
|
||||||
local polyPoint = cfxZones.createPointFromDCSPoint(dcsPoint) -- (x, y) -- (x, 0, y-->z)
|
local polyPoint = cfxZones.createPointFromDCSPoint(dcsPoint) -- (x, y) --> (x, 0, y-->z)
|
||||||
newZone.poly[v] = polyPoint
|
newZone.poly[v] = polyPoint
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -290,15 +297,18 @@ function cfxZones.calculateZoneBounds(theZone)
|
|||||||
local lr = cfxZones.createPointFromPoint(poly[1])
|
local lr = cfxZones.createPointFromPoint(poly[1])
|
||||||
local ul = cfxZones.createPointFromPoint(poly[1])
|
local ul = cfxZones.createPointFromPoint(poly[1])
|
||||||
local ur = cfxZones.createPointFromPoint(poly[1])
|
local ur = cfxZones.createPointFromPoint(poly[1])
|
||||||
|
|
||||||
|
local pRad = dcsCommon.dist(theZone.point, poly[1]) -- rRad is radius for polygon from theZone.point
|
||||||
|
|
||||||
-- now iterate through all points and adjust bounds accordingly
|
-- now iterate through all points and adjust bounds accordingly
|
||||||
for v=2, #poly do
|
for v=2, #poly do
|
||||||
local vertex = poly[v]
|
local vertex = poly[v]
|
||||||
if (vertex.x < ll.x) then ll.x = vertex.x; ul.x = vertex.x end
|
if (vertex.x < ll.x) then ll.x = vertex.x; ul.x = vertex.x end
|
||||||
if (vertex.x > lr.x) then lr.x = vertex.x; ur.x = vertex.x end
|
if (vertex.x > lr.x) then lr.x = vertex.x; ur.x = vertex.x end
|
||||||
if (vertex.z < ul.z) then ul.z = vertex.z; ur.z = vertex.z end
|
if (vertex.z < ul.z) then ul.z = vertex.z; ur.z = vertex.z end
|
||||||
if (vertex.z > ll.z) then ll.z = vertex.z; lr.z = vertex.z end
|
if (vertex.z > ll.z) then ll.z = vertex.z; lr.z = vertex.z end
|
||||||
|
local dp = dcsCommon.dist(theZone.point, vertex)
|
||||||
|
if dp > pRad then pRad = dp end -- find largst distance to vertex
|
||||||
end
|
end
|
||||||
|
|
||||||
-- now keep the new point references
|
-- now keep the new point references
|
||||||
@ -307,6 +317,9 @@ function cfxZones.calculateZoneBounds(theZone)
|
|||||||
bounds.lr = lr
|
bounds.lr = lr
|
||||||
bounds.ul = ul
|
bounds.ul = ul
|
||||||
bounds.ur = ur
|
bounds.ur = ur
|
||||||
|
-- store pRad
|
||||||
|
theZone.pRad = pRad -- not sure we'll ever need that, but at least we have it
|
||||||
|
-- trigger.action.outText("+++Zones: poly zone <" .. theZone.name .. "> has pRad = " .. pRad, 30) -- remember to remove me
|
||||||
else
|
else
|
||||||
-- huston, we have a problem
|
-- huston, we have a problem
|
||||||
if cfxZones.verbose then
|
if cfxZones.verbose then
|
||||||
@ -351,11 +364,82 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function cfxZones.createRandomPointInsideBounds(bounds)
|
function cfxZones.createRandomPointInsideBounds(bounds)
|
||||||
|
-- warning: bounds do not move woth zone! may have to be updated
|
||||||
local x = math.random(bounds.ll.x, ur.x)
|
local x = math.random(bounds.ll.x, ur.x)
|
||||||
local z = math.random(bounds.ll.z, ur.z)
|
local z = math.random(bounds.ll.z, ur.z)
|
||||||
return cfxZones.createPoint(x, 0, z)
|
return cfxZones.createPoint(x, 0, z)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cfxZones.createRandomPointInZone(theZone)
|
||||||
|
if not theZone then return nil end
|
||||||
|
if theZone.isPoly then
|
||||||
|
local loc, dx, dy = cfxZones.createRandomPointInPolyZone(theZone)
|
||||||
|
return loc, dx, dy
|
||||||
|
else
|
||||||
|
local loc, dx, dy = cfxZones.createRandomPointInCircleZone(theZone)
|
||||||
|
return loc, dx, dy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function cfxZones.randomPointInZone(theZone)
|
||||||
|
local loc, dx, dy = cfxZones.createRandomPointInZone(theZone)
|
||||||
|
return loc, dx, dy
|
||||||
|
end
|
||||||
|
|
||||||
|
function cfxZones.createRandomPointInCircleZone(theZone)
|
||||||
|
if not theZone.isCircle then
|
||||||
|
trigger.action.outText("+++Zones: warning - createRandomPointInCircleZone called for non-circle zone <" .. theZone.name .. ">", 30)
|
||||||
|
return {x=theZone.point.x, y=0, z=theZone.point.z}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ok, let's first create a random percentage value for the new radius
|
||||||
|
-- now lets get a random degree
|
||||||
|
local degrees = math.random() * 2 * 3.14152 -- radiants.
|
||||||
|
local r = theZone.radius * math.random()
|
||||||
|
local p = cfxZones.getPoint(theZone) -- force update of zone if linked
|
||||||
|
local dx = r * math.cos(degrees)
|
||||||
|
local dz = r * math.sin(degrees)
|
||||||
|
local px = p.x + dx -- r * math.cos(degrees)
|
||||||
|
local pz = p.z + dz -- r * math.sin(degrees)
|
||||||
|
return {x=px, y=0, z = pz}, dx, dz -- returns loc and offsets to theZone.point
|
||||||
|
end
|
||||||
|
|
||||||
|
function cfxZones.createRandomPointInPolyZone(theZone)
|
||||||
|
if not theZone.isPoly then
|
||||||
|
trigger.action.outText("+++Zones: warning - createRandomPointInPolyZone called for non-poly zone <" .. theZone.name .. ">", 30)
|
||||||
|
return cfxZones.createPoint(theZone.point.x, 0, theZone.point.z)
|
||||||
|
end
|
||||||
|
-- force update of all points
|
||||||
|
local p = cfxZones.getPoint(theZone)
|
||||||
|
|
||||||
|
-- point in convex poly: choose two different lines from that polygon
|
||||||
|
local lineIdxA = dcsCommon.smallRandom(#theZone.poly)
|
||||||
|
repeat lineIdxB = dcsCommon.smallRandom(#theZone.poly) until (lineIdxA ~= lineIdxB)
|
||||||
|
|
||||||
|
-- we now have two different lines. pick a random point on each.
|
||||||
|
-- we use lerp to pick any point between a and b
|
||||||
|
local a = theZone.poly[lineIdxA]
|
||||||
|
lineIdxA = lineIdxA + 1 -- get next point in poly and wrap around
|
||||||
|
if lineIdxA > #theZone.poly then lineIdxA = 1 end
|
||||||
|
local b = theZone.poly[lineIdxA]
|
||||||
|
local randompercent = math.random()
|
||||||
|
local sourceA = dcsCommon.vLerp (a, b, randompercent)
|
||||||
|
|
||||||
|
-- now get point on second line
|
||||||
|
a = theZone.poly[lineIdxB]
|
||||||
|
lineIdxB = lineIdxB + 1 -- get next point in poly and wrap around
|
||||||
|
if lineIdxB > #theZone.poly then lineIdxB = 1 end
|
||||||
|
b = theZone.poly[lineIdxB]
|
||||||
|
randompercent = math.random()
|
||||||
|
local sourceB = dcsCommon.vLerp (a, b, randompercent)
|
||||||
|
|
||||||
|
-- now take a random point on that line that entirely
|
||||||
|
-- runs through the poly
|
||||||
|
randompercent = math.random()
|
||||||
|
local polyPoint = dcsCommon.vLerp (sourceA, sourceB, randompercent)
|
||||||
|
return polyPoint, polyPoint.x - p.x, polyPoint.z - p.z -- return loc, dx, dz
|
||||||
|
end
|
||||||
|
|
||||||
function cfxZones.addZoneToManagedZones(theZone)
|
function cfxZones.addZoneToManagedZones(theZone)
|
||||||
local upperName = string.upper(theZone.name) -- newZone.name:upper()
|
local upperName = string.upper(theZone.name) -- newZone.name:upper()
|
||||||
cfxZones.zones[upperName] = theZone
|
cfxZones.zones[upperName] = theZone
|
||||||
@ -435,6 +519,7 @@ function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyIns
|
|||||||
-- create a new circular zone with center placed inside inZone
|
-- create a new circular zone with center placed inside inZone
|
||||||
-- if entirelyInside is false, only the zone's center is guaranteed to be inside
|
-- if entirelyInside is false, only the zone's center is guaranteed to be inside
|
||||||
-- inZone.
|
-- inZone.
|
||||||
|
-- entirelyInside is not guaranteed for polyzones
|
||||||
|
|
||||||
-- trigger.action.outText("Zones: creating rZiZ with tr = " .. targetRadius .. " for " .. inZone.name .. " that as r = " .. inZone.radius, 10)
|
-- trigger.action.outText("Zones: creating rZiZ with tr = " .. targetRadius .. " for " .. inZone.name .. " that as r = " .. inZone.radius, 10)
|
||||||
|
|
||||||
@ -458,6 +543,8 @@ function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyIns
|
|||||||
-- we have a poly zone. the way we do this is simple:
|
-- we have a poly zone. the way we do this is simple:
|
||||||
-- generate random x, z with ranges of the bounding box
|
-- generate random x, z with ranges of the bounding box
|
||||||
-- until the point falls within the polygon.
|
-- until the point falls within the polygon.
|
||||||
|
--[[ replaced by new code
|
||||||
|
|
||||||
local newPoint = {}
|
local newPoint = {}
|
||||||
local emergencyBrake = 0
|
local emergencyBrake = 0
|
||||||
repeat
|
repeat
|
||||||
@ -465,11 +552,12 @@ function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyIns
|
|||||||
emergencyBrake = emergencyBrake + 1
|
emergencyBrake = emergencyBrake + 1
|
||||||
if (emergencyBrake > 100) then
|
if (emergencyBrake > 100) then
|
||||||
newPoint = cfxZones.copyPoint(inZone.Point)
|
newPoint = cfxZones.copyPoint(inZone.Point)
|
||||||
trigger.action.outText("CreateZoneInZone: mergency brake for inZone" .. inZone.name, 10)
|
trigger.action.outText("CreateZoneInZone: emergency brake for inZone" .. inZone.name, 10)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
until cfxZones.isPointInsidePoly(newPoint, inZone.poly)
|
until cfxZones.isPointInsidePoly(newPoint, inZone.poly)
|
||||||
|
--]]--
|
||||||
|
local newPoint = cfxZones.createRandomPointInPolyZone(inZone)
|
||||||
-- construct new zone
|
-- construct new zone
|
||||||
local newZone = cfxZones.createCircleZone(name, newPoint.x, newPoint.z, targetRadius)
|
local newZone = cfxZones.createCircleZone(name, newPoint.x, newPoint.z, targetRadius)
|
||||||
return newZone
|
return newZone
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
cloneZones = {}
|
cloneZones = {}
|
||||||
cloneZones.version = "1.6.0"
|
cloneZones.version = "1.6.1"
|
||||||
cloneZones.verbose = false
|
cloneZones.verbose = false
|
||||||
cloneZones.requiredLibs = {
|
cloneZones.requiredLibs = {
|
||||||
"dcsCommon", -- always
|
"dcsCommon", -- always
|
||||||
@ -65,6 +65,12 @@ cloneZones.allCObjects = {} -- all clones objects
|
|||||||
1.6.0 - fixed issues with cloning for zones with linked units
|
1.6.0 - fixed issues with cloning for zones with linked units
|
||||||
- cloning with useHeading
|
- cloning with useHeading
|
||||||
- major declutter
|
- major declutter
|
||||||
|
1.6.1 - removed some verbosity when not rotating routes
|
||||||
|
- updateTaskLocations ()
|
||||||
|
- cloning groups now also adjusts tasks like search and engage in zone
|
||||||
|
- cloning with rndLoc supports polygons
|
||||||
|
- corrected rndLoc without centerOnly to not include individual offsets
|
||||||
|
- ensure support of recovery tanker resolve cloned group
|
||||||
|
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
@ -402,6 +408,21 @@ function cloneZones.rotateWPAroundCenter(thePoint, center, angle)
|
|||||||
thePoint.y = py + center.z -- !!
|
thePoint.y = py + center.z -- !!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cloneZones.updateTaskLocations(thePoint, zoneDelta)
|
||||||
|
-- parse tasks for x and y and update them by zoneDelta
|
||||||
|
if thePoint and thePoint.task and thePoint.task.params and thePoint.task.params.tasks then
|
||||||
|
local theTasks = thePoint.task.params.tasks
|
||||||
|
for idx, aTask in pairs(theTasks) do
|
||||||
|
-- EngageTargetsInZone task has x & y in params
|
||||||
|
if aTask.params and aTask.params.x and aTask.params.y then
|
||||||
|
aTask.params.x = aTask.params.x + zoneDelta.x
|
||||||
|
aTask.params.y = aTask.params.y + zoneDelta.z --!!
|
||||||
|
-- trigger.action.outText("moved search & engage zone", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function cloneZones.updateLocationsInGroupData(theData, zoneDelta, adjustAllWaypoints, center, angle)
|
function cloneZones.updateLocationsInGroupData(theData, zoneDelta, adjustAllWaypoints, center, angle)
|
||||||
-- enter with theData being group's data block
|
-- enter with theData being group's data block
|
||||||
-- remember that zoneDelta's [z] modifies theData's y!!
|
-- remember that zoneDelta's [z] modifies theData's y!!
|
||||||
@ -427,8 +448,9 @@ function cloneZones.updateLocationsInGroupData(theData, zoneDelta, adjustAllWayp
|
|||||||
if center and angle then
|
if center and angle then
|
||||||
cloneZones.rotateWPAroundCenter(thePoints[i], center, angle)
|
cloneZones.rotateWPAroundCenter(thePoints[i], center, angle)
|
||||||
else
|
else
|
||||||
trigger.action.outText("not rotating route", 30)
|
-- trigger.action.outText("not rotating route", 30)
|
||||||
end
|
end
|
||||||
|
cloneZones.updateTaskLocations(thePoints[i], zoneDelta)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- only first point
|
-- only first point
|
||||||
@ -437,6 +459,7 @@ function cloneZones.updateLocationsInGroupData(theData, zoneDelta, adjustAllWayp
|
|||||||
if center and angle then
|
if center and angle then
|
||||||
cloneZones.rotateWPAroundCenter(thePoints[1], center, angle)
|
cloneZones.rotateWPAroundCenter(thePoints[1], center, angle)
|
||||||
end
|
end
|
||||||
|
cloneZones.updateTaskLocations(thePoints[i], zoneDelta)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if there is an airodrome id given in first waypoint,
|
-- if there is an airodrome id given in first waypoint,
|
||||||
@ -617,8 +640,10 @@ function cloneZones.resolveWPReferences(rawData, theZone, dataTable)
|
|||||||
local task = aPoint.task
|
local task = aPoint.task
|
||||||
if task and task.params and task.params.tasks then
|
if task and task.params and task.params.tasks then
|
||||||
local tasks = task.params.tasks
|
local tasks = task.params.tasks
|
||||||
|
-- iterate all tasks for this waypoint
|
||||||
for idy, taskData in pairs(tasks) do
|
for idy, taskData in pairs(tasks) do
|
||||||
-- resolve group references in TASKS
|
-- resolve group references in TASKS
|
||||||
|
-- also covers recovery tanke etc
|
||||||
if taskData.id and taskData.params and taskData.params.groupId
|
if taskData.id and taskData.params and taskData.params.groupId
|
||||||
then
|
then
|
||||||
-- we resolve group reference
|
-- we resolve group reference
|
||||||
@ -628,7 +653,7 @@ function cloneZones.resolveWPReferences(rawData, theZone, dataTable)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- resolve EMBARK/DISEMBARK groupd references
|
-- resolve EMBARK/DISEMBARK group references
|
||||||
if taskData.id and taskData.params and taskData.params.groupsForEmbarking
|
if taskData.id and taskData.params and taskData.params.groupsForEmbarking
|
||||||
then
|
then
|
||||||
-- build new groupsForEmbarking
|
-- build new groupsForEmbarking
|
||||||
@ -686,6 +711,7 @@ function cloneZones.resolveWPReferences(rawData, theZone, dataTable)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- resolve unit references in ACTIONS
|
-- resolve unit references in ACTIONS
|
||||||
|
-- for example TACAN
|
||||||
if taskData.params and taskData.params.action and
|
if taskData.params and taskData.params.action and
|
||||||
taskData.params.action.params and taskData.params.action.params.unitId then
|
taskData.params.action.params and taskData.params.action.params.unitId then
|
||||||
local uID = taskData.params.action.params.unitId
|
local uID = taskData.params.action.params.unitId
|
||||||
@ -795,24 +821,32 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
|
|||||||
if spawnZone.rndLoc then
|
if spawnZone.rndLoc then
|
||||||
-- calculate the entire group's displacement
|
-- calculate the entire group's displacement
|
||||||
local units = rawData.units
|
local units = rawData.units
|
||||||
|
--[[
|
||||||
local r = math.random() * spawnZone.radius
|
local r = math.random() * spawnZone.radius
|
||||||
local phi = 6.2831 * math.random() -- that's 2Pi, folx
|
local phi = 6.2831 * math.random() -- that's 2Pi, folx
|
||||||
local dx = r * math.cos(phi)
|
local dx = r * math.cos(phi)
|
||||||
local dy = r * math.sin(phi)
|
local dy = r * math.sin(phi)
|
||||||
|
--]]
|
||||||
|
local loc, dx, dy = cfxZones.createRandomPointInZone(spawnZone) -- also supports polygonal zones
|
||||||
|
|
||||||
for idx, aUnit in pairs(units) do
|
for idx, aUnit in pairs(units) do
|
||||||
if not spawnZone.centerOnly then
|
if not spawnZone.centerOnly then
|
||||||
-- *every unit's displacement is randomized
|
-- *every unit's displacement is randomized
|
||||||
r = math.random() * spawnZone.radius
|
-- r = math.random() * spawnZone.radius
|
||||||
phi = 6.2831 * math.random() -- that's 2Pi, folx
|
-- phi = 6.2831 * math.random() -- that's 2Pi, folx
|
||||||
dx = r * math.cos(phi)
|
-- dx = r * math.cos(phi)
|
||||||
dy = r * math.sin(phi)
|
-- dy = r * math.sin(phi)
|
||||||
|
loc, dx, dy = cfxZones.createRandomPointInZone(spawnZone)
|
||||||
|
aUnit.x = loc.x
|
||||||
|
aUnit.y = loc.z
|
||||||
|
else
|
||||||
|
aUnit.x = aUnit.x + dx
|
||||||
|
aUnit.y = aUnit.y + dy
|
||||||
end
|
end
|
||||||
if spawnZone.verbose or cloneZones.verbose then
|
if spawnZone.verbose or cloneZones.verbose then
|
||||||
trigger.action.outText("+++clnZ: <" .. spawnZone.name .. "> R = " .. spawnZone.radius .. ":G<" .. rawData.name .. "/" .. aUnit.name .. "> - rndLoc: r = " .. r .. ", dx = " .. dx .. ", dy= " .. dy .. ".", 30)
|
trigger.action.outText("+++clnZ: <" .. spawnZone.name .. "> R = " .. spawnZone.radius .. ":G<" .. rawData.name .. "/" .. aUnit.name .. "> - rndLoc: r = " .. r .. ", dx = " .. dx .. ", dy= " .. dy .. ".", 30)
|
||||||
end
|
end
|
||||||
aUnit.x = aUnit.x + dx
|
|
||||||
aUnit.y = aUnit.y + dy
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -982,10 +1016,11 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
|
|||||||
|
|
||||||
-- randomize if enabled
|
-- randomize if enabled
|
||||||
if spawnZone.rndLoc then
|
if spawnZone.rndLoc then
|
||||||
local r = math.random() * spawnZone.radius
|
--local r = math.random() * spawnZone.radius
|
||||||
local phi = 6.2831 * math.random() -- that's 2Pi, folx
|
--local phi = 6.2831 * math.random() -- that's 2Pi, folx
|
||||||
local dx = r * math.cos(phi)
|
--local dx = r * math.cos(phi)
|
||||||
local dy = r * math.sin(phi)
|
--local dy = r * math.sin(phi)
|
||||||
|
local loc, dx, dy = cfxZones.createRandomPointInZone(spawnZone) -- also supports polygonal zones
|
||||||
rawData.x = rawData.x + dx
|
rawData.x = rawData.x + dx
|
||||||
rawData.y = rawData.y + dy
|
rawData.y = rawData.y + dy
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
dcsCommon = {}
|
dcsCommon = {}
|
||||||
dcsCommon.version = "2.7.9"
|
dcsCommon.version = "2.7.10"
|
||||||
--[[-- VERSION HISTORY
|
--[[-- VERSION HISTORY
|
||||||
2.2.6 - compassPositionOfARelativeToB
|
2.2.6 - compassPositionOfARelativeToB
|
||||||
- clockPositionOfARelativeToB
|
- clockPositionOfARelativeToB
|
||||||
@ -117,6 +117,7 @@ dcsCommon.version = "2.7.9"
|
|||||||
- createGroundGroupWithUnits corrected spelling of minDist, crashed scattered formation
|
- createGroundGroupWithUnits corrected spelling of minDist, crashed scattered formation
|
||||||
- randomPointInCircle fixed erroneous local for x, z
|
- randomPointInCircle fixed erroneous local for x, z
|
||||||
- "scattered" formation repaired
|
- "scattered" formation repaired
|
||||||
|
2.7.10- semaphore groundwork
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
@ -2892,7 +2893,30 @@ function dcsCommon.LSR(a, num)
|
|||||||
return a
|
return a
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- SEMAPHORES
|
||||||
|
--
|
||||||
|
dcsCommon.semaphores = {}
|
||||||
|
|
||||||
|
-- replacement for trigger.misc.getUserFlag
|
||||||
|
function dcsCommon.getUserFlag(flagName)
|
||||||
|
if dcsCommon.semaphores[flagName] then
|
||||||
|
return dcsCommon.semaphores[flagName]
|
||||||
|
end
|
||||||
|
|
||||||
|
return trigger.misc.getUserFlag(flagName)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- replacement for trigger.action.setUserFlag
|
||||||
|
function dcsCommon.setUserFlag(flagName, theValue)
|
||||||
|
-- not yet connected: semaphores
|
||||||
|
|
||||||
|
-- forget semaphore content if new value is old-school
|
||||||
|
if type(theValue) == "number" then
|
||||||
|
dcsCommon.semaphores[theValue] = nil --return to old-school
|
||||||
|
end
|
||||||
|
trigger.action.setUserFlag(flagName, theValue)
|
||||||
|
end
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
-- INIT
|
-- INIT
|
||||||
|
|||||||
@ -43,24 +43,24 @@ messenger.messengers = {}
|
|||||||
- unit
|
- unit
|
||||||
- group
|
- group
|
||||||
2.0.1 - config optimization
|
2.0.1 - config optimization
|
||||||
2.1.0 - unit only: dynamicUnitProcessing for
|
2.1.0 - unit only: dynamicUnitProcessing with other units/zones
|
||||||
- <bae: u/z> bearing to unit/zone
|
- <bae: u/z> bearing to unit/zone
|
||||||
- <rbae u/z> response mapped by unit's heading
|
- <rbae u/z> response mapped by unit's heading
|
||||||
- <clk: u/z> bearing in clock position to unit/zone
|
- <clk: u/z> bearing in clock position to unit/zone
|
||||||
- <rng: u/z> range to unit/zone
|
- <rng: u/z> range to unit/zone
|
||||||
- <hnd: u/z> bearing in left/right/ahead/behind
|
- <hnd: u/z> bearing in left/right/ahead/behind
|
||||||
- <sde: u/z> bearing in starboard/port/ahead/aft
|
- <sde: u/z> bearing in starboard/port/ahead/aft
|
||||||
- added dynamicGroupProcessing to select unit 1
|
- added dynamicGroupProcessing to select unit 1
|
||||||
- responses attribute
|
- responses attribute
|
||||||
- <rsp: flag>
|
- <rsp: flag>
|
||||||
- <rrnd> response randomized
|
- <rrnd> response randomized
|
||||||
- <rhdg: u/z> respons mapped by unit's heading
|
- <rhdg: u/z> respons mapped by unit's heading
|
||||||
- <cls unit> closing speed
|
- <cls unit> closing speed
|
||||||
- <vel unit> velocity (speed)
|
- <vel unit> velocity (speed)
|
||||||
- <asp unit> aspect
|
- <asp unit> aspect
|
||||||
- fix to messageMute
|
- fix to messageMute
|
||||||
- <type: unit>
|
- <type: unit>
|
||||||
|
2.1.1 - cosmetic: only output text if len>0 and not cls
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
@ -665,14 +665,18 @@ function messenger.isTriggered(theZone)
|
|||||||
if theZone.spaceAfter then msg = msg .. "\n" end
|
if theZone.spaceAfter then msg = msg .. "\n" end
|
||||||
|
|
||||||
if theZone.msgCoalition then
|
if theZone.msgCoalition then
|
||||||
trigger.action.outTextForCoalition(theZone.msgCoalition, msg, theZone.duration, theZone.clearScreen)
|
if #msg > 0 or theZone.clearScreen then
|
||||||
|
trigger.action.outTextForCoalition(theZone.msgCoalition, msg, theZone.duration, theZone.clearScreen)
|
||||||
|
end
|
||||||
trigger.action.outSoundForCoalition(theZone.msgCoalition, fileName)
|
trigger.action.outSoundForCoalition(theZone.msgCoalition, fileName)
|
||||||
elseif theZone.msgGroup then
|
elseif theZone.msgGroup then
|
||||||
local theGroup = Group.getByName(theZone.msgGroup)
|
local theGroup = Group.getByName(theZone.msgGroup)
|
||||||
if theGroup and Group.isExist(theGroup) then
|
if theGroup and Group.isExist(theGroup) then
|
||||||
local ID = theGroup:getID()
|
local ID = theGroup:getID()
|
||||||
msg = messenger.dynamicGroupProcessing(msg, theZone, theGroup)
|
msg = messenger.dynamicGroupProcessing(msg, theZone, theGroup)
|
||||||
trigger.action.outTextForGroup(ID, msg, theZone.duration, theZone.clearScreen)
|
if #msg > 0 or theZone.clearScreen then
|
||||||
|
trigger.action.outTextForGroup(ID, msg, theZone.duration, theZone.clearScreen)
|
||||||
|
end
|
||||||
trigger.action.outSoundForGroup(ID, fileName)
|
trigger.action.outSoundForGroup(ID, fileName)
|
||||||
end
|
end
|
||||||
elseif theZone.msgUnit then
|
elseif theZone.msgUnit then
|
||||||
@ -680,12 +684,16 @@ function messenger.isTriggered(theZone)
|
|||||||
if theUnit and Unit.isExist(theUnit) then
|
if theUnit and Unit.isExist(theUnit) then
|
||||||
local ID = theUnit:getID()
|
local ID = theUnit:getID()
|
||||||
msg = messenger.dynamicUnitProcessing(msg, theZone, theUnit)
|
msg = messenger.dynamicUnitProcessing(msg, theZone, theUnit)
|
||||||
trigger.action.outTextForUnit(ID, msg, theZone.duration, theZone.clearScreen)
|
if #msg > 0 or theZone.clearScreen then
|
||||||
|
trigger.action.outTextForUnit(ID, msg, theZone.duration, theZone.clearScreen)
|
||||||
|
end
|
||||||
trigger.action.outSoundForUnit(ID, fileName)
|
trigger.action.outSoundForUnit(ID, fileName)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- out to all
|
-- out to all
|
||||||
trigger.action.outText(msg, theZone.duration, theZone.clearScreen)
|
if #msg > 0 or theZone.clearScreen then
|
||||||
|
trigger.action.outText(msg, theZone.duration, theZone.clearScreen)
|
||||||
|
end
|
||||||
trigger.action.outSound(fileName)
|
trigger.action.outSound(fileName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -25,6 +25,7 @@ persistence.requiredLibs = {
|
|||||||
1.0.3 - no longer always tells " mission saved to"
|
1.0.3 - no longer always tells " mission saved to"
|
||||||
new 'saveNotification" can be off
|
new 'saveNotification" can be off
|
||||||
1.0.4 - new optional 'root' property
|
1.0.4 - new optional 'root' property
|
||||||
|
1.0.5 - desanitize check on readConfig to early-abort
|
||||||
|
|
||||||
|
|
||||||
PROVIDES LOAD/SAVE ABILITY TO MODULES
|
PROVIDES LOAD/SAVE ABILITY TO MODULES
|
||||||
@ -419,6 +420,11 @@ function persistence.collectFlagsFromZone(theZone)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function persistence.readConfigZone()
|
function persistence.readConfigZone()
|
||||||
|
if not _G["lfs"] then
|
||||||
|
trigger.action.outText("+++persistence: DCS not correctly desanitized. Persistence disabled", 30)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local theZone = cfxZones.getZoneByName("persistenceConfig")
|
local theZone = cfxZones.getZoneByName("persistenceConfig")
|
||||||
local hasConfig = true
|
local hasConfig = true
|
||||||
if not theZone then
|
if not theZone then
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
radioMenu = {}
|
radioMenu = {}
|
||||||
radioMenu.version = "2.0.0"
|
radioMenu.version = "2.0.1"
|
||||||
radioMenu.verbose = false
|
radioMenu.verbose = false
|
||||||
radioMenu.ups = 1
|
radioMenu.ups = 1
|
||||||
radioMenu.requiredLibs = {
|
radioMenu.requiredLibs = {
|
||||||
@ -24,6 +24,8 @@ radioMenu.menus = {}
|
|||||||
gereric helo type
|
gereric helo type
|
||||||
generic plane type
|
generic plane type
|
||||||
type works with coalition
|
type works with coalition
|
||||||
|
2.0.1 corrections to installMenu(), as suggested by GumidekCZ
|
||||||
|
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
@ -198,8 +200,9 @@ function radioMenu.installMenu(theZone)
|
|||||||
if cfxZones.hasProperty(theZone, "itemB") then
|
if cfxZones.hasProperty(theZone, "itemB") then
|
||||||
local menuB = cfxZones.getStringFromZoneProperty(theZone, "itemB", "<no B submenu>")
|
local menuB = cfxZones.getStringFromZoneProperty(theZone, "itemB", "<no B submenu>")
|
||||||
if theZone.menuGroup or theZone.menuTypes then
|
if theZone.menuGroup or theZone.menuTypes then
|
||||||
|
theZone.menuB = {}
|
||||||
for idx, grp in pairs(gID) do
|
for idx, grp in pairs(gID) do
|
||||||
theZone.menuB[grp] = missionCommands.addCommandForGroup(grp, menuB, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "B"})
|
theZone.menuB[grp] = missionCommands.addCommandForGroup(grp, menuB, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "B", grp})
|
||||||
end
|
end
|
||||||
elseif theZone.coalition == 0 then
|
elseif theZone.coalition == 0 then
|
||||||
theZone.menuB = missionCommands.addCommand(menuB, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "B"})
|
theZone.menuB = missionCommands.addCommand(menuB, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "B"})
|
||||||
@ -211,8 +214,9 @@ function radioMenu.installMenu(theZone)
|
|||||||
if cfxZones.hasProperty(theZone, "itemC") then
|
if cfxZones.hasProperty(theZone, "itemC") then
|
||||||
local menuC = cfxZones.getStringFromZoneProperty(theZone, "itemC", "<no C submenu>")
|
local menuC = cfxZones.getStringFromZoneProperty(theZone, "itemC", "<no C submenu>")
|
||||||
if theZone.menuGroup or theZone.menuTypes then
|
if theZone.menuGroup or theZone.menuTypes then
|
||||||
|
theZone.menuC = {}
|
||||||
for idx, grp in pairs(gID) do
|
for idx, grp in pairs(gID) do
|
||||||
theZone.menuC[grp] = missionCommands.addCommandForGroup(grp, menuC, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "C"})
|
theZone.menuC[grp] = missionCommands.addCommandForGroup(grp, menuC, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "C", grp})
|
||||||
end
|
end
|
||||||
elseif theZone.coalition == 0 then
|
elseif theZone.coalition == 0 then
|
||||||
theZone.menuC = missionCommands.addCommand(menuC, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "C"})
|
theZone.menuC = missionCommands.addCommand(menuC, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "C"})
|
||||||
@ -224,8 +228,9 @@ function radioMenu.installMenu(theZone)
|
|||||||
if cfxZones.hasProperty(theZone, "itemD") then
|
if cfxZones.hasProperty(theZone, "itemD") then
|
||||||
local menuD = cfxZones.getStringFromZoneProperty(theZone, "itemD", "<no D submenu>")
|
local menuD = cfxZones.getStringFromZoneProperty(theZone, "itemD", "<no D submenu>")
|
||||||
if theZone.menuGroup or theZone.menuTypes then
|
if theZone.menuGroup or theZone.menuTypes then
|
||||||
|
theZone.menuD = {}
|
||||||
for idx, grp in pairs(gID) do
|
for idx, grp in pairs(gID) do
|
||||||
theZone.menuD[grp] = missionCommands.addCommandForGroup(grp, menuD, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "D"})
|
theZone.menuD[grp] = missionCommands.addCommandForGroup(grp, menuD, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "D", grp})
|
||||||
end
|
end
|
||||||
elseif theZone.coalition == 0 then
|
elseif theZone.coalition == 0 then
|
||||||
theZone.menuD = missionCommands.addCommand(menuD, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "D"})
|
theZone.menuD = missionCommands.addCommand(menuD, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "D"})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user