Jump to content
simicsko

Run a script on behalf of a specific player (MP)

Recommended Posts

Hello All!

How to use a script on behalf of a specific player in multiplayer mode?

There is an object whose INIT field contains this line to run the script (for testing):


this addAction [("<t color=""#00FF00"">" + ("PlayerName") +"</t>"), "PlayerName.sqf",[],1,false,true];

This is the content of the PlayerName.sqf script:

_playerName = name player;
if (_name == "Playername1") then {hint "Hello Alpha_1";};
if (_name == "Playername2") then {hint "Hello Bravo_1";};
hint str _playerName;

Playername1 runs the server and Playername2 is the client.

If I run it with PlayerName1, it shows "Hello Alpha_1", but if I run it with Playername2, it doesn't. The goal is to execute different code depending on the player's name. Can someone help me with this?

Share this post


Link to post
Share on other sites

You don't give us a lot to work with 🙂

 

There's nothing wrong with playername.sqf except maybe that there's no delay before the third hint which means it would immediately override the previous two.

 

My guess is on this being a locality issue. addAction has local effect, meaning two things:

1. the action is added only on the machine executing addAction.

2. When activated the action code runs only on the machine that triggered the activation (the pc belonging to the player who used the action).

 

The "player" command returns the player of the current machine, combine that with point 2 above and you've got a likely explanation for the issue.

 

I recommend reading up on multiplayer locality on the BIKI.

 

For more support your stated goal is too generic, I'd need more info on your actual use case. What do you wish to accomplish and who is involved?

16 hours ago, simicsko said:

The goal is to execute different code depending on the player's name

 

Share this post


Link to post
Share on other sites
19 hours ago, simicsko said:

If I run it with PlayerName1, it shows "Hello Alpha_1"

I doubt it does this as you check _name which is undefined.

 

At the most, all its doing is this...

_playerName = name player;
hint str _playerName;

 

Share this post


Link to post
Share on other sites
19 hours ago, mrcurry said:

You don't give us a lot to work with 🙂

 

 

I'm sorry if I ask too much but I'm just learning scripting and I haven't managed to solve the secret of this "local" or "non-local" execution yet. 🙂

The goal is to:

There is a helicopter and a jeep on standby at the base and can be called to the battlefield with a trigger. When the script starts, the helicopter will bring the jeep to the location where the player is standing at the moment of the request. Then it goes back to the base (Supp_WP3) and is deleted.

My son and I used to play together. Thus, there are two playable units in the mission, called Alpha_1 and Bravo_1.

I would like to solve it within a script so that the given helicopter takes the jeep to the player who requests it. If I write it in a separate script for Alpha_1 and Bravo_1 (using getPosATL Alpha_1 and getPosATL Bravo_1 methods), it works great.

But if the script is written in the following way, it will always recognize the Alpha_1 player who is hosting the mission. Of course, the name Player1 and Player2 is replaced by our real Arma3 name.

It was also observed that if I remove the "if (isServer)" condition from the script, the helikpoter does not perform the "UNHOOK" task, it just descends with it, but does not release it, but raises it again.

So I would like your help to understand why these things are not working. 🙂 What do I do wrong?

_name = name player;

if (_name == "Player1") then {Alpha_1 sideChat "Alpha_1 requesting vehicle support!";};

if (_name == "Player2") then {Bravo_1 sideChat "Bravo_1 requesting vehicle support!";};

sleep 5;

["VEHICLE SUPPORT STARTED"] spawn BIS_fnc_infoText;

