From 6360b8c58f2dcb9de9d556c91f134eefd6fb7429 Mon Sep 17 00:00:00 2001 From: TommyC81 Date: Sat, 4 Dec 2021 21:50:05 +0400 Subject: [PATCH] General documentation and code fixes (#1650) Documentation updates for correctness and clarity. General code formatting updates. Ajustment to POSITIONABLE:GetCoord to make use of existing POINT:UpdateFromVec3. Added comments about clarifying the difference between POSITIONABLE:GetCoordinate() and POSITIONABLE:GetCoord() and to perhaps consider a renaming or merging the functions with an optional flag. --- Moose Development/Moose/Core/Point.lua | 73 ++- Moose Development/Moose/Functional/Range.lua | 88 +-- .../Moose/Wrapper/Positionable.lua | 508 +++++++++--------- Moose Development/Moose/Wrapper/Static.lua | 140 +++-- Moose Development/Moose/Wrapper/Unit.lua | 16 - 5 files changed, 408 insertions(+), 417 deletions(-) diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index f79d54593..1851db807 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -314,39 +314,38 @@ do -- COORDINATE -- @param DCS#Vec3 Vec3 The 3D vector with x,y,z components. -- @return #COORDINATE The modified COORDINATE itself. function COORDINATE:UpdateFromVec3(Vec3) - + self.x=Vec3.x self.y=Vec3.y self.z=Vec3.z - + return self end - + --- Update x,y,z coordinates from another given COORDINATE. -- @param #COORDINATE self -- @param #COORDINATE Coordinate The coordinate with the new x,y,z positions. -- @return #COORDINATE The modified COORDINATE itself. function COORDINATE:UpdateFromCoordinate(Coordinate) - + self.x=Coordinate.x self.y=Coordinate.y self.z=Coordinate.z - + return self - end + end --- Update x and z coordinates from a given 2D vector. -- @param #COORDINATE self -- @param DCS#Vec2 Vec2 The 2D vector with x,y components. x is overwriting COORDINATE.x while y is overwriting COORDINATE.z. -- @return #COORDINATE The modified COORDINATE itself. function COORDINATE:UpdateFromVec2(Vec2) - + self.x=Vec2.x self.z=Vec2.y - + return self end - --- Returns the coordinate from the latitude and longitude given in decimal degrees. -- @param #COORDINATE self @@ -355,13 +354,13 @@ do -- COORDINATE -- @param #number altitude (Optional) Altitude in meters. Default is the land height at the coordinate. -- @return #COORDINATE function COORDINATE:NewFromLLDD( latitude, longitude, altitude) - + -- Returns a point from latitude and longitude in the vec3 format. local vec3=coord.LLtoLO(latitude, longitude) - + -- Convert vec3 to coordinate object. local _coord=self:NewFromVec3(vec3) - + -- Adjust height if altitude==nil then _coord.y=self:GetLandHeight() @@ -372,23 +371,22 @@ do -- COORDINATE return _coord end - --- Returns if the 2 coordinates are at the same 2D position. -- @param #COORDINATE self -- @param #COORDINATE Coordinate -- @param #number Precision -- @return #boolean true if at the same position. function COORDINATE:IsAtCoordinate2D( Coordinate, Precision ) - + self:F( { Coordinate = Coordinate:GetVec2() } ) self:F( { self = self:GetVec2() } ) - + local x = Coordinate.x local z = Coordinate.z - + return x - Precision <= self.x and x + Precision >= self.x and z - Precision <= self.z and z + Precision >= self.z end - + --- Scan/find objects (units, statics, scenery) within a certain radius around the coordinate using the world.searchObjects() DCS API function. -- @param #COORDINATE self -- @param #number radius (Optional) Scan radius in meters. Default 100 m. @@ -423,7 +421,7 @@ do -- COORDINATE if scanscenery==nil then scanscenery=false end - + --{Object.Category.UNIT, Object.Category.STATIC, Object.Category.SCENERY} local scanobjects={} if scanunits then @@ -435,7 +433,7 @@ do -- COORDINATE if scanscenery then table.insert(scanobjects, Object.Category.SCENERY) end - + -- Found stuff. local Units = {} local Statics = {} @@ -443,40 +441,40 @@ do -- COORDINATE local gotstatics=false local gotunits=false local gotscenery=false - + local function EvaluateZone(ZoneObject) - + if ZoneObject then - + -- Get category of scanned object. local ObjectCategory = ZoneObject:getCategory() - + -- Check for unit or static objects if ObjectCategory==Object.Category.UNIT and ZoneObject:isExist() then - + table.insert(Units, UNIT:Find(ZoneObject)) gotunits=true - + elseif ObjectCategory==Object.Category.STATIC and ZoneObject:isExist() then - + table.insert(Statics, ZoneObject) gotstatics=true - + elseif ObjectCategory==Object.Category.SCENERY then - + table.insert(Scenery, ZoneObject) gotscenery=true - + end - + end - + return true end - + -- Search the world. world.searchObjects(scanobjects, SphereSearch, EvaluateZone) - + for _,unit in pairs(Units) do self:T(string.format("Scan found unit %s", unit:GetName())) end @@ -551,7 +549,7 @@ do -- COORDINATE -- @param DCS#Distance Distance The Distance to be added in meters. -- @param DCS#Angle Angle The Angle in degrees. Defaults to 0 if not specified (nil). -- @param #boolean Keepalt If true, keep altitude of original coordinate. Default is that the new coordinate is created at the translated land height. - -- @param #boolean Overwrite If true, overwrite the original COORDINATE with the translated one. Otherwise, create a new COODINATE. + -- @param #boolean Overwrite If true, overwrite the original COORDINATE with the translated one. Otherwise, create a new COORDINATE. -- @return #COORDINATE The new calculated COORDINATE. function COORDINATE:Translate( Distance, Angle, Keepalt, Overwrite ) @@ -2987,7 +2985,7 @@ do -- POINT_VEC3 local self = BASE:Inherit( self, COORDINATE:New( x, y, z ) ) -- Core.Point#POINT_VEC3 self:F2( self ) - + return self end @@ -3004,7 +3002,6 @@ do -- POINT_VEC3 return self end - --- Create a new POINT_VEC3 object from Vec3 coordinates. -- @param #POINT_VEC3 self -- @param DCS#Vec3 Vec3 The Vec3 point. @@ -3013,12 +3010,10 @@ do -- POINT_VEC3 local self = BASE:Inherit( self, COORDINATE:NewFromVec3( Vec3 ) ) -- Core.Point#POINT_VEC3 self:F2( self ) - + return self end - - --- Return the x coordinate of the POINT_VEC3. -- @param #POINT_VEC3 self -- @return #number The x coodinate. diff --git a/Moose Development/Moose/Functional/Range.lua b/Moose Development/Moose/Functional/Range.lua index 9f4675ef7..64c4d49a3 100644 --- a/Moose Development/Moose/Functional/Range.lua +++ b/Moose Development/Moose/Functional/Range.lua @@ -152,7 +152,7 @@ -- -- * The first parameter *targetnames* defines the target or targets. This can be a single item or a Table with the name(s) of @{Wrapper.Unit} or @{Static} objects defined in the mission editor. -- * The (optional) parameter *goodhitrange* specifies the radius in metres around the target within which a bomb/rocket hit is considered to be "good". --- * If final (optional) parameter "*randommove*" can be enabled to create moving targets. If this parameter is set to true, the units of this bombing target will randomly move within the range zone. +-- * If final (optional) parameter *randommove* can be enabled to create moving targets. If this parameter is set to true, the units of this bombing target will randomly move within the range zone. -- Note that there might be quirks since DCS units can get stuck in buildings etc. So it might be safer to manually define a route for the units in the mission editor if moving targets are desired. -- -- ## Adding Groups @@ -903,10 +903,10 @@ end --- Set player setting whether bomb impact points are smoked or not. -- @param #RANGE self --- @param #boolean switch If true nor nil default is to smoke impact points of bombs. +-- @param #boolean switch (Optional) If true, impact points of bombs will be smoked. Default is true. -- @return #RANGE self function RANGE:SetDefaultPlayerSmokeBomb(switch) - if switch==true or switch==nil then + if switch == nil or switch == true then self.defaultsmokebomb=true else self.defaultsmokebomb=false @@ -1249,7 +1249,7 @@ end -- @param #number boxlength (Optional) Length of the approach box in meters. Default is 3000 m. -- @param #number boxwidth (Optional) Width of the approach box in meters. Default is 300 m. -- @param #number heading (Optional) Approach heading in Degrees. Default is heading of the unit as defined in the mission editor. --- @param #boolean inverseheading (Optional) Take inverse heading (heading --> heading - 180 Degrees). Default is false. +-- @param #boolean inverseheading (Optional) Use inverse heading (heading --> heading - 180 Degrees). Default is false. -- @param #number goodpass (Optional) Number of hits for a "good" strafing pass. Default is 20. -- @param #number foulline (Optional) Foul line distance. Hits from closer than this distance are not counted. Default 610 m = 2000 ft. Set to 0 for no foul line. -- @return #RANGE self @@ -1284,8 +1284,8 @@ end --- Add bombing target(s) to range. -- @param #RANGE self -- @param #table targetnames Single or multiple (Table) names of unit or static objects serving as bomb targets. --- @param #number goodhitrange (Optional) Max distance from target unit (in meters) which is considered as a good hit. Default is 25 m. --- @param #boolean randommove If true, unit will move randomly within the range. Default is false. +-- @param #number goodhitrange (Optional) Max hit distance from target unit in meters which is considered as a good hit. Default is 25 m. +-- @param #boolean randommove (Optional) If true, unit will move randomly within the range. Default is false. -- @return #RANGE self function RANGE:AddBombingTargets(targetnames, goodhitrange, randommove) self:F({targetnames=targetnames, goodhitrange=goodhitrange, randommove=randommove}) @@ -1323,8 +1323,8 @@ end --- Add a unit or static object as bombing target. -- @param #RANGE self -- @param Wrapper.Positionable#POSITIONABLE unit Positionable (unit or static) of the strafe target. --- @param #number goodhitrange Max distance from unit which is considered as a good hit. --- @param #boolean randommove If true, unit will move randomly within the range. Default is false. +-- @param #number goodhitrange (Optional) Max hit distance from target unit in meters which is considered as a good hit. Default is 25 m. +-- @param #boolean randommove (Optional) If true, unit will move randomly within the range. Default is false. -- @return #RANGE self function RANGE:AddBombingTargetUnit(unit, goodhitrange, randommove) self:F({unit=unit, goodhitrange=goodhitrange, randommove=randommove}) @@ -1339,7 +1339,7 @@ function RANGE:AddBombingTargetUnit(unit, goodhitrange, randommove) goodhitrange=goodhitrange or RANGE.Defaults.goodhitrange -- Set randommove to false if it was not specified. - if randommove==nil or _isstatic==true then + if randommove == nil or _isstatic == true then randommove=false end @@ -1354,7 +1354,7 @@ function RANGE:AddBombingTargetUnit(unit, goodhitrange, randommove) -- Get max speed of unit in km/h. local speed=0 - if _isstatic==false then + if _isstatic == false then speed=self:_GetSpeed(unit) end @@ -1377,12 +1377,23 @@ function RANGE:AddBombingTargetUnit(unit, goodhitrange, randommove) return self end ---- Add a coordinate of a bombing target. This +--- Add a coordinate of a bombing target. -- @param #RANGE self -- @param Core.Point#COORDINATE coord The coordinate. --- @param #string name Name of target. --- @param #number goodhitrange Max distance from unit which is considered as a good hit. +-- @param #string name (Optional) Name of target. Default is "Bomb Target". +-- @param #number goodhitrange (Optional) Max hit distance from target unit in meters which is considered as a good hit. Default is 25 m. -- @return #RANGE self +-- @usage +-- +-- -- Setup a Range +-- RangeOne = RANGE:New( "Range One" ) +-- -- Find the STATIC target object as setup in the ME +-- RangeOneBombTarget = STATIC:FindByName( "RangeOneBombTarget" ): +-- -- Add the coordinate of the STATIC target object as a bomb target (thus keeping the bomb function active, even if the STATIC target is destroyed) +-- RangeOne:AddBombingTargetCoordinate( RangeOneBombTarget:GetCoordinate(), "RangeOneBombTarget", 50) +-- -- Or, add the coordinate of the STATIC target object as a bomb target using default values (name will be "Bomb Target", goodhitrange will be 25 m) +-- RangeOne:AddBombingTargetCoordinate( RangeOneBombTarget:GetCoordinate() ) +-- function RANGE:AddBombingTargetCoordinate(coord, name, goodhitrange) local target={} --#RANGE.BombTarget @@ -1403,8 +1414,8 @@ end --- Add all units of a group as bombing targets. -- @param #RANGE self -- @param Wrapper.Group#GROUP group Group of bombing targets. --- @param #number goodhitrange Max distance from unit which is considered as a good hit. --- @param #boolean randommove If true, unit will move randomly within the range. Default is false. +-- @param #number goodhitrange (Optional) Max hit distance from target unit in meters which is considered as a good hit. Default is 25 m. +-- @param #boolean randommove (Optional) If true, unit will move randomly within the range. Default is false. -- @return #RANGE self function RANGE:AddBombingTargetGroup(group, goodhitrange, randommove) self:F({group=group, goodhitrange=goodhitrange, randommove=randommove}) @@ -1423,10 +1434,10 @@ function RANGE:AddBombingTargetGroup(group, goodhitrange, randommove) return self end ---- Measures the foule line distance between two unit or static objects. +--- Returns the foul line distance between strafe pit target and a foul line distance marker object. -- @param #RANGE self -- @param #string namepit Name of the strafe pit target object. --- @param #string namefoulline Name of the fould line distance marker object. +-- @param #string namefoulline Name of the foul line distance marker object. -- @return #number Foul line distance in meters. function RANGE:GetFoullineDistance(namepit, namefoulline) self:F({namepit=namepit, namefoulline=namefoulline}) @@ -1437,7 +1448,7 @@ function RANGE:GetFoullineDistance(namepit, namefoulline) -- Get the unit or static pit object. local pit=nil - if _staticpit==true then + if _staticpit == true then pit=STATIC:FindByName(namepit, false) elseif _staticpit==false then pit=UNIT:FindByName(namepit) @@ -1447,9 +1458,9 @@ function RANGE:GetFoullineDistance(namepit, namefoulline) -- Get the unit or static foul line object. local foul=nil - if _staticfoul==true then + if _staticfoul == true then foul=STATIC:FindByName(namefoulline, false) - elseif _staticfoul==false then + elseif _staticfoul == false then foul=UNIT:FindByName(namefoulline) else self:E(self.id..string.format("ERROR! Foul line object %s could not be found in GetFoullineDistance function. Check the name in the ME.", namefoulline)) @@ -1457,7 +1468,7 @@ function RANGE:GetFoullineDistance(namepit, namefoulline) -- Get the distance between the two objects. local fouldist=0 - if pit~=nil and foul~=nil then + if pit ~= nil and foul ~= nil then fouldist=pit:GetCoordinate():Get2DDistance(foul:GetCoordinate()) else self:E(self.id..string.format("ERROR! Foul line distance could not be determined. Check pit object name %s and foul line object name %s in the ME.", namepit, namefoulline)) @@ -1552,7 +1563,6 @@ function RANGE:OnEventBirth(EventData) self:T3(self.id.."BIRTH: player = "..tostring(_playername)) if _unit and _playername then - local _uid=_unit:GetID() local _group=_unit:GetGroup() local _gid=_group:GetID() @@ -1589,8 +1599,8 @@ function RANGE:OnEventBirth(EventData) self.timerCheckZone=TIMER:New(self._CheckInZone, self, EventData.IniUnitName):Start(1, 1) self.planes[_uid] = true end - end + end --- Range event handler for event hit. @@ -1607,7 +1617,7 @@ function RANGE:OnEventHit(EventData) -- Player info local _unitName = EventData.IniUnitName local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) - if _unit==nil or _playername==nil then + if _unit == nil or _playername == nil then return end @@ -1681,6 +1691,7 @@ function RANGE:OnEventHit(EventData) end end end + end --- Range event handler for event shot (when a unit releases a rocket or bomb (but not a fast firing gun). @@ -1690,10 +1701,10 @@ function RANGE:OnEventShot(EventData) self:F({eventshot = EventData}) -- Nil checks. - if EventData.Weapon==nil then + if EventData.Weapon == nil then return end - if EventData.IniDCSUnit==nil then + if EventData.IniDCSUnit == nil then return end @@ -1741,7 +1752,6 @@ function RANGE:OnEventShot(EventData) -- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons. if _track and dPR<=self.BombtrackThreshold and _unit and _playername then - -- Player data. local playerData=self.PlayerSettings[_playername] --#RANGE.PlayerData @@ -1911,7 +1921,7 @@ function RANGE:onafterStatus(From, Event, To) local text=string.format("Range status: %s", fsmstate) - if self.instructor then + if self.instructor then local alive="N/A" if self.instructorrelayname then local relay=UNIT:FindByName(self.instructorrelayname) @@ -2363,7 +2373,7 @@ function RANGE:_DisplayMyBombingResults(_unitName) end -- Best 10 runs only. - if i==self.ndisplayresult then + if i == self.ndisplayresult then break end @@ -2694,7 +2704,7 @@ function RANGE:_CheckPlayers() if not playersettings.inzone then playersettings.inzone=true - self:EnterRange(playersettings) + self:EnterRange(playersettings) end else @@ -2705,7 +2715,7 @@ function RANGE:_CheckPlayers() if playersettings.inzone==true then playersettings.inzone=false - self:ExitRange(playersettings) + self:ExitRange(playersettings) end end @@ -2738,12 +2748,12 @@ function RANGE:_CheckInZone(_unitName) if towardspit then local vec3=_unit:GetVec3() - local vec2={x=vec3.x, y=vec3.z} --DCS#Vec2 - local landheight=land.getHeight(vec2) + local vec2={x=vec3.x, y=vec3.z} --DCS#Vec2 + local landheight=land.getHeight(vec2) local unitalt=vec3.y-landheight - if unitalt<=self.strafemaxalt then - local unitinzone=zone:IsVec2InZone(vec2) + if unitalt<=self.strafemaxalt then + local unitinzone=zone:IsVec2InZone(vec2) return unitinzone end end @@ -3008,7 +3018,7 @@ end -- Helper Functions ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Get the number of shells a unit currently has. +--- Get the coordinate of a Bomb target. -- @param #RANGE self -- @param #RANGE.BombTarget target Bomb target data. -- @return Core.Point#COORDINATE Target coordinate. @@ -3016,7 +3026,7 @@ function RANGE:_GetBombTargetCoordinate(target) local coord=nil --Core.Point#COORDINATE - if target.type==RANGE.TargetType.UNIT then + if target.type == RANGE.TargetType.UNIT then if not target.move then -- Target should not move. @@ -3028,12 +3038,12 @@ function RANGE:_GetBombTargetCoordinate(target) end end - elseif target.type==RANGE.TargetType.STATIC then + elseif target.type == RANGE.TargetType.STATIC then -- Static targets dont move. coord=target.coordinate - elseif target.type==RANGE.TargetType.COORD then + elseif target.type == RANGE.TargetType.COORD then -- Coordinates dont move. coord=target.coordinate diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index e4a7b4e4c..b2706fa02 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -57,7 +57,6 @@ POSITIONABLE.__ = {} --- @field #POSITIONABLE.__.Cargo POSITIONABLE.__.Cargo = {} - --- A DCSPositionable -- @type DCSPositionable -- @field id_ The ID of the controllable in DCS @@ -75,16 +74,19 @@ end --- Destroys the POSITIONABLE. -- @param #POSITIONABLE self --- @param #boolean GenerateEvent (Optional) true if you want to generate a crash or dead event for the unit. +-- @param #boolean GenerateEvent (Optional) If true, generates a crash or dead event for the unit. If false, no event generated. If nil, a remove event is generated. -- @return #nil The DCS Unit is not existing or alive. -- @usage --- -- Air unit example: destroy the Helicopter and generate a S_EVENT_CRASH for each unit in the Helicopter group. +-- +-- Air unit example: destroy the Helicopter and generate a S_EVENT_CRASH for each unit in the Helicopter group. -- Helicopter = UNIT:FindByName( "Helicopter" ) -- Helicopter:Destroy( true ) +-- -- @usage -- -- Ground unit example: destroy the Tanks and generate a S_EVENT_DEAD for each unit in the Tanks group. -- Tanks = UNIT:FindByName( "Tanks" ) -- Tanks:Destroy( true ) +-- -- @usage -- -- Ship unit example: destroy the Ship silently. -- Ship = STATIC:FindByName( "Ship" ) @@ -147,7 +149,7 @@ function POSITIONABLE:GetPosition() return PositionablePosition end - BASE:E( { "Cannot GetPositionVec3", Positionable = self, Alive = self:IsAlive() } ) + BASE:E( { "Cannot GetPosition", Positionable = self, Alive = self:IsAlive() } ) return nil end @@ -157,8 +159,9 @@ end -- @return DCS#Vec3 X orientation, i.e. parallel to the direction of movement. -- @return DCS#Vec3 Y orientation, i.e. vertical. -- @return DCS#Vec3 Z orientation, i.e. perpendicular to the direction of movement. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetOrientation() - local position=self:GetPosition() + local position = self:GetPosition() if position then return position.x, position.y, position.z else @@ -170,8 +173,9 @@ end --- Returns a {@DCS#Vec3} table of the objects current X orientation in 3D space, i.e. along the direction of movement. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Vec3 X orientation, i.e. parallel to the direction of movement. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetOrientationX() - local position=self:GetPosition() + local position = self:GetPosition() if position then return position.x else @@ -183,8 +187,9 @@ end --- Returns a {@DCS#Vec3} table of the objects current Y orientation in 3D space, i.e. vertical orientation. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Vec3 Y orientation, i.e. vertical. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetOrientationY() - local position=self:GetPosition() + local position = self:GetPosition() if position then return position.y else @@ -196,8 +201,9 @@ end --- Returns a {@DCS#Vec3} table of the objects current Z orientation in 3D space, i.e. perpendicular to direction of movement. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Vec3 Z orientation, i.e. perpendicular to movement. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetOrientationZ() - local position=self:GetPosition() + local position = self:GetPosition() if position then return position.z else @@ -228,19 +234,20 @@ end --- Returns the @{DCS#Vec3} vector indicating the 3D vector of the POSITIONABLE within the mission. -- @param Wrapper.Positionable#POSITIONABLE self --- @return DCS#Vec3 The 3D point vector of the POSITIONABLE or `nil` if it is not existing or alive. +-- @return DCS#Vec3 The 3D point vector of the POSITIONABLE. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetVec3() local DCSPositionable = self:GetDCSObject() if DCSPositionable then - local vec3=DCSPositionable:getPoint() + local vec3 = DCSPositionable:getPoint() if vec3 then return vec3 else - self:E("ERROR: Cannot get vec3!") + self:E( "ERROR: Cannot get vec3!" ) end end @@ -251,16 +258,17 @@ end --- Returns the @{DCS#Vec2} vector indicating the point in 2D of the POSITIONABLE within the mission. -- @param Wrapper.Positionable#POSITIONABLE self --- @return DCS#Vec2 The 2D point vector of the POSITIONABLE or #nil if it is not existing or alive. +-- @return DCS#Vec2 The 2D point vector of the POSITIONABLE. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetVec2() local DCSPositionable = self:GetDCSObject() if DCSPositionable then - local Vec3=DCSPositionable:getPoint() --DCS#Vec3 + local Vec3 = DCSPositionable:getPoint() -- DCS#Vec3 - return {x=Vec3.x, y=Vec3.z} + return { x = Vec3.x, y = Vec3.z } end self:E( { "Cannot GetVec2", Positionable = self, Alive = self:IsAlive() } ) @@ -282,7 +290,7 @@ function POSITIONABLE:GetPointVec2() local PositionablePointVec2 = POINT_VEC2:NewFromVec3( PositionableVec3 ) - --self:F( PositionablePointVec2 ) + -- self:F( PositionablePointVec2 ) return PositionablePointVec2 end @@ -307,14 +315,14 @@ function POSITIONABLE:GetPointVec3() if false and self.pointvec3 then -- Update vector. - self.pointvec3.x=PositionableVec3.x - self.pointvec3.y=PositionableVec3.y - self.pointvec3.z=PositionableVec3.z + self.pointvec3.x = PositionableVec3.x + self.pointvec3.y = PositionableVec3.y + self.pointvec3.z = PositionableVec3.z else -- Create a new POINT_VEC3 object. - self.pointvec3=POINT_VEC3:NewFromVec3(PositionableVec3) + self.pointvec3 = POINT_VEC3:NewFromVec3( PositionableVec3 ) end @@ -327,8 +335,10 @@ function POSITIONABLE:GetPointVec3() end --- Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission. +-- If the POSITIONABLE has a COORDINATE OBJECT set, it updates it. If not, it creates a new COORDINATE object. -- @param Wrapper.Positionable#POSITIONABLE self -- @return Core.Point#COORDINATE The COORDINATE of the POSITIONABLE. +-- TODO: Seems to have been introduced with Airboss. Should it be renamed to better reflect the difference to "GetCoordinate" (it is currently ambiguous)? Or perhaps just be a switch in the the GetCoordinate function; forceCoordinateUpate? function POSITIONABLE:GetCoord() -- Get DCS object. @@ -337,20 +347,14 @@ function POSITIONABLE:GetCoord() if DCSPositionable then -- Get the current position. - local Vec3 = self:GetVec3() + local PositionableVec3 = self:GetVec3() if self.coordinate then - - -- Update vector. - self.coordinate.x=Vec3.x - self.coordinate.y=Vec3.y - self.coordinate.z=Vec3.z - + -- Update COORDINATE from 3D vector. + self.coordinate:UpdateFromVec3( PositionableVec3 ) else - -- New COORDINATE. - self.coordinate=COORDINATE:NewFromVec3(Vec3) - + self.coordinate = COORDINATE:NewFromVec3( PositionableVec3 ) end return self.coordinate @@ -375,9 +379,9 @@ function POSITIONABLE:GetCoordinate() -- Get the current position. local PositionableVec3 = self:GetVec3() - local coord=COORDINATE:NewFromVec3(PositionableVec3) + local coord = COORDINATE:NewFromVec3( PositionableVec3 ) - -- Return a new coordiante object. + -- Return a new coordinate object. return coord end @@ -393,36 +397,36 @@ end -- @param #number y Offset "above" the unit in meters. Default 0 m. -- @param #number z Offset in the direction "the wing" of the unit is pointing in meters. z>0 starboard, z<0 port. Default 0 m. -- @return Core.Point#COORDINATE The COORDINATE of the offset with respect to the orientation of the POSITIONABLE. -function POSITIONABLE:GetOffsetCoordinate(x,y,z) +function POSITIONABLE:GetOffsetCoordinate( x, y, z ) -- Default if nil. - x=x or 0 - y=y or 0 - z=z or 0 + x = x or 0 + y = y or 0 + z = z or 0 -- Vectors making up the coordinate system. - local X=self:GetOrientationX() - local Y=self:GetOrientationY() - local Z=self:GetOrientationZ() + local X = self:GetOrientationX() + local Y = self:GetOrientationY() + local Z = self:GetOrientationZ() -- Offset vector: x meters ahead, z meters starboard, y meters above. - local A={x=x, y=y, z=z} + local A = { x = x, y = y, z = z } -- Scale components of orthonormal coordinate vectors. - local x={x=X.x*A.x, y=X.y*A.x, z=X.z*A.x} - local y={x=Y.x*A.y, y=Y.y*A.y, z=Y.z*A.y} - local z={x=Z.x*A.z, y=Z.y*A.z, z=Z.z*A.z} + local x = { x = X.x * A.x, y = X.y * A.x, z = X.z * A.x } + local y = { x = Y.x * A.y, y = Y.y * A.y, z = Y.z * A.y } + local z = { x = Z.x * A.z, y = Z.y * A.z, z = Z.z * A.z } -- Add up vectors in the unit coordinate system ==> this gives the offset vector relative the the origin of the map. - local a={x=x.x+y.x+z.x, y=x.y+y.y+z.y, z=x.z+y.z+z.z} + local a = { x = x.x + y.x + z.x, y = x.y + y.y + z.y, z = x.z + y.z + z.z } -- Vector from the origin of the map to the unit. - local u=self:GetVec3() + local u = self:GetVec3() -- Translate offset vector from map origin to the unit: v=u+a. - local v={x=a.x+u.x, y=a.y+u.y, z=a.z+u.z} + local v = { x = a.x + u.x, y = a.y + u.y, z = a.z + u.z } - local coord=COORDINATE:NewFromVec3(v) + local coord = COORDINATE:NewFromVec3( v ) -- Return the offset coordinate. return coord @@ -445,7 +449,7 @@ function POSITIONABLE:GetRandomVec3( Radius ) if Radius then local PositionableRandomVec3 = {} - local angle = math.random() * math.pi*2; + local angle = math.random() * math.pi * 2; PositionableRandomVec3.x = PositionablePointVec3.x + math.cos( angle ) * math.random() * Radius; PositionableRandomVec3.y = PositionablePointVec3.y PositionableRandomVec3.z = PositionablePointVec3.z + math.sin( angle ) * math.random() * Radius; @@ -453,7 +457,7 @@ function POSITIONABLE:GetRandomVec3( Radius ) self:T3( PositionableRandomVec3 ) return PositionableRandomVec3 else - self:F("Radius is nil, returning the PointVec3 of the POSITIONABLE", PositionablePointVec3) + self:F( "Radius is nil, returning the PointVec3 of the POSITIONABLE", PositionablePointVec3 ) return PositionablePointVec3 end end @@ -463,18 +467,17 @@ function POSITIONABLE:GetRandomVec3( Radius ) return nil end - --- Get the bounding box of the underlying POSITIONABLE DCS Object. -- @param #POSITIONABLE self -- @return DCS#Box3 The bounding box of the POSITIONABLE. -- @return #nil The POSITIONABLE is not existing or alive. -function POSITIONABLE:GetBoundingBox() --R2.1 +function POSITIONABLE:GetBoundingBox() self:F2() local DCSPositionable = self:GetDCSObject() if DCSPositionable then - local PositionableDesc = DCSPositionable:getDesc() --DCS#Desc + local PositionableDesc = DCSPositionable:getDesc() -- DCS#Desc if PositionableDesc then local PositionableBox = PositionableDesc.box return PositionableBox @@ -486,7 +489,6 @@ function POSITIONABLE:GetBoundingBox() --R2.1 return nil end - --- Get the object size. -- @param #POSITIONABLE self -- @return DCS#Distance Max size of object in x, z or 0 if bounding box could not be obtained. @@ -496,28 +498,29 @@ end function POSITIONABLE:GetObjectSize() -- Get bounding box. - local box=self:GetBoundingBox() + local box = self:GetBoundingBox() if box then - local x=box.max.x+math.abs(box.min.x) --length - local y=box.max.y+math.abs(box.min.y) --height - local z=box.max.z+math.abs(box.min.z) --width - return math.max(x,z), x , y, z + local x = box.max.x + math.abs( box.min.x ) -- length + local y = box.max.y + math.abs( box.min.y ) -- height + local z = box.max.z + math.abs( box.min.z ) -- width + return math.max( x, z ), x, y, z end - return 0,0,0,0 + return 0, 0, 0, 0 end --- Get the bounding radius of the underlying POSITIONABLE DCS Object. -- @param #POSITIONABLE self -- @param #number mindist (Optional) If bounding box is smaller than this value, mindist is returned. --- @return DCS#Distance The bounding radius of the POSITIONABLE or #nil if the POSITIONABLE is not existing or alive. -function POSITIONABLE:GetBoundingRadius(mindist) +-- @return DCS#Distance The bounding radius of the POSITIONABLE +-- @return #nil The POSITIONABLE is not existing or alive. +function POSITIONABLE:GetBoundingRadius( mindist ) self:F2() local Box = self:GetBoundingBox() - local boxmin=mindist or 0 + local boxmin = mindist or 0 if Box then local X = Box.max.x - Box.min.x local Z = Box.max.z - Box.min.z @@ -541,7 +544,7 @@ function POSITIONABLE:GetAltitude() local DCSPositionable = self:GetDCSObject() if DCSPositionable then - local PositionablePointVec3 = DCSPositionable:getPoint() --DCS#Vec3 + local PositionablePointVec3 = DCSPositionable:getPoint() -- DCS#Vec3 return PositionablePointVec3.y end @@ -574,7 +577,6 @@ function POSITIONABLE:IsAboveRunway() return nil end - function POSITIONABLE:GetSize() local DCSObject = self:GetDCSObject() @@ -586,11 +588,10 @@ function POSITIONABLE:GetSize() end end - - --- Returns the POSITIONABLE heading in degrees. -- @param Wrapper.Positionable#POSITIONABLE self --- @return #number The POSITIONABLE heading in degrees or `nil` if not existing or alive. +-- @return #number The POSITIONABLE heading in degrees. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetHeading() local DCSPositionable = self:GetDCSObject() @@ -598,22 +599,21 @@ function POSITIONABLE:GetHeading() if DCSPositionable then local PositionablePosition = DCSPositionable:getPosition() - + if PositionablePosition then local PositionableHeading = math.atan2( PositionablePosition.x.z, PositionablePosition.x.x ) - + if PositionableHeading < 0 then PositionableHeading = PositionableHeading + 2 * math.pi end - + PositionableHeading = PositionableHeading * 180 / math.pi - + return PositionableHeading end end - self:E({"Cannot GetHeading", Positionable = self, Alive = self:IsAlive()}) - + self:E( { "Cannot GetHeading", Positionable = self, Alive = self:IsAlive() } ) return nil end @@ -623,6 +623,7 @@ end -- If the unit is a helicopter or a plane, then this method will return true, otherwise false. -- @param #POSITIONABLE self -- @return #boolean Air category evaluation result. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:IsAir() self:F2() @@ -638,6 +639,7 @@ function POSITIONABLE:IsAir() return IsAirResult end + self:E( { "Cannot check IsAir", Positionable = self, Alive = self:IsAlive() } ) return nil end @@ -645,6 +647,7 @@ end -- If the unit is a ground vehicle or infantry, this method will return true, otherwise false. -- @param #POSITIONABLE self -- @return #boolean Ground category evaluation result. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:IsGround() self:F2() @@ -654,19 +657,20 @@ function POSITIONABLE:IsGround() local UnitDescriptor = DCSUnit:getDesc() self:T3( { UnitDescriptor.category, Unit.Category.GROUND_UNIT } ) - local IsGroundResult = ( UnitDescriptor.category == Unit.Category.GROUND_UNIT ) + local IsGroundResult = (UnitDescriptor.category == Unit.Category.GROUND_UNIT) self:T3( IsGroundResult ) return IsGroundResult end + self:E( { "Cannot check IsGround", Positionable = self, Alive = self:IsAlive() } ) return nil end - --- Returns if the unit is of ship category. -- @param #POSITIONABLE self -- @return #boolean Ship category evaluation result. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:IsShip() self:F2() @@ -674,16 +678,18 @@ function POSITIONABLE:IsShip() if DCSUnit then local UnitDescriptor = DCSUnit:getDesc() + self:T3( { UnitDescriptor.category, Unit.Category.SHIP } ) - local IsShip = ( UnitDescriptor.category == Unit.Category.SHIP ) + local IsShipResult = (UnitDescriptor.category == Unit.Category.SHIP) - return IsShip + self:T3( IsShipResult ) + return IsShipResult end + self:E( { "Cannot check IsShip", Positionable = self, Alive = self:IsAlive() } ) return nil end - --- Returns if the unit is a submarine. -- @param #POSITIONABLE self -- @return #boolean Submarines attributes result. @@ -701,10 +707,10 @@ function POSITIONABLE:IsSubmarine() end end + self:E( { "Cannot check IsSubmarine", Positionable = self, Alive = self:IsAlive() } ) return nil end - --- Returns true if the POSITIONABLE is in the air. -- Polymorphic, is overridden in GROUP and UNIT. -- @param Wrapper.Positionable#POSITIONABLE self @@ -716,8 +722,7 @@ function POSITIONABLE:InAir() return nil end - ---- Returns the a @{Velocity} object from the positionable. +--- Returns the a @{Velocity} object from the POSITIONABLE. -- @param Wrapper.Positionable#POSITIONABLE self -- @return Core.Velocity#VELOCITY Velocity The Velocity object. -- @return #nil The POSITIONABLE is not existing or alive. @@ -736,8 +741,6 @@ function POSITIONABLE:GetVelocity() return nil end - - --- Returns the POSITIONABLE velocity Vec3 vector. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Vec3 The velocity Vec3 vector @@ -760,30 +763,29 @@ end --- Get relative velocity with respect to another POSITIONABLE. -- @param #POSITIONABLE self --- @param #POSITIONABLE positionable Other positionable. +-- @param #POSITIONABLE positionable Other POSITIONABLE. -- @return #number Relative velocity in m/s. -function POSITIONABLE:GetRelativeVelocity(positionable) +function POSITIONABLE:GetRelativeVelocity( positionable ) self:F2( self.PositionableName ) - local v1=self:GetVelocityVec3() - local v2=positionable:GetVelocityVec3() + local v1 = self:GetVelocityVec3() + local v2 = positionable:GetVelocityVec3() - local vtot=UTILS.VecAdd(v1,v2) + local vtot = UTILS.VecAdd( v1, v2 ) - return UTILS.VecNorm(vtot) + return UTILS.VecNorm( vtot ) end - --- Returns the POSITIONABLE height in meters. -- @param Wrapper.Positionable#POSITIONABLE self --- @return DCS#Vec3 The height of the positionable. +-- @return DCS#Vec3 The height of the POSITIONABLE in meters. -- @return #nil The POSITIONABLE is not existing or alive. -function POSITIONABLE:GetHeight() --R2.1 +function POSITIONABLE:GetHeight() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - if DCSPositionable then + if DCSPositionable and DCSPositionable:isExist() then local PositionablePosition = DCSPositionable:getPosition() if PositionablePosition then local PositionableHeight = PositionablePosition.p.y @@ -795,10 +797,9 @@ function POSITIONABLE:GetHeight() --R2.1 return nil end - --- Returns the POSITIONABLE velocity in km/h. -- @param Wrapper.Positionable#POSITIONABLE self --- @return #number The velocity in km/h +-- @return #number The velocity in km/h. function POSITIONABLE:GetVelocityKMH() self:F2( self.PositionableName ) @@ -838,12 +839,13 @@ end -- @return #number The velocity in knots. function POSITIONABLE:GetVelocityKNOTS() self:F2( self.PositionableName ) - return UTILS.MpsToKnots(self:GetVelocityMPS()) + return UTILS.MpsToKnots( self:GetVelocityMPS() ) end ---- Returns the Angle of Attack of a positionable. +--- Returns the Angle of Attack of a POSITIONABLE. -- @param Wrapper.Positionable#POSITIONABLE self -- @return #number Angle of attack in degrees. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetAoA() -- Get position of the unit. @@ -854,34 +856,34 @@ function POSITIONABLE:GetAoA() -- Get velocity vector of the unit. local unitvel = self:GetVelocityVec3() - if unitvel and UTILS.VecNorm(unitvel)~=0 then + if unitvel and UTILS.VecNorm( unitvel ) ~= 0 then -- Get wind vector including turbulences. - local wind=self:GetCoordinate():GetWindWithTurbulenceVec3() + local wind = self:GetCoordinate():GetWindWithTurbulenceVec3() -- Include wind vector. - unitvel.x=unitvel.x-wind.x - unitvel.y=unitvel.y-wind.y - unitvel.z=unitvel.z-wind.z + unitvel.x = unitvel.x - wind.x + unitvel.y = unitvel.y - wind.y + unitvel.z = unitvel.z - wind.z -- Unit velocity transformed into aircraft axes directions. local AxialVel = {} -- Transform velocity components in direction of aircraft axes. - AxialVel.x = UTILS.VecDot(unitpos.x, unitvel) - AxialVel.y = UTILS.VecDot(unitpos.y, unitvel) - AxialVel.z = UTILS.VecDot(unitpos.z, unitvel) + AxialVel.x = UTILS.VecDot( unitpos.x, unitvel ) + AxialVel.y = UTILS.VecDot( unitpos.y, unitvel ) + AxialVel.z = UTILS.VecDot( unitpos.z, unitvel ) -- AoA is angle between unitpos.x and the x and y velocities. - local AoA = math.acos(UTILS.VecDot({x = 1, y = 0, z = 0}, {x = AxialVel.x, y = AxialVel.y, z = 0})/UTILS.VecNorm({x = AxialVel.x, y = AxialVel.y, z = 0})) + local AoA = math.acos( UTILS.VecDot( { x = 1, y = 0, z = 0 }, { x = AxialVel.x, y = AxialVel.y, z = 0 } ) / UTILS.VecNorm( { x = AxialVel.x, y = AxialVel.y, z = 0 } ) ) - --Set correct direction: + -- Set correct direction: if AxialVel.y > 0 then AoA = -AoA end -- Return AoA value in degrees. - return math.deg(AoA) + return math.deg( AoA ) end end @@ -889,9 +891,10 @@ function POSITIONABLE:GetAoA() return nil end ---- Returns the unit's climb or descent angle. +--- Returns the climb or descent angle of the POSITIONABLE. -- @param Wrapper.Positionable#POSITIONABLE self --- @return #number Climb or descent angle in degrees. Or 0 if velocity vector norm is zero (or nil). Or nil, if the position of the POSITIONABLE returns nil. +-- @return #number Climb or descent angle in degrees. Or 0 if velocity vector norm is zero. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetClimbAngle() -- Get position of the unit. @@ -902,31 +905,33 @@ function POSITIONABLE:GetClimbAngle() -- Get velocity vector of the unit. local unitvel = self:GetVelocityVec3() - if unitvel and UTILS.VecNorm(unitvel)~=0 then + if unitvel and UTILS.VecNorm( unitvel ) ~= 0 then -- Calculate climb angle. - local angle=math.asin(unitvel.y/UTILS.VecNorm(unitvel)) + local angle = math.asin( unitvel.y / UTILS.VecNorm( unitvel ) ) -- Return angle in degrees. - return math.deg(angle) + return math.deg( angle ) else return 0 end + end return nil end ---- Returns the pitch angle of a unit. +--- Returns the pitch angle of a POSITIONABLE. -- @param Wrapper.Positionable#POSITIONABLE self --- @return #number Pitch ange in degrees. +-- @return #number Pitch angle in degrees. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetPitch() -- Get position of the unit. local unitpos = self:GetPosition() if unitpos then - return math.deg(math.asin(unitpos.x.y)) + return math.deg( math.asin( unitpos.x.y ) ) end return nil @@ -934,7 +939,8 @@ end --- Returns the roll angle of a unit. -- @param Wrapper.Positionable#POSITIONABLE self --- @return #number Pitch ange in degrees. +-- @return #number Pitch angle in degrees. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetRoll() -- Get position of the unit. @@ -942,87 +948,98 @@ function POSITIONABLE:GetRoll() if unitpos then - --first, make a vector that is perpendicular to y and unitpos.x with cross product - local cp = UTILS.VecCross(unitpos.x, {x = 0, y = 1, z = 0}) + -- First, make a vector that is perpendicular to y and unitpos.x with cross product + local cp = UTILS.VecCross( unitpos.x, { x = 0, y = 1, z = 0 } ) - --now, get dot product of of this cross product with unitpos.z - local dp = UTILS.VecDot(cp, unitpos.z) + -- Now, get dot product of of this cross product with unitpos.z + local dp = UTILS.VecDot( cp, unitpos.z ) - --now get the magnitude of the roll (magnitude of the angle between two vectors is acos(vec1.vec2/|vec1||vec2|) - local Roll = math.acos(dp/(UTILS.VecNorm(cp)*UTILS.VecNorm(unitpos.z))) + -- Now get the magnitude of the roll (magnitude of the angle between two vectors is acos(vec1.vec2/|vec1||vec2|) + local Roll = math.acos( dp / (UTILS.VecNorm( cp ) * UTILS.VecNorm( unitpos.z )) ) - --now, have to get sign of roll. - -- by convention, making right roll positive - -- to get sign of roll, use the y component of unitpos.z. For right roll, y component is negative. + -- Now, have to get sign of roll. By convention, making right roll positive + -- To get sign of roll, use the y component of unitpos.z. For right roll, y component is negative. if unitpos.z.y > 0 then -- left roll, flip the sign of the roll Roll = -Roll end - return math.deg(Roll) - end -end + return math.deg( Roll ) ---- Returns the yaw angle of a unit. --- @param Wrapper.Positionable#POSITIONABLE self --- @return #number Yaw ange in degrees. -function POSITIONABLE:GetYaw() - - local unitpos = self:GetPosition() - if unitpos then - -- get unit velocity - local unitvel = self:GetVelocityVec3() - - if unitvel and UTILS.VecNorm(unitvel) ~= 0 then --must have non-zero velocity! - local AxialVel = {} --unit velocity transformed into aircraft axes directions - - --transform velocity components in direction of aircraft axes. - AxialVel.x = UTILS.VecDot(unitpos.x, unitvel) - AxialVel.y = UTILS.VecDot(unitpos.y, unitvel) - AxialVel.z = UTILS.VecDot(unitpos.z, unitvel) - - --Yaw is the angle between unitpos.x and the x and z velocities - --define right yaw as positive - local Yaw = math.acos(UTILS.VecDot({x = 1, y = 0, z = 0}, {x = AxialVel.x, y = 0, z = AxialVel.z})/UTILS.VecNorm({x = AxialVel.x, y = 0, z = AxialVel.z})) - - --now set correct direction: - if AxialVel.z > 0 then - Yaw = -Yaw - end - return Yaw - end - end - -end - - ---- Returns the message text with the callsign embedded (if there is one). --- @param #POSITIONABLE self --- @param #string Message The message text --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. --- @return #string The message text -function POSITIONABLE:GetMessageText( Message, Name ) - - local DCSObject = self:GetDCSObject() - if DCSObject then - local Callsign = string.format( "%s", ( ( Name ~= "" and Name ) or self:GetCallsign() ~= "" and self:GetCallsign() ) or self:GetName() ) - local MessageText = string.format("%s - %s", Callsign, Message ) - return MessageText end return nil end +--- Returns the yaw angle of a POSITIONABLE. +-- @param Wrapper.Positionable#POSITIONABLE self +-- @return #number Yaw angle in degrees. +-- @return #nil The POSITIONABLE is not existing or alive. +function POSITIONABLE:GetYaw() + + -- Get position of the unit. + local unitpos = self:GetPosition() + + if unitpos then + + -- get unit velocity + local unitvel = self:GetVelocityVec3() + + if unitvel and UTILS.VecNorm( unitvel ) ~= 0 then -- must have non-zero velocity! + local AxialVel = {} -- unit velocity transformed into aircraft axes directions + + -- transform velocity components in direction of aircraft axes. + AxialVel.x = UTILS.VecDot( unitpos.x, unitvel ) + AxialVel.y = UTILS.VecDot( unitpos.y, unitvel ) + AxialVel.z = UTILS.VecDot( unitpos.z, unitvel ) + + -- Yaw is the angle between unitpos.x and the x and z velocities + -- define right yaw as positive + local Yaw = math.acos( UTILS.VecDot( { x = 1, y = 0, z = 0 }, { x = AxialVel.x, y = 0, z = AxialVel.z } ) / UTILS.VecNorm( { x = AxialVel.x, y = 0, z = AxialVel.z } ) ) + + -- now set correct direction: + if AxialVel.z > 0 then + Yaw = -Yaw + end + return Yaw + end + + end + + return nil +end + +--- Returns the message text with the callsign embedded (if there is one). +-- @param #POSITIONABLE self +-- @param #string Message The message text. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. +-- @return #string The message text. +-- @return #nil The POSITIONABLE is not existing or alive. +function POSITIONABLE:GetMessageText( Message, Name ) + + local DCSObject = self:GetDCSObject() + + if DCSObject then + + local Callsign = string.format( "%s", ((Name ~= "" and Name) or self:GetCallsign() ~= "" and self:GetCallsign()) or self:GetName() ) + local MessageText = string.format( "%s - %s", Callsign, Message ) + return MessageText + + end + + return nil +end --- Returns a message with the callsign embedded (if there is one). -- @param #POSITIONABLE self -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. -- @return Core.Message#MESSAGE -function POSITIONABLE:GetMessage( Message, Duration, Name ) --R2.1 changed callsign and name and using GetMessageText +function POSITIONABLE:GetMessage( Message, Duration, Name ) local DCSObject = self:GetDCSObject() + if DCSObject then local MessageText = self:GetMessageText( Message, Name ) return MESSAGE:New( MessageText, Duration ) @@ -1035,7 +1052,7 @@ end -- @param #POSITIONABLE self -- @param #string Message The message text -- @param Core.Message#MESSAGE MessageType MessageType The message type. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. -- @return Core.Message#MESSAGE function POSITIONABLE:GetMessageType( Message, MessageType, Name ) -- R2.2 changed callsign and name and using GetMessageText @@ -1053,7 +1070,7 @@ end -- @param #POSITIONABLE self -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. function POSITIONABLE:MessageToAll( Message, Duration, Name ) self:F2( { Message, Duration } ) @@ -1071,7 +1088,7 @@ end -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. -- @param DCS#coalition MessageCoalition The Coalition receiving the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name ) self:F2( { Message, Duration } ) @@ -1085,14 +1102,13 @@ function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, N return nil end - --- Send a message to a coalition. -- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message. -- @param #POSITIONABLE self -- @param #string Message The message text -- @param Core.Message#MESSAGE.Type MessageType The message type that determines the duration. -- @param DCS#coalition MessageCoalition The Coalition receiving the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. function POSITIONABLE:MessageTypeToCoalition( Message, MessageType, MessageCoalition, Name ) self:F2( { Message, MessageType } ) @@ -1106,13 +1122,12 @@ function POSITIONABLE:MessageTypeToCoalition( Message, MessageType, MessageCoali return nil end - --- Send a message to the red coalition. -- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message. -- @param #POSITIONABLE self -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. function POSITIONABLE:MessageToRed( Message, Duration, Name ) self:F2( { Message, Duration } ) @@ -1129,7 +1144,7 @@ end -- @param #POSITIONABLE self -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. function POSITIONABLE:MessageToBlue( Message, Duration, Name ) self:F2( { Message, Duration } ) @@ -1147,7 +1162,7 @@ end -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. -- @param Wrapper.Client#CLIENT Client The client object receiving the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. function POSITIONABLE:MessageToClient( Message, Duration, Client, Name ) self:F2( { Message, Duration } ) @@ -1165,7 +1180,7 @@ end -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. -- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name ) self:F2( { Message, Duration } ) @@ -1178,11 +1193,15 @@ function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name ) BASE:E( { "Message not sent to Group; Group is not alive...", Message = Message, MessageGroup = MessageGroup } ) end else - BASE:E( { "Message not sent to Group; Positionable is not alive ...", Message = Message, Positionable = self, MessageGroup = MessageGroup } ) + BASE:E( { + "Message not sent to Group; Positionable is not alive ...", + Message = Message, + Positionable = self, + MessageGroup = MessageGroup + } ) end end - return nil end @@ -1192,7 +1211,7 @@ end -- @param #string Message The message text -- @param Core.Message#MESSAGE.Type MessageType The message type that determines the duration. -- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, the Name is the type of the POSITIONABLE. function POSITIONABLE:MessageTypeToGroup( Message, MessageType, MessageGroup, Name ) self:F2( { Message, MessageType } ) @@ -1212,18 +1231,16 @@ end -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. -- @param Core.Set#SET_GROUP MessageSetGroup The SET_GROUP collection receiving the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -function POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Name ) --R2.1 +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. +function POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Name ) self:F2( { Message, Duration } ) local DCSObject = self:GetDCSObject() if DCSObject then if DCSObject:isExist() then - MessageSetGroup:ForEachGroupAlive( - function( MessageGroup ) - self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup ) - end - ) + MessageSetGroup:ForEachGroupAlive( function( MessageGroup ) + self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup ) + end ) end end @@ -1235,7 +1252,7 @@ end -- @param #POSITIONABLE self -- @param #string Message The message text -- @param DCS#Duration Duration The duration of the message. --- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. +-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE. function POSITIONABLE:Message( Message, Duration, Name ) self:F2( { Message, Duration } ) @@ -1251,17 +1268,17 @@ end -- Set parameters with the methods provided, then use RADIO:Broadcast() to actually broadcast the message -- @param #POSITIONABLE self -- @return Core.Radio#RADIO Radio -function POSITIONABLE:GetRadio() --R2.1 - self:F2(self) - return RADIO:New(self) +function POSITIONABLE:GetRadio() + self:F2( self ) + return RADIO:New( self ) end --- Create a @{Core.Radio#BEACON}, to allow this POSITIONABLE to broadcast beacon signals -- @param #POSITIONABLE self -- @return Core.Radio#RADIO Radio -function POSITIONABLE:GetBeacon() --R2.1 - self:F2(self) - return BEACON:New(self) +function POSITIONABLE:GetBeacon() + self:F2( self ) + return BEACON:New( self ) end --- Start Lasing a POSITIONABLE @@ -1270,7 +1287,7 @@ end -- @param #number LaserCode Laser code or random number in [1000, 9999]. -- @param #number Duration Duration of lasing in seconds. -- @return Core.Spot#SPOT -function POSITIONABLE:LaseUnit( Target, LaserCode, Duration ) --R2.1 +function POSITIONABLE:LaseUnit( Target, LaserCode, Duration ) self:F2() LaserCode = LaserCode or math.random( 1000, 9999 ) @@ -1278,9 +1295,9 @@ function POSITIONABLE:LaseUnit( Target, LaserCode, Duration ) --R2.1 local RecceDcsUnit = self:GetDCSObject() local TargetVec3 = Target:GetVec3() - self:F("bulding spot") + self:F( "building spot" ) self.Spot = SPOT:New( self ) -- Core.Spot#SPOT - self.Spot:LaseOn( Target, LaserCode, Duration) + self.Spot:LaseOn( Target, LaserCode, Duration ) self.LaserCode = LaserCode return self.Spot @@ -1289,17 +1306,17 @@ end --- Start Lasing a COORDINATE. -- @param #POSITIONABLE self --- @param Core.Point#COORDIUNATE Coordinate The coordinate where the lase is pointing at. +-- @param Core.Point#COORDINATE Coordinate The coordinate where the lase is pointing at. -- @param #number LaserCode Laser code or random number in [1000, 9999]. -- @param #number Duration Duration of lasing in seconds. -- @return Core.Spot#SPOT -function POSITIONABLE:LaseCoordinate(Coordinate, LaserCode, Duration) +function POSITIONABLE:LaseCoordinate( Coordinate, LaserCode, Duration ) self:F2() - LaserCode = LaserCode or math.random(1000, 9999) + LaserCode = LaserCode or math.random( 1000, 9999 ) - self.Spot = SPOT:New(self) -- Core.Spot#SPOT - self.Spot:LaseOnCoordinate(Coordinate, LaserCode, Duration) + self.Spot = SPOT:New( self ) -- Core.Spot#SPOT + self.Spot:LaseOnCoordinate( Coordinate, LaserCode, Duration ) self.LaserCode = LaserCode return self.Spot @@ -1308,7 +1325,7 @@ end --- Stop Lasing a POSITIONABLE -- @param #POSITIONABLE self -- @return #POSITIONABLE -function POSITIONABLE:LaseOff() --R2.1 +function POSITIONABLE:LaseOff() self:F2() if self.Spot then @@ -1322,7 +1339,7 @@ end --- Check if the POSITIONABLE is lasing a target -- @param #POSITIONABLE self -- @return #boolean true if it is lasing a target -function POSITIONABLE:IsLasing() --R2.1 +function POSITIONABLE:IsLasing() self:F2() local Lasing = false @@ -1337,7 +1354,7 @@ end --- Get the Spot -- @param #POSITIONABLE self -- @return Core.Spot#SPOT The Spot -function POSITIONABLE:GetSpot() --R2.1 +function POSITIONABLE:GetSpot() return self.Spot end @@ -1345,7 +1362,7 @@ end --- Get the last assigned laser code -- @param #POSITIONABLE self -- @return #number The laser code -function POSITIONABLE:GetLaserCode() --R2.1 +function POSITIONABLE:GetLaserCode() return self.LaserCode end @@ -1368,8 +1385,6 @@ do -- Cargo return self.__.Cargo end - - --- Remove cargo. -- @param #POSITIONABLE self -- @param Core.Cargo#CARGO Cargo @@ -1457,7 +1472,7 @@ do -- Cargo if WeightLimit then self.__.CargoBayWeightLimit = WeightLimit - elseif self.__.CargoBayWeightLimit~=nil then + elseif self.__.CargoBayWeightLimit ~= nil then -- Value already set ==> Do nothing! else -- If weightlimit is not provided, we will calculate it depending on the type of unit. @@ -1465,29 +1480,29 @@ do -- Cargo -- When an airplane or helicopter, we calculate the weightlimit based on the descriptor. if self:IsAir() then local Desc = self:GetDesc() - self:F({Desc=Desc}) + self:F( { Desc = Desc } ) local Weights = { - ["C-17A"] = 35000, --77519 cannot be used, because it loads way too much apcs and infantry., - ["C-130"] = 22000 --The real value cannot be used, because it loads way too much apcs and infantry., + ["C-17A"] = 35000, -- 77519 cannot be used, because it loads way too many APCs and infantry. + ["C-130"] = 22000 -- The real value cannot be used, because it loads way too many APCs and infantry. } - self.__.CargoBayWeightLimit = Weights[Desc.typeName] or ( Desc.massMax - ( Desc.massEmpty + Desc.fuelMassMax ) ) + self.__.CargoBayWeightLimit = Weights[Desc.typeName] or (Desc.massMax - (Desc.massEmpty + Desc.fuelMassMax)) elseif self:IsShip() then local Desc = self:GetDesc() - self:F({Desc=Desc}) + self:F( { Desc = Desc } ) local Weights = { - ["Type_071"] = 245000, - ["LHA_Tarawa"] = 500000, - ["Ropucha-class"] = 150000, - ["Dry-cargo ship-1"] = 70000, - ["Dry-cargo ship-2"] = 70000, - ["Higgins_boat"] = 3700, -- Higgins Boat can load 3700 kg of general cargo or 36 men (source wikipedia). - ["USS_Samuel_Chase"] = 25000, -- Let's say 25 tons for now. Wiki says 33 Higgins boats, which would be 264 tons (can't be right!) and/or 578 troops. - ["LST_Mk2"] =2100000, -- Can carry 2100 tons according to wiki source! + ["Type_071"] = 245000, + ["LHA_Tarawa"] = 500000, + ["Ropucha-class"] = 150000, + ["Dry-cargo ship-1"] = 70000, + ["Dry-cargo ship-2"] = 70000, + ["Higgins_boat"] = 3700, -- Higgins Boat can load 3700 kg of general cargo or 36 men (source wikipedia). + ["USS_Samuel_Chase"] = 25000, -- Let's say 25 tons for now. Wiki says 33 Higgins boats, which would be 264 tons (can't be right!) and/or 578 troops. + ["LST_Mk2"] = 2100000 -- Can carry 2100 tons according to wiki source! } - self.__.CargoBayWeightLimit = ( Weights[Desc.typeName] or 50000 ) + self.__.CargoBayWeightLimit = (Weights[Desc.typeName] or 50000) else local Desc = self:GetDesc() @@ -1496,14 +1511,14 @@ do -- Cargo ["AAV7"] = 25, ["Bedford_MWD"] = 8, -- new by kappa ["Blitz_36-6700A"] = 10, -- new by kappa - ["BMD-1"] = 9, -- IRL should be 4 passengers + ["BMD-1"] = 9, -- IRL should be 4 passengers ["BMP-1"] = 8, ["BMP-2"] = 7, - ["BMP-3"] = 8, -- IRL should be 7+2 passengers + ["BMP-3"] = 8, -- IRL should be 7+2 passengers ["Boman"] = 25, ["BTR-80"] = 9, -- IRL should be 7 passengers ["BTR-82A"] = 9, -- new by kappa -- IRL should be 7 passengers - ["BTR_D"] = 12, -- IRL should be 10 passengers + ["BTR_D"] = 12, -- IRL should be 10 passengers ["Cobra"] = 8, ["Land_Rover_101_FC"] = 11, -- new by kappa ["Land_Rover_109_S3"] = 7, -- new by kappa @@ -1514,11 +1529,11 @@ do -- Cargo ["M1126 Stryker ICV"] = 9, ["M1134 Stryker ATGM"] = 9, ["M2A1_halftrack"] = 9, - ["M-113"] = 9, -- IRL should be 11 passengers + ["M-113"] = 9, -- IRL should be 11 passengers ["Marder"] = 6, ["MCV-80"] = 9, -- IRL should be 7 passengers ["MLRS FDDM"] = 4, - ["MTLB"] = 25, -- IRL should be 11 passengers + ["MTLB"] = 25, -- IRL should be 11 passengers ["GAZ-66"] = 8, ["GAZ-3307"] = 12, ["GAZ-3308"] = 14, @@ -1534,14 +1549,14 @@ do -- Cargo ["Ural-4320 APA-5D"] = 10, ["Ural-4320T"] = 14, ["ZBD04A"] = 7, -- new by kappa - ["VAB_Mephisto"] = 8, -- new by Apple + ["VAB_Mephisto"] = 8 -- new by Apple } - local CargoBayWeightLimit = ( Weights[Desc.typeName] or 0 ) * 95 + local CargoBayWeightLimit = (Weights[Desc.typeName] or 0) * 95 self.__.CargoBayWeightLimit = CargoBayWeightLimit end end - self:F({CargoBayWeightLimit = self.__.CargoBayWeightLimit}) + self:F( { CargoBayWeightLimit = self.__.CargoBayWeightLimit } ) end end --- Cargo @@ -1550,28 +1565,28 @@ end --- Cargo -- @param Utilities.Utils#FLARECOLOR FlareColor function POSITIONABLE:Flare( FlareColor ) self:F2() - trigger.action.signalFlare( self:GetVec3(), FlareColor , 0 ) + trigger.action.signalFlare( self:GetVec3(), FlareColor, 0 ) end --- Signal a white flare at the position of the POSITIONABLE. -- @param #POSITIONABLE self function POSITIONABLE:FlareWhite() self:F2() - trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.White , 0 ) + trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.White, 0 ) end --- Signal a yellow flare at the position of the POSITIONABLE. -- @param #POSITIONABLE self function POSITIONABLE:FlareYellow() self:F2() - trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Yellow , 0 ) + trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Yellow, 0 ) end --- Signal a green flare at the position of the POSITIONABLE. -- @param #POSITIONABLE self function POSITIONABLE:FlareGreen() self:F2() - trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Green , 0 ) + trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Green, 0 ) end --- Signal a red flare at the position of the POSITIONABLE. @@ -1586,9 +1601,9 @@ end --- Smoke the POSITIONABLE. -- @param #POSITIONABLE self --- @param Utilities.Utils#SMOKECOLOR SmokeColor The color to smoke to positionable. --- @param #number Range The range in meters to randomize the smoking around the positionable. --- @param #number AddHeight The height in meters to add to the altitude of the positionable. +-- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color. +-- @param #number Range The range in meters to randomize the smoking around the POSITIONABLE. +-- @param #number AddHeight The height in meters to add to the altitude of the POSITIONABLE. function POSITIONABLE:Smoke( SmokeColor, Range, AddHeight ) self:F2() if Range then @@ -1638,7 +1653,6 @@ function POSITIONABLE:SmokeBlue() trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Blue ) end - --- Returns true if the unit is within a @{Zone}. -- @param #POSITIONABLE self -- @param Core.Zone#ZONE_BASE Zone The zone to test. diff --git a/Moose Development/Moose/Wrapper/Static.lua b/Moose Development/Moose/Wrapper/Static.lua index 8377d9803..7394d0861 100644 --- a/Moose Development/Moose/Wrapper/Static.lua +++ b/Moose Development/Moose/Wrapper/Static.lua @@ -1,52 +1,46 @@ --- **Wrapper** -- STATIC wraps the DCS StaticObject class. --- +-- -- === --- +-- -- ### Author: **FlightControl** --- +-- -- ### Contributions: **funkyfranky** --- +-- -- === --- +-- -- @module Wrapper.Static -- @image Wrapper_Static.JPG - - --- @type STATIC -- @extends Wrapper.Positionable#POSITIONABLE - --- Wrapper class to handle Static objects. --- +-- -- Note that Statics are almost the same as Units, but they don't have a controller. -- The @{Wrapper.Static#STATIC} class is a wrapper class to handle the DCS Static objects: --- +-- -- * Wraps the DCS Static objects. -- * Support all DCS Static APIs. -- * Enhance with Static specific APIs not in the DCS API set. --- +-- -- ## STATIC reference methods --- +-- -- For each DCS Static will have a STATIC wrapper object (instance) within the _@{DATABASE} object. -- This is done at the beginning of the mission (when the mission starts). --- +-- -- The STATIC class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference -- using the Static Name. --- +-- -- Another thing to know is that STATIC objects do not "contain" the DCS Static object. -- The STATIc methods will reference the DCS Static object by name when it is needed during API execution. -- If the DCS Static object does not exist or is nil, the STATIC methods will return nil and log an exception in the DCS.log file. --- +-- -- The STATIc class provides the following functions to retrieve quickly the relevant STATIC instance: --- +-- -- * @{#STATIC.FindByName}(): Find a STATIC instance from the _DATABASE object using a DCS Static name. --- --- IMPORTANT: ONE SHOULD NEVER SANATIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil). --- +-- +-- IMPORTANT: ONE SHOULD NEVER SANITIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil). +-- -- @field #STATIC -STATIC = { - ClassName = "STATIC", -} - +STATIC = { ClassName = "STATIC" } --- Register a static object. -- @param #STATIC self @@ -58,7 +52,6 @@ function STATIC:Register( StaticName ) return self end - --- Finds a STATIC from the _DATABASE using a DCSStatic object. -- @param #STATIC self -- @param DCS#StaticObject DCSStatic An existing DCS Static object reference. @@ -83,13 +76,13 @@ function STATIC:FindByName( StaticName, RaiseError ) -- Set static name. self.StaticName = StaticName - + if StaticFound then - return StaticFound + return StaticFound end - - if RaiseError == nil or RaiseError == true then - error( "STATIC not found for: " .. StaticName ) + + if RaiseError == nil or RaiseError == true then + error( "STATIC not found for: " .. StaticName ) end return nil @@ -97,38 +90,39 @@ end --- Destroys the STATIC. -- @param #STATIC self --- @param #boolean GenerateEvent (Optional) true if you want to generate a crash or dead event for the static. --- @return #nil The DCS StaticObject is not existing or alive. +-- @param #boolean GenerateEvent (Optional) true to generate a crash or dead event, false to not generate any event. `nil` (default) creates a remove event. +-- @return #nil The DCS StaticObject is not existing or alive. +-- -- @usage -- -- Air static example: destroy the static Helicopter and generate a S_EVENT_CRASH. -- Helicopter = STATIC:FindByName( "Helicopter" ) -- Helicopter:Destroy( true ) --- +-- -- @usage -- -- Ground static example: destroy the static Tank and generate a S_EVENT_DEAD. -- Tanks = UNIT:FindByName( "Tank" ) -- Tanks:Destroy( true ) --- +-- -- @usage -- -- Ship static example: destroy the Ship silently. -- Ship = STATIC:FindByName( "Ship" ) -- Ship:Destroy() --- +-- -- @usage -- -- Destroy without event generation example. -- Ship = STATIC:FindByName( "Boat" ) --- Ship:Destroy( false ) -- Don't generate an event upon destruction. --- +-- Ship:Destroy( false ) -- Don't generate any event upon destruction. +-- function STATIC:Destroy( GenerateEvent ) self:F2( self.ObjectName ) local DCSObject = self:GetDCSObject() - + if DCSObject then - + local StaticName = DCSObject:getName() self:F( { StaticName = StaticName } ) - + if GenerateEvent and GenerateEvent == true then if self:IsAir() then self:CreateEventCrash( timer.getTime(), DCSObject ) @@ -140,7 +134,7 @@ function STATIC:Destroy( GenerateEvent ) else self:CreateEventRemoveUnit( timer.getTime(), DCSObject ) end - + DCSObject:destroy() return true end @@ -148,17 +142,16 @@ function STATIC:Destroy( GenerateEvent ) return nil end - --- Get DCS object of static of static. -- @param #STATIC self -- @return DCS static object function STATIC:GetDCSObject() local DCSStatic = StaticObject.getByName( self.StaticName ) - + if DCSStatic then return DCSStatic end - + return nil end @@ -170,7 +163,7 @@ function STATIC:GetUnits() local DCSStatic = self:GetDCSObject() local Statics = {} - + if DCSStatic then Statics[1] = STATIC:Find( DCSStatic ) self:T3( Statics ) @@ -180,7 +173,6 @@ function STATIC:GetUnits() return nil end - --- Get threat level of static. -- @param #STATIC self -- @return #number Threat level 1. @@ -194,66 +186,62 @@ end -- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static. -- @param #number Heading The heading of the static respawn in degrees. Default is 0 deg. -- @param #number Delay Delay in seconds before the static is spawned. -function STATIC:SpawnAt(Coordinate, Heading, Delay) +function STATIC:SpawnAt( Coordinate, Heading, Delay ) - Heading=Heading or 0 + Heading = Heading or 0 - if Delay and Delay>0 then - SCHEDULER:New(nil, self.SpawnAt, {self, Coordinate, Heading}, Delay) + if Delay and Delay > 0 then + SCHEDULER:New( nil, self.SpawnAt, { self, Coordinate, Heading }, Delay ) else - local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName) - + local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName ) + SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName ) - + end - + return self end - --- Respawn the @{Wrapper.Unit} at the same location with the same properties. -- This is useful to respawn a cargo after it has been destroyed. -- @param #STATIC self -- @param DCS#country.id CountryID (Optional) The country ID used for spawning the new static. Default is same as currently. -- @param #number Delay (Optional) Delay in seconds before static is respawned. Default now. -function STATIC:ReSpawn(CountryID, Delay) +function STATIC:ReSpawn( CountryID, Delay ) - if Delay and Delay>0 then - SCHEDULER:New(nil, self.ReSpawn, {self, CountryID}, Delay) + if Delay and Delay > 0 then + SCHEDULER:New( nil, self.ReSpawn, { self, CountryID }, Delay ) else - CountryID=CountryID or self:GetCountry() + CountryID = CountryID or self:GetCountry() + + local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, CountryID ) + + SpawnStatic:Spawn( nil, self.StaticName ) - local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName, CountryID) - - SpawnStatic:Spawn(nil, self.StaticName) - end - + return self end - --- Respawn the @{Wrapper.Unit} at a defined Coordinate with an optional heading. -- @param #STATIC self -- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static. --- @param #number Heading (Optional) The heading of the static respawn in degrees. Default the current heading. --- @param #number Delay (Optional) Delay in seconds before static is respawned. Default now. -function STATIC:ReSpawnAt(Coordinate, Heading, Delay) +-- @param #number Heading (Optional) The heading of the static respawn in degrees. Default is the current heading. +-- @param #number Delay (Optional) Delay in seconds before static is respawned. Default is now. +function STATIC:ReSpawnAt( Coordinate, Heading, Delay ) - --Heading=Heading or 0 + -- Heading=Heading or 0 - if Delay and Delay>0 then - SCHEDULER:New(nil, self.ReSpawnAt, {self, Coordinate, Heading}, Delay) + if Delay and Delay > 0 then + SCHEDULER:New( nil, self.ReSpawnAt, { self, Coordinate, Heading }, Delay ) else - - local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName, self:GetCountry()) - - SpawnStatic:SpawnFromCoordinate(Coordinate, Heading, self.StaticName) - + local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, self:GetCountry() ) + + SpawnStatic:SpawnFromCoordinate( Coordinate, Heading, self.StaticName ) end - + return self end diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index d878c3b72..ad2ddc433 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -168,9 +168,6 @@ function UNIT:GetDCSObject() return nil end - - - --- Respawn the @{Wrapper.Unit} using a (tweaked) template of the parent Group. -- -- This function will: @@ -263,8 +260,6 @@ function UNIT:ReSpawnAt( Coordinate, Heading ) _DATABASE:Spawn( SpawnGroupTemplate ) end - - --- Returns if the unit is activated. -- @param #UNIT self -- @return #boolean `true` if Unit is activated. `nil` The DCS Unit is not existing or alive. @@ -301,8 +296,6 @@ function UNIT:IsAlive() return nil end - - --- Returns the Unit's callsign - the localized string. -- @param #UNIT self -- @return #string The Callsign of the Unit. @@ -961,7 +954,6 @@ end -- @return #string Some text. function UNIT:GetThreatLevel() - local ThreatLevel = 0 local ThreatText = "" @@ -987,7 +979,6 @@ function UNIT:GetThreatLevel() "LR SAMs" } - if Attributes["LR SAM"] then ThreatLevel = 10 elseif Attributes["MR SAM"] then ThreatLevel = 9 elseif Attributes["SR SAM"] and @@ -1023,7 +1014,6 @@ function UNIT:GetThreatLevel() "Fighter" } - if Attributes["Fighters"] then ThreatLevel = 10 elseif Attributes["Multirole fighters"] then ThreatLevel = 9 elseif Attributes["Battleplanes"] then ThreatLevel = 8 @@ -1141,12 +1131,6 @@ function UNIT:OtherUnitInRadius( AwaitUnit, Radius ) return nil end - - - - - - --- Returns if the unit is a friendly unit. -- @param #UNIT self -- @return #boolean IsFriendly evaluation result.