mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 1.4.4
stopGap refresh interpreted wildcards unitZone "*" match all
This commit is contained in:
121
modules/duel.lua
121
modules/duel.lua
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user