lenymo 10 Posted December 3, 2014 So i have a few questions and hopefully they dont seem too ignorant. I am currently writing a bounty hunter mission for a wasteland server. At the start of the mission a random player is selected to be the bounty and they need to live for 20 minutes. What would be the best way to select the player at random? while searching through the forums I found the following code off of an A2 post but it does make sense to me: _unit = playableUnits select floor(random count playableUnits) ---------- Post added at 19:22 ---------- Previous post was at 19:21 ---------- And I hit the submit button too early, lol I was also wanting to know the best way to check if the player is alive or dead for the reward to spawn. Share this post Link to post Share on other sites
jshock 513 Posted December 3, 2014 _unit = playableUnits call BIS_fnc_selectRandom; if (isPlayer _unit) then { _bountyTime = [] spawn { sleep 1200; };//20 minutes waitUntil { !alive _unit || scriptDone _bountyTime }; if (alive _unit && {scriptDone _bountyTime}) then { //give reward } else { //no reward }; }; Share this post Link to post Share on other sites
lenymo 10 Posted December 3, 2014 Thanks, I was wondering about using the call BIS_fnc_selectRandom instead Share this post Link to post Share on other sites
jshock 513 Posted December 3, 2014 (edited) Actually, on further thought, below is a bit better :p: while {true} do { _unit = playableUnits call BIS_fnc_selectRandom; if (isPlayer _unit) exitWith { _unit }; sleep 0.01; }; if (!isNull _unit) then { _bountyTime = [] spawn { sleep 1200; };//20 minutes waitUntil { !alive _unit || scriptDone _bountyTime }; if (alive _unit && {scriptDone _bountyTime}) then { //give reward } else { //no reward terminate _bountyTime; }; }; Edited December 3, 2014 by JShock Share this post Link to post Share on other sites
shuko 59 Posted December 3, 2014 I might be nitpicking here, but is it optimal/safe to have a loop that can go on forever? Sure, in most cases it will pick a human player right away. How about doing something like this: _units = []; { if (isPlayer _x) then { _units pushBack _x; } } foreach playableUnits; _unit = _units call BIS_fnc_selectRandom; Share this post Link to post Share on other sites
jshock 513 Posted December 3, 2014 I might be nitpicking here, but is it optimal/safe to have a loop that can go on forever? Sure, in most cases it will pick a human player right away. Nope that is quite a valid point, I just made the assumption that at some point it would have to hit a player and exit out, but there is always the off chance :D. Share this post Link to post Share on other sites
fn_Quiksilver 1636 Posted December 4, 2014 The code blocks above will throw an 'undefined variable in expression' error if no players in the game ... Would suggest a !isNull check on _unit prior to any other evaluations, or a ((count playableUnits) > 0) prior to trying to select a random element from it. Also won't work for editor testing, as playableUnits is a MP array ... (playableUnits + switchableUnits) tends to be a bit friendlier to the RPT :) while {TRUE} do { waitUntil {((count playableUnits) > 0)}; /* rest of code */ Share this post Link to post Share on other sites
Tajin 349 Posted December 4, 2014 (edited) Hey, JShock when did you stop using EventHandlers ? ;) @ MDCCLXXVI. Just don't test mp-missions in the singleplayer-editor. Go to multiplayer, create a server, use the editor there. (untested): I'd use something like this: bounty_minplayers = 5; bounty_startdelay = 10; bounty_timeout = 20; bounty_fnc_mpkilled = { private ["_unit","_killer","_txt"]; _unit = _this select 0; _killer = _this select 1; _txt = format["%1 has been killed. %2 claimed the bounty.", name _unit, name _killer]; [ _txt, "BIS_fnc_infoText", true, false] call BIS_fnc_MP; //--> reward the _killer here if (isServer) then { _unit removeEventHandler["MPKilled", _unit getVariable "bounty_EH"]; _unit setVariable["bounty_EH",-1]; }; }; if (!isServer) exitWith {}; bounty_fnc_create = { private ["_txt","_starttime"]; if ( ({alive _x} count playableUnits) < bounty_minplayers ) exitWith { false }; _target = playableUnits call BIS_fnc_selectRandom; if (!alive _target) exitWith { false }; if (_target getVariable["bounty_EH",-1] < 0) exitWith { false }; _txt = format["%1 has received a bounty on his head. Kill him within the next %2 minutes.", name _target, bounty_timeout]; [ _txt, "BIS_fnc_infoText", true, false] call BIS_fnc_MP; _target setVariable["bounty_EH", _target addEventHandler ["MPKilled", _this call bounty_fnc_mpkilled ]]; _starttime = time; sleep 1; waitUntil { sleep 60; ( (time - _starttime) > bounty_timeout ) || ( (_target getVariable["bounty_EH",-1]) < 0 ) }; if ( (_target getVariable["bounty_EH",-1]) > -1 ) then { _txt = format["The bounty on %1 has expired.", name _target]; [ _txt, "BIS_fnc_infoText", true, false] call BIS_fnc_MP; //--> reward the _target here }; sleep 60*bounty_startdelay; }; sleep 60*bounty_startdelay; while { true } do { [] call bounty_fnc_create; sleep 10; }; ps.: In theory that also allows for multiply bounty-targets at once, if you call the create function manually (serverside). Edited December 4, 2014 by Tajin Share this post Link to post Share on other sites
Deform 10 Posted December 4, 2014 Hey Tajin. "Just don't test mp-missions in the singleplayer-editor. Go to multiplayer, create a server, use the editor there." How can I export my mission so I can edit it at multiplayer? Share this post Link to post Share on other sites
jshock 513 Posted December 4, 2014 Hey, JShock when did you stop using EventHandlers ? ;) Whenever a lot of the day's questions were about using EHs, just didn't even think about it. And mine just looks simple too :p. Share this post Link to post Share on other sites
lenymo 10 Posted December 4, 2014 So I have been attempting to adapt this code to my needs, as I mentioned I am attempting to input this as a mission for a wasteland server (Mainly using the A3Wasteland scripts) so I have been taking bits of code from here and there. This code does not appear to be working properly and I can not get it figured out. It probably isn't the prettiest code and I haven't quite finished up with the mission complete/failed portions but any help would be appreciated. if (!isServer) exitwith {}; #include "moneyMissionDefines.sqf"; _unit = playableUnits call BIS_fnc_selectRandom; _missionHintText = format ["<t color='%1'>_unit</t> has a bounty on their head. Kill them to collect $2,000. If they evade for 20 minutes _unit will receive $4,000", "PLAIN"]; sleep 60; titleText ["<t color='%1'>_unit</t> has been marked on the map. Let the hunt begin!", "PLAIN"]; _pos = getPos _unit; createMarker ["Mark1", _pos]; "Mark1" setMarkerSize [1200, 1200]; "Mark1" setMarkerShape "ELLIPSES"; "Mark1" setMarkerText "Bounty"; "Mark1" setMarkerColor "ColorRed"; sleep 300; deleteMarker "Mark1"; _pos = getPos _unit; _missionHintText = format["<t color='%1'>_unit</t> has been updated on the map", "PLAIN"]; createMarker ["Mark1", _pos]; "Mark1" setMarkerSize [1000, 1000]; "Mark1" setMarkerShape "ELLIPSES"; "Mark1" setMarkerText "Bounty"; "Mark1" setMarkerColor "ColorRed"; sleep 300; deleteMarker "Mark1"; _pos = getPos _unit; _missionHintText = format ["<t color='%1'>_unit</t> has been updated on the map", "PLAIN"]; createMarker ["Mark1", _pos]; "Mark1" setMarkerSize [900, 900]; "Mark1" setMarkerShape "ELLIPSES"; "Mark1" setMarkerText "Bounty"; "Mark1" setMarkerColor "ColorRed"; sleep 300; deleteMarker "Mark1"; _pos = getPos _unit; _missionHintText = format["<t color='%1'>_unit</t> has been updated on the map", "PLAIN"]; createMarker ["Mark1", _pos]; "Mark1" setMarkerSize [800, 800]; "Mark1" setMarkerShape "ELLIPSES"; "Mark1" setMarkerText "Bounty"; "Mark1" setMarkerColor "ColorRed"; sleep 300; _failedExec = { // Mission failed { _x setVariable ["cmoney", 4000, true]; _x setVariable ["owner", "world", true]; } forEach _cashObjects; }; _successExec = { // Mission complete _box1 setVariable ["R3F_LOG_disabled", false, true]; // Give the rewards { _x setVariable ["cmoney", 2000, true]; _x setVariable ["owner", "world", true]; } forEach _cashObjects; _successHintMessage = "The bounty has been claimed."; }; _this call moneyMissionProcessor; Share this post Link to post Share on other sites
jshock 513 Posted December 4, 2014 (edited) We established earlier that playableUnits might not return a player so try doing something with Shuko's or Tajin's code that they provided (exampled below is Shuko's): if (!isServer) exitWith {}; #include "moneyMissionDefines.sqf"; waitUntil {(count (playableUnits + switchableUnits)) > 0};//remove switchableUnits if not doing SP _units = []; { if (isPlayer _x) then { _units pushBack _x; } } foreach (playableUnits + switchableUnits);//remove switchableUnits if not doing SP _unit = _units call BIS_fnc_selectRandom; //rest of code And what exactly isn't working the way you want? Edited December 4, 2014 by JShock Share this post Link to post Share on other sites
lenymo 10 Posted December 4, 2014 I didn't see the part about the playableUnits not providing a player so that very well might be the issue. I can't test it right now but I certainly will as soon as possible. The issue that is occurring is that when the mission is supposed to come active it disregards the entire script and acts like it isn't there. I will have to tinker around with it a little bit more. Thanks. Share this post Link to post Share on other sites
terox 316 Posted December 4, 2014 _players = []; {if(IsPlayer _x)then{_Players = _players + [_x]}}foreach PlayableUnits; _player = _players call call BIS_fnc_selectRandom; will select 1 player from the list of players at random Share this post Link to post Share on other sites