mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 1.2.7
Maintenance Updade, OwnedZones and CountDown
This commit is contained in:
parent
52985a2d4c
commit
aeafc854ac
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
cfxNDB = {}
|
||||
cfxNDB.version = "1.2.0"
|
||||
cfxNDB.version = "1.2.1"
|
||||
|
||||
--[[--
|
||||
cfxNDB:
|
||||
@ -22,6 +22,10 @@ cfxNDB.version = "1.2.0"
|
||||
- startNDB() can accept string
|
||||
- stopNDB() can accept string
|
||||
1.2.0 - DML full integration
|
||||
1.2.1 - height correction for NDB on creation
|
||||
- update only when moving and delta > maxDelta
|
||||
- zone-local verbosity support
|
||||
- better config defaulting
|
||||
|
||||
--]]--
|
||||
|
||||
@ -47,7 +51,7 @@ function cfxNDB.startNDB(theNDB)
|
||||
|
||||
if not theNDB.freq then
|
||||
-- this zone is not an NDB. Exit
|
||||
if cfxNDB.verbose then
|
||||
if cfxNDB.verbose or theNDB.verbose then
|
||||
trigger.action.outText("+++ndb: start() -- " .. theNDB.name .. " is not a cfxNDB.", 30)
|
||||
end
|
||||
return
|
||||
@ -60,10 +64,12 @@ function cfxNDB.startNDB(theNDB)
|
||||
local modulation = 0
|
||||
if theNDB.fm then modulation = 1 end
|
||||
|
||||
local loc = cfxZones.getPoint(theNDB)
|
||||
local loc = cfxZones.getPoint(theNDB) -- y === 0
|
||||
loc.y = land.getHeight({x = loc.x, y = loc.z}) -- get y from land
|
||||
trigger.action.radioTransmission(fileName, loc, modulation, true, theNDB.freq, theNDB.power, theNDB.ndbID)
|
||||
theNDB.lastLoc = loc -- save for delta comparison
|
||||
|
||||
if cfxNDB.verbose then
|
||||
if cfxNDB.verbose or theNDB.verbose then
|
||||
local dsc = ""
|
||||
if theNDB.linkedUnit then
|
||||
dsc = " (linked to ".. theNDB.linkedUnit:getName() .. "!, r=" .. theNDB.ndbRefresh .. ") "
|
||||
@ -72,7 +78,7 @@ function cfxNDB.startNDB(theNDB)
|
||||
end
|
||||
theNDB.paused = false
|
||||
|
||||
if cfxNDB.verbose then
|
||||
if cfxNDB.verbose or theNDB.verbose then
|
||||
trigger.action.outText("+++ndb: " .. theNDB.name .. " started", 30)
|
||||
end
|
||||
end
|
||||
@ -84,7 +90,7 @@ function cfxNDB.stopNDB(theNDB)
|
||||
|
||||
if not theNDB.freq then
|
||||
-- this zone is not an NDB. Exit
|
||||
if cfxNDB.verbose then
|
||||
if cfxNDB.verbose or theNDB.verbose then
|
||||
trigger.action.outText("+++ndb: stop() -- " .. theNDB.name .. " is not a cfxNDB.", 30)
|
||||
end
|
||||
return
|
||||
@ -92,7 +98,7 @@ function cfxNDB.stopNDB(theNDB)
|
||||
|
||||
trigger.action.stopRadioTransmission(theNDB.ndbID)
|
||||
theNDB.paused = true
|
||||
if cfxNDB.verbose then
|
||||
if cfxNDB.verbose or theNDB.verbose then
|
||||
trigger.action.outText("+++ndb: " .. theNDB.name .. " stopped", 30)
|
||||
end
|
||||
end
|
||||
@ -159,8 +165,19 @@ function cfxNDB.update()
|
||||
-- yupp, need to update
|
||||
if (not theNDB.paused) and
|
||||
(now > theNDB.ndbRefreshTime) then
|
||||
cfxNDB.stopNDB(theNDB) -- also pauses
|
||||
cfxNDB.startNDB(theNDB) -- turns off pause
|
||||
-- optimization: check that it moved far enough
|
||||
-- to merit update.
|
||||
if not theNDB.lastLoc then
|
||||
cfxNDB.startNDB(theNDB) -- never was started
|
||||
else
|
||||
local loc = cfxZones.getPoint(theNDB) -- y === 0
|
||||
loc.y = land.getHeight({x = loc.x, y = loc.z}) -- get y from land
|
||||
local delta = dcsCommon.dist(loc, theNDB.lastLoc)
|
||||
if delta > cfxNDB.maxDist then
|
||||
cfxNDB.stopNDB(theNDB)
|
||||
cfxNDB.startNDB(theNDB)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -185,15 +202,14 @@ end
|
||||
function cfxNDB.readConfig()
|
||||
local theZone = cfxZones.getZoneByName("ndbConfig")
|
||||
if not theZone then
|
||||
if cfxNDB.verbose then
|
||||
trigger.action.outText("***ndb: NO config zone!", 30)
|
||||
end
|
||||
return
|
||||
theZone = cfxZones.createSimpleZone("ndbConfig")
|
||||
end
|
||||
|
||||
cfxNDB.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
|
||||
cfxNDB.ndbRefresh = cfxZones.getNumberFromZoneProperty(theZone, "ndbRefresh", 10)
|
||||
|
||||
cfxNDB.maxDist = cfxZones.getNumberFromZoneProperty(theZone, "maxDist", 50) -- max 50m error for movement
|
||||
|
||||
if cfxNDB.verbose then
|
||||
trigger.action.outText("***ndb: read config", 30)
|
||||
end
|
||||
@ -218,6 +234,7 @@ function cfxNDB.start()
|
||||
-- start update
|
||||
cfxNDB.update()
|
||||
|
||||
trigger.action.outText("cf/x NDB version " .. cfxNDB.version .. " started", 30)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
cfxOwnedZones = {}
|
||||
cfxOwnedZones.version = "1.2.4"
|
||||
cfxOwnedZones.version = "1.3.0"
|
||||
cfxOwnedZones.verbose = false
|
||||
cfxOwnedZones.announcer = true
|
||||
cfxOwnedZones.name = "cfxOwnedZones"
|
||||
@ -49,8 +49,19 @@ cfxOwnedZones.name = "cfxOwnedZones"
|
||||
1.2.2 - redCap! and blueCap!
|
||||
1.2.3 - fix for persistence bug when not using conquered flag
|
||||
1.2.4 - pause? and activate? inputs
|
||||
1.3.0 - new update method
|
||||
- new fastEval option in config
|
||||
- new numCap option in config
|
||||
- new numKeep option in config
|
||||
- new easyContest option in config
|
||||
- new logic to keep and lose zones. controlled with numKeep and numCap.
|
||||
- winSound
|
||||
- loseSound
|
||||
- redLost! zone output
|
||||
- blueLost! zone output
|
||||
- ownedBy direct zone output
|
||||
- neutral! zone output
|
||||
|
||||
|
||||
--]]--
|
||||
cfxOwnedZones.requiredLibs = {
|
||||
"dcsCommon", -- common is of course needed for everything
|
||||
@ -91,7 +102,7 @@ cfxOwnedZones.conqueredCallbacks = {}
|
||||
-- zone attributes when owned
|
||||
-- owner: coalition that owns the zone
|
||||
-- status: FSM for spawning
|
||||
-- defendersRED/BLUE - coma separated type string for the group to spawm on defense cycle completion
|
||||
-- defendersRED/BLUE - coma separated type string for the group to spawn on defense cycle completion
|
||||
-- attackersRED/BLUE - as above for attack cycle.
|
||||
-- timeStamp - time when zone switched into current state
|
||||
-- spawnRadius - overrides zone's radius when placing defenders. can be use to place defenders inside or outside zone itself
|
||||
@ -232,10 +243,26 @@ function cfxOwnedZones.addOwnedZone(aZone)
|
||||
aZone.redCap = cfxZones.getStringFromZoneProperty(aZone, "redCap!", "none")
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(aZone, "redLost!") then
|
||||
aZone.redLost = cfxZones.getStringFromZoneProperty(aZone, "redLost!", "none")
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(aZone, "blueCap!") then
|
||||
aZone.blueCap = cfxZones.getStringFromZoneProperty(aZone, "blueCap!", "none")
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(aZone, "blueLost!") then
|
||||
aZone.blueLost = cfxZones.getStringFromZoneProperty(aZone, "blueLost!", "none")
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(aZone, "neutral!") then
|
||||
aZone.neutralCap = cfxZones.getStringFromZoneProperty(aZone, "neutral!", "none")
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(aZone, "ownedBy") then
|
||||
aZone.ownedBy = cfxZones.getStringFromZoneProperty(aZone, "ownedBy", "none")
|
||||
end
|
||||
|
||||
-- pause? and activate?
|
||||
if cfxZones.hasProperty(aZone, "pause?") then
|
||||
aZone.pauseFlag = cfxZones.getStringFromZoneProperty(aZone, "pause?", "none")
|
||||
@ -534,17 +561,25 @@ end
|
||||
|
||||
function cfxOwnedZones.zoneConquered(aZone, theSide, formerOwner) -- 0 = neutral 1 = RED 2 = BLUE
|
||||
local who = "REDFORCE"
|
||||
if theSide == 2 then who = "BLUEFORCE" end
|
||||
if theSide == 2 then who = "BLUEFORCE"
|
||||
elseif theSide == 0 then who = "NEUTRAL" end
|
||||
|
||||
if cfxOwnedZones.announcer then
|
||||
trigger.action.outText(who .. " have secured zone " .. aZone.name, 30)
|
||||
aZone.owner = theSide
|
||||
if theSide == 0 then
|
||||
trigger.action.outText(aZone.name .. " has become NEUTRAL", 30)
|
||||
else
|
||||
trigger.action.outText(who .. " have secured zone " .. aZone.name, 30)
|
||||
end
|
||||
aZone.owner = theSide -- just to be sure
|
||||
-- play different sounds depending on who's won
|
||||
if theSide == 1 then
|
||||
trigger.action.outSoundForCoalition(1, "Quest Snare 3.wav")
|
||||
trigger.action.outSoundForCoalition(2, "Death BRASS.wav")
|
||||
trigger.action.outSoundForCoalition(1, cfxOwnedZones.winSound)
|
||||
trigger.action.outSoundForCoalition(2, cfxOwnedZones.loseSound)
|
||||
elseif theSide == 2 then
|
||||
trigger.action.outSoundForCoalition(2, cfxOwnedZones.winSound)
|
||||
trigger.action.outSoundForCoalition(1, cfxOwnedZones.loseSound)
|
||||
else
|
||||
trigger.action.outSoundForCoalition(2, "Quest Snare 3.wav")
|
||||
trigger.action.outSoundForCoalition(1, "Death BRASS.wav")
|
||||
-- no sound played, new owner is neutral
|
||||
end
|
||||
end
|
||||
|
||||
@ -556,10 +591,22 @@ function cfxOwnedZones.zoneConquered(aZone, theSide, formerOwner) -- 0 = neutral
|
||||
cfxZones.pollFlag(aZone.redCap, "inc", aZone)
|
||||
end
|
||||
|
||||
if formerOwner == 1 and aZone.redLost then
|
||||
cfxZones.pollFlag(aZone.redLost, "inc", aZone)
|
||||
end
|
||||
|
||||
if theSide == 2 and aZone.blueCap then
|
||||
cfxZones.pollFlag(aZone.blueCap, "inc", aZone)
|
||||
end
|
||||
|
||||
if formerOwner == 2 and aZone.blueLost then
|
||||
cfxZones.pollFlag(aZone.blueLost, "inc", aZone)
|
||||
end
|
||||
|
||||
if theSide == 0 and aZone.neutralCap then
|
||||
cfxZones.pollFlag(aZone.neutralCap, "inc", aZone)
|
||||
end
|
||||
|
||||
-- invoke callbacks now
|
||||
cfxOwnedZones.invokeConqueredCallbacks(aZone, theSide, formerOwner)
|
||||
|
||||
@ -852,7 +899,150 @@ function cfxOwnedZones.GC()
|
||||
end
|
||||
|
||||
function cfxOwnedZones.update()
|
||||
-- to speed this up we might only want to check the first unit
|
||||
-- in group, and if inside, count the entire group as inside
|
||||
-- new. unit counting update
|
||||
cfxOwnedZones.updateSchedule = timer.scheduleFunction(cfxOwnedZones.update, {}, timer.getTime() + 1/cfxOwnedZones.ups)
|
||||
-- iterate all groups and their units to count how many
|
||||
-- units are in each zone
|
||||
for idz, theZone in pairs(cfxOwnedZones.zones) do
|
||||
theZone.numRed = 0
|
||||
theZone.numBlue = 0
|
||||
-- count red units
|
||||
local allRed = coalition.getGroups(1, Group.Category.GROUND)
|
||||
for idx, aGroup in pairs(allRed) do
|
||||
if Group.isExist(aGroup) then
|
||||
if cfxOwnedZones.fastEval then
|
||||
-- we only check first unit that is alive
|
||||
local theUnit = dcsCommon.getGroupUnit(aGroup)
|
||||
if theUnit and cfxZones.unitInZone(theUnit, theZone) then
|
||||
theZone.numRed = theZone.numRed + aGroup:getSize()
|
||||
end
|
||||
else
|
||||
local allUnits = aGroup:getUnits()
|
||||
for idy, theUnit in pairs(allUnits) do
|
||||
if cfxZones.unitInZone(theUnit, theZone) then
|
||||
theZone.numRed = theZone.numRed + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- count blue units
|
||||
local allBlue = coalition.getGroups(2, Group.Category.GROUND)
|
||||
for idx, aGroup in pairs(allBlue) do
|
||||
if Group.isExist(aGroup) then
|
||||
if cfxOwnedZones.fastEval then
|
||||
-- we only check first unit that is alive
|
||||
local theUnit = dcsCommon.getGroupUnit(aGroup)
|
||||
if theUnit and cfxZones.unitInZone(theUnit, theZone) then
|
||||
theZone.numBlue = theZone.numBlue + aGroup:getSize()
|
||||
end
|
||||
else
|
||||
local allUnits = aGroup:getUnits()
|
||||
for idy, theUnit in pairs(allUnits) do
|
||||
if cfxZones.unitInZone(theUnit, theZone) then
|
||||
theZone.numBlue = theZone.numBlue + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- trigger.action.outText(theZone.name .. " blue: " .. theZone.numBlue .. " red " .. theZone.numRed, 30)
|
||||
local lastOwner = theZone.owner
|
||||
local newOwner = 0 -- neutral is default
|
||||
-- determine new owner
|
||||
-- step one: no troops here. Become neutral?
|
||||
if theZone.numRed < 1 and theZone.numBlue < 1 then
|
||||
if cfxOwnedZones.numKeep < 1 then
|
||||
newOwner = lastOwner -- keep it, else turns neutral
|
||||
else
|
||||
-- noone here, zone becomes neutral
|
||||
newOwner = 0 -- not strictly required. to be explicit
|
||||
end
|
||||
elseif theZone.numRed < 1 then
|
||||
-- only blue here. enough to keep?
|
||||
if theZone.numBlue >= cfxOwnedZones.numCap then
|
||||
newOwner = 2 -- blue owns it
|
||||
elseif lastOwner == 2 and theZone.numBlue >= cfxOwnedZones.numKeep then
|
||||
-- enough to keep if owned before
|
||||
newOwner = 2
|
||||
else
|
||||
newOwner = 0 -- just to make it explicit
|
||||
end
|
||||
elseif theZone.numBlue < 1 then
|
||||
-- only red here. enough to keep?
|
||||
if theZone.numRed >= cfxOwnedZones.numCap then
|
||||
newOwner = 1
|
||||
elseif lastOwner == 1 and theZone.numRed >= cfxOwnedZones.numKeep then
|
||||
newOwner = 1
|
||||
else
|
||||
newOwner = 0
|
||||
end
|
||||
else
|
||||
-- blue and red units here.
|
||||
-- owner keeps hanging on only they have enough
|
||||
-- units left
|
||||
if cfxOwnedZones.easyContest then
|
||||
-- this zone is immediately contested
|
||||
newOwner = 0 -- just to be explicit
|
||||
elseif cfxOwnedZones.numKeep < 1 then
|
||||
-- old owner keeps it until none left
|
||||
newOwner = lastOwner
|
||||
else
|
||||
if lastOwner == 1 then
|
||||
-- red can keep it as long as enough units here
|
||||
if theZone.numRed >= cfxOwnedZones.numKeep then
|
||||
newOwner = 1
|
||||
end -- else 0
|
||||
elseif lastOwner == 2 then
|
||||
-- blue can keep it if enough units here
|
||||
if theZone.numBlue >= cfxOwnedZones.numKeep then
|
||||
newOwner = 2
|
||||
end -- else 0
|
||||
else -- stay 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- now see if owner changed, and react accordingly
|
||||
if newOwner == lastOwner then
|
||||
-- nothing happened, do nothing
|
||||
else
|
||||
trigger.action.outText(theZone.name .. " change hands from " .. lastOwner .. " to " .. newOwner, 30)
|
||||
if newOwner == 0 then -- zone turned neutral
|
||||
cfxOwnedZones.zoneConquered(theZone, newOwner, lastOwner)
|
||||
else
|
||||
cfxOwnedZones.zoneConquered(theZone, newOwner, lastOwner)
|
||||
end
|
||||
end
|
||||
theZone.owner = newOwner
|
||||
|
||||
-- production & flags
|
||||
-- see if pause/unpause was issued
|
||||
-- note that capping a zone will not change pause status
|
||||
if theZone.pauseFlag and cfxZones.testZoneFlag(theZone, theZone.pauseFlag, theZone.ownedTriggerMethod, "lastPauseValue") then
|
||||
theZone.paused = true
|
||||
end
|
||||
|
||||
if theZone.activateFlag and cfxZones.testZoneFlag(theZone, theZone.activateFlag, theZone.ownedTriggerMethod, "lastActivateValue") then
|
||||
theZone.paused = false
|
||||
end
|
||||
|
||||
-- update ownership flag if exists
|
||||
if theZone.ownedBy then
|
||||
cfxZones.setFlagValue(theZone.ownedBy, theZone.owner, theZone)
|
||||
end
|
||||
|
||||
-- now, perhaps with their new owner call updateZone()
|
||||
-- to calcualte production for this zone
|
||||
cfxOwnedZones.updateZone(theZone)
|
||||
end -- iterating all zones
|
||||
end
|
||||
|
||||
|
||||
function cfxOwnedZones.updateOLD()
|
||||
cfxOwnedZones.updateSchedule = timer.scheduleFunction(cfxOwnedZones.updateOLD, {}, timer.getTime() + 1/cfxOwnedZones.ups)
|
||||
|
||||
-- iterate all zones, and determine their current ownership status
|
||||
for key, aZone in pairs(cfxOwnedZones.zones) do
|
||||
@ -1065,6 +1255,14 @@ function cfxOwnedZones.readConfigZone(theZone)
|
||||
cfxOwnedZones.attackingTime = cfxZones.getNumberFromZoneProperty(theZone, "attackingTime", 300)
|
||||
cfxOwnedZones.shockTime = cfxZones.getNumberFromZoneProperty(theZone, "shockTime", 200)
|
||||
cfxOwnedZones.repairTime = cfxZones.getNumberFromZoneProperty(theZone, "repairTime", 200)
|
||||
-- numKeep, numCap, fastEval, easyContest
|
||||
cfxOwnedZones.numCap = cfxZones.getNumberFromZoneProperty(theZone, "numCap", 1) -- minimal number of units required to cap zone
|
||||
cfxOwnedZones.numKeep = cfxZones.getNumberFromZoneProperty(theZone, "numKeep", 0) -- number required to keep zone
|
||||
cfxOwnedZones.fastEval = cfxZones.getBoolFromZoneProperty(theZone, "fastEval", true)
|
||||
cfxOwnedZones.easyContest = cfxZones.getBoolFromZoneProperty(theZone, "easyContest", false)
|
||||
-- winSound, loseSound
|
||||
cfxOwnedZones.winSound = cfxZones.getStringFromZoneProperty(theZone, "winSound", "Quest Snare 3.wav" )
|
||||
cfxOwnedZones.loseSound = cfxZones.getStringFromZoneProperty(theZone, "loseSound", "Death BRASS.wav")
|
||||
end
|
||||
|
||||
function cfxOwnedZones.init()
|
||||
|
||||
@ -39,7 +39,7 @@ cfxPlayerScore.requiredLibs = {
|
||||
"cfxZones", -- zones for config
|
||||
}
|
||||
cfxPlayerScore.playerScore = {} -- init to empty
|
||||
|
||||
cfxPlayerScore.deferred = false -- on deferred, we only award after landing, and erase on any form of re-slot
|
||||
-- typeScore: dictionary sorted by typeString for score
|
||||
-- extend to add more types. It is used by unitType2score to
|
||||
-- determine the base unit score
|
||||
@ -153,8 +153,10 @@ function cfxPlayerScore.getPlayerScore(playerName)
|
||||
thePlayerScore.name = playerName
|
||||
thePlayerScore.score = 0 -- score
|
||||
thePlayerScore.killTypes = {} -- the type strings killed, dict <typename> <numkilla>
|
||||
thePlayerScore.killQueue = {} -- when using deferred
|
||||
thePlayerScore.totalKills = 0 -- number of kills total
|
||||
thePlayerScore.featTypes = {} -- dict <featname> <number> of other things player did
|
||||
thePlayerScore.featQueue = {} -- when using deferred
|
||||
thePlayerScore.totalFeats = 0
|
||||
end
|
||||
return thePlayerScore
|
||||
|
||||
@ -124,7 +124,7 @@ cfxZones.version = "3.0.6"
|
||||
- 3.0.5 - getPositiveRangeFromZoneProperty() now also supports upper bound (optional)
|
||||
- 3.0.6 - new createSimplePolyZone()
|
||||
- new createSimpleQuadZone()
|
||||
|
||||
- 3.0.7 - getPoint() can also get land y when passing true as second param
|
||||
--]]--
|
||||
cfxZones.verbose = false
|
||||
cfxZones.caseSensitiveProperties = false -- set to true to make property names case sensitive
|
||||
@ -2540,7 +2540,9 @@ function cfxZones.getLinkedUnit(theZone)
|
||||
return theZone.linkedUnit
|
||||
end
|
||||
|
||||
function cfxZones.getPoint(aZone) -- always works, even linked, returned point can be reused
|
||||
function cfxZones.getPoint(aZone, getHeight) -- always works, even linked, returned point can be reused
|
||||
-- returned y (when using getHeight) is that of the land, else 0
|
||||
if not getHeight then getHeight = false end
|
||||
if aZone.linkedUnit then
|
||||
local theUnit = aZone.linkedUnit
|
||||
-- has a link. is link existing?
|
||||
@ -2557,9 +2559,13 @@ function cfxZones.getPoint(aZone) -- always works, even linked, returned point c
|
||||
end
|
||||
local thePos = {}
|
||||
thePos.x = aZone.point.x
|
||||
thePos.y = 0 -- aZone.y
|
||||
thePos.z = aZone.point.z
|
||||
|
||||
if not getHeight then
|
||||
thePos.y = 0 -- aZone.y
|
||||
else
|
||||
thePos.y = land.getHeight({x = thePos.x, y = thePos.z})
|
||||
end
|
||||
|
||||
return thePos
|
||||
end
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
countDown = {}
|
||||
countDown.version = "1.3.0"
|
||||
countDown.version = "1.3.1"
|
||||
countDown.verbose = false
|
||||
countDown.ups = 1
|
||||
countDown.requiredLibs = {
|
||||
@ -9,7 +9,7 @@ countDown.requiredLibs = {
|
||||
|
||||
--[[--
|
||||
count down on flags to generate new signal on out
|
||||
Copyright (c) 2022 by Christian Franz and cf/x AG
|
||||
Copyright (c) 2022, 2023 by Christian Franz and cf/x AG
|
||||
|
||||
Version History
|
||||
1.0.0 - initial version
|
||||
@ -23,8 +23,11 @@ countDown.requiredLibs = {
|
||||
1.2.1 - disableCounter?
|
||||
1.3.0 - DML & Watchflags upgrade
|
||||
- method --> ctdwnMethod
|
||||
|
||||
|
||||
1.3.1 - clock? synonym
|
||||
- new reset? input
|
||||
- improved verbosity
|
||||
- zone-local verbosity
|
||||
|
||||
--]]--
|
||||
|
||||
countDown.counters = {}
|
||||
@ -48,7 +51,6 @@ function countDown.getCountDownZoneByName(aName)
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- callbacks
|
||||
--
|
||||
@ -81,7 +83,6 @@ function countDown.createCountDownWithZone(theZone)
|
||||
trigger.action.outText("+++cntD: initing count down <" .. theZone.name .. "> with " .. theZone.currVal, 30)
|
||||
end
|
||||
|
||||
|
||||
-- loop
|
||||
theZone.loop = cfxZones.getBoolFromZoneProperty(theZone, "loop", false)
|
||||
|
||||
@ -94,7 +95,7 @@ function countDown.createCountDownWithZone(theZone)
|
||||
theZone.ctdwnMethod = cfxZones.getStringFromZoneProperty(theZone, "ctdwnMethod", "flip")
|
||||
end
|
||||
|
||||
-- triggerMethod
|
||||
-- triggerMethod for inputs
|
||||
theZone.ctdwnTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
|
||||
|
||||
if cfxZones.hasProperty(theZone, "ctdwnTriggerMethod") then
|
||||
@ -104,16 +105,21 @@ function countDown.createCountDownWithZone(theZone)
|
||||
-- trigger flag "count" / "start?"
|
||||
if cfxZones.hasProperty(theZone, "count?") then
|
||||
theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, "count?", "<none>")
|
||||
end
|
||||
|
||||
|
||||
elseif cfxZones.hasProperty(theZone, "clock?") then
|
||||
theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, "clock?", "<none>")
|
||||
-- can also use in? for counting. we always use triggerCountFlag
|
||||
if cfxZones.hasProperty(theZone, "in?") then
|
||||
elseif cfxZones.hasProperty(theZone, "in?") then
|
||||
theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, "in?", "<none>")
|
||||
end
|
||||
|
||||
if theZone.triggerCountFlag then
|
||||
theZone.lastCountTriggerValue = cfxZones.getFlagValue(theZone.triggerCountFlag, theZone) -- trigger.misc.getUserFlag(theZone.triggerCountFlag) -- save last value
|
||||
theZone.lastCountTriggerValue = cfxZones.getFlagValue(theZone.triggerCountFlag, theZone)
|
||||
end
|
||||
|
||||
-- reset
|
||||
if cfxZones.hasProperty(theZone, "reset?") then
|
||||
theZone.resetFlag = cfxZones.getStringFromZoneProperty(theZone, "reset?", "<none>")
|
||||
theZone.resetFlagValue = cfxZones.getFlagValue(theZone.resetFlag, theZone)
|
||||
end
|
||||
|
||||
-- zero! bang
|
||||
@ -146,10 +152,25 @@ end
|
||||
--
|
||||
-- Update
|
||||
--
|
||||
function countDown.reset(theZone)
|
||||
local val = dcsCommon.randomBetween(theZone.startMinVal, theZone.startMaxVal)
|
||||
if countDown.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++cntD: resetting <" .. theZone.name .. "> to (" .. val .. ")", 30)
|
||||
end
|
||||
|
||||
theZone.currVal = val
|
||||
if theZone.counterOut then
|
||||
cfxZones.setFlagValue(theZone.counterOut, val, theZone)
|
||||
end
|
||||
-- read and ignore any pulling of the clock flag
|
||||
local ignore = cfxZones.testZoneFlag(theZone, theZone.triggerCountFlag, theZone.ctdwnTriggerMethod, "lastCountTriggerValue")
|
||||
-- simply updates lastTriggerValue to current clock value
|
||||
end
|
||||
|
||||
function countDown.isTriggered(theZone)
|
||||
-- this module has triggered
|
||||
local val = theZone.currVal - 1 -- decrease counter
|
||||
if countDown.verbose then
|
||||
if countDown.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++cntD: enter triggered: val now: " .. val, 30)
|
||||
end
|
||||
local tMinus = false
|
||||
@ -165,8 +186,8 @@ function countDown.isTriggered(theZone)
|
||||
tMinus = true
|
||||
-- see if we need to bang Tminus
|
||||
if theZone.tMinusFlag then
|
||||
if countDown.verbose then
|
||||
trigger.action.outText("+++cntD: TMINUTS", 30)
|
||||
if countDown.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++cntD: <" .. theZone.name .. "> TMINUTS on flag <" .. theZone.tMinusFlag .. ">", 30)
|
||||
end
|
||||
cfxZones.pollFlag(theZone.tMinusFlag, theZone.ctdwnMethod, theZone)
|
||||
end
|
||||
@ -175,8 +196,8 @@ function countDown.isTriggered(theZone)
|
||||
-- reached zero
|
||||
zero = true
|
||||
if theZone.zeroFlag then
|
||||
if countDown.verbose then
|
||||
trigger.action.outText("+++cntD: ZERO", 30)
|
||||
if countDown.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++cntD: ZERO <" .. theZone.name .. "> on flag <" .. theZone.zeroFlag .. ">", 30)
|
||||
end
|
||||
cfxZones.pollFlag(theZone.zeroFlag, theZone.ctdwnMethod, theZone)
|
||||
end
|
||||
@ -184,17 +205,17 @@ function countDown.isTriggered(theZone)
|
||||
if theZone.loop then
|
||||
-- restart time
|
||||
looping = true
|
||||
if countDown.verbose then
|
||||
trigger.action.outText("+++cntD: Looping", 30)
|
||||
end
|
||||
val = dcsCommon.randomBetween(theZone.startMinVal, theZone.startMaxVal)
|
||||
if countDown.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++cntD: Looping <" .. theZone.name .. ">, start val is (" .. val .. ")", 30)
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
-- below zero
|
||||
belowZero = true
|
||||
if theZone.belowZero and theZone.zeroFlag then
|
||||
if countDown.verbose then
|
||||
if countDown.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++cntD: Below Zero", 30)
|
||||
end
|
||||
cfxZones.pollFlag(theZone.zeroFlag, theZone.ctdwnMethod, theZone)
|
||||
@ -207,7 +228,6 @@ function countDown.isTriggered(theZone)
|
||||
|
||||
-- update & return
|
||||
theZone.currVal = val
|
||||
|
||||
end
|
||||
|
||||
function countDown.update()
|
||||
@ -215,8 +235,17 @@ function countDown.update()
|
||||
timer.scheduleFunction(countDown.update, {}, timer.getTime() + 1/countDown.ups)
|
||||
|
||||
for idx, aZone in pairs(countDown.counters) do
|
||||
if aZone.resetFlag then
|
||||
if cfxZones.testZoneFlag(aZone, aZone.resetFlag, aZone.ctdwnTriggerMethod, "resetFlagValue") then
|
||||
-- reset pulled, reset the timer to start condition
|
||||
countDown.reset(aZone)
|
||||
end
|
||||
end
|
||||
|
||||
-- make sure to re-start before reading time limit
|
||||
if (not aZone.counterDisabled) and cfxZones.testZoneFlag(aZone, aZone.triggerCountFlag, aZone.ctdwnTriggerMethod, "lastCountTriggerValue")
|
||||
-- if reset, lastTriggerValue is updated and will not trigger
|
||||
if (not aZone.counterDisabled) and
|
||||
cfxZones.testZoneFlag(aZone, aZone.triggerCountFlag, aZone.ctdwnTriggerMethod, "lastCountTriggerValue")
|
||||
then
|
||||
if countDown.verbose then
|
||||
trigger.action.outText("+++cntD: triggered on in?", 30)
|
||||
@ -224,20 +253,6 @@ function countDown.update()
|
||||
countDown.isTriggered(aZone)
|
||||
end
|
||||
|
||||
-- old colde
|
||||
--[[--
|
||||
if aZone.triggerCountFlag and not aZone.counterDisabled then
|
||||
local currTriggerVal = cfxZones.getFlagValue(aZone.triggerCountFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerCountFlag)
|
||||
if currTriggerVal ~= aZone.lastCountTriggerValue
|
||||
then
|
||||
if countDown.verbose then
|
||||
trigger.action.outText("+++cntD: triggered on in?", 30)
|
||||
end
|
||||
countDown.isTriggered(aZone)
|
||||
aZone.lastCountTriggerValue = cfxZones.getFlagValue(aZone.triggerCountFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerCountFlag) -- save last value
|
||||
end
|
||||
end
|
||||
--]]--
|
||||
if cfxZones.testZoneFlag(aZone, aZone.disableCounterFlag, aZone.ctdwnTriggerMethod, "disableCounterFlagVal") then
|
||||
if countDown.verbose then
|
||||
trigger.action.outText("+++cntD: disabling counter " .. aZone.name, 30)
|
||||
@ -245,18 +260,6 @@ function countDown.update()
|
||||
aZone.counterDisabled = true
|
||||
end
|
||||
|
||||
-- old code
|
||||
--[[--
|
||||
if aZone.disableCounterFlag then
|
||||
local currVal = cfxZones.getFlagValue(aZone.disableCounterFlag, aZone)
|
||||
if currVal ~= aZone.disableCounterFlagVal then
|
||||
if countDown.verbose then
|
||||
trigger.action.outText("+++cntD: disabling counter " .. aZone.name, 30)
|
||||
end
|
||||
aZone.counterDisabled = true
|
||||
end
|
||||
end
|
||||
--]]--
|
||||
end
|
||||
end
|
||||
|
||||
@ -273,8 +276,6 @@ function countDown.readConfigZone()
|
||||
end
|
||||
|
||||
countDown.ups = cfxZones.getNumberFromZoneProperty(theZone, "ups", 1)
|
||||
-- slowest is once avery 1000 seconds = 17 minutes, doesn't make much sense slower than 1/second anyway
|
||||
|
||||
if countDown.ups < 0.001 then countDown.ups = 0.001 end
|
||||
|
||||
countDown.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
|
||||
@ -304,7 +305,6 @@ function countDown.start()
|
||||
countDown.addCountDown(aZone) -- add to list
|
||||
end
|
||||
|
||||
|
||||
-- start update
|
||||
countDown.update()
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
csarManager = {}
|
||||
csarManager.version = "2.2.4"
|
||||
csarManager.version = "2.2.5"
|
||||
csarManager.verbose = false
|
||||
csarManager.ups = 1
|
||||
|
||||
@ -62,6 +62,7 @@ csarManager.ups = 1
|
||||
- deprecated coalition attribute
|
||||
- 2.2.4 - CSAR attribute value defaults name
|
||||
- start? attribute for CSAR as startCSAR? synonym
|
||||
- 2.2.5 - manual freq for CSAR was off by a factor of 10 - Corrected
|
||||
|
||||
INTEGRATES AUTOMATICALLY WITH playerScore IF INSTALLED
|
||||
|
||||
@ -758,10 +759,10 @@ function csarManager.doListCSARRequests(args)
|
||||
local b = dcsCommon.bearingInDegreesFromAtoB(point, mission.zone.point)
|
||||
local status = "alive"
|
||||
if csarManager.vectoring then
|
||||
report = report .. "\n".. mission.name .. ", bearing " .. b .. ", " ..d .."nm, " .. " ADF " .. mission.freq .. "0 kHz - " .. status
|
||||
report = report .. "\n".. mission.name .. ", bearing " .. b .. ", " ..d .."nm, " .. " ADF " .. mission.freq * 10 .. " kHz - " .. status
|
||||
else
|
||||
-- leave out vectoring
|
||||
report = report .. "\n".. mission.name .. " ADF " .. mission.freq .. "0 kHz - " .. status
|
||||
report = report .. "\n".. mission.name .. " ADF " .. mission.freq * 10 .. " kHz - " .. status
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1291,7 +1292,10 @@ function csarManager.readCSARZone(theZone)
|
||||
end
|
||||
|
||||
theZone.csarFreq = cfxZones.getNumberFromZoneProperty(theZone, "freq", 0)
|
||||
if theZone.csarFreq == 0 then theZone.csarFreq = nil end
|
||||
-- since freqs are set in 10kHz multiplier by DML
|
||||
-- we have to divide the feq given here by 10
|
||||
theZone.csarFreq = theZone.csarFreq / 10
|
||||
if theZone.csarFreq < 0.01 then theZone.csarFreq = nil end
|
||||
theZone.numCrew = 1
|
||||
theZone.csarMapMarker = nil
|
||||
theZone.timeLimit = cfxZones.getNumberFromZoneProperty(theZone, "timeLimit", 0)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
dcsCommon = {}
|
||||
dcsCommon.version = "2.8.4"
|
||||
dcsCommon.version = "2.8.5"
|
||||
--[[-- VERSION HISTORY
|
||||
2.2.6 - compassPositionOfARelativeToB
|
||||
- clockPositionOfARelativeToB
|
||||
@ -144,6 +144,7 @@ dcsCommon.version = "2.8.4"
|
||||
- new rotatePointAroundPointDeg()
|
||||
- new rotatePointAroundPointRad()
|
||||
- getClosestAirbaseTo() now supports passing list of air bases
|
||||
2.8.5 - better guard in getGroupUnit()
|
||||
|
||||
|
||||
--]]--
|
||||
@ -999,7 +1000,7 @@ dcsCommon.version = "2.8.4"
|
||||
|
||||
-- iterate through all members of group until one is alive and exists
|
||||
for index, theUnit in pairs(allUnits) do
|
||||
if (theUnit:isExist() and theUnit:getLife() > 0) then
|
||||
if Unit.isExist(theUnit) and theUnit:getLife() > 0 then
|
||||
return theUnit
|
||||
end;
|
||||
end
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
pulseFlags = {}
|
||||
pulseFlags.version = "1.3.2"
|
||||
pulseFlags.version = "1.3.3"
|
||||
pulseFlags.verbose = false
|
||||
pulseFlags.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
@ -38,6 +38,7 @@ pulseFlags.requiredLibs = {
|
||||
- 1.3.0 persistence
|
||||
- 1.3.1 typos corrected
|
||||
- 1.3.2 removed last pulse's timeID upon entry in doPulse
|
||||
- 1.3.3 removed 'pulsing' when pausing, so we can restart
|
||||
|
||||
--]]--
|
||||
|
||||
@ -275,6 +276,7 @@ function pulseFlags.update()
|
||||
trigger.action.outText("+++pulF: pausing <" .. aZone.name .. ">", 30)
|
||||
end
|
||||
aZone.pulsePaused = true -- prevents new start
|
||||
aZone.pulsing = false -- we are stopped
|
||||
if aZone.timerID then
|
||||
timer.removeFunction(aZone.timerID)
|
||||
aZone.timerID = nil
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user