jwllorens 43 Posted July 30, 2016 I wrote a script to set up all the areas that can be captured around my map. Each area consists of a flag, a marker (ellipse that covers the area of interest), and one to three game logics that mark respawn positions. All of these use a naming convention so they can be found by my scripts easily during setup. Basically, I just type the name into the init script, and add the flag, marker, and logics where I want them around the area, and it creates a new sector. The idea is that I have several sectors. Each sector is captured by using a hold action on a flag pole in that sector for 10 seconds. This hold action is added to all clients via remoteExec, but only appears if the sector is not under your side's control which is determined by a public variable that is updated whenever the side of the sector changes. Capturing a sector also remoteExecs a function to the server which basically re-jiggers the local server variable containing all the pertinent information about that sector, and changes flag textures and marker colors and enables and disables respawns. This function also remoteExecs another function to all clients that alerts them that the area has been taken by CSAT or NATO, and plays a little sound depending on whether the side that took it is your enemy or not. What I want to know is if I am doing this horribly wrong. I can't test it because I only have one machine. Although I hope to be able to test it in a few months. Is this the proper way to do multiplayer coding? I am trying to do everything I can on the server, and keep only the really really local stuff on the clients. I am also trying to not publicvariable much at all and when I do trying to make sure they are not spammed. It all works (in singleplayer at least) but I just wanted to get some advice from more experienced coders to see if I am going in the wrong direction with tackling this problem. Here are the functions: initServer.sqf _areaNames = ["LumberYard","CommsAlpha","DieselPlant"]; //create a unique identifier for server variables that can't be fucked with by publicvariable. _nums = ["1","2","3","4","5","6","7","8","9","0"]; JWL_KeyCode = ""; for "_i" from 1 to 10 do { JWL_KeyCode = (JWL_KeyCode + (selectRandom _nums)); }; _nums = nil; //add respawn trucks as initial spawn point [west,JWL_SpawnTruck_west] call BIS_fnc_addRespawnPosition; [east,JWL_SpawnTruck_east] call BIS_fnc_addRespawnPosition; //start setting up all the objectives. { _area = _x; //get the flag variable, store it, delete global public variable. _flag = missionNamespace getVariable ("JWL_flag_" + _area); missionNamespace setVariable [("JWL_flag_" + _area),nil,true]; //Create readable name from variable name by inserting spaces _name = _area call JWL_fnc_insertSpace; //create respawn array _rArr = []; { _logic = missionNamespace getVariable ("JWL_respawn_" + _area + "_" + _x); if (!(isNil "_logic")) then { _rArr pushBack _logic; missionNamespace setVariable [("JWL_respawn_" + _area + "_" + _x),nil,true]; }; } count ["1","2","3"]; //set keyed areaData variable missionNamespace setVariable [("JWL_areaData_" + _x + "_" + JWL_KeyCode),[_name,independent,_flag,_rArr,[[[WEST,-1],[WEST,-1],[WEST,-1]],[[EAST,-1],[EAST,-1],[EAST,-1]]]],false]; missionNamespace setVariable [("JWL_areaSide_" + _x),independent,true]; //set flag texture and marker color _flag setFlagTexture "a3\data_f_exp\flags\flag_synd_co.paa"; ("JWL_areaMarker_" + _x) setMarkerColor "colorIndependent"; //add capture action to all the flags, make sure JIP = true _grbg = [ _flag, (format ["Capture %1",_name]), "\A3\ui_f\data\igui\cfg\simpleTasks\types\interact_ca.paa", "\a3\3DEN\Data\CfgWaypoints\Scripted_ca.paa", (format ["((_target distance _this) < 5) && ((missionNameSpace getVariable ""JWL_areaSide_%1"") != (side _this))",_x]), "true", {}, {}, {[((_this select 3) select 0),((_this select 3) select 1),(side (_this select 1))] remoteExecCall ["JWL_fnc_captureArea",2];}, {}, [_x,_name], 10, 0, false, false ] remoteExecCall ["BIS_fnc_holdActionAdd",([0,-2] select (isMultiplayer && isDedicated)),true]; } count _areaNames; //update areaSide on all computers for the local holdaction condition _areaNames spawn { _sideOld = []; while {true} do { { _aVar = missionNamespace getVariable ("JWL_areaData_" + _x + "_" + JWL_KeyCode); _sideNew = _aVar select 1; if (_sideNew != (_sideOld select _forEachIndex)) then { missionNamespace setVariable [("JWL_areaSide_" + _x),_sideNew,true]; hint "updated"; }; _sideOld set [_forEachIndex,_sideNew]; } forEach _this; sleep 1; }; }; fn_captureArea.sqf params [ ["_area", "", [""], 1], ["_name", "", [""], 1], ["_side", independent, [west], 1] ]; //get keyed area variable _aVar = missionNamespace getVariable ("JWL_areaData_" + _area + "_" + JWL_KeyCode); //set side of keyed area variable _aVar set [1, _side]; //flag object _flag = _aVar select 2; //logic entities for spawn locations _spawnLogics = _aVar select 3; //pull out respawn indices of area variable to work with it _spawnIndices = _aVar select 4; //empty variable to work with later _spawnIndicesSide = []; _color = switch (_side) do { case west: { { _spawnIndicesSide pushBack ([west,_x] call BIS_fnc_addRespawnPosition); _aVar set [4,_spawnIndices]; } count _spawnLogics; _spawnIndices set [0,_spawnIndicesSide]; { if ((_x select 1) != -1) then { _x call BIS_fnc_removeRespawnPosition; }; true } count (_spawnIndices select 1); ["a3\data_f\flags\flag_nato_co.paa","colorBLUFOR"] }; case east: { { _spawnIndicesSide pushBack ([east,_x] call BIS_fnc_addRespawnPosition); _aVar set [4,_spawnIndices]; } count _spawnLogics; _spawnIndices set [1,_spawnIndicesSide]; { if ((_x select 1) != -1) then { _x call BIS_fnc_removeRespawnPosition; }; true } count (_spawnIndices select 0); ["a3\data_f\flags\flag_csat_co.paa","colorOPFOR"] }; }; //set flag and marker colors/textures _flag setFlagTexture (_color select 0); ("JWL_areaMarker_" + _area) setMarkerColor (_color select 1); //alert all players [(_aVar select 0),_side] remoteExecCall ["JWL_fnc_alertCapture",([0,-2] select (isMultiplayer && isDedicated)),false]; missionNamespace setVariable [("JWL_areaData_" + _area + "_" + JWL_KeyCode),_aVar,true]; fn_alertCapture.sqf params [["_area", "NONE", [], 1], ["_side", civilian, [civilian], 1] ]; if (!((_area == "NONE") || ((_side != west) || (_side != east)))) exitWith {diag_log "ERROR: Must define both side and area!";}; _team = call { if (_side == west) exitWith {["NATO","2443D1"]}; if (_side == east) exitWith {["CSAT","D12424"]}; }; [(format["<t size='0.65' color='#%1'>%2</t>",(_team select 1),(_team select 0)]),(format["<t size='0.6' color='#E0E0E0'> captured %1!</t>",_area])] call BIS_fnc_showSubtitle; if ((side player) == _side) then [{playSound "FD_Timer_F";},{playSound "addItemFailed";}]; Share this post Link to post Share on other sites
Tiberius_161 41 Posted July 30, 2016 Hi Jwllorens, I cant say much about the code. What you can do is run a dedicated server from your own machine. https://forums.bistudio.com/topic/139003-tutorial-installation-configuration-of-arma3-dedicated-server/ I use this to test mission editing stuff on mp all the time ☺. Good luck! 1 Share this post Link to post Share on other sites
killzone_kid 1331 Posted July 31, 2016 I can't test it because I only have one machine. If your PC has good CPU you can easily run 2 clients and dedicated all on the same PC Share this post Link to post Share on other sites