ange1u5 11 Posted August 22, 2014 Hi there. I'm experimenting with attaching these helper markers like Sign_Arrow_Large_Blue_F to objects and that works fine. What I'd like though is to have these markers appear over players heads whilst driving. I can attach it to the player fine but as soon as I get into a vehicle and drive away, the marker sits at the last known position of the player before he got in the car. I can't attach it to specific cars because cars will change over the course of the mission. _playerarrow = "Sign_Arrow_F" createVehicle position p1; _playerarrow attachTo [p1,[0,-0.5,3]]; I have 14 players to assign this to. Any help appreciated :) Share this post Link to post Share on other sites
f2k sel 164 Posted August 22, 2014 You will need to run a loop to keep a track of the unit and update it. _playerarrow = "Sign_Arrow_F" createVehicle position p1; while {alive p1} do { vehicle _playerarrow attachTo [p1,[0,-0.5,3]]; sleep 1; }; Share this post Link to post Share on other sites
ange1u5 11 Posted August 23, 2014 Great, would I have to do that individually for each player or can I create an array for it? I did play around with. I tried something like _player = [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14] _playerarrow = "Sign_Arrow_F" createVehicle position _player; while {alive _player;} do { vehicle _playerarrow attachTo [_player,[0,-0.5,3]]; sleep 1; }; And a few other variations to no avail. Share this post Link to post Share on other sites
sxp2high 23 Posted August 23, 2014 (edited) You need to spawn one thread per player, or use a completely different method. If one of the 14 slots is empty (no player or ai) this will exit with an error (because pX doesn't exist at all). So it's probably better to use playableUnits + switchableUnits instead of direct references. Also, run this on the server only. Or use createVehicleLocal. Otherwise you will get 14 arrows per player. :D _player = (playableUnits + switchableUnits); { _x spawn { _player = _this; _playerarrow = "Sign_Arrow_F" createVehicle (getPosATL (vehicle _player)); _playerarrow attachTo [_player, [0,-0.5,3]]; while {alive _player} do { _vehicle = (vehicle _player); waitUntil {sleep 1; ((vehicle _player) != _vehicle)}; // Wait for vehicle change deTach _playerarrow; // Not sure if necessary _playerarrow attachTo [(vehicle _player), [0,-0.5,3]]; }; }; } forEach _player; This will not work with JIP and respawn however. If you use respawn or expect JIP, the code needs to be changed. Let me know. Edited August 23, 2014 by sxp2high Share this post Link to post Share on other sites
ange1u5 11 Posted August 23, 2014 I do indeed use respawn. JIP is generally not expected as once the race begins, anyone joining later will start at the beginning and there will be no chance for them to catch up. But should expect this as a factor though. Speaking of it though, is there actually a way to disable JIP once the mission begins, and if so is it advisable? Say a player drops out (as so often happens) he can't rejoin I would assume. I noticed the arrow obviously only moved every second because of sleep. If I set that to say 0.01 do I run the risk of crapping the server out because its running this thread constantly so fast? Share this post Link to post Share on other sites
sxp2high 23 Posted August 24, 2014 You can disable JIP, in a way. Advisable? I don't know. That's up to you. I probably wouldn't bother doing so. Usually admins lock the server to archive this. You could simply add a time check to your init.sqf though: if (time > 60) then { endMission "End1"; }; This means, if mission has been running for more than 60 seconds, the mission will be ended for new players that join afterwards. The once-a-second-update is because the code F2k Sel gave you is not really a nice solution. There is no reason to run the attachTo command each second, attachTo attaches it, so you don't have to update it constantly, it will stay with the unit. It should be perfectly fluid following the object/player/vehicle. The loop is only needed to account for the vehicle change. The code I posted, has this extra line added, that waits for the vehicle to actually change, before attaching again: waitUntil {sleep 1; ((vehicle _player) != _vehicle)}; // Wait for vehicle change But no, theoretically the server could easily handle 14 loops with sleep 0.01. Depending on how much else is running, the server could handle 50 of that or more. :) However, I would let each client handle it's own marker: if (!isDedicated) then { _playerarrow = createVehicle ["Sign_Arrow_F", (getPosATL (vehicle player)), [], 0, "NONE"]; _playerarrow attachTo [player, [0,-0.5,3]]; while {true} do { _vehicle = (vehicle player); waitUntil {sleep 1; ((vehicle player) != _vehicle) || !(alive player)}; // Wait for vehicle change OR player not alive deTach _playerarrow; // Not sure if necessary if (!(alive player)) then { waitUntil {(alive player)}; }; // If player is dead, wait for respawn _playerarrow attachTo [(vehicle player), [0,-0.5,3]]; }; }; Share this post Link to post Share on other sites
ange1u5 11 Posted August 24, 2014 Works a treat, thank you =D One more question though, looking at it, though I like it myself, I can imagine some people might find it irritating or an eyesore. Would an addaction work best to toggle the signs on or off as they choose? If so how? Share this post Link to post Share on other sites
sxp2high 23 Posted August 24, 2014 Well, good decision, I wouldn't like them either. addAction should be avoided, especially for minor things like this. Action menu is cumbersome and cluttered enough as it is :) Probably best to use a button press to toggle them on and off. First you need to change the code, so all arrows are added to an array, so you can refer to them: if (isServer) then { player_arrows = []; publicVariable "player_arrows"; // Create array on the server }; if (!isDedicated) then { waitUntil {!(isNil "player_arrows")}; // wait for the server _playerarrow = createVehicle ["Sign_Arrow_F", (getPosATL (vehicle player)), [], 0, "NONE"]; _playerarrow attachTo [player, [0,-0.5,3]]; player_arrows set [(count player_arrows), _playerarrow]; publicVariable "player_arrows"; // Add arrow to the array and publicize while {true} do { _vehicle = (vehicle player); waitUntil {sleep 1; ((vehicle player) != _vehicle) || !(alive player)}; // Wait for vehicle change OR player not alive deTach _playerarrow; // Not sure if necessary if (!(alive player)) then { waitUntil {(alive player)}; }; // If player is dead, wait for respawn _playerarrow attachTo [(vehicle player), [0,-0.5,3]]; }; }; Then add a displayEventHandler for the button: [] spawn { // Function for toggle fnc_toggleArrows = { if (isNil "toggleArrows") then { toggleArrows = true; { _x hideObject true; } forEach player_arrows; // Hide all arrows } else { toggleArrows = nil; { _x hideObject false; } forEach player_arrows; // UN-hide all arrows }; }; waituntil {!(isNull (finddisplay 46))}; // needed for displayeventhandlers sleep 0.1; // sometimes they dont get added without a tiny sleep // Add keyhandler _keyHandlerUp = (findDisplay 46) displayAddEventHandler ["KeyUp", "if ((_this select 1) == 23) then { [] call fnc_toggleArrows; };"]; hint "Press I to toggle player markers."; }; Key would be i in this example. Which is 23. _keyHandlerUp = (findDisplay 46) displayAddEventHandler ["KeyUp", "if ((_this select 1) == [b][color="#FF0000"]23[/color][/b]) then { [] call fnc_toggleArrows; };"]; Change that to whatever you see fit. A list of the available keycodes can be found here. 1 Share this post Link to post Share on other sites