Home   Help Search Login Register  

Author Topic: SOLVED: Arrays-- a really, really big one  (Read 1849 times)

0 Members and 1 Guest are viewing this topic.

Offline LeeHunt

  • Former Staff
  • ****
  • John 21:25
SOLVED: Arrays-- a really, really big one
« on: 21 Jun 2007, 05:23:04 »
I've got a very large array of 27 positions and then 27 sounds correlated with each position.  I would love to add more, but I am not sure if I am doing this in the best way and would appreciate some wisdom/advice!  I am running the script below once every 2.5 minutes in my mission to move various sound triggers around near the player.  Basically I am trying to cut down on lag by having only one "chicken" sound and one "dog" sound but multiple places to put them.  I'd love to get up to 100 positions or so, would really add a lot of value to the mission.

My question is, can you store this large Array of positions once and make it easier for the CPU to process it, or do i need to run all the positions every time, like every 2.5 minutes in my mission?   What's the best way to handle this?   :dunno: With 27 positions now i get a second or two of lag as the PC runs through the script.  Thanks so much for your help!   :)


Here's the script, which has 5 different sound triggers that will move to locations near the player to give "ear candy" during the mission.

Code: [Select]
;Move Sound Candy by Lee Hunt, thanks to Mr. Peanut and Ofpec.com for the help! 
; Inspiration & idea for moving sound candy based on THobson's MoveTriggers in Abandoned Armies 1.40

_cow = _this select 0
_owl = _this select 1
_chicken = _this select 2
_wolf = _this select 3
_dog = _this select 4

; The locations are the objects the player wants to place sounds near

_Locations = [getpos player nearestObject 190635,getpos player nearestObject 202858,getpos player nearestObject 197342,getpos player nearestObject 139079,getpos player nearestObject 204230,getpos player nearestObject 587129,getpos player nearestObject 124858,getpos player nearestObject 60840,getpos player nearestObject 63502, getpos player nearestObject 64828,getpos player nearestObject 375029,getpos player nearestObject 433270,getpos player nearestObject 199685,getpos player nearestObject 219430,getpos player nearestObject 119372,getpos player nearestObject 446084,getpos player nearestObject 561030,getpos player nearestObject 256089,getpos player nearestObject 445124,getpos player nearestObject 264607,getpos player nearestObject 361471,getpos player nearestObject 373323,getpos player nearestObject 113770,getpos player nearestObject 255324,getpos player nearestObject 206350, getpos player nearestObject 64982,getpos player nearestObject 64384]

;The messages are the different sounds to be played at each location object, and can and should use the same sound to avoid having too many
; triggers on the map.
~5
_Messages = [_cow,_cow,_cow,_cow,_cow,_cow,_cow,_owl,_owl,_owl,_owl,_owl,_chicken,_chicken,_chicken,_chicken,_chicken,_chicken,_wolf,_wolf,_wolf,_wolf,_dog,_dog,_dog,_owl,_wolf]
~2
;Find out which location the player is closest to, _atrocity is used based on Thobson's Abandoned Armies
_GL = "logic" createvehicle [0,0,0]

_GL setPos getpos (_Locations select 0)
_atrocity = 0
_dist = player distance _GL
_i = 0


#loopfindAtrocity

_GL setPos getpos (_Locations select _i)
if ((player distance _GL) < _dist) then {_atrocity = _i;_dist = player distance _GL}
_i = _i + 1
if (_i < count _Locations) then {goto"loopfindAtrocity"}

_SoundCandy = (_Messages select _atrocity)
_SoundCandy setpos getpos (_locations select _atrocity)

~3

deleteVehicle _GL


exit
« Last Edit: 21 Jun 2007, 22:14:25 by Lee »

Offline johnnyboy

  • OFPEC Patron
  • ****
  • Matan los Pantalones!!!
Re: Arrays-- a really, really big one
« Reply #1 on: 21 Jun 2007, 06:07:41 »
For those arrays whose contents don't change during the mission, you can use global arrays that are defined once only in the init.sqs, then have your scripts reference the global arrays.  I do this frequently, although I usually don't have more than 20 or so items in the array.

After initializing the array with the list of values, I then use the shuffle.sqs function (available on the comref here at ofpec) to shuffle the values in the array once (also called in the init.sqs).  That way the order is different each time the mission is played.
El Cojon: "Do you like to Tango?"
You: "Only in Bagango."
Download Last Tango in Bagango and discover how El Cojon earned his name...

Offline Cheetah

  • Former Staff
  • ****
Re: Arrays-- a really, really big one
« Reply #2 on: 21 Jun 2007, 09:29:49 »
I'm going to experiment with the use of large arrays in one of my missions currently in development. I want to know what's possible with them and when ArmA has trouble with saving etc. Going to be more of an experiment than a real mission initially, but it's quite a lot of work and I lack the time to complete the alpha version of it.

Anyway, arrays can be pretty big as johnnyboy mentioned. I can only conclude that from the start of the mission, don't know if ArmA has trouble with that large (100) arrays after half an hour of playtime.
Like missions? Help with Beta Testing! or take a look at the OFPEC Missions Depot for reviewed missions!

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re: Arrays-- a really, really big one
« Reply #3 on: 21 Jun 2007, 16:34:08 »
Your script is not lagging from the array size of 27, which is trivial, it is lagging from running the nearestObject command 27 times without pause each time you exec the script.  What you should do instead is exec the script only once and place the bottom part of your script in another loop with another pause in it.  If you need to turn the sound candy on or off, use a global variable as a condition for this outer loop.  I also do not understand why you bother using a game logic for the distance calculation, when you could simply use player distance (_Locations select _i) and _dist = 1e20.

Code: [Select]
.
.
.
;Find out which location the player is closest to, _atrocity is used based on Thobson's Abandoned Armies
#mainloop
_atrocity = -1
_dist = 1e20
_i = 0

#loopfindAtrocity
if ((player distance (_Locations select _i)) < _dist) then {_atrocity = _i;_dist = player distance (_Locations select _i)}
_i = _i + 1
if (_i < count _Locations) then {goto"loopfindAtrocity"}
if (_atrocity != -1) then {(_Messages select _atrocity) setpos getpos (_locations select _atrocity)}

~5
if (alive player) then {goto "mainloop"}
exit
« Last Edit: 21 Jun 2007, 16:57:25 by Mr.Peanut »
urp!

Offline CrashDome

  • Members
  • *
Re: Arrays-- a really, really big one
« Reply #4 on: 21 Jun 2007, 16:46:19 »
SoW built 100s of arrays with 12-15 values each. There was no performance drop. Note: I indexed the arrays witha primary key for reference to improve searching.

Offline LeeHunt

  • Former Staff
  • ****
  • John 21:25
Solved: Arrays-- a really, really big one
« Reply #5 on: 21 Jun 2007, 20:11:33 »
Thanks for these suggestions!   :clap:  This is great, my problem is solved, in a better way, and with the knowledge that i can even increase the array size.  That's the last hurdle in my mission, now i can get to beta testing more of other people's missions and icing the cake on mine  :)

Thanks Mr. Peanut i figured i was doing something stupid there.  You can probably tell I'm not a programmer by trade.  Sorry i attached your name to the credits of an incomplete, unelegant script.  Now its better! 
« Last Edit: 22 Jun 2007, 04:50:35 by Lee »