Shahdoh Posted February 26, 2013 Share Posted February 26, 2013 (edited) I have successfully been using scripting to track a single aircraft through a course with accuracy to the hundredth of a second, but having a tough time figuring out how to do this for multiple aircraft at once. The initial table creation I understand, its when it gets to the gate checks to update each aircraft (only once) that I am having a tough time figuring out how to code it. Here is stripped down code (usually there are 17 gate checks) from my time trial mission: function RaceTimer() --Course entry if PilotOC == "open" then local Planes = mist.makeUnitTable( {'[red][plane]', '[red][helicopter]'} ) local inZoneUnit = mist.getUnitsInZones( Planes, {'Race_Course'} ) if #inZoneUnit > 0 then PilotOC = inZoneUnit[1]:getName() rb_running = 0 rb_start = 0 rb_split2 = 0 rb_stopped = 0 rb_total = 0 Gate1 = "off" -- Flags for Polygon gate checks -Start Gate2 = "off" Gate17 = "off" trigger.action.setUserFlag(1000, false) trigger.action.setUserFlag(1001, false) trigger.action.setUserFlag(1002, false) trigger.action.setUserFlag(1017, false) trigger.action.setUserFlag(2001, false) trigger.action.setUserFlag(2002, true) trigger.action.setUserFlag(2017, true) -- Flags for Polygon gate checks -End if CourseClosed == 0 then trigger.action.outText(PilotOC..' is on the course',5) CourseClosed = 1 end end end -- Course Entry end -- Gate 1 start if trigger.misc.getUserFlag(1000) == trigger.misc.getUserFlag(2001) and Gate1 == "off" then mist.flagFunc.units_in_polygon{ units = {PilotOC}, zone = {[1] = mist.DBs.unitsByName['G11'].point, [2] = mist.DBs.unitsByName['G12'].point, [3] = mist.DBs.unitsByName['G13'].point, [4] = mist.DBs.unitsByName['G14'].point,}, flag = 1001, stopflag = 2001, maxalt = 579.12, interval = .1 } Gate1 = "on" end if trigger.misc.getUserFlag(1001) == 1 and trigger.misc.getUserFlag(2001) == 0 then rb_start = timer.getTime() trigger.action.setUserFlag(1, true) trigger.action.setUserFlag(2002, false) trigger.action.setUserFlag(2003, false) trigger.action.setUserFlag(2004, false) trigger.action.setUserFlag(2001, true) trigger.action.outText('Gate 1 \n Timer started',2) end -- Gate 1 end -- Gate 2 Start if trigger.misc.getUserFlag(1000) == trigger.misc.getUserFlag(2002) and Gate2 == "off" then mist.flagFunc.units_in_polygon{ units = {PilotOC}, zone = {[1] = mist.DBs.unitsByName['G21'].point, [2] = mist.DBs.unitsByName['G22'].point, [3] = mist.DBs.unitsByName['G23'].point, [4] = mist.DBs.unitsByName['G24'].point,}, flag = 1002, stopflag = 2002, maxalt = 524.25, interval = .1 } Gate2 = "on" end if trigger.misc.getUserFlag(1002) == 1 and trigger.misc.getUserFlag(2002) == 0 then rb_split2 = timer.getTime() - rb_start trigger.action.setUserFlag(2003, false) trigger.action.setUserFlag(2004, false) trigger.action.setUserFlag(2005, false) trigger.action.setUserFlag(2001, true) trigger.action.setUserFlag(2002, true) if rb_split2 < rb_t_split2 then trigger.action.outText('Gate 2\n Time split: '..string.format("%.2f",rb_split2)..' ***',2) rb_t_split2 = rb_split2 rb_p_split2 = PilotOC else trigger.action.outText('Gate 2\n Time split: '..string.format("%.2f",rb_split2),2) end end -- Gate 2 end -- Gate 17 Start if trigger.misc.getUserFlag(1000) == trigger.misc.getUserFlag(2017) and Gate17 == "off" then mist.flagFunc.units_in_polygon{ units = {PilotOC}, zone = {[1] = mist.DBs.unitsByName['G11'].point, [2] = mist.DBs.unitsByName['G12'].point, [3] = mist.DBs.unitsByName['G13'].point, [4] = mist.DBs.unitsByName['G14'].point,}, flag = 1017, stopflag = 2017, maxalt = 579.12, interval = .1 } Gate17 = "on" end if trigger.misc.getUserFlag(1017) == 1 and trigger.misc.getUserFlag(2017) == 0 then rb_stopped = timer.getTime() - rb_start if rb_stopped < rb_t_stopped then trigger.action.outText('Gate 17\n Time split: '..string.format("%.2f",rb_stopped)..' *** \n Timer stopped, Race officials are calculating your time',10) rb_t_stopped = rb_stopped rb_p_stopped = PilotOC else trigger.action.outText('Gate 17\n Time split: '..string.format("%.2f",rb_stopped)..'\n Timer stopped, Race officials are calculating your time',10) end trigger.action.setUserFlag(1, false) trigger.action.setUserFlag(2015, true) trigger.action.setUserFlag(2016, true) trigger.action.setUserFlag(2017, true) end -- Gate 17 end end -- RaceTimer function end mist.scheduleFunction(RaceTimer, nil, timer.getTime(), 0.01) In the code, when the aircraft hits the gate in the polygon trigger area, it turns on the next 3 gates and turns off the gate it passed and several preceding gates ( so they can not be repeated). Since the trigger is being checked at 10 times per second, I only want the first occurrence, but this would not work when tracking multiple aircraft. Any help or info that you can provide would be great, or even better, a few minutes on TS or equivalant to talk over things. Thank you, Shahdoh Edited February 26, 2013 by Shahdoh Link to comment Share on other sites More sharing options...
Speed Posted February 26, 2013 Share Posted February 26, 2013 (edited) I got a lot of stuff going on, but I'll check it out when I get a chance. The first thing that comes to mind though is why are you using flags? Lua doesn't need them. Nothing needs them now, in fact, you can just use Lua variables. Instead of flag 1001, which only God knows what that means, you can use a variable named something like, raceStarted = true And now you know what in the heck that means. Additionally, 1.2.3 adds the new trigger condition for a Lua expression. So if you need to interface back with triggers, you can just use this for your Lua expresssion (assuming you want to have a trigger condition based off of the raceStarted Lua variable): return raceStarted And that trigger condition will be true of raceStarted is anything other than nil or false. Oh and finally, when you post code in the forums, please place it inside boxes, not boxes (or if it is in a box, put it inside a [code] box inside the box). I can't read the code you posted without copying it into Notepad++ and adding in the tabs for the various closure levels or whatever they are called. Edited February 26, 2013 by Speed Intelligent discourse can only begin with the honest admission of your own fallibility. Member of the Virtual Tactical Air Group: http://vtacticalairgroup.com/ Lua scripts and mods: MIssion Scripting Tools (Mist): http://forums.eagle.ru/showthread.php?t=98616 Slmod version 7.0 for DCS: World: http://forums.eagle.ru/showthread.php?t=80979 Now includes remote server administration tools for kicking, banning, loading missions, etc. Link to comment Share on other sites More sharing options...
Shahdoh Posted February 26, 2013 Author Share Posted February 26, 2013 Thanks for the info about posting code, sorry about that and will be sure to fix that in the future. The flags are carry overs from when I was trying to use standard trigger zones for the course. As I adapted it to LUA code, I left them in because I knew what they were. Also, some mist functions like the polygon zones still use flags as well. But your right, the regular variable names would make things easier. :) Link to comment Share on other sites More sharing options...
Speed Posted February 26, 2013 Share Posted February 26, 2013 Thanks for the info about posting code, sorry about that and will be sure to fix that in the future. The flags are carry overs from when I was trying to use standard trigger zones for the course. As I adapted it to LUA code, I left them in because I knew what they were. Also, some mist functions like the polygon zones still use flags as well. But your right, the regular variable names would make things easier. :) True. We probably need a mist.unitsInPolygonZone scripting function... I actually thought that there was one, but it looks like I was wrong- mist.flagFunc.units_in_polygon actually uses mist.pointInPolygon internally. So you would need to re-write your script to get unit positions and then use mist.pointInPolygon on those unit positions, and that would free you from ever needing to use flags again. Anyway, I just created a set of flag-like Lua conditions for use with the new LUA EXPRESSION trigger condition- I haven't tested the code yet though. The point of these Lua conditions is to emulate flag-like behavior, but use Lua to do so that you can have conditions with actual names instead of random confusing numbers, you can use whatever logical comparisons you want, you can bypass the 100 flag limit on stop conditions, etc. condition = { create = function(value) value = value or false local timeSet if value then timeSet = timer.getTime() end local new = {} new.value = value new.timeSet = timeSet setmetatable(new, {__index = condition}) return new end, getTimeSet = function(self) return self.timeSet end, isTrue = function(self) if not self.value or type(self.value) == 'number' and self.value == 0 then return false else return true end end, isFalse = function(self) if not self.value or type(self.value) == 'number' and self.value == 0 then return true else return false end end, timeSinceMoreThan = function(self, time) -- time since set to true is more than and condition is true. if self:isTrue() and self.timeSet then return self.timeSet > time else return false end end, timeSinceLessThan = function(self, time) if self:isTrue() and self.timeSet then return self.timeSet < time else return false end end, setTrue = function(self) self.value = true self.timeSet = timer.getTime() end, on = setTrue, setFalse = function(self) self.value = false end, off = setFalse, addValue = function(self, value) self.value = self.value + value self.timeSet = timer.getTime() end, setValue = function(self, value) self.value = value if value then self.timeSet = timer.getTime() end end, getValue = function(self) return self.value end, valueEqual = function(self, value) if type(self.value) == type(value) then return self.value == value else return false end end, valueLessThan = function(self, value) if self.value and type(self.value) == type(value) then return self.value < value else return false end end, valueMoreThan = function(self, value) if self.value and type(self.value) == type(value) then return self.value > value else return false end end, } -- At mission start, define your conditions in a DO SCRIPT action. Conditions initialized to false if no value given. ZugdidiCaptured = condition.create() -- When when you want to set this condition true, call this in a DO SCRIPT action ZugdidiCaptured:setTrue() -- when you want a trigger condition based off of this Lua condition, use these scripts in a LUA EXPRESSION trigger condition: -- example 1: is Zugdidi captured? return ZugdidiCaptured:isTrue() -- example 2: is Zugdidi not captured? return ZugdidiCaptured:isFalse() -- example 3: was Zugdidi captured more than 30 minutes ago? return ZugdidiCaptured:timeSinceMoreThan(1800) -- example 4: was Zugdidi captured less than 30 minutes ago? return ZugdidiCaptured:timeSinceLessThan(1800) Anyway, I'll probably make a post eventually on how to use Lua conditions, and how to replace your flag conditions with Lua conditions. Basically, there is really no need to ever use flags again :) Intelligent discourse can only begin with the honest admission of your own fallibility. Member of the Virtual Tactical Air Group: http://vtacticalairgroup.com/ Lua scripts and mods: MIssion Scripting Tools (Mist): http://forums.eagle.ru/showthread.php?t=98616 Slmod version 7.0 for DCS: World: http://forums.eagle.ru/showthread.php?t=80979 Now includes remote server administration tools for kicking, banning, loading missions, etc. Link to comment Share on other sites More sharing options...
Recommended Posts