Jump to content
Sign in to follow this  
cornhelium

Stuffing global variables into an array

Recommended Posts

Hi,

Still working on my wildlife sounds system for Tonal. The goal is to have mission editor templates for each separate area of Tonal that mission makers can simply merge over their finished mission, giving them reactive, authentic SE African wildlife sounds that change around the clock.

So far, everything's going great. The basics are in place and working, now got a few months of editing and placing all the sounds.

However, I've been reading about the savegame bug, and I might have a basic flaw in that I'm using a >lot< of global variables (could eventually run to a few hundred if other lag issues allow).

All of these globals are needed, as many different groups of 2 trigger + 1 logic are passed to the same fauna.sqs at different times.

Now, I've read here that the ECP team got around the savegame bug by stuffing all of their globals into a few arrays, then referencing them with selection numbers. Taking this approach, I could put half of my globals and array names into one array per area, probably buying myself enough headroom to get the system working safely at a decent scale.

I've just tried a little re-write and have hit a wall of error messages. Could someone advise the correct syntax please?

Here's what works, using the full global variable set for one 2trig+1logic "soundcentre". First, the elements and their names:

Globvars passed to fauna.sqs

va1m main trigger. covers a 250m radius. emits wildlife sounds. adds firedEH to units that can exec another "fly away in panic and don't come back for 10 minutes" script. zapped to 0,0,0 for 1 second in every 31 so that list va1m can refresh.

va1t inner trigger. covers a 50m radius. used by fauna.sqs to determine if units are too near, in which case the main trigger will emit warning calls or go silent. Also emits the "panic" sounds as va1m is zapped to 0,0,0 for 10 minutes. Also the only element that never moves - this acts as an anchor point within the fauna.sqs which uses local variables exclusively.

va1l logic. used by a looping script that checks the player's distance from all such logics. When player is within 500m, the script passes these three globals to fauna.sqs (along with a "type" that determines which section of fauna.sqs is used). We only want fauna.sqs to be executed once by any one group, so it now moves this logic 10km away for the duration.

I think of each of these 2 trigger + 1 logic groups as a "soundcentre"

Globvars referenced by va1m activation/deactivation fields to manage the firedEH

va1 condition to activate/deactivate the firedEH. When a unit fires, the wildlife should flee in panic only once. Thus the firedEH itself sets va1 to false the first time a unit fires. This disables the EH until va1m is returned after 10 minutes or so, when it is reset to true by the activation field.

va1i condition to isolate the units in list va1m at mission start. part of the archiving system described below. set to true in fauna_init.sqs, sets permanently to false first time va1m deactivates.

Globarrays referenced by va1m activation/deactivation fields to manage the firedEH

va1r copy of va1m list. refreshed on each activation (ie every 31 seconds)

va1a growing archive of va1m list. set in fauna_init.sqs as list va1m, then added to with each trigger deactivation

va1n new units in the area. va1m list from current activation minus va1m archive from previous deactivation.

SilencedBullets set in fauna_init.sqs. small array of bullet classnames that should not make wildlife flee. easily accessible to mission makers to add/remove bullet types as they wish

Explosives also set in fauna_init.sqs. another small array of explosives that will trigger a delayed flyoff script when "fired".

Smokeshells another small array of smokeshells, flares etc that should not cause wildlife to flee at all.

SilentShots SilencedBullets + Explosives + Smokeshells.

OK - here's the current syntax which works fine:

Globvars set in fauna_init.sqs (executed via init.sqs):

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

SilencedBullets = ["StrokeFistHit","StrokeGunHit","BulletSilencedSingle",etc]

Explosives = ["GrenadeHand","PipeBomb","TimeBomb",etc]

Smokeshells = ["JAM_SmokeGrenadeRed","JAM_SmokeGrenadeGreen",etc]

SilentShots = SilencedBullets + Explosives + Smokeshells

~1

va1i = true

;similar lines here for other trigger groups making different sounds vb1i, vc1i, va2i etc. currently using 6 groups OK

~5

va1a = list va1m

;starts archive by waiting until va1m has activated then capturing its list before it deactivates for the first time

;similar lines here for other trigger groups making different sounds vb1a, vc1a, va2a etc. currently using 6 groups OK

#loop

;script now runs in 60 second loops checking player distance to the logics and passing the elements to fauna.sqs when <500m

