mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Progress on Route
This commit is contained in:
parent
4ac962a87a
commit
23ea389b8f
BIN
Moose Development/Documentation/FAC_Detection logic.pdf
Normal file
BIN
Moose Development/Documentation/FAC_Detection logic.pdf
Normal file
Binary file not shown.
@ -153,7 +153,7 @@ function AIBALANCER:_ClientAliveMonitorScheduler()
|
||||
-- If there is no CLIENT within the self.ReturnTresholdRange, then the unit will return to the Airbase return method selected.
|
||||
|
||||
local PlayerInRange = { Value = false }
|
||||
local RangeZone = ZONE_RADIUS:New( 'RangeZone', AIGroup:GetPointVec2(), self.ReturnTresholdRange )
|
||||
local RangeZone = ZONE_RADIUS:New( 'RangeZone', AIGroup:GetVec2(), self.ReturnTresholdRange )
|
||||
|
||||
self:E( RangeZone )
|
||||
|
||||
@ -183,7 +183,7 @@ function AIBALANCER:_ClientAliveMonitorScheduler()
|
||||
else
|
||||
-- Okay, we need to send this Group back to the nearest base of the Coalition of the AI.
|
||||
--TODO: i need to rework the POINT_VEC2 thing.
|
||||
local PointVec2 = POINT_VEC2:New( AIGroup:GetPointVec2().x, AIGroup:GetPointVec2().y )
|
||||
local PointVec2 = POINT_VEC2:New( AIGroup:GetVec2().x, AIGroup:GetVec2().y )
|
||||
local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 )
|
||||
self:T( ClosestAirbase.AirbaseName )
|
||||
AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 )
|
||||
|
||||
@ -588,7 +588,7 @@ function CONTROLLABLE:TaskOrbitCircle( Altitude, Speed )
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
|
||||
if DCSControllable then
|
||||
local ControllablePoint = self:GetPointVec2()
|
||||
local ControllablePoint = self:GetVec2()
|
||||
return self:TaskOrbitCircleAtVec2( ControllablePoint, Altitude, Speed )
|
||||
end
|
||||
|
||||
@ -765,7 +765,7 @@ function CONTROLLABLE:TaskLandAtZone( Zone, Duration, RandomPoint )
|
||||
if RandomPoint then
|
||||
Point = Zone:GetRandomVec2()
|
||||
else
|
||||
Point = Zone:GetPointVec2()
|
||||
Point = Zone:GetVec2()
|
||||
end
|
||||
|
||||
local DCSTask = self:TaskLandAtVec2( Point, Duration )
|
||||
@ -1365,7 +1365,7 @@ end
|
||||
function CONTROLLABLE:TaskRouteToVec2( Point, Speed )
|
||||
self:F2( { Point, Speed } )
|
||||
|
||||
local ControllablePoint = self:GetUnit( 1 ):GetPointVec2()
|
||||
local ControllablePoint = self:GetUnit( 1 ):GetVec2()
|
||||
|
||||
local PointFrom = {}
|
||||
PointFrom.x = ControllablePoint.x
|
||||
@ -1504,7 +1504,7 @@ function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation )
|
||||
|
||||
if DCSControllable then
|
||||
|
||||
local ControllablePoint = self:GetPointVec2()
|
||||
local ControllablePoint = self:GetVec2()
|
||||
|
||||
local PointFrom = {}
|
||||
PointFrom.x = ControllablePoint.x
|
||||
@ -1520,7 +1520,7 @@ function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation )
|
||||
if Randomize then
|
||||
ZonePoint = Zone:GetRandomVec2()
|
||||
else
|
||||
ZonePoint = Zone:GetPointVec2()
|
||||
ZonePoint = Zone:GetVec2()
|
||||
end
|
||||
|
||||
PointTo.x = ZonePoint.x
|
||||
@ -1602,7 +1602,7 @@ function CONTROLLABLE:RouteReturnToAirbase( ReturnAirbase, Speed )
|
||||
|
||||
if DCSControllable then
|
||||
|
||||
local ControllablePoint = self:GetPointVec2()
|
||||
local ControllablePoint = self:GetVec2()
|
||||
local ControllableVelocity = self:GetMaxVelocity()
|
||||
|
||||
local PointFrom = {}
|
||||
@ -1614,7 +1614,7 @@ function CONTROLLABLE:RouteReturnToAirbase( ReturnAirbase, Speed )
|
||||
|
||||
|
||||
local PointTo = {}
|
||||
local AirbasePoint = ReturnAirbase:GetPointVec2()
|
||||
local AirbasePoint = ReturnAirbase:GetVec2()
|
||||
|
||||
PointTo.x = AirbasePoint.x
|
||||
PointTo.y = AirbasePoint.y
|
||||
|
||||
@ -674,7 +674,7 @@ function ESCORT._HoldPosition( MenuParam )
|
||||
PointFrom.alt = GroupPoint.y
|
||||
PointFrom.alt_type = AI.Task.AltitudeType.BARO
|
||||
|
||||
local OrbitPoint = OrbitUnit:GetPointVec2()
|
||||
local OrbitPoint = OrbitUnit:GetVec2()
|
||||
local PointTo = {}
|
||||
PointTo.x = OrbitPoint.x
|
||||
PointTo.y = OrbitPoint.y
|
||||
@ -867,7 +867,7 @@ function ESCORT._AttackTarget( MenuParam )
|
||||
SCHEDULER:New( EscortGroup,
|
||||
EscortGroup.PushTask,
|
||||
{ EscortGroup:TaskCombo(
|
||||
{ EscortGroup:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 )
|
||||
{ EscortGroup:TaskFireAtPoint( AttackUnit:GetVec2(), 50 )
|
||||
}
|
||||
)
|
||||
}, 10
|
||||
@ -907,7 +907,7 @@ function ESCORT._AssistTarget( MenuParam )
|
||||
SCHEDULER:New( EscortGroupAttack,
|
||||
EscortGroupAttack.PushTask,
|
||||
{ EscortGroupAttack:TaskCombo(
|
||||
{ EscortGroupAttack:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 )
|
||||
{ EscortGroupAttack:TaskFireAtPoint( AttackUnit:GetVec2(), 50 )
|
||||
}
|
||||
)
|
||||
}, 10
|
||||
|
||||
@ -475,12 +475,12 @@ end
|
||||
--- Returns the current point (Vec2 vector) of the first DCS Unit in the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return DCSTypes#Vec2 Current Vec2 point of the first DCS Unit of the DCS Group.
|
||||
function GROUP:GetPointVec2()
|
||||
function GROUP:GetVec2()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local UnitPoint = self:GetUnit(1)
|
||||
UnitPoint:GetPointVec2()
|
||||
local GroupPointVec2 = UnitPoint:GetPointVec2()
|
||||
UnitPoint:GetVec2()
|
||||
local GroupPointVec2 = UnitPoint:GetVec2()
|
||||
self:T3( GroupPointVec2 )
|
||||
return GroupPointVec2
|
||||
end
|
||||
|
||||
@ -138,7 +138,7 @@ function PATROLZONE:NewPatrolRoute()
|
||||
-- If not, make a waypoint within the to that the PatrolGroup will fly at maximum speed to that point.
|
||||
|
||||
-- --- Calculate the current route point.
|
||||
-- local CurrentVec2 = self.PatrolGroup:GetPointVec2()
|
||||
-- local CurrentVec2 = self.PatrolGroup:GetVec2()
|
||||
-- local CurrentAltitude = self.PatrolGroup:GetUnit(1):GetAltitude()
|
||||
-- local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||
-- local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
-- ===============================================
|
||||
-- The @{Point#POINT_VEC3} class defines a 3D point in the simulator.
|
||||
--
|
||||
-- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts.
|
||||
-- In order to keep the credibility of the the author, I want to emphasize that the of the MIST framework was created by Grimes, who you can find on the Eagle Dynamics Forums.
|
||||
--
|
||||
-- 1.1) POINT_VEC3 constructor
|
||||
-- ---------------------------
|
||||
--
|
||||
@ -28,6 +31,7 @@
|
||||
--- The POINT_VEC3 class
|
||||
-- @type POINT_VEC3
|
||||
-- @extends Base#BASE
|
||||
-- @field DCSTypes#Vec3 PointVec3
|
||||
-- @field #POINT_VEC3.SmokeColor SmokeColor
|
||||
-- @field #POINT_VEC3.FlareColor FlareColor
|
||||
-- @field #POINT_VEC3.RoutePointAltType RoutePointAltType
|
||||
@ -48,6 +52,7 @@ POINT_VEC3 = {
|
||||
White = trigger.flareColor.White,
|
||||
Yellow = trigger.flareColor.Yellow
|
||||
},
|
||||
Metric = true,
|
||||
RoutePointAltType = {
|
||||
BARO = "BARO",
|
||||
},
|
||||
@ -114,6 +119,148 @@ function POINT_VEC3:New( x, y, z )
|
||||
end
|
||||
|
||||
|
||||
--- Return the coordinates of the POINT_VEC3 in Vec3 format.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return DCSTypes#Vec3 The Vec3 coodinate.
|
||||
function POINT_VEC3:GetVec3()
|
||||
return self.PointVec3
|
||||
end
|
||||
|
||||
|
||||
--- Return the x coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #number The x coodinate.
|
||||
function POINT_VEC3:GetX()
|
||||
return self.PointVec3.x
|
||||
end
|
||||
|
||||
--- Return the y coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #number The y coodinate.
|
||||
function POINT_VEC3:GetY()
|
||||
return self.PointVec3.y
|
||||
end
|
||||
|
||||
--- Return the z coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #number The z coodinate.
|
||||
function POINT_VEC3:GetZ()
|
||||
return self.PointVec3.z
|
||||
end
|
||||
|
||||
|
||||
--- Return a direction vector Vec3 from POINT_VEC3 to the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3 TargetPointVec3 The target PointVec3.
|
||||
-- @return DCSTypes#Vec3 DirectionVec3 The direction vector in Vec3 format.
|
||||
function POINT_VEC3:GetDirectionVec3( TargetPointVec3 )
|
||||
return { x = TargetPointVec3:GetX() - self:GetX(), y = TargetPointVec3:GetY() - self:GetY(), z = TargetPointVec3:GetZ() - self:GetZ() }
|
||||
end
|
||||
|
||||
--- Get a correction in radians of the real magnetic north of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #number CorrectionRadians The correction in radians.
|
||||
function POINT_VEC3:GetNorthCorrectionRadians()
|
||||
local TargetVec3 = self:GetVec3()
|
||||
local lat, lon = coord.LOtoLL(TargetVec3)
|
||||
local north_posit = coord.LLtoLO(lat + 1, lon)
|
||||
return math.atan2( north_posit.z - TargetVec3.z, north_posit.x - TargetVec3.x )
|
||||
end
|
||||
|
||||
|
||||
--- Return a direction in radians from the POINT_VEC3 using a direction vector in Vec3 format.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param DCSTypes#Vec3 DirectionVec3 The direction vector in Vec3 format.
|
||||
-- @return #number DirectionRadians The direction in radians.
|
||||
function POINT_VEC3:GetDirectionRadians( DirectionVec3 )
|
||||
local DirectionRadians = math.atan2( DirectionVec3.z, DirectionVec3.x )
|
||||
DirectionRadians = DirectionRadians + self:GetNorthCorrectionRadians()
|
||||
if DirectionRadians < 0 then
|
||||
DirectionRadians = DirectionRadians + 2 * math.pi -- put dir in range of 0 to 2*pi ( the full circle )
|
||||
end
|
||||
return DirectionRadians
|
||||
end
|
||||
|
||||
--- Return the 2D distance in meters between the target POINT_VEC3 and the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3 TargetPointVec3 The target PointVec3.
|
||||
-- @return DCSTypes#Distance Distance The distance in meters.
|
||||
function POINT_VEC3:Get2DDistance( TargetPointVec3 )
|
||||
local TargetVec3 = TargetPointVec3:GetVec3()
|
||||
local SourceVec3 = self:GetVec3()
|
||||
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
|
||||
end
|
||||
|
||||
--- Return the 3D distance in meters between the target POINT_VEC3 and the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3 TargetPointVec3 The target PointVec3.
|
||||
-- @return DCSTypes#Distance Distance The distance in meters.
|
||||
function POINT_VEC3:Get3DDistance( TargetPointVec3 )
|
||||
local TargetVec3 = TargetPointVec3:GetVec3()
|
||||
local SourceVec3 = self:GetVec3()
|
||||
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.y - SourceVec3.y ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
|
||||
end
|
||||
|
||||
--- Provides a Bearing / Range string
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number AngleRadians The angle in randians
|
||||
-- @param #number Distance The distance
|
||||
-- @return #string The BR Text
|
||||
function POINT_VEC3:ToStringBR( AngleRadians, Distance )
|
||||
|
||||
AngleRadians = UTILS.Round( UTILS.ToDegree( AngleRadians ), 0 )
|
||||
if self:IsMetric() then
|
||||
Distance = UTILS.Round( Distance / 1000, 2 )
|
||||
else
|
||||
Distance = UTILS.Round( UTILS.MetersToNM( Distance ), 2 )
|
||||
end
|
||||
|
||||
local s = string.format( '%03d', AngleRadians ) .. ' for ' .. Distance
|
||||
|
||||
s = s .. self:GetAltitudeText() -- When the POINT is a VEC2, there will be no altitude shown.
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
--- Return the altitude text of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #string Altitude text.
|
||||
function POINT_VEC3:GetAltitudeText()
|
||||
if self:IsMetric() then
|
||||
return ' at ' .. UTILS.Round( self:GetY(), 0 )
|
||||
else
|
||||
return ' at ' .. UTILS.Round( UTILS.MetersToFeet( self:GetY() ), 0 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Return a BR string from a POINT_VEC3 to the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3 TargetPointVec3 The target PointVec3.
|
||||
-- @return #string The BR text.
|
||||
function POINT_VEC3:GetBRText( TargetPointVec3 )
|
||||
local DirectionVec3 = self:GetDirectionVec3( TargetPointVec3 )
|
||||
local AngleRadians = self:GetDirectionRadians( DirectionVec3 )
|
||||
local Distance = self:Get2DDistance( TargetPointVec3 )
|
||||
return self:ToStringBR( AngleRadians, Distance )
|
||||
end
|
||||
|
||||
--- Sets the POINT_VEC3 metric or NM.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #boolean Metric true means metric, false means NM.
|
||||
function POINT_VEC3:SetMetric( Metric )
|
||||
self.Metric = Metric
|
||||
end
|
||||
|
||||
--- Gets if the POINT_VEC3 is metric or NM.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #boolean Metric true means metric, false means NM.
|
||||
function POINT_VEC3:IsMetric()
|
||||
return self.Metric
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Build an air type route point.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3.RoutePointAltType AltType The altitude type.
|
||||
@ -299,3 +446,10 @@ function POINT_VEC2:DistanceFromVec2( Vec2Reference )
|
||||
end
|
||||
|
||||
|
||||
--- Return no text for the altitude of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @return #string Empty string.
|
||||
function POINT_VEC2:GetAltitudeText()
|
||||
return ''
|
||||
end
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ end
|
||||
-- @param Positionable#POSITIONABLE self
|
||||
-- @return DCSTypes#Vec2 The 2D point vector of the DCS Positionable.
|
||||
-- @return #nil The DCS Positionable is not existing or alive.
|
||||
function POSITIONABLE:GetPointVec2()
|
||||
function POSITIONABLE:GetVec2()
|
||||
self:F2( self.PositionableName )
|
||||
|
||||
local DCSPositionable = self:GetDCSObject()
|
||||
@ -137,7 +137,7 @@ function POSITIONABLE:IsAboveRunway()
|
||||
|
||||
if DCSPositionable then
|
||||
|
||||
local PointVec2 = self:GetPointVec2()
|
||||
local PointVec2 = self:GetVec2()
|
||||
local SurfaceType = land.getSurfaceType( PointVec2 )
|
||||
local IsAboveRunway = SurfaceType == land.SurfaceType.RUNWAY
|
||||
|
||||
|
||||
@ -245,22 +245,6 @@ end
|
||||
|
||||
|
||||
|
||||
-- From http://lua-users.org/wiki/SimpleRound
|
||||
-- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place
|
||||
routines.utils.round = function(num, idp)
|
||||
local mult = 10^(idp or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
-- porting in Slmod's dostring
|
||||
routines.utils.dostring = function(s)
|
||||
local f, err = loadstring(s)
|
||||
if f then
|
||||
return true, f()
|
||||
else
|
||||
return false, err
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--3D Vector manipulation
|
||||
|
||||
@ -399,9 +399,9 @@ function SET_BASE:FindNearestObjectFromPointVec2( PointVec2 )
|
||||
for ObjectID, ObjectData in pairs( self.Set ) do
|
||||
if NearestObject == nil then
|
||||
NearestObject = ObjectData
|
||||
ClosestDistance = PointVec2:DistanceFromVec2( ObjectData:GetPointVec2() )
|
||||
ClosestDistance = PointVec2:DistanceFromVec2( ObjectData:GetVec2() )
|
||||
else
|
||||
local Distance = PointVec2:DistanceFromVec2( ObjectData:GetPointVec2() )
|
||||
local Distance = PointVec2:DistanceFromVec2( ObjectData:GetVec2() )
|
||||
if Distance < ClosestDistance then
|
||||
NearestObject = ObjectData
|
||||
ClosestDistance = Distance
|
||||
|
||||
@ -563,7 +563,7 @@ function SPAWN:SpawnFromUnit( HostUnit, OuterRadius, InnerRadius, SpawnIndex )
|
||||
|
||||
if SpawnTemplate then
|
||||
|
||||
local UnitPoint = HostUnit:GetPointVec2()
|
||||
local UnitPoint = HostUnit:GetVec2()
|
||||
|
||||
self:T( { "Current point of ", self.SpawnTemplatePrefix, UnitPoint } )
|
||||
|
||||
@ -646,7 +646,7 @@ function SPAWN:SpawnInZone( Zone, ZoneRandomize, SpawnIndex )
|
||||
if ZoneRandomize == true then
|
||||
ZonePoint = Zone:GetRandomVec2()
|
||||
else
|
||||
ZonePoint = Zone:GetPointVec2()
|
||||
ZonePoint = Zone:GetVec2()
|
||||
end
|
||||
|
||||
SpawnTemplate.route.points[1].x = ZonePoint.x
|
||||
|
||||
83
Moose Development/Moose/TaskClientRoute.lua
Normal file
83
Moose Development/Moose/TaskClientRoute.lua
Normal file
@ -0,0 +1,83 @@
|
||||
--- @module Task_Route
|
||||
|
||||
--- TASK2_ROUTE_CLIENT class
|
||||
-- @type TASK2_ROUTE_CLIENT
|
||||
-- @field Mission#MISSION Mission
|
||||
-- @field Client#CLIENT Client
|
||||
-- @field Zone#ZONE_BASE TargetZone
|
||||
-- @extends Task2#TASK2
|
||||
TASK2_ROUTE_CLIENT = {
|
||||
ClassName = "TASK2_ROUTE_CLIENT",
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new routing state machine. The task will route a CLIENT to a ZONE until the CLIENT is within that ZONE.
|
||||
-- @param #TASK2_ROUTE_CLIENT self
|
||||
-- @param Mission#MISSION Mission
|
||||
-- @param Client#CLIENT Client
|
||||
-- @return #TASK2_ROUTE_CLIENT self
|
||||
function TASK2_ROUTE_CLIENT:New( Mission, Client, TargetZone )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, TASK2:New( Mission, Client ) ) -- #TASK2_ROUTE_CLIENT
|
||||
|
||||
self.TargetZone = TargetZone
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 1
|
||||
self.DisplayMessage = true
|
||||
self.DisplayTime = 10 -- 10 seconds is the default
|
||||
self.DisplayCategory = "Route" -- Route is the default display category
|
||||
|
||||
self.Fsm = STATEMACHINE_TASK:New( self, {
|
||||
initial = 'Unarrived',
|
||||
events = {
|
||||
{ name = 'Route', from = 'UnArrived', to = 'Arrived' },
|
||||
{ name = 'Fail', from = 'UnArrived', to = 'Failed' },
|
||||
},
|
||||
callbacks = {
|
||||
onleaveUnarrived = self.OnBeforeRoute,
|
||||
onFail = self.OnFail,
|
||||
},
|
||||
endstates = {
|
||||
'Arrived', 'Failed'
|
||||
},
|
||||
} )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Task Events
|
||||
|
||||
--- StateMachine callback function for a TASK2
|
||||
-- @param #TASK2_ROUTE_CLIENT self
|
||||
-- @param StateMachine#STATEMACHINE_TASK Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function TASK2_ROUTE_CLIENT:OnBeforeRoute( Fsm, Event, From, To )
|
||||
self:E( { Event, From, To, self.Client.ClientName } )
|
||||
|
||||
local IsInZone = self.Client:IsInZone( self.TargetZone )
|
||||
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
if not IsInZone then
|
||||
local ZoneVec2 = self.TargetZone:GetVec2()
|
||||
local ZonePointVec2 = POINT_VEC2:New( ZoneVec2.x, ZoneVec2.y )
|
||||
local ClientVec2 = self.Client:GetVec2()
|
||||
local ClientPointVec2 = POINT_VEC2:New( ClientVec2.x, ClientVec2.y )
|
||||
local RouteText = ClientPointVec2:GetBRText( ZonePointVec2 )
|
||||
self.Client:Message( RouteText, self.DisplayTime, self.DisplayCategory )
|
||||
end
|
||||
self.DisplayCount = 1
|
||||
else
|
||||
self.DisplayCount = self.DisplayCount + 1
|
||||
end
|
||||
|
||||
if not IsInZone then
|
||||
self:NextEvent( Fsm.Route )
|
||||
end
|
||||
|
||||
return IsInZone -- if false, then the event will not be executed...
|
||||
|
||||
end
|
||||
|
||||
176
Moose Development/Moose/Utils.lua
Normal file
176
Moose Development/Moose/Utils.lua
Normal file
@ -0,0 +1,176 @@
|
||||
|
||||
--- Utilities static class.
|
||||
-- @type UTILS
|
||||
UTILS = {}
|
||||
|
||||
|
||||
--from http://lua-users.org/wiki/CopyTable
|
||||
UTILS.DeepCopy = function(object)
|
||||
local lookup_table = {}
|
||||
local function _copy(object)
|
||||
if type(object) ~= "table" then
|
||||
return object
|
||||
elseif lookup_table[object] then
|
||||
return lookup_table[object]
|
||||
end
|
||||
local new_table = {}
|
||||
lookup_table[object] = new_table
|
||||
for index, value in pairs(object) do
|
||||
new_table[_copy(index)] = _copy(value)
|
||||
end
|
||||
return setmetatable(new_table, getmetatable(object))
|
||||
end
|
||||
local objectreturn = _copy(object)
|
||||
return objectreturn
|
||||
end
|
||||
|
||||
|
||||
-- porting in Slmod's serialize_slmod2
|
||||
UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
||||
|
||||
lookup_table = {}
|
||||
|
||||
local function _Serialize( tbl )
|
||||
|
||||
if type(tbl) == 'table' then --function only works for tables!
|
||||
|
||||
if lookup_table[tbl] then
|
||||
return lookup_table[object]
|
||||
end
|
||||
|
||||
local tbl_str = {}
|
||||
|
||||
lookup_table[tbl] = tbl_str
|
||||
|
||||
tbl_str[#tbl_str + 1] = '{'
|
||||
|
||||
for ind,val in pairs(tbl) do -- serialize its fields
|
||||
local ind_str = {}
|
||||
if type(ind) == "number" then
|
||||
ind_str[#ind_str + 1] = '['
|
||||
ind_str[#ind_str + 1] = tostring(ind)
|
||||
ind_str[#ind_str + 1] = ']='
|
||||
else --must be a string
|
||||
ind_str[#ind_str + 1] = '['
|
||||
ind_str[#ind_str + 1] = routines.utils.basicSerialize(ind)
|
||||
ind_str[#ind_str + 1] = ']='
|
||||
end
|
||||
|
||||
local val_str = {}
|
||||
if ((type(val) == 'number') or (type(val) == 'boolean')) then
|
||||
val_str[#val_str + 1] = tostring(val)
|
||||
val_str[#val_str + 1] = ','
|
||||
tbl_str[#tbl_str + 1] = table.concat(ind_str)
|
||||
tbl_str[#tbl_str + 1] = table.concat(val_str)
|
||||
elseif type(val) == 'string' then
|
||||
val_str[#val_str + 1] = routines.utils.basicSerialize(val)
|
||||
val_str[#val_str + 1] = ','
|
||||
tbl_str[#tbl_str + 1] = table.concat(ind_str)
|
||||
tbl_str[#tbl_str + 1] = table.concat(val_str)
|
||||
elseif type(val) == 'nil' then -- won't ever happen, right?
|
||||
val_str[#val_str + 1] = 'nil,'
|
||||
tbl_str[#tbl_str + 1] = table.concat(ind_str)
|
||||
tbl_str[#tbl_str + 1] = table.concat(val_str)
|
||||
elseif type(val) == 'table' then
|
||||
if ind == "__index" then
|
||||
-- tbl_str[#tbl_str + 1] = "__index"
|
||||
-- tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||
else
|
||||
|
||||
val_str[#val_str + 1] = _Serialize(val)
|
||||
val_str[#val_str + 1] = ',' --I think this is right, I just added it
|
||||
tbl_str[#tbl_str + 1] = table.concat(ind_str)
|
||||
tbl_str[#tbl_str + 1] = table.concat(val_str)
|
||||
end
|
||||
elseif type(val) == 'function' then
|
||||
-- tbl_str[#tbl_str + 1] = "function " .. tostring(ind)
|
||||
-- tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||
else
|
||||
-- env.info('unable to serialize value type ' .. routines.utils.basicSerialize(type(val)) .. ' at index ' .. tostring(ind))
|
||||
-- env.info( debug.traceback() )
|
||||
end
|
||||
|
||||
end
|
||||
tbl_str[#tbl_str + 1] = '}'
|
||||
return table.concat(tbl_str)
|
||||
else
|
||||
return tostring(tbl)
|
||||
end
|
||||
end
|
||||
|
||||
local objectreturn = _Serialize(tbl)
|
||||
return objectreturn
|
||||
end
|
||||
|
||||
--porting in Slmod's "safestring" basic serialize
|
||||
UTILS.BasicSerialize = function(s)
|
||||
if s == nil then
|
||||
return "\"\""
|
||||
else
|
||||
if ((type(s) == 'number') or (type(s) == 'boolean') or (type(s) == 'function') or (type(s) == 'table') or (type(s) == 'userdata') ) then
|
||||
return tostring(s)
|
||||
elseif type(s) == 'string' then
|
||||
s = string.format('%q', s)
|
||||
return s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
UTILS.ToDegree = function(angle)
|
||||
return angle*180/math.pi
|
||||
end
|
||||
|
||||
UTILS.ToRadian = function(angle)
|
||||
return angle*math.pi/180
|
||||
end
|
||||
|
||||
UTILS.MetersToNM = function(meters)
|
||||
return meters/1852
|
||||
end
|
||||
|
||||
UTILS.MetersToFeet = function(meters)
|
||||
return meters/0.3048
|
||||
end
|
||||
|
||||
UTILS.NMToMeters = function(NM)
|
||||
return NM*1852
|
||||
end
|
||||
|
||||
UTILS.FeetToMeters = function(feet)
|
||||
return feet*0.3048
|
||||
end
|
||||
|
||||
UTILS.MpsToKnots = function(mps)
|
||||
return mps*3600/1852
|
||||
end
|
||||
|
||||
UTILS.MpsToKmph = function(mps)
|
||||
return mps*3.6
|
||||
end
|
||||
|
||||
UTILS.KnotsToMps = function(knots)
|
||||
return knots*1852/3600
|
||||
end
|
||||
|
||||
UTILS.KmphToMps = function(kmph)
|
||||
return kmph/3.6
|
||||
end
|
||||
|
||||
|
||||
--- From http://lua-users.org/wiki/SimpleRound
|
||||
-- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place
|
||||
function UTILS.Round( num, idp )
|
||||
local mult = 10 ^ ( idp or 0 )
|
||||
return math.floor( num * mult + 0.5 ) / mult
|
||||
end
|
||||
|
||||
-- porting in Slmod's dostring
|
||||
function UTILS.DoString( s )
|
||||
local f, err = loadstring( s )
|
||||
if f then
|
||||
return true, f()
|
||||
else
|
||||
return false, err
|
||||
end
|
||||
end
|
||||
@ -101,10 +101,10 @@ end
|
||||
|
||||
--- Returns if a location is within the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param DCSTypes#Vec2 PointVec2 The location to test.
|
||||
-- @param DCSTypes#Vec2 Vec2 The location to test.
|
||||
-- @return #boolean true if the location is within the zone.
|
||||
function ZONE_BASE:IsPointVec2InZone( PointVec2 )
|
||||
self:F2( PointVec2 )
|
||||
function ZONE_BASE:IsPointVec2InZone( Vec2 )
|
||||
self:F2( Vec2 )
|
||||
|
||||
return false
|
||||
end
|
||||
@ -121,18 +121,27 @@ function ZONE_BASE:IsPointVec3InZone( PointVec3 )
|
||||
return InZone
|
||||
end
|
||||
|
||||
--- Returns the Vec2 coordinate of the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return #nil.
|
||||
function ZONE_BASE:GetVec2()
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
return nil
|
||||
end
|
||||
--- Define a random @{DCSTypes#Vec2} within the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return DCSTypes#Vec2 The Vec2 coordinates.
|
||||
-- @return #nil The Vec2 coordinates.
|
||||
function ZONE_BASE:GetRandomVec2()
|
||||
return { x = 0, y = 0 }
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the bounding square the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return #ZONE_BASE.BoundingSquare The bounding square.
|
||||
-- @return #nil The bounding square.
|
||||
function ZONE_BASE:GetBoundingSquare()
|
||||
return { x1 = 0, y1 = 0, x2 = 0, y2 = 0 }
|
||||
--return { x1 = 0, y1 = 0, x2 = 0, y2 = 0 }
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
@ -147,7 +156,7 @@ end
|
||||
|
||||
--- The ZONE_RADIUS class, defined by a zone name, a location and a radius.
|
||||
-- @type ZONE_RADIUS
|
||||
-- @field DCSTypes#Vec2 PointVec2 The current location of the zone.
|
||||
-- @field DCSTypes#Vec2 Vec2 The current location of the zone.
|
||||
-- @field DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @extends Zone#ZONE_BASE
|
||||
ZONE_RADIUS = {
|
||||
@ -157,15 +166,15 @@ ZONE_RADIUS = {
|
||||
--- Constructor of ZONE_RADIUS, taking the zone name, the zone location and a radius.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param DCSTypes#Vec2 PointVec2 The location of the zone.
|
||||
-- @param DCSTypes#Vec2 Vec2 The location of the zone.
|
||||
-- @param DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @return #ZONE_RADIUS self
|
||||
function ZONE_RADIUS:New( ZoneName, PointVec2, Radius )
|
||||
function ZONE_RADIUS:New( ZoneName, Vec2, Radius )
|
||||
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) )
|
||||
self:F( { ZoneName, PointVec2, Radius } )
|
||||
self:F( { ZoneName, Vec2, Radius } )
|
||||
|
||||
self.Radius = Radius
|
||||
self.PointVec2 = PointVec2
|
||||
self.Vec2 = Vec2
|
||||
|
||||
return self
|
||||
end
|
||||
@ -179,7 +188,7 @@ function ZONE_RADIUS:SmokeZone( SmokeColor, Points )
|
||||
self:F2( SmokeColor )
|
||||
|
||||
local Point = {}
|
||||
local PointVec2 = self:GetPointVec2()
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
Points = Points and Points or 360
|
||||
|
||||
@ -188,8 +197,8 @@ function ZONE_RADIUS:SmokeZone( SmokeColor, Points )
|
||||
|
||||
for Angle = 0, 360, 360 / Points do
|
||||
local Radial = Angle * RadialBase / 360
|
||||
Point.x = PointVec2.x + math.cos( Radial ) * self:GetRadius()
|
||||
Point.y = PointVec2.y + math.sin( Radial ) * self:GetRadius()
|
||||
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
||||
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
||||
POINT_VEC2:New( Point.x, Point.y ):Smoke( SmokeColor )
|
||||
end
|
||||
|
||||
@ -207,7 +216,7 @@ function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth )
|
||||
self:F2( { FlareColor, Azimuth } )
|
||||
|
||||
local Point = {}
|
||||
local PointVec2 = self:GetPointVec2()
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
Points = Points and Points or 360
|
||||
|
||||
@ -216,8 +225,8 @@ function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth )
|
||||
|
||||
for Angle = 0, 360, 360 / Points do
|
||||
local Radial = Angle * RadialBase / 360
|
||||
Point.x = PointVec2.x + math.cos( Radial ) * self:GetRadius()
|
||||
Point.y = PointVec2.y + math.sin( Radial ) * self:GetRadius()
|
||||
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
||||
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
||||
POINT_VEC2:New( Point.x, Point.y ):Flare( FlareColor, Azimuth )
|
||||
end
|
||||
|
||||
@ -251,26 +260,26 @@ end
|
||||
--- Returns the location of the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @return DCSTypes#Vec2 The location of the zone.
|
||||
function ZONE_RADIUS:GetPointVec2()
|
||||
function ZONE_RADIUS:GetVec2()
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
self:T2( { self.PointVec2 } )
|
||||
self:T2( { self.Vec2 } )
|
||||
|
||||
return self.PointVec2
|
||||
return self.Vec2
|
||||
end
|
||||
|
||||
--- Sets the location of the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param DCSTypes#Vec2 PointVec2 The new location of the zone.
|
||||
-- @param DCSTypes#Vec2 Vec2 The new location of the zone.
|
||||
-- @return DCSTypes#Vec2 The new location of the zone.
|
||||
function ZONE_RADIUS:SetPointVec2( PointVec2 )
|
||||
function ZONE_RADIUS:SetPointVec2( Vec2 )
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
self.PointVec2 = PointVec2
|
||||
self.Vec2 = Vec2
|
||||
|
||||
self:T2( { self.PointVec2 } )
|
||||
self:T2( { self.Vec2 } )
|
||||
|
||||
return self.PointVec2
|
||||
return self.Vec2
|
||||
end
|
||||
|
||||
--- Returns the point of the zone.
|
||||
@ -280,9 +289,9 @@ end
|
||||
function ZONE_RADIUS:GetPointVec3( Height )
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
local PointVec2 = self:GetPointVec2()
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
local PointVec3 = { x = PointVec2.x, y = land.getHeight( self:GetPointVec2() ) + Height, z = PointVec2.y }
|
||||
local PointVec3 = { x = Vec2.x, y = land.getHeight( self:GetVec2() ) + Height, z = Vec2.y }
|
||||
|
||||
self:T2( { PointVec3 } )
|
||||
|
||||
@ -292,14 +301,14 @@ end
|
||||
|
||||
--- Returns if a location is within the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param DCSTypes#Vec2 PointVec2 The location to test.
|
||||
-- @param DCSTypes#Vec2 Vec2 The location to test.
|
||||
-- @return #boolean true if the location is within the zone.
|
||||
function ZONE_RADIUS:IsPointVec2InZone( PointVec2 )
|
||||
self:F2( PointVec2 )
|
||||
function ZONE_RADIUS:IsPointVec2InZone( Vec2 )
|
||||
self:F2( Vec2 )
|
||||
|
||||
local ZonePointVec2 = self:GetPointVec2()
|
||||
local ZoneVec2 = self:GetVec2()
|
||||
|
||||
if (( PointVec2.x - ZonePointVec2.x )^2 + ( PointVec2.y - ZonePointVec2.y ) ^2 ) ^ 0.5 <= self:GetRadius() then
|
||||
if (( Vec2.x - ZoneVec2.x )^2 + ( Vec2.y - ZoneVec2.y ) ^2 ) ^ 0.5 <= self:GetRadius() then
|
||||
return true
|
||||
end
|
||||
|
||||
@ -310,10 +319,10 @@ end
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param DCSTypes#Vec3 PointVec3 The point to test.
|
||||
-- @return #boolean true if the point is within the zone.
|
||||
function ZONE_RADIUS:IsPointVec3InZone( PointVec3 )
|
||||
self:F2( PointVec3 )
|
||||
function ZONE_RADIUS:IsPointVec3InZone( Vec3 )
|
||||
self:F2( Vec3 )
|
||||
|
||||
local InZone = self:IsPointVec2InZone( { x = PointVec3.x, y = PointVec3.z } )
|
||||
local InZone = self:IsPointVec2InZone( { x = Vec3.x, y = Vec3.z } )
|
||||
|
||||
return InZone
|
||||
end
|
||||
@ -325,11 +334,11 @@ function ZONE_RADIUS:GetRandomVec2()
|
||||
self:F( self.ZoneName )
|
||||
|
||||
local Point = {}
|
||||
local PointVec2 = self:GetPointVec2()
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
local angle = math.random() * math.pi*2;
|
||||
Point.x = PointVec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
||||
Point.y = PointVec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
||||
Point.x = Vec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
||||
Point.y = Vec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
||||
|
||||
self:T( { Point } )
|
||||
|
||||
@ -383,8 +392,8 @@ ZONE_UNIT = {
|
||||
-- @param DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @return #ZONE_UNIT self
|
||||
function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius )
|
||||
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetPointVec2(), Radius ) )
|
||||
self:F( { ZoneName, ZoneUNIT:GetPointVec2(), Radius } )
|
||||
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius ) )
|
||||
self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } )
|
||||
|
||||
self.ZoneUNIT = ZoneUNIT
|
||||
|
||||
@ -395,14 +404,14 @@ end
|
||||
--- Returns the current location of the @{Unit#UNIT}.
|
||||
-- @param #ZONE_UNIT self
|
||||
-- @return DCSTypes#Vec2 The location of the zone based on the @{Unit#UNIT}location.
|
||||
function ZONE_UNIT:GetPointVec2()
|
||||
function ZONE_UNIT:GetVec2()
|
||||
self:F( self.ZoneName )
|
||||
|
||||
local ZonePointVec2 = self.ZoneUNIT:GetPointVec2()
|
||||
local ZoneVec2 = self.ZoneUNIT:GetVec2()
|
||||
|
||||
self:T( { ZonePointVec2 } )
|
||||
self:T( { ZoneVec2 } )
|
||||
|
||||
return ZonePointVec2
|
||||
return ZoneVec2
|
||||
end
|
||||
|
||||
-- Polygons
|
||||
@ -492,10 +501,10 @@ end
|
||||
--- Returns if a location is within the zone.
|
||||
-- Source learned and taken from: https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @param DCSTypes#Vec2 PointVec2 The location to test.
|
||||
-- @param DCSTypes#Vec2 Vec2 The location to test.
|
||||
-- @return #boolean true if the location is within the zone.
|
||||
function ZONE_POLYGON_BASE:IsPointVec2InZone( PointVec2 )
|
||||
self:F2( PointVec2 )
|
||||
function ZONE_POLYGON_BASE:IsPointVec2InZone( Vec2 )
|
||||
self:F2( Vec2 )
|
||||
|
||||
local Next
|
||||
local Prev
|
||||
@ -506,8 +515,8 @@ function ZONE_POLYGON_BASE:IsPointVec2InZone( PointVec2 )
|
||||
|
||||
while Next <= #self.Polygon do
|
||||
self:T( { Next, Prev, self.Polygon[Next], self.Polygon[Prev] } )
|
||||
if ( ( ( self.Polygon[Next].y > PointVec2.y ) ~= ( self.Polygon[Prev].y > PointVec2.y ) ) and
|
||||
( PointVec2.x < ( self.Polygon[Prev].x - self.Polygon[Next].x ) * ( PointVec2.y - self.Polygon[Next].y ) / ( self.Polygon[Prev].y - self.Polygon[Next].y ) + self.Polygon[Next].x )
|
||||
if ( ( ( self.Polygon[Next].y > Vec2.y ) ~= ( self.Polygon[Prev].y > Vec2.y ) ) and
|
||||
( Vec2.x < ( self.Polygon[Prev].x - self.Polygon[Next].x ) * ( Vec2.y - self.Polygon[Next].y ) / ( self.Polygon[Prev].y - self.Polygon[Next].y ) + self.Polygon[Next].x )
|
||||
) then
|
||||
InPolygon = not InPolygon
|
||||
end
|
||||
|
||||
@ -8,7 +8,7 @@ local Client = CLIENT:FindByName( "Test SEAD" )
|
||||
local TargetSet = SET_UNIT:New():FilterPrefixes( "US Hawk SR" ):FilterStart()
|
||||
|
||||
local Task_Menu = TASK2_CLIENT_MENU:New( Client, Mission, "SEAD" )
|
||||
--local Task_Route = TASK2_ROUTE:New( Client, Mission ) -- Zone is dynamically defined in state machine
|
||||
local Task_Route = TASK2_ROUTE:New( Client, Mission ) -- The target location is dynamically defined in state machine
|
||||
local Task_Client_Sead = TASK2_SEAD:New( Client, Mission, TargetSet )
|
||||
|
||||
Task_Client_Sead:AddScore( "Destroy", "Destroyed RADAR", 25 )
|
||||
@ -19,15 +19,18 @@ local Task_Sead = STATEMACHINE:New( {
|
||||
events = {
|
||||
{ name = 'Start', from = 'None', to = 'Unassigned' },
|
||||
{ name = 'Next', from = 'Unassigned', to = 'Assigned' },
|
||||
-- { name = 'Route', from = 'Assigned', to = 'Arrived' },
|
||||
{ name = 'Next', from = 'Assigned', to = 'Success' },
|
||||
{ name = 'Failed', from = 'Assigned', to = 'Failed' },
|
||||
{ name = 'Next', from = 'Assigned', to = 'Arrived' },
|
||||
{ name = 'Next', from = 'Arrived', to = 'Success' },
|
||||
{ name = 'Fail', from = 'Assigned', to = 'Failed' },
|
||||
{ name = 'Fail', from = 'Arrived', to = 'Failed' }
|
||||
},
|
||||
subs = {
|
||||
Menu = { onstateparent = 'Unassigned', oneventparent = 'Start', fsm = Task_Menu.Fsm, event = 'Menu', returnevents = { 'Next' } },
|
||||
--Assigned = { onstateparent = 'Assigned', oneventparent = 'Assign', fsm = Task_Route.Fsm, event = 'Route' },
|
||||
Sead = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = Task_Client_Sead.Fsm, event = 'Await', returnevents = { 'Next' } }
|
||||
Route = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = Task_Route.Fsm, event = 'Route', returnevents = { 'Next' } },
|
||||
Sead = { onstateparent = 'Arrived', oneventparent = 'Next', fsm = Task_Client_Sead.Fsm, event = 'Await', returnevents = { 'Next' } }
|
||||
}
|
||||
} )
|
||||
|
||||
Task_Sead:Start()
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user