From 04923b65b2278ce157a53114f76e6a783affca5b Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 24 Jul 2020 01:34:38 +0200 Subject: [PATCH] Stuff --- Moose Development/Moose/Core/Astar.lua | 92 +++++++++++++++----- Moose Development/Moose/Modules.lua | 1 + Moose Development/Moose/Ops/ArmyGroup.lua | 20 ++--- Moose Development/Moose/Ops/Auftrag.lua | 40 +++++---- Moose Development/Moose/Ops/ChiefOfStaff.lua | 18 +++- 5 files changed, 114 insertions(+), 57 deletions(-) diff --git a/Moose Development/Moose/Core/Astar.lua b/Moose Development/Moose/Core/Astar.lua index 6650e15dc..58459db13 100644 --- a/Moose Development/Moose/Core/Astar.lua +++ b/Moose Development/Moose/Core/Astar.lua @@ -78,8 +78,6 @@ function ASTAR:New() local self=BASE:Inherit(self, BASE:New()) --#ASTAR self.lid="ASTAR | " - - self.Debug=true return self end @@ -136,6 +134,19 @@ function ASTAR:AddNode(Node) return self end +--- Add a node to the table of grid nodes specifying its coordinate. +-- @param #ASTAR self +-- @param Core.Point#COORDINATE Coordinate The coordinate where the node is created. +-- @return #ASTAR self +function ASTAR:AddNodeFromCoordinate(Coordinate) + + local node=self:GetNodeFromCoordinate(Coordinate) + + self:AddNode(node) + + return self +end + --- Check if the coordinate of a node has is at a valid surface type. -- @param #ASTAR self -- @param #ASTAR.Node Node The node to be added. @@ -163,17 +174,6 @@ function ASTAR:CheckValidSurfaceType(Node, SurfaceTypes) end ---- Set valid neighbours to require line of sight between two nodes. --- @param #ASTAR self --- @param #number CorridorWidth Width of LoS corridor in meters. --- @return #ASTAR self -function ASTAR:SetValidNeighbourLoS(CorridorWidth) - - self:SetValidNeighbourFunction(ASTAR.LoS, CorridorWidth) - - return self -end - --- Add a function to determine if a neighbour of a node is valid. -- @param #ASTAR self -- @param #function NeighbourFunction Function that needs to return *true* for a neighbour to be valid. @@ -191,6 +191,32 @@ function ASTAR:SetValidNeighbourFunction(NeighbourFunction, ...) return self end + +--- Set valid neighbours to require line of sight between two nodes. +-- @param #ASTAR self +-- @param #number CorridorWidth Width of LoS corridor in meters. +-- @return #ASTAR self +function ASTAR:SetValidNeighbourLoS(CorridorWidth) + + self:SetValidNeighbourFunction(ASTAR.LoS, CorridorWidth) + + return self +end + +--- Set valid neighbours to be in a certain distance. +-- @param #ASTAR self +-- @param #number MaxDistance Max distance between nodes in meters. Default is 2000 m. +-- @return #ASTAR self +function ASTAR:SetValidNeighbourDistance(MaxDistance) + + self:SetValidNeighbourFunction(ASTAR.DistMax, MaxDistance) + + return self +end + + + + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Grid functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -329,6 +355,20 @@ function ASTAR.LoS(nodeA, nodeB, corridor) return los end +--- Function to check if two nodes have line of sight (LoS). +-- @param #ASTAR.Node nodeA First node. +-- @param #ASTAR.Node nodeB Other node. +-- @param #number distmax Max distance in meters. Default is 2000 m. +-- @return #boolean If true, distance between the two nodes is below threshold. +function ASTAR.DistMax(nodeA, nodeB, distmax) + + distmax=distmax or 2000 + + local dist=nodeA.coordinate:Get2DDistance(nodeB.coordinate) + + return dist<=distmax +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Misc functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -338,6 +378,7 @@ end -- @param #ASTAR self -- @param Core.Point#COORDINATE Coordinate. -- @return #ASTAR.Node Cloest node to the coordinate. +-- @return #number Distance to closest node in meters. function ASTAR:FindClosestNode(Coordinate) local distMin=math.huge @@ -355,16 +396,22 @@ function ASTAR:FindClosestNode(Coordinate) end - return closeNode + return closeNode, distMin end ---- Add a node. +--- Find the start node. -- @param #ASTAR self -- @param #ASTAR.Node Node The node to be added to the nodes table. -- @return #ASTAR self function ASTAR:FindStartNode() - self.startNode=self:FindClosestNode(self.startCoord) + local node, dist=self:FindClosestNode(self.startCoord) + + self.startNode=node + + if dist>1000 then + self:AddNode(node) + end return self end @@ -375,7 +422,13 @@ end -- @return #ASTAR self function ASTAR:FindEndNode() - self.endNode=self:FindClosestNode(self.endCoord) + local node, dist=self:FindClosestNode(self.endCoord) + + self.endNode=node + + if dist>1000 then + self:AddNode(node) + end return self end @@ -432,9 +485,6 @@ function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode) table.remove(path, 1) end - -- Set end time. - local T9=timer.getAbsTime() - -- Debug message. local text=string.format("Found path with %d nodes", #path) self:I(self.lid..text) @@ -473,7 +523,7 @@ function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode) -- Debug message. local text=string.format("WARNING: Could NOT find valid path!") - self:I(self.lid..text) + self:E(self.lid..text) MESSAGE:New(text, 60, "ASTAR"):ToAllIf(self.Debug) return nil -- no valid path diff --git a/Moose Development/Moose/Modules.lua b/Moose Development/Moose/Modules.lua index f4a6ab8b6..d13ac38b5 100644 --- a/Moose Development/Moose/Modules.lua +++ b/Moose Development/Moose/Modules.lua @@ -75,6 +75,7 @@ __Moose.Include( 'Scripts/Moose/Ops/Auftrag.lua' ) __Moose.Include( 'Scripts/Moose/Ops/OpsGroup.lua' ) __Moose.Include( 'Scripts/Moose/Ops/FlightGroup.lua' ) __Moose.Include( 'Scripts/Moose/Ops/NavyGroup.lua' ) +__Moose.Include( 'Scripts/Moose/Ops/ArmyGroup.lua' ) __Moose.Include( 'Scripts/Moose/Ops/Squadron.lua' ) __Moose.Include( 'Scripts/Moose/Ops/AirWing.lua' ) __Moose.Include( 'Scripts/Moose/Ops/Intelligence.lua' ) diff --git a/Moose Development/Moose/Ops/ArmyGroup.lua b/Moose Development/Moose/Ops/ArmyGroup.lua index 0533311fc..86171b2af 100644 --- a/Moose Development/Moose/Ops/ArmyGroup.lua +++ b/Moose Development/Moose/Ops/ArmyGroup.lua @@ -70,6 +70,7 @@ function ARMYGROUP:New(GroupName) -- Add FSM transitions. -- From State --> Event --> To State self:AddTransition("*", "FullStop", "Holding") -- Hold position. + self:AddTransition("*", "Cruise", "Cruising") -- Hold position. self:AddTransition("*", "Detour", "OnDetour") -- Make a detour to a coordinate and resume route afterwards. self:AddTransition("OnDetour", "DetourReached", "Cruising") -- Group reached the detour coordinate. @@ -342,11 +343,6 @@ function ARMYGROUP:onafterSpawned(From, Event, To) end - -- Get orientation. - self.Corientlast=self.group:GetUnit(1):GetOrientationX() - - self.depth=self.group:GetHeight() - -- Update route. self:Cruise() @@ -462,7 +458,7 @@ function ARMYGROUP:onafterDetour(From, Event, To, Coordinate, Speed, Depth, Resu local speed=Speed and UTILS.KnotsToKmph(Speed) or self.group:GetVelocityKMH() -- Current waypoint. - local current=self:GetCoordinate():WaypointGround(Speed,Formation,DCSTasks) + local current=self:GetCoordinate():WaypointGround(Speed, Formation, DCSTasks) table.insert(waypoints, current) -- At each waypoint report passing. @@ -534,8 +530,6 @@ function ARMYGROUP:onafterCruise(From, Event, To, Speed) end - - --- On after "Dead" event. -- @param #ARMYGROUP self -- @param #string From From state. @@ -624,7 +618,7 @@ function ARMYGROUP:OnEventBirth(EventData) end ---- Flightgroup event function handling the crash of a unit. +--- Event function handling the crash of a unit. -- @param #ARMYGROUP self -- @param Core.Event#EVENTDATA EventData Event data. function ARMYGROUP:OnEventDead(EventData) @@ -649,7 +643,7 @@ function ARMYGROUP:OnEventDead(EventData) end ---- Flightgroup event function handling the crash of a unit. +--- Event function handling the crash of a unit. -- @param #ARMYGROUP self -- @param Core.Event#EVENTDATA EventData Event data. function ARMYGROUP:OnEventRemoveUnit(EventData) @@ -755,9 +749,7 @@ function ARMYGROUP:_InitGroup() self.position=self:GetCoordinate() -- Radio parameters from template. - self.radioOn=true -- Radio is always on for ships. - self.radioFreq=tonumber(self.template.units[1].frequency)/1000000 - self.radioModu=tonumber(self.template.units[1].modulation)/1000000 + self.radioOn=false -- Radio is always OFF for ground. -- If not set by the use explicitly yet, we take the template values as defaults. if not self.radioFreqDefault then @@ -810,7 +802,7 @@ function ARMYGROUP:_InitGroup() --text=text..string.format("Speed cruise = %.1f Knots\n", UTILS.KmphToKnots(self.speedCruise)) text=text..string.format("Elements = %d\n", #self.elements) text=text..string.format("Waypoints = %d\n", #self.waypoints) - text=text..string.format("Radio = %.1f MHz %s %s\n", self.radioFreq, UTILS.GetModulationName(self.radioModu), tostring(self.radioOn)) + --text=text..string.format("Radio = %.1f MHz %s %s\n", self.radioFreq, UTILS.GetModulationName(self.radioModu), tostring(self.radioOn)) --text=text..string.format("Ammo = %d (G=%d/R=%d/B=%d/M=%d)\n", self.ammo.Total, self.ammo.Guns, self.ammo.Rockets, self.ammo.Bombs, self.ammo.Missiles) text=text..string.format("FSM state = %s\n", self:GetState()) text=text..string.format("Is alive = %s\n", tostring(self.group:IsAlive())) diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 2501b6693..143b0f9e1 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -1817,13 +1817,15 @@ function AUFTRAG:onafterStatus(From, Event, To) self:E(self.lid..string.format("ERROR: FSM state %s != %s mission status!", fsmstate, self.status)) end + -- Data on assigned groups. local text="Group data:" for groupname,_groupdata in pairs(self.groupdata) do local groupdata=_groupdata --#AUFTRAG.GroupData text=text..string.format("\n- %s: status mission=%s opsgroup=%s", groupname, groupdata.status, groupdata.opsgroup and groupdata.opsgroup:GetState() or "N/A") end - self:I(self.lid..text) + self:T(self.lid..text) + -- Ready to evaluate mission outcome? local ready2evaluate=self.Tover and Tnow-self.Tover>=self.dTevaluate or false -- Check if mission is OVER (done or cancelled) and enough time passed to evaluate the result. @@ -2014,7 +2016,7 @@ end -- @param Ops.OpsGroup#OPSGROUP opsgroup The flight group. -- @param Ops.OpsGroup#OPSGROUP.Task task Waypoint task. function AUFTRAG:SetGroupWaypointTask(opsgroup, task) - self:I(self.lid..string.format("Setting waypoint task %s", task and task.description or "WTF")) + self:T2(self.lid..string.format("Setting waypoint task %s", task and task.description or "WTF")) local groupdata=self:GetGroupData(opsgroup) if groupdata then groupdata.waypointtask=task @@ -2037,7 +2039,7 @@ end -- @param Ops.OpsGroup#OPSGROUP opsgroup The flight group. -- @param #number waypointindex Waypoint index. function AUFTRAG:SetGroupWaypointIndex(opsgroup, waypointindex) - self:I(self.lid..string.format("Setting waypoint index %d", waypointindex)) + self:T2(self.lid..string.format("Setting waypoint index %d", waypointindex)) local groupdata=self:GetGroupData(opsgroup) if groupdata then groupdata.waypointindex=waypointindex @@ -2127,7 +2129,7 @@ end function AUFTRAG:onafterQueued(From, Event, To, Airwing) self.status=AUFTRAG.Status.QUEUED self.airwing=Airwing - self:I(self.lid..string.format("New mission status=%s at airwing %s", self.status, tostring(Airwing.alias))) + self:T(self.lid..string.format("New mission status=%s at airwing %s", self.status, tostring(Airwing.alias))) end @@ -2138,7 +2140,7 @@ end -- @param #string To To state. function AUFTRAG:onafterRequested(From, Event, To) self.status=AUFTRAG.Status.REQUESTED - self:I(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "Assign" event. @@ -2148,7 +2150,7 @@ end -- @param #string To To state. function AUFTRAG:onafterAssign(From, Event, To) self.status=AUFTRAG.Status.ASSIGNED - self:I(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "Schedule" event. Mission is added to the mission queue of a FLIGHTGROUP. @@ -2159,7 +2161,7 @@ end -- @param Ops.OpsGroup#OPSGROUP FlightGroup function AUFTRAG:onafterScheduled(From, Event, To, FlightGroup) self.status=AUFTRAG.Status.SCHEDULED - self:I(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "Start" event. @@ -2169,7 +2171,7 @@ end -- @param #string To To state. function AUFTRAG:onafterStarted(From, Event, To) self.status=AUFTRAG.Status.STARTED - self:I(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "Execute" event. @@ -2179,7 +2181,7 @@ end -- @param #string To To state. function AUFTRAG:onafterExecuting(From, Event, To) self.status=AUFTRAG.Status.EXECUTING - self:I(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) end --- On after "Done" event. @@ -2189,7 +2191,7 @@ end -- @param #string To To state. function AUFTRAG:onafterDone(From, Event, To) self.status=AUFTRAG.Status.DONE - self:I(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) -- Set time stamp. self.Tover=timer.getAbsTime() @@ -2259,7 +2261,7 @@ end function AUFTRAG:onafterSuccess(From, Event, To) self.status=AUFTRAG.Status.SUCCESS - self:I(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) -- Stop mission. self:Stop() @@ -2287,20 +2289,20 @@ function AUFTRAG:onafterCancel(From, Event, To) if self.wingcommander then - self:I(self.lid..string.format("Wingcommander will cancel the mission. Will wait for mission DONE before evaluation!")) + self:T(self.lid..string.format("Wingcommander will cancel the mission. Will wait for mission DONE before evaluation!")) self.wingcommander:CancelMission(self) elseif self.airwing then - self:I(self.lid..string.format("Airwing %s will cancel the mission. Will wait for mission DONE before evaluation!", self.airwing.alias)) + self:T(self.lid..string.format("Airwing %s will cancel the mission. Will wait for mission DONE before evaluation!", self.airwing.alias)) -- Airwing will cancel all flight missions and remove queued request from warehouse queue. self.airwing:MissionCancel(self) else - self:I(self.lid..string.format("No airwing or wingcommander. Attached flights will cancel the mission on their own. Will wait for mission DONE before evaluation!")) + self:T(self.lid..string.format("No airwing or wingcommander. Attached flights will cancel the mission on their own. Will wait for mission DONE before evaluation!")) for _,_groupdata in pairs(self.groupdata) do local groupdata=_groupdata --#AUFTRAG.GroupData @@ -2311,7 +2313,7 @@ function AUFTRAG:onafterCancel(From, Event, To) -- Special mission states. if self.status==AUFTRAG.Status.PLANNED then - self:I(self.lid..string.format("Cancelled mission was in planned stage. Call it done!")) + self:T(self.lid..string.format("Cancelled mission was in planned stage. Call it done!")) self:Done() end @@ -2325,7 +2327,7 @@ end function AUFTRAG:onafterFailed(From, Event, To) self.status=AUFTRAG.Status.FAILED - self:I(self.lid..string.format("New mission status=%s", self.status)) + self:T(self.lid..string.format("New mission status=%s", self.status)) if self.missionRepeated>=self.missionRepeatMax then @@ -2353,7 +2355,7 @@ function AUFTRAG:onafterRepeat(From, Event, To) -- Set mission status to PLANNED. self.status=AUFTRAG.Status.PLANNED - self:I(self.lid..string.format("New mission status=%s (on Repeat)", self.status)) + self:T(self.lid..string.format("New mission status=%s (on Repeat)", self.status)) -- Increase repeat counter. self.missionRepeated=self.missionRepeated+1 @@ -2452,7 +2454,7 @@ function AUFTRAG:DelAsset(Asset) local asset=_asset --Ops.AirWing#AIRWING.SquadronAsset if asset.uid==Asset.uid then - self:I(self.lid..string.format("Removing asset \"%s\" from mission", tostring(asset.spawngroupname))) + self:T(self.lid..string.format("Removing asset \"%s\" from mission", tostring(asset.spawngroupname))) table.remove(self.assets, i) return self end @@ -3289,7 +3291,7 @@ function AUFTRAG:_TargetFromObject(Object) self.Ntargets=Ninitial -- Debug info. - self:I(self.lid..string.format("Mission Target %s Type=%s, Ntargets=%d, Lifepoints=%d", target.Name, target.Type, Ninitial, Lifepoints)) + self:T(self.lid..string.format("Mission Target %s Type=%s, Ntargets=%d, Lifepoints=%d", target.Name, target.Type, Ninitial, Lifepoints)) return target end diff --git a/Moose Development/Moose/Ops/ChiefOfStaff.lua b/Moose Development/Moose/Ops/ChiefOfStaff.lua index af72725a3..682872dbc 100644 --- a/Moose Development/Moose/Ops/ChiefOfStaff.lua +++ b/Moose Development/Moose/Ops/ChiefOfStaff.lua @@ -374,7 +374,7 @@ function CHIEF:onafterStatus(From, Event, To) -- Clean up missions where the contact was lost. for _,_contact in pairs(self.ContactsLost) do - local contact=_contact --#CHIEF.Contact + local contact=_contact --#INTEL.Contact if contact.mission and contact.mission:IsNotOver() then @@ -539,7 +539,6 @@ end -- @param #string Event Event. -- @param #string To To state. -- @param #string Defcon New defence condition. --- @param Ops.Auftrag#AUFTRAG Mission The mission. function CHIEF:onbeforeDefcon(From, Event, To, Defcon) local gotit=false @@ -569,7 +568,6 @@ end -- @param #string Event Event. -- @param #string To To state. -- @param #string Defcon New defence condition. --- @param Ops.Auftrag#AUFTRAG Mission The mission. function CHIEF:onafterDefcon(From, Event, To, Defcon) self:I(self.lid..string.format("Changing Defcon from %s --> %s", self.Defcon, Defcon)) @@ -577,6 +575,20 @@ function CHIEF:onafterDefcon(From, Event, To, Defcon) self.Defcon=Defcon end +--- On after "DeclareWar" event. +-- @param #CHIEF self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #CHIEF Chief The Chief we declared war on. +function CHIEF:onafterDeclareWar(From, Event, To, Chief) + + if Chief then + self:AddWarOnChief(Chief) + end + +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Resources -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------