Jump to content

Race timers


Shahdoh

Recommended Posts

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

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 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

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

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

  • Recently Browsing   0 members

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