if (isServer) then { 

_success1 = Supply_Heli_1 setSlingLoad SJeep_1;

_POS11 = position player;
_POS13 = getMarkerPos "Supp_WP3";

_Supp1wp1 = SupplyTransport_1 addWaypoint [_POS11, 0];
	_Supp1wp1 setWaypointType "UNHOOK"; 
	_Supp1wp1 setWaypointSpeed "FULL";
	_Supp1wp1 setWaypointBehaviour "CARELESS"; 
	_Supp1wp1 setWaypointCombatMode "GREEN";
	_Supp1wp1 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 10;"];
	_Supp1wp1 setWaypointStatements  ["true", "_success1 = Supply_Heli_1 setSlingLoad objNull;"];

_Supp1wp3 = SupplyTransport_1 addWaypoint [_POS13, 0];
	_Supp1wp3 setWaypointType "MOVE"; 
	_Supp1wp3 setWaypointSpeed "FULL";
	_Supp1wp3 setWaypointBehaviour "CARELESS"; 
	_Supp1wp3 setWaypointCombatMode "GREEN";
	_Supp1wp2 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 5;"];
	_Supp1wp3 setWaypointStatements ["true", "{deleteVehicle _x;}forEach crew Supply_Heli_1; deleteVehicle Supply_Heli_1;"];

}; 

 

Share this post


Link to post
Share on other sites

Use available params.

 

addAction:

this addAction
[
	("<t color=""#00FF00"">" + ("PlayerName") +"</t>"), 
	{
		params ["_target", "_caller", "_actionId", "_arguments"];
		[_caller] execVM "PlayerName.sqf";
	},
	nil,
	1,
	false,
	true
];

PlayerName.sqf:

params ["_caller"];

_name = name _caller;

if (_name == "Player1") then {Alpha_1 sideChat "Alpha_1 requesting vehicle support!";};

if (_name == "Player2") then {Bravo_1 sideChat "Bravo_1 requesting vehicle support!";};

sleep 5;

["VEHICLE SUPPORT STARTED"] spawn BIS_fnc_infoText;

if (isServer) then { 

_success1 = Supply_Heli_1 setSlingLoad SJeep_1;

_POS11 = position _caller;
_POS13 = getMarkerPos "Supp_WP3";

_Supp1wp1 = SupplyTransport_1 addWaypoint [_POS11, 0];
	_Supp1wp1 setWaypointType "UNHOOK"; 
	_Supp1wp1 setWaypointSpeed "FULL";
	_Supp1wp1 setWaypointBehaviour "CARELESS"; 
	_Supp1wp1 setWaypointCombatMode "GREEN";
	_Supp1wp1 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 10;"];
	_Supp1wp1 setWaypointStatements  ["true", "_success1 = Supply_Heli_1 setSlingLoad objNull;"];

_Supp1wp3 = SupplyTransport_1 addWaypoint [_POS13, 0];
	_Supp1wp3 setWaypointType "MOVE"; 
	_Supp1wp3 setWaypointSpeed "FULL";
	_Supp1wp3 setWaypointBehaviour "CARELESS"; 
	_Supp1wp3 setWaypointCombatMode "GREEN";
	_Supp1wp2 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 5;"];
	_Supp1wp3 setWaypointStatements ["true", "{deleteVehicle _x;}forEach crew Supply_Heli_1; deleteVehicle Supply_Heli_1;"];

};

Not tested.

Share this post


Link to post
Share on other sites
11 hours ago, Harzach said:

Use available params.

 

addAction:


this addAction
[
	("<t color=""#00FF00"">" + ("PlayerName") +"</t>"), 
	{
		params ["_target", "_caller", "_actionId", "_arguments"];
		[_caller] execVM "PlayerName.sqf";
	},
	nil,
	1,
	false,
	true
];

If I put the "this addiction" section in the init field of an object, then "PlayerName" appears in the object's menu, and when called, it attaches the jeep to the helicopter, but the helicopter does not start. I think it's because the "_POS11 = position _caller;" command cannot identify the caller, so it cannot create a waypoint.

Do you have an idea?

 

Share this post


Link to post
Share on other sites
On 3/16/2023 at 7:46 AM, simicsko said:

