johnboy Posted January 19, 2023 Posted January 19, 2023 (edited) Greetings! What I'm trying to achieve: ---------------------------- To create a volume of airburst explosions, to simulate flak dispersed horizontally and vertically around a point, with random (short) delays between explosions. What I did using standard triggers: ------------------------------------ 1. As a test, I spread nine small trigger zones around an airfield, named Explosion-1, -2 etc. 2. In ME, I made an action to spit out random values for FLAG 2 between 2-9. 3. Then I made a SWITCHED CONDITION for each of the random values. Each line checks the value of FLAG 2, fires the explosion, then re-sets the flag to value 1 to continue the loop. 4. In the ACTIONS panel, I changed the altitude of the explosion in each line, so that the flak bursts are spread vertically and well as horizontally. 5. I kept the altitude low (<200) so I could observe it more easily from a parked plane. 6. I kept the volume (power) of the explosions low (100) in my test but this could be set to 1 if the effect desired was visual rather than destructive. 7. Here are some screenshots of the map and triggers panel, if that's helpful: Spoiler The above set-up works well. However, I'd love to be able to do all triggering processes in a script. It seems to me (still learning lua) that the script might do the following things: ---------------------------------------------------------------------------------- 1. Get the vec3 coordinates for Point X in the middle of the area (perhaps the coordinates of a suitably placed vehicle) using a .getPoint thingie. 2. Create a number of new points (say, Points A-J for a ten-point field) scattered randomly (horizontally and vertically) around Point X, by making ten new x,y and z vec3 coordinates for each Point A-J. I think this could be done using a math.random thingie for x,y,z values? Perhaps then all the new coordinates could be stored in a table using a local BurstPoints_Table thingie? 3. Then create some code to detonate an EXPLOSION event at each of the randomly generated Points A-J at random (short, say 1-3 seconds) time intervals. For more timing randomness, perhaps one explosive array could be superimposed on top of another, running from a different mission time start point? 4. Continue this process until another trigger stops the loop, such as after a defined time or when a unit leaves the area. I have no idea how that could be done! In summary, the script would: ------------------------------- 1. Get a starting point. 2. Create randomly scattered points around it. 3. When triggered, randomly detonate explosions at those points. 4. Stop when required. Taking it to the next level: --------------------------- A next-level version of such a script might take the coordinates of a moving aircraft every few seconds and create the array of explosions in a pattern ahead and to the sides of the aircraft. Kind of a moving flak field, as though the AA gunners were tracking the aircraft/group. That might be difficult to script? My request: ------------ I'd be *super-grateful* if one of the community scripting wizards could give the main concept some thought (the next-level stuff can wait maybe). I am still on the lua learning pathway so I am yet to make the jump from know roughly what the script needs to do, to actually writing the code. My attempts so far produced errors or nothing. Previously cfrag and veteran66 helped me with some scripting, so I'm hoping they or others might be willing to continue to teach this stuff. Thanks and best wishes from Australia, John Edited January 19, 2023 by johnboy Intel i7-2600K 3.4Ghz ASUS P8P67 EVO Motherboard B3 Kingston HyperX KHX1600C9D3K2/8GX (2x4GB) DDR3 OCZ RevoDrive PCI-Express SSD 120GB Corsair Hydro Series H70 CPU Cooler 2 xWestern Digital Caviar Black 1TB WD1002FAEX TM Warthog Hotas TrackIR 5 Pro
johnboy Posted January 21, 2023 Author Posted January 21, 2023 Perhaps my post was in the tldr category? Here's what I have been able to come up with so far, with help from a scripting video by Ditch3r (highly recommended). This creates a single airburst explosion, offset from a unit on the x, y, and z axes. What I need to do next is find a way to produce a bunch of similar offsets, then detonate an explosion in each point, at a random time interval, for a period of time (say, 60 seconds). Can anyone help? John --Create an explosion offset in x,y and z space from a unit function ExplodeNearUnit(GroupName) ExplodeNearUnit = Group.getByName( GroupName ):getUnits() ExplodeVec3 = ExplodeNearUnit[1]:getPoint() ExplodeVec3.x = ExplodeVec3.x + math.random(-100,100) ExplodeVec3.z = ExplodeVec3.z + math.random(-100,100) ExplodeVec3.y = ExplodeVec3.y + math.random(0,200) trigger.action.explosion(ExplodeVec3, 100) -- Vec3 position, power end ExplodeNearUnit("Unit1") Intel i7-2600K 3.4Ghz ASUS P8P67 EVO Motherboard B3 Kingston HyperX KHX1600C9D3K2/8GX (2x4GB) DDR3 OCZ RevoDrive PCI-Express SSD 120GB Corsair Hydro Series H70 CPU Cooler 2 xWestern Digital Caviar Black 1TB WD1002FAEX TM Warthog Hotas TrackIR 5 Pro
cfrag Posted January 21, 2023 Posted January 21, 2023 2 hours ago, johnboy said: What I need to do next is find a way to produce a bunch of similar offsets, then detonate an explosion in each point, at a random time interval, for a period of time (say, 60 seconds). Can anyone help? John What you want to do is to invoke ExplodeNearUnit() for a number of time (say 45) staggered over the next 60 seconds. Thankfully that's easily done with timer.scheduleFunction() (you'll need a slight adaptation method for ExplodeNearUnit, see below). Randomize the time that the explosion happens, and you should be done. In all, only a few more lines function ExplodeNearUnit(GroupName) ExplodeNearUnit = Group.getByName( GroupName ):getUnits() ExplodeVec3 = ExplodeNearUnit[1]:getPoint() ExplodeVec3.x = ExplodeVec3.x + math.random(-100,100) ExplodeVec3.z = ExplodeVec3.z + math.random(-100,100) ExplodeVec3.y = ExplodeVec3.y + math.random(0,200) trigger.action.explosion(ExplodeVec3, 100) -- Vec3 position, power end -- make ExplodeNearUnit callable from scheduleFunction function timedExplosionNear(args) ExplodeNearUnit(args[1]) end -- create 45 explosions in the next randomly picked 60 seconds for i=1, 45 do timer.scheduleFunction(timedExplosionNear, {"Unit1"}, timer.getTime() + math.random(60)) end
johnboy Posted January 22, 2023 Author Posted January 22, 2023 (edited) 15 hours ago, cfrag said: What you want to do is to invoke ExplodeNearUnit() for a number of time (say 45) staggered over the next 60 seconds. Thankfully that's easily done with timer.scheduleFunction() (you'll need a slight adaptation method for ExplodeNearUnit, see below). Randomize the time that the explosion happens, and you should be done. In all, only a few more lines Hi Chris, thanks very much for taking a look at this for me. I'm afraid I'm getting errors when I run the script in DCS (see below). I've double-checked spelling etc but I don't really know enough to troubleshoot the problem. Is there something I'm supposed to add to the script, perhaps? Sorry to bother you with this. John Spoiler Edited January 22, 2023 by johnboy Intel i7-2600K 3.4Ghz ASUS P8P67 EVO Motherboard B3 Kingston HyperX KHX1600C9D3K2/8GX (2x4GB) DDR3 OCZ RevoDrive PCI-Express SSD 120GB Corsair Hydro Series H70 CPU Cooler 2 xWestern Digital Caviar Black 1TB WD1002FAEX TM Warthog Hotas TrackIR 5 Pro
ADHS Posted January 22, 2023 Posted January 22, 2023 (edited) 22 hours ago, johnboy said: ExplodeNearUnit("Unit1") A fast answer: Is this a UNIT's or a GROUP's name ? Does exist in the mission ? Edited January 22, 2023 by ADHS Democracy was already invented, while Scrat was eating oak fruits.
johnboy Posted January 22, 2023 Author Posted January 22, 2023 9 minutes ago, ADHS said: Is the a UNIT or a GROUP name ? Hey mate, it's both; the Group is Unit1 and so is the unit. Is that a problem? John Intel i7-2600K 3.4Ghz ASUS P8P67 EVO Motherboard B3 Kingston HyperX KHX1600C9D3K2/8GX (2x4GB) DDR3 OCZ RevoDrive PCI-Express SSD 120GB Corsair Hydro Series H70 CPU Cooler 2 xWestern Digital Caviar Black 1TB WD1002FAEX TM Warthog Hotas TrackIR 5 Pro
ADHS Posted January 22, 2023 Posted January 22, 2023 No problem from the time that do exists in the mission. Democracy was already invented, while Scrat was eating oak fruits.
johnboy Posted January 22, 2023 Author Posted January 22, 2023 19 minutes ago, ADHS said: No problem from the time that do exists in the mission. Still puzzled. In case the naming convention was the problem, I tried changing the name of the Group and Unit so that the Group was "Convoy1" and the unit was "Unit1", and also tried the Group name as "Unit1" and the unit as "Unit1-1". Both arrangements crashed to errors. I also made sure the script was being freshly injected into the mission file, in case there was an older script still embedded. No joy. When I run the mission with only the short script I posted above originally, the script works fine and I get one explosion in a random location, as expected. If it's any help, I've attached the mission file (that works) with just my simple first version embedded. Once again, I really appreciate any help that's offered! John FlakTesting-1.miz Intel i7-2600K 3.4Ghz ASUS P8P67 EVO Motherboard B3 Kingston HyperX KHX1600C9D3K2/8GX (2x4GB) DDR3 OCZ RevoDrive PCI-Express SSD 120GB Corsair Hydro Series H70 CPU Cooler 2 xWestern Digital Caviar Black 1TB WD1002FAEX TM Warthog Hotas TrackIR 5 Pro
ADHS Posted January 22, 2023 Posted January 22, 2023 Sorry mate but i am out of time here and have to go. Try Unit.getByName(GROUP[i]) as you are based on unit. And for multiple explossions use a random for to loop. 1 Democracy was already invented, while Scrat was eating oak fruits.
johnboy Posted January 22, 2023 Author Posted January 22, 2023 (edited) Okay, we have a solution. By removing the function: function timedExplosionNear(args) ExplodeNearUnit(args[1]) end ...the script ran perfectly, producing a nice volume of random bursts around and above the unit. See pic below. Because I'm a mere lua apprentice, I don't fully understand why the 'args' function was a problem. But, it works. The Group name is Unit1 and the unit name is Unit1-1, but the unit name doesn't matter it seems. The modified/working script is also below. Thanks all for your interest and assistance! John Spoiler Spoiler -- Create airburst explosions in a volume around and above a unit, to simulate flak. function ExplodeNearUnit(GroupName) ExplodeNearUnit = Group.getByName( GroupName ):getUnits() ExplodeVec3 = ExplodeNearUnit[1]:getPoint() ExplodeVec3.x = ExplodeVec3.x + math.random(-200,200) ExplodeVec3.z = ExplodeVec3.z + math.random(-200,200) ExplodeVec3.y = ExplodeVec3.y + math.random(50,200) -- the previous setting of the lower y-axis value to zero produced occasional ground bursts trigger.action.explosion(ExplodeVec3, 100) -- Vec3 position, power end -- Create 45 explosions in the next randomly picked 60 seconds - this part added by cfrag. Thank you! for i=1, 45 do timer.scheduleFunction(ExplodeNearUnit, "Unit1", timer.getTime() + math.random(60)) end Edited January 22, 2023 by johnboy 1 Intel i7-2600K 3.4Ghz ASUS P8P67 EVO Motherboard B3 Kingston HyperX KHX1600C9D3K2/8GX (2x4GB) DDR3 OCZ RevoDrive PCI-Express SSD 120GB Corsair Hydro Series H70 CPU Cooler 2 xWestern Digital Caviar Black 1TB WD1002FAEX TM Warthog Hotas TrackIR 5 Pro
cfrag Posted January 22, 2023 Posted January 22, 2023 (edited) 9 hours ago, johnboy said: the script ran perfectly, That threw me until I messed around with it myself. And I'm amazed: you actually managed to pull off a fully-blown Jedi code-trick! Let me explain: While reporting on the error that you received, you probably did not realize a small strange detail and therefore didn't mention it happening: the script works once (you hear one (1) BOOM!), and then suddenly it starts failing by throwing the error on all subsequent invocations. And then you managed to get the script to run although it really should not. Absolutely fantastic. This is because in the original script you (probably erroneously) redefine the method ExplodeNearUnit by assigning it the result of Group.getByName():getUnits() function ExplodeNearUnit(GroupName) ExplodeNearUnit = Group.getByName( GroupName ):getUnits() -- this redefines the method!!! ExplodeVec3 = ExplodeNearUnit[1]:getPoint() ExplodeVec3.x = ExplodeVec3.x + math.random(-100,100) ExplodeVec3.z = ExplodeVec3.z + math.random(-100,100) ExplodeVec3.y = ExplodeVec3.y + math.random(0,200) trigger.action.explosion(ExplodeVec3, 100) -- Vec3 position, power end As it happens in scripting so often, the ONLY condition where this isn't immediately obvious and will work without an error is when you schedule ExplodeNearUnit() directly for invocation like timer.scheduleFunction() and before it has been invoked even once. This unlikely combination of things is exactly what you did, Master Jedi ! [nod of respect] And of course, this then masks the erroneous redefinition of ExplodeNearUnit (because at the time the call is scheduled it hasn't been redefined and the scheduling process assigns the correct method location). That is the reason why it works even though it should (and will) not under any other circumstances (simply invoke ExplodeNearUnit directly from the loop to see it fail on the second and all other invocation). The workaround is easy: either rename the variable that you assign the result of Group.getByName():getUnits() or add a 'local' tag that prevents the global function being overwritten by the result: local ExplodeNearUnit = Group.getByName( GroupName ):getUnits() The corrected and fully timer-compatible script that will also work with non-timed invocations: function ExplodeNearUnit(GroupName) local ExplodeNearUnit = Group.getByName( GroupName ):getUnits() -- local!!! ExplodeVec3 = ExplodeNearUnit[1]:getPoint() ExplodeVec3.x = ExplodeVec3.x + math.random(-100,100) ExplodeVec3.z = ExplodeVec3.z + math.random(-100,100) ExplodeVec3.y = ExplodeVec3.y + math.random(50,200) trigger.action.explosion(ExplodeVec3, 100) -- Vec3 position, power end -- make ExplodeNearUnit callable from scheduleFunction function timedExplosionNear(args) ExplodeNearUnit(args[1]) end -- create 45 explosions in the next randomly picked 60 seconds for i=1, 45 do timer.scheduleFunction(timedExplosionNear, {"Unit1"}, timer.getTime() + math.random(60)) end Cheers, and thank you for a great sunday-morning mystery -ch Edited January 22, 2023 by cfrag 1
johnboy Posted January 22, 2023 Author Posted January 22, 2023 Wow! From coding noob to Jedi in one day! I've re-read your explanation half a dozen times to make sure I understand it. I'm convinced that lua coding is really black magic in disguise! Thank you for finding and fixing the gremlin! *thumbsup* Cheers, John 1 Intel i7-2600K 3.4Ghz ASUS P8P67 EVO Motherboard B3 Kingston HyperX KHX1600C9D3K2/8GX (2x4GB) DDR3 OCZ RevoDrive PCI-Express SSD 120GB Corsair Hydro Series H70 CPU Cooler 2 xWestern Digital Caviar Black 1TB WD1002FAEX TM Warthog Hotas TrackIR 5 Pro
Recommended Posts