diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index e3e7c17c1..ac290aa2f 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -449,10 +449,10 @@ do -- Zones and Pathlines -- Loop over layers. for layerID, layerData in pairs(env.mission.drawings.layers or {}) do - + -- Loop over objects in layers. for objectID, objectData in pairs(layerData.objects or {}) do - + -- Check for polygon which has at least 4 points (we would need 3 but the origin seems to be there twice) if objectData.polygonMode and (objectData.polygonMode=="free") and objectData.points and #objectData.points>=4 then @@ -488,10 +488,32 @@ do -- Zones and Pathlines -- Create new polygon zone. local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName, points) - + + --Zone.DrawID = objectID + -- Set color. Zone:SetColor({1, 0, 0}, 0.15) - + Zone:SetFillColor({1, 0, 0}, 0.15) + + if objectData.colorString then + -- eg colorString = 0xff0000ff + local color = string.gsub(objectData.colorString,"^0x","") + local r = tonumber(string.sub(color,1,2),16)/255 + local g = tonumber(string.sub(color,3,4),16)/255 + local b = tonumber(string.sub(color,5,6),16)/255 + local a = tonumber(string.sub(color,7,8),16)/255 + Zone:SetColor({r, g, b}, a) + end + if objectData.fillColorString then + -- eg fillColorString = 0xff00004b + local color = string.gsub(objectData.colorString,"^0x","") + local r = tonumber(string.sub(color,1,2),16)/255 + local g = tonumber(string.sub(color,3,4),16)/255 + local b = tonumber(string.sub(color,5,6),16)/255 + local a = tonumber(string.sub(color,7,8),16)/255 + Zone:SetFillColor({r, g, b}, a) + end + -- Store in DB. self.ZONENAMES[ZoneName] = ZoneName @@ -532,7 +554,26 @@ do -- Zones and Pathlines -- Set color. Zone:SetColor({1, 0, 0}, 0.15) - + + if objectData.colorString then + -- eg colorString = 0xff0000ff + local color = string.gsub(objectData.colorString,"^0x","") + local r = tonumber(string.sub(color,1,2),16)/255 + local g = tonumber(string.sub(color,3,4),16)/255 + local b = tonumber(string.sub(color,5,6),16)/255 + local a = tonumber(string.sub(color,7,8),16)/255 + Zone:SetColor({r, g, b}, a) + end + if objectData.fillColorString then + -- eg fillColorString = 0xff00004b + local color = string.gsub(objectData.colorString,"^0x","") + local r = tonumber(string.sub(color,1,2),16)/255 + local g = tonumber(string.sub(color,3,4),16)/255 + local b = tonumber(string.sub(color,5,6),16)/255 + local a = tonumber(string.sub(color,7,8),16)/255 + Zone:SetFillColor({r, g, b}, a) + end + -- Store in DB. self.ZONENAMES[ZoneName] = ZoneName @@ -756,7 +797,7 @@ end -- cargo --- Finds a CLIENT based on the ClientName. -- @param #DATABASE self --- @param #string ClientName +-- @param #string ClientName - Note this is the UNIT name of the client! -- @return Wrapper.Client#CLIENT The found CLIENT. function DATABASE:FindClient( ClientName ) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 1037ddf02..2b5b1d4f3 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -2020,7 +2020,7 @@ _ZONE_TRIANGLE = { Coords={}, CenterVec2={x=0, y=0}, SurfaceArea=0, - DrawIDs={} + DrawID={} } --- -- @param #_ZONE_TRIANGLE self @@ -2100,15 +2100,35 @@ function _ZONE_TRIANGLE:Draw(Coalition, Color, Alpha, FillColor, FillAlpha, Line for i=1, #self.Coords do local c1 = self.Coords[i] local c2 = self.Coords[i % #self.Coords + 1] - table.add(self.DrawIDs, c1:LineToAll(c2, Coalition, Color, Alpha, LineType, ReadOnly)) + local id = c1:LineToAll(c2, Coalition, Color, Alpha, LineType, ReadOnly) + self.DrawID[#self.DrawID+1] = id end - return self.DrawIDs + local newID = self.Coords[1]:MarkupToAllFreeForm({self.Coords[2],self.Coords[3]},Coalition,Color,Alpha,FillColor,FillAlpha,LineType,ReadOnly) + self.DrawID[#self.DrawID+1] = newID + return self.DrawID +end + +--- Draw the triangle +-- @param #_ZONE_TRIANGLE self +-- @return #table of draw IDs +function _ZONE_TRIANGLE:Fill(Coalition, FillColor, FillAlpha, ReadOnly) + Coalition=Coalition or -1 + FillColor = FillColor + FillAlpha = FillAlpha + local newID = self.Coords[1]:MarkupToAllFreeForm({self.Coords[2],self.Coords[3]},Coalition,nil,nil,FillColor,FillAlpha,0,nil) + self.DrawID[#self.DrawID+1] = newID + return self.DrawID end --- -- @type ZONE_POLYGON_BASE -- @field #ZONE_POLYGON_BASE.ListVec2 Polygon The polygon defined by an array of @{DCS#Vec2}. +-- @field #number SurfaceArea +-- @field #table DrawID +-- @field #table FillTriangles +-- @field #table _Triangles +-- @field #table Borderlines -- @extends #ZONE_BASE @@ -2133,9 +2153,11 @@ end -- @field #ZONE_POLYGON_BASE ZONE_POLYGON_BASE = { ClassName="ZONE_POLYGON_BASE", - _Triangles={}, -- _ZONE_TRIANGLES + _Triangles={}, -- #table of #_ZONE_TRIANGLE SurfaceArea=0, - DrawID={} -- making a table out of the MarkID so its easier to draw an n-sided polygon, see ZONE_POLYGON_BASE:Draw() + DrawID={}, -- making a table out of the MarkID so its easier to draw an n-sided polygon, see ZONE_POLYGON_BASE:Draw() + FillTriangles = {}, + Borderlines = {}, } --- A 2D points array. @@ -2172,7 +2194,7 @@ function ZONE_POLYGON_BASE:New( ZoneName, PointsArray ) self._Triangles = self:_Triangulate() -- set the polygon's surface area self.SurfaceArea = self:_CalculateSurfaceArea() - + end return self @@ -2470,18 +2492,18 @@ end -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. -- doesn't seem to work -- @param #number FillAlpha Transparency [0,1]. Default 0.15. -- doesn't seem to work -- @param #number LineType Line type: 0=No line, 1=Solid, 2=Dashed, 3=Dotted, 4=Dot dash, 5=Long dash, 6=Two dash. Default 1=Solid. --- @param #boolean ReadOnly (Optional) Mark is readonly and cannot be removed by users. Default false. +-- @param #boolean ReadOnly (Optional) Mark is readonly and cannot be removed by users. Default false.s -- @return #ZONE_POLYGON_BASE self function ZONE_POLYGON_BASE:DrawZone(Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, IncludeTriangles) local coords = self:GetVerticiesCoordinates() - + local coord=coords[1] --Core.Point#COORDINATE - + table.remove(coords, 1) - + coord:MarkupToAllFreeForm(coords, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, "Drew Polygon") - + if true then return end @@ -2533,8 +2555,94 @@ function ZONE_POLYGON_BASE:DrawZone(Coalition, Color, Alpha, FillColor, FillAlph table.add(self.DrawID, c1:LineToAll(c2, Coalition, Color, Alpha, LineType, ReadOnly)) end end + + if self._.Polygon and #self._.Polygon >= 3 then + Coalition = Coalition or self:GetDrawCoalition() + + -- Set draw coalition. + self:SetDrawCoalition(Coalition) + + Color = Color or self:GetColorRGB() + Alpha = Alpha or self:GetColorAlpha() + + FillColor = FillColor or self:GetFillColorRGB() + FillAlpha = FillAlpha or self:GetFillColorAlpha() + + if FillColor then + self:ReFill(FillColor,FillAlpha) end - return self + + if Color then + self:ReDrawBorderline(Color,Alpha,LineType) + end + end + + return self +end + +--- Change/Re-fill a Polygon Zone +-- @param #ZONE_POLYGON_BASE self +-- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red. +-- @param #number Alpha Transparency [0,1]. Default 1. +-- @return #ZONE_POLYGON_BASE self +function ZONE_POLYGON_BASE:ReFill(Color,Alpha) + local color = Color or self:GetFillColorRGB() or {1,0,0} + local alpha = Alpha or self:GetFillColorAlpha() or 1 + local coalition = self:GetDrawCoalition() or -1 + -- undraw if already filled + if #self.FillTriangles > 0 then + for _, triangle in pairs(self._Triangles) do + triangle:UndrawZone() + end + -- remove mark IDs + for _,_value in pairs(self.FillTriangles) do + table.remove_by_value(self.DrawID, _value) + end + self.FillTriangles = nil + self.FillTriangles = {} + end + -- refill + for _, triangle in pairs(self._Triangles) do + local draw_ids = triangle:Fill(coalition,color,alpha,nil) + self.FillTriangles = draw_ids + table.combine(self.DrawID, draw_ids) + end + return self +end + +--- Change/Re-draw the border of a Polygon Zone +-- @param #ZONE_POLYGON_BASE self +-- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red. +-- @param #number Alpha Transparency [0,1]. Default 1. +-- @param #number LineType Line type: 0=No line, 1=Solid, 2=Dashed, 3=Dotted, 4=Dot dash, 5=Long dash, 6=Two dash. Default 1=Solid. +-- @return #ZONE_POLYGON_BASE +function ZONE_POLYGON_BASE:ReDrawBorderline(Color, Alpha, LineType) + local color = Color or self:GetFillColorRGB() or {1,0,0} + local alpha = Alpha or self:GetFillColorAlpha() or 1 + local coalition = self:GetDrawCoalition() or -1 + local linetype = LineType or 1 + -- undraw if already drawn + if #self.Borderlines > 0 then + for _, MarkID in pairs(self.Borderlines) do + trigger.action.removeMark(MarkID) + end + -- remove mark IDs + for _,_value in pairs(self.Borderlines) do + table.remove_by_value(self.DrawID, _value) + end + self.Borderlines = nil + self.Borderlines = {} + end + -- Redraw border + local coords = self:GetVerticiesCoordinates() + for i = 1, #coords do + local c1 = coords[i] + local c2 = coords[i % #coords + 1] + local newID = c1:LineToAll(c2, coalition, color, alpha, linetype, nil) + self.DrawID[#self.DrawID+1]=newID + self.Borderlines[#self.Borderlines+1] = newID + end + return self end --- Get the surface area of this polygon @@ -2870,6 +2978,7 @@ function ZONE_POLYGON_BASE:Boundary(Coalition, Color, Radius, Alpha, Segments, C Alpha = Alpha or 1 Segments = Segments or 10 Closed = Closed or false + local Limit local i = 1 local j = #self._.Polygon if (Closed) then @@ -3068,18 +3177,18 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories ) self.ScanData.Scenery = {} self.ScanData.SceneryTable = {} self.ScanData.Units = {} - + local vectors = self:GetBoundingSquare() - + local minVec3 = {x=vectors.x1, y=0, z=vectors.y1} local maxVec3 = {x=vectors.x2, y=0, z=vectors.y2} - + local minmarkcoord = COORDINATE:NewFromVec3(minVec3) local maxmarkcoord = COORDINATE:NewFromVec3(maxVec3) local ZoneRadius = minmarkcoord:Get2DDistance(maxmarkcoord)/2 -- self:I("Scan Radius:" ..ZoneRadius) local CenterVec3 = self:GetCoordinate():GetVec3() - + --[[ this a bit shaky in functionality it seems local VolumeBox = { id = world.VolumeType.BOX, @@ -3089,7 +3198,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories ) } } --]] - + local SphereSearch = { id = world.VolumeType.SPHERE, params = { @@ -3097,13 +3206,13 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories ) radius = ZoneRadius, } } - + local function EvaluateZone( ZoneObject ) if ZoneObject then local ObjectCategory = Object.getCategory(ZoneObject) - + if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then local CoalitionDCSUnit = ZoneObject:getCoalition() @@ -3137,7 +3246,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories ) self:F2( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } ) end end - + -- trying with box search if ObjectCategory == Object.Category.SCENERY and self:IsVec3InZone(ZoneObject:getPoint()) then local SceneryType = ZoneObject:getTypeName() @@ -3156,7 +3265,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories ) -- Search objects. local inzoneunits = SET_UNIT:New():FilterZones({self}):FilterOnce() local inzonestatics = SET_STATIC:New():FilterZones({self}):FilterOnce() - + inzoneunits:ForEach( function(unit) local Unit = unit --Wrapper.Unit#UNIT @@ -3164,7 +3273,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories ) EvaluateZone(DCS) end ) - + inzonestatics:ForEach( function(static) local Static = static --Wrapper.Static#STATIC @@ -3172,19 +3281,19 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories ) EvaluateZone(DCS) end ) - + local searchscenery = false for _,_type in pairs(ObjectCategories) do if _type == Object.Category.SCENERY then searchscenery = true end end - + if searchscenery then -- Search objects. world.searchObjects({Object.Category.SCENERY}, SphereSearch, EvaluateZone ) end - + end --- Count the number of different coalitions inside the zone. @@ -3400,7 +3509,7 @@ end end do -- ZONE_ELASTIC - + --- -- @type ZONE_ELASTIC -- @field #table points Points in 2D. @@ -3427,14 +3536,14 @@ do -- ZONE_ELASTIC function ZONE_ELASTIC:New(ZoneName, Points) local self=BASE:Inherit(self, ZONE_POLYGON_BASE:New(ZoneName, Points)) --#ZONE_ELASTIC - + -- Zone objects are added to the _DATABASE and SET_ZONE objects. _EVENTDISPATCHER:CreateEventNewZone( self ) - + if Points then self.points=Points end - + return self end @@ -3443,10 +3552,10 @@ do -- ZONE_ELASTIC -- @param DCS#Vec2 Vec2 Point in 2D (with x and y coordinates). -- @return #ZONE_ELASTIC self function ZONE_ELASTIC:AddVertex2D(Vec2) - + -- Add vec2 to points. table.insert(self.points, Vec2) - + return self end @@ -3456,10 +3565,10 @@ do -- ZONE_ELASTIC -- @param DCS#Vec3 Vec3 Point in 3D (with x, y and z coordinates). Only the x and z coordinates are used. -- @return #ZONE_ELASTIC self function ZONE_ELASTIC:AddVertex3D(Vec3) - + -- Add vec2 from vec3 to points. table.insert(self.points, {x=Vec3.x, y=Vec3.z}) - + return self end @@ -3469,10 +3578,10 @@ do -- ZONE_ELASTIC -- @param Core.Set#SET_GROUP GroupSet Set of groups. -- @return #ZONE_ELASTIC self function ZONE_ELASTIC:AddSetGroup(GroupSet) - + -- Add set to table. table.insert(self.setGroups, GroupSet) - + return self end @@ -3484,13 +3593,13 @@ do -- ZONE_ELASTIC -- @param #boolean Draw Draw the zone. Default `nil`. -- @return #ZONE_ELASTIC self function ZONE_ELASTIC:Update(Delay, Draw) - + -- Debug info. self:T(string.format("Updating ZONE_ELASTIC %s", tostring(self.ZoneName))) - + -- Copy all points. local points=UTILS.DeepCopy(self.points or {}) - + if self.setGroups then for _,_setGroup in pairs(self.setGroups) do local setGroup=_setGroup --Core.Set#SET_GROUP @@ -3505,7 +3614,7 @@ do -- ZONE_ELASTIC -- Update polygon verticies from points. self._.Polygon=self:_ConvexHull(points) - + if Draw~=false then if self.DrawID or Draw==true then self:UndrawZone() @@ -3515,7 +3624,7 @@ do -- ZONE_ELASTIC return self end - + --- Start the updating scheduler. -- @param #ZONE_ELASTIC self -- @param #number Tstart Time in seconds before the updating starts. @@ -3524,9 +3633,9 @@ do -- ZONE_ELASTIC -- @param #boolean Draw Draw the zone. Default `nil`. -- @return #ZONE_ELASTIC self function ZONE_ELASTIC:StartUpdate(Tstart, dT, Tstop, Draw) - + self.updateID=self:ScheduleRepeat(Tstart, dT, 0, Tstop, ZONE_ELASTIC.Update, self, 0, Draw) - + return self end @@ -3535,46 +3644,46 @@ do -- ZONE_ELASTIC -- @param #number Delay Delay in seconds before the scheduler will be stopped. Default 0. -- @return #ZONE_ELASTIC self function ZONE_ELASTIC:StopUpdate(Delay) - + if Delay and Delay>0 then self:ScheduleOnce(Delay, ZONE_ELASTIC.StopUpdate, self) else - + if self.updateID then - + self:ScheduleStop(self.updateID) - + self.updateID=nil - + end - + end - + return self end - + --- Create a convec hull. -- @param #ZONE_ELASTIC self -- @param #table pl Points -- @return #table Points function ZONE_ELASTIC:_ConvexHull(pl) - + if #pl == 0 then return {} end - + table.sort(pl, function(left,right) return left.x < right.x end) - + local h = {} - + -- Function: ccw > 0 if three points make a counter-clockwise turn, clockwise if ccw < 0, and collinear if ccw = 0. local function ccw(a,b,c) return (b.x - a.x) * (c.y - a.y) > (b.y - a.y) * (c.x - a.x) end - + -- lower hull for i,pt in pairs(pl) do while #h >= 2 and not ccw(h[#h-1], h[#h], pt) do @@ -3582,7 +3691,7 @@ do -- ZONE_ELASTIC end table.insert(h,pt) end - + -- upper hull local t = #h + 1 for i=#pl, 1, -1 do @@ -3592,12 +3701,12 @@ do -- ZONE_ELASTIC end table.insert(h, pt) end - + table.remove(h, #h) - + return h - end - + end + end @@ -3634,7 +3743,7 @@ ZONE_OVAL = { function ZONE_OVAL:New(name, vec2, major_axis, minor_axis, angle) self = BASE:Inherit(self, ZONE_BASE:New()) - + self.ZoneName = name self.CenterVec2 = vec2 self.MajorAxis = major_axis @@ -3672,7 +3781,7 @@ function ZONE_OVAL:NewFromDrawing(DrawingName) return self end ---- Gets the major axis of the oval. +--- Gets the major axis of the oval. -- @param #ZONE_OVAL self -- @return #number The major axis of the oval function ZONE_OVAL:GetMajorAxis() @@ -3868,7 +3977,7 @@ do -- ZONE_AIRBASE self._.ZoneAirbase = Airbase self._.ZoneVec2Cache = self._.ZoneAirbase:GetVec2() - + if Airbase:IsShip() then self.isShip=true self.isHelipad=false @@ -3876,11 +3985,11 @@ do -- ZONE_AIRBASE elseif Airbase:IsHelipad() then self.isShip=false self.isHelipad=true - self.isAirdrome=false + self.isAirdrome=false elseif Airbase:IsAirdrome() then self.isShip=false self.isHelipad=false - self.isAirdrome=true + self.isAirdrome=true end -- Zone objects are added to the _DATABASE and SET_ZONE objects. diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 9fe3d9823..49739f2a6 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -1064,9 +1064,9 @@ function UTILS.BeaufortScale(speed) return bn,bd end ---- Split string at seperators. C.f. [split-string-in-lua](http://stackoverflow.com/questions/1426954/split-string-in-lua). +--- Split string at separators. C.f. [split-string-in-lua](http://stackoverflow.com/questions/1426954/split-string-in-lua). -- @param #string str Sting to split. --- @param #string sep Speparator for split. +-- @param #string sep Separator for split. -- @return #table Split text. function UTILS.Split(str, sep) local result = {} @@ -2146,17 +2146,17 @@ function UTILS.IsLoadingDoorOpen( unit_name ) return true end - if string.find(type_name, "Bell-47") then -- bell aint got no doors so always ready to load injured soldiers + if type_name == "Bell-47" then -- bell aint got no doors so always ready to load injured soldiers BASE:T(unit_name .. " door is open") return true end - - if string.find(type_name, "UH-60L") and (unit:getDrawArgumentValue(401) == 1 or unit:getDrawArgumentValue(402) == 1) then + + if type_name == "UH-60L" and (unit:getDrawArgumentValue(401) == 1 or unit:getDrawArgumentValue(402) == 1) then BASE:T(unit_name .. " cargo door is open") return true end - if string.find(type_name, "UH-60L" ) and (unit:getDrawArgumentValue(38) == 1 or unit:getDrawArgumentValue(400) == 1 ) then + if type_name == "UH-60L" and (unit:getDrawArgumentValue(38) > 0 or unit:getDrawArgumentValue(400) == 1 ) then BASE:T(unit_name .. " front door(s) are open") return true end diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index e7d4ca3c9..0bed05a72 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -3772,54 +3772,66 @@ function CONTROLLABLE:OptionProhibitAfterburner( Prohibit ) return self end ---- Defines the usage of Electronic Counter Measures by airborne forces. Disables the ability for AI to use their ECM. +--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. -- @param #CONTROLLABLE self +-- @param #number ECMvalue Can be - 0=Never on, 1=if locked by radar, 2=if detected by radar, 3=always on, defaults to 1 -- @return #CONTROLLABLE self -function CONTROLLABLE:OptionECM_Never() +function CONTROLLABLE:OptionECM( ECMvalue ) self:F2( { self.ControllableName } ) - if self:IsAir() then - self:SetOption( AI.Option.Air.id.ECM_USING, 0 ) + local DCSControllable = self:GetDCSObject() + if DCSControllable then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ECM_USING, ECMvalue or 1 ) + end + end return self end ---- Defines the usage of Electronic Counter Measures by airborne forces. If the AI is actively being locked by an enemy radar they will enable their ECM jammer. +--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. Disables the ability for AI to use their ECM. +-- @param #CONTROLLABLE self +-- @return #CONTROLLABLE self +function CONTROLLABLE:OptionECM_Never() + self:F2( { self.ControllableName } ) + + self:OptionECM(0) + + return self +end + +--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. If the AI is actively being locked by an enemy radar they will enable their ECM jammer. -- @param #CONTROLLABLE self -- @return #CONTROLLABLE self function CONTROLLABLE:OptionECM_OnlyLockByRadar() self:F2( { self.ControllableName } ) - if self:IsAir() then - self:SetOption( AI.Option.Air.id.ECM_USING, 1 ) - end + self:OptionECM(1) return self end ---- Defines the usage of Electronic Counter Measures by airborne forces. If the AI is being detected by a radar they will enable their ECM. +--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. If the AI is being detected by a radar they will enable their ECM. -- @param #CONTROLLABLE self -- @return #CONTROLLABLE self function CONTROLLABLE:OptionECM_DetectedLockByRadar() self:F2( { self.ControllableName } ) - if self:IsAir() then - self:SetOption( AI.Option.Air.id.ECM_USING, 2 ) - end + self:OptionECM(2) return self end ---- Defines the usage of Electronic Counter Measures by airborne forces. AI will leave their ECM on all the time. +--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. AI will leave their ECM on all the time. -- @param #CONTROLLABLE self -- @return #CONTROLLABLE self function CONTROLLABLE:OptionECM_AlwaysOn() self:F2( { self.ControllableName } ) - if self:IsAir() then - self:SetOption( AI.Option.Air.id.ECM_USING, 3 ) - end + self:OptionECM(3) return self end diff --git a/docs/beginner/ask-for-help.md b/docs/beginner/ask-for-help.md new file mode 100644 index 000000000..bf8a9c8f6 --- /dev/null +++ b/docs/beginner/ask-for-help.md @@ -0,0 +1,77 @@ +--- +parent: Beginner +nav_order: 06 +--- +# How to ask for help +{: .no_toc } + +1. Table of contents +{:toc} + +After you have tried to solve the problem on your own, you can also get help +from the community. + +{: .highlight } +> But it is important to follow certain rules! Read them below. + +## Communities + +There are two ways to communicate with the community. +The fastest way is to use Discord: + +- {:target="_blank"} + +But if you don't like Discord, you are able to post in the DCS forum. +Check out the MOOSE thread here: + +- + +## How to post requests + +MOOSE is a community project and support is community based. + +Please remember when posting a question: + +- Before posting anything follow the [troubleshooting steps]. +- **Read your logs**. + +A post should contain the following: + +1. A describtion what you expected to happen and what actually happened. + - Do not use vague words this stuff is hard to help with! Be specific. + +2. Describe what happens instead. + - The less detail you offer, the less chance you can be helped. + - Don’t say it doesn’t work. Or is it broken. Say what it actually does. + +3. Post your code in Discord as formatted code: + + - Wrap a single line of code in backticks \` like this: + + ![discord-single-line-code.png](../images/beginner/discord-single-line-code.png) + + - Multiple lines of code should be posted like this: + + ![discord-multi-line-code.png](../images/beginner/discord-multi-line-code.png) + +- Post your log lines with the error or warning messages. Format them like this: + + ![discord-fomat-logs.png](../images/beginner/discord-fomat-logs.png) + +- Some complex problems need the mission (.miz file) also. + + - But post your mission only when requested. + - Try to simplify your mission if it is complex! + +There are people in the Discord and in the forum, who spend their free time to +help you.
+It is your responsibility to make their "work" as easy as possible. + +Welcome to MOOSE and good luck! + +## Next step + +Last but not least some [tipps and tricks]. + +[troubleshooting steps]: problems.md +[tipps and tricks]: tipps-and-tricks.md diff --git a/docs/beginner/demo-missions.md b/docs/beginner/demo-missions.md index 073ae42fd..b5e3eea1b 100644 --- a/docs/beginner/demo-missions.md +++ b/docs/beginner/demo-missions.md @@ -9,5 +9,50 @@ nav_order: 04 1. Table of contents {:toc} -{: .warning } -> THIS DOCUMENT IS STILL WORK IN PROGRESS! +The best way to get compftable with a Moose class is to try the demo missions of +the class you want to learn. The Moose team created a lot of demo missions for +most of the classes. + +## Download demo missions + +Go to the repository [MOOSE_MISSIONS]{:target="_blank"}, search the folder of +the class, download the mission (`.miz`) and rum them. + +## Read the mission script + +In the same folder a `.lua` file with the same name is placed which is the +included mission script. You can watch these mission scripts easily online at +GitHub to understand what is happening in the mission. + +## Read documentation + +Next step is to read the [documentation]{:target="_blank"} of the class to +understand the code of the demo mission. + +{: .note } +> The documentation is quite long and might be confusing for beginners. +> Start by looking at the description at the top of the documentation of a +> class. It often contains examples and explanations.

