feat: Implement basic mission management framework
All checks were successful
Build / Build (push) Successful in 28s
All checks were successful
Build / Build (push) Successful in 28s
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.
This commit is contained in:
parent
9f672e1795
commit
0858d9a173
191
addons/task/CfgMissions.hpp
Normal file
191
addons/task/CfgMissions.hpp
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
// TODO: Move to mission template and provide documentation
|
||||||
|
class CfgMissions {
|
||||||
|
// Global settings
|
||||||
|
maxConcurrentMissions = 3;
|
||||||
|
missionInterval = 300; // 5 minutes between mission generation
|
||||||
|
|
||||||
|
// Mission type weights
|
||||||
|
class MissionWeights {
|
||||||
|
attack = 0.2;
|
||||||
|
defend = 0.2;
|
||||||
|
hostage = 0.2;
|
||||||
|
hvt = 0.15;
|
||||||
|
defuse = 0.15;
|
||||||
|
delivery = 0.1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mission locations
|
||||||
|
class Locations {
|
||||||
|
class CityOne {
|
||||||
|
position[] = {1000, 1000, 0};
|
||||||
|
type = "city";
|
||||||
|
radius = 300;
|
||||||
|
suitable[] = {"attack", "defend", "hostage"};
|
||||||
|
};
|
||||||
|
class MilitaryBase {
|
||||||
|
position[] = {2000, 2000, 0};
|
||||||
|
type = "military";
|
||||||
|
radius = 500;
|
||||||
|
suitable[] = {"hvt", "defend", "attack"};
|
||||||
|
};
|
||||||
|
class Industrial {
|
||||||
|
position[] = {3000, 3000, 0};
|
||||||
|
type = "industrial";
|
||||||
|
radius = 200;
|
||||||
|
suitable[] = {"delivery", "defuse"};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// AI Groups configuration
|
||||||
|
class AIGroups {
|
||||||
|
class Infantry {
|
||||||
|
side = "EAST";
|
||||||
|
class Units {
|
||||||
|
class Unit0 {
|
||||||
|
vehicle = "O_Soldier_TL_F";
|
||||||
|
rank = "SERGEANT";
|
||||||
|
position[] = {0, 0, 0};
|
||||||
|
};
|
||||||
|
class Unit1 {
|
||||||
|
vehicle = "O_Soldier_AR_F";
|
||||||
|
rank = "CORPORAL";
|
||||||
|
position[] = {5, -5, 0};
|
||||||
|
};
|
||||||
|
class Unit2 {
|
||||||
|
vehicle = "O_Soldier_LAT_F";
|
||||||
|
rank = "PRIVATE";
|
||||||
|
position[] = {-5, -5, 0};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
suitable[] = {"attack", "defend", "hostage"};
|
||||||
|
};
|
||||||
|
class SpecOps {
|
||||||
|
side = "EAST";
|
||||||
|
class Units {
|
||||||
|
class Unit0 {
|
||||||
|
vehicle = "O_recon_TL_F";
|
||||||
|
rank = "SERGEANT";
|
||||||
|
position[] = {0, 0, 0};
|
||||||
|
};
|
||||||
|
class Unit1 {
|
||||||
|
vehicle = "O_recon_M_F";
|
||||||
|
rank = "CORPORAL";
|
||||||
|
position[] = {5, -5, 0};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
suitable[] = {"hvt", "hostage"};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Continue to refine mission types and their specific settings
|
||||||
|
// Mission type specific settings
|
||||||
|
class MissionTypes {
|
||||||
|
class Attack {
|
||||||
|
minUnits = 4;
|
||||||
|
maxUnits = 8;
|
||||||
|
class Rewards {
|
||||||
|
money[] = {500000, 1500000};
|
||||||
|
reputation[] = {100, 500};
|
||||||
|
equipment[] = {{"ItemGPS", 0.5}, {"ItemCompass", 0.3}};
|
||||||
|
supplies[] = {{"FirstAidKit", 0.2}, {"Medikit", 0.1}};
|
||||||
|
weapons[] = {{"arifle_MX_F", 0.3}, {"arifle_Katiba_F", 0.2}};
|
||||||
|
vehicles[] = {{"B_MRAP_01_F", 0.1}, {"B_APC_Wheeled_01_cannon_F", 0.05}};
|
||||||
|
special[] = {{"B_UAV_01_F", 0.05}, {"B_Heli_Light_01_F", 0.02}};
|
||||||
|
};
|
||||||
|
penalty[] = {-100, -25};
|
||||||
|
timeLimit[] = {900, 1800}; // 15-30 minutes
|
||||||
|
};
|
||||||
|
|
||||||
|
class Defend {
|
||||||
|
minWaves = 3;
|
||||||
|
maxWaves = 8;
|
||||||
|
unitsPerWave[] = {4, 8};
|
||||||
|
waveCooldown = 300;
|
||||||
|
class Rewards {
|
||||||
|
money[] = {750000, 2000000};
|
||||||
|
reputation[] = {150, 600};
|
||||||
|
equipment[] = {{"ItemGPS", 0.5}, {"ItemCompass", 0.3}};
|
||||||
|
supplies[] = {{"FirstAidKit", 0.2}, {"Medikit", 0.1}};
|
||||||
|
weapons[] = {{"arifle_MX_F", 0.3}, {"arifle_Katiba_F", 0.2}};
|
||||||
|
vehicles[] = {{"B_MRAP_01_F", 0.1}, {"B_APC_Wheeled_01_cannon_F", 0.05}};
|
||||||
|
special[] = {{"B_UAV_01_F", 0.05}, {"B_Heli_Light_01_F", 0.02}};
|
||||||
|
};
|
||||||
|
penalty[] = {-150, -50};
|
||||||
|
timeLimit[] = {1800, 3600}; // 30-60 minutes
|
||||||
|
};
|
||||||
|
|
||||||
|
class Hostage {
|
||||||
|
class Hostages {
|
||||||
|
civilian[] = {"C_man_1", "C_man_polo_1_F"};
|
||||||
|
military[] = {"B_Pilot_F", "B_officer_F"};
|
||||||
|
};
|
||||||
|
class Rewards {
|
||||||
|
money[] = {1000000, 2500000};
|
||||||
|
reputation[] = {200, 700};
|
||||||
|
equipment[] = {{"ItemGPS", 0.5}, {"ItemCompass", 0.3}};
|
||||||
|
supplies[] = {{"FirstAidKit", 0.2}, {"Medikit", 0.1}};
|
||||||
|
weapons[] = {{"arifle_MX_F", 0.3}, {"arifle_Katiba_F", 0.2}};
|
||||||
|
vehicles[] = {{"B_MRAP_01_F", 0.1}, {"B_APC_Wheeled_01_cannon_F", 0.05}};
|
||||||
|
special[] = {{"B_UAV_01_F", 0.05}, {"B_Heli_Light_01_F", 0.02}};
|
||||||
|
};
|
||||||
|
penalty[] = {-200, -75};
|
||||||
|
timeLimit[] = {600, 900}; // 10-15 minutes
|
||||||
|
};
|
||||||
|
|
||||||
|
class HVT {
|
||||||
|
class Targets {
|
||||||
|
officer[] = {"O_officer_F"};
|
||||||
|
sniper[] = {"O_sniper_F"};
|
||||||
|
};
|
||||||
|
escorts = 4;
|
||||||
|
class Rewards {
|
||||||
|
money[] = {800000, 2000000};
|
||||||
|
reputation[] = {175, 650};
|
||||||
|
equipment[] = {{"ItemGPS", 0.5}, {"ItemCompass", 0.3}};
|
||||||
|
supplies[] = {{"FirstAidKit", 0.2}, {"Medikit", 0.1}};
|
||||||
|
weapons[] = {{"arifle_MX_F", 0.3}, {"arifle_Katiba_F", 0.2}};
|
||||||
|
vehicles[] = {{"B_MRAP_01_F", 0.1}, {"B_APC_Wheeled_01_cannon_F", 0.05}};
|
||||||
|
special[] = {{"B_UAV_01_F", 0.05}, {"B_Heli_Light_01_F", 0.02}};
|
||||||
|
};
|
||||||
|
penalty[] = {-175, -50};
|
||||||
|
timeLimit[] = {900, 1800}; // 15-30 minutes
|
||||||
|
};
|
||||||
|
|
||||||
|
class Defuse {
|
||||||
|
class Devices {
|
||||||
|
small[] = {"DemoCharge_Remote_Mag"};
|
||||||
|
large[] = {"SatchelCharge_Remote_Mag"};
|
||||||
|
};
|
||||||
|
maxDevices = 3;
|
||||||
|
class Rewards {
|
||||||
|
money[] = {600000, 1500000};
|
||||||
|
reputation[] = {125, 450};
|
||||||
|
equipment[] = {{"ItemGPS", 0.5}, {"ItemCompass", 0.3}};
|
||||||
|
supplies[] = {{"FirstAidKit", 0.2}, {"Medikit", 0.1}};
|
||||||
|
weapons[] = {{"arifle_MX_F", 0.3}, {"arifle_Katiba_F", 0.2}};
|
||||||
|
vehicles[] = {{"B_MRAP_01_F", 0.1}, {"B_APC_Wheeled_01_cannon_F", 0.05}};
|
||||||
|
special[] = {{"B_UAV_01_F", 0.05}, {"B_Heli_Light_01_F", 0.02}};
|
||||||
|
};
|
||||||
|
penalty[] = {-125, -40};
|
||||||
|
timeLimit[] = {600, 900}; // 10-15 minutes
|
||||||
|
};
|
||||||
|
|
||||||
|
class Delivery {
|
||||||
|
class Cargo {
|
||||||
|
supplies[] = {"Land_CargoBox_V1_F"};
|
||||||
|
vehicles[] = {"B_MRAP_01_F", "B_Truck_01_transport_F"};
|
||||||
|
};
|
||||||
|
class Rewards {
|
||||||
|
money[] = {400000, 1200000};
|
||||||
|
reputation[] = {75, 350};
|
||||||
|
equipment[] = {{"ItemGPS", 0.5}, {"ItemCompass", 0.3}};
|
||||||
|
supplies[] = {{"FirstAidKit", 0.2}, {"Medikit", 0.1}};
|
||||||
|
weapons[] = {{"arifle_MX_F", 0.3}, {"arifle_Katiba_F", 0.2}};
|
||||||
|
vehicles[] = {{"B_MRAP_01_F", 0.1}, {"B_APC_Wheeled_01_cannon_F", 0.05}};
|
||||||
|
special[] = {{"B_UAV_01_F", 0.05}, {"B_Heli_Light_01_F", 0.02}};
|
||||||
|
};
|
||||||
|
penalty[] = {-75, -25};
|
||||||
|
timeLimit[] = {900, 1800}; // 15-30 minutes
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -24,6 +24,7 @@ PREP(makeIED);
|
|||||||
PREP(makeObject);
|
PREP(makeObject);
|
||||||
PREP(makeShooter);
|
PREP(makeShooter);
|
||||||
PREP(makeTarget);
|
PREP(makeTarget);
|
||||||
|
PREP(missionManager);
|
||||||
PREP(protectedModule);
|
PREP(protectedModule);
|
||||||
PREP(shootersModule);
|
PREP(shootersModule);
|
||||||
PREP(spawnEnemyWave);
|
PREP(spawnEnemyWave);
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
GVAR(defusedCount) = 0;
|
GVAR(defusedCount) = 0;
|
||||||
|
|
||||||
|
// TODO: Implement mission manager
|
||||||
|
// if (isServer) then { [] call FUNC(missionManager); };
|
||||||
|
|
||||||
["ace_explosives_defuse", {
|
["ace_explosives_defuse", {
|
||||||
GVAR(defusedCount) = GVAR(defusedCount) + 1;
|
GVAR(defusedCount) = GVAR(defusedCount) + 1;
|
||||||
}] call CFUNC(addEventHandler);
|
}] call CFUNC(addEventHandler);
|
@ -15,4 +15,5 @@ class CfgPatches {
|
|||||||
|
|
||||||
#include "CfgEventHandlers.hpp"
|
#include "CfgEventHandlers.hpp"
|
||||||
#include "CfgFactionClasses.hpp"
|
#include "CfgFactionClasses.hpp"
|
||||||
#include "CfgVehicles.hpp"
|
#include "CfgVehicles.hpp"
|
||||||
|
#include "CfgMissions.hpp"
|
212
addons/task/functions/fnc_missionManager.sqf
Normal file
212
addons/task/functions/fnc_missionManager.sqf
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
#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);
|
Loading…
x
Reference in New Issue
Block a user