diff --git a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua index 8ce9bcb42..be200d882 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua @@ -132,7 +132,7 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet ) AirplaneUnit:SetCargoBayWeightLimit() end - self.Relocating = true + self.Relocating = false --FF should be false or set according to state of airplane! return self end diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua index 94e67686a..777c3cff8 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua @@ -127,8 +127,8 @@ function AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo ) self:AddTransition( "*", "BackHome", "*" ) --FF self.MonitorTimeInterval = 30 - self.DeployRadiusInner = 200 - self.DeployRadiusOuter = 500 + self.DeployInnerRadius = 200 + self.DeployOuterRadius = 500 self.PickupCargo = {} self.CarrierHome = {} @@ -231,19 +231,6 @@ function AI_CARGO_DISPATCHER:SetHomeBase( HomeBase ) end ---- Set the home base. --- When there is nothing anymore to pickup, the carriers will return to their home airbase. There they will await new orders. --- @param #AI_CARGO_DISPATCHER self --- @param Wrapper.Airbase#AIRBASE HomeBase The airbase where the carrier will go to, once they completed all pending assignments. --- @return #AI_CARGO_DISPATCHER self -function AI_CARGO_DISPATCHER:SetHomeBase( HomeBase ) - - self.HomeBase = HomeBase - - return self -end - - --- Sets or randomizes the pickup location for the carrier around the cargo coordinate in a radius defined an outer and optional inner radius. -- This radius is influencing the location where the carrier will land to pickup the cargo. -- There are two aspects that are very important to remember and take into account: @@ -368,12 +355,13 @@ end -- @param #AI_CARGO_DISPATCHER self function AI_CARGO_DISPATCHER:onafterMonitor() - env.info("FF number of cargo set = "..self.SetCargo:Count()) - for CarrierGroupName, Carrier in pairs( self.SetCarrier:GetSet() ) do + env.info("FF cargo dispatcher carrier group "..CarrierGroupName) + local Carrier = Carrier -- Wrapper.Group#GROUP local AI_Cargo = self.AI_Cargo[Carrier] if not AI_Cargo then + env.info("FF not AI CARGO") -- ok, so this Carrier does not have yet an AI_CARGO handling object... -- let's create one and also declare the Loaded and UnLoaded handlers. @@ -404,10 +392,15 @@ function AI_CARGO_DISPATCHER:onafterMonitor() self:Unloaded( Carrier, Cargo ) end - -- FF added back home event. + -- FF added BackHome event. function AI_Cargo.OnAfterBackHome( AI_Cargo, Carrier, From, Event, To) self:BackHome( Carrier ) end + + -- FF added RTB event. + function AI_Cargo.OnAfterRTB( AI_Cargo, Carrier, From, Event, To, Airbase) + self:RTB( Carrier, Airbase ) + end end -- The Pickup sequence ... @@ -459,6 +452,7 @@ function AI_CARGO_DISPATCHER:onafterMonitor() end if PickupCargo then + self.CarrierHome[Carrier] = nil local PickupCoordinate = PickupCargo:GetCoordinate():GetRandomCoordinateInRadius( self.PickupOuterRadius, self.PickupInnerRadius ) @@ -472,18 +466,34 @@ function AI_CARGO_DISPATCHER:onafterMonitor() AI_Cargo:Pickup( PickupCoordinate, math.random( self.PickupMinSpeed, self.PickupMaxSpeed ) ) end break + else + + env.info("FF HomeZone or HomeBase?") if self.HomeZone then + + env.info("FF HomeZone! Really?") if not self.CarrierHome[Carrier] then + env.info("FF Yes!") self.CarrierHome[Carrier] = true AI_Cargo:__Home( 60, self.HomeZone:GetRandomPointVec2() ) + else + env.info("FF Nope!") end - elseif self.HomeBase then + + elseif self.HomeBase2 then + + env.info("FF HomeBase! Really?") if not self.CarrierHome[Carrier] then + env.info("FF Yes!") self.CarrierHome[Carrier] = true - AI_Cargo:__RTB( 60, self.HomeBase ) - end + AI_Cargo:__RTB( 1, self.HomeBase ) + else + env.info("FF Nope!") + end + end + end end end diff --git a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua index e40f357a4..46cf934a5 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua @@ -827,16 +827,6 @@ function AI_CARGO_HELICOPTER:onafterHome( Helicopter, From, Event, To, Coordinat Tasks[#Tasks+1] = Helicopter:TaskLandAtVec2( CoordinateTo:GetVec2() ) Route[#Route].task = Helicopter:TaskCombo( Tasks ) - -- FF - --[[ - local Tasks2 = {} - Tasks2[#Tasks2+1] = Helicopter:TaskFunction("AI_CARGO_HELICOPTER._BackHome", self) - - Route[#Route+1] = WaypointTo - Route[#Route].task = Helicopter:TaskCombo( Tasks2 ) - -- FF - ]] - Route[#Route+1] = WaypointTo -- Now route the helicopter @@ -930,9 +920,10 @@ end --- Function called when transport is back home and nothing more to do. Triggering the event BackHome. -- @param Wrapper.Group#GROUP Helicopter Cargo helicopter. -- @param #AI_CARGO_HELICOPTER self -function AI_CARGO_HELICOPTER._BackHome(Group, self) - --Trigger BackHome event. +function AI_CARGO_HELICOPTER._BackHome(Group, self) + env.info("FF ai cargo helicopter back home task function") Group:SmokeRed() + --Trigger BackHome event. self:__BackHome(1) end @@ -944,5 +935,6 @@ end -- @param Event -- @param To function AI_CARGO_HELICOPTER:onafterBackHome( Helicopter, From, Event, To ) + env.info("FF ai cargo helicopter back home event") Helicopter:SmokeRed() end \ No newline at end of file diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 7cf4dacc8..410c17c82 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -636,7 +636,7 @@ function SET_BASE:Flush( MasterObject ) for ObjectName, Object in pairs( self.Set ) do ObjectNames = ObjectNames .. ObjectName .. ", " end - self:I( { MasterObject = MasterObject and MasterObject:GetClassNameAndID(), "Objects in Set:", ObjectNames } ) + self:T( { MasterObject = MasterObject and MasterObject:GetClassNameAndID(), "Objects in Set:", ObjectNames } ) return ObjectNames end diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index 9feccd938..c51d69f4e 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -48,7 +48,7 @@ -- @field #table defending Table holding all defending requests, i.e. self requests that were if the warehouse is under attack. Table elements are of type @{#WAREHOUSE.Pendingitem}. -- @field Core.Zone#ZONE portzone Zone defining the port of a warehouse. This is where naval assets are spawned. -- @field #table shippinglanes Table holding the user defined shipping between warehouses. --- @field #boolean selfdefence When the warehouse is under attack, automatically spawn assets to defend the warehouse. +-- @field #boolean autodefence When the warehouse is under attack, automatically spawn assets to defend the warehouse. -- @extends Core.Fsm#FSM --- Have your assets at the right place at the right time - or not! @@ -135,7 +135,7 @@ -- Assets of the warehouse can be requested by other MOOSE warehouses. A request will first be scrutinize to check if can be fulfilled at all. If the request is valid, it is -- put into the warehouse queue and processed as soon as possible. -- --- A request can be assed by the @{#WAREHOUSE.AddRequest}(*warehouse*, *AssetDescriptor*, *AssetDescriptorValue*, *nAsset*, *TransportType*, *nTransport*, *Prio*) function. +-- A request can be assed by the @{#WAREHOUSE.AddRequest}(*warehouse*, *AssetDescriptor*, *AssetDescriptorValue*, *nAsset*, *TransportType*, *nTransport*, *Prio*, *Assignment*) function. -- The parameters are -- -- * *warehouse*: The requesting MOOSE @{#WAREHOUSE}. Assets will be delivered there. @@ -144,7 +144,8 @@ -- * *nAsset*: (Optional) Number of asset group requested. Default is one group. -- * *TransportType*: (Optional) The transport method used to deliver the assets to the requestor. Default is that assets go to the requesting warehouse on their own. -- * *nTransport*: (Optional) Number of asset groups used to transport the cargo assets from A to B. Default is one group. --- * *Prio*: A number between 1 (high) and 100 (low) describing the priority of the request. Request with high priority are processed first. Default is 50, i.e. medium priority. +-- * *Prio*: (Optional) A number between 1 (high) and 100 (low) describing the priority of the request. Request with high priority are processed first. Default is 50, i.e. medium priority. +-- * *Assignment*: (Optional) A free to choose string describing the assignment. For self requests, this can be used to assign the spawned groups to specific tasks. -- -- So for example: -- @@ -348,7 +349,7 @@ WAREHOUSE = { defending = {}, portzone = nil, shippinglanes = {}, - selfdefence = false, + autodefence = false, } --- Item of the warehouse stock table. @@ -488,7 +489,7 @@ WAREHOUSE.db = { --- Warehouse class version. -- @field #string version -WAREHOUSE.version="0.3.2" +WAREHOUSE.version="0.3.3" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO: Warehouse todo list. @@ -498,7 +499,7 @@ WAREHOUSE.version="0.3.2" -- TODO: Add autoselfdefence switch and user function. Default should be off. -- DONE: Warehouse re-capturing not working?! -- DONE: Naval assets dont go back into stock once arrived. --- TODO: Take cargo weight into consideration, when selecting transport assets. +-- DONE: Take cargo weight into consideration, when selecting transport assets. -- TODO: Add transport units from dispatchers back to warehouse stock once they completed their mission. -- DONE: Add ports for spawning naval assets. -- TODO: Added habours as interface for transport to from warehouses? @@ -683,8 +684,8 @@ function WAREHOUSE:New(warehouse, alias) -- @param #number nAsset Number of groups requested that match the asset specification. -- @param #WAREHOUSE.TransportType TransportType Type of transport. -- @param #number nTransport Number of transport units requested. - -- @param #string Assignment A keyword or text that later be used to identify this request and postprocess the assets. -- @param #number Prio Priority of the request. Number ranging from 1=high to 100=low. + -- @param #string Assignment A keyword or text that later be used to identify this request and postprocess the assets. --- Triggers the FSM event "AddRequest" with a delay. Add a request to the warehouse queue, which is processed when possible. -- @function [parent=#WAREHOUSE] __AddRequest @@ -696,8 +697,8 @@ function WAREHOUSE:New(warehouse, alias) -- @param #number nAsset Number of groups requested that match the asset specification. -- @param #WAREHOUSE.TransportType TransportType Type of transport. -- @param #number nTransport Number of transport units requested. - -- @param #string Assignment A keyword or text that later be used to identify this request and postprocess the assets. -- @param #number Prio Priority of the request. Number ranging from 1=high to 100=low. + -- @param #string Assignment A keyword or text that later be used to identify this request and postprocess the assets. --- Triggers the FSM event "Request". Executes a request from the queue if possible. @@ -845,7 +846,39 @@ end -- User functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Set interval of status updates +--- Set debug mode on. Error messages will be displayed on screen, units will be smoked at some events. +-- @param #WAREHOUSE self +-- @return #WAREHOUSE self +function WAREHOUSE:SetDebugOn() + self.Debug=true + return self +end + +--- Set debug mode off. This is the default +-- @param #WAREHOUSE self +-- @return #WAREHOUSE self +function WAREHOUSE:SetDebugOff() + self.Debug=false + return self +end + +--- Set report on. Messages at events will be displayed on screen to the coalition owning the warehouse. +-- @param #WAREHOUSE self +-- @return #WAREHOUSE self +function WAREHOUSE:SetReportOn() + self.Report=true + return self +end + +--- Set report off. Warehouse does not report about its status and at certain events. +-- @param #WAREHOUSE self +-- @return #WAREHOUSE self +function WAREHOUSE:SetReportOff() + self.Report=false + return self +end + +--- Set interval of status updates. Note that only one request can be processed per time interval. -- @param #WAREHOUSE self -- @param #number timeinterval Time interval in seconds. -- @return #WAREHOUSE self @@ -872,6 +905,23 @@ function WAREHOUSE:SetWarehouseZone(zone) return self end +--- Set auto defence on. When the warehouse is under attack, all ground assets are spawned automatically and will defend the warehouse zone. +-- @param #WAREHOUSE self +-- @return #WAREHOUSE self +function WAREHOUSE:SetAutoDefenceOn() + self.autodefence=true + return self +end + +--- Set auto defence off. This is the default. +-- @param #WAREHOUSE self +-- @return #WAREHOUSE self +function WAREHOUSE:SetAutoDefenceOff() + self.autodefence=false + return self +end + + --- Set the airbase belonging to this warehouse. -- Note that it has to be of the same coalition as the warehouse. -- Also, be reasonable and do not put it too far from the phyiscal warehouse structure because you troops might have a long way to get to their transports. @@ -956,8 +1006,6 @@ function WAREHOUSE:AddShippingLane(remotewarehouse, group) -- Add the shipping lane. Need to take care of the wrong "direction". local lane={} - --lane.towarehouse=remotewarehouse.warehouse:GetName() - --lane.coordinates={} if distF0 then + self:AddRequest(self, WAREHOUSE.Descriptor.CATEGORY, Group.Category.GROUND, "all", nil, nil , 0) + else + local text=string.format("No ground assets currently available.") + MESSAGE:New(text, 20):ToCoalitionIf(self.coalition, self.Report or self.Debug) + self:I(self.wid..text) + end + else + local text=string.format("Warehouse auto defence inactive.") + self:I(self.wid..text) end end @@ -2595,28 +2681,35 @@ function WAREHOUSE:onafterDefeated(From, Event, To) MESSAGE:New(text, 20):ToCoalitionIf(self.coalition, self.Report or self.Debug) self:I(self.wid..text) - --if self.defenderrequest then - for _,request in pairs(self.defending) do + -- Debug smoke. + if self.Debug then + self.coordinate:SmokeGreen() + end + + -- Auto defence: put assets back into stock. + if self.autodefence then + for _,request in pairs(self.defending) do + + -- Route defenders back to warehoue (for visual reasons only) and put them back into stock. + for _,_group in pairs(request.cargogroupset:GetSetObjects()) do + local group=_group --Wrapper.Group#GROUP + + -- Get max speed of group and route it back slowly to the warehouse. + local speed=group:GetSpeedMax() + if group:IsGround() and speed>1 then + group:RouteGroundTo(self.coordinate, speed*0.3) + end + + -- Add asset group back to stock after 60 seconds. + self:__AddAsset(60, group) + end - -- Route defenders back to warehoue (for visual reasons only) and put them back into stock. - for _,_group in pairs(request.cargogroupset:GetSetObjects()) do - local group=_group --Wrapper.Group#GROUP - - -- Get max speed of group and route it back slowly to the warehouse. - local speed=group:GetSpeedMax() - if group:IsGround() and speed>1 then - group:RouteGroundTo(self.coordinate, speed*0.3) - end - - -- Add asset group back to stock after 60 seconds. - self:__AddAsset(60, group) + --self:_DeleteQueueItem(request, self.defending) end - --self:_DeleteQueueItem(request, self.defending) + self.defending=nil + self.defending={} end - - self.defending=nil - self.defending={} end --- On after "Captured" event. Warehouse has been captured by another coalition. @@ -2643,10 +2736,6 @@ function WAREHOUSE:onafterCaptured(From, Event, To, Coalition, Country) -- Delete all waiting requests because they are not valid any more self.queue=nil self.queue={} - - --TODO: What about pending items? Is there any problem due to the coalition change? - --TODO: Maybe if the receiving warehouse gets captured! Oh, oh :( - -- What to do? send the items back? Impossible. -- Airbase could have been captured before and already belongs to the new coalition. local airbase=AIRBASE:FindByName(self.airbasename) @@ -2661,6 +2750,15 @@ function WAREHOUSE:onafterCaptured(From, Event, To, Coalition, Country) self.airbase=nil self.category=-1 end + + -- Debug smoke. + if self.Debug then + if Coalition==coalition.side.RED then + self.coordinate:SmokeRed() + elseif Coalition==coalition.side.BLUE then + self.coordinate:SmokeBlue() + end + end end @@ -2678,8 +2776,14 @@ function WAREHOUSE:onafterAirbaseCaptured(From, Event, To, Coalition) self:I(self.wid..text) -- Debug smoke. - self.airbase:GetCoordinate():SmokeRed() - + if self.Debug then + if Coalition==coalition.side.RED then + self.airbase:GetCoordinate():SmokeRed() + elseif Coalition==coalition.side.BLUE then + self.airbase:GetCoordinate():SmokeBlue() + end + end + -- Set airbase to nil and category to no airbase. self.airbase=nil self.category=-1 -- -1 indicates no airbase. @@ -2703,7 +2807,14 @@ function WAREHOUSE:onafterAirbaseRecaptured(From, Event, To, Coalition) self.category=self.airbase:GetDesc().category -- Debug smoke. - self.airbase:GetCoordinate():SmokeGreen() + if self.Debug then + if Coalition==coalition.side.RED then + self.airbase:GetCoordinate():SmokeRed() + elseif Coalition==coalition.side.BLUE then + self.airbase:GetCoordinate():SmokeBlue() + end + end + end @@ -2959,7 +3070,6 @@ function WAREHOUSE:_OnEventBirth(EventData) if EventData and EventData.IniGroup then local group=EventData.IniGroup - -- env.info(string.format("FF birth of group %s (alive=%s) unit %s", tostring(EventData.IniGroupName), tostring(EventData.IniGroup:IsAlive()), tostring(EventData.IniUnitName))) -- Note: Remember, group:IsAlive might(?) not return true here. local wid,aid,rid=self:_GetIDsFromGroup(group) if wid==self.uid then @@ -2980,7 +3090,7 @@ function WAREHOUSE:_OnEventEngineStartup(EventData) local group=EventData.IniGroup local wid,aid,rid=self:_GetIDsFromGroup(group) if wid==self.uid then - self:E(self.wid..string.format("Warehouse %s captured event engine startup of its asset unit %s.", self.alias, EventData.IniUnitName)) + self:I(self.wid..string.format("Warehouse %s captured event engine startup of its asset unit %s.", self.alias, EventData.IniUnitName)) end end end @@ -2995,7 +3105,7 @@ function WAREHOUSE:_OnEventTakeOff(EventData) local group=EventData.IniGroup local wid,aid,rid=self:_GetIDsFromGroup(group) if wid==self.uid then - self:E(self.wid..string.format("Warehouse %s captured event takeoff of its asset unit %s.", self.alias, EventData.IniUnitName)) + self:I(self.wid..string.format("Warehouse %s captured event takeoff of its asset unit %s.", self.alias, EventData.IniUnitName)) end end end @@ -3010,7 +3120,7 @@ function WAREHOUSE:_OnEventLanding(EventData) local group=EventData.IniGroup local wid,aid,rid=self:_GetIDsFromGroup(group) if wid==self.uid then - self:E(self.wid..string.format("Warehouse %s captured event landing of its asset unit %s.", self.alias, EventData.IniUnitName)) + self:I(self.wid..string.format("Warehouse %s captured event landing of its asset unit %s.", self.alias, EventData.IniUnitName)) -- Get request of this group local request=self:_GetRequestOfGroup(group,self.pending) @@ -3019,7 +3129,7 @@ function WAREHOUSE:_OnEventLanding(EventData) -- TODO: I might need to add a delivered table, to be better able to get this right. if request==nil then - -- Check if helicopter landed in spawn zone. If so, we call it a day and add it back to stock. + -- Check if helicopter landed in spawn zone. If so, we call it a day and add it back to stock. if group:GetCategory()==Group.Category.HELICOPTER then if self.spawnzone:IsCoordinateInZone(EventData.IniUnit:GetCoordinate()) then group:SmokeWhite() @@ -3542,11 +3652,11 @@ function WAREHOUSE:_CheckRequestNow(request) -- Assume request is okay and check scenarios. local okay=true - -- Check if receiving warehouse is running. - if not request.warehouse:IsRunning() then + -- Check if receiving warehouse is running. We do allow self requests if the warehouse is under attack though! + if (not request.warehouse:IsRunning()) and (not request.toself and self:IsAttacked()) then local text=string.format("Warehouse %s: Request denied! Receiving warehouse %s is not running. Current state %s.", self.alias, request.warehouse.alias, request.warehouse:GetState()) MESSAGE:New(text, 5):ToCoalitionIf(self.coalition, self.Report or self.Debug) - self:E(self.wid..text) + self:I(self.wid..text) return false end @@ -3558,7 +3668,7 @@ function WAREHOUSE:_CheckRequestNow(request) if not _enough then local text=string.format("Warehouse %s: Request denied! Not enough (cargo) assets currently available.", self.alias) MESSAGE:New(text, 5):ToCoalitionIf(self.coalition, self.Report or self.Debug) - self:E(self.wid..text) + self:I(self.wid..text) return false end @@ -3577,9 +3687,9 @@ function WAREHOUSE:_CheckRequestNow(request) --if Parking==nil and not (self.category==Airbase.Category.HELIPAD) then if Parking==nil then - local text=string.format("Warehouse %s: Request denied! Not enough free parking spots for all assets at the moment.", self.alias) + local text=string.format("Warehouse %s: Request denied! Not enough free parking spots for all requested assets at the moment.", self.alias) MESSAGE:New(text, 5):ToCoalitionIf(self.coalition, self.Report or self.Debug) - self:E(self.wid..text) + self:I(self.wid..text) return false end @@ -3612,7 +3722,7 @@ function WAREHOUSE:_CheckRequestNow(request) if Parking==nil then local text=string.format("Warehouse %s: Request denied! Not enough free parking spots for all transports at the moment.", self.alias) MESSAGE:New(text, 5):ToCoalitionIf(self.coalition, self.Report or self.Debug) - self:E(self.wid..text) + self:I(self.wid..text) return false end @@ -3628,7 +3738,7 @@ function WAREHOUSE:_CheckRequestNow(request) -- Not enough or the right transport carriers. local text=string.format("Warehouse %s: Request denied! Not enough transport carriers available at the moment.", self.alias) MESSAGE:New(text, 5):ToCoalitionIf(self.coalition, self.Report or self.Debug) - self:E(self.wid..text) + self:I(self.wid..text) return false end @@ -4173,16 +4283,16 @@ function WAREHOUSE:_FilterStock(stock, item, value, nmax) if type(nmax)=="string" then if nmax:lower()=="all" then nmax=ntot + elseif nmax:lower()=="threequarter" then + nmax=ntot*3/4 elseif nmax:lower()=="half" then nmax=ntot/2 elseif nmax:lower()=="third" then - nmax=ntot/3 + nmax=ntot/3 elseif nmax:lower()=="quarter" then nmax=ntot/4 - elseif nmax:lower()=="fivth" then - nmax=ntot/5 else - nmax=math.min(1,ntot) + nmax=math.min(1, ntot) end end @@ -4229,10 +4339,6 @@ function WAREHOUSE:_GetAttribute(groupname) local attribute=WAREHOUSE.Attribute.UNKNOWN --#WAREHOUSE.Attribute if group then - - -- Get generalized attributes. - -- TODO: need to work on ships and trucks and SAMs and ... - -- Also the Yak-52 for example is OTHER since it only has the attribute "Battleplanes". ----------- --- Air --- @@ -4486,15 +4592,18 @@ function WAREHOUSE:_UpdateWarehouseMarkText() -- Get assets in stock. local _data=self:GetStockInfo(self.stock) - - -- Create mark text. - local marktext="Warehouse stock:\n" - for _attribute,_count in pairs(_data) do - marktext=marktext..string.format("%s=%d, ", _attribute,_count) -- Dont use \n because too many make DCS crash! - end + -- Text. + local text="Warehouse Stock:\n" + text=text..string.format("Total assets: %d\n", #_data) + local total=0 + for _attribute,_count in pairs(_data) do + local attribute=tostring(UTILS.Split(_attribute, "_")[2]) + text=text..string.format("%s=%d", attribute,_count) + end + -- Create/update marker at warehouse in F10 map. - self.markerid=self.coordinate:MarkToCoalition(marktext, self.coalition, true) + self.markerid=self.coordinate:MarkToCoalition(text, self.coalition, true) end --- Display stock items of warehouse.