diff --git a/Moose Development/Moose/Core/Vector.lua b/Moose Development/Moose/Core/Vector.lua index 68ead6645..47fdafac3 100644 --- a/Moose Development/Moose/Core/Vector.lua +++ b/Moose Development/Moose/Core/Vector.lua @@ -282,7 +282,7 @@ end -- @param #VECTOR self -- @param #number Latitude Latitude in decimal degrees. -- @param #number Longitude Longitude in decimal degrees. --- @param #number altitude (Optional) Altitude in meters. Default is the land height at the 2D position. +-- @param #number Altitude (Optional) Altitude in meters. Default is the land height at the 2D position. -- @return #VECTOR self function VECTOR:NewFromLLDD(Latitude, Longitude, Altitude) @@ -291,13 +291,11 @@ function VECTOR:NewFromLLDD(Latitude, Longitude, Altitude) -- Convert vec3 to coordinate object. self=VECTOR:NewFromVec(vec3) - --- -- Adjust height --- if Altitude==nil then --- self.y=self:GetSurfaceHeight() --- else --- self.y=Altitude --- end + + -- Adjust height + if Altitude then + self.y=Altitude + end return self end @@ -533,15 +531,17 @@ function VECTOR:GetLatitudeLongitude() end ---- Get MGRS coordinates of this vector. +--- Get MGRS information of this vector. +-- +-- `MGRS = {UTMZone = string, MGRSDigraph = string, Easting = number, Northing = number}` +-- -- @param #VECTOR self --- @return #number Easting --- @return #number Northing +-- @return #table MGRS table with `UTMZone`, `MGRSDiGraph`, `Easting` and `Northing` keys. function VECTOR:GetMGRS() local lat, long=self:GetLatitudeLongitude() - local mrgs=coord.LLtoMGRS(lat, long) + local mgrs=coord.LLtoMGRS(lat, long) -- Example table returned by coord.LLtoMGRS --[[ @@ -553,7 +553,7 @@ function VECTOR:GetMGRS() } ]] - return mrgs.Easting, mrgs.Northing + return mgrs end --- Get the difference of the heading of this vector w. @@ -648,14 +648,13 @@ end --- Set z-component of vector. The z-axis points to the East. -- @param #VECTOR self -- @param #number z Value of z. Default 0. --- @param #VECTOR self +-- @return #VECTOR self function VECTOR:SetZ(z) self.z=z or 0 return self end - --- Add a vector to this. This function works for DCS#Vec2, DCS#Vec3, VECTOR, COORDINATE objects. -- Note that if you want to add a VECTOR, you can also simply use the `+` operator. -- @param #VECTOR self @@ -677,7 +676,8 @@ function VECTOR:AddVec(Vec) end --- Subtract a vector from this one. This function works for DCS#Vec2, DCS#Vec3, VECTOR, COORDINATE objects. --- Note that if you want to add a VECTOR, you can also simply use the `-` operator. +-- +-- **Note** that if you want to add a VECTOR, you can also simply use the `-` operator. -- @param #VECTOR self -- @param DCS#Vec3 Vec Vector to substract. Can also be a DCS#Vec2, DCS#Vec3, COORDINATE or VECTOR object. -- @return #VECTOR self @@ -828,10 +828,14 @@ function VECTOR:Rotate2D(Angle, Copy) local x = X*sinPhi + Y*cosPhi -- Create new vector. - -- TODO: Copy argument - local vector=VECTOR:New(x, self.y, z) - - return vector + if Copy then + local vector=VECTOR:New(x, self.y, z) + return vector + else + self:SetX(x) + self:SetZ(z) + return self + end end @@ -1061,47 +1065,28 @@ end --- Creates a smoke at this vector. -- @param #VECTOR self -- @param #number Color Color of the smoke: 0=Green, 1=Red, 2=White, 3=Orange, 4=Blue. Default 0. --- @param #number Duration (Optional) Duration of the smoke in seconds. Default nil. +-- @param #number Duration (Optional) Duration of the smoke in seconds. Default nil. +-- @return #string Name of the smoke object. Can be used to stop it. function VECTOR:Smoke(Color, Duration) local vec3=self:GetVec3() Color=Color or 0 - self.nameSmoke=string.format("Vector-Smoke-%d", self.uid) - - trigger.action.smoke(vec3, Color, self.nameSmoke) + -- Create a name for the smoke object + local name=string.format("Vector-Smoke-%d", self.uid) + -- Create smoke at this position + trigger.action.smoke(vec3, Color, name) if Duration and Duration>0 then - self:StopSmoke(Duration) + self:StopSmoke(name, Duration) end - return self + return name end ---- Stops smoke. --- @param #VECTOR self --- @return #VECTOR self -function VECTOR:StopSmoke(Delay) - - printf("stop smoke") - - if Delay and Delay>0 then - timer.scheduleFunction(VECTOR.StopSmoke, self, timer.getTime()+Delay) - printf("stop smoke scheduled") - else - if self.nameSmoke then - trigger.action.effectSmokeStop(self.nameSmoke) - self.nameSmoke=nil - printf("stop smoke NOW") - end - end - - return self -end - --- Creates a large smoke and fire effect of a specified type and density at this vector. -- -- * 1 = small smoke and fire @@ -1116,29 +1101,62 @@ end -- @param #VECTOR self -- @param #number Preset Preset of smoke. Default `BIGSMOKEPRESET.LargeSmokeAndFire`. -- @param #number Density Density between [0,1]. Default 0.5. --- @return #string Name of the smoke. Can be used to stop it. -function VECTOR:SmokeAndFire(Preset, Density) +-- @param #number Duration (Optional) Duration of the smoke and fire in seconds. +-- @return #string Name of the smoke. Can be used to stop it. +function VECTOR:SmokeAndFire(Preset, Density, Duration) Preset=Preset or BIGSMOKEPRESET.LargeSmokeAndFire Density=Density or 0.5 local vec3=self:GetVec3() - --TODO: Get a unique name or pass name as parameter? + -- Get a name of this smoke & fire object + local name=string.format("Vector-Fire-%d", self.uid) - trigger.action.effectSmokeBig(vec3, Preset, Density, Name) + trigger.action.effectSmokeBig(vec3, Preset, Density, name) + + if Duration and Duration>0 then + self:StopSmoke(name, Duration) + end - return Name + return name end +--- Stop smoke or fire effect. +-- @param #VECTOR self +-- @param #string Name Name of the smoke object. +-- @param #number Delay Delay in seconds before the smoke is stopped. +-- @return #VECTOR self +function VECTOR:StopSmoke(Name, Delay) + + if Delay and Delay>0 then + TIMER:New(VECTOR.StopSmoke, self, Name):Start(Delay) + else + if Name then + trigger.action.effectSmokeStop(Name) + else + env.error(string.format("No name provided in VECTOR.StopSmoke function!")) + end + end + + return self +end + + --- Creates an illumination bomb at the specified point. -- @param #VECTOR self -- @param #number Power The power in Candela (cd). Should be between 1 and 1000000. Default 1000 cd. +-- @param #number Altitude (Optional) Altitude [m] at which the illumination bomb is created. -- @return #VECTOR self -function VECTOR:IlluminationBomb(Power) +function VECTOR:IlluminationBomb(Power, Altitude) local vec3=self:GetVec3() + + if Altitude then + vec3.y=Altitude + end + -- Create an illumination bomb. trigger.action.illuminationBomb(vec3, Power or 1000) return self @@ -1199,6 +1217,49 @@ function VECTOR:ArrowTo(Vector, Coalition, Color, FillColor, LineType) return id end + +--- Create mark on F10 map. +-- @param #VECTOR self +-- @param #string MarkText Free format text that shows the marking clarification. +-- @param #number Recipient Recipient of the mark: -1=All (default), 0=Neutral, 1=Red, 2=Blue. Can also be a `GROUP` object. +-- @param #boolean ReadOnly (Optional) Mark is readonly and cannot be removed by users. Default false. +-- @return #number Mark ID. +function VECTOR:Mark(MarkText, Recipient, ReadOnly) + + Recipient=Recipient or -1 + + if type(Recipient)=="number" then + + local MarkID = UTILS.GetMarkID() + + if Recipient==-1 then + trigger.action.markToAll(MarkID, MarkText, self:GetVec3(), ReadOnly, "") + elseif Recipient==0 then + trigger.action.markToCoalition(MarkID, MarkText, self:GetVec3(), coalition.side.NEUTRAL, ReadOnly, "") + elseif Recipient==1 then + trigger.action.markToCoalition(MarkID, MarkText, self:GetVec3(), coalition.side.RED, ReadOnly, "") + elseif Recipient==2 then + trigger.action.markToCoalition(MarkID, MarkText, self:GetVec3(), coalition.side.BLUE, ReadOnly, "") + end + + return MarkID + + elseif type(Recipient)=="table" then + + local MarkID = UTILS.GetMarkID() + + local group=Recipient --Wrapper.Group#GROUP + + trigger.action.markToGroup( MarkID, MarkText, self:GetVec3(), group:GetID(), ReadOnly, "") + + return MarkID + + end + + return nil +end + + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Private Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -1256,17 +1317,21 @@ function VECTOR.__mul(a, b) return c end ---- Meta function for dividing vectors by scalars. +--- Meta function for dividing a vector by a scalar or by another vector. -- @param #VECTOR a Vector a. --- @param #number b Number by which the components of the vector are divided. --- @return #VECTOR Returns a new VECTOR c with c[i]=a[i]/b for i=x,y,z. +-- @param #VECTOR b Vector b. Can also be a #number. +-- @return #VECTOR Returns a new VECTOR c with c[i]=a[i]/b or c[i]=a[i]/b[i] for i=x,y,z. function VECTOR.__div(a, b) - assert(VECTOR._IsVector(a) and type(b) == "number", "div: wrong argument types (expected and )") - - env.info("FF __div") + assert(VECTOR._IsVector(a) and (type(b) == "number" or VECTOR._IsVector(b)), "div: wrong argument types (expected and ( or ))") - local c=VECTOR:New(a.x/b, a.y/b, a.z/b) + local c=nil --#VECTOR + + if type(b) == "number" then + c=VECTOR:New(a.x/b, a.y/b, a.z/b) + else + c=VECTOR:New(a.x/b.x, a.y/b.y, a.z/b.z) + end return c end @@ -1295,7 +1360,7 @@ end -- @param #VECTOR self -- @return #string String representation of vector. function VECTOR:__tostring() - local text=string.format("(x=%.1f, y=%.1f, z=%.1f) |v|=%.1f Phi=%4.1f°", self.x, self.y, self.z, self:GetLength(), self:GetHeading(false)) + local text=string.format("VECTOR: x=%.1f, y=%.1f, z=%.1f |v|=%.1f Phi=%4.1f°", self.x, self.y, self.z, self:GetLength(), self:GetHeading(false)) return text end diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index 13008b613..3e980c0ab 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -219,6 +219,25 @@ function POSITIONABLE:GetOrientationZ() end end +--- Returns the vectors of the orientation of the object: +-- X is the orientation parallel to the movement of the object, Z perpendicular and Y vertical orientation. +-- @param #POSITIONABLE self +-- @return Core.Vector#VECTOR X orientation, i.e. parallel to the direction of movement. +-- @return Core.Vector#VECTOR Y orientation, i.e. vertical. +-- @return Core.Vector#VECTOR Z orientation, i.e. perpendicular to the direction of movement. +function POSITIONABLE:GetOrientationVectors() + local position = self:GetPosition() + if position then + local vecx=VECTOR:NewFromVec(position.x) + local vecy=VECTOR:NewFromVec(position.y) + local vecz=VECTOR:NewFromVec(position.z) + return vecx, vecy, vecz + else + BASE:E( { "Cannot GetOrientation", Positionable = self, Alive = self:IsAlive() } ) + return nil, nil, nil + end +end + --- Returns the @{DCS#Position3} position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission. -- @param #POSITIONABLE self -- @return DCS#Position The 3D position vectors of the POSITIONABLE. @@ -935,6 +954,24 @@ function POSITIONABLE:GetVelocityVec3() return nil end +--- Returns the velocity vector. +-- @param #POSITIONABLE self +-- @return Core.Vector#VECTOR The velocity vector or `nil` if the object does not exist. +function POSITIONABLE:GetVelocityVector() + + local DCSPositionable = self:GetDCSObject() + + if DCSPositionable and DCSPositionable:isExist() then + local vec3 = DCSPositionable:getVelocity() + local vector=VECTOR:NewFromVec(vec3) + return vector + end + + BASE:E( { "Cannot GetVelocityVector", Positionable = self, Alive = self:IsAlive() } ) + + return nil +end + --- Get relative velocity with respect to another POSITIONABLE. -- @param #POSITIONABLE self -- @param #POSITIONABLE Positionable Other POSITIONABLE.