Version 0.99

DML Flags
unGrief
messenger
The Zonal Countdowm
This commit is contained in:
Christian Franz 2022-03-03 17:40:00 +01:00
parent f1aa9cabf1
commit a1f5ca8567
21 changed files with 527 additions and 316 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
rndFlags = {}
rndFlags.version = "1.0.0"
rndFlags.version = "1.1.0"
rndFlags.verbose = false
rndFlags.requiredLibs = {
"dcsCommon", -- always
@ -13,7 +13,15 @@ rndFlags.requiredLibs = {
Version History
1.0.0 - Initial Version
1.1.0 - DML flag conversion:
flagArrayFromString: strings OK, trim
remove pollFlag
pollFlag from cfxZones, include zone
randomBetween for pollSize
pollFlag to bang done with inc
getFlagValue in update
some code clean-up
rndMethod synonym
--]]
rndFlags.rndGen = {}
@ -32,9 +40,9 @@ function rndFlags.flagArrayFromString(inString)
local flags = {}
local rawElements = dcsCommon.splitString(inString, ",")
-- go over all elements
for idx, anElement in pairs(rawElements) do
if dcsCommon.containsString(anElement, "-") then
if dcsCommon.stringStartsWithDigit(anElement) and dcsCommon.containsString(anElement, "-") then
-- interpret this as a range
local theRange = dcsCommon.splitString(anElement, "-")
local lowerBound = theRange[1]
@ -51,7 +59,7 @@ function rndFlags.flagArrayFromString(inString)
-- now add add numbers to flags
for f=lowerBound, upperBound do
table.insert(flags, f)
--trigger.action.outText("+++RND: added <" .. f .. "> (range)", 30)
end
else
-- bounds illegal
@ -59,10 +67,10 @@ function rndFlags.flagArrayFromString(inString)
end
else
-- single number
f = tonumber(anElement)
f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)
if f then
table.insert(flags, f)
--trigger.action.outText("+++RND: added <" .. f .. "> (single)", 30)
else
trigger.action.outText("+++RND: ignored element <" .. anElement .. "> (single)", 30)
end
@ -101,8 +109,16 @@ function rndFlags.createRNDWithZone(theZone)
theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, "f?", "none")
end
if cfxZones.hasProperty(theZone, "in?") then
theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, "in?", "none")
end
if cfxZones.hasProperty(theZone, "rndPoll?") then
theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, "rndPoll?", "none")
end
if theZone.triggerFlag then
theZone.lastTriggerValue = trigger.misc.getUserFlag(theZone.triggerFlag) -- save last value
theZone.lastTriggerValue = cfxZones.getFlagValue(theZone.triggerFlag, theZone) --trigger.misc.getUserFlag(theZone.triggerFlag) -- save last value
end
theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, "onStart", false)
@ -111,7 +127,10 @@ function rndFlags.createRNDWithZone(theZone)
theZone.onStart = true
end
theZone.method = cfxZones.getStringFromZoneProperty(theZone, "method", "on")
theZone.rndMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "on")
if cfxZones.hasProperty(theZone, "rndMethod") then
theZone.rndMethod = cfxZones.getStringFromZoneProperty(theZone, "rndMethod", "on")
end
theZone.reshuffle = cfxZones.getBoolFromZoneProperty(theZone, "reshuffle", false)
if theZone.reshuffle then
@ -119,8 +138,6 @@ function rndFlags.createRNDWithZone(theZone)
theZone.flagStore = dcsCommon.copyArray(theFlags)
end
--theZone.rndPollSize = cfxZones.getBoolFromZoneProperty(theZone, "rndPollSize", false)
-- done flag
if cfxZones.hasProperty(theZone, "done+1") then
theZone.doneFlag = cfxZones.getStringFromZoneProperty(theZone, "done+1", "none")
@ -137,42 +154,6 @@ end
--
-- fire RND
--
function rndFlags.pollFlag(theFlag, method)
if rndFlags.verbose then
trigger.action.outText("+++RND: polling flag " .. theFlag .. " with " .. method, 30)
end
method = method:lower()
local currVal = trigger.misc.getUserFlag(theFlag)
if method == "inc" or method == "f+1" then
trigger.action.setUserFlag(theFlag, currVal + 1)
elseif method == "dec" or method == "f-1" then
trigger.action.setUserFlag(theFlag, currVal - 1)
elseif method == "off" or method == "f=0" then
trigger.action.setUserFlag(theFlag, 0)
elseif method == "flip" or method == "xor" then
if currVal ~= 0 then
trigger.action.setUserFlag(theFlag, 0)
else
trigger.action.setUserFlag(theFlag, 1)
end
else
if method ~= "on" and method ~= "f=1" then
trigger.action.outText("+++RND: unknown method <" .. method .. "> - using 'on'", 30)
end
-- default: on.
trigger.action.setUserFlag(theFlag, 1)
end
local newVal = trigger.misc.getUserFlag(theFlag)
if rndFlags.verbose then
trigger.action.outText("+++RND: flag <" .. theFlag .. "> changed from " .. currVal .. " to " .. newVal, 30)
end
end
function rndFlags.fire(theZone)
-- fire this rnd
@ -181,38 +162,19 @@ function rndFlags.fire(theZone)
rndFlags.reshuffle(theZone)
end
local availableFlags = dcsCommon.copyArray(theZone.myFlags)--{}
-- for idx, aFlag in pairs(theZone.myFlags) do
-- table.insert(availableFlags, aFlag)
-- end
local availableFlags = dcsCommon.copyArray(theZone.myFlags)
-- do this pollSize times
local pollSize = theZone.pollSize
local pollSizeMin = theZone.pollSizeMin
if pollSize ~= pollSizeMin then
-- pick random in range , say 3-7 --> 5 items!
pollSize = (pollSize - pollSizeMin) + 1 -- 7-3 + 1
pollSize = dcsCommon.smallRandom(pollSize) - 1 --> 0-4
-- trigger.action.outText("+++RND: RAW pollsize " .. pollSize, 30)
pollSize = pollSize + pollSizeMin
-- trigger.action.outText("+++RND: adj pollsize " .. pollSize, 30)
if pollSize > theZone.pollSize then pollSize = theZone.pollSize end
if pollSize < 1 then pollSize = 1 end
if rndFlags.verbose then
trigger.action.outText("+++RND: RND " .. theZone.name .. " range " .. pollSizeMin .. "-" .. theZone.pollSize .. ": selected " .. pollSize, 30)
end
end
local pollSize = dcsCommon.randomBetween(theZone.pollSizeMin, theZone.pollSize)
if #availableFlags < 1 then
if rndFlags.verbose then
trigger.action.outText("+++RND: RND " .. theZone.name .. " ran out of flags. aborting fire", 30)
end
if theZone.doneFlag then
local currVal = trigger.misc.getUserFlag(theZone.doneFlag)
trigger.action.setUserFlag(theZone.doneFlag, currVal + 1)
if theZone.doneFlag then
cfxZones.pollFlag(theZone.doneFlag, "inc", theZone)
end
return
@ -239,8 +201,8 @@ function rndFlags.fire(theZone)
-- poll this flag and remove from available
local theFlag = table.remove(availableFlags,theFlagIndex)
rndFlags.pollFlag(theFlag, theZone.method)
--rndFlags.pollFlag(theFlag, theZone.rndMethod)
cfxZones.pollFlag(theFlag, theZone.rndMethod, theZone)
end
-- remove if requested
@ -258,7 +220,7 @@ function rndFlags.update()
for idx, aZone in pairs(rndFlags.rndGen) do
if aZone.triggerFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.triggerFlag)
local currTriggerVal = cfxZones.getFlagValue(aZone.triggerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerFlag)
if currTriggerVal ~= aZone.lastTriggerValue
then
if rndFlags.verbose then
@ -347,6 +309,3 @@ if not rndFlags.start() then
rndFlags = nil
end
--[[
pulser / repeat until
--]]

View File

