Add SetUnitInternalCargo to UNIT

Add PerCrateMass to CTLD_CARGO (default = 0kg)
Update unit internal cargo after each load/unload operation.
Add mass to cargo reports
This commit is contained in:
Ben Birch 2021-07-24 22:39:26 +10:00
parent 49397df90b
commit a6880d4569
2 changed files with 84 additions and 16 deletions

View File

@ -37,6 +37,7 @@ do
-- @field #number CratesNeeded Crates needed to build. -- @field #number CratesNeeded Crates needed to build.
-- @field Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission. -- @field Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission.
-- @field #boolean HasBeenDropped True if dropped from heli. -- @field #boolean HasBeenDropped True if dropped from heli.
-- @field #number PerCrateMass Mass in kg
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
CTLD_CARGO = { CTLD_CARGO = {
ClassName = "CTLD_CARGO", ClassName = "CTLD_CARGO",
@ -49,6 +50,7 @@ CTLD_CARGO = {
CratesNeeded = 0, CratesNeeded = 0,
Positionable = nil, Positionable = nil,
HasBeenDropped = false, HasBeenDropped = false,
PerCrateMass = 0
} }
--- Define cargo types. --- Define cargo types.
@ -73,8 +75,9 @@ CTLD_CARGO = {
-- @param #number CratesNeeded Crates needed to build. -- @param #number CratesNeeded Crates needed to build.
-- @param Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission. -- @param Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission.
-- @param #boolean Dropped Cargo/Troops have been unloaded from a chopper. -- @param #boolean Dropped Cargo/Troops have been unloaded from a chopper.
-- @param #number PerCrateMass Mass in kg
-- @return #CTLD_CARGO self -- @return #CTLD_CARGO self
function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped) function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass)
-- Inherit everything from BASE class. -- Inherit everything from BASE class.
local self=BASE:Inherit(self, BASE:New()) -- #CTLD local self=BASE:Inherit(self, BASE:New()) -- #CTLD
self:T({ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped}) self:T({ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped})
@ -87,6 +90,7 @@ CTLD_CARGO = {
self.CratesNeeded = CratesNeeded or 0 -- #number self.CratesNeeded = CratesNeeded or 0 -- #number
self.Positionable = Positionable or nil -- Wrapper.Positionable#POSITIONABLE self.Positionable = Positionable or nil -- Wrapper.Positionable#POSITIONABLE
self.HasBeenDropped = Dropped or false --#boolean self.HasBeenDropped = Dropped or false --#boolean
self.PerCrateMass = PerCrateMass or 0 -- #number
return self return self
end end
@ -955,13 +959,14 @@ function CTLD:_LoadTroops(Group, Unit, Cargotype)
return return
else else
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, CTLD_CARGO.Enum.TROOPS, true, true, Cargotype.CratesNeeded) local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, CTLD_CARGO.Enum.TROOPS, true, true, Cargotype.CratesNeeded,nil,nil,Cargotype.PerCrateMass)
self:T({cargotype=loadcargotype}) self:T({cargotype=loadcargotype})
loaded.Troopsloaded = loaded.Troopsloaded + troopsize loaded.Troopsloaded = loaded.Troopsloaded + troopsize
table.insert(loaded.Cargo,loadcargotype) table.insert(loaded.Cargo,loadcargotype)
self.Loaded_Cargo[unitname] = loaded self.Loaded_Cargo[unitname] = loaded
self:_SendMessage("Troops boarded!", 10, false, Group) self:_SendMessage("Troops boarded!", 10, false, Group)
self:__TroopsPickedUp(1,Group, Unit, Cargotype) self:__TroopsPickedUp(1,Group, Unit, Cargotype)
self:_UpdateUnitCargoMass(Unit)
end end
return self return self
end end
@ -1062,7 +1067,7 @@ function CTLD:_RepairObjectFromCrates(Group,Unit,Crates,Build,Number)
self:_CleanUpCrates(Crates,Build,Number) self:_CleanUpCrates(Crates,Build,Number)
local desttimer = TIMER:New(function() NearestGroup:Destroy(false) end, self) local desttimer = TIMER:New(function() NearestGroup:Destroy(false) end, self)
desttimer:Start(self.repairtime - 1) desttimer:Start(self.repairtime - 1)
local buildtimer = TIMER:New(self._BuildObjectFromCrates,self,Group,Unit,object,true) local buildtimer = TIMER:New(self._BuildObjectFromCrates,self,Group,Unit,object,true,NearestGroup:GetCoordinate())
buildtimer:Start(self.repairtime) buildtimer:Start(self.repairtime)
--self:_BuildObjectFromCrates(Group,Unit,object) --self:_BuildObjectFromCrates(Group,Unit,object)
else else
@ -1146,12 +1151,13 @@ end
return return
else else
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, CTLD_CARGO.Enum.TROOPS, true, true, Cargotype.CratesNeeded) local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, CTLD_CARGO.Enum.TROOPS, true, true, Cargotype.CratesNeeded,nil,nil,Cargotype.PerCrateMass)
self:T({cargotype=loadcargotype}) self:T({cargotype=loadcargotype})
loaded.Troopsloaded = loaded.Troopsloaded + troopsize loaded.Troopsloaded = loaded.Troopsloaded + troopsize
table.insert(loaded.Cargo,loadcargotype) table.insert(loaded.Cargo,loadcargotype)
self.Loaded_Cargo[unitname] = loaded self.Loaded_Cargo[unitname] = loaded
self:_SendMessage("Troops boarded!", 10, false, Group) self:_SendMessage("Troops boarded!", 10, false, Group)
self:_UpdateUnitCargoMass(Unit)
self:__TroopsExtracted(1,Group, Unit, nearestGroup) self:__TroopsExtracted(1,Group, Unit, nearestGroup)
-- clean up: -- clean up:
@ -1238,10 +1244,10 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
self.CargoCounter = self.CargoCounter +1 self.CargoCounter = self.CargoCounter +1
local realcargo = nil local realcargo = nil
if drop then if drop then
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],true) realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],true,cargotype.PerCrateMass)
table.insert(droppedcargo,realcargo) table.insert(droppedcargo,realcargo)
else else
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter]) realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],nil,cargotype.PerCrateMass)
end end
table.insert(self.Spawned_Cargo, realcargo) table.insert(self.Spawned_Cargo, realcargo)
end end
@ -1273,7 +1279,7 @@ function CTLD:_ListCratesNearby( _group, _unit)
if dropped then if dropped then
text:Add(string.format("Dropped crate for %s",name)) text:Add(string.format("Dropped crate for %s",name))
else else
text:Add(string.format("Crate for %s",name)) text:Add(string.format("Crate for %s, %d Kg",name, entry.PerCrateMass))
end end
end end
if text:GetCount() == 1 then if text:GetCount() == 1 then
@ -1367,6 +1373,7 @@ function CTLD:_LoadCratesNearby(Group, Unit)
else else
-- have we loaded stuff already? -- have we loaded stuff already?
local numberonboard = 0 local numberonboard = 0
local massonboard = 0
local loaded = {} local loaded = {}
if self.Loaded_Cargo[unitname] then if self.Loaded_Cargo[unitname] then
loaded = self.Loaded_Cargo[unitname] -- #CTLD.LoadedCargo loaded = self.Loaded_Cargo[unitname] -- #CTLD.LoadedCargo
@ -1408,6 +1415,7 @@ function CTLD:_LoadCratesNearby(Group, Unit)
crate:GetPositionable():Destroy() crate:GetPositionable():Destroy()
crate.Positionable = nil crate.Positionable = nil
self:_SendMessage(string.format("Crate ID %d for %s loaded!",crate:GetID(),crate:GetName()), 10, false, Group) self:_SendMessage(string.format("Crate ID %d for %s loaded!",crate:GetID(),crate:GetName()), 10, false, Group)
self:_UpdateUnitCargoMass(Unit)
self:__CratesPickedUp(1, Group, Unit, crate) self:__CratesPickedUp(1, Group, Unit, crate)
end end
end end
@ -1431,6 +1439,43 @@ function CTLD:_LoadCratesNearby(Group, Unit)
return self return self
end end
--- (Internal) Function to get current loaded mass
-- @param #CTLD self
-- @param Wrapper.Unit#UNIT Unit
-- @return #number mass in kgs
function CTLD:_GetUnitCargoMass(Unit)
self:T(self.lid .. " _GetUnitCargoMass")
local unitname = Unit:GetName()
local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo
local loadedmass = 0 -- #number
if self.Loaded_Cargo[unitname] then
local cargotable = loadedcargo.Cargo or {} -- #table
for _,_cargo in pairs(cargotable) do
local cargo = _cargo -- #CTLD_CARGO
local type = cargo:GetType() -- #CTLD_CARGO.Enum
if type == CTLD_CARGO.Enum.TROOPS and not cargo:WasDropped() then
loadedmass = loadedmass + (cargo.PerCrateMass * cargo:GetCratesNeeded())
end
if type ~= CTLD_CARGO.Enum.TROOPS and not cargo:WasDropped() then
loadedmass = loadedmass + cargo.PerCrateMass
end
end
end
return loadedmass
end
--- (Internal) Function to calculate and set Unit internal cargo mass
-- @param #CTLD self
-- @param Wrapper.Unit#UNIT Unit
function CTLD:_UpdateUnitCargoMass(Unit)
self:T(self.lid .. " _UpdateUnitCargoMass")
local calculatedMass = self:_GetUnitCargoMass(Unit)
Unit:SetUnitInternalCargo(calculatedMass)
local report = REPORT:New("Loadmaster report")
report:Add("Carrying " .. calculatedMass .. "Kg")
self:_SendMessage(report:Text(),10,false,Unit:GetGroup())
end
--- (Internal) Function to list loaded cargo. --- (Internal) Function to list loaded cargo.
-- @param #CTLD self -- @param #CTLD self
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
@ -1444,6 +1489,7 @@ function CTLD:_ListCargo(Group, Unit)
local trooplimit = capabilities.trooplimit -- #boolean local trooplimit = capabilities.trooplimit -- #boolean
local cratelimit = capabilities.cratelimit -- #number local cratelimit = capabilities.cratelimit -- #number
local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo
local loadedmass = self:_GetUnitCargoMass(Unit) -- #number
if self.Loaded_Cargo[unitname] then if self.Loaded_Cargo[unitname] then
local no_troops = loadedcargo.Troopsloaded or 0 local no_troops = loadedcargo.Troopsloaded or 0
local no_crates = loadedcargo.Cratesloaded or 0 local no_crates = loadedcargo.Cratesloaded or 0
@ -1469,7 +1515,7 @@ function CTLD:_ListCargo(Group, Unit)
for _,_cargo in pairs(cargotable) do for _,_cargo in pairs(cargotable) do
local cargo = _cargo -- #CTLD_CARGO local cargo = _cargo -- #CTLD_CARGO
local type = cargo:GetType() -- #CTLD_CARGO.Enum local type = cargo:GetType() -- #CTLD_CARGO.Enum
if type ~= CTLD_CARGO.Enum.TROOPS then if type ~= CTLD_CARGO.Enum.TROOPS and not cargo:WasDropped() then
report:Add(string.format("Crate: %s size 1",cargo:GetName())) report:Add(string.format("Crate: %s size 1",cargo:GetName()))
cratecount = cratecount + 1 cratecount = cratecount + 1
end end
@ -1478,6 +1524,7 @@ function CTLD:_ListCargo(Group, Unit)
report:Add(" N O N E") report:Add(" N O N E")
end end
report:Add("------------------------------------------------------------") report:Add("------------------------------------------------------------")
report:Add("Total Mass: ".. loadedmass .. " kg")
local text = report:Text() local text = report:Text()
self:_SendMessage(text, 30, true, Group) self:_SendMessage(text, 30, true, Group)
else else
@ -1580,6 +1627,7 @@ function CTLD:_UnloadTroops(Group, Unit)
end end
self.Loaded_Cargo[unitname] = nil self.Loaded_Cargo[unitname] = nil
self.Loaded_Cargo[unitname] = loaded self.Loaded_Cargo[unitname] = loaded
self:_UpdateUnitCargoMass(Unit)
else else
if IsHerc then if IsHerc then
self:_SendMessage("Nothing loaded or not within airdrop parameters!", 10, false, Group) self:_SendMessage("Nothing loaded or not within airdrop parameters!", 10, false, Group)
@ -1648,6 +1696,7 @@ function CTLD:_UnloadCrates(Group, Unit)
end end
self.Loaded_Cargo[unitname] = nil self.Loaded_Cargo[unitname] = nil
self.Loaded_Cargo[unitname] = loaded self.Loaded_Cargo[unitname] = loaded
self:_UpdateUnitCargoMass(Unit)
else else
if IsHerc then if IsHerc then
self:_SendMessage("Nothing loaded or not within airdrop parameters!", 10, false, Group) self:_SendMessage("Nothing loaded or not within airdrop parameters!", 10, false, Group)
@ -1821,7 +1870,8 @@ end
-- @param Wrapper.Group#UNIT Unit -- @param Wrapper.Group#UNIT Unit
-- @param #CTLD.Buildable Build -- @param #CTLD.Buildable Build
-- @param #boolean Repair If true this is a repair and not a new build -- @param #boolean Repair If true this is a repair and not a new build
function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair) -- @param Core.Point#COORDINATE Coordinate Location for repair (e.g. where the destroyed unit was)
function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
self:T(self.lid .. " _BuildObjectFromCrates") self:T(self.lid .. " _BuildObjectFromCrates")
-- Spawn-a-crate-content -- Spawn-a-crate-content
local position = Unit:GetCoordinate() or Group:GetCoordinate() local position = Unit:GetCoordinate() or Group:GetCoordinate()
@ -1833,6 +1883,9 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair)
local temptable = Build.Template or {} local temptable = Build.Template or {}
local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,100) local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,100)
local randomcoord = zone:GetRandomCoordinate(35):GetVec2() local randomcoord = zone:GetRandomCoordinate(35):GetVec2()
if Repair then
randomcoord = RepairLocation:GetVec2()
end
for _,_template in pairs(temptable) do for _,_template in pairs(temptable) do
self.TroopCounter = self.TroopCounter + 1 self.TroopCounter = self.TroopCounter + 1
if canmove then if canmove then
@ -2023,11 +2076,12 @@ function CTLD:_RefreshF10Menus()
-- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP making up this troop. -- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP making up this troop.
-- @param #CTLD_CARGO.Enum Type Type of cargo, here TROOPS - these will move to a nearby destination zone when dropped/build. -- @param #CTLD_CARGO.Enum Type Type of cargo, here TROOPS - these will move to a nearby destination zone when dropped/build.
-- @param #number NoTroops Size of the group in number of Units across combined templates (for loading). -- @param #number NoTroops Size of the group in number of Units across combined templates (for loading).
function CTLD:AddTroopsCargo(Name,Templates,Type,NoTroops) -- @param #number PerTroopMass Mass in kg of each soldier
function CTLD:AddTroopsCargo(Name,Templates,Type,NoTroops,PerTroopMass)
self:T(self.lid .. " AddTroopsCargo") self:T(self.lid .. " AddTroopsCargo")
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
-- Troops are directly loadable -- Troops are directly loadable
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,true,NoTroops) local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,true,NoTroops,nil,nil,PerTroopMass)
table.insert(self.Cargo_Troops,cargo) table.insert(self.Cargo_Troops,cargo)
return self return self
end end
@ -2038,11 +2092,12 @@ end
-- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP building this cargo. -- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP building this cargo.
-- @param #CTLD_CARGO.Enum Type Type of cargo. I.e. VEHICLE or FOB. VEHICLE will move to destination zones when dropped/build, FOB stays put. -- @param #CTLD_CARGO.Enum Type Type of cargo. I.e. VEHICLE or FOB. VEHICLE will move to destination zones when dropped/build, FOB stays put.
-- @param #number NoCrates Number of crates needed to build this cargo. -- @param #number NoCrates Number of crates needed to build this cargo.
function CTLD:AddCratesCargo(Name,Templates,Type,NoCrates) -- @param #number PerCrateMass Mass in kg of each crate
function CTLD:AddCratesCargo(Name,Templates,Type,NoCrates,PerCrateMass)
self:T(self.lid .. " AddCratesCargo") self:T(self.lid .. " AddCratesCargo")
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
-- Crates are not directly loadable -- Crates are not directly loadable
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,false,NoCrates) local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,false,NoCrates,nil,nil,PerCrateMass)
table.insert(self.Cargo_Crates,cargo) table.insert(self.Cargo_Crates,cargo)
return self return self
end end
@ -2053,11 +2108,12 @@ end
-- @param #string Template Template of VEHICLE or FOB cargo that this can repair. -- @param #string Template Template of VEHICLE or FOB cargo that this can repair.
-- @param #CTLD_CARGO.Enum Type Type of cargo, here REPAIR. -- @param #CTLD_CARGO.Enum Type Type of cargo, here REPAIR.
-- @param #number NoCrates Number of crates needed to build this cargo. -- @param #number NoCrates Number of crates needed to build this cargo.
function CTLD:AddCratesRepair(Name,Template,Type,NoCrates) -- @param #number PerCrateMass Mass in kg of each crate
function CTLD:AddCratesRepair(Name,Template,Type,NoCrates, PerCrateMass)
self:T(self.lid .. " AddCratesRepair") self:T(self.lid .. " AddCratesRepair")
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
-- Crates are not directly loadable -- Crates are not directly loadable
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Template,Type,false,false,NoCrates) local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Template,Type,false,false,NoCrates,nil,nil,PerCrateMass)
table.insert(self.Cargo_Crates,cargo) table.insert(self.Cargo_Crates,cargo)
return self return self
end end

View File

@ -580,6 +580,18 @@ function UNIT:GetAmmo()
return nil return nil
end end
--- Sets the Unit's Internal Cargo Mass, in kg
-- @param #UNIT self
-- @param #number mass to set cargo to
-- @return #UNIT self
function UNIT:SetUnitInternalCargo(mass)
local DCSUnit = self:GetDCSObject()
if DCSUnit then
trigger.action.setUnitInternalCargo(DCSUnit:getName(), mass)
end
return self
end
--- Get the number of ammunition and in particular the number of shells, rockets, bombs and missiles a unit currently has. --- Get the number of ammunition and in particular the number of shells, rockets, bombs and missiles a unit currently has.
-- @param #UNIT self -- @param #UNIT self
-- @return #number Total amount of ammo the unit has left. This is the sum of shells, rockets, bombs and missiles. -- @return #number Total amount of ammo the unit has left. This is the sum of shells, rockets, bombs and missiles.