mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 1.2.0
LINK UNIT support
This commit is contained in:
parent
3de20ed5f1
commit
46afa49c3a
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
cfxZones = {}
|
||||
cfxZones.version = "2.9.2"
|
||||
cfxZones.version = "3.0.0"
|
||||
|
||||
-- cf/x zone management module
|
||||
-- reads dcs zones and makes them accessible and mutable
|
||||
@ -113,6 +113,9 @@ cfxZones.version = "2.9.2"
|
||||
- createRandomZoneInZone uses createRandomPointInPolyZone
|
||||
- new createRandomPointInZone()
|
||||
- new randomPointInZone()
|
||||
- 3.0.0 - support for DCS 2.8 linkUnit attribute, integration with
|
||||
linedUnit and warning.
|
||||
- initZoneVerbosity()
|
||||
|
||||
|
||||
--]]--
|
||||
@ -216,8 +219,18 @@ function cfxZones.readFromDCS(clearfirst)
|
||||
-- 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
|
||||
-- drop y from zone calculations to see if inside.
|
||||
newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)
|
||||
newZone.dcsOrigin = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)
|
||||
-- WARNING: ME linked zones have a relative x any y
|
||||
-- to the linked unit
|
||||
if dcsZone.linkUnit then
|
||||
-- calculate the zone's real position by accessing the unit's MX data
|
||||
-- as precached by dcsCommon
|
||||
local ux, uy = dcsCommon.getUnitStartPosByID(dcsZone.linkUnit)
|
||||
newZone.point = cfxZones.createPoint(ux + dcsZone.x, 0, uy + dcsZone.y)
|
||||
newZone.dcsOrigin = cfxZones.createPoint(ux + dcsZone.x, 0, uy + dcsZone.y)
|
||||
else
|
||||
newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)
|
||||
newZone.dcsOrigin = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)
|
||||
end
|
||||
|
||||
-- start type processing. if zone.type exists, we have a mission
|
||||
-- created with 2.7 or above, else earlier
|
||||
@ -2319,22 +2332,29 @@ function cfxZones.updateMovingZones()
|
||||
end
|
||||
|
||||
function cfxZones.initLink(theZone)
|
||||
--trigger.action.outText("enter initlink for <" .. theZone.name .. ">", 30)
|
||||
--trigger.action.outText("entry verbose check: <" .. theZone.name .. "> is verbose = " .. dcsCommon.bool2YesNo(theZone.verbose), 30)
|
||||
theZone.linkBroken = true
|
||||
theZone.linkedUnit = nil
|
||||
theUnit = Unit.getByName(theZone.linkName)
|
||||
if theUnit then
|
||||
--trigger.action.outText("initlink has link to <" .. theZone.linkName .. "> for <" .. theZone.name .. ">", 30)
|
||||
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
|
||||
local A = cfxZones.getDCSOrigin(theZone)
|
||||
local B = theUnit:getPoint()
|
||||
local delta = dcsCommon.vSub(A,B)
|
||||
dx = delta.x
|
||||
dz = delta.z
|
||||
end
|
||||
cfxZones.linkUnitToZone(theUnit, theZone, dx, dz) -- also sets theZone.linkedUnit
|
||||
--trigger.action.outText("verbose check: <" .. theZone.name .. "> is verbose = " .. dcsCommon.bool2YesNo(theZone.verbose), 30)
|
||||
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
|
||||
--trigger.action.outText("done linking <" .. theZone.linkName .. "> to zone <" .. theZone.name .. ">", 30)
|
||||
else
|
||||
if theZone.verbose then
|
||||
trigger.action.outText("Linked unit: no unit <" .. theZone.linkName .. "> to link <" .. theZone.name .. "> to", 30)
|
||||
@ -2343,49 +2363,48 @@ function cfxZones.initLink(theZone)
|
||||
end
|
||||
|
||||
function cfxZones.startMovingZones()
|
||||
-- read all zoness, and look for a property called 'linkedUnit'
|
||||
-- read all zones, and look for a property called 'linkedUnit'
|
||||
-- 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
|
||||
|
||||
local lU = nil
|
||||
if cfxZones.hasProperty(aZone, "linkedUnit") then
|
||||
-- check if DCS zone has the linkUnit new attribute introduced in
|
||||
-- late 2022 with 2.8
|
||||
if aZone.dcsZone.linkUnit then
|
||||
local theID = aZone.dcsZone.linkUnit
|
||||
lU = dcsCommon.getUnitNameByID(theID)
|
||||
if not lU then
|
||||
trigger.action.outText("WARNING: Zone <" .. aZone.name .. ">: cannot resolve linked unit ID <" .. theID .. ">", 30)
|
||||
lU = "***DML link err***"
|
||||
end
|
||||
elseif cfxZones.hasProperty(aZone, "linkedUnit") then
|
||||
lU = cfxZones.getZoneProperty(aZone, "linkedUnit")
|
||||
end
|
||||
|
||||
-- sanity check
|
||||
if aZone.dcsZone.linkUnit and cfxZones.hasProperty(aZone, "linkedUnit") then
|
||||
trigger.action.outText("WARNING: Zone <" .. aZone.name .. "> has dual unit link definition. Will use link to unit <" .. lU .. ">", 30)
|
||||
end
|
||||
|
||||
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
|
||||
theUnit = Unit.getByName(lU)
|
||||
local useOffset = cfxZones.getBoolFromZoneProperty(aZone, "useOffset", false)
|
||||
if useOffset then aZone.useOffset = true end
|
||||
local useHeading = cfxZones.getBoolFromZoneProperty(aZone, "useHeading")
|
||||
if useHeading then aZone.useHeading = true end
|
||||
if theUnit then
|
||||
local dx = 0
|
||||
local dz = 0
|
||||
if useOffset or useHeading then
|
||||
local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A
|
||||
dx = delta.x
|
||||
dz = delta.z
|
||||
end
|
||||
cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)
|
||||
--trigger.action.outText("Link setup: dx=<" .. dx .. ">, dz=<" .. dz .. ">", 30)
|
||||
if useOffset then
|
||||
end
|
||||
else
|
||||
trigger.action.outText("Linked unit: no unit to link <" .. aZone.name .. "> to", 30)
|
||||
end
|
||||
--]]--
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function cfxZones.initZoneVerbosity()
|
||||
for aName,aZone in pairs(cfxZones.zones) do
|
||||
-- support for zone-local verbose flag
|
||||
aZone.verbose = cfxZones.getBoolFromZoneProperty(aZone, "verbose", false)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- init
|
||||
--
|
||||
@ -2405,6 +2424,9 @@ function cfxZones.init()
|
||||
aZone.owner = cfxZones.getCoalitionFromZoneProperty(aZone, "owner", 0)
|
||||
end
|
||||
|
||||
-- enable all zone's verbose flags if present
|
||||
-- must be done BEFORE we start the moving zones
|
||||
cfxZones.initZoneVerbosity()
|
||||
|
||||
-- now initialize moving zones
|
||||
cfxZones.startMovingZones()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
cloneZones = {}
|
||||
cloneZones.version = "1.6.1"
|
||||
cloneZones.version = "1.6.3"
|
||||
cloneZones.verbose = false
|
||||
cloneZones.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
@ -71,7 +71,10 @@ cloneZones.allCObjects = {} -- all clones objects
|
||||
- cloning with rndLoc supports polygons
|
||||
- corrected rndLoc without centerOnly to not include individual offsets
|
||||
- ensure support of recovery tanker resolve cloned group
|
||||
|
||||
1.6.2 - optimization to hasLiveUnits()
|
||||
1.6.3 - removed verbosity bug with rndLoc
|
||||
uniqueNameGroupData has provisions for naming scheme
|
||||
new uniqueNameStaticData() for naming scheme
|
||||
|
||||
--]]--
|
||||
|
||||
@ -512,14 +515,23 @@ function cloneZones.uniqueID()
|
||||
return uid
|
||||
end
|
||||
|
||||
function cloneZones.uniqueNameGroupData(theData)
|
||||
function cloneZones.uniqueNameGroupData(theData, theCloneZone)
|
||||
theData.name = dcsCommon.uuid(theData.name)
|
||||
local units = theData.units
|
||||
for idx, aUnit in pairs(units) do
|
||||
aUnit.name = dcsCommon.uuid(aUnit.name)
|
||||
if theCloneZone and theCloneZone.namingScheme then
|
||||
else
|
||||
-- default naming scheme: <name>-<uuid>
|
||||
aUnit.name = dcsCommon.uuid(aUnit.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cloneZones.uniqueNameStaticData(theData, spawnZone)
|
||||
theData.name = dcsCommon.uuid(theData.name)
|
||||
|
||||
end
|
||||
|
||||
function cloneZones.uniqueIDGroupData(theData)
|
||||
theData.groupId = cloneZones.uniqueID()
|
||||
end
|
||||
@ -821,21 +833,12 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
|
||||
if spawnZone.rndLoc then
|
||||
-- calculate the entire group's displacement
|
||||
local units = rawData.units
|
||||
--[[
|
||||
local r = math.random() * spawnZone.radius
|
||||
local phi = 6.2831 * math.random() -- that's 2Pi, folx
|
||||
local dx = r * math.cos(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
|
||||
if not spawnZone.centerOnly then
|
||||
-- *every unit's displacement is randomized
|
||||
-- r = math.random() * spawnZone.radius
|
||||
-- phi = 6.2831 * math.random() -- that's 2Pi, folx
|
||||
-- dx = r * math.cos(phi)
|
||||
-- dy = r * math.sin(phi)
|
||||
loc, dx, dy = cfxZones.createRandomPointInZone(spawnZone)
|
||||
aUnit.x = loc.x
|
||||
aUnit.y = loc.z
|
||||
@ -844,7 +847,7 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
|
||||
aUnit.y = aUnit.y + dy
|
||||
end
|
||||
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: dx = " .. dx .. ", dy= " .. dy .. ".", 30)
|
||||
end
|
||||
|
||||
end
|
||||
@ -923,7 +926,7 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
|
||||
dcsCommon.rotateGroupData(rawData, spawnZone.turn + 57.2958 *dHeading, newCenter.x, newCenter.z)
|
||||
|
||||
-- make sure unit and group names are unique
|
||||
cloneZones.uniqueNameGroupData(rawData)
|
||||
cloneZones.uniqueNameGroupData(rawData, spawnZone)
|
||||
|
||||
-- see what country we spawn for
|
||||
ctry = cloneZones.resolveOwnership(spawnZone, ctry)
|
||||
@ -1042,7 +1045,8 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
|
||||
dcsCommon.rotateUnitData(rawData, spawnZone.turn + 57.2958 * dHeading, newCenter.x, newCenter.z)
|
||||
|
||||
-- make sure static name is unique and remember original
|
||||
rawData.name = dcsCommon.uuid(rawData.name)
|
||||
cloneZones.uniqueNameStaticData(rawData, spawnZone)
|
||||
--rawData.name = dcsCommon.uuid(rawData.name)
|
||||
rawData.unitId = cloneZones.uniqueID()
|
||||
rawData.CZTargetID = rawData.unitId
|
||||
|
||||
@ -1210,12 +1214,18 @@ function cloneZones.hasLiveUnits(theZone)
|
||||
if theZone.mySpawns then
|
||||
for idx, aGroup in pairs(theZone.mySpawns) do
|
||||
if aGroup:isExist() then
|
||||
-- an easier/faster method would be to invoke
|
||||
-- aGroup:getSize()
|
||||
local uNum = aGroup:getSize()
|
||||
if uNum > 0 then return true end
|
||||
--[[
|
||||
local allUnits = aGroup:getUnits()
|
||||
for idy, aUnit in pairs(allUnits) do
|
||||
if aUnit:isExist() and aUnit:getLife() >= 1 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
--]]--
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
dcsCommon = {}
|
||||
dcsCommon.version = "2.7.10"
|
||||
dcsCommon.version = "2.8.0"
|
||||
--[[-- VERSION HISTORY
|
||||
2.2.6 - compassPositionOfARelativeToB
|
||||
- clockPositionOfARelativeToB
|
||||
@ -118,6 +118,11 @@ dcsCommon.version = "2.7.10"
|
||||
- randomPointInCircle fixed erroneous local for x, z
|
||||
- "scattered" formation repaired
|
||||
2.7.10- semaphore groundwork
|
||||
2.8.0 - new collectMissionIDs at start-up
|
||||
- new getUnitNameByID
|
||||
- new getGroupNameByID
|
||||
- bool2YesNo alsco can return NIL
|
||||
- new getUnitStartPosByID
|
||||
|
||||
--]]--
|
||||
|
||||
@ -134,6 +139,12 @@ dcsCommon.version = "2.7.10"
|
||||
dcsCommon.troopCarriers = {"Mi-8MT", "UH-1H", "Mi-24P"} -- Ka-50 and Gazelle can't carry troops
|
||||
dcsCommon.coalitionSides = {0, 1, 2}
|
||||
|
||||
-- lookup tables
|
||||
dcsCommon.groupID2Name = {}
|
||||
dcsCommon.unitID2Name = {}
|
||||
dcsCommon.unitID2X = {}
|
||||
dcsCommon.unitID2Y = {}
|
||||
|
||||
-- verify that a module is loaded. obviously not required
|
||||
-- for dcsCommon, but all higher-order modules
|
||||
function dcsCommon.libCheck(testingFor, requiredLibs)
|
||||
@ -147,6 +158,82 @@ dcsCommon.version = "2.7.10"
|
||||
return canRun
|
||||
end
|
||||
|
||||
-- read all groups and units from miz and build a reference table
|
||||
function dcsCommon.collectMissionIDs()
|
||||
-- create cross reference tables to be able to get a group or
|
||||
-- unit's name by ID
|
||||
for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions
|
||||
local coa_name = coa_name_miz
|
||||
if string.lower(coa_name_miz) == 'neutrals' then -- remove 's' at neutralS
|
||||
coa_name = 'neutral'
|
||||
end
|
||||
-- directly convert coalition into number for easier access later
|
||||
local coaNum = 0
|
||||
if coa_name == "red" then coaNum = 1 end
|
||||
if coa_name == "blue" then coaNum = 2 end
|
||||
|
||||
if type(coa_data) == 'table' then -- coalition = {bullseye, nav_points, name, county},
|
||||
-- with county being an array
|
||||
if coa_data.country then -- make sure there a country table for this coalition
|
||||
for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this
|
||||
-- per country = {id, name, vehicle, helicopter, plane, ship, static}
|
||||
local countryName = string.lower(cntry_data.name)
|
||||
local countryID = cntry_data.id
|
||||
if type(cntry_data) == 'table' then -- filter strings .id and .name
|
||||
for obj_type_name, obj_type_data in pairs(cntry_data) do
|
||||
-- only look at helos, ships, planes and vehicles
|
||||
if obj_type_name == "helicopter" or
|
||||
obj_type_name == "ship" or
|
||||
obj_type_name == "plane" or
|
||||
obj_type_name == "vehicle" or
|
||||
obj_type_name == "static" -- what about "cargo"?
|
||||
then -- (so it's not id or name)
|
||||
local category = obj_type_name
|
||||
if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's at least one group!
|
||||
for group_num, group_data in pairs(obj_type_data.group) do
|
||||
|
||||
local aName = group_data.name
|
||||
local aID = group_data.groupId
|
||||
-- store this reference
|
||||
dcsCommon.groupID2Name[aID] = aName
|
||||
|
||||
-- now iterate all units in this group
|
||||
-- for player into
|
||||
for unit_num, unit_data in pairs(group_data.units) do
|
||||
if unit_data.name and unit_data.unitId then
|
||||
-- store this reference
|
||||
dcsCommon.unitID2Name[unit_data.unitId] = unit_data.name
|
||||
dcsCommon.unitID2X[unit_data.unitId] = unit_data.x
|
||||
dcsCommon.unitID2Y[unit_data.unitId] = unit_data.y
|
||||
end
|
||||
end -- for all units
|
||||
end -- for all groups
|
||||
end --if has category data
|
||||
end --if plane, helo etc... category
|
||||
end --for all objects in country
|
||||
end --if has country data
|
||||
end --for all countries in coalition
|
||||
end --if coalition has country table
|
||||
end -- if there is coalition data
|
||||
end --for all coalitions in mission
|
||||
end
|
||||
|
||||
function dcsCommon.getUnitNameByID(theID)
|
||||
-- accessor function for later expansion
|
||||
return dcsCommon.unitID2Name[theID]
|
||||
end
|
||||
|
||||
function dcsCommon.getGroupNameByID(theID)
|
||||
-- accessor function for later expansion
|
||||
return dcsCommon.groupID2Name[theID]
|
||||
end
|
||||
|
||||
function dcsCommon.getUnitStartPosByID(theID)
|
||||
local x = dcsCommon.unitID2X[theID]
|
||||
local y = dcsCommon.unitID2Y[theID]
|
||||
return x, y
|
||||
end
|
||||
|
||||
-- returns only positive values, lo must be >0 and <= hi
|
||||
function dcsCommon.randomBetween(loBound, hiBound)
|
||||
if not loBound then loBound = 1 end
|
||||
@ -2042,7 +2129,10 @@ end
|
||||
end
|
||||
|
||||
function dcsCommon.bool2YesNo(theBool)
|
||||
if not theBool then theBool = false end
|
||||
if not theBool then
|
||||
theBool = false
|
||||
return "NIL"
|
||||
end
|
||||
if theBool then return "yes" end
|
||||
return "no"
|
||||
end
|
||||
@ -2917,14 +3007,18 @@ function dcsCommon.setUserFlag(flagName, theValue)
|
||||
end
|
||||
trigger.action.setUserFlag(flagName, theValue)
|
||||
end
|
||||
|
||||
--
|
||||
--
|
||||
-- INIT
|
||||
--
|
||||
--
|
||||
-- init any variables the lib requires internally
|
||||
-- init any variables, tables etc that the lib requires internally
|
||||
function dcsCommon.init()
|
||||
cbID = 0
|
||||
-- create ID tables
|
||||
dcsCommon.collectMissionIDs()
|
||||
|
||||
--dcsCommon.uuIdent = 0
|
||||
if (dcsCommon.verbose) or true then
|
||||
trigger.action.outText("dcsCommon v" .. dcsCommon.version .. " loaded", 10)
|
||||
@ -2935,10 +3029,3 @@ end
|
||||
-- do init.
|
||||
dcsCommon.init()
|
||||
|
||||
--[[--
|
||||
|
||||
to do:
|
||||
- formation 2Column
|
||||
- formation 3Column
|
||||
|
||||
-]]--
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user