@ -25,7 +25,9 @@ cfxArtilleryZones.verbose = false
- made compatible with linked zones
- added silent attribute
- added transition time to arty command chatter
2.0.2 - boom?, arty? synonyms
2.0.2 - boom?, arty? synonyms
2.1.0 - DML Flag Support
- code cleanup
Artillery Target Zones *** EXTENDS ZONES ***
Target Zones for artillery. Can determine which zones are in range and visible and then handle artillery barrage to this zone
@ -276,8 +278,7 @@ function cfxArtilleryZones.doFireAt(aZone, maxDistFromCenter)
boomArgs.zone = aZone
local timeVar = 5 * (2 * dcsCommon.randomPercent() - 1.0) -- +/- 1.5 seconds
if timeVar < 0 then timeVar = -timeVar end
-- if transitionTime + timeVar < 0 then timeVar = -timeVar end
--boomArgs.tDelta = timeVar
timer.scheduleFunction(cfxArtilleryZones.doBoom, boomArgs, timer.getTime() + transitionTime + timeVar)
end
@ -286,22 +287,9 @@ function cfxArtilleryZones.doFireAt(aZone, maxDistFromCenter)
end
function cfxArtilleryZones.simFireAtZone(aZone, aGroup, dist)
-- all very simple. We simulate shellNum
-- projectiles impacting in aZone
-- before calling doFire, we calculate accuracy
-- for given dist
if not dist then dist = aZone.spotRange end
--local transitionTime = 20 -- seconds until shells hit
--transitionTime = aZone.transitionTime
--local shellNum = 17
--if aZone.shellNum then shellNum = aZone.shellNum end
--local shellBaseStrength = 500
--if aZone.shellStrength then
local shellBaseStrength = aZone.shellStrength
--local shellVariance = 0.2 -- +/-10%
--shellVariance = aZone.shellVariance
--local center = {x=aZone.point.x, y=aZone.landHeight, z=aZone.point.z} -- center of where shells hit
local maxAccuracy = 100 -- m radius when close
local minAccuracy = 500 -- m radius whan at max sport dist
@ -314,23 +302,7 @@ function cfxArtilleryZones.simFireAtZone(aZone, aGroup, dist)
end
currAccuracy = math.floor(currAccuracy)
cfxArtilleryZones.doFireAt(aZone, currAccuracy)
--[[-- Old code follows
for i=1, shellNum do
local thePoint = dcsCommon.randomPointInCircle(currAccuracy, 0, center.x, center.z)
thePoint.y = land.getHeight({x=thePoint.x, y=thePoint.z})
local boomArgs = {}
local strVar = shellBaseStrength * shellVariance
strVar = strVar * (2 * dcsCommon.randomPercent() - 1.0) -- go from -1 to 1
boomArgs.strength = shellBaseStrength + strVar
thePoint.y = land.getHeight({x = thePoint.x, y = thePoint.z}) + 1 -- elevate to ground height + 1
boomArgs.point = thePoint
local timeVar = 5 * (2 * dcsCommon.randomPercent() - 1.0) -- +/- 1.5 seconds
boomArgs.tDelta = timeVar
timer.scheduleFunction(cfxArtilleryZones.doBoom, boomArgs, timer.getTime() + transitionTime + timeVar)
end
--]]--
aZone.artyCooldownTimer = timer.getTime() + aZone.cooldown -- 120 -- 2 minutes reload
if not aZone.silent then
local addInfo = " with d=" .. dist .. ", var = " .. currAccuracy .. " pB=" .. shellBaseStrength .. " tt=" .. aZone.transitionTime
@ -360,7 +332,6 @@ function cfxArtilleryZones.simSmokeZone(aZone, aGroup, aColor)
local currAccuracy = 200
local thePoint = dcsCommon.randomPointInCircle(currAccuracy, 50, center.x, center.z)
-- thePoint.y = land.getHeight({ x = thePoint.x, y = thePoint.z})
timer.scheduleFunction(cfxArtilleryZones.doSmoke, {thePoint, aColor}, timer.getTime() + transitionTime)
@ -387,7 +358,7 @@ function cfxArtilleryZones.update()
-- iterate all zones to see if a trigger has changed
for idx, aZone in pairs(cfxArtilleryZones.artilleryZones) do
if aZone.artyTriggerFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.artyTriggerFlag)
local currTriggerVal = cfxZones.getFlagValue(aZone.artyTriggerFlag, aZone) -- trigger.misc.getUserFlag(aZone.artyTriggerFlag)
if currTriggerVal ~= aZone.lastTriggerValue
then
-- a triggered release!
@ -438,17 +409,3 @@ if not cfxArtilleryZones.start() then
cfxArtilleryZones = nil
end
--[[--
TODO: link artillery units that are starting fire, stop when all inside is destroyed
TODO: "Free" link: look for closest artillery zone that is not cooling down or engaged with diofferent targets and is in range
DONE: smoke target zon
DONE: add smoke to UI menu
DONE: move doBoom from demon to this module
DONE: trigger on flag
DONE: inflight time for arty projectiles
DONE: invoke callback for firing
TODO: duration param for bombardment
TODO: silent attribute
--]]--

View File

