Jump to content

Need help creating lau Script


Rapier-VCG-

Recommended Posts

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

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 by shnicklefritz
Link to comment
Share on other sites

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

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

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 by shnicklefritz
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...