#include "..\script_component.hpp" /* * Author: IDSolutions * Manages the dynamic mission system * * Arguments: * None * * Return Value: * None * * Example: * [] call forge_client_task_fnc_missionManager */ // Load mission configuration private _missionConfig = missionConfigFile >> "CfgMissions"; private _weightsConfig = _missionConfig >> "MissionWeights"; private _locationsConfig = _missionConfig >> "Locations"; private _aiGroupsConfig = _missionConfig >> "AIGroups"; private _missionTypesConfig = _missionConfig >> "MissionTypes"; // Get mission weights from config private _missionTypes = []; { private _weight = getNumber(_weightsConfig >> configName _x); _missionTypes pushBack [configName _x, _weight]; } forEach "true" configClasses _weightsConfig; // Function to get a suitable location for a mission type private _fnc_getMissionLocation = { params ["_type"]; private _suitableLocations = []; { private _suitable = getArray(_x >> "suitable"); if (_type in _suitable) then { _suitableLocations pushBack _x; }; } forEach "true" configClasses _locationsConfig; selectRandom _suitableLocations }; // TODO: Implement a more sophisticated AI spawning system // Function to spawn AI group for mission private _fnc_spawnAIGroup = { params ["_type", "_pos"]; private _suitableGroups = []; { private _suitable = getArray(_x >> "suitable"); if (_type in _suitable) then { _suitableGroups pushBack _x; }; } forEach "true" configClasses _aiGroupsConfig; private _groupConfig = selectRandom _suitableGroups; if (isNil "_groupConfig") exitWith { grpNull }; private _side = getText(_groupConfig >> "side"); private _group = createGroup (call compile _side); { private _unitClass = getText(_x >> "vehicle"); private _unitPos = getArray(_x >> "position"); private _unit = _group createUnit [_unitClass, _pos vectorAdd _unitPos, [], 0, "NONE"]; _unit setRank getText(_x >> "rank"); } forEach "true" configClasses (_groupConfig >> "Units"); _group }; // Generate a random mission based on weights private _fnc_getRandomMission = { private _rand = random 1; private _cumulative = 0; { _x params ["_type", "_weight"]; _cumulative = _cumulative + _weight; if (_rand <= _cumulative) exitWith { _type }; } forEach _missionTypes; }; // TODO: Implement a more sophisticated mission selection algorithm // Generate mission parameters based on type private _fnc_generateMissionParams = { params ["_type"]; private _taskId = format ["task_%1_%2", _type, round(random 999999)]; private _typeConfig = _missionTypesConfig >> (_type call CFUNC(capitalize)); // Get location for mission private _location = [_type] call _fnc_getMissionLocation; private _pos = getArray(_location >> "position"); private _radius = getNumber(_location >> "radius"); // Generate rewards private _moneyRange = getArray(_typeConfig >> "Rewards" >> "money"); private _repRange = getArray(_typeConfig >> "Rewards" >> "reputation"); private _penaltyRange = getArray(_typeConfig >> "penalty"); private _timeRange = getArray(_typeConfig >> "timeLimit"); private _reward = _moneyRange call BIS_fnc_randomNum; private _reputation = _repRange call BIS_fnc_randomNum; private _penalty = _penaltyRange call BIS_fnc_randomNum; private _timeLimit = _timeRange call BIS_fnc_randomNum; // Generate random reward items private _equipmentRewards = []; private _supplyRewards = []; private _weaponRewards = []; private _vehicleRewards = []; private _specialRewards = []; { private _category = _x; { _x params ["_item", "_chance"]; if (random 1 < _chance) then { switch (_category) do { case "equipment": { _equipmentRewards pushBack _item }; case "supplies": { _supplyRewards pushBack _item }; case "weapons": { _weaponRewards pushBack _item }; case "vehicles": { _vehicleRewards pushBack _item }; case "special": { _specialRewards pushBack _item }; }; }; } forEach (getArray(_typeConfig >> "Rewards" >> _category)); } forEach ["equipment", "supplies", "weapons", "vehicles", "special"]; // TODO: Continue to refine mission types and their specific settings // Return parameters based on mission type switch (_type) do { case "attack": { private _group = [_type, _pos] call _fnc_spawnAIGroup; private _units = units _group; private _unitCount = count _units; [_taskId, _unitCount, _radius, _reward, _penalty, _reputation, false, false, _equipmentRewards, _supplyRewards, _weaponRewards, _vehicleRewards, _specialRewards] }; case "defend": { private _minWaves = getNumber(_typeConfig >> "minWaves"); private _maxWaves = getNumber(_typeConfig >> "maxWaves"); private _waves = floor(random (_maxWaves - _minWaves + 1)) + _minWaves; private _waveCooldown = getNumber(_typeConfig >> "waveCooldown"); [_taskId, _pos, _timeLimit, _reward, _penalty, _reputation, false, false, _waves, _waveCooldown, _radius, _equipmentRewards, _supplyRewards, _weaponRewards, _vehicleRewards, _specialRewards] }; case "hostage": { private _hostages = getArray(_typeConfig >> "Hostages" >> "civilian"); private _hostage = selectRandom _hostages; [_taskId, _hostage, _radius, _pos, _reward, _penalty, _reputation, [false, true], false, false, _equipmentRewards, _supplyRewards, _weaponRewards, _vehicleRewards, _specialRewards] }; case "hvt": { private _targets = getArray(_typeConfig >> "Targets" >> "officer"); private _target = selectRandom _targets; private _escorts = getNumber(_typeConfig >> "escorts"); [_taskId, _target, _escorts, _pos, _reward, _penalty, _reputation, false, false, _equipmentRewards, _supplyRewards, _weaponRewards, _vehicleRewards, _specialRewards] }; case "defuse": { private _devices = getArray(_typeConfig >> "Devices" >> "small"); private _maxDevices = getNumber(_typeConfig >> "maxDevices"); private _deviceCount = floor(random _maxDevices) + 1; [_taskId, _deviceCount, _timeLimit, _reward, _penalty, _reputation, false, false, _devices, _equipmentRewards, _supplyRewards, _weaponRewards, _vehicleRewards, _specialRewards] }; case "delivery": { private _cargo = selectRandom (getArray(_typeConfig >> "Cargo" >> "supplies")); [_taskId, _pos, [_pos, _radius] call BIS_fnc_randomPos, _timeLimit, _reward, _penalty, _reputation, false, false, _cargo, _equipmentRewards, _supplyRewards, _weaponRewards, _vehicleRewards, _specialRewards] }; }; }; // Generate and start a random mission private _fnc_startRandomMission = { private _type = call _fnc_getRandomMission; private _params = [_type] call _fnc_generateMissionParams; // Start the mission based on type switch (_type) do { case "attack": { _params spawn forge_client_task_fnc_attack }; case "defend": { _params spawn forge_client_task_fnc_defend }; case "hostage": { _params spawn forge_client_task_fnc_hostage }; case "hvt": { _params spawn forge_client_task_fnc_hvt }; case "defuse": { _params spawn forge_client_task_fnc_defuse }; case "delivery": { _params spawn forge_client_task_fnc_delivery }; }; // Return the task ID for tracking _params select 0 }; // Mission queue management GVAR(missionQueue) = []; GVAR(activeMissions) = []; GVAR(maxConcurrentMissions) = getNumber(_missionConfig >> "maxConcurrentMissions"); GVAR(missionInterval) = getNumber(_missionConfig >> "missionInterval"); // Main mission manager loop [{ // Check if we can generate new missions if (count GVAR(activeMissions) < GVAR(maxConcurrentMissions)) then { private _taskId = call _fnc_startRandomMission; GVAR(activeMissions) pushBack _taskId; // Clean up completed missions GVAR(activeMissions) = GVAR(activeMissions) select { !((missionNamespace getVariable [format ["FORGE_task_%1_completed", _x], false]) || (missionNamespace getVariable [format ["FORGE_task_%1_failed", _x], false])) }; }; }, GVAR(missionInterval), []] call CFUNC(addPerFrameHandler);