Warmbrak Posted March 2, 2021 Posted March 2, 2021 Premise I have built a multiplayer mission that will test the ability of 8 participants where each follow a set of waypoints, and destroy targets with specific weapons. Upon landing, they taxi to an area, lower their tail hook (F-18) and receives their score (pass or fail). Each participant requires 6 conditions to be tracked for a total of 48. Using the ME and triggers to test for various conditions, I have a LOAD of triggers that caters for each individual candidate. Repurposing the mission becomes a nightmare based on the sheer number of triggers that need to be managed. My Goal To replace the 48 flags with an object that I can instantiate for each participant - OR - create a data object that can track x number of conditions for y number of candidates, set when instantiating the object. For each participant I would like to store a string with the participant's name, and then basically a boolean for each of the conditions. After the data object is instantiated at the start of the mission, I would like to access it using functions to set the conditions for each boolean for a specific participant id. Some of the functions would include testing for pre-defined conditions including the final evaluation. My Challenge I can read and understand code much better than I am able to produce it, and my LUA skills are limited. I have read the threads regarding LUA scripting for DCS in the ME, and I have seen examples of class definitions where such a data container can be defined, and member functions to access it. The problem is I don't really know how it all fits together, and even if something like this is going to work. Can I create a lua file that defines the class and member functions at the start, and can I in the same file instantiate the object, or do I need to instantiate if after the definition lua file has been called using DO SCRIPT? Is that object global, and can it be accessed by all subsequent DO SCRIPT calls to the member functions? It is safe to say that I know enough to be dangerous in this area. My Request I know it takes a lot of time for someone to look into something like this and I am not asking anyone to write any scripts for me. I have been looking for working examples missions that I can study by looking at the ME and the LUA files to try and understand how it all fits together, but I am probably looking in the wrong places as I can't seem to find anything. I am sure there are existing frameworks out there that might be able to do what I want, but I am trying to learn and understand the basics and would like to avoid those for the moment. If someone can please share with me an example they have that may shed some light on how these things fit together and how my goals can be accomplished it will be greatly appreciated - or point me in the right direction.
Grimes Posted March 2, 2021 Posted March 2, 2021 It doesn't strictly need to be an object in the sense of object oriented programming. You could just create a table and discrete functions that get passed the table that can manipulate the table or return a value for an entry within that table. It fits together depending on how you want to set it up, generally it is mostly a question of creating local or global variables and where you want to run the code. Anything set to local is only accessible within a given block that it is defined in. However you can still make a global function that has access to it as long as it is also defined within the same block. This would be useful if say you were to do a bit of a "hybrid" of using triggers and the scripting engine. You can always make it global anyway and always have access to it, but things in lua tend to run much smoother the fewer global variables you have. A quick dumb example. This bit would be in a do script. local players = {} function createPlayer(uName) local obj = Unit.getByName(uName) local pEntry = {unitName = uName, unitObj = obj, playerName = obj:getPlayerName(), atWP = 1, type = obj:getTypeName()} table.insert(players, pEntry) return pEntry end function unitSetAtWP(name, wp) for i = 1, #players do if players[i].unitName == name then players[i].atWP = wp end end end Then after it is declared you could call either createPlayer or unitSetAtWP anywhere. If you removed the local in front of players then the table itself could be accessible from anywhere. Its slightly convoluted, but within a block that you call createPlayer() you can make it a local variable within there that is a reference created by a global function of a local table from another block. I guess I'm trying to say is you can make everything global, but you can also make almost everything local except for a few global functions to transfer data between each block as needed. In terms of how I make stuff it tends to be as self contained as possible. If there is some config, customized, or is a general "tool" for others to use there will typically be something globally accessible. If it were some bespoke script I don't really intent to publish then it can all be in one big lua file that just needs to be loaded and has all the code within looped and kicked off on its own. 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
Warmbrak Posted March 3, 2021 Author Posted March 3, 2021 Thanks for responding Grimes. I think I understand what are you are saying but again I have trouble visualising how this would be implemented and play out. In my mission for instance the number of participants is capped to 8 players, and these are differentiated by 8 x F/A-18C slots, each in their own group. At the start of the mission I want to create the object/table that will house all the information. Seeing that not all players may be have logged in at the start of the mission, I will only detect once they are in by detecting a spawn slot being allocated, or for that group ID to pass a trigger check. If I understand correctly, I can call the script from your example at the start of the mission to declare the container 'players' and the two functions. With players being set to local, it cannot be accessed by any other do script or script files, but I can call the createPlayer and unitSetAtWP functions from any do script or script file subsequently? So the first candidate passes the first trigger. I now know there is a human occupying that slot (or I can detect the slot being taken up, but don't know how to do that yet). At the first trigger for candidate 1, I call 'createPlayer(CD1)', where CD1 is the group name of candidate 1's F-18 I specified in the ME? That will then create a '2D' table entry where the list pEntry gets added into the list/array 'players'. Call the same function for similar triggers for the other candidates will then insert their entries into the 'players' list. Sorry for repeating what you have written, but I am writing it out in the way that I understand it and will hopefully make it easier to catch things that I may be misunderstanding. I will test this out in the ME, thanks again!
Grimes Posted March 4, 2021 Posted March 4, 2021 20 hours ago, Warmbrak said: If I understand correctly, I can call the script from your example at the start of the mission to declare the container 'players' and the two functions. With players being set to local, it cannot be accessed by any other do script or script files, but I can call the createPlayer and unitSetAtWP functions from any do script or script file subsequently? Correct. But again you can keep everything self contained within a single script call, change players to be global, or whatever else you want in terms of setting it up. 20 hours ago, Warmbrak said: So the first candidate passes the first trigger. I now know there is a human occupying that slot (or I can detect the slot being taken up, but don't know how to do that yet). At the first trigger for candidate 1, I call 'createPlayer(CD1)', where CD1 is the group name of candidate 1's F-18 I specified in the ME? That will then create a '2D' table entry where the list pEntry gets added into the list/array 'players'. Call the same function for similar triggers for the other candidates will then insert their entries into the 'players' list. CD1 would have to be declared someplace to be a string of the unit's name. So it could be createPlayer('f18slot1') or local CD1 = 'f18slot1' createPlayer(CD1) When it runs createPlayer twice lets say, then the players table could look something like: { [1] = {unitName = 'f18slot2', unitObj = {obj}, playerName = 'Bob', atWP = 1, type = 'FA_18_HORNET'}, [2] = {unitName = 'f18slot5', unitObj = {obj}, playerName = 'whatever', atWP = 1, type = 'FA_18_HORNET'} } It is a little flawed because depending on the rules of how createPlayer is executed and if you don't delete anything then there could be multiple entries with the same unitName, which with how the unitSetAtWP function is written would just set that to the first entry it found with a matching unit name. 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
Warmbrak Posted March 4, 2021 Author Posted March 4, 2021 Grimes, thank you very much for your help! I had some trouble getting it working as I initialised my script file based on a trigger at mission start with time more than 10. This resulted in an error message although I was confident in my syntax; I changed the starting trigger from Mission Start to No Event instead and it worked. I am now able to set up custom flags, set the values after conditions are met and print results to the screen for a specific candidate by passing the unit name. With my mission being used in a relatively closed environment and then ends once all participants completes the course I hope to avoid the flaws you have pointed out. This will save a me lot of time in future when setting up similar scenarios. Thanks again.
Recommended Posts