From d1aa5d5de3768501e170ab23dab16749695c3d3a Mon Sep 17 00:00:00 2001 From: funkyfranky Date: Mon, 20 Aug 2018 00:08:19 +0200 Subject: [PATCH] Warehouse v0.2.2 --- Moose Development/Moose/Core/Database.lua | 4 +- Moose Development/Moose/Core/Point.lua | 1 + .../Moose/Functional/Warehouse.lua | 400 ++++++++++-------- Moose Development/Moose/Wrapper/Group.lua | 26 +- 4 files changed, 229 insertions(+), 202 deletions(-) diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 3b0fb0337..85e78482a 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -533,8 +533,8 @@ end -- SpawnCountryID, SpawnCategoryID -- This method is used by the SPAWN class. -- @param #DATABASE self --- @param #table SpawnTemplate --- @return #DATABASE self +-- @param #table SpawnTemplate Template of the group to spawn. +-- @return Wrapper.Group#GROUP Spawned group. function DATABASE:Spawn( SpawnTemplate ) self:F( SpawnTemplate.name ) diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index b67ed1bef..c899a48c6 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -1028,6 +1028,7 @@ do -- COORDINATE RoutePoint.task.params = {} RoutePoint.task.params.tasks = DCSTasks or {} + self:E({RoutePoint=RoutePoint}) return RoutePoint end diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index 70375574b..a602549a3 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -140,12 +140,11 @@ WAREHOUSE = { --- Item of the warehouse pending queue table. -- @type WAREHOUSE.Pendingitem -- @extends #WAREHOUSE.Queueitem --- @field #table cargoassets Table of assets to be delivered. Each element of the table is a @{#WAREHOUSE.Stockitem}. +-- @field #table assets Table of assets - cargo or transport. Each element of the table is a @{#WAREHOUSE.Stockitem}. -- @field Core.Set#SET_GROUP cargogroupset Set of cargo groups do be delivered. -- @field #number ndelivered Number of groups delivered to destination. -- @field #number cargoattribute Attribute of cargo assets of type @{#WAREHOUSE.Attribute}. -- @field #number cargocategory Category of cargo assets of type @{#WAREHOUSE.Category}. --- @field #table transportassets Table of assets to be delivered. Each element of the table is a @{#WAREHOUSE.Stockitem}. -- @field Core.Set#SET_GROUP transportgroupset Set of cargo transport groups. -- @field #number transportattribute Attribute of transport assets of type @{#WAREHOUSE.Attribute}. -- @field #number transportcategory Category of transport assets of type @{#WAREHOUSE.Category}. @@ -196,7 +195,7 @@ WAREHOUSE.TransportType = { --- Warehouse class version. -- @field #string version -WAREHOUSE.version="0.2.1" +WAREHOUSE.version="0.2.2" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO: Warehouse todo list. @@ -516,24 +515,24 @@ function WAREHOUSE:IsAttacked() return self:is("Attacked") end ---- Check if the warehouse has a road connection to another warehouse. +--- Check if the warehouse has a road connection to another warehouse. Both warehouses need to be running! -- @param #WAREHOUSE self -- @param #WAREHOUSE warehouse The remote warehose to where the connection is checked. -- @param #boolean markpath If true, place markers of path segments on the F10 map. -- @param #boolean smokepath If true, put green smoke on path segments. -- @return #boolean If true, the two warehouses are connected by road. --- @return #number Path length in meters. +-- @return #number Path length in meters. Negative distance -1 meter indicates no connection. function WAREHOUSE:HasConnectionRoad(warehouse, markpath, smokepath) if warehouse then if self.road and warehouse.road then local _,length,gotpath=self.road:GetPathOnRoad(warehouse.road, false, false, markpath, smokepath) - return gotpath, length or 0 + return gotpath, length or -1 else -- At least one of the warehouses has no road connection. - return false, 0 + return false, -1 end end - return nil + return nil, -1 end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -711,66 +710,36 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. --- @param #string templategroupname Name of the late activated template group as defined in the mission editor. +-- @param Wrapper.Group#GROUP group Group or template group to be added to the warehouse stock. -- @param #number ngroups Number of groups to add to the warehouse stock. Default is 1. -function WAREHOUSE:onafterAddAsset(From, Event, To, templategroupname, ngroups) +function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups) -- Set default. local n=ngroups or 1 + + local asset --Wrapper.Group#GROUP + if type(group)=="string" then + env.info("New asset passed as string") + asset=GROUP:FindByName(group) + elseif type(group)=="table" and group.aid~=nil then + env.info("New asset passed as asset") + self:_AddExistingAsset(group) + return + elseif group:IsInstanceOf("GROUP") then + env.info("New asset passed as string") + asset=group + else + self:E("ERROR: Invalid asset added!") + return nil + end - -- Get MOOSE group. - local group=GROUP:FindByName(templategroupname) -- Check if group exists and has a DCS object. -- TODO: Need to check this carefully if this words with CARGO etc. - if group and group:IsAlive()~=nil and group:GetDCSObject() then + if asset and asset:IsAlive()~=nil and asset:GetDCSObject() then - local DCSgroup=group:GetDCSObject() - local DCSunit=DCSgroup:getUnit(1) - local DCSdesc=DCSunit:getDesc() - local DCSdisplay=DCSdesc.displayName - local DCScategory=DCSgroup:getCategory() - local DCStype=DCSunit:getTypeName() - local SpeedMax=group:GetSpeedMax() - local RangeMin=group:GetRange() - group:GetCategory() - - env.info(string.format("New asset for warehouse %s:", self.alias)) - env.info(string.format("Group name = %s", group:GetName())) - env.info(string.format("Display name = %s", DCSdisplay)) - env.info(string.format("Category = %s", DCScategory)) - env.info(string.format("Type = %s", DCStype)) - env.info(string.format("Speed max = %s km/h", tostring(SpeedMax))) - env.info(string.format("Range min = %s m", tostring(RangeMin))) - self:E({fullassetdesc=DCSdesc}) - - -- Get the generalized attribute. - local attribute=self:_GetAttribute(templategroupname) - - -- Add this n times to the table. - for i=1,n do - local stockitem={} --#WAREHOUSE.Stockitem - - -- Increase asset unique id counter. - self.assetid=self.assetid+1 - - -- Set parameters. - stockitem.uid=self.assetid - stockitem.templatename=templategroupname - stockitem.template=UTILS.DeepCopy(_DATABASE.Templates.Groups[templategroupname].Template) - stockitem.category=DCScategory - stockitem.unittype=DCStype - stockitem.attribute=attribute - stockitem.range=RangeMin - stockitem.speedmax=SpeedMax - - -- Modify the template so that the group is spawned with the right coalition. - -- TODO: somehow this is now acknoleged properly. Found a workaround however with SPAWN AIP functions. - stockitem.template.CoalitionID=self.coalition - stockitem.template.CountryID=self.country - - table.insert(self.stock, stockitem) - end + -- Add new asset. + self:_AddNewAsset(asset, ngroups) -- Destroy group if it is alive. if group:IsAlive()==true then @@ -784,6 +753,73 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, templategroupname, ngroups) end +--- Add an existing asset to the warehouse stock. +-- @param #WAREHOUSE self +-- @param #WAREHOUSE.Stockitem asset The asset to be added. +function WAREHOUSE:_AddExistingAsset(asset) + table.insert(self.stock, asset) +end + +--- Add a completely new asset to the warehouse. +-- @param #WAREHOUSE self +-- @param Wrapper.Group#GROUP group The group that will be added to the warehouse stock. +-- @param #number ngroups Number of groups to be added. +function WAREHOUSE:_AddNewAsset(group, ngroups) + + -- Set default. + local n=ngroups or 1 + + local templategroupname=group:GetName() + + local DCSgroup=group:GetDCSObject() + local DCSunit=DCSgroup:getUnit(1) + local DCSdesc=DCSunit:getDesc() + local DCSdisplay=DCSdesc.displayName + local DCScategory=DCSgroup:getCategory() + local DCStype=DCSunit:getTypeName() + local SpeedMax=group:GetSpeedMax() + local RangeMin=group:GetRange() + group:GetCategory() + + env.info(string.format("New asset for warehouse %s:", self.alias)) + env.info(string.format("Group name = %s", group:GetName())) + env.info(string.format("Display name = %s", DCSdisplay)) + env.info(string.format("Category = %s", DCScategory)) + env.info(string.format("Type = %s", DCStype)) + env.info(string.format("Speed max = %s km/h", tostring(SpeedMax))) + env.info(string.format("Range min = %s m", tostring(RangeMin))) + self:E({fullassetdesc=DCSdesc}) + + -- Get the generalized attribute. + local attribute=self:_GetAttribute(templategroupname) + + -- Add this n times to the table. + for i=1,n do + local stockitem={} --#WAREHOUSE.Stockitem + + -- Increase asset unique id counter. + self.assetid=self.assetid+1 + + -- Set parameters. + stockitem.uid=self.assetid + stockitem.templatename=templategroupname + stockitem.template=UTILS.DeepCopy(_DATABASE.Templates.Groups[templategroupname].Template) + stockitem.category=DCScategory + stockitem.unittype=DCStype + stockitem.attribute=attribute + stockitem.range=RangeMin + stockitem.speedmax=SpeedMax + + -- Modify the template so that the group is spawned with the right coalition. + -- TODO: somehow this is now acknoleged properly. Found a workaround however with SPAWN AIP functions. + stockitem.template.CoalitionID=self.coalition + stockitem.template.CountryID=self.country + + table.insert(self.stock, stockitem) + end + +end + --- On after "AddAsset" event. Add a group to the warehouse stock. If the group is alive, it is destroyed. -- @param #WAREHOUSE self -- @param #string templategroupname Name of the late activated template group as defined in the mission editor. @@ -798,7 +834,7 @@ end -- @param #WAREHOUSE.Stockitem asset Ground asset that will be spawned. -- @param #WAREHOUSE.Queueitem request Request belonging to this asset. Needed for the name/alias. -- @return Wrapper.Group#GROUP The spawned group or nil if the group could not be spawned. -function WAREHOUSE:_SpawnGroundAsset(asset, request) +function WAREHOUSE:_SpawnAssetGround(asset, request) if asset and asset.category==Group.Category.GROUND then @@ -853,8 +889,9 @@ end -- @param #WAREHOUSE self -- @param #WAREHOUSE.Stockitem asset Ground asset that will be spawned. -- @param #WAREHOUSE.Queueitem request Request belonging to this asset. Needed for the name/alias. +-- @param #table parking Parking data for this asset. -- @return Wrapper.Group#GROUP The spawned group or nil if the group could not be spawned. -function WAREHOUSE:_SpawnAssetAircraft(asset, request) +function WAREHOUSE:_SpawnAssetAircraft(asset, request, parking) if asset and asset.category==Group.Category.AIRPLANE or asset.category==Group.Category.HELICOPTER then @@ -892,39 +929,56 @@ function WAREHOUSE:_SpawnAssetAircraft(asset, request) end -- Get the right terminal type for this kind of aircraft. - local terminaltype=self:_GetTerminal(asset.attribute) + --local terminaltype=self:_GetTerminal(asset.attribute) -- Get parking data. - local parking=self.airbase:GetFreeParkingSpotsTable(terminaltype) + --local parking=self.airbase:GetFreeParkingSpotsTable(terminaltype) - if #parking<#template.units then - self:E("ERROR: Not enough parking!") - return nil + if AirbaseCategory == Airbase.Category.HELIPAD or AirbaseCategory == Airbase.Category.SHIP then + --TODO Figure out what's necessary in this case. + + else + + if #parking<#template.units then + local text=string.format("ERROR: Not enough parking! Free parking = %d < %d aircraft to be spawned.", #parking, #template.units) + self:E(text) + return nil + end end - + -- Position the units. for i=1,#template.units do -- Unit template. local unit = template.units[i] - - -- Nillify the unit ID. - unit.unitId=nil - - -- Set unit name. - unit.name=string.format("%s-%02d", template.name , i) - - local coord=parking[i].Coordinate --Core.Point#COORDINATE - local terminal=parking[i].TerminalID --#number - - coord:MarkToAll(string.format("spawnplace terminal %d", terminal)) - - unit.x=coord.x - unit.y=coord.z - unit.alt=coord.y - unit.parking_id = nil - unit.parking = terminal + if AirbaseCategory == Airbase.Category.HELIPAD or AirbaseCategory == Airbase.Category.SHIP then + + -- Helipads we take the position of the airbase location, since the exact location of the spawn point does not make sense. + local coord=self.airbase:GetCoordinate() + + unit.x=coord.x + unit.y=coord.z + unit.alt=coord.y + + unit.parking_id = nil + unit.parking = nil + + else + + local coord=parking[i].Coordinate --Core.Point#COORDINATE + local terminal=parking[i].TerminalID --#number + + coord:MarkToAll(string.format("spawnplace unit %s terminal %d", unit.name, terminal)) + + unit.x=coord.x + unit.y=coord.z + unit.alt=coord.y + + unit.parking_id = nil + unit.parking = terminal + + end end -- Set general spawnpoint position. @@ -939,6 +993,8 @@ function WAREHOUSE:_SpawnAssetAircraft(asset, request) -- Uncontrolled spawning. template.uncontrolled=true + + -- Debug info. self:E({airtemplate=template}) @@ -1111,9 +1167,13 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) ------------------------------------------------------------------------------------------------------------------------------------ -- Cargo assets. ------------------------------------------------------------------------------------------------------------------------------------ + + -- Pending request. Add cargo groups to request. + local Pending=Request --#WAREHOUSE.Pendingitem + Pending.assets={} -- Spawn assets of this request. - local _spawngroups,_cargoassets=self:_SpawnAssetRequest(Request) --Core.Set#SET_GROUP + local _spawngroups,_cargoassets=self:_SpawnAssetRequest(Pending) --Core.Set#SET_GROUP -- Check if any group was spawned. If not, delete the request. if _spawngroups:Count()==0 then @@ -1123,14 +1183,11 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) return end - -- General type and category. + -- General type and category. local _cargotype=_cargoassets[1].attribute --#WAREHOUSE.Attribute local _cargocategory=_cargoassets[1].category --DCS#Group.Category - -- Pending request. Add cargo groups to request. - local Pending=Request --#WAREHOUSE.Pendingitem Pending.cargogroupset=_spawngroups - Pending.cargoassets=_cargoassets Pending.cargoattribute=_cargotype Pending.cargocategory=_cargocategory @@ -1175,9 +1232,7 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) self:_RouteGround(group, ToCoordinate) elseif _cargocategory==Group.Category.AIRPLANE then env.info("FF route plane "..group:GetName()) - --self:_RouteAir(group, Request.airbase) - -- TEST! - group=self:_RouteAirRat(group, Request.airbase) + self:_RouteAir(group, Request.airbase) elseif _cargocategory==Group.Category.HELICOPTER then env.info("FF route helo "..group:GetName()) self:_RouteAir(group, Request.airbase) @@ -1291,6 +1346,7 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) -- Add group to transportset. TransportSet:AddGroup(spawngroup) + Pending.assets[_assetitem.uid]=_assetitem table.insert(_transportassets,_assetitem) end end @@ -1329,6 +1385,7 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) -- Add group to transportset. TransportSet:AddGroup(spawngroup) + Pending.assets[_assetitem.uid]=_assetitem table.insert(_transportassets,_assetitem) else self:E(self.wid.."ERROR: spawngroup helo transport does not exist!") @@ -1370,6 +1427,7 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) -- Add group to transportset. TransportSet:AddGroup(spawngroup) + Pending.assets[_assetitem.uid]=_assetitem table.insert(_transportassets,_assetitem) end end @@ -1440,13 +1498,9 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) -- Start dispatcher. CargoTransport:__Start(5) - - -- Add transportassets to pending queue item. - Pending.transportassets=_transportassets - + -- Add cargo groups to request. Pending.transportgroupset=TransportSet - Pending.transportassets=_transportassets Pending.transportattribute=_transporttype Pending.transportcategory=_transportcategory @@ -1481,7 +1535,7 @@ function WAREHOUSE:_SpawnAssetRequest(Request) -- Now we try to find all parking spots for all cargo groups in advance. Due to the for loop, the parking spots do not get updated while spawning. local Parking={} if _cargocategory==Group.Category.AIRPLANE or _cargocategory==Group.Category.HELICOPTER then - Parking=self:_GetParkingForAssets(_assetstock) + Parking=self:_GetParkingForAssets(_assetstock) end -- Spawn aircraft in uncontrolled state if request comes from the same warehouse. @@ -1492,11 +1546,10 @@ function WAREHOUSE:_SpawnAssetRequest(Request) AIOnOff=false end - -- Create an empty set. + -- Create an empty group set. local _groupset=SET_GROUP:New():FilterDeads() - -- Spawn the assets. - local _spawngroups={} + -- Table for all spawned assets. local _assets={} -- Loop over cargo requests. @@ -1522,7 +1575,7 @@ function WAREHOUSE:_SpawnAssetRequest(Request) -- Spawn ground troops. --_group=_spawn:SpawnFromCoordinate(spawncoord) - _group=self:_SpawnGroundAsset(_assetitem, Request) + _group=self:_SpawnAssetGround(_assetitem, Request) elseif _assetitem.category==Group.Category.AIRPLANE or _assetitem.category==Group.Category.HELICOPTER then @@ -1530,7 +1583,7 @@ function WAREHOUSE:_SpawnAssetRequest(Request) -- Spawn air units. --_group=_spawn:SpawnAtAirbase(self.airbase, SPAWN.Takeoff.Cold, nil, nil, true, Parking[i]) - _group=self:_SpawnAssetAircraft(_assetitem, Request) + _group=self:_SpawnAssetAircraft(_assetitem, Request, Parking[i]) elseif _assetitem.category==Group.Category.TRAIN then @@ -1542,6 +1595,7 @@ function WAREHOUSE:_SpawnAssetRequest(Request) end + -- Add group to group set and asset list. if _group then _groupset:AddGroup(_group) table.insert(_assets, _assetitem) @@ -1552,8 +1606,10 @@ function WAREHOUSE:_SpawnAssetRequest(Request) end -- Delete spawned items from warehouse stock. - for _,_item in pairs(_assets) do - self:_DeleteStockItem(_item) + for _,_asset in pairs(_assets) do + local asset=_asset --#WAREHOUSE.Stockitem + Request.assets[asset.uid]=asset + self:_DeleteStockItem(asset) end return _groupset,_assets @@ -1580,8 +1636,9 @@ function WAREHOUSE:onafterUnloaded(From, Event, To, group) local speedmax=group:GetSpeedMax() if group:IsGround() then + -- Route group to spawn zone. if speedmax>1 then - group:RouteGroundTo(self.spawnzone:GetRandomCoordinate(50), speedmax*0.5, AI.Task.VehicleFormation.RANK, 3) + group:RouteGroundTo(self.spawnzone:GetRandomCoordinate(), speedmax*0.5, AI.Task.VehicleFormation.RANK, 3) else -- Immobile ground unit ==> directly put it into the warehouse. self:Arrived(group) @@ -1626,9 +1683,8 @@ function WAREHOUSE:onafterArrived(From, Event, To, group) group:RouteGroundTo(request.warehouse.coordinate, group:GetSpeedMax()*0.3, "Off Road") end - -- Move asset into new warehouse. - -- TODO: need to figure out which template group name I best take. - request.warehouse:__AddAsset(60, group:GetName(), 1) + -- Move asset from pending queue into new warehouse. + request.warehouse:__AddAsset(60, self:_GetAssetFromGroupRequest(group,request), 1) -- All cargo delivered. if request and ncargo==0 then @@ -1639,6 +1695,20 @@ function WAREHOUSE:onafterArrived(From, Event, To, group) end +--- Get asset from group and request. +-- @param #WAREHOUSE self +-- @param Wrapper.Group#GROUP group The group that has arrived at its destination. +-- @param #WAREHOUSE.Pendingitem request Pending request. +-- @return #WAREHOUSE.Stockitem The asset. +function WAREHOUSE:_GetAssetFromGroupRequest(group,request) + + -- Get the IDs for this group. In particular, we use the asset ID to figure out which group was delivered. + local wid,aid,rid=self:_GetIDsFromGroup(group) + + -- Retrieve asset from request. + local asset=request.assets[aid] +end + --- Update the pending requests by removing assets that have arrived. -- @param #WAREHOUSE self -- @param Wrapper.Group#GROUP group The group that has arrived at its destination. @@ -1671,7 +1741,7 @@ function WAREHOUSE:_UpdatePending(group) self:E(self.wid..string.format("WARNING: pending request could not be updated since request did not exist in pending queue!")) end - return request + return request,wid,aid,rid end @@ -1797,60 +1867,6 @@ function WAREHOUSE:_RouteGround(Group, Coordinate, Speed) end end ---- Route the airplane from one airbase another. --- @param #WAREHOUSE self --- @param Wrapper.Group#GROUP Aircraft Airplane group to be routed. --- @param Wrapper.Airbase#AIRBASE ToAirbase Destination airbase. --- @param #number Speed Speed in km/h. Default is 80% of max possible speed the group can do. --- @return Wrapper.Group#GROUP Group that was spawned by RAT. -function WAREHOUSE:_RouteAirRat(Aircraft, ToAirbase, Speed) - - if Aircraft and Aircraft:IsAlive()~=nil then - - -- Get parking data of all units. - local parkingdata={} - - local units=Aircraft:GetUnits() - for _,_unit in pairs(units) do - local unit=_unit --Wrapper.Unit#UNIT - local _spot,_terminal,_distance=unit:GetCoordinate():GetClosestOccupiedParkingSpot(self.airbase) - table.insert(parkingdata, {Coordinate=_spot, TerminalID=_terminal}) - end - env.info("FF parking data") - self:E(parkingdata) - - -- Create a RAT object to use its flight plan. - local rat=RAT:New(Aircraft:GetName()) - - -- Init some parameters. - rat:SetDeparture(self.airbase:GetName()) - rat:SetDestination(ToAirbase:GetName()) - --rat:SetCoalitionAircraft(color) - rat:SetCountry(self.country) - rat:NoRespawn() - - -- Init spawn but do not actually spawn. - rat:Spawn(0) - --rat:_SpawnWithRoute(_departure,_destination,_takeoff,_landing,_livery,_waypoint,_lastpos,_nrespawn,parkingdata) - - -- Destroy the original aircraft. - Aircraft:Destroy() - - -- Spawn RAT aircraft at specific parking sports. - local spawnindex=rat:_SpawnWithRoute(self.airbase:GetName(), ToAirbase:GetName(), RAT.wp.hot, nil, nil, nil, nil, nil, parkingdata) - - -- Get the group and check it's name. - local group=rat.ratcraft[spawnindex].group --Wrapper.Group#GROUP - self:E(self.wid..string.format("Spawned new RAT aircraft as group %s", group:GetName())) - - group:SmokeBlue() - -- Activate group. - local bla=group:SetCommand({id='Start', params={}}) - self:E({bla=bla}) - return group - end - -end --- Route the airplane from one airbase another. -- @param #WAREHOUSE self @@ -1916,9 +1932,6 @@ function WAREHOUSE:_RouteAir(Aircraft, ToAirbase, Speed) local newAC=Aircraft:RespawnAtCurrentAirbase(Template, Takeoff, false) env.info("FF Respawn at current airbase group = "..newAC:GetName().." name after") - -- Handle event engine shutdown and trigger delivered event. - -- Not this did not work unless the routine would retrive the state from get/set state! - --newAC:HandleEvent(EVENTS.EngineShutdown, self._OnEventArrived) else self:E(string.format("ERROR: aircraft %s cannot be routed since it does not exist or is not alive %s!", tostring(Aircraft:GetName()), tostring(Aircraft:IsAlive()))) end @@ -2653,12 +2666,12 @@ function WAREHOUSE:_GetParkingForAssets(assetlist, parkingdata) local nunits=#group:GetUnits() local terminal=self:_GetTerminal(asset.attribute) - --[[ + env.info("asset name = "..tostring(asset.templatename)) env.info("asset attribute = "..tostring(asset.attribute)) env.info("terminal type = "..tostring(terminal)) + env.info("parking spots = "..tostring(nunits)) env.info("parking spots = "..tostring(#parkingdata)) - ]] -- Find appropiate parking spots for this group. local spots=self.airbase:FindFreeParkingSpotForAircraft(group, terminal, nil, nil, nil, nil, nil, nil, parkingdata) @@ -2667,7 +2680,7 @@ function WAREHOUSE:_GetParkingForAssets(assetlist, parkingdata) if spot then local coord=spot.Coordinate --Core.Point#COORDINATE local text=string.format("Parking spot for %s:\nAsset id=%d, Terminal id=%d", asset.templatename, asset.uid, spot.TerminalID) - coord:MarkToAll(text) + --coord:MarkToAll(text) self:E(self.wid..text) end end @@ -2925,14 +2938,14 @@ function WAREHOUSE:_GetAttribute(groupname) attribute=WAREHOUSE.Attribute.TANKER elseif awacs then attribute=WAREHOUSE.Attribute.AWACS + elseif bomber then + attribute=WAREHOUSE.Attribute.BOMBER elseif artillery then attribute=WAREHOUSE.Attribute.ARTILLERY elseif infantry then attribute=WAREHOUSE.Attribute.INFANTRY elseif attackhelicopter then attribute=WAREHOUSE.Attribute.ATTACKHELICOPTER - elseif bomber then - attribute=WAREHOUSE.Attribute.BOMBER elseif tank then attribute=WAREHOUSE.Attribute.TANK elseif truck then @@ -3160,7 +3173,7 @@ function WAREHOUSE:_GetFlightplan(group,_departure,_destination) local AlphaDescent=math.rad(4) -- Expected cruise level (peak of Gaussian distribution) - local FLcruise_expect=200*RAT.unit.FL2m + local FLcruise_expect=150*RAT.unit.FL2m --- DEPARTURE AIRPORT @@ -3180,9 +3193,9 @@ function WAREHOUSE:_GetFlightplan(group,_departure,_destination) --- DESCENT/HOLDING POINT - -- Get a random point between 5 and 20 km away from the destination. - local Rhmin=8000 - local Rhmax=20000 + -- Get a random point between 5 and 10 km away from the destination. + local Rhmin=5000 + local Rhmax=10000 if _category==Group.Category.HELICOPTER then -- For helos we set a distance between 500 to 1000 m. Rhmin=500 @@ -3190,8 +3203,9 @@ function WAREHOUSE:_GetFlightplan(group,_departure,_destination) end -- Coordinates of the holding point. y is the land height at that point. - local Vholding=Pdestination:GetRandomVec2InRadius(Rhmax, Rhmin) - local Pholding=COORDINATE:NewFromVec2(Vholding) + --local Vholding=Pdestination:GetRandomVec2InRadius(Rhmax, Rhmin) + --local Pholding=COORDINATE:NewFromVec2(Vholding) + local Pholding=Pdestination:GetRandomCoordinateInRadius(Rhmax, Rhmin) -- AGL height of holding point. local H_holding=Pholding.y @@ -3293,8 +3307,26 @@ function WAREHOUSE:_GetFlightplan(group,_departure,_destination) -- Distances. local d_climb = h_climb/math.tan(AlphaClimb) local d_descent = h_descent/math.tan(AlphaDescent) - local d_cruise = d_total-d_climb-d_descent + local d_cruise = d_total-d_climb-d_descent + -- Debug. + local text=string.format("Flight plan:\n") + text=text..string.format("Vx max = %d\n", Vmax) + text=text..string.format("Vx climb = %d\n", VxClimb) + text=text..string.format("Vx cruise = %d\n", VxCruise) + text=text..string.format("Vx descent = %d\n", VxDescent) + text=text..string.format("Vx holding = %d\n", VxHolding) + text=text..string.format("Vx final = %d\n", VxFinal) + text=text..string.format("Dist climb = %d\n", d_climb) + text=text..string.format("Dist cruise = %d\n", d_cruise) + text=text..string.format("Dist descent = %d\n", d_descent) + text=text..string.format("Dist total = %d\n", d_total) + text=text..string.format("FL min = %d\n", FLmin) + text=text..string.format("FL cruise * = %d\n", FLcruise) + text=text..string.format("FL max = %d\n", FLmax) + text=text..string.format("Ceiling = %d\n", ceiling) + env.info(text) + -- Ensure that cruise distance is positve. Can be slightly negative in special cases. And we don't want to turn back. if d_cruise<0 then d_cruise=100 @@ -3307,52 +3339,44 @@ function WAREHOUSE:_GetFlightplan(group,_departure,_destination) --- Departure/Take-off c[#c+1]=Pdeparture wp[#wp+1]=Pdeparture:WaypointAir("RADIO", COORDINATE.WaypointType.TakeOffParking, COORDINATE.WaypointAction.FromParkingArea, VxClimb, true,_departure, nil, "Departure") - --wp[#wp+1]=self:_Waypoint(#wp+1, "Departure", takeoff, c[#wp+1], VxClimb, H_departure, departure) --- Climb local Pclimb=Pdeparture:Translate(d_climb/2, heading) Pclimb.y=H_departure+(FLcruise-H_departure)/2 c[#c+1]=Pclimb wp[#wp+1]=Pclimb:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, VxClimb, true, nil, nil, "Climb") - --wp[#wp+1]=self:_Waypoint(#wp+1, "Climb", RAT.wp.climb, c[#wp+1], VxClimb, ) --- Begin of Cruise local Pcruise1=Pclimb:Translate(d_climb/2, heading) Pcruise1.y=FLcruise c[#c+1]=Pcruise1 wp[#wp+1]=Pcruise1:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, VxCruise, true, nil, nil, "Begin of Cruise") - --wp[#wp+1]=self:_Waypoint(#wp+1, "Begin of Cruise", RAT.wp.cruise, c[#wp+1], VxCruise, FLcruise) --- End of Cruise local Pcruise2=Pcruise1:Translate(d_cruise, heading) Pcruise2.y=FLcruise c[#c+1]=Pcruise2 wp[#wp+1]=Pcruise2:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, VxCruise, true, nil, nil, "End of Cruise") - --wp[#wp+1]=self:_Waypoint(#wp+1, "End of Cruise", RAT.wp.cruise, c[#wp+1], VxCruise, FLcruise) --- Descent local Pdescent=Pcruise2:Translate(d_descent/2, heading) Pdescent.y=FLcruise-(FLcruise-(h_holding+H_holding))/2 c[#c+1]=Pdescent wp[#wp+1]=Pcruise2:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, VxDescent, true, nil, nil, "Descent") - --wp[#wp+1]=self:_Waypoint(#wp+1, "Descent", RAT.wp.descent, c[#wp+1], VxDescent, FLcruise-(FLcruise-(h_holding+H_holding))/2) --- Holding point Pholding.y=H_holding+h_holding c[#c+1]=Pholding wp[#wp+1]=Pholding:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, VxHolding, true, nil, nil, "Holding") - --wp[#wp+1]=self:_Waypoint(#wp+1, "Holding Point", RAT.wp.holding, c[#wp+1], VxHolding, H_holding+h_holding) --- Final destination. c[#c+1]=Pdestination - wp[#wp+1]=Pcruise2:WaypointAir("BARO", COORDINATE.WaypointType.Land, COORDINATE.WaypointAction.Landing, VxFinal, true, nil, nil, "Final Destination") - --wp[#wp+1]=self:_Waypoint(#wp+1, "Final Destination", landing, c[#wp+1], VxFinal, H_destination, destination) + wp[#wp+1]=Pcruise2:WaypointAir("RADIO", COORDINATE.WaypointType.Land, COORDINATE.WaypointAction.Landing, VxFinal, true, _destination, nil, "Final Destination") return wp,c end - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 10174dd5b..34d76c792 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -1453,7 +1453,7 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) -- SpawnPoint.airdromeId = AirbaseID end - SpawnPoint.alt = AirbaseCoord:GetLandHeight() + SpawnPoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type SpawnPoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action @@ -1474,7 +1474,7 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) -- -- Get unit coordinates for respawning position. local uc=unit:GetCoordinate() - + uc:MarkToAll(string.format("re-spawnplace %s terminal %d", unit:GetName(), TermialID)) SpawnTemplate.units[UnitID].x = uc.x --Parkingspot.x SpawnTemplate.units[UnitID].y = uc.z --Parkingspot.z @@ -1483,24 +1483,26 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) -- SpawnTemplate.units[UnitID].parking = TermialID SpawnTemplate.units[UnitID].parking_id = nil - if UnitID==1 then - x=uc.x - y=uc.z - end - + --SpawnTemplate.units[UnitID].unitId=nil end - SpawnPoint.x = x --AirbaseCoord.x - SpawnPoint.y = y --AirbaseCoord.z + --SpawnTemplate.groupId=nil - SpawnTemplate.x = x --AirbaseCoord.x - SpawnTemplate.y = y --AirbaseCoord.z + SpawnPoint.x = SpawnTemplate.units[1].x --x --AirbaseCoord.x + SpawnPoint.y = SpawnTemplate.units[1].y --y --AirbaseCoord.z + SpawnPoint.alt = SpawnTemplate.units[1].alt --AirbaseCoord:GetLandHeight() + + SpawnTemplate.x = SpawnTemplate.units[1].x --x --AirbaseCoord.x + SpawnTemplate.y = SpawnTemplate.units[1].y --y --AirbaseCoord.z -- Set uncontrolled state. SpawnTemplate.uncontrolled=Uncontrolled - -- Destroy and respawn. + -- Destroy old group. self:Destroy() + + + --SCHEDULER:New(nil, DATABASE.Spawn, {_DATABASE, SpawnTemplate}, 0.00001) _DATABASE:Spawn( SpawnTemplate ) -- Reset events.