Jump to content
Sign in to follow this  
lenymo

Select a random player

Recommended Posts

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
_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

Thanks, I was wondering about using the call BIS_fnc_selectRandom instead

Share this post


Link to post
Share on other sites

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 by JShock

Share this post


Link to post
Share on other sites

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
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

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

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 by Tajin

Share this post


Link to post
Share on other sites

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
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

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

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 by JShock

Share this post


Link to post
Share on other sites

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

_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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×