mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 1.1.8b
update to cfxZones
This commit is contained in:
parent
da1abe4e6b
commit
5c1afa0c4b
@ -1,5 +1,5 @@
|
|||||||
cfxZones = {}
|
cfxZones = {}
|
||||||
cfxZones.version = "2.8.7"
|
cfxZones.version = "2.9.0"
|
||||||
|
|
||||||
-- 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
|
||||||
@ -95,6 +95,17 @@ cfxZones.version = "2.8.7"
|
|||||||
- 2.8.6 - fix in getFlagValue for missing delay
|
- 2.8.6 - fix in getFlagValue for missing delay
|
||||||
- 2.8.7 - update isPointInsideZone(thePoint, theZone, radiusIncrease) - new radiusIncrease
|
- 2.8.7 - update isPointInsideZone(thePoint, theZone, radiusIncrease) - new radiusIncrease
|
||||||
- isPointInsideZone() returns delta as well
|
- isPointInsideZone() returns delta as well
|
||||||
|
- 2.9.0 - linked zones can useOffset and useHeading
|
||||||
|
- getPoint update
|
||||||
|
- new getOrigin()
|
||||||
|
- pointInZone understands useOrig
|
||||||
|
- allStaticsInZone supports useOrig
|
||||||
|
- dPhi for zones with useHeading
|
||||||
|
- uHdg for zones with useHading, contains linked unit's original heading
|
||||||
|
- Late-linking implemented:
|
||||||
|
- linkUnit works for late-activating units
|
||||||
|
- linkUnit now also works for player / clients, dynamic (re-)linking
|
||||||
|
- linkUnit uses zone's origin for all calculations
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
cfxZones.verbose = false
|
cfxZones.verbose = false
|
||||||
@ -198,7 +209,7 @@ function cfxZones.readFromDCS(clearfirst)
|
|||||||
-- 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.
|
||||||
newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)
|
newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)
|
||||||
|
newZone.dcsOrigin = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)
|
||||||
|
|
||||||
-- start type processing. if zone.type exists, we have a mission
|
-- start type processing. if zone.type exists, we have a mission
|
||||||
-- created with 2.7 or above, else earlier
|
-- created with 2.7 or above, else earlier
|
||||||
@ -631,7 +642,7 @@ function cfxZones.allGroupNamesInZone(theZone, categ) -- categ is optional, must
|
|||||||
return inZones
|
return inZones
|
||||||
end
|
end
|
||||||
|
|
||||||
function cfxZones.allStaticsInZone(theZone) -- categ is optional, must be code
|
function cfxZones.allStaticsInZone(theZone, useOrigin) -- categ is optional, must be code
|
||||||
-- warning: does not check for exiting!
|
-- warning: does not check for exiting!
|
||||||
local inZones = {}
|
local inZones = {}
|
||||||
local coals = {0, 1, 2} -- all coalitions
|
local coals = {0, 1, 2} -- all coalitions
|
||||||
@ -639,7 +650,12 @@ function cfxZones.allStaticsInZone(theZone) -- categ is optional, must be code
|
|||||||
local allStats = coalition.getStaticObjects(coa)
|
local allStats = coalition.getStaticObjects(coa)
|
||||||
for key, statO in pairs(allStats) do -- iterate all groups
|
for key, statO in pairs(allStats) do -- iterate all groups
|
||||||
local oP = statO:getPoint()
|
local oP = statO:getPoint()
|
||||||
if cfxZones.pointInZone(oP, theZone) then
|
if useOrigin then
|
||||||
|
if cfxZones.pointInZone(oP, theZone, true) then
|
||||||
|
-- use DCS original coords
|
||||||
|
table.insert(inZones, statO)
|
||||||
|
end
|
||||||
|
elseif cfxZones.pointInZone(oP, theZone) then
|
||||||
table.insert(inZones, statO)
|
table.insert(inZones, statO)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -941,13 +957,18 @@ end
|
|||||||
-- the second value returned is the percentage of distance
|
-- the second value returned is the percentage of distance
|
||||||
-- from center to rim, with 100% being entirely in center, 0 = outside
|
-- from center to rim, with 100% being entirely in center, 0 = outside
|
||||||
-- the third value returned is the distance to center
|
-- the third value returned is the distance to center
|
||||||
function cfxZones.pointInZone(thePoint, theZone)
|
function cfxZones.pointInZone(thePoint, theZone, useOrig)
|
||||||
|
|
||||||
if not (theZone) then return false, 0, 0 end
|
if not (theZone) then return false, 0, 0 end
|
||||||
|
|
||||||
local pflat = {x = thePoint.x, y = 0, z = thePoint.z}
|
local pflat = {x = thePoint.x, y = 0, z = thePoint.z}
|
||||||
|
|
||||||
local zpoint = cfxZones.getPoint(theZone) -- updates zone if linked
|
local zpoint
|
||||||
|
if useOrig then
|
||||||
|
zpoint = cfxZones.getDCSOrigin(theZone)
|
||||||
|
else
|
||||||
|
zpoint = cfxZones.getPoint(theZone) -- updates zone if linked
|
||||||
|
end
|
||||||
local ppoint = thePoint -- xyz
|
local ppoint = thePoint -- xyz
|
||||||
local pflat = {x = ppoint.x, y = 0, z = ppoint.z}
|
local pflat = {x = ppoint.x, y = 0, z = ppoint.z}
|
||||||
local dist = dcsCommon.dist(zpoint, pflat)
|
local dist = dcsCommon.dist(zpoint, pflat)
|
||||||
@ -2033,26 +2054,39 @@ end
|
|||||||
--
|
--
|
||||||
-- requires that readFromDCS has been done
|
-- requires that readFromDCS has been done
|
||||||
--
|
--
|
||||||
function cfxZones.getPoint(aZone) -- always works, even linked, point can be reused
|
function cfxZones.getDCSOrigin(aZone)
|
||||||
|
local o = {}
|
||||||
|
o.x = aZone.dcsOrigin.x
|
||||||
|
o.y = 0
|
||||||
|
o.z = aZone.dcsOrigin.z
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
function cfxZones.getPoint(aZone) -- always works, even linked, returned point can be reused
|
||||||
if aZone.linkedUnit then
|
if aZone.linkedUnit then
|
||||||
local theUnit = aZone.linkedUnit
|
local theUnit = aZone.linkedUnit
|
||||||
-- has a link. is link existing?
|
-- has a link. is link existing?
|
||||||
if theUnit:isExist() then
|
if theUnit:isExist() then
|
||||||
-- updates zone position
|
-- updates zone position
|
||||||
cfxZones.centerZoneOnUnit(aZone, theUnit)
|
cfxZones.centerZoneOnUnit(aZone, theUnit)
|
||||||
cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)
|
local dx = aZone.dx
|
||||||
|
local dy = aZone.dy
|
||||||
|
if aZone.useHeading then
|
||||||
|
dx, dy = cfxZones.calcHeadingOffset(aZone, theUnit)
|
||||||
|
end
|
||||||
|
cfxZones.offsetZone(aZone, dx, dy)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local thePos = {}
|
local thePos = {}
|
||||||
thePos.x = aZone.point.x
|
thePos.x = aZone.point.x
|
||||||
thePos.y = 0 -- aZone.y
|
thePos.y = 0 -- aZone.y
|
||||||
thePos.z = aZone.point.z
|
thePos.z = aZone.point.z
|
||||||
-- update the zone as well -- that's stupid!
|
--[[--
|
||||||
--[[-- aZone.point = thePos
|
if aZone.linkedUnit then
|
||||||
local retPoint = {} -- create new copy to pass back
|
trigger.action.outText("GetPoint: LINKED <".. aZone.name .. "> p = " .. dcsCommon.point2text(thePos) .. ", O = " .. dcsCommon.point2text(cfxZones.getDCSOrigin(aZone)), 30 )
|
||||||
retPoint.x = thePos.x
|
else
|
||||||
retPoint.y = 0
|
trigger.action.outText("GetPoint: unlinked <".. aZone.name .. "> p = " .. dcsCommon.point2text(thePos) .. ", O = " .. dcsCommon.point2text(cfxZones.getDCSOrigin(aZone)), 30 )
|
||||||
retPoint.z = thePos.z
|
end
|
||||||
--]]--
|
--]]--
|
||||||
return thePos
|
return thePos
|
||||||
end
|
end
|
||||||
@ -2063,6 +2097,22 @@ function cfxZones.linkUnitToZone(theUnit, theZone, dx, dy) -- note: dy is really
|
|||||||
if not dy then dy = 0 end
|
if not dy then dy = 0 end
|
||||||
theZone.dx = dx
|
theZone.dx = dx
|
||||||
theZone.dy = dy
|
theZone.dy = dy
|
||||||
|
theZone.rxy = math.sqrt(dx * dx + dy * dy) -- radius
|
||||||
|
local unitHeading = dcsCommon.getUnitHeading(theUnit)
|
||||||
|
local bearingOffset = math.atan2(dy, dx) -- rads
|
||||||
|
if bearingOffset < 0 then bearingOffset = bearingOffset + 2 * 3.141592 end
|
||||||
|
--trigger.action.outText("zone <" .. theZone.name .. "> is <" .. math.floor(bearingOffset * 57.2958) .. "> degrees from Unit <" .. theUnit:getName() .. ">", 30)
|
||||||
|
--trigger.action.outText("Unit <" .. theUnit:getName() .. "> has heading .. <" .. math.floor(57.2958 * unitHeading) .. ">", 30)
|
||||||
|
local dPhi = bearingOffset - unitHeading
|
||||||
|
if dPhi < 0 then dPhi = dPhi + 2 * 3.141592 end
|
||||||
|
if (theZone.verbose and theZone.useHeading) then
|
||||||
|
trigger.action.outText("Zone is at <" .. math.floor(57.2958 * dPhi) .. "> relative to unit heading", 30)
|
||||||
|
end
|
||||||
|
theZone.dPhi = dPhi -- constant delta between unit heading and
|
||||||
|
-- direction to zone
|
||||||
|
theZone.uHdg = unitHeading -- original unit heading to turn other
|
||||||
|
-- units if need be
|
||||||
|
--trigger.action.outText("Link setup: dx=<" .. dx .. ">, dy=<" .. dy .. "> unit original hdg = <" .. math.floor(57.2958 * unitHeading) .. ">", 30)
|
||||||
end
|
end
|
||||||
|
|
||||||
function cfxZones.zonesLinkedToUnit(theUnit) -- returns all zones linked to this unit
|
function cfxZones.zonesLinkedToUnit(theUnit) -- returns all zones linked to this unit
|
||||||
@ -2076,19 +2126,74 @@ function cfxZones.zonesLinkedToUnit(theUnit) -- returns all zones linked to this
|
|||||||
return linkedZones
|
return linkedZones
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cfxZones.calcHeadingOffset(aZone, theUnit)
|
||||||
|
-- recalc dx and dy based on ry and current heading
|
||||||
|
-- since 0 degrees is [0,1] = [0,r] the calculation of
|
||||||
|
-- rotated coords can be simplified from
|
||||||
|
-- xr = x cos phi - y sin phi = -r sin phi
|
||||||
|
-- yr = y cos phi + x sin phi = r cos phi
|
||||||
|
local unitHeading = dcsCommon.getUnitHeading(theUnit)
|
||||||
|
-- add heading offset
|
||||||
|
local zoneBearing = unitHeading + aZone.dPhi
|
||||||
|
if zoneBearing > 2 * 3.141592 then zoneBearing = zoneBearing - 2 * 3.141592 end
|
||||||
|
|
||||||
|
-- in DCS, positive x is north (wtf?) and positive z is east
|
||||||
|
local dy = (-aZone.rxy) * math.sin(zoneBearing)
|
||||||
|
local dx = aZone.rxy * math.cos(zoneBearing)
|
||||||
|
|
||||||
|
--trigger.action.outText("zone bearing is " .. math.floor(zoneBearing * 57.2958) .. " dx = <" .. dx .. "> , dy = <" .. dy .. ">", 30)
|
||||||
|
return dx, -dy -- note: dy is z coord!!!!
|
||||||
|
end
|
||||||
|
|
||||||
function cfxZones.updateMovingZones()
|
function cfxZones.updateMovingZones()
|
||||||
cfxZones.updateSchedule = timer.scheduleFunction(cfxZones.updateMovingZones, {}, timer.getTime() + 1/cfxZones.ups)
|
cfxZones.updateSchedule = timer.scheduleFunction(cfxZones.updateMovingZones, {}, timer.getTime() + 1/cfxZones.ups)
|
||||||
-- simply scan all cfx zones for the linkedUnit property and if there
|
-- simply scan all cfx zones for the linkedUnit property and if there
|
||||||
-- update the zone's points
|
-- update the zone's points
|
||||||
for aName,aZone in pairs(cfxZones.zones) do
|
for aName,aZone in pairs(cfxZones.zones) do
|
||||||
|
if aZone.linkBroken then
|
||||||
|
-- try to relink
|
||||||
|
cfxZones.initLink(aZone)
|
||||||
|
end
|
||||||
if aZone.linkedUnit then
|
if aZone.linkedUnit then
|
||||||
local theUnit = aZone.linkedUnit
|
local theUnit = aZone.linkedUnit
|
||||||
-- has a link. is link existing?
|
-- has a link. is link existing?
|
||||||
if theUnit:isExist() then
|
if theUnit:isExist() then
|
||||||
cfxZones.centerZoneOnUnit(aZone, theUnit)
|
cfxZones.centerZoneOnUnit(aZone, theUnit)
|
||||||
cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)
|
local dx = aZone.dx
|
||||||
--trigger.action.outText("cf/x zones update " .. aZone.name, 30)
|
local dy = aZone.dy -- this is actually z
|
||||||
|
if aZone.useHeading then
|
||||||
|
dx, dy = cfxZones.calcHeadingOffset(aZone, theUnit)
|
||||||
end
|
end
|
||||||
|
cfxZones.offsetZone(aZone, dx, dy)
|
||||||
|
else
|
||||||
|
-- we lost link
|
||||||
|
aZone.linkBroken = true
|
||||||
|
aZone.linkedUnit = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function cfxZones.initLink(theZone)
|
||||||
|
theZone.linkBroken = true
|
||||||
|
theZone.linkedUnit = nil
|
||||||
|
theUnit = Unit.getByName(theZone.linkName)
|
||||||
|
if theUnit then
|
||||||
|
local dx = 0
|
||||||
|
local dz = 0
|
||||||
|
if theZone.useOffset or theZone.useHeading then
|
||||||
|
local delta = dcsCommon.vSub(cfxZones.getDCSOrigin(theZone),theUnit:getPoint()) -- delta = B - A
|
||||||
|
dx = delta.x
|
||||||
|
dz = delta.z
|
||||||
|
end
|
||||||
|
cfxZones.linkUnitToZone(theUnit, theZone, dx, dz) -- also sets theZone.linkedUnit
|
||||||
|
if theZone.verbose then
|
||||||
|
trigger.action.outText("Link established for zone <" .. theZone.name .. "> to unit <" .. theZone.linkName .. ">: dx=<" .. math.floor(dx) .. ">, dz=<" .. math.floor(dz) .. "> dist = <" .. math.floor(math.sqrt(dx * dx + dz * dz)) .. ">" , 30)
|
||||||
|
end
|
||||||
|
theZone.linkBroken = nil
|
||||||
|
else
|
||||||
|
if theZone.verbose then
|
||||||
|
trigger.action.outText("Linked unit: no unit <" .. theZone.linkName .. "> to link <" .. theZone.name .. "> to", 30)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2096,29 +2201,43 @@ end
|
|||||||
function cfxZones.startMovingZones()
|
function cfxZones.startMovingZones()
|
||||||
-- read all zoness, and look for a property called 'linkedUnit'
|
-- read all zoness, and look for a property called 'linkedUnit'
|
||||||
-- which will make them a linked zone if there is a unit that exists
|
-- which will make them a linked zone if there is a unit that exists
|
||||||
|
-- also suppors 'useOffset' and 'useHeading'
|
||||||
for aName,aZone in pairs(cfxZones.zones) do
|
for aName,aZone in pairs(cfxZones.zones) do
|
||||||
local lU = cfxZones.getZoneProperty(aZone, "linkedUnit")
|
local lU = nil
|
||||||
|
if cfxZones.hasProperty(aZone, "linkedUnit") then
|
||||||
|
lU = cfxZones.getZoneProperty(aZone, "linkedUnit")
|
||||||
|
end
|
||||||
if lU then
|
if lU then
|
||||||
|
aZone.linkName = lU
|
||||||
|
aZone.useOffset = cfxZones.getBoolFromZoneProperty(aZone, "useOffset", false)
|
||||||
|
aZone.useHeading = cfxZones.getBoolFromZoneProperty(aZone, "useHeading", false)
|
||||||
|
|
||||||
|
cfxZones.initLink(aZone)
|
||||||
|
--[[--
|
||||||
-- this zone is linked to a unit
|
-- this zone is linked to a unit
|
||||||
theUnit = Unit.getByName(lU)
|
theUnit = Unit.getByName(lU)
|
||||||
local useOffset = cfxZones.getBoolFromZoneProperty(aZone, "useOffset", false)
|
local useOffset = cfxZones.getBoolFromZoneProperty(aZone, "useOffset", false)
|
||||||
if useOffset then aZone.useOffset = true end
|
if useOffset then aZone.useOffset = true end
|
||||||
|
local useHeading = cfxZones.getBoolFromZoneProperty(aZone, "useHeading")
|
||||||
|
if useHeading then aZone.useHeading = true end
|
||||||
if theUnit then
|
if theUnit then
|
||||||
local dx = 0
|
local dx = 0
|
||||||
local dz = 0
|
local dz = 0
|
||||||
if useOffset then
|
if useOffset or useHeading then
|
||||||
local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A
|
local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A
|
||||||
dx = delta.x
|
dx = delta.x
|
||||||
dz = delta.z
|
dz = delta.z
|
||||||
end
|
end
|
||||||
cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)
|
cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)
|
||||||
--trigger.action.outText("cf/x zones: linked " .. aZone.name .. " to " .. theUnit:getName(), 30)
|
--trigger.action.outText("Link setup: dx=<" .. dx .. ">, dz=<" .. dz .. ">", 30)
|
||||||
if useOffset then
|
if useOffset then
|
||||||
--trigger.action.outText("and dx = " .. dx .. " dz = " .. dz, 30)
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
trigger.action.outText("Linked unit: no unit to link <" .. aZone.name .. "> to", 30)
|
||||||
end
|
end
|
||||||
|
--]]--
|
||||||
end
|
end
|
||||||
-- support for local verbose flag
|
-- support for zone-local verbose flag
|
||||||
aZone.verbose = cfxZones.getBoolFromZoneProperty(aZone, "verbose", false)
|
aZone.verbose = cfxZones.getBoolFromZoneProperty(aZone, "verbose", false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user