From f0037151e621a015be729c20458a784873859773 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Mon, 26 Jul 2021 09:24:35 +0200 Subject: [PATCH 01/17] CTLD - added factor for troops extraction, making Destroy()s silent for scoring, refined autohoverload messaging --- Moose Development/Moose/Ops/CTLD.lua | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 63d7985b5..b91663397 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -659,6 +659,7 @@ function CTLD:New(Coalition, Prefixes, Alias) -- setup self.CrateDistance = 30 -- list/load crates in this radius + self.ExtractFactor = 3.33 -- factor for troops extraction, i.e. CrateDistance * Extractfactor self.prefixes = Prefixes or {"Cargoheli"} --self.I({prefixes = self.prefixes}) self.useprefix = true @@ -1116,8 +1117,10 @@ end nearestDistance = distance end end - - if nearestGroup == nil or nearestDistance > self.CrateDistance then + + local extractdistance = self.CrateDistance * self.ExtractFactor + + if nearestGroup == nil or nearestDistance > extractdistance then self:_SendMessage("No units close enough to extract!", 10, false, Group) return self end @@ -1165,7 +1168,7 @@ end -- clean up: table.remove(self.DroppedTroops, nearestGroupIndex) - nearestGroup:Destroy() + nearestGroup:Destroy(false) end return self end @@ -1390,8 +1393,13 @@ function CTLD:_LoadCratesNearby(Group, Unit) -- get nearby crates local finddist = self.CrateDistance or 30 local nearcrates,number = self:_FindCratesNearby(Group,Unit,finddist) -- #table - if number == 0 or numberonboard == cratelimit then - self:_SendMessage("Sorry no loadable crates nearby or fully loaded!", 10, false, Group) + if number == 0 and self.hoverautoloading then + return -- exit + elseif number == 0 then + self:_SendMessage("Sorry no loadable crates nearby!", 10, false, Group) + return -- exit + elseif numberonboard == cratelimit then + self:_SendMessage("Sorry no fully loaded!", 10, false, Group) return -- exit else -- go through crates and load @@ -1415,7 +1423,7 @@ function CTLD:_LoadCratesNearby(Group, Unit) table.insert(loaded.Cargo, crate) table.insert(crateidsloaded,crate:GetID()) -- destroy crate - crate:GetPositionable():Destroy() + crate:GetPositionable():Destroy(false) crate.Positionable = nil self:_SendMessage(string.format("Crate ID %d for %s loaded!",crate:GetID(),crate:GetName()), 10, false, Group) self:_UpdateUnitCargoMass(Unit) @@ -1967,7 +1975,7 @@ function CTLD:_CleanUpCrates(Crates,Build,Number) if name == nametype then -- matching crate type table.insert(destIDs,thisID) found = found + 1 - nowcrate:GetPositionable():Destroy() + nowcrate:GetPositionable():Destroy(false) nowcrate.Positionable = nil end if found == numberdest then break end -- got enough @@ -2651,7 +2659,7 @@ end if self.hoverautoloading then for _,_pilot in pairs (self.CtldUnits) do local Unit = UNIT:FindByName(_pilot) - self:AutoHoverLoad(Unit) + if self:CanHoverLoad(Unit) then self:AutoHoverLoad(Unit) end end end return self From d245a73d7ffd4d77568567b29665c1be1349d6b7 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Mon, 26 Jul 2021 09:24:52 +0200 Subject: [PATCH 02/17] Make Destroy() silent for scoring --- Moose Development/Moose/Ops/CSAR.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 943b17cdd..03f9882a0 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -1112,7 +1112,7 @@ function CSAR:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupNam player = grouptable.player, } - _woundedGroup:Destroy() + _woundedGroup:Destroy(false) self:_RemoveNameFromDownedPilots(_woundedGroupName,true) self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s I\'m in! Get to the MASH ASAP! ", _heliName, _pilotName), self.messageTime,true,true) From b66d2039bee5b546d52c70b1756693806a26dbab Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 27 Jul 2021 14:09:10 +0200 Subject: [PATCH 03/17] Added function to set speed and height parameters for landing --- .../Moose/AI/AI_Cargo_Helicopter.lua | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua index 3a83a48ae..106a28ce7 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua @@ -207,6 +207,9 @@ function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet ) self:SetCarrier( Helicopter ) + self.landingspeed = 15 -- kph + self.landingheight = 5.5 -- meter + return self end @@ -255,6 +258,25 @@ function AI_CARGO_HELICOPTER:SetCarrier( Helicopter ) return self end +--- Set landingspeed and -height for helicopter landings. Adjust after tracing if your helis get stuck after landing. +-- @param #AI_CARGO_HELICOPTER self +-- @param #number speed Landing speed in kph(!), e.g. 15 +-- @param #number height Landing height in meters(!), e.g. 5.5 +-- @return #AI_CARGO_HELICOPTER self +-- @usage If your choppers get stuck, add tracing to your script to determine if they hit the right parameters like so: +-- +-- BASE:TraceOn() +-- BASE:TraceClass("AI_CARGO_HELICOPTER") +-- +-- Watch the DCS.log for entries stating `Helicopter:, Height = Helicopter:, Velocity = Helicopter:` +-- Adjust if necessary. +function AI_CARGO_HELICOPTER:SetLandingSpeedAndHeight(speed, height) + local _speed = speed or 15 + local _height = height or 5.5 + self.landingheight = _height + self.landingspeed = _speed + return self +end --- @param #AI_CARGO_HELICOPTER self -- @param Wrapper.Group#GROUP Helicopter @@ -271,13 +293,13 @@ function AI_CARGO_HELICOPTER:onafterLanded( Helicopter, From, Event, To ) -- 1 - When the helo lands normally on the ground. -- 2 - when the helo is hit and goes RTB or even when it is destroyed. -- For point 2, this is an issue, the infantry may not unload in this case! - -- So we check if the helo is on the ground, and velocity< 5. + -- So we check if the helo is on the ground, and velocity< 15. -- Only then the infantry can unload (and load too, for consistency)! - self:F( { Helicopter:GetName(), Height = Helicopter:GetHeight( true ), Velocity = Helicopter:GetVelocityKMH() } ) + self:T( { Helicopter:GetName(), Height = Helicopter:GetHeight( true ), Velocity = Helicopter:GetVelocityKMH() } ) if self.RoutePickup == true then - if Helicopter:GetHeight( true ) <= 5.5 and Helicopter:GetVelocityKMH() < 15 then + if Helicopter:GetHeight( true ) <= self.landingheight and Helicopter:GetVelocityKMH() < self.landingspeed then --self:Load( Helicopter:GetPointVec2() ) self:Load( self.PickupZone ) self.RoutePickup = false @@ -285,7 +307,7 @@ function AI_CARGO_HELICOPTER:onafterLanded( Helicopter, From, Event, To ) end if self.RouteDeploy == true then - if Helicopter:GetHeight( true ) <= 5.5 and Helicopter:GetVelocityKMH() < 15 then + if Helicopter:GetHeight( true ) <= self.landingheight and Helicopter:GetVelocityKMH() < self.landingspeed then self:Unload( self.DeployZone ) self.RouteDeploy = false end From 82432686aa592384dd18f84cacb8edbddb303391 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 27 Jul 2021 14:10:10 +0200 Subject: [PATCH 04/17] Fixed display messages to all SAR, added option to suppress messaging --- Moose Development/Moose/Ops/CSAR.lua | 41 ++++++++-------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 03f9882a0..e87f6ece8 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -95,6 +95,8 @@ -- self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters -- self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters -- self.pilotmustopendoors = false -- switch to true to enable check of open doors +-- -- (added 0.1.9) +-- self.suppressmessages = false -- switch off all messaging if you want to do your own -- -- ## 2.1 Experimental Features -- @@ -214,26 +216,6 @@ CSAR = { -- @field Wrapper.Group#GROUP group Spawned group object. -- @field #number timestamp Timestamp for approach process -- @field #boolean alive Group is alive or dead/rescued --- ---- Updated and sorted list of known NDB beacons (in kHz!) from the available maps. - ---[[ Moved to Utils --- @field #CSAR.SkipFrequencies -CSAR.SkipFrequencies = { - 214,274,291.5,295,297.5, - 300.5,304,307,309.5,311,312,312.5,316, - 320,324,328,329,330,336,337, - 342,343,348,351,352,353,358, - 363,365,368,372.5,374, - 380,381,384,389,395,396, - 414,420,430,432,435,440,450,455,462,470,485, - 507,515,520,525,528,540,550,560,570,577,580,602,625,641,662,670,680,682,690, - 705,720,722,730,735,740,745,750,770,795, - 822,830,862,866, - 905,907,920,935,942,950,995, - 1000,1025,1030,1050,1065,1116,1175,1182,1210 - } ---]] --- All slot / Limit settings -- @type CSAR.AircraftType @@ -251,7 +233,7 @@ CSAR.AircraftType["Mi-24V"] = 8 --- CSAR class version. -- @field #string version -CSAR.version="0.1.8r3" +CSAR.version="0.1.9r1" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -378,6 +360,7 @@ function CSAR:New(Coalition, Template, Alias) self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters self.pilotmustopendoors = false -- switch to true to enable check on open doors + self.suppressmessages = false -- WARNING - here\'ll be dragons -- for this to work you need to de-sanitize your mission environment in \Scripts\MissionScripting.lua @@ -642,7 +625,7 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla local _typeName = _typeName or "Pilot" if not noMessage then - self:_DisplayToAllSAR("MAYDAY MAYDAY! " .. _typeName .. " is down. ", self.coalition, 10) + self:_DisplayToAllSAR("MAYDAY MAYDAY! " .. _typeName .. " is down. ", self.coalition, self.messageTime) end if _freq then @@ -806,8 +789,7 @@ function CSAR:_EventHandler(EventData) if self:_DoubleEjection(_unitname) then return end - self:_DisplayToAllSAR("MAYDAY MAYDAY! " .. _unit:GetTypeName() .. " shot down. No Chute!", self.coalition, 10) - --local m = MESSAGE:New("MAYDAY MAYDAY! " .. _unit:GetTypeName() .. " shot down. No Chute!",10,"Info"):ToCoalition(self.coalition) + self:_DisplayToAllSAR("MAYDAY MAYDAY! " .. _unit:GetTypeName() .. " shot down. No Chute!", self.coalition, self.messageTime) else self:T(self.lid .. " Pilot has not taken off, ignore") end @@ -1403,7 +1385,9 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak) local group = _unit:GetGroup() local _clear = _clear or nil local _time = _time or self.messageTime - local m = MESSAGE:New(_text,_time,"Info",_clear):ToGroup(group) + if not self.suppressmessages then + local m = MESSAGE:New(_text,_time,"Info",_clear):ToGroup(group) + end -- integrate SRS if _speak and self.useSRS then local srstext = SOUNDTEXT:New(_text) @@ -1570,12 +1554,11 @@ end -- @param #number _messagetime How long to show. function CSAR:_DisplayToAllSAR(_message, _side, _messagetime) self:T(self.lid .. " _DisplayToAllSAR") + local messagetime = _messagetime or self.messageTime for _, _unitName in pairs(self.csarUnits) do local _unit = self:_GetSARHeli(_unitName) - if _unit then - if not _messagetime then - self:_DisplayMessageToSAR(_unit, _message, _messagetime) - end + if _unit and not self.suppressmessages then + self:_DisplayMessageToSAR(_unit, _message, _messagetime) end end return self From 061032e3d742f57a49c8b31025e03bd09c4f49d9 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Wed, 28 Jul 2021 18:31:39 +0200 Subject: [PATCH 05/17] Transition cleanup for AI Helicopter, deleted speed test bc in 20% of cases AI lands shit, which stops the FSM --- Moose Development/Moose/AI/AI_Cargo.lua | 25 ++++++++------- .../AI/AI_Cargo_Dispatcher_Helicopter.lua | 9 ++++-- .../Moose/AI/AI_Cargo_Helicopter.lua | 32 +++++++++++-------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo.lua b/Moose Development/Moose/AI/AI_Cargo.lua index 5bcd94437..0751abc6a 100644 --- a/Moose Development/Moose/AI/AI_Cargo.lua +++ b/Moose Development/Moose/AI/AI_Cargo.lua @@ -47,19 +47,20 @@ function AI_CARGO:New( Carrier, CargoSet ) self:SetStartState( "Unloaded" ) - self:AddTransition( "Unloaded", "Pickup", "*" ) - self:AddTransition( "Loaded", "Deploy", "*" ) + -- Board + self:AddTransition( "Unloaded", "Pickup", "Unloaded" ) + self:AddTransition( "*", "Load", "*" ) + self:AddTransition( "*", "Reload", "*" ) + self:AddTransition( "*", "Board", "*" ) + self:AddTransition( "*", "Loaded", "Loaded" ) + self:AddTransition( "Loaded", "PickedUp", "Loaded" ) - self:AddTransition( "*", "Load", "Boarding" ) - self:AddTransition( "Boarding", "Board", "Boarding" ) - self:AddTransition( "Loaded", "Board", "Loaded" ) - self:AddTransition( "Boarding", "Loaded", "Boarding" ) - self:AddTransition( "Boarding", "PickedUp", "Loaded" ) - - self:AddTransition( "Loaded", "Unload", "Unboarding" ) - self:AddTransition( "Unboarding", "Unboard", "Unboarding" ) - self:AddTransition( "Unboarding", "Unloaded", "Unboarding" ) - self:AddTransition( "Unboarding", "Deployed", "Unloaded" ) + -- Unload + self:AddTransition( "Loaded", "Deploy", "*" ) + self:AddTransition( "*", "Unload", "*" ) + self:AddTransition( "*", "Unboard", "*" ) + self:AddTransition( "*", "Unloaded", "Unloaded" ) + self:AddTransition( "Unloaded", "Deployed", "Unloaded" ) --- Pickup Handler OnBefore for AI_CARGO -- @function [parent=#AI_CARGO] OnBeforePickup diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua index 127c67dbb..bba9b7108 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua @@ -174,8 +174,8 @@ function AI_CARGO_DISPATCHER_HELICOPTER:New( HelicopterSet, CargoSet, PickupZone self:SetPickupSpeed( 350, 150 ) self:SetDeploySpeed( 350, 150 ) - self:SetPickupRadius( 0, 0 ) - self:SetDeployRadius( 0, 0 ) + self:SetPickupRadius( 40, 12 ) + self:SetDeployRadius( 40, 12 ) self:SetPickupHeight( 500, 200 ) self:SetDeployHeight( 500, 200 ) @@ -186,6 +186,9 @@ end function AI_CARGO_DISPATCHER_HELICOPTER:AICargo( Helicopter, CargoSet ) - return AI_CARGO_HELICOPTER:New( Helicopter, CargoSet ) + local dispatcher = AI_CARGO_HELICOPTER:New( Helicopter, CargoSet ) + dispatcher:SetLandingSpeedAndHeight(27, 6) + return dispatcher + end diff --git a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua index 106a28ce7..2c1d5c028 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua @@ -64,20 +64,24 @@ function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet ) self.Zone = ZONE_GROUP:New( Helicopter:GetName(), Helicopter, 300 ) self:SetStartState( "Unloaded" ) + -- Boarding + self:AddTransition( "Unloaded", "Pickup", "Unloaded" ) + self:AddTransition( "*", "Landed", "*" ) + self:AddTransition( "*", "Load", "*" ) + self:AddTransition( "*", "Loaded", "Loaded" ) + self:AddTransition( "Loaded", "PickedUp", "Loaded" ) - self:AddTransition( "Unloaded", "Pickup", "*" ) - self:AddTransition( "Loaded", "Deploy", "*" ) - self:AddTransition( "*", "Loaded", "Loaded" ) - self:AddTransition( "Unboarding", "Pickup", "Unloaded" ) - self:AddTransition( "Unloaded", "Unboard", "Unloaded" ) - self:AddTransition( "Unloaded", "Unloaded", "Unloaded" ) - self:AddTransition( "*", "PickedUp", "*" ) - self:AddTransition( "*", "Landed", "*" ) - self:AddTransition( "*", "Queue", "*" ) - self:AddTransition( "*", "Orbit" , "*" ) + -- Unboarding + self:AddTransition( "Loaded", "Deploy", "*" ) + self:AddTransition( "*", "Queue", "*" ) + self:AddTransition( "*", "Orbit" , "*" ) + self:AddTransition( "*", "Destroyed", "*" ) + self:AddTransition( "*", "Unload", "*" ) + self:AddTransition( "*", "Unloaded", "Unloaded" ) + self:AddTransition( "Unloaded", "Deployed", "Unloaded" ) + + -- RTB self:AddTransition( "*", "Home" , "*" ) - - self:AddTransition( "*", "Destroyed", "Destroyed" ) --- Pickup Handler OnBefore for AI_CARGO_HELICOPTER -- @function [parent=#AI_CARGO_HELICOPTER] OnBeforePickup @@ -299,7 +303,7 @@ function AI_CARGO_HELICOPTER:onafterLanded( Helicopter, From, Event, To ) self:T( { Helicopter:GetName(), Height = Helicopter:GetHeight( true ), Velocity = Helicopter:GetVelocityKMH() } ) if self.RoutePickup == true then - if Helicopter:GetHeight( true ) <= self.landingheight and Helicopter:GetVelocityKMH() < self.landingspeed then + if Helicopter:GetHeight( true ) <= self.landingheight then --and Helicopter:GetVelocityKMH() < self.landingspeed then --self:Load( Helicopter:GetPointVec2() ) self:Load( self.PickupZone ) self.RoutePickup = false @@ -307,7 +311,7 @@ function AI_CARGO_HELICOPTER:onafterLanded( Helicopter, From, Event, To ) end if self.RouteDeploy == true then - if Helicopter:GetHeight( true ) <= self.landingheight and Helicopter:GetVelocityKMH() < self.landingspeed then + if Helicopter:GetHeight( true ) <= self.landingheight then --and Helicopter:GetVelocityKMH() < self.landingspeed then self:Unload( self.DeployZone ) self.RouteDeploy = false end From 8b45067226979f07481e071ee1a41815376d6485 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 29 Jul 2021 12:41:27 +0200 Subject: [PATCH 06/17] Various patches for AI_CARGO --- Moose Development/Moose/AI/AI_Cargo.lua | 6 +++--- Moose Development/Moose/AI/AI_Cargo_APC.lua | 3 ++- Moose Development/Moose/Ops/CSAR.lua | 6 ++++-- Moose Development/Moose/Utilities/Utils.lua | 4 ++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo.lua b/Moose Development/Moose/AI/AI_Cargo.lua index 0751abc6a..43d5eb358 100644 --- a/Moose Development/Moose/AI/AI_Cargo.lua +++ b/Moose Development/Moose/AI/AI_Cargo.lua @@ -61,6 +61,7 @@ function AI_CARGO:New( Carrier, CargoSet ) self:AddTransition( "*", "Unboard", "*" ) self:AddTransition( "*", "Unloaded", "Unloaded" ) self:AddTransition( "Unloaded", "Deployed", "Unloaded" ) + --- Pickup Handler OnBefore for AI_CARGO -- @function [parent=#AI_CARGO] OnBeforePickup @@ -394,7 +395,7 @@ end function AI_CARGO:onafterBoard( Carrier, From, Event, To, Cargo, CarrierUnit, PickupZone ) self:F( { Carrier, From, Event, To, Cargo, CarrierUnit:GetName() } ) - if Carrier and Carrier:IsAlive() and From == "Boarding" then + if Carrier and Carrier:IsAlive() then self:F({ IsLoaded = Cargo:IsLoaded(), Cargo:GetName(), Carrier:GetName() } ) if not Cargo:IsLoaded() and not Cargo:IsDestroyed() then self:__Board( -10, Cargo, CarrierUnit, PickupZone ) @@ -510,7 +511,7 @@ end function AI_CARGO:onafterUnboard( Carrier, From, Event, To, Cargo, CarrierUnit, DeployZone, Defend ) self:F( { Carrier, From, Event, To, Cargo:GetName(), DeployZone = DeployZone, Defend = Defend } ) - if Carrier and Carrier:IsAlive() and From == "Unboarding" then + if Carrier and Carrier:IsAlive() then if not Cargo:IsUnLoaded() then self:__Unboard( 10, Cargo, CarrierUnit, DeployZone, Defend ) return @@ -581,4 +582,3 @@ function AI_CARGO:onafterDeployed( Carrier, From, Event, To, DeployZone, Defend end end - diff --git a/Moose Development/Moose/AI/AI_Cargo_APC.lua b/Moose Development/Moose/AI/AI_Cargo_APC.lua index bee08e1b1..6bc78debb 100644 --- a/Moose Development/Moose/AI/AI_Cargo_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_APC.lua @@ -98,7 +98,8 @@ function AI_CARGO_APC:New( APC, CargoSet, CombatRadius ) self:AddTransition( "*", "Guard", "Unloaded" ) self:AddTransition( "*", "Home", "*" ) self:AddTransition( "*", "Reload", "Boarding" ) - + self:AddTransition( "*", "Deployed", "*" ) + self:AddTransition( "*", "PickedUp", "*" ) self:AddTransition( "*", "Destroyed", "Destroyed" ) self:SetCombatRadius( CombatRadius ) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index e87f6ece8..b18fbb93b 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -1,4 +1,3 @@ - --- **Ops** -- Combat Search and Rescue. -- -- === @@ -1125,6 +1124,8 @@ end -- @return #boolean outcome The outcome. function CSAR:_IsLoadingDoorOpen( unit_name ) self:T(self.lid .. " _IsLoadingDoorOpen") + + --[[ local ret_val = false local unit = Unit.getByName(unit_name) if unit ~= nil then @@ -1156,8 +1157,9 @@ function CSAR:_IsLoadingDoorOpen( unit_name ) return ret_val end -- nil + --]] + return UTILS.IsLoadingDoorOpen(unit_name) - return false end --- (Internal) Function to check if heli is close to group. diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 87198a2d7..91d5149b5 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -1578,8 +1578,8 @@ function UTILS.IsLoadingDoorOpen( unit_name ) if unit ~= nil then local type_name = unit:getTypeName() - if type_name == "Mi-8MT" and unit:getDrawArgumentValue(86) == 1 or unit:getDrawArgumentValue(250) == 1 then - BASE:T(unit_name .. " Cargo doors are open or cargo door not present") + if type_name == "Mi-8MT" and unit:getDrawArgumentValue(38) == 1 or unit:getDrawArgumentValue(86) == 1 or unit:getDrawArgumentValue(250) == 1 then + self:T(unit_name .. " Cargo doors are open or cargo door not present") ret_val = true end From 63431bb54be18cc429bb402ba76447ab13c6911d Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Fri, 30 Jul 2021 17:30:32 +0200 Subject: [PATCH 07/17] Couple of changes to make finding the distance to nearest pilot more stable --- Moose Development/Moose/Ops/CSAR.lua | 47 +++++++++++++++++++--------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index b18fbb93b..d3c0a3d2a 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -232,7 +232,7 @@ CSAR.AircraftType["Mi-24V"] = 8 --- CSAR class version. -- @field #string version -CSAR.version="0.1.9r1" +CSAR.version="0.1.10r1" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -1487,10 +1487,17 @@ function CSAR:_GetClosestDownedPilot(_heli) local _shortestDistance = -1 local _distance = 0 local _closestGroupInfo = nil - local _heliCoord = _heli:GetCoordinate() + local _heliCoord = _heli:GetCoordinate() or _heli:GetCoordinate() + + if _heliCoord == nil then + self:E("****Error obtaining coordinate!") + return nil + end local DownedPilotsTable = self.downedPilots - for _, _groupInfo in pairs(DownedPilotsTable) do + + for _, _groupInfo in UTILS.spairs(DownedPilotsTable) do + --for _, _groupInfo in pairs(DownedPilotsTable) do local _woundedName = _groupInfo.name local _tempWounded = _groupInfo.group @@ -1732,9 +1739,21 @@ end function CSAR:_GetDistance(_point1, _point2) self:T(self.lid .. " _GetDistance") if _point1 and _point2 then - local distance = _point1:DistanceFromPointVec2(_point2) - return distance + local distance1 = _point1:Get2DDistance(_point2) + local distance2 = _point1:DistanceFromPointVec2(_point2) + self:I({dist1=distance1, dist2=distance2}) + 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 @@ -1900,19 +1919,19 @@ end -- @param #CSAR self function CSAR:_CheckDownedPilotTable() local pilots = self.downedPilots - for _,_entry in pairs (pilots) do - self:T("Checking for " .. _entry.name) - self:T({entry=_entry}) - local group = _entry.group - if not group:IsAlive() then - self:T("Group is dead") - if _entry.alive == true then - self:T("Switching .alive to false") + local npilots = {} + + for _ind,_entry in pairs(pilots) do + local _group = _entry.group + if _group:IsAlive() then + npilots[_ind] = _entry + else + if _entry.alive then self:__KIA(1,_entry.desc) - self:_RemoveNameFromDownedPilots(_entry.name,true) end end end + self.downedPilots = npilots return self end From 642cc0e98fc92144ab9d9524d2dabba4347a865c Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sat, 31 Jul 2021 13:05:51 +0200 Subject: [PATCH 08/17] Added self.FARPRescueDistance reduced landing check to one call --- Moose Development/Moose/Ops/CSAR.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index d3c0a3d2a..ba603486f 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -232,7 +232,7 @@ CSAR.AircraftType["Mi-24V"] = 8 --- CSAR class version. -- @field #string version -CSAR.version="0.1.10r1" +CSAR.version="0.1.10r2" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -342,6 +342,7 @@ function CSAR:New(Coalition, Template, Alias) self.loadtimemax = 135 -- seconds self.radioSound = "beacon.ogg" -- the name of the sound file to use for the Pilot radio beacons. If this isnt added to the mission BEACONS WONT WORK! self.allowFARPRescue = true --allows pilot to be rescued by landing at a FARP or Airbase + self.FARPRescueDistance = 250 -- you need to be this close to a FARP or Airport for the pilot to be rescued. self.max_units = 6 --max number of pilots that can be carried self.useprefix = true -- Use the Prefixed defined below, Requires Unit have the Prefix defined below self.csarPrefix = { "helicargo", "MEDEVAC"} -- prefixes used for useprefix=true - DON\'T use # in names! @@ -875,11 +876,14 @@ function CSAR:_EventHandler(EventData) end if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then + self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName) + --[[ if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_event.IniUnitName) then self:_DisplayMessageToSAR(_unit, "Open the door to let me out!", self.messageTime, true) else self:_RescuePilots(_unit) end + --]] else self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition())) end @@ -1321,8 +1325,8 @@ function CSAR:_ScheduledSARFlight(heliname,groupname) return end - if _dist < 200 and _heliUnit:InAir() == false then - if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(heliname) then + if _dist < self.FARPRescueDistance and _heliUnit:InAir() == false then + if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true) else self:_RescuePilots(_heliUnit) From 1b414b840e79e62e2b36037300bb400de6f368c7 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sat, 31 Jul 2021 15:50:50 +0200 Subject: [PATCH 09/17] added AP check on landing/rescue --- Moose Development/Moose/Ops/CSAR.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index ba603486f..5295dd02d 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -69,6 +69,7 @@ -- -- self.allowDownedPilotCAcontrol = false -- Set to false if you don\'t want to allow control by Combined Arms. -- self.allowFARPRescue = true -- allows pilots to be rescued by landing at a FARP or Airbase. Else MASH only! +-- self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued. -- self.autosmoke = false -- automatically smoke a downed pilot\'s location when a heli is near. -- self.autosmokedistance = 1000 -- distance for autosmoke -- self.coordtype = 1 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates. @@ -342,7 +343,7 @@ function CSAR:New(Coalition, Template, Alias) self.loadtimemax = 135 -- seconds self.radioSound = "beacon.ogg" -- the name of the sound file to use for the Pilot radio beacons. If this isnt added to the mission BEACONS WONT WORK! self.allowFARPRescue = true --allows pilot to be rescued by landing at a FARP or Airbase - self.FARPRescueDistance = 250 -- you need to be this close to a FARP or Airport for the pilot to be rescued. + self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued. self.max_units = 6 --max number of pilots that can be carried self.useprefix = true -- Use the Prefixed defined below, Requires Unit have the Prefix defined below self.csarPrefix = { "helicargo", "MEDEVAC"} -- prefixes used for useprefix=true - DON\'T use # in names! @@ -876,7 +877,7 @@ function CSAR:_EventHandler(EventData) end if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then - self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName) + self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true) --[[ if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_event.IniUnitName) then self:_DisplayMessageToSAR(_unit, "Open the door to let me out!", self.messageTime, true) @@ -1302,7 +1303,8 @@ end -- @param #CSAR self -- @param #string heliname Heli name -- @param #string groupname Group name -function CSAR:_ScheduledSARFlight(heliname,groupname) +-- @param #boolean isairport If true, EVENT.Landing took place at an airport or FARP +function CSAR:_ScheduledSARFlight(heliname,groupname, isairport) self:T(self.lid .. " _ScheduledSARFlight") self:T({heliname,groupname}) local _heliUnit = self:_GetSARHeli(heliname) @@ -1325,7 +1327,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname) return end - if _dist < self.FARPRescueDistance and _heliUnit:InAir() == false then + if ( _dist < self.FARPRescueDistance or isairport ) and _heliUnit:InAir() == false then if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true) else From 730dabd9cf836d1e33c9a1c1247af2aa65e38965 Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 3 Aug 2021 07:16:42 +0200 Subject: [PATCH 10/17] Update CSAR.lua --- Moose Development/Moose/Ops/CSAR.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 5295dd02d..59bbd18dd 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -349,7 +349,7 @@ function CSAR:New(Coalition, Template, Alias) self.csarPrefix = { "helicargo", "MEDEVAC"} -- prefixes used for useprefix=true - DON\'T use # in names! self.template = Template or "generic" -- template for downed pilot self.mashprefix = {"MASH"} -- prefixes used to find MASHes - self.mash = SET_GROUP:New():FilterCoalitions(self.coalition):FilterPrefixes(self.mashprefix):FilterOnce() -- currently only GROUP objects, maybe support STATICs also? + self.autosmoke = false -- automatically smoke location when heli is near self.autosmokedistance = 2000 -- distance for autosmoke -- added 0.1.4 @@ -1917,6 +1917,7 @@ function CSAR:onafterStart(From, Event, To) else self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart() end + self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart() -- currently only GROUP objects, maybe support STATICs also? self:__Status(-10) return self end From 2201b2addae6c7261ad74566c4c0001a89a3f24f Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Wed, 4 Aug 2021 11:07:47 +0200 Subject: [PATCH 11/17] Update Utils.lua Corrected self to BASE --- Moose Development/Moose/Utilities/Utils.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 91d5149b5..bc73bc716 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -1579,7 +1579,7 @@ function UTILS.IsLoadingDoorOpen( unit_name ) local type_name = unit:getTypeName() if type_name == "Mi-8MT" and unit:getDrawArgumentValue(38) == 1 or unit:getDrawArgumentValue(86) == 1 or unit:getDrawArgumentValue(250) == 1 then - self:T(unit_name .. " Cargo doors are open or cargo door not present") + BASE:T(unit_name .. " Cargo doors are open or cargo door not present") ret_val = true end @@ -1751,4 +1751,4 @@ function UTILS.GenerateLaserCodes() _count = _count + 1 end return jtacGeneratedLaserCodes -end \ No newline at end of file +end From bce28cf3890cb1f9723984d578284c5e5a5561ed Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Mon, 9 Aug 2021 09:06:15 +0200 Subject: [PATCH 12/17] CSAR fix for #1588 Fixes #1588 --- Moose Development/Moose/Ops/CSAR.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 59bbd18dd..b4daaaaed 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -920,7 +920,7 @@ function CSAR:_InitSARForPilot(_downedGroup, _GroupName, _freq, _nomessage) end -- trigger FSM event - self:__PilotDown(2,_downedGroup, _freqk, _leadername, _coordinatesText) + self:__PilotDown(2,_downedGroup, _freqk, _groupName, _coordinatesText) return self end From 30623f7d38895a7cde70593a8bd90427f02b1f28 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Wed, 18 Aug 2021 09:28:30 +0200 Subject: [PATCH 13/17] AIRBOSS / ATIS deleted extra char before degree char. Small correction for CSAR landings at Airports --- Moose Development/Moose/Ops/ATIS.lua | 60 +++++++-------- Moose Development/Moose/Ops/Airboss.lua | 98 ++++++++++++------------- Moose Development/Moose/Ops/CSAR.lua | 11 +-- 3 files changed, 85 insertions(+), 84 deletions(-) diff --git a/Moose Development/Moose/Ops/ATIS.lua b/Moose Development/Moose/Ops/ATIS.lua index f865f98be..2902df550 100644 --- a/Moose Development/Moose/Ops/ATIS.lua +++ b/Moose Development/Moose/Ops/ATIS.lua @@ -383,13 +383,13 @@ ATIS.Alphabet = { --- Runway correction for converting true to magnetic heading. -- @type ATIS.RunwayM2T --- @field #number Caucasus 0° (East). --- @field #number Nevada +12° (East). --- @field #number Normandy -10° (West). --- @field #number PersianGulf +2° (East). --- @field #number TheChannel -10° (West). --- @field #number Syria +5° (East). --- @field #number MarianaIslands +2° (East). +-- @field #number Caucasus 0 (East). +-- @field #number Nevada +12 (East). +-- @field #number Normandy -10 (West). +-- @field #number PersianGulf +2 (East). +-- @field #number TheChannel -10 (West). +-- @field #number Syria +5 (East). +-- @field #number MarianaIslands +2 (East). ATIS.RunwayM2T={ Caucasus=0, Nevada=12, @@ -839,9 +839,9 @@ function ATIS:SetMapMarks(switch) return self end ---- Set magnetic runway headings as depicted on the runway, *e.g.* "13" for 130° or "25L" for the left runway with magnetic heading 250°. +--- Set magnetic runway headings as depicted on the runway, *e.g.* "13" for 130 or "25L" for the left runway with magnetic heading 250. -- @param #ATIS self --- @param #table headings Magnetic headings. Inverse (-180°) headings are added automatically. You only need to specify one heading per runway direction. "L"eft and "R" right can also be appended. +-- @param #table headings Magnetic headings. Inverse (-180) headings are added automatically. You only need to specify one heading per runway direction. "L"eft and "R" right can also be appended. -- @return #ATIS self function ATIS:SetRunwayHeadingsMagnetic(headings) @@ -974,12 +974,12 @@ end -- -- To get *true* from *magnetic* heading one has to add easterly or substract westerly variation, e.g -- --- A magnetic heading of 180° corresponds to a true heading of +-- A magnetic heading of 180 corresponds to a true heading of -- --- * 186° on the Caucaus map --- * 192° on the Nevada map --- * 170° on the Normany map --- * 182° on the Persian Gulf map +-- * 186 on the Caucaus map +-- * 192 on the Nevada map +-- * 170 on the Normany map +-- * 182 on the Persian Gulf map -- -- Likewise, to convert *true* into *magnetic* heading, one has to substract easterly and add westerly variation. -- @@ -1314,7 +1314,7 @@ function ATIS:onafterBroadcast(From, Event, To) local g= 9.80665 --[m/s^2] local M= 0.0289644 --[kg/mol] local T0=coord:GetTemperature(0)+273.15 --[K] Temp at sea level. - local TS=288.15 -- Standard Temperature assumed by Altimeter is 15°C + local TS=288.15 -- Standard Temperature assumed by Altimeter is 15C local q=qnh*100 -- Calculate Pressure. @@ -1451,13 +1451,13 @@ function ATIS:onafterBroadcast(From, Event, To) --- Temperature and Dew Point --- --------------------------------- - -- Temperature in °C. + -- Temperature in C. local temperature=coord:GetTemperature(height+5) - -- Dew point in °C. + -- Dew point in C. local dewpoint=temperature-(100-self.relHumidity)/5 - -- Convert to °F. + -- Convert to F. if self.TDegF then temperature=UTILS.CelciusToFarenheit(temperature) dewpoint=UTILS.CelciusToFarenheit(dewpoint) @@ -1901,15 +1901,15 @@ function ATIS:onafterBroadcast(From, Event, To) -- Temperature if self.TDegF then if temperature<0 then - subtitle=string.format("Temperature -%s °F", TEMPERATURE) + subtitle=string.format("Temperature -%s F", TEMPERATURE) else - subtitle=string.format("Temperature %s °F", TEMPERATURE) + subtitle=string.format("Temperature %s F", TEMPERATURE) end else if temperature<0 then - subtitle=string.format("Temperature -%s °C", TEMPERATURE) + subtitle=string.format("Temperature -%s C", TEMPERATURE) else - subtitle=string.format("Temperature %s °C", TEMPERATURE) + subtitle=string.format("Temperature %s C", TEMPERATURE) end end local _TEMPERATURE=subtitle @@ -1930,15 +1930,15 @@ function ATIS:onafterBroadcast(From, Event, To) -- Dew point if self.TDegF then if dewpoint<0 then - subtitle=string.format("Dew point -%s °F", DEWPOINT) + subtitle=string.format("Dew point -%s F", DEWPOINT) else - subtitle=string.format("Dew point %s °F", DEWPOINT) + subtitle=string.format("Dew point %s F", DEWPOINT) end else if dewpoint<0 then - subtitle=string.format("Dew point -%s °C", DEWPOINT) + subtitle=string.format("Dew point -%s C", DEWPOINT) else - subtitle=string.format("Dew point %s °C", DEWPOINT) + subtitle=string.format("Dew point %s C", DEWPOINT) end end local _DEWPOINT=subtitle @@ -2276,8 +2276,8 @@ function ATIS:onafterReport(From, Event, To, Text) -- Replace other stuff. local text=string.gsub(text, "SM", "statute miles") - local text=string.gsub(text, "°C", "degrees Celsius") - local text=string.gsub(text, "°F", "degrees Fahrenheit") + local text=string.gsub(text, "C", "degrees Celsius") + local text=string.gsub(text, "F", "degrees Fahrenheit") local text=string.gsub(text, "inHg", "inches of Mercury") local text=string.gsub(text, "mmHg", "millimeters of Mercury") local text=string.gsub(text, "hPa", "hecto Pascals") @@ -2397,7 +2397,7 @@ end --- Get runway from user supplied magnetic heading. -- @param #ATIS self -- @param #number windfrom Wind direction (from) in degrees. --- @return #string Runway magnetic heading divided by ten (and rounded). Eg, "13" for 130°. +-- @return #string Runway magnetic heading divided by ten (and rounded). Eg, "13" for 130. function ATIS:GetMagneticRunway(windfrom) local diffmin=nil @@ -2440,7 +2440,7 @@ function ATIS:GetNavPoint(navpoints, runway, left) local navL=self:GetRunwayLR(nav.runway) local hdgD=UTILS.HdgDiff(navy,rwyy) - if hdgD<=15 then --We allow an error of +-15° here. + if hdgD<=15 then --We allow an error of +-15 here. if navL==nil or (navL==true and left==true) or (navL==false and left==false) then return nav end diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index 97e6cb764..4b23fc01b 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -725,7 +725,7 @@ -- -- The same holds true after the recovery window closes. The carrier will head back to the place where he left its assigned route and resume the path to the next waypoint defined in the mission editor. -- --- Note that the carrier will only head into the wind, if the wind direction is different by more than 5° from the current heading of the carrier (the angled runway, if any, fis taken into account here). +-- Note that the carrier will only head into the wind, if the wind direction is different by more than 5 from the current heading of the carrier (the angled runway, if any, fis taken into account here). -- -- === -- @@ -864,10 +864,10 @@ -- -- The graph displays the lineup error (LUE) as a function of the distance to the carrier. -- --- The pilot approaches the carrier from the port side, LUE>0°, at a distance of ~1 NM. --- At the beginning of the groove (X), he significantly overshoots to the starboard side (LUE<5°). +-- The pilot approaches the carrier from the port side, LUE>0, at a distance of ~1 NM. +-- At the beginning of the groove (X), he significantly overshoots to the starboard side (LUE<5). -- In the middle (IM), he performs good corrections and smoothly reduces the lineup error. --- Finally, at a distance of ~0.3 NM (IC) he has corrected his lineup with the runway to a reasonable level, |LUE|<0.5°. +-- Finally, at a distance of ~0.3 NM (IC) he has corrected his lineup with the runway to a reasonable level, |LUE|<0.5. -- -- ## Glideslope Error -- @@ -876,7 +876,7 @@ -- The graph displays the glideslope error (GSE) as a function of the distance to the carrier. -- -- In this case the pilot already enters the groove (X) below the optimal glideslope. He is not able to correct his height in the IM part and --- stays significantly too low. In close, he performs a harsh correction to gain altitude and ends up even slightly too high (GSE>0.5°). +-- stays significantly too low. In close, he performs a harsh correction to gain altitude and ends up even slightly too high (GSE>0.5). -- At his point further corrections are necessary. -- -- ## Angle of Attack @@ -2438,7 +2438,7 @@ end -- @param #number duration Default duration of the recovery in minutes. Default 30 min. -- @param #number windondeck Default wind on deck in knots. Default 25 knots. -- @param #boolean uturn U-turn after recovery window closes on=true or off=false/nil. Default off. --- @param #number offset Relative Marshal radial in degrees for Case II/III recoveries. Default 30°. +-- @param #number offset Relative Marshal radial in degrees for Case II/III recoveries. Default 30. -- @return #AIRBOSS self function AIRBOSS:SetMenuRecovery(duration, windondeck, uturn, offset) @@ -3878,7 +3878,7 @@ function AIRBOSS:_CheckRecoveryTimes() -- Check if time is less than 5 minutes. if nextwindow.WIND and nextwindow.START-time 5° different from the current heading. + -- Check that wind is blowing from a direction > 5 different from the current heading. local hdg=self:GetHeading() local wind=self:GetHeadingIntoWind() local delta=self:_GetDeltaHeading(hdg, wind) @@ -3896,7 +3896,7 @@ function AIRBOSS:_CheckRecoveryTimes() end --Debug info - self:T(self.lid..string.format("Heading=%03d°, Wind=%03d° %.1f kts, Delta=%03d° ==> U-turn=%s", hdg, wind,UTILS.MpsToKnots(vwind), delta, tostring(uturn))) + self:T(self.lid..string.format("Heading=%03d, Wind=%03d %.1f kts, Delta=%03d ==> U-turn=%s", hdg, wind,UTILS.MpsToKnots(vwind), delta, tostring(uturn))) -- Time into the wind 1 day or if longer recovery time + the 5 min early. local t=math.max(nextwindow.STOP-nextwindow.START+self.dTturn, 60*60*24) @@ -6933,7 +6933,7 @@ function AIRBOSS:_AddMarshalGroup(flight, stack) -- For case 1 we want the BRC but above routine return FB. radial=self:GetBRC() end - local text=string.format("Select TACAN %03d°, channel %d%s (%s)", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) + local text=string.format("Select TACAN %03d, channel %d%s (%s)", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) self:MessageToPlayer(flight, text, nil, "") end @@ -9346,7 +9346,7 @@ function AIRBOSS:_Initial(playerData) -- Hook down for students. if playerData.difficulty==AIRBOSS.Difficulty.EASY and playerData.actype~=AIRBOSS.AircraftCarrier.AV8B then if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then - hint=hint.." - Hook down, SAS on, Wing Sweep 68°!" + hint=hint.." - Hook down, SAS on, Wing Sweep 68!" else hint=hint.." - Hook down!" end @@ -11331,15 +11331,15 @@ function AIRBOSS:_AttitudeMonitor(playerData) -- Output local text=string.format("Pattern step: %s", step) - text=text..string.format("\nAoA=%.1f° = %.1f Units | |V|=%.1f knots", aoa, self:_AoADeg2Units(playerData, aoa), UTILS.MpsToKnots(vabs)) + text=text..string.format("\nAoA=%.1f = %.1f Units | |V|=%.1f knots", aoa, self:_AoADeg2Units(playerData, aoa), UTILS.MpsToKnots(vabs)) if self.Debug then -- Velocity vector. text=text..string.format("\nVx=%.1f Vy=%.1f Vz=%.1f m/s", velo.x, velo.y, velo.z) --Wind vector. text=text..string.format("\nWind Vx=%.1f Vy=%.1f Vz=%.1f m/s", wind.x, wind.y, wind.z) end - text=text..string.format("\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°", pitch, roll, yaw) - text=text..string.format("\nClimb Angle=%.1f° | Rate=%d ft/min", unit:GetClimbAngle(), velo.y*196.85) + text=text..string.format("\nPitch=%.1f | Roll=%.1f | Yaw=%.1f", pitch, roll, yaw) + text=text..string.format("\nClimb Angle=%.1f | Rate=%d ft/min", unit:GetClimbAngle(), velo.y*196.85) local dist=self:_GetOptLandingCoordinate():Get3DDistance(playerData.unit) -- Get player velocity in km/h. local vplayer=playerData.unit:GetVelocityKMH() @@ -11360,14 +11360,14 @@ function AIRBOSS:_AttitudeMonitor(playerData) playerData.step==AIRBOSS.PatternStep.GROOVE_IW then local lue=self:_Lineup(playerData.unit, true) local gle=self:_Glideslope(playerData.unit) - text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi) - text=text..string.format("\nLineUp=%.2f° | GlideSlope=%.2f° | AoA=%.1f Units", lue, gle, self:_AoADeg2Units(playerData, aoa)) + text=text..string.format("\nGamma=%.1f | Rho=%.1f", relhead, phi) + text=text..string.format("\nLineUp=%.2f | GlideSlope=%.2f | AoA=%.1f Units", lue, gle, self:_AoADeg2Units(playerData, aoa)) local grade, points, analysis=self:_LSOgrade(playerData) text=text..string.format("\nTgroove=%.1f sec", self:_GetTimeInGroove(playerData)) text=text..string.format("\nGrade: %s %.1f PT - %s", grade, points, analysis) else text=text..string.format("\nR=%.2f NM | X=%d Z=%d m", UTILS.MetersToNM(rho), dx, dz) - text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi) + text=text..string.format("\nGamma=%.1f | Rho=%.1f", relhead, phi) end MESSAGE:New(text, 1, nil , true):ToClient(playerData.client) @@ -12695,7 +12695,7 @@ function AIRBOSS:_PlayerHint(playerData, delay, soundoff) if self.holdingoffset<0 then turn="left" end - hint=hint..string.format("\nTurn %s and select TACAN %03d°.", turn, radial) + hint=hint..string.format("\nTurn %s and select TACAN %03d.", turn, radial) end end @@ -12704,7 +12704,7 @@ function AIRBOSS:_PlayerHint(playerData, delay, soundoff) if playerData.step==AIRBOSS.PatternStep.DIRTYUP then if playerData.difficulty==AIRBOSS.Difficulty.EASY then if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - hint=hint.."\nFAF! Checks completed. Nozzles 50°." + hint=hint.."\nFAF! Checks completed. Nozzles 50." else --TODO: Tomcat? hint=hint.."\nDirty up! Hook, gear and flaps down." @@ -12773,14 +12773,14 @@ function AIRBOSS:_StepHint(playerData, step) -- Late break. if step==AIRBOSS.PatternStep.LATEBREAK then if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then - hint=hint.."\nWing Sweep 20°, Gear DOWN < 280 KIAS." + hint=hint.."\nWing Sweep 20, Gear DOWN < 280 KIAS." end end -- Abeam. if step==AIRBOSS.PatternStep.ABEAM then if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - hint=hint.."\nNozzles 50°-60°. Antiskid OFF. Lights OFF." + hint=hint.."\nNozzles 50-60. Antiskid OFF. Lights OFF." elseif playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then hint=hint.."\nSlats/Flaps EXTENDED < 225 KIAS. DLC SELECTED. Auto Throttle IF DESIRED." else @@ -13215,7 +13215,7 @@ function AIRBOSS:_Debrief(playerData) end -- Re-enter message. - local text=string.format("fly heading %03d° for %d NM to re-enter the pattern.", heading, UTILS.MetersToNM(distance)) + local text=string.format("fly heading %03d for %d NM to re-enter the pattern.", heading, UTILS.MetersToNM(distance)) self:MessageToPlayer(playerData, text, "LSO", nil, nil, false, 5) else @@ -13411,9 +13411,9 @@ function AIRBOSS:_CheckCollisionCoord(coordto, coordfrom) local text="" if clear then - text=string.format("Path into direction %03d° is clear for the next %.1f NM.", direction, UTILS.MetersToNM(d)) + text=string.format("Path into direction %03d is clear for the next %.1f NM.", direction, UTILS.MetersToNM(d)) else - text=string.format("Detected obstacle at distance %.1f NM into direction %03d°.", UTILS.MetersToNM(d), direction) + text=string.format("Detected obstacle at distance %.1f NM into direction %03d.", UTILS.MetersToNM(d), direction) end self:T2(self.lid..text) @@ -13473,7 +13473,7 @@ function AIRBOSS:_Pathfinder() local collision=self:_CheckFreePathToNextWP(fromcoord) -- Debug info. - self:T2(self.lid..string.format("Pathfinder d=%.1f m, direction=%03d°, collision=%s", distance, direction, tostring(collision))) + self:T2(self.lid..string.format("Pathfinder d=%.1f m, direction=%03d, collision=%s", distance, direction, tostring(collision))) -- If path is clear, we start a little detour. if not collision then @@ -13907,7 +13907,7 @@ function AIRBOSS:_CheckPatternUpdate() -- Update if carrier moves by more than 2.5 NM. local Dupdate=UTILS.NMToMeters(2.5) - -- Update if carrier turned by more than 5°. + -- Update if carrier turned by more than 5. local Hupdate=5 ----------------------- @@ -13941,7 +13941,7 @@ function AIRBOSS:_CheckPatternUpdate() -- Check if orientation changed. local Hchange=false if math.abs(deltaHeading)>=Hupdate then - self:T(self.lid..string.format("Carrier heading changed by %d°.", deltaHeading)) + self:T(self.lid..string.format("Carrier heading changed by %d.", deltaHeading)) Hchange=true end @@ -15642,7 +15642,7 @@ end function AIRBOSS:_MarshalCallNewFinalBearing(FB) -- Subtitle. - local text=string.format("new final bearing %03d°.", FB) + local text=string.format("new final bearing %03d.", FB) -- Debug message. self:I(self.lid..text) @@ -15665,7 +15665,7 @@ end function AIRBOSS:_MarshalCallCarrierTurnTo(hdg) -- Subtitle. - local text=string.format("carrier is now starting turn to heading %03d°.", hdg) + local text=string.format("carrier is now starting turn to heading %03d.", hdg) -- Debug message. self:I(self.lid..text) @@ -15718,11 +15718,11 @@ function AIRBOSS:_MarshalCallRecoveryStart(case) -- Debug output. local text=string.format("Starting aircraft recovery Case %d ops.", case) if case==1 then - text=text..string.format(" BRC %03d°.", self:GetBRC()) + text=text..string.format(" BRC %03d.", self:GetBRC()) elseif case==2 then - text=text..string.format(" Marshal radial %03d°. BRC %03d°.", radial, self:GetBRC()) + text=text..string.format(" Marshal radial %03d. BRC %03d.", radial, self:GetBRC()) elseif case==3 then - text=text..string.format(" Marshal radial %03d°. Final heading %03d°.", radial, self:GetFinalBearing(false)) + text=text..string.format(" Marshal radial %03d. Final heading %03d.", radial, self:GetFinalBearing(false)) end self:T(self.lid..text) @@ -15767,7 +15767,7 @@ function AIRBOSS:_MarshalCallArrived(modex, case, brc, altitude, charlie, qfe) local CT=UTILS.Split(clock[1], ":") -- Subtitle text. - local text=string.format("Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe) + local text=string.format("Case %d, expected BRC %03d, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe) -- Debug message. self:I(self.lid..text) @@ -15944,11 +15944,11 @@ function AIRBOSS:_AddF10Commands(_unitName) missionCommands.addCommandForGroup(gid, "60 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 60) missionCommands.addCommandForGroup(gid, "90 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 90) local _menusetrtime=missionCommands.addSubMenuForGroup(gid, "Set Marshal Radial", _skipperPath) - missionCommands.addCommandForGroup(gid, "+30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 30) - missionCommands.addCommandForGroup(gid, "+15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 15) - missionCommands.addCommandForGroup(gid, "0°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0) - missionCommands.addCommandForGroup(gid, "-15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -15) - missionCommands.addCommandForGroup(gid, "-30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -30) + missionCommands.addCommandForGroup(gid, "+30", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 30) + missionCommands.addCommandForGroup(gid, "+15", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 15) + missionCommands.addCommandForGroup(gid, "0", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0) + missionCommands.addCommandForGroup(gid, "-15", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -15) + missionCommands.addCommandForGroup(gid, "-30", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -30) missionCommands.addCommandForGroup(gid, "U-turn On/Off", _skipperPath, self._SkipperRecoveryUturn, self, _unitName) missionCommands.addCommandForGroup(gid, "Start CASE I", _skipperPath, self._SkipperStartRecovery, self, _unitName, 1) missionCommands.addCommandForGroup(gid, "Start CASE II", _skipperPath, self._SkipperStartRecovery, self, _unitName, 2) @@ -16005,7 +16005,7 @@ function AIRBOSS:_SkipperStartRecovery(_unitName, case) -- Inform player. local text=string.format("affirm, Case %d recovery will start in 5 min for %d min. Wind on deck %d knots. U-turn=%s.", case, self.skipperTime, self.skipperSpeed, tostring(self.skipperUturn)) if case>1 then - text=text..string.format(" Marshal radial %d°.", self.skipperOffset) + text=text..string.format(" Marshal radial %d.", self.skipperOffset) end if self:IsRecovering() then text="negative, carrier is already recovering." @@ -16071,7 +16071,7 @@ function AIRBOSS:_SkipperRecoveryOffset(_unitName, offset) if playerData then -- Inform player. - local text=string.format("roger, relative CASE II/III Marshal radial set to %d°.", offset) + local text=string.format("roger, relative CASE II/III Marshal radial set to %d.", offset) self:MessageToPlayer(playerData, text, "AIRBOSS") self.skipperOffset=offset @@ -16534,7 +16534,7 @@ function AIRBOSS:_RequestCommence(_unitName) -- For case 1 we want the BRC but above routine return FB. radial=self:GetBRC() end - text=text..string.format("\nSelect TACAN %03d°, Channel %d%s (%s).\n", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) + text=text..string.format("\nSelect TACAN %03d, Channel %d%s (%s).\n", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) end -- TODO: Inform section members. @@ -17146,7 +17146,7 @@ function AIRBOSS:_DisplayCarrierInfo(_unitname) -- Only include current and future recovery windows. if Tabs1 then -- Get inverse magnetic radial potential offset. local radial=self:GetRadial(playerData.case, true, true, true) - stacktext=stacktext..string.format("Select TACAN %03d°, %d DME\n", radial, angels+15) + stacktext=stacktext..string.format("Select TACAN %03d, %d DME\n", radial, angels+15) end end @@ -17545,7 +17545,7 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName) local brc=self:GetBRC() -- Help player to find its way to the initial zone. - text=text..string.format("\nTo Initial: Fly heading %03d° for %.1f NM and turn to BRC %03d°", flyhdg, flydist, brc) + text=text..string.format("\nTo Initial: Fly heading %03d for %.1f NM and turn to BRC %03d", flyhdg, flydist, brc) elseif playerData.step==AIRBOSS.PatternStep.PLATFORM then @@ -17560,7 +17560,7 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName) local hdg=self:GetRadial(playerData.case, true, true, true) -- Help player to find its way to the initial zone. - text=text..string.format("\nTo Platform: Fly heading %03d° for %.1f NM and turn to %03d°", flyhdg, flydist, hdg) + text=text..string.format("\nTo Platform: Fly heading %03d for %.1f NM and turn to %03d", flyhdg, flydist, hdg) end diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index b4daaaaed..c452c652c 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -22,7 +22,7 @@ -- @module Ops.CSAR -- @image OPS_CSAR.jpg --- Date: July 2021 +-- Date: Aug 2021 ------------------------------------------------------------------------- --- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM @@ -233,7 +233,7 @@ CSAR.AircraftType["Mi-24V"] = 8 --- CSAR class version. -- @field #string version -CSAR.version="0.1.10r2" +CSAR.version="0.1.10r3" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -1337,7 +1337,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname, isairport) end --queue up - self:__Returning(-5,heliname,_woundedGroupName) + self:__Returning(-5,heliname,_woundedGroupName, isairport) return self end @@ -2058,9 +2058,10 @@ end -- @param #string To To state. -- @param #string Heliname Name of the helicopter group. -- @param #string Woundedgroupname Name of the downed pilot\'s group. -function CSAR:onbeforeReturning(From, Event, To, Heliname, Woundedgroupname) +-- @param #boolean IsAirport True if heli has landed on an AFB (from event land). +function CSAR:onbeforeReturning(From, Event, To, Heliname, Woundedgroupname, IsAirPort) self:T({From, Event, To, Heliname, Woundedgroupname}) - self:_ScheduledSARFlight(Heliname,Woundedgroupname) + self:_ScheduledSARFlight(Heliname,Woundedgroupname, IsAirPort) return self end From c55b8d29f7fc6d77772b914a74585277ae23dda3 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Wed, 18 Aug 2021 11:51:41 +0200 Subject: [PATCH 14/17] Fix for degree sign extra char --- Moose Development/Moose/Functional/Fox.lua | 10 +++++----- .../Moose/Functional/PseudoATC.lua | 8 ++++---- Moose Development/Moose/Functional/Range.lua | 18 +++++++++--------- .../Moose/Tasking/DetectionManager.lua | 2 +- .../Moose/Tasking/Task_Cargo_Dispatcher.lua | 2 +- Moose Development/Moose/Utilities/Utils.lua | 14 +++++++------- Moose Development/Moose/Wrapper/Airbase.lua | 6 +++--- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Moose Development/Moose/Functional/Fox.lua b/Moose Development/Moose/Functional/Fox.lua index 5c5ec9f20..56dd5f51f 100644 --- a/Moose Development/Moose/Functional/Fox.lua +++ b/Moose Development/Moose/Functional/Fox.lua @@ -791,7 +791,7 @@ function FOX:onafterMissileLaunch(From, Event, To, missile) if (missile.targetPlayer and player.unitname==missile.targetPlayer.unitname) or (distance idx="07". +-- @field #string idx Runway ID: heading 070 ==> idx="07". -- @field #number length Length of runway in meters. -- @field Core.Point#COORDINATE position Position of runway start. -- @field Core.Point#COORDINATE endpoint End point of runway. @@ -1532,7 +1532,7 @@ function AIRBASE:GetRunwayData(magvar, mark) -- Heading of runway. local hdg=c1:HeadingTo(c2) - -- Runway ID: heading=070° ==> idx="07" + -- Runway ID: heading=070 ==> idx="07" local idx=string.format("%02d", UTILS.Round((hdg-magvar)/10, 0)) -- Runway table. @@ -1610,7 +1610,7 @@ function AIRBASE:GetActiveRunway(magvar) local dot=UTILS.VecDot(Vwind, Vrunway) -- Debug. - --env.info(string.format("runway=%03d° dot=%.3f", runway.heading, dot)) + --env.info(string.format("runway=%03d dot=%.3f", runway.heading, dot)) -- New min? if dotmin==nil or dot Date: Wed, 18 Aug 2021 14:59:58 +0200 Subject: [PATCH 15/17] Fix for SAM pattern matching not working --- Moose Development/Moose/Functional/Sead.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Moose Development/Moose/Functional/Sead.lua b/Moose Development/Moose/Functional/Sead.lua index c99e1f241..008b9ae01 100644 --- a/Moose Development/Moose/Functional/Sead.lua +++ b/Moose Development/Moose/Functional/Sead.lua @@ -92,7 +92,7 @@ function SEAD:New( SEADGroupPrefixes ) end self:HandleEvent( EVENTS.Shot, self.HandleEventShot ) - self:I("*** SEAD - Started Version 0.2.8") + self:I("*** SEAD - Started Version 0.2.9") return self end @@ -102,7 +102,7 @@ end -- @return #SEAD self function SEAD:UpdateSet( SEADGroupPrefixes ) - self:F( SEADGroupPrefixes ) + self:T( SEADGroupPrefixes ) if type( SEADGroupPrefixes ) == 'table' then for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do @@ -120,7 +120,7 @@ end -- @param #number range Set the engagement range in percent, e.g. 50 -- @return self function SEAD:SetEngagementRange(range) - self:F( { range } ) + self:T( { range } ) range = range or 75 if range < 0 or range > 100 then range = 75 @@ -135,7 +135,7 @@ end -- @param #string WeaponName -- @return #boolean Returns true for a match function SEAD:_CheckHarms(WeaponName) - self:F( { WeaponName } ) + self:T( { WeaponName } ) local hit = false for _,_name in pairs (SEAD.Harms) do if string.find(WeaponName,_name,1) then hit = true end @@ -166,7 +166,7 @@ function SEAD:HandleEventShot( EventData ) local _targetUnit = UNIT:Find(_targetMim) -- Unit name by DCS Object if _targetUnit and _targetUnit:IsAlive() then local _targetMimgroup = _targetUnit:GetGroup() - local _targetMimgroupName = _targetMimgroup:GetName() -- group name + _targetMimgroupName = _targetMimgroup:GetName() -- group name --local _targetskill = _DATABASE.Templates.Units[_targetUnit].Template.skill self:T( self.SEADGroupPrefixes ) self:T( _targetMimgroupName ) @@ -174,6 +174,7 @@ function SEAD:HandleEventShot( EventData ) -- see if we are shot at local SEADGroupFound = false for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do + self:T( SEADGroupPrefix ) if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then SEADGroupFound = true self:T( '*** SEAD - Group Found' ) From 830f76e90997e21212150a50010d4a69fb5e6747 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Wed, 18 Aug 2021 18:00:38 +0200 Subject: [PATCH 16/17] Cleanup UTF-8 Mess --- .../Moose/AI/AI_A2A_Dispatcher.lua | 10 +- Moose Development/Moose/Functional/Fox.lua | 10 +- Moose Development/Moose/Functional/Mantis.lua | 2 +- .../Moose/Functional/MissileTrainer.lua | 2 +- .../Moose/Functional/PseudoATC.lua | 8 +- Moose Development/Moose/Functional/RAT.lua | 2 +- Moose Development/Moose/Functional/Range.lua | 18 ++-- Moose Development/Moose/Ops/ATIS.lua | 60 ++++++------ Moose Development/Moose/Ops/Airboss.lua | 98 +++++++++---------- Moose Development/Moose/Sound/RadioSpeech.lua | 36 +++---- .../Moose/Tasking/DetectionManager.lua | 2 +- .../Moose/Tasking/Task_Cargo_Dispatcher.lua | 2 +- Moose Development/Moose/Utilities/Utils.lua | 12 +-- Moose Development/Moose/Wrapper/Airbase.lua | 6 +- 14 files changed, 134 insertions(+), 134 deletions(-) diff --git a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua index b7b3b641a..7b03c5692 100644 --- a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua @@ -3477,7 +3477,7 @@ do -- AI_A2A_DISPATCHER if Squadron.Language == "EN" and self.SetSendPlayerMessages then Dispatcher:MessageToPlayers( Squadron, DefenderName .. " wheels up.", DefenderGroup ) elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then - Dispatcher:MessageToPlayers( Squadron, DefenderName .. " колеÑ�а вверх.", DefenderGroup ) + Dispatcher:MessageToPlayers( Squadron, DefenderName .. " колёса вверх.", DefenderGroup ) end --Fsm:__Engage( 2, DefenderTarget.Set ) -- Engage on the TargetSetUnit Fsm:EngageRoute( DefenderTarget.Set ) -- Engage on the TargetSetUnit @@ -3498,7 +3498,7 @@ do -- AI_A2A_DISPATCHER if Squadron.Language == "EN" and self.SetSendPlayerMessages then Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", intercepting bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup ) elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then - Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", перехват Ñ�амолетов в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup ) + Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", перехватывая боги в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup ) elseif Squadron.Language == "DE" and self.SetSendPlayerMessages then Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", Eindringlinge abfangen bei" .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup ) end @@ -3520,7 +3520,7 @@ do -- AI_A2A_DISPATCHER if Squadron.Language == "EN" and self.SetSendPlayerMessages then Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup ) elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then - Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", захватывающие Ñ�амолеты в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup ) + Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", задействуя боги в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup ) end end self:GetParent( Fsm ).onafterEngage( self, DefenderGroup, From, Event, To, AttackSetUnit ) @@ -3538,7 +3538,7 @@ do -- AI_A2A_DISPATCHER if Squadron.Language == "EN" and self.SetSendPlayerMessages then Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup ) elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then - Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", возвращаÑ�Ñ�ÑŒ на базу.", DefenderGroup ) + Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", возвращение на базу.", DefenderGroup ) end end Dispatcher:ClearDefenderTaskTarget( DefenderGroup ) @@ -3569,7 +3569,7 @@ do -- AI_A2A_DISPATCHER if Squadron.Language == "EN" and self.SetSendPlayerMessages then Dispatcher:MessageToPlayers( Squadron, DefenderName .. " landing at base.", DefenderGroup ) elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then - Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", захватывающие Ñ�амолеты в поÑ�адка на базу.", DefenderGroup ) + Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", посадка на базу.", DefenderGroup ) end if Action and Action == "Destroy" then diff --git a/Moose Development/Moose/Functional/Fox.lua b/Moose Development/Moose/Functional/Fox.lua index 56dd5f51f..efcdc99a5 100644 --- a/Moose Development/Moose/Functional/Fox.lua +++ b/Moose Development/Moose/Functional/Fox.lua @@ -791,7 +791,7 @@ function FOX:onafterMissileLaunch(From, Event, To, missile) if (missile.targetPlayer and player.unitname==missile.targetPlayer.unitname) or (distance0, at a distance of ~1 NM. --- At the beginning of the groove (X), he significantly overshoots to the starboard side (LUE<5). +-- The pilot approaches the carrier from the port side, LUE>0°, at a distance of ~1 NM. +-- At the beginning of the groove (X), he significantly overshoots to the starboard side (LUE<5°). -- In the middle (IM), he performs good corrections and smoothly reduces the lineup error. --- Finally, at a distance of ~0.3 NM (IC) he has corrected his lineup with the runway to a reasonable level, |LUE|<0.5. +-- Finally, at a distance of ~0.3 NM (IC) he has corrected his lineup with the runway to a reasonable level, |LUE|<0.5°. -- -- ## Glideslope Error -- @@ -876,7 +876,7 @@ -- The graph displays the glideslope error (GSE) as a function of the distance to the carrier. -- -- In this case the pilot already enters the groove (X) below the optimal glideslope. He is not able to correct his height in the IM part and --- stays significantly too low. In close, he performs a harsh correction to gain altitude and ends up even slightly too high (GSE>0.5). +-- stays significantly too low. In close, he performs a harsh correction to gain altitude and ends up even slightly too high (GSE>0.5°). -- At his point further corrections are necessary. -- -- ## Angle of Attack @@ -2438,7 +2438,7 @@ end -- @param #number duration Default duration of the recovery in minutes. Default 30 min. -- @param #number windondeck Default wind on deck in knots. Default 25 knots. -- @param #boolean uturn U-turn after recovery window closes on=true or off=false/nil. Default off. --- @param #number offset Relative Marshal radial in degrees for Case II/III recoveries. Default 30. +-- @param #number offset Relative Marshal radial in degrees for Case II/III recoveries. Default 30°. -- @return #AIRBOSS self function AIRBOSS:SetMenuRecovery(duration, windondeck, uturn, offset) @@ -3878,7 +3878,7 @@ function AIRBOSS:_CheckRecoveryTimes() -- Check if time is less than 5 minutes. if nextwindow.WIND and nextwindow.START-time 5 different from the current heading. + -- Check that wind is blowing from a direction > 5° different from the current heading. local hdg=self:GetHeading() local wind=self:GetHeadingIntoWind() local delta=self:_GetDeltaHeading(hdg, wind) @@ -3896,7 +3896,7 @@ function AIRBOSS:_CheckRecoveryTimes() end --Debug info - self:T(self.lid..string.format("Heading=%03d, Wind=%03d %.1f kts, Delta=%03d ==> U-turn=%s", hdg, wind,UTILS.MpsToKnots(vwind), delta, tostring(uturn))) + self:T(self.lid..string.format("Heading=%03d°, Wind=%03d° %.1f kts, Delta=%03d° ==> U-turn=%s", hdg, wind,UTILS.MpsToKnots(vwind), delta, tostring(uturn))) -- Time into the wind 1 day or if longer recovery time + the 5 min early. local t=math.max(nextwindow.STOP-nextwindow.START+self.dTturn, 60*60*24) @@ -6933,7 +6933,7 @@ function AIRBOSS:_AddMarshalGroup(flight, stack) -- For case 1 we want the BRC but above routine return FB. radial=self:GetBRC() end - local text=string.format("Select TACAN %03d, channel %d%s (%s)", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) + local text=string.format("Select TACAN %03d°, channel %d%s (%s)", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) self:MessageToPlayer(flight, text, nil, "") end @@ -9346,7 +9346,7 @@ function AIRBOSS:_Initial(playerData) -- Hook down for students. if playerData.difficulty==AIRBOSS.Difficulty.EASY and playerData.actype~=AIRBOSS.AircraftCarrier.AV8B then if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then - hint=hint.." - Hook down, SAS on, Wing Sweep 68!" + hint=hint.." - Hook down, SAS on, Wing Sweep 68°!" else hint=hint.." - Hook down!" end @@ -11331,15 +11331,15 @@ function AIRBOSS:_AttitudeMonitor(playerData) -- Output local text=string.format("Pattern step: %s", step) - text=text..string.format("\nAoA=%.1f = %.1f Units | |V|=%.1f knots", aoa, self:_AoADeg2Units(playerData, aoa), UTILS.MpsToKnots(vabs)) + text=text..string.format("\nAoA=%.1f° = %.1f Units | |V|=%.1f knots", aoa, self:_AoADeg2Units(playerData, aoa), UTILS.MpsToKnots(vabs)) if self.Debug then -- Velocity vector. text=text..string.format("\nVx=%.1f Vy=%.1f Vz=%.1f m/s", velo.x, velo.y, velo.z) --Wind vector. text=text..string.format("\nWind Vx=%.1f Vy=%.1f Vz=%.1f m/s", wind.x, wind.y, wind.z) end - text=text..string.format("\nPitch=%.1f | Roll=%.1f | Yaw=%.1f", pitch, roll, yaw) - text=text..string.format("\nClimb Angle=%.1f | Rate=%d ft/min", unit:GetClimbAngle(), velo.y*196.85) + text=text..string.format("\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°", pitch, roll, yaw) + text=text..string.format("\nClimb Angle=%.1f° | Rate=%d ft/min", unit:GetClimbAngle(), velo.y*196.85) local dist=self:_GetOptLandingCoordinate():Get3DDistance(playerData.unit) -- Get player velocity in km/h. local vplayer=playerData.unit:GetVelocityKMH() @@ -11360,14 +11360,14 @@ function AIRBOSS:_AttitudeMonitor(playerData) playerData.step==AIRBOSS.PatternStep.GROOVE_IW then local lue=self:_Lineup(playerData.unit, true) local gle=self:_Glideslope(playerData.unit) - text=text..string.format("\nGamma=%.1f | Rho=%.1f", relhead, phi) - text=text..string.format("\nLineUp=%.2f | GlideSlope=%.2f | AoA=%.1f Units", lue, gle, self:_AoADeg2Units(playerData, aoa)) + text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi) + text=text..string.format("\nLineUp=%.2f° | GlideSlope=%.2f° | AoA=%.1f Units", lue, gle, self:_AoADeg2Units(playerData, aoa)) local grade, points, analysis=self:_LSOgrade(playerData) text=text..string.format("\nTgroove=%.1f sec", self:_GetTimeInGroove(playerData)) text=text..string.format("\nGrade: %s %.1f PT - %s", grade, points, analysis) else text=text..string.format("\nR=%.2f NM | X=%d Z=%d m", UTILS.MetersToNM(rho), dx, dz) - text=text..string.format("\nGamma=%.1f | Rho=%.1f", relhead, phi) + text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi) end MESSAGE:New(text, 1, nil , true):ToClient(playerData.client) @@ -12695,7 +12695,7 @@ function AIRBOSS:_PlayerHint(playerData, delay, soundoff) if self.holdingoffset<0 then turn="left" end - hint=hint..string.format("\nTurn %s and select TACAN %03d.", turn, radial) + hint=hint..string.format("\nTurn %s and select TACAN %03d°.", turn, radial) end end @@ -12704,7 +12704,7 @@ function AIRBOSS:_PlayerHint(playerData, delay, soundoff) if playerData.step==AIRBOSS.PatternStep.DIRTYUP then if playerData.difficulty==AIRBOSS.Difficulty.EASY then if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - hint=hint.."\nFAF! Checks completed. Nozzles 50." + hint=hint.."\nFAF! Checks completed. Nozzles 50°." else --TODO: Tomcat? hint=hint.."\nDirty up! Hook, gear and flaps down." @@ -12773,14 +12773,14 @@ function AIRBOSS:_StepHint(playerData, step) -- Late break. if step==AIRBOSS.PatternStep.LATEBREAK then if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then - hint=hint.."\nWing Sweep 20, Gear DOWN < 280 KIAS." + hint=hint.."\nWing Sweep 20°, Gear DOWN < 280 KIAS." end end -- Abeam. if step==AIRBOSS.PatternStep.ABEAM then if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - hint=hint.."\nNozzles 50-60. Antiskid OFF. Lights OFF." + hint=hint.."\nNozzles 50°-60°. Antiskid OFF. Lights OFF." elseif playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then hint=hint.."\nSlats/Flaps EXTENDED < 225 KIAS. DLC SELECTED. Auto Throttle IF DESIRED." else @@ -13215,7 +13215,7 @@ function AIRBOSS:_Debrief(playerData) end -- Re-enter message. - local text=string.format("fly heading %03d for %d NM to re-enter the pattern.", heading, UTILS.MetersToNM(distance)) + local text=string.format("fly heading %03d° for %d NM to re-enter the pattern.", heading, UTILS.MetersToNM(distance)) self:MessageToPlayer(playerData, text, "LSO", nil, nil, false, 5) else @@ -13411,9 +13411,9 @@ function AIRBOSS:_CheckCollisionCoord(coordto, coordfrom) local text="" if clear then - text=string.format("Path into direction %03d is clear for the next %.1f NM.", direction, UTILS.MetersToNM(d)) + text=string.format("Path into direction %03d° is clear for the next %.1f NM.", direction, UTILS.MetersToNM(d)) else - text=string.format("Detected obstacle at distance %.1f NM into direction %03d.", UTILS.MetersToNM(d), direction) + text=string.format("Detected obstacle at distance %.1f NM into direction %03d°.", UTILS.MetersToNM(d), direction) end self:T2(self.lid..text) @@ -13473,7 +13473,7 @@ function AIRBOSS:_Pathfinder() local collision=self:_CheckFreePathToNextWP(fromcoord) -- Debug info. - self:T2(self.lid..string.format("Pathfinder d=%.1f m, direction=%03d, collision=%s", distance, direction, tostring(collision))) + self:T2(self.lid..string.format("Pathfinder d=%.1f m, direction=%03d°, collision=%s", distance, direction, tostring(collision))) -- If path is clear, we start a little detour. if not collision then @@ -13907,7 +13907,7 @@ function AIRBOSS:_CheckPatternUpdate() -- Update if carrier moves by more than 2.5 NM. local Dupdate=UTILS.NMToMeters(2.5) - -- Update if carrier turned by more than 5. + -- Update if carrier turned by more than 5°. local Hupdate=5 ----------------------- @@ -13941,7 +13941,7 @@ function AIRBOSS:_CheckPatternUpdate() -- Check if orientation changed. local Hchange=false if math.abs(deltaHeading)>=Hupdate then - self:T(self.lid..string.format("Carrier heading changed by %d.", deltaHeading)) + self:T(self.lid..string.format("Carrier heading changed by %d°.", deltaHeading)) Hchange=true end @@ -15642,7 +15642,7 @@ end function AIRBOSS:_MarshalCallNewFinalBearing(FB) -- Subtitle. - local text=string.format("new final bearing %03d.", FB) + local text=string.format("new final bearing %03d°.", FB) -- Debug message. self:I(self.lid..text) @@ -15665,7 +15665,7 @@ end function AIRBOSS:_MarshalCallCarrierTurnTo(hdg) -- Subtitle. - local text=string.format("carrier is now starting turn to heading %03d.", hdg) + local text=string.format("carrier is now starting turn to heading %03d°.", hdg) -- Debug message. self:I(self.lid..text) @@ -15718,11 +15718,11 @@ function AIRBOSS:_MarshalCallRecoveryStart(case) -- Debug output. local text=string.format("Starting aircraft recovery Case %d ops.", case) if case==1 then - text=text..string.format(" BRC %03d.", self:GetBRC()) + text=text..string.format(" BRC %03d°.", self:GetBRC()) elseif case==2 then - text=text..string.format(" Marshal radial %03d. BRC %03d.", radial, self:GetBRC()) + text=text..string.format(" Marshal radial %03d°. BRC %03d°.", radial, self:GetBRC()) elseif case==3 then - text=text..string.format(" Marshal radial %03d. Final heading %03d.", radial, self:GetFinalBearing(false)) + text=text..string.format(" Marshal radial %03d°. Final heading %03d°.", radial, self:GetFinalBearing(false)) end self:T(self.lid..text) @@ -15767,7 +15767,7 @@ function AIRBOSS:_MarshalCallArrived(modex, case, brc, altitude, charlie, qfe) local CT=UTILS.Split(clock[1], ":") -- Subtitle text. - local text=string.format("Case %d, expected BRC %03d, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe) + local text=string.format("Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe) -- Debug message. self:I(self.lid..text) @@ -15944,11 +15944,11 @@ function AIRBOSS:_AddF10Commands(_unitName) missionCommands.addCommandForGroup(gid, "60 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 60) missionCommands.addCommandForGroup(gid, "90 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 90) local _menusetrtime=missionCommands.addSubMenuForGroup(gid, "Set Marshal Radial", _skipperPath) - missionCommands.addCommandForGroup(gid, "+30", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 30) - missionCommands.addCommandForGroup(gid, "+15", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 15) - missionCommands.addCommandForGroup(gid, "0", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0) - missionCommands.addCommandForGroup(gid, "-15", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -15) - missionCommands.addCommandForGroup(gid, "-30", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -30) + missionCommands.addCommandForGroup(gid, "+30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 30) + missionCommands.addCommandForGroup(gid, "+15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 15) + missionCommands.addCommandForGroup(gid, "0°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0) + missionCommands.addCommandForGroup(gid, "-15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -15) + missionCommands.addCommandForGroup(gid, "-30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -30) missionCommands.addCommandForGroup(gid, "U-turn On/Off", _skipperPath, self._SkipperRecoveryUturn, self, _unitName) missionCommands.addCommandForGroup(gid, "Start CASE I", _skipperPath, self._SkipperStartRecovery, self, _unitName, 1) missionCommands.addCommandForGroup(gid, "Start CASE II", _skipperPath, self._SkipperStartRecovery, self, _unitName, 2) @@ -16005,7 +16005,7 @@ function AIRBOSS:_SkipperStartRecovery(_unitName, case) -- Inform player. local text=string.format("affirm, Case %d recovery will start in 5 min for %d min. Wind on deck %d knots. U-turn=%s.", case, self.skipperTime, self.skipperSpeed, tostring(self.skipperUturn)) if case>1 then - text=text..string.format(" Marshal radial %d.", self.skipperOffset) + text=text..string.format(" Marshal radial %d°.", self.skipperOffset) end if self:IsRecovering() then text="negative, carrier is already recovering." @@ -16071,7 +16071,7 @@ function AIRBOSS:_SkipperRecoveryOffset(_unitName, offset) if playerData then -- Inform player. - local text=string.format("roger, relative CASE II/III Marshal radial set to %d.", offset) + local text=string.format("roger, relative CASE II/III Marshal radial set to %d°.", offset) self:MessageToPlayer(playerData, text, "AIRBOSS") self.skipperOffset=offset @@ -16534,7 +16534,7 @@ function AIRBOSS:_RequestCommence(_unitName) -- For case 1 we want the BRC but above routine return FB. radial=self:GetBRC() end - text=text..string.format("\nSelect TACAN %03d, Channel %d%s (%s).\n", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) + text=text..string.format("\nSelect TACAN %03d°, Channel %d%s (%s).\n", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) end -- TODO: Inform section members. @@ -17146,7 +17146,7 @@ function AIRBOSS:_DisplayCarrierInfo(_unitname) -- Only include current and future recovery windows. if Tabs1 then -- Get inverse magnetic radial potential offset. local radial=self:GetRadial(playerData.case, true, true, true) - stacktext=stacktext..string.format("Select TACAN %03d, %d DME\n", radial, angels+15) + stacktext=stacktext..string.format("Select TACAN %03d°, %d DME\n", radial, angels+15) end end @@ -17545,7 +17545,7 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName) local brc=self:GetBRC() -- Help player to find its way to the initial zone. - text=text..string.format("\nTo Initial: Fly heading %03d for %.1f NM and turn to BRC %03d", flyhdg, flydist, brc) + text=text..string.format("\nTo Initial: Fly heading %03d° for %.1f NM and turn to BRC %03d°", flyhdg, flydist, brc) elseif playerData.step==AIRBOSS.PatternStep.PLATFORM then @@ -17560,7 +17560,7 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName) local hdg=self:GetRadial(playerData.case, true, true, true) -- Help player to find its way to the initial zone. - text=text..string.format("\nTo Platform: Fly heading %03d for %.1f NM and turn to %03d", flyhdg, flydist, hdg) + text=text..string.format("\nTo Platform: Fly heading %03d° for %.1f NM and turn to %03d°", flyhdg, flydist, hdg) end diff --git a/Moose Development/Moose/Sound/RadioSpeech.lua b/Moose Development/Moose/Sound/RadioSpeech.lua index f77c446a2..d16b92706 100644 --- a/Moose Development/Moose/Sound/RadioSpeech.lua +++ b/Moose Development/Moose/Sound/RadioSpeech.lua @@ -162,33 +162,33 @@ RADIOSPEECH.Vocabulary.RU = { ["8000"] = { "8000", 0.92 }, ["9000"] = { "9000", 0.87 }, - ["Ñ�тепени"] = { "degrees", 0.5 }, - ["километров"] = { "kilometers", 0.65 }, + ["градусы"] = { "degrees", 0.5 }, + ["километры"] = { "kilometers", 0.65 }, ["km"] = { "kilometers", 0.65 }, - ["миль"] = { "miles", 0.45 }, + ["мили"] = { "miles", 0.45 }, ["mi"] = { "miles", 0.45 }, - ["метры"] = { "meters", 0.41 }, + ["метров"] = { "meters", 0.41 }, ["m"] = { "meters", 0.41 }, - ["ноги"] = { "feet", 0.37 }, + ["ноги"] = { "feet", 0.37 }, ["br"] = { "br", 1.1 }, ["bra"] = { "bra", 0.3 }, - ["возвращаÑ�Ñ�ÑŒ на базу"] = { "returning_to_base", 1.40 }, - ["на пути к наземной цели"] = { "on_route_to_ground_target", 1.45 }, - ["перехват Ñ�амолетов"] = { "intercepting_bogeys", 1.22 }, - ["поражение наземной цели"] = { "engaging_ground_target", 1.53 }, - ["захватывающие Ñ�амолеты"] = { "engaging_bogeys", 1.68 }, - ["колеÑ�а вверх"] = { "wheels_up", 0.92 }, - ["поÑ�адка на базу"] = { "landing at base", 1.04 }, - ["патрулирующий"] = { "patrolling", 0.96 }, + ["возвращение на базу"] = { "returning_to_base", 1.40 }, + ["на пути к наземной цели"] = { "on_route_to_ground_target", 1.45 }, + ["перехват боги"] = { "intercepting_bogeys", 1.22 }, + ["поражение наземной цели"] = { "engaging_ground_target", 1.53 }, + ["привлечение болотных птиц"] = { "engaging_bogeys", 1.68 }, + ["колёса вверх..."] = { "wheels_up", 0.92 }, + ["посадка на базу"] = { "landing at base", 1.04 }, + ["патрулирование"] = { "patrolling", 0.96 }, - ["за"] = { "for", 0.27 }, - ["и"] = { "and", 0.17 }, - ["в"] = { "at", 0.19 }, - ["dot"] = { "dot", 0.51 }, - ["defender"] = { "defender", 0.45 }, + ["для"] = { "for", 0.27 }, + ["и"] = { "and", 0.17 }, + ["на сайте"] = { "at", 0.19 }, + ["точка"] = { "dot", 0.51 }, + ["защитник"] = { "defender", 0.45 }, } --- Create a new RADIOSPEECH object for a given radio frequency/modulation. diff --git a/Moose Development/Moose/Tasking/DetectionManager.lua b/Moose Development/Moose/Tasking/DetectionManager.lua index 2e0a3e148..3e16fad29 100644 --- a/Moose Development/Moose/Tasking/DetectionManager.lua +++ b/Moose Development/Moose/Tasking/DetectionManager.lua @@ -286,7 +286,7 @@ do -- DETECTION MANAGER self.CC:MessageToCoalition( Message ) end - Message = Message:gsub( "", " degrees " ) + Message = Message:gsub( "°", " degrees " ) Message = Message:gsub( "(%d)%.(%d)", "%1 dot %2" ) -- Here we handle the transmission of the voice over. diff --git a/Moose Development/Moose/Tasking/Task_Cargo_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_Cargo_Dispatcher.lua index 50fd4b86f..6833f197c 100644 --- a/Moose Development/Moose/Tasking/Task_Cargo_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_Cargo_Dispatcher.lua @@ -574,7 +574,7 @@ do -- TASK_CARGO_DISPATCHER -- local Coordinate = PlaneUnit:GetPointVec2() -- TaskA2ADispatcher:AddCSARTask( "CSAR Task", Coordinate ) -- - -- -- Add a CSAR task to rescue a downed pilot from within a coordinate of country RUSSIA, which is pointing to the west (270). + -- -- Add a CSAR task to rescue a downed pilot from within a coordinate of country RUSSIA, which is pointing to the west (270°). -- local Coordinate = PlaneUnit:GetPointVec2() -- TaskA2ADispatcher:AddCSARTask( "CSAR Task", Coordinate, 270, Country.RUSSIA ) -- diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 7f090c243..1b54ab17a 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -507,9 +507,9 @@ UTILS.tostringLL = function( lat, lon, acc, DMS) secFrmtStr = '%0' .. width .. '.' .. acc .. 'f' end - -- 024 23' 12"N or 024 23' 12.03"N - return string.format('%03d', latDeg)..string.format('%02d', latMin)..'\''..string.format(secFrmtStr, latSec)..'"'..latHemi..' ' - .. string.format('%03d', lonDeg)..string.format('%02d', lonMin)..'\''..string.format(secFrmtStr, lonSec)..'"'..lonHemi + -- 024° 23' 12"N or 024° 23' 12.03"N + return string.format('%03d°', latDeg)..string.format('%02d', latMin)..'\''..string.format(secFrmtStr, latSec)..'"'..latHemi..' ' + .. string.format('%03d°', lonDeg)..string.format('%02d', lonMin)..'\''..string.format(secFrmtStr, lonSec)..'"'..lonHemi else -- degrees, decimal minutes. latMin = UTILS.Round(latMin, acc) @@ -534,8 +534,8 @@ UTILS.tostringLL = function( lat, lon, acc, DMS) end -- 024 23'N or 024 23.123'N - return string.format('%03d', latDeg) .. ' ' .. string.format(minFrmtStr, latMin) .. '\'' .. latHemi .. ' ' - .. string.format('%03d', lonDeg) .. ' ' .. string.format(minFrmtStr, lonMin) .. '\'' .. lonHemi + return string.format('%03d°', latDeg) .. ' ' .. string.format(minFrmtStr, latMin) .. '\'' .. latHemi .. ' ' + .. string.format('%03d°', lonDeg) .. ' ' .. string.format(minFrmtStr, lonMin) .. '\'' .. lonHemi end end @@ -923,7 +923,7 @@ function UTILS.RandomGaussian(x0, sigma, xmin, xmax, imax) local x1=math.random() local x2=math.random() - -- Transform to Gaussian exp(-(x-x0)/(2*sigma). + -- Transform to Gaussian exp(-(x-x0)°/(2*sigma°). r = math.sqrt(-2*sigma*sigma * math.log(x1)) * math.cos(2*math.pi * x2) + x0 i=i+1 diff --git a/Moose Development/Moose/Wrapper/Airbase.lua b/Moose Development/Moose/Wrapper/Airbase.lua index 0f63f197d..0d8387985 100644 --- a/Moose Development/Moose/Wrapper/Airbase.lua +++ b/Moose Development/Moose/Wrapper/Airbase.lua @@ -510,7 +510,7 @@ AIRBASE.TerminalType = { --- Runway data. -- @type AIRBASE.Runway -- @field #number heading Heading of the runway in degrees. --- @field #string idx Runway ID: heading 070 ==> idx="07". +-- @field #string idx Runway ID: heading 070° ==> idx="07". -- @field #number length Length of runway in meters. -- @field Core.Point#COORDINATE position Position of runway start. -- @field Core.Point#COORDINATE endpoint End point of runway. @@ -1532,7 +1532,7 @@ function AIRBASE:GetRunwayData(magvar, mark) -- Heading of runway. local hdg=c1:HeadingTo(c2) - -- Runway ID: heading=070 ==> idx="07" + -- Runway ID: heading=070° ==> idx="07" local idx=string.format("%02d", UTILS.Round((hdg-magvar)/10, 0)) -- Runway table. @@ -1610,7 +1610,7 @@ function AIRBASE:GetActiveRunway(magvar) local dot=UTILS.VecDot(Vwind, Vrunway) -- Debug. - --env.info(string.format("runway=%03d dot=%.3f", runway.heading, dot)) + --env.info(string.format("runway=%03d° dot=%.3f", runway.heading, dot)) -- New min? if dotmin==nil or dot Date: Fri, 20 Aug 2021 12:33:10 +0200 Subject: [PATCH 17/17] CTLD - added ability to spawn crates on ships --- Moose Development/Moose/Ops/CTLD.lua | 108 ++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 17 deletions(-) diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index b91663397..26547d2eb 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -22,7 +22,7 @@ -- @module Ops.CTLD -- @image OPS_CTLD.jpg --- Date: July 2021 +-- Date: Aug 2021 do ------------------------------------------------------ @@ -264,7 +264,7 @@ do -- Add zones for loading troops and crates and dropping, building crates -- -- -- Add a zone of type LOAD to our setup. Players can load troops and crates. --- -- "Loadzone" is the name of the zone from the ME. Players can load, if they are inside of the zone. +-- -- "Loadzone" is the name of the zone from the ME. Players can load, if they are inside the zone. -- -- Smoke and Flare color for this zone is blue, it is active (can be used) and has a radio beacon. -- my_ctld:AddCTLDZone("Loadzone",CTLD.CargoZoneType.LOAD,SMOKECOLOR.Blue,true,true) -- @@ -279,6 +279,13 @@ do -- -- my_ctld:AddCTLDZone("Movezone2",CTLD.CargoZoneType.MOVE,SMOKECOLOR.White,true,true) -- +-- -- Add a zone of type SHIP to our setup. Players can load troops and crates from this ship +-- -- "Tarawa" is the unitname (callsign) of the ship from the ME. Players can load, if they are inside the zone. +-- -- The ship is 240 meters long and 20 meters wide. +-- -- Note that smoke, flares, beacons don't work for this type of loadzone (yet). Also, you need to adjust +-- -- the max hover height to deck height plus 5 meters or so for loading to work. +-- -- When the ship is moving, forcing hoverload might not be a good idea. +-- my_ctld:AddCTLDZone("Tarawa",CTLD.CargoZoneType.SHIP,SMOKECOLOR.Blue,true,true,240,20) -- -- ## 2. Options -- @@ -511,11 +518,13 @@ CTLD = { -- @field #string name Name of Zone. -- @field #string color Smoke color for zone, e.g. SMOKECOLOR.Red. -- @field #boolean active Active or not. --- @field #string type Type of zone, i.e. load,drop,move +-- @field #string type Type of zone, i.e. load,drop,move,ship -- @field #boolean hasbeacon Create and run radio beacons if active. -- @field #table fmbeacon Beacon info as #CTLD.ZoneBeacon -- @field #table uhfbeacon Beacon info as #CTLD.ZoneBeacon -- @field #table vhfbeacon Beacon info as #CTLD.ZoneBeacon +-- @field #number shiplength For ships - length of ship +-- @field #number shipwidth For ships - width of ship --- Zone Type Info. -- @type CTLD.CargoZoneType @@ -523,6 +532,7 @@ CTLD.CargoZoneType = { LOAD = "load", DROP = "drop", MOVE = "move", + SHIP = "ship", } --- Buildable table info. @@ -557,7 +567,7 @@ CTLD.UnitTypes = { --- CTLD class version. -- @field #string version -CTLD.version="0.1.4r3" +CTLD.version="0.1.5a1" --- Instantiate a new CTLD. -- @param #CTLD self @@ -643,6 +653,7 @@ function CTLD:New(Coalition, Prefixes, Alias) self.pickupZones = {} self.dropOffZones = {} self.wpZones = {} + self.shipZones = {} -- Cargo self.Cargo_Crates = {} @@ -928,6 +939,9 @@ function CTLD:_LoadTroops(Group, Unit, Cargotype) local hoverload = self:CanHoverLoad(Unit) -- check if we are in LOAD zone local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) + if not inzone then + inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP) + end if not inzone then self:_SendMessage("You are not close enough to a logistics zone!", 10, false, Group) if not self.debug then return self end @@ -1186,8 +1200,13 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop) -- check if we are in LOAD zone local inzone = false local drop = drop or false + local ship = nil + local width = 20 if not drop then inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) + if not inzone then + inzone, ship, zone, distance, width = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP) + end else if self.dropcratesanywhere then -- #1570 inzone = true @@ -1233,18 +1252,33 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop) for i=1,50 do math.random(90,270) end - local rheading = math.floor(math.random(90,270) * heading + 1 / 360) + local rheading = math.floor(((math.random(90,270) * heading) + 1) / 360) if not IsHerc then rheading = rheading + 180 -- mirror for Helis end if rheading > 360 then rheading = rheading - 360 end -- catch > 360 local cratecoord = position:Translate(cratedistance,rheading) local cratevec2 = cratecoord:GetVec2() - self.CrateCounter = self.CrateCounter + 1 + self.CrateCounter = self.CrateCounter + 1 + if type(ship) == "string" then + self:T("Spawning on ship "..ship) + local Ship = UNIT:FindByName(ship) + local shipcoord = Ship:GetCoordinate() + local unitcoord = Unit:GetCoordinate() + local dist = shipcoord:Get2DDistance(unitcoord) + dist = dist - (20 + math.random(1,10)) + local width = width / 2 + local Offy = math.random(-width,width) + self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType("container_cargo","Cargos",country.id.GERMANY) + --:InitCoordinate(cratecoord) + :InitLinkToUnit(Ship,dist,Offy,0) + :Spawn(270,cratealias) + else self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType("container_cargo","Cargos",country.id.GERMANY) :InitCoordinate(cratecoord) + --:InitLinkToUnit(Unit,OffsetX,OffsetY,OffsetAngle) :Spawn(270,cratealias) - + end local templ = cargotype:GetTemplates() local sorte = cargotype:GetType() self.CargoCounter = self.CargoCounter +1 @@ -1482,9 +1516,10 @@ function CTLD:_UpdateUnitCargoMass(Unit) self:T(self.lid .. " _UpdateUnitCargoMass") local calculatedMass = self:_GetUnitCargoMass(Unit) Unit:SetUnitInternalCargo(calculatedMass) - local report = REPORT:New("Loadmaster report") - report:Add("Carrying " .. calculatedMass .. "Kg") - self:_SendMessage(report:Text(),10,false,Unit:GetGroup()) + --local report = REPORT:New("Loadmaster report") + --report:Add("Carrying " .. calculatedMass .. "Kg") + --self:_SendMessage(report:Text(),10,false,Unit:GetGroup()) + return self end --- (Internal) Function to list loaded cargo. @@ -1565,6 +1600,9 @@ function CTLD:_UnloadTroops(Group, Unit) -- check if we are in LOAD zone local droppingatbase = false local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) + if not inzone then + inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP) + end if inzone then droppingatbase = true end @@ -2141,6 +2179,8 @@ function CTLD:AddZone(Zone) table.insert(self.pickupZones,zone) elseif zone.type == CTLD.CargoZoneType.DROP then table.insert(self.dropOffZones,zone) + elseif zone.type == CTLD.CargoZoneType.SHIP then + table.insert(self.shipZones,zone) else table.insert(self.wpZones,zone) end @@ -2166,6 +2206,8 @@ function CTLD:ActivateZone(Name,ZoneType,NewState) table = self.pickupZones elseif ZoneType == CTLD.CargoZoneType.DROP then table = self.dropOffZones + elseif ZoneType == CTLD.CargoZoneType.SHIP then + table = self.shipZones else table = self.wpZones end @@ -2263,8 +2305,10 @@ end -- @param #number Color Smoke/Flare color e.g. #SMOKECOLOR.Red -- @param #string Active Is this zone currently active? -- @param #string HasBeacon Does this zone have a beacon if it is active? +-- @param #number Shiplength Length of Ship for shipzones +-- @param #number Shipwidth Width of Ship for shipzones -- @return #CTLD self -function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon) +function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon, Shiplength, Shipwidth) self:T(self.lid .. " AddCTLDZone") local ctldzone = {} -- #CTLD.CargoZone @@ -2284,6 +2328,11 @@ function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon) ctldzone.vhfbeacon = nil end + if Type == CTLD.CargoZoneType.SHIP then + ctldzone.shiplength = Shiplength or 100 + ctldzone.shipwidth = Shipwidth or 10 + end + self:AddZone(ctldzone) return self end @@ -2375,10 +2424,12 @@ end -- @param #CTLD.CargoZoneType Zonetype Zonetype -- @return #boolean Outcome Is in zone or not -- @return #string name Closest zone name --- @return #string zone Closest Core.Zone#ZONE object +-- @return Core.Zone#ZONE zone Closest Core.Zone#ZONE object -- @return #number distance Distance to closest zone +-- @return #number width Radius of zone or width of ship function CTLD:IsUnitInZone(Unit,Zonetype) self:T(self.lid .. " IsUnitInZone") + self:T(Zonetype) local unitname = Unit:GetName() local zonetable = {} local outcome = false @@ -2386,6 +2437,8 @@ function CTLD:IsUnitInZone(Unit,Zonetype) zonetable = self.pickupZones -- #table elseif Zonetype == CTLD.CargoZoneType.DROP then zonetable = self.dropOffZones -- #table + elseif Zonetype == CTLD.CargoZoneType.SHIP then + zonetable = self.shipZones -- #table else zonetable = self.wpZones -- #table end @@ -2394,16 +2447,29 @@ function CTLD:IsUnitInZone(Unit,Zonetype) local colorret = nil local maxdist = 1000000 -- 100km local zoneret = nil + local zonewret = nil local zonenameret = nil for _,_cargozone in pairs(zonetable) do local czone = _cargozone -- #CTLD.CargoZone local unitcoord = Unit:GetCoordinate() local zonename = czone.name - local zone = ZONE:FindByName(zonename) - zonecoord = zone:GetCoordinate() local active = czone.active local color = czone.color - local zoneradius = zone:GetRadius() + local zone = nil + local zoneradius = 100 + local zonewidth = 20 + if Zonetype == CTLD.CargoZoneType.SHIP then + self:T("Checking Type Ship: "..zonename) + zone = UNIT:FindByName(zonename) + zonecoord = zone:GetCoordinate() + zoneradius = czone.shiplength + zonewidth = czone.shipwidth + else + zone = ZONE:FindByName(zonename) + zonecoord = zone:GetCoordinate() + zoneradius = zone:GetRadius() + zonewidth = zoneradius + end local distance = self:_GetDistance(zonecoord,unitcoord) if distance <= zoneradius and active then outcome = true @@ -2412,10 +2478,15 @@ function CTLD:IsUnitInZone(Unit,Zonetype) maxdist = distance zoneret = zone zonenameret = zonename + zonewret = zonewidth colorret = color end end - return outcome, zonenameret, zoneret, maxdist + if Zonetype == CTLD.CargoZoneType.SHIP then + return outcome, zonenameret, zoneret, maxdist, zonewret + else + return outcome, zonenameret, zoneret, maxdist + end end --- User function - Start smoke in a zone close to the Unit. @@ -2598,6 +2669,9 @@ end self:T(self.lid .. " CanHoverLoad") if self:IsHercules(Unit) then return false end local outcome = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) and self:IsCorrectHover(Unit) + if not outcome then + outcome = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP) --and self:IsCorrectHover(Unit) + end return outcome end @@ -2691,7 +2765,7 @@ end -- @return #CTLD self function CTLD:onafterStart(From, Event, To) self:T({From, Event, To}) - self:I(self.lid .. "Started.") + self:I(self.lid .. "Started ("..self.version..")") if self.useprefix or self.enableHercules then local prefix = self.prefixes if self.enableHercules then