cornhelium 0 Posted July 23, 2006 Hi, I'm working on a wildlife sounds system, and the last hurdle is getting singing birds etc to "fly away" in alarm when a loud shot or explosion occurs. Here's part of the init field of the trigger for one area: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> tna1 = true; player globalChat "activated tna1"; {if (tna1i) then {_x addEventHandler ["fired",{if (tna1 && (_this select 0) distance tna1m < 500 && ((_this select 4) in ["JAM_West_762x51_Single_Bullet","JAM_West_762x51_Burst_Bullet","JAM_West_762x51_Auto_Bullet"])) then {[(_this select 0),tna1m, tna1l, tna1t,"tnaf"] exec "flyoff.sqs"; tna1 = false; player globalchat "tna1 original fired"}; if (tna1 && (_this select 0) distance tna1m < 500 && ((_this select 4) in ["GrenadeHand","PipeBomb","TimeBomb"])) then {[(_this select 4),tna1m, tna1l, tna1t,"tnaf"] exec "flyoffdelayed.sqs"; player globalchat "tna1 original bomb"}}]}} foreach thislist flyoff.sqs causes the wildlife to flee immediately, away from the firing unit flyoffdelayed.sqs will wait for the ammo to explode, then the wildlife will flee from the explosion It's all working great, but I really want to expand the types of ammo that will cause flyoff.sqs or flyoffdelayed.sqs to execute. I'd like to just list the ammotypes in 2 sqf files, "flyoffbullets.sqf" and "flyoffexplosives.sqs". This would also allow mission editors to easily add/remove ammo from the sqf files, rather than trawling through several dozen triggers. Can anyone advise me of the correct syntax to take the ammo classnames out of the trigger initfield and into the sqf files please? Thanks, CH Share this post Link to post Share on other sites
UNN 0 Posted July 23, 2006 Ok, a bit of a guess as I cant test it and I'm not exactly sure what the mission is. But a basic function that would help simplify your trigger code could be written like this: AmmoHeard.sqf <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_Source=_This Select 0; _Ammo=_This Select 1; If (tna1 And ((_Source Distance tna1m)<500)) Then       {       If (_Ammo In ["JAM_West_762x51_Single_Bullet","JAM_West_762x51_Burst_Bullet","JAM_West_762x51_Auto_Bullet"]) Then             {             [_Source,tna1m, tna1l, tna1t,"tnaf"] exec "flyoff.sqs";             tna1 = False;             player globalchat "tna1 original fired";             }             Else             {             If (_Ammo in ["GrenadeHand","PipeBomb","TimeBomb"]) Then                   {                   [_Source,tna1m, tna1l, tna1t,"tnaf"] exec "flyoff.sqs";                   tna1=false;                   player globalchat "tna1 original fired";                                     };             };       }; Then in your trigger you would just call: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">tna1 = true; player globalChat "activated tna1"; {if (tna1i) then {_x addEventHandler ["fired",{[_This Select 0,_This Select 4] Call AmmoHeard}]} ForEach thislist; You would have to put this in your init.sqs e.t.c <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">AmmoHeard=PreProcessFile "AmmoHeard.sqf" If thats the kind of thing your looking for? Then you might want to consider moving your ammo types into global arrays. To make it easier to update for yourself and other mission makers. Also, you still have constants "tna1","tna1m","tna1t","tnaf" e.t.c I guess they refeer to triggers and such like? Passing them in as parameters might make your function more flexible? BTW is tna1 used anywhere else, or just in this event? Share this post Link to post Share on other sites
hardrock 1 Posted July 24, 2006 Note that preprocessFile doesn't work with functions stored in Addon PBOs. You need to use loadFile there. I already tried using countType to check the ammo for its base class Å• la <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">if ("BulletSingle" countType [_ammo] == 1) ... but this doesn't work. So you can use an additional file to store all magazines in, which you can load as array. This will be quite huge though and I don't know if it wouldn't be overkill for many fired events in a large mission. Just to clarify my concept: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">[ "magazine1", "magazine2", "magazine3" ] <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_magazines = loadFile "magazines.txt"; if(_magazine in _magazines) ... A IMO much more reliable and performant way would be to simply query the speed of the bullet. This can be done with a simple function like this, overwriting the function of UNN above: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_source = _this select 0; _ammo = _this select 4; _bullet = nearestObject [_source, _ammo]; if (tna1 and (_source distance tna1m < 500)) then { if (speed _bullet > 1000) then { [_source, tna1m, tna1l, tna1t, "tnaf"] exec "flyoff.sqs"; tna1 = false; player globalchat "tna1 original fired"; } else(if (_ammo in ["GrenadeHand","PipeBomb","TimeBomb"]) then { [_source, tna1m, tna1l, tna1t, "tnaf"] exec "flyoff.sqs"; tna1 = false; player globalchat "tna1 original fired"; }); }; This function would be called by the fired event handler like this: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">unit addEventHandler ["fired", {_this call myFunction}] Share this post Link to post Share on other sites
cornhelium 0 Posted July 24, 2006 Thanks guys. Just to clarify what I'm looking for: This snippet works perfectly, but I want to include about 100 bullet types rather than just the 3: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> {if (tna1 && (_this select 0) distance tna1m < 500 && ((_this select 4) in ["JAM_West_762x51_Single_Bullet","JAM_West_762x51_Burst_Bullet","JAM_West_762x51_Auto_Bullet"])) then {[(_this select 0),tna1m, tna1l, tna1t,"tnaf"] exec "flyoff.sqs"; So, I'm looking for something like this, except I'm not sure of the right syntax <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> {if (tna1 && (_this select 0) distance tna1m < 500 && ((_this select 4) in BulletArray.sqf)) then {[(_this select 0),tna1m, tna1l, tna1t,"tnaf"] exec "flyoff.sqs"; I'll have a few dozen of these triggers around, and I want a couple of global ammo arrays they can all refer to. I'd like to have these arrays in an .sqf or .sqs file so that missionmakers can easily add ammotypes (I plan to put the core scripts and sound files in a .pbo) I'm using the actual bullet/bomb classes, not the base classes. The trigger initfields need to pass global variables to a central fauna.sqs, so if I assigned the EH in an .sqf I'd need one for each trigger. Thus better in this case to assign the EH within the trigger itself. Maybe I can just run a separate ammotypes.sqs at mission start, to define the two global arrays? Eg. in init.sqs: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> [] exec "ammotypes.sqs" ammotypes.sqs <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> BulletArray = ["JAM_West_762x51_Single_Bullet","JAM_West_762x51_Burst_Bullet","JAM_West_762x51_Auto_Bullet","LSR_M4_Bullet",etc",etc"...] ExplosiveArray = ["GrenadeHand","PipeBomb","TimeBomb","COCM18A1","etc","etc","etc"...] exit D'you think this would work? Is this an efficient way of doing it? What would be the correct syntax to refer to the array? I'm away from home at the moment and can't try this out. Many thanks CH Ps Quote[/b] ]you still have constants "tna1","tna1m","tna1t","tnaf" e.t.c I guess they refeer to triggers and such like? Passing them in as parameters might make your function more flexible? Yeah, they refer to triggers and logics in the group. It's basically so that one large central fauna.sqs can be used by the many 2trigger&logic groups (<40 of them I hope). Really, it's working fine and is robust, I just need to get over this last wrinkle then I can "load test" it Quote[/b] ]BTW is tna1 used anywhere else, or just in this event? Just this event. It's set to false by the firedEH, so that a shot can only make the birdies fly away >once< ...then a few minutes later "they" (ie the trigger) will return from [0,0,0] and will start singing again. The trigger resets to true if anybody is present. There's also code to make sure each unit can only get the trigger's EH added >once<, though it never gets removed (beyond my ability and available time). Share this post Link to post Share on other sites
UNN 0 Posted July 24, 2006 Quote[/b] ]{if (tna1 && (_this select 0) distance tna1m < 500 && ((_this select 4) in BulletArray.sqf)) then {[(_this select 0),tna1m, tna1l, tna1t,"tnaf"] exec "flyoff.sqs"; Ah, I see. Then it's not a function you want. Just define the two arrays you mentioned, BulletArray & ExplosiveArray: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">BulletArray = ["JAM_West_762x51_Single_Bullet","JAM_West_762x51_Burst_Bullet","JAM_West_762x51_Auto_Bullet","LSR_M4_Bullet",etc",etc"...] ExplosiveArray = ["GrenadeHand","PipeBomb","TimeBomb","COCM18A1","etc","etc","etc"...] And use these: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">{if (tna1 && (_this select 0) distance tna1m < 500 && ((_this select 4) in BulletArray)) then {[(_this select 0),tna1m, tna1l, tna1t,"tnaf"] exec "flyoff.sqs"; <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">{if (tna1 && (_this select 0) distance tna1m < 500 && ((_this select 4) in ExplosiveArray)) then {[(_this select 0),tna1m, tna1l, tna1t,"tnaf"] exec "flyoffdelayed.sqs"; Share this post Link to post Share on other sites
hardrock 1 Posted July 25, 2006 @cornhelium: Did you read my post? Because I answered all your questions in it . . . I showed you how to export an array into an external file, and I showed you an easy way of detecting whether some ammo is a bullet or not by querying its speed. It is very cpu intensive to iterate over large arrays of strings everytime a bullet is shot, which is quite often. So I really advice you to query the speed of the ammo to find out whether it's a bullet. You can still iterate over minor arrays in the else-statement, in case it was something else than a bullet. Share this post Link to post Share on other sites