From 29ed630536ef4429f425da52f927f7c972d2a37d Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 13 Aug 2023 17:40:28 +0200 Subject: [PATCH 1/3] COORDINATE - Generalized MarkupToAllFreeForm UTILS - Added some functions from MIST --- Moose Development/Moose/Core/Point.lua | 26 +++- Moose Development/Moose/Utilities/Utils.lua | 160 +++++++++++++++++++- 2 files changed, 181 insertions(+), 5 deletions(-) diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index d942e49ba..99e8eb593 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -2389,7 +2389,6 @@ do -- COORDINATE end --- Creates a free form shape on the F10 map. The first point is the current COORDINATE. The remaining points need to be specified. - -- **NOTE**: A free form polygon must have **at least three points** in total and currently only **up to 15 points** in total are supported. -- @param #COORDINATE self -- @param #table Coordinates Table of coordinates of the remaining points of the shape. -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. @@ -2463,9 +2462,30 @@ do -- COORDINATE vecs[11], vecs[12], vecs[13], vecs[14], vecs[15], Color, FillColor, LineType, ReadOnly, Text or "") else - self:E("ERROR: Currently a free form polygon can only have 15 points in total!") + -- Unfortunately, unpack(vecs) does not work! So no idea how to generalize this :( - trigger.action.markupToAll(7, Coalition, MarkID, unpack(vecs), Color, FillColor, LineType, ReadOnly, Text or "") + --trigger.action.markupToAll(7, Coalition, MarkID, unpack(vecs), Color, FillColor, LineType, ReadOnly, Text or "") + + -- Write command as string and execute that. Idea by Grimes https://forum.dcs.world/topic/324201-mark-to-all-function/#comment-5273793 + local s=string.format("trigger.action.markupToAll(7, %d, %d,", Coalition, MarkID) + for _,vec in pairs(vecs) do + s=s..string.format("%s,", UTILS._OneLineSerialize(vec)) + end + s=s..string.format("%s, %s, %s, %s", UTILS._OneLineSerialize(Color), UTILS._OneLineSerialize(FillColor), tostring(LineType), tostring(ReadOnly)) + if Text and Text~="" then + s=s..string.format(", \"%s\"", Text) + end + s=s..")" + + + -- Execute string command + local success=UTILS.DoString(s) + + if not success then + self:E("ERROR: Could not draw polygon") + env.info(s) + end + end return MarkID diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 7b0467ed1..cc5f1df8b 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -293,8 +293,9 @@ UTILS.DeepCopy = function(object) end ---- Porting in Slmod's serialize_slmod2. +--- Serialize a given table. -- @param #table tbl Input table. +-- @return #string Table as a string. UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function lookup_table = {} @@ -371,7 +372,54 @@ UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a s return objectreturn end ---porting in Slmod's "safestring" basic serialize +--- Serialize a table to a single line string. +-- @param #table tbl table to serialize. +-- @return #string string containing serialized table. +function UTILS._OneLineSerialize(tbl) + + if type(tbl) == 'table' then --function only works for tables! + + local tbl_str = {} + + tbl_str[#tbl_str + 1] = '{ ' + + for ind,val in pairs(tbl) do -- serialize its fields + if type(ind) == "number" then + tbl_str[#tbl_str + 1] = '[' + tbl_str[#tbl_str + 1] = tostring(ind) + tbl_str[#tbl_str + 1] = '] = ' + else --must be a string + tbl_str[#tbl_str + 1] = '[' + tbl_str[#tbl_str + 1] = UTILS.BasicSerialize(ind) + tbl_str[#tbl_str + 1] = '] = ' + end + + if ((type(val) == 'number') or (type(val) == 'boolean')) then + tbl_str[#tbl_str + 1] = tostring(val) + tbl_str[#tbl_str + 1] = ', ' + elseif type(val) == 'string' then + tbl_str[#tbl_str + 1] = UTILS.BasicSerialize(val) + tbl_str[#tbl_str + 1] = ', ' + elseif type(val) == 'nil' then -- won't ever happen, right? + tbl_str[#tbl_str + 1] = 'nil, ' + elseif type(val) == 'table' then + tbl_str[#tbl_str + 1] = UTILS._OneLineSerialize(val) + tbl_str[#tbl_str + 1] = ', ' --I think this is right, I just added it + else + --log:warn('Unable to serialize value type $1 at index $2', mist.utils.basicSerialize(type(val)), tostring(ind)) + end + + end + + tbl_str[#tbl_str + 1] = '}' + return table.concat(tbl_str) + else + return UTILS.BasicSerialize(tbl) + end +end + +--- Basic serialize (porting in Slmod's "safestring" basic serialize). +-- @param #string s Table to serialize. UTILS.BasicSerialize = function(s) if s == nil then return "\"\"" @@ -402,6 +450,114 @@ function UTILS.PrintTableToLog(table, indent) end end +--- Returns table in a easy readable string representation. +-- @param tbl table to show +-- @param loc +-- @param indent +-- @param tableshow_tbls +-- @return Human readable string representation of given table. +function UTILS.TableShow(tbl, loc, indent, tableshow_tbls) + tableshow_tbls = tableshow_tbls or {} --create table of tables + loc = loc or "" + indent = indent or "" + if type(tbl) == 'table' then --function only works for tables! + tableshow_tbls[tbl] = loc + + local tbl_str = {} + + tbl_str[#tbl_str + 1] = indent .. '{\n' + + for ind,val in pairs(tbl) do -- serialize its fields + if type(ind) == "number" then + tbl_str[#tbl_str + 1] = indent + tbl_str[#tbl_str + 1] = loc .. '[' + tbl_str[#tbl_str + 1] = tostring(ind) + tbl_str[#tbl_str + 1] = '] = ' + else + tbl_str[#tbl_str + 1] = indent + tbl_str[#tbl_str + 1] = loc .. '[' + tbl_str[#tbl_str + 1] = UTILS.BasicSerialize(ind) + tbl_str[#tbl_str + 1] = '] = ' + end + + if ((type(val) == 'number') or (type(val) == 'boolean')) then + tbl_str[#tbl_str + 1] = tostring(val) + tbl_str[#tbl_str + 1] = ',\n' + elseif type(val) == 'string' then + tbl_str[#tbl_str + 1] = UTILS.BasicSerialize(val) + tbl_str[#tbl_str + 1] = ',\n' + elseif type(val) == 'nil' then -- won't ever happen, right? + tbl_str[#tbl_str + 1] = 'nil,\n' + elseif type(val) == 'table' then + if tableshow_tbls[val] then + tbl_str[#tbl_str + 1] = tostring(val) .. ' already defined: ' .. tableshow_tbls[val] .. ',\n' + else + tableshow_tbls[val] = loc .. '[' .. UTILS.BasicSerialize(ind) .. ']' + tbl_str[#tbl_str + 1] = tostring(val) .. ' ' + tbl_str[#tbl_str + 1] = UTILS.TableShow(val, loc .. '[' .. UTILS.BasicSerialize(ind).. ']', indent .. ' ', tableshow_tbls) + tbl_str[#tbl_str + 1] = ',\n' + end + elseif type(val) == 'function' then + if debug and debug.getinfo then + local fcnname = tostring(val) + local info = debug.getinfo(val, "S") + if info.what == "C" then + tbl_str[#tbl_str + 1] = string.format('%q', fcnname .. ', C function') .. ',\n' + else + if (string.sub(info.source, 1, 2) == [[./]]) then + tbl_str[#tbl_str + 1] = string.format('%q', fcnname .. ', defined in (' .. info.linedefined .. '-' .. info.lastlinedefined .. ')' .. info.source) ..',\n' + else + tbl_str[#tbl_str + 1] = string.format('%q', fcnname .. ', defined in (' .. info.linedefined .. '-' .. info.lastlinedefined .. ')') ..',\n' + end + end + + else + tbl_str[#tbl_str + 1] = 'a function,\n' + end + else + tbl_str[#tbl_str + 1] = 'unable to serialize value type ' .. UTILS.BasicSerialize(type(val)) .. ' at index ' .. tostring(ind) + end + end + + tbl_str[#tbl_str + 1] = indent .. '}' + return table.concat(tbl_str) + end +end + +--- Dumps the global table _G. +-- This dumps the global table _G to a file in the DCS\Logs directory. +-- This function requires you to disable script sanitization in $DCS_ROOT\Scripts\MissionScripting.lua to access lfs and io libraries. +-- @param #string fname File name. +function UTILS.Gdump(fname) + if lfs and io then + + local fdir = lfs.writedir() .. [[Logs\]] .. fname + + local f = io.open(fdir, 'w') + + f:write(UTILS.TableShow(_G)) + + f:close() + + env.info(string.format('Wrote debug data to $1', fdir)) + else + env.error("WARNING: lfs and/or io not de-sanitized - cannot dump _G!") + end +end + +--- Executes the given string. +-- borrowed from Slmod +-- @param #string s string containing LUA code. +-- @return #boolean `true` if successfully executed, `false` otherwise. +function UTILS.DoString(s) + local f, err = loadstring(s) + if f then + return true, f() + else + return false, err + end +end + UTILS.ToDegree = function(angle) return angle*180/math.pi From 32e1d4f8fad6a5bcee0a424746ffc3a928c804ba Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 16 Aug 2023 23:58:32 +0200 Subject: [PATCH 2/3] DCS Warehouse --- Moose Development/Moose/DCS.lua | 95 +++++++- Moose Development/Moose/Modules.lua | 1 + Moose Development/Moose/Wrapper/Storage.lua | 247 ++++++++++++++++++++ Moose Setup/Moose.files | 1 + 4 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 Moose Development/Moose/Wrapper/Storage.lua diff --git a/Moose Development/Moose/DCS.lua b/Moose Development/Moose/DCS.lua index ee1c9e9d7..46a7ded63 100644 --- a/Moose Development/Moose/DCS.lua +++ b/Moose Development/Moose/DCS.lua @@ -793,11 +793,104 @@ do -- Airbase -- @function [parent=#Airbase] getDesc -- @param self -- @return #Airbase.Desc - + + --- Returns the warehouse object associated with the airbase object. Can then be used to call the warehouse class functions to modify the contents of the warehouse. + -- @function [parent=#Airbase] getWarehouse + -- @param self + -- @return #Warehouse The DCS warehouse object of this airbase. + + --- Enables or disables the airbase and FARP auto capture game mechanic where ownership of a base can change based on the presence of ground forces or the default setting assigned in the editor. + -- @function [parent=#Airbase] autoCapture + -- @param self + -- @param #boolean setting `true` : enables autoCapture behavior, `false` : disables autoCapture behavior + + --- Returns the current autoCapture setting for the passed base. + -- @function [parent=#Airbase] autoCaptureIsOn + -- @param self + -- @return #boolean `true` if autoCapture behavior is enabled and `false` otherwise. + + --- Changes the passed airbase object's coalition to the set value. Must be used with Airbase.autoCapture to disable auto capturing of the base, otherwise the base can revert back to a different coalition depending on the situation and built in game capture rules. + -- @function [parent=#Airbase] setCoalition + -- @param self + -- @param #number coa The new owner coalition: 0=neutra, 1=red, 2=blue. + Airbase = {} --#Airbase end -- Airbase + +do -- Warehouse + + --- [DCS Class Warehouse](https://wiki.hoggitworld.com/view/DCS_Class_Warehouse) + -- The warehouse class gives control over warehouses that exist in airbase objects. These warehouses can limit the aircraft, munitions, and fuel available to coalition aircraft. + -- @type Warehouse + + --- Adds the passed amount of a given item to the warehouse. + -- itemName is the typeName associated with the item: "weapons.missiles.AIM_54C_Mk47" + -- A wsType table can also be used, however the last digit with wsTypes has been known to change. {4, 4, 7, 322} + -- @function [parent=#Warehouse] addItem + -- @param self + -- @param #string itemName Name of the item. + -- @param #number count Number of items to add. + + --- Returns the number of the passed type of item currently in a warehouse object. + -- @function [parent=#Warehouse] getItemCount + -- @param self + -- @param #string itemName Name of the item. + + --- Sets the passed amount of a given item to the warehouse. + -- @function [parent=#Warehouse] setItem + -- @param self + -- @param #string itemName Name of the item. + -- @param #number count Number of items to add. + + --- Removes the amount of the passed item from the warehouse. + -- @function [parent=#Warehouse] removeItem + -- @param self + -- @param #string itemName Name of the item. + -- @param #number count Number of items to be removed. + + --- Adds the passed amount of a liquid fuel into the warehouse inventory. + -- @function [parent=#Warehouse] addLiquid + -- @param self + -- @param #number liquidType Type of liquid to add: 0=jetfuel, 1=aviation gasoline, 2=MW50, 3=Diesel. + -- @param #number count Amount of liquid to add. + + --- Returns the amount of the passed liquid type within a given warehouse. + -- @function [parent=#Warehouse] getLiquidAmount + -- @param self + -- @param #number liquidType Type of liquid to add: 0=jetfuel, 1=aviation gasoline, 2=MW50, 3=Diesel. + -- @return #number Amount of liquid. + + --- Sets the passed amount of a liquid fuel into the warehouse inventory. + -- @function [parent=#Warehouse] setLiquidAmount + -- @param self + -- @param #number liquidType Type of liquid to add: 0=jetfuel, 1=aviation gasoline, 2=MW50, 3=Diesel. + -- @param #number count Amount of liquid. + + --- Removes the set amount of liquid from the inventory in a warehouse. + -- @function [parent=#Warehouse] setLiquidAmount + -- @param self + -- @param #number liquidType Type of liquid to add: 0=jetfuel, 1=aviation gasoline, 2=MW50, 3=Diesel. + -- @param #number count Amount of liquid. + + --- Returns the airbase object associated with the warehouse object. + -- @function [parent=#Warehouse] getOwner + -- @param self + -- @return #Airbase The airbase object owning this warehouse. + + --- Returns a full itemized list of everything currently in a warehouse. If a category is set to unlimited then the table will be returned empty. + -- Aircraft and weapons are indexed by strings. Liquids are indexed by number. + -- @function [parent=#Warehouse] getInventory + -- @param self + -- @param #string itemName Name of the item. + -- @return #table Itemized list of everything currently in a warehouse + + + Warehouse = {} --#Warehouse + +end + do -- Spot --- [DCS Class Spot](https://wiki.hoggitworld.com/view/DCS_Class_Spot) diff --git a/Moose Development/Moose/Modules.lua b/Moose Development/Moose/Modules.lua index 9d4ae533c..22b16d9ef 100644 --- a/Moose Development/Moose/Modules.lua +++ b/Moose Development/Moose/Modules.lua @@ -48,6 +48,7 @@ __Moose.Include( 'Scripts/Moose/Wrapper/Scenery.lua' ) __Moose.Include( 'Scripts/Moose/Wrapper/Marker.lua' ) __Moose.Include( 'Scripts/Moose/Wrapper/Weapon.lua' ) __Moose.Include( 'Scripts/Moose/Wrapper/Net.lua' ) +__Moose.Include( 'Scripts/Moose/Wrapper/Storage.lua' ) __Moose.Include( 'Scripts/Moose/Cargo/Cargo.lua' ) __Moose.Include( 'Scripts/Moose/Cargo/CargoUnit.lua' ) diff --git a/Moose Development/Moose/Wrapper/Storage.lua b/Moose Development/Moose/Wrapper/Storage.lua new file mode 100644 index 000000000..cda71906c --- /dev/null +++ b/Moose Development/Moose/Wrapper/Storage.lua @@ -0,0 +1,247 @@ +--- **Wrapper** - Warehouse storage of DCS airbases. +-- +-- ## Main Features: +-- +-- * Convenient access to DCS API functions +-- +-- === +-- +-- ## Example Missions: +-- +-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Wrapper%20-%20Storage). +-- +-- === +-- +-- ### Author: **funkyfranky** +-- +-- === +-- @module Wrapper.Storage +-- @image Wrapper_Storage.png + + +--- STORAGE class. +-- @type STORAGE +-- @field #string ClassName Name of the class. +-- @field #number verbose Verbosity level. +-- @field #string lid Class id string for output to DCS log file. +-- @field DCS#Warehouse warehouse The DCS warehouse object. +-- @field DCS#Airbase airbase The DCS airbase object. +-- @extends Core.Base#BASE + +--- *The capitalist cannot store labour-power in warehouses after he has bought it, as he may do with the raw material.* -- Karl Marx +-- +-- === +-- +-- # The STORAGE Concept +-- +-- The STORAGE class offers an easy-to-use wrapper interface to all DCS API functions of DCS warehouses. We named the class STORAGE, because the name WAREHOUSE is already taken by another MOOSE class. +-- +-- This class allows you to add and remove items to a DCS warehouse, such as aircraft, weapons and liquids. +-- +-- # Constructor +-- +-- A DCS warehouse is associated with an airbase. Therefore, to get the storage, you need to pass the airbase name as parameter: +-- +-- -- Create a STORAGE instance of the Batumi warehouse +-- local storage=STORAGE:New("Batumi") +-- +-- +-- @field #STORAGE +STORAGE = { + ClassName = "STORAGE", + verbose = 0, +} + +--- Liquid types. +-- @type STORAGE.Liquid +-- @field #number JETFUEL Jet fuel. +-- @field #number GASOLINE Aviation gasoline. +-- @field #number MW50 MW50. +-- @field #number DIESEL Diesel. +STORAGE.Liquid = { + JETFUEL = 0, + GASOLINE = 1, + MW50 = 2, + DIESEL = 3, +} + +--- STORAGE class version. +-- @field #string version +STORAGE.version="0.0.1" + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- TODO list +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +-- TODO: A lot... +-- TODO: Persistence + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Constructor +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Create a new STORAGE object from the DCS weapon object. +-- @param #STORAGE self +-- @param #string AirbaseName Name of the airbase. +-- @return #STORAGE self +function STORAGE:New(AirbaseName) + + -- Inherit everything from FSM class. + local self=BASE:Inherit(self, BASE:New()) -- #STORAGE + + self.airbase=Airbase.getByName(AirbaseName) + + self.warehouse=self.airbase:getWarehouse() + + + return self +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- User API Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Set verbosity level. +-- @param #STORAGE self +-- @param #number VerbosityLevel Level of output (higher=more). Default 0. +-- @return #STORAGE self +function STORAGE:SetVerbosity(VerbosityLevel) + self.verbose=VerbosityLevel or 0 + return self +end + + +--- Adds the passed amount of a given item to the warehouse. +-- @param #STORAGE self +-- @param #string Name Name of the item to add. +-- @param #number Amount Amount of items to add. +-- @return #STORAGE self +function STORAGE:AddItem(Name, Amount) + + self:T(self.lid..string.format("Adding %d items of %s", Amount, Name)) + + self.warehouse:addItem(Name, Amount) + + return self +end + + +--- Sets the specified amount of a given item to the warehouse. +-- @param #STORAGE self +-- @param #string Name Name of the item. +-- @param #number Amount Amount of items. +-- @return #STORAGE self +function STORAGE:SetItem(Name, Amount) + + self:T(self.lid..string.format("Setting item %s to N=%d", Name, Amount)) + + self.warehouse:setItem(Name, Amount) + + return self +end + +--- Gets the amount of a given item currently present the warehouse. +-- @param #STORAGE self +-- @param #string Name Name of the item. +-- @return #number Amount of items. +function STORAGE:GetItemAmount(Name) + + local N=self.warehouse:getItemCount(Name) + + return N +end + + + +--- Removes the amount of the passed item from the warehouse. +-- @param #STORAGE self +-- @param #string Name Name of the item. +-- @param #number Amount Amount of items. +-- @return #STORAGE self +function STORAGE:RemoveItem(Name, Amount) + + self:T(self.lid..string.format("Removing N=%d of item %s", Amount, Name)) + + self.warehouse:removeItem(Name, Amount) + + return self +end + + + + +--- Adds the passed amount of a given liquid to the warehouse. +-- @param #STORAGE self +-- @param #number Type Type of liquid. +-- @param #number Amount Amount of liquid to add. +-- @return #STORAGE self +function STORAGE:AddLiquid(Type, Amount) + + self:T(self.lid..string.format("Adding %d liquids of %s", Amount, Type)) + + self.warehouse:addLiquid(Name, Amount) + + return self +end + + +--- Sets the specified amount of a given liquid to the warehouse. +-- @param #STORAGE self +-- @param #number Type Type of liquid. +-- @param #number Amount Amount of liquid. +-- @return #STORAGE self +function STORAGE:SetLiquid(Type, Amount) + + self:T(self.lid..string.format("Setting liquid %s to N=%d", Type, Amount)) + + self.warehouse:setLiquid(Type, Amount) + + return self +end + +--- Removes the amount of the passed liquid from the warehouse. +-- @param #STORAGE self +-- @param #number Type Type of liquid. +-- @param #number Amount Amount of liquid to remove. +-- @return #STORAGE self +function STORAGE:RemoveLiquid(Type, Amount) + + self:T(self.lid..string.format("Removing N=%d of liquid %s", Amount, Type)) + + self.warehouse:removeLiquid(Type, Amount) + + return self +end + +--- Gets the amount of a given liquid currently present the warehouse. +-- @param #STORAGE self +-- @param #number Type Type of liquid. +-- @return #number Amount of liquid. +function STORAGE:GetLiquidAmount(Type) + + local N=self.warehouse:getLiquidAmount(Type) + + return N +end + + +--- Returns a full itemized list of everything currently in a warehouse. If a category is set to unlimited then the table will be returned empty. +-- @param #STORAGE self +-- @param #string Item Name of item as #string or type of liquid as #number. +-- @return #table Table of aircraft. Table is emtpy `{}` if number of aircraft is set to be unlimited. +-- @return #table Table of liquids. Table is emtpy `{}` if number of liquids is set to be unlimited. +-- @return #table Table of weapons. Table is emtpy `{}` if number of liquids is set to be unlimited. +function STORAGE:GetInventory(Item) + + local inventory=self.warehouse:getInventory(Item) + + return inventory.aircraft, inventory.liquids, inventory.weapon +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Private Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Setup/Moose.files b/Moose Setup/Moose.files index ecb27c170..46213ce2e 100644 --- a/Moose Setup/Moose.files +++ b/Moose Setup/Moose.files @@ -49,6 +49,7 @@ Wrapper/Scenery.lua Wrapper/Marker.lua Wrapper/Weapon.lua Wrapper/Net.lua +Wrapper/Storage.lua Cargo/Cargo.lua Cargo/CargoUnit.lua From 4471ec9b9644d805b0bd161a8bdb94df3b79bf20 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 17 Aug 2023 18:46:09 +0200 Subject: [PATCH 3/3] DCS Warehouse --- Moose Development/Moose/Core/Database.lua | 38 ++++- Moose Development/Moose/DCS.lua | 12 +- Moose Development/Moose/Wrapper/Airbase.lua | 85 +++++++++++ Moose Development/Moose/Wrapper/Storage.lua | 150 +++++++++++++++++--- 4 files changed, 263 insertions(+), 22 deletions(-) diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 4ad7f9e50..1398d7088 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -32,10 +32,12 @@ -- @image Core_Database.JPG ---- @type DATABASE +--- DATABASE class. +-- @type DATABASE -- @field #string ClassName Name of the class. -- @field #table Templates Templates: Units, Groups, Statics, ClientsByName, ClientsByID. -- @field #table CLIENTS Clients. +-- @field #table STORAGES DCS warehouse storages. -- @extends Core.Base#BASE --- Contains collections of wrapper objects defined within MOOSE that reflect objects within the simulator. @@ -50,6 +52,7 @@ -- * PLAYERSJOINED -- * PLAYERS -- * CARGOS +-- * STORAGES (DCS warehouses) -- -- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor. -- @@ -90,6 +93,7 @@ DATABASE = { FLIGHTCONTROLS = {}, OPSZONES = {}, PATHLINES = {}, + STORAGES = {}, } local _DATABASECoalition = @@ -246,6 +250,38 @@ function DATABASE:FindAirbase( AirbaseName ) end + +--- Adds a STORAGE (DCS warehouse wrapper) based on the Airbase Name to the DATABASE. +-- @param #DATABASE self +-- @param #string AirbaseName The name of the airbase. +-- @return Wrapper.Storage#STORAGE Storage object. +function DATABASE:AddStorage( AirbaseName ) + + if not self.STORAGES[AirbaseName] then + self.STORAGES[AirbaseName] = STORAGE:New( AirbaseName ) + end + + return self.STORAGES[AirbaseName] +end + + +--- Deletes a STORAGE from the DATABASE based on the name of the associated airbase. +-- @param #DATABASE self +-- @param #string AirbaseName The name of the airbase. +function DATABASE:DeleteStorage( AirbaseName ) + self.STORAGES[AirbaseName] = nil +end + + +--- Finds an STORAGE based on the name of the associated airbase. +-- @param #DATABASE self +-- @param #string AirbaseName Name of the airbase. +-- @return Wrapper.Storage#STORAGE The found STORAGE. +function DATABASE:FindStorage( AirbaseName ) + local storage = self.STORAGES[AirbaseName] + return storage +end + do -- Zones and Pathlines --- Finds a @{Core.Zone} based on the zone name. diff --git a/Moose Development/Moose/DCS.lua b/Moose Development/Moose/DCS.lua index 46a7ded63..8a76a867d 100644 --- a/Moose Development/Moose/DCS.lua +++ b/Moose Development/Moose/DCS.lua @@ -799,7 +799,8 @@ do -- Airbase -- @param self -- @return #Warehouse The DCS warehouse object of this airbase. - --- Enables or disables the airbase and FARP auto capture game mechanic where ownership of a base can change based on the presence of ground forces or the default setting assigned in the editor. + --- Enables or disables the airbase and FARP auto capture game mechanic where ownership of a base can change based on the presence of ground forces or the + -- default setting assigned in the editor. -- @function [parent=#Airbase] autoCapture -- @param self -- @param #boolean setting `true` : enables autoCapture behavior, `false` : disables autoCapture behavior @@ -809,11 +810,18 @@ do -- Airbase -- @param self -- @return #boolean `true` if autoCapture behavior is enabled and `false` otherwise. - --- Changes the passed airbase object's coalition to the set value. Must be used with Airbase.autoCapture to disable auto capturing of the base, otherwise the base can revert back to a different coalition depending on the situation and built in game capture rules. + --- Changes the passed airbase object's coalition to the set value. Must be used with Airbase.autoCapture to disable auto capturing of the base, + -- otherwise the base can revert back to a different coalition depending on the situation and built in game capture rules. -- @function [parent=#Airbase] setCoalition -- @param self -- @param #number coa The new owner coalition: 0=neutra, 1=red, 2=blue. + --- Returns the wsType of every object that exists in DCS. A wsType is a table consisting of 4 entries indexed numerically. + -- It can be used to broadly categorize object types. The table can be broken down as: {mainCategory, subCat1, subCat2, index} + -- @function [parent=#Airbase] getResourceMap + -- @param self + -- @return #table wsType of every object that exists in DCS. + Airbase = {} --#Airbase end -- Airbase diff --git a/Moose Development/Moose/Wrapper/Airbase.lua b/Moose Development/Moose/Wrapper/Airbase.lua index dd52825fa..5dcf2757b 100644 --- a/Moose Development/Moose/Wrapper/Airbase.lua +++ b/Moose Development/Moose/Wrapper/Airbase.lua @@ -30,6 +30,7 @@ -- @field #table runways Runways of airdromes. -- @field #AIRBASE.Runway runwayLanding Runway used for landing. -- @field #AIRBASE.Runway runwayTakeoff Runway used for takeoff. +-- @field Wrapper.Storage#STORAGE storage The DCS warehouse storage. -- @extends Wrapper.Positionable#POSITIONABLE --- Wrapper class to handle the DCS Airbase objects: @@ -832,6 +833,9 @@ function AIRBASE:Register(AirbaseName) -- Init coordinate. self:GetCoordinate() + + -- Storage. + self.storage=_DATABASE:AddStorage(AirbaseName) if vec2 then if self.isShip then @@ -919,6 +923,87 @@ function AIRBASE:GetZone() return self.AirbaseZone end +--- Get the DCS warehouse. +-- @param #AIRBASE self +-- @return DCS#Warehouse The DCS warehouse object. +function AIRBASE:GetWarehouse() + local warehouse=nil --DCS#Warehouse + local airbase=self:GetDCSObject() + if airbase then + warehouse=airbase:getWarehouse() + end + return warehouse +end + +--- Get the warehouse storage of this airbase. The returned `STORAGE` object is the wrapper of the DCS warehouse. +-- This allows you to add and remove items such as aircraft, liquids, weapons and other equipment. +-- @param #AIRBASE self +-- @return Wrapper.Storage#STORAGE The storage. +function AIRBASE:GetStorage() + return self.storage +end + +--- Enables or disables automatic capturing of the airbase. +-- @param #AIRBASE self +-- @param #boolean Switch If `true`, enable auto capturing. If `false`, disable it. +-- @return #AIRBASE self +function AIRBASE:SetAutoCapture(Switch) + + local airbase=self:GetDCSObject() + + if airbase then + airbase:autoCapture(Switch) + end + + return self +end + +--- Enables automatic capturing of the airbase. +-- @param #AIRBASE self +-- @return #AIRBASE self +function AIRBASE:SetAutoCaptureON() + self:SetAutoCapture(true) + return self +end + +--- Disables automatic capturing of the airbase. +-- @param #AIRBASE self +-- @return #AIRBASE self +function AIRBASE:SetAutoCaptureOFF() + self:SetAutoCapture(false) + return self +end + +--- Returns whether auto capturing of the airbase is on or off. +-- @param #AIRBASE self +-- @return #boolean Returns `true` if auto capturing is on, `false` if off and `nil` if the airbase object cannot be retrieved. +function AIRBASE:IsAutoCapture() + + local airbase=self:GetDCSObject() + + local auto=nil + if airbase then + auto=airbase:autoCaptureIsOn() + end + + return auto +end + +--- Sets the coalition of the airbase. +-- @param #AIRBASE self +-- @param #number Coal Coalition that the airbase should have (0=Neutral, 1=Red, 2=Blue). +-- @return #AIRBASE self +function AIRBASE:SetCoalition(Coal) + + local airbase=self:GetDCSObject() + + if airbase then + airbase:setCoalition(Coal) + end + + return self +end + --- Get all airbases of the current map. This includes ships and FARPS. -- @param DCS#Coalition coalition (Optional) Return only airbases belonging to the specified coalition. By default, all airbases of the map are returned. -- @param #number category (Optional) Return only airbases of a certain category, e.g. Airbase.Category.FARP diff --git a/Moose Development/Moose/Wrapper/Storage.lua b/Moose Development/Moose/Wrapper/Storage.lua index cda71906c..191e916ca 100644 --- a/Moose Development/Moose/Wrapper/Storage.lua +++ b/Moose Development/Moose/Wrapper/Storage.lua @@ -34,17 +34,95 @@ -- -- # The STORAGE Concept -- --- The STORAGE class offers an easy-to-use wrapper interface to all DCS API functions of DCS warehouses. We named the class STORAGE, because the name WAREHOUSE is already taken by another MOOSE class. +-- The STORAGE class offers an easy-to-use wrapper interface to all DCS API functions of DCS warehouses. +-- We named the class STORAGE, because the name WAREHOUSE is already taken by another MOOSE class. -- --- This class allows you to add and remove items to a DCS warehouse, such as aircraft, weapons and liquids. +-- This class allows you to add and remove items to a DCS warehouse, such as aircraft, liquids, weapons and other equipment. -- -- # Constructor -- --- A DCS warehouse is associated with an airbase. Therefore, to get the storage, you need to pass the airbase name as parameter: +-- A DCS warehouse is associated with an airbase. Therefore, a `STORAGE` instance is automatically created, once an airbase is registered and added to the MOOSE database. +-- +-- You can get the `STORAGE` object from the -- -- -- Create a STORAGE instance of the Batumi warehouse --- local storage=STORAGE:New("Batumi") +-- local storage=STORAGE:FindByName("Batumi") -- +-- An other way to get the `STORAGE` object is to retrieve it from the AIRBASE function `AIRBASE:GetStorage()` +-- +-- -- Get storage instance of Batumi airbase +-- local Batumi=AIRBASE:FindByName("Batumi") +-- local storage=Batumi:GetStorage() +-- +-- # Aircraft, Weapons and Equipment +-- +-- ## Adding Items +-- +-- To add aircraft, weapons and/or othe equipment, you can use the @{#STORAGE.AddItem}() function +-- +-- storage:AddItem("A-10C", 3) +-- storage:AddItem("weapons.missiles.AIM_120C", 10) +-- +-- This will add three A-10Cs and ten AIM-120C missiles to the warehouse inventory. +-- +-- ## Setting Items +-- +-- You can also explicitly set, how many items are in the inventory with the @{#STORAGE.SetItem}() function. +-- +-- ## Removing Items +-- +-- Items can be removed from the inventory with the @{#STORAGE.RemoveItem}() function. +-- +-- ## Getting Amount +-- +-- The number of items currently in the inventory can be obtained with the @{#STORAGE.GetItemAmount}() function +-- +-- local N=storage:GetItemAmount("A-10C") +-- env.info(string.format("We currently have %d A-10Cs available", N)) +-- +-- # Liquids +-- +-- Liquids can be added and removed by slightly different functions as described below. Currently there are four types of liquids +-- +-- * Jet fuel `STORAGE.Liquid.JETFUEL` +-- * Aircraft gasoline `STORAGE.Liquid.GASOLINE` +-- * MW 50 `STORAGE.Liquid.MW50` +-- * Diesel `STORAGE.Liquid.DIESEL` +-- +-- ## Adding Liquids +-- +-- To add a certain type of liquid, you can use the @{#STORAGE.AddItem}(Type, Amount) function +-- +-- storage:AddLiquid(STORAGE.Liquid.JETFUEL, 10000) +-- storage:AddLiquid(STORAGE.Liquid.DIESEL, 20000) +-- +-- This will add 10,000 kg of jet fuel and 20,000 kg of diesel to the inventory. +-- +-- ## Setting Liquids +-- +-- You can also explicitly set the amount of liquid with the @{#STORAGE.SetLiquid}(Type, Amount) function. +-- +-- ## Removing Liquids +-- +-- Liquids can be removed with @{#STORAGE.RemoveLiquid}(Type, Amount) function. +-- +-- ## Getting Amount +-- +-- The current amount of a certain liquid can be obtained with the @{#STORAGE.GetLiquidAmount}(Type) function +-- +-- local N=storage:GetLiquidAmount(STORAGE.Liquid.DIESEL) +-- env.info(string.format("We currently have %d kg of Diesel available", N)) +-- +-- +-- # Inventory +-- +-- The current inventory of the warehouse can be obtained with the @{#STORAGE.GetInventory}() function. This returns three tables with the aircraft, liquids and weapons: +-- +-- local aircraft, liquids, weapons=storage:GetInventory() +-- +-- UTILS.PrintTableToLog(aircraft) +-- UTILS.PrintTableToLog(liquids) +-- UTILS.PrintTableToLog(weapons) -- -- @field #STORAGE STORAGE = { @@ -54,10 +132,10 @@ STORAGE = { --- Liquid types. -- @type STORAGE.Liquid --- @field #number JETFUEL Jet fuel. --- @field #number GASOLINE Aviation gasoline. --- @field #number MW50 MW50. --- @field #number DIESEL Diesel. +-- @field #number JETFUEL Jet fuel (0). +-- @field #number GASOLINE Aviation gasoline (1). +-- @field #number MW50 MW50 (2). +-- @field #number DIESEL Diesel (3). STORAGE.Liquid = { JETFUEL = 0, GASOLINE = 1, @@ -86,17 +164,28 @@ STORAGE.version="0.0.1" -- @return #STORAGE self function STORAGE:New(AirbaseName) - -- Inherit everything from FSM class. + -- Inherit everything from BASE class. local self=BASE:Inherit(self, BASE:New()) -- #STORAGE self.airbase=Airbase.getByName(AirbaseName) self.warehouse=self.airbase:getWarehouse() + self.lid = string.format("STORAGE %s", AirbaseName) return self end + +--- Find a STORAGE in the **_DATABASE** using the name associated airbase. +-- @param #STORAGE self +-- @param #string AirbaseName The Airbase Name. +-- @return #STORAGE self +function STORAGE:FindByName( AirbaseName ) + local storage = _DATABASE:FindStorage( AirbaseName ) + return storage +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- User API Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -118,7 +207,7 @@ end -- @return #STORAGE self function STORAGE:AddItem(Name, Amount) - self:T(self.lid..string.format("Adding %d items of %s", Amount, Name)) + self:T(self.lid..string.format("Adding %d items of %s", Amount, UTILS.OneLineSerialize(Name))) self.warehouse:addItem(Name, Amount) @@ -133,7 +222,7 @@ end -- @return #STORAGE self function STORAGE:SetItem(Name, Amount) - self:T(self.lid..string.format("Setting item %s to N=%d", Name, Amount)) + self:T(self.lid..string.format("Setting item %s to N=%d", UTILS.OneLineSerialize(Name), Amount)) self.warehouse:setItem(Name, Amount) @@ -177,9 +266,9 @@ end -- @return #STORAGE self function STORAGE:AddLiquid(Type, Amount) - self:T(self.lid..string.format("Adding %d liquids of %s", Amount, Type)) + self:T(self.lid..string.format("Adding %d liquids of %s", Amount, self:GetLiquidName(Type))) - self.warehouse:addLiquid(Name, Amount) + self.warehouse:addLiquid(Type, Amount) return self end @@ -192,21 +281,21 @@ end -- @return #STORAGE self function STORAGE:SetLiquid(Type, Amount) - self:T(self.lid..string.format("Setting liquid %s to N=%d", Type, Amount)) + self:T(self.lid..string.format("Setting liquid %s to N=%d", self:GetLiquidName(Type), Amount)) self.warehouse:setLiquid(Type, Amount) return self end ---- Removes the amount of the passed liquid from the warehouse. +--- Removes the amount of the given liquid type from the warehouse. -- @param #STORAGE self -- @param #number Type Type of liquid. --- @param #number Amount Amount of liquid to remove. +-- @param #number Amount Amount of liquid in kg to be removed. -- @return #STORAGE self function STORAGE:RemoveLiquid(Type, Amount) - self:T(self.lid..string.format("Removing N=%d of liquid %s", Amount, Type)) + self:T(self.lid..string.format("Removing N=%d of liquid %s", Amount, self:GetLiquidName(Type))) self.warehouse:removeLiquid(Type, Amount) @@ -216,7 +305,7 @@ end --- Gets the amount of a given liquid currently present the warehouse. -- @param #STORAGE self -- @param #number Type Type of liquid. --- @return #number Amount of liquid. +-- @return #number Amount of liquid in kg. function STORAGE:GetLiquidAmount(Type) local N=self.warehouse:getLiquidAmount(Type) @@ -224,13 +313,36 @@ function STORAGE:GetLiquidAmount(Type) return N end +--- Returns the name of the liquid from its numeric type. +-- @param #STORAGE self +-- @param #number Type Type of liquid. +-- @return #string Name of the liquid. +function STORAGE:GetLiquidName(Type) + + local name="Unknown" + + if Type==STORAGE.Liquid.JETFUEL then + name = "Jet fuel" + elseif Type==STORAGE.Liquid.GASOLINE then + name = "Aircraft gasoline" + elseif Type==STORAGE.Liquid.MW50 then + name = "MW 50" + elseif Type==STORAGE.Liquid.DIESEL then + name = "Diesel" + else + self:E(self.lid..string.format("ERROR: Unknown liquid type %s", tostring(Type))) + end + + return name +end + --- Returns a full itemized list of everything currently in a warehouse. If a category is set to unlimited then the table will be returned empty. -- @param #STORAGE self -- @param #string Item Name of item as #string or type of liquid as #number. -- @return #table Table of aircraft. Table is emtpy `{}` if number of aircraft is set to be unlimited. -- @return #table Table of liquids. Table is emtpy `{}` if number of liquids is set to be unlimited. --- @return #table Table of weapons. Table is emtpy `{}` if number of liquids is set to be unlimited. +-- @return #table Table of weapons and other equipment. Table is emtpy `{}` if number of liquids is set to be unlimited. function STORAGE:GetInventory(Item) local inventory=self.warehouse:getInventory(Item)