Jump to content
Sign in to follow this  
mons00n

Shared Objectives?

Recommended Posts

Is there any documentation on how to setup the new Shared Objectives? I really like the way tasks are done in the new End Game Kavala mission, but I can't find which pbo file it's in =/

Share this post


Link to post
Share on other sites

Its probably in one of the encrypted EBOs. My guess would be missions_f_mark.ebo. You might have to wait until the framework is introduced completely.

Edited by Fight9

Share this post


Link to post
Share on other sites

I found this in the function viewer.

BIS_fnc_sharedObjectives

/*
Author: Jiri Wainar

Meant to be run by the framework in MP scenarions. Do not run it by it's own.
*/

#define DEBUG_LOG		bis_fnc_logFormat

//exit if the new task system is not activated
if (isNil "bis_taskManagement_markers2D") then
{
bis_taskManagement_markers2D = getNumber(missionConfigFile >> "taskManagement_markers2D") == 1;
};
if !(bis_taskManagement_markers2D) exitWith {};

//exit if not in the multiplayer game
if !(isMultiplayer) exitWith
{
bis_taskManagement_propagate = false;
[player] call bis_fnc_objectVar;		//make sure player has always some variable attached in SP games
};

//exit if task propagation is not activated
if (isNil "bis_taskManagement_propagate") then
{
bis_taskManagement_propagate = getNumber(missionConfigFile >> "taskManagement_propagate") == 1;
};
if !(bis_taskManagement_propagate) exitWith {};


private["_mode","_unitVar"];

_mode = _this select 0;