@ -1,5 +1,5 @@
cfxObjectSpawnZones = {}
cfxObjectSpawnZones.version = "1.1.5"
cfxObjectSpawnZones.version = "1.2.0"
cfxObjectSpawnZones.requiredLibs = {
"dcsCommon", -- common is of course needed for everything
-- pretty stupid to check for this since we
@ -24,35 +24,8 @@ cfxObjectSpawnZones.ups = 1
-- 1.1.3 - ME-triggered flag via f? and triggerFlag
-- 1.1.4 - activate?, pause? attributes
-- 1.1.5 - spawn?, spawnObjects? synonyms
-- Object spawn zones have the following major uses:
-- - dynamically spawn cargo
-- - litter a zone with static obejcts quickly
-- - linking static dynamic objects with ships, including cargo
--
--
-- How do we recognize an object spawn zone?
-- contains a "objectSpawner" attribute
-- a spawner must also have the following attributes
-- - objectSpawner - anything, must be present to signal. put in 'ground' to be able to expand to other types
-- - types - type strings, comma separated. They all spawn in the same spot.
-- see here: https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB
-- - count - repeat types n times. optional, defaults to 1
-- - country - defaults to 2 (usa) -- see here https://wiki.hoggitworld.com/view/DCS_enum_country
-- some important: 0 = Russia, 2 = US, 82 = UN neutral
-- country is converted to coalition and then assigned to
-- Joint Task Force <side> upon spawn
-- - baseName - MANDATORY, for naming spawned objects - MUST BE UNIQUE!!!!
-- - heading in DEGREES (default 0 = north ) direction entire group is facing
-- - weight - weight in kg if transportable
-- - isCargo - boolean yes means it can be carried by other units
-- - cooldown - seconds to cool down before re-spawning
-- - maxSpawns - how many times we spawn. default = 1, -1 = unlimited
-- - requestable -- via comms menu, will auto-pause
-- - managed -- if cargo, it's automatically passed to cfx cargo manager for handling (if cargo manager is loaded)
-- - (linkedUnit) for placing on ships
-- - (useOffset) for not using ship's center
-- 1.2.0 - DML flag upgrade
-- respawn currently happens after theSpawns is deleted and cooldown seconds have passed
cfxObjectSpawnZones.allSpawners = {}
cfxObjectSpawnZones.callbacks = {} -- signature: cb(reason, group, spawner)
@ -83,30 +56,31 @@ function cfxObjectSpawnZones.createSpawner(inZone)
-- connect with ME if a trigger flag is given
if cfxZones.hasProperty(inZone, "f?") then
theSpawner.triggerFlag = cfxZones.getStringFromZoneProperty(inZone, "f?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
end
if cfxZones.hasProperty(inZone, "spawn?") then
theSpawner.triggerFlag = cfxZones.getStringFromZoneProperty(inZone, "spawn?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
end
if cfxZones.hasProperty(inZone, "spawnObjects?") then
theSpawner.triggerFlag = cfxZones.getStringFromZoneProperty(inZone, "spawnObjects?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
end
if theSpawner.triggerFlag then
theSpawner.lastTriggerValue = cfxZones.getFlagValue(theSpawner.triggerFlag, theSpawner) -- trigger.misc.getUserFlag(theSpawner.triggerFlag)
end
if cfxZones.hasProperty(inZone, "activate?") then
theSpawner.activateFlag = cfxZones.getStringFromZoneProperty(inZone, "activate?", "none")
theSpawner.lastActivateValue = trigger.misc.getUserFlag(theSpawner.activateFlag)
theSpawner.lastActivateValue = cfxZones.getFlagValue(theSpawner.activateFlag, theSpawner) --trigger.misc.getUserFlag(theSpawner.activateFlag)
end
if cfxZones.hasProperty(inZone, "pause?") then
theSpawner.pauseFlag = cfxZones.getStringFromZoneProperty(inZone, "pause?", "none")
theSpawner.lastPauseValue = trigger.misc.getUserFlag(theSpawner.pauseFlag)
theSpawner.lastPauseValue = cfxZones.getFlagValue(theSpawner.lastPauseValue, theSpawner) -- trigger.misc.getUserFlag(theSpawner.pauseFlag)
end
--theSpawner.types = cfxZones.getZoneProperty(inZone, "types")
theSpawner.types = cfxZones.getStringFromZoneProperty(inZone, "types", "White_Tyre")
local n = cfxZones.getNumberFromZoneProperty(inZone, "count", 1) -- DO NOT CONFUSE WITH OWN PROPERTY COUNT for unique names!!!
if n < 1 then n = 1 end -- sanity check.
@ -140,13 +114,11 @@ function cfxObjectSpawnZones.createSpawner(inZone)
theSpawner.requestable = cfxZones.getBoolFromZoneProperty(inZone, "requestable", false)
if theSpawner.requestable then theSpawner.paused = true end
-- see if it is linked to a ship to set realtive orig headiong
if inZone.linkedUnit then
local shipUnit = inZone.linkedUnit
theSpawner.linkedUnit = shipUnit
--trigger.action.outText("+++obSpZ: zone " .. inZone.name .. " linked to ship (?) " .. shipUnit:getName() .. " of cat " .. shipUnit:getCategory(), 30)
local origHeading = dcsCommon.getUnitHeadingDegrees(shipUnit)
@ -155,10 +127,7 @@ function cfxObjectSpawnZones.createSpawner(inZone)
theSpawner.dx = delta.x
theSpawner.dy = delta.z
--theSpawner.dx = inZone.dx
--theSpawner.dy = inZone.dy
theSpawner.origHeading = origHeading
--trigger.action.outText("+++obSpZ: with dx = " .. theSpawner.dx .. " dy = " .. theSpawner.dy .. " hdg = " .. origHeading, 30)
end
return theSpawner
end
@ -198,18 +167,8 @@ function cfxObjectSpawnZones.getRequestableSpawnersInRange(aPoint, aRange, aSide
local delta = dcsCommon.dist(aPoint, cfxZones.getPoint(aZone))
if delta>aRange then hasMatch = false end
if aSide ~= 0 then
--[[--
-- check if side is correct for owned zone
--]]--
end
--[[--
if aSide ~= aSpawner.rawOwner then
-- only return spawners with this side
-- note: this will NOT work with neutral players
hasMatch = false
end
--]]--
if not aSpawner.requestable then
hasMatch = false
@ -228,10 +187,6 @@ end
--
function cfxObjectSpawnZones.verifySpawnOwnership(spawner)
--[[--
-- returns false ONLY if masterSpawn disagrees
--]]--
return true
end
@ -433,7 +388,7 @@ function cfxObjectSpawnZones.update()
local needsSpawn = cfxObjectSpawnZones.needsSpawning(spawner)
-- check if perhaps our watchtrigger causes spawn
if spawner.pauseFlag then
local currTriggerVal = trigger.misc.getUserFlag(spawner.pauseFlag)
local currTriggerVal = cfxZones.getFlagValue(spawner.pauseFlag, spawner)-- trigger.misc.getUserFlag(spawner.pauseFlag)
if currTriggerVal ~= spawner.lastPauseValue then
spawner.paused = true
needsSpawn = false
@ -442,7 +397,7 @@ function cfxObjectSpawnZones.update()
end
if spawner.triggerFlag then
local currTriggerVal = trigger.misc.getUserFlag(spawner.triggerFlag)
local currTriggerVal = cfxZones.getFlagValue(spawner.triggerFlag, spawner)-- trigger.misc.getUserFlag(spawner.triggerFlag)
if currTriggerVal ~= spawner.lastTriggerValue then
needsSpawn = true
spawner.lastTriggerValue = currTriggerVal
@ -450,7 +405,7 @@ function cfxObjectSpawnZones.update()
end
if spawner.activateFlag then
local currTriggerVal = trigger.misc.getUserFlag(spawner.activateFlag)
local currTriggerVal = spawner.getFlagValue(spawner.activateFlag, spawner) -- trigger.misc.getUserFlag(spawner.activateFlag)
if currTriggerVal ~= spawner.lastActivateValue then
spawner.paused = false
spawner.lastActivateValue = currTriggerVal
@ -517,7 +472,3 @@ if not cfxObjectSpawnZones.start() then
cfxObjectSpawnZones = nil
end
--[[--
IMPROVEMENTS
'formations' - concentric, pile, random, array etc.
--]]--

View File

@ -1,5 +1,5 @@
cfxPlayerScore = {}
cfxPlayerScore.version = "1.2.0"
cfxPlayerScore.version = "1.3.0"
cfxPlayerScore.badSound = "Death BRASS.wav"
cfxPlayerScore.scoreSound = "Quest Snare 3.wav"
cfxPlayerScore.announcer = true
@ -16,6 +16,13 @@ cfxPlayerScore.announcer = true
- announcer attribute
- badSound name
- scoreSound name
1.3.0 - object2score
- static objects also can score
- can now also score members of group by adding group name
- scenery objects are now supported. use the
number that is given under OBJECT ID when
using assign as...
--]]--
cfxPlayerScore.requiredLibs = {
@ -54,16 +61,46 @@ function cfxPlayerScore.cat2BaseScore(inCat)
return 1
end
function cfxPlayerScore.object2score(inVictim) -- does not have group
if not inVictim then return end
local inName = inVictim:getName()
if not inName then return 0 end
if type(inName) == "number" then
inName = tostring(inName)
end
local objectScore = cfxPlayerScore.typeScore[inName]
if not objectScore then
-- try the type desc
local theType = inVictim:getTypeName()
objectScore = cfxPlayerScore.typeScore[theType]
end
if type(objectScore) == "string" then
objectScore = tonumber(objectScore)
end
if not objectScore then return 0 end
return objectScore
end
function cfxPlayerScore.unit2score(inUnit)
local vicGroup = inUnit:getGroup()
local vicCat = vicGroup:getCategory()
local vicType = inUnit:getTypeName()
local vicName = inUnit:getName()
if type(vicName) == "number" then vicName = tostring(vicName) end
-- simply extend by adding items to the typescore table.concat
-- we first try by unit name. This allows individual
-- named hi-value targets to have individual scores
local uScore = cfxPlayerScore.typeScore[vicName]
-- see if all members of group score
if not uScore then
local grpName = vicGroup:getName()
uScore = cfxPlayerScore.typeScore[grpName]
end
if uScore == nil then
-- WE NOW TRY TO ACCESS BY VICTIM'S TYPE STRING
uScore = cfxPlayerScore.typeScore[vicType]
@ -155,6 +192,14 @@ function cfxPlayerScore.isNamedUnit(theUnit)
end
return false
end
function cfxPlayerScore.awardScoreTo(killSide, theScore, killerName)
local playerScore = cfxPlayerScore.updateScoreForPlayer(killerName, theScore)
if cfxPlayerScore.announcer then
trigger.action.outTextForCoalition(killSide, "Killscore: " .. theScore .. " for a total of " .. playerScore .. " for " .. killerName, 30)
end
end
--
-- EVENT HANDLING
--
@ -167,22 +212,18 @@ function cfxPlayerScore.preProcessor(theEvent)
-- there is an initiator, and the initiator is
-- a player
if theEvent.initiator == nil then
-- trigger.action.outText("+++scr pre: nil INITIATOR", 30)
return false
end
--trigger.action.outText("+++scr pre: initiator is " .. theEvent.initiator:getName(), 30)
local killer = theEvent.initiator
if theEvent.target == nil then
if cfxPlayerScore.verbose then trigger.action.outText("+++scr pre: nil TARGET", 30) end
if cfxPlayerScore.verbose then
trigger.action.outText("+++scr pre: nil TARGET", 30)
end
return false
end
local wasPlayer = cfxPlayer.isPlayerUnit(killer)
if wasPlayer then
else
end
return wasPlayer
end
return false
@ -196,6 +237,7 @@ function cfxPlayerScore.killDetected(theEvent)
-- we are only getting called when and if
-- a kill occured and killer was a player
-- and target exists
local killer = theEvent.initiator
local killerName = killer:getPlayerName()
if not killerName then killerName = "<nil>" end
@ -207,12 +249,19 @@ function cfxPlayerScore.killDetected(theEvent)
-- was it a player kill?
local pk = cfxPlayer.isPlayerUnit(victim)
-- was it a scenery object
-- was it a scenery object?
local wasBuilding = dcsCommon.isSceneryObject(victim)
if wasBuilding then
-- these objects have no coalition; we simply award the score if
-- it exists in look-up table.
local staticScore = cfxPlayerScore.object2score(victim)
if staticScore > 0 then
trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.scoreSound)
cfxPlayerScore.awardScoreTo(killSide, staticScore, killerName)
end
return
end
-- was it fraternicide?
local vicSide = victim:getCoalition()
local fraternicide = killSide == vicSide
@ -221,8 +270,26 @@ function cfxPlayerScore.killDetected(theEvent)
-- see what kind of unit (category) we killed
-- and look up base score
if not victim.getGroup then
if cfxPlayerScore.verbose then trigger.action.outText("+++scr: no group for " .. killVehicle .. ", killed by " .. killerName .. ", no score", 30) end
if not victim.getGroup then
-- static objects have no group
local staticName = victim:getName() -- on statics, this returns
-- name as entered in TOP LINE
local staticScore = cfxPlayerScore.object2score(victim)
if staticScore > 0 then
-- this was a named static, return the score - unless our own
if fraternicide then
scoreMod = -2 * scoreMod
trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.badSound)
else
trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.scoreSound)
end
staticScore = scoreMod * staticScore
cfxPlayerScore.awardScoreTo(killSide, staticScore, killerName)
else
-- no score, no mentions
end
return
end
@ -276,13 +343,8 @@ function cfxPlayerScore.killDetected(theEvent)
end
local totalScore = unitScore * scoreMod
local playerScore = cfxPlayerScore.updateScoreForPlayer(killerName, totalScore)
if cfxPlayerScore.announcer then
trigger.action.outTextForCoalition(killSide, "Killscore: " .. totalScore .. " for a total of " .. playerScore .. " for " .. killerName, 30)
end
--trigger.action.outTextForCoalition(killSide, cfxPlayerScore.scoreTextForPlayerNamed(killerName), 30)
cfxPlayerScore.awardScoreTo(killSide, totalScore, killerName)
end
function cfxPlayerScore.readConfigZone(theZone)

View File

@ -13,7 +13,7 @@ cfxSmokeZone.requiredLibs = {
- added f? attribute --> onFlag
- broke out startSmoke
1.0.4 - startSmoke? synonym
- alphanum flag upgrade
- alphanum DML flag upgrade
- random color support
SMOKE ZONES *** EXTENDS ZONES ***

View File

@ -6,7 +6,7 @@
--
cfxZones = {}
cfxZones.version = "2.5.6"
cfxZones.version = "2.5.7"
--[[-- VERSION HISTORY
- 2.2.4 - getCoalitionFromZoneProperty
- getStringFromZoneProperty
@ -50,10 +50,11 @@ cfxZones.version = "2.5.6"
- extractPropertyFromDCS trims key and property
- 2.5.5 - pollFlag() centralized for banging
- allStaticsInZone
- 2.5.6 - flag accessor setFlagValue(), getFlagValue
- 2.5.6 - flag accessor setFlagValue(), getFlagValue()
- pollFlag supports theZone as final parameter
- randomDelayFromPositiveRange
- isMEFlag
- 2.5.7 - pollFlag supports dml flags
--]]--
cfxZones.verbose = false
@ -1064,22 +1065,33 @@ function cfxZones.pollFlag(theFlag, method, theZone)
trigger.action.outText("+++zones: polling flag " .. theFlag .. " with " .. method, 30)
end
if not theZone then
trigger.action.outText("+++zones: nil theZone on pollFlag", 30)
end
method = method:lower()
local currVal = trigger.misc.getUserFlag(theFlag)
--trigger.action.outText("+++zones: polling " .. theZone.name .. " method " .. method .. " flag " .. theFlag, 30)
local currVal = cfxZones.getFlagValue(theFlag, theZone)
if method == "inc" or method == "f+1" then
trigger.action.setUserFlag(theFlag, currVal + 1)
--trigger.action.setUserFlag(theFlag, currVal + 1)
cfxZones.setFlagValue(theFlag, currVal+1, theZone)
elseif method == "dec" or method == "f-1" then
trigger.action.setUserFlag(theFlag, currVal - 1)
-- trigger.action.setUserFlag(theFlag, currVal - 1)
cfxZones.setFlagValue(theFlag, currVal-1, theZone)
elseif method == "off" or method == "f=0" then
trigger.action.setUserFlag(theFlag, 0)
-- trigger.action.setUserFlag(theFlag, 0)
cfxZones.setFlagValue(theFlag, 0, theZone)
elseif method == "flip" or method == "xor" then
if currVal ~= 0 then
trigger.action.setUserFlag(theFlag, 0)
-- trigger.action.setUserFlag(theFlag, 0)
cfxZones.setFlagValue(theFlag, 0, theZone)
else
trigger.action.setUserFlag(theFlag, 1)
--trigger.action.setUserFlag(theFlag, 1)
cfxZones.setFlagValue(theFlag, 1, theZone)
end
else
@ -1087,11 +1099,13 @@ function cfxZones.pollFlag(theFlag, method, theZone)
trigger.action.outText("+++zones: unknown method <" .. method .. "> - using 'on'", 30)
end
-- default: on.
trigger.action.setUserFlag(theFlag, 1)
-- trigger.action.setUserFlag(theFlag, 1)
cfxZones.setFlagValue(theFlag, 1, theZone)
end
local newVal = trigger.misc.getUserFlag(theFlag)
if cfxZones.verbose then
local newVal = cfxZones.getFlagValue(theFlag, theZone)
trigger.action.outText("+++zones: flag <" .. theFlag .. "> changed from " .. currVal .. " to " .. newVal, 30)
end
end
@ -1120,7 +1134,7 @@ function cfxZones.setFlagValue(theFlag, theValue, theZone)
-- now do wildcard processing. we have alphanumeric
if dcsCommon.stringStartsWith(theFlag, "*") then
theFlag = zoneName .. theFlag
theFlag = zoneName .. theFlag
end
trigger.action.setUserFlag(theFlag, theValue)
end
@ -1128,7 +1142,7 @@ end
function cfxZones.getFlagValue(theFlag, theZone)
local zoneName = "<dummy>"
if not theZone then
trigger.action.outText("+++Zne: no zone on getFlagValue")
trigger.action.outText("+++Zne: no zone on getFlagValue", 30)
else
zoneName = theZone.name -- for flag wildcards
end

View File

@ -1,5 +1,5 @@
cloneZones = {}
cloneZones.version = "1.2.0"
cloneZones.version = "1.3.0"
cloneZones.verbose = false
cloneZones.requiredLibs = {
"dcsCommon", -- always
@ -31,6 +31,7 @@ cloneZones.uniqueCounter = 9200000 -- we start group numbering here
- linkUnit resolve
- clone? synonym
- empty! and method attributes
1.3.0 - DML flag upgrade
--]]--
@ -179,46 +180,54 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
end
end
-- f? and spawn? map to the same
-- f? and spawn? and other synonyms map to the same
if cfxZones.hasProperty(theZone, "f?") then
theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, "f?", "none")
theZone.lastSpawnValue = trigger.misc.getUserFlag(theZone.spawnFlag) -- save last value
end
if cfxZones.hasProperty(theZone, "in?") then
theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, "in?", "none")
theZone.lastSpawnValue = trigger.misc.getUserFlag(theZone.spawnFlag) -- save last value
end
if cfxZones.hasProperty(theZone, "spawn?") then
theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, "spawn?", "none")
theZone.lastSpawnValue = trigger.misc.getUserFlag(theZone.spawnFlag) -- save last value
end
-- synonyms
if cfxZones.hasProperty(theZone, "clone?") then
theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, "clone?", "none")
theZone.lastSpawnValue = trigger.misc.getUserFlag(theZone.spawnFlag) -- save last value
end
if theZone.spawnFlag then
theZone.lastSpawnValue = cfxZones.getFlagValue(theZone.spawnFlag, theZone)
end
-- deSpawn?
if cfxZones.hasProperty(theZone, "deSpawn?") then
theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, "deSpawn?", "none")
theZone.lastDeSpawnValue = trigger.misc.getUserFlag(theZone.deSpawnFlag) -- save last value
end
if cfxZones.hasProperty(theZone, "deClone?") then
theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, "deClone?", "none")
end
if theZone.deSpawnFlag then
theZone.lastDeSpawnValue = cfxZones.getFlagValue(theZone.deSpawnFlag, theZone)
end
-- to be deprecated
theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, "onStart", false)
theZone.moveRoute = cfxZones.getBoolFromZoneProperty(theZone, "moveRoute", false)
theZone.preWipe = cfxZones.getBoolFromZoneProperty(theZone, "preWipe", false)
-- to be deprecated
if cfxZones.hasProperty(theZone, "empty+1") then
theZone.emptyFlag = cfxZones.getNumberFromZoneProperty(theZone, "empty+1", "<None>") -- note string on number default
theZone.emptyFlag = cfxZones.getStringFromZoneProperty(theZone, "empty+1", "<None>") -- note string on number default
end
if cfxZones.hasProperty(theZone, "empty!") then
theZone.emptyBangFlag = cfxZones.getNumberFromZoneProperty(theZone, "empty!", "<None>") -- note string on number default
theZone.emptyBangFlag = cfxZones.getStringFromZoneProperty(theZone, "empty!", "<None>") -- note string on number default
end
theZone.method = cfxZones.getStringFromZoneProperty(theZone, "method", "inc")
@ -804,11 +813,13 @@ function cloneZones.hasLiveUnits(theZone)
end
-- old code, deprecated
--[[--
function cloneZones.pollFlag(flagNum, method)
-- we currently ignore method
local num = trigger.misc.getUserFlag(flagNum)
trigger.action.setUserFlag(flagNum, num+1)
end
--]]--
--
-- UPDATE
--
@ -818,7 +829,7 @@ function cloneZones.update()
for idx, aZone in pairs(cloneZones.cloners) do
-- see if deSpawn was pulled. Must run before spawn
if aZone.deSpawnFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.deSpawnFlag)
local currTriggerVal = cfxZones.getFlagValue(aZone.deSpawnFlag, aZone) -- trigger.misc.getUserFlag(aZone.deSpawnFlag)
if currTriggerVal ~= aZone.lastDeSpawnValue then
if cloneZones.verbose then
trigger.action.outText("+++clnZ: DEspawn triggered for <" .. aZone.name .. ">", 30)
@ -830,7 +841,7 @@ function cloneZones.update()
-- see if we got spawn? command
if aZone.spawnFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.spawnFlag)
local currTriggerVal = cfxZones.getFlagValue(aZone.spawnFlag, aZone) -- trigger.misc.getUserFlag(aZone.spawnFlag)
if currTriggerVal ~= aZone.lastSpawnValue
then
if cloneZones.verbose then
@ -846,11 +857,15 @@ function cloneZones.update()
if isEmpty then
-- see if we need to bang a flag
if aZone.emptyFlag then
cloneZones.pollFlag(aZone.emptyFlag)
--cloneZones.pollFlag(aZone.emptyFlag)
cfxZones.pollFlag(aZone.emptyFlag, 'inc', aZone)
end
if aZone.emptyBangFlag then
cfxZones.pollFlag(aZone.emptyBangFlag, aZone.method)
cfxZones.pollFlag(aZone.emptyBangFlag, aZone.method, aZone)
if cloneZones.verbose then
trigger.action.outText("+++clnZ: bang! on " .. aZone.emptyBangFlag, 30)
end
end
-- invoke callbacks
cloneZones.invokeCallbacks(aZone, "empty", {})

