Merge branch 'FlightControl-Master:develop' into develop

This commit is contained in:
shaji-Dev 2025-01-31 10:21:37 +02:00 committed by GitHub
commit 0ffcdf2f66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 275 additions and 8 deletions

View File

@ -56,6 +56,7 @@ do
-- @field #string StaticType Individual type if set.
-- @field #string StaticCategory Individual static category if set.
-- @field #list<#string> TypeNames Table of unit types able to pick this cargo up.
-- @field #number Stock0 Initial stock, if any given.
-- @extends Core.Base#BASE
---
@ -73,6 +74,7 @@ CTLD_CARGO = {
HasBeenDropped = false,
PerCrateMass = 0,
Stock = nil,
Stock0 = nil,
Mark = nil,
DontShowInMenu = false,
Location = nil,
@ -131,6 +133,7 @@ CTLD_CARGO = {
self.HasBeenDropped = Dropped or false --#boolean
self.PerCrateMass = PerCrateMass or 0 -- #number
self.Stock = Stock or nil --#number
self.Stock0 = Stock or nil --#number
self.Mark = nil
self.Subcategory = Subcategory or "Other"
self.DontShowInMenu = DontShowInMenu or false
@ -321,7 +324,7 @@ CTLD_CARGO = {
--- Get Stock.
-- @param #CTLD_CARGO self
-- @return #number Stock
-- @return #number Stock or -1 if unlimited.
function CTLD_CARGO:GetStock()
if self.Stock then
return self.Stock
@ -330,6 +333,28 @@ CTLD_CARGO = {
end
end
--- Get Stock0.
-- @param #CTLD_CARGO self
-- @return #number Stock0 or -1 if unlimited.
function CTLD_CARGO:GetStock0()
if self.Stock0 then
return self.Stock0
else
return -1
end
end
--- Get relative Stock.
-- @param #CTLD_CARGO self
-- @return #number Stock Percentage like 75, or -1 if unlimited.
function CTLD_CARGO:GetRelativeStock()
if self.Stock and self.Stock0 then
return math.floor((self.Stock/self.Stock0)*100)
else
return -1
end
end
--- Add Stock.
-- @param #CTLD_CARGO self
-- @param #number Number to add, none if nil.
@ -986,6 +1011,14 @@ do
-- function my_ctld:OnAfterCratesDropped(From, Event, To, Group, Unit, Cargotable)
-- ... your code here ...
-- end
--
--- ## 3.6 OnAfterHelicopterLost
--
-- This function is called when a player has deployed left a unit or crashed/died:
--
-- function my_ctld:OnAfterHelicopterLost(From, Event, To, Unitname, Cargotable)
-- ... your code here ...
-- end
--
-- ## 3.6 OnAfterCratesBuild, OnAfterCratesRepaired
--
@ -1355,7 +1388,7 @@ CTLD.UnitTypeCapabilities = {
--- CTLD class version.
-- @field #string version
CTLD.version="1.1.28"
CTLD.version="1.1.29"
--- Instantiate a new CTLD.
-- @param #CTLD self
@ -1422,6 +1455,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
self:AddTransition("*", "CratesRepaired", "*") -- CTLD repair event.
self:AddTransition("*", "CratesBuildStarted", "*") -- CTLD build event.
self:AddTransition("*", "CratesRepairStarted", "*") -- CTLD repair event.
self:AddTransition("*", "HelicopterLost", "*") -- CTLD lost event.
self:AddTransition("*", "Load", "*") -- CTLD load event.
self:AddTransition("*", "Loaded", "*") -- CTLD load event.
self:AddTransition("*", "Save", "*") -- CTLD save event.
@ -1831,6 +1865,24 @@ function CTLD:New(Coalition, Prefixes, Alias)
-- @param #string To State.
-- @param Wrapper.Group#GROUP Group Group Object.
-- @param Wrapper.Unit#UNIT Unit Unit Object.
--- FSM Function OnBeforeHelicopterLost.
-- @function [parent=#CTLD] OnBeforeHelicopterLost
-- @param #CTLD self
-- @param #string From State.
-- @param #string Event Trigger.
-- @param #string To State.
-- @param #string Unitname The name of the unit lost.
-- @param #table LostCargo Table of #CTLD_CARGO object which were aboard the helicopter/transportplane lost. Can be an empty table!
--- FSM Function OnAfterHelicopterLost.
-- @function [parent=#CTLD] OnAfterHelicopterLost
-- @param #CTLD self
-- @param #string From State.
-- @param #string Event Trigger.
-- @param #string To State.
-- @param #string Unitname The name of the unit lost.
-- @param #table LostCargo Table of #CTLD_CARGO object which were aboard the helicopter/transportplane lost. Can be an empty table!
--- FSM Function OnAfterLoad.
-- @function [parent=#CTLD] OnAfterLoad
@ -1972,6 +2024,10 @@ function CTLD:_EventHandler(EventData)
elseif event.id == EVENTS.PlayerLeaveUnit or event.id == EVENTS.UnitLost then
-- remove from pilot table
local unitname = event.IniUnitName or "none"
if self.CtldUnits[unitname] then
local lostcargo = UTILS.DeepCopy(self.Loaded_Cargo[unitname] or {})
self:__HelicopterLost(1,unitname,lostcargo)
end
self.CtldUnits[unitname] = nil
self.Loaded_Cargo[unitname] = nil
self.MenusDone[unitname] = nil
@ -5290,6 +5346,129 @@ end
self.EngineersInField = engtable
return self
end
--- User - Count both the stock and groups in the field for available cargo types. Counts only limited cargo items and only troops and vehicle/FOB crates!
-- @param #CTLD self
-- @param #boolean Restock If true, restock the cargo and troop items.
-- @param #number Threshold Percentage below which to restock, used in conjunction with Restock (must be true). Defaults to 75 (percent).
-- @return #table Table A table of contents with numbers.
-- @usage
-- The index is the unique cargo name.
-- Each entry in the returned table contains a table with the following entries:
--
-- {
-- Stock0 -- number of original stock when the cargo entry was created.
-- Stock -- number of currently available stock.
-- StockR -- relative number of available stock, e.g. 75 (percent).
-- Infield -- number of groups alive in the field of this kind.
-- Inhelo -- number of troops/crates in any helo alive. Can be with decimals < 1 if e.g. you have cargo that need 4 crates, but you have 2 loaded.
-- Sum -- sum is stock + infield + inhelo.
-- GenericCargo -- this filed holds the generic CTLD_CARGO object which drives the available stock. Only populated if Restock is true.
-- }
function CTLD:_CountStockPlusInHeloPlusAliveGroups(Restock,Threshold)
local Troopstable = {}
-- generics
for _id,_cargo in pairs(self.Cargo_Crates) do
local generic = _cargo -- #CTLD_CARGO
local genname = generic:GetName()
if generic and generic:GetStock0() > 0 and not Troopstable[genname] then
Troopstable[genname] = {
Stock0 = generic:GetStock0(),
Stock = generic:GetStock(),
StockR = generic:GetRelativeStock(),
Infield = 0,
Inhelo = 0,
Sum = generic:GetStock(),
}
if Restock == true then
Troopstable[genname].GenericCargo = generic
end
end
end
---
for _id,_cargo in pairs(self.Cargo_Troops) do
local generic = _cargo -- #CTLD_CARGO
local genname = generic:GetName()
if generic and generic:GetStock0() > 0 and not Troopstable[genname] then
Troopstable[genname] = {
Stock0 = generic:GetStock0(),
Stock = generic:GetStock(),
StockR = generic:GetRelativeStock(),
Infield = 0,
Inhelo = 0,
Sum = generic:GetStock(),
}
if Restock == true then
Troopstable[genname].GenericCargo = generic
end
end
end
-- Troops & Built Crates
for _index, _group in pairs (self.DroppedTroops) do
if _group and _group:IsAlive() then
self:T("Looking at ".._group:GetName() .. " in the field")
local generic = self:GetGenericCargoObjectFromGroupName(_group:GetName()) -- #CTLD_CARGO
if generic then
local genname = generic:GetName()
self:T("Found Generic "..genname .. " in the field. Adding.")
if generic:GetStock0() > 0 then -- don't count unlimited stock
Troopstable[genname].Infield = Troopstable[genname].Infield + 1
Troopstable[genname].Sum = Troopstable[genname].Infield + Troopstable[genname].Stock + Troopstable[genname].Inhelo
end
else
self:E(self.lid.."Group without Cargo Generic: ".._group:GetName())
end
end
end
-- Helos
for _unitname,_loaded in pairs(self.Loaded_Cargo) do
local _unit = UNIT:FindByName(_unitname)
if _unit and _unit:IsAlive() then
local unitname = _unit:GetName()
local loadedcargo = self.Loaded_Cargo[unitname].Cargo or {}
for _,_cgo in pairs (loadedcargo) do
local cargo = _cgo -- #CTLD_CARGO
local type = cargo.CargoType
local gname = cargo.Name
local gcargo = self:_FindCratesCargoObject(gname) or self:_FindTroopsCargoObject(gname)
self:T("Looking at ".. gname .. " in the helo - type = "..type)
if (type == CTLD_CARGO.Enum.TROOPS or type == CTLD_CARGO.Enum.ENGINEERS or type == CTLD_CARGO.Enum.VEHICLE or type == CTLD_CARGO.Enum.FOB) then
-- valid troops/engineers
if gcargo and gcargo:GetStock0() > 0 then -- don't count unlimited stock
self:T("Adding ".. gname .. " in the helo - type = "..type)
if (type == CTLD_CARGO.Enum.TROOPS or type == CTLD_CARGO.Enum.ENGINEERS) then
Troopstable[gname].Inhelo = Troopstable[gname].Inhelo + 1
end
if (type == CTLD_CARGO.Enum.VEHICLE or type == CTLD_CARGO.Enum.FOB) then
-- maybe multiple crates of the same type
local counting = gcargo.CratesNeeded
local added = 1
if counting > 1 then
added = added/counting
end
Troopstable[gname].Inhelo = Troopstable[gname].Inhelo + added
end
Troopstable[gname].Sum = Troopstable[gname].Infield + Troopstable[gname].Stock + Troopstable[gname].Inhelo
end
end
end
end
end
-- Restock?
if Restock == true then
local threshold = Threshold or 75
for _name,_data in pairs(Troopstable) do
if _data.StockR and _data.StockR < threshold then
if _data.GenericCargo then
_data.GenericCargo:SetStock(_data.Stock0) -- refill to start level
end
end
end
end
-- Return
return Troopstable
end
--- User - function to add stock of a certain troops type
-- @param #CTLD self
@ -5304,6 +5483,7 @@ end
for _id,_troop in pairs (gentroops) do -- #number, #CTLD_CARGO
if _troop.Name == name then
_troop:AddStock(number)
break
end
end
return self
@ -5322,6 +5502,7 @@ end
for _id,_troop in pairs (gentroops) do -- #number, #CTLD_CARGO
if _troop.Name == name then
_troop:AddStock(number)
break
end
end
return self
@ -5340,6 +5521,7 @@ end
for _id,_troop in pairs (gentroops) do -- #number, #CTLD_CARGO
if _troop.Name == name then
_troop:AddStock(number)
break
end
end
return self
@ -5358,6 +5540,7 @@ end
for _id,_troop in pairs (gentroops) do -- #number, #CTLD_CARGO
if _troop.Name == name then
_troop:SetStock(number)
break
end
end
return self
@ -5376,6 +5559,7 @@ end
for _id,_troop in pairs (gentroops) do -- #number, #CTLD_CARGO
if _troop.Name == name then
_troop:SetStock(number)
break
end
end
return self
@ -5394,6 +5578,7 @@ end
for _id,_troop in pairs (gentroops) do -- #number, #CTLD_CARGO
if _troop.Name == name then
_troop:SetStock(number)
break
end
end
return self
@ -5519,19 +5704,24 @@ end
-- @return #CTLD_CARGO The cargo object or nil if not found
function CTLD:GetGenericCargoObjectFromGroupName(GroupName)
local Cargotype = nil
local template = GroupName
if string.find(template,"#") then
template = string.gsub(GroupName,"#(%d+)$","")
end
template = string.gsub(template,"-(%d+)$","")
for k,v in pairs(self.Cargo_Troops) do
local comparison = ""
if type(v.Templates) == "string" then comparison = v.Templates else comparison = v.Templates[1] end
if comparison == GroupName then
if comparison == template then
Cargotype = v
break
end
end
if not Cargotype then
for k,v in pairs(self.Cargo_Crates) do
for k,v in pairs(self.Cargo_Crates) do -- #number, #CTLD_CARGO
local comparison = ""
if type(v.Templates) == "string" then comparison = v.Templates else comparison = v.Templates[1] end
if comparison == GroupName then
if comparison == template and v.CargoType ~= CTLD_CARGO.Enum.REPAIR then
Cargotype = v
break
end
@ -5656,7 +5846,7 @@ end
if not match then
self.CargoCounter = self.CargoCounter + 1
cargo.ID = self.CargoCounter
cargo.Stock = 1
--cargo.Stock = 1
table.insert(self.Cargo_Troops,cargo)
end
@ -5806,7 +5996,7 @@ end
if not match then
self.CargoCounter = self.CargoCounter + 1
cargo.ID = self.CargoCounter
cargo.Stock = 1
--cargo.Stock = 1
table.insert(self.Cargo_Crates,cargo)
end

View File

@ -1279,6 +1279,8 @@ ENUMS.Storage.weapons.nurs.S_5M = "weapons.nurs.S_5M"
ENUMS.Storage.weapons.missiles.AGM_12A = "weapons.missiles.AGM_12A"
ENUMS.Storage.weapons.droptanks.JAYHAWK_120_Fuel_Tank = "weapons.droptanks.JAYHAWK_120_Fuel_Tank"
ENUMS.Storage.weapons.bombs.GBU_15_V_1_B = "weapons.bombs.GBU_15_V_1_B"
ENUMS.Storage.weapons.missiles.HYDRA_70_M151_APKWS = {4,4,8,292}
ENUMS.Storage.weapons.missiles.HYDRA_70_M282_APKWS = {4,4,8,293}
-- dupes with typos
ENUMS.Storage.weapons.bombs.BAP100 = "weapons.bombs.BAP_100"
ENUMS.Storage.weapons.bombs.BLU3B_GROUP = "weapons.bombs.BLU-3B_GROUP"
@ -1327,7 +1329,7 @@ ENUMS.Storage.weapons.OH58.Smk_Grenade_Violet = {4,5,9,490}
ENUMS.Storage.weapons.OH58.Smk_Grenade_White = {4,5,9,492}
ENUMS.Storage.weapons.OH58.Smk_Grenade_Yellow = {4,5,9,491}
-- Apache
ENUMS.Storage.weapons.AH64D.AN_APG78 = {4,15,44,2138}
ENUMS.Storage.weapons.AH64D.AN_APG78 = {4,15,44,2114}
ENUMS.Storage.weapons.AH64D.Internal_Aux_FuelTank = {1,3,43,1700}
---

View File

@ -4324,3 +4324,78 @@ end
function UTILS.ScalarMult(vec, mult)
return {x = vec.x*mult, y = vec.y*mult, z = vec.z*mult}
end
--- Utilities weather class for fog mainly.
-- @type UTILS.Weather
UTILS.Weather = {}
--- Returns the current fog thickness in meters. Returns zero if fog is not present.
function UTILS.Weather.GetFogThickness()
return world.weather.getFogThickness()
end
--- Sets the fog to the desired thickness in meters at sea level.
-- @param #number Thickness Thickness in meters.
-- Any fog animation will be discarded.
-- Valid range : 100 to 5000 meters
function UTILS.Weather.SetFogThickness(Thickness)
local value = Thickness
if value < 100 then value = 100
elseif value > 5000 then value = 5000 end
return world.weather.setFogThickness(value)
end
--- Removes the fog.
function UTILS.Weather.RemoveFog()
return world.weather.setFogThickness(0)
end
--- Gets the maximum visibility distance of the current fog setting.
-- Returns 0 if no fog is present.
function UTILS.Weather.GetFogVisibilityDistanceMax()
return world.weather.getFogVisibilityDistance()
end
--- Sets the maximum visibility at sea level in meters.
-- @param #number Thickness Thickness in meters.
-- Limit: 100 to 100000
function UTILS.Weather.SetFogVisibilityDistance(Thickness)
local value = Thickness
if value < 100 then value = 100
elseif value > 100000 then value = 100000 end
return world.weather.setFogVisibilityDistance(value)
end
--- Uses data from the passed table to change the fog visibility and thickness over a desired timeframe. This allows for a gradual increase/decrease of fog values rather than abruptly applying the values.
-- Animation Key Format: {time, visibility, thickness}
-- @param #table AnimationKeys Table of AnimationKey tables
-- @usage
-- Time: in seconds 0 to infinity
-- Time is relative to when the function was called. Time value for each key must be larger than the previous key. If time is set to 0 then the fog will be applied to the corresponding visibility and thickness values at that key. Any time value greater than 0 will result in the current fog being inherited and changed to the first key.
-- Visibility: in meters 100 to 100000
-- Thickness: in meters 100 to 5000
-- The speed at which the visibility and thickness changes is based on the time between keys and the values that visibility and thickness are being set to.
--
-- When the function is passed an empty table {} or nil the fog animation will be discarded and whatever the current thickness and visibility are set to will remain.
--
-- The following will set the fog in the mission to disappear in 1 minute.
--
-- UTILS.Weather.SetFogAnimation({ {60, 0, 0} })
--
-- The following will take 1 hour to get to the first fog setting, it will maintain that fog setting for another hour, then lightly removes the fog over the 2nd and 3rd hour, the completely removes the fog after 3 hours and 3 minutes from when the function was called.
--
-- UTILS.Weather.SetFogAnimation({
-- {3600, 10000, 3000}, -- one hour to get to that fog setting
-- {7200, 10000, 3000}, -- will maintain for 2 hours
-- {10800, 20000, 2000}, -- at 3 hours visibility will have been increased while thickness decreases slightly
-- {12600, 0, 0}, -- at 3:30 after the function was called the fog will be completely removed.
-- })
--
function UTILS.Weather.SetFogAnimation(AnimationKeys)
return world.weather.setFogAnimation(AnimationKeys)
end
--- The fog animation will be discarded and whatever the current thickness and visibility are set to will remain
function UTILS.Weather.StopFogAnimation()
return world.weather.setFogAnimation({})
end