+> Then search for the function names and look at the description of the +> functions and its parameters. + +## Make small changes to the script + +Download the `.lua` file, change the parameters to suit your needs in +[Notepad++]{:target="_blank"}, add it to the mission and rerun the mission. +Observe what happens and adapt the code. + +If you want to use more functions combine them all up. + +{: .note } +> But it is wise to do this in small steps. So it is easier to find errors. + +## Next step + +If the mission shows not the expected behaviour take a look at section +[problems]. + +[MOOSE_MISSIONS]: https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop +[documentation]: https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/index.html +[Notepad++]: https://notepad-plus-plus.org/downloads/ +[problems]: problems.md diff --git a/docs/beginner/hello-world-build.md b/docs/beginner/hello-world-build.md index 1f7509abd..5227a295d 100644 --- a/docs/beginner/hello-world-build.md +++ b/docs/beginner/hello-world-build.md @@ -144,9 +144,16 @@ have create everything on your own. - Change the text a little bit, like `Hello Dude! ...` and save the file. - Run the mission again. - The text will not be changed in the mission. Why? - The mission editor copies the script into the mission file when you add it. - Ever change on the script file on your hard disk is not recognized by mission editor. - You have to add the file after each change again. + +{: .important } +The mission editor copies the script into the mission file when you add it. +Every change on the script file on your hard disk is not recognized by mission +editor. **You have to add the file after each change again!** + +There is also another method available to dynamically load mission scripts. +But this method has some brawbacks and will be explained in the advanced section. + +Now we add the mission script again: - On the left side of the `TRIGGERS` dialog click on `Load Mission Script`. - On the right side under `ACTIONS` you need to add the script again: diff --git a/docs/beginner/problems.md b/docs/beginner/problems.md new file mode 100644 index 000000000..ebc71077a --- /dev/null +++ b/docs/beginner/problems.md @@ -0,0 +1,46 @@ +--- +parent: Beginner +nav_order: 05 +--- + +# Problems +{: .no_toc } + +1. Table of contents +{:toc} + +## Something went wrong + +If the mission shows not the expected behaviour do the following steps: + +1. Double check if you added the changed mission script to the mission again! +1. Check if the triggers are configured as requested in the last sections. + +## Read the logs + +The DCS log is a super important and useful log for the entire of DCS World. +All scripting and other errors are recorded here. It is the one stop shop for +things that occurred in your mission. It will tell you if there was a mistake. + +1. Open the file `dcs.log` in the `Logs` subfolder in your DCS + [Saved Games folder]. + +1. Search for the following line: `*** MOOSE INCLUDE END ***` + - If it is included in the log, Moose was loaded. + - If the line is not in the log check the triggers again! + +1. Search for lines with `SCRIPTING` and `WARNING` or `ERROR` and read them. + - This might help to find your error. + + {: .note } + > You will find a lot of warning and error lines in the log which are not + > related to `SCRIPTING`. They are related to stuff from Eagle Dynamics or + > Third Parties and you have to ignore them. EA does the same. ;o) + +## Next step + +If you don't find the error and/or don't understand the messages in the log file +you can [ask for help]. + +[Saved Games folder]: tipps-and-tricks.md#find-the-saved-games-folder +[ask for help]: ask-for-help.md diff --git a/docs/beginner/tipps-and-tricks.md b/docs/beginner/tipps-and-tricks.md index 3ea1bd781..f97615318 100644 --- a/docs/beginner/tipps-and-tricks.md +++ b/docs/beginner/tipps-and-tricks.md @@ -33,7 +33,9 @@ This folder can be found in your userprofile as subfolder of `Saved Games`. The easiest way to find it, is to open search and paste the text below into it and press Enter: -```%userprofile%\Saved Games``` +``` +%userprofile%\Saved Games +``` {: .note } > The text will work even if your Windows is installed with another language, diff --git a/docs/images/beginner/discord-fomat-logs.png b/docs/images/beginner/discord-fomat-logs.png new file mode 100644 index 000000000..a78cecce3 Binary files /dev/null and b/docs/images/beginner/discord-fomat-logs.png differ diff --git a/docs/images/beginner/discord-multi-line-code.png b/docs/images/beginner/discord-multi-line-code.png new file mode 100644 index 000000000..84b7f3841 Binary files /dev/null and b/docs/images/beginner/discord-multi-line-code.png differ diff --git a/docs/images/beginner/discord-single-line-code.png b/docs/images/beginner/discord-single-line-code.png new file mode 100644 index 000000000..fc1e7dafd Binary files /dev/null and b/docs/images/beginner/discord-single-line-code.png differ