View File

@ -1,6 +1,7 @@
countDown = {}
countDown.version = "1.1.0"
countDown.version = "1.2.0"
countDown.verbose = true
countDown.ups = 1
countDown.requiredLibs = {
"dcsCommon", -- always
"cfxZones", -- Zones, of course
@ -16,6 +17,9 @@ countDown.requiredLibs = {
- corrected verbose (erroneously always suppressed)
- triggerFlag --> triggerCountFlag
1.1.1 - corrected bug in invokeCallback
1.2.0 - DML Flags
- counterOut!
- ups config
--]]--
@ -85,33 +89,37 @@ function countDown.createCountDownWithZone(theZone)
-- trigger flag "count" / "start?"
if cfxZones.hasProperty(theZone, "count?") then
theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, "count?", "none")
theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, "count?", "<none>")
end
-- can also use in? for counting. we always use triggerCountFlag
if cfxZones.hasProperty(theZone, "in?") then
theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, "in?", "none")
theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, "in?", "<none>")
end
if theZone.triggerCountFlag then
theZone.lastCountTriggerValue = trigger.misc.getUserFlag(theZone.triggerCountFlag) -- save last value
theZone.lastCountTriggerValue = cfxZones.getFlagValue(theZone.triggerCountFlag, theZone) -- trigger.misc.getUserFlag(theZone.triggerCountFlag) -- save last value
end
-- zero! bang
if cfxZones.hasProperty(theZone, "zero!") then
theZone.zeroFlag = cfxZones.getNumberFromZoneProperty(theZone, "zero!", -1)
theZone.zeroFlag = cfxZones.getStringFromZoneProperty(theZone, "zero!", "<none>")
end
if cfxZones.hasProperty(theZone, "out!") then
theZone.zeroFlag = cfxZones.getNumberFromZoneProperty(theZone, "out!", -1)
theZone.zeroFlag = cfxZones.getStringFromZoneProperty(theZone, "out!", "<none>")
end
-- TMinus! bang
if cfxZones.hasProperty(theZone, "tMinus!") then
theZone.tMinusFlag = cfxZones.getNumberFromZoneProperty(theZone, "tMinus!", -1)
theZone.tMinusFlag = cfxZones.getStringFromZoneProperty(theZone, "tMinus!", "<none>")
end
-- counterOut val
if cfxZones.hasProperty(theZone, "counterOut!") then
theZone.counterOut = cfxZones.getStringFromZoneProperty(theZone, "counterOut!", "<none>")
end
end
--
@ -128,6 +136,10 @@ function countDown.isTriggered(theZone)
local belowZero = false
local looping = false
if theZone.counterOut then
cfxZones.setFlagValue(theZone.counterOut, val, theZone)
end
if val > 0 then
tMinus = true
-- see if we need to bang Tminus
@ -135,7 +147,7 @@ function countDown.isTriggered(theZone)
if countDown.verbose then
trigger.action.outText("+++cntD: TMINUTS", 30)
end
cfxZones.pollFlag(theZone.tMinusFlag, theZone.method)
cfxZones.pollFlag(theZone.tMinusFlag, theZone.method, theZone)
end
elseif val == 0 then
@ -145,7 +157,7 @@ function countDown.isTriggered(theZone)
if countDown.verbose then
trigger.action.outText("+++cntD: ZERO", 30)
end
cfxZones.pollFlag(theZone.zeroFlag, theZone.method)
cfxZones.pollFlag(theZone.zeroFlag, theZone.method, theZone)
end
if theZone.loop then
@ -164,7 +176,7 @@ function countDown.isTriggered(theZone)
if countDown.verbose then
trigger.action.outText("+++cntD: Below Zero", 30)
end
cfxZones.pollFlag(theZone.zeroFlag, theZone.method)
cfxZones.pollFlag(theZone.zeroFlag, theZone.method, theZone)
end
end
@ -178,20 +190,20 @@ function countDown.isTriggered(theZone)
end
function countDown.update()
-- call me in a second to poll triggers
timer.scheduleFunction(countDown.update, {}, timer.getTime() + 1)
-- call me in a second/ups to poll triggers
timer.scheduleFunction(countDown.update, {}, timer.getTime() + 1/countDown.ups)
for idx, aZone in pairs(countDown.counters) do
-- make sure to re-start before reading time limit
if aZone.triggerCountFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.triggerCountFlag)
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 = trigger.misc.getUserFlag(aZone.triggerCountFlag) -- save last value
aZone.lastCountTriggerValue = cfxZones.getFlagValue(aZone.triggerCountFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerCountFlag) -- save last value
end
end
end
@ -209,6 +221,11 @@ function countDown.readConfigZone()
return
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)
if countDown.verbose then