if (isServer) then { 

_success1 = Supply_Heli_1 setSlingLoad SJeep_1;

_POS11 = position player;
_POS13 = getMarkerPos "Supp_WP3";

_Supp1wp1 = SupplyTransport_1 addWaypoint [_POS11, 0];
	_Supp1wp1 setWaypointType "UNHOOK"; 
	_Supp1wp1 setWaypointSpeed "FULL";
	_Supp1wp1 setWaypointBehaviour "CARELESS"; 
	_Supp1wp1 setWaypointCombatMode "GREEN";
	_Supp1wp1 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 10;"];
	_Supp1wp1 setWaypointStatements  ["true", "_success1 = Supply_Heli_1 setSlingLoad objNull;"];

_Supp1wp3 = SupplyTransport_1 addWaypoint [_POS13, 0];
	_Supp1wp3 setWaypointType "MOVE"; 
	_Supp1wp3 setWaypointSpeed "FULL";
	_Supp1wp3 setWaypointBehaviour "CARELESS"; 
	_Supp1wp3 setWaypointCombatMode "GREEN";
	_Supp1wp3 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 5;"];
	_Supp1wp3 setWaypointStatements ["true", "{deleteVehicle _x;}forEach crew Supply_Heli_1; deleteVehicle Supply_Heli_1;"];

}; 

 

This will only ever happen if the host uses the action because of the isServer.

 

2 hours ago, simicsko said:

	_Supp1wp3 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 5;"];
	_Supp1wp3 setWaypointStatements ["true", "{deleteVehicle _x;}forEach crew Supply_Heli_1; deleteVehicle Supply_Heli_1;"];

 

A waypoint only has one waypointStatement, all you're doing here is immediately replacing the first with the second. Same for both waypoints.

 

 

Separate out the slingLoading stuff into its own function and remoteExec it on the server/where the vehicle is local.

//Description.ext

class CfgFunctions {
	class supportFunctions {
		tag = "TAG";
		class sling {
			file = "functions";
			class slingSupport {};
		};
	};
};
//functions\fn_slingSupport.sqf

params[ "_caller" ];

_success1 = Supply_Heli_1 setSlingLoad SJeep_1;

_POS11 = getPosATL _caller;
_POS13 = getMarkerPos "Supp_WP3";

