Harvath.S 3 Posted November 8, 2018 I have searched both google and the forums for this and see a couple answers to this question that do not make sense to me. I have a couple different firing ranges for my unit that are run via script. They work correctly in both hosted and on the dedi with one small exception. The rangemaster - which is a recording of one of our members played in the script - only executes on the player that activated the firing range, even though the range itself is working for every player on the server. I am 100% sure that it is a locality issue, as the addAction that calls the sqf is located in the init.sqf of the mission. I keep finding answers that have things like this: [Computadora1, ['Disparar a Barco',{<your code here>}] ] remoteExec ["addAction",0,true]; But I do not understand exactly what it all means as most people just provide a script and not an explanation of why it fixes the issues. My question is: how do I execute the addAction in game via remoteExec so that all players can both see the range and hear the rangemaster? Below is a snippet of my range code that involves the recordings - just to ensure that I haven't made a boneheaded error. init.sqf Spoiler laptop1 addAction ["Activate Range","Scripts\range4.sqf"]; range4.sqf (partial) Spoiler {_x animate["terc",1]} forEach _targets; nopop=true; sleep 4; loud4 say3D "L1"; loud5 say3D "L1"; sleep 1; loud4 say3D "QR1"; loud5 say3D "QR1"; sleep 12; loud4 say3D "Hot"; loud5 say3D "Hot"; sleep 3; l4_200_1 animate["terc", 0]; l4_200_2 animate["terc", 0]; l4_200_3 animate["terc", 0]; l4_200_4 animate["terc", 0]; l4_200_5 animate["terc", 0]; sleep 25; if (l4_200_1 animationPhase "terc" != 0) then { _count = _count + 1; }; l4_200_1 animate["terc", 1]; _inc = _inc +1; if (l4_200_2 animationPhase "terc" != 0) then { _count = _count + 1; }; l4_200_2 animate["terc", 1]; _inc = _inc +1; if (l4_200_3 animationPhase "terc" != 0) then { _count = _count + 1; }; l4_200_3 animate["terc", 1]; _inc = _inc +1; if (l4_200_4 animationPhase "terc" != 0) then { _count = _count + 1; }; l4_200_4 animate["terc", 1]; _inc = _inc +1; if (l4_200_5 animationPhase "terc" != 0) then { _count = _count + 1; }; l4_200_5 animate["terc", 1]; _inc = _inc +1; loud4 say3D "L1"; loud5 say3D "L1"; sleep 1; loud4 say3D "Cease"; loud5 say3D "Cease"; sleep 8; loud4 say3D "L1"; loud5 say3D "L1"; sleep 1; loud4 say3D "QR2"; loud5 say3D "QR2"; sleep 14; loud4 say3D "Hot"; loud5 say3D "Hot"; sleep 3; l4_200_1 animate["terc", 0]; l4_200_2 animate["terc", 0]; l4_200_3 animate["terc", 0]; l4_200_4 animate["terc", 0]; l4_200_5 animate["terc", 0]; sleep 25; Thank you all in advance for the help! 1 Share this post Link to post Share on other sites
davidoss 552 Posted November 8, 2018 first of all you need to decide where you put addaction command. Editor init field of object or script. This addaction command is simple. Works like eventhandler without event (push by player) If you use init.sqf or editors init field of object (laptop) you do not need to remoteexec addaction because those places are executed by any client already. But keep in mind it will only add a action to object. Next is commands locality in your scrip executed by action. There are two "params" about. Argument and effect. For example say3d: loud4 say3D "L1"; In this case Argument is loud4 and this dont have to be local to the client where command is executed. An effect of this is local it means sound "L1" can be hear only by client where the say3d command was executed. To allow it to be hear by everyone you need to remoteexec it like this: [loud4,"L1"] remoteexec ["say3d",[0,-2] select isDedicated,false]; Commands parameters locality you can always check on wiki and this looks like: 1 1 Share this post Link to post Share on other sites
Harvath.S 3 Posted November 8, 2018 Thanks for the response! So should I change the say3D command over to a playSound3D instead? I thought since the init.sqf was executed on every client that the script would also execute that way, hence the use of say3D. But since that is not the case, using playSound3D, which executes on every computer on the network, should work..... Right? Share this post Link to post Share on other sites
pierremgi 4850 Posted November 8, 2018 You can remoteExec the say3D as well as a hint . The inner code is local (only for caller) but the effect of each command can be local or global (public). If command, you can remoteExec it. The true difficulty for such code (in addAction or event hanlders) is that you need to think about effect for each command/function inside. Furthermore, the arguments are also important, even if, most of time are friendly and can be applied without problem. The latest commands are often like that. But... with command, difficulty raises when you apply such command/function on an object which is not local (doesn't belong to the player caller of addAction). All are not equal for that. You can read: "Arguments of this scripting command have to be local to the client the command is executed on". There are plenty of cases where a car owner switches (when the driver changes). A laptop is usually on server, but you can't say in advance whom the car will belong to. Same for units who depend on their group leader (AI leader on server or HC, players on clients) So, most of the time, applying a code on an object, here, will look like: [yourObject, arguments] remoteExec ["yourCommand" , yourObject]; see remoteExec for details. @davidoss Did you ever experience an error for a globally remote executed addAction, even on a dedicated server? IMHO, [0,-2] select isDedicated is not important. I know there is no player to play addAction on dedi, but that doesn't return any error. Or, i missed something. 1 Share this post Link to post Share on other sites
davidoss 552 Posted November 8, 2018 Of course its not. Anyway we should always carry about where things goes especially about network stuff. We all knew how laggy/desync arma can get. If you don't need something there don't put it there - best idea i think. 3 Share this post Link to post Share on other sites
HazJ 1289 Posted November 9, 2018 Not directly related to the thread question but: Sometimes it isn't ideal to remoteExec actions but rather handle them client-side. Even for JIP. It all comes down to specifics though, and your mission structure. Just something to keep in mind. 1 Share this post Link to post Share on other sites
Tankbuster 1744 Posted November 9, 2018 6 hours ago, HazJ said: Not directly related to the thread question but: Sometimes it isn't ideal to remoteExec actions but rather handle them client-side. Even for JIP. It all comes down to specifics though, and your mission structure. Just something to keep in mind. Yes, very much. my non expert method is to add the addaction to the players right at the start, but hold them off using a condition. Having the server set the condition on the client is better than having the server add the addaction. 1 Share this post Link to post Share on other sites
pierremgi 4850 Posted November 9, 2018 4 hours ago, Tankbuster said: Having the server set the condition on the client is better than having the server add the addaction. Could you elaborate? Share this post Link to post Share on other sites
Tankbuster 1744 Posted November 9, 2018 6 hours ago, pierremgi said: Could you elaborate? The addaction has a condition field. In there, you check a boolean variable which is set by the server when and only when you want to addaction to appear. It can be a public variable if the addaction is to appear of all players simultaneously, or the server can publicvariableclient or setvariable the boolean when the addaction is supposed to be shown to the player. Share this post Link to post Share on other sites
pierremgi 4850 Posted November 9, 2018 2 hours ago, Tankbuster said: The addaction has a condition field. In there, you check a boolean variable which is set by the server when and only when you want to addaction to appear. It can be a public variable if the addaction is to appear of all players simultaneously, or the server can publicvariableclient or setvariable the boolean when the addaction is supposed to be shown to the player. As discussion, it's difficult for me to understand: "you check a boolean variable which is set by the server when and only when you want to addaction to appear." Imho, the addAction checks conditions on clients/hosted where the script runs the addAction command, locally, and each frame. I can't imagine a broadcast check on each frame. If you place this command in an init field of an object, every client/hosted will run this command at local start. There is absolutely no reason to check some conditions from server. Furthermore, apart, if you place this command in a server script (server only trigger, initServer.sqf...) , usually for spawning objects/units, the addaction will be seen on hosted server only (noob error). But you can remoteExec the command from anywhere BI says: The action can only be activated when in proximity to the object (default 50m). Adding an action to the player obviously makes that action available to the player at all times. On my mind, that means that: - the whole condition is checked on each frame (and locally) if you apply the addAction to the player; - an embedded distance condition (not your code) has to check if the player is within 50 m of the object, target of the addAction, on each frame. If yes, then your code is checked, on each frame also til the embedded distance condition is false. Now, to see where an addAction condition is checked , in both cases (on player or object), you can write a code like: "hint 'ok'; _target distance _this < 10" The condition parameter must end by a boolean but you have a cheap onEachFrame code before. Share this post Link to post Share on other sites
Larrow 2820 Posted November 10, 2018 I don't think you understand what TB is getting at. //Some object init field this addaction[ "Use Me" , { hint "Action Used"; },[],1,true,true, "missionNamespace getvariable[ 'someVar', false ]" ]; //Server side //when you want the action to be available to clients someVar = true; publicVariable "someVar"; //when you don't want the action to be available to clients someVar = false; publicVariable "someVar"; 3 2 Share this post Link to post Share on other sites
pierremgi 4850 Posted November 10, 2018 Ah OK...bright clearer as is. Furthermore, that's the method I'm using here for grabbing/ dropping a canister or a truck battery in MP here. Sorry for the misunderstanding. 2 Share this post Link to post Share on other sites
Tankbuster 1744 Posted November 10, 2018 @Larrow to the rescue again! Thank you. You can publicvariableclient the variable to individual clients using this method too 1 Share this post Link to post Share on other sites
Harvath.S 3 Posted November 14, 2018 My apologies for the delay in response, work is a cruel mistress. I will be tweaking the scripts applying the knowledge from what you all have posted. I think I learned more catching up on this forum than I realized. I will update within the next day or two with the outcome of the editing. Share this post Link to post Share on other sites
noricum 10 Posted November 14, 2018 Hello Community, May someone can help me here too? I ran into a similar Problem and thought i ask/post it here. Basically i try to spawn an object on a dedicated Server with an Action: // Spawn OBj on dedicated Server if (isServer) then { terminal = createVehicle ["Land_DataTerminal_01_F", _rndPos, [], 0, "NONE"]; [terminal, ["Download Intel", "scripts\intel.sqf", nil, 2, true, true, "", "true", 3.5, false]] remoteExec ["addAction",0, true]; }; And here goes the simple Action: //Intel.sqf if (isServer) then { Systemchat "Downloading Intel - STANDBY"; sleep 3; removeAllActions terminal; sleep 2; terminal setdamage 1; Systemchat "Downloading Intel - FINISHED"; sleep 5; deleteVehicle terminal; }; I tried already different ways to get this work, but failed at every attempt (like systemchats are shown, but the object doesn't get deleted) - kinda clueless now. So, if someone could provide me a solution or a hint, what's going on here, it will be highly appreciated! Share this post Link to post Share on other sites
pierremgi 4850 Posted November 14, 2018 You created a "Land_DataTerminal_01_F" but terminal is a variable known on server only. Your intel.sqf runs locally to the caller, so that can't work with if (isServer) except for the hosting one. if (isServer) then { terminal = createVehicle ["Land_DataTerminal_01_F", _rndPos, [], 0, "NONE"]; [terminal, ["Download Intel", "scripts\intel.sqf", nil, 2, true, true, "", "true", 3.5, false]] remoteExec ["addAction",0, terminal]; }; //Intel.sqf params ["_target"]; Systemchat "Downloading Intel - STANDBY"; removeAllActions _target; sleep 5; Systemchat "Downloading Intel - FINISHED"; sleep 5; deleteVehicle _target; 3 2 Share this post Link to post Share on other sites
noricum 10 Posted November 15, 2018 THANK YOU very much! It works now Share this post Link to post Share on other sites
HazJ 1289 Posted November 16, 2018 Alternative method would be just publicVariable/publicVariableClient the terminal variable, ditch the remoteExec and create addAction locally when joining (initPlayerLocal). All down to you, many possible ways for most things. Not all are best approach, depends for certain situations. Share this post Link to post Share on other sites
LSValmont 789 Posted April 25, 2019 On 11/10/2018 at 12:11 AM, Larrow said: I don't think you understand what TB is getting at. //Some object init field this addaction[ "Use Me" , { hint "Action Used"; },[],1,true,true, "missionNamespace getvariable[ 'someVar', false ]" ]; //Server side //when you want the action to be available to clients someVar = true; publicVariable "someVar"; //when you don't want the action to be available to clients someVar = false; publicVariable "someVar"; I think this method is the most efficient bandwidth wise! But how would you apply this method if the object (to get the addAction) is spawned via script rather than EDITOR (So no access to Object's init field)? Share this post Link to post Share on other sites
pierremgi 4850 Posted April 25, 2019 This is specific to the init field of the edited object. But when you spawn an object by a command or a function in a script, usually the returned value is the object and you can run your code on it.Here you need to remoteExec the code (such as an init field which is "public", ran by all players) Example: _veh = "C_Offroad_01_F" createVehicle position player; [_veh,[ "Use Me" , { hint "Action Used"; },[],1,true,true, "missionNamespace getvariable[ 'someVar', false ]" ] ] remoteExec ["addAction",[0,-2] select isdedicated] ; 1 1 Share this post Link to post Share on other sites