View File

@ -1,5 +1,5 @@
delayFlag = {}
delayFlag.version = "1.0.4"
delayFlag.version = "1.1.0"
delayFlag.verbose = false
delayFlag.requiredLibs = {
"dcsCommon", -- always
@ -23,6 +23,11 @@ delayFlag.flags = {}
- removed message attribute, moved to own module
- triggerFlag --> triggerDelayFlag
1.0.4 - startDelay
1.1.0 - DML flag upgrade
- removed onStart. use local raiseFlag instead
- delayDone! synonym
- pauseDelay?
- unpauseDelay?
--]]--
@ -69,7 +74,7 @@ function delayFlag.createTimerWithZone(theZone)
end
if theZone.triggerDelayFlag then
theZone.lastDelayTriggerValue = trigger.misc.getUserFlag(theZone.triggerDelayFlag) -- save last value
theZone.lastDelayTriggerValue = cfxZones.getFlagValue(theZone.triggerDelayFlag, theZone) -- trigger.misc.getUserFlag(theZone.triggerDelayFlag) -- save last value
end
@ -77,17 +82,24 @@ function delayFlag.createTimerWithZone(theZone)
-- out flag
if cfxZones.hasProperty(theZone, "out!") then
theZone.outFlag = cfxZones.getNumberFromZoneProperty(theZone, "out!", -1)
theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "out!", -1)
end
-- on start
if cfxZones.hasProperty(theZone, "onStart") then
theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, "onStart", false)
if cfxZones.hasProperty(theZone, "delayDone!") then
theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "delayDone!", -1)
end
-- stop the press!
if cfxZones.hasProperty(theZone, "stopDelay?") then
theZone.triggerStopDelay = cfxZones.getStringFromZoneProperty(theZone, "stopDelay?", "none")
theZone.lastTriggerStopValue = cfxZones.getFlagValue(theZone.triggerStopDelay, theZone)
end
-- init
theZone.running = false
theZone.delayRunning = false
theZone.timeLimit = -1
end
@ -99,7 +111,7 @@ end
function delayFlag.startDelay(theZone)
-- refresh timer
theZone.running = true
theZone.delayRunning = true
-- set new expiry date
local delayMax = theZone.delayMax
@ -129,13 +141,24 @@ function delayFlag.update()
local now = timer.getTime()
for idx, aZone in pairs(delayFlag.flags) do
-- see if we need to stop
if aZone.triggerStopDelay then
local currTriggerVal = cfxZones.getFlagValue(aZone.triggerStopDelay, aZone)
if currTriggerVal ~= lastTriggerStopValue then
aZone.delayRunning = false -- simply stop.
if delayFlag.verbose then
trigger.action.outText("+++dlyF: stopped delay " .. aZone.name, 30)
end
end
end
-- make sure to re-start before reading time limit
if aZone.triggerDelayFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.triggerDelayFlag)
local currTriggerVal = cfxZones.getFlagValue(aZone.triggerDelayFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerDelayFlag)
if currTriggerVal ~= aZone.lastDelayTriggerValue
then
if delayFlag.verbose then
if aZone.running then
if aZone.delayRunning then
trigger.action.outText("+++dlyF: re-starting timer " .. aZone.name, 30)
else
trigger.action.outText("+++dlyF: init timer for " .. aZone.name, 30)
@ -146,17 +169,16 @@ function delayFlag.update()
end
end
if aZone.running then
if aZone.delayRunning then
-- check expiry
if now > aZone.timeLimit then
-- end timer
aZone.running = false
aZone.delayRunning = false
-- poll flag
cfxZones.pollFlag(aZone.outFlag, aZone.method)
-- say message
--if aZone.myMessage then
-- trigger.action.outText(aZone.myMessage, 30)
--end
cfxZones.pollFlag(aZone.delayDoneFlag, aZone.method, aZone)
if delayFlag.verbose then
trigger.action.outText("+++dlyF: banging on " .. aZone.delayDoneFlag, 30)
end
end
end
@ -167,7 +189,7 @@ end
-- START
--
function delayFlag.readConfigZone()
local theZone = cfxZones.getZoneByName("delayZonesConfig")
local theZone = cfxZones.getZoneByName("delayFlagsConfig")
if not theZone then
if delayFlag.verbose then
trigger.action.outText("+++dlyF: NO config zone!", 30)
@ -182,6 +204,7 @@ function delayFlag.readConfigZone()
end
end
--[[--
function delayFlag.onStart()
for idx, theZone in pairs(delayFlag.flags) do
if theZone.onStart then
@ -192,6 +215,7 @@ function delayFlag.onStart()
end
end
end
--]]--
function delayFlag.start()
-- lib check
@ -215,7 +239,7 @@ function delayFlag.start()
end
-- kick onStart
delayFlag.onStart()
--delayFlag.onStart()
-- start update
delayFlag.update()

