RESCUEHELO v0.9.7

- Fixed spawn bug with multiple helos.
- Adjusted default parameters.
- Changed RTB to respawn (not perfect).
- Improved documentation.
This commit is contained in:
Frank 2018-12-15 23:06:36 +01:00
parent 242151eedf
commit 1559f14f11
3 changed files with 332 additions and 130 deletions

View File

@ -1002,11 +1002,15 @@ do -- COORDINATE
function COORDINATE:WaypointAir( AltType, Type, Action, Speed, SpeedLocked, airbase, DCSTasks, description )
self:F2( { AltType, Type, Action, Speed, SpeedLocked } )
-- Defaults
-- Set alttype or "RADIO" which is AGL.
AltType=AltType or "RADIO"
-- Speedlocked by default
if SpeedLocked==nil then
SpeedLocked=true
end
-- Speed or default 500 km/h.
Speed=Speed or 500
-- Waypoint array.
@ -1015,19 +1019,26 @@ do -- COORDINATE
-- Coordinates.
RoutePoint.x = self.x
RoutePoint.y = self.z
-- Altitude.
RoutePoint.alt = self.y
RoutePoint.alt_type = AltType
-- Waypoint type.
RoutePoint.type = Type or nil
RoutePoint.action = Action or nil
-- Set speed/ETA.
-- Speed.
RoutePoint.speed = Speed/3.6
RoutePoint.speed_locked = SpeedLocked
-- ETA.
RoutePoint.ETA=nil
RoutePoint.ETA_locked = false
RoutePoint.ETA_locked = false
-- Waypoint description.
RoutePoint.name=description
-- Airbase parameters for takeoff and landing points.
if airbase then
local AirbaseID = airbase:GetID()
@ -1036,31 +1047,24 @@ do -- COORDINATE
RoutePoint.linkUnit = AirbaseID
RoutePoint.helipadId = AirbaseID
elseif AirbaseCategory == Airbase.Category.AIRDROME then
RoutePoint.airdromeId = AirbaseID
RoutePoint.airdromeId = AirbaseID
else
self:T("ERROR: Unknown airbase category in COORDINATE:WaypointAir()!")
end
end
end
self:MarkToAll(string.format("Landing waypoint at airbase %s", airbase:GetName()))
end
-- ["task"] =
-- {
-- ["id"] = "ComboTask",
-- ["params"] =
-- {
-- ["tasks"] =
-- {
-- }, -- end of ["tasks"]
-- }, -- end of ["params"]
-- }, -- end of ["task"]
-- Waypoint tasks.
RoutePoint.task = {}
RoutePoint.task.id = "ComboTask"
RoutePoint.task.params = {}
RoutePoint.task.params.tasks = DCSTasks or {}
-- Debug.
self:T({RoutePoint=RoutePoint})
-- Return waypoint.
return RoutePoint
end

View File

