Version 1.4.2

NoGap, Wiper
This commit is contained in:
Christian Franz
2023-08-24 17:49:27 +02:00
parent 7c6deec7a6
commit 23830d47db
11 changed files with 672 additions and 80 deletions

View File

@@ -1,14 +1,16 @@
duel = {}
duel.version = "1.0.0"
duel.version = "1.0.2"
duel.verbose = false
duel.requiredLibs = {
"dcsCommon",
"cfxZones",
"cfxMX",
}
}
--[[--
Version History
1.0.0 - Initial Version
1.0.1 - verbosity bug with SSB removed
1.0.2 - units are reserved for player when they disappear
--]]--
@@ -16,13 +18,16 @@ duel.requiredLibs = {
ATTENTION!
- REQUIRES that SSB is running on the host
- REQUIRTES that SSB is confgured that '0' (zero) means slot is enabled (this is SSB default)
- REQUIRES MULTIPLAYER (kind of obvious...)
- This script must run at MISSION START and will enable SSB
--]]--
duel.duelZones = {}
duel.activeDuelists = {}
duel.allDuelists = {}
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
--
@@ -45,7 +50,7 @@ function duel.createDuelZone(theZone)
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)
-- 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
@@ -63,6 +68,20 @@ function duel.createDuelZone(theZone)
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")
theZone.lastDuelOn = theZone:getFlagValue(theZone.duelOnFlag)
end
if theZone:hasProperty("off?") then
theZone.duelOffFlag = theZone:getStringFromZoneProperty("off?", "*none")
theZone.lastDuelOff = theZone:getFlagValue(theZone.duelOffFlag)
end
theZone.onStart = theZone:getBoolFromZoneProperty("onStart", true)
theZone.active = true
if not theZone.onStart then
theZone.active = false
end
end
@@ -77,8 +96,8 @@ function duel.closeSlotsForZoneAndCoaExceptGroupNamed(theZone, coa, groupName)
if (theDuelist.coa == coa) and (dgName ~= groupName) then
if duel.verbose then
trigger.action.outText("+++duel: closing SSB slot for group <" .. dgName .. ">, coa <" .. theDuelist.coa .. ">", 30)
trigger.action.setUserFlag(dgName,100) -- anything but 0 means closed
end
trigger.action.setUserFlag(dgName,100) -- anything but 0 means closed
end
end
end
@@ -90,8 +109,8 @@ function duel.openSlotsForZoneAndCoa(theZone, coa)
if (theDuelist.coa == coa) then
if duel.verbose then
trigger.action.outText("+++duel: opening SSB slot for group <" .. theDuelist.groupName .. ">, coa <" .. theDuelist.coa .. ">", 30)
trigger.action.setUserFlag(theDuelist.groupName, 0) -- 0 means OPEN
end
trigger.action.setUserFlag(theDuelist.groupName, 0) -- 0 means OPEN
end
end
end
@@ -112,8 +131,15 @@ function duel.checkReopenSlotsForZoneAndCoa(theZone, coa)
end
if allUnengaged 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)
end
end
end
@@ -132,8 +158,45 @@ function duel.duelistEnteredArena(theUnit, theDuelist)
trigger.action.outText("Player <" .. player .. "> entered arena <" .. theZone:getName() .. "> in unit <" .. unitName .. "> of group <" .. groupName .. "> type <" .. theDuelist.type .. ">, belongs to coalition <" .. coa .. ">", 30)
end
-- close all slots for this zone and coalition
duel.closeSlotsForZoneAndCoaExceptGroupNamed(theZone, coa, groupName)
-- remember this player should they go missing
local playerData = {}
playerData.playerName = player
playerData.unitName = unitName
playerData.lastSeen = timer.getTime()
playerData.theZone = theZone
playerData.coa = coa
-- see if we are updating an existing player.
-- this will require a cleanup of the last time they
-- were here
if duel.activePlayers[player] then
-- we need to update slots and flags if player has chosen a
-- different unit
local lastData = duel.activePlayers[player]
if lastData.unitName ~= unitName then
if duel.verbose then
trigger.action.outText("Duel: player changed slots. Cleaning up", 30)
end
duel.checkReopenSlotsForZoneAndCoa(lastData.theZone, lastData.coa)
else
if duel.verbose then
trigger.action.outText("Duel: player re-slotted, no update required", 30)
end
end
end
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)
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)
end
end
end
@@ -155,6 +218,12 @@ function duel:onEvent(event)
-- unit that entered is player controlled, and duelist
duel.duelistEnteredArena(theUnit, duel.allDuelists[unitName])
end
if event.id == 21 then
if duel.verbose then
trigger.action.outText("DUEL: player left unit <" .. theUnit:getName() .. ">", 30)
end
end
end
--
@@ -166,6 +235,7 @@ function duel.update()
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
@@ -185,10 +255,54 @@ function duel.update()
end
end
end
--]]--
-- now check the active players and their units
local now = timer.getTime()
local filtered = {}
for playerName, playerData in pairs(duel.activePlayers) do
local unitName = playerData.unitName
local theUnit = Unit.getByName(unitName)
if theUnit and Unit.isExist(theUnit) then
-- all is well, nothing to do except update time stamp
playerData.lastSeen = now
filtered[playerName] = playerData
else
-- unit has disappeared. let's see how long
local delta = math.floor(now - playerData.lastSeen)
if duel.verbose then
trigger.action.outText("player <" .. playerName .. ">'s unit is gone for <" .. delta .. "> seconds now.", 30)
end
-- if gone long enough, open all slots and delete player entry
if delta < (duel.keepSlot + 1) then
filtered[playerName] = playerData -- remember me
else
if duel.verbose then
trigger.action.outText("Time's up, all slots reopen now, player lost tabs on <" .. unitName .. ">", 30)
end
-- update duelist data (if required)
-- open all slots in that zone for player's coa
duel.checkReopenSlotsForZoneAndCoa(playerData.theZone, playerData.coa)
-- not remembered
end
end
end
duel.activePlayers = filtered
-- now handle FSM for each zone separately
for zoneName, theZone in pairs(duel.duelZones) do
-- first, check if they have been turned on or off
if theZone:testZoneFlag(theZone.duelOnFlag, theZone.duelTriggerMethod, "lastDuelOn") then
theZone.active = true
end
if theZone:testZoneFlag(theZone.duelOffFlag, theZone.duelTriggerMethod, "lastDuelOff") then
theZone.active = false
duel.openSlotsForZoneAndCoa(theZone, 1)
duel.openSlotsForZoneAndCoa(theZone, 2)
end
end
end
@@ -205,6 +319,8 @@ function duel.readConfigZone()
duel.verbose = theZone.verbose
duel.ups = theZone:getNumberFromZoneProperty("ups", 1)
duel.keepSlot = theZone:getNumberFromZoneProperty("keepSlot", 30) -- grace period (in seconds) after unit vanishes in which they can re-slot via Briefing screen
duel.inside = theZone:getBoolFromZoneProperty("inside", true)
duel.gracePeriod = theZone:getNumberFromZoneProperty("gracePeriod", 30)
duel.keepScore = theZone:getBoolFromZoneProperty("score", true)