View File

@ -1,5 +1,5 @@
messenger = {}
messenger.version = "1.0.1"
messenger.version = "1.1.0"
messenger.verbose = false
messenger.requiredLibs = {
"dcsCommon", -- always
@ -11,6 +11,10 @@ messenger.messengers = {}
1.0.0 - initial version
1.0.1 - messageOut? synonym
- spelling types in about
1.1.0 - DML flag support
- clearScreen option
- inValue?
- message preprocessor
--]]--
@ -41,11 +45,13 @@ function messenger.createMessengerDownWithZone(theZone)
theZone.soundFile = cfxZones.getStringFromZoneProperty(theZone, "soundFile", "<none>")
theZone.clearScreen = cfxZones.getBoolFromZoneProperty(theZone, "clearScreen", false)
-- alternate version: messages: list of messages, need string parser first
theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, "duration", 30)
-- trigger flag "count" / "start?"
-- trigger flag f? in? messageOut?
if cfxZones.hasProperty(theZone, "f?") then
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "f?", "none")
end
@ -60,31 +66,57 @@ function messenger.createMessengerDownWithZone(theZone)
end
if theZone.triggerMessagerFlag then
theZone.lastMessageTriggerValue = trigger.misc.getUserFlag(theZone.triggerMessagerFlag) -- save last value
theZone.lastMessageTriggerValue = cfxZones.getFlagValue(theZone.triggerMessagerFlag, theZone)-- trigger.misc.getUserFlag(theZone.triggerMessagerFlag) -- save last value
end
if cfxZones.hasProperty(theZone, "coalition") then
theZone.coalition = cfxZones.getCoalitionFromZoneProperty(theZone, "coalition", 0)
end
-- flag whose value can be read
if cfxZones.hasProperty(theZone, "messageValue?") then
theZone.messageValue = cfxZones.getStringFromZoneProperty(theZone, "messageValue?", "<none>")
end
end
--
-- Update
--
function messenger.getMessage(theZone)
local msg = theZone.message
-- see if it has a "$val" in there
local zName = theZone.name
if not zName then zName = "<strange!>" end
local zVal = "<n/a>"
if theZone.messageValue then
zVal = cfxZones.getFlagValue(theZone.messageValue, theZone)
zVal = tostring(zVal)
if not zVal then zVal = "<err>" end
end
-- replace *zone and *value wildcards
msg = string.gsub(msg, "*name", zName)
msg = string.gsub(msg, "*value", zVal)
return msg
end
function messenger.isTriggered(theZone)
-- this module has triggered
local fileName = "l10n/DEFAULT/" .. theZone.soundFile
local msg = theZone.message
local msg = messenger.getMessage(theZone)
if theZone.spaceBefore then msg = "\n"..msg end
if theZone.spaceAfter then msg = msg .. "\n" end
if theZone.coalition then
trigger.action.outTextForCoalition(theZone.coalition, msg, theZone.duration)
trigger.action.outTextForCoalition(theZone.coalition, msg, theZone.duration, theZone.clearScreen)
trigger.action.outSoundForCoalition(theZone.coalition, fileName)
else
-- out to all
trigger.action.outText(msg, theZone.duration)
trigger.action.outText(msg, theZone.duration, theZone.clearScreen)
trigger.action.outSound(fileName)
end
end
@ -96,14 +128,14 @@ function messenger.update()
for idx, aZone in pairs(messenger.messengers) do
-- make sure to re-start before reading time limit
if aZone.triggerMessagerFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.triggerMessagerFlag)
local currTriggerVal = cfxZones.getFlagValue(aZone.triggerMessagerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerMessagerFlag)
if currTriggerVal ~= aZone.lastMessageTriggerValue
then
if messenger.verbose then
trigger.action.outText("+++msgr: triggered on in?", 30)
end
messenger.isTriggered(aZone)
aZone.lastMessageTriggerValue = trigger.misc.getUserFlag(aZone.triggerMessagerFlag) -- save last value
aZone.lastMessageTriggerValue = cfxZones.getFlagValue(aZone.triggerMessagerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerMessagerFlag) -- save last value
end
end
end
@ -159,4 +191,9 @@ end
if not messenger.start() then
trigger.action.outText("cfx Messenger aborted: missing libraries", 30)
messenger = nil
end
end
--[[--
Wildcard extension:
messageValue supports multiple flags like 1-3, *hi ther, *bingo and then *value[name] returns that value
--]]--