@ -13,7 +13,8 @@
--
-- ===
--
-- ### Author: **funkyfranky**
-- ### Author: **funkyfranky**
-- ### Contributions: Flightcontrol (@{#AI_FORMATION} class)
--
-- @module Ops.RescueHelo
-- @image MOOSE.JPG
@ -26,6 +27,7 @@
-- @field Wrapper.Unit#UNIT carrier The carrier the helo is attached to.
-- @field #string carriertype Carrier type.
-- @field #string helogroupname Name of the late activated helo template group.
-- @field #string helogroupalias Spawn alias name of the group. Necessary for multiple RESCUEHELO objects in one mission. Uses groupname plus carrier name.
-- @field Wrapper.Group#GROUP helo Helo group.
-- @field #number takeoff Takeoff type.
-- @field Wrapper.Airbase#AIRBASE airbase The airbase object acting as home base of the helo.
@ -45,6 +47,7 @@
-- @field #boolean rescuestopboat If true, stop carrier during rescue operations.
-- @field #boolean carrierstop If true, route of carrier was stopped.
-- @field #number HeloFuel0 Initial fuel of helo in percent. Necessary due to DCS bug that helo with full tank does not return fuel via API function.
-- @field #boolean rtb If true, Helo will be return to base on the next status check.
-- @extends Core.Fsm#FSM
--- Rescue Helo
@ -77,13 +80,13 @@
--
-- Once the helo is out of fuel, it will return to the carrier. When the helo lands, it will be respawned immidiately and go back on station.
--
-- If a unit crashes or a pilot ejects within a radius of 100 km from the USS Stennis, the helo will automatically fly to the crash side and
-- If a unit crashes or a pilot ejects within a radius of 30 km from the USS Stennis, the helo will automatically fly to the crash side and
-- rescue to pilot. This will take around 5 minutes. After that, the helo will return to the Stennis, land there and bring back the poor guy.
-- When this is done, the helo will go back on station.
--
-- # Fine Tuning
--
-- The implementation allows to customize quite a few settings easily
-- The implementation allows to customize quite a few settings easily.
--
-- ## Takeoff Type
--
@ -129,7 +132,22 @@
--
-- * @{#RESCUEHELO.SetAltitude}(*altitude*), where *altitude* is the altitude the helo flies at in meters. Default is 70 meters.
-- * @{#RESCUEHELO.SetOffsetX}(*distance*)}, where *distance is the distance in the direction of movement of the carrier. Default is 200 meters.
-- * @{#RESCUEHELO.SetOffsetZ}(*distance*)}, where *distance is the distance on the starboard side. Default is 200 meters.
-- * @{#RESCUEHELO.SetOffsetZ}(*distance*)}, where *distance is the distance on the starboard side. Default is 100 meters.
--
-- ## Rescue Operations
--
-- By default the rescue helo will start a rescue operation if an aircraft crashes or a pilot ejects in the vicinity of the carrier.
-- The standard "rescue zone" has a radius of 30 km around the carrier. The radius can be adjusted via the @{#RESCUEHELO.SetRescueZone}(*radius*) functions,
-- where *radius* is the radius of the zone in kilometers. If you use multiple rescue helos in the same mission, you might want to ensure that the radii
-- are not overlapping so that two helos try to rescue the same pilot. But it should not hurt either way.
--
-- Once the helo reaches the crash site, the rescue operation will last 5 minutes. This time can be changed by @{#RESCUEHELO.SetRescueDuration(*time*),
-- where *time* is the duration in minutes.
--
-- During the rescue operation, the helo will hover (orbit) over the crash site at a speed of 10 km/h. The speed can be set by @{#RESCUEHELO.SetRescueHoverSpeed}(*speed*),
-- where the *speed* is given in km/h.
--
-- If no rescue operations should be carried out by the helo, this option can be completely disabled by using @{#RESCUEHELO.SetRescueOff}().
--
-- # Finite State Machine
--
@ -164,6 +182,7 @@
-- You have the option to enable the debug mode for this class via the @{#RESCUEHELO.SetDebugModeON} function.
-- If enabled, text messages about the helo status will be displayed on screen and marks of the pattern created on the F10 map.
--
--
-- @field #RESCUEHELO
RESCUEHELO = {
ClassName = "RESCUEHELO",
@ -172,6 +191,7 @@ RESCUEHELO = {
carrier = nil,
carriertype = nil,
helogroupname = nil,
helogroupalias = nil,
helo = nil,
airbase = nil,
takeoff = nil,
@ -190,17 +210,19 @@ RESCUEHELO = {
rescuespeed = nil,
rescuestopboat = nil,
HeloFuel0 = nil,
carrierstop = false,
rtb = nil,
carrierstop = nil,
}
--- Class version.
-- @field #string version
RESCUEHELO.version="0.9.6"
RESCUEHELO.version="0.9.7"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Add messages for rescue mission.
-- TODO: Add option to stop carrier while rescue operation is in progress? Done but NOT working!
-- DONE: Write documenation.
-- DONE: Add option to deactivate the rescueing.
@ -250,7 +272,17 @@ function RESCUEHELO:New(carrierunit, helogroupname)
self:SetRescueHoverSpeed()
self:SetRescueDuration()
self:SetRescueStopBoatOff()
-- Some more.
self.rtb=false
self.carrierstop=false
--[[
BASE:TraceOnOff(true)
BASE:TraceClass("RESCUEHELO")
BASE:TraceLevel(1)
]]
-----------------------
--- FSM Transitions ---
-----------------------
@ -263,6 +295,7 @@ function RESCUEHELO:New(carrierunit, helogroupname)
self:AddTransition("Stopped", "Start", "Running")
self:AddTransition("Running", "Rescue", "Rescuing")
self:AddTransition("Running", "RTB", "Returning")
self:AddTransition("Rescuing", "RTB", "Returning")
self:AddTransition("*", "Run", "Running")
self:AddTransition("*", "Status", "*")
self:AddTransition("*", "Stop", "Stopped")
@ -301,11 +334,13 @@ function RESCUEHELO:New(carrierunit, helogroupname)
--- Triggers the FSM event "RTB" that sends the helo home.
-- @function [parent=#RESCUEHELO] RTB
-- @param #RESCUEHELO self
-- @param Wrapper.Airbase#AIRBASE airbase The airbase to return to. Default is the home base.
--- Triggers the FSM event "RTB" that sends the helo home after a delay.
-- @function [parent=#RESCUEHELO] __RTB
-- @param #RESCUEHELO self
-- @param #number delay Delay in seconds.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase to return to. Default is the home base.
--- On after "RTB" event user function. Called when a the the helo returns to its home base.
-- @function [parent=#RESCUEHELO] OnAfterRTB
@ -313,6 +348,7 @@ function RESCUEHELO:New(carrierunit, helogroupname)
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase to return to. Default is the home base.
--- Triggers the FSM event "Run".
@ -369,21 +405,22 @@ function RESCUEHELO:SetHomeBase(airbase)
return self
end
--- Set rescue zone radius. Crashed or ejected units inside this radius of the carrier will be rescued.
--- Set rescue zone radius. Crashed or ejected units inside this radius of the carrier will be rescued if possible.
-- @param #RESCUEHELO self
-- @param #number radius Radius of rescue zone in meters. Default is 100000 m = 100 km.
-- @param #number radius Radius of rescue zone in kilometers. Default is 30 km.
-- @return #RESCUEHELO self
function RESCUEHELO:SetRescueZone(radius)
self.rescuezone=ZONE_UNIT:New("Rescue Zone", self.carrier, radius or 100000)
radius=(radius or 30)*1000
self.rescuezone=ZONE_UNIT:New("Rescue Zone", self.carrier, radius)
return self
end
--- Set rescue hover speed.
-- @param #RESCUEHELO self
-- @param #number speed Speed in km/h. Default 25 km/h.
-- @param #number speed Speed in km/h. Default 10 km/h.
-- @return #RESCUEHELO self
function RESCUEHELO:SetRescueHoverSpeed(speed)
self.rescuespeed=UTILS.KmphToMps(speed or 25)
self.rescuespeed=UTILS.KmphToMps(speed or 10)
return self
end
@ -471,21 +508,21 @@ function RESCUEHELO:SetAltitude(alt)
return self
end
--- Set latitudinal offset to carrier.
--- Set offset parallel to orienation of carrier.
-- @param #RESCUEHELO self
-- @param #number distance Latitual offset distance in meters. Default 200 m.
-- @param #number distance Offset distance in meters. Default 200 m.
-- @return #RESCUEHELO self
function RESCUEHELO:SetOffsetX(distance)
self.offsetX=distance or 200
return self
end
--- Set longitudal offset to carrier.
--- Set offset perpendicular to orientation to carrier.
-- @param #RESCUEHELO self
-- @param #number distance Longitual offset distance in meters. Default 200 m.
-- @param #number distance Offset distance in meters. Default 100 m.
-- @return #RESCUEHELO self
function RESCUEHELO:SetOffsetZ(distance)
self.offsetZ=distance or 200
self.offsetZ=distance or 100
return self
end
@ -576,6 +613,13 @@ function RESCUEHELO:IsRescuing()
return self:is("Rescuing")
end
--- Check if FMS was stopped.
-- @param #RESCUEHELO self
-- @return #boolean If true, is stopped.
function RESCUEHELO:IsStopped()
return self:is("Stopped")
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- EVENT functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -587,18 +631,39 @@ function RESCUEHELO:OnEventLand(EventData)
local group=EventData.IniGroup --Wrapper.Group#GROUP
if group:IsAlive() then
-- Group name that landed.
local groupname=group:GetName()
if groupname:match(self.helogroupname) then
-- Check that it was our helo that landed.
if groupname==self.helo:GetName() then
-- Respawn the Helo.
local text=string.format("Respawning rescue helo group %s at home base.", groupname)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:T(self.lid..text)
if self:IsRescuing() then
self:T(string.format("Rescue helo %s returned from rescue operation.", groupname))
end
if self.takeoff==SPAWN.Takeoff.Air or self.respawninair then
self:E("ERROR: Rescue helo %s landed. This should not happen for Takeoff=Air or respawninair=true!", groupname)
if self:IsRescuing() then
self:T(string.format("Rescue helo %s returned from rescue operation.", groupname))
else
self:T2(string.format("WARNING: Rescue helo %s landed. This should not happen for Takeoff=Air or respawninair=true unless a rescue operation finished.", groupname))
end
-- Respawn helo at current airbase anyway.
self.helo=group:RespawnAtCurrentAirbase()
else
@ -609,6 +674,7 @@ function RESCUEHELO:OnEventLand(EventData)
-- Restart the formation.
self:__Run(10)
end
end
end
@ -686,10 +752,13 @@ function RESCUEHELO:onafterStart(From, Event, To)
self:HandleEvent(EVENTS.Ejection, self._OnEventCrashOrEject)
-- Delay before formation is started.
local delay=120
local delay=120
-- Spawn helo.
local Spawn=SPAWN:New(self.helogroupname):InitUnControlled(false)
-- Set unique alias for spawn.
self.helogroupalias=string.format("%s_%s", self.helogroupname, self.carrier:GetName())
-- Spawn helo. We need to introduce an alias in case this class is used twice. This would confuse the spawn routine.
local Spawn=SPAWN:NewWithAlias(self.helogroupname, self.helogroupalias)
-- Spawn in air or at airbase.
if self.takeoff==SPAWN.Takeoff.Air then
@ -697,11 +766,11 @@ function RESCUEHELO:onafterStart(From, Event, To)
-- Carrier heading
local hdg=self.carrier:GetHeading()
-- Spawn distance behind carrier.
-- Spawn distance in front of carrier.
local dist=UTILS.NMToMeters(0.2)
-- Coordinate behind the carrier
local Carrier=self.carrier:GetCoordinate():SetAltitude(math.min(100, self.altitude)):Translate(dist, hdg)
-- Coordinate behind the carrier. Altitude at least 100 meters for spawning because it drops down a bit.
local Carrier=self.carrier:GetCoordinate():SetAltitude(math.max(140, self.altitude)):Translate(dist, hdg)
-- Orientation of spawned group.
Spawn:InitHeading(hdg)
@ -720,6 +789,9 @@ function RESCUEHELO:onafterStart(From, Event, To)
-- Use an uncontrolled aircraft group.
self.helo=GROUP:FindByName(self.helogroupname)
-- Also set the alias just in case.
self.helogroupalias=self.helogroupname
if self.helo:IsAlive() then
-- Start uncontrolled group.
@ -770,7 +842,6 @@ function RESCUEHELO:onafterStart(From, Event, To)
-- Init status check
self:__Status(1)
end
--- On after Status event. Checks player status.
@ -791,13 +862,50 @@ function RESCUEHELO:onafterStatus(From, Event, To)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:T(self.lid..text)
-- If fuel < threshold ==> send helo to home base!
if fuel<self.lowfuel and self:IsRunning() then
self:RTB()
-- Check if helo is running and not RTBing already or rescuing.
if self:IsRunning() then
-- Check if fuel is low.
if fuel<self.lowfuel then
-- Check if spawn in air is activated.
if self.takeoff==SPAWN.Takeoff.Air or self.respawninair then
-- Check if respawn is enabled.
if self.respawn then
-- Respawn helo in air.
self.helo:Respawn(nil, true)
end
else
-- Send helo back to base.
self:RTB()
end
end
elseif self:IsRescuing() then
if self.rtb then
-- Send helo back to base.
self:RTB()
-- Switch to false.
self.rtb=false
end
end
-- Call status again in one minute.
self:__Status(-60)
-- Call status again in 30 seconds.
if not self:IsStopped() then
self:__Status(-30)
end
end
--- On after "Run" event. FSM will go to "Running" state. If formation is topped, it will be started again.
@ -832,6 +940,20 @@ function RESCUEHELO:onafterRun(From, Event, To)
end
--- Function called when a group is passing a waypoint.
--@param Wrapper.Group#GROUP group Group that passed the waypoint
--@param #RESCUEHELO rescuehelo Rescue helo object.
function RESCUEHELO._TaskRTB(group, rescuehelo)
env.info(string.format("FF Executing TaskRTB for group %s.", group:GetName()))
-- Set RTB switch so on next status update, the helo is respawned with RTB waypoints.
rescuehelo.rtb=true
-- This made DCS crash to desktop!
--rescuehelo:RTB()
end
--- On after "Rescue" event. Helo will fly to the given coordinate, orbit there for 5 minutes and then return to the carrier.
-- @param #RESCUEHELO self
-- @param #string From From state.
@ -850,17 +972,32 @@ function RESCUEHELO:onafterRescue(From, Event, To, RescueCoord)
--local RescueTask=self.helo:TaskControlled(self.helo:TaskOrbitCircle(20, 2, RescueCoord), self.helo:TaskCondition(nil, nil, nil, nil, 5*60, nil))
-- Rescue task: Orbit at crash site for 5 minutes.
-- Rescue task: Orbit at crash site for ~5 minutes at 20 meters altitude and ~10 km/h.
local RescueTask={}
RescueTask.id="ControlledTask"
RescueTask.params={}
RescueTask.params.task=self.helo:TaskOrbit(RescueCoord, 20, self.rescuespeed)
RescueTask.params.stopCondition={duration=self.rescueduration}
-- Set Waypoints.
wp[1]=self.helo:GetCoordinate():WaypointAirTurningPoint(nil, 200, {}, "Current Position")
wp[2]=RescueCoord:SetAltitude(50):WaypointAirTurningPoint(nil, 200, {RescueTask}, "Crash Site")
wp[3]=self.airbase:GetCoordinate():SetAltitude(70):WaypointAirLanding(200, self.airbase, {}, "Land at Home Base")
-- Passing waypoint taskfunction
local TaskRTB=self.helo:TaskFunction("RESCUEHELO._TaskRTB", self)
-- Rescue speed 90% of max possible.
local speed=self.helo:GetSpeedMax()*0.9
-- Set Waypoints:
-- Current position.
wp[1]=self.helo:GetCoordinate():WaypointAirTurningPoint(nil, speed, {}, "Current Position")
-- Go to crash site and hover a bit.
wp[2]=RescueCoord:SetAltitude(50):WaypointAirTurningPoint(nil, speed, {RescueTask, TaskRTB}, "Crash Site")
-- Route helo back home and respawn next status update.
wp[3]=self.airbase:GetCoordinate():SetAltitude(50):WaypointAirTurningPoint(nil, speed, {}, "RTB")
-- Unfortunately not possible reliably due to DCS bug that units dont land or just land on any nearby base.
--wp[3]=self.airbase:GetCoordinate():SetAltitude(70):WaypointAirLanding(200, self.airbase, {}, "Land at Home Base")
-- Initialize WP and route helo.
self.helo:WayPointInitialize(wp)
@ -882,61 +1019,44 @@ function RESCUEHELO:onafterRescue(From, Event, To, RescueCoord)
end
end
--- On before RTB event. Check if takeoff type is air and if so respawn the helo and deny RTB transition.
-- @param #RESCUEHELO self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @return #boolean If true, transition is allowed.
function RESCUEHELO:onbeforeRTB(From, Event, To)
-- For takeoff in air, we just respawn the helo with full fuel.
if (self.takeoff==SPAWN.Takeoff.Air or self.respawninair) and self.respawn then
-- Debug message.
local text=string.format("Respawning rescue helo group %s in air.", self.helo:GetName())
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:T(self.lid..text)
-- Respawn helo.
self.helo:InitHeading(self.helo:GetHeading())
self.helo=self.helo:Respawn(nil, true)
-- Deny transition to RTB.
return false
end
return true
end
--- On after RTB event. Send helo back to carrier.
-- @param #RESCUEHELO self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function RESCUEHELO:onafterRTB(From, Event, To)
-- @param Wrapper.Airbase#AIRBASE airbase The base to return to. Default is the home base.
function RESCUEHELO:onafterRTB(From, Event, To, airbase)
-- Debug message.
local text=string.format("Rescue helo %s is returning to airbase %s.", self.helo:GetName(), self.airbase:GetName())
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:T(self.lid..text)
-- Waypoint array.
local wp={}
-- Set landing waypoint at home base.
wp[1]=self.helo:GetCoordinate():WaypointAirTurningPoint(nil, 300, {}, "Current Position")
wp[2]=self.airbase:GetCoordinate():SetAltitude(70):WaypointAirLanding(300, self.airbase, {}, "Landing at Home Base")
-- Set airbase.
airbase=airbase or self.airbase
-- Initialize WP and route helo.
self.helo:WayPointInitialize(wp)
-- Debug message.
local text=string.format("Rescue helo %s is returning to airbase %s.", self.helo:GetName(), airbase:GetName())
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:T(self.lid..text)
-- Set task.
self.helo:Route(wp, 1)
-- Stop formation.
--[[
-- Waypoint array.
local wp={}
-- Set landing waypoint at home base.
wp[1]=self.helo:GetCoordinate():WaypointAirTurningPoint(nil, 300, {}, "Current Position")
wp[2]=self.airbase:GetCoordinate():SetAltitude(70):WaypointAirLanding(300, self.airbase, {}, "Landing at Home Base")
-- Initialize WP and route helo.
self.helo:WayPointInitialize(wp)
-- Set task.
self.helo:Route(wp, 1)
]]
-- Stop formation.
if From=="Running" then
self.formation:Stop()
end
-- Route helo back home. It is respawned! But this is the only way to ensure that it actually lands at the airbase.
self.helo:RouteRTB(airbase)
end
--- On after Stop event. Unhandle events and stop status updates.
@ -950,7 +1070,6 @@ function RESCUEHELO:onafterStop(From, Event, To)
self:UnHandleEvent(EVENTS.Ejection)
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -1477,11 +1477,12 @@ end
--
-- @param Wrapper.Group#GROUP self
-- @param #table Template (optional) The template of the Group retrieved with GROUP:GetTemplate(). If the template is not provided, the template will be retrieved of the group itself.
-- @param #boolean Reset Reset positons if TRUE.
-- @return Wrapper.Group#GROUP self
function GROUP:Respawn( Template, Reset )
if not Template then
Template = self:GetTemplate()
end
-- Given template or get old.
Template = Template or self:GetTemplate()
-- Get correct heading.
local function _Heading(course)
@ -1494,23 +1495,43 @@ function GROUP:Respawn( Template, Reset )
return h
end
-- First check if group is alive.
if self:IsAlive() then
-- Respawn zone.
local Zone = self.InitRespawnZone -- Core.Zone#ZONE
-- Zone position or current group position.
local Vec3 = Zone and Zone:GetVec3() or self:GetVec3()
-- From point of the template.
local From = { x = Template.x, y = Template.y }
-- X, Y
Template.x = Vec3.x
Template.y = Vec3.z
--Template.x = nil
--Template.y = nil
-- Debug number of units.
self:F( #Template.units )
-- Reset position etc?
if Reset == true then
-- Loop over units in group.
for UnitID, UnitData in pairs( self:GetUnits() ) do
local GroupUnit = UnitData -- Wrapper.Unit#UNIT
self:F( GroupUnit:GetName() )
self:F(GroupUnit:GetName())
if GroupUnit:IsAlive() then
self:F( "Alive" )
local GroupUnitVec3 = GroupUnit:GetVec3()
self:F("Alive")
-- Get unit position vector.
local GroupUnitVec3 = GroupUnit:GetVec3()
-- Check if respawn zone is set.
if Zone then
if self.InitRespawnRandomizePositionZone then
GroupUnitVec3 = Zone:GetRandomVec3()
@ -1523,18 +1544,38 @@ function GROUP:Respawn( Template, Reset )
end
end
-- Altitude
Template.units[UnitID].alt = self.InitRespawnHeight and self.InitRespawnHeight or GroupUnitVec3.y
Template.units[UnitID].x = ( Template.units[UnitID].x - From.x ) + GroupUnitVec3.x -- Keep the original x position of the template and translate to the new position.
Template.units[UnitID].y = ( Template.units[UnitID].y - From.y ) + GroupUnitVec3.z -- Keep the original z position of the template and translate to the new position.
-- Unit position. Why not simply take the current positon?
if Zone then
Template.units[UnitID].x = ( Template.units[UnitID].x - From.x ) + GroupUnitVec3.x -- Keep the original x position of the template and translate to the new position.
Template.units[UnitID].y = ( Template.units[UnitID].y - From.y ) + GroupUnitVec3.z -- Keep the original z position of the template and translate to the new position.
else
Template.units[UnitID].x=GroupUnitVec3.x
Template.units[UnitID].y=GroupUnitVec3.z
end
-- Set heading.
Template.units[UnitID].heading = _Heading(self.InitRespawnHeading and self.InitRespawnHeading or GroupUnit:GetHeading())
Template.units[UnitID].psi = -Template.units[UnitID].heading
-- Debug.
self:F( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
end
end
else
else -- Reset=false or nil
-- Loop over template units.
for UnitID, TemplateUnitData in pairs( Template.units ) do
self:F( "Reset" )
-- Position from template.
local GroupUnitVec3 = { x = TemplateUnitData.x, y = TemplateUnitData.alt, z = TemplateUnitData.y }
-- Respawn zone position.
if Zone then
if self.InitRespawnRandomizePositionZone then
GroupUnitVec3 = Zone:GetRandomVec3()
@ -1547,23 +1588,36 @@ function GROUP:Respawn( Template, Reset )
end
end
-- Set altitude.
Template.units[UnitID].alt = self.InitRespawnHeight and self.InitRespawnHeight or GroupUnitVec3.y
-- Unit position.
Template.units[UnitID].x = ( Template.units[UnitID].x - From.x ) + GroupUnitVec3.x -- Keep the original x position of the template and translate to the new position.
Template.units[UnitID].y = ( Template.units[UnitID].y - From.y ) + GroupUnitVec3.z -- Keep the original z position of the template and translate to the new position.
-- Heading
Template.units[UnitID].heading = self.InitRespawnHeading and self.InitRespawnHeading or TemplateUnitData.heading
-- Debug.
self:F( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
end
end
end
self:Destroy()
_DATABASE:Spawn( Template )
-- Destroy old group. Dont trigger any dead/crash events since this is a respawn.
self:Destroy(false)
self:E({Template=Template})
-- Spawn new group.
_DATABASE:Spawn(Template)
-- Reset events.
self:ResetEvents()
return self
end
@ -1664,6 +1718,7 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) --
-- Destroy old group.
self:Destroy(false)
-- Spawn new group.
_DATABASE:Spawn( SpawnTemplate )
-- Reset events.
@ -1812,8 +1867,8 @@ do -- Route methods
--
-- @param #GROUP self
-- @param Wrapper.Airbase#AIRBASE RTBAirbase (optional) The @{Wrapper.Airbase} to return to. If blank, the controllable will return to the nearest friendly airbase.
-- @param #number Speed (optional) The Speed, if no Speed is given, the maximum Speed of the first unit is selected.
-- @return #GROUP
-- @param #number Speed (optional) The Speed, if no Speed is given, 80% of maximum Speed of the group is selected.
-- @return #GROUP self
function GROUP:RouteRTB( RTBAirbase, Speed )
self:F( { RTBAirbase:GetName(), Speed } )
@ -1823,17 +1878,19 @@ do -- Route methods
if RTBAirbase then
-- If speed is not given take 80% of max speed.
local Speed=Speed or self:GetSpeedMax()*0.8
--[[
local GroupPoint = self:GetVec2()
local GroupVelocity = self:GetUnit(1):GetDesc().speedMax
local GroupVelocity = self:GetUnit(1):GetDesc().speedMax
local PointFrom = {}
PointFrom.x = GroupPoint.x
PointFrom.y = GroupPoint.y
PointFrom.type = "Turning Point"
PointFrom.action = "Turning Point"
PointFrom.speed = GroupVelocity
local PointTo = {}
local AirbasePointVec2 = RTBAirbase:GetPointVec2()
local AirbaseAirPoint = AirbasePointVec2:WaypointAir(
@ -1844,21 +1901,43 @@ do -- Route methods
)
AirbaseAirPoint["airdromeId"] = RTBAirbase:GetID()
AirbaseAirPoint["speed_locked"] = true,
AirbaseAirPoint["speed_locked"] = true
]]
-- Curent (from) waypoint.
local coord=self:GetCoordinate()
local PointFrom=coord:WaypointAirTurningPoint(nil, Speed)
-- Airbase coordinate.
--local PointAirbase=RTBAirbase:GetCoordinate():SetAltitude(coord.y):WaypointAirTurningPoint(nil ,Speed)
-- Landing waypoint. More general than prev version since it should also work with FAPRS and ships.
local PointLanding=RTBAirbase:GetCoordinate():WaypointAirLanding(Speed, RTBAirbase)
-- Waypoint table.
local Points={PointFrom, PointLanding}
--local Points={PointFrom, PointAirbase, PointLanding}
self:F(AirbaseAirPoint )
local Points = { PointFrom, AirbaseAirPoint }
self:T3( Points )
-- Debug info.
self:T3(Points)
local Template = self:GetTemplate()
Template.route.points = Points
self:Respawn( Template )
--self:Route( Points )
-- Get group template.
local Template=self:GetTemplate()
-- Set route points.
Template.route.points=Points
-- Respawn the group.
self:Respawn(Template, true)
-- Route the group or this will not work.
self:Route(Points)
else
-- Clear all tasks.
self:ClearTasks()
end
end