Jump to content
Sign in to follow this  
xxbbcc

Random position in multiplayer...

Recommended Posts

Sorry if this is the wrong forum - I wasn't entirely sure where to post this. Feel free to move if necessary.

I'm working on an MP mission and don't have a whole lot of experience in ArmA scripting. I'd like to have a bunch of random positions for the player group and every time the mission starts, I want the group to appear at one of the random points.

Here is the code I'm using:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">if ( !( local server ) ) exitWith {};

if ( !isServer ) exitWith {};

_lRnd = floor ( random 5 );

_oStartMarkers = ["Start1", "Start2", "Start3", "Start4", "Start5"];

_sMarker = ( _oStartMarkers select _lRnd );

_oPos = getMarkerPos _sMarker;

_lX = _oPos select 0;

_lZ = _oPos select 1;

s1 setPos _oPos;

s2 setPos [_lX + 1, _lZ];

s3 setPos [_lX + 2, _lZ];

s4 setPos [_lX + 1, _lZ + 1];

s5 setPos [_lX + 1, _lZ + 2];

s6 setPos [_lX + 2, _lZ + 1];

if ( true ) exitWith {};

s1, s2, ... s6 are the playable units on the map.

This works fine in single-player and in MP with a single human player. With multiple human players, each human appears in a random spot and the AI soldiers appear with the group leader.

Can someone explain me what I'm doing wrong? At first I thought the above code ran for all client computers, but it happens even with the isServer check in place, so now I'm lost.

Thanks in advance.

Share this post


Link to post
Share on other sites

1. exitWith command does not break scritpt as exit (in sqs) command does.

If you want to create server only block use something like that:

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

if( isServer )then

{

//server only code

//computing position etc

};

2. local server isn't neccessary, beacuse we have isServer command

3. as I said in 1st point, exitWith nothing chages, hence avery player run the script, computing their random LOCAL position (which usually is various on various PC)

4. I don't know if server can move soldiers which aren't local (simply are players), but check it.

So: if 4th is false (server can move non-local soldiers) the script should look like:

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

if( isServer )then

{

_lRnd = floor ( random 5 );

_oStartMarkers = ["Start1", "Start2", "Start3", "Start4", "Start5"];

_sMarker = ( _oStartMarkers select _lRnd );

_oPos = getMarkerPos _sMarker;

_lX = _oPos select 0;

_lZ = _oPos select 1;

s1 setPos _oPos;

s2 setPos [_lX + 1, _lZ];

s3 setPos [_lX + 2, _lZ];

s4 setPos [_lX + 1, _lZ + 1];

s5 setPos [_lX + 1, _lZ + 2];

s6 setPos [_lX + 2, _lZ + 1];

};

Share this post


Link to post
Share on other sites

Thank you for the ideas! I read somewhere else that players are local, so I didn't try to move them on the server. Instead I ended up doing it differently: first I randomly select a marker name on the server, publish it to clients and then when client init runs, each client uses the same marker that they receive from the server.

Here is the code if anyone else is interested:

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

//---------

// in init.sqf

//---------

if ( isServer ) then

{

   _lRnd = floor ( random 5 );

   _oStartMarkers = ["Start1", "Start2", "Start3", "Start4", "Start5"];

   sMarker = ( _oStartMarkers select _lRnd );

   PublicVariable "sMarker";

};

onPlayerConnected

"

   PublicVariable ""sMarker"";

   PublicVariable ""bWestDetected"";

   PublicVariable ""bEnemyDefeat"";

";

_dummy = execVM "PositionPlayers.sqf";

// ...

//---------

// in PositionPlayers.sqf

//---------

_oPos = getMarkerPos sMarker;

_lX = _oPos select 0;

_lZ = _oPos select 1;

s1 setPos _oPos;

s2 setPos [_lX + 1, _lZ];

s3 setPos [_lX + 2, _lZ];

// ...

Share this post


Link to post
Share on other sites

I am as always not entirely sure, but if all your playables are in the same group, the following solution might be possible:

1: Place yer group down - make sure they are 'in formation'.

2: Place a marker on each location you want as a possible spawn location.

3: Group (F2) the leader to each of the markers.

