Jump to content
🛡️FORUMS ARE IN READ-ONLY MODE Read more... ×
Sign in to follow this  
KaRRiLLioN

Passing server-side array info to clients?

Recommended Posts

I have 2 questions:

1. According to BIS's code guide, Number, Boolean, Object and Group are the supported types of info that can be passed to clients via PublicVariable.

I have an array in a script that I want to keep updating with a server-side script, but there is information that clients need to receive in order to make markers and messages work for them. Right now I run everything except the scoring on all clients because of the need for them to see marker changes. The information in the particular array that I'm referencing is Number. It's like this:

FlagStatus=[0,0,0,0,]

Each flag is represented here. I've tried doing a PublicVariable "FlagStatus" but of course that doesn't work. Does anyone have any clever workarounds for this?

2. This script works great even with large numbers of player, but I almost constantly get an error that seems to occur when either a player dies, or a player gets into a vehicle. I know it has something to do with the way that the player is counted in his particular team list.

There are 2 triggers on the map, 6000x6000. One detects East, the other West. It creates WList and EList using

WList=thislist

EList=thislist

I have a loop that loops through each person in each list, determines if they're near a flag, and if so adds them to an array. Sometimes, however I get this error:

'_unit=(WList Select _x)|#|' Error Zero Divisor

OR

'_unit=(EList Select _x)|#|' Error Zero Divisor

From what I can gather, this is occuring becausethe script is trying to select a null unit, or a unit that was killed perhaps? Essentially I can start a game by myself, shoot a few units and kill them, and this error appears. It does not in any way affect the gameplay, and works just fine, but I get tired of seeing an error up there. People also tend to think something is wrong with the mission.

Perhaps if I better arranged something in the list? Here's the script. As always, I appreciate your insight!

The init contains the Array info:

FlagList=[Flag1,Flag2,Flag3]

FSL=[0,0,0] (FSL means FlagStatusList)

;;BEGIN TW-TStatus.sqs

#start

_f=0

_cwl=(Count Wlist)

_cel=(Count Elist)

_cfl=(Count FlagList)

#FlagLoop

_x=0

_y=0

?(_f==_cfl):_f=0

_flag=(FlagList Select _f)

_flagstatus=(FSL Select _f)

_flagname=(FlagNameList Select _f)

;;titletext[Format["DEBUG: %1,%2",_flagname,_f],"PLAIN"]

_flaglistW=[]

_flaglistE=[]

#FlagStatusLoop

~.001

;;titletext[Format["%1\n%2",_flaglistW,_flaglistE],"PLAIN DOWN"]

#W

?(Count WList==0):Goto "E"

_unit=(Wlist Select _x)

?(_unit Distance _flag<=100) AND !(_unit in _flaglistW):_flaglistW=_flaglistW+[_unit]

?(_unit Distance _flag >100) AND (_unit in _flaglistW):_flaglistW=_flaglistW-[_unit]

#E

?(Count EList==0):Goto "ListLoopEnd"

_unit=(Elist Select _y)

?(_unit Distance _flag<=100) AND !(_unit in _flaglistE):_flaglistE=_flaglistE+[_unit]

?(_unit Distance _flag >100) AND (_unit in _flaglistE):_flaglistE=_flaglistE-[_unit]

#ListLoopEnd

_x=_x+1

_y=_y+1

?(_cwl>=_cel) AND (_x==_cwl):Goto "StatusCheck"

?(_cel>=_cwl) AND (_y==_cel):Goto "StatusCheck"

Goto "W"

#StatusCheck

?(_flagstatus==4) AND ((Count _flaglistW>0) OR (Count _flaglistE<1)):Goto "skip"

?(_flagstatus==5) AND ((Count _flaglistE>0) OR (Count _flaglistW<1)):Goto "skip"

?(_flagstatus==4) AND (Count _flaglistW)<1 AND (Count _flaglistE)>0:_flagstatus=6; FSL Set [_f,_flagstatus]

?(_flagstatus==5) AND (Count _flaglistE)<1 AND (Count _flaglistW)>0:_flagstatus=7; FSL Set [_f,_flagstatus]

?(_flagstatus==6) AND ((Count _flaglistW>0) OR (Count _flaglistE<1)):_flagstatus=4; FSL Set [_f,_flagstatus]

?(_flagstatus==7) AND ((Count _flaglistE>0) OR (Count _flaglistW<1)):_flagstatus=5; FSL Set [_f,_flagstatus]

?(_flagstatus <4) AND (_flagstatus !=3) AND (Count _flaglistW)>0 AND (Count _flaglistE)>0:_flagstatus=3; FSL Set [_f,_flagstatus]

?(_flagstatus <4) AND (_flagstatus !=0) AND (Count _flaglistW)<1 AND (Count _flaglistE)<1:_flagstatus=0; FSL Set [_f,_flagstatus]

?(_flagstatus <4) AND (_flagstatus !=1) AND (Count _flaglistW)>0 AND (Count _flaglistE)<1:_flagstatus=1; FSL Set [_f,_flagstatus]

