diff --git a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua index b780591fe..0e13f7c2c 100644 --- a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua @@ -3656,7 +3656,7 @@ do -- AI_A2A_DISPATCHER for DefenderSquadronName, DefenderSquadron in pairs( self.DefenderSquadrons ) do - self:I( { DefenderSquadron = DefenderSquadron.Name } ) + self:T( { DefenderSquadron = DefenderSquadron.Name } ) local Airbase = DefenderSquadron.Airbase local AirbaseCoordinate = Airbase:GetCoordinate() diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 1b55b5ba3..8ef630eee 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -689,6 +689,10 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories ) local ObjectCategory = ZoneObject:getCategory() + --local name=ZoneObject:getName() + --env.info(string.format("Zone object %s", tostring(name))) + --self:E(ZoneObject) + if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then local CoalitionDCSUnit = ZoneObject:getCoalition() diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index 76b5007f5..e402dba23 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -3694,11 +3694,11 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu -- Get the original warehouse this group belonged to. local warehouse=self:FindWarehouseInDB(wid) - + if warehouse then - + local request=warehouse:_GetRequestOfGroup(group, warehouse.pending) - + if request then -- Increase number of cargo delivered and transports home. @@ -3729,14 +3729,14 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu -- Note the group is only added once, i.e. the ngroups parameter is ignored here. -- This is because usually these request comes from an asset that has been transfered from another warehouse and hence should only be added once. if asset~=nil then - self:_DebugMessage(string.format("Warehouse %s: Adding KNOWN asset uid=%d with attribute=%s to stock.", self.alias, asset.uid, asset.attribute), 5) - + self:_DebugMessage(string.format("Warehouse %s: Adding KNOWN asset uid=%d with attribute=%s to stock.", self.alias, asset.uid, asset.attribute), 5) + -- Asset now belongs to this warehouse. Set warehouse ID. asset.wid=self.uid - + -- No request associated with this asset. asset.rid=nil - + -- Set livery. if liveries then if type(liveries)=="table" then @@ -3745,17 +3745,17 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu asset.livery=liveries end end - + -- Set skill. - asset.skill=skill - + asset.skill=skill + -- Asset is not spawned. asset.spawned=false asset.iscargo=nil - + -- Add asset to stock. table.insert(self.stock, asset) - + -- Trigger New asset event. self:__NewAsset(0.1, asset, assignment or "") else @@ -3775,16 +3775,16 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu -- Add created assets to stock of this warehouse. for _,asset in pairs(assets) do - + -- Asset belongs to this warehouse. Set warehouse ID. asset.wid=self.uid - + -- No request associated with this asset. asset.rid=nil - + -- Add asset to stock. table.insert(self.stock, asset) - + -- Trigger NewAsset event. Delay a bit for OnAfterNewAsset functions to work properly. self:__NewAsset(0.1, asset, assignment or "") end @@ -4230,9 +4230,9 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) -- Create an alias name with the UIDs for the sending warehouse, asset and request. --local _alias=self:_alias(_assetitem.unittype, self.uid, _assetitem.uid, Request.uid) - + local _alias=_assetitem.spawngroupname - + _assetitem.rid=Request.uid -- Asset is transport. @@ -4284,9 +4284,9 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request) Request.assets[_assetitem.uid]=_assetitem end - + -- Init problem table. - Request.assetproblem={} + Request.assetproblem={} -- Add request to pending queue. table.insert(self.pending, Request) @@ -5350,7 +5350,7 @@ function WAREHOUSE:_SpawnAssetRequest(Request) -- Alias of the group. --local _alias=self:_Alias(asset, Request) - + local _alias=asset.spawngroupname -- Spawn an asset group. @@ -5577,11 +5577,11 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol if asset.livery then unit.livery_id = asset.livery end - + if asset.skill then unit.skill= asset.skill end - + if asset.payload then unit.payload=asset.payload end @@ -5604,7 +5604,7 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol -- Debug info. self:T2({airtemplate=template}) - + -- Create a flight group. --FLIGHTGROUP:New(template.name) @@ -5820,7 +5820,7 @@ function WAREHOUSE:_RouteAir(aircraft) -- Give start command to activate uncontrolled aircraft within the next 60 seconds. local starttime=math.random(60) - + local fc=_DATABASE:GetFlightControl(self.airbasename) if fc then -- Nothing to do. FC will start the aircraft once it gets taxi clearance. @@ -6093,26 +6093,26 @@ function WAREHOUSE:_OnEventArrived(EventData) if self.uid==wid then local request=self:_GetRequestOfGroup(group, self.pending) - - -- Better check that the request still exists, because for a group with more units, the + + -- Better check that the request still exists, because for a group with more units, the if request then - + local istransport=self:_GroupIsTransport(group, request) - + -- Get closest airbase. -- Note, this crashed at somepoint when the Tarawa was in the mission. Don't know why. Deleting the Tarawa and adding it again solved the problem. local closest=group:GetCoordinate():GetClosestAirbase() - + -- Check if engine shutdown happend at right airbase because the event is also triggered in other situations. local rightairbase=closest:GetName()==request.warehouse:GetAirbase():GetName() - + -- Check that group is cargo and not transport. if istransport==false and rightairbase then - + -- Debug info. local text=string.format("Air asset group %s from warehouse %s arrived at its destination.", group:GetName(), self.alias) self:_InfoMessage(text) - + -- Trigger arrived event for this group. Note that each unit of a group will trigger this event. So the onafterArrived function needs to take care of that. -- Actually, we only take the first unit of the group that arrives. If it does, we assume the whole group arrived, which might not be the case, since -- some units might still be taxiing or whatever. Therefore, we add 10 seconds for each additional unit of the group until the first arrived event is triggered. @@ -6120,9 +6120,8 @@ function WAREHOUSE:_OnEventArrived(EventData) local dt=10*(nunits-1)+1 -- one unit = 1 sec, two units = 11 sec, three units = 21 sec before we call the group arrived. self:__Arrived(dt, group) end - - end + end end else @@ -7351,7 +7350,7 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets) self:T3(string.format("l1=%.1f l2=%.1f s=%.1f d=%.1f ==> safe=%s", l1,l2,safedist,dist,tostring(safe))) return safe end - + -- Get client coordinates. local function _clients() local clients=_DATABASE.CLIENTS @@ -7369,7 +7368,7 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets) env.info(string.format("Found client %s on parking spot %d at airbase %s", unit.name, TermID, airbase:GetName())) end ]] - end + end end return coords end @@ -7466,7 +7465,7 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets) free=false self:I(self.wid..string.format("Parking spot %d is occupied by other aircraft taking off (TOAC).", _termid)) end - + -- Check if spot is reserved. local fc=_DATABASE:GetFlightControl(self.airbasename) if fc then @@ -7476,7 +7475,7 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets) self:I(self.wid..string.format("Parking spot %d is reserved for flight element %s", _termid, tostring(reserved))) end end - + -- Loop over all obstacles. for _,obstacle in pairs(obstacles) do @@ -7688,10 +7687,10 @@ function WAREHOUSE:_GetIDsFromGroup(group) -- Get asset id from group name. local wid,aid,rid=analyse(name) - + -- Get Asset. local asset=self:GetAssetByID(aid) - + -- Get warehouse and request id from asset table. if asset then wid=asset.wid @@ -8637,7 +8636,7 @@ function WAREHOUSE:_GetFlightplan(asset, departure, destination) c[#c+1]=Pholding wp[#wp+1]=Pholding:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, VxHolding*3.6, true, nil, nil, "Holding") end - + --- Final destination. c[#c+1]=Pdestination wp[#wp+1]=Pdestination:WaypointAir("RADIO", COORDINATE.WaypointType.Land, COORDINATE.WaypointAction.Landing, VxFinal*3.6, true, destination, nil, "Final Destination") diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index c33197ed6..4b017862d 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1,4 +1,4 @@ ---- **Wrapper** -- CONTROLLABLE is an intermediate class wrapping Group and Unit classes "controllers". + --- **Wrapper** -- CONTROLLABLE is an intermediate class wrapping Group and Unit classes "controllers". -- -- === -- @@ -2379,16 +2379,30 @@ do -- Route methods -- @param #number Speed (optional) Speed in km/h. The default speed is 20 km/h. -- @param #string Formation (optional) The route point Formation, which is a text string that specifies exactly the Text in the Type of the route point, like "Vee", "Echelon Right". -- @param #number DelaySeconds Wait for the specified seconds before executing the Route. + -- @param #function WaypointFunction (Optional) Function called when passing a waypoint. First parameters of the function are the @{CONTROLLABLE} object, the number of the waypoint and the total number of waypoints. + -- @param #table WaypointFunctionArguments (Optional) List of parameters passed to the *WaypointFunction*. -- @return #CONTROLLABLE The CONTROLLABLE. - function CONTROLLABLE:RouteGroundTo( ToCoordinate, Speed, Formation, DelaySeconds ) + function CONTROLLABLE:RouteGroundTo( ToCoordinate, Speed, Formation, DelaySeconds, WaypointFunction, WaypointFunctionArguments ) local FromCoordinate = self:GetCoordinate() - --local FromWP = FromCoordinate:WaypointGround() local FromWP = FromCoordinate:WaypointGround(Speed, Formation) local ToWP = ToCoordinate:WaypointGround( Speed, Formation ) - self:Route( { FromWP, ToWP }, DelaySeconds ) + local route={FromWP, ToWP} + + -- Add passing waypoint function. + if WaypointFunction then + local N=#route + for n,waypoint in pairs(route) do + waypoint.task = {} + waypoint.task.id = "ComboTask" + waypoint.task.params = {} + waypoint.task.params.tasks = {self:TaskFunction("CONTROLLABLE.___PassingWaypoint", n, N, WaypointFunction, unpack(WaypointFunctionArguments or {}))} + end + end + + self:Route( route, DelaySeconds ) return self end @@ -2399,8 +2413,10 @@ do -- Route methods -- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h. -- @param #number DelaySeconds (Optional) Wait for the specified seconds before executing the Route. Default is one second. -- @param #string OffRoadFormation (Optional) The formation at initial and final waypoint. Default is "Off Road". + -- @param #function WaypointFunction (Optional) Function called when passing a waypoint. First parameters of the function are the @{CONTROLLABLE} object, the number of the waypoint and the total number of waypoints. + -- @param #table WaypointFunctionArguments (Optional) List of parameters passed to the *WaypointFunction*. -- @return #CONTROLLABLE The CONTROLLABLE. - function CONTROLLABLE:RouteGroundOnRoad( ToCoordinate, Speed, DelaySeconds, OffRoadFormation ) + function CONTROLLABLE:RouteGroundOnRoad( ToCoordinate, Speed, DelaySeconds, OffRoadFormation, WaypointFunction, WaypointFunctionArguments ) -- Defaults. Speed=Speed or 20 @@ -2408,7 +2424,7 @@ do -- Route methods OffRoadFormation=OffRoadFormation or "Off Road" -- Get the route task. - local route=self:TaskGroundOnRoad(ToCoordinate, Speed, OffRoadFormation) + local route=self:TaskGroundOnRoad(ToCoordinate, Speed, OffRoadFormation, nil, nil, WaypointFunction, WaypointFunctionArguments) -- Route controllable to destination. self:Route( route, DelaySeconds ) @@ -2421,15 +2437,17 @@ do -- Route methods -- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. -- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h. -- @param #number DelaySeconds (Optional) Wait for the specified seconds before executing the Route. Default is one second. + -- @param #function WaypointFunction (Optional) Function called when passing a waypoint. First parameters of the function are the @{CONTROLLABLE} object, the number of the waypoint and the total number of waypoints. + -- @param #table WaypointFunctionArguments (Optional) List of parameters passed to the *WaypointFunction*. -- @return #CONTROLLABLE The CONTROLLABLE. - function CONTROLLABLE:RouteGroundOnRailRoads( ToCoordinate, Speed, DelaySeconds) + function CONTROLLABLE:RouteGroundOnRailRoads( ToCoordinate, Speed, DelaySeconds, WaypointFunction, WaypointFunctionArguments ) -- Defaults. Speed=Speed or 20 DelaySeconds=DelaySeconds or 1 -- Get the route task. - local route=self:TaskGroundOnRailRoads(ToCoordinate, Speed) + local route=self:TaskGroundOnRailRoads(ToCoordinate, Speed, WaypointFunction, WaypointFunctionArguments ) -- Route controllable to destination. self:Route( route, DelaySeconds ) @@ -2446,10 +2464,12 @@ do -- Route methods -- @param #string OffRoadFormation (Optional) The formation at initial and final waypoint. Default is "Off Road". -- @param #boolean Shortcut (Optional) If true, controllable will take the direct route if the path on road is 10x longer or path on road is less than 5% of total path. -- @param Core.Point#COORDINATE FromCoordinate (Optional) Explicit initial coordinate. Default is the position of the controllable. + -- @param #function WaypointFunction (Optional) Function called when passing a waypoint. First parameters of the function are the @{CONTROLLABLE} object, the number of the waypoint and the total number of waypoints. + -- @param #table WaypointFunctionArguments (Optional) List of parameters passed to the *WaypointFunction*. -- @return DCS#Task Task. -- @return #boolean If true, path on road is possible. If false, task will route the group directly to its destination. - function CONTROLLABLE:TaskGroundOnRoad( ToCoordinate, Speed, OffRoadFormation, Shortcut, FromCoordinate ) - self:F2({ToCoordinate=ToCoordinate, Speed=Speed, OffRoadFormation=OffRoadFormation}) + function CONTROLLABLE:TaskGroundOnRoad( ToCoordinate, Speed, OffRoadFormation, Shortcut, FromCoordinate, WaypointFunction, WaypointFunctionArguments ) + self:I({ToCoordinate=ToCoordinate, Speed=Speed, OffRoadFormation=OffRoadFormation, WaypointFunction=WaypointFunction, Args=WaypointFunctionArguments}) -- Defaults. Speed=Speed or 20 @@ -2499,6 +2519,7 @@ do -- Route methods if LongRoad and Shortcut then -- Road is long ==> we take the short cut. + table.insert(route, FromCoordinate:WaypointGround(Speed, OffRoadFormation)) table.insert(route, ToCoordinate:WaypointGround(Speed, OffRoadFormation)) @@ -2527,7 +2548,18 @@ do -- Route methods table.insert(route, ToCoordinate:WaypointGround(Speed, OffRoadFormation)) end - + + -- Add passing waypoint function. + if WaypointFunction then + local N=#route + for n,waypoint in pairs(route) do + waypoint.task = {} + waypoint.task.id = "ComboTask" + waypoint.task.params = {} + waypoint.task.params.tasks = {self:TaskFunction("CONTROLLABLE.___PassingWaypoint", n, N, WaypointFunction, unpack(WaypointFunctionArguments or {}))} + end + end + return route, canroad end @@ -2535,8 +2567,10 @@ do -- Route methods -- @param #CONTROLLABLE self -- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. -- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h. + -- @param #function WaypointFunction (Optional) Function called when passing a waypoint. First parameters of the function are the @{CONTROLLABLE} object, the number of the waypoint and the total number of waypoints. + -- @param #table WaypointFunctionArguments (Optional) List of parameters passed to the *WaypointFunction*. -- @return Task - function CONTROLLABLE:TaskGroundOnRailRoads(ToCoordinate, Speed) + function CONTROLLABLE:TaskGroundOnRailRoads(ToCoordinate, Speed, WaypointFunction, WaypointFunctionArguments ) self:F2({ToCoordinate=ToCoordinate, Speed=Speed}) -- Defaults. @@ -2561,10 +2595,31 @@ do -- Route methods table.insert(route, PathOnRail[2]:WaypointGround(Speed, "On Railroad")) end + + -- Add passing waypoint function. + if WaypointFunction then + local N=#route + for n,waypoint in pairs(route) do + waypoint.task = {} + waypoint.task.id = "ComboTask" + waypoint.task.params = {} + waypoint.task.params.tasks = {self:TaskFunction("CONTROLLABLE.___PassingWaypoint", n, N, WaypointFunction, unpack(WaypointFunctionArguments or {}))} + end + end return route end + --- Task function when controllable passes a waypoint. + -- @param #CONTROLLABLE controllable The controllable object. + -- @param #number n Current waypoint number passed. + -- @param #number N Total number of waypoints. + -- @param #function waypointfunction Function called when a waypoint is passed. + function CONTROLLABLE.___PassingWaypoint(controllable, n, N, waypointfunction, ...) + waypointfunction(controllable, n, N, ...) + end + + --- Make the AIR Controllable fly towards a specific point. -- @param #CONTROLLABLE self -- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to.