DarkCrow Posted September 18, 2016 Posted September 18, 2016 I want to learn simple scripting functions in DCS but I am having a very difficult time with what I think should be a simple task. I've been at this simple task for 2 days and I haven't made any headway. So am I even in the ballpark. My goal is to have a ME trigger the script (which I already have that down) for the infantry unit to walk to my helicopter. I have tried creating moving zones. All kinds of stuff but I always get a scripting error. I was able to use the goToPoint function with a static zone setup in the mission editor without any scripting errors but the infantry unit just ran in circles. My goal for the script below when ran was : Detect helicopters position and create a trigger zone there for use in the goToPoint function. Execute goToPoint function using created TriggerZone Am I even close? Sent from my iPhone using Tapatalk
Panhead Posted September 18, 2016 Posted September 18, 2016 Off Topic RE: Screenshot with your phone. LOL ;) Try this instead: 1) Snipping Tool that ships with Windows -or- 2) http://puush.me/ Sorry, but I couldn't resist.
DarkCrow Posted September 18, 2016 Author Posted September 18, 2016 Off Topic RE: Screenshot with your phone. LOL ;) Try this instead: 1) Snipping Tool that ships with Windows -or- 2) http://puush.me/ Sorry, but I couldn't resist. No problem. Normally I would but I currently don't have internet at my house. My cell service is also poor where I'm at so I can't use it as a hotspot. Sent from my iPhone using Tapatalk
Grimes Posted September 19, 2016 Posted September 19, 2016 Two things, mostly syntax related. 1. The mist.getLeadPos() function returns a vec 3 coordinate, which is roughly in the same format that a trigger zone uses. There is no second input variable for it. local triggerZone = mist.getLeadPos('Player Unit') To help visualize it, here is an example of the difference between what you made, what mist.getLeadPos returns, and what a triggerZone table looks like. It is worth mentioning that the function mist.groupToPoint can use either a vec3 or triggerZone table format for the point value. {{x = number, y = number, z = number}, 10} -- What you made {x = number, y = number, z = number} -- Vec3 coordinate and what mist.getLeadPos returns {point = {x = number, y = number, z = number}, radius = number} -- What a triggerZone table looks like 2. By using 'TriggerZone' within the groupToPoint function you are making it look for a zone defined in the editor with the name 'TriggerZone' and not the table variable you created in the lines above. So just remove the quotes and it will directly use the variable you created named TriggerZone. mist.groupToPoint('Infantry Group #001', TriggerZone) 1 The right man in the wrong place makes all the difference in the world. Current Projects: Grayflag Server, Scripting Wiki Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread) SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum
DarkCrow Posted September 19, 2016 Author Posted September 19, 2016 Ty Grimes for taking the time to help me. I won't have time until this weekend to play with it again so I will let you know. I downloaded the lua binaries on my work laptop and installed lua on it and downloaded the free first edition of Programming with Lua by Roberto in hopes to learn more about coding/scripting so I can understand the syntax logic if that makes any sense. Thanks again this has sparked my interest. Sent from my iPhone using Tapatalk
DarkCrow Posted September 25, 2016 Author Posted September 25, 2016 (edited) groupToPoint in Mist for the complete newbie to scripting Seems that no matter how I write it it gives me an error saying that I'm trying to index a global object = to a nil value I also , instead of using mist.getLeadPos, tried object.getPoint which also returns a Vec3 table. Another question I have is where are the global values written? In the mission lua file I can't find unit names. What I attempted to do was run the mission lua in ZeroBrane by dofile then try to print a 'simulated' function that calls on global values and they were also = to nil. I then searched the mission lua and realized the unit names were not in there. A simple example of what I did in ZeroBrane to test if it could be done = -- File Name = globalValue.lua -- a = 10 --------------- -- File Name = globalValueCall.lua -- dofile ('globalValue.lua') print (a) --> 10 Sent from my iPhone using Tapatalk Edited September 25, 2016 by DarkCrow
DarkCrow Posted September 26, 2016 Author Posted September 26, 2016 (edited) This is the latest iteration of what I have been trying. I'm guessing that the global values must first be called into a local function otherwise their values would still be nil. Is this correct? do local groupNames = mist.DBs.groupsByName vec3 = mist.getLeadPos(PlayerUnit) -- or vec3 = Object.getPoint(PlayerUnit) function mist.groupToPoint (InfantryGroup001 , vec3) end end I get a error saying that either the mist.getLeadPos or the Object.getPoint is trying to index a global value that is = to nil. Or something along those lines. So, after looking through the MIST manual, I wrote this following code to simulate what I think these functions are trying to do to get the vec3 value of a specified unit. I am still getting a nil value return. Am I thinking about this right? do local -- Simulate mist.DBs.groupsByName -- groupNames = { { InfantryGroup001, blue, USA, Vehicle, 1, -- example (unknown) 1, -- example (unknown) uncontrolled, false, -- not hidden (not sure if this is boolean) startTime, { InfantryUnit001, InfantryGroup001, x, -- vec2? y, -- vec2? point, --vec3? blue, USA, vehicle, infantry, skill, unitId, 1, -- example (unknown) 1, -- example (unknown) startingPointVec2 } }, { PlayerGroup, blue, USA, helicopter, 2, -- example (unknown) 1, -- example (unknown) false, -- says "uncontrolled" assuming it is boolean? false, -- says "hidden" assuming it is boolean? startTime, frequency, modulation, radioSet, { PlayerUnit, PlayerGroup, x, -- vec2? y, -- vec2? point = {x,y,z}, --vec3? blue, USA, helicopter, SA342M, player, unitId, 2, -- example (unknown) 1, -- example (unknown) startingPointVec2, speed, livery_id, onboard_num, callsign, psi, AddPropAircraft, } } } -- End Simulate mist.DBs.groupsByName -- -- Simulate Object.getPoint or mist.getLeadPos by returning point as Vec3 -- print (point) --> returns nil value -- End Simulate Object.getPoint or mist.getLeadPos by returning point as Vec3 -- end Any guidance is greatly appreciated as I begin this long journey of learning this stuff :smilewink: edit: I just tested my simulated code in a much simpler way and found out that I can't print values from inside a table the way I did it above. I'm guessing that there is more complex way of extracting the values from a table :doh: do local table = { vec3 = {x,y,z} } print (vec3) --> returns nil end Edited September 26, 2016 by DarkCrow
nomdeplume Posted September 26, 2016 Posted September 26, 2016 (edited) I just tested my simulated code in a much simpler way and found out that I can't print values from inside a table the way I did it above. I'm guessing that there is more complex way of extracting the values from a table :doh: do local table = { vec3 = {x,y,z} } print (vec3) --> returns nil end First, your "do local" is a bit strange, and is more normally written the way lua will interpret it: do local table = { ... } end i.e. you are creating a local variable called 'table' which only exist within the scope of the do/end block. So: you've created a local variable called "table" which has "vec3" as one of its keys (the value of which is another table). You can't print "vec3" because it does not exist (therefore it's nil). print(table.vec3) is probably what you want. If it works, it will just print "table: 0x12341234". You can also use table["vec3"] to access that element of it. The dot notation is more convenient for directly accessing them in your code; the array access is useful when the name of the field is contained within a variable. i.e. ages = {alice = 26, bob = 22} print(ages.alice) -- prints 26 person = "alice" print(ages[person]) -- also prints 26 --- Hopefully that's clear, so next thing: you probably shouldn't use the name 'table' for your tables, because it's actually a lua built-in. If you overwrite it you'll lose access to some functionality you might potentially want to use one day. So, best kick the habit early. --- In your first example, where you put function mist.groupToPoint (InfantryGroup001 , vec3) endyou are declaring a function named mist.groupToPoint, not calling the existing function! Also, if "InfantryGroup001" is the name of your group, then you should be quoting it. Without the quotes you would be passing it a variable named InfantryGroup001, which is probably not defined (nil). The easiest way to use the function if you're just starting would be to send the group to a trigger zone you've added in the mission editor: mist.groupToPoint("InfantryGroup001", "Zone name") This is because mist.groupToPoint() passes the provided point through a function which will, if it's a table, use the point.x, point.y and point.z elements, or the x, y, and z elements; and if it's a string, it'll try to find a trigger zone with the same name and use the centre of that as the location. Which basically means it can be called with a point directly (DCS scripting environment 'Vec3' table), a trigger zone 'object', or the name of a trigger zone (as a string). Edited September 26, 2016 by nomdeplume
nomdeplume Posted September 26, 2016 Posted September 26, 2016 I then searched the mission lua and realized the unit names were not in there. Just to try to add some clarity here. The group/unit names are not lua variables. In the scripting environment, groups and units are objects, which in lua really means it's just a table with specific keys/values. I think most of the 'objects' are just tables with a single "id" key which has the unit/group/whatever number which uniquely identifies that object, and all the calls into the game engine use that to identify it and return the data you want. The innards don't matter though - from your point of view, a unit is an "object". There is a global function that allows you to get a unit object from the name given to it in the mission editor, Unit.getByName(), which you would use like: local unit = Unit.getByName("My First Unit") local unitpos = unit:getPoint() env.info(string.format("Unit is at: %.2f, %.2f", unitpos.x, unitpos.z)) That should log a line with the X and Z (north/east) coordinates of the unit named "My First Unit" into the dcs.log. So, to explain line by line: unit = Unit.getByName("My First Unit")This calls Unit.getByName() which is one of the scripting environment built-in functions to get the unit with the given name. If that unit does not exist, it will return nil. You should normally check for that in real code, otherwise you'll get errors when you try to access it. This will create a local variable named unit which contains the unit 'object' mentioned above. --- local unitpos = unit:getPoint()This creates another variable called unitpos which - assuming the previous call actually worked and returned a valid unit object - will contain the position of the unit - Unit.getPoint() returns a "vec3" object, i.e. a table with x, y and z keys, each of which contain the corresponding distance/position value (in metres from the map origin point). The varname colon(:) functionname syntax is lua's notation for calling a 'method' on an object, and in this case it's basically equivalent to: local unitpos = Unit.getPoint(unit)but, to me, a little easier to understand. Essentially the : is telling Lua to call the function and pass the variable itself as the first parameter. Again, the details don't really matter - so long as you understand the syntax. --- env.info(string.format("Unit is at: %.2f, %.2f", unitpos.x, unitpos.z))Despite appearances, this is a fairly simple way to output stuff. It calls two functions: env.info() which accepts a string to log; and string.format(), to which you pass a string with special formatting characters and then the variables you want to interpolate into it. Basically it just provides an easier syntax than doing it yourself with string concatenation, which would otherwise look like: env.info("Unit is at :" .. unitpos.x .. ", " .. unitpos.z)although that output would be slightly different since it'd print every meaningful digit after the decimal point. 1
DarkCrow Posted September 26, 2016 Author Posted September 26, 2016 Ty nomdeplume, I will dissect and try to digest what you have written here when I get off work. Sent from my iPhone using Tapatalk
DarkCrow Posted October 2, 2016 Author Posted October 2, 2016 Finally got something that works!!! By works I mean the infantry does what they did when I tested the mist.groupToPoint with a static zone set in the Mission Editor. They ran around in circles never making it to their assigned point. But this script at least gets them doing that with the vec3 position of my helicopter. do local group = Group.getByName('InfantryGroupp001') local unit = Unit.getByName('PlayerUnit'):getPoint() local InfantryMovement = mist.groupToPoint(group, unit) end Anybody have any idea why they won't actually run to the location using the mist.groupToPoint function? Thank you again nomdeplume and Grimes for your help and guidance.
DarkCrow Posted October 2, 2016 Author Posted October 2, 2016 I was able to get the infantry to run to the helicopter using the mist.ground.buildWP and mist.goRoute functions instead of the mist.groupToPoint function. Here is the script: do local group = Group.getByName('InfantryGroup001') local startPoint = Unit.getByName('InfantryUnit001'):getPoint() local endPoint = Unit.getByName('PlayerUnit'):getPoint() local path = {} path[#path + 1] = mist.ground.buildWP (startPoint,'Off Road',5) path[#path + 1] = mist.ground.buildWP (endPoint,'Off Road',5) local route = mist.goRoute(group, path) end
Recommended Posts