From 2e66a854b1b849786d0490d80ece8d9d83dd8338 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 1 May 2021 00:55:43 +0200 Subject: [PATCH 1/8] Events and Templates --- Moose Development/Moose/Core/Event.lua | 74 +++++-- Moose Development/Moose/DCS.lua | 11 ++ Moose Development/Moose/Modules.lua | 1 + .../Moose/Utilities/Templates.lua | 183 ++++++++++++++++++ Moose Setup/Moose.files | 1 + 5 files changed, 255 insertions(+), 15 deletions(-) create mode 100644 Moose Development/Moose/Utilities/Templates.lua diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 07ddcfdf1..e243d2266 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -236,11 +236,11 @@ EVENTS = { RemoveUnit = world.event.S_EVENT_REMOVE_UNIT, PlayerEnterAircraft = world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT, -- Added with DCS 2.5.6 - DetailedFailure = world.event.S_EVENT_DETAILED_FAILURE or -1, --We set this to -1 for backward compatibility to DCS 2.5.5 and earlier - Kill = world.event.S_EVENT_KILL or -1, - Score = world.event.S_EVENT_SCORE or -1, - UnitLost = world.event.S_EVENT_UNIT_LOST or -1, - LandingAfterEjection = world.event.S_EVENT_LANDING_AFTER_EJECTION or -1, + DetailedFailure = world.event.S_EVENT_DETAILED_FAILURE or -1, --We set this to -1 for backward compatibility to DCS 2.5.5 and earlier + Kill = world.event.S_EVENT_KILL or -1, + Score = world.event.S_EVENT_SCORE or -1, + UnitLost = world.event.S_EVENT_UNIT_LOST or -1, + LandingAfterEjection = 31, --world.event.S_EVENT_LANDING_AFTER_EJECTION or -1, -- Added with DCS 2.7.0 ParatrooperLanding = world.event.S_EVENT_PARATROOPER_LENDING or -1, DiscardChairAfterEjection = world.event.S_EVENT_DISCARD_CHAIR_AFTER_EJECTION or -1, @@ -524,7 +524,7 @@ local _EVENTMETA = { Event = "OnEventUnitLost", Text = "S_EVENT_UNIT_LOST" }, - [EVENTS.LandingAfterEjection] = { + [world.event.S_EVENT_LANDING_AFTER_EJECTION] = { Order = 1, Event = "OnEventLandingAfterEjection", Text = "S_EVENT_LANDING_AFTER_EJECTION" @@ -578,6 +578,10 @@ function EVENT:New() -- Add world event handler. self.EventHandler = world.addEventHandler(self) + for _,Event in pairs(self.Events) do + self:Init(Event,EventClass) + end + return self end @@ -588,7 +592,9 @@ end -- @param Core.Base#BASE EventClass The class object for which events are handled. -- @return #EVENT.Events function EVENT:Init( EventID, EventClass ) - self:F3( { _EVENTMETA[EventID].Text, EventClass } ) + self:I( { _EVENTMETA[EventID].Text, EventClass } ) + + env.info("FF EVENT.Init ID="..EventID) if not self.Events[EventID] then -- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned. @@ -983,6 +989,8 @@ end -- @param #EVENTDATA Event Event data table. function EVENT:onEvent( Event ) + env.info("FF some event") + local ErrorHandler = function( errmsg ) env.info( "Error in SCHEDULER function:" .. errmsg ) @@ -1000,17 +1008,37 @@ function EVENT:onEvent( Event ) -- Check if this is a known event? if EventMeta then - if self and - self.Events and - self.Events[Event.id] and - self.MissionEnd == false and - ( Event.initiator ~= nil or ( Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit ) ) then + env.info("FF some event 100 ID="..tostring(Event.id)) + + if Event.id==31 then + env.info("FF got event 31") + local initiator=Event.initiator~=nil + env.info(string.format("FF got event 31 initiator=%s", tostring(initiator))) + if self then + env.info(string.format("FF got event 31 self=true")) + end + if self.Events then + env.info(string.format("FF got event 31 self.Events=true")) + end + if self.Events[Event.id] then + env.info(string.format("FF got event 31 self.Events[Event.id]=true")) + else + env.info(string.format("FF NO event 31 self.Events[Event.id]=FALSE!")) + end + end + + --if self and self.Events and self.Events[Event.id] and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.idss~=EVENTS.PlayerLeaveUnit)) then + if self and self.Events and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.idss~=EVENTS.PlayerLeaveUnit)) then if Event.id and Event.id == EVENTS.MissionEnd then self.MissionEnd = true end - if Event.initiator then + env.info("FF some event 150") + + if Event.initiator then + + env.info("FF some event 200") Event.IniObjectCategory = Event.initiator:getCategory() @@ -1039,9 +1067,14 @@ function EVENT:onEvent( Event ) end if Event.IniObjectCategory == Object.Category.STATIC then + + env.info("FF some event 300") + if Event.id==31 then - --env.info("FF event 31") - -- Event.initiator is a Static object representing the pilot. But getName() error due to DCS bug. + + env.info("FF event 31") + + -- Event.initiator is a Static object representing the pilot. But getName() errors due to DCS bug. Event.IniDCSUnit = Event.initiator local ID=Event.initiator.id_ Event.IniDCSUnitName = string.format("Ejected Pilot ID %s", tostring(ID)) @@ -1049,6 +1082,17 @@ function EVENT:onEvent( Event ) Event.IniCoalition = 0 Event.IniCategory = 0 Event.IniTypeName = "Ejected Pilot" + + local static=Event.initiator + local vec3=static:getPoint() + + local template=TEMPLATE.GetGround(TEMPLATE.Ground.SoldierM4, "Ejected Pilot", country.id.USA, vec3) + local group=_DATABASE:Spawn(template) + Event.IniDCSGroup=group:GetDCSObject() + Event.IniCoalition=group:GetCoalition() + Event.IniCategory=group:GetCategory() + + else Event.IniDCSUnit = Event.initiator Event.IniDCSUnitName = Event.IniDCSUnit:getName() diff --git a/Moose Development/Moose/DCS.lua b/Moose Development/Moose/DCS.lua index 92052d5cf..01661a678 100644 --- a/Moose Development/Moose/DCS.lua +++ b/Moose Development/Moose/DCS.lua @@ -295,6 +295,17 @@ do -- country -- @field QATAR -- @field OMAN -- @field UNITED_ARAB_EMIRATES + -- @field SOUTH_AFRICA + -- @field CUBA + -- @field PORTUGAL + -- @field GDR + -- @field LEBANON + -- @field CJTF_BLUE + -- @field CJTF_RED + -- @field UN_PEACEKEEPERS + -- @field Argentinia + -- @field Cyprus + -- @field Slovenia country = {} --#country diff --git a/Moose Development/Moose/Modules.lua b/Moose Development/Moose/Modules.lua index 62d483052..c4bb9eb87 100644 --- a/Moose Development/Moose/Modules.lua +++ b/Moose Development/Moose/Modules.lua @@ -2,6 +2,7 @@ __Moose.Include( 'Scripts/Moose/Utilities/Enums.lua' ) __Moose.Include( 'Scripts/Moose/Utilities/Routines.lua' ) __Moose.Include( 'Scripts/Moose/Utilities/Utils.lua' ) __Moose.Include( 'Scripts/Moose/Utilities/Profiler.lua' ) +__Moose.Include( 'Scripts/Moose/Utilities/Templates.lua' ) __Moose.Include( 'Scripts/Moose/Core/Base.lua' ) __Moose.Include( 'Scripts/Moose/Core/UserFlag.lua' ) diff --git a/Moose Development/Moose/Utilities/Templates.lua b/Moose Development/Moose/Utilities/Templates.lua new file mode 100644 index 000000000..51885c4a9 --- /dev/null +++ b/Moose Development/Moose/Utilities/Templates.lua @@ -0,0 +1,183 @@ +--- **Utils** Templates +-- +-- DCS unit templates +-- +-- @module Utilities.Templates +-- @image MOOSE.JPG + +--- TEMPLATE class. +-- @type TEMPLATE +-- @field #string ClassName Name of the class. + +--- *Templates* +-- +-- === +-- +-- ![Banner Image](..\Presentations\Utilities\PROFILER_Main.jpg) +-- +-- Get DCS templates from thin air. +-- +-- # Ground Units +-- +-- Ground units. +-- +-- # Naval Units +-- +-- Ships are not implemented yet. +-- +-- # Aircraft +-- +-- ## Airplanes +-- +-- Airplanes are not implemented yet. +-- +-- ## Helicopters +-- +-- Helicopters are not implemented yet. +-- +-- @field #TEMPLATE +TEMPLATE = { + ClassName = "TEMPLATE", + Ground = {}, + Naval = {}, + Airplane = {}, + Helicopter = {}, +} + +--- Pattern steps. +-- @type TEMPLATE.Ground +-- @param #string InfantryAK +TEMPLATE.Ground={ + InfantryAK="Infantry AK", + ParatrooperAKS74="Paratrooper AKS-74", + ParatrooperRPG16="Paratrooper RPG-16", + SoldierWWIIUS="soldier_wwii_us", + InfantryM248="Infantry M249", + SoldierM4="Soldier M4", +} + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Start/Stop Profiler +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Get template for ground units. +-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`. +-- @param #string GroupName Name of the spawned group. **Must be unique!** +-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to. +-- @param DCS#Vec3 Vec3 Position of the group. +-- @param #number Nunits Number of units. Default 1. +-- @param #number Radius Spawn radius for additonal units in meters. Default 50 m. +-- @return #table Template Template table. +function TEMPLATE.GetGround(TypeName, GroupName, CountryID, Vec3, Nunits, Radius) + + local template=UTILS.DeepCopy(TEMPLATE.GenericGround) + + template.name=GroupName or "Ground-1" + + -- These are additional entries required by the MOOSE _DATABASE:Spawn() function. + template.CountryID=country.id.USA + template.CoalitionID=coalition.getCountryCoalition(template.CountryID) + template.CategoryID=Unit.Category.GROUND_UNIT + + template.units[1].type=TypeName or "Infantry AK" + template.units[1].name=GroupName.."-1" + + if Vec3 then + TEMPLATE.SetPositionFromVec3(template, Vec3) + end + + return template +end + +TEMPLATE.GenericGround= +{ + ["visible"] = false, + ["tasks"] = {}, -- end of ["tasks"] + ["uncontrollable"] = false, + ["task"] = "Ground Nothing", + ["route"] = + { + ["spans"] = {}, -- end of ["spans"] + ["points"] = + { + [1] = + { + ["alt"] = 0, + ["type"] = "Turning Point", + ["ETA"] = 0, + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["y"] = 0, + ["x"] = 0, + ["ETA_locked"] = true, + ["speed"] = 0, + ["action"] = "Off Road", + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = nil, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["transportable"] = + { + ["randomTransportable"] = false, + }, -- end of ["transportable"] + ["skill"] = "Average", + ["type"] = "Infantry AK", + ["unitId"] = nil, + ["y"] = 0, + ["x"] = 0, + ["name"] = "Infantry AK-47 Rus", + ["heading"] = 0, + ["playerCanDrive"] = false, + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 0, + ["x"] = 0, + ["name"] = "Infantry AK-47 Rus", + ["start_time"] = 0, +} + +--- Set the position of the template. +-- @param #table Template The template to be modified. +-- @param DCS#Vec2 Vec2 2D Position vector with x and y components of the group. +function TEMPLATE.SetPositionFromVec2(Template, Vec2) + + Template.x=Vec2.x + Template.y=Vec2.y + + for _,unit in pairs(Template.units) do + unit.x=Vec2.x + unit.y=Vec2.y + end + + Template.route.points[1].x=Vec2.x + Template.route.points[1].y=Vec2.y + Template.route.points[1].alt=0 --TODO: Use land height. + +end + +--- Set the position of the template. +-- @param #table Template The template to be modified. +-- @param DCS#Vec3 Vec3 Position vector of the group. +function TEMPLATE.SetPositionFromVec3(Template, Vec3) + + local Vec2={x=Vec3.x, y=Vec3.z} + + TEMPLATE.SetPositionFromVec2(Template, Vec2) + +end \ No newline at end of file diff --git a/Moose Setup/Moose.files b/Moose Setup/Moose.files index f64bb2ff3..79c9b120e 100644 --- a/Moose Setup/Moose.files +++ b/Moose Setup/Moose.files @@ -3,6 +3,7 @@ Utilities/Routines.lua Utilities/Utils.lua Utilities/Enums.lua Utilities/Profiler.lua +Utilities/Templates.lua Core/Base.lua Core/UserFlag.lua From d1f3e3f4bbd654d6e4c990622a5e1e2b62afd9d2 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 2 May 2021 00:08:17 +0200 Subject: [PATCH 2/8] Update Templates.lua --- .../Moose/Utilities/Templates.lua | 220 +++++++++++++++--- 1 file changed, 194 insertions(+), 26 deletions(-) diff --git a/Moose Development/Moose/Utilities/Templates.lua b/Moose Development/Moose/Utilities/Templates.lua index 51885c4a9..df7c3ff0b 100644 --- a/Moose Development/Moose/Utilities/Templates.lua +++ b/Moose Development/Moose/Utilities/Templates.lua @@ -89,6 +89,42 @@ function TEMPLATE.GetGround(TypeName, GroupName, CountryID, Vec3, Nunits, Radius return template end + + +--- Set the position of the template. +-- @param #table Template The template to be modified. +-- @param DCS#Vec2 Vec2 2D Position vector with x and y components of the group. +function TEMPLATE.SetPositionFromVec2(Template, Vec2) + + Template.x=Vec2.x + Template.y=Vec2.y + + for _,unit in pairs(Template.units) do + unit.x=Vec2.x + unit.y=Vec2.y + end + + Template.route.points[1].x=Vec2.x + Template.route.points[1].y=Vec2.y + Template.route.points[1].alt=0 --TODO: Use land height. + +end + +--- Set the position of the template. +-- @param #table Template The template to be modified. +-- @param DCS#Vec3 Vec3 Position vector of the group. +function TEMPLATE.SetPositionFromVec3(Template, Vec3) + + local Vec2={x=Vec3.x, y=Vec3.z} + + TEMPLATE.SetPositionFromVec2(Template, Vec2) + +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Generic Ground Template +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + TEMPLATE.GenericGround= { ["visible"] = false, @@ -152,32 +188,164 @@ TEMPLATE.GenericGround= ["start_time"] = 0, } ---- Set the position of the template. --- @param #table Template The template to be modified. --- @param DCS#Vec2 Vec2 2D Position vector with x and y components of the group. -function TEMPLATE.SetPositionFromVec2(Template, Vec2) +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Generic Ship Template +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Template.x=Vec2.x - Template.y=Vec2.y - - for _,unit in pairs(Template.units) do - unit.x=Vec2.x - unit.y=Vec2.y - end - - Template.route.points[1].x=Vec2.x - Template.route.points[1].y=Vec2.y - Template.route.points[1].alt=0 --TODO: Use land height. - -end +TEMPLATE.GenericNaval= +{ + ["visible"] = false, + ["tasks"] = {}, -- end of ["tasks"] + ["uncontrollable"] = false, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 0, + ["type"] = "Turning Point", + ["ETA"] = 0, + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["y"] = 0, + ["x"] = 0, + ["ETA_locked"] = true, + ["speed"] = 0, + ["action"] = "Turning Point", + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = nil, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["transportable"] = + { + ["randomTransportable"] = false, + }, -- end of ["transportable"] + ["skill"] = "Average", + ["type"] = "TICONDEROG", + ["unitId"] = nil, + ["y"] = 0, + ["x"] = 0, + ["name"] = "Naval-1-1", + ["heading"] = 0, + ["modulation"] = 0, + ["frequency"] = 127500000, + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 0, + ["x"] = 0, + ["name"] = "Naval-1", + ["start_time"] = 0, +} ---- Set the position of the template. --- @param #table Template The template to be modified. --- @param DCS#Vec3 Vec3 Position vector of the group. -function TEMPLATE.SetPositionFromVec3(Template, Vec3) +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Generic Ship Template +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +TEMPLATE.GenericHelicopter= +{ + ["modulation"] = 0, + ["tasks"] = {}, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "Nothing", + ["uncontrolled"] = false, + ["taskSelected"] = true, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 10, + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["speed"] = 41.666666666667, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["type"] = "TakeOffParking", + ["ETA"] = 0, + ["ETA_locked"] = true, + ["y"] = 618351.087765, + ["x"] = -356168.27327001, + ["formation_template"] = "", + ["airdromeId"] = 22, + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = nil, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 10, + ["alt_type"] = "BARO", + ["livery_id"] = "USA X Black", + ["skill"] = "High", + ["parking"] = "4", + ["ropeLength"] = 15, + ["speed"] = 41.666666666667, + ["type"] = "AH-1W", + ["unitId"] = 8, + ["psi"] = 0, + ["parking_id"] = "10", + ["x"] = -356168.27327001, + ["name"] = "Rotary-1-1", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = "1250.0", + ["flare"] = 30, + ["chaff"] = 30, + ["gun"] = 100, + }, -- end of ["payload"] + ["y"] = 618351.087765, + ["heading"] = 0, + ["callsign"] = + { + [1] = 2, + [2] = 1, + [3] = 1, + ["name"] = "Springfield11", + }, -- end of ["callsign"] + ["onboard_num"] = "050", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 0, + ["x"] = 0, + ["name"] = "Rotary-1", + ["communication"] = true, + ["start_time"] = 0, + ["frequency"] = 127.5, +} +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - local Vec2={x=Vec3.x, y=Vec3.z} - - TEMPLATE.SetPositionFromVec2(Template, Vec2) - -end \ No newline at end of file From 20fe2ee5053ba72852e5f680c645f7b77fa1d138 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 10 May 2021 08:33:15 +0200 Subject: [PATCH 3/8] Update Event.lua --- Moose Development/Moose/Core/Event.lua | 30 +------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 17baca821..cac2433e2 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -1008,38 +1008,14 @@ function EVENT:onEvent( Event ) -- Check if this is a known event? if EventMeta then - env.info("FF some event 100 ID="..tostring(Event.id)) - - if Event.id==31 then - env.info("FF got event 31") - local initiator=Event.initiator~=nil - env.info(string.format("FF got event 31 initiator=%s", tostring(initiator))) - if self then - env.info(string.format("FF got event 31 self=true")) - end - if self.Events then - env.info(string.format("FF got event 31 self.Events=true")) - end - if self.Events[Event.id] then - env.info(string.format("FF got event 31 self.Events[Event.id]=true")) - else - env.info(string.format("FF NO event 31 self.Events[Event.id]=FALSE!")) - end - end - - --if self and self.Events and self.Events[Event.id] and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.idss~=EVENTS.PlayerLeaveUnit)) then - if self and self.Events and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.idss~=EVENTS.PlayerLeaveUnit)) then + if self and self.Events and self.Events[Event.id] and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.idss~=EVENTS.PlayerLeaveUnit)) then if Event.id and Event.id == EVENTS.MissionEnd then self.MissionEnd = true end - env.info("FF some event 150") - if Event.initiator then - env.info("FF some event 200") - Event.IniObjectCategory = Event.initiator:getCategory() if Event.IniObjectCategory == Object.Category.UNIT then @@ -1068,12 +1044,8 @@ function EVENT:onEvent( Event ) if Event.IniObjectCategory == Object.Category.STATIC then - env.info("FF some event 300") - if Event.id==31 then - env.info("FF event 31") - -- Event.initiator is a Static object representing the pilot. But getName() errors due to DCS bug. Event.IniDCSUnit = Event.initiator local ID=Event.initiator.id_ From 59e4f487264fc402ce80b113f91492913d933f74 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 10 May 2021 17:47:42 +0200 Subject: [PATCH 4/8] COORDINATES and ZONES - Quad zones defined in the ME are now registered as ZONE_POLYGON_BASE - Added draw functions to COORDINATE (line, circle, arrow, rectangle, text) --- Moose Development/Moose/Core/Database.lua | 69 +++++- Moose Development/Moose/Core/Event.lua | 6 +- Moose Development/Moose/Core/Fsm.lua | 2 +- Moose Development/Moose/Core/Point.lua | 208 +++++++++++++++-- Moose Development/Moose/Core/Zone.lua | 239 +++++++++++++++++++- Moose Development/Moose/Utilities/Utils.lua | 11 + 6 files changed, 504 insertions(+), 31 deletions(-) diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index eafe78140..0d6d2bb35 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -298,24 +298,81 @@ do -- Zones -- @return #DATABASE self function DATABASE:_RegisterZones() - for ZoneID, ZoneData in pairs( env.mission.triggers.zones ) do + for ZoneID, ZoneData in pairs(env.mission.triggers.zones) do local ZoneName = ZoneData.name + + -- Color + local color=ZoneData.color or {1, 0, 0, 0.15} + + -- Create new Zone + local Zone=nil --Core.Zone#ZONE_BASE + + if ZoneData.type==0 then + + --- + -- Circular zone + --- + + self:I(string.format("Register ZONE: %s (Circular)", ZoneName)) + + Zone=ZONE:New(ZoneName) + + else - self:I( { "Register ZONE:", Name = ZoneName } ) - local Zone = ZONE:New( ZoneName ) - self.ZONENAMES[ZoneName] = ZoneName - self:AddZone( ZoneName, Zone ) + --- + -- Quad-point zone + --- + + self:I(string.format("Register ZONE: %s (Polygon, Quad)", ZoneName)) + + Zone=ZONE_POLYGON_BASE:New(ZoneName, ZoneData.verticies) + + for i,vec2 in pairs(ZoneData.verticies) do + local coord=COORDINATE:NewFromVec2(vec2) + coord:MarkToAll(string.format("%s Point %d", ZoneName, i)) + end + + end + + if Zone then + + -- Debug output. + --self:I({"Register ZONE: %s (", Name = ZoneName}) + + Zone.Color=color + + + -- Store in DB. + self.ZONENAMES[ZoneName] = ZoneName + + -- Add zone. + self:AddZone(ZoneName, Zone) + + end + end + -- Polygon zones defined by late activated groups. for ZoneGroupName, ZoneGroup in pairs( self.GROUPS ) do if ZoneGroupName:match("#ZONE_POLYGON") then + local ZoneName1 = ZoneGroupName:match("(.*)#ZONE_POLYGON") local ZoneName2 = ZoneGroupName:match(".*#ZONE_POLYGON(.*)") local ZoneName = ZoneName1 .. ( ZoneName2 or "" ) - self:I( { "Register ZONE_POLYGON:", Name = ZoneName } ) + -- Debug output + self:I(string.format("Register ZONE: %s (Polygon)", ZoneName)) + + -- Create a new polygon zone. local Zone_Polygon = ZONE_POLYGON:New( ZoneName, ZoneGroup ) + + -- Set color. + Zone_Polygon:SetColor({1, 0, 0}, 0.15) + + -- Store name in DB. self.ZONENAMES[ZoneName] = ZoneName + + -- Add zone to DB. self:AddZone( ZoneName, Zone_Polygon ) end end diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index cac2433e2..85384ac02 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -592,9 +592,7 @@ end -- @param Core.Base#BASE EventClass The class object for which events are handled. -- @return #EVENT.Events function EVENT:Init( EventID, EventClass ) - self:I( { _EVENTMETA[EventID].Text, EventClass } ) - - env.info("FF EVENT.Init ID="..EventID) + self:F( { _EVENTMETA[EventID].Text, EventClass } ) if not self.Events[EventID] then -- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned. @@ -989,8 +987,6 @@ end -- @param #EVENTDATA Event Event data table. function EVENT:onEvent( Event ) - env.info("FF some event") - local ErrorHandler = function( errmsg ) env.info( "Error in SCHEDULER function:" .. errmsg ) diff --git a/Moose Development/Moose/Core/Fsm.lua b/Moose Development/Moose/Core/Fsm.lua index 80dfcb0c5..644a04d63 100644 --- a/Moose Development/Moose/Core/Fsm.lua +++ b/Moose Development/Moose/Core/Fsm.lua @@ -540,7 +540,7 @@ do -- FSM --- Returns a table with the scores defined. -- @param #FSM self - -- @param #table Scores. + -- @return #table Scores. function FSM:GetScores() return self._Scores or {} end diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index 26aaa9dd7..59465fdd2 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -164,6 +164,7 @@ do -- COORDINATE -- -- * @{#COORDINATE.WaypointAir}(): Build an air route point. -- * @{#COORDINATE.WaypointGround}(): Build a ground route point. + -- * @{#COORDINATE.WaypointNaval}(): Build a naval route point. -- -- Route points can be used in the Route methods of the @{Wrapper.Group#GROUP} class. -- @@ -183,10 +184,18 @@ do -- COORDINATE -- -- ## 9) Coordinate text generation -- - -- -- * @{#COORDINATE.ToStringBR}(): Generates a Bearing & Range text in the format of DDD for DI where DDD is degrees and DI is distance. -- * @{#COORDINATE.ToStringLL}(): Generates a Latutude & Longutude text. -- + -- ## 10) Drawings on F10 map + -- + -- * @{#COORDINATE.CircleToAll}(): Draw a circle on the F10 map. + -- * @{#COORDINATE.LineToAll}(): Draw a line on the F10 map. + -- * @{#COORDINATE.RectToAll}(): Draw a rectangle on the F10 map. + -- * @{#COORDINATE.QuadToAll}(): Draw a shape with four points on the F10 map. + -- * @{#COORDINATE.TextToAll}(): Write some text on the F10 map. + -- * @{#COORDINATE.ArrowToAll}(): Draw an arrow on the F10 map. + -- -- @field #COORDINATE COORDINATE = { ClassName = "COORDINATE", @@ -1984,13 +1993,13 @@ do -- COORDINATE -- @param #COORDINATE self -- @param #COORDINATE Endpoint COORDIANTE to where the line is drawn. -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. - -- @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 #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). -- @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. -- @param #boolean ReadOnly (Optional) Mark is readonly and cannot be removed by users. Default false. -- @param #string Text (Optional) Text displayed when mark is added. Default none. - -- @return #number The resulting Mark ID which is a number. - function COORDINATE:LineToAll(Endpoint, Coalition, LineType, Color, Alpha, ReadOnly, Text) + -- @return #number The resulting Mark ID, which is a number. Can be used to remove the object again. + function COORDINATE:LineToAll(Endpoint, Coalition, Color, Alpha, LineType, ReadOnly, Text) local MarkID = UTILS.GetMarkID() if ReadOnly==nil then ReadOnly=false @@ -2007,18 +2016,17 @@ do -- COORDINATE --- Circle to all. -- Creates a circle on the map with a given radius, color, fill color, and outline. -- @param #COORDINATE self - -- @param #COORDINATE Center COORDIANTE of the center of the circle. -- @param #numberr Radius Radius in meters. Default 1000 m. -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. - -- @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 #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). -- @param #number Alpha Transparency [0,1]. Default 1. - -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red (default). - -- @param #number FillAlpha Transparency [0,1]. Default 0.5. + -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. + -- @param #number FillAlpha Transparency [0,1]. Default 0.15. + -- @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 #string Text (Optional) Text displayed when mark is added. Default none. - -- @return #number The resulting Mark ID which is a number. - function COORDINATE:CircleToAll(Radius, Coalition, LineType, Color, Alpha, FillColor, FillAlpha, ReadOnly, Text) + -- @return #number The resulting Mark ID, which is a number. Can be used to remove the object again. + function COORDINATE:CircleToAll(Radius, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, Text) local MarkID = UTILS.GetMarkID() if ReadOnly==nil then ReadOnly=false @@ -2029,14 +2037,188 @@ do -- COORDINATE Color=Color or {1,0,0} Color[4]=Alpha or 1.0 LineType=LineType or 1 - FillColor=FillColor or {1,0,0} - FillColor[4]=FillAlpha or 0.5 + FillColor=FillColor or Color + FillColor[4]=FillAlpha or 0.15 trigger.action.circleToAll(Coalition, MarkID, vec3, Radius, Color, FillColor, LineType, ReadOnly, Text or "") return MarkID end end -- Markings - + + --- Rectangle to all. Creates a rectangle on the map from the COORDINATE in one corner to the end COORDINATE in the opposite corner. + -- Creates a line on the F10 map from one point to another. + -- @param #COORDINATE self + -- @param #COORDINATE Endpoint COORDIANTE in the opposite corner. + -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. + -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). + -- @param #number Alpha Transparency [0,1]. Default 1. + -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. + -- @param #number FillAlpha Transparency [0,1]. Default 0.15. + -- @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 #string Text (Optional) Text displayed when mark is added. Default none. + -- @return #number The resulting Mark ID, which is a number. Can be used to remove the object again. + function COORDINATE:RectToAll(Endpoint, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, Text) + local MarkID = UTILS.GetMarkID() + if ReadOnly==nil then + ReadOnly=false + end + local vec3=Endpoint:GetVec3() + Coalition=Coalition or -1 + Color=Color or {1,0,0} + Color[4]=Alpha or 1.0 + LineType=LineType or 1 + FillColor=FillColor or Color + FillColor[4]=FillAlpha or 0.15 + trigger.action.rectToAll(Coalition, MarkID, self:GetVec3(), vec3, Color, FillColor, LineType, ReadOnly, Text or "") + return MarkID + end + + --- Creates a shape defined by 4 points on the F10 map. The first point is the current COORDINATE. The remaining three points need to be specified. + -- @param #COORDINATE self + -- @param #COORDINATE Coord2 Second COORDIANTE of the quad shape. + -- @param #COORDINATE Coord3 Third COORDIANTE of the quad shape. + -- @param #COORDINATE Coord4 Fourth COORDIANTE of the quad shape. + -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. + -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). + -- @param #number Alpha Transparency [0,1]. Default 1. + -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. + -- @param #number FillAlpha Transparency [0,1]. Default 0.15. + -- @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 #string Text (Optional) Text displayed when mark is added. Default none. + -- @return #number The resulting Mark ID, which is a number. Can be used to remove the object again. + function COORDINATE:QuadToAll(Coord2, Coord3, Coord4, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, Text) + local MarkID = UTILS.GetMarkID() + if ReadOnly==nil then + ReadOnly=false + end + local point1=self:GetVec3() + local point2=Coord2:GetVec3() + local point3=Coord3:GetVec3() + local point4=Coord4:GetVec3() + Coalition=Coalition or -1 + Color=Color or {1,0,0} + Color[4]=Alpha or 1.0 + LineType=LineType or 1 + FillColor=FillColor or Color + FillColor[4]=FillAlpha or 0.15 + trigger.action.quadToAll(Coalition, MarkID, self:GetVec3(), point2, point3, point4, Color, FillColor, LineType, ReadOnly, Text or "") + return MarkID + end + + --- Creates a free form shape on the F10 map. The first point is the current COORDINATE. The remaining points need to be specified. + -- **NOTE**: A free form polygon must have **at least three points** in total and currently only **up to 10 points** in total are supported. + -- @param #COORDINATE self + -- @param #table Coordinates Table of coordinates of the remaining points of the shape. + -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. + -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). + -- @param #number Alpha Transparency [0,1]. Default 1. + -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. + -- @param #number FillAlpha Transparency [0,1]. Default 0.15. + -- @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 #string Text (Optional) Text displayed when mark is added. Default none. + -- @return #number The resulting Mark ID, which is a number. Can be used to remove the object again. + function COORDINATE:MarkupToAllFreeForm(Coordinates, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, Text) + local MarkID = UTILS.GetMarkID() + if ReadOnly==nil then + ReadOnly=false + end + Coalition=Coalition or -1 + Color=Color or {1,0,0} + Color[4]=Alpha or 1.0 + LineType=LineType or 1 + FillColor=FillColor or Color + FillColor[4]=FillAlpha or 0.15 + + local vecs={} + table.insert(vecs, self:GetVec3()) + for _,coord in ipairs(Coordinates) do + table.insert(vecs, coord:GetVec3()) + end + + if #vecs<3 then + self:E("ERROR: A free form polygon needs at least three points!") + elseif #vecs==3 then + trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], Color, FillColor, LineType, ReadOnly, Text or "") + elseif #vecs==4 then + trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], Color, FillColor, LineType, ReadOnly, Text or "") + elseif #vecs==5 then + trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], Color, FillColor, LineType, ReadOnly, Text or "") + elseif #vecs==6 then + trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], Color, FillColor, LineType, ReadOnly, Text or "") + elseif #vecs==7 then + trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], Color, FillColor, LineType, ReadOnly, Text or "") + elseif #vecs==8 then + trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], Color, FillColor, LineType, ReadOnly, Text or "") + elseif #vecs==9 then + trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], Color, FillColor, LineType, ReadOnly, Text or "") + elseif #vecs==10 then + trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], vecs[10], Color, FillColor, LineType, ReadOnly, Text or "") + else + self:E("ERROR: Currently a free form polygon can only have 10 points in total!") + -- Unfortunately, unpack(vecs) does not work! So no idea how to generalize this :( + trigger.action.markupToAll(7, Coalition, MarkID, unpack(vecs), Color, FillColor, LineType, ReadOnly, Text or "") + end + + return MarkID + end + + --- Text to all. Creates a text imposed on the map at the COORDINATE. Text scales with the map. + -- @param #COORDINATE self + -- @param #string Text Text displayed on the F10 map. + -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. + -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). + -- @param #number Alpha Transparency [0,1]. Default 1. + -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. + -- @param #number FillAlpha Transparency [0,1]. Default 0.15. + -- @param #number FontSize Font size. + -- @param #boolean ReadOnly (Optional) Mark is readonly and cannot be removed by users. Default false. + -- @return #number The resulting Mark ID, which is a number. Can be used to remove the object again. + function COORDINATE:TextToAll(Text, Coalition, Color, Alpha, FillColor, FillAlpha, FontSize, ReadOnly) + local MarkID = UTILS.GetMarkID() + if ReadOnly==nil then + ReadOnly=false + end + Coalition=Coalition or -1 + Color=Color or {1,0,0} + Color[4]=Alpha or 1.0 + FillColor=FillColor or Color + FillColor[4]=FillAlpha or 0.15 + FontSize=FontSize or 12 + trigger.action.textToAll(Coalition, MarkID, self:GetVec3(), Color, FillColor, FontSize, ReadOnly, Text or "Hello World") + return MarkID + end + + --- Arrow to all. Creates an arrow from the COORDINATE to the endpoint COORDINATE on the F10 map. There is no control over other dimensions of the arrow. + -- @param #COORDINATE self + -- @param #COORDINATE Endpoint COORDINATE where the tip of the arrow is pointing at. + -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. + -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). + -- @param #number Alpha Transparency [0,1]. Default 1. + -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. + -- @param #number FillAlpha Transparency [0,1]. Default 0.15. + -- @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 #string Text (Optional) Text displayed when mark is added. Default none. + -- @return #number The resulting Mark ID, which is a number. Can be used to remove the object again. + function COORDINATE:ArrowToAll(Endpoint, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, Text) + local MarkID = UTILS.GetMarkID() + if ReadOnly==nil then + ReadOnly=false + end + local vec3=Endpoint:GetVec3() + Coalition=Coalition or -1 + Color=Color or {1,0,0} + Color[4]=Alpha or 1.0 + LineType=LineType or 1 + FillColor=FillColor or Color + FillColor[4]=FillAlpha or 0.15 + --trigger.action.textToAll(Coalition, MarkID, self:GetVec3(), Color, FillColor, FontSize, ReadOnly, Text or "Hello World") + trigger.action.arrowToAll(Coalition, MarkID, vec3, self:GetVec3(), Color, FillColor, LineType, ReadOnly, Text or "") + return MarkID + end --- Returns if a Coordinate has Line of Sight (LOS) with the ToCoordinate. -- @param #COORDINATE self diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 8ef630eee..f14619959 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -56,6 +56,8 @@ --- @type ZONE_BASE -- @field #string ZoneName Name of the zone. -- @field #number ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability. +-- @field #number DrawID Unique ID of the drawn zone on the F10 map. +-- @field #table Color Table with four entries, e.g. {1, 0, 0, 0.15}. First three are RGB color code. Fourth is the transparency Alpha value. -- @extends Core.Fsm#FSM @@ -104,7 +106,9 @@ ZONE_BASE = { ClassName = "ZONE_BASE", ZoneName = "", ZoneProbability = 1, - } + DrawID=nil, + Color={} +} --- The ZONE_BASE.BoundingSquare @@ -324,6 +328,76 @@ function ZONE_BASE:BoundZone() end + +--- Set color of zone. +-- @param #ZONE_BASE self +-- @param #table RGBcolor RGB color table. Default `{1, 0, 0}`. +-- @param #number Alpha Transparacy between 0 and 1. Default 0.15. +-- @return #ZONE_BASE self +function ZONE_BASE:SetColor(RGBcolor, Alpha) + + RGBcolor=RGBcolor or {1, 0, 0} + Alpha=Alpha or 0.15 + + self.Color={} + self.Color[1]=RGBcolor[1] + self.Color[2]=RGBcolor[2] + self.Color[3]=RGBcolor[3] + self.Color[4]=Alpha + + return self +end + +--- Get color table of the zone. +-- @param #ZONE_BASE self +-- @return #table Table with four entries, e.g. {1, 0, 0, 0.15}. First three are RGB color code. Fourth is the transparency Alpha value. +function ZONE_BASE:GetColor() + return self.Color +end + +--- Get RGB color of zone. +-- @param #ZONE_BASE self +-- @return #table Table with three entries, e.g. {1, 0, 0}, which is the RGB color code. +function ZONE_BASE:GetColorRGB() + local rgb={} + rgb[1]=self.Color[1] + rgb[2]=self.Color[2] + rgb[3]=self.Color[3] + return rgb +end + +--- Get transperency Alpha value of zone. +-- @param #ZONE_BASE self +-- @return #number Alpha value. +function ZONE_BASE:GetColorAlpha() + local alpha=self.Color[4] + return alpha +end + +--- Remove the drawing of the zone from the F10 map. +-- @param #ZONE_BASE self +-- @param #number Delay (Optional) Delay before the drawing is removed. +-- @return #ZONE_BASE self +function ZONE_BASE:UndrawZone(Delay) + if Delay and Delay>0 then + self:ScheduleOnce(Delay, ZONE_BASE.UndrawZone, self) + else + if self.DrawID then + UTILS.RemoveMark(self.DrawID) + end + end + return self +end + +--- Get ID of the zone object drawn on the F10 map. +-- The ID can be used to remove the drawn object from the F10 map view via `UTILS.RemoveMark(MarkID)`. +-- @param #ZONE_BASE self +-- @return #number Unique ID of the +function ZONE_BASE:GetDrawID() + return self.DrawID +end + + --- Smokes the zone boundaries in a color. -- @param #ZONE_BASE self -- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color. @@ -469,6 +543,32 @@ function ZONE_RADIUS:MarkZone(Points) end +--- Draw the zone circle on the F10 map. +-- @param #ZONE_RADIUS self +-- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. +-- @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 #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. +-- @param #number FillAlpha Transparency [0,1]. Default 0.15. +-- @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. +-- @return #ZONE_RADIUS self +function ZONE_RADIUS:DrawZone(Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly) + + local coordinate=self:GetCoordinate() + + local Radius=self:GetRadius() + + Color=Color or self:GetColorRGB() + Alpha=Alpha or 1 + FillColor=FillColor or Color + FillAlpha=FillAlpha or self:GetColorAlpha() + + self.DrawID=coordinate:CircleToAll(Radius, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly) + + return self +end + --- Bounds the zone with tires. -- @param #ZONE_RADIUS self -- @param #number Points (optional) The amount of points in the circle. Default 360. @@ -1116,22 +1216,37 @@ ZONE = { } ---- Constructor of ZONE, taking the zone name. +--- Constructor of ZONE taking the zone name. -- @param #ZONE self -- @param #string ZoneName The name of the zone as defined within the mission editor. --- @return #ZONE +-- @return #ZONE self function ZONE:New( ZoneName ) + -- First try to find the zone in the DB. + local zone=_DATABASE:FindZone(ZoneName) + + if zone then + --env.info("FF found zone in DB") + return zone + end + + -- Get zone from DCS trigger function. local Zone = trigger.misc.getZone( ZoneName ) + -- Error! if not Zone then error( "Zone " .. ZoneName .. " does not exist." ) return nil end - local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, { x = Zone.point.x, y = Zone.point.z }, Zone.radius ) ) - self:F( ZoneName ) + -- Create a new ZONE_RADIUS. + local self=BASE:Inherit( self, ZONE_RADIUS:New(ZoneName, {x=Zone.point.x, y=Zone.point.z}, Zone.radius)) + self:F(ZoneName) + + -- Color of zone. + self.Color={1, 0, 0, 0.15} + -- DCS zone. self.Zone = Zone return self @@ -1425,7 +1540,7 @@ function ZONE_POLYGON_BASE:New( ZoneName, PointsArray ) end --- Returns the center location of the polygon. --- @param #ZONE_GROUP self +-- @param #ZONE_POLYGON_BASE self -- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Group} location. function ZONE_POLYGON_BASE:GetVec2() self:F( self.ZoneName ) @@ -1435,6 +1550,78 @@ function ZONE_POLYGON_BASE:GetVec2() return { x = ( Bounds.x2 + Bounds.x1 ) / 2, y = ( Bounds.y2 + Bounds.y1 ) / 2 } end +--- Get a vertex of the polygon. +-- @param #ZONE_POLYGON_BASE self +-- @param #number Index Index of the vertex. Default 1. +-- @return DCS#Vec2 Vertex of the polygon. +function ZONE_POLYGON_BASE:GetVertexVec2(Index) + return self._.Polygon[Index or 1] +end + +--- Get a vertex of the polygon. +-- @param #ZONE_POLYGON_BASE self +-- @param #number Index Index of the vertex. Default 1. +-- @return DCS#Vec3 Vertex of the polygon. +function ZONE_POLYGON_BASE:GetVertexVec3(Index) + local vec2=self:GetVertexVec2(Index) + if vec2 then + local vec3={x=vec2.x, y=land.getHeight(vec2), z=vec2.y} + return vec3 + end + return nil +end + +--- Get a vertex of the polygon. +-- @param #ZONE_POLYGON_BASE self +-- @param #number Index Index of the vertex. Default 1. +-- @return Core.Point#COORDINATE Vertex of the polygon. +function ZONE_POLYGON_BASE:GetVertexCoordinate(Index) + local vec2=self:GetVertexVec2(Index) + if vec2 then + local coord=COORDINATE:NewFromVec2(vec2) + return coord + end + return nil +end + + +--- Get a list of verticies of the polygon. +-- @param #ZONE_POLYGON_BASE self +-- @return List of DCS#Vec2 verticies defining the edges of the polygon. +function ZONE_POLYGON_BASE:GetVerticiesVec2() + return self._.Polygon +end + +--- Get a list of verticies of the polygon. +-- @param #ZONE_POLYGON_BASE self +-- @return #table List of DCS#Vec3 verticies defining the edges of the polygon. +function ZONE_POLYGON_BASE:GetVerticiesVec3() + + local coords={} + + for i,vec2 in ipairs(self._.Polygon) do + local vec3={x=vec2.x, y=land.getHeight(vec2), z=vec2.y} + table.insert(coords, vec3) + end + + return coords +end + +--- Get a list of verticies of the polygon. +-- @param #ZONE_POLYGON_BASE self +-- @return #table List of COORDINATES verticies defining the edges of the polygon. +function ZONE_POLYGON_BASE:GetVerticiesCoordinates() + + local coords={} + + for i,vec2 in ipairs(self._.Polygon) do + local coord=COORDINATE:NewFromVec2(vec2) + table.insert(coords, coord) + end + + return coords +end + --- Flush polygon coordinates as a table in DCS.log. -- @param #ZONE_POLYGON_BASE self -- @return #ZONE_POLYGON_BASE self @@ -1494,6 +1681,46 @@ function ZONE_POLYGON_BASE:BoundZone( UnBound ) end +--- Draw the zone on the F10 map. **NOTE** Currently, only polygons with **exactly four points** are supported! +-- @param #ZONE_POLYGON_BASE self +-- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. +-- @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 #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. +-- @param #number FillAlpha Transparency [0,1]. Default 0.15. +-- @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. +-- @return #ZONE_POLYGON_BASE self +function ZONE_POLYGON_BASE:DrawZone(Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly) + + local coordinate=COORDINATE:NewFromVec2(self._.Polygon[1]) + + Color=Color or self:GetColorRGB() + Alpha=Alpha or 1 + FillColor=FillColor or Color + FillAlpha=FillAlpha or self:GetColorAlpha() + + + if #self._.Polygon==4 then + + local Coord2=COORDINATE:NewFromVec2(self._.Polygon[2]) + local Coord3=COORDINATE:NewFromVec2(self._.Polygon[3]) + local Coord4=COORDINATE:NewFromVec2(self._.Polygon[4]) + + self.DrawID=coordinate:QuadToAll(Coord2, Coord3, Coord4, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly) + + else + + local Coordinates=self:GetVerticiesCoordinates() + table.remove(Coordinates, 1) + + self.DrawID=coordinate:MarkupToAllFreeForm(Coordinates, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly) + + end + + + return self +end --- Smokes the zone boundaries in a color. -- @param #ZONE_POLYGON_BASE self diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 693550719..db7d189d2 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -652,6 +652,17 @@ function UTILS.GetMarkID() end +--- Remove an object (marker, circle, arrow, text, quad, ...) on the F10 map. +-- @param #number MarkID Unique ID of the object. +-- @param #number Delay (Optional) Delay in seconds before the mark is removed. +function UTILS.RemoveMark(MarkID, Delay) + if Delay and Delay>0 then + TIMER:New(UTILS.RemoveMark, MarkID):Start(Delay) + else + trigger.action.removeMark(MarkID) + end +end + -- Test if a Vec2 is in a radius of another Vec2 function UTILS.IsInRadius( InVec2, Vec2, Radius ) From 7cd29501a9990f84762f203ce72a241097572856 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 11 May 2021 00:21:50 +0200 Subject: [PATCH 5/8] Templates update --- Moose Development/Moose/Core/Event.lua | 55 ++- Moose Development/Moose/Core/Point.lua | 14 +- Moose Development/Moose/Core/Zone.lua | 12 +- .../Moose/Utilities/Templates.lua | 365 +++++++++++++++--- 4 files changed, 358 insertions(+), 88 deletions(-) diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 85384ac02..e06b6c979 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -240,7 +240,7 @@ EVENTS = { Kill = world.event.S_EVENT_KILL or -1, Score = world.event.S_EVENT_SCORE or -1, UnitLost = world.event.S_EVENT_UNIT_LOST or -1, - LandingAfterEjection = 31, --world.event.S_EVENT_LANDING_AFTER_EJECTION or -1, + LandingAfterEjection = world.event.S_EVENT_LANDING_AFTER_EJECTION or -1, -- Added with DCS 2.7.0 ParatrooperLanding = world.event.S_EVENT_PARATROOPER_LENDING or -1, DiscardChairAfterEjection = world.event.S_EVENT_DISCARD_CHAIR_AFTER_EJECTION or -1, @@ -524,7 +524,7 @@ local _EVENTMETA = { Event = "OnEventUnitLost", Text = "S_EVENT_UNIT_LOST" }, - [world.event.S_EVENT_LANDING_AFTER_EJECTION] = { + [EVENTS.LandingAfterEjection] = { Order = 1, Event = "OnEventLandingAfterEjection", Text = "S_EVENT_LANDING_AFTER_EJECTION" @@ -592,7 +592,7 @@ end -- @param Core.Base#BASE EventClass The class object for which events are handled. -- @return #EVENT.Events function EVENT:Init( EventID, EventClass ) - self:F( { _EVENTMETA[EventID].Text, EventClass } ) + self:F3( { _EVENTMETA[EventID].Text, EventClass } ) if not self.Events[EventID] then -- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned. @@ -1124,34 +1124,33 @@ function EVENT:onEvent( Event ) end if Event.TgtObjectCategory == Object.Category.STATIC then - BASE:T({StaticTgtEvent = Event.id}) -- get base data - Event.TgtDCSUnit = Event.target - if Event.target:isExist() and Event.id ~= 33 then -- leave out ejected seat object - Event.TgtDCSUnitName = Event.TgtDCSUnit:getName() + Event.TgtDCSUnit = Event.target + if Event.target:isExist() and Event.id ~= 33 then -- leave out ejected seat object + Event.TgtDCSUnitName = Event.TgtDCSUnit:getName() + Event.TgtUnitName = Event.TgtDCSUnitName + Event.TgtUnit = STATIC:FindByName( Event.TgtDCSUnitName, false ) + Event.TgtCoalition = Event.TgtDCSUnit:getCoalition() + Event.TgtCategory = Event.TgtDCSUnit:getDesc().category + Event.TgtTypeName = Event.TgtDCSUnit:getTypeName() + else + Event.TgtDCSUnitName = string.format("No target object for Event ID %s", tostring(Event.id)) + Event.TgtUnitName = Event.TgtDCSUnitName + Event.TgtUnit = nil + Event.TgtCoalition = 0 + Event.TgtCategory = 0 + if Event.id == 6 then + Event.TgtTypeName = "Ejected Pilot" + Event.TgtDCSUnitName = string.format("Ejected Pilot ID %s", tostring(Event.IniDCSUnitName)) + Event.TgtUnitName = Event.TgtDCSUnitName + elseif Event.id == 33 then + Event.TgtTypeName = "Ejection Seat" + Event.TgtDCSUnitName = string.format("Ejection Seat ID %s", tostring(Event.IniDCSUnitName)) Event.TgtUnitName = Event.TgtDCSUnitName - Event.TgtUnit = STATIC:FindByName( Event.TgtDCSUnitName, false ) - Event.TgtCoalition = Event.TgtDCSUnit:getCoalition() - Event.TgtCategory = Event.TgtDCSUnit:getDesc().category - Event.TgtTypeName = Event.TgtDCSUnit:getTypeName() else - Event.TgtDCSUnitName = string.format("No target object for Event ID %s", tostring(Event.id)) - Event.TgtUnitName = Event.TgtDCSUnitName - Event.TgtUnit = nil - Event.TgtCoalition = 0 - Event.TgtCategory = 0 - if Event.id == 6 then - Event.TgtTypeName = "Ejected Pilot" - Event.TgtDCSUnitName = string.format("Ejected Pilot ID %s", tostring(Event.IniDCSUnitName)) - Event.TgtUnitName = Event.TgtDCSUnitName - elseif Event.id == 33 then - Event.TgtTypeName = "Ejection Seat" - Event.TgtDCSUnitName = string.format("Ejection Seat ID %s", tostring(Event.IniDCSUnitName)) - Event.TgtUnitName = Event.TgtDCSUnitName - else - Event.TgtTypeName = "Static" - end - end + Event.TgtTypeName = "Static" + end + end end if Event.TgtObjectCategory == Object.Category.SCENERY then diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index 59465fdd2..1df5bdc7b 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -634,9 +634,9 @@ do -- COORDINATE --- Return a random Coordinate within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE. -- @param #COORDINATE self - -- @param DCS#Distance OuterRadius - -- @param DCS#Distance InnerRadius - -- @return #COORDINATE + -- @param DCS#Distance OuterRadius Outer radius in meters. + -- @param DCS#Distance InnerRadius Inner radius in meters. + -- @return #COORDINATE self function COORDINATE:GetRandomCoordinateInRadius( OuterRadius, InnerRadius ) self:F2( { OuterRadius, InnerRadius } ) @@ -2172,8 +2172,8 @@ do -- COORDINATE -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). -- @param #number Alpha Transparency [0,1]. Default 1. -- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. - -- @param #number FillAlpha Transparency [0,1]. Default 0.15. - -- @param #number FontSize Font size. + -- @param #number FillAlpha Transparency [0,1]. Default 0.3. + -- @param #number FontSize Font size. Default 14. -- @param #boolean ReadOnly (Optional) Mark is readonly and cannot be removed by users. Default false. -- @return #number The resulting Mark ID, which is a number. Can be used to remove the object again. function COORDINATE:TextToAll(Text, Coalition, Color, Alpha, FillColor, FillAlpha, FontSize, ReadOnly) @@ -2185,8 +2185,8 @@ do -- COORDINATE Color=Color or {1,0,0} Color[4]=Alpha or 1.0 FillColor=FillColor or Color - FillColor[4]=FillAlpha or 0.15 - FontSize=FontSize or 12 + FillColor[4]=FillAlpha or 0.3 + FontSize=FontSize or 14 trigger.action.textToAll(Coalition, MarkID, self:GetVec3(), Color, FillColor, FontSize, ReadOnly, Text or "Hello World") return MarkID end diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index f14619959..035d0e2a4 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -17,6 +17,7 @@ -- * Get zone properties. -- * Get zone bounding box. -- * Set/get zone name. +-- * Draw zones (circular and polygon) on the F10 map. -- -- -- There are essentially two core functions that zones accomodate: @@ -495,6 +496,10 @@ end -- * @{#ZONE_RADIUS.GetRandomPointVec2}(): Gets a @{Core.Point#POINT_VEC2} object representing a random 2D point in the zone. -- * @{#ZONE_RADIUS.GetRandomPointVec3}(): Gets a @{Core.Point#POINT_VEC3} object representing a random 3D point in the zone. Note that the height of the point is at landheight. -- +-- ## Draw zone +-- +-- * @{#ZONE_RADIUS.DrawZone}(): Draws the zone on the F10 map. +-- -- @field #ZONE_RADIUS ZONE_RADIUS = { ClassName="ZONE_RADIUS", @@ -1506,6 +1511,11 @@ end -- * @{#ZONE_POLYGON_BASE.GetRandomVec2}(): Gets a random 2D point in the zone. -- * @{#ZONE_POLYGON_BASE.GetRandomPointVec2}(): Return a @{Core.Point#POINT_VEC2} object representing a random 2D point within the zone. -- * @{#ZONE_POLYGON_BASE.GetRandomPointVec3}(): Return a @{Core.Point#POINT_VEC3} object representing a random 3D point at landheight within the zone. +-- +-- ## Draw zone +-- +-- * @{#ZONE_POLYGON_BASE.DrawZone}(): Draws the zone on the F10 map. +-- -- -- @field #ZONE_POLYGON_BASE ZONE_POLYGON_BASE = { @@ -1938,7 +1948,7 @@ end -- This is especially handy if you want to quickly setup a SET_ZONE... -- So when you would declare `local SetZone = SET_ZONE:New():FilterPrefixes( "Defense" ):FilterStart()`, -- then SetZone would contain the ZONE_POLYGON object `DefenseZone` as part of the zone collection, --- without much scripting overhead!!! +-- without much scripting overhead! -- -- @field #ZONE_POLYGON ZONE_POLYGON = { diff --git a/Moose Development/Moose/Utilities/Templates.lua b/Moose Development/Moose/Utilities/Templates.lua index df7c3ff0b..182925689 100644 --- a/Moose Development/Moose/Utilities/Templates.lua +++ b/Moose Development/Moose/Utilities/Templates.lua @@ -44,10 +44,10 @@ TEMPLATE = { Helicopter = {}, } ---- Pattern steps. --- @type TEMPLATE.Ground +--- Ground unit type names. +-- @type TEMPLATE.TypeGround -- @param #string InfantryAK -TEMPLATE.Ground={ +TEMPLATE.TypeGround={ InfantryAK="Infantry AK", ParatrooperAKS74="Paratrooper AKS-74", ParatrooperRPG16="Paratrooper RPG-16", @@ -56,40 +56,227 @@ TEMPLATE.Ground={ SoldierM4="Soldier M4", } +--- Naval unit type names. +-- @type TEMPLATE.TypeNaval +-- @param #string Ticonderoga +TEMPLATE.TypeNaval={ + Ticonderoga="TICONDEROG", +} + +--- Rotary wing unit type names. +-- @type TEMPLATE.TypeAirplane +-- @param #string A10C +TEMPLATE.TypeAirplane={ + A10C="A-10C", +} + +--- Rotary wing unit type names. +-- @type TEMPLATE.TypeHelicopter +-- @param #string AH1W +TEMPLATE.TypeHelicopter={ + AH1W="AH-1W", +} + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Start/Stop Profiler +-- Ground Template ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Get template for ground units. -- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`. -- @param #string GroupName Name of the spawned group. **Must be unique!** -- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to. --- @param DCS#Vec3 Vec3 Position of the group. +-- @param DCS#Vec3 Vec3 Position of the group and the first unit. -- @param #number Nunits Number of units. Default 1. -- @param #number Radius Spawn radius for additonal units in meters. Default 50 m. -- @return #table Template Template table. function TEMPLATE.GetGround(TypeName, GroupName, CountryID, Vec3, Nunits, Radius) + -- Defaults. + TypeName=TypeName or TEMPLATE.TypeGround.SoldierM4 + GroupName=GroupName or "Ground-1" + CountryID=CountryID or country.id.USA + Vec3=Vec3 or {x=0, y=0, z=0} + Nunits=Nunits or 1 + Radius=Radius or 50 + + + -- Get generic template. local template=UTILS.DeepCopy(TEMPLATE.GenericGround) - - template.name=GroupName or "Ground-1" + + -- Set group name. + template.name=GroupName -- These are additional entries required by the MOOSE _DATABASE:Spawn() function. - template.CountryID=country.id.USA + template.CountryID=CountryID template.CoalitionID=coalition.getCountryCoalition(template.CountryID) template.CategoryID=Unit.Category.GROUND_UNIT - template.units[1].type=TypeName or "Infantry AK" - template.units[1].name=GroupName.."-1" + -- Set first unit. + template.units[1].type=TypeName + template.units[1].name=GroupName.."-1" if Vec3 then TEMPLATE.SetPositionFromVec3(template, Vec3) end + + TEMPLATE.SetUnits(template, Nunits, COORDINATE:NewFromVec3(Vec3), Radius) + + return template +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Naval Template +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Get template for ground units. +-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`. +-- @param #string GroupName Name of the spawned group. **Must be unique!** +-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to. +-- @param DCS#Vec3 Vec3 Position of the group and the first unit. +-- @param #number Nunits Number of units. Default 1. +-- @param #number Radius Spawn radius for additonal units in meters. Default 500 m. +-- @return #table Template Template table. +function TEMPLATE.GetNaval(TypeName, GroupName, CountryID, Vec3, Nunits, Radius) + + -- Defaults. + TypeName=TypeName or TEMPLATE.TypeNaval.Ticonderoga + GroupName=GroupName or "Naval-1" + CountryID=CountryID or country.id.USA + Vec3=Vec3 or {x=0, y=0, z=0} + Nunits=Nunits or 1 + Radius=Radius or 500 + + + -- Get generic template. + local template=UTILS.DeepCopy(TEMPLATE.GenericNaval) + + -- Set group name. + template.name=GroupName + + -- These are additional entries required by the MOOSE _DATABASE:Spawn() function. + template.CountryID=CountryID + template.CoalitionID=coalition.getCountryCoalition(template.CountryID) + template.CategoryID=Unit.Category.SHIP + + -- Set first unit. + template.units[1].type=TypeName + template.units[1].name=GroupName.."-1" + + if Vec3 then + TEMPLATE.SetPositionFromVec3(template, Vec3) + end + + TEMPLATE.SetUnits(template, Nunits, COORDINATE:NewFromVec3(Vec3), Radius) + + return template +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Aircraft Template +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Get template for fixed wing units. +-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`. +-- @param #string GroupName Name of the spawned group. **Must be unique!** +-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to. +-- @param DCS#Vec3 Vec3 Position of the group and the first unit. +-- @param #number Nunits Number of units. Default 1. +-- @param #number Radius Spawn radius for additonal units in meters. Default 500 m. +-- @return #table Template Template table. +function TEMPLATE.GetAirplane(TypeName, GroupName, CountryID, Vec3, Nunits, Radius) + + -- Defaults. + TypeName=TypeName or TEMPLATE.TypeAirplane.A10C + GroupName=GroupName or "Airplane-1" + CountryID=CountryID or country.id.USA + Vec3=Vec3 or {x=0, y=1000, z=0} + Nunits=Nunits or 1 + Radius=Radius or 100 + + local template=TEMPLATE._GetAircraft(true, TypeName, GroupName, CountryID, Vec3, Nunits, Radius) + + return template +end + +--- Get template for fixed wing units. +-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`. +-- @param #string GroupName Name of the spawned group. **Must be unique!** +-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to. +-- @param DCS#Vec3 Vec3 Position of the group and the first unit. +-- @param #number Nunits Number of units. Default 1. +-- @param #number Radius Spawn radius for additonal units in meters. Default 500 m. +-- @return #table Template Template table. +function TEMPLATE.GetHelicopter(TypeName, GroupName, CountryID, Vec3, Nunits, Radius) + + -- Defaults. + TypeName=TypeName or TEMPLATE.TypeHelicopter.AH1W + GroupName=GroupName or "Helicopter-1" + CountryID=CountryID or country.id.USA + Vec3=Vec3 or {x=0, y=500, z=0} + Nunits=Nunits or 1 + Radius=Radius or 100 + + -- Limit unis to 4. + Nunits=math.min(Nunits, 4) + + local template=TEMPLATE._GetAircraft(false, TypeName, GroupName, CountryID, Vec3, Nunits, Radius) return template end +--- Get template for aircraft units. +-- @param #boolean Airplane If true, this is a fixed wing. Else, rotary wing. +-- @param #string TypeName Type name of the unit(s) in the groups. See `TEMPLATE.Ground`. +-- @param #string GroupName Name of the spawned group. **Must be unique!** +-- @param #number CountryID Country ID. Default `country.id.USA`. Coalition is automatically determined by the one the country belongs to. +-- @param DCS#Vec3 Vec3 Position of the group and the first unit. +-- @param #number Nunits Number of units. Default 1. +-- @param #number Radius Spawn radius for additonal units in meters. Default 500 m. +-- @return #table Template Template table. +function TEMPLATE._GetAircraft(Airplane, TypeName, GroupName, CountryID, Vec3, Nunits, Radius) + + -- Defaults. + TypeName=TypeName + GroupName=GroupName or "Aircraft-1" + CountryID=CountryID or country.id.USA + Vec3=Vec3 or {x=0, y=0, z=0} + Nunits=Nunits or 1 + Radius=Radius or 100 + + -- Get generic template. + local template=UTILS.DeepCopy(TEMPLATE.GenericAircraft) + + -- Set group name. + template.name=GroupName + + -- These are additional entries required by the MOOSE _DATABASE:Spawn() function. + template.CountryID=CountryID + template.CoalitionID=coalition.getCountryCoalition(template.CountryID) + if Airplane then + template.CategoryID=Unit.Category.AIRPLANE + else + template.CategoryID=Unit.Category.HELICOPTER + end + + -- Set first unit. + template.units[1].type=TypeName + template.units[1].name=GroupName.."-1" + + -- Set position. + if Vec3 then + TEMPLATE.SetPositionFromVec3(template, Vec3) + end + + -- Set number of units. + TEMPLATE.SetUnits(template, Nunits, COORDINATE:NewFromVec3(Vec3), Radius) + + return template +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Misc Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Set the position of the template. -- @param #table Template The template to be modified. @@ -121,6 +308,84 @@ function TEMPLATE.SetPositionFromVec3(Template, Vec3) end +--- Set the position of the template. +-- @param #table Template The template to be modified. +-- @param #number N Total number of units in the group. +-- @param Core.Point#COORDINATE Coordinate Position of the first unit. +-- @param #number Radius Radius in meters to randomly place the additional units. +function TEMPLATE.SetUnits(Template, N, Coordinate, Radius) + + local units=Template.units + + local unit1=units[1] + + local Vec3=Coordinate:GetVec3() + + unit1.x=Vec3.x + unit1.y=Vec3.z + unit1.alt=Vec3.y + + for i=2,N do + units[i]=UTILS.DeepCopy(unit1) + end + + for i=1,N do + local unit=units[i] + unit.name=string.format("%s-%d", Template.name, i) + if i>1 then + local vec2=Coordinate:GetRandomCoordinateInRadius(Radius, 5):GetVec2() + unit.x=vec2.x + unit.y=vec2.y + unit.alt=unit1.alt + end + end + +end + +--- Set the position of the template. +-- @param #table Template The template to be modified. +-- @param Wrapper.Airbase#AIRBASE AirBase The airbase where the aircraft are spawned. +-- @param #table ParkingSpots List of parking spot IDs. Every unit needs one! +-- @param #boolean EngineOn If true, aircraft are spawned hot. +function TEMPLATE.SetAirbase(Template, AirBase, ParkingSpots, EngineOn) + + -- Airbase ID. + local AirbaseID=AirBase:GetID() + + -- Spawn point. + local point=Template.route.points[1] + + -- Set ID. + if AirBase:IsAirdrome() then + point.airdromeId=AirbaseID + else + point.helipadId=AirbaseID + point.linkUnit=AirbaseID + end + + if EngineOn then + point.action=COORDINATE.WaypointAction.FromParkingAreaHot + point.type=COORDINATE.WaypointType.TakeOffParkingHot + else + point.action=COORDINATE.WaypointAction.FromParkingArea + point.type=COORDINATE.WaypointType.TakeOffParking + end + + for i,unit in ipairs(Template.units) do + unit.parking_id=ParkingSpots[i] + end + +end + +--- Add a waypoint. +-- @param #table Template The template to be modified. +-- @param #table Waypoint Waypoint table. +function TEMPLATE.AddWaypoint(Template, Waypoint) + + table.insert(Template.route.points, Waypoint) + +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Generic Ground Template ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -255,79 +520,82 @@ TEMPLATE.GenericNaval= } ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Generic Ship Template +-- Generic Aircraft Template ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -TEMPLATE.GenericHelicopter= +TEMPLATE.GenericAircraft= { - ["modulation"] = 0, - ["tasks"] = {}, -- end of ["tasks"] - ["radioSet"] = false, - ["task"] = "Nothing", + ["groupId"] = nil, + ["name"] = "Rotary-1", ["uncontrolled"] = false, - ["taskSelected"] = true, + ["hidden"] = false, + ["task"] = "Nothing", + ["y"] = 0, + ["x"] = 0, + ["start_time"] = 0, + ["communication"] = true, + ["radioSet"] = false, + ["frequency"] = 127.5, + ["modulation"] = 0, + ["taskSelected"] = true, + ["tasks"] = {}, -- end of ["tasks"] ["route"] = { ["points"] = { [1] = { - ["alt"] = 10, - ["action"] = "From Parking Area", - ["alt_type"] = "BARO", - ["speed"] = 41.666666666667, + ["y"] = 0, + ["x"] = 0, + ["alt"] = 1000, + ["alt_type"] = "BARO", + ["action"] = "Turning Point", + ["type"] = "Turning Point", + ["airdromeId"] = nil, ["task"] = { ["id"] = "ComboTask", ["params"] = { - ["tasks"] = - { - }, -- end of ["tasks"] + ["tasks"] = {}, -- end of ["tasks"] }, -- end of ["params"] }, -- end of ["task"] - ["type"] = "TakeOffParking", ["ETA"] = 0, ["ETA_locked"] = true, - ["y"] = 618351.087765, - ["x"] = -356168.27327001, + ["speed"] = 100, + ["speed_locked"] = true, ["formation_template"] = "", - ["airdromeId"] = 22, - ["speed_locked"] = true, }, -- end of [1] }, -- end of ["points"] }, -- end of ["route"] - ["groupId"] = nil, - ["hidden"] = false, ["units"] = { [1] = { - ["alt"] = 10, - ["alt_type"] = "BARO", + ["name"] = "Rotary-1-1", + ["unitId"] = nil, + ["type"] = "AH-1W", + ["onboard_num"] = "050", ["livery_id"] = "USA X Black", ["skill"] = "High", - ["parking"] = "4", ["ropeLength"] = 15, - ["speed"] = 41.666666666667, - ["type"] = "AH-1W", - ["unitId"] = 8, + ["speed"] = 0, + ["x"] = 0, + ["y"] = 0, + ["alt"] = 10, + ["alt_type"] = "BARO", + ["heading"] = 0, ["psi"] = 0, - ["parking_id"] = "10", - ["x"] = -356168.27327001, - ["name"] = "Rotary-1-1", + ["parking"] = nil, + ["parking_id"] = nil, ["payload"] = { - ["pylons"] = - { - }, -- end of ["pylons"] + ["pylons"] = {}, -- end of ["pylons"] ["fuel"] = "1250.0", ["flare"] = 30, ["chaff"] = 30, ["gun"] = 100, }, -- end of ["payload"] - ["y"] = 618351.087765, - ["heading"] = 0, ["callsign"] = { [1] = 2, @@ -335,15 +603,8 @@ TEMPLATE.GenericHelicopter= [3] = 1, ["name"] = "Springfield11", }, -- end of ["callsign"] - ["onboard_num"] = "050", }, -- end of [1] }, -- end of ["units"] - ["y"] = 0, - ["x"] = 0, - ["name"] = "Rotary-1", - ["communication"] = true, - ["start_time"] = 0, - ["frequency"] = 127.5, } ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- From 057e231a9d57133d422eec2d3b23e49ba9200e00 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 11 May 2021 11:41:26 +0200 Subject: [PATCH 6/8] Emission --- Moose Development/Moose/Wrapper/Group.lua | 6 ++-- Moose Development/Moose/Wrapper/Unit.lua | 40 +++-------------------- 2 files changed, 8 insertions(+), 38 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 1a2f00fa8..263b3a0ec 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -2551,9 +2551,10 @@ do -- Players end ---- GROUND - Switch on/off radar emissions +--- GROUND - Switch on/off radar emissions for the group. -- @param #GROUP self --- @param #boolean switch +-- @param #boolean switch If true, emission is enabled. If false, emission is disabled. +-- @return #GROUP self function GROUP:EnableEmission(switch) self:F2( self.GroupName ) local switch = switch or false @@ -2566,6 +2567,7 @@ function GROUP:EnableEmission(switch) end + return self end --do -- Smoke diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 65199d97d..eb6d472d8 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -761,40 +761,6 @@ function UNIT:GetFuel() return nil end ---- Sets the passed group or unit objects radar emitters on or off. Can be used on sam sites for example to shut down the radar without setting AI off or changing the alarm state. --- @param #UNIT self --- @param #boolean Switch If `true` or `nil`, emission is enabled. If `false`, emission is turned off. --- @return #UNIT self -function UNIT:SetEmission(Switch) - - if Switch==nil then - Switch=true - end - - local DCSUnit = self:GetDCSObject() - - if DCSUnit then - DCSUnit:enableEmission(Switch) - end - - return self -end - ---- Sets the passed group or unit objects radar emitters ON. Can be used on sam sites for example to shut down the radar without setting AI off or changing the alarm state. --- @param #UNIT self --- @return #UNIT self -function UNIT:EnableEmission() - self:SetEmission(true) - return self -end - ---- Sets the passed group or unit objects radar emitters OFF. Can be used on sam sites for example to shut down the radar without setting AI off or changing the alarm state. --- @param #UNIT self --- @return #UNIT self -function UNIT:DisableEmission() - self:SetEmission(false) - return self -end --- Returns a list of one @{Wrapper.Unit}. -- @param #UNIT self @@ -1429,9 +1395,10 @@ function UNIT:GetTemplateFuel() return nil end ---- GROUND - Switch on/off radar emissions. +--- GROUND - Switch on/off radar emissions of a unit. -- @param #UNIT self --- @param #boolean switch +-- @param #boolean switch If true, emission is enabled. If false, emission is disabled. +-- @return #UNIT self function UNIT:EnableEmission(switch) self:F2( self.UnitName ) @@ -1445,4 +1412,5 @@ function UNIT:EnableEmission(switch) end + return self end From b68f271fb726cf989bf6ad29f74ed5098de0ab91 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 11 May 2021 11:51:25 +0200 Subject: [PATCH 7/8] Update Event.lua --- Moose Development/Moose/Core/Event.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index e06b6c979..1b3952ac1 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -578,10 +578,6 @@ function EVENT:New() -- Add world event handler. self.EventHandler = world.addEventHandler(self) - for _,Event in pairs(self.Events) do - self:Init(Event,EventClass) - end - return self end From a893d46cb9684f9e286459a57f77880ed7104794 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 11 May 2021 11:54:27 +0200 Subject: [PATCH 8/8] Update Event.lua --- Moose Development/Moose/Core/Event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 1b3952ac1..02dab0afc 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -1000,7 +1000,7 @@ function EVENT:onEvent( Event ) -- Check if this is a known event? if EventMeta then - if self and self.Events and self.Events[Event.id] and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.idss~=EVENTS.PlayerLeaveUnit)) then + if self and self.Events and self.Events[Event.id] and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.id~=EVENTS.PlayerLeaveUnit)) then if Event.id and Event.id == EVENTS.MissionEnd then self.MissionEnd = true