Version 2,27

The Debugger XRef
This commit is contained in:
Christian Franz 2024-07-04 11:03:00 +02:00
parent 0513fac2f2
commit 76083ff2b6
14 changed files with 641 additions and 42 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
cfxMX = {}
cfxMX.version = "2.0.1"
cfxMX.version = "2.0.2"
cfxMX.verbose = false
--[[--
Mission data decoder. Access to ME-built mission structures
@ -12,7 +12,7 @@ cfxMX.verbose = false
2.0.0 - clean-up
- harmonized with cfxGroups
2.0.1 - groupHotByName
2.0.2 - partOfGroupDataInZone(), allGroupsInZoneByData() from milHelo
--]]--
cfxMX.groupNamesByID = {}
@ -343,6 +343,38 @@ function cfxMX.catText2ID(inText)
return outCat
end
function cfxMX.partOfGroupDataInZone(theZone, theUnits) -- move to mx?
--local zP --= cfxZones.getPoint(theZone)
local zP = theZone:getDCSOrigin() -- don't use getPoint now.
zP.y = 0
for idx, aUnit in pairs(theUnits) do
local uP = {}
uP.x = aUnit.x
uP.y = 0
uP.z = aUnit.y -- !! y-z
if theZone:pointInZone(uP) then return true end
end
return false
end
function cfxMX.allGroupsInZoneByData(theZone) -- returns groups indexed by name and count
local theGroupsInZone = {}
local count = 0
for groupName, groupData in pairs(cfxMX.groupDataByName) do
if groupData.units then
if cfxMX.partOfGroupDataInZone(theZone, groupData.units) then
theGroupsInZone[groupName] = groupData -- DATA! work on clones!
count = count + 1
if theZone.verbose then
trigger.action.outText("+++cfxMX: added group <" .. groupName .. "> for zone <" .. theZone.name .. ">", 30)
end
end
end
end
return theGroupsInZone, count
end
function cfxMX.start()
cfxMX.createCrossReferences()

View File

