Refactored Persistance managed by SpawnManager for groups, and added … (#53)
* Refactored Persistance managed by SpawnManager for groups, and added Persistence for buildables * get last file based on the iteration number * Working persistence of everything as a MVP version
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
---@class SpawnManager : OnUnitLostListener
|
||||
---@field private _persistedUnits table<string,boolean>
|
||||
---@field private _logger Logger
|
||||
local SpawnManager = {}
|
||||
SpawnManager.__index = SpawnManager
|
||||
|
||||
---@class SpawnOverrides
|
||||
---@field countryID number?
|
||||
---@field emptyLoadouts boolean? if true, the group will spawn with empty loadouts
|
||||
---@field route table? route of the group. If nil will be the default route.
|
||||
---@field uncontrolled boolean? Sets the group to be uncontrolled on spawn
|
||||
|
||||
---@param logger Logger
|
||||
function SpawnManager.new(logger)
|
||||
local self = setmetatable({}, SpawnManager)
|
||||
|
||||
self._logger = logger
|
||||
|
||||
self._persistedUnits = {} -- Stores units that should be persisted by name
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param groupName string
|
||||
---@param overrides SpawnOverrides? overrides for the spawn
|
||||
---@param isGroupPersistant boolean? whether or not a group and all its units should be persisted.
|
||||
---@return StaticObject|Group|nil spawned
|
||||
---@return boolean isStatic
|
||||
function SpawnManager:SpawnGroup(groupName, overrides, isGroupPersistant)
|
||||
|
||||
local spawnData = Spearhead.classes.helpers.MizGroupsManager.getSpawnTemplateData(groupName)
|
||||
|
||||
if spawnData == nil then
|
||||
env.error("SpawnManager:SpawnGroup - No spawn template found for group: " .. groupName)
|
||||
return nil, false
|
||||
end
|
||||
|
||||
if spawnData.isStatic == true then
|
||||
return self:SpawnStaticInternal(groupName, spawnData, overrides, isGroupPersistant), true
|
||||
else
|
||||
return self:SpawnGroupInternal(groupName, spawnData, overrides, isGroupPersistant), false
|
||||
end
|
||||
end
|
||||
|
||||
function SpawnManager:DestroyGroup(groupName)
|
||||
if groupName == nil then return end
|
||||
|
||||
if self:IsGroupStatic(groupName) == true then
|
||||
local object = StaticObject.getByName(groupName)
|
||||
if object ~= nil then
|
||||
object:destroy()
|
||||
else
|
||||
env.error("SpawnManager:DestroyGroup - Static object not found: " .. groupName)
|
||||
end
|
||||
else
|
||||
local group = Group.getByName(groupName)
|
||||
if group and group:isExist() then
|
||||
group:destroy()
|
||||
else
|
||||
env.error("SpawnManager:DestroyGroup - Group not found or does not exist: " .. groupName)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param groupName string
|
||||
---@return boolean
|
||||
function SpawnManager:IsGroupStatic(groupName)
|
||||
local isStatic = Spearhead.classes.helpers.MizGroupsManager.IsGroupStatic(groupName)
|
||||
if isStatic ~= nil then return isStatic end
|
||||
|
||||
return StaticObject.getByName(groupName) ~= nil
|
||||
end
|
||||
|
||||
|
||||
---@param object Object
|
||||
function SpawnManager:OnUnitLost(object)
|
||||
local name = object:getName()
|
||||
|
||||
if self._persistedUnits[name] then
|
||||
local heading = 0
|
||||
local pos = object:getPosition()
|
||||
if pos then
|
||||
heading = math.atan2(pos.x.z, pos.x.x)
|
||||
if heading < 0 then
|
||||
heading = heading + 2*math.pi
|
||||
end
|
||||
heading = heading
|
||||
end
|
||||
|
||||
Spearhead.classes.persistence.Persistence.UnitKilled(
|
||||
name,
|
||||
object:getPoint(),
|
||||
heading,
|
||||
object:getTypeName()
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function SpawnManager:SpawnCorpsesOnly(groupName)
|
||||
|
||||
end
|
||||
|
||||
do --- privates
|
||||
|
||||
---@private
|
||||
---@param groupName string
|
||||
---@param spawnData SpawnData
|
||||
---@param override SpawnOverrides?
|
||||
---@param isPersistent boolean?
|
||||
---@return Group|nil
|
||||
function SpawnManager:SpawnGroupInternal(groupName, spawnData, override, isPersistent)
|
||||
|
||||
if not spawnData then return end
|
||||
|
||||
local country = spawnData.country
|
||||
if override then
|
||||
country = override.countryID or spawnData.country
|
||||
end
|
||||
|
||||
local spawnTemplate = Spearhead.Util.deepCopyTable(spawnData.groupTemplate)
|
||||
---@type Array<string>
|
||||
local removeableUnitNames = {}
|
||||
--[[
|
||||
TODO: Spawn units at "current"/LastKnown position with them going to the next waypoint.
|
||||
ONLY when perstable data is found.
|
||||
]]
|
||||
|
||||
if spawnTemplate and spawnTemplate["units"] then
|
||||
for _, unit in pairs(spawnTemplate["units"]) do
|
||||
local name = unit["name"]
|
||||
|
||||
Spearhead.Events.addOnUnitLostEventListener(name, self)
|
||||
local state = Spearhead.classes.persistence.Persistence.UnitState(name)
|
||||
if state then
|
||||
if state.isDead == true then
|
||||
removeableUnitNames[#removeableUnitNames+1] = name
|
||||
end
|
||||
end
|
||||
|
||||
if override and override.emptyLoadouts == true then
|
||||
if unit["payload"] and unit["payload"]["pylons"] then
|
||||
unit["payload"]["pylons"] = {}
|
||||
end
|
||||
end
|
||||
|
||||
if unit["parking"] then
|
||||
unit["parking_landing"] = unit["parking"]
|
||||
end
|
||||
|
||||
if unit["parking_id"] then
|
||||
unit["parking_landing_id"] = unit["parking_id"]
|
||||
end
|
||||
end
|
||||
|
||||
if override and override.route ~= nil then
|
||||
spawnTemplate["route"] = override.route
|
||||
end
|
||||
|
||||
if override and override.uncontrolled ~= nil then
|
||||
spawnTemplate["uncontrolled"] = override.uncontrolled
|
||||
end
|
||||
|
||||
local group = coalition.addGroup(country, spawnData.category, spawnTemplate)
|
||||
|
||||
|
||||
for _, unit in pairs(group:getUnits()) do
|
||||
self:CheckUnitAndReplaceIfPersistentDead(unit)
|
||||
if isPersistent == true then
|
||||
self._persistedUnits[unit:getName()] = true
|
||||
end
|
||||
Spearhead.Events.addOnUnitLostEventListener(unit:getName(), self)
|
||||
end
|
||||
|
||||
return group
|
||||
end
|
||||
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param groupName string
|
||||
---@param spawnData SpawnData
|
||||
---@param isPersistent any
|
||||
---@param overrides SpawnOverrides?
|
||||
---@return StaticObject?
|
||||
function SpawnManager:SpawnStaticInternal(groupName, spawnData, overrides, isPersistent)
|
||||
|
||||
if not spawnData then return end
|
||||
|
||||
local country = spawnData.country
|
||||
if overrides then
|
||||
country = overrides.countryID or spawnData.country
|
||||
end
|
||||
|
||||
local spawnTemplate = Spearhead.Util.deepCopyTable(spawnData.groupTemplate)
|
||||
|
||||
--for static Objecst groupNames and unit names are the same and is always 1:1
|
||||
local persistentState = Spearhead.classes.persistence.Persistence.UnitState(groupName)
|
||||
if persistentState then
|
||||
if persistentState.isDead == true then
|
||||
spawnTemplate["dead"] = true
|
||||
if persistentState.pos then
|
||||
spawnTemplate["x"] = persistentState.pos.x
|
||||
spawnTemplate["y"] = persistentState.pos.z
|
||||
if spawnTemplate["units"] and spawnTemplate["units"][1] then
|
||||
spawnTemplate["units"][1]["x"] = persistentState.pos.x
|
||||
spawnTemplate["units"][1]["y"] = persistentState.pos.z
|
||||
spawnTemplate["units"][1]["heading"] = persistentState.heading or 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---disable diagnostic as -1 is actually valid
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
coalition.addGroup(country, -1, spawnTemplate)
|
||||
|
||||
local object = StaticObject.getByName(groupName)
|
||||
if object == nil then
|
||||
env.error("Could not retrieve spawned static object after spawning with name: " .. groupName)
|
||||
return nil
|
||||
end
|
||||
|
||||
if isPersistent == true then
|
||||
self._persistedUnits[groupName] = true
|
||||
Spearhead.Events.addOnUnitLostEventListener(groupName, self)
|
||||
end
|
||||
|
||||
return object
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param unit Unit
|
||||
function SpawnManager:CheckUnitAndReplaceIfPersistentDead(unit)
|
||||
|
||||
if not unit then return end
|
||||
|
||||
local deadState = Spearhead.classes.persistence.Persistence.UnitState(unit:getName())
|
||||
if deadState and deadState.isDead == true then
|
||||
unit:destroy() -- Destroy the unit if it is dead
|
||||
local staticObject = {
|
||||
["heading"] = deadState.heading or 0,
|
||||
["type"] = deadState.type or unit:getTypeName(),
|
||||
["name"] = unit:getName() .. "_dead",
|
||||
["x"] = deadState.pos.x,
|
||||
["y"] = deadState.pos.z,
|
||||
["dead"] = true,
|
||||
}
|
||||
coalition.addStaticObject(unit:getCountry(), staticObject)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if not Spearhead then Spearhead = {} end
|
||||
if not Spearhead.classes then Spearhead.classes = {} end
|
||||
if not Spearhead.classes.helpers then Spearhead.classes.helpers = {} end
|
||||
Spearhead.classes.helpers.SpawnManager = SpawnManager
|
||||
|
||||
--Old Spawn Method
|
||||
|
||||
-- --- spawns the units as specified in the mission file itself
|
||||
-- --- location and route can be nil and will then use default route
|
||||
-- ---@param groupName string
|
||||
-- ---@param location table? vector 3 data. { x , z, alt }
|
||||
-- ---@param route table? route of the group. If nil wil be the default route.
|
||||
-- ---@param uncontrolled boolean? Sets the group to be uncontrolled on spawn
|
||||
-- ---@param countryId CountryID? Overwrites the country
|
||||
-- ---@param emptyLoadouts boolean? If true, the group will spawn with empty loadouts
|
||||
-- ---@return table? new_group the Group class that was spawned
|
||||
-- ---@return boolean? isStatic whether the group is a static or not
|
||||
-- function DCS_UTIL.SpawnGroupTemplate(groupName, location, route, uncontrolled, countryId, emptyLoadouts)
|
||||
-- if groupName == nil then
|
||||
-- return nil, nil
|
||||
-- end
|
||||
|
||||
-- local template = DCS_UTIL.GetMizGroupOrDefault(groupName, nil)
|
||||
-- if template == nil then
|
||||
-- return nil, nil
|
||||
-- end
|
||||
-- if template.category == DCS_UTIL.GroupCategory.STATIC then
|
||||
-- --TODO: Implement location and route stuff
|
||||
-- local spawn_template = template.group_template
|
||||
-- local country = countryId or template.country_id
|
||||
|
||||
-- ---disable diagnostic as -1 is actually valid
|
||||
-- ---@diagnostic disable-next-line: param-type-mismatch
|
||||
-- coalition.addGroup(country, -1, spawn_template)
|
||||
|
||||
-- local object = StaticObject.getByName(spawn_template.name)
|
||||
-- if object then
|
||||
-- return object, true
|
||||
-- end
|
||||
-- else
|
||||
-- local spawn_template = Spearhead.Util.deepCopyTable(template.group_template)
|
||||
-- if location ~= nil then
|
||||
-- local x_offset
|
||||
-- if location.x ~= nil then x_offset = spawn_template.x - location.x end
|
||||
|
||||
-- local y_offset
|
||||
-- if location.z ~= nil then y_offset = spawn_template.y - location.z end
|
||||
|
||||
-- spawn_template.x = location.x
|
||||
-- spawn_template.y = location.z
|
||||
|
||||
-- for i, unit in pairs(spawn_template.units) do
|
||||
-- unit.x = unit.x - x_offset
|
||||
-- unit.y = unit.y - y_offset
|
||||
-- unit.alt = location.alt
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if spawn_template.units then
|
||||
-- for _, unit in pairs(spawn_template.units) do
|
||||
-- if unit["parking"] then
|
||||
-- unit["parking_landing"] = unit["parking"]
|
||||
-- end
|
||||
|
||||
-- if unit["parking_id"] then
|
||||
-- unit["parking_landing_id"] = unit["parking_id"]
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if emptyLoadouts == true then
|
||||
-- for _, unit in pairs(spawn_template.units) do
|
||||
-- if unit["payload"] and unit["payload"]["pylons"] then
|
||||
-- unit["payload"]["pylons"] = {}
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if route ~= nil then
|
||||
-- spawn_template.route = route
|
||||
-- end
|
||||
|
||||
-- if uncontrolled ~= nil then
|
||||
-- spawn_template.uncontrolled = uncontrolled
|
||||
-- end
|
||||
|
||||
-- local country = countryId or template.country_id
|
||||
-- local new_group = coalition.addGroup(country, template.category, spawn_template)
|
||||
-- return new_group, false
|
||||
-- end
|
||||
-- end
|
||||
Reference in New Issue
Block a user