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/AI/AI_Cargo.lua b/Moose Development/Moose/AI/AI_Cargo.lua index 5bcd94437..43d5eb358 100644 --- a/Moose Development/Moose/AI/AI_Cargo.lua +++ b/Moose Development/Moose/AI/AI_Cargo.lua @@ -47,19 +47,21 @@ 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 @@ -393,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 ) @@ -509,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 @@ -580,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/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 3a83a48ae..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 @@ -207,6 +211,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 +262,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 +297,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 then --and Helicopter:GetVelocityKMH() < self.landingspeed then --self:Load( Helicopter:GetPointVec2() ) self:Load( self.PickupZone ) self.RoutePickup = false @@ -285,7 +311,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 then --and Helicopter:GetVelocityKMH() < self.landingspeed then self:Unload( self.DeployZone ) self.RouteDeploy = false end diff --git a/Moose Development/Moose/Functional/Fox.lua b/Moose Development/Moose/Functional/Fox.lua index 5c5ec9f20..efcdc99a5 100644 --- a/Moose Development/Moose/Functional/Fox.lua +++ b/Moose Development/Moose/Functional/Fox.lua @@ -1707,8 +1707,8 @@ end --- Returns the unit of a player and the player name. If the unit does not belong to a player, nil is returned. -- @param #FOX self -- @param DCS#Weapon weapon The weapon. --- @return #number Notching heading right, i.e. missile heading +90� --- @return #number Notching heading left, i.e. missile heading -90�. +-- @return #number Notching heading right, i.e. missile heading +90°. +-- @return #number Notching heading left, i.e. missile heading -90°. function FOX:_GetNotchingHeadings(weapon) if weapon then diff --git a/Moose Development/Moose/Functional/Mantis.lua b/Moose Development/Moose/Functional/Mantis.lua index 6891fd3fd..047d3cd91 100644 --- a/Moose Development/Moose/Functional/Mantis.lua +++ b/Moose Development/Moose/Functional/Mantis.lua @@ -59,7 +59,7 @@ -- @extends Core.Base#BASE ---- *The worst thing that can happen to a good cause is, not to be skillfully attacked, but to be ineptly defended.* - Frdric Bastiat +--- *The worst thing that can happen to a good cause is, not to be skillfully attacked, but to be ineptly defended.* - Frédéric Bastiat -- -- Simple Class for a more intelligent Air Defense System -- diff --git a/Moose Development/Moose/Functional/MissileTrainer.lua b/Moose Development/Moose/Functional/MissileTrainer.lua index eb9c50e86..c0911ac36 100644 --- a/Moose Development/Moose/Functional/MissileTrainer.lua +++ b/Moose Development/Moose/Functional/MissileTrainer.lua @@ -5,7 +5,7 @@ -- ## Features: -- -- * Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes. --- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range � +-- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range -- * Provide alerts when a missile would have killed your aircraft. -- * Provide alerts when the missile self destructs. -- * Enable / Disable and Configure the Missile Trainer using the various menu options. diff --git a/Moose Development/Moose/Functional/RAT.lua b/Moose Development/Moose/Functional/RAT.lua index 691f53338..55278f686 100644 --- a/Moose Development/Moose/Functional/RAT.lua +++ b/Moose Development/Moose/Functional/RAT.lua @@ -5371,7 +5371,7 @@ function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, take if spawnonground then - -- Sh�ps and FARPS seem to have a build in queue. + -- Ships and FARPS seem to have a build in queue. if spawnonship or spawnonfarp or spawnonrunway or automatic then self:T(RAT.id..string.format("RAT group %s spawning at farp, ship or runway %s.", self.alias, departure:GetName())) 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' ) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 943b17cdd..c452c652c 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -1,4 +1,3 @@ - --- **Ops** -- Combat Search and Rescue. -- -- === @@ -23,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 @@ -70,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. @@ -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.10r3" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -361,12 +343,13 @@ 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 = 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! 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 @@ -378,6 +361,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 +626,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 +790,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 @@ -894,11 +877,14 @@ function CSAR:_EventHandler(EventData) end if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then + 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) else self:_RescuePilots(_unit) end + --]] else self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition())) end @@ -934,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 @@ -1112,7 +1098,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) @@ -1143,6 +1129,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 @@ -1174,8 +1162,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. @@ -1314,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) @@ -1337,8 +1327,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 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 self:_RescuePilots(_heliUnit) @@ -1347,7 +1337,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname) end --queue up - self:__Returning(-5,heliname,_woundedGroupName) + self:__Returning(-5,heliname,_woundedGroupName, isairport) return self end @@ -1403,7 +1393,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) @@ -1501,10 +1493,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 @@ -1570,12 +1569,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 @@ -1747,9 +1745,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 @@ -1907,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 @@ -1915,19 +1926,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 @@ -2047,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 diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 56e52dd3f..60b111f26 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 = {} @@ -659,6 +670,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 @@ -927,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 @@ -1116,8 +1131,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 +1182,7 @@ end -- clean up: table.remove(self.DroppedTroops, nearestGroupIndex) - nearestGroup:Destroy() + nearestGroup:Destroy(false) end return self end @@ -1183,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 @@ -1230,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 @@ -1390,8 +1427,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 +1457,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:__CratesPickedUp(1, Group, Unit, crate) @@ -1474,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. @@ -1557,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 @@ -1966,7 +2012,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 @@ -2132,6 +2178,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 @@ -2157,6 +2205,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 @@ -2254,8 +2304,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 @@ -2275,6 +2327,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 @@ -2366,10 +2423,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 @@ -2377,6 +2436,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 @@ -2385,16 +2446,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 @@ -2403,10 +2477,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. @@ -2589,6 +2668,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 @@ -2650,7 +2732,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 @@ -2682,7 +2764,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 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/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 87198a2d7..1b54ab17a 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -507,7 +507,7 @@ UTILS.tostringLL = function( lat, lon, acc, DMS) secFrmtStr = '%0' .. width .. '.' .. acc .. 'f' end - -- 024� 23' 12"N or 024� 23' 12.03"N + -- 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 @@ -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 @@ -1553,7 +1553,7 @@ end --@return #table function UTILS.ShuffleTable(t) if t == nil or type(t) ~= "table" then - BASE:I("Error in ShuffleTable: Missing or wrong tyåe of Argument") + BASE:I("Error in ShuffleTable: Missing or wrong type of Argument") return end math.random() @@ -1578,7 +1578,7 @@ 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 + if type_name == "Mi-8MT" and unit:getDrawArgumentValue(38) == 1 or unit:getDrawArgumentValue(86) == 1 or unit:getDrawArgumentValue(250) == 1 then 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