Rapier-VCG- Posted March 9, 2020 Share Posted March 9, 2020 Hoping someone will be able to hep me out with this Lau Script. Objective is to have a script constantly see what a current fuel level of a aircraft unit is, and when it dips below a set level, it set a task to air to air refuel if a tanker is on the grid. just starting to try and Lau code AI behavior, but have gone though the Mist read me and I don't see anything that will pull the aircraft data. Link to comment Share on other sites More sharing options...
dark_wood Posted March 9, 2020 Share Posted March 9, 2020 First, is LUA not LAU. Second, you can also use (together with MIST) DCS functions: https://wiki.hoggitworld.com/view/Category:Functions In your case, getFuel: https://wiki.hoggitworld.com/view/DCS_func_getFuel Happy coding :) Link to comment Share on other sites More sharing options...
shnicklefritz Posted March 9, 2020 Share Posted March 9, 2020 (edited) Hoping someone will be able to hep me out with this Lau Script. Objective is to have a script constantly see what a current fuel level of a aircraft unit is, and when it dips below a set level, it set a task to air to air refuel if a tanker is on the grid. just starting to try and Lau code AI behavior, but have gone though the Mist read me and I don't see anything that will pull the aircraft data. Tasking an AI to go to the nearest tanker at a given fuel level is not challenging. The difficulty arises when deciding 1) when the aircraft should NOT go for fuel; and 2) after the aircraft is done refueling, what then? Once an AI is done refueling at a tanker, it will simply return to its route. And if the next route is return to base, it will do so. Example: if an aircraft is on its way to base from a mission, if it meets the parameters, i.e., below percentage of fuel, it could abandon its approach and attempt to go to the nearest tanker, which could be 200nm away. Here is a start. To run this: 1) change the names "Hornet", "Hornet2" in the aircraft table to the group names in the mission editor that you want to track. You can add group names to the table, just make sure they follow the same format, i.e., wrapped in "" followed by a comma. 2) Change the percentage to your liking. Right now its set to send the AI once the get to or below 30%. 3) Set how often you want the function to run. Currently, it will check every 30 seconds. You can change that to whatever you want. Make sure it is a number. 4) Set trigger in the mission editor "ONCE," no conditions, Do script, and paste the below code in the box. 5) Set another trigger with a time delay of whatever, 30 seconds, doesn't matter, but should be at least 1 second, Do script and paste fuelTracker() in it. This will run the function once, but then the function is built to repeat itself ever x amount of seconds (as you set in the lowFuelCheckTime parameter). I will add to this when I have time. Hopefully this will help you get started. lowFuelPercentage = 30 lowFuelCheckTime = 30 aircraftTable = { "Hornet", "Hornet2", } aircaftLowFuel = {} function fuelTracker() local tempTable = {} for i, grp in pairs(aircraftTable) do if grp ~= nil then local group = Group.getByName(grp) if group:isExist() == true then local units = group:getUnits() if units ~= nil then for x, unit in pairs(units) do tempTable[#tempTable+1] = unit:getName() end end end end end for i, val in pairs(tempTable) do if val ~= nil then local unit = Unit.getByName(val) local fuel = unit:getFuel() local fuelThresh = (lowFuelPercentage *.01) if fuel / 1 <= fuelThresh then local dispFuel = math.floor(fuel) local groupName = unit:getGroup():getName() if not aircaftLowFuel[groupName] then aircaftLowFuel[groupName] = {unitName = unit:getName(), fuel = unit:getFuel() / 1} end end end end for groupName, t in pairs(aircaftLowFuel) do if groupName then goToTanker(groupName) aircaftLowFuel[groupName] = nil end end timer.scheduleFunction(fuelTracker, {}, timer.getTime() + lowFuelCheckTime) end function goToTanker(groupName) local group = Group.getByName(groupName) local task = { id = 'Refueling', params = {} } local controller = group:getController() controller:pushTask(task) end Edited March 9, 2020 by shnicklefritz Link to comment Share on other sites More sharing options...
xXMustangXx Posted March 10, 2020 Share Posted March 10, 2020 Tasking an AI to go to the nearest tanker at a given fuel level is not challenging. The difficulty arises when deciding 1) when the aircraft should NOT go for fuel; and 2) after the aircraft is done refueling, what then? Once an AI is done refueling at a tanker, it will simply return to its route. And if the next route is return to base, it will do so. Example: if an aircraft is on its way to base from a mission, if it meets the parameters, i.e., below percentage of fuel, it could abandon its approach and attempt to go to the nearest tanker, which could be 200nm away. Here is a start. To run this: 1) change the names "Hornet", "Hornet2" in the aircraft table to the group names in the mission editor that you want to track. You can add group names to the table, just make sure they follow the same format, i.e., wrapped in "" followed by a comma. 2) Change the percentage to your liking. Right now its set to send the AI once the get to or below 30%. 3) Set how often you want the function to run. Currently, it will check every 30 seconds. You can change that to whatever you want. Make sure it is a number. 4) Set trigger in the mission editor "ONCE," no conditions, Do script, and paste the below code in the box. 5) Set another trigger with a time delay of whatever, 30 seconds, doesn't matter, but should be at least 1 second, Do script and paste fuelTracker() in it. This will run the function once, but then the function is built to repeat itself ever x amount of seconds (as you set in the lowFuelCheckTime parameter). I will add to this when I have time. Hopefully this will help you get started. lowFuelPercentage = 30 lowFuelCheckTime = 30 aircraftTable = { "Hornet", "Hornet2", } aircaftLowFuel = {} function fuelTracker() local tempTable = {} for i, grp in pairs(aircraftTable) do if grp ~= nil then local group = Group.getByName(grp) if group:isExist() == true then local units = group:getUnits() if units ~= nil then for x, unit in pairs(units) do tempTable[#tempTable+1] = unit:getName() end end end end end for i, val in pairs(tempTable) do if val ~= nil then local unit = Unit.getByName(val) local fuel = unit:getFuel() local fuelThresh = (lowFuelPercentage *.01) if fuel / 1 <= fuelThresh then local dispFuel = math.floor(fuel) local groupName = unit:getGroup():getName() if not aircaftLowFuel[groupName] then aircaftLowFuel[groupName] = {unitName = unit:getName(), fuel = unit:getFuel() / 1} end end end end for groupName, t in pairs(aircaftLowFuel) do if groupName then goToTanker(groupName) aircaftLowFuel[groupName] = nil end end timer.scheduleFunction(fuelTracker, {}, timer.getTime() + lowFuelCheckTime) end function goToTanker(groupName) local group = Group.getByName(groupName) local task = { id = 'Refueling', params = {} } local controller = group:getController() controller:pushTask(task) end Very Useful!!! would this work even if the AI have fuel tanks? Thanks Link to comment Share on other sites More sharing options...
shnicklefritz Posted March 10, 2020 Share Posted March 10, 2020 Very Useful!!! would this work even if the AI have fuel tanks? Thanks Yes it will. The only thing, that I am aware of, with fuel tanks is that -n aircraft will return greater than 1.00 or 100% with fuel tanks. So for example, when fully fueled with fuel tanks, a hornet might show 1.45 (145%) or whatever; I am making that up. But it will steadily reduce to 0 over time and doesn’t effect the script. Disclaimer: I haven’t tested this script without a tanker, meaning it might throw an error when tasking the AI if the tanker is killed, RTBs, or otherwise disappears from the missions. I am away from my desktop and will not be able to test it until later this week. But I will try to add something in anyway when I get time. Link to comment Share on other sites More sharing options...
shnicklefritz Posted March 11, 2020 Share Posted March 11, 2020 (edited) Updated the above code, if anyone is interested. Accepts both coalitions. If a proper tanker isn't available, i.e., need a boom but only basket is available, the aircraft ignores the command. No need to input aircraft names, automatically tracks all coalition aircraft that are refuellable in air and tasks them to refuel based on the parameters you set. You can set a parameter that if the aircraft is within x meters of base, it will ignore the task to refuel. Will update this, eventually, to add message to coalition when aircraft tasks to a tanker. lowFuelPercentage = 35 --number, percentage: percent when aircraft dips below that will prompt it to go for fuel lowFuelCheckTime = 60 --number, seconds: How often the function will check aricraft fuel levels lowFuelCoalition = "Blue" --string: "Both" or "Red" or "Blue" Which coalition are you sending to tanker distanceFromEnemy = 30000 --number, meters: 30km Not working at moment distanceFromBase = 92600 --number, meters: 92.6km (50nm) distance from final waypoint that a group will ignore the command to go to tanker aircraftTaskedToRefuel = {} function fuelTracker() local aircraftTable = {} local aircaftLowFuel = {} aircraftTable = populateAircraft() for i, grpName in pairs(aircraftTable) do if grpName ~= nil then if not aircraftTaskedToRefuel[grpName] then local group = Group.getByName(grpName) if group:isExist() == true then local closerToBase = areCloseToBase(grpName) if closerToBase == true then local units = group:getUnits() if units ~= nil then for x, unit in pairs(units) do if unit:hasAttribute("Refuelable") == true then if unit:hasAttribute("Tankers") == false then local fuel = unit:getFuel() if (fuel / .01) <= lowFuelPercentage then local groupName = unit:getGroup():getName() aircaftLowFuel[#aircaftLowFuel+1] = groupName end end end end end end end end end end for i, grpName in pairs(aircaftLowFuel) do if grpName then aircraftTaskedToRefuel[grpName] = {unitNo = {}} local group = Group.getByName(grpName) local units = group:getUnits() for x, unit in pairs(units) do aircraftTaskedToRefuel[grpName].unitNo[#aircraftTaskedToRefuel[grpName].unitNo+1] = {unitName = unit:getName(), unitFuel = unit:getFuel() / .01, unitCall = unit:getCallsign()} end end end for i, grpName in pairs(aircaftLowFuel) do if grpName then --local enemyNear = aircraftDetectedTars(groupName) --if enemyNear == false then goToTanker(grpName) aircaftLowFuel[grpName] = nil --end end end timer.scheduleFunction(fuelTracker, {}, timer.getTime() + lowFuelCheckTime) end function areCloseToBase(groupName) local points = mist.getGroupPoints(groupName) local maxWypt = 0 for i, v in pairs(points) do if i >= maxWypt then maxWypt = i end end local maxWyptPoint = points[maxWypt] local unitPos = Group.getByName(groupName):getUnit(1):getPoint() local distToHome = getDistanceAir(maxWyptPoint, unitPos) local maxDistFrom = distanceFromBase if distToHome >= maxDistFrom then return true else return false end end function checkForTanker(groupName) local side = Group.getByName(groupName):getCoalition() local groups = coalition.getGroups(side, 0) for i, group in pairs(groups) do if group then if group:isExist() == true then if group:getUnit(1):isActive() == true then if group:getUnit(1):hasAttribute("Tankers") == true then return true end end end end end end function goToTanker(groupName) local isTanker = checkForTanker(groupName) if isTanker == true then local group = Group.getByName(groupName) local task = { id = 'Refueling', params = {} } local controller = group:getController() controller:pushTask(task) end end refuelStopEvent = {} function refuelStopEvent:onEvent(event) if event.id == 14 and event.initiator:getPlayerName() == nil then local unit = event.initiator local group = unit:getGroup() --if #aircraftTaskedToRefuel[group:getName()].unitNo > 1 then --timer.scheduleFunction(removeGroupFromTasked, {group:getName()}, timer.getTime() + 20) --else timer.scheduleFunction(removeGroupFromTasked, {group:getName()}, timer.getTime() + 120) --end end end world.addEventHandler(refuelStopEvent) function removeGroupFromTasked(args) local groupName = args[1] aircraftTaskedToRefuel[groupName] = nil end function populateAircraft() local aircraftTable = {} local lowFuelCoaCheck = string.lower(lowFuelCoalition) if lowFuelCoaCheck == "blue" then local blueAircraft = coalition.getGroups(2,0) for i, ac in pairs(blueAircraft) do if ac ~= nil then if ac:isExist() == true then aircraftTable[#aircraftTable+1] = ac:getName() end end end end if lowFuelCoaCheck == "red" then local redAircraft = coalition.getGroups(1,0) for i, ac in pairs(redAircraft) do if ac ~= nil then if ac:isExist() == true then aircraftTable[#aircraftTable+1] = ac:getName() end end end end --lowFuelCoaCheck == "red" or "both" doesn't ****ing work... if lowFuelCoaCheck == "both" then local redAircraftAll = coalition.getGroups(1,0) local blueAircraftAll = coalition.getGroups(2,0) for i, ac in pairs(redAircraftAll) do if ac ~= nil then if ac:isExist() == true then aircraftTable[#aircraftTable+1] = ac:getName() end end end for i, ac in pairs(blueAircraftAll) do if ac ~= nil then if ac:isExist() == true then aircraftTable[#aircraftTable+1] = ac:getName() end end end end return aircraftTable end function getDistanceAir(point1, point2) local xUnit = point1.x local yUnit = point1.y local xZone = point2.x local yZone = point2.y local xDiff = xUnit - xZone local yDiff = yUnit - yZone return math.sqrt(xDiff * xDiff + yDiff * yDiff) end Edited March 11, 2020 by shnicklefritz Link to comment Share on other sites More sharing options...
xXMustangXx Posted March 11, 2020 Share Posted March 11, 2020 Awesome!! Thanks! Link to comment Share on other sites More sharing options...
Recommended Posts