Jump to content
Guest

Object variable attached to an Ai unit (east) that has the 'Player' object put in it on client side, then the object variable is accessed by server

Recommended Posts

Guest

This is my last Multiplayer coded function that works between both clients and host, and it's, of course, turning out to be questionable in whether or not the code is

actually going to work.

What I'm trying to do is make an object variable that is attached to various enemy (east) units, which is actually set on various clients side, set to be public, and

contains the player object of the particular client in the object variable itself, and then the server script accesses the object variable attached to the East units,

and gets correct player unit that is contained in the object variable.

The code below is just an example, and shows exactly what I need to do with the object variable and it's stored player object. The code from my mission itself actually has nothing to do with unit distance to player and is pretty complex, so I just created this somewhat simplistic example for easier reading:

 

 

On Client side:

Private ["_TempArray"];

_TempArray = [];

{

If ((Side _x == EAST) && ((_x Distance Player) < 50)) then {_x SetVariable ["PlayerCloseToEnemy",[1,Player],True];_TempArray = _TempArray + [_x];};

} ForEach AllUnits;

Sleep 5.0


if ((Count _TempArray) > 0) then
{

{_x SetVariable ["PlayerCloseToEnemy",[0,Player],True];} ForEach _TempArray;

};


On Server Side:

Private ["_PlayerCloseToEnemy","_TimeOutFlag","_PlayerUnit","_RunScript"];

_RunScript = 1;
_TimeOutFlag = 0;
_PlayerUnit = Georgee;

While {(_RunScript == 1)} Do
{


{
 If (Side _x == EAST) then
 {

 _PlayerCloseToEnemy = _x GetVariable "PlayerCloseToEnemy";

  if !(IsNil "_PlayerCloseToEnemy") then
  {
  _TimeOutFlag = (_PlayerCloseToEnemy Select 0);
  _PlayerUnit = (_PlayerCloseToEnemy Select 1);

  if (_TimeOutFlag == 1) then {_x Reveal [_PlayerUnit,4.0];};
  };

 };

} ForEach AllUnits;

Sleep 1.0


};

My concerns are, that I am communicating a local object (the player object) within the object variable over to the server, and I don't know if that will work?

Or do I need a seperate global variable that is equal to each player set on all computers ahead of time, and then put this in the object variable instead of player?

The problem with creating separate global variables, is that I cannot seem to find a way to create a unique global name for each seperate player in client code.

 

I would really appreciate any help here, everythng else from this point on that is to be scripted is purely server side, so this is like the last major hurdle for my

mission.

 

(/Edit - I am aware that the desired function of the code above could be accomplished purely on server side, again the script is just an example, the object variable attached to ai units with the player object in it from client side and being communicated from client to server is the only real concern)

Share this post


Link to post
Share on other sites

May not work with it like this:

While {_RunScript == 1)//<-- }

And:

(PlayerCloseToEnemy Select 1);// missing '_' in front of variable

And I think it should work the way you have it...

Share this post


Link to post
Share on other sites
Guest

Thanks for the heads up Jshock there on the typos, fixed them up.

 

 Your saying that the local player object being stored in the object variable there can be safely accessed and checked on server side? I was thinking that the server would not be able to identify the object, because of the player object not being local to the server.

 

But hey, if the script looks like it will work, I'm all for using this method.

Share this post


Link to post
Share on other sites

Filtering through allUnits should also include any players and the variables being public should make that variable available on the server (I believe :p).

Share this post


Link to post
Share on other sites
Guest

The 'Player' command is being used directly on each client in the code, not being a part of the AllUnits array. The AllUnits array is only being used to pick up Ai controlled units. So, the player object that is gained from the Player command on a client is stored in an AI units attached object variable, with public set to True - so in the end, the server is accessing the original local player object through the object variable attached to the Ai unit, where I was concerned that on the servers end, it may not recognize that 'version', or copy, of that player object.

 

Either way, it's certainly the most simple way to start with, and the day ever come the thing ever actually gets to final MP testing phase, if an issue comes up it can be tweaked then.

 

Thanks again :)

 

 

//Edit

 

Public Variable limitations (from the Arma 3 commands list) : " It is also not possible to transfer references to entities which are local, like scripts, displays, or local objects."

 

Actually, what you said there regarding the AllUnits command could be the fix here, as like you said, one would think the units in the AllUnits array are likely (hopefully) not in local form but in global form, so I could just run through the AllUnits listing on the clients side and find which unit equal to player, and then use that object in the AllUnits array, and hopefully that would provide the object in a global form that would work on the server side.

Share this post


Link to post
Share on other sites

You should be able to access any object's namespace, just so long as your variable set on that object is public, I believe there shouldn't be an issue, so when you go through the iterations of all units you should be able to obtain the object's variables to check for values, you could easily check this with a simple variable to set true/false, make it public, then on the server check all units and return a count of how many returned true for that variable, and maybe even how many return nil, and you should have your answer as to whether the object's namespace is accessible.

Share this post


Link to post
Share on other sites
Guest

Gotcha, yea I've made a few changes to the code, so that the player unit on client side is gained through the AllUnits command, therefore at least avoiding any locality issues that might have come up with just using the "Player" command, and then putting that gained object into the AI units object variable with public set to True, as right now getting into actual Mp testing instead of Sp testing is not something I'm ready to get into yet. The game has a lot of nice features, but dealing with some of the details in Mp client/server data sharing can get just a tad complicated sometimes lol.

 

Hey thanks again for the help :)

Share this post


Link to post
Share on other sites
The problem with creating separate global variables, is that I cannot seem to find a way to create a unique global name for each seperate player in client code.
player call BIS_fnc_objectVar

Will create a unique variable for the player and will be shared via PV across all machines. (In MP the name is based off of the objects netID if it does not already have a name)

Share this post


Link to post
Share on other sites
Guest

Thanks Larrow for the function :)

 

I've been trying to figure out how to use that, I think I got it right now :

 

Set a global on each clients end in the Init that is never public, and make it equal to the newly created variable :

 

SpecialControllerVar = player call BIS_fnc_objectVar;

 

(being it's a global, thought maybe I should avoid putting the word player in it to avoid any kind of game conflict)

 

And then in the script on client side, instead of using Player, or getting the player from AllUnits, just use the global to put into the Ai's Object var :

 

 

{ If ((Side _x == EAST) && ((_x Distance Player) < 50)) then {_x SetVariable ["PlayerCloseToEnemy",[1,SpecialControllerVar],True];}; } ForEach AllUnits;

 

 

And then, hopefully on server side, the server will recognize the variable passed as the particular player.

 

As long as the global there on client side is never made public, then of course on each clients end it will end up equaling their player object only.

 

 

I've got some testing to do.

 

Thanks!

 

 

/Edit

 

Got it all working now, didn't initially realize the variable name created is directly attached to the player unit, so on server side I just have to quickly cycle through the player units array to see which of the players has the variable attached :

 

 

   if (_EnemyPlayerShooterFlag == 1) then {

   {
   _x GetVariable _EnemyPlayerUnit;
   if !(IsNil "_EnemyPlayerUnit") then {[_CurrentUnit,_x] Call TakeCoverA;Hint Format ["Player Unit Found With !nil var %1",_x];};
   } ForEach ArrayOfPlayerUnits;

   } Else {[_CurrentUnit] Call TakeCoverA;};

 

 

Thanks again, phew, finally got it all working.

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

×