diff --git a/@ExileServer/addons/a3_dms/config.cpp b/@ExileServer/addons/a3_dms/config.cpp index cad366c..adabe6b 100644 --- a/@ExileServer/addons/a3_dms/config.cpp +++ b/@ExileServer/addons/a3_dms/config.cpp @@ -90,6 +90,7 @@ class CfgFunctions class SpawnStaticMission {}; class SubArr {}; class TargetsKilled {}; + class TargetsKilledPercent {}; }; }; }; diff --git a/@ExileServer/addons/a3_dms/missions/bandit/bandits.sqf b/@ExileServer/addons/a3_dms/missions/bandit/bandits.sqf index 2757554..3f1c3ab 100644 --- a/@ExileServer/addons/a3_dms/missions/bandit/bandits.sqf +++ b/@ExileServer/addons/a3_dms/missions/bandit/bandits.sqf @@ -133,14 +133,16 @@ _markers = // Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) _time = diag_tickTime; +private _initialUnitCount = count (_group call DMS_fnc_GetAllUnits); //Get inital count of bots then mission starts. It need only for "killpercent" condnition. Look for detailed info in DMS_fnc_TargetsKilledPercent + // Parse and add mission info to missions monitor _added = [ _pos, [ [ - "kill", - _group + "killpercent", + [_initialUnitCount, _group] ], [ "playerNear", diff --git a/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf b/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf index 61b648a..f59e770 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf @@ -1,7 +1,7 @@ /* DMS_fnc_GetAllUnits Created by eraser1 - + Modified by Ravenger2709 Usage: [ @@ -14,12 +14,14 @@ Returns all living units from a given array of groups or objects. */ -if !(_this isEqualType []) then -{ +if !(_this isEqualType []) then { _this = [_this]; }; private _units = []; +private _footUnits = []; +private _vehicleUnits = []; +private _staticUnits = []; { private _parameter = _x; @@ -35,10 +37,18 @@ private _units = []; case "OBJECT": { - [ - [], - [_parameter] - ] select (alive _parameter); + if (alive _parameter) then { + if (_parameter isKindOf "LandVehicle" || _parameter isKindOf "Air" || _parameter isKindOf "Ship") then { + _vehicleUnits append (crew _parameter select {alive _x}); + } else if (_parameter isKindOf "StaticWeapon") then { + _staticUnits append (crew _parameter select {alive _x}); + } else { + _footUnits pushBack _parameter; + }; + [_parameter]; + } else { + []; + }; }; case "GROUP": @@ -55,10 +65,11 @@ private _units = []; ); } forEach _this; -if (DMS_DEBUG) then -{ - (format ["GetAllUnits :: Input (%1) produced units: %2",_this,_units]) call DMS_fnc_DebugLog; +if (DMS_DEBUG) then { + diag_log format ["GetAllUnits :: Foot units: %1", _footUnits]; + diag_log format ["GetAllUnits :: Vehicle units: %1", _vehicleUnits]; + diag_log format ["GetAllUnits :: Static units: %1", _staticUnits]; + diag_log format ["GetAllUnits :: Total units: %1", _units]; }; - _units diff --git a/@ExileServer/addons/a3_dms/scripts/fn_MissionSuccessState.sqf b/@ExileServer/addons/a3_dms/scripts/fn_MissionSuccessState.sqf index c0c57d0..9bd9771 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_MissionSuccessState.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_MissionSuccessState.sqf @@ -1,95 +1,74 @@ /* - DMS_fnc_MissionSuccessState - Created by eraser1 + DMS_fnc_MissionSuccessState + Created by eraser1 + Modified by Ravenger2709 - Usage: - [ - [_completionType1,_completionArgs1,_isAbsoluteCondition], - [_completionType2,_completionArgs2,_isAbsoluteCondition], - ... - [_completionTypeN,_completionArgsN,_isAbsoluteCondition] - ] call DMS_fnc_MissionSuccessState; + Usage: + [ + [_completionType1,_completionArgs1,_isAbsoluteCondition], + [_completionType2,_completionArgs2,_isAbsoluteCondition], + ... + [_completionTypeN,_completionArgsN,_isAbsoluteCondition] + ] call DMS_fnc_MissionSuccessState; */ -if !(_this isEqualType []) exitWith -{ - diag_log format ["DMS ERROR :: DMS_fnc_MissionSuccessState called with invalid parameter: %1",_this]; +if !(_this isEqualType []) exitWith { + diag_log format ["DMS ERROR :: DMS_fnc_MissionSuccessState called with invalid parameter: %1",_this]; }; private _success = true; private _exit = false; { - if (_exit) exitWith {}; - - try - { - if !(_x params - [ - "_completionType", - "_completionArgs" - ]) - then - { - diag_log format ["DMS ERROR :: DMS_fnc_MissionSuccessState has invalid parameters in: %1",_x]; - throw "ERROR"; - }; + if (_exit) exitWith {}; + try { + if !(_x params ["_completionType", "_completionArgs"]) then { + diag_log format ["DMS ERROR :: DMS_fnc_MissionSuccessState has invalid parameters in: %1",_x]; + throw "ERROR"; + }; - private _absoluteWinCondition = _x param [2, false, [true]]; + private _absoluteWinCondition = _x param [2, false, [true]]; - if (!_success && {!_absoluteWinCondition}) then - { - throw format ["Skipping completion check for condition |%1|; Condition is not absolute and a previous condition has already been failed.",_x]; - }; + if (!_success && {!_absoluteWinCondition}) then { + throw format ["Skipping completion check for condition |%1|; Condition is not absolute and a previous condition has already been failed.",_x]; + }; + if (DMS_DEBUG) then { + (format ["MissionSuccessState :: Checking completion type ""%1"" with argument |%2|. Absolute: %3",_completionType,_completionArgs,_absoluteWinCondition]) call DMS_fnc_DebugLog; + }; - if (DMS_DEBUG) then - { - (format ["MissionSuccessState :: Checking completion type ""%1"" with argument |%2|. Absolute: %3",_completionType,_completionArgs,_absoluteWinCondition]) call DMS_fnc_DebugLog; - }; - - switch (toLower _completionType) do - { - case "kill": - { - _success = _completionArgs call DMS_fnc_TargetsKilled; - }; - /* - case "killpercent": - { - _success = _completionArgs call DMS_fnc_TargetsKilledPercent;//<---TODO - }; - */ - case "playernear": - { - _success = _completionArgs call DMS_fnc_IsPlayerNearby; - }; - case "external": // This is a special completion type. It is intended to be a flag for people who want to control mission completion using _onMonitorStart and _onMonitorEnd through array manipulation. You probably don't want to use this unless you know what you're doing. - { - _success = _completionArgs; - }; - default - { - diag_log format ["DMS ERROR :: Invalid completion type (%1) with args: %2",_completionType,_completionArgs]; - throw "ERROR"; + switch (toLower _completionType) do { + case "kill": { + _success = _completionArgs call DMS_fnc_TargetsKilled; + }; + case "killpercent": { + private _initialUnitCount = _completionArgs select 0; + private _args = _completionArgs select [1, count _completionArgs - 1]; //Look for bandit.sqf mission for "killpercent" condnition example. + _success = [_initialUnitCount, _args] call DMS_fnc_TargetsKilledPercent; + }; + case "playernear": { + _success = _completionArgs call DMS_fnc_IsPlayerNearby; + }; + case "external": { + _success = _completionArgs; + }; + default { + diag_log format ["DMS ERROR :: Invalid completion type (%1) with args: %2",_completionType,_completionArgs]; + throw "ERROR"; + }; }; - }; - if (_success && {_absoluteWinCondition}) then - { - _exit = true; - throw format ["Mission completed because of absolute win condition: %1",_x]; - }; - } - catch - { - if (DMS_DEBUG) then - { - (format ["MissionSuccessState :: %1",_exception]) call DMS_fnc_DebugLog; - }; - }; + if (_success && {_absoluteWinCondition}) then { + _exit = true; + throw format ["Mission completed because of absolute win condition: %1",_x]; + }; + } catch { + if (DMS_DEBUG) then { + (format ["MissionSuccessState :: %1",_exception]) call DMS_fnc_DebugLog; + }; + }; } forEach _this; _success; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilledPercent.sqf b/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilledPercent.sqf new file mode 100644 index 0000000..7e86390 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilledPercent.sqf @@ -0,0 +1,50 @@ +/* + DMS_fnc_TargetsKilledPercent + Created by Ravenger2709 + + Usage: + [ + _initialUnitCount, + _unit, + _group, + _object + ] call DMS_fnc_TargetsKilledPercent; + + Will accept non-array argument of group, unit, or object. +*/ + +if (_this isEqualTo []) exitWith { + diag_log "DMS ERROR :: Calling DMS_TargetsKilled with empty array!"; +}; + +private _initialUnitCount = _this select 0; +private _args = _this select [1, count _this - 1]; +private _killedpercent = false; + +// Get the kill percent value from config +private _killPercent = DMS_AI_KillPercent; +//diag_log format ["DMS DEBUG :: Kill percent value: %1", _killPercent]; +//diag_log format ["DMS DEBUG :: Initial unit count: %1", _initialUnitCount]; + +// Calculate the acceptable number of killed units based on initial unit count +private _unitsThreshold = ceil(_killPercent * _initialUnitCount / 100); +//diag_log format ["DMS DEBUG :: Units threshold (killed units): %1", _unitsThreshold]; + +// Get all living AI units +private _allUnits = _args call DMS_fnc_GetAllUnits; +private _totalUnits = count _allUnits; +//diag_log format ["DMS DEBUG :: Total living units: %1", _totalUnits]; + +// Calculate the number of killed units +private _killedUnits = if (_initialUnitCount - _totalUnits > 0) then {_initialUnitCount - _totalUnits} else {0}; +//diag_log format ["DMS DEBUG :: Total killed units: %1", _killedUnits]; + +// Check if the number of killed units is greater than or equal to the threshold +if (_killedUnits >= _unitsThreshold) then { + _killedpercent = true; + //diag_log "DMS DEBUG :: Kill percent condition met"; +} else { + //diag_log "DMS DEBUG :: Kill percent condition not met"; +}; + +_killedpercent;