Merge branch 'master' into FF/MasterDevel

This commit is contained in:
Frank 2023-12-21 22:22:10 +01:00
commit 8fb126682f
12 changed files with 438 additions and 99 deletions

View File

@ -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 )

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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:
- <https://discord.gg/gj68fm969S>{:target="_blank"}
But if you don't like Discord, you are able to post in the DCS forum.
Check out the MOOSE thread here:
- <https://forums.eagle.ru/showthread.php?t=138043>
## 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.
- Dont say it doesnt 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. <br />
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

View File

@ -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. <br /><br />
> 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

View File

@ -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:

46
docs/beginner/problems.md Normal file
View File

@ -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

View File

@ -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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB