From 3289ad281794f15089caf43d2ff3a7f0aa4f93e9 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 29 Jun 2021 17:49:42 +0200 Subject: [PATCH] Added basic support for Hercules mod --- Moose Development/Moose/Ops/CTLD.lua | 173 ++++++++++++++++++++++++--- 1 file changed, 156 insertions(+), 17 deletions(-) diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 6c62d5046..4adaa0c24 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: 22 June 2021 +-- Date: July 2021 do ------------------------------------------------------ @@ -379,6 +379,27 @@ do -- -- Lists hover parameters and indicates if these are curently fulfilled. Also @see options on hover heights. -- +-- ## 5. Support for Hercules mod by Anubis +-- +-- Basic support for the Hercules mod By Anubis has been build into CTLD. Currently this does **not** cover objects and troops which can +-- be loaded from the Rearm/Refuel menu, i.e. you can drop them into the field, but you cannot use them in functions scripted with this class. +-- +-- local my_ctld = CTLD:New(coalition.side.BLUE,{"Helicargo", "Hercules"},"Lufttransportbrigade I") +-- +-- Enable these options for Hercules support: +-- +-- my_ctld.enableHercules = true +-- my_ctld.HercMinAngels = 155 -- for troop/cargo drop via chute in meters, ca 470 ft +-- my_ctld.HercMaxAngels = 2000 -- for troop/cargo drop via chute in meters, ca 6000 ft +-- +-- Also, the following options need to be set to `true`: +-- +-- my_ctld.useprefix = true -- this is true by default +-- +-- Standard transport capabilities as per the real Hercules are: +-- +-- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64}, -- 19t cargo, 64 paratroopers +-- -- @field #CTLD CTLD = { ClassName = "CTLD", @@ -415,6 +436,7 @@ CTLD = { -- DONE: Troops running to WP Zone -- DONE: Zone Radio Beacons -- DONE: Stats Running +-- DONE: Added support for Hercules ------------------------------ --- Radio Beacons @@ -468,6 +490,7 @@ CTLD.UnitTypes = { ["Ka-50"] = {type="Ka-50", crates=false, troops=false, cratelimit = 0, trooplimit = 0}, ["Mi-24P"] = {type="Mi-24P", crates=true, troops=true, cratelimit = 2, trooplimit = 8}, ["Mi-24V"] = {type="Mi-24V", crates=true, troops=true, cratelimit = 2, trooplimit = 8}, + ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64}, -- 19t cargo, 64 paratroopers } --- Updated and sorted known NDB beacons (in kHz!) from the available maps @@ -590,7 +613,8 @@ function CTLD:New(Coalition, Prefixes, Alias) -- setup self.CrateDistance = 30 -- list/load crates in this radius - self.prefixes = Prefixes or {"cargoheli"} + self.prefixes = Prefixes or {"Cargoheli"} + --self.I({prefixes = self.prefixes}) self.useprefix = true self.maximumHoverHeight = 15 @@ -602,6 +626,11 @@ function CTLD:New(Coalition, Prefixes, Alias) self.movetroopstowpzone = true self.movetroopsdistance = 5000 + -- added support Hercules Mod + self.enableHercules = true + self.HercMinAngels = 165 -- for troop/cargo drop via chute + self.HercMaxAngels = 2000 -- for troop/cargo drop via chute + for i=1,100 do math.random() end @@ -863,7 +892,12 @@ function CTLD:_EventHandler(EventData) local _group = event.IniGroup if _unit:IsHelicopter() or _group:IsHelicopter() then self:_RefreshF10Menus() - end + end + -- Herc support + self:I(_unit:GetTypeName()) + if _unit:GetTypeName() == "Hercules" and self.enableHercules then + self:_RefreshF10Menus() + end return elseif event.id == EVENTS.PlayerLeaveUnit then -- remove from pilot table @@ -965,6 +999,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop) return self end -- spawn crates in front of helicopter + local IsHerc = self:IsHercules(Unit) -- Herc local cargotype = Cargo -- #CTLD_CARGO local number = number or cargotype:GetCratesNeeded() --#number local cratesneeded = cargotype:GetCratesNeeded() --#number @@ -980,8 +1015,14 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop) for i=1,number do local cratealias = string.format("%s-%d", cratetemplate, math.random(1,100000)) local cratedistance = i*4 + 6 + if IsHerc then + -- wider radius + cratedistance = i*4 + 12 + end local rheading = math.floor(math.random(90,270) * heading + 1 / 360) - local rheading = rheading + 180 -- mirror + 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() @@ -1249,6 +1290,18 @@ function CTLD:_ListCargo(Group, Unit) return self end +--- (Internal) Function to check if a unit is a Hercules C-130. +-- @param #CTLD self +-- @param Wrapper.Unit#UNIT Unit +-- @return #boolean Outcome +function CTLD:IsHercules(Unit) + if Unit:GetTypeName() == "Hercules" then + return true + else + return false + end +end + --- (Internal) Function to unload troops from heli. -- @param #CTLD self -- @param Wrapper.Group#GROUP Group @@ -1263,6 +1316,11 @@ function CTLD:_UnloadTroops(Group, Unit) end -- check for hover unload local hoverunload = self:IsCorrectHover(Unit) --if true we\'re hovering in parameters + local IsHerc = self:IsHercules(Unit) + if IsHerc then + -- no hover but airdrop here + hoverunload = self:IsCorrectFlightParameters(Unit) + end -- check if we\'re landed local grounded = not self:IsUnitInAir(Unit) -- Get what we have loaded @@ -1280,8 +1338,14 @@ function CTLD:_UnloadTroops(Group, Unit) local name = cargo:GetName() or "none" local temptable = cargo:GetTemplates() or {} local position = Group:GetCoordinate() - local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,100) - local randomcoord = zone:GetRandomCoordinate(10,30):GetVec2() + local zoneradius = 100 -- drop zone radius + local factor = 1 + if IsHerc then + factor = cargo:GetCratesNeeded() or 1 -- spread a bit more if airdropping + zoneradius = Unit:GetVelocityMPS() or 100 + end + local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,zoneradius*factor) + local randomcoord = zone:GetRandomCoordinate(10,30*factor):GetVec2() for _,_template in pairs(temptable) do self.TroopCounter = self.TroopCounter + 1 local alias = string.format("%s-%d", _template, math.random(1,100000)) @@ -1321,7 +1385,11 @@ function CTLD:_UnloadTroops(Group, Unit) self.Loaded_Cargo[unitname] = nil self.Loaded_Cargo[unitname] = loaded else - local m = MESSAGE:New("Nothing loaded or not hovering within parameters!",10,"CTLD"):ToGroup(Group) + if IsHerc then + local m = MESSAGE:New("Nothing loaded or not within airdrop parameters!",10,"CTLD"):ToGroup(Group) + else + local m = MESSAGE:New("Nothing loaded or not hovering within parameters!",10,"CTLD"):ToGroup(Group) + end end return self end @@ -1342,6 +1410,11 @@ function CTLD:_UnloadCrates(Group, Unit) end -- check for hover unload local hoverunload = self:IsCorrectHover(Unit) --if true we\'re hovering in parameters + local IsHerc = self:IsHercules(Unit) + if IsHerc then + -- no hover but airdrop here + hoverunload = self:IsCorrectFlightParameters(Unit) + end -- check if we\'re landed local grounded = not self:IsUnitInAir(Unit) -- Get what we have loaded @@ -1379,7 +1452,11 @@ function CTLD:_UnloadCrates(Group, Unit) self.Loaded_Cargo[unitname] = nil self.Loaded_Cargo[unitname] = loaded else - local m = MESSAGE:New("Nothing loaded or not hovering within parameters!",10,"CTLD"):ToGroup(Group) + if IsHerc then + local m = MESSAGE:New("Nothing loaded or not within airdrop parameters!",10,"CTLD"):ToGroup(Group) + else + local m = MESSAGE:New("Nothing loaded or not hovering within parameters!",10,"CTLD"):ToGroup(Group) + end end return self end @@ -1579,10 +1656,10 @@ end -- @param #CTLD self -- @return #CTLD self function CTLD:_RefreshF10Menus() - self:T(self.lid .. " _RefreshF10Menus") + self:I(self.lid .. " _RefreshF10Menus") local PlayerSet = self.PilotGroups -- Core.Set#SET_GROUP local PlayerTable = PlayerSet:GetSetObjects() -- #table of #GROUP objects - + --self:I({PlayerTable=PlayerTable}) -- rebuild units table local _UnitList = {} for _key, _group in pairs (PlayerTable) do @@ -1644,7 +1721,11 @@ function CTLD:_RefreshF10Menus() local unloadmenu1 = MENU_GROUP_COMMAND:New(_group,"Drop troops",toptroops, self._UnloadTroops, self, _group, _unit):Refresh() end local rbcns = MENU_GROUP_COMMAND:New(_group,"List active zone beacons",topmenu, self._ListRadioBeacons, self, _group, _unit) - local hoverpars = MENU_GROUP_COMMAND:New(_group,"Show hover parameters",topmenu, self._ShowHoverParams, self, _group, _unit):Refresh() + if unittype == "Hercules" then + local hoverpars = MENU_GROUP_COMMAND:New(_group,"Show flight parameters",topmenu, self._ShowFlightParams, self, _group, _unit):Refresh() + else + local hoverpars = MENU_GROUP_COMMAND:New(_group,"Show hover parameters",topmenu, self._ShowHoverParams, self, _group, _unit):Refresh() + end self.MenusDone[_unitName] = true end -- end group end -- end unit @@ -1901,7 +1982,7 @@ end --- (Internal) Function to refresh radio beacons -- @param #CTLD self function CTLD:_RefreshRadioBeacons() - self:I(self.lid .. " _RefreshRadioBeacons") + self:T(self.lid .. " _RefreshRadioBeacons") local zones = {[1] = self.pickupZones, [2] = self.wpZones, [3] = self.dropOffZones} for i=1,3 do @@ -2070,7 +2151,35 @@ end local minh = self.minimumHoverHeight -- 5 local mspeed = 2 -- 2 m/s self:T(string.format("%s Unit parameters: at %dm AGL with %dmps",self.lid,aheight,uspeed)) - if (uspeed <= maxh) and (aheight <= maxh) and (aheight >= minh) then + if (uspeed <= mspeed) and (aheight <= maxh) and (aheight >= minh) then + -- yep within parameters + outcome = true + end + end + return outcome + end + + --- (Internal) Check if a Hercules is flying *in parameters* for air drops. + -- @param #CTLD self + -- @param Wrapper.Unit#UNIT Unit + -- @return #boolean Outcome + function CTLD:IsCorrectFlightParameters(Unit) + self:T(self.lid .. " IsCorrectFlightParameters") + local outcome = false + -- see if we are in air and within parameters. + if self:IsUnitInAir(Unit) then + -- get speed and height + local uspeed = Unit:GetVelocityMPS() + local uheight = Unit:GetHeight() + local ucoord = Unit:GetCoordinate() + local gheight = ucoord:GetLandHeight() + local aheight = uheight - gheight -- height above ground + local maxh = self.HercMinAngels-- 1500m + local minh = self.HercMaxAngels -- 5000m + local mspeed = 2 -- 2 m/s + -- TODO:Add speed test for Herc, should not be above 280kph/150kn + self:T(string.format("%s Unit parameters: at %dm AGL with %dmps",self.lid,aheight,uspeed)) + if (aheight <= maxh) and (aheight >= minh) then -- yep within parameters outcome = true end @@ -2086,17 +2195,34 @@ end local inhover = self:IsCorrectHover(Unit) local htxt = "true" if not inhover then htxt = "false" end - local text = string.format("Hover parameter (autoload):\n - Min height %dm \n - Max height %dm \n - Max speed 2mps \n - In parameter: %s", self.minimumHoverHeight, self.maximumHoverHeight, htxt) + local text = string.format("Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 2mps \n - In parameter: %s", self.minimumHoverHeight, self.maximumHoverHeight, htxt) local m = MESSAGE:New(text,10,"CTLD",false):ToGroup(Group) return self end + --- (Internal) List if a Herc unit is flying *in parameters*. + -- @param #CTLD self + -- @param Wrapper.Group#GROUP Group + -- @param Wrapper.Unit#UNIT Unit + function CTLD:_ShowFlightParams(Group,Unit) + local inhover = self:IsCorrectFlightParameters(Unit) + local htxt = "true" + if not inhover then htxt = "false" end + local minheight = UTILS.MetersToFeet(self.HercMinAngels) + local maxheight = UTILS.MetersToFeet(self.HercMaxAngels) + local text = string.format("Flight parameters (airdrop):\n - Min height %dft \n - Max height %dft \n - In parameter: %s", minheight, maxheight, htxt) + local m = MESSAGE:New(text,10,"CTLD",false):ToGroup(Group) + return self + end + + --- (Internal) Check if a unit is in a load zone and is hovering in parameters. -- @param #CTLD self -- @param Wrapper.Unit#UNIT Unit -- @return #boolean Outcome function CTLD:CanHoverLoad(Unit) 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) return outcome end @@ -2107,11 +2233,15 @@ end -- @return #boolean Outcome function CTLD:IsUnitInAir(Unit) -- get speed and height + local minheight = self.minimumHoverHeight + if self.enableHercules and Unit:GetTypeName() == "Hercules" then + minheight = 5.1 -- herc is 5m AGL on the ground + end local uheight = Unit:GetHeight() local ucoord = Unit:GetCoordinate() local gheight = ucoord:GetLandHeight() local aheight = uheight - gheight -- height above ground - if aheight >= self.minimumHoverHeight then + if aheight >= minheight then return true else return false @@ -2174,8 +2304,17 @@ end function CTLD:onafterStart(From, Event, To) self:I({From, Event, To}) if self.useprefix then - self.PilotGroups = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.prefixes):FilterCategoryHelicopter():FilterStart() + local prefix = self.prefixes + self:I({prefix=prefix}) + if self.enableHercules then + --self:I("CTLD with prefixes and Hercules") + self.PilotGroups = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(prefix):FilterStart() + else + --self:I("CTLD with prefixes NO Hercules") + self.PilotGroups = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(prefix):FilterCategoryHelicopter():FilterStart() + end else + --self:I("CTLD NO prefixes NO Hercules") self.PilotGroups = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart() end -- Events @@ -2320,4 +2459,4 @@ end end -- end do ------------------------------------------------------------------- -- End Ops.CTLD.lua -------------------------------------------------------------------- +------------------------------------------------------------------- \ No newline at end of file