From 7c15e1119b0e4497d4bfa0fcca837603f743ea02 Mon Sep 17 00:00:00 2001 From: Thomas <72444570+Applevangelist@users.noreply.github.com> Date: Sat, 28 Feb 2026 17:32:50 +0100 Subject: [PATCH] #CTLD - Added localization and SRS #CTLD - Added localization and SRS --- Moose Development/Moose/Ops/CTLD_CARGO.lua | 720 +++++++++++++++++ Moose Development/Moose/Ops/CTLD_Hercules.lua | 669 ++++++++++++++++ .../Moose/Ops/CTLD_Localization.lua | 752 ++++++++++++++++++ 3 files changed, 2141 insertions(+) create mode 100644 Moose Development/Moose/Ops/CTLD_CARGO.lua create mode 100644 Moose Development/Moose/Ops/CTLD_Hercules.lua create mode 100644 Moose Development/Moose/Ops/CTLD_Localization.lua diff --git a/Moose Development/Moose/Ops/CTLD_CARGO.lua b/Moose Development/Moose/Ops/CTLD_CARGO.lua new file mode 100644 index 000000000..aef388204 --- /dev/null +++ b/Moose Development/Moose/Ops/CTLD_CARGO.lua @@ -0,0 +1,720 @@ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +-- TODO CTLD_CARGO +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + +do + +------------------------------------------------------ +--- **CTLD_CARGO** class, extends Core.Base#BASE +-- @type CTLD_CARGO +-- @field #string ClassName Class name. +-- @field #number ID ID of this cargo. +-- @field #string Name Name for menu. +-- @field #string DisplayName Display name for menu/messages. +-- @field #table Templates Table of #POSITIONABLE objects. +-- @field #string CargoType Enumerator of Type. +-- @field #boolean HasBeenMoved Flag for moving. +-- @field #boolean LoadDirectly Flag for direct loading. +-- @field #number CratesNeeded Crates needed to build. +-- @field Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission. +-- @field #boolean HasBeenDropped True if dropped from heli. +-- @field #number PerCrateMass Mass in kg. +-- @field #number Stock Number of builds available, -1 for unlimited. +-- @field #string Subcategory Sub-category name. +-- @field #boolean DontShowInMenu Show this item in menu or not. +-- @field Core.Zone#ZONE Location Location (if set) where to get this cargo item. +-- @field #table ResourceMap Resource Map information table if it has been set for static cargo items. +-- @field #string StaticShape Individual shape if set. +-- @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 + +--- +-- @field #CTLD_CARGO CTLD_CARGO +CTLD_CARGO = { + ClassName = "CTLD_CARGO", + ID = 0, + Name = "none", + DisplayName = "none", + Templates = {}, + CargoType = "none", + HasBeenMoved = false, + LoadDirectly = false, + CratesNeeded = 0, + Positionable = nil, + HasBeenDropped = false, + PerCrateMass = 0, + Stock = nil, + Stock0 = nil, + Mark = nil, + DontShowInMenu = false, + Location = nil, + } + + --- Define cargo types. + -- @type CTLD_CARGO.Enum + -- @field #string VEHICLE + -- @field #string TROOPS + -- @field #string FOB + -- @field #string CRATE + -- @field #string REPAIR + -- @field #string ENGINEERS + -- @field #string STATIC + -- @field #string GCLOADABLE + CTLD_CARGO.Enum = { + VEHICLE = "Vehicle", -- #string vehicles + TROOPS = "Troops", -- #string troops + FOB = "FOB", -- #string FOB + CRATE = "Crate", -- #string crate + REPAIR = "Repair", -- #string repair + ENGINEERS = "Engineers", -- #string engineers + STATIC = "Static", -- #string statics + GCLOADABLE = "GC_Loadable", -- #string dynamiccargo + } + + --- Function to create new CTLD_CARGO object. + -- @param #CTLD_CARGO self + -- @param #number ID ID of this #CTLD_CARGO + -- @param #string Name Name for menu. + -- @param #table Templates Table of #POSITIONABLE objects. + -- @param #CTLD_CARGO.Enum Sorte Enumerator of Type. + -- @param #boolean HasBeenMoved Flag for moving. + -- @param #boolean LoadDirectly Flag for direct loading. + -- @param #number CratesNeeded Crates needed to build. + -- @param Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission. + -- @param #boolean Dropped Cargo/Troops have been unloaded from a chopper. + -- @param #number PerCrateMass Mass in kg + -- @param #number Stock Number of builds available, nil for unlimited + -- @param #string Subcategory Name of subcategory, handy if using > 10 types to load. + -- @param #boolean DontShowInMenu Show this item in menu or not (default: false == show it). + -- @param Core.Zone#ZONE Location (optional) Where the cargo is available (one location only). + -- @return #CTLD_CARGO self + function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock, Subcategory, DontShowInMenu, Location) + -- Inherit everything from BASE class. + local self=BASE:Inherit(self, BASE:New()) -- #CTLD_CARGO + self:T({ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped}) + self.ID = ID or math.random(100000,1000000) + self.Name = Name or "none" -- #string + self.DisplayName = Name or "none" -- #string + self.Templates = Templates or {} -- #table + self.CargoType = Sorte or "type" -- #CTLD_CARGO.Enum + self.HasBeenMoved = HasBeenMoved or false -- #boolean + self.LoadDirectly = LoadDirectly or false -- #boolean + self.CratesNeeded = CratesNeeded or 0 -- #number + self.Positionable = Positionable or nil -- Wrapper.Positionable#POSITIONABLE + 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 + self.ResourceMap = nil + self.StaticType = "container_cargo" -- "container_cargo" + if self:IsStatic() then + self.StaticType = self.Templates + end + self.StaticShape = nil + self.TypeNames = nil + self.StaticCategory = "Cargos" + if type(Location) == "string" then + Location = ZONE:New(Location) + end + self.Location = Location + self.NoMoveToZone = false + return self + end + + --- Add specific static type and shape to this CARGO. + -- @param #CTLD_CARGO self + -- @param #string TypeName + -- @param #string ShapeName + -- @return #CTLD_CARGO self + function CTLD_CARGO:SetStaticTypeAndShape(Category,TypeName,ShapeName) + self.StaticCategory = Category or "Cargos" + self.StaticType = TypeName or "container_cargo" + self.StaticShape = ShapeName + return self + end + + --- Get the specific static type and shape from this CARGO if set. + -- @param #CTLD_CARGO self + -- @return #string Category + -- @return #string TypeName + -- @return #string ShapeName + function CTLD_CARGO:GetStaticTypeAndShape() + return self.StaticCategory, self.StaticType, self.StaticShape + end + + --- Add specific unit types to this CARGO (restrict what types can pick this up). + -- @param #CTLD_CARGO self + -- @param #string UnitTypes Unit type name, can also be a #list<#string> table of unit type names. + -- @return #CTLD_CARGO self + function CTLD_CARGO:AddUnitTypeName(UnitTypes) + if not self.TypeNames then self.TypeNames = {} end + if type(UnitTypes) ~= "table" then UnitTypes = {UnitTypes} end + for _,_singletype in pairs(UnitTypes or {}) do + self.TypeNames[_singletype]=_singletype + end + return self + end + + --- Check if a specific unit can carry this CARGO (restrict what types can pick this up). + -- @param #CTLD_CARGO self + -- @param Wrapper.Unit#UNIT Unit + -- @return #boolean Outcome + function CTLD_CARGO:UnitCanCarry(Unit) + if not Unit then return false end + if self.TypeNames == nil then return true end + local typename = Unit:GetTypeName() or "none" + if self.TypeNames[typename] then + return true + else + return false + end + end + + --- Add Resource Map information table + -- @param #CTLD_CARGO self + -- @param #table ResourceMap + -- @return #CTLD_CARGO self + function CTLD_CARGO:SetStaticResourceMap(ResourceMap) + self.ResourceMap = ResourceMap + return self + end + + --- Get Resource Map information table + -- @param #CTLD_CARGO self + -- @return #table ResourceMap + function CTLD_CARGO:GetStaticResourceMap() + return self.ResourceMap + end + + --- Query Location. + -- @param #CTLD_CARGO self + -- @return Core.Zone#ZONE location or `nil` if not set + function CTLD_CARGO:GetLocation() + return self.Location + end + + --- Query ID. + -- @param #CTLD_CARGO self + -- @return #number ID + function CTLD_CARGO:GetID() + return self.ID + end + + --- Query Subcategory + -- @param #CTLD_CARGO self + -- @return #string SubCategory + function CTLD_CARGO:GetSubCat() + return self.Subcategory + end + + --- Query Mass. + -- @param #CTLD_CARGO self + -- @return #number Mass in kg + function CTLD_CARGO:GetMass() + return self.PerCrateMass + end + + --- Query Name. + -- @param #CTLD_CARGO self + -- @return #string Name + function CTLD_CARGO:GetName() + return self.Name + end + + --- Set display name. + -- @param #CTLD_CARGO self + -- @param #string DisplayName Display label used in menus/messages (optional). + -- @return #CTLD_CARGO self + function CTLD_CARGO:SetDisplayName(DisplayName) + if type(DisplayName) == "string" and DisplayName ~= "" then + self.DisplayName = DisplayName + else + self.DisplayName = self.Name + end + return self + end + + --- Query display name. + -- @param #CTLD_CARGO self + -- @return #string Display name, or Name if not set + function CTLD_CARGO:GetDisplayName() + return self.DisplayName or self.Name + end + + --- Query Templates. + -- @param #CTLD_CARGO self + -- @return #table Templates + function CTLD_CARGO:GetTemplates() + return self.Templates + end + + --- Query has moved. + -- @param #CTLD_CARGO self + -- @return #boolean Has moved + function CTLD_CARGO:HasMoved() + return self.HasBeenMoved + end + + --- Query was dropped. + -- @param #CTLD_CARGO self + -- @param #boolean hercOnly If true, only treat Herc drops as 'dropped'. + -- @return #boolean Has been dropped. + function CTLD_CARGO:WasDropped(hercOnly) + if hercOnly then + return self.HasBeenDropped and self.IsHercDrop==true + end + return self.HasBeenDropped + end + + --- Query directly loadable. + -- @param #CTLD_CARGO self + -- @return #boolean loadable + function CTLD_CARGO:CanLoadDirectly() + return self.LoadDirectly + end + + --- Query number of crates or troopsize. + -- @param #CTLD_CARGO self + -- @return #number Crates or size of troops. + function CTLD_CARGO:GetCratesNeeded() + return self.CratesNeeded + end + + --- Query type. + -- @param #CTLD_CARGO self + -- @return #CTLD_CARGO.Enum Type + function CTLD_CARGO:GetType() + return self.CargoType + end + + --- Query type. + -- @param #CTLD_CARGO self + -- @return Wrapper.Positionable#POSITIONABLE Positionable + function CTLD_CARGO:GetPositionable() + return self.Positionable + end + + --- Set HasMoved. + -- @param #CTLD_CARGO self + -- @param #boolean moved + function CTLD_CARGO:SetHasMoved(moved) + self.HasBeenMoved = moved or false + end + + --- Query if cargo has been loaded. + -- @param #CTLD_CARGO self + -- @param #boolean loaded + function CTLD_CARGO:Isloaded() + if self.HasBeenMoved and not self:WasDropped() then + return true + else + return false + end + end + + --- Set WasDropped. + -- @param #CTLD_CARGO self + -- @param #boolean dropped + -- @param #boolean isHercDrop set when _GetCrates is used by the herc + function CTLD_CARGO:SetWasDropped(dropped, isHercDrop) + self.HasBeenDropped = dropped or false + self.IsHercDrop = isHercDrop or false + end + + --- Get Stock. + -- @param #CTLD_CARGO self + -- @return #number Stock or -1 if unlimited. + function CTLD_CARGO:GetStock() + if self.Stock then + return self.Stock + else + return -1 + 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. + -- @return #CTLD_CARGO self + function CTLD_CARGO:AddStock(Number) + if self.Stock then -- Stock nil? + local number = Number or 1 + self.Stock = self.Stock + number + end + return self + end + + --- Remove Stock. + -- @param #CTLD_CARGO self + -- @param #number Number to reduce, none if nil. + -- @return #CTLD_CARGO self + function CTLD_CARGO:RemoveStock(Number) + if self.Stock then -- Stock nil? + local number = Number or 1 + self.Stock = self.Stock - number + if self.Stock < 0 then self.Stock = 0 end + end + return self + end + + --- Set Stock. + -- @param #CTLD_CARGO self + -- @param #number Number to set, nil means unlimited. + -- @return #CTLD_CARGO self + function CTLD_CARGO:SetStock(Number) + self.Stock = Number + return self + end + + --- Query crate type for REPAIR + -- @param #CTLD_CARGO self + -- @param #boolean + function CTLD_CARGO:IsRepair() + if self.CargoType == "Repair" then + return true + else + return false + end + end + + --- Query crate type for STATIC + -- @param #CTLD_CARGO self + -- @return #boolean + function CTLD_CARGO:IsStatic() + if self.CargoType == "Static" then + return true + else + return false + end + end + + --- Add mark + -- @param #CTLD_CARGO self + -- @return #CTLD_CARGO self + function CTLD_CARGO:AddMark(Mark) + self.Mark = Mark + return self + end + + --- Get mark + -- @param #CTLD_CARGO self + -- @return #string Mark + function CTLD_CARGO:GetMark(Mark) + return self.Mark + end + + --- Wipe mark + -- @param #CTLD_CARGO self + -- @return #CTLD_CARGO self + function CTLD_CARGO:WipeMark() + self.Mark = nil + return self + end + + --- Get overall mass of a cargo object, i.e. crates needed x mass per crate + -- @param #CTLD_CARGO self + -- @return #number mass + function CTLD_CARGO:GetNetMass() + return self.CratesNeeded * self.PerCrateMass + end + +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +-- END CTLD_CARGO +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + +do + +------------------------------------------------------ +--- **CTLD_ENGINEERING** class, extends Core.Base#BASE +-- @type CTLD_ENGINEERING +-- @field #string ClassName +-- @field #string lid +-- @field #string Name +-- @field Wrapper.Group#GROUP Group +-- @field Wrapper.Unit#UNIT Unit +-- @field Wrapper.Group#GROUP HeliGroup +-- @field Wrapper.Unit#UNIT HeliUnit +-- @field #string State +-- @extends Core.Base#BASE + +--- +-- @field #CTLD_ENGINEERING CTLD_ENGINEERING +CTLD_ENGINEERING = { + ClassName = "CTLD_ENGINEERING", + lid = "", + Name = "none", + Group = nil, + Unit = nil, + --C_Ops = nil, + HeliGroup = nil, + HeliUnit = nil, + State = "", + } + + --- CTLD_ENGINEERING class version. + -- @field #string version + CTLD_ENGINEERING.Version = "0.0.3" + + --- Create a new instance. + -- @param #CTLD_ENGINEERING self + -- @param #string Name + -- @param #string GroupName Name of Engineering #GROUP object + -- @param Wrapper.Group#GROUP HeliGroup HeliGroup + -- @param Wrapper.Unit#UNIT HeliUnit HeliUnit + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:New(Name, GroupName, HeliGroup, HeliUnit) + + -- Inherit everything from BASE class. + local self=BASE:Inherit(self, BASE:New()) -- #CTLD_ENGINEERING + + --BASE:I({Name, GroupName}) + + self.Name = Name or "Engineer Squad" -- #string + self.Group = GROUP:FindByName(GroupName) -- Wrapper.Group#GROUP + self.Unit = self.Group:GetUnit(1) -- Wrapper.Unit#UNIT + self.HeliGroup = HeliGroup -- Wrapper.Group#GROUP + self.HeliUnit = HeliUnit -- Wrapper.Unit#UNIT + self.currwpt = nil -- Core.Point#COORDINATE + self.lid = string.format("%s (%s) | ",self.Name, self.Version) + -- Start State. + self.State = "Stopped" + self.marktimer = 300 -- wait this many secs before trying a crate again + self:Start() + local parent = self:GetParent(self) + return self + end + + --- (Internal) Set the status + -- @param #CTLD_ENGINEERING self + -- @param #string State + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:SetStatus(State) + self.State = State + return self + end + + --- (Internal) Get the status + -- @param #CTLD_ENGINEERING self + -- @return #string State + function CTLD_ENGINEERING:GetStatus() + return self.State + end + + --- (Internal) Check the status + -- @param #CTLD_ENGINEERING self + -- @param #string State + -- @return #boolean Outcome + function CTLD_ENGINEERING:IsStatus(State) + return self.State == State + end + + --- (Internal) Check the negative status + -- @param #CTLD_ENGINEERING self + -- @param #string State + -- @return #boolean Outcome + function CTLD_ENGINEERING:IsNotStatus(State) + return self.State ~= State + end + + --- (Internal) Set start status. + -- @param #CTLD_ENGINEERING self + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:Start() + self:T(self.lid.."Start") + self:SetStatus("Running") + return self + end + + --- (Internal) Set stop status. + -- @param #CTLD_ENGINEERING self + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:Stop() + self:T(self.lid.."Stop") + self:SetStatus("Stopped") + return self + end + + --- (Internal) Set build status. + -- @param #CTLD_ENGINEERING self + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:Build() + self:T(self.lid.."Build") + self:SetStatus("Building") + return self + end + + --- (Internal) Set done status. + -- @param #CTLD_ENGINEERING self + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:Done() + self:T(self.lid.."Done") + local grp = self.Group -- Wrapper.Group#GROUP + grp:RelocateGroundRandomInRadius(7,100,false,false,"Diamond") + self:SetStatus("Running") + return self + end + + --- (Internal) Search for crates in reach. + -- @param #CTLD_ENGINEERING self + -- @param #table crates Table of found crate Ops.CTLD#CTLD_CARGO objects. + -- @param #number number Number of crates found. + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:Search(crates,number) + self:T(self.lid.."Search") + self:SetStatus("Searching") + -- find crates close by + --local COps = self.C_Ops -- Ops.CTLD#CTLD + local dist = self.distance -- #number + local group = self.Group -- Wrapper.Group#GROUP + --local crates,number = COps:_FindCratesNearby(group,nil, dist) -- #table + local ctable = {} + local ind = 0 + if number > 0 then + -- get set of dropped only + for _,_cargo in pairs (crates) do + local cgotype = _cargo:GetType() + if _cargo:WasDropped() and cgotype ~= CTLD_CARGO.Enum.STATIC then + local ok = false + local chalk = _cargo:GetMark() + if chalk == nil then + ok = true + else + -- have we tried this cargo recently? + local tag = chalk.tag or "none" + local timestamp = chalk.timestamp or 0 + -- enough time gone? + local gone = timer.getAbsTime() - timestamp + if gone >= self.marktimer then + ok = true + _cargo:WipeMark() + end -- end time check + end -- end chalk + if ok then + local chalk = {} + chalk.tag = "Engineers" + chalk.timestamp = timer.getAbsTime() + _cargo:AddMark(chalk) + ind = ind + 1 + table.insert(ctable,ind,_cargo) + end + end -- end dropped + end -- end for + end -- end number + + if ind > 0 then + local crate = ctable[1] -- Ops.CTLD#CTLD_CARGO + local static = crate:GetPositionable() -- Wrapper.Static#STATIC + local crate_pos = static:GetCoordinate() -- Core.Point#COORDINATE + local gpos = group:GetCoord() -- Core.Point#COORDINATE + -- see how far we are from the crate + local distance = self:_GetDistance(gpos,crate_pos) + self:T(string.format("%s Distance to crate: %d", self.lid, distance)) + -- move there + if distance > 30 and distance ~= -1 and self:IsStatus("Searching") then + group:RouteGroundTo(crate_pos,15,"Line abreast",1) + self.currwpt = crate_pos -- Core.Point#COORDINATE + self:Move() + elseif distance <= 30 and distance ~= -1 then + -- arrived + self:Arrive() + end + else + self:T(self.lid.."No crates in reach!") + end + return self + end + + --- (Internal) Move towards crates in reach. + -- @param #CTLD_ENGINEERING self + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:Move() + self:T(self.lid.."Move") + self:SetStatus("Moving") + -- check if we arrived on target + --local COps = self.C_Ops -- Ops.CTLD#CTLD + local group = self.Group -- Wrapper.Group#GROUP + local tgtpos = self.currwpt -- Core.Point#COORDINATE + local gpos = group:GetCoord() -- Core.Point#COORDINATE + -- see how far we are from the crate + local distance = self:_GetDistance(gpos,tgtpos) + self:T(string.format("%s Distance remaining: %d", self.lid, distance)) + if distance <= 30 and distance ~= -1 then + -- arrived + self:Arrive() + end + return self + end + + --- (Internal) Arrived at crates in reach. Stop group. + -- @param #CTLD_ENGINEERING self + -- @return #CTLD_ENGINEERING self + function CTLD_ENGINEERING:Arrive() + self:T(self.lid.."Arrive") + self:SetStatus("Arrived") + self.currwpt = nil + local Grp = self.Group -- Wrapper.Group#GROUP + Grp:RouteStop() + return self + end + + --- (Internal) Return distance in meters between two coordinates. + -- @param #CTLD_ENGINEERING self + -- @param Core.Point#COORDINATE _point1 Coordinate one + -- @param Core.Point#COORDINATE _point2 Coordinate two + -- @return #number Distance in meters or -1 + function CTLD_ENGINEERING:_GetDistance(_point1, _point2) + self:T(self.lid .. " _GetDistance") + if _point1 and _point2 then + local distance1 = _point1:Get2DDistance(_point2) + local distance2 = _point1:DistanceFromPointVec2(_point2) + if distance1 and type(distance1) == "number" then + return distance1 + elseif distance2 and type(distance2) == "number" then + return distance2 + else + self:E("*****Cannot calculate distance!") + self:E({_point1,_point2}) + return -1 + end + else + self:E("******Cannot calculate distance!") + self:E({_point1,_point2}) + return -1 + end + end + +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +-- END CTLD_ENGINEERING +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/Moose Development/Moose/Ops/CTLD_Hercules.lua b/Moose Development/Moose/Ops/CTLD_Hercules.lua new file mode 100644 index 000000000..03d72b47d --- /dev/null +++ b/Moose Development/Moose/Ops/CTLD_Hercules.lua @@ -0,0 +1,669 @@ +do +--- **Hercules Cargo AIR Drop Events** by Anubis Yinepu +-- Moose CTLD OO refactoring by Applevangelist +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +-- TODO CTLD_HERCULES +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +-- This script will only work for the Herculus mod by Anubis, and only for **Air Dropping** cargo from the Hercules. +-- It *DOES NOT* work with the purchaseable Hercules module from ED. +-- Use the standard Moose CTLD if you want to unload on the ground. +-- Payloads carried by pylons 11, 12 and 13 need to be declared in the Herculus_Loadout.lua file +-- Except for Ammo pallets, this script will spawn whatever payload gets launched from pylons 11, 12 and 13 +-- Pylons 11, 12 and 13 are moveable within the Hercules cargobay area +-- Ammo pallets can only be jettisoned from these pylons with no benefit to DCS world +-- To benefit DCS world, Ammo pallets need to be off/on loaded using DCS arming and refueling window +-- Cargo_Container_Enclosed = true: Cargo enclosed in container with parachute, need to be dropped from 100m (300ft) or more, except when parked on ground +-- Cargo_Container_Enclosed = false: Open cargo with no parachute, need to be dropped from 10m (30ft) or less + +------------------------------------------------------ +--- **CTLD_HERCULES** class, extends Core.Base#BASE +-- @type CTLD_HERCULES +-- @field #string ClassName +-- @field #string lid +-- @field #string Name +-- @field #string Version +-- @extends Core.Base#BASE +CTLD_HERCULES = { + ClassName = "CTLD_HERCULES", + lid = "", + Name = "", + Version = "0.0.3", +} + +--- Define cargo types. +-- @type CTLD_HERCULES.Types +-- @field #table Type Name of cargo type, container (boolean) in container or not. +CTLD_HERCULES.Types = { + ["ATGM M1045 HMMWV TOW Air [7183lb]"] = {['name'] = "M1045 HMMWV TOW", ['container'] = true}, + ["ATGM M1045 HMMWV TOW Skid [7073lb]"] = {['name'] = "M1045 HMMWV TOW", ['container'] = false}, + ["APC M1043 HMMWV Armament Air [7023lb]"] = {['name'] = "M1043 HMMWV Armament", ['container'] = true}, + ["APC M1043 HMMWV Armament Skid [6912lb]"] = {['name'] = "M1043 HMMWV Armament", ['container'] = false}, + ["SAM Avenger M1097 Air [7200lb]"] = {['name'] = "M1097 Avenger", ['container'] = true}, + ["SAM Avenger M1097 Skid [7090lb]"] = {['name'] = "M1097 Avenger", ['container'] = false}, + ["APC Cobra Air [10912lb]"] = {['name'] = "Cobra", ['container'] = true}, + ["APC Cobra Skid [10802lb]"] = {['name'] = "Cobra", ['container'] = false}, + ["APC M113 Air [21624lb]"] = {['name'] = "M-113", ['container'] = true}, + ["APC M113 Skid [21494lb]"] = {['name'] = "M-113", ['container'] = false}, + ["Tanker M978 HEMTT [34000lb]"] = {['name'] = "M978 HEMTT Tanker", ['container'] = false}, + ["HEMTT TFFT [34400lb]"] = {['name'] = "HEMTT TFFT", ['container'] = false}, + ["SPG M1128 Stryker MGS [33036lb]"] = {['name'] = "M1128 Stryker MGS", ['container'] = false}, + ["AAA Vulcan M163 Air [21666lb]"] = {['name'] = "Vulcan", ['container'] = true}, + ["AAA Vulcan M163 Skid [21577lb]"] = {['name'] = "Vulcan", ['container'] = false}, + ["APC M1126 Stryker ICV [29542lb]"] = {['name'] = "M1126 Stryker ICV", ['container'] = false}, + ["ATGM M1134 Stryker [30337lb]"] = {['name'] = "M1134 Stryker ATGM", ['container'] = false}, + ["APC LAV-25 Air [22520lb]"] = {['name'] = "LAV-25", ['container'] = true}, + ["APC LAV-25 Skid [22514lb]"] = {['name'] = "LAV-25", ['container'] = false}, + ["M1025 HMMWV Air [6160lb]"] = {['name'] = "Hummer", ['container'] = true}, + ["M1025 HMMWV Skid [6050lb]"] = {['name'] = "Hummer", ['container'] = false}, + ["IFV M2A2 Bradley [34720lb]"] = {['name'] = "M-2 Bradley", ['container'] = false}, + ["IFV MCV-80 [34720lb]"] = {['name'] = "MCV-80", ['container'] = false}, + ["IFV BMP-1 [23232lb]"] = {['name'] = "BMP-1", ['container'] = false}, + ["IFV BMP-2 [25168lb]"] = {['name'] = "BMP-2", ['container'] = false}, + ["IFV BMP-3 [32912lb]"] = {['name'] = "BMP-3", ['container'] = false}, + ["ARV BRDM-2 Air [12320lb]"] = {['name'] = "BRDM-2", ['container'] = true}, + ["ARV BRDM-2 Skid [12210lb]"] = {['name'] = "BRDM-2", ['container'] = false}, + ["APC BTR-80 Air [23936lb]"] = {['name'] = "BTR-80", ['container'] = true}, + ["APC BTR-80 Skid [23826lb]"] = {['name'] = "BTR-80", ['container'] = false}, + ["APC BTR-82A Air [24998lb]"] = {['name'] = "BTR-82A", ['container'] = true}, + ["APC BTR-82A Skid [24888lb]"] = {['name'] = "BTR-82A", ['container'] = false}, + ["SAM ROLAND ADS [34720lb]"] = {['name'] = "Roland Radar", ['container'] = false}, + ["SAM ROLAND LN [34720b]"] = {['name'] = "Roland ADS", ['container'] = false}, + ["SAM SA-13 STRELA [21624lb]"] = {['name'] = "Strela-10M3", ['container'] = false}, + ["AAA ZSU-23-4 Shilka [32912lb]"] = {['name'] = "ZSU-23-4 Shilka", ['container'] = false}, + ["SAM SA-19 Tunguska 2S6 [34720lb]"] = {['name'] = "2S6 Tunguska", ['container'] = false}, + ["Transport UAZ-469 Air [3747lb]"] = {['name'] = "UAZ-469", ['container'] = true}, + ["Transport UAZ-469 Skid [3630lb]"] = {['name'] = "UAZ-469", ['container'] = false}, + ["AAA GEPARD [34720lb]"] = {['name'] = "Gepard", ['container'] = false}, + ["SAM CHAPARRAL Air [21624lb]"] = {['name'] = "M48 Chaparral", ['container'] = true}, + ["SAM CHAPARRAL Skid [21516lb]"] = {['name'] = "M48 Chaparral", ['container'] = false}, + ["SAM LINEBACKER [34720lb]"] = {['name'] = "M6 Linebacker", ['container'] = false}, + ["Transport URAL-375 [14815lb]"] = {['name'] = "Ural-375", ['container'] = false}, + ["Transport M818 [16000lb]"] = {['name'] = "M 818", ['container'] = false}, + ["IFV MARDER [34720lb]"] = {['name'] = "Marder", ['container'] = false}, + ["Transport Tigr Air [15900lb]"] = {['name'] = "Tigr_233036", ['container'] = true}, + ["Transport Tigr Skid [15730lb]"] = {['name'] = "Tigr_233036", ['container'] = false}, + ["IFV TPZ FUCH [33440lb]"] = {['name'] = "TPZ", ['container'] = false}, + ["IFV BMD-1 Air [18040lb]"] = {['name'] = "BMD-1", ['container'] = true}, + ["IFV BMD-1 Skid [17930lb]"] = {['name'] = "BMD-1", ['container'] = false}, + ["IFV BTR-D Air [18040lb]"] = {['name'] = "BTR_D", ['container'] = true}, + ["IFV BTR-D Skid [17930lb]"] = {['name'] = "BTR_D", ['container'] = false}, + ["EWR SBORKA Air [21624lb]"] = {['name'] = "Dog Ear radar", ['container'] = true}, + ["EWR SBORKA Skid [21624lb]"] = {['name'] = "Dog Ear radar", ['container'] = false}, + ["ART 2S9 NONA Air [19140lb]"] = {['name'] = "SAU 2-C9", ['container'] = true}, + ["ART 2S9 NONA Skid [19030lb]"] = {['name'] = "SAU 2-C9", ['container'] = false}, + ["ART GVOZDIKA [34720lb]"] = {['name'] = "SAU Gvozdika", ['container'] = false}, + ["APC MTLB Air [26400lb]"] = {['name'] = "MTLB", ['container'] = true}, + ["APC MTLB Skid [26290lb]"] = {['name'] = "MTLB", ['container'] = false}, +} + +--- Cargo Object +-- @type CTLD_HERCULES.CargoObject +-- @field #number Cargo_Drop_Direction +-- @field #table Cargo_Contents +-- @field #string Cargo_Type_name +-- @field #boolean Container_Enclosed +-- @field #boolean ParatrooperGroupSpawn +-- @field #number Cargo_Country +-- @field #boolean offload_cargo +-- @field #boolean all_cargo_survive_to_the_ground +-- @field #boolean all_cargo_gets_destroyed +-- @field #boolean destroy_cargo_dropped_without_parachute +-- @field Core.Timer#TIMER scheduleFunctionID + +--- [User] Instantiate a new object +-- @param #CTLD_HERCULES self +-- @param #string Coalition Coalition side, "red", "blue" or "neutral" +-- @param #string Alias Name of this instance +-- @param Ops.CTLD#CTLD CtldObject CTLD instance to link into +-- @return #CTLD_HERCULES self +-- @usage +-- Integrate to your CTLD instance like so, where `my_ctld` is a previously created CTLD instance: +-- +-- my_ctld.enableFixedWing = false -- avoid dual loading via CTLD F10 and F8 ground crew +-- local herccargo = CTLD_HERCULES:New("blue", "Hercules Test", my_ctld) +-- +-- You also need: +-- * A template called "Infantry" for 10 Paratroopers (as set via herccargo.infantrytemplate). +-- * Depending on what you are loading with the help of the ground crew, there are 42 more templates for the various vehicles that are loadable. +-- There's a **quick check output in the `dcs.log`** which tells you what's there and what not. +-- E.g.: +-- ...Checking template for APC BTR-82A Air [24998lb] (BTR-82A) ... MISSING) +-- ...Checking template for ART 2S9 NONA Skid [19030lb] (SAU 2-C9) ... MISSING) +-- ...Checking template for EWR SBORKA Air [21624lb] (Dog Ear radar) ... MISSING) +-- ...Checking template for Transport Tigr Air [15900lb] (Tigr_233036) ... OK) +-- +-- Expected template names are the ones in the rounded brackets. +-- +-- ### HINTS +-- +-- The script works on the EVENTS.Shot trigger, which is used by the mod when you **drop cargo from the Hercules while flying**. Unloading on the ground does +-- not achieve anything here. If you just want to unload on the ground, use the normal Moose CTLD. +-- **Do not use** the **splash damage** script together with this, your cargo will just explode when reaching the ground! +-- +-- ### Airdrops +-- +-- There are two ways of airdropping: +-- 1) Very low and very slow (>5m and <10m AGL) - here you can drop stuff which has "Skid" at the end of the cargo name (loaded via F8 Ground Crew menu) +-- 2) Higher up and slow (>100m AGL) - here you can drop paratroopers and cargo which has "Air" at the end of the cargo name (loaded via F8 Ground Crew menu) +-- +-- ### General +-- +-- Use either this method to integrate the Hercules **or** the one from the "normal" CTLD. Never both! +function CTLD_HERCULES:New(Coalition, Alias, CtldObject) + -- Inherit everything from FSM class. + local self=BASE:Inherit(self, FSM:New()) -- #CTLD_HERCULES + + --set Coalition + if Coalition and type(Coalition)=="string" then + if Coalition=="blue" then + self.coalition=coalition.side.BLUE + self.coalitiontxt = Coalition + elseif Coalition=="red" then + self.coalition=coalition.side.RED + self.coalitiontxt = Coalition + elseif Coalition=="neutral" then + self.coalition=coalition.side.NEUTRAL + self.coalitiontxt = Coalition + else + self:E("ERROR: Unknown coalition in CTLD!") + end + else + self.coalition = Coalition + self.coalitiontxt = string.lower(UTILS.GetCoalitionName(self.coalition)) + end + + -- Set alias. + if Alias then + self.alias=tostring(Alias) + else + self.alias="UNHCR" + if self.coalition then + if self.coalition==coalition.side.RED then + self.alias="Red CTLD Hercules" + elseif self.coalition==coalition.side.BLUE then + self.alias="Blue CTLD Hercules" + end + end + end + + -- Set some string id for output to DCS.log file. + self.lid=string.format("%s (%s) | ", self.alias, self.coalitiontxt) + + self.infantrytemplate = "Infantry" -- template for a group of 10 paratroopers + self.CTLD = CtldObject -- Ops.CTLD#CTLD + + self.verbose = true + + self.j = 0 + self.carrierGroups = {} + self.Cargo = {} + self.ParatrooperCount = {} + + self.ObjectTracker = {} + + -- Set some string id for output to DCS.log file. + self.lid=string.format("%s (%s) | ", self.alias, self.coalition and UTILS.GetCoalitionName(self.coalition) or "unknown") + + self:HandleEvent(EVENTS.Shot, self._HandleShot) + + self:I(self.lid .. "Started") + + self:CheckTemplates() + + return self +end + +--- [Internal] Function to check availability of templates +-- @param #CTLD_HERCULES self +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:CheckTemplates() + self:T(self.lid .. 'CheckTemplates') + -- inject Paratroopers + self.Types["Paratroopers 10"] = { + name = self.infantrytemplate, + container = false, + available = false, + } + local missing = {} + local nomissing = 0 + local found = {} + local nofound = 0 + + -- list of groundcrew loadables + for _index,_tab in pairs (self.Types) do + local outcometxt = "MISSING" + if _DATABASE.Templates.Groups[_tab.name] then + outcometxt = "OK" + self.Types[_index].available= true + found[_tab.name] = true + else + self.Types[_index].available = false + missing[_tab.name] = true + end + if self.verbose then + self:I(string.format(self.lid .. "Checking template for %s (%s) ... %s", _index,_tab.name,outcometxt)) + end + end + for _,_name in pairs(found) do + nofound = nofound + 1 + end + for _,_name in pairs(missing) do + nomissing = nomissing + 1 + end + self:I(string.format(self.lid .. "Template Check Summary: Found %d, Missing %d, Total %d",nofound,nomissing,nofound+nomissing)) + return self +end + +--- [Internal] Function to spawn a soldier group of 10 units +-- @param #CTLD_HERCULES self +-- @param Wrapper.Group#GROUP Cargo_Drop_initiator +-- @param Core.Point#COORDINATE Cargo_Drop_Position +-- @param #string Cargo_Type_name +-- @param #number CargoHeading +-- @param #number Cargo_Country +-- @param #number GroupSpacing +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Drop_Position, Cargo_Type_name, CargoHeading, Cargo_Country, GroupSpacing) + --- TODO: Rework into Moose Spawns + self:T(self.lid .. 'Soldier_SpawnGroup') + self:T(Cargo_Drop_Position) + -- create a matching #CTLD_CARGO type + local InjectTroopsType = CTLD_CARGO:New(nil,self.infantrytemplate,{self.infantrytemplate},CTLD_CARGO.Enum.TROOPS,true,true,10,nil,false,80) + -- get a #ZONE object + local position = Cargo_Drop_Position:GetVec2() + local dropzone = ZONE_RADIUS:New("Infantry " .. math.random(1,10000),position,100) + -- and go: + self.CTLD:InjectTroops(dropzone,InjectTroopsType) + return self +end + +--- [Internal] Function to spawn a group +-- @param #CTLD_HERCULES self +-- @param Wrapper.Group#GROUP Cargo_Drop_initiator +-- @param Core.Point#COORDINATE Cargo_Drop_Position +-- @param #string Cargo_Type_name +-- @param #number CargoHeading +-- @param #number Cargo_Country +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:Cargo_SpawnGroup(Cargo_Drop_initiator,Cargo_Drop_Position, Cargo_Type_name, CargoHeading, Cargo_Country) + --- TODO: Rework into Moose Spawns + self:T(self.lid .. "Cargo_SpawnGroup") + self:T(Cargo_Type_name) + if Cargo_Type_name ~= 'Container red 1' then + -- create a matching #CTLD_CARGO type + local InjectVehicleType = CTLD_CARGO:New(nil,Cargo_Type_name,{Cargo_Type_name},CTLD_CARGO.Enum.VEHICLE,true,true,1,nil,false,1000) + -- get a #ZONE object + local position = Cargo_Drop_Position:GetVec2() + local dropzone = ZONE_RADIUS:New("Vehicle " .. math.random(1,10000),position,100) + -- and go: + self.CTLD:InjectVehicles(dropzone,InjectVehicleType) + end + return self +end + +--- [Internal] Function to spawn static cargo +-- @param #CTLD_HERCULES self +-- @param Wrapper.Group#GROUP Cargo_Drop_initiator +-- @param Core.Point#COORDINATE Cargo_Drop_Position +-- @param #string Cargo_Type_name +-- @param #number CargoHeading +-- @param #boolean dead +-- @param #number Cargo_Country +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:Cargo_SpawnStatic(Cargo_Drop_initiator,Cargo_Drop_Position, Cargo_Type_name, CargoHeading, dead, Cargo_Country) + --- TODO: Rework into Moose Static Spawns + self:T(self.lid .. "Cargo_SpawnStatic") + self:T("Static " .. Cargo_Type_name .. " Dead " .. tostring(dead)) + local position = Cargo_Drop_Position:GetVec2() + local Zone = ZONE_RADIUS:New("Cargo Static " .. math.random(1,10000),position,100) + if not dead then + local injectstatic = CTLD_CARGO:New(nil,"Cargo Static Group "..math.random(1,10000),"iso_container",CTLD_CARGO.Enum.STATIC,true,false,1,nil,true,4500,1) + self.CTLD:InjectStatics(Zone,injectstatic,true,true) + end + return self +end + +--- [Internal] Function to spawn cargo by type at position +-- @param #CTLD_HERCULES self +-- @param #string Cargo_Type_name +-- @param Core.Point#COORDINATE Cargo_Drop_Position +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:Cargo_SpawnDroppedAsCargo(_name, _pos) + local theCargo = self.CTLD:_FindCratesCargoObject(_name) -- #CTLD_CARGO + if theCargo then + self.CTLD.CrateCounter = self.CTLD.CrateCounter + 1 + local CCat, CType, CShape = theCargo:GetStaticTypeAndShape() + local basetype = CType or self.CTLD.basetype or "container_cargo" + CCat = CCat or "Cargos" + local theStatic = SPAWNSTATIC:NewFromType(basetype,CCat,self.cratecountry) + :InitCargoMass(theCargo.PerCrateMass) + :InitCargo(self.CTLD.enableslingload) + :InitCoordinate(_pos) + if CShape then + theStatic:InitShape(CShape) + end + theStatic:Spawn(270,_name .. "-Container-".. math.random(1,100000)) + + self.CTLD.Spawned_Crates[self.CTLD.CrateCounter] = theStatic + local newCargo = CTLD_CARGO:New(self.CTLD.CargoCounter, theCargo.Name, theCargo.Templates, theCargo.CargoType, true, false, theCargo.CratesNeeded, self.CTLD.Spawned_Crates[self.CTLD.CrateCounter], true, theCargo.PerCrateMass, nil, theCargo.Subcategory) + local map=theCargo:GetStaticResourceMap() + newCargo:SetStaticResourceMap(map) + table.insert(self.CTLD.Spawned_Cargo, newCargo) + + newCargo:SetWasDropped(true) + newCargo:SetHasMoved(true) + end + return self +end + +--- [Internal] Spawn cargo objects +-- @param #CTLD_HERCULES self +-- @param Wrapper.Group#GROUP Cargo_Drop_initiator +-- @param #number Cargo_Drop_Direction +-- @param Core.Point#COORDINATE Cargo_Content_position +-- @param #string Cargo_Type_name +-- @param #boolean Cargo_over_water +-- @param #boolean Container_Enclosed +-- @param #boolean ParatrooperGroupSpawn +-- @param #boolean offload_cargo +-- @param #boolean all_cargo_survive_to_the_ground +-- @param #boolean all_cargo_gets_destroyed +-- @param #boolean destroy_cargo_dropped_without_parachute +-- @param #number Cargo_Country +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:Cargo_SpawnObjects(Cargo_Drop_initiator,Cargo_Drop_Direction, Cargo_Content_position, Cargo_Type_name, Cargo_over_water, Container_Enclosed, ParatrooperGroupSpawn, offload_cargo, all_cargo_survive_to_the_ground, all_cargo_gets_destroyed, destroy_cargo_dropped_without_parachute, Cargo_Country) + self:T(self.lid .. 'Cargo_SpawnObjects') + + local CargoHeading = self.CargoHeading + + if offload_cargo == true or ParatrooperGroupSpawn == true then + if ParatrooperGroupSpawn == true then + self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 10) + else + self:Cargo_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country) + end + else + if all_cargo_gets_destroyed == true or Cargo_over_water == true then + + else + if all_cargo_survive_to_the_ground == true then + if ParatrooperGroupSpawn == true then + self:Cargo_SpawnStatic(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, true, Cargo_Country) + else + self:Cargo_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country) + end + if Container_Enclosed == true then + if ParatrooperGroupSpawn == false then + self:Cargo_SpawnStatic(Cargo_Drop_initiator,Cargo_Content_position, "Hercules_Container_Parachute_Static", CargoHeading, false, Cargo_Country) + end + end + end + if destroy_cargo_dropped_without_parachute == true then + if Container_Enclosed == true then + if ParatrooperGroupSpawn == true then + self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 0) + else + if self.CTLD.dropAsCargoCrate then + self:Cargo_SpawnDroppedAsCargo(Cargo_Type_name, Cargo_Content_position) + else + self:Cargo_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country) + self:Cargo_SpawnStatic(Cargo_Drop_initiator,Cargo_Content_position, "Hercules_Container_Parachute_Static", CargoHeading, false, Cargo_Country) + end + end + else + self:Cargo_SpawnStatic(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, true, Cargo_Country) + end + end + end + end + return self +end + +--- [Internal] Function to calculate object height +-- @param #CTLD_HERCULES self +-- @param Wrapper.Group#GROUP group The group for which to calculate the height +-- @return #number height over ground +function CTLD_HERCULES:Calculate_Object_Height_AGL(group) + self:T(self.lid .. "Calculate_Object_Height_AGL") + if group.ClassName and group.ClassName == "GROUP" then + local gcoord = group:GetCoordinate() + local height = group:GetHeight() + local lheight = gcoord:GetLandHeight() + self:T(self.lid .. "Height " .. height - lheight) + return height - lheight + else + -- DCS object + if group:isExist() then + local dcsposition = group:getPosition().p + local dcsvec2 = {x = dcsposition.x, y = dcsposition.z} -- Vec2 + local height = math.floor(group:getPosition().p.y - land.getHeight(dcsvec2)) + self.ObjectTracker[group.id_] = dcsposition -- Vec3 + self:T(self.lid .. "Height " .. height) + return height + else + return 0 + end + end +end + +--- [Internal] Function to check surface type +-- @param #CTLD_HERCULES self +-- @param Wrapper.Group#GROUP group The group for which to calculate the height +-- @return #number height over ground +function CTLD_HERCULES:Check_SurfaceType(object) + self:T(self.lid .. "Check_SurfaceType") + -- LAND,--1 SHALLOW_WATER,--2 WATER,--3 ROAD,--4 RUNWAY--5 + if object:isExist() then + return land.getSurfaceType({x = object:getPosition().p.x, y = object:getPosition().p.z}) + else + return 1 + end +end + +--- [Internal] Function to track cargo objects +-- @param #CTLD_HERCULES self +-- @param #CTLD_HERCULES.CargoObject cargo +-- @param Wrapper.Group#GROUP initiator +-- @return #number height over ground +function CTLD_HERCULES:Cargo_Track(cargo, initiator) + self:T(self.lid .. "Cargo_Track") + local Cargo_Drop_initiator = initiator + if cargo.Cargo_Contents ~= nil then + if self:Calculate_Object_Height_AGL(cargo.Cargo_Contents) < 10 then --pallet less than 5m above ground before spawning + if self:Check_SurfaceType(cargo.Cargo_Contents) == 2 or self:Check_SurfaceType(cargo.Cargo_Contents) == 3 then + cargo.Cargo_over_water = true--pallets gets destroyed in water + end + local dcsvec3 = self.ObjectTracker[cargo.Cargo_Contents.id_] or initiator:GetVec3() -- last known position + self:T("SPAWNPOSITION: ") + self:T({dcsvec3}) + local Vec2 = { + x=dcsvec3.x, + y=dcsvec3.z, + } + local vec3 = COORDINATE:NewFromVec2(Vec2) + self.ObjectTracker[cargo.Cargo_Contents.id_] = nil + self:Cargo_SpawnObjects(Cargo_Drop_initiator,cargo.Cargo_Drop_Direction, vec3, cargo.Cargo_Type_name, cargo.Cargo_over_water, cargo.Container_Enclosed, cargo.ParatrooperGroupSpawn, cargo.offload_cargo, cargo.all_cargo_survive_to_the_ground, cargo.all_cargo_gets_destroyed, cargo.destroy_cargo_dropped_without_parachute, cargo.Cargo_Country) + if cargo.Cargo_Contents:isExist() then + cargo.Cargo_Contents:destroy()--remove pallet+parachute before hitting ground and replace with Cargo_SpawnContents + end + --timer.removeFunction(cargo.scheduleFunctionID) + cargo.scheduleFunctionID:Stop() + cargo = {} + end + end + return self +end + +--- [Internal] Function to calc north correction +-- @param #CTLD_HERCULES self +-- @param Core.Point#POINT_Vec3 point Position Vec3 +-- @return #number north correction +function CTLD_HERCULES:Calculate_Cargo_Drop_initiator_NorthCorrection(point) + self:T(self.lid .. "Calculate_Cargo_Drop_initiator_NorthCorrection") + if not point.z then --Vec2; convert to Vec3 + point.z = point.y + point.y = 0 + end + local lat, lon = coord.LOtoLL(point) + local north_posit = coord.LLtoLO(lat + 1, lon) + return math.atan2(north_posit.z - point.z, north_posit.x - point.x) +end + +--- [Internal] Function to calc initiator heading +-- @param #CTLD_HERCULES self +-- @param Wrapper.Group#GROUP Cargo_Drop_initiator +-- @return #number north corrected heading +function CTLD_HERCULES:Calculate_Cargo_Drop_initiator_Heading(Cargo_Drop_initiator) + self:T(self.lid .. "Calculate_Cargo_Drop_initiator_Heading") + local Heading = Cargo_Drop_initiator:GetHeading() + Heading = Heading + self:Calculate_Cargo_Drop_initiator_NorthCorrection(Cargo_Drop_initiator:GetVec3()) + if Heading < 0 then + Heading = Heading + (2 * math.pi)-- put heading in range of 0 to 2*pi + end + return Heading + 0.06 -- rad +end + +--- [Internal] Function to initialize dropped cargo +-- @param #CTLD_HERCULES self +-- @param Wrapper.Group#GROUP Initiator +-- @param #table Cargo_Contents Table 'weapon' from event data +-- @param #string Cargo_Type_name Name of this cargo +-- @param #boolean Container_Enclosed Is container? +-- @param #boolean SoldierGroup Is soldier group? +-- @param #boolean ParatrooperGroupSpawnInit Is paratroopers? +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:Cargo_Initialize(Initiator, Cargo_Contents, Cargo_Type_name, Container_Enclosed, SoldierGroup, ParatrooperGroupSpawnInit) + self:T(self.lid .. "Cargo_Initialize") + local Cargo_Drop_initiator = Initiator:GetName() + if Cargo_Drop_initiator ~= nil then + if ParatrooperGroupSpawnInit == true then + self:T("Paratrooper Drop") + -- Paratroopers + if not self.ParatrooperCount[Cargo_Drop_initiator] then + self.ParatrooperCount[Cargo_Drop_initiator] = 1 + else + self.ParatrooperCount[Cargo_Drop_initiator] = self.ParatrooperCount[Cargo_Drop_initiator] + 1 + end + + local Paratroopers = self.ParatrooperCount[Cargo_Drop_initiator] + + self:T("Paratrooper Drop Number " .. self.ParatrooperCount[Cargo_Drop_initiator]) + + local SpawnParas = false + + if math.fmod(Paratroopers,10) == 0 then + SpawnParas = true + end + + self.j = self.j + 1 + self.Cargo[self.j] = {} + self.Cargo[self.j].Cargo_Drop_Direction = self:Calculate_Cargo_Drop_initiator_Heading(Initiator) + self.Cargo[self.j].Cargo_Contents = Cargo_Contents + self.Cargo[self.j].Cargo_Type_name = Cargo_Type_name + self.Cargo[self.j].Container_Enclosed = Container_Enclosed + self.Cargo[self.j].ParatrooperGroupSpawn = SpawnParas + self.Cargo[self.j].Cargo_Country = Initiator:GetCountry() + + if self:Calculate_Object_Height_AGL(Initiator) < 5.0 then --aircraft on ground + self.Cargo[self.j].offload_cargo = true + elseif self:Calculate_Object_Height_AGL(Initiator) < 10.0 then --aircraft less than 10m above ground + self.Cargo[self.j].all_cargo_survive_to_the_ground = true + elseif self:Calculate_Object_Height_AGL(Initiator) < 100.0 then --aircraft more than 10m but less than 100m above ground + self.Cargo[self.j].all_cargo_gets_destroyed = true + else + self.Cargo[self.j].all_cargo_gets_destroyed = false + end + + local timer = TIMER:New(self.Cargo_Track,self,self.Cargo[self.j],Initiator) + self.Cargo[self.j].scheduleFunctionID = timer + timer:Start(1,1,600) + + else + -- no paras + self.j = self.j + 1 + self.Cargo[self.j] = {} + self.Cargo[self.j].Cargo_Drop_Direction = self:Calculate_Cargo_Drop_initiator_Heading(Initiator) + self.Cargo[self.j].Cargo_Contents = Cargo_Contents + self.Cargo[self.j].Cargo_Type_name = Cargo_Type_name + self.Cargo[self.j].Container_Enclosed = Container_Enclosed + self.Cargo[self.j].ParatrooperGroupSpawn = false + self.Cargo[self.j].Cargo_Country = Initiator:GetCountry() + + if self:Calculate_Object_Height_AGL(Initiator) < 5.0 then--aircraft on ground + self.Cargo[self.j].offload_cargo = true + elseif self:Calculate_Object_Height_AGL(Initiator) < 10.0 then--aircraft less than 10m above ground + self.Cargo[self.j].all_cargo_survive_to_the_ground = true + elseif self:Calculate_Object_Height_AGL(Initiator) < 100.0 then--aircraft more than 10m but less than 100m above ground + self.Cargo[self.j].all_cargo_gets_destroyed = true + else + self.Cargo[self.j].destroy_cargo_dropped_without_parachute = true --aircraft more than 100m above ground + end + + local timer = TIMER:New(self.Cargo_Track,self,self.Cargo[self.j],Initiator) + self.Cargo[self.j].scheduleFunctionID = timer + timer:Start(1,1,600) + end + end + return self +end + +--- [Internal] Function to change cargotype per group (Wrench) +-- @param #CTLD_HERCULES self +-- @param #number key Carrier key id +-- @param #string cargoType Type of cargo +-- @param #number cargoNum Number of cargo objects +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:SetType(key,cargoType,cargoNum) + self:T(self.lid .. "SetType") + self.carrierGroups[key]['cargoType'] = cargoType + self.carrierGroups[key]['cargoNum'] = cargoNum + return self +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +-- EventHandlers +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + +--- [Internal] Function to capture SHOT event +-- @param #CTLD_HERCULES self +-- @param Core.Event#EVENTDATA Cargo_Drop_Event The event data +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:_HandleShot(Cargo_Drop_Event) + self:T(self.lid .. "Shot Event ID:" .. Cargo_Drop_Event.id) + if Cargo_Drop_Event.id == EVENTS.Shot then + + local GT_Name = "" + local SoldierGroup = false + local ParatrooperGroupSpawnInit = false + + local GT_DisplayName = Weapon.getDesc(Cargo_Drop_Event.weapon).typeName:sub(15, -1)--Remove "weapons.bombs." from string + self:T(string.format("%sCargo_Drop_Event: %s", self.lid, Weapon.getDesc(Cargo_Drop_Event.weapon).typeName)) + + if (GT_DisplayName == "Squad 30 x Soldier [7950lb]") then + self:Cargo_Initialize(Cargo_Drop_Event.IniGroup, Cargo_Drop_Event.weapon, "Soldier M4 GRG", false, true, true) + end + + if self.Types[GT_DisplayName] then + local GT_Name = self.Types[GT_DisplayName]['name'] + local Cargo_Container_Enclosed = self.Types[GT_DisplayName]['container'] + self:Cargo_Initialize(Cargo_Drop_Event.IniGroup, Cargo_Drop_Event.weapon, GT_Name, Cargo_Container_Enclosed) + end + end + return self +end + +--- [Internal] Function to capture BIRTH event +-- @param #CTLD_HERCULES self +-- @param Core.Event#EVENTDATA event The event data +-- @return #CTLD_HERCULES self +function CTLD_HERCULES:_HandleBirth(event) + -- not sure what this is needed for? I think this for setting generic crates "content" setting. + self:T(self.lid .. "Birth Event ID:" .. event.id) + return self +end + +end + +------------------------------------------------------------------- +-- End Ops.CTLD.lua +------------------------------------------------------------------- diff --git a/Moose Development/Moose/Ops/CTLD_Localization.lua b/Moose Development/Moose/Ops/CTLD_Localization.lua new file mode 100644 index 000000000..0ffa5e397 --- /dev/null +++ b/Moose Development/Moose/Ops/CTLD_Localization.lua @@ -0,0 +1,752 @@ +--- +-- @field Messages +CTLD.Messages = { + EN = { + -- ============================================================ + -- Crate / Cargo Loading + -- ============================================================ + CRATE_LOADED_GROUNDCREW = "Crate %s loaded by ground crew!", + CRATE_UNLOADED_GROUNDCREW = "Crate %s unloaded by ground crew!", + CRATE_LOADED_ID = "Crate ID %d for %s loaded!", + LOADED_FULL = "Loaded %d %s.", + LOADED_SETS_LEFTOVER = "Loaded %d %s(s), with %d leftover crate(s).", + LOADED_SETS = "Loaded %d %s(s).", + LOADED_PARTIAL = "Loaded only %d/%d crate(s) of %s.", + LOADED_PARTIAL_LIMIT = "Loaded only %d/%d crate(s) of %s. Cargo limit is now reached!", + LOADED_BATCH = "Loaded %d %s.", + LOADED_BATCH_PARTIAL = "Some sets could not be fully loaded.", + -- ============================================================ + -- Dropping / Unloading + -- ============================================================ + DROPPED_FULL = "Dropped %d %s.", + DROPPED_SETS_LEFTOVER = "Dropped %d %s(s), with %d leftover crate(s).", + DROPPED_SETS = "Dropped %d %s(s).", + DROPPED_PARTIAL = "Dropped %d/%d crate(s) of %s.", + DROPPED_INTO_ACTION = "Dropped %s into action!", + DROPPED_BEACON = "Dropped %s | FM %s Mhz | VHF %s KHz | UHF %s Mhz ", + CRATES_POSITIONED = "%d crates for %s have been positioned near you!", + CRATES_DROPPED = "%d crates for %s have been dropped!", + -- ============================================================ + -- Troops + -- ============================================================ + BOARDED = "%s boarded!", + BOARDING = "%s boarding!", + TROOPS_RETURNED = "Troops have returned to base!", + -- ============================================================ + -- Deployment + -- ============================================================ + DEPLOYED_NEAR_YOU = "%s have been deployed near you!", + UNITS_REMOVED = "%s have been removed", + -- ============================================================ + -- Build / Repair + -- ============================================================ + BUILD_STARTED = "Build started, ready in %d seconds!", + REPAIR_STARTED = "Repair started using %s taking %d secs", + NO_UNIT_TO_REPAIR = "No unit close enough to repair!", + CANT_REPAIR_WITH = "Can't repair this unit with %s", + CRATES_MOVE_BEFORE_BUILD = "*** Crates need to be moved before building!", + -- ============================================================ + -- Errors - Chopper / Weight / Capacity + -- ============================================================ + CHOPPER_CANNOT_CARRY = "Sorry this chopper cannot carry crates!", + TOO_HEAVY = "Sorry, that's too heavy to load!", + FULLY_LOADED = "Sorry, we are fully loaded!", + CRAMMED = "Sorry, we're crammed already!", + NO_CAPACITY_NOW = "No capacity to load more now!", + NO_MORE_CAPACITY = "No more capacity to load crates!", + CANNOT_LOAD_NONE_OR_FULL = "Cannot load crates: either none found or no capacity left.", + -- ============================================================ + -- Errors - Position + -- ============================================================ + NEED_TO_LAND_OR_HOVER_LOAD = "You need to land or hover in position to load!", + HOVER_OVER_CRATES = "Hover over the crates to pick them up!", + LAND_OR_HOVER_OVER_CRATES = "Land or hover over the crates to pick them up!", + MUST_LAND_OR_HOVER_CRATES = "You must land or hover to load crates!", + NEED_TO_LAND_BUILD = "You need to land / stop to build something, Pilot!", + NOT_CLOSE_ENOUGH_LOGISTICS = "You are not close enough to a logistics zone!", + NOT_CLOSE_ENOUGH_DROP = "You are not close enough to a drop zone!", + NOT_CLOSE_ENOUGH_ZONE_NM = "Negative, need to be closer than %dnm to a zone!", + CANNOT_BUILD_LOADING_AREA = "You cannot build in a loading area, Pilot!", + -- ============================================================ + -- Errors - Doors + -- ============================================================ + OPEN_DOORS_LOAD_CARGO = "You need to open the door(s) to load cargo!", + OPEN_DOORS_LOAD_TROOPS = "You need to open the door(s) to load troops!", + OPEN_DOORS_EXTRACT_TROOPS = "You need to open the door(s) to extract troops!", + OPEN_DOORS_UNLOAD_TROOPS = "You need to open the door(s) to unload troops!", + OPEN_DOORS_DROP_CARGO = "You need to open the door(s) to drop cargo!", + -- ============================================================ + -- Errors - Stock / Availability + -- ============================================================ + ALL_GONE = "Sorry, all %s are gone!", + RAN_OUT_OF = "Sorry, we ran out of %s", + CARGO_NOT_AVAILABLE_ZONE = "The requested cargo is not available in this zone!", + ENOUGH_CRATES_NEARBY = "There are enough crates nearby already! Take care of those first!", + NO_CRATES_WITHIN = "No (loadable) crates within %d meters!", + NO_CRATES_WITHIN_PLAIN = "No crates within %d meters!", + NO_CRATES_IN_RANGE = "No crates found in range!", + NO_NAMED_CRATES_IN_RANGE = "No \"%s\" crates found in range!", + NO_LOADABLE_CRATES = "Sorry, no loadable crates nearby or max cargo weight reached!", + NO_UNITS_TO_EXTRACT = "No units close enough to extract!", + NO_UNIT_CONFIG = "No unit configuration found for %s", + CANT_ONBOARD = "Can't onboard %s", + TOO_MANY_UNITS_NEARBY = "You already have %d units nearby!", + NO_CRATE_GROUPS = "No crate groups found for this unit!", + NO_CRATE_SET = "No crate set found or index invalid!", + NO_CRATE_IN_SET = "No crate found in that set!", + NO_TROOP_CHUNK = "No troop cargo chunk found for ID %d!", + TROOP_CHUNK_EMPTY = "Troop chunk is empty for ID %d!", + -- ============================================================ + -- Nothing loaded / in stock + -- ============================================================ + NOTHING_LOADED = "Nothing loaded!\nTroop limit: %d | Crate limit %d | Weight limit %d kgs", + NOTHING_LOADED_AIRDROP = "Nothing loaded or not within airdrop parameters!", + NOTHING_LOADED_HOVER = "Nothing loaded or not hovering within parameters!", + NOTHING_IN_STOCK = "Nothing in stock!", + NOTHING_TO_PACK = "Nothing to pack at this distance pilot!", + NOTHING_TO_REMOVE = "Nothing to remove at this distance pilot!", + -- ============================================================ + -- Zone / Info + -- ============================================================ + ROGER_ZONE = "Roger, %s zone %s!", + -- ============================================================ + -- Report: Hover / Flight Parameters + -- ============================================================ + HOVER_PARAMS_METRIC = "Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 2mps \n - In parameter: %s", + HOVER_PARAMS_IMPERIAL = "Hover parameters (autoload/drop):\n - Min height %dft \n - Max height %dft \n - Max speed 6ftps \n - In parameter: %s", + FLIGHT_PARAMS_IMPERIAL = "Flight parameters (airdrop):\n - Min height %dft \n - Max height %dft \n - In parameter: %s", + FLIGHT_PARAMS_METRIC = "Flight parameters (airdrop):\n - Min height %dm \n - Max height %dm \n - In parameter: %s", + -- ============================================================ + -- Report Titles (REPORT:New()) + -- ============================================================ + REPORT_CRATES_FOUND = "Crates Found Nearby:", + REPORT_REMOVING_CRATES = "Removing Crates Found Nearby:", + REPORT_TRANSPORT_CHECKOUT = "Transport Checkout Sheet", + REPORT_INVENTORY = "Inventory Sheet", + REPORT_BUILD_CHECKLIST = "Checklist Buildable Crates", + REPORT_REPAIR_CHECKLIST = "Checklist Repairs", + REPORT_BEACONS = "Active Zone Beacons", + -- ============================================================ + -- Report Section Headers (report:Add()) + -- ============================================================ + REPORT_SECTION_TROOPS = " -- TROOPS --", + REPORT_SECTION_CRATES = " -- CRATES --", + REPORT_SECTION_CRATES_GC = " -- CRATES loaded via Ground Crew --", + REPORT_SECTION_NONE = " N O N E", + REPORT_SECTION_NONE_ALT = " --- None found! ---", + REPORT_SECTION_NONE_REPAIR = " --- None Found ---", + REPORT_GC_LOADABLE_HINT = "Probably ground crew loadable (F8)", + REPORT_TOTAL_MASS = "Total Mass: %s kg. Loadable: %s kg.", + REPORT_TROOPS_CRATES_COUNT = "Troops: %d(%d), Crates: %d(%d)", + REPORT_TROOPS_CRATETYPES_COUNT = "Troops: %d, Cratetypes: %d", + -- ============================================================ + -- Report Row Templates (per-item lines in reports) + -- ============================================================ + REPORT_ROW_TROOP = "Troop: %s size %d", + REPORT_ROW_CRATE = "Crate: %s %d/%d", + REPORT_ROW_CRATE_SIZE1 = "Crate: %s size 1", + REPORT_ROW_GC_CRATE = "GC loaded Crate: %s size 1", + REPORT_ROW_DROPPED_CRATE = "Dropped crate for %s, %dkg", + REPORT_ROW_CRATE_KG = "Crate for %s, %dkg", + REPORT_ROW_CRATE_REMOVED = "Crate for %s, %dkg removed", + REPORT_ROW_UNIT_STOCK = "Unit: %s | Soldiers: %d | Stock: %s", + REPORT_ROW_TYPE_CRATE_STOCK = "Type: %s | Crates per Set: %d | Stock: %s", + REPORT_ROW_TYPE_STOCK = "Type: %s | Stock: %s", + REPORT_ROW_BUILD_CHECK = "Type: %s | Required %d | Found %d | Can Build %s", + REPORT_ROW_REPAIR_CHECK = "Type: %s | Required %d | Found %d | Can Repair %s", + REPORT_ROW_BEACON = " %s | FM %s Mhz | VHF %s KHz | UHF %s Mhz ", + -- ============================================================ + -- Weight / Crate limit tokens + -- ============================================================ + WEIGHT_LIMIT = "Weight limit reached", + CRATE_LIMIT = "Crate limit reached", + -- ============================================================ + -- Menu labels - Top level + -- ============================================================ + MENU_CTLD = "CTLD", + MENU_MANAGE_TROOPS = "Manage Troops", + MENU_MANAGE_CRATES = "Manage Crates", + MENU_MANAGE_UNITS = "Manage Units", + -- ============================================================ + -- Menu labels - Troops + -- ============================================================ + MENU_LOAD_TROOPS = "Load troops", + MENU_DROP_TROOPS = "Drop Troops", + MENU_DROP_ALL_TROOPS = "Drop ALL troops", + MENU_EXTRACT_TROOPS = "Extract troops", + MENU_DROP_N_TROOPS = "Drop (%d) %s", + -- ============================================================ + -- Menu labels - Crates: Get + -- ============================================================ + MENU_GET_CRATES = "Get Crates", + MENU_GET = "Get", + MENU_GET_AND_LOAD = "Get and Load", + MENU_GET_ANYWAY = "Get anyway", + MENU_PARTIALLY_LOAD = "Partially load", + MENU_OUT_OF_STOCK = "Out of stock", + MENU_TROOP_LIMIT = "Troop limit reached", + -- ============================================================ + -- Menu labels - Crates: Load + -- ============================================================ + MENU_LOAD_CRATES = "Load Crates", + MENU_LOAD_ALL = "Load ALL", + MENU_SHOW_LOADABLE_CRATES = "Show loadable crates", + MENU_NO_CRATES_FOUND_RESCAN = "No crates found! Rescan?", + MENU_USE_C130_LOAD = "Use C-130 Load system", + -- ============================================================ + -- Menu labels - Crates: Drop + -- ============================================================ + MENU_DROP_CRATES = "Drop Crates", + MENU_DROP_ALL_CRATES = "Drop ALL crates", + MENU_DROP = "Drop", + MENU_DROP_AND_BUILD = "Drop and build", + MENU_DROP_N_SETS = "Drop %d Set%s", + MENU_NO_CRATES_TO_DROP = "No crates to drop!", + -- ============================================================ + -- Menu labels - Crates: Build / Repair / Pack / Remove + -- ============================================================ + MENU_BUILD_CRATES = "Build crates", + MENU_REPAIR = "Repair", + MENU_PACK_CRATES = "Pack crates", + MENU_PACK = "Pack", + MENU_PACK_AND_LOAD = "Pack and Load", + MENU_PACK_AND_REMOVE = "Pack and Remove", + MENU_REMOVE_CRATES = "Remove crates", + MENU_REMOVE_CRATES_NEARBY = "Remove crates nearby", + MENU_LIST_CRATES_NEARBY = "List crates nearby", + MENU_CRATES_NEEDED = "%d crate%s %s (%dkg)", + -- ============================================================ + -- Menu labels - Units (C-130) + -- ============================================================ + MENU_GET_UNITS = "Get Units", + MENU_REMOVE_UNITS_NEARBY = "Remove units nearby", + -- ============================================================ + -- Menu labels - Info / Cargo + -- ============================================================ + MENU_LIST_BOARDED_CARGO = "List boarded cargo", + MENU_INVENTORY = "Inventory", + MENU_LIST_ZONE_BEACONS = "List active zone beacons", + -- ============================================================ + -- Menu labels - Smokes / Flares / Beacons + -- ============================================================ + MENU_SMOKES_FLARES_BEACONS = "Smokes, Flares, Beacons", + MENU_SMOKE_ZONES_NEARBY = "Smoke zones nearby", + MENU_DROP_SMOKE_NOW = "Drop smoke now", + MENU_RED_SMOKE = "Red smoke", + MENU_BLUE_SMOKE = "Blue smoke", + MENU_GREEN_SMOKE = "Green smoke", + MENU_ORANGE_SMOKE = "Orange smoke", + MENU_WHITE_SMOKE = "White smoke", + MENU_FLARE_ZONES_NEARBY = "Flare zones nearby", + MENU_FIRE_FLARE_NOW = "Fire flare now", + MENU_DROP_BEACON_NOW = "Drop beacon now", + -- ============================================================ + -- Menu labels - Parameters + -- ============================================================ + MENU_SHOW_FLIGHT_PARAMS = "Show flight parameters", + MENU_SHOW_HOVER_PARAMS = "Show hover parameters", + STOCK_NONE = "none", + STOCK_UNLIMITED = "unlimited", + BUILD_YES = "YES", + BUILD_NO = "NO", + }, + DE = { + -- ============================================================ + -- Kiste / Fracht laden + -- ============================================================ + CRATE_LOADED_GROUNDCREW = "Kiste %s vom Bodenpersonal geladen!", + CRATE_UNLOADED_GROUNDCREW = "Kiste %s vom Bodenpersonal entladen!", + CRATE_LOADED_ID = "Kiste ID %d für %s geladen!", + LOADED_FULL = "%d %s geladen.", + LOADED_SETS_LEFTOVER = "%d %s geladen, %d Kiste(n) übrig.", + LOADED_SETS = "%d %s geladen.", + LOADED_PARTIAL = "Nur %d/%d Kiste(n) von %s geladen.", + LOADED_PARTIAL_LIMIT = "Nur %d/%d Kiste(n) von %s geladen. Frachtlimit erreicht!", + LOADED_BATCH = "%d %s geladen.", + LOADED_BATCH_PARTIAL = "Einige Sets konnten nicht vollständig geladen werden.", + -- ============================================================ + -- Abwerfen / Entladen + -- ============================================================ + DROPPED_FULL = "%d %s abgeworfen.", + DROPPED_SETS_LEFTOVER = "%d %s abgeworfen, %d Kiste(n) übrig.", + DROPPED_SETS = "%d %s abgeworfen.", + DROPPED_PARTIAL = "%d/%d Kiste(n) von %s abgeworfen.", + DROPPED_INTO_ACTION = "%s im Einsatz abgesetzt!", + DROPPED_BEACON = "%s abgesetzt | FM %s Mhz | VHF %s KHz | UHF %s Mhz ", + CRATES_POSITIONED = "%d Kisten für %s in Ihrer Nähe positioniert!", + CRATES_DROPPED = "%d Kisten für %s abgeworfen!", + -- ============================================================ + -- Truppen + -- ============================================================ + BOARDED = "%s eingestiegen!", + BOARDING = "%s steigt ein!", + TROOPS_RETURNED = "Truppen zur Basis zurückgekehrt!", + -- ============================================================ + -- Einsatz + -- ============================================================ + DEPLOYED_NEAR_YOU = "%s in Ihrer Nähe eingesetzt!", + UNITS_REMOVED = "%s entfernt", + -- ============================================================ + -- Bauen / Reparieren + -- ============================================================ + BUILD_STARTED = "Bau gestartet, fertig in %d Sekunden!", + REPAIR_STARTED = "Reparatur mit %s gestartet, dauert %d Sek.", + NO_UNIT_TO_REPAIR = "Keine Einheit in Reichweite zum Reparieren!", + CANT_REPAIR_WITH = "Diese Einheit kann nicht mit %s repariert werden", + CRATES_MOVE_BEFORE_BUILD = "*** Kisten müssen vor dem Bau verschoben werden!", + -- ============================================================ + -- Fehler - Hubschrauber / Gewicht / Kapazität + -- ============================================================ + CHOPPER_CANNOT_CARRY = "Dieser Hubschrauber kann keine Kisten transportieren!", + TOO_HEAVY = "Entschuldigung, das ist zu schwer zum Laden!", + FULLY_LOADED = "Entschuldigung, wir sind voll beladen!", + CRAMMED = "Entschuldigung, wir sind bereits voll besetzt!", + NO_CAPACITY_NOW = "Aktuell keine Ladekapazität mehr vorhanden!", + NO_MORE_CAPACITY = "Keine Kapazität mehr für weitere Kisten!", + CANNOT_LOAD_NONE_OR_FULL = "Laden nicht möglich: keine Kisten gefunden oder Kapazität erschöpft.", + -- ============================================================ + -- Fehler - Position + -- ============================================================ + NEED_TO_LAND_OR_HOVER_LOAD = "Bitte landen oder schweben Sie zum Laden!", + HOVER_OVER_CRATES = "Schweben Sie über die Kisten, um sie aufzunehmen!", + LAND_OR_HOVER_OVER_CRATES = "Landen oder schweben Sie über die Kisten, um sie aufzunehmen!", + MUST_LAND_OR_HOVER_CRATES = "Sie müssen landen oder schweben, um Kisten zu laden!", + NEED_TO_LAND_BUILD = "Sie müssen landen / anhalten, um etwas zu bauen, Pilot!", + NOT_CLOSE_ENOUGH_LOGISTICS = "Sie sind nicht nah genug an einer Logistikzone!", + NOT_CLOSE_ENOUGH_DROP = "Sie sind nicht nah genug an einer Abwurfzone!", + NOT_CLOSE_ENOUGH_ZONE_NM = "Negativ, Sie müssen näher als %d Seemeilen an einer Zone sein!", + CANNOT_BUILD_LOADING_AREA = "In einem Ladebereich kann nicht gebaut werden, Pilot!", + -- ============================================================ + -- Fehler - Türen + -- ============================================================ + OPEN_DOORS_LOAD_CARGO = "Bitte öffnen Sie die Tür(en) zum Laden von Fracht!", + OPEN_DOORS_LOAD_TROOPS = "Bitte öffnen Sie die Tür(en) zum Einladen von Truppen!", + OPEN_DOORS_EXTRACT_TROOPS = "Bitte öffnen Sie die Tür(en) zum Aussteigen der Truppen!", + OPEN_DOORS_UNLOAD_TROOPS = "Bitte öffnen Sie die Tür(en) zum Entladen der Truppen!", + OPEN_DOORS_DROP_CARGO = "Bitte öffnen Sie die Tür(en) zum Abwerfen der Fracht!", + -- ============================================================ + -- Fehler - Bestand / Verfügbarkeit + -- ============================================================ + ALL_GONE = "Entschuldigung, alle %s sind vergriffen!", + RAN_OUT_OF = "Entschuldigung, %s ist nicht mehr vorrätig", + CARGO_NOT_AVAILABLE_ZONE = "Die angeforderte Fracht ist in dieser Zone nicht verfügbar!", + ENOUGH_CRATES_NEARBY = "Es sind bereits genügend Kisten in der Nähe! Bitte zuerst um diese kümmern!", + NO_CRATES_WITHIN = "Keine (ladbaren) Kisten in %d Metern Umkreis!", + NO_CRATES_WITHIN_PLAIN = "Keine Kisten in %d Metern Umkreis!", + NO_CRATES_IN_RANGE = "Keine Kisten in Reichweite gefunden!", + NO_NAMED_CRATES_IN_RANGE = "Keine \"%s\"-Kisten in Reichweite gefunden!", + NO_LOADABLE_CRATES = "Entschuldigung, keine ladbaren Kisten in der Nähe oder maximales Frachtgewicht erreicht!", + NO_UNITS_TO_EXTRACT = "Keine Einheiten nah genug zum Aussteigen!", + NO_UNIT_CONFIG = "Keine Einheitenkonfiguration für %s gefunden", + CANT_ONBOARD = "%s kann nicht eingeladen werden", + TOO_MANY_UNITS_NEARBY = "Sie haben bereits %d Einheiten in der Nähe!", + NO_CRATE_GROUPS = "Keine Kistengruppen für diese Einheit gefunden!", + NO_CRATE_SET = "Kein Kistenset gefunden oder Index ungültig!", + NO_CRATE_IN_SET = "Keine Kiste in diesem Set gefunden!", + NO_TROOP_CHUNK = "Kein Truppenfracht-Block für ID %d gefunden!", + TROOP_CHUNK_EMPTY = "Truppenfracht-Block für ID %d ist leer!", + -- ============================================================ + -- Nichts geladen / kein Bestand + -- ============================================================ + NOTHING_LOADED = "Nichts geladen!\nTruppenlimit: %d | Kistenlimit: %d | Gewichtslimit: %d kg", + NOTHING_LOADED_AIRDROP = "Nichts geladen oder nicht innerhalb der Abwurfparameter!", + NOTHING_LOADED_HOVER = "Nichts geladen oder Schwebeparameter nicht erfüllt!", + NOTHING_IN_STOCK = "Nichts vorrätig!", + NOTHING_TO_PACK = "Nichts in dieser Entfernung zum Verpacken, Pilot!", + NOTHING_TO_REMOVE = "Nichts in dieser Entfernung zum Entfernen, Pilot!", + -- ============================================================ + -- Zone / Info + -- ============================================================ + ROGER_ZONE = "Verstanden, %s Zone %s!", + -- ============================================================ + -- Report: Schwebe- / Flugparameter + -- ============================================================ + HOVER_PARAMS_METRIC = "Schwebeparameter (Autoladen/Abwurf):\n - Min. Höhe %dm \n - Max. Höhe %dm \n - Max. Geschwindigkeit 2m/s \n - Im Parameter: %s", + HOVER_PARAMS_IMPERIAL = "Schwebeparameter (Autoladen/Abwurf):\n - Min. Höhe %dft \n - Max. Höhe %dft \n - Max. Geschwindigkeit 6ft/s \n - Im Parameter: %s", + FLIGHT_PARAMS_IMPERIAL = "Flugparameter (Luftabwurf):\n - Min. Höhe %dft \n - Max. Höhe %dft \n - Im Parameter: %s", + FLIGHT_PARAMS_METRIC = "Flugparameter (Luftabwurf):\n - Min. Höhe %dm \n - Max. Höhe %dm \n - Im Parameter: %s", + -- ============================================================ + -- Report-Titel + -- ============================================================ + REPORT_CRATES_FOUND = "Kisten in der Nähe:", + REPORT_REMOVING_CRATES = "Entferne Kisten in der Nähe:", + REPORT_TRANSPORT_CHECKOUT = "Transport-Checkliste", + REPORT_INVENTORY = "Inventarliste", + REPORT_BUILD_CHECKLIST = "Checkliste baubare Kisten", + REPORT_REPAIR_CHECKLIST = "Checkliste Reparaturen", + REPORT_BEACONS = "Aktive Zonenfeuer", + -- ============================================================ + -- Report-Sektionskopfzeilen + -- ============================================================ + REPORT_SECTION_TROOPS = " -- TRUPPEN --", + REPORT_SECTION_CRATES = " -- KISTEN --", + REPORT_SECTION_CRATES_GC = " -- KISTEN via Bodenpersonal geladen --", + REPORT_SECTION_NONE = " K E I N E", + REPORT_SECTION_NONE_ALT = " --- Keine gefunden! ---", + REPORT_SECTION_NONE_REPAIR = " --- Keine gefunden ---", + REPORT_GC_LOADABLE_HINT = "Wahrscheinlich durch Bodenpersonal ladbar (F8)", + REPORT_TOTAL_MASS = "Gesamtgewicht: %s kg. Ladbar: %s kg.", + REPORT_TROOPS_CRATES_COUNT = "Truppen: %d(%d), Kisten: %d(%d)", + REPORT_TROOPS_CRATETYPES_COUNT = "Truppen: %d, Kistentypen: %d", + -- ============================================================ + -- Report-Zeilenvorlagen + -- ============================================================ + REPORT_ROW_TROOP = "Truppe: %s Größe %d", + REPORT_ROW_CRATE = "Kiste: %s %d/%d", + REPORT_ROW_CRATE_SIZE1 = "Kiste: %s Größe 1", + REPORT_ROW_GC_CRATE = "Bodenpersonal-Kiste: %s Größe 1", + REPORT_ROW_DROPPED_CRATE = "Abgeworfene Kiste für %s, %dkg", + REPORT_ROW_CRATE_KG = "Kiste für %s, %dkg", + REPORT_ROW_CRATE_REMOVED = "Kiste für %s, %dkg entfernt", + REPORT_ROW_UNIT_STOCK = "Einheit: %s | Soldaten: %d | Bestand: %s", + REPORT_ROW_TYPE_CRATE_STOCK = "Typ: %s | Kisten pro Set: %d | Bestand: %s", + REPORT_ROW_TYPE_STOCK = "Typ: %s | Bestand: %s", + REPORT_ROW_BUILD_CHECK = "Typ: %s | Benötigt: %d | Gefunden: %d | Baubar: %s", + REPORT_ROW_REPAIR_CHECK = "Typ: %s | Benötigt: %d | Gefunden: %d | Reparierbar: %s", + REPORT_ROW_BEACON = " %s | FM %s Mhz | VHF %s KHz | UHF %s Mhz ", + -- ============================================================ + -- Gewichts- / Kistenlimit-Token + -- ============================================================ + WEIGHT_LIMIT = "Gewichtslimit erreicht", + CRATE_LIMIT = "Kistenlimit erreicht", + -- ============================================================ + -- Menübezeichnungen - Obere Ebene + -- ============================================================ + MENU_CTLD = "CTLD", + MENU_MANAGE_TROOPS = "Truppen verwalten", + MENU_MANAGE_CRATES = "Kisten verwalten", + MENU_MANAGE_UNITS = "Einheiten verwalten", + -- ============================================================ + -- Menübezeichnungen - Truppen + -- ============================================================ + MENU_LOAD_TROOPS = "Truppen einladen", + MENU_DROP_TROOPS = "Truppen absetzen", + MENU_DROP_ALL_TROOPS = "ALLE Truppen absetzen", + MENU_EXTRACT_TROOPS = "Truppen aufnehmen", + MENU_DROP_N_TROOPS = "(%d) %s absetzen", + -- ============================================================ + -- Menübezeichnungen - Kisten: Holen + -- ============================================================ + MENU_GET_CRATES = "Kisten holen", + MENU_GET = "Holen", + MENU_GET_AND_LOAD = "Holen und laden", + MENU_GET_ANYWAY = "Trotzdem holen", + MENU_PARTIALLY_LOAD = "Teilweise laden", + MENU_OUT_OF_STOCK = "Nicht vorrätig", + MENU_TROOP_LIMIT = "Truppenlimit erreicht", + -- ============================================================ + -- Menübezeichnungen - Kisten: Laden + -- ============================================================ + MENU_LOAD_CRATES = "Kisten laden", + MENU_LOAD_ALL = "ALLE laden", + MENU_SHOW_LOADABLE_CRATES = "Ladbare Kisten anzeigen", + MENU_NO_CRATES_FOUND_RESCAN = "Keine Kisten gefunden! Neu scannen?", + MENU_USE_C130_LOAD = "C-130-Ladesystem verwenden", + -- ============================================================ + -- Menübezeichnungen - Kisten: Abwerfen + -- ============================================================ + MENU_DROP_CRATES = "Kisten abwerfen", + MENU_DROP_ALL_CRATES = "ALLE Kisten abwerfen", + MENU_DROP = "Abwerfen", + MENU_DROP_AND_BUILD = "Abwerfen und bauen", + MENU_DROP_N_SETS = "%d Set%s abwerfen", + MENU_NO_CRATES_TO_DROP = "Keine Kisten zum Abwerfen!", + -- ============================================================ + -- Menübezeichnungen - Kisten: Bauen / Reparieren / Packen / Entfernen + -- ============================================================ + MENU_BUILD_CRATES = "Kisten bauen", + MENU_REPAIR = "Reparieren", + MENU_PACK_CRATES = "Kisten packen", + MENU_PACK = "Packen", + MENU_PACK_AND_LOAD = "Packen und laden", + MENU_PACK_AND_REMOVE = "Packen und entfernen", + MENU_REMOVE_CRATES = "Kisten entfernen", + MENU_REMOVE_CRATES_NEARBY = "Nahe Kisten entfernen", + MENU_LIST_CRATES_NEARBY = "Nahe Kisten auflisten", + MENU_CRATES_NEEDED = "%d Kiste%s %s (%dkg)", + -- ============================================================ + -- Menübezeichnungen - Einheiten (C-130) + -- ============================================================ + MENU_GET_UNITS = "Einheiten holen", + MENU_REMOVE_UNITS_NEARBY = "Nahe Einheiten entfernen", + -- ============================================================ + -- Menübezeichnungen - Info / Fracht + -- ============================================================ + MENU_LIST_BOARDED_CARGO = "Geladene Fracht anzeigen", + MENU_INVENTORY = "Inventar", + MENU_LIST_ZONE_BEACONS = "Aktive Zonenfeuer anzeigen", + -- ============================================================ + -- Menübezeichnungen - Rauch / Leuchtfeuer / Baken + -- ============================================================ + MENU_SMOKES_FLARES_BEACONS = "Rauch, Leuchtfeuer, Baken", + MENU_SMOKE_ZONES_NEARBY = "Nahe Zonen einrauchen", + MENU_DROP_SMOKE_NOW = "Rauch jetzt setzen", + MENU_RED_SMOKE = "Roter Rauch", + MENU_BLUE_SMOKE = "Blauer Rauch", + MENU_GREEN_SMOKE = "Grüner Rauch", + MENU_ORANGE_SMOKE = "Oranger Rauch", + MENU_WHITE_SMOKE = "Weißer Rauch", + MENU_FLARE_ZONES_NEARBY = "Nahe Zonen befeuern", + MENU_FIRE_FLARE_NOW = "Leuchtfeuer jetzt abfeuern", + MENU_DROP_BEACON_NOW = "Bake jetzt setzen", + -- ============================================================ + -- Menübezeichnungen - Parameter + -- ============================================================ + MENU_SHOW_FLIGHT_PARAMS = "Flugparameter anzeigen", + MENU_SHOW_HOVER_PARAMS = "Schwebeparameter anzeigen", + STOCK_NONE = "keiner", + STOCK_UNLIMITED = "unbegrenzt", + BUILD_YES = "JA", + BUILD_NO = "NEIN", +}, +FR = { + --- ============================================================ + -- Chargement caisse / fret + -- ============================================================ + CRATE_LOADED_GROUNDCREW = "Caisse(s) %s chargée(s) par l'équipe au sol !", + CRATE_UNLOADED_GROUNDCREW = "Caisse(s) %s déchargée(s) par l'équipe au sol !", + CRATE_LOADED_ID = "Caisse(s) ID %d pour %s chargée(s) !", + LOADED_FULL = "%d %s chargé(s).", + LOADED_SETS_LEFTOVER = "%d %s chargé(s), %d caisse(s) restante(s).", + LOADED_SETS = "%d %s chargé(s).", + LOADED_PARTIAL = "Seulement %d/%d caisse(s) de %s chargée(s).", + LOADED_PARTIAL_LIMIT = "Seulement %d/%d caisse(s) de %s chargée(s). Limite de fret atteinte !", + LOADED_BATCH = "%d %s chargé(s).", + LOADED_BATCH_PARTIAL = "Certains ensembles n'ont pas pu être complètement chargés.", + -- ============================================================ + -- Largage / Déchargement + -- ============================================================ + DROPPED_FULL = "%d %s largué(s).", + DROPPED_SETS_LEFTOVER = "%d %s largué(s), %d caisse(s) restante(s).", + DROPPED_SETS = "%d %s largué(s).", + DROPPED_PARTIAL = "%d/%d caisse(s) de %s larguée(s).", + DROPPED_INTO_ACTION = "%s engagé(s) en action !", + DROPPED_BEACON = "%s largué | FM %s Mhz | VHF %s KHz | UHF %s Mhz ", + CRATES_POSITIONED = "%d caisses pour %s positionnées près de vous !", + CRATES_DROPPED = "%d caisses pour %s larguées !", + -- ============================================================ + -- Troupes + -- ============================================================ + BOARDED = "%s embarqué(s) !", + BOARDING = "%s en cours d'embarquement !", + TROOPS_RETURNED = "Les troupes sont retournées à la base !", + -- ============================================================ + -- Déploiement + -- ============================================================ + DEPLOYED_NEAR_YOU = "%s déployé(s) près de vous !", + UNITS_REMOVED = "%s supprimé(s)", + -- ============================================================ + -- Construction / Réparation + -- ============================================================ + BUILD_STARTED = "Construction démarrée, prête dans %d secondes !", + REPAIR_STARTED = "Réparation démarrée avec %s, durée %d sec.", + NO_UNIT_TO_REPAIR = "Aucune unité(s) assez proche pour être réparée(s) !", + CANT_REPAIR_WITH = "Impossible de réparer cette unité avec %s", + CRATES_MOVE_BEFORE_BUILD = "*** Les caisses doivent être déplacées avant la construction !", + -- ============================================================ + -- Erreurs - Hélicoptère / Poids / Capacité + -- ============================================================ + CHOPPER_CANNOT_CARRY = "Cet hélicoptère ne peut pas transporter de caisses !", + TOO_HEAVY = "Désolé, c'est trop lourd à charger !", + FULLY_LOADED = "Désolé, capacité maximale atteinte !", + CRAMMED = "Désolé, nous sommes déjà au complet !", + NO_CAPACITY_NOW = "Aucune capacité de chargement disponible pour le moment !", + NO_MORE_CAPACITY = "Plus de capacité pour charger des caisses !", + CANNOT_LOAD_NONE_OR_FULL = "Chargement impossible : aucune caisse trouvée ou capacité épuisée.", + -- ============================================================ + -- Erreurs - Position + -- ============================================================ + NEED_TO_LAND_OR_HOVER_LOAD = "Vous devez atterrir ou rester en vol stationnaire pour charger !", + HOVER_OVER_CRATES = "Survolez les caisses en stationnaire pour les récupérer !", + LAND_OR_HOVER_OVER_CRATES = "Atterrissez ou survolez les caisses en stationnaire pour les récupérer !", + MUST_LAND_OR_HOVER_CRATES = "Vous devez atterrir ou rester en stationnaire pour charger les caisses !", + NEED_TO_LAND_BUILD = "Vous devez atterrir / vous arrêter pour construire quelque chose, Pilote !", + NOT_CLOSE_ENOUGH_LOGISTICS = "Vous n'êtes pas assez proche d'une zone logistique !", + NOT_CLOSE_ENOUGH_DROP = "Vous n'êtes pas assez proche d'une zone de largage !", + NOT_CLOSE_ENOUGH_ZONE_NM = "Négatif, vous devez être à moins de %d nm d'une zone !", + CANNOT_BUILD_LOADING_AREA = "Vous ne pouvez pas construire dans une zone de chargement, Pilote !", + -- ============================================================ + -- Erreurs - Portes + -- ============================================================ + OPEN_DOORS_LOAD_CARGO = "Vous devez ouvrir la/les porte(s) pour charger du fret !", + OPEN_DOORS_LOAD_TROOPS = "Vous devez ouvrir la/les porte(s) pour embarquer des troupes !", + OPEN_DOORS_EXTRACT_TROOPS = "Vous devez ouvrir la/les porte(s) pour extraire des troupes !", + OPEN_DOORS_UNLOAD_TROOPS = "Vous devez ouvrir la/les porte(s) pour débarquer des troupes !", + OPEN_DOORS_DROP_CARGO = "Vous devez ouvrir la/les porte(s) pour larguer du fret !", + -- ============================================================ + -- Erreurs - Stock / Disponibilité + -- ============================================================ + ALL_GONE = "Désolé, tous les %s sont épuisés !", + RAN_OUT_OF = "Désolé, nous n'avons plus de %s !", + CARGO_NOT_AVAILABLE_ZONE = "Le fret demandé n'est pas disponible dans cette zone !", + ENOUGH_CRATES_NEARBY = "Il y a déjà suffisamment de caisses à proximité ! Occupez-vous d'abord de celles-ci !", + NO_CRATES_WITHIN = "Aucune caisse (chargeable) dans un rayon de %d mètres !", + NO_CRATES_WITHIN_PLAIN = "Aucune caisse dans un rayon de %d mètres !", + NO_CRATES_IN_RANGE = "Aucune caisse trouvée à portée !", + NO_NAMED_CRATES_IN_RANGE = "Aucune caisse \"%s\" trouvée à portée !", + NO_LOADABLE_CRATES = "Désolé, aucune caisse chargeable à proximité ou poids maximum atteint !", + NO_UNITS_TO_EXTRACT = "Aucune unité assez proche pour être extraite !", + NO_UNIT_CONFIG = "Aucune configuration d'unité trouvée pour %s", + CANT_ONBOARD = "Impossible d'embarquer %s", + TOO_MANY_UNITS_NEARBY = "Vous avez déjà %d unités à proximité !", + NO_CRATE_GROUPS = "Aucun groupe de caisses trouvé pour cette unité !", + NO_CRATE_SET = "Aucun ensemble de caisses trouvé ou index invalide !", + NO_CRATE_IN_SET = "Aucune caisse trouvée dans cet ensemble !", + NO_TROOP_CHUNK = "Aucun bloc de fret de troupes trouvé pour l'ID %d !", + TROOP_CHUNK_EMPTY = "Le bloc de fret de troupes pour l'ID %d est vide !", + -- ============================================================ + -- Rien de chargé / en stock + -- ============================================================ + NOTHING_LOADED = "Rien de chargé !\nLimite de troupes : %d | Limite de caisses : %d | Limite en poids : %d kg", + NOTHING_LOADED_AIRDROP = "Rien de chargé ou paramètres de largage non respectés !", + NOTHING_LOADED_HOVER = "Rien de chargé ou paramètres de vol stationnaire non respectés !", + NOTHING_IN_STOCK = "Rien en stock !", + NOTHING_TO_PACK = "Rien à charger à cette distance, Pilote !", + NOTHING_TO_REMOVE = "Rien à retirer à cette distance, Pilote !", + -- ============================================================ + -- Zone / Info + -- ============================================================ + ROGER_ZONE = "Compris, zone %s %s !", + -- ============================================================ + -- Rapport : Paramètres stationnaire / vol + -- ============================================================ + HOVER_PARAMS_METRIC = "Paramètres stationnaires (autochargement/largage) :\n - Hauteur min. %dm \n - Hauteur max. %dm \n - Vitesse max. 2m/s \n - Dans les paramètres : %s", + HOVER_PARAMS_IMPERIAL = "Paramètres stationnaires (autochargement/largage) :\n - Hauteur min. %dft \n - Hauteur max. %dft \n - Vitesse max. 6ft/s \n - Dans les paramètres : %s", + FLIGHT_PARAMS_IMPERIAL = "Paramètres de vol (largage aérien) :\n - Hauteur min. %dft \n - Hauteur max. %dft \n - Dans les paramètres : %s", + FLIGHT_PARAMS_METRIC = "Paramètres de vol (largage aérien) :\n - Hauteur min. %dm \n - Hauteur max. %dm \n - Dans les paramètres : %s", + -- ============================================================ + -- Titres de rapport + -- ============================================================ + REPORT_CRATES_FOUND = "Caisses trouvées à proximité :", + REPORT_REMOVING_CRATES = "Suppression des caisses à proximité :", + REPORT_TRANSPORT_CHECKOUT = "Fiche de contrôle transport", + REPORT_INVENTORY = "Fiche d'inventaire", + REPORT_BUILD_CHECKLIST = "Checklist caisses constructibles", + REPORT_REPAIR_CHECKLIST = "Checklist réparations", + REPORT_BEACONS = "Balises de zone actives", + -- ============================================================ + -- En-têtes de sections de rapport + -- ============================================================ + REPORT_SECTION_TROOPS = " -- TROUPES --", + REPORT_SECTION_CRATES = " -- CAISSES --", + REPORT_SECTION_CRATES_GC = " -- CAISSES chargées via équipe au sol --", + REPORT_SECTION_NONE = " A U C U N", + REPORT_SECTION_NONE_ALT = " --- Aucun trouvé ! ---", + REPORT_SECTION_NONE_REPAIR = " --- Aucun trouvé ---", + REPORT_GC_LOADABLE_HINT = "Probablement chargeable via l’équipe au sol (F8)", + REPORT_TOTAL_MASS = "Masse totale : %s kg. Chargeable : %s kg.", + REPORT_TROOPS_CRATES_COUNT = "Troupes : %d(%d), Caisses : %d(%d)", + REPORT_TROOPS_CRATETYPES_COUNT = "Troupes : %d, Types de caisses : %d", + -- ============================================================ + -- Modèles de lignes de rapport + -- ============================================================ + REPORT_ROW_TROOP = "Troupe : %s taille %d", + REPORT_ROW_CRATE = "Caisse : %s %d/%d", + REPORT_ROW_CRATE_SIZE1 = "Caisse : %s taille 1", + REPORT_ROW_GC_CRATE = "Caisses chargées par l'équipe au sol : %s taille 1", + REPORT_ROW_DROPPED_CRATE = "Caisses larguées pour %s, %dkg", + REPORT_ROW_CRATE_KG = "Caisses pour %s, %dkg", + REPORT_ROW_CRATE_REMOVED = "Caisses pour %s, %dkg retirées", + REPORT_ROW_UNIT_STOCK = "Unités : %s | Soldats : %d | Stock : %s", + REPORT_ROW_TYPE_CRATE_STOCK = "Type : %s | Caisses par ensemble : %d | Stock : %s", + REPORT_ROW_TYPE_STOCK = "Type : %s | Stock : %s", + REPORT_ROW_BUILD_CHECK = "Type : %s | Requis : %d | Trouvé : %d | Constructible : %s", + REPORT_ROW_REPAIR_CHECK = "Type : %s | Requis : %d | Trouvé : %d | Réparable : %s", + REPORT_ROW_BEACON = " %s | FM %s Mhz | VHF %s KHz | UHF %s Mhz ", + -- ============================================================ + -- Tokens limite poids / caisses + -- ============================================================ + WEIGHT_LIMIT = "Limite de poids atteinte", + CRATE_LIMIT = "Limite de caisses atteinte", + -- ============================================================ + -- Libellés de menu - Niveau supérieur + -- ============================================================ + MENU_CTLD = "CTLD", + MENU_MANAGE_TROOPS = "Gérer les troupes", + MENU_MANAGE_CRATES = "Gérer les caisses", + MENU_MANAGE_UNITS = "Gérer les unités", + -- ============================================================ + -- Libellés de menu - Troupes + -- ============================================================ + MENU_LOAD_TROOPS = "Embarquer troupes", + MENU_DROP_TROOPS = "Déposer troupes", + MENU_DROP_ALL_TROOPS = "Déposer TOUTES les troupes", + MENU_EXTRACT_TROOPS = "Extraire troupes", + MENU_DROP_N_TROOPS = "Déposer (%d) %s", + -- ============================================================ + -- Libellés de menu - Caisses : Récupérer + -- ============================================================ + MENU_GET_CRATES = "Récupérer caisses", + MENU_GET = "Récupérer", + MENU_GET_AND_LOAD = "Récupérer et charger", + MENU_GET_ANYWAY = "Récupérer quand même", + MENU_PARTIALLY_LOAD = "Chargement partiel", + MENU_OUT_OF_STOCK = "Rupture de stock", + MENU_TROOP_LIMIT = "Limite de troupes atteinte", + -- ============================================================ + -- Libellés de menu - Caisses : Charger + -- ============================================================ + MENU_LOAD_CRATES = "Charger caisses", + MENU_LOAD_ALL = "Tout charger", + MENU_SHOW_LOADABLE_CRATES = "Afficher caisses chargeables", + MENU_NO_CRATES_FOUND_RESCAN = "Aucune caisse trouvée ! Rescanner ?", + MENU_USE_C130_LOAD = "Utiliser le système de chargement C-130", + -- ============================================================ + -- Libellés de menu - Caisses : Larguer + -- ============================================================ + MENU_DROP_CRATES = "Larguer caisses", + MENU_DROP_ALL_CRATES = "Larguer TOUTES les caisses", + MENU_DROP = "Larguer", + MENU_DROP_AND_BUILD = "Larguer et construire", + MENU_DROP_N_SETS = "Larguer %d ensemble%s", + MENU_NO_CRATES_TO_DROP = "Aucune caisse à larguer !", + -- ============================================================ + -- Libellés de menu - Caisses : Construire / Réparer / Emballer / Retirer + -- ============================================================ + MENU_BUILD_CRATES = "Construire caisses", + MENU_REPAIR = "Réparer", + MENU_PACK_CRATES = "Emballer caisses", + MENU_PACK = "Emballer", + MENU_PACK_AND_LOAD = "Emballer et charger", + MENU_PACK_AND_REMOVE = "Emballer et retirer", + MENU_REMOVE_CRATES = "Retirer caisses", + MENU_REMOVE_CRATES_NEARBY = "Retirer caisses proches", + MENU_LIST_CRATES_NEARBY = "Lister caisses proches", + MENU_CRATES_NEEDED = "%d caisse%s %s (%dkg)", + -- ============================================================ + -- Libellés de menu - Unités (C-130) + -- ============================================================ + MENU_GET_UNITS = "Récupérer unités", + MENU_REMOVE_UNITS_NEARBY = "Retirer les unités proches", + -- ============================================================ + -- Libellés de menu - Info / Fret + -- ============================================================ + MENU_LIST_BOARDED_CARGO = "Lister le fret embarqué", + MENU_INVENTORY = "Inventaire", + MENU_LIST_ZONE_BEACONS = "Lister les balises de zones actives", + -- ============================================================ + -- Libellés de menu - Fumigènes / Fusées / Balises + -- ============================================================ + MENU_SMOKES_FLARES_BEACONS = "Fumigènes, Fusées, Balises", + MENU_SMOKE_ZONES_NEARBY = "Fumigène sur les zones proches", + MENU_DROP_SMOKE_NOW = "Poser fumigène maintenant", + MENU_RED_SMOKE = "Fumigène rouge", + MENU_BLUE_SMOKE = "Fumigène bleu", + MENU_GREEN_SMOKE = "Fumigène vert", + MENU_ORANGE_SMOKE = "Fumigène orange", + MENU_WHITE_SMOKE = "Fumigène blanc", + MENU_FLARE_ZONES_NEARBY = "Baliser zones proches", + MENU_FIRE_FLARE_NOW = "Tirer une fusée maintenant", + MENU_DROP_BEACON_NOW = "Poser une balise maintenant", + -- ============================================================ + -- Libellés de menu - Paramètres + -- ============================================================ + MENU_SHOW_FLIGHT_PARAMS = "Afficher paramètres de vol", + MENU_SHOW_HOVER_PARAMS = "Afficher les paramètres stationnaire", + STOCK_NONE = "aucun", + STOCK_UNLIMITED = "illimité", + BUILD_YES = "OUI", + BUILD_NO = "NON", + }, + } + \ No newline at end of file