@ -1,5 +1,5 @@
cfxZones = {}
cfxZones.version = "4.3.4"
cfxZones.version = "4.3.6"
-- cf/x zone management module
-- reads dcs zones and makes them accessible and mutable
@ -53,6 +53,11 @@ cfxZones.version = "4.3.4"
- 4.3.2 - new getListFromZoneProperty()
- 4.3.3 - hardened calculateZoneBounds
- 4.3.4 - rewrote zone bounds for poly zones
- 4.3.5 - hardened getStringFromZoneProperty against number value returns (WebEd bug)
- 4.3.6 - tiny optimization in isPointInsideQuad
- moving zone - hardening code for static objects
- moving zones - now deriving dx, dy,uHeading from dcsCommon xref for linked zones
--]]--
--
@ -208,7 +213,7 @@ function cfxZones.readFromDCS(clearfirst)
-- add to my table
cfxZones.zones[upperName] = newZone -- WARNING: UPPER ZONE!!!
--trigger.action.outText("znd: procced " .. newZone.name .. " with radius " .. newZone.radius, 30)
else
if cfxZones.verbose then
trigger.action.outText("cf/x zones: malformed zone #" .. i .. " dropped", 10)
@ -706,7 +711,7 @@ function cfxZones.isPointInsideQuad(thePoint, A, B, C, D)
-- so all we need to do is make sure all results of isLeft for all
-- four sides are the same
mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok
local mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok
-- they just must be the same side.
if (cfxZones.isLeftXZ(B, C, thePoint ~= mustMatch)) then return false end -- on other side than all before
if (cfxZones.isLeftXZ(C, D, thePoint ~= mustMatch)) then return false end
@ -2220,6 +2225,9 @@ function cfxZones.getStringFromZoneProperty(theZone, theProperty, default)
-- OOP heavy duty test here
local p = theZone:getZoneProperty(theProperty)
if not p then return default end
if type(p) == "number" then
p = tostring(p)
end
if type(p) == "string" then
p = dcsCommon.trim(p)
if p == "" then p = default end
@ -2232,6 +2240,9 @@ function dmlZone:getStringFromZoneProperty(theProperty, default)
if not default then default = "" end
local p = self:getZoneProperty(theProperty)
if not p then return default end
if type(p) == "number" then
p = tostring(p)
end
if type(p) == "string" then
p = dcsCommon.trim(p)
if p == "" then p = default end
@ -3341,7 +3352,9 @@ function cfxZones.linkUnitToZone(theUnit, theZone, dx, dy) -- note: dy is really
theZone.dx = dx
theZone.dy = dy
theZone.rxy = math.sqrt(dx * dx + dy * dy) -- radius
local unitHeading = dcsCommon.getUnitHeading(theUnit)
local uName = theUnit:getName()
-- local unitHeading = dcsCommon.getUnitHeading(theUnit)
local unitHeading = dcsCommon.unitName2Heading[uName] -- get original unit's heading from ME
local bearingOffset = math.atan2(dy, dx) -- rads
if bearingOffset < 0 then bearingOffset = bearingOffset + 2 * 3.141592 end
@ -3431,8 +3444,9 @@ function cfxZones.updateMovingZones()
cfxZones.initLink(aZone)
else --if aZone.linkName then
-- always re-acquire linkedUnit via Unit.getByName()
-- this way we gloss over any replacements via spawns
-- this way we gloss over any replacements via spawns/clones
aZone.linkedUnit = Unit.getByName(aZone.linkName)
if not aZone.linkUnit then aZone.linkUnit = StaticObject.getByName(aZone.linkName) end
end
if aZone.linkedUnit then
@ -3465,14 +3479,15 @@ end
function cfxZones.initLink(theZone)
theZone.linkBroken = true
theZone.linkedUnit = nil
theUnit = Unit.getByName(theZone.linkName)
theUnit = Unit.getByName(theZone.linkName) -- unit or static
if not theUnit then theUnit = StaticObject.getByName(theZone.linkName) end
if theUnit then
local dx = 0
local dz = 0
if theZone.useOffset or theZone.useHeading then
local A = cfxZones.getDCSOrigin(theZone)
local B = theUnit:getPoint()
local B = dcsCommon.getOrigPositionByID(theZone.linkedUID)
local delta = dcsCommon.vSub(A,B)
dx = delta.x
dz = delta.z
@ -3483,7 +3498,6 @@ function cfxZones.initLink(theZone)
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)
@ -3494,14 +3508,14 @@ end
function dmlZone:initLink()
self.linkBroken = true
self.linkedUnit = nil
theUnit = Unit.getByName(self.linkName)
theUnit = Unit.getByName(self.linkName) -- unit or static
if not theUnit then theUnit = StaticObject.getByName(self.linkName) end
if theUnit then
local dx = 0
local dz = 0
if self.useOffset or self.useHeading then
local A = self:getDCSOrigin()
local B = theUnit:getPoint()
local B = dcsCommon.getOrigPositionByID(self.linkedUID)
local delta = dcsCommon.vSub(A,B)
dx = delta.x
dz = delta.z
@ -3509,7 +3523,7 @@ function dmlZone:initLink()
self:linkUnitToZone(theUnit, dx, dz) -- also sets theZone.linkedUnit
if self.verbose then
trigger.action.outText("Link established for zone <" .. self.name .. "> to unit <" .. self.linkName .. ">: dx=<" .. math.floor(dx) .. ">, dz=<" .. math.floor(dz) .. "> dist = <" .. math.floor(math.sqrt(dx * dx + dz * dz)) .. ">" , 30)
trigger.action.outText("DML:Link established for zone <" .. self.name .. "> to unit <" .. self.linkName .. ">: dx=<" .. math.floor(dx) .. ">, dz=<" .. math.floor(dz) .. "> dist = <" .. math.floor(math.sqrt(dx * dx + dz * dz)) .. ">" , 30)
end
self.linkBroken = nil
@ -3531,27 +3545,33 @@ function cfxZones.startMovingZones()
-- late 2022 with 2.8
if aZone.dcsZone.linkUnit then
local theID = aZone.dcsZone.linkUnit
lU = dcsCommon.getUnitNameByID(theID)
lU = dcsCommon.getUnitNameByID(theID) -- can be unit OR STATIC OBJECT
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")
aZone.linkedUID = lU
elseif aZone:hasProperty("linkedUnit") then
lU = aZone:getZoneProperty("linkedUnit") -- getString: name of unit
local luid = dcsCommon.unitName2ID[lU]
if luid then
aZone.linkedUID = luid
else
trigger.action.outText("WARNING: zone <" .. aZone.name .. "> linked unit (by attribute) <" .. lU .. "> does not exist!", 30)
lU = nil
end
end
-- sanity check
if aZone.dcsZone.linkUnit and cfxZones.hasProperty(aZone, "linkedUnit") then
if aZone.dcsZone.linkUnit and aZone:hasProperty("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)
aZone.useOffset = aZone:getBoolFromZoneProperty("useOffset", false)
aZone.useHeading = aZone:getBoolFromZoneProperty("useHeading", false)
cfxZones.initLink(aZone)
end
end

219
modules/convoy.lua Normal file
View File

@ -0,0 +1,219 @@
convoy = {}
convoy.version = "0.0.0"
convoy.requiredLibs = {
"dcsCommon",
"cfxZones",
"cfxMX",
}
convoy.zones = {}
convoy.running = {}
convoy.ups = 1
function convoy.addConvoyZone(theZone)
convoy.zones[theZone.name] = theZone
end
function convoy.readConvoyZone(theZone)
theZone.coa = theZone:getCoalitionFromZoneProperty("coalition", 0)
if theZone:hasProperty("masterOwner") then
local mo = theZone:getStringFromZoneProperty("masterOwner")
local mz = cfxZones.getZoneByName(mo)
if not mz then
trigger.action.outText("+++cvoy: WARNING: Master Owner <" .. mo .. "> for zone <" .. theZone.name .. "> does not exist!", 30)
else
theZone.masterOwner = mz
end
theZone.isDynamic = theZone:getBoolFromZoneProperty("dynamic", true)
end
-- get groups inside me.
local myGroups, count = cfxMX.allGroupsInZoneByData(theZone)
trigger.action.outText("zone <" .. theZone.name .. ">: <" .. count .. "> convoy groups", 30)
theZone.myGroups = myGroups
theZone.unique = theZone:getBoolFromZoneProperty("unique", true)
theZone.preWipe = theZone:getBoolFromZoneProperty("preWipe", true) or theZone.unique
theZone.onStart = theZone:getBoolFromZoneProperty("onStart", false)
-- wipe all existing
for groupName, data in pairs(myGroups) do
local g = Group.getByName(groupName)
if g then
Group.destroy(g)
end
end
end
function convoy.startConvoy(theZone)
-- make sure my coa is set up correctly
local mo = theZone.masterOwner
if mo then
theZone.owner = mo.owner
if theZone.isDynamic then
theZone.coa = mo.owner
end
end
-- iterate all groups
local spawns = {}
for gName, gOrig in pairs(theZone.myGroups) do
trigger.action.outText("convoy: startting group <" .. gName .. "> for zone <" .. theZone.name .. ">", 30)
local gData = dcsCommon.clone(gOrig)
-- make unique names for group and units if desired
if theZone.unique then
gData.name = dcsCommon.uuid(gOrig.name)
for idx, theUnit in pairs (gData.units) do
theUnit.name = dcsCommon.uuid(theUnit.name)
end
end
convoy.amendData(theZone, gData) -- add actions to route
-- wipe existing if requested
if theZone.preWipe then
end
local catRaw = cfxMX.groupTypeByName[gName]
local gCat = Group.Category.GROUND
if catRaw == "helicopter" then
gCat = Group.Category.HELICOPTER
elseif catRaw == "plane" then
gCat = Group.Category.AIRPLANE
elseif catRaw == "vehicle" then
gCat = Group.Category.GROUND
else -- missing so far: ship
trigger.action.outText("+++milH: ignored group <" .. gName .. ">: unknown type <" .. catRaw .. ">", 30)
end
local cty = dcsCommon.getACountryForCoalition(theZone.coa)
local theSpawnedGroup = coalition.addGroup(cty, gCat, gData)
spawns[gData.name] = theSpawnedGroup
trigger.action.outText("convoy <" .. theSpawnedGroup:getName() .. "> spawned for <" .. theZone.name .. ">", 30)
end
end
function convoy.amendData(theZone, theData)
-- place a callback action for each waypoint
-- in data block
if not theData.route then return end
local route = theData.route
if not route.points then return end
local points = route.points
local np = #points
if np < 1 then return end
trigger.action.outText("convoy: group <" .. theData.name .. ">, zone <" .. theZone.name .. ">, points=<" .. np .. ">", 30)
-- for i=1, np do
local newPoints = {}
for idx, aPoint in pairs(points) do
local wp = dcsCommon.clone(aPoint) -- points[i]
local tasks = wp.task.params.tasks
--local i = idx
-- if not tasks then tasks = {} end
-- if tasks then
-- dcsCommon.dumpVar2Str("RAW tasks 1bc " .. idx, tasks)
local tnew = #tasks + 1 -- new number for this task
local t = {
["number"] = tnew,
["auto"] = false,
["id"] = "WrappedAction",
["enabled"] = true,
["params"] = {
["action"] = {
["id"] = "Script",
["params"] = {
["command"] = "trigger.action.outText(\"convoy reached WP Index " .. idx .." = WP(" .. idx-1 .. ") of " .. np .. "\", 30)",
}, -- end of ["params"]
}, -- end of ["action"]
}, -- end of ["params"]
} -- end of task
-- add t to tasks
table.insert(tasks, t)
-- tasks[tnew] = t
-- dcsCommon.dumpVar2Str("tasks for modded 1bc " .. idx, tasks)
newPoints[idx] = wp
trigger.action.outText("convoy: added wp task to wp <" .. idx .. ">", 30)
-- end
-- dcsCommon.dumpVar2Str("modded point 1BC WP" .. idx, wp)
newPoints[idx] = wp
end
route.points = newPoints
-- dcsCommon.dumpVar2Str("points", points)
end
--
-- UPDATE
--
function convoy.update()
timer.scheduleFunction(convoy.update, {}, timer.getTime() + 1/convoy.ups)
-- update all master owners
for idx, theZone in pairs (convoy.zones) do
--[[-- local mo = theZone.masterOwner
if mo then
theZone.owner = mo.owner
if theZone.isDynamic then
theZone.coa = mo.owner
end
end --]]--
end
end
--
-- START
--
function convoy.readConfigZone()
local theZone = cfxZones.getZoneByName("convoyConfig")
if not theZone then
theZone = cfxZones.createSimpleZone("convoyConfig")
end
convoy.verbose = theZone.verbose
convoy.ups = theZone:getNumberFromZoneProperty("ups", 1)
end
function convoy.start()
if not dcsCommon.libCheck then
trigger.action.outText("cfx convoy requires dcsCommon", 30)
return false
end
if not dcsCommon.libCheck("cfx convoy", convoy.requiredLibs) then
return false
end
-- read config
convoy.readConfigZone()
-- process convoy Zones
local attrZones = cfxZones.getZonesWithAttributeNamed("convoy")
for k, aZone in pairs(attrZones) do
convoy.readConvoyZone(aZone) -- process attributes
convoy.addConvoyZone(aZone) -- add to list
end
-- start update
timer.scheduleFunction(convoy.update, {}, timer.getTime() + 1/convoy.ups)
-- start all zones that have onstart
for gName, theZone in pairs(convoy.zones) do
if theZone.onStart then
convoy.startConvoy(theZone)
end
end
return true
end
if not convoy.start() then
trigger.action.outText("convoy failed to start up")
convoy = nil
end
--[[--
convoy module
place over a fully configured group, will clone on command (start?)
reportWaypoint option. Add small script to each and every waypoint, will create report
destinationReached! -- adds script to last waypoint to hit this signal, also inits cb
dead! signal and cb. only applies to ground troops? can they disembark troops when hit?
attacked signal each time a unit is destroyed
importantType - type that must survive=
coalition / masterOwner
isActive# 0/1
can only have one active convoy
can it have helicopters?
--]]--

View File

@ -1,5 +1,5 @@
dcsCommon = {}
dcsCommon.version = "3.0.8"
dcsCommon.version = "3.0.9"
--[[-- VERSION HISTORY
3.0.0 - removed bad bug in stringStartsWith, only relevant if caseSensitive is false
- point2text new intsOnly option
@ -20,9 +20,12 @@ dcsCommon.version = "3.0.8"
- new pointXpercentYdegOffAB()
3.0.6 - new arrayContainsStringCaseInsensitive()
3.0.7 - fixed small bug in wildArrayContainsString
3.0.8 - deepCopy() and deepTableCopy() alternates to clone() to patch
3.0.9 - deepCopy() and deepTableCopy() alternates to clone() to patch
around a strange DCS 2.9 issue
Kiowa added to Troop Carriers
3.0.9 - new getOrigPositionByID()
- unitName2ID[] reverse lookup
- unitName2Heading
--]]--
@ -45,6 +48,8 @@ dcsCommon.version = "3.0.8"
dcsCommon.unitID2Name = {}
dcsCommon.unitID2X = {}
dcsCommon.unitID2Y = {}
dcsCommon.unitName2ID = {}
dcsCommon.unitName2Heading = {}
-- verify that a module is loaded. obviously not required
-- for dcsCommon, but all higher-order modules
@ -97,15 +102,18 @@ dcsCommon.version = "3.0.8"
local aID = group_data.groupId
-- store this reference
dcsCommon.groupID2Name[aID] = aName
-- trigger.action.outText("cmn: group <" .. aName .. "> has id <" .. aID .. ">", 30)
-- 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
-- trigger.action.outText("cmn: unit/obj <" .. unit_data.name .. "> has id <" .. unit_data.unitId .. ">", 30)
dcsCommon.unitName2Heading[unit_data.name] = unit_data.heading
dcsCommon.unitID2X[unit_data.unitId] = unit_data.x
dcsCommon.unitID2Y[unit_data.unitId] = unit_data.y
dcsCommon.unitName2ID[unit_data.name] = unit_data.unitId
end
end -- for all units
end -- for all groups
@ -121,9 +129,14 @@ dcsCommon.version = "3.0.8"
function dcsCommon.getUnitNameByID(theID)
-- accessor function for later expansion
return dcsCommon.unitID2Name[theID]
return dcsCommon.unitID2Name[theID] -- warning: can be unit or static object
end
function dcsCommon.getOrigPositionByID(theID)
local p = {x=dcsCommon.unitID2X[theID], y=0, z=dcsCommon.unitID2Y[theID]}
return p
end
function dcsCommon.getGroupNameByID(theID)
-- accessor function for later expansion
return dcsCommon.groupID2Name[theID]

View File

@ -1,5 +1,5 @@
milHelo = {}
milHelo.version = "1.0.0"
milHelo.version = "1.0.2"
milHelo.requiredLibs = {
"dcsCommon",
"cfxZones",
@ -31,10 +31,10 @@ end
function milHelo.addMilTargetZone(theZone)
milHelo.targets[theZone.name] = theZone -- overwrite if duplicate
end
--[[--
function milHelo.partOfGroupDataInZone(theZone, theUnits) -- move to mx?
local zP = cfxZones.getPoint(theZone)
zP = theZone:getDCSOrigin() -- don't use getPoint now.
--local zP --= cfxZones.getPoint(theZone)
local zP = theZone:getDCSOrigin() -- don't use getPoint now.
zP.y = 0
for idx, aUnit in pairs(theUnits) do
@ -63,6 +63,7 @@ function milHelo.allGroupsInZoneByData(theZone) -- move to MX?
end
return theGroupsInZone, count
end
--]]--
function milHelo.readMilHeloZone(theZone) -- process attributes
-- get mission type. part of milHelo
@ -88,7 +89,7 @@ function milHelo.readMilHeloZone(theZone) -- process attributes
end
-- get all groups inside me
local myGroups, count = milHelo.allGroupsInZoneByData(theZone)
local myGroups, count = cfxMX.allGroupsInZoneByData(theZone)
theZone.myGroups = myGroups
theZone.groupCount = count
theZone.hGroups = {}
@ -662,7 +663,7 @@ end
-- update and event
--
function milHelo.update()
timer.scheduleFunction(milHelo.update, {}, timer.getTime() + 1)
timer.scheduleFunction(milHelo.update, {}, timer.getTime() + 1/milHelo.ups)
-- update all master owners
for idx, theZone in pairs (milHelo.zones) do
local mo = theZone.masterOwner
@ -791,6 +792,7 @@ function milHelo.readConfigZone()
end
milHelo.verbose = theZone.verbose
milHelo.landingDuration = theZone:getNumberFromZoneProperty("landingDuration", 180) -- seconds = 3 minutes
milHelo.ups = theZone:getNumberFromZoneProperty("ups", 1)
end

View File

@ -1,5 +1,5 @@
cfxObjectDestructDetector = {}
cfxObjectDestructDetector.version = "2.0.2"
cfxObjectDestructDetector.version = "2.0.3"
cfxObjectDestructDetector.verbose = false
cfxObjectDestructDetector.requiredLibs = {
"dcsCommon", -- always
@ -22,6 +22,7 @@ cfxObjectDestructDetector.requiredLibs = {
API for PlayerScore to pass back redScore/blueScore
if objects was killed by player
verbosity bug fixed after kill (ref to old ID)
2.0.3 if no output! given,a warning and default are given
--]]--
cfxObjectDestructDetector.objectZones = {}
@ -81,6 +82,9 @@ function cfxObjectDestructDetector.processObjectDestructZone(aZone)
aZone.outDestroyFlag = aZone:getStringFromZoneProperty("destroyed!", "*none")
elseif aZone:hasProperty("objectDestroyed!") then
aZone.outDestroyFlag = aZone:getStringFromZoneProperty( "objectDestroyed!", "*none")
else
trigger.action.outText("+++ODD: WARNING: destrcut detector <" .. aZone.name .. "> has no output! attribute", 30)
aZone.outDestroyFlag = "sorryIforgot" -- so saving works
end
--PlayerScore interface (data)

View File

@ -1,5 +1,5 @@
cfxSpawnZones = {}
cfxSpawnZones.version = "2.0.2"
cfxSpawnZones.version = "2.0.3"
cfxSpawnZones.requiredLibs = {
"dcsCommon", -- common is of course needed for everything
-- pretty stupid to check for this since we
@ -28,6 +28,7 @@ cfxSpawnZones.spawnedGroups = {}
- spawnWithSpawner direct link in spawner to spawnZones
2.0.1 - fix in verifySpawnOwnership() when not master zone found
2.0.2 - new "moveFormation" attribute
2.0.3 - corrected type in spawnUnits? attribute
--]]--
@ -76,7 +77,7 @@ function cfxSpawnZones.createSpawner(inZone)
theSpawner.triggerFlag = inZone:getStringFromZoneProperty("spawn?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
elseif inZone:hasProperty("spawnUnits?") then
theSpawner.triggerFlag = inZone:getStringFromZoneProperty( "spawnObject?", "none")
theSpawner.triggerFlag = inZone:getStringFromZoneProperty( "spawnUnits?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
end

View File

@ -1,5 +1,5 @@
stopGap = {}
stopGap.version = "1.1.1"
stopGap.version = "1.1.2"
stopGap.verbose = false
stopGap.ssbEnabled = true
stopGap.ignoreMe = "-sg"
@ -51,6 +51,7 @@ stopGap.requiredLibs = {
1.0.10 - some more verbosity for spIgnore and sgIgnore zones (DML only)
1.1.0 - kickTheDead option
1.1.1 - filter "from runway" clients
1.1.2 - allNeutral (DML only)
--]]--
@ -76,6 +77,10 @@ function stopGap.staticMXFromUnitMX(theGroup, theUnit)
theStatic.type = theUnit.type
theStatic.name = theUnit.name -- will magically be replaced with player unit
theStatic.cty = cfxMX.countryByName[theGroup.name]
-- DML only: allNeutral
if stopGap.allNeutral then
theStatic.cty = dcsCommon.getACountryForCoalition(0)
end
return theStatic
end
@ -432,6 +437,7 @@ function stopGap.readConfigZone(theZone)
stopGap.refreshInterval = theZone:getNumberFromZoneProperty("refresh", -1) -- default: no refresh
stopGap.kickTheDead = theZone:getBoolFromZoneProperty("kickDead", true)
stopGap.allNeutral = theZone:getBoolFromZoneProperty("allNeutral", false)
end
--
@ -492,4 +498,7 @@ end
if not stopGap.start() then
trigger.action.outText("+++ aborted stopGap v" .. stopGap.version .. " -- startup failed", 30)
stopGap = nil
end
end
--[[-- TODO
- allNeutral: spawn all player aircraft as neutral
--]]--

View File

@ -1,6 +1,5 @@
-- theDebugger 2.x
debugger = {}
debugger.version = "2.1.1"
debugger.version = "3.0.0"
debugDemon = {}
debugDemon.version = "2.1.0"
@ -40,6 +39,13 @@ debugger.log = ""
readback verification of flag set
fixed getProperty() in debugger with zone
2.1.1 - removed bug that skipped events? when zone not verbose
3.0.0 - xref module added
- x <zone/flag>
- x *
- x *f
- x *z
- x ?
--]]--
@ -138,6 +144,263 @@ debugger.spawnTypes = {
["manpad"] = "Soldier stinger",
["obj"] = "house2arm"
}
--
-- XREF MODULE
--
xref = {}
xref.version = "1.0.0"
xref.dmlObjects = {} -- dict by zone name:upper()
-- has inputs: dict of string for each '?' input, contains input flag name
-- has output: dict of array for each output '!', contains output flag names as array
xref.flags = {} -- dict by flag name
-- has froms: dict of zone of attributes that can write to this flags
-- has tos: dict of zones of attributes that read from flag
function xref.getDmlObject(name)
name = name:upper()
local theObject = xref.dmlObjects[name]
if not theObject then
theObject = {}
theObject.inputs = {} -- dict of string
theObject.outputs = {} -- dict of array
xref.dmlObjects[name] = theObject
end
return theObject
end
function xref.getFlag(name, theZone)
if theZone and dcsCommon.stringStartsWith(name, "*") then
-- local name conversion
name = theZone.name .. name
end
local theFlag = xref.flags[name]
if not theFlag then
theFlag = {}
theFlag.froms = {} -- dict by zone name/output that write to this flag
theFlag.tos = {} -- dict by zone name / inputs that reads from this flag
xref.flags[name] = theFlag
end
return theFlag
end
function xref.flagTo(flagName, inputName, theZone) -- connect flag to input in zone. Flag can connect to multiple inputs in same zone
local theFlag = xref.getFlag(flagName, theZone)
if not theFlag.tos[theZone.name] then
theFlag.tos[theZone.name] = {}
end
table.insert(theFlag.tos[theZone.name],inputName)
end
function xref.flagFrom(flagName, outputName, theZone) -- connect flag to output in zone. multiple outputs per zone
local theFlag = xref.getFlag(flagName, theZone)
if not theFlag.froms[theZone.name] then
theFlag.froms[theZone.name] = {}
end
table.insert(theFlag.froms[theZone.name], outputName)
end
function xref.addInput(theZone, inputName, inputFlagName)
local theObject = xref.getDmlObject(theZone.name)
local inputs = theObject.inputs
if not inputs then inputs = {} end
inputs[inputName] = inputFlagName -- each input connects one flag
xref.flagTo(inputFlagName, inputName, theZone)
theObject.inputs = inputs
end
function xref.addOutput(theZone, outputName, outputFlags)
local theObject = xref.getDmlObject(theZone.name)
local outputs = theObject.outputs
if not outputs then outputs = {} end
if dcsCommon.containsString(outputFlags, ",") then
local theArray = dcsCommon.splitString(outputFlags, ',')
theArray = dcsCommon.trimArray(theArray)
for idx, aFlagName in pairs(theArray) do
xref.flagFrom(aFlagName, outputName, theZone)
end
outputs[outputName] = theArray
else
local outputFlagName = dcsCommon.trim(outputFlags)
outputs[outputName] = {outputFlagName}
xref.flagFrom(outputFlagName, outputName, theZone)
end
theObject.outputs = outputs
end
function xref.scanMissionZones()
-- iterate all trigger zones
for idx, theZone in pairs(cfxZones.zones) do
-- iterate all properties
local attributes = theZone:getAllZoneProperties()
for name, value in pairs(attributes) do
-- find inputs
if dcsCommon.stringEndsWith(name, "?") then
xref.addInput(theZone, name, value)
end
-- find outputs
if dcsCommon.stringEndsWith(name, "!") then
xref.addOutput(theZone, name, value)
end
-- other stuff, e.g. "#"
-- find outputs
if dcsCommon.stringEndsWith(name, "#") then
xref.addOutput(theZone, name, value)
end
end
end
end
function xref.xrefFlag(name)
local msg = "\n<" .. name .. "> flag cross reference:"
local theFlag = xref.flags[name]
local tos = theFlag.tos
if dcsCommon.getSizeOfTable(tos) < 1 then
msg = msg .. "\n (NO INPUTS CONNECTED)"
else
msg = msg .. "\n '?' These zones/inputs? look at <" .. name .. ">:"
for zName, attributes in pairs (tos) do
msg = msg .. "\n " .. zName .. " - "
local c = 0
for idx, anInput in pairs(attributes) do
if c > 0 then msg = msg .. ", " end
c = 1
msg = msg .. anInput
end
end
end
local froms = theFlag.froms
if dcsCommon.getSizeOfTable(froms) < 1 then
msg = msg .. "\n (NO OUTPUTS CONNECTED)"
else
msg = msg .. "\n '!' These zones/outputs! change <" .. name .. ">:"
for zName, attributes in pairs (froms) do
msg = msg .. "\n " .. zName .." - "
local c = 0
for idx, anOutput in pairs(attributes) do
if c > 0 then msg = msg .. ", " end
c = 1
msg = msg .. anOutput
end
end
end
-- trigger.action.outText(msg, 30)
return msg
end
function xref.xrefZone(name, theObject)
local msg = "\nZone <" .. name .. "> :"
local ins = theObject.inputs
if dcsCommon.getSizeOfTable(ins) < 1 then
msg = msg .. "\n (NO INPUTS)"
else
msg = msg .. "\n has the following inputs:"
for iName, flagName in pairs (ins) do
msg = msg .. "\n " .. iName .. " : " .. flagName
end
end
local outs = theObject.outputs
if dcsCommon.getSizeOfTable(outs) < 1 then
msg = msg .. "\n (NO OUTPUTS)"
else
msg = msg .. "\n has the following outputs:"
for oName, flagList in pairs (outs) do
msg = msg .. "\n " .. oName .." - "
local c = 0
for idx, anOutput in pairs(flagList) do
if c > 0 then msg = msg .. ", " end
c = 1
msg = msg .. anOutput
end
end
end
-- trigger.action.outText(msg, 30)
return msg
end
function xref.xrefName(name)
if not name then name = "" end
if xref.flags[name] then
return xref.xrefFlag(name)
end
if xref.dmlObjects[name:upper()] then
return xref.xrefZone(name, xref.dmlObjects[name:upper()])
end
return "*** xref: <" .. name .. "> NOT USED WITH DML"
end
function xref.allFlags()
local msg = "xref: all flags used with DML in this mission:\n"
local c = 0
for name, data in pairs(xref.flags) do
if c > 0 then msg = msg .. ", " end
c = 1
msg = msg .. "<" .. name .. ">"
end
return msg
end
function xref.allZones()
local msg = "xref: all DML Zones in this mission:\n"
local c = 0
for name, data in pairs(xref.dmlObjects) do
if c > 0 then msg = msg .. ", " end
c = 1
msg = msg .. "<" .. name .. ">"
end
return msg
end
function xref.xall()
msg = ""
-- now dump all flags
for flagName, data in pairs (xref.flags) do
-- msg = msg .. xref.xrefFlag(flagName)
msg = msg .. xref.xrefName(flagName)
end
-- dump all zones
for zoneName, data in pairs(xref.dmlObjects) do
-- msg = msg .. xref.xrefZone(zoneName, data)
msg = msg .. xref.xrefName(zoneName)
end
return msg
-- trigger.action.outText(msg, 30)
end
function xref.start()
xref.scanMissionZones()
local flagNum = dcsCommon.getSizeOfTable(xref.flags)
local dmlObNum = dcsCommon.getSizeOfTable(xref.dmlObjects)
trigger.action.outText("XRef v" .. xref.version .. " full DML object scan on mission complete:\n<" .. flagNum .. "> flags are referenced in <" .. dmlObNum .. "> DML zones", 30)
-- trigger.action.outText(xref.xall(), 30)
end
-- run the xref
xref.start()
--[[--
to do
scan messenger and wildcards for flag access
--]]--
--
-- DEBUGGER MAIn
--
--
-- Logging & saving
--
@ -824,6 +1087,9 @@ debugger.outText("*** debugger: commands are:" ..
"\n " .. debugDemon.markOfDemon .. "inc <flagname> -- increase flag by 1, changing it" ..
"\n " .. debugDemon.markOfDemon .. "flip <flagname> -- when flag's value is 0, set it to 1, else to 0" ..
"\n\n " .. debugDemon.markOfDemon .. "x <zone/flagname> -- cross reference DML zone or flag" ..
"\n\n " .. debugDemon.markOfDemon .. "observe <flagname> [with <observername>] -- observe a flag for change" ..
"\n " .. debugDemon.markOfDemon .. "o <flagname> [with <observername>] -- observe a flag for change" ..
"\n " .. debugDemon.markOfDemon .. "forget <flagname> [with <observername>] -- stop observing a flag" ..
@ -1609,6 +1875,36 @@ function debugDemon.processBoomCommand(args, event)
debugger.outText("*** boom: placed <" .. power .. "> explosion at <" .. dcsCommon.point2text(p, true) .. ">.", 30)
end
--
-- xref
--
function debugDemon.processXrefCommand(args, event)
-- syntax: -x <name> | "*" | "*f" "*z"
local larg = args[1]
if not larg or larg == "" then larg = "?" end
larg = larg:lower()
if larg == "?" then
debugger.outText("*** xRef: ? = help (this), * = xref all, *f = list all DML flags, *z = list all DML zones, <name> xref flag or zone", 30)
return true -- leave up
elseif larg == "*" then
debugger.outText(xref.xall(), 30)
return true
elseif larg == "*f" then
debugger.outText(xref.allFlags(), 30)
return true
elseif larg == "*z" then
debugger.outText(xref.allZones(), 30)
return true
else
larg = event.remainder
larg = dcsCommon.trim(larg)
if not larg then larg = "" end
local msg = xref.xrefName(larg)
debugger.outText(msg, 30)
return true
end
end
--
-- spawning units at the location of the mark
--
@ -1965,6 +2261,7 @@ function debugDemon.init()
debugDemon.addCommndProcessor("a", debugDemon.processAnalyzeCommand)
debugDemon.addCommndProcessor("smoke", debugDemon.processSmokeCommand)
debugDemon.addCommndProcessor("boom", debugDemon.processBoomCommand)
debugDemon.addCommndProcessor("x", debugDemon.processXrefCommand)
return true
end

View File

@ -1,5 +1,5 @@
williePete = {}
williePete.version = "2.0.4"
williePete.version = "2.0.5"
williePete.ups = 10 -- we update at 10 fps, so accuracy of a
-- missile moving at Mach 2 is within 33 meters,
-- with interpolation even at 3 meters
@ -21,6 +21,7 @@ williePete.requiredLibs = {
2.0.2 - hardened playerUpdate()
2.0.3 - further hardened playerUpdate()
2.0.4 - support for the Kiowa's Hydra M259
2.0.5 - support for Mirage F1 WP that differ from Gazelle (?)
--]]--
williePete.willies = {}
@ -32,7 +33,8 @@ williePete.blastedObjects = {} -- used when we detonate something
-- recognizes WP munitions. May require regular update when new
-- models come out.
williePete.smokeWeapons = {"HYDRA_70_M274","HYDRA_70_MK61","HYDRA_70_MK1","HYDRA_70_WTU1B","HYDRA_70_M156","HYDRA_70_M158","BDU_45B","BDU_33","BDU_45","BDU_45LGB","BDU_50HD","BDU_50LD","BDU_50LGB","C_8CM", "SNEB_TYPE254_H1_GREEN", "SNEB_TYPE254_H1_RED", "SNEB_TYPE254_H1_YELLOW", "FFAR M156 WP",
williePete.smokeWeapons = {"HYDRA_70_M274","HYDRA_70_MK61","HYDRA_70_MK1","HYDRA_70_WTU1B","HYDRA_70_M156","HYDRA_70_M158","BDU_45B","BDU_33","BDU_45","BDU_45LGB","BDU_50HD","BDU_50LD","BDU_50LGB","C_8CM", "SNEB_TYPE254_H1_GREEN", "SNEB_TYPE254_H1_RED", "SNEB_TYPE254_H1_YELLOW",
"SNEB_TYPE254_F1B_YELLOW", "SNEB_TYPE254_F1B_GREEN", "SNEB_TYPE254_F1B_RED", "FFAR M156 WP",
"HYDRA_70_M259"}
function williePete.addWillie(theWillie)