From b4e2d3edfe24ce5dee1affadf385848d1c65ade9 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 30 Aug 2022 14:26:52 +0200 Subject: [PATCH] #ZONE * Added `ZONE_RADIUS:GetRandomCoordinateWithoutBuildings(...)` #MARKEROPS * Some documentation improvement #PLAYTASKCONTROLLER * Added `PLAYERTASKCONTROLLER:EnableMarkerOps(Tag)` #OPSGROUP * Changed offset to 2m for lasing ground units *AUFTRAG * Documentation correction `NewARMOREDGUARD` --- .../Moose/Core/MarkerOps_Base.lua | 6 +- Moose Development/Moose/Core/Zone.lua | 83 ++++++++++++++++++- Moose Development/Moose/Ops/Auftrag.lua | 2 +- Moose Development/Moose/Ops/OpsGroup.lua | 2 +- Moose Development/Moose/Ops/PlayerTask.lua | 44 ++++++++-- 5 files changed, 124 insertions(+), 13 deletions(-) diff --git a/Moose Development/Moose/Core/MarkerOps_Base.lua b/Moose Development/Moose/Core/MarkerOps_Base.lua index eb5e17110..8e318a7a7 100644 --- a/Moose Development/Moose/Core/MarkerOps_Base.lua +++ b/Moose Development/Moose/Core/MarkerOps_Base.lua @@ -123,7 +123,7 @@ function MARKEROPS_BASE:New(Tagname,Keywords) end --- (internal) Handle events. --- @param #MARKEROPS self +-- @param #MARKEROPS_BASE self -- @param Core.Event#EVENTDATA Event function MARKEROPS_BASE:OnEventMark(Event) self:T({Event}) @@ -173,7 +173,7 @@ function MARKEROPS_BASE:OnEventMark(Event) end --- (internal) Match tag. --- @param #MARKEROPS self +-- @param #MARKEROPS_BASE self -- @param #string Eventtext Text added to the marker. -- @return #boolean function MARKEROPS_BASE:_MatchTag(Eventtext) @@ -186,7 +186,7 @@ function MARKEROPS_BASE:_MatchTag(Eventtext) end --- (internal) Match keywords table. --- @param #MARKEROPS self +-- @param #MARKEROPS_BASE self -- @param #string Eventtext Text added to the marker. -- @return #table function MARKEROPS_BASE:_MatchKeywords(Eventtext) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 02c915c90..0a94fdc04 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -970,7 +970,7 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories ) local SceneryName = ZoneObject:getName() self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {} self.ScanData.Scenery[SceneryType][SceneryName] = SCENERY:Register( SceneryName, ZoneObject ) - self:F2( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } ) + self:T( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } ) end end @@ -1373,7 +1373,86 @@ function ZONE_RADIUS:GetRandomCoordinate(inner, outer, surfacetypes) return Coordinate end - +--- Returns a @{Core.Point#COORDINATE} object reflecting a random location within the zone where there are no **map objects** of type "Building". +-- Does not find statics you might have placed there. **Note** This might be quite CPU intensive, use with care. +-- @param #ZONE_RADIUS self +-- @param #number inner (Optional) Minimal distance from the center of the zone in meters. Default is 0m. +-- @param #number outer (Optional) Maximal distance from the outer edge of the zone in meters. Default is the radius of the zone. +-- @param #number distance (Optional) Minumum distance from any building coordinate. Defaults to 100m. +-- @param #boolean markbuildings (Optional) Place markers on found buildings (if any). +-- @param #boolean markfinal (Optional) Place marker on the final coordinate (if any). +-- @return Core.Point#COORDINATE The random coordinate or `nil` if cannot be found in 1000 iterations. +function ZONE_RADIUS:GetRandomCoordinateWithoutBuildings(inner,outer,distance,markbuildings,markfinal) + + local dist = distance or 100 + + local objects = {} + + if self.ScanData and self.ScanData.Scenery then + objects = self:GetScannedScenery() + else + self:Scan({Object.Category.SCENERY}) + objects = self:GetScannedScenery() + end + + local T0 = timer.getTime() + local T1 = timer.getTime() + + + local buildings = {} + if self.ScanData and self.ScanData.BuildingCoordinates then + buildings = self.ScanData.BuildingCoordinates + else + -- build table of buildings coordinates + for _,_object in pairs (objects) do + for _,_scen in pairs (_object) do + local scenery = _scen -- Wrapper.Scenery#SCENERY + local description=scenery:GetDesc() + if description and description.attributes and description.attributes.Buildings then + if markbuildings then + MARKER:New(scenery:GetCoordinate(),"Building"):ToAll() + end + buildings[#buildings+1] = scenery:GetCoordinate() + end + end + end + self.ScanData.BuildingCoordinates = buildings + end + + -- max 1000 tries + local rcoord = nil + local found = false + local iterations = 0 + + for i=1,1000 do + iterations = iterations + 1 + rcoord = self:GetRandomCoordinate(inner,outer) + found = false + for _,_coord in pairs (buildings) do + local coord = _coord -- Core.Point#COORDINATE + -- keep >50m dist from buildings + if coord:Get2DDistance(rcoord) > dist then + found = true + else + found = false + end + end + if found then + -- we have a winner! + if markfinal then + MARKER:New(rcoord,"FREE"):ToAll() + end + break + end + end + + T1=timer.getTime() + + self:T(string.format("Found a coordinate: %s | Iterations: %d | Time: %d",tostring(found),iterations,T1-T0)) + + if found then return rcoord else return nil end + +end --- @type ZONE -- @extends #ZONE_RADIUS diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 69b9a7fd6..895aaa387 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -2185,7 +2185,7 @@ end --- **[GROUND]** Create an ARMORED ON GUARD mission. -- @param #AUFTRAG self -- @param Core.Point#COORDINATE Coordinate Coordinate, where to stand guard. --- @param #string Formation Formation to take, e.g. "on Road", "Vee" etc. +-- @param #string Formation Formation to take, e.g. "On Road", "Vee" etc. -- @return #AUFTRAG self function AUFTRAG:NewARMOREDGUARD(Coordinate,Formation) diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 840911bfd..a8c556fd1 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -6421,7 +6421,7 @@ function OPSGROUP:onbeforeLaserOn(From, Event, To, Target) self.spot.element=element -- Height offset. No offset for aircraft. We take the height for ground or naval. - local offsetY=0 + local offsetY=2 --2m for ARMYGROUP, else there might be no LOS if self.isFlightgroup or self.isNavygroup then offsetY=element.height end diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index 866b8c054..f799bf2e2 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -703,6 +703,7 @@ do -- @field #string locale -- @field #boolean precisionbombing -- @field Ops.FlightGroup#FLIGHTGROUP LasingDrone +-- @field Core.MarkerOps_BASE#MARKEROPS_BASE MarkerOps -- @extends Core.Fsm#FSM --- @@ -1324,6 +1325,37 @@ function PLAYERTASKCONTROLLER:EnablePrecisionBombing(FlightGroup,LaserCode) return self end +--- [User] Allow addition of targets with user F10 map markers. +-- @param #PLAYERTASKCONTROLLER self +-- @param #string Tag (Optional) The tagname to use to identify commands, defaults to "TASK" +-- @return #PLAYERTASKCONTROLLER self +function PLAYERTASKCONTROLLER:EnableMarkerOps(Tag) + self:T(self.lid.."EnableMarkerOps") + + local tag = Tag or "TASK" + local MarkerOps = MARKEROPS_BASE:New(tag) + + local function Handler(Keywords,Coord,Text) + if self.verbose then + local m = MESSAGE:New(string.format("Target added from marker at: %s", Coord:ToStringLLDMS()),15,"INFO"):ToAll() + end + self:AddTarget(Coord) + end + + -- Event functions + function MarkerOps:OnAfterMarkAdded(From,Event,To,Text,Keywords,Coord) + Handler(Keywords,Coord,Text) + end + + function MarkerOps:OnAfterMarkChanged(From,Event,To,Text,Keywords,Coord) + Handler(Keywords,Coord,Text) + end + + self.MarkerOps = MarkerOps + + return self +end + --- [Internal] Get player name -- @param #PLAYERTASKCONTROLLER self -- @param Wrapper.Client#CLIENT Client @@ -1595,7 +1627,7 @@ function PLAYERTASKCONTROLLER:_CheckPrecisionTasks() if self.LasingDrone and self.LasingDrone:IsAlive() then if self.LasingDrone.playertask and (not self.LasingDrone.playertask.busy) then -- not busy, get a task - self:I(self.lid.."Sending lasing unit to target") + self:T(self.lid.."Sending lasing unit to target") local task = self.PrecisionTasks:Pull() -- Ops.PlayerTask#PLAYERTASK self.LasingDrone.playertask.id = task.PlayerTaskNr self.LasingDrone.playertask.busy = true @@ -1612,7 +1644,7 @@ function PLAYERTASKCONTROLLER:_CheckPrecisionTasks() local tgtzone = ZONE_RADIUS:New("ArmyGroup-"..math.random(1,10000),tgtcoord:GetVec2(),3000) local finalpos=nil -- Core.Point#COORDINATE for i=1,50 do - finalpos = tgtzone:GetRandomCoordinate(2000,0,{land.SurfaceType.LAND,land.SurfaceType.ROAD,land.SurfaceType.SHALLOW_WATER}) + finalpos = tgtzone:GetRandomCoordinate(2500,0,{land.SurfaceType.LAND,land.SurfaceType.ROAD,land.SurfaceType.SHALLOW_WATER}) if finalpos then if finalpos:IsLOS(tgtcoord,0) then break @@ -1621,7 +1653,7 @@ function PLAYERTASKCONTROLLER:_CheckPrecisionTasks() end if finalpos then -- yeah we got one - local auftrag = AUFTRAG:NewARMOREDGUARD(finalpos) + local auftrag = AUFTRAG:NewARMOREDGUARD(finalpos,"Off road") local currmission = self.LasingDrone:GetMissionCurrent() self.LasingDrone:AddMission(auftrag) if currmission then currmission:__Cancel(-2) end @@ -1638,7 +1670,7 @@ function PLAYERTASKCONTROLLER:_CheckPrecisionTasks() elseif self.LasingDrone.playertask and self.LasingDrone.playertask.busy then -- drone is busy, set up laser when over target local task = self.PrecisionTasks:ReadByID(self.LasingDrone.playertask.id) -- Ops.PlayerTask#PLAYERTASK - self:I("Looking at Task: "..task.PlayerTaskNr.." Type: "..task.Type.." State: "..task:GetState()) + self:T("Looking at Task: "..task.PlayerTaskNr.." Type: "..task.Type.." State: "..task:GetState()) if (not task) or task:GetState() == "Done" or task:GetState() == "Stopped" then -- we're done here local task = self.PrecisionTasks:PullByID(self.LasingDrone.playertask.id) -- Ops.PlayerTask#PLAYERTASK @@ -1651,7 +1683,7 @@ function PLAYERTASKCONTROLLER:_CheckPrecisionTasks() self.LasingDrone.playertask.inreach = false self.LasingDrone.playertask.id = 0 self.LasingDrone.playertask.reachmessage = false - self:I(self.lid.."Laser Off") + self:T(self.lid.."Laser Off") else -- not done yet local dcoord = self.LasingDrone:GetCoordinate() @@ -1659,7 +1691,7 @@ function PLAYERTASKCONTROLLER:_CheckPrecisionTasks() local dist = dcoord:Get2DDistance(tcoord) -- close enough? if dist < 3000 and not self.LasingDrone:IsLasing() then - self:I(self.lid.."Laser On") + self:T(self.lid.."Laser On") self.LasingDrone:__LaserOn(-1,tcoord) self.LasingDrone.playertask.inreach = true if not self.LasingDrone.playertask.reachmessage then