ARTY v0.7

Added "NewTarget" event.
Improved task function for waypoints
Removed TargetQueue scheduler.
This commit is contained in:
funkyfranky 2018-05-03 23:42:03 +02:00
parent 531c1d7e90
commit 4fccfa38d4
2 changed files with 166 additions and 63 deletions

View File

@ -682,15 +682,15 @@ do -- FSM
end end
if execute then if execute then
self:_call_handler("onafter", EventName, Params, EventName )
self:_call_handler("OnAfter", EventName, Params, EventName )
-- only execute the call if the From state is not equal to the To state! Otherwise this function should never execute! -- only execute the call if the From state is not equal to the To state! Otherwise this function should never execute!
--if from ~= to then --if from ~= to then
self:_call_handler("onenter", To, Params, EventName ) self:_call_handler("onenter", To, Params, EventName )
self:_call_handler("OnEnter", To, Params, EventName ) self:_call_handler("OnEnter", To, Params, EventName )
--end --end
self:_call_handler("onafter", EventName, Params, EventName )
self:_call_handler("OnAfter", EventName, Params, EventName )
self:_call_handler("onstate", "change", Params, EventName ) self:_call_handler("onstate", "change", Params, EventName )
end end
else else

View File

@ -3,7 +3,7 @@
-- --
-- === -- ===
-- --
-- ![Banner Image](..\Presentations\ARTY\Artillery_Main.png) -- ![Banner Image](..\Presentations\ARTY\ARTY_Main.png)
-- --
-- ==== -- ====
-- --
@ -50,8 +50,6 @@
-- @field #number Nmissiles0 Initial amount of missiles of the whole group. -- @field #number Nmissiles0 Initial amount of missiles of the whole group.
-- @field #number FullAmmo Full amount of all ammunition taking the number of alive units into account. -- @field #number FullAmmo Full amount of all ammunition taking the number of alive units into account.
-- @field Core.Scheduler#SCHEDULER scheduler Scheduler object handling various timed functions. -- @field Core.Scheduler#SCHEDULER scheduler Scheduler object handling various timed functions.
-- @field #number SchedIDTargetQueue Scheduler ID for updating the target queue and calling OpenFire event.
-- @field #number TargetQueueUpdate Interval between updates of the target queue.
-- @field #number SchedIDCheckRearmed Scheduler ID responsible for checking whether rearming of the ARTY group is complete. -- @field #number SchedIDCheckRearmed Scheduler ID responsible for checking whether rearming of the ARTY group is complete.
-- @field #number SchedIDCheckShooting Scheduler ID for checking whether a group startet firing within a certain time after the fire at point task was assigned. -- @field #number SchedIDCheckShooting Scheduler ID for checking whether a group startet firing within a certain time after the fire at point task was assigned.
-- @field #number WaitForShotTime Max time in seconds to wait until fist shot event occurs after target is assigned. If time is passed without shot, the target is deleted. Default is 300 seconds. -- @field #number WaitForShotTime Max time in seconds to wait until fist shot event occurs after target is assigned. If time is passed without shot, the target is deleted. Default is 300 seconds.
@ -87,7 +85,7 @@
-- --
-- ## The ARTY Process -- ## The ARTY Process
-- --
-- ![Process](..\Presentations\ARTY\Artillery_Process.png) -- ![Process](..\Presentations\ARTY\ARTY_Process.png)
-- --
-- After the FMS process is started the ARTY group will be in the state **CombatReady**. Once a target is assigned the **OpenFire** event will be triggered and the group starts -- After the FMS process is started the ARTY group will be in the state **CombatReady**. Once a target is assigned the **OpenFire** event will be triggered and the group starts
-- firing. At this point the group in in the state **Firing**. -- firing. At this point the group in in the state **Firing**.
@ -204,7 +202,6 @@
-- * @{#ARTY.SetMinFiringRange}(*range*) defines the minimum firing range. Targets closer than this distance are not engaged. -- * @{#ARTY.SetMinFiringRange}(*range*) defines the minimum firing range. Targets closer than this distance are not engaged.
-- * @{#ARTY.SetRearmingUnit}(*unit*) sets the unit resposible for rearming of the ARTY group once it is out of ammo. -- * @{#ARTY.SetRearmingUnit}(*unit*) sets the unit resposible for rearming of the ARTY group once it is out of ammo.
-- * @{#ARTY.SetReportON}() and @{#ARTY.SetReportOFF}() can be used to enable/disable status reports of the ARTY group send to all coalition members. -- * @{#ARTY.SetReportON}() and @{#ARTY.SetReportOFF}() can be used to enable/disable status reports of the ARTY group send to all coalition members.
-- * @{#ARTY.SetTargetQueueUpdateInterval}(*interval*) sets the interval (in seconds) at which the target queue is updated. Default is every 5 seconds.
-- * @{#ARTY.SetWaitForShotTime}(*waittime*) sets the time after which a target is deleted from the queue if no shooting event occured after the target engagement started. -- * @{#ARTY.SetWaitForShotTime}(*waittime*) sets the time after which a target is deleted from the queue if no shooting event occured after the target engagement started.
-- Default is 300 seconds. Note that this can for example happen, when the assigned target is out of range. -- Default is 300 seconds. Note that this can for example happen, when the assigned target is out of range.
-- * @{#ARTY.SetDebugON}() and @{#ARTY.SetDebugOFF}() can be used to enable/disable the debug mode. -- * @{#ARTY.SetDebugON}() and @{#ARTY.SetDebugOFF}() can be used to enable/disable the debug mode.
@ -233,8 +230,6 @@ ARTY={
Nmissiles0=0, Nmissiles0=0,
FullAmmo=0, FullAmmo=0,
scheduler=nil, scheduler=nil,
SchedIDTargetQueue=nil,
TargetQueueUpdate=5,
SchedIDCheckRearmed=nil, SchedIDCheckRearmed=nil,
SchedIDCheckShooting=nil, SchedIDCheckShooting=nil,
WaitForShotTime=300, WaitForShotTime=300,
@ -274,7 +269,7 @@ ARTY.id="ARTY | "
--- Arty script version. --- Arty script version.
-- @field #number version -- @field #number version
ARTY.version="0.6.0" ARTY.version="0.7.0"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -340,8 +335,8 @@ function ARTY:New(group)
self:T3({id=id, desc=desc}) self:T3({id=id, desc=desc})
end end
-- Set speed to maximum in km/h. -- Set speed to 1/2 of maximum in km/h.
self.Speed=self.DCSdesc.speedMax*3.6 self.Speed=self.DCSdesc.speedMax*3.6 * 0.5
-- Displayed name (similar to type name below) -- Displayed name (similar to type name below)
self.DisplayName=self.DCSdesc.displayName self.DisplayName=self.DCSdesc.displayName
@ -365,6 +360,7 @@ function ARTY:New(group)
self:AddTransition("Rearming", "Rearmed", "CombatReady") self:AddTransition("Rearming", "Rearmed", "CombatReady")
self:AddTransition("CombatReady", "Move", "Moving") self:AddTransition("CombatReady", "Move", "Moving")
self:AddTransition("Moving", "Arrived", "CombatReady") self:AddTransition("Moving", "Arrived", "CombatReady")
self:AddTransition("*", "NewTarget", "*")
self:AddTransition("*", "Dead", "*") self:AddTransition("*", "Dead", "*")
--- User function for OnBefore "OpenFire" event. --- User function for OnBefore "OpenFire" event.
@ -582,6 +578,9 @@ function ARTY:AssignTargetCoord(coord, prio, radius, nshells, maxengage, time, w
-- Debug info. -- Debug info.
self:T(ARTY.id..string.format("Added target %s, prio=%d, radius=%d, nshells=%d, maxengage=%d, time=%s, weapontype=%d", name, prio, radius, nshells, maxengage, tostring(_clock), weapontype)) self:T(ARTY.id..string.format("Added target %s, prio=%d, radius=%d, nshells=%d, maxengage=%d, time=%s, weapontype=%d", name, prio, radius, nshells, maxengage, tostring(_clock), weapontype))
-- Trigger new target event.
self:NewTarget(_target)
end end
@ -649,14 +648,6 @@ function ARTY:SetDebugOFF()
self.Debug=false self.Debug=false
end end
--- Set target queue update time interval.
-- @param #ARTY self
-- @param #number interval Time interval in seconds. Default is 5 seconds.
function ARTY:SetTargetQueueUpdateInterval(interval)
self:F2({interval=interval})
self.TargetQueueUpdate=interval or 5
end
--- Delete target from target list. --- Delete target from target list.
-- @param #ARTY self -- @param #ARTY self
-- @param #string name Name of the target. -- @param #string name Name of the target.
@ -715,6 +706,17 @@ end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Before "Start" event. Initialized ROE and alarm state. Starts the event handler.
-- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function ARTY:onbeforeStart(Controllable, From, Event, To)
self:_EventFromTo("onbeforeStart", Event, From, To)
env.info("FF: onbeforeStart")
end
--- After "Start" event. Initialized ROE and alarm state. Starts the event handler. --- After "Start" event. Initialized ROE and alarm state. Starts the event handler.
-- @param #ARTY self -- @param #ARTY self
@ -779,9 +781,6 @@ function ARTY:onafterStart(Controllable, From, Event, To)
self:HandleEvent(EVENTS.Shot, self._OnEventShot) self:HandleEvent(EVENTS.Shot, self._OnEventShot)
self:HandleEvent(EVENTS.Dead, self._OnEventDead) self:HandleEvent(EVENTS.Dead, self._OnEventDead)
-- Start scheduler to monitor task queue.
self.SchedIDTargetQueue=self.scheduler:Schedule(self, ARTY._TargetQueue, {self}, 5, self.TargetQueueUpdate)
-- Start scheduler to monitor if ARTY group started firing within a certain time. -- Start scheduler to monitor if ARTY group started firing within a certain time.
self.SchedIDCheckShooting=self.scheduler:Schedule(self, ARTY._CheckShootingStarted, {self}, 60, 60) self.SchedIDCheckShooting=self.scheduler:Schedule(self, ARTY._CheckShootingStarted, {self}, 60, 60)
@ -950,6 +949,23 @@ end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- After "NewTarget" event.
-- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #table target Array holding the target info.
-- @return #boolean If true, proceed to onafterOpenfire.
function ARTY:onafterNewTarget(Controllable, From, Event, To, target)
self:_EventFromTo("onafterNewTarget", Event, From, To)
-- Debug message.
local text=string.format("Adding new target %s.", target.name)
MESSAGE:New(text, 30):ToAllIf(self.Debug)
self:T(ARTY.id..text)
end
--- Before "OpenFire" event. Checks if group already has a target. Checks for valid min/max range and removes the target if necessary. --- Before "OpenFire" event. Checks if group already has a target. Checks for valid min/max range and removes the target if necessary.
-- @param #ARTY self -- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group. -- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
@ -973,6 +989,7 @@ function ARTY:onbeforeOpenFire(Controllable, From, Event, To, target)
return true return true
end end
-- Check that group has no current target already. -- Check that group has no current target already.
if self.currentTarget then if self.currentTarget then
-- Debug info. -- Debug info.
@ -1095,6 +1112,36 @@ function ARTY:onafterCeaseFire(Controllable, From, Event, To, target)
end end
--- Enter "CombatReady" state. Route the group back if necessary.
-- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function ARTY:onenterCombatReady(Controllable, From, Event, To)
env.info(string.format("FF: onenterComabReady, from=%s, event=%s, to=%s", From, Event, To))
if From=="Rearming" and Event=="Rearmed" then
env.info("FF: Comabatready after Rearmed")
-- Distance to initial position.
local dist=Controllable:GetCoordinate():Get2DDistance(self.InitialCoord)
if dist>100 then
-- Route group back to its original position, when rearming was at another place.
self:T(ARTY.id..string.format("%s is routed back to its initial position. Distance = %d m.", Controllable:GetName(), dist))
self:__Move(30, self.InitialCoord, true)
end
else
-- Update target queue and open fire.
env.info("FF: Comabatready ==> _openfireontarget.")
self:_openfireontarget()
end
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Before "Winchester" event. Cease fire on current target. --- Before "Winchester" event. Cease fire on current target.
-- @param #ARTY self -- @param #ARTY self
@ -1105,8 +1152,6 @@ end
-- @return #boolean If true, proceed to onafterWinchester. -- @return #boolean If true, proceed to onafterWinchester.
function ARTY:onbeforeWinchester(Controllable, From, Event, To) function ARTY:onbeforeWinchester(Controllable, From, Event, To)
return true return true
end end
@ -1141,6 +1186,7 @@ end
function ARTY:onbeforeRearm(Controllable, From, Event, To) function ARTY:onbeforeRearm(Controllable, From, Event, To)
self:_EventFromTo("onbeforeRearm", Event, From, To) self:_EventFromTo("onbeforeRearm", Event, From, To)
-- Check if a reaming unit or rearming place was specified.
if self.RearmingUnit and self.RearmingUnit:IsAlive() then if self.RearmingUnit and self.RearmingUnit:IsAlive() then
return true return true
elseif self.RearmingPlaceCoord then elseif self.RearmingPlaceCoord then
@ -1162,7 +1208,9 @@ function ARTY:onafterRearm(Controllable, From, Event, To)
-- Coordinate of ARTY unit. -- Coordinate of ARTY unit.
local coordARTY=self.Controllable:GetCoordinate() local coordARTY=self.Controllable:GetCoordinate()
local coordRARM
-- Coordinate of rearming unit.
local coordRARM=nil
if self.RearmingUnit then if self.RearmingUnit then
-- Coordinate of the rearming unit. -- Coordinate of the rearming unit.
coordRARM=self.RearmingUnit:GetCoordinate() coordRARM=self.RearmingUnit:GetCoordinate()
@ -1172,22 +1220,28 @@ function ARTY:onafterRearm(Controllable, From, Event, To)
if self.RearmingUnit and self.RearmingPlaceCoord and self.Speed>0 then if self.RearmingUnit and self.RearmingPlaceCoord and self.Speed>0 then
-- Rearming unit and ARTY group meet at rearming place. -- CASE 1: Rearming unit and ARTY group meet at rearming place.
-- Distances.
local dA=coordARTY:Get2DDistance(self.RearmingPlaceCoord) local dA=coordARTY:Get2DDistance(self.RearmingPlaceCoord)
local dR=coordRARM:Get2DDistance(self.RearmingPlaceCoord) local dR=coordRARM:Get2DDistance(self.RearmingPlaceCoord)
-- Route ARTY group to rearming place. -- Route ARTY group to rearming place.
if dA>100 then if dA>100 then
self.Controllable:RouteGroundOnRoad(self.RearmingPlaceCoord, self.Speed, 1) --self.Controllable:RouteGroundOnRoad(self.RearmingPlaceCoord, self.Speed, 1)
self:_Move(self.Controllable, self.RearmingPlaceCoord, self.Speed, true)
end end
-- Route Rearming unit to rearming place -- Route Rearming unit to rearming place
if dR>100 then if dR>100 then
self.RearmingUnit:RouteGroundOnRoad(self.RearmingPlaceCoord, 50, 1) self.RearmingUnit:RouteGroundOnRoad(self.RearmingPlaceCoord, 50, 1)
--self:_Move(self.RearmingUnit, self.RearmingPlaceCoord, 50, true)
end end
elseif self.RearmingUnit then elseif self.RearmingUnit then
-- CASE 2: Rearming unit drives to ARTY group.
-- Send message. -- Send message.
local text=string.format("%s, %s, request rearming.", Controllable:GetName(), self.RearmingUnit:GetName()) local text=string.format("%s, %s, request rearming.", Controllable:GetName(), self.RearmingUnit:GetName())
self:T(ARTY.id..text) self:T(ARTY.id..text)
@ -1199,12 +1253,26 @@ function ARTY:onafterRearm(Controllable, From, Event, To)
-- If distance is larger than 100 m, the Rearming unit is routed to the ARTY group. -- If distance is larger than 100 m, the Rearming unit is routed to the ARTY group.
if distance > 100 then if distance > 100 then
-- Random point 20-100 m away from unit. -- Random point 20-100 m away from unit.
local vec2=coord:GetRandomVec2InRadius(20, 100) local vec2=coordARTY:GetRandomVec2InRadius(20, 100)
local pops=COORDINATE:NewFromVec2(vec2) local pops=COORDINATE:NewFromVec2(vec2)
-- Route unit to ARTY group. -- Route unit to ARTY group.
self.RearmingUnit:RouteGroundOnRoad(pops, 50, 1) self.RearmingUnit:RouteGroundOnRoad(pops, 50, 1)
end end
elseif self.RearmingPlaceCoord then
-- CASE 3: ARTY drives to rearming place.
-- Distance.
local dA=coordARTY:Get2DDistance(self.RearmingPlaceCoord)
-- Route ARTY group to rearming place.
if dA>100 then
--self.Controllable:RouteGroundOnRoad(self.RearmingPlaceCoord, self.Speed, 1)
self:_Move(self.Controllable, self.RearmingPlaceCoord, self.Speed, true)
end
end end
-- Start scheduler to monitor ammo count until rearming is complete. -- Start scheduler to monitor ammo count until rearming is complete.
@ -1325,14 +1393,30 @@ function ARTY:onafterMove(Controllable, From, Event, To, ToCoord, OnRoad)
self.Controllable:OptionROEHoldFire() self.Controllable:OptionROEHoldFire()
-- Route group to coodinate. -- Route group to coodinate.
if OnRoad then self:_Move(self.Controllable, ToCoord, self.Speed, OnRoad)
self.Controllable:RouteGroundOnRoad(ToCoord, self.Speed, 1)
else
self.Controllable:RouteGroundTo(ToCoord, self.Speed, "Vee", 1)
end
end end
--- After "Arrived" event. Group has reached its destination.
-- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function ARTY:onafterArrived(Controllable, From, Event, To)
self:_EventFromTo("onafterArrived", Event, From, To)
-- Set alarm state to auto.
self.Controllable:OptionAlarmStateAuto()
-- Send message
local text=string.format("%s, arrived at destination.", Controllable:GetName())
self:T(ARTY.id..text)
MESSAGE:New(text, 10):ToCoalitionIf(Controllable:GetCoalition(), self.report or self.Debug)
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- After "Dead" event, when a unit has died. When all units of a group are dead trigger "Stop" event. --- After "Dead" event, when a unit has died. When all units of a group are dead trigger "Stop" event.
@ -1398,9 +1482,6 @@ function ARTY:onafterStop(Controllable, From, Event, To)
-- Remove all targets. -- Remove all targets.
--self:RemoveAllTargets() --self:RemoveAllTargets()
-- Stop schedulers. -- Stop schedulers.
if self.SchedIDTargetQueue then
self.scheduler:Stop(self.SchedIDTargetQueue)
end
if self.SchedIDCheckShooting then if self.SchedIDCheckShooting then
self.scheduler:Stop(self.SchedIDCheckShooting) self.scheduler:Stop(self.SchedIDCheckShooting)
end end
@ -1443,9 +1524,9 @@ function ARTY:_FireAtCoord(coord, radius, nshells, weapontype)
end end
--- Go through queue of assigned tasks. --- Go through queue of assigned tasks and trigger OpenFire event.
-- @param #ARTY self -- @param #ARTY self
function ARTY:_TargetQueue() function ARTY:_openfireontarget()
self:F2() self:F2()
-- Debug info -- Debug info
@ -1453,7 +1534,7 @@ function ARTY:_TargetQueue()
-- No targets assigned at the moment. -- No targets assigned at the moment.
if #self.targets==0 then if #self.targets==0 then
self:T3(ARTY.id..string.format("Group %s, no targets assigned at the moment. No need for _TargetQueue.", self.Controllable:GetName())) self:T3(ARTY.id..string.format("Group %s, no targets assigned at the moment. No need for _OpenFire.", self.Controllable:GetName()))
return return
end end
@ -1471,7 +1552,7 @@ function ARTY:_TargetQueue()
self:T(ARTY.id..string.format("Engaging timed target %s. Prio=%d, engaged=%d, time=%s, tnow=%s",_target.name,_target.prio,_target.engaged,_clock,_Cnow)) self:T(ARTY.id..string.format("Engaging timed target %s. Prio=%d, engaged=%d, time=%s, tnow=%s",_target.name,_target.prio,_target.engaged,_clock,_Cnow))
-- Call OpenFire event. -- Call OpenFire event.
self:OpenFire(_target) self:__OpenFire(1, _target)
end end
end end
@ -1491,9 +1572,8 @@ function ARTY:_TargetQueue()
self:T(ARTY.id..string.format("Engaging target %s. Prio = %d, engaged = %d", _target.name, _target.prio, _target.engaged)) self:T(ARTY.id..string.format("Engaging target %s. Prio = %d, engaged = %d", _target.name, _target.prio, _target.engaged))
-- Call OpenFire event. -- Call OpenFire event.
self:OpenFire(_target) self:__OpenFire(1, _target)
break
end end
end end
@ -1548,8 +1628,11 @@ end
--- Get the number of shells a unit or group currently has. For a group the ammo count of all units is summed up. --- Get the number of shells a unit or group currently has. For a group the ammo count of all units is summed up.
-- @param #ARTY self -- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE controllable -- @param Wrapper.Controllable#CONTROLLABLE controllable Controllable for which the ammo is counted.
-- @return Number of ALL shells left from the whole group. -- @return #number Total amount of ammo the whole group has left.
-- @return #number Number of shells the group has left.
-- @return #number Number of rockets the group has left.
-- @return #number Number of missiles the group has left.
function ARTY:_GetAmmo(controllable) function ARTY:_GetAmmo(controllable)
self:F2(controllable) self:F2(controllable)
@ -1570,7 +1653,7 @@ function ARTY:_GetAmmo(controllable)
if unit and unit:IsAlive() then if unit and unit:IsAlive() then
local ammotable=unit:GetAmmo() local ammotable=unit:GetAmmo()
self:T({ammotable=ammotable}) self:T2({ammotable=ammotable})
local name=unit:GetName() local name=unit:GetName()
@ -1768,6 +1851,7 @@ end
-- @param #number tnumber Number of weapon type ARTY.WeaponType.XXX -- @param #number tnumber Number of weapon type ARTY.WeaponType.XXX
-- @return #number tnumber of weapon type. -- @return #number tnumber of weapon type.
function ARTY:_WeaponTypeName(tnumber) function ARTY:_WeaponTypeName(tnumber)
self:F2(tnumber)
local name="unknown" local name="unknown"
if tnumber==ARTY.WeaponType.Auto then if tnumber==ARTY.WeaponType.Auto then
name="Auto (Cannon, Rockets, Missiles)" name="Auto (Cannon, Rockets, Missiles)"
@ -1823,7 +1907,6 @@ function ARTY:_SecondsToClock(seconds)
if seconds==nil then if seconds==nil then
return nil return nil
--return "00:00:00"
end end
-- Seconds -- Seconds
@ -1833,14 +1916,13 @@ function ARTY:_SecondsToClock(seconds)
local _seconds=seconds%(60*60*24) local _seconds=seconds%(60*60*24)
if seconds <= 0 then if seconds <= 0 then
return "00:00:00" return nil
else else
local hours = string.format("%02.f", math.floor(_seconds/3600)) local hours = string.format("%02.f", math.floor(_seconds/3600))
local mins = string.format("%02.f", math.floor(_seconds/60 - (hours*60))) local mins = string.format("%02.f", math.floor(_seconds/60 - (hours*60)))
local secs = string.format("%02.f", math.floor(_seconds - hours*3600 - mins *60)) local secs = string.format("%02.f", math.floor(_seconds - hours*3600 - mins *60))
local days = string.format("%d", seconds/(60*60*24)) local days = string.format("%d", seconds/(60*60*24))
return hours..":"..mins..":"..secs.."+"..days return hours..":"..mins..":"..secs.."+"..days
--return hours, mins, secs
end end
end end
@ -1908,7 +1990,6 @@ function ARTY:_Move(group, ToCoord, Speed, OnRoad)
-- Current coordinates of group. -- Current coordinates of group.
local cpini=group:GetCoordinate() local cpini=group:GetCoordinate()
cpini:SmokeWhite()
-- Distance between current and final point. -- Distance between current and final point.
local dist=cpini:Get2DDistance(ToCoord) local dist=cpini:Get2DDistance(ToCoord)
@ -1916,24 +1997,46 @@ function ARTY:_Move(group, ToCoord, Speed, OnRoad)
-- Waypoint and task arrays. -- Waypoint and task arrays.
local path={} local path={}
local task={} local task={}
-- First waypoint is the current position of the group. -- First waypoint is the current position of the group.
path[#path+1]=cpini:WaypointGround(Speed, formation) path[#path+1]=cpini:WaypointGround(Speed, formation)
task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, 0, false) task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false)
-- Route group on road if requested.
if OnRoad then
--path[#path+1]=cpini:GetClosestPointToRoad():WaypointGround(Speed, "On road")
--task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false)
local _first=cpini:GetClosestPointToRoad()
local _last=ToCoord:GetClosestPointToRoad()
local _onroad=_first:GetPathOnRoad(_last)
-- Points on road.
for i=1,#_onroad do
path[#path+1]=_onroad[i]:WaypointGround(Speed, "On road")
task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false)
end
--path[#path+1]=ToCoord:GetClosestPointToRoad():WaypointGround(Speed, "On road")
--task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false)
end
-- Last waypoint at ToCoord.
path[#path+1]=ToCoord:WaypointGround(Speed, formation) path[#path+1]=ToCoord:WaypointGround(Speed, formation)
task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, 1, true) task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, true)
-- Init waypoints of the group. -- Init waypoints of the group.
local Waypoints={} local Waypoints={}
-- New points are added to the default route. -- New points are added to the default route.
for i,p in ipairs(path) do for i=1,#path do
table.insert(Waypoints, i, path[i]) table.insert(Waypoints, i, path[i])
end end
-- Set task for all waypoints. -- Set task for all waypoints.
for i,wp in ipairs(Waypoints) do for i=1,#Waypoints do
group:SetTaskWaypoint(Waypoints[i], task[i]) group:SetTaskWaypoint(Waypoints[i], task[i])
end end
@ -1952,15 +2055,15 @@ function ARTY._PassingWaypoint(group, arty, i, final)
-- Debug message. -- Debug message.
local text=string.format("Group %s passing waypoint %d (final=%s)", group:GetName(), i, tostring(final)) local text=string.format("Group %s passing waypoint %d (final=%s)", group:GetName(), i, tostring(final))
local pos=group:GetCoordinate() --local pos=group:GetCoordinate()
local MarkerID=pos:MarkToAll(string.format("Reached Waypoint %d of group %s", i, group:GetName())) --local MarkerID=pos:MarkToAll(string.format("Reached Waypoint %d of group %s", i, group:GetName()))
pos:SmokeRed() --pos:SmokeRed()
MESSAGE:New(text,10):ToAll() MESSAGE:New(text,10):ToAll()
env.info(ARTY.id..text) env.info(ARTY.id..text)
-- Move --> Moving --> Arrived --> CombatReady. -- Move --> Moving --> Arrived --> CombatReady.
if final then if final and arty.Controllable:GetName()==group:GetName() then
arty:Arrived() arty:Arrived()
end end