goto "loop"

va1m activation field (split to make a little clearer - basically the first section is only used once, after that only the second section is used

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

va1r = +thislist; va1 = true; player globalChat "activated va1m"; {if (va1i) then {_x addEventHandler ["fired",{if (va1 && (_this select 0) distance va1m < 500) then {if !((_this select 4) in SilentShots) then {[_this select 0,va1m, va1l, va1t,"va"] exec "flyoff.sqs"; va1 = false; player globalchat "va1 original fired"}}; if (va1 && (_this select 0) distance va1m < 500) then {if ((_this select 4) in Explosives) then {[_this select 0,_this select 4,va1m, va1l, va1t,"va"] exec "flyoffdelayed.sqs"; player globalchat "va1 original bomb"}}}]}} foreach thislist;

{_x addEventHandler ["fired",{if (va1 && (_this select 0) distance va1m < 500) then {if !((_this select 4) in SilentShots) then {[_this select 0,va1m, va1l, va1t,"va"] exec "flyoff.sqs"; va1 = false; player globalchat "va1 addition fired"}}; if (va1 && (_this select 0) distance va1m < 500) then {if ((_this select 4) in Explosives) then {[_this select 0,_this select 4,va1m, va1l, va1t,"va"] exec "flyoffdelayed.sqs"; player globalchat "va1 addition bomb"}}}]} foreach (va1r - va1a)

va1m deactivation field

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

va1n = va1r - va1a; va1a = va1a + va1n; va1i = false; player globalChat "deactivated va1m"

All the above works fine, and so far is working with 6 soundcentres (each one using different global names vb1m,vbl,vb1t, vb1i, vb1a etc).

Now, here's my extremely noob attempt to put some of these globvars into a single array icon_redface.gif

Method put the globvars va1 and va1i, and the global arrays va1r, va1r, va1n, into a single array "vd" (short for "Veld area")

va1 becomes (vd select 0)

va1i becomes (vd select 1)

va1r becomes (vd select 2)

va1a becomes (vd select 3)

va1n becomes (vd select 4)

the globvars and arrays for subsequent veld soundcentres will just follow on sequentially ie vb1 becomes (vd select 5), vb1i becomes (vd select 6) etc.

the global names for the triggers & logics will remain as they are

New syntax

fauna_init.sqs

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

~1

(vd select 1) = true

~5

(vd select 3) = list va1m

;etc. loop unchanged as trigger & logic names remain the same

va1m activation field (not working - editor won't accept syntax)

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

(vd select 2) = +thislist; (vd select 0) = true; player globalChat "activated va1m etc"; {if ((vd select 1)) then {_x addEventHandler ["fired",{if ((vd select 0) && (_this select 0) distance va1m < 500) then {if !((_this select 4) in SilentShots) then {[_this select 0,va1m, va1l, va1t,"va"] exec "flyoff.sqs"; (vd select 0) = false; player globalchat "va1m etc original fired"}}; if ((vd select 0) && (_this select 0) distance va1m < 500) then {if ((_this select 4) in Explosives) then {[_this select 0,_this select 4,va1m, va1l, va1t,"va"] exec "flyoffdelayed.sqs"; player globalchat "va1m etc original bomb"}}}]}} foreach thislist;

{_x addEventHandler ["fired",{if ((vd select 0) && (_this select 0) distance va1m < 500) then {if !((_this select 4) in SilentShots) then {[_this select 0,va1m, va1l, va1t,"va"] exec "flyoff.sqs"; (vd select 0) = false; player globalchat "va1m etc addition fired"}}; if ((vd select 0) && (_this select 0) distance va1m < 500) then {if ((_this select 4) in Explosives) then {[_this select 0,_this select 4,va1m, va1l, va1t,"va"] exec "flyoffdelayed.sqs"; player globalchat "va1m etc addition bomb"}}}]} foreach ((vd select 2) - (vd select 3))

va1m deactivation field

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

(vd select 4) = (vd select 2) - (vd select 3); (vd select 3) = (vd select 3) + (vd select 4); (vd select 1) = false; player globalChat "deactivated va1"

also tried this, after having a quick look at some ECP scripts:

fauna_init.sqs

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

~1

vd set [1, true]

~5

vd set [3, (list va1m)]

;etc. loop unchanged as trigger & logic names remain the same

va1m activation field (not working - long error message on trigger activation looks like something to do with one of the {_x addEH...} sections)

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

vd set [2, (+thislist)]; vd set [0, true]; player globalChat "activated va1m"; {if ((vd select 1)) then {_x addEventHandler ["fired",{if ((vd select 0) && (_this select 0) distance va1m < 500) then {if !((_this select 4) in SilentShots) then {[_this select 0,va1m, va1l, va1t,"va"] exec "flyoff.sqs"; vd set [0, false]; player globalchat "va1m etc original fired"}}; if ((vd select 0) && (_this select 0) distance va1m < 500) then {if ((_this select 4) in Explosives) then {[_this select 0,_this select 4,va1m, va1l, va1t,"va"] exec "flyoffdelayed.sqs"; player globalchat "va1m etc original bomb"}}}]}} foreach thislist;

{_x addEventHandler ["fired",{if ((vd select 0) && (_this select 0) distance va1m < 500) then {if !((_this select 4) in SilentShots) then {[_this select 0,va1m, va1l, va1t,"va"] exec "flyoff.sqs"; vd set [0, false]; player globalchat "va1m etc addition fired"}}; if ((vd select 0) && (_this select 0) distance va1m < 500) then {if ((_this select 4) in Explosives) then {[_this select 0,_this select 4,va1m, va1l, va1t,"va"] exec "flyoffdelayed.sqs"; player globalchat "va1m etc addition bomb"}}}]} foreach ((vd select 2) - (vd select 3))

va1m deactivation field

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

vd set [4, (vd select 2) + (vd select 3)]; vd set [3, (vd select 3) + (vd select 4)]; vd set [1, false]; player globalChat "deactivated va1m"

Anyone who can advise me of the right syntax will be the proud owner of a wookie life-debt wink_o.gif

Thanks for your time,

CH

Share this post


Link to post
Share on other sites

Ah, think I've found the cause of my syntax errors...

...If I'm stuffing variables into a global array, guess I better define an empty array to start with icon_redface.gif :

vd = []

This now seems to work:

fauna_init.sqs

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

SilencedBullets = ["StrokeFistHit","StrokeGunHit","BulletSilencedSingle",etc]

Explosives = ["GrenadeHand","PipeBomb","TimeBomb",etc]

Smokeshells = ["JAM_SmokeGrenadeRed",etc]

SilentShots = SilencedBullets + Explosives + Smokeshells

vd = []

~1

vd set [1, true ]

~5

vd set [3, (list va1m) ]

;loop etc

va1m activation field (split for the sake of readability)

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

vd set [2, (+thislist)]; vd set [0, true ]; player globalChat "activated va1m"; {if (vd select 1) then {_x addEventHandler ["fired",{if ((vd select 0) && (_this select 0) distance va1m < 500) then {if !((_this select 4) in SilentShots) then {[_this select 0,va1m, va1l, va1t,"va"] exec "flyoff.sqs"; vd set [0, false ]; player globalchat "va1m  original fired"}}; if ((vd select 0) && (_this select 0) distance va1m < 500) then {if ((_this select 4) in Explosives) then {[_this select 0,_this select 4,va1m, va1l, va1t,"va"] exec "flyoffdelayed.sqs"; player globalchat "va1m original bomb"}}}]}} foreach thislist;

{_x addEventHandler ["fired",{if ((vd select 0) && (_this select 0) distance va1m < 500) then {if !((_this select 4) in SilentShots) then {[_this select 0,va1m, va1l, va1t,"va"] exec "flyoff.sqs"; vd set [0, false]; player globalchat "va1m addition fired"}}; if ((vd select 0) && (_this select 0) distance va1m < 500) then {if ((_this select 4) in Explosives) then {[_this select 0,_this select 4,va1m, va1l, va1t,"va"] exec "flyoffdelayed.sqs"; player globalchat "va1m addition bomb"}}}]} foreach ((vd select 2) - (vd select 3))

va1m deactivation field

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

vd set [4, ((vd select 2) - (vd select 3))]; vd set [3, ((vd select 3) + (vd select 4))]; vd set [1, false]; player globalChat "deactivated va1m"

...as far as the savegame bug is concerned, shouldn't this save 5 global variables per soundcentre? huh.gif   thumbs-up.gif

Cheers,

CH

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×