switch (_mode) do
{
case "postInit":
{
	if (isNil "bis_fnc_sharedObjectives_cache") then {bis_fnc_sharedObjectives_cache = [];};
	if (isNil "bis_fnc_sharedObjectives_serverUpdate") then {bis_fnc_sharedObjectives_serverUpdate = false;};
	if (isNil "bis_fnc_sharedObjectives_toAdd") then {bis_fnc_sharedObjectives_toAdd = "";};
	if (isNil "bis_fnc_sharedObjectives_toRemove") then {bis_fnc_sharedObjectives_toRemove = [];};


	//make sure the player's name is always registered on server
	if (hasInterface) then
	{
		if (isServer) then
		{
			[player] call bis_fnc_objectVar;
		}
		else
		{
			[[player],"bis_fnc_objectVar",false] call bis_fnc_MP;
		};
	};

	//server only
	if (isServer) then
	{
		addMissionEventHandler["HandleDisconnect",
			{
			private["_unit","_unitVar","_side"];

			_unit = _this select 0;
			_side = side group _unit;
			_unitVar = [_unit] call bis_fnc_objectVar;

			//["[i][%1] Disconnect event fired (_unitVar: %2).",_unit,_unitVar] call DEBUG_LOG;

			if (_unitVar == "") exitWith {};

			[_unitVar,_side] spawn
			{
				scriptName "fn_sharedObjectives_onDisconnect";

				_unitVar = _this select 0;
				_side = _this select 1;

				sleep 1;

				["calc",_unitVar,"",missionNamespace getVariable ["bis_fnc_sharedObjectives_cache",[]],_side] call bis_fnc_sharedObjectives;
			};
		}];

		[] spawn
		{
			scriptName "fn_sharedObjectives_monitorGroupTasks";

			private["_players","_groups","_group","_task","_subordinates","_side","_key","_assignedUnits","_leader","_fn_getAssignedTask"];

			//_task = [_unit,_side] call _fn_getAssignedTask;
			_fn_getAssignedTask =
			{
				private["_unitVar","_assignedUnits","_key","_side","_task","_tasks"];

				_unitVar = [_this] call bis_fnc_objectVar;
				_task = "";
				_side = side group _this;

				_tasks =+ bis_fnc_sharedObjectives_cache;

				{
					_key = format["%1_%2_units",_x,_side];
					_assignedUnits = missionNamespace getVariable [_key,[]];

					if (_unitVar in _assignedUnits) exitWith
					{
						_task = _x;
					};
				}
				forEach _tasks;

				_task
			};

			while {true} do
			{
				waitUntil{bis_fnc_sharedObjectives_serverUpdate};

				//["[!] 'bis_fnc_sharedObjectives_serverUpdate' commencing..."] call DEBUG_LOG;

				sleep 3;

				//["[!] 'bis_fnc_sharedObjectives_serverUpdate' executed!"] call DEBUG_LOG;

				bis_fnc_sharedObjectives_serverUpdate = false;

				_players = [] call bis_fnc_listPlayers;
				_groups = [];

				{
					_group = group _x;

					if !(_group in _groups) then
					{
						_groups pushBack _group;
					};
				}
				forEach _players;

				{
					_group = _x;
					_side = side _group;
					_leader = leader _group;
					_subordinates = (units _group) - [_leader];

					//["[!] Group: %1 | Leader: %2 | Subordinates: %3",_group,_leader,_subordinates] call DEBUG_LOG;

					if (count _subordinates > 0) then
					{
						//get leader's task
						_task = _leader call _fn_getAssignedTask;

						//["[!] Group: %1 | Leader: %2 | Task: %3",_group,_leader,_task] call DEBUG_LOG;

						//leader has task assigned
						if (_task != "") then
						{
							_key = format["%1_%2_units",_task,_side];
							_assignedUnits = missionNamespace getVariable [_key,[]];

							//["[!] Group: %1 | Leader: %2 | Task: %3 | Assigned: %4",_group,_leader,_task,_assignedUnits] call DEBUG_LOG;

							{
								_subordinates = _subordinates - [missionNamespace getVariable [_x,objNull]];
							}
							forEach _assignedUnits;

							//["[!] Group: %1 | Leader: %2 | Subordinates 4 propagation: %3",_group,_leader,_subordinates] call DEBUG_LOG;
						}
						//leader doesn't have task assigned
						else
						{
							{
								_xTask = _x call _fn_getAssignedTask;

								if (_xTask == "") then
								{
									//["[!] Group: %1 | Leader: %2 | Subordinate skipped from propagation: %3",_group,_leader,_x] call DEBUG_LOG;

									_subordinates set [_forEachIndex,objNull];
								};
							}
							forEach _subordinates; _subordinates = _subordinates - [objNull];

							//["[!] Group: %1 | Leader: %2 | Subordinates 4 propagation: %3",_group,_leader,_subordinates] call DEBUG_LOG;
						};


						//["[!] Group: %1 | Leader: %2 | Task: %3 | Re-assign #: %4/%5",_group,_leader,_task,count _subordinates,count units _group] call DEBUG_LOG;


						{
							[["reassign",_leader,_task],"bis_fnc_sharedObjectives",_x] call bis_fnc_MP;
						}
						forEach _subordinates;
					};
				}
				forEach _groups;
			};
		};
	};

	//playable only
	if (!isDedicated && {hasInterface}) then
	{
		_unitVar = [player] call bis_fnc_objectVar;

		//["[ ][%1] Join event fired (_unitVar: %2).",player,_unitVar] call DEBUG_LOG;

		private["_currentTask"];

		_currentTask = [player] call bis_fnc_taskCurrent;

		bis_fnc_sharedObjectives_currentTask = _currentTask;
		bis_fnc_sharedObjectives_toRemove = (player call bis_fnc_tasksUnit) - [_currentTask];

		if (bis_fnc_sharedObjectives_toAdd != _currentTask) then
		{
			missionNamespace setVariable ["bis_fnc_sharedObjectives_toAdd",_currentTask];
		};

		player addEventHandler ["TaskSetAsCurrent",
		{
			private["_unit","_task","_newCurrent","_prevCurrent","_tasks"];

			_unit = _this select 0;
			_task = _this select 1;

			if !(isPlayer _unit) exitWith {};

			_newCurrent = "";
			_prevCurrent = missionNamespace getVariable ["bis_fnc_sharedObjectives_currentTask",""];

			_tasks = [_unit] call bis_fnc_tasksUnit;

			{
				_xTask = _unit getVariable [_x call bis_fnc_taskVar,taskNull];

				if (typeName _xTask == typeName _task && {_xTask == _task}) exitWith
				{
					_newCurrent = _x;
				};
			}
			forEach _tasks;

			//stop if no change was detected
			if (_newCurrent == _prevCurrent) exitWith
			{
				//["[ ][%1] EH *TaskSetAsCurrent* fired & terminated (_task: %2). No change detected.",_unit,_task] call DEBUG_LOG;
			};

			//["[ ][%1] EH *TaskSetAsCurrent* fired (_task: %2).",_unit,_task] call DEBUG_LOG;

			switch (true) do
			{
				//task assigned
				case ((_newCurrent != "") && (_prevCurrent == "")):
				{
					//["[ ][%2] Task '%1' assigned.",_newCurrent,_unit] call DEBUG_LOG;
				};

				//task unassigned
				case ((_newCurrent == "") && (_prevCurrent != "")):
				{
					//["[ ][%2] Task '%1' un-assigned.",_prevCurrent,_unit] call DEBUG_LOG;
				};

				//reassigned to different task
				case ((_newCurrent != "") && (_prevCurrent != "")):
				{
					//["[ ][%3] Tasks re-assigned '%1' -> '%2'.",_prevCurrent,_newCurrent,_unit] call DEBUG_LOG;
				};

				//nothing changed
				default
				{
					//["[ ][%1] Tasks not changed (_prevCurrent = '%1', _newCurrent = '%2').",_unit,_prevCurrent,_newCurrent] call DEBUG_LOG;
				};
			};

			//store the actual current task
			missionNamespace setVariable ["bis_fnc_sharedObjectives_currentTask",_newCurrent];

			//schedule the task state update
			private["_toAdd","_toRemove"];

			_toAdd = missionNamespace getVariable ["bis_fnc_sharedObjectives_toAdd",""];
			_toRemove = missionNamespace getVariable ["bis_fnc_sharedObjectives_toRemove",[]];

			_toAdd = _newCurrent;

			if (_prevCurrent != "") then
			{
				_toRemove = _toRemove - [_prevCurrent] + [_prevCurrent];
			};

			missionNamespace setVariable ["bis_fnc_sharedObjectives_toAdd",_toAdd];
			missionNamespace setVariable ["bis_fnc_sharedObjectives_toRemove",_toRemove];
		}];

		[] spawn
		{
			scriptName "fn_sharedObjectives_monitorTaskAssignChange";

			private["_unitVar"];

			waitUntil
			{
				_unitVar = [player] call bis_fnc_objectVar;

				_unitVar != ""
			};

			while {true} do
			{
				waitUntil
				{
					sleep 0.1;

					(bis_fnc_sharedObjectives_toAdd != "") || {count bis_fnc_sharedObjectives_toRemove > 0}
				};

				sleep 0.5;

				[["calc",_unitVar,bis_fnc_sharedObjectives_toAdd,bis_fnc_sharedObjectives_toRemove],"bis_fnc_sharedObjectives",false] call bis_fnc_MP;

				//reset the variables
				bis_fnc_sharedObjectives_toAdd = "";
				bis_fnc_sharedObjectives_toRemove = [];
			};
		};

		[] spawn
		{
			scriptName "fn_sharedObjectives_monitorGroupLeaderChange";

			private["_group","_leader"];

			while {true} do
			{
				sleep 0.5;

				_group = group player;
				_leader = leader _group;

				bis_fnc_sharedObjectives_serverUpdate = true;
				publicVariable "bis_fnc_sharedObjectives_serverUpdate";

				waitUntil
				{
					sleep 0.5;

					(group player) != _group || {(leader group player) != _leader}
				};
			};
		};
	};
};

//runs on server: calculate number of players assigned to different tasks
case "calc":
{
	//["[x][calc] init: %1",_this] call DEBUG_LOG;

	if (!isServer) exitWith {};

	private["_unitVar","_unit","_add","_remove","_side"];

	_unitVar = [_this,1,"",[""]] call BIS_fnc_param;
	_add 	 = [_this,2,"",[""]] call BIS_fnc_param;
	_remove	 = [_this,3,[],[[]]] call BIS_fnc_param;
	_side	 = [_this,4,sideUnknown,[sideUnknown]] call BIS_fnc_param;

	if (_unitVar == "") exitWith {};

	_unit = missionNamespace getVariable [_unitVar,objNull];

	if (isNull _unit && {_side == sideUnknown}) exitWith {["[x][calc] Error: Both unit and side are not defined!"] call DEBUG_LOG;};

	if (_side == sideUnknown) then
	{
		_side = side group _unit;
	};

	//build task cache
	private["_cache"];

	_cache = missionNamespace getVariable ["bis_fnc_sharedObjectives_cache",[]];

	{
		if (!(_x in _cache) && {_x != ""}) then
		{
			_cache pushBack _x;
		};
	}
	forEach (_remove + [_add]);

	missionNamespace setVariable ["bis_fnc_sharedObjectives_cache",_cache];

	//force the server update -> propagation will be checked and executed if needed
	bis_fnc_sharedObjectives_serverUpdate = true;

	//unregister player from all tasks he was previously registered
	private["_key","_units"];

	{
		_key = format["%1_%2_units",_x,_side];
		_units = missionNamespace getVariable [_key,[]];

		if (_unitVar in _units) then
		{
			_units = _units - [_unitVar];
			missionNamespace setVariable [_key,_units];
			publicVariable _key;

			//["[ ][calc][%1] Unit un-assigned from task '%2' | %3 = %4",_unitVar,_x,_key,_units] call DEBUG_LOG;
		};
	}
	forEach _remove;

	//register the new current task
	if (_add != "") then
	{
		_key = format["%1_%2_units",_add,_side];
		_units = missionNamespace getVariable [_key,[]];

		if ({_x == _unitVar} count _units != 1) then
		{
			_units = _units - [_unitVar] + [_unitVar];
			missionNamespace setVariable [_key,_units];
			publicVariable _key;

			//["[ ][calc][%1] Unit assigned to task '%2' | %3 = %4",_unitVar,_add,_key,_units] call DEBUG_LOG;
		};
	};
};

//runs localy: re-assign player's task to the same task the 'unit' has
case "reassign":
{
	//["[x][reassign] init: %1",_this] call DEBUG_LOG;

	private["_unit","_task","_unitVar","_key","_units","_propagate"];

	_unit	 = [_this,1,objNull,[objNull]] call BIS_fnc_param; if (isNull _unit || {player == _unit}) exitWith {};
	_task	 = [_this,2,"-autodetect-",[""]] call BIS_fnc_param;
	_unitVar = [_unit] call bis_fnc_objectVar; if (_unitVar == "") exitWith {["[x][reassign] No object var is set for object '%1'!",_unit] call DEBUG_LOG;};

	if !(isNil "bis_taskManagement_propagate") then
	{
		_propagate = bis_taskManagement_propagate;
	}
	else
	{
		_propagate = false;
	};

	if !(_propagate) exitWith {["[x][reassign] Propagate is OFF!"] call DEBUG_LOG;};

	if (_task == "-autodetect-") then
	{
		_task == "";

		{
			_key = format["%1_%2_units",_x,side group _unit];
			_units = missionNamespace getVariable [_key,[]];

			if (_unitVar in _units) exitWith
			{
				_task = _x;
			};
		}
		forEach ([player] call bis_fnc_tasksUnit);
	};

	private["_taskReal","_customData","_i","_data","_texture","_share","_desc"];

	//handle un-assign
	if (_task == "") then
	{
		_taskReal	= currentTask player; if (isNull _taskReal) exitWith {["[x][reassign] Player has no task assigned!"] call DEBUG_LOG;};
		_customData 	= player getVariable ["bis_fnc_setTaskLocal_customData",[]];
		_i		= _customData find _taskReal; if (_i < 0) exitWith {["[x][reassign] Task '%1' not found in custom data!",_task] call DEBUG_LOG;};

		_data 		= _customData select (_i + 1); if (typeName _data != typeName [] || {count _data < 4}) exitWith {};
		_texture	= _data select 1;
		_share 		= _data select 3;
		_desc		= taskDescription _taskReal;

		if (_share) then
		{
			["[i][reassign] Player's task un-assigned according to unit %1.",_unitVar] call DEBUG_LOG;

			player setCurrentTask taskNull;

			//show notification
			["TaskUnassignedIcon",[_texture,_desc select 1]] call bis_fnc_showNotification;
		};
	}
	//handle re-assign
	else
	{
		_taskReal	= [_task,player] call bis_fnc_taskReal; if (isNull _taskReal) exitWith {["[x][reassign] Cannot get real task assiciated with task '%1'!",_task] call DEBUG_LOG;};
		_customData 	= player getVariable ["bis_fnc_setTaskLocal_customData",[]];
		_i		= _customData find _taskReal; if (_i < 0) exitWith {["[x][reassign] Task '%1' not found in custom data!",_task] call DEBUG_LOG;};

		_data 		= _customData select (_i + 1); if (typeName _data != typeName [] || {count _data < 4}) exitWith {};
		_texture	= _data select 1;
		_share 		= _data select 3;
		_desc		= taskDescription _taskReal;

		if (_share && {currentTask player != _taskReal}) then
		{
			//["[i][reassign] Player's task re-assigned according to unit %1 to task %2.",_unitVar,_task] call DEBUG_LOG;

			player setCurrentTask _taskReal;

			//show notification
			["TaskAssignedIcon",[_texture,_desc select 1]] call bis_fnc_showNotification;
		};
	};
};

default
{
};
};

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  

×