View File

@ -1,5 +1,5 @@
pulseFlags = {}
pulseFlags.version = "1.0.3"
pulseFlags.version = "1.1.0"
pulseFlags.verbose = false
pulseFlags.requiredLibs = {
"dcsCommon", -- always
@ -18,6 +18,15 @@ pulseFlags.requiredLibs = {
uses randomDelayFromPositiveRange
flag! now is string
WARNING: still needs full alphaNum flag upgrade
- 1.1.0 Full DML flag integration
removed zone!
made pulse and pulse! the out flag carrier
done!
pulsesDone! synonym
pausePulse? synonym
pulseMethod synonym
startPulse? synonym
pulseStopped synonym
--]]--
@ -32,8 +41,14 @@ end
--
function pulseFlags.createPulseWithZone(theZone)
theZone.flag = cfxZones.getStringFromZoneProperty(theZone, "flag!", -1) -- the flag to pulse
if cfxZones.hasProperty(theZone, "pulse") then
theZone.pulseFlag = cfxZones.getStringFromZoneProperty(theZone, "pulse", "*none") -- the flag to pulse
end
if cfxZones.hasProperty(theZone, "pulse!") then
theZone.pulseFlag = cfxZones.getStringFromZoneProperty(theZone, "pulse!", "*none") -- the flag to pulse
end
-- time can be number, or number-number range
theZone.minTime, theZone.time = cfxZones.getPositiveRangeFromZoneProperty(theZone, "time", 1)
if pulseFlags.verbose then
@ -45,23 +60,45 @@ function pulseFlags.createPulseWithZone(theZone)
-- trigger flags
if cfxZones.hasProperty(theZone, "activate?") then
theZone.activateFlag = cfxZones.getStringFromZoneProperty(theZone, "activate?", "none")
theZone.lastActivateValue = trigger.misc.getUserFlag(theZone.activateFlag) -- save last value
theZone.activatePulseFlag = cfxZones.getStringFromZoneProperty(theZone, "activate?", "none")
theZone.lastActivateValue = cfxZones.getFlagValue(theZone.activatePulseFlag, theZone) -- trigger.misc.getUserFlag(theZone.activatePulseFlag) -- save last value
end
if cfxZones.hasProperty(theZone, "startPulse?") then
theZone.activatePulseFlag = cfxZones.getStringFromZoneProperty(theZone, "startPulse?", "none")
theZone.lastActivateValue = cfxZones.getFlagValue(theZone.activatePulseFlag, theZone) -- trigger.misc.getUserFlag(theZone.activatePulseFlag) -- save last value
end
if cfxZones.hasProperty(theZone, "pause?") then
theZone.pauseFlag = cfxZones.getStringFromZoneProperty(theZone, "pause?", "none")
theZone.lastPauseValue = trigger.misc.getUserFlag(theZone.pauseFlag) -- save last value
theZone.pausePulseFlag = cfxZones.getStringFromZoneProperty(theZone, "pause?", "*none")
theZone.lastPauseValue = cfxZones.getFlagValue(theZone.lastPauseValue, theZone)-- trigger.misc.getUserFlag(theZone.pausePulseFlag) -- save last value
end
theZone.paused = cfxZones.getBoolFromZoneProperty(theZone, "paused", false)
if cfxZones.hasProperty(theZone, "pausePulse?") then
theZone.pausePulseFlag = cfxZones.getStringFromZoneProperty(theZone, "pausePulse?", "*none")
theZone.lastPauseValue = cfxZones.getFlagValue(theZone.lastPauseValue, theZone)-- trigger.misc.getUserFlag(theZone.pausePulseFlag) -- save last value
end
theZone.pulsePaused = cfxZones.getBoolFromZoneProperty(theZone, "paused", false)
if cfxZones.hasProperty(theZone, "pulseStopped") then
theZone.pulsePaused = cfxZones.getBoolFromZoneProperty(theZone, "pulseStopped", false)
end
theZone.method = cfxZones.getStringFromZoneProperty(theZone, "method", "flip")
if cfxZones.hasProperty(theZone, "pulseMethod") then
theZone.method = cfxZones.getStringFromZoneProperty(theZone, "pulseMethod", "flip")
end
-- done flag
if cfxZones.hasProperty(theZone, "done+1") then
theZone.doneFlag = cfxZones.getStringFromZoneProperty(theZone, "done+1", "none")
theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "done+1", "*none")
end
if cfxZones.hasProperty(theZone, "pulsesDone!") then
theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "pulsesDone!", "*none")
end
if cfxZones.hasProperty(theZone, "done!") then
theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "done!", "*none")
end
theZone.pulsing = false -- not running
@ -78,7 +115,7 @@ function pulseFlags.doPulse(args)
local theZone = args[1]
-- check if we have been paused. if so, simply
-- exit with no new schedule
if theZone.paused then
if theZone.pulsePaused then
theZone.pulsing = false
return
end
@ -86,7 +123,11 @@ function pulseFlags.doPulse(args)
-- do a poll on flags
-- first, we only do an initial pulse if zeroPulse is set
if theZone.hasPulsed or theZone.zeroPulse then
cfxZones.pollFlag(theZone.flag, theZone.method, theZone)
if pulseFlags.verbose then
trigger.action.outText("+++pulF: will bang " .. theZone.pulseFlag, 30);
end
cfxZones.pollFlag(theZone.pulseFlag, theZone.method, theZone)
-- decrease count
if theZone.pulses > 0 then
@ -96,15 +137,15 @@ function pulseFlags.doPulse(args)
-- see if we are done
if theZone.pulsesLeft < 1 then
-- increment done flag if set
if theZone.doneFlag then
local currVal = trigger.misc.getUserFlag(theZone.doneFlag)
trigger.action.setUserFlag(theZone.doneFlag, currVal + 1)
if theZone.pulseDoneFlag then
--local currVal = cfxZones.getFlagValue(theZone.pulseDoneFlag, theZone)-- trigger.misc.getUserFlag(theZone.pulseDoneFlag)
cfxZones.pollFlag(theZone.pulseDoneFlag, "inc", theZone) -- trigger.action.setUserFlag(theZone.pulseDoneFlag, currVal + 1)
end
if pulseFlags.verbose then
trigger.action.outText("***PulF: pulse <" .. theZone.name .. "> ended!", 30)
end
theZone.pulsing = false
theZone.paused = true
theZone.pulsePaused = true
return
end
end
@ -117,18 +158,8 @@ function pulseFlags.doPulse(args)
theZone.hasPulsed = true -- we are past initial pulse
-- if we get here, schedule next pulse
--[[--
local delay = theZone.time
if theZone.minTime > 0 and theZone.minTime < delay then
-- we want a randomized from time from minTime .. delay
local varPart = delay - theZone.minTime + 1
varPart = dcsCommon.smallRandom(varPart) - 1
delay = theZone.minTime + varPart
end
--]]--
local delay = cfxZones.randomDelayFromPositiveRange(theZone.minTime, theZone.time)
--trigger.action.outText("***PulF: pulse <" .. theZone.name .. "> scheduled in ".. delay .."!", 30)
-- schedule in delay time
theZone.timerID = timer.scheduleFunction(pulseFlags.doPulse, args, timer.getTime() + delay)
@ -162,7 +193,7 @@ function pulseFlags.update()
else
-- this zone has not scheduled a new pulse
-- let's see why
if aZone.paused then
if aZone.pulsePaused then
-- ok, zone is paused. all clear
else
-- zone isn't paused. we need to start the zone
@ -171,24 +202,28 @@ function pulseFlags.update()
end
-- see if we got a pause or activate command
if aZone.activateFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.activateFlag)
if aZone.activatePulseFlag then
local currTriggerVal = cfxZones.getFlagValue(aZone.activatePulseFlag, aZone) -- trigger.misc.getUserFlag(aZone.activatePulseFlag)
if currTriggerVal ~= aZone.lastActivateValue
then
trigger.action.outText("+++PulF: activating <" .. aZone.name .. ">", 30)
if pulseFlags.verbose then
trigger.action.outText("+++PulF: activating <" .. aZone.name .. ">", 30)
end
aZone.lastActivateValue = currTriggerVal
aZone.paused = false -- will start anew
aZone.pulsePaused = false -- will start anew
end
end
if aZone.pauseFlag then
local currTriggerVal = trigger.misc.getUserFlag(aZone.pauseFlag)
if aZone.pausePulseFlag then
local currTriggerVal = cfxZones.getFlagValue(aZone.pausePulseFlag, aZone)-- trigger.misc.getUserFlag(aZone.pausePulseFlag)
if currTriggerVal ~= aZone.lastPauseValue
then
trigger.action.outText("+++PulF: pausing <" .. aZone.name .. ">", 30)
if pulseFlags.verbose then
trigger.action.outText("+++PulF: pausing <" .. aZone.name .. ">", 30)
end
aZone.lastPauseValue = currTriggerVal
aZone.paused = true -- prevents new start
aZone.pulsePaused = true -- prevents new start
if aZone.timerID then
timer.removeFunction(aZone.timerID)
aZone.timerID = nil
@ -242,6 +277,15 @@ function pulseFlags.start()
pulseFlags.addPulse(aZone) -- remember it so we can pulse it
end
local attrZones = cfxZones.getZonesWithAttributeNamed("pulse!")
-- now create a pulse gen for each one and add them
-- to our watchlist
for k, aZone in pairs(attrZones) do
pulseFlags.createPulseWithZone(aZone) -- process attribute and add to zone
pulseFlags.addPulse(aZone) -- remember it so we can pulse it
end
-- start update in 1 second
--pulseFlags.update()
timer.scheduleFunction(pulseFlags.update, {}, timer.getTime() + 1)

