Version 1.4.4

stopGap refresh
interpreted wildcards
unitZone "*" match all
This commit is contained in:
Christian Franz
2023-09-21 15:48:56 +02:00
parent 0f1e814d22
commit d1d4af63a0
8 changed files with 360 additions and 143 deletions

View File

@@ -1,5 +1,5 @@
duel = {}
duel.version = "1.0.2"
duel.version = "1.1.0"
duel.verbose = false
duel.requiredLibs = {
"dcsCommon",
@@ -11,7 +11,9 @@ duel.requiredLibs = {
1.0.0 - Initial Version
1.0.1 - verbosity bug with SSB removed
1.0.2 - units are reserved for player when they disappear
1.1.0 - maxRed and maxBlue per zone to be able to create
1v1, 2v2, XvY duel zones
--]]--
--[[--
@@ -25,8 +27,6 @@ duel.requiredLibs = {
duel.duelZones = {}
duel.activePlayers = {} -- by player name
--duel.activeUnits = {} -- as above, by unit name
--duel.missingPlayers = {}
duel.allDuelists = {} -- all potential dualists as collected from zones
--
-- reading attributes
@@ -49,8 +49,8 @@ function duel.createDuelZone(theZone)
local groupData = cfxMX.playerUnit2Group[unitName]
duelist.groupName = groupData.name
duelist.coa = cfxMX.groupCoalitionByName[duelist.groupName]
if duel.verbose then
-- trigger.action.outText("Detected player unit <" .. duelist.name .. ">, type <" .. duelist.type .. "> of group <" .. duelist.groupName .. "> of coa <" .. duelist.coa .. "> in zone <" .. theZone.name .. "> as duelist", 30)
if duel.verbose or theZone.verbose then
trigger.action.outText("Detected player unit <" .. duelist.name .. ">, type <" .. duelist.type .. "> of group <" .. duelist.groupName .. "> of coa <" .. duelist.coa .. "> in zone <" .. theZone.name .. "> as duelist", 30)
end
duelist.active = false
@@ -60,14 +60,13 @@ function duel.createDuelZone(theZone)
-- enter into global table
-- player can only be in at maximum one duelist zones
if duel.allDuelists[unitName] then
trigger.action.outText("+++WARNING: overlapping duelists! Overwriting previous data", 30)
trigger.action.outText("+++WARNING: overlapping duelists for zone <" .. theZone.name .. ">! Overwriting previous data", 30)
end
duel.allDuelists[unitName] = duelist
theZone.duelists[unitName] = duelist
end
end
theZone.state = "waiting" -- FSM, init to waiting state
theZone.duelTriggerMethod = theZone:getStringFromZoneProperty("duelTriggerMethod", "change")
if theZone:hasProperty("on?") then
theZone.duelOnFlag = theZone:getStringFromZoneProperty("on?", "*none")
@@ -83,6 +82,8 @@ function duel.createDuelZone(theZone)
theZone.active = false
end
theZone.maxRed = theZone:getNumberFromZoneProperty("maxRed", 1)
theZone.maxBlue = theZone:getNumberFromZoneProperty("maxBlue", 1)
end
--
@@ -102,12 +103,48 @@ function duel.closeSlotsForZoneAndCoaExceptGroupNamed(theZone, coa, groupName)
end
end
function duel.closeSlotsForZoneAndCoaExceptActive(theZone, coa)
-- iterate this zone's duelist groups and tell SSB to close them now
local allDuelists = theZone.duelists
for unitName, theDuelist in pairs(allDuelists) do
local theUnit = Unit.getByName(unitName)
if theUnit and Unit.isExist(theUnit) then
-- is unit exists already, do not close down
if theZone.verbose or duel.verbose then
trigger.action.outText("+++duel: leaving unit <" .. unitName .. "> in game", 30)
end
else
-- this unit is not live, close group down
local dgName = theDuelist.groupName
if (theDuelist.coa == coa) and (dgName ~= groupName) then
if duel.verbose or theZone.verbose then
trigger.action.outText("+++duel: closing SSB slot for group <" .. dgName .. ">, coa <" .. theDuelist.coa .. ">", 30)
end
trigger.action.setUserFlag(dgName,100) -- anything but 0 means closed
end
end
end
end
function duel.countActiveUnitsForCoaInZone(theZone, coa)
local allDuelists = theZone.duelists
local activeCount = 0
for unitName, theDuelist in pairs(allDuelists) do
if theDuelist.coa == coa then
local theUnit = Unit.getByName(unitName)
if theUnit and Unit.isExist(theUnit) then
activeCount = activeCount + 1
end
end
end
return activeCount
end
function duel.openSlotsForZoneAndCoa(theZone, coa)
local allDuelists = theZone.duelists
for unitName, theDuelist in pairs(allDuelists) do
if (theDuelist.coa == coa) then
if duel.verbose then
if duel.verbose or theZone.verbose then
trigger.action.outText("+++duel: opening SSB slot for group <" .. theDuelist.groupName .. ">, coa <" .. theDuelist.coa .. ">", 30)
end
trigger.action.setUserFlag(theDuelist.groupName, 0) -- 0 means OPEN
@@ -117,28 +154,30 @@ end
function duel.checkReopenSlotsForZoneAndCoa(theZone, coa)
-- test if one side can reopen all slots to enter the duel
-- if so, will reset FSM for zone
--
local maxForCoa = theZone.maxRed
if coa == 2 then maxForCoa = theZone.maxBlue end
local allDuelists = theZone.duelists
local allUnengaged = true
local canReopen = true
local engageCount = 0
for unitName, theDuelist in pairs(allDuelists) do
if (theDuelist.coa == coa) then
local theUnit = Unit.getByName(unitName)
if theUnit and Unit.isExist(theUnit) then
-- unit is still alive on this side, can't reopen
allUnengaged = false
-- unit is still alive on this side
engageCount = engageCount + 1
end
end
end
if allUnengaged then
if engageCount < maxForCoa then canReopen = true end
if canReopen then
if duel.verbose then
trigger.action.outText("+++duel: will open all slots for <" .. theZone:getName() .. ">, coa <" .. coa .. ">", 30)
end
duel.openSlotsForZoneAndCoa(theZone, coa)
theZone.state = "waiting"
else
if duel.verbose then
trigger.action.outText("+++duel: unable to reopenslots for <" .. theZone:getName() .. ">, coa <" .. coa .. ">, still engaged", 30)
trigger.action.outText("+++duel: unable to reopenslots for <" .. theZone:getName() .. ">, coa <" .. coa .. ">, " .. engageCount .. " units are still engaged", 30)
end
end
end
@@ -149,6 +188,10 @@ function duel.duelistEnteredArena(theUnit, theDuelist)
theDuelist.active = true
local player = theUnit:getPlayerName()
if not player then
trigger.action.outText("+++Duel: WARNING: no player name for unit <" .. theUnit:getName() .. "> upon enter arena", 30)
return
end
local unitName = theUnit:getName()
local groupName = theDuelist.groupName
local theZone = theDuelist.zone --duel.duelZones[theDuelist.arena]
@@ -187,11 +230,22 @@ function duel.duelistEnteredArena(theUnit, theDuelist)
duel.activePlayers[player] = playerData
-- close all slots for this zone and coalition if it is active
if theZone.active then
if theZone.verbose or duel.verbose then
trigger.action.outText("+++duel: zone <" .. theZone:getName() .. ">, closing coa <" .. coa .. "> slots except for player's <" .. player .. "> group <" .. groupName .. ">", 30)
-- and we have reched the maximum of players for that coalition
local maxForCoa = theZone.maxRed
if coa == 2 then maxForCoa = theZone.maxBlue end
local activeInZone = duel.countActiveUnitsForCoaInZone(theZone, coa)
if theZone.active then
if(activeInZone >= maxForCoa) then
if theZone.verbose or duel.verbose then
trigger.action.outText("+++duel: zone <" .. theZone:getName() .. ">, closing coa <" .. coa .. "> slots except for player's <" .. player .. "> group <" .. groupName .. ">", 30)
end
--duel.closeSlotsForZoneAndCoaExceptGroupNamed(theZone, coa, groupName)
duel.closeSlotsForZoneAndCoaExceptActive(theZone, coa)
else
if duel.verbose or theZone.verbose then
trigger.action.outText("Zone <" .. theZone.name .. "> Coa <" .. coa .. "> remains open, have <" .. activeInZone .. "> participants, max is <" .. maxForCoa .. ">", 30)
end
end
duel.closeSlotsForZoneAndCoaExceptGroupNamed(theZone, coa, groupName)
else
if theZone.verbose or duel.verbose then
trigger.action.outText("+++duel: zone <" .. theZone:getName() .. "> currently not active, not closing slots", 30)
@@ -234,30 +288,7 @@ function duel.update()
-- call me in a second to poll triggers
timer.scheduleFunction(duel.update, {}, timer.getTime() + 1/duel.ups)
-- find units that have disappeared, and react accordingly
--[[--
for unitName, theDuelist in pairs (duel.allDuelists) do
local theZone = theDuelist.zone
if theDuelist.active then
-- trigger.action.outText("+++duel: unit <" .. unitName .. "> is active in zone <" .. theZone:getName() .. ">, controlled by <" .. theDuelist.playerName .. ">", 30)
local theUnit = Unit.getByName(unitName)
if theUnit and Unit.isExist(theUnit) then
-- all is well
else
if duel.verbose then
trigger.action.outText("+++duel: unit <" .. unitName .. "> controlled by <" .. theDuelist.playerName .. "> has disappeared, starting cleanup", 30)
end
theDuelist.playerName = nil
theDuelist.active = false
duel.checkReopenSlotsForZoneAndCoa(theZone, theDuelist.coa)
end
end
end
--]]--
-- now check the active players and their units
-- check active players and their units
local now = timer.getTime()
local filtered = {}
for playerName, playerData in pairs(duel.activePlayers) do