client/addons/task/functions/fnc_missionManager.sqf
Jacob Schmidt 0858d9a173
All checks were successful
Build / Build (push) Successful in 28s
feat: Implement basic mission management framework
This commit introduces a basic framework for mission management.

- Includes `CfgMissions.hpp` in `config.cpp`.
- Adds `missionManager` to `XEH_PREP.hpp` for event handling preparation.
- Adds a placeholder call to `FUNC(missionManager)` in `XEH_postInit.sqf` with a TODO comment for future implementation.
2025-05-26 00:47:24 -05:00

212 lines
8.6 KiB
Plaintext

#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);