View File

@ -1,5 +1,5 @@
raiseFlag = {}
raiseFlag.version = "1.0.0"
raiseFlag.version = "1.0.1"
raiseFlag.verbose = false
raiseFlag.requiredLibs = {
"dcsCommon", -- always
@ -11,6 +11,8 @@ raiseFlag.flags = {}
Version History
1.0.0 - initial release
1.0.1 - synonym "raiseFlag!"
--]]--
function raiseFlag.addRaiseFlag(theZone)
table.insert(raiseFlag.flags, theZone)
@ -32,8 +34,12 @@ end
--
function raiseFlag.createRaiseFlagWithZone(theZone)
-- get flag from faiseFlag itself
theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, "raiseFlag", "<none>") -- the flag to raise
if cfxZones.hasProperty(theZone, "raiseFlag") then
theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, "raiseFlag", "<none>") -- the flag to raise
else
theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, "raiseFlag!", "<none>") -- the flag to raise
end
theZone.flagValue = cfxZones.getNumberFromZoneProperty(theZone, "value", 1) -- value to set to
theZone.minAfterTime, theZone.maxAfterTime = cfxZones.getPositiveRangeFromZoneProperty(theZone, "afterTime", -1)
@ -109,7 +115,7 @@ function raiseFlag.start()
trigger.action.outText("cfx raise flag requires dcsCommon", 30)
return false
end
if not dcsCommon.libCheck("cfx Count Down", raiseFlag.requiredLibs) then
if not dcsCommon.libCheck("cfx Raise Flag", raiseFlag.requiredLibs) then
return false
end
@ -122,6 +128,12 @@ function raiseFlag.start()
raiseFlag.createRaiseFlagWithZone(aZone) -- process attributes
raiseFlag.addRaiseFlag(aZone) -- add to list
end
-- try synonym
attrZones = cfxZones.getZonesWithAttributeNamed("raiseFlag!")
for k, aZone in pairs(attrZones) do
raiseFlag.createRaiseFlagWithZone(aZone) -- process attributes
raiseFlag.addRaiseFlag(aZone) -- add to list
end
-- start update
raiseFlag.update()

119
modules/unGrief.lua Normal file
View File

@ -0,0 +1,119 @@
unGrief = {}
unGrief.version = "1.0.0"
unGrief.verbose = false
unGrief.requiredLibs = {
"dcsCommon", -- always
"cfxZones", -- Zones, of course
}
unGrief.enabledFlagValue = 0 -- DO NOT CHANGE, MUST MATCH SSB
unGrief.disabledFlagValue = unGrief.enabledFlagValue + 100 -- DO NOT CHANGE
--[[--
unGrief - allow only so many friendly kills.
Version History
1.0.0 - initial release
--]]--
unGrief.griefers = {} -- offenders are stored here
-- event proccer
function unGrief:onEvent(theEvent)
if not theEvent then return end
if theEvent.id ~= 28 then return end -- only S_EVENT_KILL events allowed
if not theEvent.initiator then return end -- no initiator, no interest
if not theEvent.target then return end -- wtf happened here? begone!
local killer = theEvent.initiator
if not killer:isExist() then return end -- may have exited already
local stiff = theEvent.target
if not killer.getPlayerName then return end -- wierd stuff happening here
local playerName = killer:getPlayerName()
if not playerName then return end -- AI kill, not interesting
-- map (scenery) objects don't have coalition, so check this first
if not stiff.getCoalition then return end
-- get the two coalitions involved
local killSide = killer:getCoalition()
local stiffSide = stiff:getCoalition()
if killSide ~= stiffSide then return end -- fair & square
-- if we get here, we have a problem.
local previousKills = unGrief.griefers[playerName]
if not previousKills then previousKills = 0 end
previousKills = previousKills + 1
unGrief.griefers[playerName] = previousKills
if previousKills <= unGrief.graceKills then
-- ok, let them off with a warning
trigger.action.outText(playerName .. " has killed one of their own. YOU ARE ON NOTICE!", 30)
return
end
-- ok, time to get serious
trigger.action.outText(playerName .. " is killing their own. ".. previousKills .. " kills recorded so far. We disaprove", 30)
-- lets set them up the bomb
local p = killer:getPoint()
if unGrief.retaliation == "ssb" then
-- use ssb to kick/block the entire group
local theGroup = killer:getGroup()
if not theGroup then return end -- you got lucky!
local groupName = theGroup:getName()
-- tell ssb to kick now:
trigger.action.setUserFlag(groupName, unGrief.disabledFlagValue)
return
end
-- aaand all your base are belong to us!
trigger.action.explosion(p, 100)
trigger.action.outText("Have a nice day, " .. playerName, 30)
-- (or kick via SSB or do some other stuff. be creative to boot this idiot)
end
function unGrief.readConfigZone()
local theZone = cfxZones.getZoneByName("unGriefConfig")
if not theZone then
if unGrief.verbose then
trigger.action.outText("+++uGrf: NO config zone!", 30)
end
return
end
unGrief.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
unGrief.graceKills = cfxZones.getNumberFromZoneProperty(theZone, "graceKills", 1)
unGrief.retaliation = cfxZones.getStringFromZoneProperty(theZone, "retaliation", "boom") -- other possible methods: ssb
if unGrief.verbose then
trigger.action.outText("+++uGrf: read config", 30)
end
end
function unGrief.start()
-- lib check
if not dcsCommon.libCheck then
trigger.action.outText("cfx unGrief requires dcsCommon", 30)
return false
end
if not dcsCommon.libCheck("cfx unGrief", unGrief.requiredLibs) then
return false
end
-- read config
unGrief.readConfigZone()
-- connect event proccer
world.addEventHandler(unGrief)
trigger.action.outText("cfx unGrief v" .. unGrief.version .. " started.", 30)
return true
end
-- let's go!
if not unGrief.start() then
trigger.action.outText("cfx unGrief aborted: missing libraries", 30)
unGrief = nil
end

Binary file not shown.