diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index 53db3504b..f7632d687 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -1,13 +1,13 @@ --- **Wrapper** -- POSITIONABLE wraps DCS classes that are "positionable". --- +-- -- === --- +-- -- ### Author: **FlightControl** --- +-- -- ### Contributions: **Hardcard**, **funkyfranky** --- +-- -- === --- +-- -- @module Wrapper.Positionable -- @image Wrapper_Positionable.JPG @@ -27,23 +27,23 @@ -- * Manage the "state" of the POSITIONABLE. -- -- ## POSITIONABLE constructor --- +-- -- The POSITIONABLE class provides the following functions to construct a POSITIONABLE instance: -- -- * @{#POSITIONABLE.New}(): Create a POSITIONABLE instance. --- +-- -- ## Get the current speed --- +-- -- There are 3 methods that can be used to determine the speed. -- Use @{#POSITIONABLE.GetVelocityKMH}() to retrieve the current speed in km/h. Use @{#POSITIONABLE.GetVelocityMPS}() to retrieve the speed in meters per second. -- The method @{#POSITIONABLE.GetVelocity}() returns the speed vector (a Vec3). --- +-- -- ## Get the current altitude --- +-- -- Altitude can be retrieved using the method @{#POSITIONABLE.GetHeight}() and returns the current altitude in meters from the orthonormal plane. --- --- --- @field #POSITIONABLE +-- +-- +-- @field #POSITIONABLE POSITIONABLE = { ClassName = "POSITIONABLE", PositionableName = "", @@ -76,7 +76,7 @@ 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. --- @return #nil The DCS Unit is not existing or alive. +-- @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. -- Helicopter = UNIT:FindByName( "Helicopter" ) @@ -89,23 +89,23 @@ end -- -- Ship unit 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. --- +-- function POSITIONABLE:Destroy( GenerateEvent ) self:F2( self.ObjectName ) local DCSObject = self:GetDCSObject() - + if DCSObject then - + local UnitGroup = self:GetGroup() local UnitGroupName = UnitGroup:GetName() self:F( { UnitGroupName = UnitGroupName } ) - + if GenerateEvent and GenerateEvent == true then if self:IsAir() then self:CreateEventCrash( timer.getTime(), DCSObject ) @@ -117,7 +117,7 @@ function POSITIONABLE:Destroy( GenerateEvent ) else self:CreateEventRemoveUnit( timer.getTime(), DCSObject ) end - + USERFLAG:New( UnitGroupName ):Set( 100 ) DCSObject:destroy() end @@ -140,19 +140,19 @@ function POSITIONABLE:GetPosition() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then local PositionablePosition = DCSPositionable:getPosition() self:T3( PositionablePosition ) return PositionablePosition end - + BASE:E( { "Cannot GetPositionVec3", Positionable = self, Alive = self:IsAlive() } ) - return nil + return nil end --- Returns a {@DCS#Vec3} table of the objects current orientation in 3D space. X, Y, Z values are unit vectors defining the objects orientation. --- X is the orientation parallel to the movement of the object, Z perpendicular and Y vertical orientation. +-- X is the orientation parallel to the movement of the object, Z perpendicular and Y vertical orientation. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Vec3 X orientation, i.e. parallel to the direction of movement. -- @return DCS#Vec3 Y orientation, i.e. vertical. @@ -164,7 +164,7 @@ function POSITIONABLE:GetOrientation() else BASE:E( { "Cannot GetOrientation", Positionable = self, Alive = self:IsAlive() } ) return nil, nil, nil - end + end end --- Returns a {@DCS#Vec3} table of the objects current X orientation in 3D space, i.e. along the direction of movement. @@ -177,7 +177,7 @@ function POSITIONABLE:GetOrientationX() else BASE:E( { "Cannot GetOrientationX", Positionable = self, Alive = self:IsAlive() } ) return nil - end + end end --- Returns a {@DCS#Vec3} table of the objects current Y orientation in 3D space, i.e. vertical orientation. @@ -190,7 +190,7 @@ function POSITIONABLE:GetOrientationY() else BASE:E( { "Cannot GetOrientationY", Positionable = self, Alive = self:IsAlive() } ) return nil - end + end end --- Returns a {@DCS#Vec3} table of the objects current Z orientation in 3D space, i.e. perpendicular to direction of movement. @@ -203,24 +203,24 @@ function POSITIONABLE:GetOrientationZ() else BASE:E( { "Cannot GetOrientationZ", Positionable = self, Alive = self:IsAlive() } ) return nil - end + end end --- Returns the @{DCS#Position3} position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Position The 3D position vectors of the POSITIONABLE. --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetPositionVec3() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then local PositionablePosition = DCSPositionable:getPosition().p self:T3( PositionablePosition ) return PositionablePosition end - + BASE:E( { "Cannot GetPositionVec3", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -228,22 +228,22 @@ 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 or `nil` if it is not existing or alive. function POSITIONABLE:GetVec3() local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then - + local vec3=DCSPositionable:getPoint() - + if vec3 then return vec3 else self:E("ERROR: Cannot get vec3!") end end - + -- ERROR! self:E( { "Cannot GetVec3", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -255,14 +255,14 @@ end function POSITIONABLE:GetVec2() local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then - + local Vec3=DCSPositionable:getPoint() --DCS#Vec3 - + return {x=Vec3.x, y=Vec3.z} end - + self:E( { "Cannot GetVec2", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -271,21 +271,21 @@ end --- Returns a POINT_VEC2 object indicating the point in 2D of the POSITIONABLE within the mission. -- @param Wrapper.Positionable#POSITIONABLE self -- @return Core.Point#POINT_VEC2 The 2D point vector of the POSITIONABLE. --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetPointVec2() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then local PositionableVec3 = DCSPositionable:getPosition().p - + local PositionablePointVec2 = POINT_VEC2:NewFromVec3( PositionableVec3 ) - + --self:F( PositionablePointVec2 ) return PositionablePointVec2 end - + self:E( { "Cannot GetPointVec2", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -294,35 +294,35 @@ end --- Returns a POINT_VEC3 object indicating the point in 3D of the POSITIONABLE within the mission. -- @param Wrapper.Positionable#POSITIONABLE self -- @return Core.Point#POINT_VEC3 The 3D point vector of the POSITIONABLE. --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetPointVec3() local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then - + -- Get 3D vector. local PositionableVec3 = self:GetPositionVec3() - + if false and self.pointvec3 then - -- Update vector. + -- Update vector. self.pointvec3.x=PositionableVec3.x self.pointvec3.y=PositionableVec3.y - self.pointvec3.z=PositionableVec3.z - + self.pointvec3.z=PositionableVec3.z + else - + -- Create a new POINT_VEC3 object. self.pointvec3=POINT_VEC3:NewFromVec3(PositionableVec3) - + end - + return self.pointvec3 end BASE:E( { "Cannot GetPointVec3", Positionable = self, Alive = self:IsAlive() } ) - + return nil end @@ -333,32 +333,32 @@ function POSITIONABLE:GetCoord() -- Get DCS object. local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then - + -- Get the current position. local Vec3 = self:GetVec3() - + if self.coordinate then - -- Update vector. + -- Update vector. self.coordinate.x=Vec3.x self.coordinate.y=Vec3.y - self.coordinate.z=Vec3.z - + self.coordinate.z=Vec3.z + else - + -- New COORDINATE. self.coordinate=COORDINATE:NewFromVec3(Vec3) - + end - + return self.coordinate end - + -- Error message. BASE:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } ) - + return nil end @@ -369,21 +369,21 @@ function POSITIONABLE:GetCoordinate() -- Get DCS object. local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then - + -- Get the current position. local PositionableVec3 = self:GetVec3() - + local coord=COORDINATE:NewFromVec3(PositionableVec3) - + -- Return a new coordiante object. return coord end - + -- Error message. - self:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } ) + self:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } ) return nil end @@ -394,7 +394,7 @@ end -- @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) - + -- Default if nil. x=x or 0 y=y or 0 @@ -404,26 +404,26 @@ function POSITIONABLE:GetOffsetCoordinate(x,y,z) 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} - + -- 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} - + -- 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} - + -- Vector from the origin of the map to the unit. 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 coord=COORDINATE:NewFromVec3(v) - + -- Return the offset coordinate. return coord end @@ -432,32 +432,32 @@ end -- @param Wrapper.Positionable#POSITIONABLE self -- @param #number Radius -- @return DCS#Vec3 The 3D point vector of the POSITIONABLE. --- @return #nil The POSITIONABLE is not existing or alive. --- @usage +-- @return #nil The POSITIONABLE is not existing or alive. +-- @usage -- -- If Radius is ignored, returns the DCS#Vec3 of first UNIT of the GROUP function POSITIONABLE:GetRandomVec3( Radius ) self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then local PositionablePointVec3 = DCSPositionable:getPosition().p - + if Radius then local PositionableRandomVec3 = {} 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; - + self:T3( PositionableRandomVec3 ) return PositionableRandomVec3 - else + else self:F("Radius is nil, returning the PointVec3 of the POSITIONABLE", PositionablePointVec3) return PositionablePointVec3 end end - + BASE:E( { "Cannot GetRandomVec3", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -467,12 +467,12 @@ 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. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetBoundingBox() --R2.1 self:F2() local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then local PositionableDesc = DCSPositionable:getDesc() --DCS#Desc if PositionableDesc then @@ -480,7 +480,7 @@ function POSITIONABLE:GetBoundingBox() --R2.1 return PositionableBox end end - + BASE:E( { "Cannot GetBoundingBox", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -488,7 +488,7 @@ end --- Get the object size. --- @param #POSITIONABLE self +-- @param #POSITIONABLE self -- @return DCS#Distance Max size of object in x, z or 0 if bounding box could not be obtained. -- @return DCS#Distance Length x or 0 if bounding box could not be obtained. -- @return DCS#Distance Height y or 0 if bounding box could not be obtained. @@ -497,26 +497,26 @@ function POSITIONABLE:GetObjectSize() -- Get bounding box. 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 end - + 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. +-- @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) self:F2() local Box = self:GetBoundingBox() - + local boxmin=mindist or 0 if Box then local X = Box.max.x - Box.min.x @@ -525,7 +525,7 @@ function POSITIONABLE:GetBoundingRadius(mindist) local CZ = Z / 2 return math.max( math.max( CX, CZ ), boxmin ) end - + BASE:E( { "Cannot GetBoundingRadius", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -534,37 +534,37 @@ end --- Returns the altitude of the POSITIONABLE. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Distance The altitude of the POSITIONABLE. --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetAltitude() self:F2() local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then local PositionablePointVec3 = DCSPositionable:getPoint() --DCS#Vec3 return PositionablePointVec3.y end - + BASE:E( { "Cannot GetAltitude", Positionable = self, Alive = self:IsAlive() } ) return nil -end +end --- Returns if the Positionable is located above a runway. -- @param Wrapper.Positionable#POSITIONABLE self -- @return #boolean true if Positionable is above a runway. --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:IsAboveRunway() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then - + local Vec2 = self:GetVec2() local SurfaceType = land.getSurfaceType( Vec2 ) local IsAboveRunway = SurfaceType == land.SurfaceType.RUNWAY - + self:T2( IsAboveRunway ) return IsAboveRunway end @@ -608,7 +608,7 @@ function POSITIONABLE:GetHeading() return PositionableHeading end end - + BASE:E( { "Cannot GetHeading", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -622,19 +622,19 @@ end -- @return #boolean Air category evaluation result. function POSITIONABLE:IsAir() self:F2() - + local DCSUnit = self:GetDCSObject() - + if DCSUnit then local UnitDescriptor = DCSUnit:getDesc() self:T3( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } ) - + local IsAirResult = ( UnitDescriptor.category == Unit.Category.AIRPLANE ) or ( UnitDescriptor.category == Unit.Category.HELICOPTER ) - + self:T3( IsAirResult ) return IsAirResult end - + return nil end @@ -644,19 +644,19 @@ end -- @return #boolean Ground category evaluation result. function POSITIONABLE:IsGround() self:F2() - + local DCSUnit = self:GetDCSObject() - + if DCSUnit then local UnitDescriptor = DCSUnit:getDesc() self:T3( { UnitDescriptor.category, Unit.Category.GROUND_UNIT } ) - + local IsGroundResult = ( UnitDescriptor.category == Unit.Category.GROUND_UNIT ) - + self:T3( IsGroundResult ) return IsGroundResult end - + return nil end @@ -666,17 +666,17 @@ end -- @return #boolean Ship category evaluation result. function POSITIONABLE:IsShip() self:F2() - + local DCSUnit = self:GetDCSObject() - + if DCSUnit then local UnitDescriptor = DCSUnit:getDesc() - + local IsShip = ( UnitDescriptor.category == Unit.Category.SHIP ) - + return IsShip end - + return nil end @@ -685,7 +685,7 @@ end -- Polymorphic, is overridden in GROUP and UNIT. -- @param Wrapper.Positionable#POSITIONABLE self -- @return #boolean true if in the air. --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:InAir() self:F2( self.PositionableName ) @@ -696,39 +696,39 @@ end --- 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. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetVelocity() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then local Velocity = VELOCITY:New( self ) return Velocity end - + BASE:E( { "Cannot GetVelocity", Positionable = self, Alive = self:IsAlive() } ) return nil end - + --- Returns the POSITIONABLE velocity Vec3 vector. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Vec3 The velocity Vec3 vector --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetVelocityVec3() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable and DCSPositionable:isExist() then local PositionableVelocityVec3 = DCSPositionable:getVelocity() self:T3( PositionableVelocityVec3 ) return PositionableVelocityVec3 end - + BASE:E( { "Cannot GetVelocityVec3", Positionable = self, Alive = self:IsAlive() } ) return nil @@ -740,12 +740,12 @@ end -- @return #number Relative velocity in m/s. function POSITIONABLE:GetRelativeVelocity(positionable) self:F2( self.PositionableName ) - + local v1=self:GetVelocityVec3() local v2=positionable:GetVelocityVec3() - + local vtot=UTILS.VecAdd(v1,v2) - + return UTILS.VecNorm(vtot) end @@ -753,12 +753,12 @@ end --- Returns the POSITIONABLE height in meters. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Vec3 The height of the positionable. --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetHeight() --R2.1 self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable then local PositionablePosition = DCSPositionable:getPosition() if PositionablePosition then @@ -767,7 +767,7 @@ function POSITIONABLE:GetHeight() --R2.1 return PositionableHeight end end - + return nil end @@ -779,7 +779,7 @@ function POSITIONABLE:GetVelocityKMH() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable and DCSPositionable:isExist() then local VelocityVec3 = self:GetVelocityVec3() local Velocity = ( VelocityVec3.x ^ 2 + VelocityVec3.y ^ 2 + VelocityVec3.z ^ 2 ) ^ 0.5 -- in meters / sec @@ -787,7 +787,7 @@ function POSITIONABLE:GetVelocityKMH() self:T3( Velocity ) return Velocity end - + return 0 end @@ -798,14 +798,14 @@ function POSITIONABLE:GetVelocityMPS() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + if DCSPositionable and DCSPositionable:isExist() then local VelocityVec3 = self:GetVelocityVec3() local Velocity = ( VelocityVec3.x ^ 2 + VelocityVec3.y ^ 2 + VelocityVec3.z ^ 2 ) ^ 0.5 -- in meters / sec self:T3( Velocity ) return Velocity end - + return 0 end @@ -824,42 +824,42 @@ function POSITIONABLE:GetAoA() -- Get position of the unit. local unitpos = self:GetPosition() - + if unitpos then - + -- Get velocity vector of the unit. local unitvel = self:GetVelocityVec3() - + if unitvel and UTILS.VecNorm(unitvel)~=0 then - + -- Get wind vector including turbulences. local wind=self:GetCoordinate():GetWindWithTurbulenceVec3() - - -- Include wind vector. + + -- Include wind vector. 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) - + -- 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})) - + --Set correct direction: if AxialVel.y > 0 then AoA = -AoA end - + -- Return AoA value in degrees. return math.deg(AoA) end - + end return nil @@ -872,24 +872,24 @@ function POSITIONABLE:GetClimbAngle() -- Get position of the unit. local unitpos = self:GetPosition() - + if unitpos then - + -- Get velocity vector of the unit. local unitvel = self:GetVelocityVec3() - + if unitvel and UTILS.VecNorm(unitvel)~=0 then -- Calculate climb angle. local angle=math.asin(unitvel.y/UTILS.VecNorm(unitvel)) - + -- Return angle in degrees. return math.deg(angle) else return 0 end end - + return nil end @@ -900,11 +900,11 @@ function POSITIONABLE:GetPitch() -- Get position of the unit. local unitpos = self:GetPosition() - + if unitpos then return math.deg(math.asin(unitpos.x.y)) end - + return nil end @@ -915,7 +915,7 @@ function POSITIONABLE:GetRoll() -- Get position of the unit. local unitpos = self:GetPosition() - + if unitpos then --first, make a vector that is perpendicular to y and unitpos.x with cross product @@ -934,8 +934,8 @@ function POSITIONABLE:GetRoll() if unitpos.z.y > 0 then -- left roll, flip the sign of the roll Roll = -Roll end - - return math.deg(Roll) + + return math.deg(Roll) end end @@ -948,19 +948,19 @@ function POSITIONABLE:GetYaw() 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 @@ -968,7 +968,7 @@ function POSITIONABLE:GetYaw() return Yaw end end - + end @@ -1052,7 +1052,7 @@ function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, N self:F2( { Message, Duration } ) local Name = Name or "" - + local DCSObject = self:GetDCSObject() if DCSObject then self:GetMessage( Message, Duration, Name ):ToCoalition( MessageCoalition ) @@ -1073,7 +1073,7 @@ function POSITIONABLE:MessageTypeToCoalition( Message, MessageType, MessageCoali self:F2( { Message, MessageType } ) local Name = Name or "" - + local DCSObject = self:GetDCSObject() if DCSObject then self:GetMessageType( Message, MessageType, Name ):ToCoalition( MessageCoalition ) @@ -1157,7 +1157,7 @@ function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name ) BASE:E( { "Message not sent to Group; Positionable is not alive ...", Message = Message, Positionable = self, MessageGroup = MessageGroup } ) end end - + return nil end @@ -1198,7 +1198,7 @@ function POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Nam MessageSetGroup:ForEachGroupAlive( function( MessageGroup ) self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup ) - end + end ) end end @@ -1223,13 +1223,13 @@ function POSITIONABLE:Message( Message, Duration, Name ) return nil end ---- Create a @{Core.Radio#RADIO}, to allow radio transmission for this POSITIONABLE. +--- Create a @{Core.Radio#RADIO}, to allow radio transmission for this POSITIONABLE. -- 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) + return RADIO:New(self) end --- Create a @{Core.Radio#BEACON}, to allow this POSITIONABLE to broadcast beacon signals @@ -1237,7 +1237,7 @@ end -- @return Core.Radio#RADIO Radio function POSITIONABLE:GetBeacon() --R2.1 self:F2(self) - return BEACON:New(self) + return BEACON:New(self) end --- Start Lasing a POSITIONABLE @@ -1258,9 +1258,9 @@ function POSITIONABLE:LaseUnit( Target, LaserCode, Duration ) --R2.1 self.Spot = SPOT:New( self ) -- Core.Spot#SPOT self.Spot:LaseOn( Target, LaserCode, Duration) self.LaserCode = LaserCode - + return self.Spot - + end --- Start Lasing a COORDINATE. @@ -1273,11 +1273,11 @@ function POSITIONABLE:LaseCoordinate(Coordinate, LaserCode, Duration) self:F2() LaserCode = LaserCode or math.random(1000, 9999) - + self.Spot = SPOT:New(self) -- Core.Spot#SPOT self.Spot:LaseOnCoordinate(Coordinate, LaserCode, Duration) self.LaserCode = LaserCode - + return self.Spot end @@ -1302,7 +1302,7 @@ function POSITIONABLE:IsLasing() --R2.1 self:F2() local Lasing = false - + if self.Spot then Lasing = self.Spot:IsLasing() end @@ -1314,7 +1314,7 @@ end -- @param #POSITIONABLE self -- @return Core.Spot#SPOT The Spot function POSITIONABLE:GetSpot() --R2.1 - + return self.Spot end @@ -1322,7 +1322,7 @@ end -- @param #POSITIONABLE self -- @return #number The laser code function POSITIONABLE:GetLaserCode() --R2.1 - + return self.LaserCode end @@ -1336,16 +1336,16 @@ do -- Cargo self.__.Cargo[Cargo] = Cargo return self end - + --- Get all contained cargo. -- @param #POSITIONABLE self -- @return #POSITIONABLE function POSITIONABLE:GetCargo() return self.__.Cargo end - - - + + + --- Remove cargo. -- @param #POSITIONABLE self -- @param Core.Cargo#CARGO Cargo @@ -1354,20 +1354,20 @@ do -- Cargo self.__.Cargo[Cargo] = nil return self end - + --- Returns if carrier has given cargo. -- @param #POSITIONABLE self -- @return Core.Cargo#CARGO Cargo function POSITIONABLE:HasCargo( Cargo ) return self.__.Cargo[Cargo] end - + --- Clear all cargo. -- @param #POSITIONABLE self function POSITIONABLE:ClearCargo() self.__.Cargo = {} end - + --- Is cargo bay empty. -- @param #POSITIONABLE self function POSITIONABLE:IsCargoEmpty() @@ -1378,7 +1378,7 @@ do -- Cargo end return IsEmpty end - + --- Get cargo item count. -- @param #POSITIONABLE self -- @return Core.Cargo#CARGO Cargo @@ -1389,7 +1389,7 @@ do -- Cargo end return ItemCount end - + -- --- Get Cargo Bay Free Volume in m3. -- -- @param #POSITIONABLE self -- -- @return #number CargoBayFreeVolume @@ -1400,18 +1400,18 @@ do -- Cargo -- end -- return self.__.CargoBayVolumeLimit - CargoVolume -- end --- - +-- + --- Get Cargo Bay Free Weight in kg. -- @param #POSITIONABLE self -- @return #number CargoBayFreeWeight function POSITIONABLE:GetCargoBayFreeWeight() - + -- When there is no cargo bay weight limit set, then calculate this for this positionable! if not self.__.CargoBayWeightLimit then self:SetCargoBayWeightLimit() end - + local CargoWeight = 0 for CargoName, Cargo in pairs( self.__.Cargo ) do CargoWeight = CargoWeight + Cargo:GetWeight() @@ -1430,29 +1430,29 @@ do -- Cargo -- @param #POSITIONABLE self -- @param #number WeightLimit function POSITIONABLE:SetCargoBayWeightLimit( WeightLimit ) - + if WeightLimit then self.__.CargoBayWeightLimit = WeightLimit 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. - + -- 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}) - local Weights = { + 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., - } + } self.__.CargoBayWeightLimit = Weights[Desc.typeName] or ( Desc.massMax - ( Desc.massEmpty + Desc.fuelMassMax ) ) else local Desc = self:GetDesc() - local Weights = { + local Weights = { ["M1126 Stryker ICV"] = 9, ["M-113"] = 9, ["AAV7"] = 25, @@ -1488,7 +1488,7 @@ do -- Cargo ["Ural-4320-31"] = 14, ["Ural-4320T"] = 14, } - + local CargoBayWeightLimit = ( Weights[Desc.typeName] or 0 ) * 95 self.__.CargoBayWeightLimit = CargoBayWeightLimit end @@ -1552,7 +1552,7 @@ function POSITIONABLE:Smoke( SmokeColor, Range, AddHeight ) Vec3.y = Vec3.y + AddHeight or 0 trigger.action.smoke( self:GetVec3(), SmokeColor ) end - + end --- Smoke the POSITIONABLE Green. @@ -1600,8 +1600,8 @@ function POSITIONABLE:IsInZone( Zone ) if self:IsAlive() then local IsInZone = Zone:IsVec3InZone( self:GetVec3() ) - - return IsInZone + + return IsInZone end return false end @@ -1615,9 +1615,9 @@ function POSITIONABLE:IsNotInZone( Zone ) if self:IsAlive() then local IsNotInZone = not Zone:IsVec3InZone( self:GetVec3() ) - - return IsNotInZone + + return IsNotInZone else return false end -end \ No newline at end of file +end diff --git a/Moose Setup/Moose.files b/Moose Setup/Moose.files index f0d3c0c0a..85249125e 100644 --- a/Moose Setup/Moose.files +++ b/Moose Setup/Moose.files @@ -22,6 +22,7 @@ Core/Fsm.lua Core/Radio.lua Core/Spawn.lua Core/SpawnStatic.lua +Core/Timer.lua Core/Goal.lua Core/Spot.lua