_Supp1wp1 = SupplyTransport_1 addWaypoint [_POS11, 0];
_Supp1wp1 setWaypointType "UNHOOK"; 
_Supp1wp1 setWaypointSpeed "FULL";
_Supp1wp1 setWaypointBehaviour "CARELESS"; 
_Supp1wp1 setWaypointCombatMode "GREEN";
_Supp1wp1 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 10;"];
//Make sure heli is at a decent height before dropping the sling load
_Supp1wp1 setWaypointStatements  ["true", "
	[] spawn {
		Supply_Heli_1 flyInHeight 10;
		waituntil{ getPosATL Supply_Heli_1 select 2 <= 11 };
		_success1 = Supply_Heli_1 setSlingLoad objNull;
	};
"];

_Supp1wp3 = SupplyTransport_1 addWaypoint [_POS13, 0];
_Supp1wp3 setWaypointType "MOVE"; 
_Supp1wp3 setWaypointSpeed "FULL";
_Supp1wp3 setWaypointBehaviour "CARELESS"; 
_Supp1wp3 setWaypointCombatMode "GREEN";
_Supp1wp3 setWaypointStatements ["true", "{deleteVehicle _x;}forEach ( crew Supply_Heli_1 + Supply_Heli_1 );"];
//Object Init
this addAction
[
	("<t color=""#00FF00"">" + ("PlayerName") +"</t>"), 
	{
		params ["_target", "_caller", "_actionId", "_arguments"];
		[_caller] execVM "PlayerName.sqf";
	},
	nil,
	1,
	false,
	true
];
//PlayerName.sqf

params ["_caller"];

//As you were using Alpha_1/Bravo_1 global vars I presume this is set in the unit var field so will be their vehicleVarName
_caller sideChat format[ "%1 requesting vehicle support!", vehicleVarName _caller ];

sleep 5;

//This will only be seen by the caller
["VEHICLE SUPPORT STARTED"] spawn BIS_fnc_infoText;

//Call the function handling the sling support on the server( 2 ) 
//As its an AI vehicle this is more than likely where it is located
[ _caller ] remoteExec[ "TAG_fnc_slingSupport", 2 ];

Untested

  • Thanks 1

Share this post


Link to post
Share on other sites
2 hours ago, Larrow said:

This will only ever happen if the host uses the action because of the isServer.

 

A waypoint only has one waypointStatement, all you're doing here is immediately replacing the first with the second. Same for both waypoints.

 

 

Separate out the slingLoading stuff into its own function and remoteExec it on the server/where the vehicle is local.


//Description.ext

class CfgFunctions {
	class supportFunctions {
		tag = "TAG";
		class sling {
			file = "functions";
			class slingSupport {};
		};
	};
};

//functions\fn_slingSupport.sqf

params[ "_caller" ];

_success1 = Supply_Heli_1 setSlingLoad SJeep_1;

_POS11 = getPosATL _caller;
_POS13 = getMarkerPos "Supp_WP3";

_Supp1wp1 = SupplyTransport_1 addWaypoint [_POS11, 0];
_Supp1wp1 setWaypointType "UNHOOK"; 
_Supp1wp1 setWaypointSpeed "FULL";
_Supp1wp1 setWaypointBehaviour "CARELESS"; 
_Supp1wp1 setWaypointCombatMode "GREEN";
_Supp1wp1 setWaypointStatements  ["true", "Supply_Heli_1 flyInHeight 10;"];
//Make sure heli is at a decent height before dropping the sling load
_Supp1wp1 setWaypointStatements  ["true", "
	[] spawn {
		Supply_Heli_1 flyInHeight 10;
		waituntil{ getPosATL Supply_Heli_1 select 2 <= 11 };
		_success1 = Supply_Heli_1 setSlingLoad objNull;
	};
"];

_Supp1wp3 = SupplyTransport_1 addWaypoint [_POS13, 0];
_Supp1wp3 setWaypointType "MOVE"; 
_Supp1wp3 setWaypointSpeed "FULL";
_Supp1wp3 setWaypointBehaviour "CARELESS"; 
_Supp1wp3 setWaypointCombatMode "GREEN";
_Supp1wp3 setWaypointStatements ["true", "{deleteVehicle _x;}forEach ( crew Supply_Heli_1 + Supply_Heli_1 );"];

//Object Init
this addAction
[
	("<t color=""#00FF00"">" + ("PlayerName") +"</t>"), 
	{
		params ["_target", "_caller", "_actionId", "_arguments"];
		[_caller] execVM "PlayerName.sqf";
	},
	nil,
	1,
	false,
	true
];

//PlayerName.sqf

params ["_caller"];

//As you were using Alpha_1/Bravo_1 global vars I presume this is set in the unit var field so will be their vehicleVarName
_caller sideChat format[ "%1 requesting vehicle support!", vehicleVarName _caller ];

sleep 5;

//This will only be seen by the caller
["VEHICLE SUPPORT STARTED"] spawn BIS_fnc_infoText;

//Call the function handling the sling support on the server( 2 ) 
//As its an AI vehicle this is more than likely where it is located
[ _caller ] remoteExec[ "TAG_fnc_slingSupport", 2 ];

Untested

The following is still the problem: "PlayerName" appears in the object's menu, and when called, it attaches the jeep to the helicopter, but the helicopter does not start.

I don't understand why the helicopter doesn't start, even though what you wrote seems logical. Do you have an idea?

Share this post


Link to post
Share on other sites
58 minutes ago, simicsko said:

"PlayerName" appears in the object's menu,

Of course, you have "PlayerName" as STRING for the title. What do you want? each player to have an action named... ?

 

59 minutes ago, simicsko said:

but the helicopter does not start.

What exactly is SupplyTransport_1 ? Should be a group as you adding a waypoint to it.

Share this post


Link to post
Share on other sites
16 minutes ago, Larrow said:

Of course, you have "PlayerName" as STRING for the title. What do you want? each player to have an action named... ? 

 

What exactly is SupplyTransport_1 ? Should be a group as you adding a waypoint to it. 

 

I want the helicopter to be able to call any player to their position.

 

The SupplyTransport_1 is the name of the helicopter group (Composition Variable Name).

Share this post


Link to post
Share on other sites

Provide a simple stripped down test mission.

The helicopter, slingload jeep, two players and the object with action on it, so we can see where you are going wrong.

  • Thanks 1

Share this post


Link to post
Share on other sites
5 hours ago, Larrow said:

Provide a simple stripped down test mission.

The helicopter, slingload jeep, two players and the object with action on it, so we can see where you are going wrong. 

 

All right. Please be patient, I will probably be at the machine again on Sunday or monday

Share this post


Link to post
Share on other sites
On 3/18/2023 at 3:14 PM, Larrow said:

Provide a simple stripped down test mission.

The helicopter, slingload jeep, two players and the object with action on it, so we can see where you are going wrong.

 

Brilliant solution! 👌

Working perfectly.

I found out why the helicopter didn't start: In the original mission, I started the helicopter with a trigger that was assigned with a waypoint activation. That's why it didn't start. 🙂

One small thing: at the last waypoint, this line did not delete the helicopter:

_Supp1wp3 setWaypointStatements ["true", "{deleteVehicle _x;}forEach ( crew Supply_Heli_1 + Supply_Heli_1 );"];

I replaced it with this one, it works like this:

_Supp1wp3 setWaypointStatements ["true", "{deleteVehicle _x;}forEach crew Supply_Heli_1; deleteVehicle Supply_Heli_1;"];

Dear Larrow, thank you very much for your help! 😉

Share this post


Link to post
Share on other sites

crew Supply_Heli_1 + Supply_Heli_1  is a forbidden sum of an array + an object. Write crew supply_Heli_1 + [supply_Heli_1] instead. (just as side note)

you can also simply:

deleteVehicleCrew supply_Heli_1; deleteVehicle supply_Heli_1;  since v2.06

 

 

 

  • Like 2

Share this post


Link to post
Share on other sites
19 hours ago, simicsko said:

One small thing: at the last waypoint, this line did not delete the helicopter:

Oops my mistake, as pierremgi says I forgot to add the heli as an array.

  • Like 1

Share this post


Link to post
Share on other sites
21 hours ago, Larrow said:

Oops my mistake, as pierremgi says I forgot to add the heli as an array.

No problem! 🙂

Could you help me as much as how I can start the process on behalf of the player from the Scroll menu?

I tried to include what you wrote for object init, but for some reason it doesn't work. The first menu item is self-healing, it works perfectly. But calling the helikpoter doesn't:

menu0 =  {
	
	player addAction[("<t color=""#7FFF00"">" + ("Heal Yourself") +"</t>"),{execVM "MEDICAL\selfHealing.sqf"}];	

	player addAction
	[
		("<t color=""#00FF00"">" + ("PlayerName") +"</t>"), 
		{
			params ["_target", "_caller", "_actionId", "_arguments"];
			[_caller] execVM "PlayerName.sqf";
		},
		nil,
		1,
		false,
		true
	];

}; []spawn menu0;

hint "PLAYER MENU LOADED";

I tried a trigger (that might be the problem), which detects the spawning of the aforementioned players Alpha_1 and Bravo_1 (Object varNames) and starts the Scrollmenu.sqf script:

Trigger Condition:
Alpha_1 inArea thisTrigger;

On Activation:
execVM "ScrollMenu.sqf";

I would like to solve it with a menu so that the options are not limited by the number of radios that can be called with the trigger (Alpha to India).

Share this post


Link to post
Share on other sites
On 3/22/2023 at 12:47 PM, simicsko said:

I tried to include what you wrote for object init, but for some reason it doesn't work. The first menu item is self-healing, it works perfectly. But calling the helikpoter doesn't:

Should work, if your heal action works I'm not sure why the other wouldn't.

 

On 3/22/2023 at 12:47 PM, simicsko said:

I tried a trigger (that might be the problem), which detects the spawning of the aforementioned players Alpha_1 and Bravo_1 (Object varNames) and starts the Scrollmenu.sqf script:

Just exec the script to apply the menu from the initPlayerLocal.sqf if the player is Alpha_1 or Bravo_1. May have to wait on the player being not null and alive depending on your respawn settings, but again if your heal is working I would expect the other to work also.

 

 

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

×