mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 1.3.0
FlareZone PlayerZone shallows
This commit is contained in:
parent
97d3c10540
commit
83f9478f86
Binary file not shown.
Binary file not shown.
113
modules/asw.lua
113
modules/asw.lua
@ -1,5 +1,5 @@
|
|||||||
asw = {}
|
asw = {}
|
||||||
asw.version = "1.0.0"
|
asw.version = "1.0.1"
|
||||||
asw.verbose = false
|
asw.verbose = false
|
||||||
asw.requiredLibs = {
|
asw.requiredLibs = {
|
||||||
"dcsCommon", -- always
|
"dcsCommon", -- always
|
||||||
@ -15,6 +15,7 @@ asw.fixes = {} -- all subs that we have a fix on. indexed by sub name
|
|||||||
--[[--
|
--[[--
|
||||||
Version History
|
Version History
|
||||||
1.0.0 - initial version
|
1.0.0 - initial version
|
||||||
|
1.0.1 - integration with playerScore
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
@ -36,6 +37,10 @@ function asw.createTorpedoForUnit(theUnit)
|
|||||||
local t = asw.createTorpedo()
|
local t = asw.createTorpedo()
|
||||||
t.coalition = theUnit:getCoalition()
|
t.coalition = theUnit:getCoalition()
|
||||||
t.point = theUnit:getPoint()
|
t.point = theUnit:getPoint()
|
||||||
|
t.droppedBy = theUnit
|
||||||
|
if theUnit.getPlayerName and theUnit:getPlayerName() ~= nil then
|
||||||
|
t.playerName = theUnit:getPlayerName()
|
||||||
|
end
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -716,6 +721,7 @@ function asw.updateTorpedo(theTorpedo, allSubs)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if dist < 1.2 * displacement then
|
if dist < 1.2 * displacement then
|
||||||
|
theTorpedo.target = theSub
|
||||||
theTorpedo.state = 99 -- go boom
|
theTorpedo.state = 99 -- go boom
|
||||||
end
|
end
|
||||||
markTorpedo(theTorpedo)
|
markTorpedo(theTorpedo)
|
||||||
@ -762,10 +768,26 @@ function asw.updateTorpedo(theTorpedo, allSubs)
|
|||||||
return true
|
return true
|
||||||
elseif theTorpedo.state == 99 then -- go boom
|
elseif theTorpedo.state == 99 then -- go boom
|
||||||
if Unit.isExist(theTorpedo.target) then
|
if Unit.isExist(theTorpedo.target) then
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("99 torpedoes have target", 30)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- interface to playerScore
|
||||||
|
if cfxPlayerScore then
|
||||||
|
asw.doScore(theTorpedo)
|
||||||
|
else
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("No playerScore present", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
Unit.destroy(theTorpedo.target)
|
Unit.destroy(theTorpedo.target)
|
||||||
|
else
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("t99 no target exist", 30)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
-- impact!
|
-- impact!
|
||||||
trigger.action.outTextForCoalition(theTorpedo.coalition, "Impact for " .. theTorpedo.name .. "! We have confirmed hit on submerged contact!", 30)
|
trigger.action.outTextForCoalition(theTorpedo.coalition, "Impact for " .. theTorpedo.name .. "! We have confirmed hit on submerged contact!", 30)
|
||||||
if theTorpedo.coalition == 1 then
|
if theTorpedo.coalition == 1 then
|
||||||
if asw.redKill then
|
if asw.redKill then
|
||||||
cfxZones.pollFlag(asw.redKill, asw.method, asw)
|
cfxZones.pollFlag(asw.redKill, asw.method, asw)
|
||||||
@ -796,6 +818,86 @@ function asw.updateTorpedo(theTorpedo, allSubs)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- PlayerScore interface
|
||||||
|
function processFeat(inMsg, playerUnit, victim, timeFormat)
|
||||||
|
if not inMsg then return "<nil inMsg>" end
|
||||||
|
-- replace <t> with current mission time HMS
|
||||||
|
local absSecs = timer.getAbsTime()-- + env.mission.start_time
|
||||||
|
while absSecs > 86400 do
|
||||||
|
absSecs = absSecs - 86400 -- subtract out all days
|
||||||
|
end
|
||||||
|
if not timeFormat then timeFormat = "<:h>:<:m>:<:s>" end
|
||||||
|
-- <t>
|
||||||
|
local timeString = dcsCommon.processHMS(timeFormat, absSecs)
|
||||||
|
local outMsg = inMsg:gsub("<t>", timeString)
|
||||||
|
-- <n>
|
||||||
|
outMsg = dcsCommon.processStringWildcards(outMsg) -- <n>
|
||||||
|
-- <unit, type, player etc>
|
||||||
|
outMsg = cfxPlayerScore.preprocessWildcards(outMsg, playerUnit, victim)
|
||||||
|
return outMsg
|
||||||
|
end
|
||||||
|
|
||||||
|
function asw.doScore(theTorpedo)
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("asw: enter doScore", 30)
|
||||||
|
end
|
||||||
|
-- make sure that this is a player-dropped torpedo
|
||||||
|
if not theTorpedo then
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("no torpedo", 30)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local theUnit = theTorpedo.target
|
||||||
|
if not theTorpedo.playerName then
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("no torpedo", 30)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local pName = theTorpedo.playerName
|
||||||
|
-- make sure that the player's original unit still exists
|
||||||
|
if not (theTorpedo.droppedBy and Unit.isExist(theTorpedo.droppedBy)) then
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("torpedo dropper dead", 30)
|
||||||
|
end
|
||||||
|
return -- torpedo-dropping unit did not survive
|
||||||
|
end
|
||||||
|
|
||||||
|
local fratricide = (theTorpedo.coalition == theUnit:getCoalition())
|
||||||
|
if fratricide then
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("+++asw: fratricide detected", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if asw.killScore > 0 then
|
||||||
|
-- award score
|
||||||
|
local score = asw.killScore
|
||||||
|
if fratricide then score = -1 * score end
|
||||||
|
cfxPlayerScore.logKillForPlayer(pName, theUnit)
|
||||||
|
cfxPlayerScore.awardScoreTo(theTorpedo.coalition, score, pName)
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("updated score (" .. score .. ") for player <" .. pName .. ">", 30)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("no score num defined", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if asw.killFeat and (not fratricide) then
|
||||||
|
-- we treat killFeat as boolean
|
||||||
|
local theFeat = "Killed type <type> submerged vessel <unit> at <t>"
|
||||||
|
theFeat = processFeat(theFeat, theTorpedo.droppedBy, theUnit)
|
||||||
|
cfxPlayerScore.logFeatForPlayer(pName, theFeat)
|
||||||
|
else
|
||||||
|
if asw.verbose then
|
||||||
|
trigger.action.outText("no feat defined or fratricide", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- MAIN UPDATE
|
-- MAIN UPDATE
|
||||||
--
|
--
|
||||||
@ -941,9 +1043,16 @@ function asw.readConfigZone()
|
|||||||
asw.smokeColor = cfxZones.getSmokeColorStringFromZoneProperty(theZone, "smokeColor", "red")
|
asw.smokeColor = cfxZones.getSmokeColorStringFromZoneProperty(theZone, "smokeColor", "red")
|
||||||
asw.smokeColor = dcsCommon.smokeColor2Num(asw.smokeColor)
|
asw.smokeColor = dcsCommon.smokeColor2Num(asw.smokeColor)
|
||||||
|
|
||||||
|
asw.killScore = cfxZones.getNumberFromZoneProperty(theZone, "killScore", 0)
|
||||||
|
|
||||||
|
if cfxZones.hasProperty(theZone, "killFeat") then
|
||||||
|
asw.killFeat = cfxZones.getStringFromZoneProperty(theZone, "killFeat", "Sub Kill")
|
||||||
|
end
|
||||||
|
|
||||||
if asw.verbose then
|
if asw.verbose then
|
||||||
trigger.action.outText("+++asw: read config", 30)
|
trigger.action.outText("+++asw: read config", 30)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function asw.start()
|
function asw.start()
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
aswGUI = {}
|
aswGUI = {}
|
||||||
aswGUI.version = "1.0.1"
|
aswGUI.version = "1.0.2"
|
||||||
aswGUI.verbose = false
|
aswGUI.verbose = false
|
||||||
aswGUI.requiredLibs = {
|
aswGUI.requiredLibs = {
|
||||||
"dcsCommon", -- always
|
"dcsCommon", -- always
|
||||||
@ -12,6 +12,7 @@ aswGUI.requiredLibs = {
|
|||||||
Version History
|
Version History
|
||||||
1.0.0 - initial version
|
1.0.0 - initial version
|
||||||
1.0.1 - env.info clean-up, verbosity clean-up
|
1.0.1 - env.info clean-up, verbosity clean-up
|
||||||
|
1.0.2 - late start capability
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
@ -524,6 +525,22 @@ function aswGUI:onEvent(theEvent)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function aswGUI.processPlayerUnit(theUnit)
|
||||||
|
local name = theUnit:getName()
|
||||||
|
local conf = aswGUI.aswCraft[name]
|
||||||
|
if not conf then
|
||||||
|
-- let's init it
|
||||||
|
conf = aswGUI.initUnit(name)
|
||||||
|
aswGUI.aswCraft[name] = conf
|
||||||
|
else
|
||||||
|
aswGUI.resetConf(conf)
|
||||||
|
end
|
||||||
|
aswGUI.setMenuForUnit(theUnit)
|
||||||
|
if aswGUI.verbose then
|
||||||
|
trigger.action.outText("aswG: set up player <" .. theUnit:getPlayerName() .. "> in <" .. name .. ">", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Config & start
|
-- Config & start
|
||||||
--
|
--
|
||||||
@ -572,6 +589,9 @@ function aswGUI.start()
|
|||||||
-- subscribe to world events
|
-- subscribe to world events
|
||||||
world.addEventHandler(aswGUI)
|
world.addEventHandler(aswGUI)
|
||||||
|
|
||||||
|
-- install menus in all existing players
|
||||||
|
dcsCommon.iteratePlayers(aswGUI.processPlayerUnit)
|
||||||
|
|
||||||
-- say Hi
|
-- say Hi
|
||||||
trigger.action.outText("cfx ASW GUI v" .. aswGUI.version .. " started.", 30)
|
trigger.action.outText("cfx ASW GUI v" .. aswGUI.version .. " started.", 30)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
cfxPlayerScore = {}
|
cfxPlayerScore = {}
|
||||||
cfxPlayerScore.version = "2.0.0"
|
cfxPlayerScore.version = "2.0.1"
|
||||||
cfxPlayerScore.name = "cfxPlayerScore" -- compatibility with flag bangers
|
cfxPlayerScore.name = "cfxPlayerScore" -- compatibility with flag bangers
|
||||||
cfxPlayerScore.badSound = "Death BRASS.wav"
|
cfxPlayerScore.badSound = "Death BRASS.wav"
|
||||||
cfxPlayerScore.scoreSound = "Quest Snare 3.wav"
|
cfxPlayerScore.scoreSound = "Quest Snare 3.wav"
|
||||||
@ -70,6 +70,8 @@ cfxPlayerScore.firstSave = true -- to force overwrite
|
|||||||
- pkMod attribute
|
- pkMod attribute
|
||||||
- pvp feat
|
- pvp feat
|
||||||
- immediate awarding of all negative scores, even if deferred
|
- immediate awarding of all negative scores, even if deferred
|
||||||
|
2.0.1 - corrected access to nowString()
|
||||||
|
- more robust config reading
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
@ -1278,7 +1280,7 @@ function cfxPlayerScore.saveScores(theText, name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- prepend time for score
|
-- prepend time for score
|
||||||
theText = "\n\n====== Mission Time: " .. dcsCommon.nowstring() .. "\n" .. theText
|
theText = "\n\n====== Mission Time: " .. dcsCommon.nowString() .. "\n" .. theText
|
||||||
end
|
end
|
||||||
|
|
||||||
if persistence.saveText(theText, name, shared, append) then
|
if persistence.saveText(theText, name, shared, append) then
|
||||||
@ -1360,10 +1362,11 @@ function cfxPlayerScore.start()
|
|||||||
local theZone = cfxZones.getZoneByName("playerScoreConfig")
|
local theZone = cfxZones.getZoneByName("playerScoreConfig")
|
||||||
if not theZone then
|
if not theZone then
|
||||||
trigger.action.outText("+++scr: no config!", 30)
|
trigger.action.outText("+++scr: no config!", 30)
|
||||||
else
|
theZone = cfxZones.createSimpleZone("playerScoreConfig")
|
||||||
cfxPlayerScore.readConfigZone(theZone)
|
|
||||||
trigger.action.outText("+++scr: read config", 30)
|
|
||||||
end
|
end
|
||||||
|
cfxPlayerScore.readConfigZone(theZone)
|
||||||
|
-- trigger.action.outText("+++scr: read config", 30)
|
||||||
|
|
||||||
|
|
||||||
-- read all scoreSafe zones
|
-- read all scoreSafe zones
|
||||||
local safeZones = cfxZones.zonesWithProperty("scoreSafe")
|
local safeZones = cfxZones.zonesWithProperty("scoreSafe")
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
cfxPlayerScoreUI = {}
|
cfxPlayerScoreUI = {}
|
||||||
cfxPlayerScoreUI.version = "2.0.0"
|
cfxPlayerScoreUI.version = "2.0.1"
|
||||||
cfxPlayerScoreUI.verbose = false
|
cfxPlayerScoreUI.verbose = false
|
||||||
|
|
||||||
--[[-- VERSION HISTORY
|
--[[-- VERSION HISTORY
|
||||||
- 1.0.2 - initial version
|
- 1.0.2 - initial version
|
||||||
- 1.0.3 - module check
|
- 1.0.3 - module check
|
||||||
- 2.0.0 - removed cfxPlayer dependency, handles own commands
|
- 2.0.0 - removed cfxPlayer dependency, handles own commands
|
||||||
|
- 2.0.1 - late start capability
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
cfxPlayerScoreUI.rootCommands = {} -- by unit's group name, for player aircraft
|
cfxPlayerScoreUI.rootCommands = {} -- by unit's GROUP name, for player aircraft
|
||||||
|
|
||||||
-- redirect: avoid the debug environ of missionCommand
|
-- redirect: avoid the debug environ of missionCommand
|
||||||
function cfxPlayerScoreUI.redirectCommandX(args)
|
function cfxPlayerScoreUI.redirectCommandX(args)
|
||||||
@ -23,7 +24,7 @@ function cfxPlayerScoreUI.doCommandX(args)
|
|||||||
local gid = theGroup:getID()
|
local gid = theGroup:getID()
|
||||||
|
|
||||||
if not cfxPlayerScore.scoreTextForPlayerNamed then
|
if not cfxPlayerScore.scoreTextForPlayerNamed then
|
||||||
trigger.action.outText("***pSGui: CANNOT FIND PlayerScore MODULE", 30)
|
trigger.action.outText("***pSGUI: CANNOT FIND PlayerScore MODULE", 30)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local desc = cfxPlayerScore.scoreTextForPlayerNamed(playerName)
|
local desc = cfxPlayerScore.scoreTextForPlayerNamed(playerName)
|
||||||
@ -35,10 +36,7 @@ end
|
|||||||
-- event handling: we are only interested in birth events
|
-- event handling: we are only interested in birth events
|
||||||
-- for player aircraft
|
-- for player aircraft
|
||||||
--
|
--
|
||||||
function cfxPlayerScoreUI:onEvent(event)
|
function cfxPlayerScore.processPlayerUnit(theUnit)
|
||||||
if event.id ~= 15 then return end -- only birth
|
|
||||||
if not event.initiator then return end -- no initiator, no joy
|
|
||||||
local theUnit = event.initiator
|
|
||||||
if not theUnit.getPlayerName then return end -- no player name, bye!
|
if not theUnit.getPlayerName then return end -- no player name, bye!
|
||||||
local playerName = theUnit:getPlayerName()
|
local playerName = theUnit:getPlayerName()
|
||||||
if not playerName then return end
|
if not playerName then return end
|
||||||
@ -61,13 +59,7 @@ function cfxPlayerScoreUI:onEvent(event)
|
|||||||
-- we need to install a group menu item for scores.
|
-- we need to install a group menu item for scores.
|
||||||
-- will persist through death
|
-- will persist through death
|
||||||
local commandTxt = "Show Score / Kills"
|
local commandTxt = "Show Score / Kills"
|
||||||
local theCommand = missionCommands.addCommandForGroup(
|
local theCommand = missionCommands.addCommandForGroup(gid, commandTxt, nil, cfxPlayerScoreUI.redirectCommandX, {groupName, playerName, "score"} )
|
||||||
gid,
|
|
||||||
commandTxt,
|
|
||||||
nil, -- root level
|
|
||||||
cfxPlayerScoreUI.redirectCommandX,
|
|
||||||
{groupName, playerName, "score"}
|
|
||||||
)
|
|
||||||
cfxPlayerScoreUI.rootCommands[groupName] = theCommand
|
cfxPlayerScoreUI.rootCommands[groupName] = theCommand
|
||||||
|
|
||||||
if cfxPlayerScoreUI.verbose then
|
if cfxPlayerScoreUI.verbose then
|
||||||
@ -75,13 +67,21 @@ function cfxPlayerScoreUI:onEvent(event)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cfxPlayerScoreUI:onEvent(event)
|
||||||
|
if event.id ~= 15 then return end -- only birth
|
||||||
|
if not event.initiator then return end -- no initiator, no joy
|
||||||
|
local theUnit = event.initiator
|
||||||
|
cfxPlayerScore.processPlayerUnit(theUnit)
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Start
|
-- Start
|
||||||
--
|
--
|
||||||
function cfxPlayerScoreUI.start()
|
function cfxPlayerScoreUI.start()
|
||||||
-- install the event handler for new player planes
|
-- install the event handler for new player planes
|
||||||
world.addEventHandler(cfxPlayerScoreUI)
|
world.addEventHandler(cfxPlayerScoreUI)
|
||||||
|
-- process all existing players (late start)
|
||||||
|
dcsCommon.iteratePlayers(cfxPlayerScore.processPlayerUnit)
|
||||||
trigger.action.outText("cf/x cfxPlayerScoreUI v" .. cfxPlayerScoreUI.version .. " started", 30)
|
trigger.action.outText("cf/x cfxPlayerScoreUI v" .. cfxPlayerScoreUI.version .. " started", 30)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
cfxSmokeZone = {}
|
cfxSmokeZone = {}
|
||||||
cfxSmokeZone.version = "1.1.2"
|
cfxSmokeZone.version = "1.1.3"
|
||||||
cfxSmokeZone.requiredLibs = {
|
cfxSmokeZone.requiredLibs = {
|
||||||
"dcsCommon", -- always
|
"dcsCommon", -- always
|
||||||
"cfxZones", -- Zones, of course
|
"cfxZones", -- Zones, of course
|
||||||
@ -18,6 +18,7 @@ cfxSmokeZone.requiredLibs = {
|
|||||||
1.1.0 - Watchflag upgrade
|
1.1.0 - Watchflag upgrade
|
||||||
1.1.1 - stopSmoke? input
|
1.1.1 - stopSmoke? input
|
||||||
1.1.2 - 'agl', 'alt' synonymous for altitude to keep in line with fireFX
|
1.1.2 - 'agl', 'alt' synonymous for altitude to keep in line with fireFX
|
||||||
|
1.1.3 - corrected smokeTriggerMethod in zone definition
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
cfxSmokeZone.smokeZones = {}
|
cfxSmokeZone.smokeZones = {}
|
||||||
@ -67,7 +68,7 @@ function cfxSmokeZone.processSmokeZone(aZone)
|
|||||||
aZone.smokeTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, "triggerMethod", "change")
|
aZone.smokeTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, "triggerMethod", "change")
|
||||||
|
|
||||||
if cfxZones.hasProperty(aZone, "smokeTriggerMethod") then
|
if cfxZones.hasProperty(aZone, "smokeTriggerMethod") then
|
||||||
aZone.delayTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, "smokeTriggerMethod", "change")
|
aZone.smokeTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, "smokeTriggerMethod", "change")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
cfxSpawnZones = {}
|
cfxSpawnZones = {}
|
||||||
cfxSpawnZones.version = "1.7.4"
|
cfxSpawnZones.version = "1.7.5"
|
||||||
cfxSpawnZones.requiredLibs = {
|
cfxSpawnZones.requiredLibs = {
|
||||||
"dcsCommon", -- common is of course needed for everything
|
"dcsCommon", -- common is of course needed for everything
|
||||||
-- pretty stupid to check for this since we
|
-- pretty stupid to check for this since we
|
||||||
@ -66,6 +66,8 @@ cfxSpawnZones.spawnedGroups = {}
|
|||||||
1.7.2 - baseName now can can be set to zone name by issuing "*"
|
1.7.2 - baseName now can can be set to zone name by issuing "*"
|
||||||
1.7.3 - ability to hand off to delicates, useDelicates attribute
|
1.7.3 - ability to hand off to delicates, useDelicates attribute
|
||||||
1.7.4 - wait-attackZone fixes
|
1.7.4 - wait-attackZone fixes
|
||||||
|
1.7.5 - improved verbosity on spawning
|
||||||
|
- getRequestableSpawnersInRange() ignores height for distance
|
||||||
|
|
||||||
|
|
||||||
- types - type strings, comma separated
|
- types - type strings, comma separated
|
||||||
@ -204,6 +206,9 @@ function cfxSpawnZones.createSpawner(inZone)
|
|||||||
theSpawner.requestable = cfxZones.getBoolFromZoneProperty(inZone, "requestable", false)
|
theSpawner.requestable = cfxZones.getBoolFromZoneProperty(inZone, "requestable", false)
|
||||||
if theSpawner.requestable then
|
if theSpawner.requestable then
|
||||||
theSpawner.paused = true
|
theSpawner.paused = true
|
||||||
|
if inZone.verbose or cfxSpawnZones.verbose then
|
||||||
|
trigger.action.outText("+++spwn: spawner <" .. inZone.name .. "> paused: requestable enabled", 30)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if cfxZones.hasProperty(inZone, "target") then
|
if cfxZones.hasProperty(inZone, "target") then
|
||||||
theSpawner.target = cfxZones.getStringFromZoneProperty(inZone, "target", "")
|
theSpawner.target = cfxZones.getStringFromZoneProperty(inZone, "target", "")
|
||||||
@ -248,7 +253,7 @@ function cfxSpawnZones.getRequestableSpawnersInRange(aPoint, aRange, aSide)
|
|||||||
for aZone, aSpawner in pairs(cfxSpawnZones.allSpawners) do
|
for aZone, aSpawner in pairs(cfxSpawnZones.allSpawners) do
|
||||||
-- iterate all zones and collect those that match
|
-- iterate all zones and collect those that match
|
||||||
local hasMatch = true
|
local hasMatch = true
|
||||||
local delta = dcsCommon.dist(aPoint, aZone.point)
|
local delta = dcsCommon.distFlat(aPoint, cfxZones.getPoint(aZone))
|
||||||
if delta>aRange then hasMatch = false end
|
if delta>aRange then hasMatch = false end
|
||||||
if aSide ~= 0 then
|
if aSide ~= 0 then
|
||||||
-- check if side is correct for owned zone
|
-- check if side is correct for owned zone
|
||||||
@ -336,6 +341,17 @@ function cfxSpawnZones.spawnWithSpawner(aSpawner)
|
|||||||
unitTypes,
|
unitTypes,
|
||||||
aSpawner.formation,
|
aSpawner.formation,
|
||||||
aSpawner.heading)
|
aSpawner.heading)
|
||||||
|
if cfxSpawnZones.verbose or theZone.verbose then
|
||||||
|
-- check created group size versus requested size
|
||||||
|
trigger.action.outText("+++spwn: created <" .. theGroup:getSize() .. "> units, requested <" .. #unitTypes .. "> units, formation <" .. aSpawner.formation .. ">", 30)
|
||||||
|
trigger.action.outText("+++spwn: zone <" .. theZone.name .. ">center at <" .. dcsCommon.point2text(p) .. ">", 30)
|
||||||
|
local allUnits = theGroup:getUnits()
|
||||||
|
for idx, myUnit in pairs (allUnits) do
|
||||||
|
local pos = myUnit:getPoint()
|
||||||
|
trigger.action.outText("unit <" .. myUnit:getName() .. "> at " .. dcsCommon.point2text(pos), 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
aSpawner.theSpawn = theGroup
|
aSpawner.theSpawn = theGroup
|
||||||
aSpawner.count = aSpawner.count + 1
|
aSpawner.count = aSpawner.count + 1
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
cfxZones = {}
|
cfxZones = {}
|
||||||
cfxZones.version = "3.0.8"
|
cfxZones.version = "3.0.9"
|
||||||
|
|
||||||
-- 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
|
||||||
@ -126,6 +126,7 @@ cfxZones.version = "3.0.8"
|
|||||||
- new createSimpleQuadZone()
|
- new createSimpleQuadZone()
|
||||||
- 3.0.7 - getPoint() can also get land y when passing true as second param
|
- 3.0.7 - getPoint() can also get land y when passing true as second param
|
||||||
- 3.0.8 - new cfxZones.pointInOneOfZones(thePoint, zoneArray, useOrig)
|
- 3.0.8 - new cfxZones.pointInOneOfZones(thePoint, zoneArray, useOrig)
|
||||||
|
- 3.0.9 - new getFlareColorStringFromZoneProperty()
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
cfxZones.verbose = false
|
cfxZones.verbose = false
|
||||||
@ -2241,6 +2242,30 @@ function cfxZones.getSmokeColorStringFromZoneProperty(theZone, theProperty, defa
|
|||||||
return default
|
return default
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cfxZones.getFlareColorStringFromZoneProperty(theZone, theProperty, default) -- smoke as 'red', 'green', or 1..5
|
||||||
|
if not default then default = "red" end
|
||||||
|
local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, default)
|
||||||
|
s = s:lower()
|
||||||
|
s = dcsCommon.trim(s)
|
||||||
|
-- check numbers
|
||||||
|
if (s == "rnd") then return "random" end
|
||||||
|
if (s == "0") then return "green" end
|
||||||
|
if (s == "1") then return "red" end
|
||||||
|
if (s == "2") then return "white" end
|
||||||
|
if (s == "3") then return "yellow" end
|
||||||
|
if (s == "-1") then return "random" end
|
||||||
|
|
||||||
|
if s == "green" or
|
||||||
|
s == "red" or
|
||||||
|
s == "white" or
|
||||||
|
s == "yellow" or
|
||||||
|
s == "random" then
|
||||||
|
return s end
|
||||||
|
|
||||||
|
return default
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Zone-based wildcard processing
|
-- Zone-based wildcard processing
|
||||||
--
|
--
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
csarManager = {}
|
csarManager = {}
|
||||||
csarManager.version = "2.2.5"
|
csarManager.version = "2.2.6"
|
||||||
csarManager.verbose = false
|
csarManager.verbose = false
|
||||||
csarManager.ups = 1
|
csarManager.ups = 1
|
||||||
|
|
||||||
@ -63,6 +63,8 @@ csarManager.ups = 1
|
|||||||
- 2.2.4 - CSAR attribute value defaults name
|
- 2.2.4 - CSAR attribute value defaults name
|
||||||
- start? attribute for CSAR as startCSAR? synonym
|
- start? attribute for CSAR as startCSAR? synonym
|
||||||
- 2.2.5 - manual freq for CSAR was off by a factor of 10 - Corrected
|
- 2.2.5 - manual freq for CSAR was off by a factor of 10 - Corrected
|
||||||
|
- 2.2.6 - useFlare, now also launches a flare in addition to smoke
|
||||||
|
- zone testing uses getPoint for zones, supports moving csar zones
|
||||||
|
|
||||||
INTEGRATES AUTOMATICALLY WITH playerScore IF INSTALLED
|
INTEGRATES AUTOMATICALLY WITH playerScore IF INSTALLED
|
||||||
|
|
||||||
@ -1028,6 +1030,18 @@ function csarManager.updateCSARMissions()
|
|||||||
csarManager.openMissions = newMissions -- this is the new batch
|
csarManager.openMissions = newMissions -- this is the new batch
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function csarManager.launchFlare(args)
|
||||||
|
local color = args.color
|
||||||
|
if color < 0 then color = math.random(4) - 1 end
|
||||||
|
local loc = args.loc -- with height
|
||||||
|
if csarManager.verbose then
|
||||||
|
trigger.action.outText("+++csarM: launching flare, c = " .. color .. " (" .. dcsCommon.flareColor2Text(color) .. ")", 30)
|
||||||
|
end
|
||||||
|
trigger.action.outTextForGroup(args.uID, "Launching flare!", 30)
|
||||||
|
loc.y = loc.y + 3 -- launch 3 meters above ground
|
||||||
|
trigger.action.signalFlare(loc, color, 0)
|
||||||
|
end
|
||||||
|
|
||||||
function csarManager.update() -- every second
|
function csarManager.update() -- every second
|
||||||
-- schedule next invocation
|
-- schedule next invocation
|
||||||
timer.scheduleFunction(csarManager.update, {}, timer.getTime() + 1/csarManager.ups)
|
timer.scheduleFunction(csarManager.update, {}, timer.getTime() + 1/csarManager.ups)
|
||||||
@ -1053,7 +1067,8 @@ function csarManager.update() -- every second
|
|||||||
-- enough to trigger comms
|
-- enough to trigger comms
|
||||||
for idx, csarMission in pairs (csarManager.openMissions) do
|
for idx, csarMission in pairs (csarManager.openMissions) do
|
||||||
-- check if we are inside trigger range on the same side
|
-- check if we are inside trigger range on the same side
|
||||||
local d = dcsCommon.distFlat(uPoint, csarMission.zone.point)
|
local mp = cfxZones.getPoint(csarMission.zone, true)
|
||||||
|
local d = dcsCommon.distFlat(uPoint, mp)
|
||||||
if ((uSide == csarMission.side) or (csarMission.side == 0) )
|
if ((uSide == csarMission.side) or (csarMission.side == 0) )
|
||||||
and (d < csarManager.rescueTriggerRange) then
|
and (d < csarManager.rescueTriggerRange) then
|
||||||
-- we are in trigger distance. if we did not notify before
|
-- we are in trigger distance. if we did not notify before
|
||||||
@ -1065,7 +1080,21 @@ function csarManager.update() -- every second
|
|||||||
local oclock = dcsCommon.clockPositionOfARelativeToB(csarMission.zone.point, uPoint, ownHeading) .. " o'clock"
|
local oclock = dcsCommon.clockPositionOfARelativeToB(csarMission.zone.point, uPoint, ownHeading) .. " o'clock"
|
||||||
local msg = "\n" .. uName ..", " .. csarMission.name .. ". We can hear you, check your " .. oclock
|
local msg = "\n" .. uName ..", " .. csarMission.name .. ". We can hear you, check your " .. oclock
|
||||||
if csarManager.useSmoke then msg = msg .. " - popping smoke" end
|
if csarManager.useSmoke then msg = msg .. " - popping smoke" end
|
||||||
|
if csarManager.useFlare then
|
||||||
|
if csarManager.useSmoke then
|
||||||
|
msg = msg .. " and will launch flare in a few seconds"
|
||||||
|
else
|
||||||
|
msg = msg .. " - preparing flare"
|
||||||
|
end
|
||||||
|
-- schedule flare launch in 5-10 seconds
|
||||||
|
local args = {}
|
||||||
|
args.loc = mp
|
||||||
|
args.color = csarManager.flareColor
|
||||||
|
args.uID = uID
|
||||||
|
timer.scheduleFunction(csarManager.launchFlare, args, timer.getTime() + math.random(5))
|
||||||
|
end
|
||||||
msg = msg .. "."
|
msg = msg .. "."
|
||||||
|
|
||||||
if csarMission.isHot then
|
if csarMission.isHot then
|
||||||
msg = msg .. " Be advised: LZ is hot."
|
msg = msg .. " Be advised: LZ is hot."
|
||||||
end
|
end
|
||||||
@ -1394,6 +1423,10 @@ function csarManager.readConfigZone()
|
|||||||
csarManager.smokeColor = cfxZones.getSmokeColorStringFromZoneProperty(theZone, "smokeColor", "blue")
|
csarManager.smokeColor = cfxZones.getSmokeColorStringFromZoneProperty(theZone, "smokeColor", "blue")
|
||||||
csarManager.smokeColor = dcsCommon.smokeColor2Num(csarManager.smokeColor)
|
csarManager.smokeColor = dcsCommon.smokeColor2Num(csarManager.smokeColor)
|
||||||
|
|
||||||
|
csarManager.useFlare = cfxZones.getBoolFromZoneProperty(theZone, "useFlare", true)
|
||||||
|
csarManager.flareColor = cfxZones.getFlareColorStringFromZoneProperty(theZone, "flareColor", "red")
|
||||||
|
csarManager.flareColor = dcsCommon.flareColor2Num(csarManager.flareColor)
|
||||||
|
|
||||||
|
|
||||||
if cfxZones.hasProperty(theZone, "csarRedDelivered!") then
|
if cfxZones.hasProperty(theZone, "csarRedDelivered!") then
|
||||||
csarManager.csarRedDelivered = cfxZones.getStringFromZoneProperty(theZone, "csarRedDelivered!", "*<none>")
|
csarManager.csarRedDelivered = cfxZones.getStringFromZoneProperty(theZone, "csarRedDelivered!", "*<none>")
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
dcsCommon = {}
|
dcsCommon = {}
|
||||||
dcsCommon.version = "2.8.5"
|
dcsCommon.version = "2.8.7"
|
||||||
--[[-- VERSION HISTORY
|
--[[-- VERSION HISTORY
|
||||||
2.2.6 - compassPositionOfARelativeToB
|
2.2.6 - compassPositionOfARelativeToB
|
||||||
- clockPositionOfARelativeToB
|
- clockPositionOfARelativeToB
|
||||||
@ -147,7 +147,9 @@ dcsCommon.version = "2.8.5"
|
|||||||
2.8.5 - better guard in getGroupUnit()
|
2.8.5 - better guard in getGroupUnit()
|
||||||
2.8.6 - phonetic helpers
|
2.8.6 - phonetic helpers
|
||||||
new spellString()
|
new spellString()
|
||||||
|
2.8.7 - new flareColor2Num()
|
||||||
|
- new flareColor2Text()
|
||||||
|
- new iteratePlayers()
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
@ -2545,6 +2547,15 @@ end
|
|||||||
return ("unknown: " .. smokeColor)
|
return ("unknown: " .. smokeColor)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function dcsCommon.flareColor2Text(flareColor)
|
||||||
|
if (flareColor == 0) then return "Green" end
|
||||||
|
if (flareColor == 1) then return "Red" end
|
||||||
|
if (flareColor == 2) then return "White" end
|
||||||
|
if (flareColor == 3) then return "Yellow" end
|
||||||
|
if (flareColor < 0) then return "Random" end
|
||||||
|
return ("unknown: " .. flareColor)
|
||||||
|
end
|
||||||
|
|
||||||
function dcsCommon.smokeColor2Num(smokeColor)
|
function dcsCommon.smokeColor2Num(smokeColor)
|
||||||
if not smokeColor then smokeColor = "green" end
|
if not smokeColor then smokeColor = "green" end
|
||||||
if type(smokeColor) ~= "string" then return 0 end
|
if type(smokeColor) ~= "string" then return 0 end
|
||||||
@ -2557,6 +2568,20 @@ end
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function dcsCommon.flareColor2Num(flareColor)
|
||||||
|
if not flareColor then flareColor = "green" end
|
||||||
|
if type(flareColor) ~= "string" then return 0 end
|
||||||
|
flareColor = flareColor:lower()
|
||||||
|
if (flareColor == "green") then return 0 end
|
||||||
|
if (flareColor == "red") then return 1 end
|
||||||
|
if (flareColor == "white") then return 2 end
|
||||||
|
if (flareColor == "yellow") then return 3 end
|
||||||
|
if (flareColor == "random") then return -1 end
|
||||||
|
if (flareColor == "rnd") then return -1 end
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function dcsCommon.markPointWithSmoke(p, smokeColor)
|
function dcsCommon.markPointWithSmoke(p, smokeColor)
|
||||||
if not smokeColor then smokeColor = 0 end
|
if not smokeColor then smokeColor = 0 end
|
||||||
local x = p.x
|
local x = p.x
|
||||||
@ -3315,6 +3340,23 @@ function dcsCommon.spellString(inString)
|
|||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- iterators
|
||||||
|
--
|
||||||
|
-- iteratePlayers - call callback for all player units
|
||||||
|
-- callback is of signature callback(playerUnit)
|
||||||
|
--
|
||||||
|
|
||||||
|
function dcsCommon.iteratePlayers(callBack)
|
||||||
|
local factions = {0, 1, 2}
|
||||||
|
for idx, theFaction in pairs(factions) do
|
||||||
|
local players = coalition.getPlayers(theFaction)
|
||||||
|
for idy, theUnit in pairs(players) do
|
||||||
|
callBack(theUnit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- SEMAPHORES
|
-- SEMAPHORES
|
||||||
--
|
--
|
||||||
|
|||||||
116
modules/flareZone.lua
Normal file
116
modules/flareZone.lua
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
flareZone = {}
|
||||||
|
flareZone.version = "1.0.0"
|
||||||
|
flareZone.verbose = false
|
||||||
|
flareZone.name = "flareZone"
|
||||||
|
|
||||||
|
--[[-- VERSION HISTORY
|
||||||
|
1.0.0 - initial version
|
||||||
|
--]]--
|
||||||
|
flareZone.requiredLibs = {
|
||||||
|
"dcsCommon",
|
||||||
|
"cfxZones",
|
||||||
|
}
|
||||||
|
flareZone.flares = {} -- all flare zones
|
||||||
|
|
||||||
|
function flareZone.addFlareZone(theZone)
|
||||||
|
theZone.flareColor = cfxZones.getFlareColorStringFromZoneProperty(theZone, "flare", "green")
|
||||||
|
theZone.flareColor = dcsCommon.flareColor2Num(theZone.flareColor)
|
||||||
|
if cfxZones.hasProperty(theZone, "f?") then
|
||||||
|
cfxZones.theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "f?", "<none>")
|
||||||
|
elseif cfxZones.hasProperty(theZone, "launchFlare?") then
|
||||||
|
theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "launchFlare?", "<none>")
|
||||||
|
else
|
||||||
|
theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "launch?", "<none>")
|
||||||
|
end
|
||||||
|
theZone.lastDoFlare = trigger.misc.getUserFlag(theZone.doFlare)
|
||||||
|
-- triggerMethod
|
||||||
|
theZone.flareTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
|
||||||
|
if cfxZones.hasProperty(theZone, "flareTriggerMethod") then
|
||||||
|
theZone.flareTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "flareTriggerMethod", "change")
|
||||||
|
end
|
||||||
|
|
||||||
|
theZone.azimuthL, theZone.azimuthH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "direction", 90) -- in degrees
|
||||||
|
-- in DCS documentation, the parameter is incorrectly called 'azimuth'
|
||||||
|
if cfxZones.hasProperty(theZone, "azimuth") then
|
||||||
|
theZone.azimuthL, theZone.azimuthH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "azimuth", 90) -- in degrees
|
||||||
|
end
|
||||||
|
-- theZone.azimuth = theZone.azimuth * 0.0174533 -- rads
|
||||||
|
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "altitude", 1)
|
||||||
|
if cfxZones.hasProperty(theZone, "alt") then
|
||||||
|
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "alt", 1)
|
||||||
|
elseif cfxZones.hasProperty(theZone, "flareAlt") then
|
||||||
|
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "flareAlt", 1)
|
||||||
|
elseif cfxZones.hasProperty(theZone, "agl") then
|
||||||
|
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "agl", 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
theZone.salvoSizeL, theZone.salvoSizeH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "salvo", 1)
|
||||||
|
|
||||||
|
theZone.salvoDurationL, theZone.salvoDurationH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "duration", 1)
|
||||||
|
|
||||||
|
if theZone.verbose or flareZone.verbose then
|
||||||
|
trigger.action.outText("+++flrZ: new flare <" .. theZone.name .. ">, color (" .. theZone.flareColor .. ")", 30)
|
||||||
|
end
|
||||||
|
table.insert(flareZone.flares, theZone)
|
||||||
|
end
|
||||||
|
|
||||||
|
function flareZone.launch(theZone)
|
||||||
|
local color = theZone.flareColor
|
||||||
|
if color < 0 then color = math.random(4) - 1 end
|
||||||
|
if flareZone.verbose or theZone.verbose then
|
||||||
|
trigger.action.outText("+++flrZ: launching <" .. theZone.name .. ">, c = " .. color .. " (" .. dcsCommon.flareColor2Text(color) .. ")", 30)
|
||||||
|
end
|
||||||
|
local loc = cfxZones.getPoint(theZone, true) -- with height
|
||||||
|
loc.y = loc.y + theZone.flareAlt
|
||||||
|
-- calculate azimuth
|
||||||
|
local azimuth = cfxZones.randomInRange(theZone.azimuthL, theZone.azimuthH) * 0.0174533 -- in rads
|
||||||
|
trigger.action.signalFlare(loc, color, azimuth)
|
||||||
|
end
|
||||||
|
|
||||||
|
function flareZone.update()
|
||||||
|
-- call me again in a second
|
||||||
|
timer.scheduleFunction(flareZone.update, {}, timer.getTime() + 1)
|
||||||
|
|
||||||
|
-- launch if flag banged
|
||||||
|
for idx, theZone in pairs(flareZone.flares) do
|
||||||
|
if cfxZones.testZoneFlag(theZone, theZone.doFlare, theZone.flareTriggerMethod, "lastDoFlare") then
|
||||||
|
local salvo = cfxZones.randomInRange(theZone.salvoSizeL, theZone.salvoSizeH)
|
||||||
|
if salvo < 2 then
|
||||||
|
-- one-shot
|
||||||
|
flareZone.launch(theZone)
|
||||||
|
else
|
||||||
|
-- pick a duration from range
|
||||||
|
local duration = cfxZones.randomInRange(theZone.salvoDurationL, theZone.salvoDurationH)
|
||||||
|
local duration = duration / salvo
|
||||||
|
local d = 0
|
||||||
|
for l=1, salvo do
|
||||||
|
timer.scheduleFunction(flareZone.launch, theZone, timer.getTime() + d + 0.1)
|
||||||
|
d = d + duration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function flareZone.start()
|
||||||
|
if not dcsCommon.libCheck("cfx Flare Zones", flareZone.requiredLibs) then return false end
|
||||||
|
|
||||||
|
-- collect all flares
|
||||||
|
local attrZones = cfxZones.getZonesWithAttributeNamed("flare")
|
||||||
|
for k, theZone in pairs(attrZones) do
|
||||||
|
flareZone.addFlareZone(theZone) -- process attribute and add to zone
|
||||||
|
end
|
||||||
|
|
||||||
|
-- start update
|
||||||
|
flareZone.update() -- also starts all unpaused
|
||||||
|
|
||||||
|
-- say hi
|
||||||
|
trigger.action.outText("cfx Flare Zone v" .. flareZone.version .. " started.", 30)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- let's go
|
||||||
|
if not flareZone.start() then
|
||||||
|
trigger.action.outText("cf/x Flare Zones aborted: missing libraries", 30)
|
||||||
|
cfxSmokeZone = nil
|
||||||
|
end
|
||||||
158
modules/playerZone.lua
Normal file
158
modules/playerZone.lua
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
playerZone = {}
|
||||||
|
playerZone.version = "1.0.0"
|
||||||
|
playerZone.requiredLibs = {
|
||||||
|
"dcsCommon", -- always
|
||||||
|
"cfxZones", -- Zones, of course
|
||||||
|
}
|
||||||
|
playerZone.playerZones = {}
|
||||||
|
--[[--
|
||||||
|
Version History
|
||||||
|
1.0.0 - Initial version
|
||||||
|
|
||||||
|
--]]--
|
||||||
|
|
||||||
|
function playerZone.createPlayerZone(theZone)
|
||||||
|
-- start val - a range
|
||||||
|
theZone.pzCoalition = cfxZones.getCoalitionFromZoneProperty(theZone, "playerZone", 0)
|
||||||
|
|
||||||
|
|
||||||
|
-- Method for outputs
|
||||||
|
theZone.pzMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "inc")
|
||||||
|
if cfxZones.hasProperty(theZone, "pzMethod") then
|
||||||
|
theZone.pzMethod = cfxZones.getStringFromZoneProperty(theZone, "pwMethod", "inc")
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfxZones.hasProperty(theZone, "pNum") then
|
||||||
|
theZone.pNum = cfxZones.getStringFromZoneProperty(theZone, "pNum", "none")
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfxZones.hasProperty(theZone, "added!") then
|
||||||
|
theZone.pAdd = cfxZones.getStringFromZoneProperty(theZone, "added!", "none")
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfxZones.hasProperty(theZone, "gone!") then
|
||||||
|
theZone.pRemove = cfxZones.getStringFromZoneProperty(theZone, "gone!", "none")
|
||||||
|
end
|
||||||
|
|
||||||
|
theZone.playersInZone = {} -- indexed by unit name
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function playerZone.collectPlayersForZone(theZone)
|
||||||
|
local factions = {0, 1, 2}
|
||||||
|
local zonePlayers = {}
|
||||||
|
for idx, f in pairs (factions) do
|
||||||
|
if theZone.pzCoalition == 0 or f == theZone.pzCoalition then
|
||||||
|
local allPlayers = coalition.getPlayers(f)
|
||||||
|
for idy, theUnit in pairs (allPlayers) do
|
||||||
|
local loc = theUnit:getPoint()
|
||||||
|
if cfxZones.pointInZone(loc, theZone) then
|
||||||
|
zonePlayers[theUnit:getName()] = theUnit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return zonePlayers
|
||||||
|
end
|
||||||
|
|
||||||
|
function playerZone.processZone(theZone)
|
||||||
|
local nowInZone = playerZone.collectPlayersForZone(theZone)
|
||||||
|
-- find new players in zone
|
||||||
|
local hasNew = false
|
||||||
|
local newCount = 0
|
||||||
|
for name, theUnit in pairs(nowInZone) do
|
||||||
|
if not theZone.playersInZone[name] then
|
||||||
|
-- this unit was not here last time
|
||||||
|
hasNew = true
|
||||||
|
if playerZone.verbose or theZone.verbose then
|
||||||
|
trigger.action.outText("+++pZone: new player unit <" .. name .. "> in zone <" .. theZone.name .. ">", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
newCount = newCount + 1
|
||||||
|
end
|
||||||
|
-- find if players have left the zone
|
||||||
|
local hasGone = false
|
||||||
|
for name, theUnit in pairs(theZone.playersInZone) do
|
||||||
|
if not nowInZone[name] then
|
||||||
|
hasGone = true
|
||||||
|
if playerZone.verbose or theZone.verbose then
|
||||||
|
trigger.action.outText("+++pZone: player unit <" .. name .. "> disappeared from <" .. theZone.name .. ">", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- flag handling and banging
|
||||||
|
if theZone.pNum then
|
||||||
|
cfxZones.setFlagValueMult(theZone.pNum, newCount, theZone)
|
||||||
|
end
|
||||||
|
|
||||||
|
if theZone.pAdd and hasNew then
|
||||||
|
if theZone.verbose or playerZone.verbose then
|
||||||
|
trigger.action.outText("+++pZone: banging <" .. theZone.name .. ">'s 'added!' flags <" .. theZone.pAdd .. ">", 30)
|
||||||
|
end
|
||||||
|
cfxZones.pollFlag(theZone.pAdd, theZone.pzMethod, theZone)
|
||||||
|
end
|
||||||
|
|
||||||
|
if theZone.pRemove and hasGone then
|
||||||
|
if theZone.verbose or playerZone.verbose then
|
||||||
|
trigger.action.outText("+++pZone: banging <" .. theZone.name .. ">'s 'gone' flags <" .. theZone.pRemove .. ">", 30)
|
||||||
|
end
|
||||||
|
cfxZones.pollFlag(theZone.pAdd, theZone.pzMethod, theZone)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Update
|
||||||
|
--
|
||||||
|
function playerZone.update()
|
||||||
|
-- re-invoke in 1 second
|
||||||
|
timer.scheduleFunction(playerZone.update, {}, timer.getTime() + 1)
|
||||||
|
|
||||||
|
-- iterate all zones and check them
|
||||||
|
for idx, theZone in pairs(playerZone.playerZones) do
|
||||||
|
playerZone.processZone(theZone)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Read Config Zone
|
||||||
|
--
|
||||||
|
function playerZone.readConfigZone(theZone)
|
||||||
|
-- currently nothing to do
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Start
|
||||||
|
--
|
||||||
|
function playerZone.start()
|
||||||
|
if not dcsCommon.libCheck("cfx Player Zone",
|
||||||
|
playerZone.requiredLibs)
|
||||||
|
then return false end
|
||||||
|
|
||||||
|
local theZone = cfxZones.getZoneByName("playerZoneConfig")
|
||||||
|
if not theZone then
|
||||||
|
theZone = cfxZones.createSimpleZone("playerZoneConfig")
|
||||||
|
end
|
||||||
|
playerZone.readConfigZone(theZone)
|
||||||
|
|
||||||
|
local pZones = cfxZones.zonesWithProperty("playerZone")
|
||||||
|
for k, aZone in pairs(pZones) do
|
||||||
|
playerZone.createPlayerZone(aZone)
|
||||||
|
playerZone.playerZones[aZone.name] = aZone
|
||||||
|
end
|
||||||
|
|
||||||
|
-- start update cycle
|
||||||
|
playerZone.update()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if not playerZone.start() then
|
||||||
|
trigger.action.outText("+++ aborted playerZone v" .. playerZone.version .. " -- start failed", 30)
|
||||||
|
playerZone = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[--
|
||||||
|
additional features:
|
||||||
|
- filter by type
|
||||||
|
- filter by cat
|
||||||
|
--]]--
|
||||||
61
modules/shallows.lua
Normal file
61
modules/shallows.lua
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
shallows = {}
|
||||||
|
-- script to remove dead naval hulls that failed to sink
|
||||||
|
-- once dead, smoke is put over the hull for 5 minutes
|
||||||
|
-- and if still in game later, the hull is removed
|
||||||
|
|
||||||
|
shallows.version = "1.0.0"
|
||||||
|
shallows.removeAfter = 5 -- minutes after kill event
|
||||||
|
shallows.verbose = false
|
||||||
|
shallows.uuid = 1
|
||||||
|
|
||||||
|
-- uuid
|
||||||
|
function shallows.getUuid()
|
||||||
|
shallows.uuid = shallows.uuid + 1
|
||||||
|
return shallows.uuid
|
||||||
|
end
|
||||||
|
|
||||||
|
-- remove hull
|
||||||
|
function shallows.removeHull(args)
|
||||||
|
if shallows.verbose then
|
||||||
|
trigger.action.outText("enter remove hull for <" .. args.name .. ">", 30)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- remove smoke and whatever's left of ship
|
||||||
|
trigger.action.effectSmokeStop(args.sName)
|
||||||
|
Object.destroy(args.theUnit)
|
||||||
|
if shallows.verbose then
|
||||||
|
trigger.action.outText("Shallows: Removed <" .. args.name .. ">", 30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- watch the world turn and ships get killed
|
||||||
|
function shallows:onEvent(event)
|
||||||
|
if event.id ~= 28 then return end -- only kill events
|
||||||
|
if not event.target then return end
|
||||||
|
-- must be a ship
|
||||||
|
local theUnit = event.target
|
||||||
|
if not theUnit.getGroup or not theUnit:getGroup() then return end
|
||||||
|
local theGroup = theUnit:getGroup()
|
||||||
|
local cat = theGroup:getCategory()
|
||||||
|
if cat ~= 3 then return end -- not a ship
|
||||||
|
|
||||||
|
if shallows.verbose then
|
||||||
|
trigger.action.outText("Shallows: marking <" .. theUnit:getName() .. "> for deep-sixing", 30)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- mark it with smoke and fire
|
||||||
|
local pos = theUnit:getPoint()
|
||||||
|
local sName = theUnit:getName() .. shallows.getUuid()
|
||||||
|
trigger.action.effectSmokeBig(pos, 2, 0.5, sName)
|
||||||
|
|
||||||
|
-- set timer to re-visit later
|
||||||
|
local args = {}
|
||||||
|
args.name = theUnit:getName()
|
||||||
|
args.sName = sName
|
||||||
|
args.theUnit = theUnit
|
||||||
|
timer.scheduleFunction(shallows.removeHull, args, timer.getTime() + shallows.removeAfter * 60)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- start
|
||||||
|
world.addEventHandler(shallows)
|
||||||
|
trigger.action.outText("shallows " .. shallows.version .. " started", 30)
|
||||||
@ -1,5 +1,5 @@
|
|||||||
williePete = {}
|
williePete = {}
|
||||||
williePete.version = "1.0.1"
|
williePete.version = "1.0.2"
|
||||||
williePete.ups = 10 -- we update at 10 fps, so accuracy of a
|
williePete.ups = 10 -- we update at 10 fps, so accuracy of a
|
||||||
-- missile moving at Mach 2 is within 33 meters,
|
-- missile moving at Mach 2 is within 33 meters,
|
||||||
-- with interpolation even at 3 meters
|
-- with interpolation even at 3 meters
|
||||||
@ -13,6 +13,7 @@ williePete.requiredLibs = {
|
|||||||
Version History
|
Version History
|
||||||
1.0.0 - Initial version
|
1.0.0 - Initial version
|
||||||
1.0.1 - update to suppress verbosity
|
1.0.1 - update to suppress verbosity
|
||||||
|
1.0.2 - added Gazelle WP
|
||||||
|
|
||||||
--]]--
|
--]]--
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ williePete.blastedObjects = {} -- used when we detonate something
|
|||||||
|
|
||||||
-- recognizes WP munitions. May require regular update when new
|
-- recognizes WP munitions. May require regular update when new
|
||||||
-- models come out.
|
-- 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"}
|
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"}
|
||||||
|
|
||||||
function williePete.addWillie(theWillie)
|
function williePete.addWillie(theWillie)
|
||||||
table.insert(williePete.willies, theWillie)
|
table.insert(williePete.willies, theWillie)
|
||||||
|
|||||||
BIN
tutorial & demo missions/demo - Effects with a Flare.miz
Normal file
BIN
tutorial & demo missions/demo - Effects with a Flare.miz
Normal file
Binary file not shown.
BIN
tutorial & demo missions/demo - Not too shallow at all.miz
Normal file
BIN
tutorial & demo missions/demo - Not too shallow at all.miz
Normal file
Binary file not shown.
BIN
tutorial & demo missions/demo - Players in the Zone.miz
Normal file
BIN
tutorial & demo missions/demo - Players in the Zone.miz
Normal file
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user