mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Warehouse v0.4.1w
This commit is contained in:
parent
cc9b695b68
commit
85505f3feb
@ -1,4 +1,4 @@
|
||||
--- **Functional** - (R2.5) - Simulation of logistics.
|
||||
--- **Functional** - (R2.5) - Simulation of logistic operations.
|
||||
--
|
||||
-- The MOOSE warehouse concept simulates the organization and implementation of complex operations regarding the flow of assets between the point of origin and the point of consumption
|
||||
-- in order to meet requirements of a potential conflict. In particular, this class is concerned with maintaining army supply lines while disrupting those of the enemy, since an armed
|
||||
@ -136,14 +136,14 @@
|
||||
-- Assets can be added to the warehouse stock by using the @{#WAREHOUSE.AddAsset}(*group*, *ngroups*, *forceattribute*) function. The parameter *group* has to be a MOOSE @{Wrapper.Group#GROUP}.
|
||||
-- The parameter *ngroups* specifies how many clones of this group are added to the stock.
|
||||
--
|
||||
-- Note that the group should be a late activated template group, which was defined in the mission editor.
|
||||
--
|
||||
-- infrantry=GROUP:FindByName("Some Infantry Group")
|
||||
-- warehouse:AddAsset(infantry, 5)
|
||||
--
|
||||
-- This will add five infantry groups to the warehouse stock.
|
||||
-- This will add five infantry groups to the warehouse stock. Note that the group will normally be a late activated template group,
|
||||
-- which was defined in the mission editor. But you can also add other groups which are already spawned and present in the mission.
|
||||
--
|
||||
-- Note that you can also add assets with a delay by using the @{#WAREHOUSE.__AddAsset}(*delay*, *group*, *ngroups*, *foceattribute*), where *delay* is the delay in seconds before the asset is added.
|
||||
-- You can add assets with a delay by using the @{#WAREHOUSE.__AddAsset}(*delay*, *group*, *ngroups*, *foceattribute*), where *delay* is the delay in seconds before the asset is added.
|
||||
--
|
||||
-- By default, the generalized attribute of the asset is determined automatically from the DCS descriptor attributes. However, this might not always result in the desired outcome.
|
||||
-- Therefore, it is possible, to force a generalized attribute for the asset with the third optional parameter *forceattribute*, which is of type @{#WAREHOUSE.Attribute}.
|
||||
@ -233,10 +233,11 @@
|
||||
--
|
||||
-- end
|
||||
--
|
||||
-- The variable *groupset* is a @{Core.Set#SET_GOUP} object and holds all asset groups from the request. The code above shows, how the mission designer can access the groups
|
||||
-- The variable *groupset* is a @{Core.Set#SET_GROUP} object and holds all asset groups from the request. The code above shows, how the mission designer can access the groups
|
||||
-- for further tasking. Here, the groups are only smoked but, of course, you can use them for whatever task you fancy.
|
||||
--
|
||||
-- Note that airborne groups are spawned in uncontrolled state and need to be activated first before they can start their assigned mission.
|
||||
-- This can be done with the @{Wrapper.Controllable#CONTROLLABLE.StartUncontrolled} function.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -369,6 +370,7 @@
|
||||
--
|
||||
-- A warehouse has a limited speed to process requests. Each time the status of the warehouse is updated only one requests is processed.
|
||||
-- The time interval between status updates is 30 seconds by default and can be adjusted via the @{#WAREHOUSE.SetStatusUpdate}(*interval*) function.
|
||||
-- However, the status is also updated on other occasions, e.g. when a new request was added.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -872,7 +874,9 @@ WAREHOUSE = {
|
||||
-- @field #number timestamp Absolute mission time in seconds when the request was processed.
|
||||
-- @field Core.Set#SET_GROUP cargogroupset Set of cargo groups do be delivered.
|
||||
-- @field #number ndelivered Number of groups delivered to destination.
|
||||
-- @field Core.Set#SET_GROUP transportgroupset Set of cargo transport groups.
|
||||
-- @field Core.Set#SET_GROUP transportgroupset Set of cargo transport carrier groups.
|
||||
-- @field Core.Set#SET_CARGO transportcargoset Set of cargo objects.
|
||||
-- @field #table carriercargo Table holding the cargo groups of each carrier unit.
|
||||
-- @field #number ntransporthome Number of transports back home.
|
||||
-- @extends #WAREHOUSE.Queueitem
|
||||
|
||||
@ -987,7 +991,7 @@ WAREHOUSE.db = {
|
||||
|
||||
--- Warehouse class version.
|
||||
-- @field #string version
|
||||
WAREHOUSE.version="0.4.1"
|
||||
WAREHOUSE.version="0.4.1w"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO: Warehouse todo list.
|
||||
@ -1107,8 +1111,8 @@ function WAREHOUSE:New(warehouse, alias)
|
||||
self:AddTransition("*", "Delivered", "*") -- All cargo groups of a request have been delivered to the requesting warehouse.
|
||||
self:AddTransition("Running", "SelfRequest", "*") -- Request to warehouse itself. Requested assets are only spawned but not delivered anywhere.
|
||||
self:AddTransition("Attacked", "SelfRequest", "*") -- Request to warehouse itself. Also possible when warehouse is under attack!
|
||||
self:AddTransition("Running", "Pause", "Paused") -- TODO Pause the processing of new requests. Still possible to add assets and requests.
|
||||
self:AddTransition("Paused", "Unpause", "Running") -- TODO Unpause the warehouse. Queued requests are processed again.
|
||||
self:AddTransition("Running", "Pause", "Paused") -- DONE Pause the processing of new requests. Still possible to add assets and requests.
|
||||
self:AddTransition("Paused", "Unpause", "Running") -- DONE Unpause the warehouse. Queued requests are processed again.
|
||||
self:AddTransition("*", "Stop", "Stopped") -- DONE Stop the warehouse.
|
||||
self:AddTransition("*", "Save", "*") -- TODO Save the warehouse state to disk.
|
||||
self:AddTransition("*", "Attacked", "Attacked") -- DONE Warehouse is under attack by enemy coalition.
|
||||
@ -2069,40 +2073,6 @@ function WAREHOUSE:onafterStatus(From, Event, To)
|
||||
self:__Status(-self.dTstatus)
|
||||
end
|
||||
|
||||
--- Count alive and filter dead groups.
|
||||
-- @param #WAREHOUSE self
|
||||
-- @param Core.Set#SET_GROUP groupset Set of groups. Dead groups are removed from the set.
|
||||
-- @return #number Number of alive groups. Returns zero if groupset is nil.
|
||||
function WAREHOUSE:_FilterDead(groupset)
|
||||
|
||||
local nalive=0
|
||||
|
||||
if groupset then
|
||||
|
||||
-- Check if groups are still alive
|
||||
local dead={}
|
||||
for _,group in pairs(groupset:GetSetObjects()) do
|
||||
if group and group:IsAlive() then
|
||||
nalive=nalive+1
|
||||
else
|
||||
table.insert(dead, group)
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: Since the cargo groups are de- and re-spawned, does the counting for cargo groups actually work, when they are transported?
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.wid..string.format("FilterDead: Alive=%d, Dead=%d", nalive, #dead))
|
||||
|
||||
-- Remove dead groups
|
||||
local NoTriggerEvent=false
|
||||
for _,group in pairs(dead) do
|
||||
groupset:Remove(group, NoTriggerEvent)
|
||||
end
|
||||
end
|
||||
|
||||
return nalive
|
||||
end
|
||||
|
||||
--- Function that checks if a pending job is done and can be removed from queue
|
||||
-- @param #WAREHOUSE self
|
||||
@ -2113,20 +2083,17 @@ function WAREHOUSE:_JobDone()
|
||||
for _,request in pairs(self.pending) do
|
||||
local request=request --#WAREHOUSE.Pendingitem
|
||||
|
||||
-- Count number of cargo groups still alive and filter out dead groups.
|
||||
-- Count number of cargo groups.
|
||||
local ncargo=0
|
||||
if request.cargogroupset then
|
||||
ncargo=request.cargogroupset:Count()
|
||||
end
|
||||
--=self:_FilterDead(request.cargogroupset)
|
||||
|
||||
-- Count number of transport groups (if any) and filter out dead groups. Dead groups are removed from the set.
|
||||
-- Count number of transport groups (if any).
|
||||
local ntransport=0
|
||||
if request.transportgroupset then
|
||||
request.transportgroupset:Count()
|
||||
end
|
||||
--self:_FilterDead(request.transportgroupset)
|
||||
|
||||
end
|
||||
|
||||
if ncargo==0 and ntransport==0 then
|
||||
|
||||
@ -3091,21 +3058,21 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request)
|
||||
|
||||
elseif Request.transporttype==WAREHOUSE.TransportType.TRAIN then
|
||||
|
||||
self:E(self.wid.."ERROR: cargo transport by train not supported yet!")
|
||||
self:_ErrorMessage("ERROR: Cargo transport by train not supported yet!")
|
||||
return
|
||||
|
||||
elseif Request.transporttype==WAREHOUSE.TransportType.SHIP then
|
||||
|
||||
self:E(self.wid.."ERROR: cargo transport by ship not supported yet!")
|
||||
self:_ErrorMessage("ERROR: Cargo transport by ship not supported yet!")
|
||||
return
|
||||
|
||||
elseif Request.transporttype==WAREHOUSE.TransportType.SELFPROPELLED then
|
||||
|
||||
self:E(self.wid.."ERROR: transport type selfpropelled was already handled above. We should not get here!")
|
||||
self:_ErrorMessage("ERROR: Transport type selfpropelled was already handled above. We should not get here!")
|
||||
return
|
||||
|
||||
else
|
||||
self:E(self.wid.."ERROR: unknown transport type!")
|
||||
self:_ErrorMessage("ERROR: Unknown transport type!")
|
||||
return
|
||||
end
|
||||
|
||||
@ -3130,8 +3097,19 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request)
|
||||
self:_DeleteStockItem(_item)
|
||||
end
|
||||
|
||||
-- Add cargo groups to request.
|
||||
-- Add transport groups, i.e. the carriers to request.
|
||||
Pending.transportgroupset=TransportSet
|
||||
|
||||
-- Add cargo group set.
|
||||
Pending.transportcargoset=CargoGroups
|
||||
|
||||
-- Create empty tables which will be filled with the cargo groups of each carrier unit. Needed in case a carrier unit dies.
|
||||
Pending.carriercargo={}
|
||||
for _,carriergroup in pairs(TransportSet:GetObject()) do
|
||||
for _,carrierunit in pairs(carriergroup:GetUnits()) do
|
||||
Pending.carriercargo[carrierunit:GetName()]={}
|
||||
end
|
||||
end
|
||||
|
||||
-- Add request to pending queue.
|
||||
table.insert(self.pending, Pending)
|
||||
@ -3202,11 +3180,6 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request)
|
||||
-- Dispatcher Event Functions --
|
||||
--------------------------------
|
||||
|
||||
function CargoTransport:OnAfterLoaded(From,Event,To,CarrierGroup,Cargo,CarrierUnit,PickupZone)
|
||||
local text=string.format("FF Carrier group %s loaded cargo %s into unit %s in pickup zone %s", CarrierGroup:GetName(), Cargo:GetObject():GetName(), CarrierUnit:GetName(), PickupZone:GetName())
|
||||
env.info(text)
|
||||
end
|
||||
|
||||
function CargoTransport:OnAfterPickedUp(From,Event,To,CarrierGroup,PickupZone)
|
||||
local text=string.format("FF Carrier group %s picked up event in pickup zone %s.", CarrierGroup:GetName(), PickupZone:GetName())
|
||||
env.info(text)
|
||||
@ -3222,6 +3195,28 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request)
|
||||
env.info(text)
|
||||
end
|
||||
|
||||
--- Function called when a carrier unit has loaded a cargo group.
|
||||
function CargoTransport:OnAfterLoaded(From, Event, To, Carrier, Cargo, CarrierUnit, PickupZone)
|
||||
local text=string.format("FF Carrier group %s loaded cargo %s into unit %s in pickup zone %s", CarrierGroup:GetName(), Cargo:GetObject():GetName(), CarrierUnit:GetName(), PickupZone:GetName())
|
||||
env.info(text)
|
||||
|
||||
-- Get group object.
|
||||
local group=Cargo:GetObject() --Wrapper.Group#GROUP
|
||||
|
||||
-- Get warehouse state.
|
||||
local warehouse=Carrier:GetState(Carrier, "WAREHOUSE") --#WAREHOUSE
|
||||
|
||||
local text=string.format("FF Group %s was loaded into carrier %s.", tostring(group:GetName()), tostring(Carrier:GetName()))
|
||||
env.info(text)
|
||||
|
||||
-- Get request.
|
||||
local request=warehouse:_GetRequestOfGroup(group, warehouse.pending)
|
||||
|
||||
-- Add cargo group to this carrier.
|
||||
table.insert(request.carriercargo[CarrierUnit:GetName()], group)
|
||||
|
||||
end
|
||||
|
||||
--- Function called when cargo has arrived and was unloaded.
|
||||
function CargoTransport:OnAfterUnloaded(From, Event, To, Carrier, Cargo, CarrierUnit, DeployZone)
|
||||
|
||||
@ -4182,32 +4177,160 @@ function WAREHOUSE:_OnEventCrashOrDead(EventData)
|
||||
|
||||
-- Check if an asset unit was destroyed.
|
||||
if EventData and EventData.IniGroup then
|
||||
|
||||
local group=EventData.IniGroup
|
||||
|
||||
-- Get warehouse, asset and request IDs from the group name.
|
||||
local wid,aid,rid=self:_GetIDsFromGroup(group)
|
||||
|
||||
if wid==self.uid then
|
||||
self:T(self.wid..string.format("Warehouse %s captured event dead or crash of its asset unit %s.", self.alias, EventData.IniUnitName))
|
||||
|
||||
-- Loop over all pending requests and get the one belonging to this unit.
|
||||
for _,request in pairs(self.pending) do
|
||||
local request=request --#WAREHOUSE.Pendingitem
|
||||
|
||||
if request.uid==rid then
|
||||
-- Count number of cargo groups still alive and filter out dead groups. Dead groups are removed from the set.
|
||||
local ncargo=self:_FilterDead(request.cargogroupset)
|
||||
|
||||
-- Count number of transport groups (if any) and filter out dead groups. Dead groups are removed from the set.
|
||||
local ntransport=self:_FilterDead(request.transportgroupset)
|
||||
|
||||
self:T(self.wid..string.format("Asset groups left for request id=%d: ncargo=%d, ntransport=%d", rid, ncargo, ntransport))
|
||||
|
||||
-- Update cargo and transport group sets of this request. We need to know if this job is finished.
|
||||
self:_UnitDead(EventData.IniUnit, request)
|
||||
|
||||
--[[
|
||||
if self:_GroupIsTransport(group, request) then
|
||||
-- Count number of transport groups (if any) and filter out dead groups. Dead groups are removed from the set.
|
||||
-- TODO: Now, what about the cargo groups that are inside the transport?! Need to save in which carrier the cargo is?
|
||||
self:_FilterDead(request.transportgroupset)
|
||||
else
|
||||
-- Count number of cargo groups still alive and filter out dead groups. Dead groups are removed from the set.
|
||||
self:_FilterDead(request.cargogroupset)
|
||||
end
|
||||
]]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- A unit of a group just died. Update group sets in request.
|
||||
-- This is important in order to determine if a job is done and can be removed from the (pending) queue.
|
||||
-- @param #WAREHOUSE self
|
||||
-- @param Wrapper.Unit#UNIT deadunit Unit that died.
|
||||
-- @param #WAREHOUSE.Pendingitem request Request that needs to be updated.
|
||||
function WAREHOUSE:_UnitDead(deadunit, request)
|
||||
|
||||
-- Group the dead unit belongs to.
|
||||
local group=deadunit:GetGroup()
|
||||
|
||||
-- Check if this was the last unit of the group ==> whole group dead.
|
||||
local isgroupdead=false
|
||||
local nunits=0
|
||||
if group then
|
||||
local nunits=group:GetSize()
|
||||
-- One (or less) units in group.
|
||||
if nunits<=1 then
|
||||
isgroupdead=true
|
||||
end
|
||||
end
|
||||
|
||||
local text=string.format("Unit %s died! Group %s: #units=%d, IsAlive=%s", deadunit:GetName(), group:GetName(), nunits, tostring(group:IsAlive()))
|
||||
self:E(self.wid..text)
|
||||
|
||||
local NoTriggerEvent=false
|
||||
|
||||
if request.transporttype==WAREHOUSE.TransportType.SELFPROPELLED then
|
||||
|
||||
---
|
||||
-- Easy case: Group can simply be removed from the cargogroupset.
|
||||
---
|
||||
|
||||
-- Remove dead group from carg group set.
|
||||
if isgroupdead==true then
|
||||
request.cargogroupset:Remove(group, NoTriggerEvent)
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
---
|
||||
-- Complicated case: Dead unit could be:
|
||||
-- 1.) A Cargo unit (e.g. waiting to be picked up).
|
||||
-- 2.) A Transport unit which itself holds cargo groups.
|
||||
---
|
||||
|
||||
if self:_GroupIsTransport(group,request) then
|
||||
|
||||
-- Get the carrier unit table holding the cargo groups inside this carrier.
|
||||
local carrierunit=request.carriercargo[deadunit:GetName()]
|
||||
|
||||
if carrierunit then
|
||||
|
||||
-- Loop over all groups inside the carrier ==> all dead.
|
||||
for _,cargogroup in pairs(carrierunit) do
|
||||
|
||||
-- TODO: Check if remove really needs the name? Did I not always use the group object?!
|
||||
--request.cargogroupset:Remove(ObjectName,NoTriggerEvent)
|
||||
request.cargogroupset:Remove(cargogroup,NoTriggerEvent)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Whole carrier group is dead. Remove it from the carrier group set.
|
||||
if isgroupdead then
|
||||
request.transportcargoset:Remove(group, NoTriggerEvent)
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
-- This must have been an alive cargo group that was killed outside the carrier, e.g. waiting to be transported or waiting to be put back.
|
||||
-- Remove dead group from cargo group set.
|
||||
if isgroupdead==true then
|
||||
|
||||
request.cargogroupset:Remove(group, NoTriggerEvent)
|
||||
|
||||
-- TODO: This as well?
|
||||
--request.transportcargoset:RemoveCargosByName(RemoveCargoNames)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Count alive and filter dead groups.
|
||||
-- @param #WAREHOUSE self
|
||||
-- @param Core.Set#SET_GROUP groupset Set of groups. Dead groups are removed from the set.
|
||||
-- @return #number Number of alive groups. Returns zero if groupset is nil.
|
||||
function WAREHOUSE:_FilterDead(groupset)
|
||||
|
||||
local nalive=0
|
||||
|
||||
if groupset then
|
||||
|
||||
-- Check if groups are still alive
|
||||
local dead={}
|
||||
for _,group in pairs(groupset:GetSetObjects()) do
|
||||
if group and group:IsAlive() then
|
||||
nalive=nalive+1
|
||||
else
|
||||
table.insert(dead, group)
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: Since the cargo groups are de- and re-spawned, does the counting for cargo groups actually work, when they are transported?
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.wid..string.format("FilterDead: Alive=%d, Dead=%d", nalive, #dead))
|
||||
|
||||
-- Remove dead groups
|
||||
local NoTriggerEvent=false
|
||||
for _,group in pairs(dead) do
|
||||
groupset:Remove(group, NoTriggerEvent)
|
||||
end
|
||||
end
|
||||
|
||||
return nalive
|
||||
end
|
||||
|
||||
|
||||
--- Warehouse event handling function.
|
||||
-- Handles the case when the airbase associated with the warehous is captured.
|
||||
-- @param #WAREHOUSE self
|
||||
@ -5674,7 +5797,6 @@ function WAREHOUSE:_DisplayStatus()
|
||||
local text=string.format("\n------------------------------------------------------\n")
|
||||
text=text..string.format("Warehouse %s status: %s\n", self.alias, self:GetState())
|
||||
text=text..string.format("------------------------------------------------------\n")
|
||||
--text=text..string.format("Current status = %s\n", )
|
||||
text=text..string.format("Coalition side = %d\n", self.coalition)
|
||||
text=text..string.format("Country name = %d\n", self.country)
|
||||
text=text..string.format("Airbase name = %s\n", airbasename)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user