4: Set the size of each marker to zero, effectively making them invisible (an alternative would be to use invisible markers in the first place).

Now, in theory at least, your group should spawn randomly at one of the markers you created.

As stated, I'm not quite sure it works, and maybe only the leader will spawn at a random marker location. If this is the case, try putting yer dudes in an empty vehicle (moveindriver, moveincargo and so forth) and then group the vehicle to the invisible markers instead.

--and Bob's yer uncle.

Share this post


Link to post
Share on other sites

Create the random positions by using Logics.

Example: Create a Logic and call it "pos1" the next Logic "pos2" and so on.

Create a Trigger which covers all units/groups which should be moved.

Activated: The side you like to move

Activated: Once

On Activation: move = [thisList, [pos1,pos2,pos3] ] execVM "Move.sqf"

Move.sqf

private ["_a","_b","_c"];

if (isServer) then

{

_a = _this select 0;

_b = _this select 1;

_c = _b select floor(random count _b);

sleep 1;

{_x setPos getPos _c} foreach _a;

};

Edited by SNKMAN

Share this post


Link to post
Share on other sites

Guys,

Thanks for the replies. I found out that with multiplayer, grouping the players with markers doesn't work, because the game chooses the random position for each human player separately. So if the team has 6 members (2 human, one of them is leader), then 1 human and the 4 AI gets placed in one location, and the other human gets placed independently. It's possible that the 2nd human player will end up with the group, but because of the random placement, not very likely.

My solution has the server choose a random starting location at the very beginning of the mission and then that location is broadcasted to all clients. This way, clients always use the same position. For this to work, grouping with markers cannot be used, so I had to use a bit of custom code.

Przemek_kondor's explanation helped a lot in understanding how units are treated by the server & the client.

I'll upload the mission to some site, if someone is interested, feel free to depbo it and see the code.

Share this post


Link to post
Share on other sites
1. exitWith command does not break scritpt as exit (in sqs) command does.

Sorry for jumping into this but this statement isn't entirely true.

I've seen and used exitWith the way the OP did and I can guarantee it works wink_o.gif

Share this post


Link to post
Share on other sites
1. exitWith command does not break scritpt as exit (in sqs) command does.

Sorry for jumping into this but this statement isn't entirely true.

I've seen and used exitWith the way the OP did and I can guarantee it works wink_o.gif

Quote[/b] ]When you use exitWith not inside a loops, the behaviour is undefined - sometimes it may exit the script, sometimes some other scope, but this is not intended and designed behaviour of this command, and it is not guaranteed to work reliably.

source: http://community.bistudio.com/wiki/exitWith

Several times I noticed it didn't exit script - so we can't (shouldn't) use it for this purpose

Share this post


Link to post
Share on other sites

Mind providing some examples where it didn't work?

I know what the wiki says, but like I said - it always worked for me.

The truth is it could behave weird in functions.

Share this post


Link to post
Share on other sites

Example as I remember was something like:

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

...

if( not isServer )exitWith{};

...

but regarding to biwiki it sometimes (mostly in current implementation) exit script, sometimes (in current implementation) it doesn't.

I can't say how often it exits or not, because I don't use if for exit anymore.

The most important thing I would to say: we shouldn't use command for some "unexpected additional features" (I mean: which wasn't listed as official command feature), because developer (BIS) does not guarantee that this feature will exits later. Developer guarantee only that what is in documentation.

For example your scripts may not work properly in ArmA2 or even in next patch (when implementation of command/managing of memory may change)

Share this post


Link to post
Share on other sites

Well, I can guarantee you that 100% of times I used the above with a stand-alone script (fired with execVM) it worked.

Share this post


Link to post
Share on other sites

I, too, saw the Biki entry Przemek_kondor is referring to and I ended up removing all exit-s and exitWith-s from the code. I simply rearranged all the code to be inside if-s and then at the end the scripts simply leave.

I haven't actually seen exitWith misbehave, but the Biki is clear on how it shouldn't be used, and I didn't want to introduce a potential problem.

BTW, here's the finished mission with the random starting script, it seems to work well. Feel free to depbo it. The only issue with it is that during briefng, human players are shown in random positions - they're positioned correctly once the mission starts.

Mission topic

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  

×