?(_flagstatus <4) AND (_flagstatus !=2) AND (Count _flaglistW)<1 AND (Count _flaglistE)>0:_flagstatus=2; FSL Set [_f,_flagstatus]

PublicVariable "FSL"

#skip

;;titletext[Format["%1\n%2\n%3",_flagname,_flaglistW,_flaglistE],"PLAIN DOWN"]

;;~1

;;titletext[Format["%1,%2\nCWL: %3,X: %4\nCEL: %5, Y: %6",_flagname,_f,_cwl,_x,_cel,_y],"PLAIN"]

_f=_f+1

Goto "FlagLoop"

Share this post


Link to post
Share on other sites

I dont really see a problem... But that might just be me. My suggestion would be to make an extensive hint window which print out all the variables you use, to check it. This script isnt really complicated, but its nice to know what its doing. In such way one can often find many wierd things with it...

I use it alot when debugging my trainscript, one time passed almost 20 variables out to it, though that is something like 5 times bigger than this... And one cant have speakers on smile.gif

Just a suggestion. Then you might find out why its zero divisor.

Share this post


Link to post
Share on other sites

You could create variables that represent each flag, of course you will loose some flexibility of your script.

Share this post


Link to post
Share on other sites

Error '_unit=(WList Select _x)|#|' Error Zero Divisor means you are trying to access some array element beyond actual array size.

I can see two problems in your script that can cause this:

1) You use one loop to traverse both Wlist and Elist. From my understanding of your code _x is always equal to _y

If number of elements in Wlist and Elist is different, one of your assigments _unit=(Wlist Select _x) and _unit=(Elist Select _y) will certainly be out of array range.

2) Wlist and Elist can change while your script loop is running. It may therefore happen that some unit is removed from the list while it is running.

Here is a quote from official command reference that explains how arrays are assigned:

</span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE">Assignment used on arrays assigns only pointer to the same array to the target variable. When b is an array, after executing a = b both a and b represent the same array. When b is changed, a is changed as well. One particular situation that can lead to this behaviour is aList = list sensor_name. You can force creating a copy of array by using unary operator +<span id='postcolor'>

Share this post


Link to post
Share on other sites

Ah, yes you are correct!

I did have something in there that was resetting the smaller of the lists back to 0, but removed it when I was optimizing. If Elist has 10 players and Wlist has 12, then it will keep going until _y and _x hit 12. Since Elist doesn't have 12 players, then it doesn't exist. I'll bet that would cause an issue.

I need to add this line:

(_x==_cwl):_x=0

(_y==_cel):_y=0

OK, I see what you mean on that Suma, I need to reset _y or _x as soon as one of them equals the count of the list it represents.

I'll give that a shot and see if it helps matters.

You are also right about the array adding and subtracting people from it since when they die, I think they are removed for a moment.

So in order to create a static list, I would need to put in the following?

WList=WList+thislist

EList=Elist+thislist

Thanks!

Share this post


Link to post
Share on other sites

</span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE">So in order to create a static list, I would need to put in the following?

WList=WList+thislist

EList=Elist+thislist

<span id='postcolor'>

No, this would extend your list forever.

Correct would be:

WList=+thislist

List=+thislist

or

WList=thislist+[]

List=thislist[]

The trick is to avoid passing it as reference by doing some "dummy" calculation on it (like unary plus or adding empty array).

Be aware that you might loose some performance by doing this, as real array copy is a little bit slower than simple pointer assignment. If the arrays are huge, you may want to find some solution that will be able to handle array that can change anytime - which would certainly more complicated.

Share this post


Link to post
Share on other sites

Each array would be about 12-16 players each. That's not too large is it? I do have a version with 3 teams that have 12 members each for a total of 36 in all.

In my init I put this line:

WList=[]

Elist=[]

Then in each Trigger (non-repeating) I put

WList=Wlist+thislist

EList=Elist+thislist

So that is creating an infinite array? I ran some debugging and that didn't seem to be the case. Basically I tracked the count of each array and it didn't deviate or change, and I didn't get the 0 divisor error again either.

I also made it so the smaller of the 2 lists has it's variable reset to 0 whenever it == the count of its list.

I appreciate your time on this. I'll try your suggestions unless you think that my arrays would be too large and create a bad performance drain.

Thanks!

Share this post


Link to post
Share on other sites

</span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE">In my init I put this line:

WList=[]

Elist=[]

Then in each Trigger (non-repeating) I put

WList=Wlist+thislist

EList=Elist+thislist

<span id='postcolor'>

I may be wrong, byt I think that when doing it this way, you assign the arrays only once (on first activation of the trigger) and they will never change. I am not sure if this is what you want to do.

</span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE">Each array would be about 12-16 players each. That's not too large is it? <span id='postcolor'>

That is fine. I was afraid of performance impact when copying arrays of ~1000 elements on regular basis. As your arrays are quite small, they present no problem. Moreover, as you copy them only once during first and only trigger activation you could copy even large arrays without any problems.

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  

×