mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Updates with changes from develop
This commit is contained in:
parent
277c26821e
commit
7ca7caea75
@ -383,13 +383,13 @@ ATIS.Alphabet = {
|
|||||||
|
|
||||||
--- Runway correction for converting true to magnetic heading.
|
--- Runway correction for converting true to magnetic heading.
|
||||||
-- @type ATIS.RunwayM2T
|
-- @type ATIS.RunwayM2T
|
||||||
-- @field #number Caucasus 0° (East).
|
-- @field #number Caucasus 0° (East).
|
||||||
-- @field #number Nevada +12° (East).
|
-- @field #number Nevada +12° (East).
|
||||||
-- @field #number Normandy -10° (West).
|
-- @field #number Normandy -10° (West).
|
||||||
-- @field #number PersianGulf +2° (East).
|
-- @field #number PersianGulf +2° (East).
|
||||||
-- @field #number TheChannel -10° (West).
|
-- @field #number TheChannel -10° (West).
|
||||||
-- @field #number Syria +5° (East).
|
-- @field #number Syria +5° (East).
|
||||||
-- @field #number MarianaIslands +2° (East).
|
-- @field #number MarianaIslands +2° (East).
|
||||||
ATIS.RunwayM2T={
|
ATIS.RunwayM2T={
|
||||||
Caucasus=0,
|
Caucasus=0,
|
||||||
Nevada=12,
|
Nevada=12,
|
||||||
@ -839,9 +839,9 @@ function ATIS:SetMapMarks(switch)
|
|||||||
return self
|
return self
|
||||||
end
|
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 #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
|
-- @return #ATIS self
|
||||||
function ATIS:SetRunwayHeadingsMagnetic(headings)
|
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
|
-- 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
|
-- * 186° on the Caucaus map
|
||||||
-- * 192° on the Nevada map
|
-- * 192° on the Nevada map
|
||||||
-- * 170° on the Normany map
|
-- * 170° on the Normany map
|
||||||
-- * 182° on the Persian Gulf map
|
-- * 182° on the Persian Gulf map
|
||||||
--
|
--
|
||||||
-- Likewise, to convert *true* into *magnetic* heading, one has to substract easterly and add westerly variation.
|
-- 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 g= 9.80665 --[m/s^2]
|
||||||
local M= 0.0289644 --[kg/mol]
|
local M= 0.0289644 --[kg/mol]
|
||||||
local T0=coord:GetTemperature(0)+273.15 --[K] Temp at sea level.
|
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 15°C
|
||||||
local q=qnh*100
|
local q=qnh*100
|
||||||
|
|
||||||
-- Calculate Pressure.
|
-- Calculate Pressure.
|
||||||
@ -1451,13 +1451,13 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
--- Temperature and Dew Point ---
|
--- Temperature and Dew Point ---
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
-- Temperature in °C.
|
-- Temperature in °C.
|
||||||
local temperature=coord:GetTemperature(height+5)
|
local temperature=coord:GetTemperature(height+5)
|
||||||
|
|
||||||
-- Dew point in °C.
|
-- Dew point in °C.
|
||||||
local dewpoint=temperature-(100-self.relHumidity)/5
|
local dewpoint=temperature-(100-self.relHumidity)/5
|
||||||
|
|
||||||
-- Convert to °F.
|
-- Convert to °F.
|
||||||
if self.TDegF then
|
if self.TDegF then
|
||||||
temperature=UTILS.CelciusToFarenheit(temperature)
|
temperature=UTILS.CelciusToFarenheit(temperature)
|
||||||
dewpoint=UTILS.CelciusToFarenheit(dewpoint)
|
dewpoint=UTILS.CelciusToFarenheit(dewpoint)
|
||||||
@ -1624,6 +1624,30 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
else
|
else
|
||||||
precepitation=3 -- snow
|
precepitation=3 -- snow
|
||||||
end
|
end
|
||||||
|
elseif cloudspreset:find("RainyPreset1") then
|
||||||
|
-- Overcast + Rain
|
||||||
|
clouddens=9
|
||||||
|
if temperature>5 then
|
||||||
|
precepitation=1 -- rain
|
||||||
|
else
|
||||||
|
precepitation=3 -- snow
|
||||||
|
end
|
||||||
|
elseif cloudspreset:find("RainyPreset2") then
|
||||||
|
-- Overcast + Rain
|
||||||
|
clouddens=9
|
||||||
|
if temperature>5 then
|
||||||
|
precepitation=1 -- rain
|
||||||
|
else
|
||||||
|
precepitation=3 -- snow
|
||||||
|
end
|
||||||
|
elseif cloudspreset:find("RainyPreset3") then
|
||||||
|
-- Overcast + Rain
|
||||||
|
clouddens=9
|
||||||
|
if temperature>5 then
|
||||||
|
precepitation=1 -- rain
|
||||||
|
else
|
||||||
|
precepitation=3 -- snow
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local CLOUDBASE=string.format("%d", UTILS.MetersToFeet(cloudbase))
|
local CLOUDBASE=string.format("%d", UTILS.MetersToFeet(cloudbase))
|
||||||
@ -1877,15 +1901,15 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
-- Temperature
|
-- Temperature
|
||||||
if self.TDegF then
|
if self.TDegF then
|
||||||
if temperature<0 then
|
if temperature<0 then
|
||||||
subtitle=string.format("Temperature -%s °F", TEMPERATURE)
|
subtitle=string.format("Temperature -%s °F", TEMPERATURE)
|
||||||
else
|
else
|
||||||
subtitle=string.format("Temperature %s °F", TEMPERATURE)
|
subtitle=string.format("Temperature %s °F", TEMPERATURE)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if temperature<0 then
|
if temperature<0 then
|
||||||
subtitle=string.format("Temperature -%s °C", TEMPERATURE)
|
subtitle=string.format("Temperature -%s °C", TEMPERATURE)
|
||||||
else
|
else
|
||||||
subtitle=string.format("Temperature %s °C", TEMPERATURE)
|
subtitle=string.format("Temperature %s °C", TEMPERATURE)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local _TEMPERATURE=subtitle
|
local _TEMPERATURE=subtitle
|
||||||
@ -1906,15 +1930,15 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
-- Dew point
|
-- Dew point
|
||||||
if self.TDegF then
|
if self.TDegF then
|
||||||
if dewpoint<0 then
|
if dewpoint<0 then
|
||||||
subtitle=string.format("Dew point -%s °F", DEWPOINT)
|
subtitle=string.format("Dew point -%s °F", DEWPOINT)
|
||||||
else
|
else
|
||||||
subtitle=string.format("Dew point %s °F", DEWPOINT)
|
subtitle=string.format("Dew point %s °F", DEWPOINT)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if dewpoint<0 then
|
if dewpoint<0 then
|
||||||
subtitle=string.format("Dew point -%s °C", DEWPOINT)
|
subtitle=string.format("Dew point -%s °C", DEWPOINT)
|
||||||
else
|
else
|
||||||
subtitle=string.format("Dew point %s °C", DEWPOINT)
|
subtitle=string.format("Dew point %s °C", DEWPOINT)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local _DEWPOINT=subtitle
|
local _DEWPOINT=subtitle
|
||||||
@ -2252,8 +2276,8 @@ function ATIS:onafterReport(From, Event, To, Text)
|
|||||||
|
|
||||||
-- Replace other stuff.
|
-- Replace other stuff.
|
||||||
local text=string.gsub(text, "SM", "statute miles")
|
local text=string.gsub(text, "SM", "statute miles")
|
||||||
local text=string.gsub(text, "°C", "degrees Celsius")
|
local text=string.gsub(text, "°C", "degrees Celsius")
|
||||||
local text=string.gsub(text, "°F", "degrees Fahrenheit")
|
local text=string.gsub(text, "°F", "degrees Fahrenheit")
|
||||||
local text=string.gsub(text, "inHg", "inches of Mercury")
|
local text=string.gsub(text, "inHg", "inches of Mercury")
|
||||||
local text=string.gsub(text, "mmHg", "millimeters of Mercury")
|
local text=string.gsub(text, "mmHg", "millimeters of Mercury")
|
||||||
local text=string.gsub(text, "hPa", "hecto Pascals")
|
local text=string.gsub(text, "hPa", "hecto Pascals")
|
||||||
@ -2373,7 +2397,7 @@ end
|
|||||||
--- Get runway from user supplied magnetic heading.
|
--- Get runway from user supplied magnetic heading.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @param #number windfrom Wind direction (from) in degrees.
|
-- @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)
|
function ATIS:GetMagneticRunway(windfrom)
|
||||||
|
|
||||||
local diffmin=nil
|
local diffmin=nil
|
||||||
@ -2416,7 +2440,7 @@ function ATIS:GetNavPoint(navpoints, runway, left)
|
|||||||
local navL=self:GetRunwayLR(nav.runway)
|
local navL=self:GetRunwayLR(nav.runway)
|
||||||
local hdgD=UTILS.HdgDiff(navy,rwyy)
|
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
|
if navL==nil or (navL==true and left==true) or (navL==false and left==false) then
|
||||||
return nav
|
return nav
|
||||||
end
|
end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -368,7 +368,7 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
self.mashprefix = {"MASH"} -- prefixes used to find MASHes
|
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.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.autosmoke = false -- automatically smoke location when heli is near
|
||||||
self.autosmokedistance = 1000 -- distance for autosmoke
|
self.autosmokedistance = 2000 -- distance for autosmoke
|
||||||
-- added 0.1.4
|
-- added 0.1.4
|
||||||
self.limitmaxdownedpilots = true
|
self.limitmaxdownedpilots = true
|
||||||
self.maxdownedpilots = 25
|
self.maxdownedpilots = 25
|
||||||
@ -887,6 +887,12 @@ function CSAR:_EventHandler(EventData)
|
|||||||
return -- error!
|
return -- error!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- anyone on board?
|
||||||
|
if self.inTransitGroups[_event.IniUnitName] == nil then
|
||||||
|
-- ignore
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
|
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
|
||||||
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_event.IniUnitName) then
|
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_event.IniUnitName) then
|
||||||
self:_DisplayMessageToSAR(_unit, "Open the door to let me out!", self.messageTime, true)
|
self:_DisplayMessageToSAR(_unit, "Open the door to let me out!", self.messageTime, true)
|
||||||
@ -1002,6 +1008,11 @@ function CSAR:_CheckWoundedGroupStatus(heliname,woundedgroupname)
|
|||||||
local _heliCoord = _heliUnit:GetCoordinate()
|
local _heliCoord = _heliUnit:GetCoordinate()
|
||||||
local _leaderCoord = _woundedGroup:GetCoordinate()
|
local _leaderCoord = _woundedGroup:GetCoordinate()
|
||||||
local _distance = self:_GetDistance(_heliCoord,_leaderCoord)
|
local _distance = self:_GetDistance(_heliCoord,_leaderCoord)
|
||||||
|
-- autosmoke
|
||||||
|
if (self.autosmoke == true) and (_distance < self.autosmokedistance) and (_distance ~= -1) then
|
||||||
|
self:_PopSmokeForGroup(_woundedGroupName, _woundedGroup)
|
||||||
|
end
|
||||||
|
|
||||||
if _distance < self.approachdist_near and _distance > 0 then
|
if _distance < self.approachdist_near and _distance > 0 then
|
||||||
if self:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedGroup, _woundedGroupName) == true then
|
if self:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedGroup, _woundedGroupName) == true then
|
||||||
-- we\'re close, reschedule
|
-- we\'re close, reschedule
|
||||||
@ -1009,7 +1020,25 @@ function CSAR:_CheckWoundedGroupStatus(heliname,woundedgroupname)
|
|||||||
self:__Approach(-5,heliname,woundedgroupname)
|
self:__Approach(-5,heliname,woundedgroupname)
|
||||||
end
|
end
|
||||||
elseif _distance >= self.approachdist_near and _distance < self.approachdist_far then
|
elseif _distance >= self.approachdist_near and _distance < self.approachdist_far then
|
||||||
self.heliVisibleMessage[_lookupKeyHeli] = nil
|
-- message once
|
||||||
|
if self.heliVisibleMessage[_lookupKeyHeli] == nil then
|
||||||
|
local _pilotName = _downedpilot.desc
|
||||||
|
if self.autosmoke == true then
|
||||||
|
local dist = self.autosmokedistance / 1000
|
||||||
|
local disttext = string.format("%.0fkm",dist)
|
||||||
|
if _SETTINGS:IsImperial() then
|
||||||
|
local dist = UTILS.MetersToNM(self.autosmokedistance)
|
||||||
|
disttext = string.format("%.0fnm",dist)
|
||||||
|
end
|
||||||
|
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. I hear you! Damn, that thing is loud!\nI'll pop a smoke when you are %s away.\nLand or hover by the smoke.", _heliName, _pilotName, disttext), self.messageTime,false,true)
|
||||||
|
else
|
||||||
|
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. I hear you! Damn, that thing is loud!\nRequest a flare or smoke if you need.", _heliName, _pilotName), self.messageTime,false,true)
|
||||||
|
end
|
||||||
|
--mark as shown for THIS heli and THIS group
|
||||||
|
self.heliVisibleMessage[_lookupKeyHeli] = true
|
||||||
|
end
|
||||||
|
self.heliCloseMessage[_lookupKeyHeli] = nil
|
||||||
|
self.landedStatus[_lookupKeyHeli] = nil
|
||||||
--reschedule as units aren\'t dead yet , schedule for a bit slower though as we\'re far away
|
--reschedule as units aren\'t dead yet , schedule for a bit slower though as we\'re far away
|
||||||
_downedpilot.timestamp = timer.getAbsTime()
|
_downedpilot.timestamp = timer.getAbsTime()
|
||||||
self:__Approach(-10,heliname,woundedgroupname)
|
self:__Approach(-10,heliname,woundedgroupname)
|
||||||
@ -1169,27 +1198,13 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
|
|||||||
|
|
||||||
local _reset = true
|
local _reset = true
|
||||||
|
|
||||||
if (self.autosmoke == true) and (_distance < self.autosmokedistance) then
|
|
||||||
self:_PopSmokeForGroup(_woundedGroupName, _woundedLeader)
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.heliVisibleMessage[_lookupKeyHeli] == nil then
|
|
||||||
if self.autosmoke == true then
|
|
||||||
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. I hear you! Damn, that thing is loud! Land or hover by the smoke.", _heliName, _pilotName), self.messageTime,true,true)
|
|
||||||
else
|
|
||||||
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. I hear you! Damn, that thing is loud! Request a Flare or Smoke if you need", _heliName, _pilotName), self.messageTime,true,true)
|
|
||||||
end
|
|
||||||
--mark as shown for THIS heli and THIS group
|
|
||||||
self.heliVisibleMessage[_lookupKeyHeli] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if (_distance < 500) then
|
if (_distance < 500) then
|
||||||
|
|
||||||
if self.heliCloseMessage[_lookupKeyHeli] == nil then
|
if self.heliCloseMessage[_lookupKeyHeli] == nil then
|
||||||
if self.autosmoke == true then
|
if self.autosmoke == true then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. You\'re close now! Land or hover at the smoke.", _heliName, _pilotName), self.messageTime,true,true)
|
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. You\'re close now! Land or hover at the smoke.", _heliName, _pilotName), self.messageTime,false,true)
|
||||||
else
|
else
|
||||||
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. You\'re close now! Land in a safe place, I will go there ", _heliName, _pilotName), self.messageTime,true,true)
|
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. You\'re close now! Land in a safe place, I will go there ", _heliName, _pilotName), self.messageTime,false,true)
|
||||||
end
|
end
|
||||||
--mark as shown for THIS heli and THIS group
|
--mark as shown for THIS heli and THIS group
|
||||||
self.heliCloseMessage[_lookupKeyHeli] = true
|
self.heliCloseMessage[_lookupKeyHeli] = true
|
||||||
@ -1206,7 +1221,7 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
|
|||||||
self.landedStatus[_lookupKeyHeli] = math.floor( (_distance - self.loadDistance) / 3.6 )
|
self.landedStatus[_lookupKeyHeli] = math.floor( (_distance - self.loadDistance) / 3.6 )
|
||||||
_time = self.landedStatus[_lookupKeyHeli]
|
_time = self.landedStatus[_lookupKeyHeli]
|
||||||
self:_OrderGroupToMoveToPoint(_woundedGroup, _heliUnit:GetCoordinate())
|
self:_OrderGroupToMoveToPoint(_woundedGroup, _heliUnit:GetCoordinate())
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Wait till " .. _pilotName .. " gets in. \nETA " .. _time .. " more seconds.", self.messageTime, true)
|
self:_DisplayMessageToSAR(_heliUnit, "Wait till " .. _pilotName .. " gets in. \nETA " .. _time .. " more seconds.", self.messageTime, false)
|
||||||
else
|
else
|
||||||
_time = self.landedStatus[_lookupKeyHeli] - 10
|
_time = self.landedStatus[_lookupKeyHeli] - 10
|
||||||
self.landedStatus[_lookupKeyHeli] = _time
|
self.landedStatus[_lookupKeyHeli] = _time
|
||||||
@ -1520,8 +1535,9 @@ function CSAR:_SignalFlare(_unitName)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local _closest = self:_GetClosestDownedPilot(_heli)
|
local _closest = self:_GetClosestDownedPilot(_heli)
|
||||||
|
local smokedist = 8000
|
||||||
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance < 8000.0 then
|
if self.approachdist_far > smokedist then smokedist = self.approachdist_far end
|
||||||
|
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance < smokedist then
|
||||||
|
|
||||||
local _clockDir = self:_GetClockDirection(_heli, _closest.pilot)
|
local _clockDir = self:_GetClockDirection(_heli, _closest.pilot)
|
||||||
local _distance = 0
|
local _distance = 0
|
||||||
@ -1536,11 +1552,13 @@ function CSAR:_SignalFlare(_unitName)
|
|||||||
local _coord = _closest.pilot:GetCoordinate()
|
local _coord = _closest.pilot:GetCoordinate()
|
||||||
_coord:FlareRed(_clockDir)
|
_coord:FlareRed(_clockDir)
|
||||||
else
|
else
|
||||||
local disttext = "4.3nm"
|
local _distance = smokedist
|
||||||
if _SETTINGS:IsMetric() then
|
if _SETTINGS:IsImperial() then
|
||||||
disttext = "8km"
|
_distance = string.format("%.1fnm",UTILS.MetersToNM(smokedist))
|
||||||
|
else
|
||||||
|
_distance = string.format("%.1fkm",smokedist/1000)
|
||||||
end
|
end
|
||||||
self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",disttext), self.messageTime)
|
self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",_distance), self.messageTime)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -1572,8 +1590,10 @@ function CSAR:_Reqsmoke( _unitName )
|
|||||||
if _heli == nil then
|
if _heli == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
local smokedist = 8000
|
||||||
|
if smokedist < self.approachdist_far then smokedist = self.approachdist_far end
|
||||||
local _closest = self:_GetClosestDownedPilot(_heli)
|
local _closest = self:_GetClosestDownedPilot(_heli)
|
||||||
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance < 8000.0 then
|
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance < smokedist then
|
||||||
local _clockDir = self:_GetClockDirection(_heli, _closest.pilot)
|
local _clockDir = self:_GetClockDirection(_heli, _closest.pilot)
|
||||||
local _distance = 0
|
local _distance = 0
|
||||||
if _SETTINGS:IsImperial() then
|
if _SETTINGS:IsImperial() then
|
||||||
@ -1587,11 +1607,13 @@ function CSAR:_Reqsmoke( _unitName )
|
|||||||
local color = self.smokecolor
|
local color = self.smokecolor
|
||||||
_coord:Smoke(color)
|
_coord:Smoke(color)
|
||||||
else
|
else
|
||||||
local disttext = "4.3nm"
|
local _distance = 0
|
||||||
if _SETTINGS:IsMetric() then
|
if _SETTINGS:IsImperial() then
|
||||||
disttext = "8km"
|
_distance = string.format("%.1fnm",UTILS.MetersToNM(smokedist))
|
||||||
|
else
|
||||||
|
_distance = string.format("%.1fkm",smokedist/1000)
|
||||||
end
|
end
|
||||||
self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",disttext), self.messageTime)
|
self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",_distance), self.messageTime)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -1776,7 +1798,8 @@ function CSAR:_GetClockDirection(_heli, _group)
|
|||||||
if _heading then
|
if _heading then
|
||||||
local Aspect = Angle - _heading
|
local Aspect = Angle - _heading
|
||||||
if Aspect == 0 then Aspect = 360 end
|
if Aspect == 0 then Aspect = 360 end
|
||||||
clock = math.floor(Aspect / 30)
|
--clock = math.floor(Aspect / 30)
|
||||||
|
clock = math.abs(UTILS.Round((Aspect / 30),0))
|
||||||
if clock == 0 then clock = 12 end
|
if clock == 0 then clock = 12 end
|
||||||
end
|
end
|
||||||
return clock
|
return clock
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
--- **Ops** -- Combat Troops & Logistics Deployment.
|
--- **Ops** -- Combat Troops & Logistics Department.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -18,7 +18,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Applevangelist** (Moose Version), ***Ciribob*** (original), Thanks to: Shadowze, Cammel (testing)
|
-- ### Author: **Applevangelist** (Moose Version), ***Ciribob*** (original), Thanks to: Shadowze, Cammel (testing), bbirchnz (additional code!!)
|
||||||
-- @module Ops.CTLD
|
-- @module Ops.CTLD
|
||||||
-- @image OPS_CTLD.jpg
|
-- @image OPS_CTLD.jpg
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ do
|
|||||||
-- @field #number CratesNeeded Crates needed to build.
|
-- @field #number CratesNeeded Crates needed to build.
|
||||||
-- @field Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission.
|
-- @field Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission.
|
||||||
-- @field #boolean HasBeenDropped True if dropped from heli.
|
-- @field #boolean HasBeenDropped True if dropped from heli.
|
||||||
|
-- @field #number PerCrateMass Mass in kg
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
CTLD_CARGO = {
|
CTLD_CARGO = {
|
||||||
ClassName = "CTLD_CARGO",
|
ClassName = "CTLD_CARGO",
|
||||||
@ -49,6 +50,7 @@ CTLD_CARGO = {
|
|||||||
CratesNeeded = 0,
|
CratesNeeded = 0,
|
||||||
Positionable = nil,
|
Positionable = nil,
|
||||||
HasBeenDropped = false,
|
HasBeenDropped = false,
|
||||||
|
PerCrateMass = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Define cargo types.
|
--- Define cargo types.
|
||||||
@ -59,6 +61,7 @@ CTLD_CARGO = {
|
|||||||
["TROOPS"] = "Troops", -- #string troops
|
["TROOPS"] = "Troops", -- #string troops
|
||||||
["FOB"] = "FOB", -- #string FOB
|
["FOB"] = "FOB", -- #string FOB
|
||||||
["CRATE"] = "Crate", -- #string crate
|
["CRATE"] = "Crate", -- #string crate
|
||||||
|
["REPAIR"] = "Repair", -- #string repair
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Function to create new CTLD_CARGO object.
|
--- Function to create new CTLD_CARGO object.
|
||||||
@ -72,8 +75,9 @@ CTLD_CARGO = {
|
|||||||
-- @param #number CratesNeeded Crates needed to build.
|
-- @param #number CratesNeeded Crates needed to build.
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission.
|
-- @param Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission.
|
||||||
-- @param #boolean Dropped Cargo/Troops have been unloaded from a chopper.
|
-- @param #boolean Dropped Cargo/Troops have been unloaded from a chopper.
|
||||||
|
-- @param #number PerCrateMass Mass in kg
|
||||||
-- @return #CTLD_CARGO self
|
-- @return #CTLD_CARGO self
|
||||||
function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped)
|
function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass)
|
||||||
-- Inherit everything from BASE class.
|
-- Inherit everything from BASE class.
|
||||||
local self=BASE:Inherit(self, BASE:New()) -- #CTLD
|
local self=BASE:Inherit(self, BASE:New()) -- #CTLD
|
||||||
self:T({ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped})
|
self:T({ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped})
|
||||||
@ -86,6 +90,7 @@ CTLD_CARGO = {
|
|||||||
self.CratesNeeded = CratesNeeded or 0 -- #number
|
self.CratesNeeded = CratesNeeded or 0 -- #number
|
||||||
self.Positionable = Positionable or nil -- Wrapper.Positionable#POSITIONABLE
|
self.Positionable = Positionable or nil -- Wrapper.Positionable#POSITIONABLE
|
||||||
self.HasBeenDropped = Dropped or false --#boolean
|
self.HasBeenDropped = Dropped or false --#boolean
|
||||||
|
self.PerCrateMass = PerCrateMass or 0 -- #number
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -169,6 +174,7 @@ CTLD_CARGO = {
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set WasDropped.
|
--- Set WasDropped.
|
||||||
-- @param #CTLD_CARGO self
|
-- @param #CTLD_CARGO self
|
||||||
-- @param #boolean dropped
|
-- @param #boolean dropped
|
||||||
@ -176,6 +182,17 @@ CTLD_CARGO = {
|
|||||||
self.HasBeenDropped = dropped or false
|
self.HasBeenDropped = dropped or false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Query crate type for REPAIR
|
||||||
|
-- @param #CTLD_CARGO self
|
||||||
|
-- @param #boolean
|
||||||
|
function CTLD_CARGO:IsRepair()
|
||||||
|
if self.CargoType == "Repair" then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -224,6 +241,8 @@ do
|
|||||||
-- -- add infantry unit called "Anti-Tank Small" using template "ATS", of type TROOP with size 3
|
-- -- add infantry unit called "Anti-Tank Small" using template "ATS", of type TROOP with size 3
|
||||||
-- -- infantry units will be loaded directly from LOAD zones into the heli (matching number of free seats needed)
|
-- -- infantry units will be loaded directly from LOAD zones into the heli (matching number of free seats needed)
|
||||||
-- my_ctld:AddTroopsCargo("Anti-Tank Small",{"ATS"},CTLD_CARGO.Enum.TROOPS,3)
|
-- my_ctld:AddTroopsCargo("Anti-Tank Small",{"ATS"},CTLD_CARGO.Enum.TROOPS,3)
|
||||||
|
-- -- if you want to add weight to your Heli, troops can have a weight in kg **per person**. Currently no max weight checked. Fly carefully.
|
||||||
|
-- my_ctld:AddTroopsCargo("Anti-Tank Small",{"ATS"},CTLD_CARGO.Enum.TROOPS,3,80)
|
||||||
--
|
--
|
||||||
-- -- add infantry unit called "Anti-Tank" using templates "AA" and "AA"", of type TROOP with size 4
|
-- -- add infantry unit called "Anti-Tank" using templates "AA" and "AA"", of type TROOP with size 4
|
||||||
-- my_ctld:AddTroopsCargo("Anti-Air",{"AA","AA2"},CTLD_CARGO.Enum.TROOPS,4)
|
-- my_ctld:AddTroopsCargo("Anti-Air",{"AA","AA2"},CTLD_CARGO.Enum.TROOPS,4)
|
||||||
@ -231,10 +250,15 @@ do
|
|||||||
-- -- add vehicle called "Humvee" using template "Humvee", of type VEHICLE, size 2, i.e. needs two crates to be build
|
-- -- add vehicle called "Humvee" using template "Humvee", of type VEHICLE, size 2, i.e. needs two crates to be build
|
||||||
-- -- vehicles and FOB will be spawned as crates in a LOAD zone first. Once transported to DROP zones, they can be build into the objects
|
-- -- vehicles and FOB will be spawned as crates in a LOAD zone first. Once transported to DROP zones, they can be build into the objects
|
||||||
-- my_ctld:AddCratesCargo("Humvee",{"Humvee"},CTLD_CARGO.Enum.VEHICLE,2)
|
-- my_ctld:AddCratesCargo("Humvee",{"Humvee"},CTLD_CARGO.Enum.VEHICLE,2)
|
||||||
|
-- -- if you want to add weight to your Heli, crates can have a weight in kg **per crate**. Currently no max weight checked. Fly carefully.
|
||||||
|
-- my_ctld:AddCratesCargo("Humvee",{"Humvee"},CTLD_CARGO.Enum.VEHICLE,2,2775)
|
||||||
--
|
--
|
||||||
-- -- add infantry unit called "Forward Ops Base" using template "FOB", of type FOB, size 4, i.e. needs four crates to be build:
|
-- -- add infantry unit called "Forward Ops Base" using template "FOB", of type FOB, size 4, i.e. needs four crates to be build:
|
||||||
-- my_ctld:AddCratesCargo("Forward Ops Base",{"FOB"},CTLD_CARGO.Enum.FOB,4)
|
-- my_ctld:AddCratesCargo("Forward Ops Base",{"FOB"},CTLD_CARGO.Enum.FOB,4)
|
||||||
--
|
--
|
||||||
|
-- -- add crates to repair FOB or VEHICLE type units - the 2nd parameter needs to match the template you want to repair
|
||||||
|
-- my_ctld:AddCratesRepair("Humvee Repair","Humvee",CTLD_CARGO.Enum.REPAIR,1)
|
||||||
|
--
|
||||||
-- ## 1.3 Add logistics zones
|
-- ## 1.3 Add logistics zones
|
||||||
--
|
--
|
||||||
-- Add zones for loading troops and crates and dropping, building crates
|
-- Add zones for loading troops and crates and dropping, building crates
|
||||||
@ -272,6 +296,7 @@ do
|
|||||||
-- my_ctld.movetroopsdistance = 5000 -- .. but only if this far away (in meters)
|
-- my_ctld.movetroopsdistance = 5000 -- .. but only if this far away (in meters)
|
||||||
-- my_ctld.smokedistance = 2000 -- Only smoke or flare zones if requesting player unit is this far away (in meters)
|
-- my_ctld.smokedistance = 2000 -- Only smoke or flare zones if requesting player unit is this far away (in meters)
|
||||||
-- my_ctld.suppressmessages = false -- Set to true if you want to script your own messages.
|
-- my_ctld.suppressmessages = false -- Set to true if you want to script your own messages.
|
||||||
|
-- my_ctld.repairtime = 300 -- Number of seconds it takes to repair a unit.
|
||||||
--
|
--
|
||||||
-- ## 2.1 User functions
|
-- ## 2.1 User functions
|
||||||
--
|
--
|
||||||
@ -353,12 +378,16 @@ do
|
|||||||
-- ... your code here ...
|
-- ... your code here ...
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
-- ## 3.6 OnAfterCratesBuild
|
-- ## 3.6 OnAfterCratesBuild, OnAfterCratesRepaired
|
||||||
--
|
--
|
||||||
-- This function is called when a player has build a vehicle or FOB:
|
-- This function is called when a player has build a vehicle or FOB:
|
||||||
--
|
--
|
||||||
-- function my_ctld:OnAfterCratesBuild(From, Event, To, Group, Unit, Vehicle)
|
-- function my_ctld:OnAfterCratesBuild(From, Event, To, Group, Unit, Vehicle)
|
||||||
-- ... your code here ...
|
-- ... your code here ...
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- function my_ctld:OnAfterCratesRepaired(From, Event, To, Group, Unit, Vehicle)
|
||||||
|
-- ... your code here ...
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
-- ## 3.7 A simple SCORING example:
|
-- ## 3.7 A simple SCORING example:
|
||||||
@ -385,7 +414,7 @@ do
|
|||||||
--
|
--
|
||||||
-- ## 4.1 Manage Crates
|
-- ## 4.1 Manage Crates
|
||||||
--
|
--
|
||||||
-- Use this entry to get, load, list nearby, drop, and build crates. Also @see options.
|
-- Use this entry to get, load, list nearby, drop, build and repair crates. Also @see options.
|
||||||
--
|
--
|
||||||
-- ## 4.2 Manage Troops
|
-- ## 4.2 Manage Troops
|
||||||
--
|
--
|
||||||
@ -420,7 +449,7 @@ do
|
|||||||
-- my_ctld.enableHercules = true
|
-- my_ctld.enableHercules = true
|
||||||
-- my_ctld.HercMinAngels = 155 -- for troop/cargo drop via chute in meters, ca 470 ft
|
-- 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
|
-- my_ctld.HercMaxAngels = 2000 -- for troop/cargo drop via chute in meters, ca 6000 ft
|
||||||
-- my_ctld.HercMaxSpeed = 77 -- 77mps or 270 kph or 150 kn
|
-- my_ctld.HercMaxSpeed = 77 -- 77mps or 270kph or 150kn
|
||||||
--
|
--
|
||||||
-- Also, the following options need to be set to `true`:
|
-- Also, the following options need to be set to `true`:
|
||||||
--
|
--
|
||||||
@ -528,7 +557,7 @@ CTLD.UnitTypes = {
|
|||||||
|
|
||||||
--- CTLD class version.
|
--- CTLD class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CTLD.version="0.1.4r2"
|
CTLD.version="0.1.4r3"
|
||||||
|
|
||||||
--- Instantiate a new CTLD.
|
--- Instantiate a new CTLD.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@ -592,6 +621,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
self:AddTransition("*", "TroopsRTB", "*") -- CTLD deploy event.
|
self:AddTransition("*", "TroopsRTB", "*") -- CTLD deploy event.
|
||||||
self:AddTransition("*", "CratesDropped", "*") -- CTLD deploy event.
|
self:AddTransition("*", "CratesDropped", "*") -- CTLD deploy event.
|
||||||
self:AddTransition("*", "CratesBuild", "*") -- CTLD build event.
|
self:AddTransition("*", "CratesBuild", "*") -- CTLD build event.
|
||||||
|
self:AddTransition("*", "CratesRepaired", "*") -- CTLD repair event.
|
||||||
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
||||||
|
|
||||||
-- tables
|
-- tables
|
||||||
@ -652,6 +682,9 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
-- message suppression
|
-- message suppression
|
||||||
self.suppressmessages = false
|
self.suppressmessages = false
|
||||||
|
|
||||||
|
-- time to repair a unit/group
|
||||||
|
self.repairtime = 300
|
||||||
|
|
||||||
for i=1,100 do
|
for i=1,100 do
|
||||||
math.random()
|
math.random()
|
||||||
end
|
end
|
||||||
@ -756,6 +789,17 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
-- @param Wrapper.Group#GROUP Vehicle The #GROUP object of the vehicle or FOB build.
|
-- @param Wrapper.Group#GROUP Vehicle The #GROUP object of the vehicle or FOB build.
|
||||||
-- @return #CTLD self
|
-- @return #CTLD self
|
||||||
|
|
||||||
|
--- FSM Function OnAfterCratesRepaired.
|
||||||
|
-- @function [parent=#CTLD] OnAfterCratesRepaired
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @param #string From State.
|
||||||
|
-- @param #string Event Trigger.
|
||||||
|
-- @param #string To State.
|
||||||
|
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||||
|
-- @param Wrapper.Group#GROUP Vehicle The #GROUP object of the vehicle or FOB repaired.
|
||||||
|
-- @return #CTLD self
|
||||||
|
|
||||||
--- FSM Function OnAfterTroopsRTB.
|
--- FSM Function OnAfterTroopsRTB.
|
||||||
-- @function [parent=#CTLD] OnAfterTroopsRTB
|
-- @function [parent=#CTLD] OnAfterTroopsRTB
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@ -919,13 +963,119 @@ function CTLD:_LoadTroops(Group, Unit, Cargotype)
|
|||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.CargoCounter = self.CargoCounter + 1
|
self.CargoCounter = self.CargoCounter + 1
|
||||||
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, CTLD_CARGO.Enum.TROOPS, true, true, Cargotype.CratesNeeded)
|
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, CTLD_CARGO.Enum.TROOPS, true, true, Cargotype.CratesNeeded,nil,nil,Cargotype.PerCrateMass)
|
||||||
self:T({cargotype=loadcargotype})
|
self:T({cargotype=loadcargotype})
|
||||||
loaded.Troopsloaded = loaded.Troopsloaded + troopsize
|
loaded.Troopsloaded = loaded.Troopsloaded + troopsize
|
||||||
table.insert(loaded.Cargo,loadcargotype)
|
table.insert(loaded.Cargo,loadcargotype)
|
||||||
self.Loaded_Cargo[unitname] = loaded
|
self.Loaded_Cargo[unitname] = loaded
|
||||||
self:_SendMessage("Troops boarded!", 10, false, Group)
|
self:_SendMessage("Troops boarded!", 10, false, Group)
|
||||||
self:__TroopsPickedUp(1,Group, Unit, Cargotype)
|
self:__TroopsPickedUp(1,Group, Unit, Cargotype)
|
||||||
|
self:_UpdateUnitCargoMass(Unit)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function CTLD:_FindRepairNearby(Group, Unit, Repairtype)
|
||||||
|
self:T(self.lid .. " _FindRepairNearby")
|
||||||
|
local unitcoord = Unit:GetCoordinate()
|
||||||
|
|
||||||
|
-- find nearest group of deployed groups
|
||||||
|
local nearestGroup = nil
|
||||||
|
local nearestGroupIndex = -1
|
||||||
|
local nearestDistance = 10000000
|
||||||
|
for k,v in pairs(self.DroppedTroops) do
|
||||||
|
local distance = self:_GetDistance(v:GetCoordinate(),unitcoord)
|
||||||
|
if distance < nearestDistance and distance ~= -1 then
|
||||||
|
nearestGroup = v
|
||||||
|
nearestGroupIndex = k
|
||||||
|
nearestDistance = distance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- found one and matching distance?
|
||||||
|
if nearestGroup == nil or nearestDistance > 1000 then
|
||||||
|
self:_SendMessage("No unit close enough to repair!", 10, false, Group)
|
||||||
|
return nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local groupname = nearestGroup:GetName()
|
||||||
|
--self:I(string.format("***** Found Group %s",groupname))
|
||||||
|
|
||||||
|
-- helper to find matching template
|
||||||
|
local function matchstring(String,Table)
|
||||||
|
local match = false
|
||||||
|
if type(Table) == "table" then
|
||||||
|
for _,_name in pairs (Table) do
|
||||||
|
if string.find(String,_name) then
|
||||||
|
match = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if type(String) == "string" then
|
||||||
|
if string.find(String,Table) then match = true end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return match
|
||||||
|
end
|
||||||
|
|
||||||
|
-- walk through generics and find matching type
|
||||||
|
local Cargotype = nil
|
||||||
|
for k,v in pairs(self.Cargo_Crates) do
|
||||||
|
--self:I({groupname,v.Templates})
|
||||||
|
if matchstring(groupname,v.Templates) and matchstring(groupname,Repairtype) then
|
||||||
|
Cargotype = v -- #CTLD_CARGO
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if Cargotype == nil then
|
||||||
|
--self:_SendMessage("Can't find a matching group for " .. Repairtype, 10, false, Group)
|
||||||
|
return nil, nil
|
||||||
|
else
|
||||||
|
return nearestGroup, Cargotype
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (Internal) Function to repair an object.
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @param Wrapper.Group#GROUP Group
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit
|
||||||
|
-- @param #table Crates Table of #CTLD_CARGO objects near the unit.
|
||||||
|
-- @param #CTLD.Buildable Build Table build object.
|
||||||
|
-- @param #number Number Number of objects in Crates (found) to limit search.
|
||||||
|
function CTLD:_RepairObjectFromCrates(Group,Unit,Crates,Build,Number)
|
||||||
|
self:T(self.lid .. " _RepairObjectFromCrates")
|
||||||
|
local build = Build -- -- #CTLD.Buildable
|
||||||
|
--self:I({Build=Build})
|
||||||
|
local Repairtype = build.Template -- #string
|
||||||
|
local NearestGroup, CargoType = self:_FindRepairNearby(Group,Unit,Repairtype) -- Wrapper.Group#GROUP, #CTLD_CARGO
|
||||||
|
--self:I({Repairtype=Repairtype, CargoType=CargoType, NearestGroup=NearestGroup})
|
||||||
|
if NearestGroup ~= nil then
|
||||||
|
if self.repairtime < 2 then self.repairtime = 30 end -- noob catch
|
||||||
|
self:_SendMessage(string.format("Repair started using %s taking %d secs", build.Name, self.repairtime), 10, false, Group)
|
||||||
|
-- now we can build ....
|
||||||
|
--NearestGroup:Destroy(false)
|
||||||
|
local name = CargoType:GetName()
|
||||||
|
local required = CargoType:GetCratesNeeded()
|
||||||
|
local template = CargoType:GetTemplates()
|
||||||
|
local ctype = CargoType:GetType()
|
||||||
|
local object = {} -- #CTLD.Buildable
|
||||||
|
object.Name = CargoType:GetName()
|
||||||
|
object.Required = required
|
||||||
|
object.Found = required
|
||||||
|
object.Template = template
|
||||||
|
object.CanBuild = true
|
||||||
|
object.Type = ctype -- #CTLD_CARGO.Enum
|
||||||
|
self:_CleanUpCrates(Crates,Build,Number)
|
||||||
|
local desttimer = TIMER:New(function() NearestGroup:Destroy(false) end, self)
|
||||||
|
desttimer:Start(self.repairtime - 1)
|
||||||
|
local buildtimer = TIMER:New(self._BuildObjectFromCrates,self,Group,Unit,object,true,NearestGroup:GetCoordinate())
|
||||||
|
buildtimer:Start(self.repairtime)
|
||||||
|
--self:_BuildObjectFromCrates(Group,Unit,object)
|
||||||
|
else
|
||||||
|
self:_SendMessage("Can't repair this unit with " .. build.Name, 10, false, Group)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -961,7 +1111,7 @@ end
|
|||||||
local nearestDistance = 10000000
|
local nearestDistance = 10000000
|
||||||
for k,v in pairs(self.DroppedTroops) do
|
for k,v in pairs(self.DroppedTroops) do
|
||||||
local distance = self:_GetDistance(v:GetCoordinate(),unitcoord)
|
local distance = self:_GetDistance(v:GetCoordinate(),unitcoord)
|
||||||
if distance < nearestDistance then
|
if distance < nearestDistance and distance ~= -1 then
|
||||||
nearestGroup = v
|
nearestGroup = v
|
||||||
nearestGroupIndex = k
|
nearestGroupIndex = k
|
||||||
nearestDistance = distance
|
nearestDistance = distance
|
||||||
@ -1005,12 +1155,13 @@ end
|
|||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.CargoCounter = self.CargoCounter + 1
|
self.CargoCounter = self.CargoCounter + 1
|
||||||
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, CTLD_CARGO.Enum.TROOPS, true, true, Cargotype.CratesNeeded)
|
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, CTLD_CARGO.Enum.TROOPS, true, true, Cargotype.CratesNeeded,nil,nil,Cargotype.PerCrateMass)
|
||||||
self:T({cargotype=loadcargotype})
|
self:T({cargotype=loadcargotype})
|
||||||
loaded.Troopsloaded = loaded.Troopsloaded + troopsize
|
loaded.Troopsloaded = loaded.Troopsloaded + troopsize
|
||||||
table.insert(loaded.Cargo,loadcargotype)
|
table.insert(loaded.Cargo,loadcargotype)
|
||||||
self.Loaded_Cargo[unitname] = loaded
|
self.Loaded_Cargo[unitname] = loaded
|
||||||
self:_SendMessage("Troops boarded!", 10, false, Group)
|
self:_SendMessage("Troops boarded!", 10, false, Group)
|
||||||
|
self:_UpdateUnitCargoMass(Unit)
|
||||||
self:__TroopsExtracted(1,Group, Unit, nearestGroup)
|
self:__TroopsExtracted(1,Group, Unit, nearestGroup)
|
||||||
|
|
||||||
-- clean up:
|
-- clean up:
|
||||||
@ -1097,10 +1248,10 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
|
|||||||
self.CargoCounter = self.CargoCounter +1
|
self.CargoCounter = self.CargoCounter +1
|
||||||
local realcargo = nil
|
local realcargo = nil
|
||||||
if drop then
|
if drop then
|
||||||
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],true)
|
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],true,cargotype.PerCrateMass)
|
||||||
table.insert(droppedcargo,realcargo)
|
table.insert(droppedcargo,realcargo)
|
||||||
else
|
else
|
||||||
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter])
|
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],nil,cargotype.PerCrateMass)
|
||||||
end
|
end
|
||||||
table.insert(self.Spawned_Cargo, realcargo)
|
table.insert(self.Spawned_Cargo, realcargo)
|
||||||
end
|
end
|
||||||
@ -1132,7 +1283,7 @@ function CTLD:_ListCratesNearby( _group, _unit)
|
|||||||
if dropped then
|
if dropped then
|
||||||
text:Add(string.format("Dropped crate for %s",name))
|
text:Add(string.format("Dropped crate for %s",name))
|
||||||
else
|
else
|
||||||
text:Add(string.format("Crate for %s",name))
|
text:Add(string.format("Crate for %s, %d Kg",name, entry.PerCrateMass))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if text:GetCount() == 1 then
|
if text:GetCount() == 1 then
|
||||||
@ -1226,6 +1377,7 @@ function CTLD:_LoadCratesNearby(Group, Unit)
|
|||||||
else
|
else
|
||||||
-- have we loaded stuff already?
|
-- have we loaded stuff already?
|
||||||
local numberonboard = 0
|
local numberonboard = 0
|
||||||
|
local massonboard = 0
|
||||||
local loaded = {}
|
local loaded = {}
|
||||||
if self.Loaded_Cargo[unitname] then
|
if self.Loaded_Cargo[unitname] then
|
||||||
loaded = self.Loaded_Cargo[unitname] -- #CTLD.LoadedCargo
|
loaded = self.Loaded_Cargo[unitname] -- #CTLD.LoadedCargo
|
||||||
@ -1267,6 +1419,7 @@ function CTLD:_LoadCratesNearby(Group, Unit)
|
|||||||
crate:GetPositionable():Destroy()
|
crate:GetPositionable():Destroy()
|
||||||
crate.Positionable = nil
|
crate.Positionable = nil
|
||||||
self:_SendMessage(string.format("Crate ID %d for %s loaded!",crate:GetID(),crate:GetName()), 10, false, Group)
|
self:_SendMessage(string.format("Crate ID %d for %s loaded!",crate:GetID(),crate:GetName()), 10, false, Group)
|
||||||
|
self:_UpdateUnitCargoMass(Unit)
|
||||||
self:__CratesPickedUp(1, Group, Unit, crate)
|
self:__CratesPickedUp(1, Group, Unit, crate)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1290,6 +1443,43 @@ function CTLD:_LoadCratesNearby(Group, Unit)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Function to get current loaded mass
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit
|
||||||
|
-- @return #number mass in kgs
|
||||||
|
function CTLD:_GetUnitCargoMass(Unit)
|
||||||
|
self:T(self.lid .. " _GetUnitCargoMass")
|
||||||
|
local unitname = Unit:GetName()
|
||||||
|
local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo
|
||||||
|
local loadedmass = 0 -- #number
|
||||||
|
if self.Loaded_Cargo[unitname] then
|
||||||
|
local cargotable = loadedcargo.Cargo or {} -- #table
|
||||||
|
for _,_cargo in pairs(cargotable) do
|
||||||
|
local cargo = _cargo -- #CTLD_CARGO
|
||||||
|
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||||
|
if type == CTLD_CARGO.Enum.TROOPS and not cargo:WasDropped() then
|
||||||
|
loadedmass = loadedmass + (cargo.PerCrateMass * cargo:GetCratesNeeded())
|
||||||
|
end
|
||||||
|
if type ~= CTLD_CARGO.Enum.TROOPS and not cargo:WasDropped() then
|
||||||
|
loadedmass = loadedmass + cargo.PerCrateMass
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return loadedmass
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (Internal) Function to calculate and set Unit internal cargo mass
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit
|
||||||
|
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())
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Function to list loaded cargo.
|
--- (Internal) Function to list loaded cargo.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
-- @param Wrapper.Group#GROUP Group
|
-- @param Wrapper.Group#GROUP Group
|
||||||
@ -1303,6 +1493,7 @@ function CTLD:_ListCargo(Group, Unit)
|
|||||||
local trooplimit = capabilities.trooplimit -- #boolean
|
local trooplimit = capabilities.trooplimit -- #boolean
|
||||||
local cratelimit = capabilities.cratelimit -- #number
|
local cratelimit = capabilities.cratelimit -- #number
|
||||||
local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo
|
local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo
|
||||||
|
local loadedmass = self:_GetUnitCargoMass(Unit) -- #number
|
||||||
if self.Loaded_Cargo[unitname] then
|
if self.Loaded_Cargo[unitname] then
|
||||||
local no_troops = loadedcargo.Troopsloaded or 0
|
local no_troops = loadedcargo.Troopsloaded or 0
|
||||||
local no_crates = loadedcargo.Cratesloaded or 0
|
local no_crates = loadedcargo.Cratesloaded or 0
|
||||||
@ -1328,7 +1519,7 @@ function CTLD:_ListCargo(Group, Unit)
|
|||||||
for _,_cargo in pairs(cargotable) do
|
for _,_cargo in pairs(cargotable) do
|
||||||
local cargo = _cargo -- #CTLD_CARGO
|
local cargo = _cargo -- #CTLD_CARGO
|
||||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||||
if type ~= CTLD_CARGO.Enum.TROOPS then
|
if type ~= CTLD_CARGO.Enum.TROOPS and not cargo:WasDropped() then
|
||||||
report:Add(string.format("Crate: %s size 1",cargo:GetName()))
|
report:Add(string.format("Crate: %s size 1",cargo:GetName()))
|
||||||
cratecount = cratecount + 1
|
cratecount = cratecount + 1
|
||||||
end
|
end
|
||||||
@ -1337,6 +1528,7 @@ function CTLD:_ListCargo(Group, Unit)
|
|||||||
report:Add(" N O N E")
|
report:Add(" N O N E")
|
||||||
end
|
end
|
||||||
report:Add("------------------------------------------------------------")
|
report:Add("------------------------------------------------------------")
|
||||||
|
report:Add("Total Mass: ".. loadedmass .. " kg")
|
||||||
local text = report:Text()
|
local text = report:Text()
|
||||||
self:_SendMessage(text, 30, true, Group)
|
self:_SendMessage(text, 30, true, Group)
|
||||||
else
|
else
|
||||||
@ -1439,6 +1631,7 @@ function CTLD:_UnloadTroops(Group, Unit)
|
|||||||
end
|
end
|
||||||
self.Loaded_Cargo[unitname] = nil
|
self.Loaded_Cargo[unitname] = nil
|
||||||
self.Loaded_Cargo[unitname] = loaded
|
self.Loaded_Cargo[unitname] = loaded
|
||||||
|
self:_UpdateUnitCargoMass(Unit)
|
||||||
else
|
else
|
||||||
if IsHerc then
|
if IsHerc then
|
||||||
self:_SendMessage("Nothing loaded or not within airdrop parameters!", 10, false, Group)
|
self:_SendMessage("Nothing loaded or not within airdrop parameters!", 10, false, Group)
|
||||||
@ -1507,6 +1700,7 @@ function CTLD:_UnloadCrates(Group, Unit)
|
|||||||
end
|
end
|
||||||
self.Loaded_Cargo[unitname] = nil
|
self.Loaded_Cargo[unitname] = nil
|
||||||
self.Loaded_Cargo[unitname] = loaded
|
self.Loaded_Cargo[unitname] = loaded
|
||||||
|
self:_UpdateUnitCargoMass(Unit)
|
||||||
else
|
else
|
||||||
if IsHerc then
|
if IsHerc then
|
||||||
self:_SendMessage("Nothing loaded or not within airdrop parameters!", 10, false, Group)
|
self:_SendMessage("Nothing loaded or not within airdrop parameters!", 10, false, Group)
|
||||||
@ -1533,7 +1727,7 @@ function CTLD:_BuildCrates(Group, Unit)
|
|||||||
-- get dropped crates
|
-- get dropped crates
|
||||||
for _,_crate in pairs(crates) do
|
for _,_crate in pairs(crates) do
|
||||||
local Crate = _crate -- #CTLD_CARGO
|
local Crate = _crate -- #CTLD_CARGO
|
||||||
if Crate:WasDropped() then
|
if Crate:WasDropped() and not Crate:IsRepair() then
|
||||||
-- we can build these - maybe
|
-- we can build these - maybe
|
||||||
local name = Crate:GetName()
|
local name = Crate:GetName()
|
||||||
local required = Crate:GetCratesNeeded()
|
local required = Crate:GetCratesNeeded()
|
||||||
@ -1596,12 +1790,92 @@ function CTLD:_BuildCrates(Group, Unit)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Function to repair nearby vehicles / FOBs
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @param Wrapper.Group#GROUP Group
|
||||||
|
-- @param Wrappe.Unit#UNIT Unit
|
||||||
|
function CTLD:_RepairCrates(Group, Unit)
|
||||||
|
self:T(self.lid .. " _RepairCrates")
|
||||||
|
-- get nearby crates
|
||||||
|
local finddist = self.CrateDistance or 30
|
||||||
|
local crates,number = self:_FindCratesNearby(Group,Unit, finddist) -- #table
|
||||||
|
local buildables = {}
|
||||||
|
local foundbuilds = false
|
||||||
|
local canbuild = false
|
||||||
|
if number > 0 then
|
||||||
|
-- get dropped crates
|
||||||
|
for _,_crate in pairs(crates) do
|
||||||
|
local Crate = _crate -- #CTLD_CARGO
|
||||||
|
if Crate:WasDropped() and Crate:IsRepair() then
|
||||||
|
-- we can build these - maybe
|
||||||
|
local name = Crate:GetName()
|
||||||
|
local required = Crate:GetCratesNeeded()
|
||||||
|
local template = Crate:GetTemplates()
|
||||||
|
local ctype = Crate:GetType()
|
||||||
|
if not buildables[name] then
|
||||||
|
local object = {} -- #CTLD.Buildable
|
||||||
|
object.Name = name
|
||||||
|
object.Required = required
|
||||||
|
object.Found = 1
|
||||||
|
object.Template = template
|
||||||
|
object.CanBuild = false
|
||||||
|
object.Type = ctype -- #CTLD_CARGO.Enum
|
||||||
|
buildables[name] = object
|
||||||
|
foundbuilds = true
|
||||||
|
else
|
||||||
|
buildables[name].Found = buildables[name].Found + 1
|
||||||
|
foundbuilds = true
|
||||||
|
end
|
||||||
|
if buildables[name].Found >= buildables[name].Required then
|
||||||
|
buildables[name].CanBuild = true
|
||||||
|
canbuild = true
|
||||||
|
end
|
||||||
|
self:T({repair = buildables})
|
||||||
|
end -- end dropped
|
||||||
|
end -- end crate loop
|
||||||
|
-- ok let\'s list what we have
|
||||||
|
local report = REPORT:New("Checklist Repairs")
|
||||||
|
report:Add("------------------------------------------------------------")
|
||||||
|
for _,_build in pairs(buildables) do
|
||||||
|
local build = _build -- Object table from above
|
||||||
|
local name = build.Name
|
||||||
|
local needed = build.Required
|
||||||
|
local found = build.Found
|
||||||
|
local txtok = "NO"
|
||||||
|
if build.CanBuild then
|
||||||
|
txtok = "YES"
|
||||||
|
end
|
||||||
|
local text = string.format("Type: %s | Required %d | Found %d | Can Repair %s", name, needed, found, txtok)
|
||||||
|
report:Add(text)
|
||||||
|
end -- end list buildables
|
||||||
|
if not foundbuilds then report:Add(" --- None Found ---") end
|
||||||
|
report:Add("------------------------------------------------------------")
|
||||||
|
local text = report:Text()
|
||||||
|
self:_SendMessage(text, 30, true, Group)
|
||||||
|
-- let\'s get going
|
||||||
|
if canbuild then
|
||||||
|
-- loop again
|
||||||
|
for _,_build in pairs(buildables) do
|
||||||
|
local build = _build -- #CTLD.Buildable
|
||||||
|
if build.CanBuild then
|
||||||
|
self:_RepairObjectFromCrates(Group,Unit,crates,build,number)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:_SendMessage(string.format("No crates within %d meters!",finddist), 10, false, Group)
|
||||||
|
end -- number > 0
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Function to actually SPAWN buildables in the mission.
|
--- (Internal) Function to actually SPAWN buildables in the mission.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
-- @param Wrapper.Group#GROUP Group
|
-- @param Wrapper.Group#GROUP Group
|
||||||
-- @param Wrapper.Group#UNIT Unit
|
-- @param Wrapper.Group#UNIT Unit
|
||||||
-- @param #CTLD.Buildable Build
|
-- @param #CTLD.Buildable Build
|
||||||
function CTLD:_BuildObjectFromCrates(Group,Unit,Build)
|
-- @param #boolean Repair If true this is a repair and not a new build
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Location for repair (e.g. where the destroyed unit was)
|
||||||
|
function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
|
||||||
self:T(self.lid .. " _BuildObjectFromCrates")
|
self:T(self.lid .. " _BuildObjectFromCrates")
|
||||||
-- Spawn-a-crate-content
|
-- Spawn-a-crate-content
|
||||||
local position = Unit:GetCoordinate() or Group:GetCoordinate()
|
local position = Unit:GetCoordinate() or Group:GetCoordinate()
|
||||||
@ -1613,17 +1887,31 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build)
|
|||||||
local temptable = Build.Template or {}
|
local temptable = Build.Template or {}
|
||||||
local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,100)
|
local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,100)
|
||||||
local randomcoord = zone:GetRandomCoordinate(35):GetVec2()
|
local randomcoord = zone:GetRandomCoordinate(35):GetVec2()
|
||||||
|
if Repair then
|
||||||
|
randomcoord = RepairLocation:GetVec2()
|
||||||
|
end
|
||||||
for _,_template in pairs(temptable) do
|
for _,_template in pairs(temptable) do
|
||||||
self.TroopCounter = self.TroopCounter + 1
|
self.TroopCounter = self.TroopCounter + 1
|
||||||
|
if canmove then
|
||||||
local alias = string.format("%s-%d", _template, math.random(1,100000))
|
local alias = string.format("%s-%d", _template, math.random(1,100000))
|
||||||
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
||||||
:InitRandomizeUnits(true,20,2)
|
:InitRandomizeUnits(true,20,2)
|
||||||
:InitDelayOff()
|
:InitDelayOff()
|
||||||
:SpawnFromVec2(randomcoord)
|
:SpawnFromVec2(randomcoord)
|
||||||
|
else -- don't random position of e.g. SAM units build as FOB
|
||||||
|
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
||||||
|
--:InitRandomizeUnits(true,20,2)
|
||||||
|
:InitDelayOff()
|
||||||
|
:SpawnFromVec2(randomcoord)
|
||||||
|
end
|
||||||
if self.movetroopstowpzone and canmove then
|
if self.movetroopstowpzone and canmove then
|
||||||
self:_MoveGroupToZone(self.DroppedTroops[self.TroopCounter])
|
self:_MoveGroupToZone(self.DroppedTroops[self.TroopCounter])
|
||||||
end
|
end
|
||||||
|
if Repair then
|
||||||
|
self:__CratesRepaired(1,Group,Unit,self.DroppedTroops[self.TroopCounter])
|
||||||
|
else
|
||||||
self:__CratesBuild(1,Group,Unit,self.DroppedTroops[self.TroopCounter])
|
self:__CratesBuild(1,Group,Unit,self.DroppedTroops[self.TroopCounter])
|
||||||
|
end
|
||||||
end -- template loop
|
end -- template loop
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -1756,7 +2044,8 @@ function CTLD:_RefreshF10Menus()
|
|||||||
end
|
end
|
||||||
listmenu = MENU_GROUP_COMMAND:New(_group,"List crates nearby",topcrates, self._ListCratesNearby, self, _group, _unit)
|
listmenu = MENU_GROUP_COMMAND:New(_group,"List crates nearby",topcrates, self._ListCratesNearby, self, _group, _unit)
|
||||||
local unloadmenu = MENU_GROUP_COMMAND:New(_group,"Drop crates",topcrates, self._UnloadCrates, self, _group, _unit)
|
local unloadmenu = MENU_GROUP_COMMAND:New(_group,"Drop crates",topcrates, self._UnloadCrates, self, _group, _unit)
|
||||||
local buildmenu = MENU_GROUP_COMMAND:New(_group,"Build crates",topcrates, self._BuildCrates, self, _group, _unit):Refresh()
|
local buildmenu = MENU_GROUP_COMMAND:New(_group,"Build crates",topcrates, self._BuildCrates, self, _group, _unit)
|
||||||
|
local repairmenu = MENU_GROUP_COMMAND:New(_group,"Repair",topcrates, self._RepairCrates, self, _group, _unit):Refresh()
|
||||||
end
|
end
|
||||||
-- sub menu troops management
|
-- sub menu troops management
|
||||||
if cantroops then
|
if cantroops then
|
||||||
@ -1791,11 +2080,12 @@ function CTLD:_RefreshF10Menus()
|
|||||||
-- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP making up this troop.
|
-- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP making up this troop.
|
||||||
-- @param #CTLD_CARGO.Enum Type Type of cargo, here TROOPS - these will move to a nearby destination zone when dropped/build.
|
-- @param #CTLD_CARGO.Enum Type Type of cargo, here TROOPS - these will move to a nearby destination zone when dropped/build.
|
||||||
-- @param #number NoTroops Size of the group in number of Units across combined templates (for loading).
|
-- @param #number NoTroops Size of the group in number of Units across combined templates (for loading).
|
||||||
function CTLD:AddTroopsCargo(Name,Templates,Type,NoTroops)
|
-- @param #number PerTroopMass Mass in kg of each soldier
|
||||||
|
function CTLD:AddTroopsCargo(Name,Templates,Type,NoTroops,PerTroopMass)
|
||||||
self:T(self.lid .. " AddTroopsCargo")
|
self:T(self.lid .. " AddTroopsCargo")
|
||||||
self.CargoCounter = self.CargoCounter + 1
|
self.CargoCounter = self.CargoCounter + 1
|
||||||
-- Troops are directly loadable
|
-- Troops are directly loadable
|
||||||
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,true,NoTroops)
|
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,true,NoTroops,nil,nil,PerTroopMass)
|
||||||
table.insert(self.Cargo_Troops,cargo)
|
table.insert(self.Cargo_Troops,cargo)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -1806,11 +2096,28 @@ end
|
|||||||
-- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP building this cargo.
|
-- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP building this cargo.
|
||||||
-- @param #CTLD_CARGO.Enum Type Type of cargo. I.e. VEHICLE or FOB. VEHICLE will move to destination zones when dropped/build, FOB stays put.
|
-- @param #CTLD_CARGO.Enum Type Type of cargo. I.e. VEHICLE or FOB. VEHICLE will move to destination zones when dropped/build, FOB stays put.
|
||||||
-- @param #number NoCrates Number of crates needed to build this cargo.
|
-- @param #number NoCrates Number of crates needed to build this cargo.
|
||||||
function CTLD:AddCratesCargo(Name,Templates,Type,NoCrates)
|
-- @param #number PerCrateMass Mass in kg of each crate
|
||||||
|
function CTLD:AddCratesCargo(Name,Templates,Type,NoCrates,PerCrateMass)
|
||||||
self:T(self.lid .. " AddCratesCargo")
|
self:T(self.lid .. " AddCratesCargo")
|
||||||
self.CargoCounter = self.CargoCounter + 1
|
self.CargoCounter = self.CargoCounter + 1
|
||||||
-- Crates are not directly loadable
|
-- Crates are not directly loadable
|
||||||
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,false,NoCrates)
|
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,false,NoCrates,nil,nil,PerCrateMass)
|
||||||
|
table.insert(self.Cargo_Crates,cargo)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- User function - Add *generic* repair crates loadable as cargo. This type will create crates that need to be loaded, moved, dropped and built.
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @param #string Name Unique name of this type of cargo. E.g. "Humvee".
|
||||||
|
-- @param #string Template Template of VEHICLE or FOB cargo that this can repair.
|
||||||
|
-- @param #CTLD_CARGO.Enum Type Type of cargo, here REPAIR.
|
||||||
|
-- @param #number NoCrates Number of crates needed to build this cargo.
|
||||||
|
-- @param #number PerCrateMass Mass in kg of each crate
|
||||||
|
function CTLD:AddCratesRepair(Name,Template,Type,NoCrates, PerCrateMass)
|
||||||
|
self:T(self.lid .. " AddCratesRepair")
|
||||||
|
self.CargoCounter = self.CargoCounter + 1
|
||||||
|
-- Crates are not directly loadable
|
||||||
|
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Template,Type,false,false,NoCrates,nil,nil,PerCrateMass)
|
||||||
table.insert(self.Cargo_Crates,cargo)
|
table.insert(self.Cargo_Crates,cargo)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -1840,15 +2147,15 @@ function CTLD:ActivateZone(Name,ZoneType,NewState)
|
|||||||
self:T(self.lid .. " AddZone")
|
self:T(self.lid .. " AddZone")
|
||||||
local newstate = true
|
local newstate = true
|
||||||
-- set optional in case we\'re deactivating
|
-- set optional in case we\'re deactivating
|
||||||
if not NewState or NewState == false then
|
if NewState ~= nil then
|
||||||
newstate = false
|
newstate = NewState
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get correct table
|
-- get correct table
|
||||||
local zone = ZoneType -- #CTLD.CargoZone
|
|
||||||
local table = {}
|
local table = {}
|
||||||
if zone.type == CTLD.CargoZoneType.LOAD then
|
if ZoneType == CTLD.CargoZoneType.LOAD then
|
||||||
table = self.pickupZones
|
table = self.pickupZones
|
||||||
elseif zone.type == CTLD.CargoZoneType.DROP then
|
elseif ZoneType == CTLD.CargoZoneType.DROP then
|
||||||
table = self.dropOffZones
|
table = self.dropOffZones
|
||||||
else
|
else
|
||||||
table = self.wpZones
|
table = self.wpZones
|
||||||
@ -1864,6 +2171,7 @@ function CTLD:ActivateZone(Name,ZoneType,NewState)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- User function - Deactivate Name #CTLD.CargoZoneType ZoneType for this CTLD instance.
|
--- User function - Deactivate Name #CTLD.CargoZoneType ZoneType for this CTLD instance.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
-- @param #string Name Name of the zone to change in the ME.
|
-- @param #string Name Name of the zone to change in the ME.
|
||||||
@ -2348,6 +2656,20 @@ end
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Run through DroppedTroops and capture alive units
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @return #CTLD self
|
||||||
|
function CTLD:CleanDroppedTroops()
|
||||||
|
local troops = self.DroppedTroops
|
||||||
|
local newtable = {}
|
||||||
|
for _index, _group in pairs (troops) do
|
||||||
|
if _group and _group:IsAlive() then
|
||||||
|
newtable[_index] = _group
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.DroppedTroops = newtable
|
||||||
|
return self
|
||||||
|
end
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
-- FSM functions
|
-- FSM functions
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
@ -2387,6 +2709,7 @@ end
|
|||||||
-- @return #CTLD self
|
-- @return #CTLD self
|
||||||
function CTLD:onbeforeStatus(From, Event, To)
|
function CTLD:onbeforeStatus(From, Event, To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
|
self:CleanDroppedTroops()
|
||||||
self:_RefreshF10Menus()
|
self:_RefreshF10Menus()
|
||||||
self:_RefreshRadioBeacons()
|
self:_RefreshRadioBeacons()
|
||||||
self:CheckAutoHoverload()
|
self:CheckAutoHoverload()
|
||||||
|
|||||||
@ -580,6 +580,18 @@ function UNIT:GetAmmo()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Sets the Unit's Internal Cargo Mass, in kg
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @param #number mass to set cargo to
|
||||||
|
-- @return #UNIT self
|
||||||
|
function UNIT:SetUnitInternalCargo(mass)
|
||||||
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
if DCSUnit then
|
||||||
|
trigger.action.setUnitInternalCargo(DCSUnit:getName(), mass)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Get the number of ammunition and in particular the number of shells, rockets, bombs and missiles a unit currently has.
|
--- Get the number of ammunition and in particular the number of shells, rockets, bombs and missiles a unit currently has.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number Total amount of ammo the unit has left. This is the sum of shells, rockets, bombs and missiles.
|
-- @return #number Total amount of ammo the unit has left. This is the sum of shells, rockets, bombs and missiles.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user