diff --git a/Wrapper/Group/504-Pinpoint-Strike-Waypooints-and-Tasking/GRP-504-Pinpoint-Strike-Waypooints-and-Tasking.lua b/Wrapper/Group/504-Pinpoint-Strike-Waypooints-and-Tasking/GRP-504-Pinpoint-Strike-Waypooints-and-Tasking.lua new file mode 100644 index 0000000..d8abcc2 --- /dev/null +++ b/Wrapper/Group/504-Pinpoint-Strike-Waypooints-and-Tasking/GRP-504-Pinpoint-Strike-Waypooints-and-Tasking.lua @@ -0,0 +1,148 @@ +--- +-- Author: Wingthor +-- Created: 22.08.2020 +-- Contributors: kaltokri +-- Modified: 23.02.2024 +-- +-- # Documentation: +-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Wrapper.Group.html +-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Point.html +-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Scheduler.html +-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Spawn.html +-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Wrapper.Static.html +-- +-- # Description: +-- Mission illustrates how to make an air GROUP do a bomb run by script. +-- One template group is placed on map by DCS's Mission Editor. +-- Template is set to TASK "Ground Attack" and given proper ordonance in Mission Editor. +-- One function handles both attacks by give targets coordinates as arguments. +-- This also shows how to do a delayed function call using BASE:ScheduleOnce function. +-- Mission also feature a helper function which will return a random waypoint between Airbase and Target. +-- +-- # Guide: +-- 1. Start the mission and wait 5 seconds +-- 2. Press F2/F10 to observe the attack run of the blue aircrafts +-- 3. Use time acceleration to shorten waiting times + +-- Enable tracing when the mission doesn't work as expected. +--BASE:TraceOnOff(true) +--BASE:TraceAll(true) + +--- This function will make a random waypoint between two coordinates. +-- @param Core.Point#COORDINATE TargetCoordinate Coordinate of the target +-- @param Core.Point#COORDINATE InitCoordinate Initial Coordinate +function MakeMiddleWaypoint (TargetCoordinate, InitCoordinate) + BASE:F({TargetCoordinate,InitCoordinate}) + + -- If we can not resolve the parameters throw noting back so we don't break anything. + if TargetCoordinate == nil or InitCoordinate == nil then return nil end + + local _TargetCoordinate = TargetCoordinate -- Core.Point#COORDINATE + local _InitCoordinate = InitCoordinate -- Core.Point#COORDINATE + local Distance = TargetCoordinate:Get3DDistance( InitCoordinate ) + + if Distance < 30000 then + return nil -- To close for us + elseif Distance > 70000 then + Distance = 70000 + else + Distance = math.random(30000,70000) + end -- This is max distance from target we want our Waypoint + + local Direction = _TargetCoordinate:GetAngleDegrees(_TargetCoordinate:GetDirectionVec3(_InitCoordinate)) + + if Direction > 0 and Direction <=90 then -- North East + return _TargetCoordinate:Translate( Distance, math.random(1,90) ) + elseif Direction > 90 and Direction <= 180 then -- South East + return _TargetCoordinate:Translate( Distance, math.random(91,180) ) + elseif Direction > 180 and Direction <= 270 then -- South West then + return _TargetCoordinate:Translate( Distance,math.random(181,270) ) + elseif Direction > 270 and Direction <= 360 then -- South West then then + return _TargetCoordinate:Translate( Distance,math.random(271,360) ) + else + BASE:E("--- Something wrong in function MakeMiddleWaypoint ---") + return nil + end +end + + +--- Function to order a strike +-- @param #string Group Name of the group +-- @param Core.Point#COORDINATE Target Coordinates of the target +-- @param #string Base Name of the home base +-- @param #string TargetDescription Description of the target +function PinpointStrike( Group, Target, Base, TargetDescription ) + BASE:F({ Group, Target, Base }) + + -- nil check for arguments. + if Group == nil or Target == nil or Base == nil then return nil end + + -- Make a default description + if TargetDescription == nil then + TargetDescription = "Bomb Target" + end + + -- Make a Random heading from the target which will serve as an IP (90-180°) + local heading = math.random( 90, 180 ) + + -- Get targets vectors + local targetVec = Target:GetVec2() + + -- Make a Spawn counter + if SpawnCounter == nil then + SpawnCounter = 0 + else + SpawnCounter = SpawnCounter + 1 + end + + -- Spawn the bomber and return a GROUP object + local SpawnBomber = SPAWN:NewWithAlias( Group, "Bomber_" .. tostring(SpawnCounter) ) + :OnSpawnGroup( + --- @param + function ( group ) + group:MessageToBlue( "Launching the Pinpoint strike", 40 ) + end, {} + ) + + local homebasecoords = AIRBASE:FindByName(Base):GetCoordinate() --Core.Point#COORDINATE + local bomber = SpawnBomber:SpawnAtAirbase( AIRBASE:FindByName( Base ), SPAWN.Takeoff.Cold ) + local task = bomber:TaskBombing( targetVec, false, "All", nil, heading, 10000) + + --- Make a waypoint table + local waypoints = {} + + --- Get coordinate for Home Base + local homecoords = AIRBASE:FindByName(Base):GetCoordinate():SetAltitude(8000):Translate(10 * 10000,300) + + -- Make an ingress point for the bomber + local IngressPoint = MakeMiddleWaypoint( Target, homebasecoords ) --Core.Point#COORDINATE + if IngressPoint == nil then -- Its important to handle the edge cases so we don't break anything. Better throw something to log. + BASE:E("--- Error in PinpointStrike target is too close to base ---" ) + return nil + end + + -- Set the coordinate altitude + IngressPoint:SetAltitude(8000) + + -- Add coordinates to table and make Waypoints + waypoints[1] = homebasecoords:WaypointAirTakeOffParking() + waypoints[2] = IngressPoint:WaypointAirTurningPoint( nil, 950, {task}, TargetDescription ) + waypoints[3] = homecoords:WaypointAirTurningPoint() + waypoints[4] = homebasecoords:WaypointAirLanding() + + -- Push the waypoint table the bomber + bomber:Route( waypoints ) + +end + +-- local targetCoords = ZONE:New("Blue Bridge"):GetCoordinate() +local CommandCenterCoords = STATIC:FindByName( "SAM ControlCenter", false ):GetCoordinate() -- Core.Point#COORDINATE + +-- I have added a small zone over a scenery object in order to grab the coordinates. +local SceneryTargetCoordiate = ZONE:New("SceneryTarget"):GetCoordinate() + +-- Call the function PinpointStrike 5 seconds after mission start with 4 parameters: Group, Target, Base, TargetDescription +BASE:ScheduleOnce( 5, PinpointStrike, "Blue Owl 1-1", CommandCenterCoords, AIRBASE.Caucasus.Sukhumi_Babushara, "Bomb Command Center" ) + +-- Call the function PinpointStrike 10 seconds after mission start with 4 parameters: Group, Target, Base, TargetDescription +BASE:ScheduleOnce( 10, PinpointStrike, "Blue Owl 1-1", SceneryTargetCoordiate, AIRBASE.Caucasus.Sukhumi_Babushara, "Bomb Commanders House" ) diff --git a/Wrapper/Group/504-Pinpoint-Strike-Waypooints-and-Tasking/GRP-504-Pinpoint-Strike-Waypooints-and-Tasking.miz b/Wrapper/Group/504-Pinpoint-Strike-Waypooints-and-Tasking/GRP-504-Pinpoint-Strike-Waypooints-and-Tasking.miz new file mode 100644 index 0000000..1c9a10c Binary files /dev/null and b/Wrapper/Group/504-Pinpoint-Strike-Waypooints-and-Tasking/GRP-504-Pinpoint-Strike-Waypooints-and-Tasking.miz differ