johnboy Posted January 11, 2023 Posted January 11, 2023 Hi all, I've be trying to get my head around scripting but it isn't coming easily. I hope someone can look at the scripts below and work some magic for me? Here's the setup: I wanted a script that would monitor all three aircraft in a group (comprising Colt 11, Colt 12 and Colt 13) and set a flag each time one of them fires a missile. Each plane has at least two AIM-9 and two AIM-120 missiles. With help from Veteran66, I worked out a script that checks what guidance type the fired missile is, then sets a discrete flag according to the missile type and firing aircraft. That script works very well. I have used SWITCHED CONDITION triggers in the mission editor to play a matching sound file (such as "Colt 32 Fox 2!") then reset the flag to false so that subsequent firing are also reported. Here's that script: Spoiler AllFoxHandler = {} function AllFoxHandler:onEvent(event) if event.id == world.event.S_EVENT_SHOT and event.initiator == Unit.getByName('Colt 11') then local _wpn = event.weapon:getDesc() local _wpnType = _wpn.guidance if _wpnType == 4 then trigger.action.setUserFlag('11-Fox1', true) end if _wpnType == 2 then trigger.action.setUserFlag('11-Fox2', true) end if _wpnType == 3 then trigger.action.setUserFlag('11-Fox3', true) end end if event.id == world.event.S_EVENT_SHOT and event.initiator == Unit.getByName('Colt 12') then local _wpn = event.weapon:getDesc() local _wpnType = _wpn.guidance if _wpnType == 4 then trigger.action.setUserFlag('12-Fox1', true) end if _wpnType == 2 then trigger.action.setUserFlag('12-Fox2', true) end if _wpnType == 3 then trigger.action.setUserFlag('12-Fox3', true) end end if event.id == world.event.S_EVENT_SHOT and event.initiator == Unit.getByName('Colt 13') then local _wpn = event.weapon:getDesc() local _wpnType = _wpn.guidance if _wpnType == 4 then trigger.action.setUserFlag('13-Fox1', true) end if _wpnType == 2 then trigger.action.setUserFlag('13-Fox2', true) end if _wpnType == 3 then trigger.action.setUserFlag('13-Fox3', true) end end end world.addEventHandler(AllFoxHandler) At the moment I have to write nine 'SWITCHED CONDITION' triggers matched to all nine possible unit + missile types combinations (three units, three fox possibilities), which isn't hard but a bit of a nuisance when I use the same set-up in a different mission. Each trigger is a variation of this line: SWITCHED CONDITION >FLAG IS TRUE ("11-Fox1") > SOUND TO COALITION (BLUE, Colt 11 - Fox 1.ogg, 0) > MESSAGE TO COALITION (BLUE, Colt 11, Fox 1,2,true) > FLAG OFF "11-Fox1" I'd like to convert those triggers into script form that I can re-use. I thought I could place the UserFlag output into an if-then function to play the appropriate sound file and then reset the flag to false to await subsequent missile firing. I found a small 'switched condition' script by DeadlyFishes that I thought I could use but I can't work out how to incorporate it into my larger script. I've also tried running the smaller script after the larger one but I'm doing something wrong, it seems. Here is the small script I've been playing with: Spoiler local function main() if trigger.misc.getUserFlag('11-Fox1') == 1 then trigger.action.outTextForCoalition( 1, "Colt 11, Fox 1!", 5) trigger.action.outSoundForCoalition( 1, "11-Fox1.ogg" ) trigger.action.setUserFlag('11-Fox1', false) end end main() I suspect the solution is pretty simple but my equally simple brain can't figure it out. Any suggestions would be greatly appreciated. Cheers, 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
cfrag Posted January 11, 2023 Posted January 11, 2023 (edited) If all you want to do is play some sound or do specific stuff when the missile is fired, I'd keep it all in the same script; it seems that you are doing the same thing for each and every fox, so why not automate and consolidate the repeating code segments? It'll also eliminate the use of flags to pass information that you then have to construct tons of conditions for. That's exactly what scripting is good for, and it gives you a fuzzy warm feeling Something like this (warning: untested, written on a train): AllFoxHandler = {} function AllFoxHandler.handleFox(who, name, foxType) -- check if who matches name if who ~= Unit.getByName(name) then return end -- nope, bye! -- future proof: make it work with all coalitions local coa = who:getCoalition() -- when we get here, we know fox type and who trigger.action.outTextForCoalition( coa, name .. ", Fox " .. foxType .. "!", 5) trigger.action.outSoundForCoalition( coa, name .. "-Fox" .. foxType .. ".ogg" ) -- dynamically build sound file name, can be buggy! -- WARNING: sound files must be renamed to "Colt 11-Fox1.ogg" -- so they match the <name> variable!!! end function AllFoxHandler:onEvent(event) if event.id ~= world.event.S_EVENT_SHOT then return end -- not interested if not event.weapon then return end -- no need to check local ini = event.initiator if not ini then return end -- sanity check -- common code: check fox type local _wpn = event.weapon:getDesc() local _wpnType = _wpn.guidance local fox = nil -- init to undefined if _wpnType == 4 then fox = 1 end if _wpnType == 2 then fox = 2 end if _wpnType == 3 then fox = 3 end if not fox then return end -- not interesting, bye! -- note: better would be an array {} of players and iterate that, -- but for clarity, we leave the code closer to the original AllFoxHandler.handleFox(ini, 'Colt 11', fox) AllFoxHandler.handleFox(ini, 'Colt 12', fox) AllFoxHandler.handleFox(ini, 'Colt 13', fox) end world.addEventHandler(AllFoxHandler) Voilà - no more flags, no more conditions to query, all contained in one nice, much better performing script. Note that you need to slightly rename the ogg files to match their names, e.g. "11 Fox-1.ogg" to "Colt 11 Fox-1.ogg" so that the code can be lazy and derive the audio file name from the unit name. Also, to make the code even tighter, I'd put all relevant unit names in an array, and iterate the array. That way you can quickly adapt the script to many more players. But arrays and loops tend to turn off fresh starters, so I left that as it is for a clearer picture of what the code does. Hope this helps, -ch Edited January 11, 2023 by cfrag
johnboy Posted January 11, 2023 Author Posted January 11, 2023 Wow! If you can write stuff this good sitting on a train, you could probably produce Shakespeare seated at your desk! Thanks very much for taking the time to help out. It's early morning here in Australia so I've just started studying your script. I *think* I understand it! I like the way the script dispenses with irrelevant conditions ("-- nope, bye!" and "-- not interesting, bye!") to focus on the real deal; I'll use that in other scripts. Your 'common code' section is also very cool; it's clean and compact. I will fiddle with the sound files today to rename them as suggested; the idea of dynamically built sound files is intriguing. I've recently looked at a couple of examples of an iterated array and it made my head hurt, but trying to follow the logic is fascinating so I'll keep at it. I can't wait to try this out; I'll report back on progress. Thanks again, CH, very much appreciated! Cheers, 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
johnboy Posted January 12, 2023 Author Posted January 12, 2023 (edited) Hi again cfrag, I would have let you know sooner how your script worked but rather than sitting on a train, I spent time today catching and relocating a cranky 1.8 metre snake who had set up shop on our patio. The joys of living in Australia! Pic is here if you'd like to see the handsome fellow (the snake, I mean). The snake (a mature Scrub Python) is a powerful constrictor and he's busy trying to break the bones in my wrist as I posed for the photos! I've tried your script and it works great; that is say, the visual messages for each firing unit and missile type worked flawlessly but I had trouble getting the sound files to play from the script. I changed the sound file names to match the script, as suggested. After searching through the DCS forum I learned that a DO SCRIPT FILE called by an entry in an ME trigger alone wouldn't be able find where the referenced sound files should be. Following some advice from Grimes (posted way back in 2016) I included an entry in the ME editor to point to the sound files via line that reads MISSION START -> FLAG IS TRUE 999 -> SOUND TO COALITION... "Colt 11-Fox1.ogg" and all the other sound files. FLAG 999 is never called but it seems to 'enliven' the sound files for some reason. I also tried another Grimes suggestion, namely to add the sound files to the .miz file separately using Winzip but that didn't help. The only way I could find to get the sound files to fire was to use the uncalled flag method described above. It would be nice if one could somehow point DCS to the sounds via a script entry, but it's not a deal-breaker. The workaround is certainly easier than writing nine ME entries to run the sound files and messages! Incidentally, I would like to try to get my head around loops and arrays - would you have time to show me how it might be done based on your script? if not, no problem, you've already been a tremendous help. Many thanks again for your guidance and clever script, I'm very grateful. Cheers, John Edited January 12, 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
cfrag Posted January 12, 2023 Posted January 12, 2023 (edited) 1 hour ago, johnboy said: I had trouble getting the sound files to play from the script. It's most probably the way ME handles sound files, and the fact that they need to be added to the mission .miz file before you can play them via Lua script. If you have no trigger that plays them at least once, Mission Editor deems the sound files as unnecessary and discards all unused files with the next save. This means that your mission will lose *any* file that is not directly referenced by ME with any save, a big hassle. Once they are gone, they of course can't be played any more. The work-around (as you discovered already) is to create a trigger (as you mentioned) with a condition that will never happen (e.g. time > 99999999, or flag 'neverever' > 10 etc.), and add a 'SOUND TO ALL' action for each and every sound file that you want to have included in the .miz. That way they get loaded into the miz, and can be accessed with scripts -- and (most importantly) won't disappear with the next save, ME now remembers that they are required. It's a bit silly that there aren't better ways to manage your mission's content, but with that work-around, the sound files should be included into your mission (you'll see the .miz file swell in size to account for audio), and good to play from script. Hope that this helps to shed some light on why we do these strange things in ME Cheers, -ch Edited January 12, 2023 by cfrag 1
ADHS Posted January 12, 2023 Posted January 12, 2023 1 hour ago, johnboy said: The joys of living in Australia! If you come here in ACT to catch snakes, you are going to be rich Cheers mate 1 Democracy was already invented, while Scrat was eating oak fruits.
johnboy Posted January 12, 2023 Author Posted January 12, 2023 11 hours ago, ADHS said: If you come here in ACT to catch snakes, you are going to be rich Possibly! thx mate. 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